fix(bin): refuse stale pooled worktree ownership - #3246
Conversation
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains. Reviews (3): Last reviewed commit: "test(spawn): use distinct slots and prov..." | Re-trigger Greptile |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bb948d695b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| printf '%s' 'a marker with no readable task identity' | ||
| return 1 | ||
| fi | ||
| [ "$owner" != "$ID" ] || return 0 |
There was a problem hiding this comment.
Refuse same-task owner markers on fresh spawns
Captain, when a fresh recovery spawn reuses a task ID after its pending ownership record was lost or became unreadable, this check accepts an existing marker solely because task_id matches; stamp_task_worktree_owner then overwrites its generation and can launch a second worker into a worktree still owned by the earlier incarnation. Only relaunch has metadata and handoff evidence that can safely accept a same-ID marker, so a fresh spawn must refuse any existing marker rather than treating the ID match as ownership proof.
AGENTS.md reference: AGENTS.md:L228-L229
Useful? React with 👍 / 👎.
|
Speaking as Kun's firstmate: Reviewed HEAD Class: corrective. Destructive teardown/relaunch/recovery currently trust a recorded pool path that may have been reissued. This adds a task+generation owner marker and a shared ownership resolver so those actions refuse when the slot belongs to someone else. Captain-facing spawn/teardown stay the same; they just stop destroying the wrong worker. Does not stop the pool from handing a slot out twice (author correctly left that out of scope). VISION.md per-rule (inspected
Attestation: missing. No Codex P1 (waiting on author): a fresh recovery spawn that reuses a task id after a lost/unreadable pending-ownership record accepts an existing marker solely because Fork CI: approved this pass on this HEAD only: Overlap note (not a hold): open #3168 / #3161 also touch Waiting on the author for attestation + the fresh-spawn marker hole. Not a captain-decision. No auto-merge. |
…overable task states
…storable claim discovery
…ip before stamping
…olved pending claims
…eipts until removal
…ix restore bookkeeping
…e-marker fallback
…th runner invocation
…idence; sweep prior markers
…d-record backend advice
… lib to teardown suites
…-return refusal wording
…and secondmate docs
…own and architecture docs
bb948d6 to
dd87a73
Compare
|
Speaking as Kun's firstmate: Re-reviewed after newer activity (prior stamp was on Codex P1 (prior wait): addressed on this HEAD. Contract-class: new-default. Unconfigured new ordinary claims always stamp VISION.md per-rule (inspected
Attestation: MATCH ( Fork CI: approved this pass on this HEAD: CI/NM on this HEAD: NM
Waiting on the author to clear those CI failures (fixture/relaunch path vs marker lifecycle). Not a captain-decision while CI is red. No auto-merge. Overlap note (not a hold): several open PRs also touch |
Summary
worktree=claim before returning or removing a slot, then use a non-authoritative retirement receipt so late cleanup failures can be retried without restoring destructive authority over a recycled path.fm/<task-id>.Issue impact
.stealrecursion half is untouched and must remain open.This change makes destructive lifecycle actions refuse when ownership has moved. It does not stop the pool from handing the same slot out twice; that root cause is deliberately out of scope and is filed separately as a follow-up.
Validation
worktree=or.fm-task-ownerafter provider release.Updates from git push no-mistakes