Skip to content

Keep the warm comms session alive, confirm every prompt, and cut the Slack feed - #35

Merged
elitecoder merged 7 commits into
mainfrom
fix/comms-reliability
Sep 28, 2026
Merged

elitecoder merged 7 commits into
mainfrom
fix/comms-reliability

Conversation

@elitecoder

Copy link
Copy Markdown
Owner

Summary

Fixes the four comms problems diagnosed from the logs on 2026-09-27 and 2026-09-28.

  • The warm session kept getting killed and respawned. cmux's socket refuses connections for seconds to hours while macOS App Nap throttles it, and every refused cmux tree check read as "workspace gone." A check cmux doesn't answer now leaves the session alone. Only cmux saying the ref is unknown, or a successful workspace list without it, counts as gone, after up to three looks.
  • Prompts sat typed but unsent. Reproduced live: surface.send_key enter left a prompt unsent on a never-shown --focus false workspace, while a "\r" through surface.send_text submitted it at once. Every boot prompt and Slack message is now confirmed in the transcript, with extra Enter presses only while the prompt box still holds the daemon's marker. A spawn whose boot prompt never lands is closed instead of being declared ready, and the session is bound to the transcript that recorded its prompt, never the newest file.
  • Slack messages went unanswered. Messages that arrived while no session was up were dropped for good. They're now recorded and queued on disk on arrival, retried with backoff for up to 3 hours, and sent together once a session is up, with one "I'll answer as soon as it's back" note per outage. All spawns share one backoff, so retries can't bring back the 2026-09-14 respawn storm.
  • The channel got a robotic feed. About 1,530 automatic posts in 14 days, 16 of them real replies. The heartbeat now pages once per outage and posts once on recovery. Housekeeping ledger entries stay in the brief, a ledger pass posts at most 5 updates plus a summary, and a workspace gets at most one ping per 15 minutes unless it asks a real question. Posts lead with the workspace title and the agent's own question or last message, with refs at the end.

Also changed

  • agent_session.confirm_dir now uses Claude's real project-folder rule (every non-alphanumeric character becomes -). This also changes the pulse's dispatch check (bin/pulse.py:2116): dispatches into dotted paths such as .worktrees now look in the folder Claude actually writes. Plain paths are unchanged.
  • The retired in-process CommsSubsystem mirrors the new suppression and paging, and its unused heartbeat_dedup_sec setting is gone.
  • tests/conftest.py points CMUX_BIN at a binary that doesn't exist, so a test that misses a stub can't drive the real cmux.

Validation

  • Full suite: 2,936 passed, 1 skipped. The changed-code coverage gate (run_python_coverage.py + check_change_coverage.py --base personal/main) passes.
  • Live run against the real cmux on a separate comms instance: the spawn's boot prompt was confirmed and bound to the right transcript, liveness returned alive and gone correctly, a message submitted in 1.6 s, and a deliberately swallowed Enter was recovered by reading the real prompt box. The test workspace closed itself.
  • Two independent reviews (production logic; regressions and coverage) both returned CLEAR after their findings were fixed.
  • Not validated end to end: a real Slack reply, because that needs a message from you.

Known limits

  • The prompt-box check only understands Claude's box, so a Droid session gets one Enter press.
  • A multi-line Slack message is typed as-is, as before.
  • The heartbeat's "paged" state is in memory, so a daemon restart mid-outage pages once more.

🤖 Generated with Claude Code

elitecoder and others added 7 commits September 28, 2026 09:30
…d cut the Slack feed to messages worth reading

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…med replies, and housekeeping in the subsystem

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… messages on arrival, and clear sessions before feeding them

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… them from coverage

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… wait, and pin the page-retry window

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@elitecoder
elitecoder merged commit c55c8f8 into main Sep 28, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant