fix(coord): claim -List measured age and called it staleness - #106
Merged
Conversation
wshallwshall
enabled auto-merge (squash)
July 31, 2026 16:00
`-List` printed "[STALE ~Nh -- release it if that session is gone]" once a claim passed 12h. That measures how long the WORK has run and says nothing about whether anyone is still doing it, while recommending the destructive action and withholding the fact you would need to decide. Measured on this repo today: claim #7 rendered "STALE ~21h -- release it if that session is gone" while its holder had committed TWO MINUTES earlier. A session was told by its owner to clean up stale claims, read that line, and checked the holder before acting. Had it followed the advice, #7 would have been freed for a second session to start building the ADR 0023 deferred tail while someone was mid-flight on it -- the exact duplicate-build this registry exists to prevent, reached by following the tool's own recommendation. Reports liveness instead: worktree missing (the only state safe to act on unasked), or hours since the holder's last commit. A long claim is the normal shape of long work, so 21h with a commit an hour ago now reads as active rather than abandoned, and only a genuinely quiet holder is flagged -- as "confirm before releasing", not "release it". The catch block sets an explicit "liveness check FAILED" annotation rather than leaving it blank. An empty annotation reads as "nothing notable about this claim", which is the same silent-instrument failure the age signal had: accurate about what it measured, mute about what it could not. Verified: live holder, missing worktree, and non-git-directory paths all render correctly; -Take and -Release unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
wshallwshall
force-pushed
the
claim-liveness
branch
from
July 31, 2026 20:35
aa2f7e8 to
89c07f1
Compare
This was referenced Aug 2, 2026
Merged
wshallwshall
added a commit
that referenced
this pull request
Aug 2, 2026
…had looked at (BACKLOG #345 Half B) (#151) #106 taught `-List` to probe whether a claim's holder still exists on disk. That was the wrong half to fix alone: `-List` is where you BROWSE, and `-Take`/`-Release` are where a session is STOPPED and has to choose between waiting, picking other work, and taking the key. Both blocking paths printed the same "held by another worktree" block whether the holder had been deleted, had died, or was committing that minute -- and `-Release` went further, printing "If that session is gone, re-run with -Force" unconditionally, about a holder it had never probed. That is an instruction to guess, issued at the exact moment the guess is expensive: the cheapest way past the gate was also the one that frees a live session's key. This file's own header records what that costs -- three sessions fixed the same npm advisory on 2026-07-24, two PRs closed as duplicates, and the survivor had not tested what the others found. All three surfaces now share ONE helper, because they had been disagreeing: -List probed, the other two did not probe at all. `-Take` blocked by a vanished holder names the exact take-over commands; blocked by a living one it withholds the -Force recipe entirely and says quiet is not dead. THE ASYMMETRY IS THE DESIGN. A vanished worktree is a fact and the one state safe to act on unasked. Present, undatable and unprobeable all read as "coordinate first", never "probably fine" -- a session can be alive and simply not committing, so silence is not evidence of death. A probe hardwired to 'gone' would pass every positive assertion, so each is paired with the negative case that catches it. The catch returns 'failed', never 'gone': an unreadable path must not become a licence to release someone's live claim. -Force is deliberately untouched. This reports; it does not enforce. Refusing to override a live claim would strand every key whose holder is merely unreachable -- the same orphan, one level up. Verified: 4 of the 9 new tests FAIL against main's claim.ps1 and the other 5 are regression guards that must pass on both sides. One assertion was rewritten mid-build after it failed on the PATCHED code -- it searched for the token `-Force`, which the live-holder text contains inside "do NOT -Force it"; the property wanted is "no runnable recipe", so it now asserts the absence of the command line. Re-checked against unpatched afterwards to prove the rewrite had not made it vacuous. 41 coordination tests green.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Found by another session, which nearly acted on it.
The defect
claim.ps1 -Listprinted this once a claim passed 12h:That measures how long the work has run. It says nothing about whether anyone is still doing it — while recommending the destructive action and withholding the one fact you'd need to decide.
Measured today, on this repo:
The holder had committed two minutes earlier. A session was told by its owner to clean up stale claims, read that line, and checked the holder before acting. Had it followed the advice, #7 would have been freed for a second session to start building the ADR 0023 deferred tail while someone was mid-flight on it — the exact duplicate-build this registry exists to prevent, arrived at by following the tool's own recommendation.
The fix
Report liveness, not age:
[HOLDER GONE -- worktree no longer exists; release with -Force][held 21h; holder last committed 0h ago]… -- QUIET, confirm with the holder before releasing[held Nh; holder liveness UNKNOWN -- confirm before releasing]A long claim is the normal shape of long work. Only a genuinely quiet holder is flagged now — and as "confirm before releasing", never "release it". Worktree-gone is the only state safe to act on unasked, and it's the only one that still recommends a release.
The
catchsays so out loudIt sets an explicit
[liveness check FAILED -- treat as unknown, confirm before releasing]rather than leaving the annotation blank. An empty annotation reads as "nothing notable about this claim" — the same silent-instrument failure the age signal had: accurate about what it measured, mute about what it could not.Verification
One file, +33/−5. No behaviour change to claiming or releasing — only to what
-Listtells you.🤖 Generated with Claude Code