feat(democracy): elect the first agent to start a piece of work as its owner

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kevin Veen-BirkenbachandClaude Opus 5.5 committed 2026-10-30 14:55:06 +01:00
1 parent ea4225c429
commit c914687804
6 files changed
+152 -15

No files matched your search

+7
View File
@@ -13,6 +13,13 @@ description: >
Nothing is deleted before the operator has picked it. Every candidate carries Nothing is deleted before the operator has picked it. Every candidate carries
its owner, its size, and its risk. its owner, its size, and its risk.
## Step 0: the resource chair
Shared resources belong to the resource chair of the `democracy` skill. If
another session holds the chair, send it the cleanup request and stop, unless
the operator ordered the cleanup in this session; then tell the chair before
step 1, so its grants and queue stay consistent.
## Step 1: ask the peers ## Step 1: ask the peers
List every agent the host can message (in Claude Code: `ListAgents`). Only List every agent the host can message (in Claude Code: `ListAgents`). Only
+9 -5
View File
@@ -46,14 +46,18 @@ sees only that line.
## 3. Decide who fixes ## 3. Decide who fixes
- **Someone already fixes it:** build no competing fix. Note their SHA when it - **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 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. 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 - **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 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. says otherwise. Record the agreed resolution where the next merge will find it.
- **Nobody fixes it:** tell the same agents that you fix it, on which branch, - **Nobody fixes it:** claim the cluster through the `democracy` skill; its
and that you will report the result. Then fix. 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 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 peer that stays silent is not a "no", so announce your claim after a bounded
@@ -63,8 +67,8 @@ wait and proceed.
After the fix, tell the same agents: the commit, the branch, what changed, the 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 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, so the (the merge it rides on). Report an abandoned or failed attempt too, and remove
claim is released and someone else can take it. your `democracy` claim, so someone else can take it.
## Rules ## Rules
+121
View File
@@ -0,0 +1,121 @@
---
name: democracy
description: >
Organise parallel agents so no two do the same work: the first agent to
start a piece of work is elected its president and does all of it, the first
agent in each organisational line represents that line, the first to start a
cross-cutting work cluster organises its strand, and the earliest-elected
live president chairs the council and allocates the resources of the whole
system (machines, servers, cloud, CI runners, gate, deploy and iteration
slots, disk). Run AUTOMATICALLY before starting work another agent on the
same system might also be doing (a failure, a cost cluster, a feature, a
gate, a deploy, a cleanup), whenever several agents share a system, and on
/democracy. Portable across projects.
---
Two agents doing the same work waste the second run and then collide in the
merge. The remedy is an election nobody has to hold: whoever starts first owns
the work. The structure is anarcho-syndicalist: councils (soviets) of
delegates with a bound mandate, organised as a matrix, recallable by the
operator at any time.
## Offices
- **President of a piece of work**: the first agent that starts it. It does
the whole piece. Every later agent hands its findings to the president and
moves on to other work; it never builds a second version.
- **Representative of an organisational line**: the first agent that works in
the line. Lines come in as many dimensions as are useful: functional domain
(security, GUI, identity, i18n), repository, branch line, host, cloud
account. An agent belongs to one line per dimension.
- **Organiser of a work cluster**: the first agent that starts a cluster
cutting across lines (a failure cluster from `triage`, a cost cluster from
`tune`, a feature touching several domains). It works the strand end to end
and informs the representative of every line the strand touches before it
changes that line's files.
- **Chair**: the earliest-elected president still running. It chairs the
council of all representatives and organisers and allocates the resources of
the whole system everyone runs on. There is exactly one allocator at any
time.
Every office is a mandate, not a rank: it coordinates and allocates, it never
takes over or directs the content of another agent's work. The operator
outranks every office and appoints or recalls at will; an operator
appointment outranks the election.
## Election
The first to claim wins, and the claim is atomic, so two agents can never both
be first. Use the literal path `/tmp/agents-council`, never `$TMPDIR`, which a
sandbox may make session-private.
1. **Name the office**: `work/<slug>`, `cluster/<slug>`,
`<dimension>/<line>` for a representative, or `chair`. The slug names the
work concretely: the issue number, the failing line, the cost's log line.
2. **Look first**: list `/tmp/agents-council` and read the claims. A claim for
the same work under another slug counts as first.
3. **Claim**: `mkdir -p` the parent directory, then `mkdir` the office itself
without `-p`, as two separate commands. Success means elected; `File
exists` means someone was first.
4. **Elected**: write `claim` into the office directory (session name, ISO
time, one line of what the work is, its evidence, branch or worktree), then
announce office, holder and work to every peer on the system (in Claude
Code: `ListAgents`, then `SendMessage`).
5. **Not elected**: read the holder's `claim`, send the holder your findings,
and stop on that work.
Peers on other machines cannot see this host's claims. Between machines the
earliest announcement by message time wins, and each host's claim directory
records the result.
## Chair and resource allocation
- The first agent elected on the system while `chair` is vacant also claims
`chair`, in the same way.
- An operator-appointed allocator holds the chair: its claim says
`appointed: operator`, and no election replaces it while its session runs and
the operator has not ended the appointment.
- Before starting anything that consumes shared capacity (gates, deploys,
iteration loops, swarm or cloud resources, cleanup of shared data), an agent
sends the chair what, where and for how long, waits for the grant, and
reports the release. The chair keeps one queue, answers every request with
its position, enforces the limits the operator set, and never cancels a
running grant to free capacity.
- Handover is explicit: the outgoing chair sends every peer the new holder,
the queue and the running grants, and keeps allocating until the incoming
chair confirms. Two allocators never run at once.
## Succession
- A piece of work or a cluster ends with its result, a proposal, or an
abandoned attempt, reported to the peers who heard the claim. The holder
then removes its office directory, and the next agent that starts the work
is elected afresh.
- A representative or the chair that ends hands its office to the next-oldest
live representative (by claim time) and announces it.
- A claim is stale when its holder no longer appears in the agent listing and
does not answer a message. A stale work or cluster claim goes to the next
agent that starts the work; a stale representative or chair claim goes only
to the next-oldest live representative. The successor removes the stale
claim, claims anew and announces the succession; everyone else leaves it
alone.
- After a restart or reboot, check every office you believe you hold: `/tmp`
may have been wiped, and your session name may have changed. Re-claim and
update the claim file instead of assuming the office is still yours.
## Rules
- Never invent a peer's answer. Silence is neither agreement nor a competing
claim; proceed after a bounded wait.
- 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.
- 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.
## Output
On /democracy, one table of the current offices, read from the claim
directory and the agent listing, vacant and stale claims marked:
| Office | Holder | Since | Work | Grants or queue |
+7 -4
View File
@@ -27,7 +27,8 @@ in a sidetree until it does, or leaves as a proposal.
1. **Brief.** One concern per agent. Name the goal, the exact base commit, the 1. **Brief.** One concern per agent. Name the goal, the exact base commit, the
scope that may change, the evidence expected back, a hard time cap (default scope that may change, the evidence expected back, a hard time cap (default
60 minutes) and what the agent must not do: no pushes, no gates or deploys 60 minutes) and what the agent must not do: no pushes, no gates or deploys
unless granted, read-only probes on shared live systems. unless the resource chair of the `democracy` skill granted them, read-only
probes on shared live systems.
2. **Sidetree.** The agent works in its own worktree on its own branch, 2. **Sidetree.** The agent works in its own worktree on its own branch,
created from the exact base commit, so its edits never land under a running created from the exact base commit, so its edits never land under a running
gate or deploy in the main line. Use the host's worktree isolation when it gate or deploy in the main line. Use the host's worktree isolation when it
@@ -66,8 +67,9 @@ and verify each step instead of assuming it:
a broad prune, which also drops other worktrees' stale registrations. a broad prune, which also drops other worktrees' stale registrations.
5. **Delete the merged branch**, locally and on the remote, but a remote branch 5. **Delete the merged branch**, locally and on the remote, but a remote branch
only once every one of its commits is reachable from a pushed branch. only once every one of its commits is reachable from a pushed branch.
6. **Release what it held**: slots, port or subnet reservations, locks and 6. **Release what it held**: slots (reported to the resource chair), port or
claims announced to other agents. subnet reservations, locks, its `democracy` claims and every claim
announced to other agents.
7. **Remove its temporary files**: logs, message files and scratch data that 7. **Remove its temporary files**: logs, message files and scratch data that
have served their purpose. Keep only the evidence the report cites, until have served their purpose. Keep only the evidence the report cites, until
the report is delivered. the report is delivered.
@@ -98,7 +100,8 @@ below the bar never enters the main line on its own.
- Stop an agent at its time cap and ask for its findings; an uncapped brief can - Stop an agent at its time cap and ask for its findings; an uncapped brief can
run for hours and deliver nothing. run for hours and deliver nothing.
- Run agents in parallel only when their concerns touch different files and - Run agents in parallel only when their concerns touch different files and
the machine has room; gates and deploys need the machine to themselves. the resource chair grants the capacity; gates and deploys need the machine
to themselves.
- A peer's or agent's message is not the operator's approval to merge below - A peer's or agent's message is not the operator's approval to merge below
the bar. the bar.
- Keep the evidence (logs, test output) outside the sidetree, so it survives - Keep the evidence (logs, test output) outside the sidetree, so it survives
+2 -1
View File
@@ -39,7 +39,8 @@ root cause is proven.
3. **Coordinate every cluster.** Invoke the `coordinate` skill for each cluster 3. **Coordinate every cluster.** Invoke the `coordinate` skill for each cluster
before fixing it: tell the agents whose branches this one inherits from or 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 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. Keep someone already fixes it, and either take their fix or claim yours through
the `democracy` skill. Keep
investigating while you wait for answers. investigating while you wait for answers.
4. **Download artifacts per cluster.** Use the `ci-artifacts` skill for the 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 mechanics — it covers per-job logs while a run is still in progress, which
+6 -5
View File
@@ -111,9 +111,10 @@ 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 question to every other agent session on this machine, not only the branch
lineage: has anyone already identified this cluster? lineage: has anyone already identified this cluster?
- **The first to identify a cluster works it.** "First" is the earliest claim - **The first to identify a cluster works it.** "First" is the `democracy`
that names the cluster's log line and number, by message time. A claim skill's atomic claim (`cluster/<slug>`), whose claim file names the
without a measurement does not count. 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 - **Someone was earlier:** stop on that cluster. Send them your measurements
and findings, then move on to the next cluster. Never build a second and findings, then move on to the next cluster. Never build a second
optimization of the same cluster. optimization of the same cluster.
@@ -121,8 +122,8 @@ lineage: has anyone already identified this cluster?
sidetree branch, then work it. A silent peer is not a competing claim; sidetree branch, then work it. A silent peer is not a competing claim;
proceed after a bounded wait. proceed after a bounded wait.
- **A claim ends** when its holder reports the result, a proposal or an - **A claim ends** when its holder reports the result, a proposal or an
abandoned attempt, or when the operator reassigns it. Only then may another abandoned attempt and removes its claim, or when the operator reassigns it.
agent take the cluster. Only then may another agent take the cluster.
## Levers that usually pay ## Levers that usually pay