agent-orchestrator/backend/internal/session
harshitsinghbhandari 11475fbc72 feat(observe): reaper for liveness probe + TickEscalations heartbeat (#9)
The reaper sits OUTSIDE the LCM's per-session serial loop. On every tick it:
1. Fires lcm.TickEscalations(now) — the duration-based escalation heartbeat
   a non-polling LCM cannot wake itself to drive.
2. Asks lcm.RunningSessions for the snapshot of sessions whose runtime axis is
   alive, then calls runtime.IsAlive(handle) per session via a RuntimeRegistry
   that dispatches by RuntimeHandle.RuntimeName (so a single reaper covers
   tmux + zellij side by side).
3. Reports any non-alive result back as a fact via ApplyRuntimeObservation —
   dead -> RuntimeProbeDead, probe error -> RuntimeProbeFailed (never
   collapsed to alive: failed probe ≠ dead, but it ≠ alive either). Steady-
   state alive is skipped so we don't churn the LCM with no-op load/diff work.

The reaper REPORTS facts; the LCM owns DECIDE (anti-flap Detecting quarantine,
terminal-session rules). The reaper never writes.

Open-question resolution: add RunningSessions(ctx) to ports.LifecycleManager
(option a). The Manager implements it via an injectable session lister
(Manager.WithSessionLister) so the LCM itself does not require a new
LifecycleStore method — Tom's store contract is untouched, daemon wiring (lane
#10) will inject the production lister at startup.

Scope: reaper goroutine + the minimum LCM seam. No activity ingest, no FS
watcher, no daemon wiring, no new schema fields, no store changes.
2026-05-29 22:10:29 +05:30
..
fakes_test.go feat(observe): reaper for liveness probe + TickEscalations heartbeat (#9) 2026-05-29 22:10:29 +05:30
manager.go fix: address LCM/SM review blockers R1, RA, R11, RB 2026-05-29 17:57:46 +05:30
manager_test.go fix: address LCM/SM review blockers R1, RA, R11, RB 2026-05-29 17:57:46 +05:30