I3174 — An exclusive claim carries a fencing epoch, and a holder returning under an old epoch is refused
Give every exclusive mesh claim a monotonically increasing epoch issued by the runtime that admits it, carry it on every write the holder makes under the claim, and refuse a write or a completion whose epoch is lower than the current one, so a worker that reappears after its claim expired and was retaken cannot finish under its old right.
READY wave 0 · p1 · deep-work profile · parallel safe
Ready. Every dependency is done, so majordomus plan start I3174 will be accepted.
Objective
Give every exclusive mesh claim a monotonically increasing epoch issued by the runtime that admits it, carry it on every write the holder makes under the claim, and refuse a write or a completion whose epoch is lower than the current one, so a worker that reappears after its claim expired and was retaken cannot finish under its old right.
Why
Mesh claims converge but are not linearisable across a partition (docs/MESH.md 'Not guaranteed'); the 10-09 and 10-18 designs both required fencing before any orchestrator treats a claim as exclusive. f6's I2976 (/proceed; in flight on f6's branch, with no issue record or ADR on master yet) states it acts on 'local admission plus deterministic naming of the winner until mesh-journal-converges adds fencing'. It waits on I2825 (a released claim reaches every runtime), which is in flight on branch docs/a-released-claim-reaches-every-runtime with no record yet; depends_on I2825 is added once that record lands. Sources: chatgpt-majordomus:c294#2, chatgpt-majordomus:c203#2, chatgpt-majordomus:c210#1.
Current state
Verified: no 'fencing' anywhere in apps/majordomus-cli/src; claims and seats are journal events with expiry (mesh/cooperation.rs, ADR 0167); I2825 (released claim reaches every runtime) is in flight on branch docs/a-released-claim-reaches-every-runtime, with no record on master.
Desired state
Claim events carry epoch; mesh claim prints it; a stale-epoch completion is refused with the current holder named; the mesh lab proves it across a partition.
Scope
- apps/majordomus-cli/src/mesh/cooperation.rs
- apps/majordomus-cli/src/mesh/journal.rs
- apps/majordomus-cli/src/mesh/protocol.rs
- test/mesh-lab/run
- docs/MESH.md
Out of scope
- A distributed lock or consensus
- Seat semantics (ADR 0167) beyond carrying the epoch
Dependencies
None. This issue is a root of the graph.
What waits on this
Acceptance criteria
- Two runtimes racing one exclusive claim end with one holder at epoch n+1
- A holder whose claim expired and was retaken is refused when it writes under epoch n
- After a partition heals, the lower epoch never wins, whatever the delivery order
Validation
- majordomus plan validate
- cargo test --lib mesh::cooperation
- bash test/mesh-lab/run
Evidence required
- case_a_stale_epoch_is_refused
- mesh_lab_fenced_claim
Evidence
None recorded. Every token above needs a command or an artifact behind it before this issue can be completed; narrative is refused.
Timeline
- started
- —
- verified
- —
- completed
- —
Those three fields, the evidence above and the state of the dependencies are all the status is made of. There is no status field to disagree with them.
Canonical record: .ai/repo/project/issues/I3174.yaml. Read it back with majordomus plan show I3174.