Skip to content

fix(persistence): keep contended sessions usable - #46

Merged
willytop8 merged 2 commits into
mainfrom
wr/41-passive-lease-contention
Aug 2, 2026
Merged

fix(persistence): keep contended sessions usable#46
willytop8 merged 2 commits into
mainfrom
wr/41-passive-lease-contention

Conversation

@willytop8

Copy link
Copy Markdown
Owner

Summary

Keep a second OpenCode process usable when it opens a session whose goal-state
shard is already owned, without weakening the same-session single-writer
guarantee.

What changed

  • treat lease contention as a typed, per-session passive goal mode
  • allow ordinary chat and unrelated tools while denying all goal mutations;
    canonical tools use stable session_owned_elsewhere, while slash commands
    and legacy tools return actionable human-readable denials
  • retry ownership only from a fresh explicit goal command or tool, then reload
    durable active work paused until the user resumes it
  • replace the race-prone reclaimable lock with an atomic compatibility guard and
    immutable per-owner claims
  • fail closed for malformed, tampered, future, symlinked, or unsupported lease
    layouts and document bounded manual recovery
  • cover command correlation, delayed replies, disposal, execution context,
    retention beyond 1,000 sessions, exact v0.6.7 startup races, and portable
    filesystem behavior

Why

The issue's proposed catch-and-continue fallback would create an unpersisted
second copy of the same goal workflow. It could report successful mutations that
are silently lost and allow two continuation controllers to act on one session.
Passive goal mode preserves normal OpenCode use while keeping goal state
single-writer and recoverable.

Validation

  • npm run release:check — passed
    • full suite: 329/329 tests
    • mutation contract: 64/64 critical mutants killed
    • behavior benchmark: 100/100
    • type, source smoke, packed-host, all 11 packed tools, verifier, audit, and
      package-content gates passed
    • production dependency audit: 0 vulnerabilities
  • focused lifecycle/filesystem suite: 57/57 on macOS and 57/57 in Linux
    (node:22-bookworm)
  • lease stress: 100 rounds × 16 simultaneous contenders, no dual owners
  • real packed-package acceptance: passed on OpenCode 1.17.15 and 1.18.11
    • ordinary chat and unrelated tools remained usable while passive
    • goal mutation stayed blocked and persistence bytes stayed unchanged
    • explicit takeover recovered paused, with zero continuation before resume and
      exactly one after resume

Compatibility and rollout

The local filesystem must support regular-file hard links and preserve the
long-lived guard timestamp; unsupported layouts fail closed and capability
errors require a supported local filesystem. Safe automatic same-session
takeover requires every participating process to use the new release. The PR
expands portable filesystem CI so Linux, macOS, and Windows must all pass before
merge.

Fixes #41

Keep non-owner sessions in a passive goal mode and retry ownership only at an explicit control boundary. Harden mixed-version lease acquisition with an atomic compatibility guard and immutable owner claims.

Fixes #41
Check the exact private lease token instead of rejecting UUID-shaped hostnames, and retain a finite logger hang detector without imposing a 250ms filesystem deadline.
@willytop8
willytop8 marked this pull request as ready for review August 2, 2026 04:29
@willytop8
willytop8 merged commit 295d50b into main Aug 2, 2026
10 checks passed
@willytop8 willytop8 mentioned this pull request Aug 2, 2026
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Gracefully handle contested persistence lock when running multiple instances

1 participant