**Filbert review, row 149 round 2: changes.** Candidate: manifest `a325a32568a6a2635837455795b0965f1126f31fc25c4048e56e132263aeffcb`, Dewey's build.patch applied to ac55e84fe (origin/refactor). In a fresh worktree all 21 hashes check. The patch's added and removed lines are the same as round 1's, so only context moved. I didn't post a round 1 verdict, so this round covers the whole row, not only the 5 drifted paths. Lines below are at the candidate tree. ## Changes 1. **merge-gate can't land in the run that raised the decision, and merge-gate.md says it can** (roles/merge-gate.md:16-20). - `land_work` exists only when the broker's `landHeld` is true at launch (packages/cli/src/launcher.mjs:262, packages/harness/src/tools.mjs:134). The git socket is bound only then too (packages/cli/README.md:432-434), because merge-gate holds neither git.push.working nor review.verdict. The runner reads tools.json once, at start (packages/harness/src/runner.mjs:322). - In the raising run, `landHeld` was false at launch. When cto resolves, the approval comes in as a DECISION message to that same run (packages/bus/src/broker.mjs:1597-1612), and that run has no `land_work`. The bundle's "Landing:" prompt line (packages/harness/src/bundle.mjs:118) is missing too. So line 16's "Once the decision is resolved ..., call `land_work`" can't be done. - Row 137 meant it this way: "row 136 lets a later run of the same instance use it" (brief docs/plans/2026-10-15_q167-rows-r3.md:328-331, blob 606f7e09052f). A second run of merge-gate, in the same thread, has to start before anything lands. No contract says who starts it. merge-gate can't message anyone: its RESULT reply to the DECISION message is refused, per your probe. cto.md and chief-of-staff.md say nothing about relaunching it. As shipped, an approved merge sits unused until a person notices. - Fix: - Say the two-run flow in merge-gate.md: `land_work` appears only in a run launched after the approval, in the thread that raised it. In the raising run, the approval arrives without the tool. - Name who starts the landing run in that role's contract, or record it in BUILD.md's Follow-ups with its cost, the way follow-up 1 does for message.send. - Add a test that pins the path. In packages/bus/tests/workflow-roles.test.mjs, `b.landHeld({ business: 'demo', role: 'merge-gate', thread: null })` should be false before cto resolves, true after, and false once the approval is used. - roles/merge-gate.md is test-read (packages/business/tests/workflow-roles.test.mjs:59, 93), so this isn't doc-only under decision 137. ## Minor, fix in the same round 2. **The hard-wait list in pm.md:53-56 and chief-of-staff.md:52-55 leaves out one case the broker treats as a hard wait.** `#hardWait` is GATED plus `role.revoke` aimed at an END_PROTECTED instance, which today is `assistant` (broker.mjs:139, 516-519). A cited `role.revoke` of the assistant goes to the human (broker.mjs:1466-1469). The text says "every hard wait goes to the human" and then lists only the eight GATED_ONLY actions. Keep the eight-action sentence, since the test pins it to GATED_ONLY at workflow-roles.test.mjs:112-114. Add a sentence for ending the assistant's run. ## Checked and correct - Brief: every "What ships" bullet and every listed test (q167-rows-r3.md:162-216). - security-reviewer: read, grep, find, ls; `review.verdict` within role only; no crossRole; no credentials. - merge-gate: crossRole `git.merge.protected` only; empty withinRole; no write tools. - The proactive line is inside Authority in all 13 contracts. - The domain enum in tools.mjs is technical and delivery, with no default sent. - pm and chief-of-staff carry the REQ-DEC-2 text, and their old "for the human" wording is gone. - `raise_decision` forwards `domain`. The broker defaults it to delivery and refuses anything else with invalid-domain (broker.mjs:1461-1462). The arbitrated route matches the new tool text and the contract text (broker.mjs:1466-1469). - Row 133's refusal works on the shipped lists. merge-gate's receiveFrom includes cto. `checkMessaging(route, raiser)` runs before anything is stored (broker.mjs:1473). The bus test drops cto and gets decision-route-refused with 0 decisions. - Naming either new role as an arbiter is refused because both declare messaging lists (packages/business/src/business.mjs:167-168). The business test pins that. - security-reviewer's REVIEW-RESULT reaches the coder through `review.verdict`, with no message.send (bus test lines 86-99). `fetch_review` is offered only with a checkout (tools.mjs:151). Your follow-up 2 covers a reviewer that has no way to read a ref. - The rebase onto ac55e84fe. Row 143's Duties bullets in assistant, chief-of-staff, pm and cto don't conflict with this row's Authority paragraphs. In tools.mjs only `raise_decision` changed; `MESSAGE_CLASSES` keeps BLOCK. - READMEs: the packages/business section and the packages/harness paragraph match the code. ## Not run by me I ran no tests, mutants or gate. Finding 1 changes merge-gate.md and adds a test, so I'll run the touched files singly in round 3 with a slot. Your singles (r2/singles.log, 37 files, 337 tests) and round 1's mutants and gate are your receipts, not mine. Verdict: **changes**, on 1. Item 2 is small and can go in the same round.