Repository navigation
feat(claude-mod): run optional prompt before automatic compaction - #69
Merged
kunchenguid merged 7 commits intoOct 9, 2026
Merged
Conversation
Empty beforeCompactPrompt keeps automatic compaction immediate. A non-empty value, in confirmed auto mode, runs as one turn and compaction follows only if that turn ends in a settled answer. A leading slash is a command, because a plugin prompt does not expand slash commands and rejects text that starts with /.
A dispatched handoff that is abandoned before turn.start now treats the next plugin-origin turn as that submission and does not judge it. The live harness also runs a skill-backed command before compaction, and checks that a typed prompt while that turn is pending does not compact.
kunchenguid
approved these changes
Oct 9, 2026
kunchenguid
left a comment
Owner
There was a problem hiding this comment.
Speaking as Kun's firstmate.
contract-class: opt-in — beforeCompactPrompt defaults to ""; empty / hint / off leave today's compaction path. Only confirmed auto + a non-empty user setting runs the handoff.
VISION (per-rule):
- Timing question only: aligns (optional pre-step on the auto compact path; judge/hint unchanged).
- Advice for the person, never the model: aligns (hint channel unchanged; before-compact is user-configured command/prompt, not advice fed to the model).
- Measurement published: aligns (no judge/score change).
- Cost of being wrong: aligns (timeout / interrupt / error / non-settled turn → no compact).
- Accuracy entry price: aligns (judge untouched).
- One policy, several hosts: aligns (Claude-only host config; shared questions/score/floor unchanged; contract states that).
- What leaves the machine: aligns (no new telemetry; auto still needs explicit ack).
- Scope: aligns (not a summarizer/context manager;
/stowis the user's command).
Fork CI approved after diff review; no security risk. Green CI + CLEAN → squash-merging.
Owner
|
Speaking as Kun's firstmate: this is merged. Thank you @KaranSantra — really appreciate you taking the time on this. |
elkaix
added a commit
to elkaix/compact-adviser
that referenced
this pull request
Oct 15, 2026
Adopt upstream's before-compact prompt (kunchenguid#69) and context budget (kunchenguid#65) alongside this branch's re-ask gate and claude-mod hardening. - compactNow keeps the branch's compaction semantics (counter, stale-turn drop, re-ask gate on failure) and serves both the direct and the before-compact paths. - Budget helpers stay in the shared checkpoint.ts; budget "default" is no longer an alias for off, and a budget equal to the limit is ignored, as upstream decided.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
The ask, verbatim: "can you adjust compact-adviser auto to stow before runnign compactions?" and then "if you can this once this is done, send this as pr". On which account sends it: "yes use KaranSantra".
Context needed to read it: compact-adviser is a Claude Code plugin that, in auto mode, compacts the conversation by itself at a checkpoint its judge (TypeSafe Jev) scores as finished. Today it calls compaction directly. /stow is a skill meant to run before every compaction. Auto-compaction currently skips it. The PR goes to kunchenguid/compact-adviser from the KaranSantra fork.
Already decided, do not reopen: beforeCompactPrompt stays optional and empty by default, so other users without /stow keep today's compaction. A leading slash runs the user's own configured command. This follow-up only proves that path on the live harness and ignores a plugin turn that starts after the handoff was abandoned before it began.
What Changed
beforeCompactPromptsetting (empty by default) that, in confirmed auto mode, runs one turn before automatic compaction; a leading/is invoked as a slash command (e.g./stow) because Claude Code does not expand slash commands in plugin prompts.Risk Assessment
Testing
Plugin-host suite passed (134). Stock live e2e twice stalled on a request-logging toast flake before the new cases. A disposable focused live harness then drove real Claude Code 2.1.295 under tmux: confirmed auto through the settings pane, set beforeCompactPrompt=/marker and observed marker-then-summary with "automatic compaction completed: 70,040 to 1,519 tokens", and confirmed a typed interrupt during a held before-compact prompt produced no further compaction.
npm --prefix packages/claude-mod test); that is not a live product drive. Reproducing the post-dispatch pre-start abando…npm --prefix packages/claude-mod testempty-setting case); that is not a live product drive. The focused TUI harness onl…Evidence: Focused live before-compact run log
Evidence: Focused live result JSON (marker then summary, one compaction)
passed: auto confirmed; marker skill then compact; interrupt does not compact. liveEvents: [marker, summary]. summaries: 1Evidence: TUI screen after /marker then automatic compaction
❯ /marker → marker written → compact-adviser: automatic compaction completed: 70,040 to 1,519 tokens.Evidence: Event order proving skill before compaction
{"freshEvents":["marker","summary"],"summaries":1,"marker":"ran\n"}Evidence: TUI screen after interrupt during before-compact hold
Plugin before-compact prompt (MARKER_SKILL_E2E hold) answered; user typed "wait, one more thing"; no automatic compaction completed notice.Evidence: Interrupted path: summary count unchanged
{"summariesAtInterrupt":1,"summariesNow":1}Evidence: Claude mod plugin-host test log (before-compact suite)
Evidence: Stock live-e2e failure at request-logging toast
Follow-up notes
Empty
beforeCompactPromptkeeps today's behaviour. A leading/goes throughcommand.run, which runs any slash command the session already lists, including a user skill such as/stow, not only plugin-registered commands. Set the value to/stowto run that skill.VISION.md line 10 says the product never chooses what to keep, and line 16 says the hint is never used to steer the agent. This does not cross them: the prompt is the user's own opt-in text, not the hint, and the host's compaction still decides what to keep.
The API does not document when
$.command.runsettles for a skill-backed command such as/stow. A long-running skill is covered by the timeout and the turn-id checks, and the live harness now observes that path, but there is no separate assertion of the promise's settle time.npm run test:e2eon pinned Claude Code 2.1.275, with the session kill switch unset for the test child only: 13 live checks passed, including the marker skill running and then exactly one compaction, and a typed prompt while that turn was pending leaving the conversation uncompacted.Hook validation spelling, measured: Claude Code 2.1.275 prints
config.describe{key=compact-adviser.typesafeApiKey}unquoted; Claude Code 2.1.295 prints it quoted. Both forms stay.Follow-ups, not fixed here: the stock live harness can miss the request-logging toast on 2.1.295 even when the setting saved;
turn.starthas no origin field, so a handoff abandoned after dispatch skips judging the next completed turn rather than matching an origin.Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 1 issue found → auto-fixed ✅
packages/claude-mod/hooks/register.ts:904- The required behavior is to “ignore a plugin turn that starts after the handoff was abandoned before it began.” This new branch identifies that turn throughturn.start.origin, but accesses the field through a cast, and the new test supplies an origin explicitly rather than establishing that Claude Code supplies one. For a late/stowturn whose start event has no origin, the branch at 905 is skipped; after the retry expires, its completion reachessettleat 963 and can judge and dispatch/stowagain. Verify provenance on the pinned live host and make the handoff identification work with the event it actually emits. The remedy needs a host-supported way to identify the turn, so it requires the author's decision if that provenance is unavailable.🔧 Fix applied.
✅ Re-checked - no issues remain.
packages/claude-mod/scripts/live-e2e.mjs:428- Stocknpm run test:e2eon Claude Code 2.1.295 consistently fails at the request-logging pane step waiting for the toast "TypeSafe request logging on (all sessions)" even though the durable outcome is already visible (settings list shows "Log TypeSafe requests On" and options reload). Hot-reload after config.set appears to drop the toast before tmux capture can see it, so the harness never reaches the before-compact cases. Focused live driving that enables auto via the Mode row (durable signals only) and then exercises before-compact passed. CI pins 2.1.275; if that host still shows the toast the stock suite may stay green there. Optional harness hardening: accept pluginOptions().logRequests === true or the On label as success, not only the ephemeral toast.npm --prefix packages/claude-mod test); that is not a live product drive. Reproducing the post-dispatch pre-start abando…npm --prefix packages/claude-mod testempty-setting case); that is not a live product drive. The focused TUI harness onl…npm --prefix packages/claude-mod test(134 pass, including full before-compact prompt suite)npm --prefix packages/claude-mod run test:e2etwice (blocked at request-logging toast on Claude Code 2.1.295)node .../focused-before-compact-live.mjsagainst real Claude Code 2.1.295 under tmux: enable auto via pane, before-compact /marker then compact, interrupted before-compact does not compact✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.