fix-reopen-before-owner-release-race

Fence reopen until prior Pi owner releases

Metadata

Statusdone
Agent identityfbb2d89fe44d6b761bcb4b67748ab3d417f29df70a65f8d9403308f5bb2bab78
Created2026-07-31T19:54:05.364999642+00:00
Started2026-07-31T19:54:12.897785548+00:00
Completed2026-08-03T09:42:51.694253181+00:00
Tokens53677848 in / 82932 out

Description

Fix the WG lifecycle race where a task can be reopened/retried before its previous Pi attempt has released process/worktree ownership. A reopen intent may be recorded, but the new generation/attempt must remain non-runnable until the exact old owner is quiescent and its fenced lease is released or explicitly reaped. Never create competing Pi processes, reuse a live worktree lease, charge the breaker for expected ownership contention, or lose WIP/session evidence.

Concrete local reproducer/evidence: remove-distracting-plumbing-control, generation 0 attempt attempt-0-1, agent-949. It is terminal Abandoned and the process is dead, but the lifecycle still projects attempt outcome None, the Pi watchdog remains Active, and the retained worktree/source tuple still owns fence/lease 1. Preserve these files as evidence until the fix is validated. Audit abandon + immediate retry/requeue/reset/TUI reopen and any coordinator/convergence reopen path.

Required behavior:

  • Reopen requested while old owner is live: persist intent/hold, do not dispatch or allocate competing ownership.
  • Exact old owner exit/reap: atomically release/fence old ownership, then create/enable the new generation exactly once.
  • Crash/restart between every boundary converges without duplicate attempts.
  • Late old-owner events are stale evidence and cannot mutate the reopened generation.
  • Expected ownership contention remains breaker-neutral.
  • TUI/status explains waiting-for-owner-release rather than showing a silently runnable/open task.

Validation

  • Add a deterministic integration/smoke regression covering old Pi owner live → reopen intent → no competitor → owner exit/reap → exactly one new attempt.
  • Cover restart at the reopen/release boundary and late old-owner terminal/progress events.
  • Cover abandon followed immediately by retry/requeue/reset through supported operator surfaces.
  • Verify same session/worktree/WIP preservation where continuation is intended and fresh fenced generation only where retry semantics require it.
  • cargo fmt --check, focused lifecycle/spawn/watchdog tests, cargo check, cargo clippy.
  • Demonstrate the real agent-949 retained state can be safely reconciled only after evidence capture.

Depends on

Required by

Messages 1 message

  1. #1user2026-07-31T19:54:38.229258969+00:00read
    Operator clarified the exact failure: reopen occurred before the old Pi attempt released its worktree/session lease; after the process died, the stale `live attempt` ownership projection survived, so admission indefinitely deferred redispatch. Treat this as the primary reproducer. Fix must reconcile proven-dead process -> fenced release of BOTH worktree and Pi session ownership -> exactly-once redispatch, while a genuinely live owner remains a neutral hold. Add explicit regression asserting stale-live deferral cannot persist indefinitely across daemon restart.

Log