[FEATURE] /compact <args>: the args are prompt-shaped but never run — session goes idle while the raw <command-args> block stays inert in the new context

Status Open
Reported on v2.1.273
Maintainer reply None cached
Activity 1 comment · opened Sep 16, 2026

Preflight Checklist

  • [x] I have searched existing requests and this hasn't been requested yet
  • [x] This is a single feature request

Problem Statement

/compact <text> accepts an argument, and the composer placeholder invites you to type into it. In practice a large share of what users type there is not a summarization hint — it is the next thing they want done. The session has just been compacted precisely because they are mid-task; the natural thing to type is "and now do X".

Today that text lands nowhere useful. It is:

  1. Never dispatched. Compaction finishes and the session goes idle. No turn starts.
  2. Still in the new context, verbatim, as a raw <command-args> block — inert, unlabelled, indistinguishable from a live request.

So the argument is in the worst of both states: it does not run, but it is still sitting there looking like a pending instruction. That second half has been filed three separate times as a hazard — #20370 and #55555 (post-compaction instance re-executes the args, in one report firing Write + git commit + git push and producing a duplicate handoff document) and #62138 (args treated as a topic redirect, silently overridden). All three were closed without a fix — two to inactivity, one as a duplicate of #50724, which was itself closed as not-planned.

The recurring theme across every one of those reports is the same: nothing in the system states whether /compact args are a summary hint or a follow-up instruction, so both users and the post-compaction model guess, and they guess differently.

Evidence

Claude Code 2.1.273, macOS. One long-running interactive session, 10 manual compactions, measured from its own JSONL.

In all 10, zero assistant turns occurred between the compact_boundary and the next manually typed user message. The session is idle 100% of the time after compaction.

3 of the 10 invocations carried non-empty <command-args>. All 3 were follow-up work instructions, not summary hints:

| /compact at | <command-args> (sanitized) | boundary | what happened next |
|---|---|---|---|
| 09-08T02:21:32Z | Reply from Codex: • Two draft PRs are ready: … (a pasted agent report) | 02:23:44Z | user re-pasted the same text at 02:24:04Z |
| 09-08T19:48:46Z | and also start planning and closing work to be done around those N cells … create stacked prs wherever needed. but the testing needs to be real | 19:51:00Z | user re-typed the same request at 19:51:00Z |
| 09-16T06:15:18Z | Okay, since <X> is merged, is there something that we need to move ahead with? I need you to work on that. | 06:17:47Z | idle 2m11s, then user typed a fresh prompt at 06:19:58Z |

Two of the three are verbatim re-sends seconds later — a direct receipt that the user believed the text was a prompt, watched nothing happen, and typed it again. The third is a 2-minute dead session.

The record for the third, from the JSONL, main thread only:

06:15:18  user/meta   <local-command-caveat>…
06:15:18  user        <command-name>/compact</command-name>
                      <command-args>Okay, since <X> is merged, … I need you to work on that.</command-args>
06:17:47  system      compact_boundary  {trigger:"manual", preTokens:821068, postTokens:15034, durationMs:148714}
06:17:47  user/SUMMARY This session is being continued from a previous conversation…
06:17:47  user        <local-command-stdout>Compacted…</local-command-stdout>
          ── no assistant turn ──
06:19:58  user        <a completely different prompt, typed by hand>

Note that the <command-args> block from 06:15:18 survives into the post-compaction context alongside the summary. That is the #20370 / #55555 hazard, still present in 2.1.273, three reports and eight months later.

Proposed Solution

Make the intent explicit at the point of typing, and honor it on the far side of the boundary.

1. /compact-then <prompt> (or an equivalent affordance) — compact, then run the prompt.

The argument is unambiguously a follow-up turn. After the boundary is written, the engine submits it the way $.prompt.submit already does: as a user turn that runs once the session is idle. This is the behavior users are already reaching for.

2. /compact <instructions> keeps its documented meaning — summary focus only — but stops leaking.

Once consumed by the summarizer, the <command-args> payload should not cross the boundary as raw prompt-shaped text. Strip it, or mark it consumed ([consumed by compaction]), so the post-compaction instance cannot mistake a spent hint for a live request. This is exactly the fix shape #55555 proposed and closes a hazard that has been reported three times.

3. Say which one the placeholder means.

The current placeholder (<optional custom summarization instructions>) is already documented as misleading in #43141. If both affordances exist, the placeholder should name the one you are in.

The plumbing appears to be entirely in place. Per the public plugin type declarations shipped in mods/types/claude-code.d.ts:

  • session.compact carries instructions — "What the summary should keep or stress: the text after /compact" — and trigger: 'manual' | 'auto' | 'plugin' | 'precompute'.
  • $.prompt.submit({ text }) — "Submits a prompt: the event prompt.submit, the same call the engine makes for a typed prompt; input.text runs when the session is idle."

A session.compact hook that awaits next(e) and then calls $.prompt.submit({ text: instructions }) on a non-skipped manual compaction is the whole mechanism. I have a working plugin doing exactly that and am happy to open it as a PR if a plugin is the preferred home — though the leak in (2) is core-side and a plugin cannot fix it.

Alternative Solutions

  • Type the prompt after compaction finishes. What everyone does today. Costs a 2–3 minute wait staring at an idle session, and the argument you already typed is wasted. Two of the three cases above are the user simply typing it twice.
  • PostCompact hook. Receives compact_summary, but classic hooks can only inject context — they cannot start a turn. Wrong instrument.
  • Put the follow-up in the compaction instructions and hope the summarizer's "Optional Next Step" section carries it. Unreliable, and #50724 documents the summarizer dropping the last unanswered user message outright.

Priority

High - Significant impact on productivity

Feature Category

Interactive mode (TUI)

Use Case Example

Long agentic session, context nearly full, a dependency just landed:

  1. Type /compact Okay, since <X> is merged, is there something we need to move ahead with? I need you to work on that.
  2. Compaction runs — 148 seconds in the measured case.
  3. Today: it finishes and stops. You come back, find an idle session, and retype your request. The text you typed is sitting in the model's context doing nothing.
  4. Proposed: the boundary is written, and the prompt you already typed runs against the fresh context. You walk away and come back to work in progress, which is the entire reason you compacted mid-task rather than at a natural break.

Additional Context

  • Prior reports of the leak half, all closed without a fix: #20370 (2.1.7), #55555 (2.1.121, explicit reproduction of #20370), #50724 (closed not-planned). Related: #62138 (/compact <args> as topic redirect, silently overridden), #43141 (placeholder is misleading), #23261 (/compact-next).
  • Reproduces on every one of 10 compactions in a single session on 2.1.273.
  • Measurements taken from the session's own JSONL (compact_boundary records and main-thread type:"user" / type:"assistant" entries, sidechains excluded). Paths, session ids, private repo identifiers and the full argument texts are sanitized above.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗