Conversation
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a focused fix that queues follow-up messages only when compaction or another native maintenance run cannot accept steering, with corresponding web and mobile UI updates. Normal dispatch behavior and configured follow-up defaults remain unchanged, and the server and client paths are covered by targeted tests. You can add or adjust custom eligibility rules. Learn more. |
|
Triaged the four failing checks; none are caused by this diff. Both reproduce identically on the pristine base commit (upstream/t3code/codex-turn-mapping at 37671bd), verified locally:
Everything else is green, including the Macroscope correctness check. Happy to help port a fix for either pre-existing failure if useful. |
|
On the Macroscope approvability note about |
61a3501 to
619623f
Compare
|
Macroscope has since reviewed this pull request. An earlier review was skipped by a cost limit; a review has now completed, so that notice no longer applies. |
f4f6dcf to
0811501
Compare
|
Status after rebasing onto the canonical tip (081150145c7 + b37034d563f):
|
a1f8051 to
0337dd6
Compare
b37034d to
be4ef15
Compare
be4ef15 to
65d0637
Compare
|
Rebased onto One follow-up commit on top (
Verified: Left for a maintainer: the silent-downgrade question above. Rebased and touched up by a maintainer's agent; a human will re-review. |
|
Answering the flagged silent-downgrade question with a concrete recommendation: keep it, for four reasons.
If a maintainer would rather see the explicit error preserved for structured steer requests, the narrow alternative is to downgrade only |
|
@juliusmarminge we're making the call rather than leaving it open: the silent downgrade stays. The four reasons are in my previous comment (dead-end rejection, the queue default already delivers this send as a queued run, queued runs stay reorderable/cancellable/promotable, logout parity), and the policy comment now states the decision instead of deferring it — that's commit Rereview when you get a chance? Happy to switch to the |
8039d4b to
c361947
Compare
6ca6a24 to
3e4ca4c
Compare
1bd44f2 to
3b9c885
Compare
c361947 to
5353024
Compare
There was a problem hiding this comment.
All clear
Posted via Macroscope — UI Consistency
This comment has been minimized.
This comment has been minimized.
fe4f6ad to
87c67bd
Compare
91516fc to
84baf27
Compare
…mpaction messages is non-optional on the thread projection, so drop the optional chain and give the CommandPolicy test fixture a messages array instead. Mobile now folds isCompacting into canSteerActiveTurn so its send label and dispatch mode queue behind a compaction run, matching web. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
8b755c2 to
e4fd9d0
Compare
What Changed
A message sent while a context-compaction run is in flight now queues behind it instead of failing:
orchestration-v2): when a steer or restart decision targets a run whose user message is a native maintenance command (/compact,/logout),resolveMessageDispatchIntentdowngrades it toqueue_after_activeinstead of letting delivery fail indispatchSteerIntoRun. The maintenance-command predicate moves toCommandPolicy.tsso the decision and its guard share one definition; the existing rejection stays as the backstop for explicit promote-to-steer.ChatView's existingisCompactingsignal now reaches the composer dispatch seam. While the active turn is compacting, the primary send delivers asqueueregardless of the configured follow-up behavior, the button reads "Queue message", and the tooltip drops the Ctrl/⌘-steer hint (the alternate is also queue, since steering a compaction is not possible). Shared resolver change lives inclient-runtimeso web and mobile agree on the meaning.Why
Compact takes 30-60s on real threads, and the natural next move is to type the follow-up while it runs. That follow-up used to die: Enter resolved to steer (the pre-queue default, or a configured steer follow-up), and the decider rejects steering into a maintenance run with "Wait for context compaction to finish before steering the thread." With the queue follow-up default the same send already worked, so the steer path was the only dead end. Queueing behind compaction is strictly better than a rejected send, and the server-side downgrade covers every client, including ones that do not resolve dispatch context server-side.
UI Changes
Both takes: web client, Claude Fable 5.1, 1280×800, follow-up behavior set to "steer" to exercise the failing path. The user types the follow-up first, clicks the context meter, clicks "Compact context", then sends while compaction runs.
Before (base) — during compaction, send resolves to steer and bounces with an error toast; the draft is restored but nothing is sent:
After (candidate) — during compaction the send button reads "Queue message"; the message queues behind the compaction run and starts automatically when compaction completes:
Detail crops of the two deciding moments:
Verification
Bot follow-up on
8b755c2939:vp test run apps/server/src/orchestration-v2/CommandPolicy.test.ts apps/server/src/orchestration-v2/ThreadLaunchService.test.ts— 63 tests passed;pnpm run typecheckinapps/serverpassed./logoutmatching is case-sensitive;/compactremains case-insensitive.Restack verification on
9fcc9a4bdb:vp test run apps/server/src/orchestration-v2/ThreadLaunchService.test.ts apps/server/src/orchestration-v2/CommandPolicy.test.ts packages/client-runtime/src/state/composerDispatch.test.ts apps/server/src/orchestration-v2/SteeringCompletion.integration.test.ts apps/server/src/orchestration-v2/QueuedRunOrder.test.ts apps/web/src/session-logic.test.ts apps/web/src/composer-logic.test.ts apps/mobile/src/features/threads/composerSendPresentation.test.ts— 213 tests passed across 8 files.pnpm run typecheckinapps/server,apps/web,apps/mobile, andpackages/client-runtime— passed.Live end-to-end pass in a real web client against both revisions (Claude, real compaction, DOM-asserted outcomes): base shows the rejection toast and keeps the draft; candidate flips the button to "Queue message", queues the run, and the queued message starts automatically after "Context compacted 27.3K → 3.60K tokens". The recordings above are those sessions; I inspected the deciding states programmatically (button labels, toast text, queued row) rather than by eye.
apps/mobilejoins web:useThreadComposerStatefolds the compaction state into its steering check, so the mobile send label and dispatch mode also queue behind a compaction run.Boundaries: promoting a queued message with "Steer now" while compaction runs still reports the wait error; the queued message delivers when compaction finishes either way.