-
Notifications
You must be signed in to change notification settings - Fork 1
Closed
Description
What state is duplicated
Auto-locks are managed by LockManager but their lifecycle is driven entirely by the daemon's session tracking, not by actual process state:
session.launch→lockManager.autoLock(cwd, session.id)(tied to daemon session ID)session.stop→lockManager.autoUnlock(sessionId)(daemon decides session stopped)reconcileAndEnrich()→ marks sessions stopped →lockManager.autoUnlock(id)(daemon inferred death)cleanupDeadLaunches()→ checks PID liveness in daemon state →lockManager.autoUnlock(id)(daemon state, not adapter)
Files:
lock-manager.ts: Lock CRUDsession-tracker.ts: Triggers lock cleanup based on daemon session stateserver.ts: Wires lock cleanup to session lifecycle eventsstate.ts: Locks persisted inlocks.json
Where is the ground truth?
A directory is "in use" if and only if a coding agent process is running with that CWD. Ground truth: kill(pid, 0) + lsof for CWD verification.
How does it desync?
- Premature unlock: Daemon marks session stopped (via Arch violation: onSessionExit() marks status based on wrapper lifecycle, not process liveness #111 wrapper exit or Arch violation: reconcileAndEnrich() infers stopped status from adapter absence instead of probing truth #113 adapter absence) → lock released → another agent can launch in the same directory while the first is still running → concurrent writes, corruption.
- Stuck locks: Pending-* sessions that never resolve (Arch violation: Pending-* ID resolution is daemon-side state tracking that can create ghost sessions #114) have locks that can't be auto-cleaned because the daemon doesn't know their status.
- ID mismatch: When pending-* IDs are resolved to real UUIDs,
updateAutoLockSessionIdmust be called — but if the timing is wrong, the lock references a dead ID.
User-visible symptom
- Lock released while agent still running (potential concurrent directory access)
- Stuck locks requiring
agentctl lock releasemanual intervention --forcerequired to override locks on pending-* sessions
Proposed fix
Decouple locks from session IDs. Instead:
- Lock by PID+CWD: Store
{ directory, pid, lockedAt }instead of{ directory, sessionId } - PID-based cleanup: Check if the locking PID is alive. If dead, release the lock. No need to go through session state.
- Adapter-independent: Locks work regardless of whether session-tracker has correct state, pending-* resolution succeeds, etc.
This makes locks self-healing and independent of the session tracking layer's correctness.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels