Skip to content

serve: a manual compact no longer blocks the session loop - #270

Merged
jaredLunde merged 1 commit into
mainfrom
jared/serve-compact-cancellable
Oct 16, 2026
Merged

jaredLunde merged 1 commit into
mainfrom
jared/serve-compact-cancellable

Conversation

@jaredLunde

Copy link
Copy Markdown
Contributor

Fixes serve audit defect #4 (HANG).

do_compact! selected only on the checkpoint channel and the compaction future. compaction_cancel was never cancelled, and input_rx and shutdown were never polled. So abort, get_state and SIGTERM all waited for the summary call, which can take up to the 600 s stream idle timeout. In the audit's repro, get_state and abort sent 700 ms in were answered only after the compact response, SIGTERM was honoured 7 s later, and get_state reported is_compacting:false throughout. A deferred compact (one that runs after the prompt it arrived during) behaved the same way.

Change. The compaction now runs inside a select shaped like the host-bash loop:

  • abort cancels compaction_cancel. The compaction ends unapplied and nothing on disk changes. The abort ack is sent after the compact response, the way a mid-run abort is acknowledged.
  • Shutdown and stdin EOF cancel the compaction and end the session. The macro now evaluates to whether the session goes on, and both call sites (idle and deferred) act on that.
  • get_state (is_compacting: true, message_count as it stands until the compaction lands), get_session_stats and get_messages are answered from a snapshot taken before the compaction starts.
  • MCP Events injections are deferred, mcp_events_* commands are dispatched, and every other command is refused as busy.

The macro moved below the shutdown/deferred_events/dispatch_events declarations it now uses. It keeps #265's BusyGuard: now that EOF cancels a compaction, the guard is what stops a reap or drain from cutting one short. Docs are updated in serve.rs's module doc and ARCHITECTURE.md (the is_compacting passage and the MCP Events deferral note).

Tests. crates/agent/tests/serve_compact_cancellable.rs (new). The summary call stalls 20 s:

  • abort_cancels_a_manual_compact_and_reads_are_answered_meanwhile: get_state is answered before compact with is_compacting:true. set_session_name gets a busy refusal. abort cancels the compaction in well under 5 s, and the transcript on disk is unchanged.
  • sigterm_ends_a_manual_compact_promptly: the process exits within 3 s of SIGTERM.

Both tests fail on the old code. #265's reaper_spares_a_detached_compact still passes. The agent and agent-core suites, clippy -D warnings, fmt and dprint all pass.

Side note, not changed here: the busy prompt loop's get_messages arm reads since from the prompt's cmd instead of the incoming c.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JimHGjsfk2Ktm5GxyZJKKk

`do_compact!` selected only the checkpoint channel and the compaction,
so `abort`, `get_state` and SIGTERM all waited for the summary call
(up to the 600 s stream idle timeout). It now runs inside a select
shaped like the host-bash loop: `abort` cancels the compaction (acked
after the `compact` response), shutdown and EOF cancel it and end the
session, `get_state` (`is_compacting: true`), `get_session_stats` and
`get_messages` are answered from a pre-compaction snapshot, MCP Events
injections are deferred, and anything else is refused as busy.

The macro moved below the shutdown/deferred-events declarations it now
uses, and evaluates to whether the session goes on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JimHGjsfk2Ktm5GxyZJKKk
@jaredLunde
jaredLunde enabled auto-merge October 16, 2026 07:42
@jaredLunde
jaredLunde added this pull request to the merge queue Oct 16, 2026
Merged via the queue into main with commit e0a15a4 Oct 16, 2026
13 checks passed
@jaredLunde
jaredLunde deleted the jared/serve-compact-cancellable branch October 16, 2026 08:07
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