Skip to content

feat: complete stateless daemon core — eliminate remaining shadow state#117

Merged
c-h- merged 2 commits intomainfrom
fix/stateless-daemon-core-v2
Mar 6, 2026
Merged

feat: complete stateless daemon core — eliminate remaining shadow state#117
c-h- merged 2 commits intomainfrom
fix/stateless-daemon-core-v2

Conversation

@c-h-
Copy link
Copy Markdown
Collaborator

@c-h- c-h- commented Mar 6, 2026

Architectural Inversion: Eliminate Shadow State (Round 2)

PR #52 started the stateless daemon work but state tracking crept back. This completes the elimination.

Changes (-3,171 / +230 lines)

  • Deleted SessionRecord status tracking — derive from PID liveness
  • Gutted session-tracker.ts — no daemon-side session registry
  • Removed state.json session persistence
  • Simplified all adapters — removed LaunchedSessionMeta, rely on adapter discovery + PID
  • Kept locks.json and fuses.json (agentctl-only concepts)

Design principle (AGENTS.md)

agentctl is a stateless orchestration layer. Ground truth lives in adapters. No shadow state.

All tests pass (468/468). Build clean. Lint clean.

Fixes #109, fixes #110, fixes #111, fixes #113

Implements ADR 004: Stateless Daemon Core.

- reconcileAndEnrich() detects sessions that disappear from adapter
  discover() results and marks them stopped + autoUnlock
- 30-second grace period for recently-launched sessions to avoid
  false positives from adapter discovery latency

- session.list handler now fans out discover() to all adapters in
  parallel with 5s per-adapter timeouts
- Merges results and enriches with daemon launch metadata (prompt,
  group, spec, cwd)
- session.status also fans out to adapters for fresh data
- Graceful degradation: failed adapters are skipped, partial results
  returned. Sessions from failed adapters fall back to launch metadata.

- Removed SessionTracker.poll(), reapStaleEntries(),
  validateAllSessions(), pruneDeadSessions(), pruneOldSessions(),
  listSessions(), activeCount(), startPolling(), stopPolling()
- Removed 5-second polling interval and all background state
  reconciliation
- Simplified StateManager usage to only persist launch metadata,
  locks, and fuses
- Added lightweight 30s PID liveness check for lock cleanup
  (startLaunchCleanup) — much cheaper than full adapter fan-out
- MetricsRegistry decoupled from SessionTracker; active session count
  updated on session.list calls
- session.prune kept for backward compat but now just runs PID
  liveness cleanup

- Adapters own session truth. Daemon owns what it launched.
- session.list = fan out adapter.discover() → merge → return
- No daemon-side session registry for listing
- Handle adapter failures gracefully (partial results, not errors)

Fixes #51

Co-Authored-By: Charlie Hulcher <charlie@kindo.ai>
@c-h- c-h- enabled auto-merge (squash) March 6, 2026 20:38
The afterEach cleanup races with fake-timer-driven writes; maxRetries
prevents ENOTEMPTY on CI.

Co-Authored-By: Charlie Hulcher <charlie@kindo.ai>
@c-h- c-h- merged commit 740eb32 into main Mar 6, 2026
1 check passed
c-h- pushed a commit that referenced this pull request Mar 10, 2026
Features:
- Phase 1 ACP adoption — Codex adapter via ACP transport (#127)
- Callback metadata + lifecycle webhooks (#123)
- ADR-001: adopt ACP as primary agent interface (#126)
- Stateless daemon core (#117)

Fixes:
- Eliminate pending- session IDs — resolve real ID at launch (#131)
- Webhook numeric exit_status + compatible HMAC headers (#128)
- Daemon env derivation at spawn time (#119)
- Binary resolve util update (#121)

Docs:
- Full documentation audit and alignment (#132)
c-h- added a commit that referenced this pull request Mar 10, 2026
Features:
- Phase 1 ACP adoption — Codex adapter via ACP transport (#127)
- Callback metadata + lifecycle webhooks (#123)
- ADR-001: adopt ACP as primary agent interface (#126)
- Stateless daemon core (#117)

Fixes:
- Eliminate pending- session IDs — resolve real ID at launch (#131)
- Webhook numeric exit_status + compatible HMAC headers (#128)
- Daemon env derivation at spawn time (#119)
- Binary resolve util update (#121)

Docs:
- Full documentation audit and alignment (#132)

Co-authored-by: Doink (OpenClaw) <charlie+doink@kindo.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment