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:
1 parent
ea4225c429
commit
c914687804
6 files changed
+152
-15
No files matched your search
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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 |
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user