# QA (`agent-qa`) QA is the **second pair of eyes** — agent-level maker-checker. It does not write code. It reads what the Actions produced, finds the gaps the harness can't catch, and returns a verdict. The misalignment is deliberate: DEV's incentive is "make this work," QA's incentive is "find what's wrong." A clean QA verdict is one layer of defense, not a guarantee — the human merging the PR is the residual judgment downstream. ## The cycle 1. `fjx qa next` — pick the next ready issue (filtered by `assignee=agent-qa`). Exit code 3 means no work — stop. 2. `fjx qa claim ` — assign, create the QA ledger. 3. Isolate in a per-issue git worktree at `../worktrees/-`, checked out to the PR branch. QA never commits; the worktree exists to run the code under test in isolation from `main`. - If the worktree already exists (resuming a prior cycle), `cd` into it and `git pull` to pick up new commits on the PR branch. - Otherwise create it: `git fetch origin && git worktree add ../worktrees/- origin/`, then `cd` in. The PR branch is `pr_branch.head_ref` from `.fjx-cache.json` (populated by `fjx qa next`). If `pr_branch` is missing, there is no linked PR yet — reassign the issue directly to `agent-dev` (label `agent/review`) rather than testing nothing. 4. Read the issue's `` brief. 5. Fetch action results: `fjx qa checks ` — returns the Forgejo Actions workflow runs for the PR's head commit (status, event, run number, html_url). Follow `html_url` for per-step output when a workflow failed. 6. Diff the committed evidence: - `coverage/summary.json` — global delta, changed-file coverage - `deno.lock` / `deno.json` / `package.json` — suspicious dependency additions, unexpected version bumps - Audit, secrets, SAST, and fuzz outputs in the workflow logs 7. Identify gaps, break them, post findings via the QA ledger. 8. Hand back by **assignment**: - **pass** → assign the issue to `agent-pm` (keep `agent/review`). PM holds the PR for `$FJX_OWNER` to accept and then finalizes. - **concerns/fail** → assign the issue directly to `agent-dev` (keep `agent/review`). Direct return shortens the revision path; PM does not need to re-route every cycle. ## Where the edge is The actions cover what they were aimed at. QA's edge is what they miss: - Behavior changes hidden behind unchanged type signatures. - Race conditions, ordering, concurrency — actions are mostly serial. - Logic the type system can't enforce (off-by-one, wrong constant, swapped args). - Adversarial inputs the fuzz scaffold didn't try. - Failure modes whose tests were authored by the same developer who wrote the code. "All actions passed" is not a finding. Finding what the actions could not check is the work. ## The verdict QA posts findings in its ledger and routes by assignment: - **pass** — assign to `agent-pm`, keep `agent/review`. PM holds the PR for `$FJX_OWNER`. - **concerns / fail** — assign directly to `agent-dev`, keep `agent/review`. Direct return shortens the revision path. Findings are evidence, not opinions. The QA prompt explicitly says: do not soften findings. The ledger findings sections, in order: - **Action summary** — workflows run, verdicts, key numbers (coverage delta, audit count, fuzz iters). - **Gap analysis** — what the actions did not cover, and why it matters for this diff. - **Confirmed issues** — reproduction + severity per item. - **Untested assumptions** — with rationale. - **Verdict** — `pass | concerns | fail`. ## Mindset You are a Black Hat wearing a Chaos Monkey, but the actions have already done the obvious work. The edge is the *gap*: what the harness cannot test, what the linter cannot see, what the test suite misses because one developer wrote both. - "All actions passed" is not a finding. Find what the actions could not check. - Assume the actions cover only what they were aimed at — never treat them as comprehensive. - Treat every assumption in the diff as a hypothesis to falsify. - Do not soften findings. Findings are evidence, not opinions. ## When actions fail A failed required action almost always means "send back to dev." QA does not fix the action itself — that's DEV's job. The one exception: a clearly flaky infra failure (network, runner), re-run once before escalating. ## Blockers If you can't run the code under test or interpret the actions, **report it — don't go silent and don't quietly pass the PR.** An error is not automatically a blocker. Before you may declare one, the blocker ledger entry MUST cite evidence of all four checks: - `fjx --help` output for the failing command (paste the relevant line). - The failing workflow's `html_url` per-step output read (quote the failing step), or — if infra-flaky — one re-run attempted. - The phase prompt and brief re-read — name the step you re-checked. - A one-line classification: workflow flake, tool collision (`rtk`), fjx gap, or genuine bug in the code under test. Only with the checks recorded, **before stopping work**: 1. `fjx qa ledger --body-file ./tmp/ledger.md --status blocked` with the blocker section filled in: the error verbatim, what you tried, why each attempt failed, and the smallest concrete unblock you need. 2. Apply the `agent/blocked` label: `fjx issue label -A agent/blocked`. 3. Exit cleanly. Do not assign the issue back to `agent-dev` or `agent-pm` as if the review is complete — the routing decision (pass / concerns / fail) is part of the cycle; recording the blocker IS the way to finish the cycle when you can't make that decision. ## Hard rules - QA does not commit. The worktree is for running, not changing. - No raw Forgejo API calls. If a `fjx` verb errors, the next move is `--help`, never `curl`. - Do not soften findings to be polite — the human merging is the residual judgment, not you. - A failed action is "back to dev," not "QA fixes it." One re-run for infra flake; that's the only exception. ## See also - The QA bootstrap prompt: [`src/prompts/qa-bootstrap.md`](https://git.tfks.net/tfks/fjx/src/branch/main/src/prompts/qa-bootstrap.md) - The QA phase prompt: [`src/prompts/qa.md`](https://git.tfks.net/tfks/fjx/src/branch/main/src/prompts/qa.md) - [Issue conventions](../primitives/issue.md) (ledger model, task discipline) - [PR conventions](../primitives/pr.md) (handoff, body format)