Skip to content

Fix repeated steering and reliable stop#3903

Open
Quicksaver wants to merge 26 commits into
pingdotgg:mainfrom
Quicksaver:fix/repeated-steering-and-stop
Open

Fix repeated steering and reliable stop#3903
Quicksaver wants to merge 26 commits into
pingdotgg:mainfrom
Quicksaver:fix/repeated-steering-and-stop

Conversation

@Quicksaver

@Quicksaver Quicksaver commented Jul 12, 2026

Copy link
Copy Markdown

Summary

Allow users to send consecutive steering prompts while a conversation is running and reliably stop the active Codex turn after any number of steers. Steering dispatches clear as soon as the server projects the exact submitted user message, while root interruption resolves the provider's live active turn instead of relying on potentially stale projected state.

Explicit child-turn interruptions continue to target the requested child directly. Root lookup is bounded and failure-tolerant: failed or timed-out reads fall back to the cached active turn, while a successful read with no active turn suppresses a stale interrupt.

The workspace configuration also enables pnpm's global virtual store and makes the prerelease @effect/vitest package extension resolve vite-plus consistently.

What Changed

  • Track the expected user-message id for each local dispatch and acknowledge only that exact projected message.
  • Wire generated message ids through new-thread, follow-up, and in-turn steering send paths so the composer can re-enable after an acknowledged steer without waiting for a turn or session transition.
  • Resolve root Codex interruptions from a live thread/read request with turns included, selecting the newest in-progress turn by timestamp and falling back to provider response order when timestamps are absent.
  • Honor explicitly requested child turn ids directly without performing root active-turn lookup or fallback.
  • Bound active-turn lookup time, log lookup failures, and fall back to the cached session turn only when the lookup fails.
  • Suppress stale interrupts when a successful live lookup reports no active turn.
  • Add focused regression coverage for consecutive steering, exact-message acknowledgement, timestamp and response-order turn selection, timeout and failure fallback, and successful empty live reads.
  • Enable pnpm's global virtual store, correct the prerelease @effect/vitest package extension, and refresh the lockfile.

Why

Running conversations could leave the composer busy after steering because acknowledgement depended on turn or session transitions that do not occur for an in-turn steer. After steering, stop could also target a stale cached turn rather than the provider's actual active turn. Together, these behaviors prevented repeated steering and made interruption unreliable precisely when users needed it most.

The pnpm workspace update keeps dependency resolution stable across worktrees and ensures the patched Effect Vitest package receives the runtime dependency it imports.

Validation

  • pnpm exec vp test apps/web/src/components/ChatView.logic.test.ts apps/server/src/provider/Layers/CodexInterruptResolution.test.ts apps/server/src/orchestration/Layers/ProviderCommandReactor.test.ts (67 tests passed)

Proof

  • Automated regression coverage in the changed web and server test suites.

Note

Medium Risk
Touches live Codex interrupt resolution and composer dispatch acknowledgement in running sessions; behavior changes are covered by new tests but affect stop/steer UX on critical paths.

Overview
Improves in-turn steering and Codex stop so the composer and interrupt path stay aligned with what the server actually has.

Web: Local “sending” state now keys off an expectedUserMessageId for each dispatch instead of treating any new projected user message as acknowledgement. beginLocalDispatch runs after newMessageId() so the snapshot matches the outgoing message. While the session is running, acknowledgement clears only when that exact id appears in projected messages—supporting consecutive steers without waiting for a new turn, and ignoring unrelated user messages (e.g. another client).

Server: Root interruptTurn resolves the target via resolveCodexInterruptTurnId: live thread/read with includeTurns: true, pick the newest inProgress turn (timestamps, else provider order), 2s timeout, fallback to session activeTurnId only on lookup failure. A successful read with no active turn does not reuse a stale cached id. Explicit turnId still wins for child interrupts.

Also adds BRANCH_DETAILS.md, dedicated interrupt tests, migrates CodexSessionRuntime.test.ts to @effect/vitest, and tweaks pnpm (global virtual store, @effect/vitest / vite-plus resolution).

Reviewed by Cursor Bugbot for commit 31b31bc. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fix repeated steering and reliable stop by improving interrupt resolution and steer acknowledgement

  • Adds resolveCodexInterruptTurnId in CodexSessionRuntime.ts to perform a live provider thread read (with a 2-second timeout) to find the most recent in-progress turn before interrupting, falling back to the session's projected active turn only on failure or timeout.
  • Fixes steer acknowledgement in ChatView.logic.ts by tracking an exact expected user message id (expectedUserMessageId) instead of detecting any change to the latest user message, preventing premature or spurious acknowledgement of consecutive steers.
  • Updates ChatView.tsx so beginLocalDispatch is called only after the new message id is created, ensuring the composer waits for the server to project the exact expected id.
  • Behavioral Change: a successful interrupt lookup that finds no active turn now returns undefined instead of falling back to the stale session turn id.

Macroscope summarized 31b31bc.

- Resolve the provider runtime’s authoritative active Codex turn
- Treat projected steer messages as server dispatch acknowledgement
- Avoid stale root turn IDs when interrupting for steering
- Cover active-turn lookup and running-thread steer behavior
- Resolve active Codex turns from timed, observable thread reads
- Match projected steer acknowledgements to the dispatched message
- Add realistic regression coverage for interrupt and steer paths
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 215758a8-7a97-4ed2-b8b8-dcbffab2be2b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 12, 2026
Comment thread apps/server/src/provider/Layers/CodexSessionRuntime.ts
@macroscopeapp

macroscopeapp Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR changes runtime behavior for steering message acknowledgement and interrupt turn resolution, including new lookup logic with timeouts and fallbacks. These are significant changes to core interaction flows that warrant human verification.

You can customize Macroscope's approvability policy. Learn more.

- Fall back to provider response order when start times are absent
- Cover both mixed timestamp ordering cases
- Merge upstream/main through Android mobile support
- Keep Quicksaver Expo ownership in the mobile config
- Preserve repeated steering and live Codex interruption behavior
- Extract and test active turn ordering and interrupt fallbacks
Comment thread apps/mobile/app.config.ts
- Use the Quicksaver EAS project id for the OTA endpoint

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 06e38dc. Configure here.

Comment thread apps/mobile/app.config.ts Outdated
- Capture exact message acknowledgement and interrupt routing contracts
- Record Codex live-turn selection and fallback safeguards
- Reserve branch-specific web and server development ports
…ng-and-stop

# Conflicts:
#	apps/server/src/provider/Layers/CodexSessionRuntime.test.ts
#	apps/web/src/components/ChatView.logic.ts
#	apps/web/src/components/ChatView.tsx
- Match dispatched steering IDs across all projected user messages
- Read the session fallback only after live Codex lookup failures
- Cover multi-client steering and timeout races with regression tests
- Make timeout tests wait for the live lookup explicitly
- Clarify replacement and dispatch snapshot naming
- Scan projected messages from the latest entry first
- Record assessment fixes and review outcomes
- Update validation counts and branch divergence
- Document conflict-resolution guidance for web and Codex runtime changes
- Preserve dispatch-correlation and interruption-resolution coverage
- Enable the global virtual store
- Correct prerelease package extensions and refresh the lockfile
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant