This repository was archived by the owner on Sep 13, 2026. It is now read-only.
sync: upstream v2.51.0 (c155cc7923db) into dev - #333
Draft
cursor[bot] wants to merge 500 commits into
Draft
Conversation
The new paragraph claimed the 90-second prelude deadline is not configurable through connectTimeoutMs. The constant is not tunable, but the effective wait is: core.ts passes connectTimeoutMs (default 200s) as the header-timeout budget to fetchWithHeaderTimeout, which aborts the combined signal the WS exchange runs under, and codex-ws-exchange.ts cancels an already-sent create on that abort before the prelude timer fires. An operator who lowers connectTimeoutMs below 90 seconds keeps the shorter deadline, so state it as the shorter of the two. Addresses the Codex review finding on this PR.
…root-guidance fix(codex): report operator-owned root routing truthfully
…tches A live Codex thread switched from a native ChatGPT model to a routed provider replays the backend-minted encrypted agent message on every later turn. That turn is not a thread spawn, so the direct recovery gate skipped it and the thread was permanently unusable on that provider, with no recovery attempt and no recovery_reason on the error. Drop the threadSpawn conjunct from the direct gate only. The trust boundary is recoveryAdmission() -- Codex originator, live native ChatGPT bearer, matching chatgpt-account-id, no inbound API key -- which is unchanged. The cache restore lives inside the same if, so a mid-thread turn can now reuse a plaintext this proxy already paid for. The combo gate keeps its spawn requirement. Closes lidge-jun#4089
…e visibility The first draft said a defect 'plainly visible in code that is already published' could go to a public issue. opencodex is source-available, so that reading covers nearly every finding, and it contradicted the same file's rule that undisclosed vulnerabilities never start as public issues. The test is now whether the weakness is already public — fix shipped, or already described in a published advisory, issue, or pull request — with an explicit statement that being findable in the source is not disclosure.
…vlog-fin Docs-only devlog move. Exact-head CI at e3a4f0a: 12 success, 10 skipped by path filters, only the CodeRabbit review bot outstanding. Merged by the maintainer under the dev integration policy in MAINTAINERS.md.
The proxy has stamped a stable non-PII account label on every request row and every attempt for a long time (main, p<hex6> for Codex pool accounts, o<hex6> for other OAuth providers), but nothing could read it back. An operator running several accounts behind one provider had to grep usage.jsonl to answer "which account served this request", which is the first diagnostic question for a quota or cache anomaly. /api/logs now accepts ?account=<label>, matching failover attempts the same way ?provider and ?model already do, so a request is findable by the account that finally served it as well as the one that first refused it. ocx logs gains the matching --account flag and prints acct=<label> in human output, so a filtered result can be told apart from an empty one. No new field is persisted and no new identifier is derived: this reads back the label already written by sealRequestAttemptIdentity. Closes lidge-jun#4057
…ing MissingSessionID OpenCode closed the keyless Zen tier to its own client. A request without an x-opencode-session header is refused with error type MissingSessionID and "OpenCode's free tier can only be used in OpenCode", so every opencode-free request now fails and the user saw that raw upstream string with no indication of what happened or what to do instead. Presence of the header is the entire gate, so the proxy could pass it by minting a value. It does not: a fabricated session id plus a versioned opencode/<version> User-Agent is a claim to be the OpenCode client, and OpenCode publishes no third-party integration contract for this keyless tier, so a 200 obtained that way is a bypassed admission check rather than permission. Report the restriction instead. The Zen guidance module gains a free-tier enrichment that replaces the passthrough with the reason and the supported keyed opencode-zen route. It is scoped to Zen destinations and to this error, and is idempotent so layered enrichment cannot append it twice. Wired on both surfaces that render upstream errors: the native Chat path, where the issue reproduces, and the Responses path, whose existing single call site now goes through a composed entry point that leaves the 429 guidance unchanged. The opencode-free registry note and the providers guide document the gate, the refusal to impersonate, and the keyed alternative. Closes lidge-jun#4121
MAX_DECOMPRESSED_BODY_BYTES was hard-coded at 256 MiB, and on the 922k-token opt-in window a session's serialized history crosses it. The request that crosses it is Codex's own remote-compaction request, so the session 413s on the one operation that would have shrunk it and cannot recover. Adds the opt-in `maxInboundBodyBytes`, shaped like `maxUpstreamBodyBytes`: omitted or 0 keeps today's 256 MiB. Every reader resolves through resolveInboundBodyLimitBytes(), which clamps to [1 MiB, 512 MiB]. The ceiling is mandatory rather than advisory: readBoundedJsonRequestBody materializes the body several times over, so peak memory is a multiple of whatever is admitted and an unbounded inbound cap would be a memory exhaustion lever. The schema keeps the outbound guard's `.catch(undefined)` degradation, which is exactly why the bound cannot live there. Bun's listener rejects an oversized body before fetch() runs, so maxRequestBodySize is now resolved from config at bind time instead of being pinned to the default; an out-of-range value is clamped with one startup warning. Also separates the two 413s a client can now see on this surface. lidge-jun#4112 gives an upstream size refusal `context_length_exceeded`; a local admission refusal now answers `inbound_body_too_large` with a message that names OpenCodex as the refuser, the observed and configured sizes, and the config key that moves the limit. The diagnostic inherits the thrown error's rule about keeping non-finite and untyped values out of the text.
The reference page and the sub-agent surface guide framed agentTaskRecovery as spawn-only. It now also covers a live thread switched from a native ChatGPT model to a routed one. Combo recovery is still spawn-only, so say that explicitly in each locale rather than leaving the distinction implicit.
…sal shape Bun answers 413 and stops reading while the client is still uploading, so the write side can surface the refusal as a transport error rather than a response. Accept either shape for the refusal, and pair it with the admitted case at the same body size so the assertion stays non-vacuous: the old listener, pinned to MAX_DECOMPRESSED_BODY_BYTES, admitted this body under every configuration.
… locales The English providers guide now says the keyless tier is closed, while ko, ja, zh-cn, zh-tw, fr, ru and tr still told readers it works without a key. Each locale gets the same two paragraphs in its own register, keeping the identifiers, the quoted upstream message and both URLs verbatim.
…he rendered page `skills/ocx/references/01_management_surface.md` is generated from `CAPABILITIES` in `src/cli/capabilities.ts`, and `tests/ci-workflows/skill-ocx.test.ts` compares the committed file against a fresh render byte for byte. The previous commit edited the rendered page by hand, so the two disagreed. Declare the flag at its source instead: the logs capability now carries `--account` between `--conversation` and `--status`, its summary names the new filter, and a detail line documents the `acct=<label>` column next to the existing `conv=<id>` one. The rendered page is unchanged from the previous commit apart from that detail line, which is what the registry now emits.
…m, and guard fallback
…grant A Codex pool credential whose OAuth grant was revoked upstream kept lastCodexValidationStatus: "ok" in codex-accounts.json and was reported as healthy for as long as the install lived, while every request using it 401'd. guardianSweep's pool branch already classified the failure -- it computed `permanent` for a revoked/expired TokenRefreshError -- but spent it only on widening an in-memory backoff delay. The persisted-verdict branch next to it required `needsWarmup`, which is false in the default configuration, and additionally excluded every TokenRefreshError, so the one class of failure that proves the credential is dead was the one class that never reached the record. Persist that verdict instead, independently of needsWarmup, and add a lastCodexValidationTerminal marker so a dead grant is distinguishable from a transient warmup failure. The write is fenced on the generation the sweep actually observed, so a credential replaced mid-refresh is never branded by the previous credential's failure. The marker clears itself in both directions that disprove it: markCodexAccountValidated clears it explicitly, and every credential write drops it because the record is rebuilt from preservedValidationMetadata, which deliberately omits it. A refresh that succeeds disproves "the grant was revoked", so one spurious invalid_grant cannot brand a live account dead forever. On the read side, projectCodexAccountHealth now reads that verdict and reports reauth_required/refresh_failed -- the accurate statement, since only a re-login recovers a revoked grant, and the existing union member already carries the Codex reauth action. collectLocalCodexEntries is folded onto the same projector rather than keeping its inlined copy, which is how the CLI would otherwise have kept reporting the account healthy after the dashboard stopped. Background warmup stays opt-in; no default-on probe is introduced. Closes lidge-jun#4120
Diff-level roadmap for the three-layer chain (lidge-jun#4120 -> lidge-jun#3848 -> lidge-jun#3777), with the wp1 design decisions recorded: why the terminal marker is an extra optional key rather than a new status value, why it clears itself on every credential write, why the generation fence declines rather than clobbers, and why the dashboard fix is a server-side projection onto the existing reauth_required member.
…verflow fix(responses): classify non-streaming provider input overflow
CodeRabbit flagged that the ja and zh-cn pages disagreed about when combo recovery runs. The runtime has two triggers: no payload-eligible target is initially selectable (core.ts:2753), and native attempts are exhausted with no eligible target left (core.ts:3054-3060). The English reference page named only the first, while the sub-agent surface guide and the fr/zh pages named both, so the English page and the ja/ko/tr/ru pages were the ones out of step.
…te-followup-4073 Closes lidge-jun#4073. Exact-head CI at cf967c3: Cross-platform CI success, enforce-target success x3, PR hygiene success x2, PR Labeler success x2, React Doctor success; the two cancelled runs are superseded duplicates at the same SHA and only the CodeRabbit review bot is outstanding. Documentation only: SECURITY.md plus locale mirrors, no response SLA published. Merged by the maintainer under the dev integration policy in MAINTAINERS.md.
…ntact around the bridge
…e-90s fix(responses): allow 90 seconds for Codex WebSocket response prelude
…gle-model-envelope fix(google): restore AI Studio model discovery
…zen-lockin-4121 Closes lidge-jun#4121. Documentation and error-path change only: explains the upstream OpenCode lock-in on the keyless Zen tier and points at the supported keyed path, instead of fabricating x-opencode-session, which the maintainer comment on lidge-jun#3954 forbids. Exact-head CI at 40e183e: Cross-platform CI, enforce-target, PR hygiene, PR Labeler and React Doctor all success; the cancelled runs are concurrency-group duplicates at the same SHA.
…entity-4057 Closes lidge-jun#4057. Surfaces the routed account label that already existed in the usage log through the Logs page and an --account CLI filter, without writing raw key identifiers into the JSONL. Exact-head CI at d693361: Cross-platform CI, enforce-target (x2), PR hygiene, PR Labeler and React Doctor all success; cancelled runs are concurrency-group duplicates at the same SHA. The earlier test 4/4 failure was a hand-edited generated file and was fixed at its source in src/cli/capabilities.ts.
…ble-inbound-body-limit Closes lidge-jun#3573. Makes the inbound body admission limit configurable with a hard ceiling, default unchanged at 256 MiB, and distinguishes the inbound admission 413 from the upstream overflow 413 that lidge-jun#4127 classifies. Exact-head CI at 92e6f5a: Cross-platform CI, enforce-target, PR hygiene, PR Labeler and React Doctor all success; cancelled runs are concurrency-group duplicates. Verified that lidge-jun#4127's content is not in this diff: 15c03e8 is an ancestor of dev and the 15 changed files are all this change.
…nt-task-recovery Closes lidge-jun#4089. Drops the threadSpawn conjunct from the direct agentTaskRecovery gate in src/server/responses/core.ts so a mid-thread native-to-routed model switch gets one recovery attempt instead of failing closed forever.\n\nSecurity review (C4, trust-boundary widening): recoveryAdmission() is unchanged, so the principal set is unchanged - Codex originator, live native ChatGPT bearer, matching chatgpt-account-id, no inbound API key, no proxy-admission secret. threadSpawn only narrowed which of the session owner's own requests could spend their own session; it kept no other principal out. The combo gate keeps its spawn requirement, and canPassThroughEncryptedV2AgentTask is untouched, so an OAuth-mode routed provider still gets no ciphertext passthrough. The plaintext-oracle caution in encrypted-payload.ts already applied to the spawn path; this widens request shapes, not who may decrypt.\n\nExact-head CI at 0e95eb7: Cross-platform CI, enforce-target, PR hygiene, PR Labeler and React Doctor all success.
…-validation-4120 Closes lidge-jun#4120. A pool credential whose OAuth grant was revoked upstream kept lastCodexValidationStatus 'ok' indefinitely because the one path that records a failure excluded the terminal failure class. Now a terminal TokenRefreshError persists a failed verdict without requiring needsWarmup, with a generation fence so an in-flight failure cannot clobber a replaced credential, and background warmup stays off by default.\n\nExact-head CI at 2156fbe: Cross-platform CI, enforce-target, PR hygiene, PR Labeler and React Doctor all success. This is the bottom of the account chain; lidge-jun#3848 stacks on it.
…d registration Reconciles the two changes that both landed on the Codex credential store and health projector. - account-store: markCodexAccountValidationFailed keeps the options-bag fence (expectedGeneration + terminal) from lidge-jun#4120 and keeps this branch's rule that a validation-pending account is only settled by a caller that names the generation it observed. isCredentialRecord validates both new keys, and markCodexAccountValidated clears both markers. - token-guardian: the terminal branch from lidge-jun#4120 is fenced on the pre-refresh generation; the warmup-failure branch uses this branch's warmupGeneration, which is tighter because it is set only once warmup started against a record still at the token's generation. - health: git merged both sides' additions to projectCodexAccountHealth into a duplicate 'const needsReauth' declaration. Rewritten as one function with a single store read that derives validation-pending, the 401/403 auth failure and the terminal grant verdict together. Reauth is resolved before pending, because a revoked grant needs a re-login rather than a Refresh quotas click. - auth-api: fetchPoolAccountQuota takes both new parameters; dev's manual-reset caller passes validatePending false explicitly, and the quota flight keeps dev's onDispatch/mayPublish options alongside this branch's validation continuation. - skills surface: counts regenerated by hand from the merged registry (38 declared, 17 state-changing).
…docs-skill docs(remote-hub): the one-port hub recipe, invite flow, and launchd semantics (en+ko, skill)
…nt-hub-state feat(client): a connected client reports the hub's state, not its own
…lamp diagnostics The observed-runtime clamp matched a persisted diagnostic to the current runtime by path alone, so an in-place Codex upgrade (the normal Windows case) kept max/ultra hidden forever. The diagnostic is now version-aware, rungs nothing clamps any more no longer keep the warning alive, and the sync clamp exempts max/ultra from the observed-runtime intersection while hub admission stays fail-closed. ocx status, ocx doctor, and /api/settings now read one shared predicate. Refs lidge-jun#4204.
Plan, evidence, architecture dispositions, test impact, open gaps, and the resumed-cycle revalidation with the three-round audit synthesis (reviewer: xai/grok-4.6). Phase 3 stays withdrawn pending a live account-roster probe.
…an unselectable one CodeRabbit review on lidge-jun#4257: the exempt default must survive only when the surviving ladder advertises it; an orphaned ultra default is repaired down without naming the rung in the clamp diagnostic. Also folds the three doc-coherence findings into the devlog unit and docs-site.
…xpiry fix(codex): emit max/ultra efforts unconditionally and expire stale clamp diagnostics
The Responses preset shipped a two-model roster read off the models.json sample on BigModel's Codex page. That sample is a starter catalog, not the endpoint's roster, and taking it for the latter left Flash off a subscription that sells it. Three upstream pages disagree with the old reading, all checked 2026-09-11: - coding-plan/latest-model.md pins Codex to https://open.bigmodel.cn/api/v1 -- this preset's exact baseUrl -- and states GLM Coding Plan supports GLM-5.3 and GLM-5.3-Flash for every tier, then treats glm-5.3-flash as an already-callable id in that tool. - coding-plan/overview.md states GLM-5-Turbo calls are auto-switched to GLM-5.3-Flash. The preset already lists glm-5-turbo, so it was already reaching Flash on this endpoint under another name. - guide/models/vlm/glm-5.3-flash.md gives native multimodal input, a 1M window, and text parameters "consistent with GLM-5.3". Flash is seeded into the roster and all five sibling per-model maps. Its context tracks the 5.3 sibling on this row (1_048_576) rather than the Chat row's 1_000_000: both are documented as "1M", and this preset expresses that family's 1M the way BigModel's own Codex declaration does, so one preset does not claim two sizes for one documented window. Flash declares ["text", "image"]. It is the only row here that can actually see an image; the other two are text-only upstream and get image back from the vision sidecar at catalog-build time. Declaring Flash text-only would push a native VLM's pictures through a describe-it-first detour and hand the model prose about an image it could have read -- the defect ZAI_GLM_5X_SIDECAR_VISION_MODELS already exists to prevent on the Chat rows. The oracle moves in this same commit, because a test asserting the old roster is not evidence for the new one, it is the thing being changed. It previously locked models to two entries and asserted glm-5.3-flash was absent from the export. It now pins the three-model contract, Flash's exported window, ladder (low/high/max plus the compatibility ultra tier), default effort and native image modality, and keeps asserting the part no document supports: there is still no HTTP /models contract here, so liveModels and apiKeyValidation must not drift. Closes lidge-jun#4201
… describes The preset now seeds glm-5.3-flash, and both pages still said it did not. The guide went further and told the reader why it was excluded, which stops being staleness and becomes a false statement the moment this lands. The modality note is split rather than rewritten: 5.3 and Turbo still reach images through the vision sidecar, while Flash declares native text and image input, so the page should not describe one mechanism for all three rows.
…log-pool provider: seed GLM-5.3-Flash on the BigModel Responses preset
Two surfaces changed because one pooled account stopped being usable, and neither said so. The reporter in lidge-jun#4212 lost astra and sol through the proxy, found the proxy worked with ocx turned off, and concluded OpenCodex had broken. The real cause was a single account stuck on a failed credential refresh, which they eventually found themselves and then asked to be told about. The request-time refusal now names the account. refreshPoolForwardAuth and refreshPoolCompactContext both caught a non-terminal refresh failure and returned "Codex credential refresh did not complete; retry this request", which describes a transient server problem. It stays a retryable 503 and stays non-quarantining, because the refresh genuinely may succeed and a token-endpoint 5xx must not retire a healthy account (lidge-jun#2887). What it gains is the account and the exit: when retrying stops helping, that account has to be signed in again. The two call sites now share one helper, so the regular and compact contracts on this endpoint cannot drift the way they already had -- compact takes no RouteResult and so could not reach the public selector at all until its caller started passing it. The refusal says "sign in to that account again" rather than the more natural "needs reauthentication", and that is load-bearing. classifyError runs isAuthenticationMessage before it reaches the status === 503 arm, and that check is status-blind on the bare substring "authentication", which "reauthentication" contains. The friendlier wording reclassifies the body to authentication_error / invalid_api_key while the HTTP status stays 503, and Codex applies retry-after backoff only for server_is_overloaded -- so it would have quietly disabled the retry this refusal exists to ask for. A test pins the wording, not just the resulting code, because the next person to improve this sentence will not know. The name is a public account selector when the request carried one, otherwise the durable p-prefixed log label. Never the raw pool id and never the email: those are the identifiers responses-compaction-routing.test.ts and codex-auth-context.test.ts already assert must not reach an operator-facing surface, and an error body travels further than a log line. When neither resolves, the sentence degrades to "the selected Codex pool account" rather than naming something opaque. The catalog drop now explains itself. A gated native model that no usable account backs is omitted from the catalog -- there is no row, so nothing downstream could attach a reason to it, and no later surface can tell "never entitled" apart from "the account broke this morning". The suppression site now says which accounts are stuck while the entitlement snapshot that produced the omission is still in scope. That explanation is deliberately narrow, in two ways. It is produced only when an account needs reauthentication, because being unentitled is the default state of most installations and explaining that on every sync would bury the case an operator can act on. And it considers only accounts that could have served the model in question: an account upstream positively denied is not the reason the model is missing, so naming it would send the operator to repair a credential that was never going to help. An unconfirmed roster stays a candidate, because that is exactly what a credential stuck on a failed refresh looks like. Catalog bytes are unchanged. The suppressed slugs are still suppressed, so the existing oracles that assert gated slugs stay absent from the written catalog keep asserting exactly that. Closes lidge-jun#4212
…-account-attribution pool: name the account when a refresh fails or its models vanish
A connected client reported healthy while the installed Codex CLI exited before its first request, because the catalog on disk used a reasoning level that CLI does not know. Connection state proved the hub and the credential; it never proved the selected local runtime could consume what was written. The write-time gate cannot answer this. It runs once, on bytes about to be written, so it says nothing about a catalog that predates it, one written while the runtime ladder was unverified, or a runtime swapped afterwards. inspectClientCatalogReadiness assesses the installed file, and ocx connect status, ocx status --json and ocx connect now report the verdict. Only "ready" means ready; an unobservable runtime stays "unverified" rather than becoming an incompatibility, which is the line the write-time gate already refuses to cross. The probe runs only for a connected client, so no other install pays a Codex process for it. Closes lidge-jun#4207
Four things an independent read of the diff found. A diagnostics command should not start writing runtime selection state: the default observer now resolves the runtime without persisting and hands that command to the catalog read, which also avoids a second probe on a path that had already resolved it. The ocx connect decision moves into a pure connectCompletionReport, so the fail-closed exit is exercised without a hub. It prints the verdict first and withholds "Connected to" when it fails, because a caller grepping that phrase would otherwise read a broken catalog as success. A Claude-only connection is told about an old Codex CLI but not failed by it, since nothing in that connection launches Codex. connectClient now receives the same observer, so the write-time gate and the readiness check cannot disagree about the ladder inside one command. An installed catalog that is not JSON gets its own sentence instead of the gate's "downloaded" wording, and the subprocess fixture takes the same spawn budget the neighbouring client fixtures use.
The previous commit only forwarded catalogCompatibility when a test had injected it, so an ordinary ocx connect still let assertClientCatalogCompatible fall back to its own default -- which persists runtime selection state and runs a second probe. One command could then act on two separately observed ladders, and the comment claiming otherwise was false. Both checks now build the observer through one helper.
collectClientConnectionStatus observes the local ladder for a connected client, and observing it spawns codex debug models under a 45s budget. That is the point on ocx status and ocx connect status. config show is a different caller: it reads state, reason and token to answer whether the hub link is real, and it arrived on dev after this branch forked, so nothing here had declined the probe on its behalf. Declining it explicitly keeps a read-only config dump from turning into a runtime probe - the same reasoning the readiness check already applies when it refuses to persist runtime selection state.
…nt-display client: report local Codex readiness instead of bare connected state
Round one fixed the English remote hub guide and left the seven translated copies telling their readers to run the line that fails. Each locale still ran a nested `ocx config set hub.<field>` straight after `ocx config set runtimeRole hub`, but `runtimeRole` does not create the object and the CLI refuses to create a missing parent, so the guide's own next line died with `config parent path not found: hub`. Each locale also still offered `--allow-insecure-http`, which `ocx connect` rejects as an unknown argument, and none of them documented the data plane at all. Every locale now creates `hub` and `remoteGui` first, offers the whole-object alternative with its replace-not-merge warning, and carries the section that gives the data listener TLS: the macOS constraint that Serve proxies only to 127.0.0.1, the loopback forwarder, the split data and `--management-url` origins, and the quiet trap where a loopback-bound listener behind a TLS frontend answers 403 `origin_rejected` on `/v1/catalog` while `/readyz` still returns 200. The locales say a mistyped key is rejected at write time with a `schema_invalid` error, without pinning the literal error shape. That is deliberate: the English guide at docs-site/src/content/docs/guides/remote-hub.md:110 says the shape is `schema_invalid: hub.<field>`, but `remoteGuiConfigError` in src/config.ts only produces the dotted form when the Zod issue carries a path. An unrecognized key has an empty path, so a typo actually reports `schema_invalid: hub`. Correcting the English source is outside this change's scope, and a translation should not quietly assert a different error shape than the source it translates, so the locales state only what is true of both. tests/ci-workflows/docs-remote-hub-claims.test.ts only read the English guide, which is why this drift went unenforced. It now runs the language-independent assertions over all eight files, English included, pinning commands and literal error codes rather than prose a translator is meant to rewrite. The replace-not-merge check bounds its window on the next heading of any level and requires the warning to name `hub.managementIngress`; bounding on `##` alone and accepting any bold let the following subsection satisfy it, which made the assertion decorative in five of the eight files. Closes lidge-jun#4200
…-locales docs(i18n): make the remote hub guide runnable in every locale
…not a bad key The 2.51.0 candidate reworded the retryable main-account refusal to end with 'the main Codex account needs reauthentication'. classifyError runs isAuthenticationMessage before it reaches the status === 503 arm, and that check is status-blind on the bare substring 'authentication', which 'reauthentication' contains. The body was served as authentication_error / invalid_api_key while still returning 503. Codex keys retry-after backoff on server_is_overloaded, so a transient token refresh started reading to the client as a bad API key and it stopped retrying. On 2.50.0 the same failure classified as server_error / server_is_overloaded. The pool counterpart in core.ts documents this exact trap and words itself around it; the main path walked into it anyway. It now uses the same construction: sign in to the main Codex account again. The old test asserted only the 503 and the word 'reauthentication', which is why the reclassification shipped unnoticed. The added test asserts error.type and error.code, and that the message carries no 'authentication' substring at all - the substring is the thing that reclassifies, not the phrasing.
…fresh-classification fix(responses): keep the retryable main-refresh refusal an overload, not a bad key
[WRONG BRANCH] release: promote verified 2.51.0 product tree to main
Co-authored-by: SB Yoon <yansigit@users.noreply.github.com>
Re-apply fork overlays on upstream-owned integration paths after taking vendor/main for conflict files, and merge shared-hotspot core.ts per OWNED.md. Co-authored-by: SB Yoon <yansigit@users.noreply.github.com>
Co-authored-by: SB Yoon <yansigit@users.noreply.github.com>
|
PR automation (bot-owned)
|
⏳ DRAFT
What to do
This pull request was already a draft. Its draft status will be preserved after every issue above is resolved. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Merge upstream release v2.51.0 (
c155cc7923dbc0102e27d79185505a85d4357b2c) intoorigin/dev(785424295fc5d8ef0a66fb8ce94a55fe3b054471).The Action stopped at
decision-handoffwith 52 textual conflicts. This coordinator branch resolves them perdocs/fork/OWNED.md, re-applies fork preservation overlays where a blind upstream take would drop fork-visible behavior, and keeps upstream control flow at the shared hotspot insrc/server/responses/core.ts.Provenance
v2.51.0c155cc7923dbc0102e27d79185505a85d4357b2cdevSHA:785424295fc5d8ef0a66fb8ce94a55fe3b05447143af01f18d308364a309cc8e69b373fb657e1706vendor/mainv2.51.0 / c155cc7 — doneOWNED.md(src/server/responses/core.ts) — doneorigin/dev— pending (gh pr view --json mergeable)ci/enforce-target/hygiene— pendingDecision table
package.jsonname/version@bitkyc08/opencodex2.51.0@yansigit/opencodex; non-decreasing semvermergePackageJsonrecipebun test tests/fork/sync-ownership.test.tssrc/server/responses/core.tsimportsenrichOpenCodeZenUpstreamMessage; add passthrough web-search bridge importsgoogleProviderOptionsRouteError, CCA/media bridge importsbun test tests/routing/subagent-fallback-handle-responses.test.ts tests/responses/responses-state.test.tscore.tsshadow interceptcredentialDomainWasRewrittenshadowInterceptedfor fork loggingcore.tspassthrough SSEupstreamSseBodyterminal repair pathbun test tests/routing/subagent-fallback-handle-responses.test.tscore.tsremember passthroughtextincl.modelrememberPassthroughResponseChecked; use upstreamtextshapebun test tests/responses/responses-context-overflow.test.tsbin/ocx.mjs,bun.lock, docs, gui pages taken initially, runtime/tests)--theirsB) manual mixsrc/server/responses/fetch-helpers.tsUpstreamRedirectError, explicit test fetch, provider TLS transportbun test tests/responses/responses-context-overflow.test.tssrc/usage/log.tscursor-oauth-*kinds +isKnownAgentKindpersistencebun test tests/config/settings-stream-mode.test.tssrc/config.tsdataPublicOrigin, companion bind)replacePersistedConfig, subagent selectors, TLS/profile validators)bun test tests/server/config.test.tssrc/server/management/config-routes.tscodexClientCompactionsettings surfacesaveManagementConfigbun test tests/config/settings-stream-mode.test.tssrc/server/responses/collaboration.ts<opencodex_subagent_guidance>+ native default sync optionsbun test tests/codex-integration/multi-agent-compat.test.tssrc/claude/inbound.ts(lidge-jun#3922)strict: falsewhen omittedbun test tests/claude-integration/claude-inbound.test.tsbun run build:gui;bun test gui/tests/subagents-ultra-mode.test.tsxtests/codex-integration/codex-routing.test.tsWHAM hunkfiveHourPercentaliasbun test tests/codex-integration/codex-routing.test.tstests/codex-integration/multi-agent-compat.test.ts<opencodex_subagent_guidance>contractcollaboration.tsbun test tests/codex-integration/multi-agent-compat.test.tstests/responses/responses-context-overflow.test.tsreplacePersistedConfighelperreplacePersistedConfigbun test tests/responses/responses-context-overflow.test.tsVerification
Confirmed pin before merge:
vendor/main=c155cc7923dbc0102e27d79185505a85d4357b2c= tagv2.51.0origin/dev=785424295fc5d8ef0a66fb8ce94a55fe3b054471Commands run on head
43af01f18:Notes:
test:changedruns in this container hit worker SIGSEGV cascades unrelated to the focused domains above; isolation reruns of affected files pass.bun run prepushreports upstream-carried hygiene items (new_suppressioningui/src/pages/Models.tsx, empty catch in upstream-owned test fixture) — not introduced by hotspot/manual resolutions.Checklist
Do not squash or rebase this sync PR. Human performs the merge commit into
dev.