Repository navigation
ci(review): fold real-world test evidence into the PR review comment via the gaia-testing skill (strix-halo) #2413
Description
Problem
GAIA's automated PR review (claude.yml → claude-run.yml) posts a comment based only on reading the diff — it never runs the code, because it executes on ubuntu-latest under pull_request_target with secrets in scope (running fork code there would leak them) and has no Lemonade/GPU. Meanwhile the real tests (test_*.yml, some on self-hosted strix-halo via install-lemonade) run separately and only report pass/fail status checks. The two never meet, so the review comment carries no real-world evidence — exactly what the gaia-testing contract (#2375 / PR #2376) says every change must show.
Outcome
The PR review posts one comment = code review + real test evidence the reviewer evaluated, produced by driving each changed surface through the gaia-testing skill on capable runners. UI/agent surfaces → embedded screenshots; CLI/API/MCP → command output / request traces / tool responses. Automatic for same-repo PRs; all surfaces the PR touches.
Design (primary: two jobs, one comment)
- Evidence job (new, in
claude.yml) on[self-hosted, strix-halo]for real inference/UI (falls back toubuntu-latestfor pure CLI/API when no inference is needed): brings up the stack via theinstall-lemonadeaction +gaia chat --ui, then a Claude-code-action invocation runs thegaia-testingskill against the PR's changed surfaces — Playwright for the Agent UI, CLI/API/MCP per the contract — captures evidence (screenshots → raw…-evidencebranch per the skill's raw-URL rule; text traces → an evidence bundle), and uploads the bundle as an artifact. - Review job (existing
pr-review) gainsneeds:the evidence job, downloads the bundle, and its prompt is extended: read the evidence bundle, evaluate it, and fold it into the single review comment (embedding the raw-URL screenshots). It still never executes PR code — it evaluates evidence + diff.
Alternative (if you prefer the literal "one agent tests then reviews"): run the whole review on strix-halo so a single Claude uses the skill to test and then comments — simpler, but couples every review to the self-hosted box's uptime and moves review off cheap ubuntu. Primary keeps review cheap + available.
Acceptance criteria
- A PR that changes a UI surface gets a review comment with an embedded, rendering Agent UI screenshot (raw.githubusercontent.com) produced by the gaia-testing skill on strix-halo
- A PR that changes CLI/API/MCP gets the matching text evidence (command+output / request+response / tool call+response) in the same comment
- Exactly one comment carries both the code review and the evaluated evidence (no second bot comment)
- Evidence generation invokes the
gaia-testingskill (not a hand-rolled reimplementation) so the contract and its extraction stay single-sourced - Same-repo PRs run automatically; fork PRs do not execute on self-hosted runners without a maintainer label (untrusted-code gate) — their comment says tests were gated
- The review job's security boundary is unchanged (it reads evidence + diff, never runs PR code); rubric/skill still sourced from the base branch, never the PR head
- Surfaces the PR doesn't touch are marked N/A, not silently skipped
Scope & expectations
- Where:
.github/workflows/claude.yml(new evidence job +needs:wiring + review-prompt extension), theinstall-lemonadeaction, thegaia-testingskill (add a "CI runner mode" section: strix Windows specifics, evidence sinks that work without R2 secrets on forks, the label gate) - Depends on: PR docs(testing): bind real-world evidence contract to the changed surface #2376 (the gaia-testing skill + raw-URL evidence rule) merging first
- Out of scope: replacing the existing
test_*.ymlstatus-check suites; NPU-specific matrices; non-GAIA repos - Constraints: do not weaken the
pull_request_targetboundary; strix-halo is a Windows self-hosted runner (PowerShell,install-lemonade/ensure-lemonade-running.ps1); real-inference runs are slow — keep the evidence run scoped to changed surfaces, not the whole suite
How to verify
Open a throwaway PR touching (a) an Agent UI path and (b) a CLI path; confirm the single review comment embeds a rendering screenshot for the UI change and shows command output for the CLI change, and that the evidence run logs show the gaia-testing skill being invoked on strix-halo. (Same disposable-PR method we used to validate the contract itself.)
Activity
github-actions commentedon Jul 23, 2026
This is a solid, well-scoped design — the "two jobs, one comment" split (cheap
ubuntureview +strix-haloevidence, folded vianeeds:) is the right call over coupling every review to the self-hosted box's uptime. It's actionable as written. One security nuance worth pinning down explicitly before implementation, plus a couple of grounding notes below.The one thing I'd flag: the evidence job is the first place in this pipeline that executes PR-head code (the review jobs only read the diff). On a self-hosted Windows runner that's a real trust boundary — the maintainer-label gate you list handles forks, but the evidence job must also keep secrets out of scope and clean workspace state between runs, since self-hosted runners persist. Worth making that an explicit acceptance criterion. 🔒 cc @kovtcharov-amd since this touches the
pull_request_targetsecurity model.🔍 Technical details
Grounding against the current files:
.github/workflows/claude.yml— the review jobs (pr-review,pr-rereview) don't run inline; they call the reusableclaude-run.ymlviauses: ./.github/workflows/claude-run.yml(lines ~126, ~375). Aneeds:-wired evidence job producing an artifact the review job downloads works, but the review job is a reusable-workflow call, notsteps:— so the "download bundle + extend prompt" wiring either needs the bundle passed as an input toclaude-run.ymlor the review job restructured to inline steps. Worth deciding which in the design.pull_request_targetruns with base-repo secrets in scope even on fork PRs, and that the workflow file is sourced from base (main). The evidence job inherits that context, so: (a) it must not expose secrets to PR-head test execution, and (b) the "rubric/skill sourced from base branch" criterion is already the established pattern here — good, keep it.install-lemonadeaction +ensure-lemonade-running.ps1are the strix-halo (Windows/PowerShell) bring-up path referenced correctly; the manytest_*.ymlsuites stay as status-check sources per the out-of-scope note.gaia-testingskill exists at.claude/skills/gaia-testing, so the "invoke the skill, don't reimplement" criterion is enforceable.Suggested added acceptance criterion: the evidence job runs PR-head code with no repo secrets in its environment and resets the self-hosted workspace between runs (untrusted-code isolation on a persistent runner).
itomek commentedon Jul 23, 2026
Phase-1 implementation plan (branch
tmi/ci-review-evidenceset up off main)Security architecture (the crux): the evidence job must run the PR's code, so it runs on
pull_request(no secrets, read-only token — fork-safe), uploads the evidence as an artifact, and the existingpull_request_targetreview job (which keeps the secrets and never runs PR code) pulls that artifact and folds it into its single comment. Cross-trigger artifact hand-off is the part that needs CI validation.Phase 1 — wiring + CLI/API lane (ubuntu, validatable without strix)
pr-evidencejob (triggerpull_request,runs-on: ubuntu-latest, no secrets): checkout PR head → set up python/gaia → invokeclaude-code-actionprompted to use thegaia-testingskill to produce evidence only for the CLI/API/MCP surfaces the diff touches → writeevidence-bundle.md→actions/upload-artifact.claude-run.yml: add optionalevidence_artifactinput; when set,download-artifactinto the repo root before the Claude call so the reviewer seesevidence-bundle.mdalongsidepr-diff.txt.pr-reviewjob: passevidence_artifact; extend the prompt — "ifevidence-bundle.mdis present, evaluate it and fold its evidence (verbatim command output / request traces) into the single review comment; mark untouched surfaces N/A." Boundary unchanged: it reads evidence + diff, never executes PR code.Phase 2 — strix-halo UI/agent lane
pr-evidencegains a self-hosted[self-hosted, strix-halo]variant (label-gated for forks):install-lemonade+gaia chat --ui+ headless Playwright via the skill → screenshots pushed to a…-evidencebranch (raw-URL rule) → same bundle. Windows/PowerShell specifics perensure-lemonade-running.ps1.Skill: "CI runner mode" section
Add to
gaia-testing(AFTER #2376 merges, to avoid a SKILL.md conflict): the two-runner split, evidence sinks that work without R2 secrets on forks (artifact + raw evidence branch), the label gate.Recommended sequencing
Merge #2376 first (one approval away) so this builds on the final skill and doesn't conflict; then execute Phase 1 and iterate on CI. Same-repo PRs run automatically; fork PRs label-gated for the code-execution job.
ci(review): run gaia-testing evidence and fold it into the PR review …
ci(review): standalone pull_request evidence workflow, not the shared…
ci(review): fold gaia-testing evidence into the PR review comment (Ph…
ci(review): broaden evidence gate + require a verdict-linked evidence…