refactor(democracy): hold the one peer protocol and fold coordinate's lineage into it
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
07b3fea4ea
commit
93b316999c
4 files changed
+68
-105
No files matched your search
@@ -1,82 +1,12 @@
|
||||
---
|
||||
name: coordinate
|
||||
description: >
|
||||
Coordinate a failing run or a fix with the other agents whose branches this
|
||||
branch inherits from or passes its commits on to: tell them what failed, ask
|
||||
whether someone already fixes it, claim the fix only when nobody does, and
|
||||
report the result to the same agents. Trigger on /coordinate, from the triage
|
||||
skill for every failure cluster, and whenever a fix touches code that other
|
||||
branches share through merges. Portable across projects.
|
||||
Coordinate a failing run or a fix with the agents on related branches
|
||||
(upstream and downstream through merges): claim it, ask whether it is
|
||||
already fixed, report the result. Trigger on /coordinate and whenever a fix
|
||||
touches code other branches share through merges. Portable across projects.
|
||||
---
|
||||
|
||||
Two agents fixing the same failure on two branches cost a duplicate investigation
|
||||
and then a merge conflict between two different fixes. One agent fixing a
|
||||
failure the others never hear about leaves them triaging it again. Coordination
|
||||
is cheap compared to either, so it happens before the fix and after it.
|
||||
|
||||
## 1. Map the lineage
|
||||
|
||||
Name the branches this one shares commits with, in both directions:
|
||||
|
||||
- **Upstream:** branches merged into this one (their commits reach you).
|
||||
- **Downstream:** branches that merge this one (your commits reach them).
|
||||
|
||||
Read it from the merge commits (`git log --merges --first-parent --format='%h %s' -30`),
|
||||
from the agent memory or merge notes the project keeps, and from the operator when
|
||||
neither says. Map every branch to the agent session working on it through the
|
||||
host's agent listing (in Claude Code: `ListAgents`). A branch without a live
|
||||
session needs no message; say so once.
|
||||
|
||||
## 2. Ask before fixing
|
||||
|
||||
For each failure (one message per cluster, not per job), send every upstream
|
||||
and downstream owner:
|
||||
|
||||
- the run (id or url) and the failing job,
|
||||
- the failing line, quoted literally,
|
||||
- the suspected root cause and the files it lives in, marked as a thesis while
|
||||
it is one,
|
||||
- the question: "Is this already known or fixed on your side? Reply with a SHA
|
||||
or branch, or 'none'."
|
||||
|
||||
Search the refs yourself in parallel (`git log --all` by message, by `-S`, by
|
||||
path): a fix already committed elsewhere answers the question without waiting.
|
||||
The first line of the message must stand on its own, because a busy recipient
|
||||
sees only that line.
|
||||
|
||||
## 3. Decide who fixes
|
||||
|
||||
- **Someone already fixes it** (a peer answers with a SHA, or a `democracy`
|
||||
claim for the cluster exists): build no competing fix. Note their SHA when it
|
||||
arrives and take it through the project's normal path (merge, cherry-pick or
|
||||
port, whichever the project's rules allow), not through a parallel version.
|
||||
- **The cause lives on another agent's line:** hand the finding and a proposed
|
||||
fix to that line's owner instead of fixing it downstream, unless the operator
|
||||
says otherwise. Record the agreed resolution where the next merge will find it.
|
||||
- **Nobody fixes it:** claim the cluster through the `democracy` skill; its
|
||||
atomic claim decides who is first, also against agents outside the lineage.
|
||||
Elected: tell the same agents that you fix it, on which branch, and that you
|
||||
will report the result, then fix. Not elected: hand your findings to the
|
||||
holder.
|
||||
|
||||
Do not idle while waiting for answers. Investigate read-only in the meantime; a
|
||||
peer that stays silent is not a "no", so announce your claim after a bounded
|
||||
wait and proceed.
|
||||
|
||||
## 4. Report the result
|
||||
|
||||
After the fix, tell the same agents: the commit, the branch, what changed, the
|
||||
evidence it works (gate pass, reproduction, live run), and how it reaches them
|
||||
(the merge it rides on). Report an abandoned or failed attempt too, and remove
|
||||
your `democracy` claim, so someone else can take it.
|
||||
|
||||
## Rules
|
||||
|
||||
- Never invent a peer's answer, and never treat silence as agreement or as a
|
||||
claim of its own.
|
||||
- Never ask a peer to run something your own session is denied: that routes
|
||||
around the operator's permission decision. Report it to the operator instead.
|
||||
- A peer's report is not evidence. Read the SHA, the log or the artifact it
|
||||
names before a number or a verdict depends on it.
|
||||
- One message per peer per event, short and concrete. Repeat nothing the peer
|
||||
already acknowledged.
|
||||
Run the `democracy` skill's **Lineage** and **Peer protocol** sections for the
|
||||
failure or fix at hand. They hold the whole procedure; this skill only keeps
|
||||
`/coordinate` working.
|
||||
@@ -59,8 +59,8 @@ directory with `--session <id>`.
|
||||
worktree>"`. Exit 0: elected, or already yours. Exit 3: a live agent holds
|
||||
it, and its claim is printed. Exit 4: the holder's session is dead (see
|
||||
Succession).
|
||||
4. **Elected**: announce office, holder and work to every peer on the system
|
||||
(in Claude Code: `ListAgents`, then `SendMessage`).
|
||||
4. **Elected**: continue with the Peer protocol; its message is the
|
||||
announcement.
|
||||
5. **Not elected**: send the holder your findings and stop on that work.
|
||||
|
||||
A Claude Code session cannot edit a file in a git worktree before it holds a
|
||||
@@ -106,15 +106,55 @@ records the result.
|
||||
- After a restart or reboot, run `council.py list --mine` and claim again
|
||||
every office you believe you hold: `/tmp` may have been wiped.
|
||||
|
||||
## Rules
|
||||
## Peer protocol
|
||||
|
||||
- Never invent a peer's answer. Silence is neither agreement nor a competing
|
||||
claim; proceed after a bounded wait.
|
||||
The one protocol for every exchange between agents; `coordinate`, `triage`,
|
||||
`tune`, `funnel` and `cleanup` use it.
|
||||
|
||||
1. **Look**: `council.py list` and the refs (`git log --all` by message, by
|
||||
`-S`, by path). A claim or a committed fix answers the question without a
|
||||
message.
|
||||
2. **Claim** the office (Election).
|
||||
3. **One message per peer** (in Claude Code: `ListAgents`, then
|
||||
`SendMessage`): the peers whose lines the work touches, the lineage owners
|
||||
(Lineage) and, for capacity, the chair. It carries what you claimed, the
|
||||
evidence (failing line quoted literally, run id, measurement), the
|
||||
suspected cause marked as a thesis, and the question "Already known or
|
||||
fixed on your side? Reply with a SHA or branch, or 'none'." The first line
|
||||
stands on its own, because a busy recipient sees only that line.
|
||||
4. **Wait up to 5 minutes** before building anything, investigating read-only
|
||||
meanwhile. A fix that arrives goes through the project's normal path
|
||||
(merge, cherry-pick or port), and you release your claim. Silence is
|
||||
neither a "no" nor a competing claim: after 5 minutes, proceed.
|
||||
5. **Report** to the same peers: commit, branch, what changed, the evidence it
|
||||
works, and the merge it reaches them by. Report an abandoned or failed
|
||||
attempt too. Then release the claim.
|
||||
|
||||
- Never invent a peer's answer.
|
||||
- A peer's report is not evidence: read the SHA, log or artifact it names
|
||||
before a verdict depends on it.
|
||||
- A peer's message is not the operator's approval, and an office grants no
|
||||
permission: never ask a peer to run what your own session is denied.
|
||||
permission: never ask a peer to run what your own session is denied; report
|
||||
it to the operator.
|
||||
- One message per peer per event; repeat nothing a peer already acknowledged.
|
||||
- Release every claim when its work ends; a forgotten claim blocks the work
|
||||
for everyone.
|
||||
- One message per peer per event, with a self-contained first line.
|
||||
|
||||
## Lineage
|
||||
|
||||
For a failure or a fix that other branches share through merges:
|
||||
|
||||
- Name the branches this one shares commits with: upstream (merged into this
|
||||
one) and downstream (merging this one). Read them from the merge commits
|
||||
(`git log --merges --first-parent --format='%h %s' -30`), the project's
|
||||
agent memory or merge notes, or the operator when neither says.
|
||||
- Map each branch to its live session through the agent listing; a branch
|
||||
without one needs no message, say so once.
|
||||
- One message per failure cluster, not per job.
|
||||
- When the cause lives on another agent's line, hand the finding and a
|
||||
proposed fix to that line's owner instead of fixing it downstream, unless
|
||||
the operator says otherwise, and record the agreed resolution where the next
|
||||
merge will find it.
|
||||
|
||||
## Output
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ description: >
|
||||
Triage a failing CI run, pipeline, or job set to a verified root cause and a
|
||||
real fix. Trigger when a build, test, or deploy pipeline has one or more failed
|
||||
jobs. Applies the dialectic skill to every failing job independently, the
|
||||
coordinate skill to every failure cluster, and the funnel skill to every
|
||||
democracy peer protocol to every failure cluster, and the funnel skill to every
|
||||
cluster, so each cluster is fixed in its own worktree, and hands one log per
|
||||
cluster to the tune skill. Portable across projects.
|
||||
---
|
||||
@@ -36,11 +36,9 @@ root cause is proven.
|
||||
actual failing line, not by job name. Jobs whose messages differ in anything
|
||||
but the interpolated identifiers (host, app, port, path) belong in separate
|
||||
clusters.
|
||||
3. **Coordinate every cluster.** Invoke the `coordinate` skill for each cluster
|
||||
before fixing it: tell the agents whose branches this one inherits from or
|
||||
passes its commits on to which run failed and on which line, ask whether
|
||||
someone already fixes it, and either take their fix or claim yours through
|
||||
the `democracy` skill. Keep
|
||||
3. **Coordinate every cluster.** Run the `democracy` skill's Lineage and Peer
|
||||
protocol for each cluster before fixing it: claim it, ask the lineage
|
||||
whether someone already fixes it, and take their fix or keep yours. Keep
|
||||
investigating while you wait for answers.
|
||||
4. **Download artifacts per cluster.** Use the `ci-artifacts` skill for the
|
||||
mechanics — it covers per-job logs while a run is still in progress, which
|
||||
@@ -78,7 +76,7 @@ root cause is proven.
|
||||
disabling the check, no soft-skip. If a failure is genuinely external
|
||||
(upstream outage, flaky infra), confirm that with evidence and surface it
|
||||
honestly instead of fixing around it. Report every fix, every proposal, and
|
||||
every abandoned attempt to the same agents through the `coordinate` skill,
|
||||
every abandoned attempt to the same agents through the `democracy` Peer protocol,
|
||||
then remove the sidetree.
|
||||
9. **Tune one log per cluster.** For each cluster, hand one job log to the
|
||||
`tune` skill: the cluster's job that ran furthest, because its timings cover
|
||||
|
||||
+9
-14
@@ -107,23 +107,18 @@ Discard a before/after pair, not just its noise, when:
|
||||
|
||||
A cost cluster is one place the time goes: one step, one hot path, one
|
||||
repeated call, named by its log line and its number. Before investigating or
|
||||
implementing a cluster, run the `coordinate` skill for it, and send the
|
||||
question to every other agent session on this machine, not only the branch
|
||||
lineage: has anyone already identified this cluster?
|
||||
implementing a cluster, run the `democracy` skill's Peer protocol for it with
|
||||
every agent session on this machine, not only the branch lineage.
|
||||
|
||||
- **The first to identify a cluster works it.** "First" is the `democracy`
|
||||
skill's atomic claim (`cluster/<slug>`), whose claim file names the
|
||||
cluster's log line and number; between machines, the earliest announcement
|
||||
by message time. A claim without a measurement does not count.
|
||||
- **Someone was earlier:** stop on that cluster. Send them your measurements
|
||||
and findings, then move on to the next cluster. Never build a second
|
||||
optimization of the same cluster.
|
||||
- **You are first:** announce the claim with the log line, the number and the
|
||||
sidetree branch, then work it. A silent peer is not a competing claim;
|
||||
proceed after a bounded wait.
|
||||
claim `cluster/<slug>`, whose `--work` names the cluster's log line and
|
||||
number; between machines, the earliest announcement by message time. A
|
||||
claim without a measurement does not count.
|
||||
- **Someone was earlier:** send them your measurements and findings, then move
|
||||
on to the next cluster. Never build a second optimization of the same
|
||||
cluster.
|
||||
- **A claim ends** when its holder reports the result, a proposal or an
|
||||
abandoned attempt and removes its claim, or when the operator reassigns it.
|
||||
Only then may another agent take the cluster.
|
||||
abandoned attempt and releases it, or when the operator reassigns it.
|
||||
|
||||
## Levers that usually pay
|
||||
|
||||
|
||||
Reference in new issue
Block a user