Agents now start pre-mr-review on the work account themselves, through a Klaude delegate, and continue from its verdict. A council of models on my own accounts replaces the single reviewer before it, and adding a seat is one table row. Proof comes from T3's browser, with mp4 recordings, and capture-proof stays as the fallback. Ticket pages carry their own data, so index.html renders alone in T3's file viewer, and worktree threads share the main checkout's docs. A PreToolUse hook sends subagents in T3 threads to delegate_task. Blocker, proof, review and MR summary rules come from ideas in t3dotgg/tstack.
7.1 KiB
The review council
Several fresh agents from different model families review the same change, each knowing nothing
of how it was built. You judge what they return. This runs before pre-mr-review, because
that audit may not run anything and so cannot catch a claim that is plausible on the page and
false in reality. A reviewer that can run things can. It has caught a mitigation proven by
construction to be wrong, on a branch whose own audit had blessed it.
Order matters. pre-mr-review's verdict gets pasted verbatim into mr.md, and anything that
lands after it invalidates that verdict. Council first, fix, commit, then the audit over the
final tree.
Seats
| Seat | providerInstanceId |
model |
|---|---|---|
| Claude | claudeAgent |
omit it, so the seat runs that provider's default |
| MiMo | opencode |
opencode-go/mimo-v2.6-pro |
Klaude never takes a seat. It is the work account, and its only job is the pre-mr-review run
in Phase 2 step 7, which stays a separate required step after the council.
Adding a seat is adding a row. orchestrator_capabilities has the IDs, with search for a
model it does not list. Nothing else here changes with the seat count. T3 can leave out a model
the provider really has, as it does with opencode-go/*. List such a model under that provider's
customModels in ~/.t3/userdata/settings.json, which T3 picks up without a restart.
When it runs
Run it whenever the change adds or modifies a procedure, touches schema or migrations, touches permissions or auth, involves concurrency, or has a risk table in its ticket. When unsure, run it. A copy tweak, a styling fix, or a one line correction with no logic skips it.
Convene
- Confirm the suite is green, and note the base and head of the commit range. A seat should never spend its review on code the suite already rejects.
- In one turn, call
delegate_taskonce per seat with the brief below:role: "review",mode: "async", a title ofCouncil <seat> <KEY>, and the seat'starget. Leaveisolationunset, so each seat reads this checkout, and leaveruntimeModeunset. - End your turn. T3 wakes you as each seat finishes. Leave the checkout alone until every seat has returned, because they are reading it.
- A seat refused with
model_unavailable, or one that fails: record it withticket-page event, carry on with the rest, and name it at hand-off. Keep the seat empty rather than filling it with another model. If no seat can run, ask Gib with AskUserQuestion. A timeout or silence is not an approval.
Outside T3 Code (no T3CODE_THREAD_ID), run one fresh subagent from the harness with the same
brief. Never review the change in your own context: the value here is the reviewer not being
the author.
The brief
A delegate gets none of this thread, so the brief is all it knows. Fill the placeholders.
Review only. Do not edit, commit, push, run anything destructive, or start subagents.
Repo: <absolute path> Range: <base>..<head> Ticket: <KEY>
Read in this order, or you will report conventions this project already settled:
1. .claude/docs/epics/<EPIC-KEY>/summary.md, if it exists
2. <scratch path of `ticket-page md <KEY>`>
3. <target-dir>/resources/
4. AGENTS.md
5. git diff <base>..<head>, then the code around it
Verify rather than suspect. You may run tests and read-only checks. Try to refute each finding
before you report it. A plausible worry is not a finding.
Re-derive every "proven by X" already written into the ticket's risk or test tables. A false
proof claim in Jira is worse than an unproven one, because it stops anyone else from checking.
Answer these against the ticket and plan, not the diff alone, quoting the AC ID or plan step:
- What did the ticket ask for that is missing or only partly done?
- What behavior is in the diff that nothing asked for?
- What looks implemented but is implemented wrongly?
Hold the change to its smallest correct form. Flag code, tests, or guards the ticket does not need.
blocker = the intended case is wrong. should = a real bug callers will hit. nit = everything else,
including rare paths, small performance costs, and style.
Reply with:
VERDICT: APPROVE or CHANGES
S1 [blocker|should|nit] [CONFIRMED|PLAUSIBLE] <file>:<line> <claim>. Failure: <concrete scenario>. Fix: <smallest fix>
Judge the findings
Findings are not automatically true, and reviewers produce confident wrong answers. Check each one against the code yourself, and regrade it: a rare path is a nit whatever label it came with. Two seats reporting the same thing is one finding with more weight behind it. A finding only one seat raised is still worth checking, since catching what the others miss is why the seats differ.
Put each on the page as you judge it, with its grade and its seats in the text:
finding <KEY> add "[should] <text> (Claude, MiMo)" --severity CONFIRMED --where <file:line>, then
fixed --commit <sha>, or rejected --reason "<why>".
- Fix every blocker and should you confirm, each meaningful fix as its own commit. These do not defer to a follow-up ticket unless Gib decides that.
- Take the smallest fix. Prefer deleting or narrowing code over a new lock, cache, helper, or
option. Compare
git diff --shortstat <base>before and after: if review grew the diff, cut first. Review loops grow a change one cheap-looking fix at a time, and it is your job to hold the scope. - Decline nits in one line with
rejected --reason, and list them at hand-off as follow-ups. Agreeing just to end the review is how a change bloats. - When a fix changes a mechanism rather than a line, write a test that fails against the old behavior and passes against the new one, and confirm it fails by reverting the fix. A test that passes either way proves nothing.
- If a finding invalidates something already in Jira or a deliverable, correct it there too. Fixing the code does not fix the false claim.
Stop
One round is the default. pre-mr-review reviews the whole diff, your fixes included, and serves
as the next pass. A second round runs only if a fix changed a mechanism: fresh delegate_task
calls, the same brief, the ledger of what you fixed and rejected with your evidence, and an
instruction to check only the open ids and the changed code. Two rounds is the limit. A finding
still disputed then goes to Gib with AskUserQuestion, both sides in two or three lines each.
Checking a dev review
review-ticket borrows the seats for a draft instead of a diff. Same delegate_task settings, and
no code gets changed. Give each seat this:
Review only. Do not edit anything, write to Jira, or start subagents.
Repo: <absolute path> Draft: <dir>/review.md Story: <scratch path of the fetched story>
Check the draft against the code. Report each Current State claim that is false, each "does not
exist" that does, each named pattern that is a poor fit or has a better neighbour, each seam the
Relationships section gets wrong, and any story AC the implementation guidance would not satisfy.
Say whether the estimate misses work the code paths table leaves out.
Reply with:
VERDICT: APPROVE or CHANGES
S1 [blocker|should|nit] <section> <claim>. Evidence: <file:line>. Fix: <suggestion>