Run delegated work reliably — writing subagent charters, verifying subagent claims, keeping judgment at the orchestrator tier, ledger discipline, recovering from interruptions, and shipping/merging lane PRs. Use when spawning subagents or workflows, coordinating parallel lanes, resuming after a session limit or compaction, or rebasing and merging a lane's PR. The subagents skill covers task sizing and model choice; this skill covers everything after the spawn.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
La commande reste sur une seule ligne. Faites défiler horizontalement pour la vérifier avant de la copier.
Vous préférez une copie locale ? Téléchargez les fichiers actuellement disponibles dans SkillsMP.
Affichage de SKILL.md
SKILL.md
Instructions source · Aperçu en lecture seule
name
orchestration
description
Run delegated work reliably — writing subagent charters, verifying subagent claims, keeping judgment at the orchestrator tier, ledger discipline, recovering from interruptions, and shipping/merging lane PRs. Use when spawning subagents or workflows, coordinating parallel lanes, resuming after a session limit or compaction, or rebasing and merging a lane's PR. The subagents skill covers task sizing and model choice; this skill covers everything after the spawn.
Orchestration
Delegation only works when the orchestrator treats every subagent claim as unverified and every judgment call as its own. These rules were each paid for by a real incident.
Charters
A charter is the task prompt a subagent receives. Requirements:
Reference every document by absolute path, and only paths that live in the repository — repo skills under .claude/skills/, repo scripts behind their package commands. A relative path resolves differently (or not at all) in the agent's working directory, and a personal home-directory path can vanish out from under a live agent: ~/.claude/skills was deleted mid-goal to end personal/project skill drift, leaving in-flight charters instructing agents to sweep browsers from a path that no longer existed while the package's own sweep command was the live one.
When the work depends on an external spec or vendor document, fetch it raw — curl or a real browser, never a summarizing fetch — into a scratchpad cache file, and name that cache path in every dependent charter. All lanes then build from identical bytes; left to fetch it themselves, each agent works from its own paraphrase and the lanes drift apart on the contract they were supposed to share.
When parallel lanes could touch the same module, name the sibling lanes and give each an explicit do-not-touch list of files/functions the others own. For genuinely shared append-only files (routes config, nav layout, seeds), say up front that rebase conflicts there resolve keep-both. A fence names artifact classes as well as files — E2E specs, docs articles, and seed sections are the verification stage's territory — because a file-level list cannot fence a file that does not exist yet, and a build stage drifted into writing the spec its verification stage owned. Before launching, check each item's designed fix against its lane's do-not-touch list: an item whose only defensible fix lives in a sibling-owned file moves to the lane that owns the file, or gets an explicit carve-out — left as is, the builder must choose between skipping the item and violating the boundary, and one wave produced a skipped item, a banked residual, and a flagged two-file deviation from exactly this.
At most one repo-mutating agent per worktree at a time, and an agent that verifies against a builder's live worktree is read-only toward it. A concurrent sibling's git add/commit sweeps the other agent's half-finished files into an unrelated commit, and untangling that means rewriting the branch tip.
When parallel lanes allocate from a shared identifier pool — seed namespace prefixes, fixture ids, ports, queue names — the orchestrator publishes one canon allocation table in every lane's charter before the first launch, and each lane sub-partitions its allotment across its own flows. Lanes that pick identifiers independently collide, and the collisions surface as another lane's spec failing long after both lanes went green in isolation; one wave shipped three separate collisions (two lanes sharing a phone prefix, two sharing a fixture id, one lane colliding with itself) before the table became standing practice.
When several lanes will each touch a shared computed constant — a contract fingerprint, a generated schema hash — every charter declares the same resolution protocol up front: on rebase, recompute the value by the mechanism that owns it (its own test's computation), never keep-mine or keep-theirs. Three parallel lanes once rewrote the same fingerprint off stale bases, and every merge needed a hand repin. Each charter also declares whether its own items are expected to move the constant; an unexpected movement is a stop condition to report, never a silent repin — a lane that repins a public contract hash it had no business moving ships the change invisibly under a green suite.
Assign each subagent an explicit scratch-file namespace — its lane or task name as a filename prefix — and forbid it from writing any shared scratchpad file, above all the orchestrator's session ledger, whose actual path the charter must give since it is named for the effort rather than by a fixed convention. Parallel agents that share a scratch filename clobber each other's state, and a fix agent that writes its own notes over the session ledger destroys the orchestrator's recovery record.
Include a stop-on-contradiction clause: if the charter's factual premise (a claimed bug, a claimed missing feature, a spec citation) doesn't survive verification against the primary source, the agent halts that item and reports with citations instead of inventing. "Verified already correct, no change made" is a valid, expected outcome. The clause covers the charter's designed fix shape and its measured file:line anchors, not only the finding: sibling merges stale both between charter-writing and execution, so a builder that re-verifies the design against its own worktree and deviates with citations is complying — the deviation is adjudicated at merge, never treated as disobedience. Charter-supplied names — slugs, titles, feature labels — fall under the same clause: an agent that discovers the real feature differs from the charter's name must correct the name and flag it, not ship correct content under a stale identifier.
A charter names the repo's committed engineering conventions (absolute path in the lane's worktree) and instructs the agent to read them before coding and to treat them as binding, naming the repo's designated reference implementation where one exists; a reviewer or skeptic charter names the same conventions as the codified-house-rule source for rubric (b) below. A charter that writes or reshapes tests also names the repo's committed testing doctrine as binding and does not prescribe a test mechanic itself — a charter once offered a patch-based interleave that doctrine forbids, and only the builder's own diligence avoided shipping it.
A charter that includes a mutation proof (deliberately breaking code to show a test goes red) also specifies the restore protocol: restore byte-identically, verify via git status/git diff, and purge compiled-artifact caches (stale bytecode and the like) under the touched packages — a same-size restore within the same mtime second leaves stale build artifacts that quietly poison every later run in that tree.
When two reference sources disagree, the charter names the conflict for adjudication — it never silently picks one. A charter's factual claims are no more trustworthy than a builder's until verified.
A charter or goal text that enumerates a derivable structure — a dependency graph, a consumer list, a coverage set — instructs the agent to re-derive the complete set from primary sources and treat the enumeration as examples to check against, never as the whole set. Stop-on-contradiction cannot catch an incomplete list: nothing contradicts it, so its gaps ship. A five-edge dependency graph hand-written into a goal text was encoded verbatim as a registry's whole truth, and the guard built on it approved variants that then died mid-transaction on a generic error.
A charter for any agent that publishes text — an issue, a PR body, review comments — forbids personal data from customer datasets (names, emails) in the published artifact unless strictly necessary, and the orchestrator scans the artifact for it before shipping. A dump-sourced operator email once shipped inside a published investigation issue and had to be redacted after the fact.
Builders never run long gates. A charter ends at commit (or commit + push) and STOP, with only scoped foreground checks before it (the touched module's tests, lint) — "run the full suite in the foreground" does not survive contact with builders: they background it and end their turn terminally stalled, because a workflow agent's turn ending is final. The orchestrator runs full gates itself as its own background shell (its re-invocation on completion costs nothing) and owns push/PR/merge when the charter stops at commit.
Instruct every agent to deliver its full final report as its last message — never to end the turn "waiting on CI" or any background process: a lane that signed off with "clean, waiting on CI" had to be resumed just to extract the report it never sent. An agent never polls a process it backgrounded either — one foreground wait on a scoped check, or hand the wait up. Machine-level waits (a container image pull, an environment stall) belong to the orchestrator, who takes them over machine-side while the agent proceeds; repeated "check the state" turns have eaten a whole stage's context window.
Write each new charter/script fresh with the Write tool. Deriving one by programmatically splicing a previous one introduces silent syntax errors.
Address every SendMessage by looking up the recipient's task id in the ledger head at send time, never from memory. A charter delivered to the wrong lane's agent reads as an order to abandon its own work and take over another lane's, and only the recipient's own do-not-touch clauses stand between that misdelivery and a corrupted worktree.
A multi-stage script carries its charter discipline in the shared preamble from the first draft — commit at every milestone, read targeted ranges instead of whole generated files — never patched into one stage after a failure exposes the gap. A stage whose preamble lacked it was stopped at its context threshold with zero commits and eleven uncommitted files; the sibling stage that carried it landed five milestone commits over a comparable span.
Every build charter carries a classify-the-disk-state-first preamble from its first draft: before building anything, read git status and git log in the lane's worktree, classify every commit and dirty file as done, partial, or untouched, verify-don't-redo whatever is already correct, and run seasoned-skills provision only when the lane's worktree does not exist. A workflow auto-retries a dead agent straight back into the same worktree, so half-finished work on disk is a normal starting state rather than an exception. An API-level event killed a four-lane wave whose charters said only "provision if the worktree does not exist yet"; the retries landed in worktrees holding three to five commits and dirty trees apiece and classified them only on their own initiative, and the preamble had to be patched in at relaunch.
Relay a finding at exactly the scope it was measured. "These two named tests survive the mutation" is not "the suite survives the mutation"; widening it on the way into a charter sends the agent to disprove a claim nobody made, and its correction can bury the narrower gap that was real. Quote the finding's own boundary, and mark anything you extrapolated as yours to verify.
Cross-check a charter's exit assertions against its own items before launching: an exit gate demanding a file show no diff contradicts another item that edits the same file, leaving the agent to choose between violating the gate and dropping the item. Scope byte-identity checks to the exact lines or symbols they protect, never to whole files other items touch.
A parameterized script must parse args defensively (string-or-object) and hard-throw on any missing required field — a silently-undefined interpolation produces a plausible-looking empty result that reads as a clean pass.
A slice that ships a route, loader, or form must drive that surface live at least once — a minimal browser interaction or a real-Request smoke — before handoff. A unit-only exit bar passes code whose query crashes at runtime or whose form cannot submit (a select with no name attribute).
A live proof binds only the commits that preceded it. Sequence the browser walkthrough as the charter's last step, after the final commit, and redo it after any later change to the proven surface — a proof that predates a schema or handler commit is evidence of nothing, and a redone proof regularly catches what the suite missed (a coercion regression, a state-update race). The same binding governs specs across stage boundaries: a later stage can invalidate a spec an earlier stage wrote, so the verification stage re-runs every one of the lane's specs after the last build commit — a refusal spec asserting one stage's toast went red the moment the next stage reshaped that refusal, and nothing had re-run across the boundary.
A skeptic or verifier charter carries TWO acceptance rubrics, not one: a finding stands if either (a) its concrete-input failure scenario occurs at runtime, or (b) it identifies a violation of a codified house rule or doctrine in the work under review. A runtime-only rubric refutes correct doctrine findings — an ad hoc query fragment inlined in a view where the repo's committed conventions prescribe a model-owned query method — exactly when the fix is cheapest. Doctrine findings against unmerged schema or shape default to fix-now, because schema shapes are effectively permanent once merged.
Verify, never trust
Re-run the gates yourself before advancing any stage on a subagent's self-report.
A completeness claim — "every route covered", "every call site migrated", "every consumer updated" — is only checkable against a denominator derived live from the system of record (the URL resolver, the schema, a repo-wide census), never against the plan that produced the work: the plan omits exactly what the work omitted. Establish the denominator before declaring any "every X" objective met, and prefer a gate that recomputes it and fails on drift over a registered list or document describing coverage — registered state duplicates the system and goes stale silently.
Reconcile numbers exactly: baseline + computed delta = measured, and identical across two runs. A mismatch is a hard stop, not noise. A collect-only reconciliation carries one extra term: registry-parametrized suites expand on their own whenever the registry they parametrize over grows, so account for that expansion before reading a collect-count jump as drift.
Reconcile a builder's charter item by item against its diff, not only by counts: every charter item ends in exactly one visible state — implemented in the diff, verified-already-correct, or an explicitly reported skip. Builders silently drop items, and numeric reconciliation cannot catch an item whose omission changes no counts (a test reshape, a mechanical conversion) — one such drop shipped unnoticed and only surfaced in a later personal read of the merged diff.
Reconcile the adjudicated rulings against the union of the lane charters before the wave launches: every ruled fix appears in exactly one lane's items. Orchestrators drop whole rulings the same way builders drop charter items — three ruled fixes once reached no lane at all, caught only by a ruling-by-ruling reconciliation during the final write-up.
A charter's expected gate numbers are measured on the current base tip at charter-writing time, never carried forward from per-lane history — every sibling merge stales them. When lanes have merged since the last measurement, re-measure the union before chartering anything that asserts a count.
A task counts as launched only when its task/run id from the tool result is in the ledger. A written script or a narrated intent is not a running task. Copy every id out of the returned tool result — never from memory or prediction; when a launch and its ledger entry go out in one parallel call, write TBD and fill it in after the result returns. An id written in the same message that launched the task is a prediction, and twice it was wrong.
Never block on a running subagent or workflow — a synchronous wait for its output freezes the conversation until the agent finishes, so the user can neither interject nor redirect, and the user has had to interrupt one to say so. Launch in the background, keep the chat free for whatever else is pending, and act when the completion notification arrives. When the harness's task registration is uncertain (after a compaction), arm a background watcher on the task's own artifacts rather than polling in the foreground.
Judgment stays at the top
Never trade the mainline for an edge case: a fix whose cost lands on the bulk of use cases to close a rare corner is the wrong shape, however clean the mechanism looks. Accept the residual and record it, or scope the mitigation to the edge itself. Shipping the full route manifest up front (routeDiscovery: 'initial') to close one offline corner — a submit to a never-visited write route — was denied for exactly this: it reverses lazy route discovery, which exists because full manifests scale badly, and charges every session to fix a case almost nobody hits.
Every demand gets an architecture round before any delegation: zoom out and map the mechanism behind the ask, where else that mechanism lives, and the repercussions of candidate fixes — then design at the level the root cause lives. A defect surfacing in one route but rooted in a shared primitive gets the primitive fixed, never a route-local workaround; a batch of demands gets grouped by mechanism, not by surface, before lanes are cut. Zoom in only with full domain over the systemic impact. A route-local patch of a polling defect owned by a framework hook would have left the same bug live in fifteen sibling routes; fixing the hook also surfaced a second latent defect in it.
A stakeholder's demand names what they see. Before designing or interviewing against it, translate every term through the navigation the requester actually uses (the app's committed nav definition), never through internal section, module, or schema names — an analysis framed on internals reads as wrong to the user even when technically coherent, and one design interview had to be restarted after the user caught the frame (the demand's word named a navigation menu entry, not the internal seed section it also matched).
Answer any question about repo machinery only after reading the primary source completely: every file in .github/workflows/ before stating what CI does — one check name can live in two workflows, a per-PR job and a scheduled twin — and real run history (gh run list) before stating what a job costs in time, since a job's timeout is a ceiling and never an estimate. When the user's question hints that something is missing, it is a diligence probe, not a request for a guess: assemble the complete factual picture from the sources, then answer once. Seven consecutive user messages on one thread went into forcing a workflow-file read that should have preceded the first answer, every probe meeting a fresh inference instead — and in delegated work nobody is there to supply that correction.
Design and adjudication are orchestrator-tier work. When the evidence under a design changes (stale reference, corrected spec), redo the design at the orchestrator tier — never hand the stale design down with a "re-verify your citations" instruction.
Synthesizing a multi-agent review's findings into an adjudicated register is itself adjudication, not mechanical distillation. Read every report yourself and build the register personally — a synthesis delegated to a subagent launders the miners' claims into rulings nobody made, and the fix program built on it inherits judgments the orchestrator never exercised.
Browser and process hygiene
Every agent that drives a browser ends with its browser session closed, and the orchestrator verifies it — a successful close, or an agent's report that it closed its session, is not evidence that the processes died; only a process listing is. After each browser agent completes, and again between waves, sweep to zero with the shipped command:
seasoned-skills sweep --browsers # list survivors with their ages; exits 1 if any are alive
seasoned-skills sweep --browsers --kill # kill each survivor by its exact pid, then re-list to prove it
A gate that turns flaky while browser work is in flight is a leak suspect before it is a product bug.
Every process a lane needs beyond a single turn — a development server, a worker — runs as its own harness background task, never forked with & inside another task's shell; the orchestrator's own long gate runs follow the same rule. Every lane process is swept at session end, and the same sweep is runnable by hand at any time.
Judge leakage by process count and age, never by reported RSS — paged-out memory hides an order of magnitude (7.6GB visible while roughly 80GB was actually held).
Leakage comes from sessions accumulating across sequential waves, not from parallel width. Keep lanes parallel; the invariant is verified teardown, not a concurrency cap.
Kills are the sweep's job precisely because it kills by exact pid after listing what is about to die. Never reach for a pattern kill (pkill -f and relatives) as cleanup or as verification — a pattern that reads as lane-scoped can match unrelated long-running processes on the host, and listing the pids is the inspection step a pattern kill skips. Every kill goes through the shipped sweep, which enforces the rule.
Ledger discipline
Structure the ledger as a STANDING DIRECTIVES head (settled policy, kept current) plus a chronological log. Reground after compaction from the head AND the tail — a tail-only reground lets settled directives fade. Reground with bounded reads — the head block, then targeted slices — never by reading the whole file: a mature ledger runs hundreds of kilobytes, and one full read consumed enough context to force an immediate re-compaction.
The ledger keeps exactly one live head. When a new head goes in, move the superseded one to an archive file beside the ledger instead of stacking it below — stacked dead heads push the file past what a single read returns and tax every reground with prose no longer true. One goal's ledger reached ~390KB carrying eleven stacked superseded heads, and by the end every update to it needed byte-offset reads and count-asserted scripted edits.
Record launches with their task/run ids, lanes with their base commits, and verdicts with their evidence.
When a long effort concludes, externalize the durable record (decisions, divergences, audit results) to a permanent artifact — a GitHub issue or PR body — before the scratchpad is cleaned up.
Recovery after an interruption
Step 0 is always to positively enumerate what is alive (task list, workflow roster) — a missing state file or empty output file usually means still-running, not dead. The harness task list can come back empty after a compaction or a host sleep while the underlying shells still run: ps for the actual processes and check whether their log files are still growing before declaring anything dead. Declaring a live task dead and relaunching into its worktree corrupts both. Then, for tasks with positive evidence of death:
Audit the worktree first: git status/git log. Clean tree at a known commit → relaunch the charter unedited. Dirty tree → launch a continuation agent on the same worktree whose first step is diffing working tree vs last commit to classify done/partial/untouched, then finishing — never a blind restart. A continuation charter lists the remainder and says explicitly that when the listed remainder is done, STOP: a continuation that finishes early otherwise runs on into the next stage's ground, and one built two of a later stage's commits plus a half-written file nobody had chartered.
Audit the remote before writing any continuation charter: git ls-remote for the lane's branch and gh pr list --head <branch> for its PR. A dead agent may have finished — one continuation was chartered on a "nothing pushed" premise while the original agent's PR was already open with green CI, and the charter sent the new agent to redo completed work.
A QA agent killed mid-mutation-proof can leave deliberately broken code on disk — check for a live mutation before anything else runs there.
An agent that is still addressable resumes by message from its last checkpoint, keeping its context, instead of restarting cold — but NEVER message an agent a live workflow still owns. The message forks the transcript into two live instances sharing one worktree: each sees the other's edits as a foreign actor's, and one fork's honorable stop can strand half the work. Deliver mid-flight course corrections to a workflow-owned agent only through the workflow (edit the script and resume the run), or wait for the run to end and relaunch with an amended charter.
Probe returned capacity by attempting real work. Never idle-wait.
Shipping and merging a lane
A PR opens as a draft the moment the fast gates pass — so CI overlaps with local verification — and flips to ready for review only after the full pre-merge pipeline completes: builder claims verified, full gates green, the adversarial review run against the draft (it reads the PR's description and discussion alongside the diff, which a bare diff review never sees), and an orchestrator ruling on every confirmed finding. Small diffs are not exempt from the pipeline; they simply overlap it — momentum after green gates is exactly when the review step gets dropped, and on a three-line security fix the almost-skipped review was the one that surfaced a fourth same-class vulnerability.
Write every PR title and description for an external reader: someone with zero knowledge of the execution that produced the change must understand what it is and why it matters. No orchestration vocabulary (goals, lanes, charters, sanctioned allowances, finder/verifier counts, workspace skills or tooling-repo names), and no superseded project state — describe what the change IS in the product's own terms, and rewrite the body as the work evolves so it always reads as current truth, not history.
When the user shares another organization's work (a PR, a repo, a pattern) as the model for a change here, that source never appears in anything visible in this repo — PR bodies, commit messages, code, comments, or issues. Describe the change entirely on its own terms; the reference lives only in the conversation.
An umbrella PR's body is a deliverable, not a tracker. While work is landing it may be organized around progress, but the effort is not done — and a goal is not met — until the body is rewritten to read as finished: no tracking framing ("Landed", "updated as areas land", in-flight lists), and no links to the internal PRs that built the branch — sub-PR references are noise to an external reader, who needs the result described, not the delivery.
When a PR whose title promises no behavior change (test, docs, chore types) actually changes production behavior, the title must say so and the body must lead with a complete list of every behavior change — readers won't expect behavior in that diff. Enumerate the list from the real base-to-tip diff of non-test paths, never from memory of the work.
A defect fix described only by its new behavior reads as housekeeping. Each behavior-change entry states the problem first — what broke, under what conditions, with what consequence — and then the fix, so its real weight is legible: "event ingestion is idempotent" hides that a routine queue redelivery permanently broke a paying customer's reporting. Write the consequence in the product's terms, not the schema's.
A before/after contrast in a PR body ("no longer", "used to", "restored", "remains") is only tellable against the PR's base: if the base itself carries the old behavior, the contrast describes the change; if the branch introduced the surface, the contrast narrates the branch's own development history, which the reader never saw — state current truth only. Check each such phrase against the base, not against memory of how the work went. A refute pass does not catch this class on its own — fact-checkers verify claims as stated and confirm a contrast that is factually true but tells internal history — so make base-tellability its own explicit rubric item in any refute pass over a body.
Where lessons go
Project-empirical lessons about this skill land in workflow-content/orchestration.md through a pull request on the project — never by editing this file, which is regenerated on every upgrade. A lesson that turns out to be true of every project travels as an issue on the workflow package instead.
Plus depuis ce dépôt
Independent lanes launch simultaneously, never in staggered waves. Host contention (CPU, database) slows every lane's gates but never justifies holding a launch back — an idle lane costs more than a slow gate. Contention is managed by the orchestrator's own scheduling instead — it owns every long gate run, so it schedules heavy suites by judgment when lanes pile up, and a contention-shaped failure (connection exhaustion, timeouts under load) is re-run alone before anyone treats it as a defect.
A review or QA returning zero findings is only a clean pass if its agents all completed. Errored finders, an implausibly fast run, or a wrong agent count mean the run is broken — relaunch it.
Findings about uncommitted working-tree state from a parallel review fan-out are suspect: when finders share one worktree, one finder's in-flight mutation-proof — code deliberately broken to validate a test, then restored — is visible to its siblings and reports as a phantom defect. Verify any working-tree observation against the commit under review (git show HEAD:file), and either require finders to mutation-prove only against committed state and restore immediately, or discount working-tree-only observations at the verify stage.
Independently probe a shipping agent's claimed git state (git merge-base <lane> origin/main vs origin/main's tip) before merging. Verify mechanical batch edits landed by grepping the expected before/after state, not by exit code.
A mutation test must sabotage the transformation under test, never the input it reads. When a gate re-derives both sides of its comparison from the same source — a parser diffed against its own re-parse — mutating the source leaves both sides agreeing and the gate green, proving nothing; break the transformation (drop a word inside the parser) and watch every output fail. A wrong-sided mutation test once read as a proven gate when it had exercised nothing.
Before treating a probe's mismatch as a finding, validate the probe itself against a known-good case — a fidelity spot-check once "failed" solely because the probe's own text flattening left timing lines interleaved with the prose it matched against. And prefer the dumbest direct check over a clever detector: an n-gram loop detector reported zero loops on a file whose raw line counts (sort | uniq -c) showed one line repeated 1,691 times.
The orchestrator's PR review reads every line of the diff against the binding doctrine of the surfaces it touches — a shaped project's document contracts, the reference implementations it names, and the repo's codified skills — regardless of what the PR body flags. The author's flag is never the safeguard: a page-wide raw-fetch store with bespoke retry and revalidation machinery shipped through review while the shaping document prescribed inheriting the framework's own submission machinery, because everyone read only what the body mentioned — the departure sat unflagged in plain sight in the diff. A goal is never met while its implementation contradicts its shaping document, and conformance is checked at every PR, not discovered at goal close.
When a merged lane retires or renames a shared symbol (a manager method moved behind a facade, a renamed helper), every sibling lane still to merge can carry code written against the old idiom — the siblings branched before the rename landed, and their files never conflict, so the merge itself flags nothing. At each subsequent sibling merge, grep the whole tree for the retired idiom before running suites and retarget the hits; one seam retirement broke four consecutive lane merges in a single wave, each discovered late by a failing suite or lint instead of cheaply by the grep.
The orchestrator's own edits are subagent work for verification purposes: any orchestrator-authored change to an audited artifact — a coverage claim, a documented behavior, a spec or manifest sentence — gets the same adversarial re-verification as a builder's diff before it ships. Three separate single-sentence orchestrator edits in one goal each introduced a fresh overclaim that only a verifier caught. Write such sentences from the rendered screen or the measured number, never from the data's intent, then have a verifier try to refute them.
Personally source-read any confirmed "inconsistent with spec/reference" finding before directing the fix — especially when the fix would reverse a prior ruling. A finding's observation can be accurate while its verdict of "wrong" is not. Doctrine-flavored findings get the same read, not a shortcut: a builder's confident "this is exactly the hazard the doctrine names" was false on the file it cited, on the kind of date the rows actually carried, and on the ordering it predicted, and a whole fix lane was spent proving the premise false. Charter every fix lane to verify its premise before changing anything.
An investigation chartered around a stated finding tends to confirm and amplify it: the charter's frame decides what the agent looks for, so a mechanism living in an adjacent flow stays invisible even when the agent's own appendix names it. Before designing on, escalating, or alarming the user with an investigation's headline conclusion, commission one independent second perspective under a different frame (compare against a reference implementation, or charter a refuter) and adjudicate any disagreement yourself against primary sources.
An agent's claim that a symbol has a single consumer ("only seed.ts imports this") is a factual claim — grep the whole repo, tests/ included, before directing a refactor that removes or narrows a shared contract on its strength. It bites hardest when the claim justifies reversing another agent's deliberate earlier design, and green CI is no safety net when the broken consumer only runs against state CI never exercises, like a converging seed over a persistent local database.
Audit PR-body citations ("per spec X", "per source Y at file:line") against the actual cited location, and check any "deferred as polish / out of scope" claim against the actual contract. Builders produce plausible but fabricated attributions.
Never conclude something is absent from a truncated search: a grep … | head that fills its quota hides the line that would refute the absence. Re-run unbounded, or open the file at the cited range, before acting on any missing-symbol or missing-assertion claim — a truncated pipe nearly directed a fix for a "missing" test assertion that existed exactly where cited.
Shipped prose that makes factual claims about system behavior — docs pages, schema and endpoint descriptions, recipe text — is verified like code: before it ships, a dedicated adversarial pass tries to refute each claim against the source. Plausible-but-false wording reads well precisely because it flatters the mental model that wrote it — false revenue-semantics claims survived a builder's self-review and the orchestrator's personal read twice in one PR, and both times only a refute-charter caught them. The unwinnable class is census, totality, and lineage claims — counts of routes or tests, "every caller", "all N migrations", "unchanged from main" — over any surface too large to recount mechanically: seven such claims fell to refute passes in a single review effort, the orchestrator's own among them. Write the mechanism plus verified examples instead, and reserve exhaustive claims for small sets the prose itself defines and a refute pass can recount.
When a fix pass restructures a seam beyond what its charter asked — replacing an inherited implementation, moving a boundary, collapsing two code paths into one — its acceptance gate is re-running the measurement that exposed the original defect, never the agent's own argument that the new shape is equivalent. The restructure invalidates the earlier measurement, so the evidence you already hold no longer covers what ships. Mandating that re-run in the fix charter caught a second regression the fix pass had introduced while reasoning its way to a correct-looking shape.
Any change to a shared core module made by a fix/QA agent — a framework directory, a shared library package every surface imports — gets the orchestrator's personal diff read before shipping — its blast radius exceeds any lane's review scope.
When a builder reports it verified a UI flow by simulating requests (fetching the form's FormData, forging a session) instead of real interaction, treat that as an unverified claim and dispatch a real-interaction prober before relying on it. A "harness quirk" explanation for why real clicks failed is itself a claim to verify.
A goal text, design document, or any other foundational artifact drafted for the user is built on a verified inventory of the current codebase, never on memory of it — commission or perform the primary-source study first. A goal draft written without that diligence missed a whole class of existing sync machinery and had to be redone after the user caught it.
At design time, inventory every seam the build cannot exercise without something only the user can supply — a vendor API key, a paid account, a physical device — and hand that list to the user while the design is still open, never at verification time when the arrangement no longer fits. When a dependency cannot be arranged in time, shipping that seam reviewed-but-never-exercised is the user's explicit decision to make, recorded as a known risk. A machine-translation vendor seam was already built before anyone said out loud that no test ever calls the real API, by which point the account could not be set up in time, and the user had to ask the question the design should have answered: "Is there any other part of this project that will not be able to be exercised during building unless I provide you with something?"
When keeping an approach green demands case-by-case fixes that each breed new edge cases — or a single lane grinds for hours on one defect — that is a design smell in the approach itself, not a hard fix: pause the lane and re-open the shape question with the user instead of pushing through. A pixel-equality gate consumed a four-hour masking war, and the user, not the orchestrator, had to call the smell; the reshaped design (gate only the deterministic subset, report the rest for human eyes) held immediately.
When a lane empirically disproves a factual premise in a shared research digest, correct the digest itself immediately and visibly, before the next lane reads it. Sibling lanes read the artifact, not the report that refuted it, so every later lane inherits the same wrong premise from a document that still asserts it.
Grounding priority when state or policy is uncertain: primary sources (git, live files, the actual spec) beat live skills, and live skills beat ledger notes or compacted memory. On a policy detail, the live skill file always wins over ledger shorthand.
When parallel lanes independently invent shapes for the same shared surface, adjudicate one canon and give later-shipping lanes an explicit adopt-the-canon duty at rebase. Distribute the canon as a verbatim, byte-identical file package every lane applies unchanged — identical bytes auto-merge everywhere, so the shared file never conflicts again.
An invariant that spans several lanes' data — a shared ledger fixture, a balance every lane's writes must conserve — is orchestrator-tier design work. Derive it yourself from primary sources, commit it as a fixture, and hand lanes only consumption rules; never let each lane implement its local view of the global rule. Two successive lane agents each handled their own slice of a shared stock balance plausibly and broke the global invariant both times — a lane cannot see the whole.
When lanes re-express existing behavior (authorization gates, validation rules), builders guess wrong in both directions — stricter and looser both shipped from the same wave. Commission one audited map of every capability to its exact source-of-truth behavior (with file:line citations) before any fix pass, and make every fix charter cite the map, never intuition.
A lane reports out-of-scope findings with repro evidence; it never fixes them inline. Every finding gets its explicit disposition the moment it reaches the orchestrator, from whatever surface — a lane's report, an audit register, or a finding read in a PR body at review time — nothing parked undecided, nothing dropped. The disposition here is conservative: bank the finding with its evidence and adjudicate it with the user. An out-of-scope fix always executes in its own dedicated pass, never inline in the lane that found it — that is what keeps lanes convergent and review rounds terminating. A GitHub issue is legitimate only for a decision the user must make, work blocked on other work, or an unknown-cause investigation someone will actually run. Never file an issue as idea storage — no "maybe someday" refactors, no future-abstraction notes (Shape Up's no-backlogs rule: really important ideas come back on their own; a standing pile only makes everyone feel behind). During a scoped goal, a findings register is fine as a cycle-scoped working list — it dissolves into fixes and decision issues when the effort ends, never outliving it. Before deferring an item until some future event, check that the event does not itself depend on the item: work parked until a readiness decision it is a precondition for never restarts, because the decision waits on the work and the work waits on the decision.
A designer's "too invasive / out of scope" blast-radius claim is a factual claim, not a judgment call — grep it before accepting the compromise it justifies.
Whether to fix a known defect or a regression is not the user's decision. Once verification has established that something is broken, fixing it is the only defensible answer, so asking spends the user's attention on a question with one outcome and stalls the work until they happen to be present. Bring the user a genuine choice between shippable alternatives, or a trade-off only they can price — never a request for permission to remove a defect.
Before asking the user to rule on a surface or planning a change to it, check the repo for in-flight work: gh pr list plus a scan of remote branches. An open PR may have already settled the question — a dependency queued for a user decision had already been removed by a PR in flight, and only the user's correction caught the stale premise.
A question's premises about the live system — which domain serves what, what sits behind a proxy, what a live response carries — are probed live before the question reaches the user: a browser, curl, DNS. Production configuration overrides every default in the repo, so a code-derived claim about production is a guess, and "not determinable from the repo" is a prompt to probe, not a finding — one question shipped with both domains' roles wrong from a code-default inference, and the user had to say "open them in a browser and see for yourself".
Any selection of an external tool, model, library, or service starts with live web research, never training knowledge alone — that landscape moves faster than any cutoff, and a recommendation grounded on months-stale knowledge reads as authoritative while comparing options that have since been superseded. The user had to order the search mid-design once ("your cut-off is ~6 months old"); in delegated work nobody is there to.
Rank a recommendation the way a design is ranked: an option that dissolves the trade-off — removes the tension instead of choosing a side — outranks every option that merely prices it, and the status quo earns the recommendation only when no presented option dissolves. Recommending keep-current-and-document while the option table itself held a design that removed the coarseness handed the user a judgment the reasoning had already settled, and they overruled it as the wrong abstraction.
When audit lenses split on the same finding, the finding is usually several sub-claims bundled into one sentence, some true and some false — which is exactly why one lens confirms it and another refutes it. Read every lens's reasoning and rule on each sub-claim separately. Resolving the split by picking a winning lens ships whichever half that lens got wrong.
Merge a PR by squash (gh pr merge --squash). A branch that backs an open PR — a lane under review, a shared feature branch — syncs by merging its base in, never by rebase or force-push. Rebase is for branches nothing else references yet.
A lane's pushed commits are never rewritten — a fix pass lands as a follow-up commit, not --amend + force-push, even before any PR exists. Rewriting another agent's pushed commit trips the harness's security review, and the resulting permission blocks can stall the pipeline at PR creation until the user intervenes; a tidy single-commit history buys nothing the squash-merge doesn't.
Before rebasing, predict the conflict surface: intersect the lane's touched files with what main gained since the lane's base. Empty intersection → expect a clean rebase; non-empty → you know exactly which files need care.
On a non-empty intersection, a conflict-free rebase is not evidence of correctness. Git auto-merges a lane's hunks around a sibling's rewrite of the same function, leaving code that references symbols the lane deleted — and the lane's analysis, written against pre-merge main, can assert facts the sibling has since made false. Re-derive the lane's claims about the intersecting files against post-merge main, and resolve the rebase semantically — take the sibling's merged shape as authoritative and re-apply the lane's intent on top — never by accepting whatever auto-merge produced.
A shared shrink-only registry (a pending list every lane deletes entries from) is resolved by construction, never by conflict-hunk surgery: take the merge base's current copy, delete exactly this lane's originally-removed entries (captured from its diff before the rebase), then verify the removed set stays inside the lane's slice and the count arithmetic closes. Deleting conflict blocks textually silently drops neighboring keep-lines the moment a hunk mixes entries being removed with entries that must stay.
Run rebase and post-rebase gates as separate, individually-checked steps — a chained command can swallow a mid-rebase conflict's exit code.
After rebasing an approved commit, run a patch-identity check: diff the rebased patch against the approved patch (sorted added/removed line sets). A rebase is itself a mutation risk — a failed automated edit can commit conflict markers, and only an identity check catches it.
When two open PRs both carry database migrations, the second to merge must re-sequence its migration after the first lands so it orders after every migration already on main — a migration that is new but ordered before an already-applied one can break the migrator — then re-rebase, re-run the migration gates, and regenerate any derived types from a freshly migrated database: git can auto-merge a semantically wrong generated type file. When two lanes touch the same seam, merge the larger diff first and let the smaller one absorb the rebase.
A lane that changes user-visible copy, CTAs, or navigation greps tests/ for the retired words before pushing — a spec asserting the old copy can live outside the lane's own files, the fast gates never execute the end-to-end specs, and the full end-to-end suite runs only on the pull request's CI, never locally — so the grep is what catches it before the CI round trip.
A lane that changes product semantics — what a status does, what an action permits — additionally greps the whole repo for prose stating the old behavior: UI helper text, tooltips, empty states, emails, not just docs and the spec files. Stale in-app copy contradicting shipped semantics survives every gate — no spec asserts it, the docs live elsewhere, and it reads fine to a reviewer who doesn't know the new rules — so only the grep catches it before a user does.
When merging a lane that changed product behavior, grep the base for tests that pin the OLD behavior — deliberate defect pins included — and run the touched app's full unit package on the merged tree before pushing the merge. A lane branched before a sibling's pin landed is green on its own tip and red on the union, and scoped e2e re-runs never catch a unit-level pin: one merge shipped red because the base carried an honest pin of exactly the bypass the lane had just fixed.
The dual holds for e2e: e2e specs pin wire payloads the unit suite never re-asserts, because unit tests share the code's own fakes and schemas. When a wave changes the shape of a dispatched payload or another externally visible contract, grep the repo's e2e specs for pins of the changed shape and run the affected specs on the merged tip before pushing — a merged-tip gate set of lint plus unit suites stays green through all of it. Stale pins stack: a second wrong assertion hides behind the first, so rerun each affected spec until it passes rather than fixing only the first failure.
A clean automatic merge is not a correct merge. Git unions two same-named classes without a murmur (redefinition, F811) and keeps both sides' claims on the same registry, manifest, or census entry. When merged trees both grew one of those, sweep the merged files for duplicated meaning and re-measure the union's counts from the merged tree — never adopt either side's number.
Never chain the merge with branch or worktree teardown. A merge can be rejected transiently (after the head moves, the platform recomputes mergeability for ~30s and gh pr merge fails with "not mergeable"), and a chained cleanup then runs anyway — deleting the remote branch auto-closes the open PR. Merge, confirm the merged state with a fresh read, then tear down, each step checked. If a branch deletion does close a PR, the commits survive at pull/<n>/head: restore the branch (or repush the surviving local one), gh pr reopen, and merge properly.
Before every teardown (seasoned-skills teardown), positively enumerate the live-agent roster and confirm none is pointed at that worktree. Read-only scouts and auditors carry worktree paths in their charters and leave no trace in the lane's own PR state, so a merged-and-shipped lane is not evidence its worktree is free — one had to be restored mid-flight as a plain checkout because a live agent's charter cited the path.
When the repository requires a PR's head branch to be up to date with its base and gh pr merge is rejected with "the head branch is not up to date", run gh pr update-branch <n>, wait for the new check run to register (~45s), watch it, then take a fresh gh pr checks read and merge on that.
Verify a large PR's scope with git diff --stat against the merge base — gh pr view --json files silently caps at 100 files, and a scope check that only sees the first 100 blesses whatever hides past the cap.
A PR showing zero checks is not "CI hasn't started" — after a couple of minutes it means CI will never start. The pull_request workflow runs on the merge commit, so a PR whose branch conflicts with base (gh pr view <n> --json mergeStateStatus → DIRTY) has no merge commit to build and fires no checks at all. Binary files make this likely (two lanes regenerating the same screenshot conflict invisibly — no textual merge exists). The fix is resolving the conflict; for a generated binary, take either side, then regenerate it authoritatively against the resolved tree rather than trusting the manual resolution.
When the repo's CI declares a path filter, a PR whose files all fall inside the filter's skip trees runs only the classification job: the heavy jobs report "skipping" by design, and skipped required checks satisfy branch protection — mergeStateStatus goes CLEAN and the merge proceeds. Don't wait for, re-trigger, or investigate jobs whose status is "skipping" on such a PR; do run the fast gates locally when the change could affect them, since nothing on the PR will.
Take full commit SHAs only from git rev-parse or the API — never expand a short SHA by guessing. A fabricated SHA in a check-run poll loop waits forever on a ref that does not exist, and its silence reads as CI still pending.
update-branch mutates the remote PR head with a merge commit, and calling it immediately after your own push can 422 on a stale-head race (retry after settling). Fetch and reconcile the remote head before pushing any further commits, or the push is rejected as non-fast-forward.
A lane's local branch and its PR head branch can differ — a finalizer that pushed via refspec leaves the worktree on worktree/<lane> while the PR head carries another name. Push follow-up commits with git push origin HEAD:<pr-head-branch>, taking the head name from gh pr view --json headRefName, never from the local branch name.
A PR's CI runs on the merge of its head with its base. On a long-lived feature branch this cuts both ways: lane PRs into the feature branch never see the trunk, so drift on main — a renamed heading, retired copy, a moved route — surfaces only in the feature→main PR's CI, which tests the merge tree. Whenever main advances meaningfully, and always before declaring the feature branch done, sync it — the main-sync skill owns the protocol.
A merge into a long-lived feature branch does not reliably produce a CI run on the branch's new tip — GitHub does not always emit the pull_request: synchronize event that triggers one. When a criterion requires CI green on a tip, confirm by SHA that a run exists on that exact commit rather than inferring it from the merge; when none does, either dispatch the workflow on that ref (if the repo's CI declares workflow_dispatch) or prove the tip's tree is identical to a tree a passing run already covered.
A CI watch (gh pr checks --watch, gh run watch --exit-status) is a completion signal only — its exit code is never the verdict: gh run watch --exit-status exited 0 on genuinely failed runs three separate times in one effort. The only verdict is a fresh direct gh pr checks read (plus a mergeable/mergeStateStatus read) taken after the watch returns.
When the host kills long-lived foreground watches and background poll loops within minutes, a --watch is not a reliable completion signal at all: use a persistent Monitor task that polls the run id and emits one event on any terminal state. The fresh-read rule is unchanged — the monitor only tells you when to go look.
Arm a watch only after the new run has registered under the pushed SHA: poll gh run list --branch <branch> --json databaseId,headSha for the run id and watch that id. A fixed sleep is not enough under queued runners — a 35s wait once bound a watch to a placeholder check that vanished, reading as a false CI failure. A single branch update can also spawn two check sets moments apart, binding the watch to the first while the second becomes the one that counts — when the fresh pre-merge read shows pending checks after a green watch, re-arm the watch on the current set and keep the merge gated on the fresh read.
On a multi-wave effort against an open PR, every intermediate push gets a watch armed this way, and its verdict is read before the next push builds on the tip. Local gates are not the branch's CI — a different matrix, e2e included — and a tip nobody reads stays red invisibly: one branch ran red for two hours and four more pushes until the user flagged it.
A "failed" CI job with no step concluding failure/cancelled (check gh api .../jobs) is infrastructure death — rerun it. A job with a real failing step is investigated before anything merges. A job hung far past its normal duration is the same class: cancel it and fetch the cancelled attempt's logs (gh api .../actions/runs/<id>/attempts/<n>/logs) to see the exact step it stalled on — a suite-hang diagnosis dissolved into a stuck dependency-install step once the log showed the suite never booted. Recover with gh run rerun <id> --failed, which keeps the run's completed green jobs. When the stall is on an environment step (a dependency download, a browser install), check whether unrelated runs repo-wide hang at the identical step: that signature means external infrastructure, and a rerun armed before the outside service recovers just hangs again — confirm recovery (any fresh run passing that step) before re-arming, and never bypass the gate to merge around it.
When GitHub itself is unstable, a gh command that reports failure may still have succeeded server-side: after a failed gh pr create, read gh pr list --head <branch> before retrying, and verify exactly one PR exists once it goes through. Declaring a CI failure a flake takes positive evidence — the failing specs are disjoint across runs, each one passes elsewhere on the same tree, and the diff cannot reach the failing path — and even then the reruns that evidence buys are capped at two before someone investigates the failure for real.
Prepared-ahead scripts (placeholders patched at launch) keep the pipeline saturated, but audit a prepared script's content immediately before launching it — staleness there has shipped wrong charters.
Fixes to a reviewed feature branch land inside that branch — internal PRs merged into it, exactly as on a goal's feature branch — or are explicitly dropped. Never propose fast-follow PRs to land after the branch merges: everything ships in the branch under review or not at all.