feat(pool): add stable lease identities - #68
Merged
Conversation
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.
Intent
Add backward-compatible stable Treehouse lease ownership identity and provider-enforced conditional release so Firstmate and other automation can distinguish the current acquisition from a stale or reused worktree path. Every new lease must receive an immutable high-entropy lease_id persisted atomically and regenerated on each acquisition, including same-holder same-path reuse. Add opt-in JSON allocation and status output for path, lease_id, holder, and timestamp without changing existing human or path-only stdout behavior. Add optional --if-lease-id and --if-lease-holder return preconditions checked under the provider state lock before termination, reset, or clearing, and fence a verified release across those effects so retries, concurrent releases, repeated old identities, and same-holder ABA cannot affect a newer lease. Preserve legacy unconditional return behavior, existing scripts and environment variables, and old state files without lease IDs. Cover the real CLI reproduction plus compatibility, JSON, mismatch/no-mutation, correct and repeated release, reacquisition, ABA, and release-boundary concurrency tests. Do not edit generated changelog material or Firstmate or Herdr.
What Changed
lease_id, while preserving compatibility with existing state files and path-only lease workflows.Risk Assessment
✅ Low: The follow-up moves interactive confirmation outside the pool lock while revalidating the lease immediately before the fully fenced termination, reset, and clear sequence; the cumulative change satisfies the stated identity, compatibility, JSON, and concurrency requirements without material source risks found.
Testing
Focused compatibility, JSON, persistence, conditional lifecycle, concurrency, full repository, Windows build, and real CLI checks all passed; the captured transcript demonstrates stable identity regeneration and stale-release fencing end to end.
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 1 issue found → auto-fixed ✅
cmd/return_cmd.go:58- A conditional return of a dirty worktree without--forcecallsui.Confirmwhile holding the pool state lock. An unattended prompt can therefore block every get, status, prune, destroy, and return operation for that pool indefinitely. Validate briefly, prompt outside the lock, then revalidate and fence the mutating preparation/reset/clear sequence under the lock.🔧 Fix: Avoid holding pool lock during conditional return prompts
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
go test ./cmd -run 'Test(GetLeasePrintsOnlyPathToStdout|GetLeaseRecordsHolder|GetLeaseAndStatusJSONContracts|GetJSONRequiresLease|ReturnLegacyPathOnlyIgnoresStaleCallerHolder|ReturnConditionalLeaseIdentityLifecycle|ReturnConditionalDirtyPromptDoesNotHoldPoolLock)$' -count=1go test ./internal/pool -run 'Test(WriteState_RoundTrip|ReadState_LoadsPreIdentityLease|WriteState_InterruptedWriteNeverTouchesLiveFile|Release_PreIdentityLeaseFailsConditionalAndAllowsLegacyReturn|AcquireLease_ConcurrentAcquiresNeverDoubleLease|ReleaseConditional_ConcurrentIdentityReleasesExactlyOnce)$' -count=1go test ./... -count=1Built the CLI and exercisedget --lease --json,status --json, mismatched and correct conditional returns, same-holder same-path reacquisition, and stale ABA release in a fresh isolated Git repository.GOOS=windows go build ./...✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.