From 871b595954cd28deee58973a4d0bed61ccef6b56 Mon Sep 17 00:00:00 2001 From: Kevin Nguyen Date: Tue, 4 Aug 2026 22:32:19 +0700 Subject: [PATCH] CB-518: state the primary's orchestration as an explicit, ordered flow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CB-517 moved orchestration policy into CLAUDE.md but left it as a bullet list, so the procedure was implicit: the order of operations had to be reconstructed from a parallelisation bullet, and nothing said when to review or when to tear down. A policy you have to reassemble on each task is one you will reassemble differently each task. Restate the primary's half as a numbered 0-8 flow — role check, split, gate, spawn all, send all, collect, verify, review, adjudicate — so that following it is checkable against the tool calls rather than a matter of recall. Two steps carry the load. Spawn and send are separate on purpose: folding them into one loop is what silently serialises work that was meant to fan out. And review is now its own step ahead of the merge rather than a clause inside it, because the two have opposite owners — reviewers fan out over the diff (never the implementer of the scope they review, and briefed from the diff rather than the author's rationale, which carries the same blind spot), while adjudication, the merge and teardown stay with the primary. Merging on a reviewer's word is delegating the gate by proxy, so the step says so outright. Nothing is dropped. The six bullets that trailed the tool table are relocated into the step that owns each — profile explicitness into spawn, playbook naming and self-containment into send, claim verification into its own step, the ~60s blocking-send cap into a note beneath the flow — and the table stays as the intent→tool lookup. The wiki pointer moves with it. The block is canonical only if its template matches byte for byte, so the template was produced by splicing the block out of CLAUDE.md rather than by editing it in parallel, and the sync check the repo documents passes. Bumping the pointer in the same commit keeps charter and template versioned together, as CB-517 did. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_017Kw1FosEt3Noix5GG9wJ2r --- CLAUDE.md | 74 ++++++++++++++++++++++++++++++++----------------------- wiki | 2 +- 2 files changed, 44 insertions(+), 32 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 4afcedd..bc9bfa7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -48,25 +48,53 @@ nothing. Fail toward the recoverable error. 5. **Never drive the terminal multiplexer directly** (no `herdr` CLI, no socket). The bridge owns policy; the multiplexer owns PTYs. Going around the bridge bypasses every rule above. -### Primary (lead) — orchestration +### Primary (lead) — run this on every task, in order **Delegate by default — that is the job.** With the bridge mounted you are an orchestrator on a metered subscription, and workers are cheap, parallel, and disposable. The default answer to "who -does this?" is **a worker**, not you. Reach for `bridge_send` before you reach for `Edit`. +does this?" is **a worker**, not you. Reach for `bridge_send` before you reach for `Edit`. The steps +below are the procedure — run them in order, every task, not only the big ones. -- **Delegate**: implementation behind a clear spec, test writing, per-file or wide-area review, log - and failure triage, mechanical refactors, doc passes, and any investigation with a stated - question. If the unit of work is independent, fan out — one worker per file, area, or dimension — - and reduce the replies yourself. -- **Keep**: the conversation with the user, decomposition and planning, the final judgment call, - merges, and anything that depends on context only you hold. -- **The bar is not "could I do this faster myself?"** — usually you could. It is **"can I write a - brief good enough for a worker to succeed?"** If yes, write the brief and send it. A wasted worker - turn costs a worker turn; doing it yourself costs your context and your subscription. -- **Parallelize instead of serializing.** For independent units, spawn one worktree worker each - (`bridge_spawn{worktree:true, ticket:…}`), dispatch every one with `wait:false`, then poll the - tickets. Waiting for worker A before briefing worker B is the most common way this layer is wasted. -- **Delegating does not delegate responsibility.** You still review, verify, and merge. +0. **Know your role** — `bridge_whoami`, once per session, before anything else. +1. **Split.** Write the unit list. Every unit carries: scope · the files or PR in question · + acceptance criteria · exactly what to report back. A unit with no acceptance criteria is not + ready to delegate — refine it or keep it. +2. **Gate each unit** on one question: **"can I write a brief good enough for a worker to + succeed?"** — *not* "could I do this faster myself?" (usually you could; doing it yourself costs + your context and your subscription, while a wasted worker turn costs a worker turn). Yes ⇒ + delegate. The keep-list is closed: the conversation with the user, decomposition and planning, + the final judgment call, verification, merges, and anything that depends on context only you + hold. Nothing else is yours by default. +3. **Spawn every delegated unit first** — `bridge_spawn{profile, worktree:true, ticket}`, one per + unit, *before* sending any. Pass `profile` explicitly: profiles differ in model and cost, not in + tier, so the default is rarely what you want. +4. **Then send them all** — `bridge_send{sessionId, content, wait:false}`. Line 1 of every brief is + `Load the skill.` naming the worker's playbook; those skills are opt-in and that line is + what makes them reliable. Where the project ships no such skill, spell the procedure out in the + brief instead. The brief is self-contained — the worker sees your message and the repo, nothing + of your context, your plan, or your screen. +5. **Collect** — `bridge_poll{ticket}` → `bridge_ack{ticket, msgId}`. Answer a worker's `bridge_ask` + with `bridge_send{turnId, content}` — **not** `sessionId`. A worker gone quiet is diagnosed with + `bridge_status`, never by reading its terminal. +6. **Verify yourself.** Re-run the build and the checks. A worker mounts only the bridge MCP and + cannot run your other tooling, and a piped command (`… | tail`) hides failures behind a zero + exit — never promote a worker's "clean" to a fact. +7. **Review — fan out.** Spawn reviewers against the diff, one per dimension or per file, with + `wait:false`. Never the implementer of the scope it reviews, and brief them from the diff — not + from the implementer's rationale, which carries its own blind spot. Dispatch each PR's reviewers + as it lands; don't wait for the last implementer. Under ~50 changed lines, skip the fan-out and + read it yourself. +8. **Adjudicate, merge, tear down — yours alone.** Read the diff yourself: fully if it is small, + targeted at the reported findings and the risky paths if it is large. Reviewer findings direct + your attention; they never substitute for it. Then merge, then `bridge_stop{paneId}`. + +**Steps 3 and 4 are separate on purpose** — spawning and sending in one loop is how parallel work +silently becomes serial, and it is the most common way this layer is wasted. For the same reason, +prefer `wait:false` + `bridge_poll` for anything non-trivial: a blocking `bridge_send` is capped by +*your own* MCP client call timeout (~60s), well below the task's real runtime. + +**Delegating does not delegate responsibility.** Workers open PRs; you are the gate. Never delegate +the merge — and merging on a reviewer's word is delegating it by proxy. | Intent | Tool | |---|---| @@ -80,22 +108,6 @@ does this?" is **a worker**, not you. Reach for `bridge_send` before you reach f | Collect a held reply | `bridge_poll{target}` · then `bridge_ack{target, msgId}` | | Tear down | `bridge_stop{paneId}` | -- **Pass `profile:` explicitly.** Profiles differ in model and cost, not in tier — don't assume the - default is what you want. -- **Prefer `wait:false` + `bridge_poll` for anything non-trivial.** A blocking `bridge_send` is - capped by *your own* MCP client call timeout (~60s), well below the task's real runtime; the ticket - path is what survives a long task. -- **Every delegation names the worker's playbook.** If this project ships role skills, make the - first line of `content` `Load the skill.` — those skills are opt-in, and that line is what - makes them reliable. With no such skill, spell the procedure out in the brief instead. -- **A delegation must be self-contained**: scope, the files or PR in question, acceptance criteria, - and exactly what to report back. The worker sees your message and the repo — nothing of your - context, your plan, or your screen. -- **You are the gate.** Workers open PRs; you review and merge. Never delegate the merge. -- **Verify what a worker claims.** A worker mounts only the bridge MCP and cannot run your other - tooling, and a piped build command (`… | tail`) hides failures behind a zero exit — re-run the - build and the checks yourself before you believe "clean". - ### Worker — the turn contract 1. **Load the playbook skill the lead named** before doing anything else. diff --git a/wiki b/wiki index da015de..0c896eb 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit da015defc4290058785e894df4e90a3be33e0047 +Subproject commit 0c896eb49b042383d0de6535ffcb5344b1e11b5f