Repository navigation
fix(claude): report a timed-out first-party rollback as incomplete - #7781
Conversation
A single microtask yield depended on the current await count; draining queued microtasks with setImmediate keeps the assertions meaningful if later code adds awaits (CodeRabbit review on #7777).
Review r2 F3: startup migration and Desktop first-party removals rewrite the credential-bearing Claude settings file synchronously after an await. A CLAUDE_CONFIG_DIR nested in the opencodex home shares the config-root ACL flight, so gate the migration and every removal through withConfigDirHardeningSettled on the Claude settings home (removeDesktopFirstPartySettled maps a settle timeout to the existing unreadable refusal without writing). Regressions: nested-home migration and settled removal, red without the barrier, green with it.
Review r3 F4: POST /api/claude-code/model-defaults rewrites Claude settings, its staged file and recovery backups synchronously after the body await; gate the whole operation through withConfigDirHardeningSettled(claudeConfigDir()) inside the existing failure mapping. N1: the gateway-apply cleanup refusal no longer claims a JSON parse failure. Also asserts that the startup migration actually rewrites the stale proxy URL (CodeRabbit). Regression: model-defaults POST with a held parent flight, red without the barrier.
Rollback admission after #7777 threw WindowsSecretAclSettleTimeoutError on a settle timeout, escaping the existing 'rollback did not complete' responses. rollbackDesktopFirstPartySettled returns false instead. Also adds a barrier-entry handshake to the model-defaults POST test.
…-rollback-timeout # Conflicts: # src/claude/desktop-first-party.ts # src/cli/claude-desktop.ts # src/server/management/agent-settings-routes.ts # src/server/management/native-integration-routes.ts # tests/claude-integration/claude-intercept-acl-barrier.test.ts
|
Post-release: this lands after v2.93.0 is published on main (release freeze). Do not merge before then. |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Important Review skippedReview was skipped as selected files did not have any reviewable changes.
|
| Layer / File(s) | Summary |
|---|---|
Settled rollback helper src/claude/desktop-first-party.ts (lines 245–257) |
Adds a helper that returns the rollback result, returns false on WindowsSecretAclSettleTimeoutError, and rethrows other errors. |
Rollback paths and tests src/cli/claude-desktop.ts (lines 23, 437), src/server/management/agent-settings-routes.ts (lines 1065, 1108, 1127), src/server/management/native-integration-routes.ts (lines 34, 53, 771), tests/claude-integration/claude-intercept-acl-barrier.test.ts (lines 23, 540–570) |
The CLI and two management routes use the helper for rollback. Tests cover timeout, error propagation, successful admission, and waiting for entry into the hardening barrier. |
Priority:
Estimated code review effort: 2 (Simple) | ~10 minutes
Change: Bug fix
Suggested reviewers: luvs01
Merge Risk: 
Minimal · previous review 8df35
-
No code issue identified prevents merge after normal checks. Honor the stated v2.93.0 release sequencing.
Pre-merge checks: 
4 · 
1
-
Failed checks: 1 warning Passed checks: 4 passed -
Finishing Touches: 💡 1
-
📝 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
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.
Comment @coderabbitai help to get the list of available commands.
|
✅ Deterministic PR hygiene checks passed. |
…-rollback-timeout
Maintainer integration decision: MERGE (squash) into devv2.93.0 is published on main (release captain confirmed; Head aa6e468 = 8df35b0 + dev 736fa50 (clean merge). dev has not moved since. Review. Independent sol review
None of these saves the mode marker, and each releases its lock. No other rollback or restore caller has the same problem. The reviewer showed both tests fail when either fix is removed. CI on the exact head: PR CI all 27 checks green; lane=all workflow_dispatch run 40468314480, 28 jobs green (Windows 1–9/9, macOS, Linux). Local (pinned Bun 1.4.4): |
Summary
After #7777, the three Claude Desktop first-party rollback sites wait for overlapping ACL work through
withConfigDirHardeningSettled. When that wait hits its deadline it throws, so the rollback skipped the existing "first-party settings rollback did not complete" response and fell into the generic error path. In the management route that was a 400 with an unrelated message. The settings left on disk were the same either way; only the reported error was wrong.rollbackDesktopFirstPartySettledinsrc/claude/desktop-first-party.tsnow returnsfalseon a settle timeout without running the rollback, and rethrows any other error. It is used at all three sites:src/server/management/agent-settings-routes.ts(POST /api/claude-desktop/apply)src/server/management/native-integration-routes.ts(PUT /api/native-integrations/claude-desktop)src/cli/claude-desktop.ts(offlineocx claude-desktopapply)The model-defaults POST barrier test also gains a barrier-entry handshake, so it proves the request is held at the barrier rather than relying on a single macrotask.
Both items come from CodeRabbit on #7777 (review 5660614984 and thread r4383732541). They were moved here so #7777 could merge at its reviewed head for the v2.93.0 release gate. This PR lands after v2.93.0 is published on main.
Verification
Pinned Bun 1.4.4,
OCX_TEST_NO_QUEUE=1:bun test --isolate --timeout 60000 tests/claude-integration/claude-intercept-acl-barrier.test.ts: 30 pass, 0 fail. This includes the new testsettled first-party rollback reports a settle timeout as incomplete without running, which also covers rethrowing a non-timeout error and the normal path.bun node_modules/typescript/bin/tsc --noEmit: pass.git diff --check: pass.NOT RUN: full suite, lane=all, a route-level replay of a timed-out rollback. Hosted PR CI pending.
Checklist
Summary by CodeRabbit