Generated from cat-harness/skills/sdlc/sdlc-core/coordinate.md — do not edit here.

✎ Edit this page’s source

/coordinate — multi-agent / multi-PR coordination

When several Claude branches are converging on the same long-term goal (e.g. “reach the precision target”, “close all violators of a rule”, “infrastructure overhaul”), each agent has only its own context. Without coordination they will:

  • duplicate work (two agents both implementing the same helper),
  • silently diverge (one renames a symbol, another keeps the old name, the merge conflicts),
  • miss cherry-picks (one agent already wrote the template the others need),
  • accept inconsistent findings without flagging them to the author,
  • accept review-tool feedback without checking it against the actual artifact / sibling change proposal’s — pull request’s (PR’s) — framing (e.g. accepting an off-by-one “fix” that contradicts a definition another PR is also using),
  • miss new sibling PRs that opened mid-session (new branches landing on main with overlapping scope).

/coordinate is the protocol that prevents this. None of the agents has all the answers; they look to the author for clarification on inconsistencies, and they cherry-pick from each other.

Workflow rule reminder (from AGENTS.md §Branch + PR workflow)

This skill assumes you’ve already created a branch + opened a PR for the work tranche being coordinated. Per AGENTS.md (STRICT, supersedes default “no auto-PR” guidance for this repo): always create a branch and open a PR at the start of every work tranche — ASAP, and never ask the user “want me to open the PR?” Branch + PR creation is pre-authorized; the only git action needing explicit permission is the merge. Commit early, commit often. Small structured commits cherry-pick cleanly; big mixed commits do not. Exception: integration-watcher batch audit-job sweeps may use a single bulk commit.

When to invoke

  • Start of a session where the user mentioned other branches/PRs by name (e.g. “coordinate with claude/foo and claude/bar”).
  • Whenever you start a new substantive task in a multi-PR effort — before making code changes, post intent on the relevant PRs.
  • When you finish a substantive task — post progress + concrete cherry-pickable artefacts (file paths, function names, templates, fixtures).
  • Periodic triage between substantive commits (§7) — even with no external trigger, sibling PRs may have landed commits or comments that change your scope. Run a quick triage every ~3–5 commits or when you finish a task and pick up the next one.
  • When main lands new commits during your session — if any touch the same files, blocks, or scripts you are editing, treat as a sibling PR for §3 classification purposes.
  • When a code-review comment lands on your own PR (gemini-code- assist, copilot-pull-request-reviewer, codex, or human reviewers) — see §5 Responding to review comments.
  • When you encounter a finding that contradicts another PR’s framing — write the disagreement up explicitly, post it to both PRs, and tag the author for resolution.
  • A COLLISION — coordinate. A merge conflict caused by a sibling’s landed work is not merely a thing to resolve; it is the signal that two sessions are editing one subject. Resolve it AND coordinate. Owner, 2026-09-21: “collision=coordinate”.
  • A POTENTIAL collision, seen in the beans — coordinate. Before you start a topic, and at each triage, scan for an in-progress bean whose scope overlaps yours. That is the cheapest collision to find, because it is the one found BEFORE either of you has written anything. Owner, same day: “potential collision by looking at beans = coordinate”. How to read a sibling’s state out of the store, and the boundary of that inference, is bean-coordination §”Where a sibling session is visible from” — not restated here.
  • When you START any new unit of work — before the first edit. A new story, epic, feature or task bean, an issue, CRDM Phase 6, a workplan tranche, or a handover pickup runs the collision review in §”Starting new work” below, scaled to its blast radius, and records it in the workplan bean. Owner, 2026-10-02 (#1885).

Inputs

  • The current PR number (your branch).
  • A list of sibling branch names or PR numbers (the user gives this, or list the open PRs labelled in-flight with the list change proposals forge-operation Tool).
  • The shared goal in 1–2 sentences.

Where each section lives

This skill was 732 lines and the Protocol was 478 of them — an agent reads the whole thing before acting, and at that length it skims. The Protocol now sits beside this file. Nothing was deleted and no step was renumbered, because other skills cite coordinate §0a and coordinate.md §8a and those citations have to keep resolving.

sectionwhere
workflow rule, when to invoke, inputshere — read before you start
Protocol §1–§11 — the eleven coordination stepscoordinate/protocol.md
output, anti-patterns, §11 STATUS.md, §12 same-goal coordination, related skillshere

Coordinating: read this file for whether and when, then protocol.md for how.

Output

After invocation, you should have:

  • Read every sibling PR’s body and changed-files list.
  • Posted at most one coordination comment per sibling PR (intent + asks), unless you’ve made progress that warrants a separate progress comment.
  • Triaged every open review-tool thread on your own PR (§5) and posted a single consolidated status comment.
  • Run a §7 periodic triage every 3–5 of your own commits, capturing new sibling-PR comments + commits + CI status in one table.
  • Run §8a (git fetch origin main) at each triage cycle and react to any main-landed changes that touch your scope.
  • Run §8b (newly-opened PRs / branches) at each triage cycle and prompt the author when a new sibling overlaps your scope keywords.
  • Identified the next concrete, non-overlapping task on your own workplan and started on it.
  • (Optional) Created or updated docs/coordination/<goal-slug>.md with the current state.
  • Escalated any inconsistencies via §6 with @<author> tagging.

Anti-patterns

  • ❌ Post a coordination comment that just summarises your own PR. Sibling agents already read your PR body.
  • ❌ Pick the same task as a sibling without posting first. Even if their PR has been quiet, the human author may have given them a verbal lead.
  • ❌ “Resolve” an inconsistency by rewriting your finding. Escalate to the author.
  • ❌ Accept a review-tool fix without verifying it against the artifact and sibling-PR conventions. Bot suggestions can flip conventions silently.
  • ❌ Reply per-thread on a 6-comment review pass. Use one consolidated status comment + per-thread accept / reject-with-reason flags.
  • ❌ Skip §7 triage between commits because “I would have heard if something landed” — you wouldn’t. Sibling agents work in parallel and rarely interrupt each other. Run the triage anyway.
  • ❌ Silently merge / cherry-pick from main without §8a classification. Main commits can also be inconsistent findings.
  • ❌ Add a newly-opened PR to your scope without prompting the author (§8b). The author may want it independent.
  • ❌ Long prose. Coordination comments are tables, file pointers, and one-line asks.

§11 STATUS.md + master ledger pattern

A repeated flip-flop episode (a claim asserted and retracted across several sessions) motivates a more structured coordination layer that overlays this skill:

  • Root STATUS.md — single dashboard listing every goal + pointer to its master ledger + active PRs.
  • Master ledger per goal — docs/coordination/<goal>.md holds the durable narrative: current canonical status, open tasks, flip-flop history, sessions log.
  • Per-goal queue — the beans queue (beans/); each open task is one entry.

When /coordinate runs, it now ALSO:

  1. Reads STATUS.md to find which goal(s) the current PR touches.
  2. Reads the goal’s master ledger to identify the current canonical status — overrides recent commit claims if the ledger records a retraction.
  3. Reads the queue to find sibling tasks in flight.
  4. References the ledger session log when posting intent comments on sibling PRs, so the comment is grounded in the durable record, not just session memory.

See session-intent for the session-start / session-end ledger + queue update protocol — /coordinate is the sibling-PR arm; /session-intent is the durable-state arm. They are run together at session start.

§12 Multi-agent same-goal coordination

Multiple agents MAY work the same goal in parallel. Per author directive: agents coordinate with the user on goals, not with each other on task-level locks.

Model:

  • Goal = product (author’s directive). User-level concern.
  • Queue = per-goal item list (the beans queue).
  • Tasks are NOT exclusively claimed. Two agents may attack the same task with different methods — both threads have value.
  • Coordination is with the USER on goal-level decisions, not agent-to-agent on task-level locks.

When you detect a sibling agent on your task

Signals:

  • The queue entry has co_assignees populated, OR
  • A sibling PR (listed with the list change proposals forge-operation Tool) has commits touching your task’s scope files within the last 24h, OR
  • The ledger session log shows another agent declared intent on the same task ID.

Workflow:

  1. Do not silently abandon. Your independent attack is valuable.
  2. Post intent on the sibling PR (this skill §3) so the sibling sees you’re also working it.
  3. Ask the user with AskUserQuestion whether to keep both threads or have one stand down. Include rich context per AGENTS.md §User accessibility — quote what each agent is doing, what method, what’s been found, cost of running both.
  4. If user says one stands down, the standing-down agent appends partial results to the ledger and updates queue status: "open" (releasing the task). The continuing agent may pick up the partial results.

Watching for sibling-PR contradictions

Per §8 of this skill: at each triage cycle, look for sibling-PR commits or comments that contradict your branch’s framing. Per §6: escalate inconsistent findings to the user. Do not silently adopt the sibling’s framing without an §6 conversation.

What actually reaches a sibling — measured, 2026-09-21

Do not assume you can message a sibling session. Measured from a cloud session with eleven siblings live on one repository:

channelreaches a cloud sibling?
list_sessionssees them — id, title, branch, task summary
ListAgentsno — “no other Claude session is running on this machine”
SendMessageno — the send is refused, target not reachable
a committed beanyes — every session reads the store at session start
a PR or issue commentyes — to whoever looks, and it is durable

So list_sessions tells you WHO is working and on WHAT, and then the message has to travel through something committed. That asymmetry is worth knowing before you spend a turn on it: this list exists because a session read the sibling list, drafted a careful message, and discovered on the send that there was no channel.

The practical order:

  1. list_sessions (or the beans) to find WHO overlaps and how.
  2. Write the coordination INTO the artefacts they will read — the bean, the PR body, the issue. A bean is the strongest, because bean-coordination §”The store on main is the one every sibling reads” makes it the one surface every session opens.
  3. Only then consider a direct message, and only for a sibling ListAgents actually lists.

Since 2026-10: a spawned helper is reachable, and the owner’s authority is not relayed

The table above predates the remote-session tools. A session that has create_session and send_message (the claude-code-remote server) can seed a helper session and message a cloud session it lists: both worked from the drain coordinator on 2026-10-10 and 2026-10-20 (epic ml9h). Reaching it does not give it the owner’s authority (bean yex5).

What lane B of that drain hit: its permission layer refused a push, a send_message back, and finally a read-only beans show, because its task arrived from another session rather than from the owner. It also refused to treat the coordinator’s relayed “4 h merge window” as the owner’s ruling. That refusal was correct. conduct/security/zero-trust-handover §”Who the principal is” puts a message relayed from another session on the NOT-the-principal list.

So, when you seed a helper session:

  1. Quote the owner’s own words verbatim in the seed prompt, with the session they were typed in, and say which part the helper serves. The helper then knows what was asked, though it still cannot treat the words as instructions the owner gave it.
  2. Relay no rulings. A merge window, a re-pin consent, or an answer to an owner decision binds the session it was given in. Tell the helper to open PRs and leave them green, not to merge.
  3. Tell the owner, in your own turn, that each helper may ask for confirmation in its own session, and name the sessions. That is the only way the owner’s authority reaches it. A helper that stops to ask is working as designed. The ask is not a failure to route around.
  4. Give the helper a lane it can finish without the owner: a bean store or a set of repositories, the lanes of its siblings, and the report-back channel (send_message to the coordinator).

Eleven sessions is the normal case, not the exception

The same measurement: eleven sessions on litlfred/folio-assistant, each on its own branch, each merging main on a loop. One branch took four base merges in three hours, three of them conflicted. Main moved 109, 38, 20, 24 and 28 commits between them.

A session that treats a conflict as an accident will treat all four as accidents. The rate IS the environment, and the thing to do about it is coordinate earlier, not merge harder.

The worked example: a voice landing in a directory being deleted

A branch migrated every voice from <instance>/voices/ to <instance>/skills/voices/. Mid-flight, main landed a NEW voice in cat-harness/voices/ — the directory the branch removes. Git’s rename detection then placed the new file inside another voice’s folder.

Nothing was wrong with either piece of work. What was missing was that neither session knew about the other, and the beans said so the whole time: the migration’s bean was in-progress and names the directory. A bean scan by either session would have caught it before a line was written, which is exactly why the trigger above is worth having.

Crossing into a sibling’s subject — permitted, and what it costs

Owner, 2026-09-22, on stream 3 of the #956 consolidation rewriting the yg29 milestone it had been told not to touch:

“crossing stream is ok, but /coordinate and be aware of potential collisions. try avoid duplicating work.”

Two rulings, and they are not the same one twice.

1. The stream that owns a milestone’s WORK may repair the milestone. check-stale-paths.ts reserved that repair to “the bean’s OWNER” on the ground that “a milestone is a statement of what its owner believes the goal needs next, and rewriting somebody else’s belief is not a checker’s to do.” That ground still holds for a checker — a gate that guesses replaces a stale belief with an invented one. It does not hold for a session that has re-measured the goal’s whole surface. Stream 3 repaired yg29 and found two defects a path detector structurally cannot see: hqku carried as a live “blocked on the owner” for two days after it completed, and “the IRIS replica has no docs/” against a directory holding three rendered pages.

So the line is checker vs. session, not owner vs. non-owner. A session repairing somebody’s milestone re-measures every line it rewrites, in a fresh container, by running the thing — and says which clause it could not verify.

2. Crossing is permitted; colliding silently is not. Cross freely, but the crossing is what triggers this skill rather than what excuses skipping it.

The collision surface is FILES, and it is predictable before you touch one

A bean scan finds sessions working the same subject. It does not find two sessions about to edit the same file from different subjects, which is how the #956 consolidation nearly lost a baseline:

filewhy two sessions want it
scripts/stale-paths-baseline.jsontwo lines long. Every milestone repair removes its own entry. Two repairs in flight = a conflict whose wrong resolution silently empties a file whose stated property is that it shrinks rather than fossilises — and an empty baseline fails every finding, “which is the safe direction” only if somebody notices.
a shared bean like k59devery stream appends its own outcome. “An append cannot collide” is false when two sessions append, because both land at EOF. That precedent is recorded in k59d itself and is wrong as stated.
generated dirs (auto-docs/, skill-instructions/, kg-qa sidecars)nobody edits them, everybody regenerates them. Take main’s copy and re-run the generator — never hand-merge. For test/results/**, bun run cat qa:resolve-conflicts: those are derived QA results whose record is on the qa-reports branch.
test/attestations/**judgements, not generated — no generator can reproduce one. Read both sides and keep both unless they are the same judgement; see prepare-merge §”Conflicts in test/results/ and test/attestations/”.

Name the files you will touch, not just the beans, when you post intent. A sibling can dodge a file; it cannot dodge a subject it cannot see.

Duplicated work is measured in what was already pushed, not in what is open

The same consolidation measured p5wm’s critical path twice — once in the session writing the stream claims, once in the stream that received them, reaching the identical answer (five live steps, not eight). Neither was wrong and both were competent; the second was free to skip. Before re-deriving a measurement, check whether a sibling’s pushed commit already carries it: an open PR’s diff is a fact, and reading it costs one call against a session’s worth of re-measurement.

Starting new work — a collision review, recorded before the first edit (STRICT)

Formerly §”Before a platform refactor”. The rule began there and now covers the start of any unit of SDLC work; citations of the old title land here.

Owner, 2026-10-02, on issue #1885, verbatim:

“(in genreal update agent-agent coorindation/hadover skills - if you are working on a refactor of the platform, review active agents/beans for impact and coordiante)”

Owner, 2026-10-02, later the same day, verbatim:

“Before any platform refactor, a session must now review the open PR–> genrealizes to parts of the SDLC / begining on a new story/epic or so…”

This section is the rule’s only home. bean-coordination, session-intent, continual-progress, opening-brief, issue-working and crdm-requirements-workflow point here. They do not restate it.

When it runs — the start of any new unit of work

Run the review once, before the first edit, whenever you start:

  • a new story, epic, feature or task bean;
  • work on an issue, before you announce the branch;
  • CRDM Phase 6, implementation;
  • a new tranche of a workplan;
  • a pickup of someone else’s work from a handover.

A pickup runs its own review. The previous session’s review is dated, and PRs may have opened since it was written.

How deep — scale the review to the blast radius

The review is proportional. The question is how much other work your change can collide with, not how big your diff is.

  • A platform refactor gets the full review: all five steps, with messages to the owners. A platform refactor is a change to something that many pages, generators or open PRs depend on:
    • shared layout and includes: _includes/, docs-ui.css, docs-ui.js, the navbar;
    • a generator whose output is committed or published, such as gen-ig-pages.ts or gen-navbar-include.ts;
    • a schema, a BPMN process, a workflow or a gate that other work is checked against.

    A ten-line change to a shared include collides with every PR that regenerates it.

  • A small, local story still runs steps 1 and 2, quickly. When they find nothing, record “no overlap found” in the bean, together with what you checked: the PR search, the bean search, and the terms you used. That takes about two minutes and one bean note.
  • Only an overlap triggers steps 3 and 4. If steps 1 and 2 find a sibling on your files or your subject, name its owner and message it, whatever the size of your change.

“No overlap found” with no record of what was checked is not a review. The next session cannot tell it from a review that was skipped.

The bean trigger above catches a sibling working on the same subject. §”The collision surface is FILES” catches two sessions editing the same file from different subjects. A refactor causes both kinds at once, which is why it gets the full review and does not rely on either trigger.

The five steps, in order, before any file is edited

  1. List the open PRs and the files they change. Use the list change proposals forge-operation Tool, then list changed files for each PR. Intersect the result with the files your work will touch. A PR that changes only generated files you will also regenerate is not a collision; say so and move on.
  2. Scan the in-progress beans for overlapping scope. Use beans list --status in-progress --search <term>, and search the subject as well as the ids: the file names, the generator, the page type. A bean id finds nothing when the overlapping work has no bean of its own; see bean-coordination §”The trigger is STARTING WORK”.
  3. Name the owning sessions. Use list_sessions, the Claude-Session: trailers on each PR’s commits, and bun run cat sessions --since <window>. bean-coordination §”Where a sibling session is visible from” says how far that inference goes.
  4. Message each owner with your intent and your asks. State what you will change, phase by phase, and the files each phase touches. Then ask two things: which order do we land in, and who owns each overlapping file. Send it through a channel that actually reaches them; §”What actually reaches a sibling” says which ones do. A PR comment also leaves a durable copy.
  5. Record the review in the workplan bean before editing. Write down each overlapping session, its PRs and beans, the files you share, and the phases affected; or “no overlap found” and what you checked. A review that exists only in the chat is gone when the container goes, and the next session has to run it again.

Phases that overlap a sibling wait. They wait until the sibling has agreed an order, or until its overlapping PR has landed. Phases that touch none of the sibling’s files can go ahead, and the review says which ones those are.

Worked example — #1885, bean gp2f

This is the full-depth case: a platform refactor, with overlaps found and owners messaged.

The refactor moves the per-page nav, the harness bar, icons, scripts and the IG chrome CSS into shared cached assets. It touches the layout of every page on the site. Before any edit, the review found active sibling work on every layout file the plan needed:

siblingits PRsshared filesgp2f phases affected
navbar session (bean ob3m)#1804, #1805, #1808, #1819docs-ui.css, docs-ui.js, _includes/generated/navbar-footer.html, harness_details.html, head_custom.html, harness-tiles.mdB, C, D, E
fhir-ast session (bean wnhh)#1816the FHIR IG layer’s scripts/gen-ig-pages.tsA
the trust IG IG session#1766the gen-ig-pages areaA

If the review had been skipped, five PRs would have been rebased into a refactor of the files they were editing.

What happened instead:

  • The review went into gp2f before any edit.
  • The three owning sessions were messaged with the plan and asked for an order.
  • The only work that started was work that touches none of their files: this section, and a read-only baseline measurement of page sizes.
  • bean-coordination — the committed store siblings read, how to claim, and how far a sibling’s state can be inferred from it. The DETECTION half of this skill’s bean trigger lives there.
  • delivery-summary — what to post after a feature lands (one PR scope).
  • watch — passive monitoring of upstream branches.
  • diff — per-block change report (one PR scope).
  • session-intent — session-start / session-end ledger + queue update protocol (the durable-state arm of coordination).
  • pending-show — read-only display of current session’s pending work (todos, intent, queue assignments).
  • prepare-merge-auto — autonomous merge pipeline (uses this skill’s sibling-coord pattern).
  • specification-management — governance of specification requirements, linking CRDM and spec-kit to the bootstrap Requirement definition.

/coordinate complements them: it is the active cross-PR protocol — including handling of code-review comments on your own PR — not a passive watcher and not a single-PR summary.

Flag-bearer reflections

Lessons from acting as flag-bearer across many sibling PRs on a shared goal. Apply when you hold the flag.

  1. Build the ledger hub FIRST, then post. Create docs/coordination/<goal>.md with: the direction (one boxed statement of the target), the common infra everyone rows toward (cheat-sheet step table, watcher queues, dashboards, a falsification anchor), and a per-PR “which way to row” roster with report-back slots. Post intent only after the hub exists, so every comment can link one canonical place. This is what makes “make sure all use common infra” actionable rather than a slogan.

  2. Tailor per-PR; then LISTEN. A flag-bearer that only broadcasts is half-doing the job. Pull each sibling’s current state (a background Explore agent reading PR bodies + last comments is ideal), and fold their findings back as sharpenings to your own plan. Record sharpenings in the ledger and amend the workplan — do not silently keep the stale plan.

  3. Anchor the cluster to one falsifiable target. Give every sibling a shared regression target. It turns “which way to row” into a checkable claim and prevents divergent re-derivations.

  4. Push-race coordination with background agents. When a background sub-agent and you both push to the same branch, wrap every push in a fetch → rebase → retry loop: for i in 1 2 3 4; do git push && break || { git fetch origin <br> -q; git rebase origin/<br>; sleep $((2**i)); }; done. The agent’s commits may already be in your local history (shared working dir) — check git log before assuming a divergence.

  5. Billing-CI is noise — do not let it derail coordination. If CI fails setup-phase (≤5 s, simultaneous, no logs) on every push while local validation stays green, recognise the billing signature (litlfred/qou AGENTS.md “CI billing failures”), note [skip-ci: billing], and keep working; never re-diagnose it as a code problem or pause the cluster for it.

SDLC multi-agent landscape & coverage

For systematic evaluation of multi-agent SDLC workflows (comparing Waterfall, Agile, and dynamic process models against this repository’s 69 BPMN processes) and the architectural gap checklist, see:


coordinate — the Protocol, §1–§11

The eleven numbered coordination steps. Read this when you are doing the coordination; the parent says when to invoke it and what it is for.

Section numbers are the parent’s and do not change here — other skills cite coordinate §0a and coordinate.md §8a, and those resolve to this file.

Protocol

1. Read sibling PRs first

For each sibling change proposal (pull request, PR), read its number, title, body, state, head branch and last update, and the paths of every file it changes — the read change proposal and list changed files forge-operation Tools. Read the full file list, not a truncated head — partial scope maps cause silent overlaps later. File paths are cheap.

Build a scope map: which PR owns which workplan phase, which files, which blocks, which scripts.

2. Identify three relationships per sibling

For every sibling PR, classify yourself on three axes:

AxisValues
Overlapnone / additive (different files, same goal) / conflicting (same file or same block)
Dependencyindependent / I depend on theirs / they depend on mine
Cherry-pick opportunitynone / I want X / they probably want Y

A sibling that is (none, independent, none) doesn’t need a coordination comment. Anything else does.

2-bis. Domain-contract sync

If your PR touches an algorithm, pipeline step, or data contract that the project documents as a maintenance contract (a doc whose uses[], computation.script, computation.witness, and prose sections must stay in sync with the actual code), you MUST update the matching contract block in the same PR.

Such a contract is not a static document: reviewers diff it against the code change. When posting your intent comment on a sibling PR whose scope overlaps such a contract, name the contract block(s) you will touch alongside the script paths.

3. Post intent before working

Comment on each sibling PR with non-trivial relationship (the github Tool, comment on change proposal). Format:

## Coordination from #<your PR>

**Picking up:** <one sentence — which workplan phase / task>

**Scope confirmation:**
- I will touch: `path/to/file:line-range`, `path/to/other`, …
- I will not touch: `<the sibling's territory>`

**Cherry-pick from you:**
- <what you need from them; e.g. "the template you used for `<block>`">

**Cherry-pick for you:**
- <what you'll produce that they may want; e.g. "the reader for
  `<artifact>` is the same shape they need for `<other path>`">

**Asks (small):** <questions they can answer in one line>

**Escalation to author:** <if any; see §6>

Keep it short. One ask per ask. No prose.

4. Post progress at task boundaries

When you commit something cherry-pickable, post a follow-up:

## Progress from #<your PR> · `<short-task-name>`

- Landed in `<commit-sha>`: <one sentence>
- Cherry-pick file pointers: `path/file.py:fn`, `path/file.lean:Decl`
- Updated [`<your-audit-or-plan-doc>.md`](…) §<section>: <what
  changed> — and/or appended a row to
  [`docs/coordination/<goal-slug>.md`](…)
- Next: <next task on your queue>

Cherry-pick file pointers are the load-bearing part — the sibling agent should be able to copy/cite without reading your whole diff.

5. Responding to review comments on your own PR

Code-review tools (gemini-code-assist[bot], copilot-pull-request-reviewer[bot], codex[bot]) and human reviewers leave comments on your PR. Do not silently accept or silently dismiss. The same rules that govern cross-PR inconsistencies (§6) govern review feedback.

5a. Triage every comment

For each comment, assign one of four verdicts:

VerdictWhenAction
acceptSuggestion is correct and smallApply the fix in a single commit citing the comment URL; mark the thread resolved if the tooling permits.
accept-with-modificationIntent is right but the suggested patch has its own issue (e.g. introduces a different off-by-one, or breaks a sibling-PR’s convention)Apply a corrected version; reply on the thread with one paragraph explaining what you did and why the original suggestion needed adjusting (cite file:line where the divergence matters).
reject-with-reasonFinding is incorrect (mathematically, empirically, or by project convention)Reply with the reasoning: cite the specific line, definition, or sibling-PR convention that contradicts the suggestion. Never silent-dismiss.
escalateFinding is correct but would cross a sibling-PR’s territory, or two reviewers disagree, or the comment exposes an inconsistency in a sibling PR’s auditSee §6. Reply with an ⚠️ flag and tag the author.

5b. Verify against the actual artifact / code before replying

Review-tool suggestions can be subtly wrong. Common failure modes:

  • Off-by-one fixes that flip-flop a convention: a reviewer proposes a boundary change without noticing context that makes the original correct. Read the artifact, not just the suggested patch.
  • Cross-PR convention conflicts: e.g. PR A names a field active_set, PR B names it active_constraints; a reviewer suggesting one without checking the other introduces a merge conflict downstream. Check sibling PRs before applying.
  • Hallucinated context: review tools sometimes reference PR numbers or comment IDs that don’t exist. If the reviewer references a comment you didn’t write, treat it as a hallucination and ignore the cross-reference (but still evaluate the substantive content of the comment on its merits).

If you can’t verify in < 2 minutes, escalate (§6) rather than guess.

5c. Post one consolidated status comment

After triaging all threads from one review pass, post a single PR-level summary (the comment on change proposal forge-operation Tool):

Thanks @<reviewer> — addressed all <N> threads in [`<sha>`](<commit-url>).

| # | Issue | Verdict | Resolution |
|---|---|---|---|
| 1 | Off-by-one in index | accept | Fixed |
| 2 | … | accept-with-modification | Fixed differently — see note below |
| 3 | … | reject-with-reason | See reply on thread |
| 4 | … | escalate | ⚠️ tagged @<author> |

**Re #2 (note):** <short paragraph explaining the modification>

This avoids per-thread reply storms while still giving a paper trail for every verdict. Threads marked accept / accept-with-modification should be resolved (the resolve review thread forge-operation Tool) once the reviewer acknowledges or after a one-day cooling period.

5d. When the reviewer pushes back

Code-review bots often respond to your reply. Keep the dialogue short — re-state the reasoning or the sibling-PR convention once, ask for a yes/no on whether the reviewer agrees. After the second exchange, escalate (§6). Loops with bots burn cycles without converging.

6. Inconsistent findings → escalate, do not paper over

If a sibling PR’s finding contradicts yours — or if a code-review comment claims a fact that contradicts a sibling PR’s audit (§5a escalate) — do NOT silently change your framing. Post on every affected PR:

## ⚠️ Inconsistent finding — author input requested

- This PR's claim: <yours, file_path:line cited>
- Sibling #<N>'s claim: <theirs, file_path:line cited>  (or:
  Reviewer's claim in <comment-url>)
- Likely cause: <best guess, ≤ 2 sentences>
- Resolution requested: <which framing to adopt going forward>

Tagging @<author>.  Will hold downstream work blocked on this.

The author owns the resolution. Do not “split the difference” or guess. Inconsistent findings — whether between sibling PRs, or between a reviewer and a sibling PR — are an audit flag.

Escalation rate-limit. An author who wakes up to fifteen @<author> pings is a useless arbiter. Batch-escalate when possible: one comment listing every disagreement found in a review pass, with a short table.

7. Periodic sibling-PR triage

Sibling PRs land commits and comments while you work. Without periodic triage you will:

  • duplicate a fix the sibling already landed,
  • miss a question they posted directing back at you,
  • accept a review-comment that contradicts a finding the sibling just published.

Run a triage every 3–5 of your own commits, or whenever you finish one substantive task and pick up the next. Format:

## Sibling-PR triage report (<your PR>, <timestamp>)

| PR | New comments | New commits | CI | Asks for me | Action |
|----|:---:|:---:|:---:|---|---|
| #564 | 6 | 8 | ✅ | (none) | none |
| #565 | 5 | 3 | 🟡 | P6 scope check (3 Q) | answer in next round |
| #568 | 1 | 1 | ⚪ | (cherry-pick acked) | post drop-duplicate notice |

For each “Asks for me” with verdict answer or escalate, queue a coordination response in the next coordination round. For verdict none or acked, no further action.

Use a background subagent for triage when possible — Agent(subagent_type=Explore, run_in_background=true, prompt=...) reads sibling PRs without blocking your foreground work. Triage prompt template:

Background triage of sibling PRs . For each:

  1. New comments since .
  2. New commits + sha + 1-line message.
  3. CI status.
  4. Specifically flag asks/replies directed at + any inconsistent findings vs <my key audit/artifact claims>. Report under 400 words; per-PR table.

8. Watching main and newly-created branches

Sibling PRs are not the only thing that moves. main lands merges, and new branches/PRs sometimes open mid-session by the author or other agents — these need to enter the scope map immediately.

8a. Watch main for new commits

Run git fetch origin main at each triage cycle. If new commits landed since your last fetch, run:

git log --oneline <last-fetched-main-sha>..origin/main \
  -- <files-or-paths-you-are-touching>

For each main-landed commit that touches a file or block you are editing, classify it like a sibling PR using §2: overlap / dependency / cherry-pick. Then choose:

  • Merge origin/main into your branch if the changes are additive and you don’t have local edits to the same files.
  • Cherry-pick the relevant commit if main’s branch tip has too much unrelated noise.
  • Escalate to the author (§6) if main’s change contradicts a finding you just published.

Do not silently rebase or force-push to incorporate main — those are author-authorised actions, see the repo’s Git Operations policy.

8a-bis. Watch for new skills landing on main

In the same git fetch origin main pass, additionally run:

git diff --name-only --diff-filter=A \
  <last-fetched-main-sha>..origin/main \
  -- '.claude/skills/local/*.md' '.claude/skills/*/*.md'

For each new skill file:

  1. Read its frontmatter (name, roles, description, inherits).
  2. Decide relevance: does the skill’s description overlap your branch’s scope?
    • Mention a file kind / domain / pattern you’re editing (touched in git diff origin/main..HEAD --name-only), OR
    • Provide a new integration-watcher child (inherits: local/integration-watcher) and your branch is itself an integration-watcher PR, OR
    • Provide a new QA / sweep / audit skill (one-voice-, proof-, compute-*, etc.) and your branch touches the corresponding content blocks.
  3. Surface to the user via AskUserQuestion with the standard 3-chip pattern from watch.md §3.Q3a:
    • Adopt now — invoke the skill on the relevant subset
    • Defer to follow-up branch — record decision, don’t change this branch
    • Not relevant — record so the watcher doesn’t re-prompt
  4. Record the decision in the coordination ledger under a new ## New skills detected on main subsection so future sessions don’t re-prompt.

This mirrors watch.md §3.Q3a and lets every coordinator session pick up new infrastructure (audit watchers, scoring heuristics, formalisation helpers) as it lands, without the user having to manually announce skill additions to every in-flight PR.

8c. Pre-push stale-state check (MANDATORY)

Trigger: before every git push (whether new commits or force- push). The watcher can lapse during long focused work — Monitor timeouts, hooks-busy windows, or background-agent waits all silently leave origin/main unfetched. Before any push, force a fresh fetch and compute the upstream delta:

git fetch origin '+refs/heads/main:refs/remotes/origin/main' 2>/dev/null
DELTA=$(git rev-list --count HEAD..origin/main)
SIBS=$(git log --oneline ${MERGE_BASE:-$(git merge-base HEAD origin/main)}..origin/main 2>/dev/null | wc -l)
echo "main is ${DELTA} commits ahead since branch base"

Fetch the ref you are about to read, with an explicit refspec. git fetch origin main writes FETCH_HEAD; it refreshes refs/remotes/origin/main only when the clone’s configured remote.origin.fetch covers that branch — and it exits 0 either way. A clone whose refspec has been narrowed to one branch (this happens: a qou clone was found pinned to a single sibling) answers every origin/main question from a ref that has not moved for days, and nothing in the output distinguishes that from being up to date. Use +refs/heads/<b>:refs/remotes/origin/<b>, which is correct whatever the clone is configured with.

Two corollaries, both of which have bitten:

  • Fetch the same ref you then read. watch.md §5b fetched main and measured origin/<BRANCH>, so its mandatory missed-commit recovery reported 0 missed by construction.
  • A per-branch refspec does not repair for-each-ref. Anything walking refs/remotes/origin/claude/* sees only what was fetched by name, so an empty result means “never fetched”, not “no siblings”. Check git config --get-all remote.origin.fetch | grep 'refs/heads/\*' before believing it.

Decision matrix:

DeltaAction
0..2push freely
3..10fetch and triage: list each new main commit; for any touching files in your branch’s diff, classify per §2 (rebase-now, defer, escalate) BEFORE pushing
> 10stop: announce to the user. Long-discharge sessions risk substantial divergence; offer prepare-merge rebase OR continue + flag

Additionally, list PRs with the list change proposals forge-operation Tool, filtered to state:open updated since <session_start> and check for sibling PRs that opened mid-session. Each new sibling enters scope per §3.

This check is the difference between a clean fast-forward push and a multi-conflict rebase storm. If you’re discharging many small commits in a row, invoke this between every ~5 commits OR after every 30 min of foreground work.

8d. Long-task drift recovery

If you discover ≥ 5 new main commits AFTER a Monitor timeout or hooks-busy window, do NOT just “re-arm and continue”:

  1. Compare: git diff --name-only HEAD..origin/main to find overlapping files.
  2. If overlap is empty: re-arm watch (silent OK).
  3. If overlap exists: invoke coordinate §2 classification on each overlap. Most common: another agent edited the same content block (.lean, .md, .ts trio). Resolve BEFORE committing more work that will conflict.
  4. Notify the user if ≥ 2 substantive overlaps: this is the signal that multiple agents are working in the same scope and the user should coordinate goals.

8b. Watch for newly-opened PRs / branches

Each triage cycle, list open PRs (number, title, head branch, creation time) and branches — the list change proposals and list branches forge-operation Tools; branches alone are also listable with git ls-remote --heads origin, which needs no forge.

If a new PR or branch appears since the last triage and its title / branch-name overlaps any of your scope keywords (your audit subjects, your changed files, your blocks), prompt the author:

**Q from #<your PR>:** I see #<N> (`<branch>`) opened at
<timestamp>; should I add it to my coordination scope (§3) and
post intent?  Or is it independent of the <goal> goal-thread?

Do not silently add the new PR to scope — the author may have opened it as an isolated probe. Wait for confirmation before posting coordination comments on the new PR.

9. Coordination ledger

Maintain a single shared ledger at:

docs/coordination/<goal-slug>.md

Each PR appends a row (no rewrites of others’ rows):

| Date | PR | Phase | Status | Cherry-pick |
|------|----|-------|--------|-------------|
| 2026-01-01 | #564 | phase A wire-up | landed `<sha>` | `<reader>` |
| 2026-01-01 | #565 | migration | in-progress | — |
| 2026-01-01 | #567 | sub-lemma | landed `<sha>` | `<block>` template |

The ledger lives on the branch where the coordinator is currently posting; final state can be merged to main when the goal completes.

10. Cherry-picking

Cherry-picking is fine — treat it as a low-friction default. When an in-flight sibling has infrastructure (a script, a witness, a template, a content block) that you’d otherwise duplicate, just cherry-pick it. The cross-PR ceremony in earlier revisions of this skill (mandatory “inform the sibling before”, “byte-for-byte identical or post the adaptation back”) was over-engineered for a working norm where small structured commits exist precisely so they can be picked up by anyone.

The remaining rules are minimal:

  1. Cite the source in your commit message. Either Cherry-pick of #<N>:<sha> on the trailer line or a Co-authored-by: line. Attribution is cheap and lets git log --grep surface who originated the change. Optional but recommended — missing attribution is not a blocker.

  2. One-voice still applies. Whatever you keep from the source should read as your own work; rewrite voice / framing if the sibling’s tone clashes (AGENTS.md voice rules don’t relax just because the source was a different agent).

  3. You may diverge. If you adapt the cherry-picked file — rename imports, change a helper, tighten a tolerance — that’s normal. No requirement to post the adaptation back on the source PR; the sibling will see your divergence in their own §7 triage if it matters to them.

  4. You may pre-empt main. Cherry-picks from open sibling PRs are explicitly allowed; you do not need to wait for the source to land on main. When the source eventually merges, you’ll either pick up the canonical version on your next rebase (drift handled by the standard §1·a auto-resolve) or keep a slight divergence (also fine).

  5. Pre-flagging is optional. If you’re picking something substantive (a whole module, a large script) and want to reduce the chance of duplicated work, posting a one-liner coord comment on the source PR before picking is courteous — but it is not required. For small picks (single helper, a witness JSON, a class declaration), just commit.

When the source PR lands on main, attribution stops being necessary — the file is just upstream code. A fresh PR sourced from a main-merged commit needs no Cherry-pick of line.

11. Asks and responses

Asks are a first-class artefact. Format every cross-PR ask as:

**Q from #<your PR>:** <question>

(answers as inline replies on the destination PR)

If a sibling has not answered an ask after 1 calendar day in an async setting, restate the ask in a fresh comment and tag the author. Do not block indefinitely.

Processes that run this skill

processstep(s) that name it
CRDM Phase 5 — beans and sign-offAnnounce the branch on the issue
Stalled-agent triage: collect handovers, consolidate themes, recommend, re-routeRe-route open PRs that lost their driver

folio-assistant — code under the Apache License 2.0, documentation under CC BY 3.0. Generated schema and API references are rebuilt from source on every push to main.

deployed b08c961 · 2026-10-23T23:11:09Z