Skip to content

fix: claude attach lost-session recovery on server restart#529

Merged
danshapiro merged 4 commits into
mainfrom
fix/claude-attach-lost-session
Jul 25, 2026
Merged

fix: claude attach lost-session recovery on server restart#529
danshapiro merged 4 commits into
mainfrom
fix/claude-attach-lost-session

Conversation

@danshapiro

Copy link
Copy Markdown
Owner

Rust server now answers freshclaude/kilroy freshAgent.attach for untracked sessions with an INVALID_SESSION_ID lost-session frame instead of silently swallowing it.

Allows client's existing recovery machinery to re-create/resume the session, preventing BUSY panes from wedging after server restart.

Tests: 3 unit + 2 e2e WebSocket tests.

Part of restart-resilience campaign (docs/plans/2026-07-24-restart-resilience-architecture-analysis.md).

codex and others added 4 commits July 24, 2026 12:39
…ost-session plan

- correct WsState literal field count (24 -> 26, per harness inspection)
- correct claude.rs broadcast() citation (~140 -> ~148)
- reword tests/common convention citation to the verified claim
- record validated findings + accepted residual risks (tracked->silence
  safety, real-frame serde parse, recovery semantics, pre-existing
  markSessionLost throw / cross-client dedupe / hidden-pane gaps)
…session frame for untracked sessions

🤖 Generated with Amplifier

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
@danshapiro
danshapiro merged commit 2f5bd47 into main Jul 25, 2026
1 check passed
pull Bot pushed a commit to HinchK/freshell that referenced this pull request Jul 26, 2026
…ame only on positive denial)

Rewrite FreshClaudeState::handle_attach around the restart-parity decision
table: tracked => no-op; no canonical durable id => lost frame (unchanged
PR danshapiro#529 fallback); durable already indexed => no-op; transcript present in
any candidate root => spawn a sidecar with resumeSessionId (original cwd
from the transcript per ledger A15, falling back to path-based resume when
that cwd is gone), register under the CLIENT's session id, and emit the
idle freshAgent.session.snapshot whose timelineSessionId is the durable
UUID; transcript absent everywhere => lost frame (positive denial only);
spawn/pipe/created failure => top-level error CLAUDE_ATTACH_RESUME_FAILED,
never the lost frame. Single-flight per durable id via the new resuming
set. Consumes claude_snapshot::transcript_cwd (dead_code allow removed).

WS-level proof added to freshagent_claude_attach.rs with a resume-flavored
fake sidecar (created + sdk.session.init echoing resumeSessionId +
sdk.status idle) and a seeded CLAUDE_CONFIG_DIR transcript store.

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
pull Bot pushed a commit to HinchK/freshell that referenced this pull request Jul 26, 2026
…A4xA2)

Cross-lane interaction: freshclaude-restart-parity (A2) adds a
restart-parity attach arm (claude.rs handle_attach decision table) that
resumes an untracked session IN PLACE when the attach carries a durable
UUID and the transcript exists. On the A4 lane alone (pre-parity
fallback danshapiro#529) the server round-tripped INVALID_SESSION_ID and recovery
was proven by a CHANGED createRequestId via the client's .lost
re-create; in the merged tree that discriminator can never fire for a
claude pane with durable identity.

New combined-tree evidence, verified against a live run:
- pre-restart: poll for the durable UUID on the pane (deterministic
  attach identity)
- post-restart WITHOUT reveal: usable status AND server-side resume
  proof from the sidecar request log (FAKE_CLAUDE_SIDECAR_LOG create
  with resumeSessionId = durable UUID or its transcript .jsonl path --
  the log previously pointed at FAKE_CLAUDE_ARGV_LOG, which the sidecar
  never writes)
- createRequestId asserted STABLE: the .lost re-create fallback must
  not fire (no duplicate-create storm)

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
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.

2 participants