-
Notifications
You must be signed in to change notification settings - Fork 1
Closed
Description
What state is duplicated
Each adapter persists its own LaunchedSessionMeta JSON files alongside the adapter's native storage:
- Claude Code:
~/.claude/agentctl/sessions/<sessionId>.json - OpenCode:
~/.agentctl/opencode-sessions/<sessionId>.json - Codex:
~/.codex/agentctl/sessions/<sessionId>.json
These files contain: sessionId, pid, startTime, wrapperPid, cwd, model, prompt, launchedAt.
This creates three layers of state for a single session:
- Adapter native storage (ground truth)
- Adapter-level
LaunchedSessionMetafiles (shadow feat(phase-1): agent-ctl core + Claude Code adapter #1) - Daemon
state.jsonSessionRecord(shadow feat(openclaw): add OpenClaw gateway adapter #2, see Arch violation: Daemon state.json maintains full session registry that shadows adapter ground truth #110)
Where is the ground truth?
- PID → process liveness:
kill(pid, 0)andps auxwith start time cross-referencing - Session data: Adapter native files (JSONL, JSON session files)
- CWD mapping:
lsofon the actual process
How does it desync?
- Stale metadata accumulation: Currently
~/.agentctl/opencode-sessions/has 20+pending-*.jsonfiles for dead sessions. These files are only cleaned up duringisSessionRunning()checks — if nobody queries those sessions, they persist forever. - PID recycling false positives: Despite start-time cross-checking, the metadata can match a wrong process if the start time check fails (e.g., unparseable ps output, clock skew).
- Inconsistency with daemon state: The adapter meta may say a session is alive (PID exists) while daemon state.json says it's stopped (wrapper exited), or vice versa.
reconcileAndEnrich()tries to merge these, but the merge logic is complex and error-prone. - No TTL: Unlike adapter native files which are naturally scoped, these metadata files have no expiration mechanism.
User-visible symptom
- Ghost sessions in
agentctl listfrom stale metadata files - Inconsistent status between
agentctl list(daemon) andagentctl status <id>(adapter direct query) - Slow
discover()due to scanning metadata directories
Proposed fix
The LaunchedSessionMeta exists because adapters need PID information that isn't in their native storage (the adapter launched a detached process but the native session file doesn't record which PID is running it). The correct fix:
- Short-lived: Make metadata files self-cleaning with a hard TTL (e.g., 24h). If the process isn't alive after 24h, the metadata is definitely stale.
- Minimal: Only store the PID and process start time — drop cwd, model, prompt, launchedAt which duplicate adapter native data.
- Eventually: Explore whether adapters can determine PID association without agentctl's help (e.g., Claude Code's
--continueflag includes sessionId in args, making ps-based matching reliable).
Related: #110
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels