# Sub-agent dispatch (QA)

> Body of `## Sub-agent dispatch`. When this skill is launched as a sub-agent via `peaks sub-agent dispatch <role>` (then the LLM executes the returned toolCall) from `peaks-code`, the following sections of THIS skill are **suspended** for the sub-agent run:

## Superpowers chain refusal (L1 worktree governance — locked 2026-07-29)

You MUST NOT follow the superpowers chain for worktree decisions:

- superpowers:brainstorming → superpowers:writing-plans →
  superpowers:subagent-driven-development → superpowers:using-git-worktrees

This chain ends with `git worktree add` (superpowers:using-git-worktrees SKILL.md line 96). It bypasses peaks-loop's L2 hook gate and L3 IDE `permissions.deny`. Even when L3 denies the terminal Skill, the chain has already taught you to use raw `git worktree add`, so L3 is not sufficient.

For worktree operations, use ONLY:

- `peaks worktree spawn --rid <rid> --role <role> --purpose <text>` (after rid-L2-extended ships)
- until then: `peaks worktree auth grant --operation <op> --reason <text>` (`<op>`, e.g. `git-worktree` | `agent-isolation-worktree`)

The superpowers skills remain available as REFERENCE material for brainstorming / planning techniques, but MUST NOT be used as a workflow. peaks-qa's own QA artifacts (`.peaks/_runtime/<sessionId>/qa/<artifact>.md`) are authoritative.

If the upstream superpowers chain suggests raw `git worktree add`:

1. STOP
2. Re-author the QA plan as a peaks-qa artifact
3. Continue with `peaks worktree spawn` (or the auth-grant fallback)

- **Session id** — use the parent's sid (read `.peaks/_runtime/session.json` or pass `--session-id <parent-sid>` to any session-creating CLI). Do NOT spawn your own session. The new `peaks session info --active` reads the canonical binding for you.
- **Skill presence (MANDATORY first action)** — do NOT call `peaks skill presence:set peaks-qa`. The sub-agent must not overwrite the main presence lease; the main Code loop owns it. If you need to mark your own state, write a marker file at `.peaks/_runtime/<sessionId>/system/sub-agent-qa.json` and only that.
- **Workspace initialization** — Code has already run `peaks workspace init` before fan-out. Do not re-run it.
- **Mode selection** — Code has already chosen the mode.
- **Statusline install** — already done by Code at session startup.

What the sub-agent **MUST** still do:

0. **Do NOT call `peaks request init`** — Code has already initialised the request artefact slot in the main loop before fan-out. The sub-agent reads it via `peaks request show <rid> --role qa --project <repo> --json` if it needs to.
2. `peaks request show <rid> --role prd --project <repo> --json` (and `--role rd`, `--role ui` if UI is in the swarm plan).
3. Standards preflight (dry-run only).
4. Write `.peaks/_runtime/<sessionId>/qa/test-cases/<rid>.md` with test cases that link to PRD acceptance items.
5. Return only a compact JSON envelope:

```json
{
  "role": "qa-test-cases",
  "rid": "<rid>",
  "status": "ok" | "blocked" | "skipped",
  "artefacts": [".peaks/_runtime/<sessionId>/qa/test-cases/<rid>.md"],
  "warnings": [],
  "blockedReason": null
}
```

**Hard prohibitions** (sub-agent context):

- Do NOT call `Skill(skill="...")`.
- Do NOT call `peaks skill presence:set` — Code owns the presence lease.
- Do NOT run the actual test suite, do NOT execute security/perf tools, do NOT open a browser — those are the **QA validation** phase, not the Swarm planning phase.
- Do NOT commit, push, install hooks, or apply settings.json mutations.
- Do NOT ask the user interactive questions. If you need clarification, return `{"status":"blocked","blockedReason":"<text>"}`.

If `--type` is `docs` or `chore`, return `{"status":"skipped","reason":"type=<type>"}` and exit — there is no acceptance surface to plan tests for.

## Final report cap (mandatory, slice 2026-09-10-context-audit-and-discipline)

Your FINAL report to the parent MUST be **≤ 40 lines and ≤ 2 KB**. Write any longer detail into the artifact file you already own; the parent can `Read` that file for the full detail, so nothing is lost. The report itself MUST still carry:

- changed files (one line each)
- the exact commands you ran
- pass/fail counts
- tsc status
- any blocker

Do NOT paste file contents, full tool output, or logs into the report. **Rationale (measured, session 2026-09-07-session-245530):** 20 sub-agent final reports ≈ 60 KB ≈ 15K tokens of the orchestrator's window — the report is an index into the artifact, not a copy of it. This rule is also machine-injected into every dispatch prompt (`REPORT_CAP_BLOCK` in `src/services/context/build-dispatch-system-prompt.ts`); this doc and that constant MUST stay in lockstep.

## Test Tool Detection (mandatory)

The dispatch CLI (`peaks sub-agent dispatch`) automatically prepends a Test Tool Detection block to every sub-agent prompt — telling the sub-agent to read `package.json#scripts.test` first and use the project-local runner (`./node_modules/.bin/<runner>` or `pnpm test -- <file>`). NEVER use `npx <runner>`. This rule is machine-injected, not a prompt ritual — every sub-agent gets it including rd/qa/ui/txt/sc.

If the framework is not obvious from `package.json#scripts.test`, the sub-agent should run `peaks test --json` to introspect the resolved framework + argv before picking a runner.

See the block constant at `src/services/dispatch/test-tool-detection.ts` for the verbatim text.

## BDD Test Style Verification (effective rid-2026-08-05-bdd-test-style, v4.0.11+)

When you (peaks-qa) verify a slice, you MUST run the BDD test-style verifier on every new or modified `tests/unit/**/*.test.ts` file in the slice's git diff. Use:

```bash
node -e "
const { verifyBddStyle } = await import('./src/services/qa/bdd-test-style-verifier.ts');
const { execSync } = require('node:child_process');
const files = execSync('git diff --name-only HEAD~1 -- tests/unit', { encoding: 'utf8' })
  .split('\n').filter(f => f.endsWith('.test.ts'));
console.log(JSON.stringify(verifyBddStyle({ projectRoot: '.', testFiles: files })));
"
```

If the verifier returns `ok: false`, your verdict MUST be `failed: bdd-style-violation` with the structured reason from the verifier (do NOT mark the slice as passing).