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
|
||||
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
|
||||
|
||||
List every agent the host can message (in Claude Code: `ListAgents`). Only
|
||||
|
||||
@@ -46,14 +46,18 @@ sees only that line.
|
||||
|
||||
## 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
|
||||
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:** tell the same agents that you fix it, on which branch,
|
||||
and that you will report the result. Then fix.
|
||||
- **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
|
||||
@@ -63,8 +67,8 @@ wait and proceed.
|
||||
|
||||
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, so the
|
||||
claim is released and someone else can take it.
|
||||
(the merge it rides on). Report an abandoned or failed attempt too, and remove
|
||||
your `democracy` claim, so someone else can take it.
|
||||
|
||||
## 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
|
||||
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
|
||||
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,
|
||||
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
|
||||
@@ -66,8 +67,9 @@ and verify each step instead of assuming it:
|
||||
a broad prune, which also drops other worktrees' stale registrations.
|
||||
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.
|
||||
6. **Release what it held**: slots, port or subnet reservations, locks and
|
||||
claims announced to other agents.
|
||||
6. **Release what it held**: slots (reported to the resource chair), port or
|
||||
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
|
||||
have served their purpose. Keep only the evidence the report cites, until
|
||||
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
|
||||
run for hours and deliver nothing.
|
||||
- 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
|
||||
the bar.
|
||||
- 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
|
||||
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. Keep
|
||||
someone already fixes it, and either take their fix or claim yours through
|
||||
the `democracy` skill. 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
|
||||
|
||||
@@ -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
|
||||
lineage: has anyone already identified this cluster?
|
||||
|
||||
- **The first to identify a cluster works it.** "First" is the earliest claim
|
||||
that names the cluster's log line and number, by message time. A claim
|
||||
without a measurement does not count.
|
||||
- **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.
|
||||
@@ -121,8 +122,8 @@ lineage: has anyone already identified this cluster?
|
||||
sidetree branch, then work it. A silent peer is not a competing claim;
|
||||
proceed after a bounded wait.
|
||||
- **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
|
||||
agent take the cluster.
|
||||
abandoned attempt and removes its claim, or when the operator reassigns it.
|
||||
Only then may another agent take the cluster.
|
||||
|
||||
## Levers that usually pay
|
||||
|
||||
|
||||
Reference in new issue
Block a user