You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Lease] Crash consistency between git mutation and lease record #136
Current owner handoff — integration-first scope checkpoint (2026-09-22)
Active implementation is draft PR #203, branch cursor/lease-crash-consistency-2079, existing Cursor session bc-f8aa5137-6d0f-4ac2-a7e2-5129f27d2079. #185/#198 are preserved salvage sources, not three independent implementations to keep polishing. Continue only this current session/thread; no replacement PR or new worker.
HOLD architecture expansion; preserve and stabilize the retained binding core.Grok's OSS Position Audit recommends that writ retain binding job ownership, register-only CheckoutRef identity, handoff generations/envelope, and a single native authoritative ownership ledger. It explicitly does not select Foremerge as the default backend; semantic-conflict analysis and generic transport are optional integration candidates. Do not replace the ownership database, install sidecars, or remove working code based solely on the audit.
Within #203, retain useful crash-recovery/non-resurrection/WIP-preservation and generation-matched-handoff code/tests. Fix demonstrable bounded correctness or current-main integration problems, but do not expand messaging, semantic detection, remote coordination, supervision, or managed checkout lifecycle just to finish the old roadmap. Before a large refactor, identify the smallest binding core and the existing call boundaries that can become replaceable ports; report a concrete keep/adapt/defer map and review blockers here. A new abstraction should be justified by an actual integration, not speculative extensibility.
RM-1412/#202 is being steered in its existing session to verify and repair cross-process live-checkout ownership atomicity; consume that invariant/test after coordination rather than creating another fix. Preserve current main's status/watchlist consumers and unknown-state semantics. Advisory path overlap must not become a universal write veto; backend failure must never silently grant duplicate ownership or seize WIP. Distinguish optional advisory-service degradation from unavailable binding authority.
Keep draft and preserve branch/history/attribution. Normal assigned-branch fetch/integration/testing/commits/push for bounded fixes are permitted. No merge, repository-settings change, new session, bulk deletion, or broad dependency migration is requested. Report exact head, supported behavior, meaningful test evidence and outstanding decisions; green analyzers alone do not settle the architecture.
Note
Current planning lives in Linear:#136
GitHub remains the source / PR / review / checks surface. This issue is a compatibility/history mirror, not a second required backlog.
The attached GitHub milestone M1 — Hook enforcement (v0.3.0) is legacy taxonomy from an older architecture; current planning milestone is writ — Collaboration MVP in Linear.
Current Cursor owner direction — 2026-09-21
This is the shared-state foundation for the collaboration-first product. Preserve the existing #185/#198 branches and history; do not restart from scratch.
Key correction: PR #199 retired writ-owned worktree creation/removal. Revise #185 so crash consistency applies to registration/ownership of harness-created checkouts, not a writ-owned git worktree add lifecycle. Keep the useful SQLite, operation identity, reconciliation, tombstone, TTL/heartbeat, and crash tests. Then reconcile #198's same-host claims/messages/handoff layer on top.
Path overlap on different branches is advisory/negotiated; duplicate live task ownership must not happen silently. Normal assigned-branch merge/rebase/cherry-pick is allowed. GitHub remains the remote protected-branch merge authority. No new database, Python orchestrator, universal shell classifier, GitHub issue twin, or duplicate Cursor session.
Draft PR #185 predates the harness-owned-checkout change and still couples its prepare/reconcile protocol to writ-owned git worktree add. Treat #185 as a salvage branch, not merge-ready as-is: keep the SQLite state, operation identity, reconciliation, tombstone, TTL, and crash-test primitives that still apply, but revise the mutation boundary around registration/ownership of harness-created checkouts. Draft PR #198 remains valuable for the same-host coordination/message/handoff layer; reconcile it after the retained #185 substrate is compatible with PR #199.
Restored — 2026-09-21
This issue was unintentionally canceled when the obsolete Phase-1 enforcement parent was canceled. The work is still aligned with #1: crash-safe ownership plus the same-host coordination/handoff substrate. Preserve the existing branches and draft PRs #185 and #198; do not restart implementation from scratch.
Current-session steering — 2026-09-19
Follow the new collaboration-first direction in #1. Preserve and finish the useful crash-consistency work already on this session's branch; do not expand universal no-merge enforcement.
Own the minimal shared coordination/message/handoff contract, reusing the existing Rust/SQLite primitives. Allow independent worker processes to announce task/agent/branch identity and intended paths, report overlaps/blockers, request help, and acknowledge a handoff. Record enough identity/version information to distinguish stale messages and stale ownership from live state; do not treat TTL expiry alone as permission to overwrite WIP. Declared path overlap on distinct branches is advisory and negotiated, not an automatic repo-wide write veto.
RM-145 owns guidance/integration policy; RM-127 owns consuming state for visibility. Coordinate the small shared contract with them before divergent schemas appear. Independent cloud sessions use the shared Linear threads now, not separate local SQLite files. Prove a local runtime slice with two separate processes/worktrees using one shared store, an overlap/help/handoff round trip, and paused-worker recovery. Keep this additive follow-up separate from an already-reviewed crash-recovery diff; no distributed-service rewrite or duplicate agent launch.
This implementation direction supersedes conflicting historical enforcement-first prose below. It does not authorize merging a PR, changing repository settings, or discarding either worker's work.
Important
Product goal (2026-09-05):writ (formerly worktrees-hives) is the enforcement and admission-control layer for agent fleets. Task assignment is commoditized — Claude Code agent teams, /batch, Cursor /multitask and Codex already assign and isolate work. What nothing enforces is safe concurrent writing, and nothing arbitrates contention — whether a second agent may take a path or a work item already taken. writ enforces at the git mutation boundary through Claude Code hooks (a PreToolUse exit 2 cannot be overridden, even by another hook's permissionDecision: "allow"), leases worktrees it did not create, and never merges. Prefer work that hardens that boundary over creating worktrees or re-implementing task assignment.
Why this survived the pivot
The original framing was Python LabJobManager.allocate persisting a PENDING record before calling wh worktree create, with a crash window between Rust mutation and Python promotion. python/ is deleted in Phase 3, so that specific code is going away.
The defect is not. It reappears verbatim in the hook path:
WorktreeCreate fires. writ verifies the exact base and Claude Code creates the worktree.
The process dies before the lease row is committed.
TTL and heartbeat, planned for the lease store in #124, solve the opposite window — an orphaned lease whose owner died. They do not solve a mutation with no lease. Both halves are needed, and this issue owns the second.
Scope
Crash consistency between the git mutation and the lease record.
Persist the requested source identity before mutation, retaining enough immutable identity to distinguish a symbolic request from the exact commit that was resolved.
Close the resolve/mutate/commit gap with either a durable operation journal or an explicit prepare/reserve protocol that persists the canonical start commit before mutation.
Provide a Rust-owned inspection operation reporting derived path, symbolic branch ref, branch commit, worker HEAD, registration state, repository identity, and operation identity without mutating or adopting anything.
Define deterministic outcomes: promote when every identity matches; retry only when it is proven no mutation occurred; retain a needs-attention state for partial or conflicting evidence.
Never delete a branch, worktree, registration, or path unless ownership by this transaction is proven.
Do not use ambient HEAD, current checkout state, or a moved symbolic ref to reconstruct the original requested commit.
fix_cycles (see [writ] Advisory change-growth budgets for collaborative agents #167) is the only accumulated lease counter; every other budget dimension is derived from the resolved canonical start commit and is crash-safe by construction. This protocol therefore covers exactly one counter, and a crash between an increment and the mutation it authorized must neither double-count nor lose it.
Acceptance criteria
A crash before mutation is detected and retryable without permanently reserving the identity.
A crash after branch creation, after registration, after filesystem creation, and after full success is independently injected and reconciled at each boundary.
A fully matching interrupted allocation is promoted with its exact canonical start commit.
Conflicting branch/ref/HEAD/registration/path evidence stays fail-closed and is surfaced without destructive cleanup.
The persisted record distinguishes requested symbolic identity, resolved canonical commit, and operation identity.
Concurrent reconciliation and teardown cannot resurrect a released or tombstoned lease.
TTL expiry (orphaned lease, live worktree) and this case (live worktree, missing lease) are both covered and clearly distinguished.
Cargo fmt, Clippy with warnings denied, and Rust workspace tests pass.
Scope boundaries
Owns crash consistency of the lease record. Does not implement general branch resume (#141), fork-object import (#134), path-race hardening (#127), or merge behavior. Must not weaken exact-base or unproven-reuse fail-closed rules.
Crash-consistent lease prepare/inspect/reconcile is on cursor/lease-crash-consistency-32fa at 86dc2da.
writ worktree create now persists requested symbolic identity, resolved canonical start commit, and an operation id before git mutation. Inspect is read-only. Reconcile promotes a fully matching interrupt, retries a proven no-mutation crash, and keeps partial/conflicting residuals fail-closed without cleanup. Released/tombstoned rows cannot be resurrected; TTL expiry is distinct from a live worktree with no lease. fix_cycles uses the same prepare/commit protocol.
Crash-consistency recovered on cursor/lease-crash-consistency-32fa @ ea6cf100ebf14ec1ef10917325ae45ffc59e0ac2 (PR #185). Collaboration messages/handoff will land on stacked cursor/lease-coord-handoff-32fa in the same leases.db (coord_claims + coord_messages). No second store, no remote merge, no GitHub settings change.
Salvage of this issue after #199 is on draft PR #203 (cursor/lease-crash-consistency-2079 @ ba4e236). Crash consistency now applies to harness-owned checkout registration, not writ-owned git worktree add. Same-host coord/handoff from #198 is on the same leases.db.
Native gates passed on that SHA. #185/#198 history was used as the salvage source and is not discarded.
Current owner handoff — integration-first scope checkpoint (2026-09-22)
Active implementation is draft PR #203, branch
cursor/lease-crash-consistency-2079, existing Cursor sessionbc-f8aa5137-6d0f-4ac2-a7e2-5129f27d2079. #185/#198 are preserved salvage sources, not three independent implementations to keep polishing. Continue only this current session/thread; no replacement PR or new worker.HOLD architecture expansion; preserve and stabilize the retained binding core. Grok's OSS Position Audit recommends that writ retain binding job ownership, register-only CheckoutRef identity, handoff generations/envelope, and a single native authoritative ownership ledger. It explicitly does not select Foremerge as the default backend; semantic-conflict analysis and generic transport are optional integration candidates. Do not replace the ownership database, install sidecars, or remove working code based solely on the audit.
Within #203, retain useful crash-recovery/non-resurrection/WIP-preservation and generation-matched-handoff code/tests. Fix demonstrable bounded correctness or current-main integration problems, but do not expand messaging, semantic detection, remote coordination, supervision, or managed checkout lifecycle just to finish the old roadmap. Before a large refactor, identify the smallest binding core and the existing call boundaries that can become replaceable ports; report a concrete keep/adapt/defer map and review blockers here. A new abstraction should be justified by an actual integration, not speculative extensibility.
RM-1412/#202 is being steered in its existing session to verify and repair cross-process live-checkout ownership atomicity; consume that invariant/test after coordination rather than creating another fix. Preserve current main's status/watchlist consumers and unknown-state semantics. Advisory path overlap must not become a universal write veto; backend failure must never silently grant duplicate ownership or seize WIP. Distinguish optional advisory-service degradation from unavailable binding authority.
Keep draft and preserve branch/history/attribution. Normal assigned-branch fetch/integration/testing/commits/push for bounded fixes are permitted. No merge, repository-settings change, new session, bulk deletion, or broad dependency migration is requested. Report exact head, supported behavior, meaningful test evidence and outstanding decisions; green analyzers alone do not settle the architecture.
Note
Current planning lives in Linear: #136
GitHub remains the source / PR / review / checks surface. This issue is a compatibility/history mirror, not a second required backlog.
The attached GitHub milestone
M1 — Hook enforcement (v0.3.0)is legacy taxonomy from an older architecture; current planning milestone iswrit — Collaboration MVPin Linear.Current Cursor owner direction — 2026-09-21
This is the shared-state foundation for the collaboration-first product. Preserve the existing #185/#198 branches and history; do not restart from scratch.
Key correction: PR #199 retired writ-owned worktree creation/removal. Revise #185 so crash consistency applies to registration/ownership of harness-created checkouts, not a writ-owned
git worktree addlifecycle. Keep the useful SQLite, operation identity, reconciliation, tombstone, TTL/heartbeat, and crash tests. Then reconcile #198's same-host claims/messages/handoff layer on top.Path overlap on different branches is advisory/negotiated; duplicate live task ownership must not happen silently. Normal assigned-branch merge/rebase/cherry-pick is allowed. GitHub remains the remote protected-branch merge authority. No new database, Python orchestrator, universal shell classifier, GitHub issue twin, or duplicate Cursor session.
Revision note — after RM-1711 / PR #199
Draft PR #185 predates the harness-owned-checkout change and still couples its prepare/reconcile protocol to writ-owned
git worktree add. Treat #185 as a salvage branch, not merge-ready as-is: keep the SQLite state, operation identity, reconciliation, tombstone, TTL, and crash-test primitives that still apply, but revise the mutation boundary around registration/ownership of harness-created checkouts. Draft PR #198 remains valuable for the same-host coordination/message/handoff layer; reconcile it after the retained #185 substrate is compatible with PR #199.Restored — 2026-09-21
This issue was unintentionally canceled when the obsolete Phase-1 enforcement parent was canceled. The work is still aligned with #1: crash-safe ownership plus the same-host coordination/handoff substrate. Preserve the existing branches and draft PRs #185 and #198; do not restart implementation from scratch.
Current-session steering — 2026-09-19
Follow the new collaboration-first direction in #1. Preserve and finish the useful crash-consistency work already on this session's branch; do not expand universal no-merge enforcement.
Own the minimal shared coordination/message/handoff contract, reusing the existing Rust/SQLite primitives. Allow independent worker processes to announce task/agent/branch identity and intended paths, report overlaps/blockers, request help, and acknowledge a handoff. Record enough identity/version information to distinguish stale messages and stale ownership from live state; do not treat TTL expiry alone as permission to overwrite WIP. Declared path overlap on distinct branches is advisory and negotiated, not an automatic repo-wide write veto.
RM-145 owns guidance/integration policy; RM-127 owns consuming state for visibility. Coordinate the small shared contract with them before divergent schemas appear. Independent cloud sessions use the shared Linear threads now, not separate local SQLite files. Prove a local runtime slice with two separate processes/worktrees using one shared store, an overlap/help/handoff round trip, and paused-worker recovery. Keep this additive follow-up separate from an already-reviewed crash-recovery diff; no distributed-service rewrite or duplicate agent launch.
This implementation direction supersedes conflicting historical enforcement-first prose below. It does not authorize merging a PR, changing repository settings, or discarding either worker's work.
Important
Product goal (2026-09-05):
writ(formerlyworktrees-hives) is the enforcement and admission-control layer for agent fleets. Task assignment is commoditized — Claude Code agent teams,/batch, Cursor/multitaskand Codex already assign and isolate work. What nothing enforces is safe concurrent writing, and nothing arbitrates contention — whether a second agent may take a path or a work item already taken.writenforces at the git mutation boundary through Claude Code hooks (aPreToolUseexit 2 cannot be overridden, even by another hook'spermissionDecision: "allow"), leases worktrees it did not create, and never merges. Prefer work that hardens that boundary over creating worktrees or re-implementing task assignment.Why this survived the pivot
The original framing was Python
LabJobManager.allocatepersisting aPENDINGrecord before callingwh worktree create, with a crash window between Rust mutation and Python promotion.python/is deleted in Phase 3, so that specific code is going away.The defect is not. It reappears verbatim in the hook path:
WorktreeCreatefires.writverifies the exact base and Claude Code creates the worktree.TTL and heartbeat, planned for the lease store in #124, solve the opposite window — an orphaned lease whose owner died. They do not solve a mutation with no lease. Both halves are needed, and this issue owns the second.
Scope
Crash consistency between the git mutation and the lease record.
HEAD, registration state, repository identity, and operation identity without mutating or adopting anything.HEAD, current checkout state, or a moved symbolic ref to reconstruct the original requested commit.fix_cycles(see [writ] Advisory change-growth budgets for collaborative agents #167) is the only accumulated lease counter; every other budget dimension is derived from the resolved canonical start commit and is crash-safe by construction. This protocol therefore covers exactly one counter, and a crash between an increment and the mutation it authorized must neither double-count nor lose it.Acceptance criteria
Scope boundaries
Owns crash consistency of the lease record. Does not implement general branch resume (#141), fork-object import (#134), path-race hardening (#127), or merge behavior. Must not weaken exact-base or unproven-reuse fail-closed rules.
Relationships
NOT_PLANNED2026-09-05