Fleet comms/session identity: watcher verification, per-agent session homes, wedge detection after binary updates #1295

Open
opened 2026-08-17 21:54:15 +00:00 by mos-dt-0 · 2 comments
Collaborator

Summary

Measured on sb-it-1-dt, 2026-08-17 (docs-seat incident): a non-orchestrator fleet session ended up holding and acting on other agents' context. Root cause is three mechanical gaps in comms delivery and session identity — not model behavior. Interim prose guardrails have landed in the user-owned ~/.mosaic/ contract tree (SOUL.md fleet boundaries, STANDARDS.md session identity + watcher hygiene); this issue tracks the mechanical fixes so the prose fences can retire.

The three gaps (all measured)

  1. Session files keyed by cwd, resumable by any process in that cwd. One ~/src/stack pi session file served three lives: a /goal-command dev conversation (Aug 10), the goals seat resumed onto it (Aug 13, gpt-5.6-sol turns), then 22 comms-watcher injections absorbed while the seat was wedged (Aug 17). pi --continue in a shared cwd resumes whatever ran there last.

  2. Comms watchers deliver by tmux session name with no identity verification. install-watcher.sh units target a session name; nothing verifies the pane's process is the intended agent. A renamed or reused session name silently reroutes mail. Watchers also kept injecting for hours into a seat answering nothing — no unread-backlog alarm. (Related known gotcha: delivery confirmation is runtime-glyph-dependent — E7.)

  3. No wedge detection after runtime binary updates. pi 0.84.1→0.84.2 was installed under live seats; in-memory seats fail on first provider switch (module layout mismatch: openai-completions adapter imports a symbol exported only by 0.84.2), every call dies with stopReason:"error" before spending a token, exit code still 0, and every liveness instrument (tmux flag, -icanon, foreground process, pane_alive) stays green. Third member of the dead-seat-passes-liveness family; first that passes the terminal check too.

Proposed mechanical fixes

  • Per-agent harness homes (see jarvis-brain docs/decisions/mosaic-stack/2026-08-17_mosaic-d-002_agent-home-profiles.md, Pending): sessions/transcripts/settings under ~/.mosaic/fleet/agents/<name>/, targeted config-dir env vars per harness (not literal HOME). Prototype already validated (~/.mosaic/fleet/agents/probe — auth-bundle symlink chain, per-agent sessions).
  • Watcher identity verification: before injecting, verify the target pane's process actually runs the named agent (read MOSAIC_AGENT_NAME from /proc/<pane_pid>/environ, or match the launch-ledger PID). Mismatch or unresolvable target → refuse delivery + alert, never type into a squatter.
  • Unread-backlog + wedge alarm: N consecutive injections with no assistant response = alert; repeated stopReason:"error" in the session file after a binary change = alert. Both derivable from existing artifacts (session JSONL, launch ledger).
  • Named sessions on seat launch: launcher passes --name <seat> (or equivalent) so resume is never cwd-ambiguous.

Longer term

Message queue + forced separation (planned) supersedes the watcher path entirely; the identity-verification and wedge-detection pieces remain valid regardless of transport.

## Summary Measured on sb-it-1-dt, 2026-08-17 (docs-seat incident): a non-orchestrator fleet session ended up holding and acting on other agents' context. Root cause is three mechanical gaps in comms delivery and session identity — not model behavior. Interim prose guardrails have landed in the user-owned `~/.mosaic/` contract tree (SOUL.md fleet boundaries, STANDARDS.md session identity + watcher hygiene); this issue tracks the mechanical fixes so the prose fences can retire. ## The three gaps (all measured) 1. **Session files keyed by cwd, resumable by any process in that cwd.** One `~/src/stack` pi session file served three lives: a `/goal`-command dev conversation (Aug 10), the goals seat resumed onto it (Aug 13, `gpt-5.6-sol` turns), then 22 comms-watcher injections absorbed while the seat was wedged (Aug 17). `pi --continue` in a shared cwd resumes whatever ran there last. 2. **Comms watchers deliver by tmux session name with no identity verification.** `install-watcher.sh` units target a session name; nothing verifies the pane's process is the intended agent. A renamed or reused session name silently reroutes mail. Watchers also kept injecting for hours into a seat answering nothing — no unread-backlog alarm. (Related known gotcha: delivery confirmation is runtime-glyph-dependent — E7.) 3. **No wedge detection after runtime binary updates.** pi 0.84.1→0.84.2 was installed under live seats; in-memory seats fail on first provider switch (module layout mismatch: openai-completions adapter imports a symbol exported only by 0.84.2), every call dies with `stopReason:"error"` before spending a token, exit code still 0, and every liveness instrument (tmux flag, -icanon, foreground process, pane_alive) stays green. Third member of the dead-seat-passes-liveness family; first that passes the terminal check too. ## Proposed mechanical fixes - **Per-agent harness homes** (see jarvis-brain `docs/decisions/mosaic-stack/2026-08-17_mosaic-d-002_agent-home-profiles.md`, Pending): sessions/transcripts/settings under `~/.mosaic/fleet/agents/<name>/`, targeted config-dir env vars per harness (not literal HOME). Prototype already validated (`~/.mosaic/fleet/agents/probe` — auth-bundle symlink chain, per-agent sessions). - **Watcher identity verification**: before injecting, verify the target pane's process actually runs the named agent (read `MOSAIC_AGENT_NAME` from `/proc/<pane_pid>/environ`, or match the launch-ledger PID). Mismatch or unresolvable target → refuse delivery + alert, never type into a squatter. - **Unread-backlog + wedge alarm**: N consecutive injections with no assistant response = alert; repeated `stopReason:"error"` in the session file after a binary change = alert. Both derivable from existing artifacts (session JSONL, launch ledger). - **Named sessions on seat launch**: launcher passes `--name <seat>` (or equivalent) so resume is never cwd-ambiguous. ## Longer term Message queue + forced separation (planned) supersedes the watcher path entirely; the identity-verification and wedge-detection pieces remain valid regardless of transport.
Author
Collaborator

Provisioning follow-up (from sb-it-1-dt hardening, same day): watcher setup should move into agent instantiation — mosaic agent --new (and fleet launch) should ensure the comms watcher user-service exists, is active, and targets the right session/socket, rather than leaving it to whoever remembers.

Interim implementation now lives in the brain repo: scripts/comms/ensure-watcher.sh — idempotent ensure (present+match=no-op; missing/inactive/drift=install or repair via the existing install-watcher.sh), a non-mutating --status mode for boot checks, and two interim identity warnings that directly cover the incident's failure modes:

  • target tmux session missing on the configured socket → WARN (delivering into nothing / name-follows-squatter risk)
  • target pane's process carries a different MOSAIC_AGENT_NAME (read from /proc/<child>/environ) → WARN (misrouting class); bare runtimes get a NOTE that identity is unverifiable until per-agent launches land

Documented as a fleet requirement in the user-owned ~/.mosaic/AGENTS.md ("Fleet Comms Watcher"): provisioned at instantiation, never a running agent's duty; boot check via --status. The framework-side move is: fold ensure semantics into mosaic agent --new/fleet launch + mosaic doctor (drift check), keeping the same contract.

**Provisioning follow-up (from sb-it-1-dt hardening, same day):** watcher setup should move into agent instantiation — `mosaic agent --new` (and fleet launch) should ensure the comms watcher user-service exists, is active, and targets the right session/socket, rather than leaving it to whoever remembers. Interim implementation now lives in the brain repo: `scripts/comms/ensure-watcher.sh` — idempotent ensure (present+match=no-op; missing/inactive/drift=install or repair via the existing `install-watcher.sh`), a non-mutating `--status` mode for boot checks, and two interim identity warnings that directly cover the incident's failure modes: - target tmux session missing on the configured socket → WARN (delivering into nothing / name-follows-squatter risk) - target pane's process carries a different `MOSAIC_AGENT_NAME` (read from `/proc/<child>/environ`) → WARN (misrouting class); bare runtimes get a NOTE that identity is unverifiable until per-agent launches land Documented as a fleet requirement in the user-owned `~/.mosaic/AGENTS.md` ("Fleet Comms Watcher"): provisioned at instantiation, never a running agent's duty; boot check via `--status`. The framework-side move is: fold ensure semantics into `mosaic agent --new`/fleet launch + `mosaic doctor` (drift check), keeping the same contract.
Author
Collaborator

Continuation record for tonight's follow-on work (fleet identity, comms delivery, ~/.mosaic tree preservation): scratchpads/2026-08-17-fleet-identity-comms-mosaic-tree.md, delivered via PR #1296 into next. It consolidates the decisions register (MOSAIC-D-001/-002 pending ruling in jarvis-brain, tooling-migration direction, provisioning-at-instantiation), the as-built ~/.mosaic inventory, and the sequenced work queue whose first item is the comms-tooling migration + unit regeneration.

Continuation record for tonight's follow-on work (fleet identity, comms delivery, ~/.mosaic tree preservation): scratchpads/2026-08-17-fleet-identity-comms-mosaic-tree.md, delivered via PR #1296 into next. It consolidates the decisions register (MOSAIC-D-001/-002 pending ruling in jarvis-brain, tooling-migration direction, provisioning-at-instantiation), the as-built ~/.mosaic inventory, and the sequenced work queue whose first item is the comms-tooling migration + unit regeneration.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#1295