fix(web): instructed compact runs without a bare compaction first#24008

merged9
main
takeover/20236-compact-instructions-r2
opened2d agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 1d ago

Fixes duplicate compaction when a resumed Claude thread sends /compact with instructions while the Compact chip is enabled.

Original description by @fixfon

With the Compact chip enabled on a resumed Claude thread, sending /compact with instructions queued a bare compaction before the instructed command. This could compact twice and lose the benefit of the supplied instructions.

Recognize /compact followed by whitespace as an explicit compaction request, so it bypasses automatic pre-send compaction. Ordinary messages retain their existing behavior.

Validation: 138 focused cases passed, including one retained regression case that fails with the original exact-match predicate. Web typecheck and format passed; scoped lint reported existing warnings. Independent Claude Opus and GPT-6.1 reviews approved the source.

Integrated proof used the actual web composer, orchestration, Claude SDK, and an offline stream-json CLI peer. A completed peer turn was created first, then its context usage was aged to enable the Compact chip. Each case started from the same stopped snapshot and the SDK launched with --resume. The peer reports synthetic compaction: this verifies transport and command sequencing, not real model summarization or authentic Claude transcript restoration. Web was exercised; no native Electron or mobile run is claimed.

CaseCommands received by the peer
Baseline, instructed compact/compact, then /compact keep the auth refactor notes
Reviewed head, instructed compact/compact keep the auth refactor notes only
Reviewed head, ordinary message/compact, then Continue reviewing the auth refactor notes.

Baseline precondition: Compact chip enabled with instructed command entered.

Baseline precondition: Compact chip enabled with instructed command entered

Reviewed head: one instructed compact command completed.

Reviewed head: one instructed compact command completed

Ordinary-message control: automatic compact then queued normal message.

Ordinary-message control: automatic compact then queued normal message

Sanitized command traces: baseline, reviewed head, ordinary-message control. The baseline screenshot shows the pre-send chip precondition; the trace establishes its two-command result.

Original contribution by @fixfon. Maintainer takeover: Claude Opus 5.5 for tests/review, Claude Fable 5.1 for implementation, GPT-6.1 for independent review; Claude Code and Codex harnesses.

Takeover

Retains @fixfon’s commits from #20236. Main moved submission into planComposerTurn; the same command-boundary guard is ported there. The existing dispatch regression test is expanded, and the single-caller helper is removed.

Evidence

Final head f2177590, merged main 4812dcad. Proof incomplete: all24 interaction recordings exist, but six wide settled-image comparisons require correction of an unrelated source-control card difference.

Fixture matrix. A1: instructed compact; C1: ordinary message; C2: bare uppercase; C3: command prefix; C4: Full then Compact; C5: Never then on-return.

Cell (CSS width/theme)Before recording
4812dcad
After recording
f2177590
Diff0DiffT16Proof status
A1-1440-darkA1-1440-dark-before.mp4A1-1440-dark-after.mp4A1-1440-dark-diff0.pngA1-1440-dark-diffT.pngUnverified: unmatched details card
A1-1440-lightA1-1440-light-before.mp4A1-1440-light-after.mp4A1-1440-light-diff0.pngA1-1440-light-diffT.pngUnverified: unmatched details card
A1-390-darkA1-390-dark-before.mp4A1-390-dark-after.mp4A1-390-dark-diff0.pngA1-390-dark-diffT.pngInteraction captured; audit below
A1-390-lightA1-390-light-before.mp4A1-390-light-after.mp4A1-390-light-diff0.pngA1-390-light-diffT.pngInteraction captured; audit below
C1-1440-darkC1-1440-dark-before.mp4C1-1440-dark-after.mp4Upload pendingUpload pendingUnverified: unmatched details card
C1-1440-lightC1-1440-light-before.mp4Upload pendingUpload pendingUpload pendingUnverified: unmatched details card
C1-390-darkC1-390-dark-before.mp4C1-390-dark-after.mp4C1-390-dark-diff0.pngUpload pendingInteraction captured; audit below
C1-390-lightC1-390-light-before.mp4Upload pendingUpload pendingUpload pendingInteraction captured; audit below
C2-1440-lightC2-1440-light-before.mp4Upload pendingUpload pendingUpload pendingUnverified: unmatched details card
C3-390-darkC3-390-dark-before.mp4Upload pendingUpload pendingUpload pendingInteraction captured; audit below

|C4-390-light|C4-390-light-before.mp4|C4-390-light-after.mp4|C4-390-light-diff0.png|C4-390-light-diffT.png|Interaction captured; audit below| |C5-1440-dark|C5-1440-dark-before.mp4|C5-1440-dark-after.mp4|C5-1440-dark-diff0.png|C5-1440-dark-diffT.png|Unverified: unmatched details card|

Environment: T3 browser preview, responsive web, CSS1440×900 or390×900, light/dark, DPR2, default font scaling. Whole-surface wide video2880×1800 and preview still1280×800; narrow780×1800. Same immutable synthetic seed and frozen browser clock. Independent stills≥550ms apart settle exactly. Unmasked diffs highlight threshold0 and max-channel delta>16.

What else changed: A1 removes the bare predecessor and its timeline entry. Wide captures also show source-control card status from temporary baseline file swaps (Commit & push/+0−0 versus Commit/+20−9). That unrelated difference is not accepted as matched comparison proof; closed-card retakes remain incomplete. The continuous videos retain their original pixels and prove interactions with this difference disclosed. Offline peer proves sequencing and resumed transport, not real Claude summarization, restoration, billing, or parser acceptance.

Verification log

Tests45→45 in apps/web/src/components/ChatView.logic.test.ts; current base regression1 failed/44 passed, final45 passed. Scoped lint, format and web typecheck passed; final CI Build and Typecheck successful. Final tests.

Three fresh dual-review rounds returned MERGE/MERGE, no confirmed source defects; final merged-head review. Fixed anchored regex has constant work and no backtracking risk. CI29/29 successful on final f2177590; GitCafe reports mergeable/current conflict check, no actionable bot findings.

Final proof audit: INSUFFICIENT; Final independent audit and row verdicts. Independent A1 rebuild sent only the instructed command and reached idle, but its two stills differed by509 pixels and failed temporal settling, so its pixel comparison is unverified. Capture index/bundle: Public artifact index · Reproducible fixture/evidence bundle. Earlier c218a805 SUFFICIENT audit does not certify this final merge head.

Unverified web cells: A1-1440-light, A1-1440-dark, C1-1440-light, C1-1440-dark, C2-1440-light, C5-1440-dark need matched settled-image pairs and regenerated diffs. No Electron/mobile native capture claimed; changed surface is web. Real Claude summaries/restoration and remote/tunnel behavior are outside the sequencing claim.

Models/harnesses: Claude Opus5.5 through Claude Code for tests, implementation, reviewerB; GPT-6.1-sol through Codex for reviewerA, capture and proof audit.

### Completed evidence supplement — final pinned head

VERDICT: SUFFICIENT. This append supersedes the historical “Proof incomplete”, “INSUFFICIENT”, “Unverified” wide-cell statuses, pending links, rejected old wide diffs and failed independent rebuild above, plus the index’s pending independent-audit status. Historical records remain unchanged; the old mismatched wide diffs remain rejected and are replaced by the matched pairs below.

Independent audit and all row verdicts · Audit manifest · Independent rebuild proof.

Consolidated evidence index: all stills, diffs and recordings · Consolidated matrix · Scripts, fixtures and captures bundle.

6/6 missing wide pairs complete; 6/6 accepted narrow cells and all 24 recordings reused unchanged; all 12 visual cells audited sufficient. L1/S1 retain prior accepted records, without fresh tests or source review. No unverified rows remain within the synthetic responsive-web sequencing scope. The auditor played all 24 recordings completely and checked their narrated steps against sanitized command/resume traces. Historical wide recordings prove sequencing only and retain their disclosed card mismatch; replacement stills establish matched visual parity. C5 stills show Never opt-out; reused recordings show restoration to When you return and the subsequent automatic-predecessor send.

The six new wide pairs run the entire base 4812dca (merge-base of final head) versus the entire exact head f217759. Reused 390px cells and recordings retain the disclosed changed-file baseline substitution method; they are not full-base runtime evidence.

New capture environment: Chromium 148.0.7778.96, Linux x86_64, 1440×900 CSS, DPR2, 2880×1800 PNG, desktop emulation, normal font scaling, en-US/UTC, reduced motion, frozen browser Date 2026-10-23T12:00Z, fonts loaded and network idle, matching scroll/sidebar/details states. All new sides settle exactly; old 390px cells are unchanged. Independent A1 wide-light head frames 1143ms apart have zero temporal differing pixels; rebuild versus delivered has 0 pixels >0, 0 pixels >16, maximum channel 0. No masks or pixel-difference waivers.

A1 removes the duplicate bare command/boundary, moves the instructed row up and changes the minimap only to reflect the shorter timeline. The other four new wide control pairs have zero differing pixels at threshold zero. No unrelated visual differences were found.

Before: bare compaction followed by instructed compaction After: instructed compaction without the preceding bare compaction

Scope: offline synthetic peer proves actual web composer/server/Claude SDK command sequencing and resumed transport. It does not prove actual Claude summarization, transcript restoration, billing, parser internals, native desktop/mobile, remote or tunnel behavior; fixture notices, token counts and responses are synthetic. No new source review or tests are claimed by this evidence update.

Models/harness: GPT-6.1-sol through Codex for capture and independent proof audit.

Checks

All checks passed

Added 7 commits

  • test(web): cover /compact instructions in the composer dispatch plan111533a
  • merge: port compact instruction guard to current composer dispatch1470744
  • fix(web): /compact with instructions no longer runs a bare compaction first48664ff
  • Merge remote-tracking branch 'origin/main' into takeover/202365693af5
  • refactor(web): inline the /compact guard into planComposerTurn8c1c6be
  • fix(web): /compact with instructions is the only compaction while the Compact chip is onde326a8
  • Merge remote-tracking branch 'origin/main' into takeover/20236eceb2ca
Synced from GitHub

Approvability

Verdict: Approved at 8c1c6be

Macroscope's review found this PR approvable — This is a narrowly scoped web composer bug fix that prevents instructed /compact commands from triggering an unintended extra bare compaction. The production logic change is isolated and accompanied by focused tests for command boundaries and existing behavior.

No code changes detected at f217759. Prior analysis still applies.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
📥 Commits

Reviewing files that changed from the base of the PR and between 807319c276c6831b2c219640e9da5b38019a8f1d and 8c1c6be60b9cd7b5d77f784db097f0e5d7ab4e5d.

📒 Files selected for processing: 2
  • apps/web/src/components/ChatView.logic.test.ts
  • apps/web/src/components/ChatView.logic.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

📝 Walkthrough

The composer now skips pre-send compaction when a trimmed message starts with /compact followed by whitespace or the end of the message, regardless of case. Tests cover command variants and ordinary text.

Changes: Compact command handling

Layer / File(s)Summary
Detect compact commands
apps/web/src/components/ChatView.logic.ts, apps/web/src/components/ChatView.logic.test.ts
A case-insensitive pattern matches /compact followed by whitespace or the end of the message. compactBeforeSend uses the pattern, and tests cover matching commands and ordinary text.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested labels: bugfix, size:S

Suggested reviewers: t3dotgg, macroscopeapp

Merge Risk: ⚪ Minimal · up to 8c1c6

No actionable merge-blocking risk remains in the reviewed change.

Pre-merge checks: Passed 3 · Failed 1

Failed Failed checks: 1 warning

Check nameStatusExplanationResolution
Description checkWarningThe description states the problem (duplicate compaction when a resumed Claude thread sends /compact with instructions while the Compact chip is enabled) and the approach (treat /compact followed …1. Add the Scope and approval link: reference the triaged bug issue or the maintainer discussion that approved this direction and scope, including the approval comment. Alternatively, explain why this qualifies as a very small, focused fix …
Passed Passed checks: 3 passed
Check nameStatusExplanation
Title checkPassedThe title is concise, conventional, and clearly identifies the primary fix: instructed /compact commands no longer trigger an extra bare compaction.
Linked Issues checkPassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes checkPassedCheck skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description states the problem (duplicate compaction when a resumed Claude thread sends /compact with instructions while the Compact chip is enabled) and the approach (treat /compact followed by whitespace as an explicit request that bypasses automatic pre-send compaction). It gives validation results, an offline integrated proof with command traces, and a takeover/provenance section. Its Problem and Change content is clear. The template's Scope and approval section is not satisfied: it does not link a triaged bug issue or a maintainer-approved discussion, and it does not explain a small-fix exemption. It links PR #20236 as the original contribution but gives no approval comment. The Verification section is very long and partly contradictory. It starts with 'Proof incomplete', then adds a 'Completed evidence supplement' that declares SUFFICIENT and supersedes the earlier statuses. Many links point to unverifiable external artifacts. The description also includes unrelated-looking material, such as a source-control card difference and a long fixture matrix, which makes it hard to review. The template also asks for a model and harness attribution, and the description provides one.

Resolution

  1. Add the Scope and approval link: reference the triaged bug issue or the maintainer discussion that approved this direction and scope, including the approval comment. Alternatively, explain why this qualifies as a very small, focused fix of an obvious bug without a prior issue. 2. Consolidate the Verification section into one current account. Remove the contradictory 'Proof incomplete' and 'INSUFFICIENT' statements, or clearly separate them from the final state, so a reviewer sees one verdict. 3. State the exact tests run and their observed results for the final head in the Verification section, for example the 45 planner tests and the regression case, in one place. 4. Keep the description to one underlying problem. Move the unrelated source-control card observations out of the description or into a separate note. 5. Confirm that all linked evidence is accessible, and state what was not checked, such as native Electron and mobile runs. The template's model and harness attribution is already present; keep it.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

Added 2 commits

  • Merge remote-tracking branch 'origin/main' into takeover/20236-compact-instructions-r2c218a80
  • Merge remote-tracking branch 'origin/main' into takeover/20236-compact-instructions-r2f217759