Skip to content

Fix Codex TUI goal proxy handling#462

Merged
ndycode merged 4 commits into
mainfrom
fix/goals-tui-proxy
May 1, 2026
Merged

Fix Codex TUI goal proxy handling#462
ndycode merged 4 commits into
mainfrom
fix/goals-tui-proxy

Conversation

@ndycode

@ndycode ndycode commented May 1, 2026

Copy link
Copy Markdown
Owner

Summary:

  • Proxy Codex thread goal get/set requests through runtime rotation with managed account auth.
  • Provide a bounded local thread-goal fallback for upstream 403 storage blocks, keyed by thread/session identity and rejecting anonymous fallback state.
  • Keep response storage enabled in runtime shadow config so the TUI can read thread goals.
  • Move runtime shadow homes under the real Codex home and hard-link SQLite state files instead of copying active DB files.
  • Keep failed TUI/app helper cleanup strict so helpers are not detached after non-zero or signal exits.

Risk notes:

  • Runtime rotation now accepts Codex thread goal routes in addition to responses and model discovery.
  • Thread-goal fallback state is in-memory, bounded, and scoped to the proxy process.
  • SQLite shadow-home materialization now refuses copy fallback if hard-linking fails, avoiding inconsistent active DB snapshots at the cost of skipping that optional live state file.

Verification:

  • npm test -- runtime-rotation-proxy
  • npm test -- codex-bin-wrapper
  • npm test -- runtime-policy
  • npm run typecheck
  • npm run lint -- --quiet
  • git diff --check (only Windows line-ending warnings)

Docs and Governance Checklist:

  • README update not required; behavior is internal runtime proxy compatibility for Codex TUI goal routes.
  • Getting started / feature docs update not required; no new user-facing command or setting.
  • Reference / upgrade docs update not required; no public API or migration step changed.
  • SECURITY / CONTRIBUTING update not required; no policy or disclosure process changed.
  • Regression tests cover thread-goal forwarding, query-keyed GET fallback, anonymous fallback rejection, 4xx pass-through, concurrent fallback isolation, fallback eviction, SQLite hard-link behavior, and failed TUI helper cleanup.

note: greptile review for oc-chatgpt-multi-auth. cite files like lib/foo.ts:123. confirm regression tests + windows concurrency/token redaction coverage.

Greptile Summary

proxies codex TUI thread goal get/set routes through the runtime rotation proxy with a 403-triggered LRU in-process fallback (512-entry, keyed by thread_id/session header); shadow homes are relocated under the real codex home to guarantee same-volume hard links for sqlite state files, and disable_response_storage = false is force-written into the shadow config so the TUI can read thread goals. TUI invocations now use detachOnExit: true to keep the app helper alive across the TUI session.

Confidence Score: 5/5

safe to merge; all findings are p2 style/coverage gaps with no runtime impact on the happy path

prior p1 findings (session-key collision, recordSuccess on 4xx) are addressed in this revision. remaining findings are a missing restore-path test and no EBUSY retry on Windows hard-link creation — neither causes data loss or incorrect behavior on supported platforms.

lib/runtime/config-toml.ts restore path and scripts/codex.js materializeFileIntoShadowHome

Important Files Changed

Filename Overview
lib/runtime-rotation-proxy.ts adds thread goal proxy routes with LRU in-process fallback for 403; session-key null guard returns 400 addressing the prior 'default' collision finding; recordSuccess is skipped for all 4xx goal paths; looks correct
lib/runtime/config-toml.ts adds enableTopLevelResponseStorage and restoreTopLevelResponseStorage; logic is correct for the forward and restore paths, but no test covers the restore direction for the new key
scripts/codex.js moves shadow homes under real Codex home for same-volume hard links; materializeFileIntoShadowHome has no EBUSY/EPERM retry inconsistent with codebase convention; TUI detachOnExit path and isCodexInteractiveTuiCommand look correct
test/runtime-rotation-proxy.test.ts comprehensive new tests: forwarding, codex-path dedup, 403 fallback, anonymous rejection, GET keying, concurrency isolation, capacity eviction, auth rejection — good coverage
test/app-bind.test.ts validates forward path for disable_response_storage; missing restore-path assertion for the new key
lib/usage/types.ts adds 'thread-goal' to UsageLedgerOperation union type; mirrored correctly in ledger.ts and redaction.ts
test/codex-bin-wrapper.test.ts adds shadow-home root path assertion, ROOT_STATE_SYMLINK:false check, and TUI detach-on-failed-launch test; all look correct
test/runtime-policy.test.ts adds thread-goal operation ledger test; straightforward and correct

Sequence Diagram

sequenceDiagram
    participant TUI as Codex TUI
    participant P as Runtime Rotation Proxy
    participant U as Upstream (OpenAI)
    participant F as threadGoalFallbacks (Map)

    TUI->>P: POST /thread/goal/set {threadId, goal}
    P->>U: POST /codex/thread/goal/set (managed auth)
    alt upstream 2xx
        U-->>P: 200 OK
        P-->>TUI: forward response
    else upstream 403
        U-->>P: 403 Forbidden
        P->>F: setThreadGoalFallback(sessionKey, goal)
        P-->>TUI: 200 {ok:true, goal}
    else upstream other 4xx
        U-->>P: 4xx
        P-->>TUI: forward error response
    end

    TUI->>P: POST /thread/goal/get {threadId}
    P->>U: POST /codex/thread/goal/get (managed auth)
    alt upstream 2xx
        U-->>P: 200 {goal}
        P-->>TUI: forward response
    else upstream 403
        U-->>P: 403 Forbidden
        P->>F: getThreadGoalFallback(sessionKey)
        F-->>P: goal (or null)
        P-->>TUI: 200 {goal}
    end
Loading

Fix All in Codex

Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
test/app-bind.test.ts:536-555
**restore path not tested for `disable_response_storage`**

the additions only assert the forward (bind) direction — `bound` containing `disable_response_storage = false`. there's no assertion that `restoreConfigTomlFromRuntimeRotationProvider` cleanly restores the original `disable_response_storage = true` line (or omits it entirely when the original lacked the key). if `restoreTopLevelResponseStorage` regresses, shadow state leaks back into the real `config.toml` without a failing test.

### Issue 2 of 2
scripts/codex.js:1425-1438
**no retry on `EBUSY`/`EPERM` for SQLite hard-link creation**

`linkSync` can throw `EBUSY` or `EPERM` transiently on Windows when the `.sqlite`, `.sqlite-shm`, or `.sqlite-wal` file is momentarily locked by another reader. the codebase convention (`lib/AGENTS.md`: "Settings writes use queued retry for `EBUSY`/`EPERM`/`EAGAIN`") is to retry these errors, but `materializeFileIntoShadowHome` falls through to a single warning + silent skip with no retry. on a busy Windows TUI session, all three SQLite files could be skipped, leaving the shadow home without any state. consider wrapping `linkSync` in a brief retry loop (e.g. 3 attempts with 10 ms back-off) consistent with the rest of the codebase before giving up.

Reviews (4): Last reviewed commit: "Resolve PR body follow-up findings" | Re-trigger Greptile

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@coderabbitai

coderabbitai Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

extends runtime-rotation-proxy with Codex thread goal endpoint support, implementing upstream request forwarding with error fallback to local goal persistence, rewrites TOML config-storage settings during rotation setup, adds SQLite file special handling and runtime-shadow-home management in scripts, and covers these changes with corresponding proxy and config test cases.

Changes

Cohort / File(s) Summary
Proxy Thread Goal Support
lib/runtime-rotation-proxy.ts
Allowlists GET/POST to Codex thread goal endpoints, normalizes paths with /codex prefix, builds dedicated RequestContext with session key and codex family metadata. Implements fallback: when upstream response >= 400, consumes error, records account as active, returns HTTP 200 with extracted goal or stored per-session fallback. POST bodies trigger "diagnostic" usage recording.
TOML Response Storage Rewrite
lib/runtime/config-toml.ts
Adds enableTopLevelResponseStorage and restoreTopLevelResponseStorage functions to manipulate disable_response_storage flag during rotation pipeline. Rewrite flow now toggles top-level setting to false while preserving table-section values; restore flow recovers original state by reinserting the prior line before TOML tables.
SQLite and Shadow Home Handling
scripts/codex.js
Treats SQLite files (.sqlite, *-shm, *-wal) specially during mirror: prefers hard-link, falls back to copy + tightenFile. Introduces dedicated runtime-shadow-home directory under multi-auth/runtime-shadow-homes. Extends app-helper context creation to accept detachOnExit option, auto-enabled for interactive TUI runs (no forwarded command).
Config and Proxy Tests
test/app-bind.test.ts, test/runtime-rotation-proxy.test.ts
Updated fixture to include disable_response_storage = true at top level and in [profiles.default], verifying rewrite preserves profile value. Added three thread goal endpoint cases: POST to /thread/goal/get with bearer auth, custom /codex/thread/goal/set path handling, upstream 403 fallback with dual upstream calls.
Symlink and Shadow Home Verification
test/codex-bin-wrapper.test.ts
Instruments child process to report ROOT_STATE_SYMLINK:false status; tightens shadow home discovery assertion to confirm resolved path lives under multi-auth/runtime-shadow-homes.

Sequence Diagram

sequenceDiagram
    participant Client
    participant RuntimeProxy as Runtime Rotation Proxy
    participant Codex as Upstream Codex Service
    participant SessionStore as Session/Goal Storage

    Client->>RuntimeProxy: POST /thread/goal/set (goal data)
    RuntimeProxy->>RuntimeProxy: Normalize path to /codex/thread/goal/set
    RuntimeProxy->>RuntimeProxy: Build RequestContext (session key, auth)
    RuntimeProxy->>Codex: Forward POST with managed-account Bearer token
    
    alt Upstream Success (< 400)
        Codex-->>RuntimeProxy: HTTP 200 + response
        RuntimeProxy->>SessionStore: Persist goal
        RuntimeProxy-->>Client: HTTP 200 + response
    else Upstream Error (>= 400)
        Codex-->>RuntimeProxy: HTTP 403/5xx
        RuntimeProxy->>RuntimeProxy: Consume error, record account active
        RuntimeProxy->>SessionStore: Persist goal from request body
        RuntimeProxy-->>Client: HTTP 200 (fallback handling)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

bug


key concerns:

missing regression tests: thread goal GET requests lack explicit coverage—only POST to /set is tested. fallback goal retrieval (POST without /set) untested. no concurrency tests for simultaneous shadow-home creation or parallel goal persistence.

windows edge cases: test/codex-bin-wrapper.test.ts: symlink detection ROOT_STATE_SYMLINK:false will fail on windows—symlinks behave differently there and may require junction points. scripts/codex.js: hard-link logic on sqlite files may fail on windows depending on FS.

concurrency risk: scripts/codex.js: shadow-home directory creation under multi-auth/runtime-shadow-homes lacks mkdir with proper error handling if multiple runtime instances start simultaneously. tighten fallback in sqlite copy path (scripts/codex.js:) has no rollback if tighten fails mid-operation—file left in intermediate state.

logic density: lib/runtime-rotation-proxy.ts adds substantial request interception logic; goal extraction from POST body on error path needs validation that body is well-formed JSON.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title follows conventional commits format (fix: summary) with appropriate scope and describes the main change clearly within 72 characters.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed PR description is comprehensive and includes all required sections from the template with detailed summaries, validation steps, and a thorough governance checklist.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/goals-tui-proxy
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/goals-tui-proxy

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 and usage tips.

Comment thread lib/runtime-rotation-proxy.ts Outdated
Comment thread lib/runtime-rotation-proxy.ts Outdated

@coderabbitai coderabbitai 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.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
scripts/codex.js (1)

2882-2893: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

do not detach the helper after a failed tui launch.

options.detachOnExit === true bypasses the exit-code check here, so a tui startup that exits non-zero still leaves the helper running until the 12h idle timeout in scripts/codex.js:2543-2551 and scripts/codex.js:2740-2754. that leaks orphan helpers and shadow homes on repeated failed launches. please add a regression test for the non-zero exit path.

proposed fix
 	const cleanup = async ({ exitCode } = {}) => {
 		const livedMs = Date.now() - startedAt;
-		if (
-			options.detachOnExit === true ||
-			(exitCode === 0 && livedMs < detachGraceMs)
-		) {
+		const shouldDetach =
+			exitCode === 0 &&
+			(options.detachOnExit === true || livedMs < detachGraceMs);
+		if (shouldDetach) {
 			helper.stdout?.destroy();
 			helper.stderr?.destroy();
 			helper.unref();
 			return;
 		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/codex.js` around lines 2882 - 2893, The cleanup function currently
detaches the helper whenever options.detachOnExit === true, which lets failed
TUI launches (non-zero exitCode) leak; modify cleanup to only allow detaching
when exitCode is 0 (or undefined) or when livedMs < detachGraceMs but never when
exitCode !== 0 even if options.detachOnExit is true: change the conditional that
checks options.detachOnExit to also require (exitCode === 0 || exitCode ==
null). Ensure stopRuntimeRotationAppHelper(helper) is awaited for non-zero exits
and remove helper.unref() path for failure cases. Add a regression test that
simulates a non-zero TUI startup exit and asserts the helper is stopped/cleaned
(no unref / no lingering helper) to cover the non-zero exit path.
lib/runtime-rotation-proxy.ts (1)

927-938: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

"diagnostic" is outside the runtime usage operation contract.

createRuntimeUsageRecorder receives "diagnostic" here, but lib/usage/types.ts:8-19 does not define that operation, and lib/policy/runtime-policy.ts:219-230 expects the existing UsageLedgerOperation union. this will either fail typecheck or introduce a ledger value the rest of the runtime policy code does not understand.

safe short-term fix
 			usageRecorder = createRuntimeUsageRecorder({
 				source: "runtime-proxy",
 				operation: isModelsRequest
 					? "models"
 					: isThreadGoalRequest
-						? "diagnostic"
+						? "responses"
 						: "responses",

as per coding guidelines, lib/**: focus on auth rotation, windows filesystem io, and concurrency. verify every change cites affected tests (vitest) and that new queues handle ebusy/429 scenarios. check for logging that leaks tokens or emails.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/runtime-rotation-proxy.ts` around lines 927 - 938, The code passes an
unsupported operation string "diagnostic" into createRuntimeUsageRecorder (see
the createRuntimeUsageRecorder call in runtime-rotation-proxy.ts); fix by either
(A) replacing "diagnostic" with a currently allowed UsageLedgerOperation literal
(e.g. use the same operation as other diagnostic-like flows, such as
"responses") directly in the createRuntimeUsageRecorder call, or (B) if
"diagnostic" is required, add "diagnostic" to the UsageLedgerOperation union in
lib/usage/types.ts and update lib/policy/runtime-policy.ts to handle the new
operation branch consistently; after the change update/ add vitest cases that
exercise the isThreadGoalRequest path and ensure logging changes do not leak
tokens/emails and that any new queues handle EBUSY/429 scenarios.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/runtime-rotation-proxy.ts`:
- Around line 1130-1156: The current block at isThreadGoalRequest
unconditionally treats any upstream.status >= 400 as a success for thread-goal
routes; restrict this to only the specific upstream storage-failure codes you
expect (e.g., 502, 503, 504) so we don't turn client 4xx errors into 200s.
Update the conditional that references upstream.status to only trigger the
fallback path for those storage-failure statuses (instead of >=400); move or
remove accountManager.recordSuccess, persistRuntimeActiveAccount, and
usageRecorder.record(...) success calls from this fallback branch so they are
not invoked for errors, and for non-storage errors forward the original
upstream.status and body (using readErrorBody and writeJson) instead of
returning {ok:true}. Keep the threadGoalFallbacks.set(...) + writeJson OK
behavior only when the status is one of the allowed storage-failure codes and
add/adjust vitest regression tests to assert that 4xx client errors (e.g.,
400/401/403) are passed through and do not trigger recordSuccess or fallback
storage behavior.
- Around line 400-421: The buildThreadGoalRequestContext function only derives
sessionKey from headers and body, so GET requests with query params (e.g.,
/thread/goal/get?thread_id=...) fall back to "default" and can return another
thread's cached goal; update buildThreadGoalRequestContext to also parse the
IncomingMessage URL query (for GET) and derive sessionKey from query param names
"thread_id" and "threadId" (fallback to resolveSessionKey(headers, parsedBody)
only if not present), and add a vitest regression in the test suite that issues
GET /thread/goal/get?thread_id=... to ensure the local fallback keys by query
string; when adding this change, name the test clearly (e.g.,
thread-goal-query-param-keying.test.ts), handle edge cases where parsedBody is
null, and ensure no logs leak tokens or emails.

In `@test/codex-bin-wrapper.test.ts`:
- Around line 1046-1048: Replace the brittle substring assertion on
shadowHomeMatch[1] with a real ancestry check: compute expectedRoot =
path.resolve(originalHome, "multi-auth", "runtime-shadow-homes") and actual =
path.resolve(shadowHomeMatch[1]); then use path.relative(expectedRoot, actual)
and assert the result does not start with ".." and is not an absolute path (e.g.
expect(relative).not.toMatch(/^\.\./) &&
expect(path.isAbsolute(relative)).toBe(false)) so Windows path normalization is
handled deterministically; change the assertion around shadowHomeMatch and
originalHome accordingly.

In `@test/runtime-rotation-proxy.test.ts`:
- Around line 527-619: Add two deterministic vitest regression tests in the same
suite: (1) "rejects unauthenticated thread-goal calls" — startProxy with an
AccountManager but send postThreadGoal without credentials (or with expired/no
access token via createStorage) and assert the response is 401/unauthorized and
no upstream fetch (calls.length === 0); (2) "concurrent fallback writes isolated
per thread" — simulate upstream 403 via createRecordingFetch, then concurrently
call postThreadGoal for two different threadIds using Promise.all against the
proxy (ensure using the same AccountManager/storage), then assert both local
set/get succeed and that stored goals are isolated per thread (read back via
postThreadGoal get) and that two upstream calls were attempted; use the existing
helpers postThreadGoal, startProxy, AccountManager, createRecordingFetch,
createStorage so tests mirror existing patterns and remain deterministic.

---

Outside diff comments:
In `@lib/runtime-rotation-proxy.ts`:
- Around line 927-938: The code passes an unsupported operation string
"diagnostic" into createRuntimeUsageRecorder (see the createRuntimeUsageRecorder
call in runtime-rotation-proxy.ts); fix by either (A) replacing "diagnostic"
with a currently allowed UsageLedgerOperation literal (e.g. use the same
operation as other diagnostic-like flows, such as "responses") directly in the
createRuntimeUsageRecorder call, or (B) if "diagnostic" is required, add
"diagnostic" to the UsageLedgerOperation union in lib/usage/types.ts and update
lib/policy/runtime-policy.ts to handle the new operation branch consistently;
after the change update/ add vitest cases that exercise the isThreadGoalRequest
path and ensure logging changes do not leak tokens/emails and that any new
queues handle EBUSY/429 scenarios.

In `@scripts/codex.js`:
- Around line 2882-2893: The cleanup function currently detaches the helper
whenever options.detachOnExit === true, which lets failed TUI launches (non-zero
exitCode) leak; modify cleanup to only allow detaching when exitCode is 0 (or
undefined) or when livedMs < detachGraceMs but never when exitCode !== 0 even if
options.detachOnExit is true: change the conditional that checks
options.detachOnExit to also require (exitCode === 0 || exitCode == null).
Ensure stopRuntimeRotationAppHelper(helper) is awaited for non-zero exits and
remove helper.unref() path for failure cases. Add a regression test that
simulates a non-zero TUI startup exit and asserts the helper is stopped/cleaned
(no unref / no lingering helper) to cover the non-zero exit path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f886a0fb-105f-477c-8e66-22bd57bbb1ed

📥 Commits

Reviewing files that changed from the base of the PR and between 3f335e4 and 7e63893.

📒 Files selected for processing (6)
  • lib/runtime-rotation-proxy.ts
  • lib/runtime/config-toml.ts
  • scripts/codex.js
  • test/app-bind.test.ts
  • test/codex-bin-wrapper.test.ts
  • test/runtime-rotation-proxy.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (2)
test/**

⚙️ CodeRabbit configuration file

tests must stay deterministic and use vitest. demand regression cases that reproduce concurrency bugs, token refresh races, and windows filesystem behavior. reject changes that mock real secrets or skip assertions.

Files:

  • test/app-bind.test.ts
  • test/runtime-rotation-proxy.test.ts
  • test/codex-bin-wrapper.test.ts
lib/**

⚙️ CodeRabbit configuration file

focus on auth rotation, windows filesystem IO, and concurrency. verify every change cites affected tests (vitest) and that new queues handle EBUSY/429 scenarios. check for logging that leaks tokens or emails.

Files:

  • lib/runtime-rotation-proxy.ts
  • lib/runtime/config-toml.ts
🪛 ast-grep (0.42.1)
lib/runtime/config-toml.ts

[warning] 103-103: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^\\s*${key}\\s*=)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

🔇 Additional comments (3)
test/codex-bin-wrapper.test.ts (1)

941-942: good hardlink-vs-symlink regression coverage.

this correctly validates the non-symlink invariant and keeps the realtime state coupling check intact. ref: test/codex-bin-wrapper.test.ts:941, test/codex-bin-wrapper.test.ts:1022.

Also applies to: 1022-1023

test/app-bind.test.ts (1)

130-134: rewrite/restore expectations are scoped correctly.

this captures the intended contract: top-level disable_response_storage flips to false, profile-scoped value stays untouched, and full restore still round-trips. ref: test/app-bind.test.ts:130, test/app-bind.test.ts:154, lib/runtime/config-toml.ts:78.

Also applies to: 154-155

test/runtime-rotation-proxy.test.ts (1)

152-168: thread-goal request helper is clean and consistent.

this keeps request construction aligned with the existing responses/models helpers and keeps tests readable. ref: test/runtime-rotation-proxy.test.ts:152.

Comment thread lib/runtime-rotation-proxy.ts
Comment thread lib/runtime-rotation-proxy.ts Outdated
Comment thread test/codex-bin-wrapper.test.ts Outdated
Comment thread test/runtime-rotation-proxy.test.ts
Comment thread scripts/codex.js Outdated
@ndycode
ndycode merged commit 0e1c525 into main May 1, 2026
2 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request May 27, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant