Skip to content

[muse] fix(server): bound Codex feedback/upload with a 60s timeout - #24

Open
kvnloo wants to merge 1 commit into
mainfrom
muse/codex-feedback-upload-timeout
Open

kvnloo wants to merge 1 commit into
mainfrom
muse/codex-feedback-upload-timeout

Conversation

@kvnloo

@kvnloo kvnloo commented Sep 29, 2026

Copy link
Copy Markdown
Owner

What Changed

Bounds the Codex app-server feedback/upload request with a 60s timeout. The transport awaits an unbounded Deferred per request, so a wedged app server parked the feedback upload forever - the upload carries the session logs and the client spins with no way to report the outcome. The call was extracted into uploadCodexFeedback (next to readCodexThread/rollbackCodexThread) and the timeout maps to a CodexAppServerRequestError tagged method=feedback/upload, operation=receive-response. Same seam as #4, which only covered turn/start and turn/interrupt.

Why

Submitting bug feedback is exactly the flow a user reaches for when something is already broken; if the app server is wedged at that moment, the feedback RPC hangs the handler fiber indefinitely instead of failing with a clear error. 60s (vs 30s for turn/start) because the upload ships the session log bundle.

UI Changes

None (backend-only). On timeout the client now receives a typed request error instead of an endless spinner.

Checklist

  • This PR is small and focused (2 files, +73/-6)
  • I explained what changed and why
  • No UI changes

Evidence

  • New TestClock regression test in CodexSessionRuntime.test.ts: a never-resolving transport + TestClock.adjust("61 seconds"), with a Deferred spawn gate so the bound cannot trip vacuously. Red on base: AssertionError: a wedged app server must not park the feedback upload forever (fiber still parked after 61 virtual seconds). Green with fix: fails with the tagged CodexAppServerRequestError.
  • Full file suite: 50/50 tests green. CodexAdapter.test.ts: 54/54 green. vp fmt --check clean on both touched files.
  • Isolated tsc assignability check of the Effect.timeout + catchTag("TimeoutError") combinator chain: error channel collapses back to CodexAppServerError (full repo tsc aborts in this sandbox, documented env issue).

authored with AI assistance (Muse, Meta's Muse Spark) under the contributor's direction; reviewed and verified by the contributor before submission.

The app-server transport awaits an unbounded Deferred per request, so a
wedged Codex app server parked the feedback/upload request forever. The
upload carries the session logs and the client spins with no way to report
the outcome. Extracted uploadCodexFeedback and bounded the wait at 60s,
mapping the timeout to a CodexAppServerRequestError tagged
method=feedback/upload, operation=receive-response. Same seam as turn/start
(#4), which only covered turn/start and turn/interrupt.

Evidence: new TestClock regression test in CodexSessionRuntime.test.ts -
a never-resolving transport plus TestClock.adjust(61 seconds) fails on base
(fiber still parked) and passes with the fix (fails with the request error).
50/50 tests green in the file; CodexAdapter suite 54/54 green.

authored with AI assistance (Muse, Meta's Muse Spark) under the contributor's direction; reviewed and verified by the contributor before submission.
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:M labels Sep 29, 2026
@kvnloo kvnloo added the keep pr-janitor: never auto-close label Oct 17, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

keep pr-janitor: never auto-close size:M vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant