Skip to content

[WRONG BRANCH] release: promote frozen tip 9c33e4658 to main as 2.94.0 - #7933

Closed
lidge-jun wants to merge 105 commits into
mainfrom
codex/promote-main-2.94.0
Closed

lidge-jun wants to merge 105 commits into
mainfrom
codex/promote-main-2.94.0

Conversation

@lidge-jun

Copy link
Copy Markdown
Owner

Summary

Promotes the frozen dev candidate 9c33e4658b7b180ec8dd20f0e6a21daf3699f76e to main as stable 2.94.0. The promotion head merges in main ancestry with the ours strategy, so its tree is exactly the candidate tree (git diff 9c33e4658 HEAD is empty). Candidate version sources already say 2.94.0.

Regressions found after 2.93 and fixed in this candidate: dashboard restart refusal (#7871, fixed by #7874), Windows updater lock/identity (#7872, fixed by #7875), and Windows recovery pending-child adoption (#7909). Known issue carried: #7872's synchronous recovery ACL/PowerShell work on parent admission remains deferred.

Draft until the release gate below is settled.

Verification

  • Candidate 9c33e4658: workflow_dispatch Cross-platform CI lane=all 40796504652: 33 jobs succeeded, including all four macOS shards, macOS control and 8/11 Windows shards.
  • Windows 4/11 (management-route-registry.test.ts:149, 2703ms vs a 2500ms bound) and 10/11 (claude-native-passthrough.test.ts:1362, 250ms header timeout before the byte-cap path) are hosted timing bounds; test-only fix in test(windows): budget management responsiveness and native stream fixtures #7932.
  • Windows 2/11 (codex-cli-windows-plan.test.ts:77): the second inspection of an unchanged fixture returned a null install digest in 98ms. Root cause under triage; release gate pending.
  • bun scripts/release-version-sources.ts check 2.94.0: all 4 version sources carry 2.94.0; origin/main is an ancestor of this head.
  • Push-event Cross-platform CI and Service lifecycle on the merged SHA gate release.yml.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

github-actions Bot and others added 30 commits October 27, 2026 12:37
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…7781)

* fix(claude): drain parent ACL flights before intercept secret writes

* fix(claude): bound ACL admission and guard picker cleanup steps

* test(claude): yield a macrotask before barrier ordering assertions

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).

* fix(claude): admit nested Claude settings rewrites after the bind await

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.

* fix(claude): admit model-default rewrites of a nested Claude home

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.

* fix(claude): report a timed-out first-party rollback as incomplete

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.

---------

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
* feat(responses): preserve structural tool turns

* fix(responses): own signing bytes independently of Buffer storage

---------

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
* feat(providers): add Runcrate to the free directory

* fix(providers): bound Runcrate free allowance in the directory row

Only five named open models have a free allowance (GitHub account at least
30 days old, limited per session and per week, shared by the workspace).
Seed those ids, keep live discovery of the full paid catalog, cite the
free-allowance page, chat-completions docs and terms, and add a focused
projection test for the row.

* test(providers): move the Runcrate row test to a sibling file

provider-registry-parity.test.ts sits at the 2000-line file-size threshold; the new case pushed it to 2034 lines (NEW_OVERSIZED) once merged with dev. Move the case byte for byte into tests/providers/free-directory-runcrate.test.ts, registered in a new explicitShards map and the expected layout fixture.

* fix(providers): list RunCrate's sixth free model, DeepSeek V4.1 Flash 1017

RunCrate's free page and /v1/models (free_tier: true) include deepseek-ai/DeepSeek-V4.1-Flash-1017, which the entry omitted while saying every other model is paid. Checked 2026-10-27.

---------

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
* chore(ci): take every Bun pin from package.json

The orphaned-workflow cleanup job installs Bun through setup-project-bun instead of a hand-pinned 1.4.2, and @types/bun moves to 1.4.4 to match dependencies.bun.

Closes #7811

* chore(ci): pin the docs build to the package.json Bun

deploy-docs installed bun@latest through withastro/action; it now requests the dependencies.bun version and a test keeps the two equal.

---------

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
…k 4.5-4.7 (#7701)

* fix(xai): publish the subscription lane's widest context rung for Grok 4.5-4.7

Grok's OAuth subscription lane (cli-chat-proxy.grok.com) reports its default rung
in `context_window` and the selectable ladder in `context_windows`. Probed live
2026-10-24, all four rows read `context_window: 256000` with
`context_windows: [256000, 500000]`.

`catalogHintsFromModelsApiItem` read only the default rung, so grok-4.5,
grok-4.6 and grok-4.7 reached Codex and every client exporter at 256k while the
registry table, the generated metadata and the api.x.ai lane all say 500k
(`context_length: 500000` there). The 500k the registry already carried could not
correct it: `clampObservedModelLimits` lets a configured window LOWER an
observation and never raise it, so the lane-reported short window was sticky.

Read the ladder and use its widest valid rung, placed immediately above the
`context_window` fallback: a ladder outranks the default rung printed beside it,
every other recognized field keeps the precedence it had, and a lane that
publishes no ladder is unaffected. Inspection is bounded to eight rungs.

Verified: tests/codex-integration/catalog-context-window-ladder.test.ts (6 cases),
the other catalog-hints fixtures, `bun run typecheck`, and
`bun run structure:check` for this doc.

* fix(catalog): preserve provider context limits during capture

* fix(catalog): preserve case-varied model limit overrides

---------

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
…#7784)

* fix(claude): expire idle picker uploads without a lifetime cap

Publish the exact locally tested candidate tree. See the draft PR for
focused validation, remaining native/operational coverage and acceptance holds.

* test(claude): cover picker upload backpressure and correct guide placement

* test(claude): wait for sustained upload backpressure across runtimes

* docs(claude): clarify picker idle guard runtime limits

* fix(claude): abort expired picker uploads without synthetic success

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Epinephrine <27862058+luvs01@users.noreply.github.com>
Replay prior thinking for api.mistral.ai Chat targets as native thinking content chunks before assistant text, instead of omitting it or sending reasoning_content. The default applies only when the hostname is exactly api.mistral.ai and preserveReasoningContentModels is unset; an explicit list, including [], stays authoritative. Other hosts keep their existing replay fields, and Mistral placeholder reasoning is no longer synthesized.
* fix(windows): preserve bounded ACL failure diagnostics

Distinguish spawn, runner rejection, caller watchdog and child-result evidence without exposing paths, principals or command output. Keep existing hardening and reap behavior, and add opt-in stage timing for the bearer-admission fixture.

* test(windows): trace complete bearer request and cleanup stages

* test(windows): accept URL in bearer trace helpers

---------

Co-authored-by: JUN <jun@lidgeai.com>
…anges (#7704) (#7719)

* feat(integrations): refresh connected Hermes configs after catalog changes (#7704)

* fix(integrations): keep an unchanged Hermes refresh current after external edits

Co-authored-by: rrmlima <137737127+rrmlima@users.noreply.github.com>

* docs(integrations): qualify the Korean Hermes refresh refusal by a pending catalog update

Co-authored-by: rrmlima <137737127+rrmlima@users.noreply.github.com>

---------

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
…esponses routes (#7453)

* fix(claude): preserve append-only tool discovery on opted-in routes

Preserve structured client ToolSearch discovery positions with additional_tools instead of growing the initial tool catalog. Keep current declarations authoritative, validate the bounded opt-in, and salvage malformed optional settings without losing providers.

Co-Authored-By: Claude Code <noreply@anthropic.com>

* test(claude): cover newline-suffixed tool-loading selectors

Co-Authored-By: Claude Code <noreply@anthropic.com>

* test(claude): assert the actual parsed tool catalog

Compare context.tools rather than nonexistent top-level tools fields, check the exact tool names and schema preservation, and assert discovery metadata explicitly.

Co-Authored-By: Claude Code <noreply@anthropic.com>

* docs(claude): document native routing for Claude behind a Responses gateway

The append-only tool-loading opt-in cannot keep Claude prefixes stable on a gateway that lifts additional_tools into top-level tools. Document the existing operator path: adapter anthropic with modelAdapters keeping other models on Responses, plus protocols.rollout.managedMessagesNative.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(claude): apply append-only tool loading only on a settled direct Responses route

Selector validation checks only string shape, so a selected combo or policy could rewrite tools before routing and then settle on a destination that flattens additional_tools into initial tools. Move the rewrite after route settlement and require an openai-responses adapter on a non-combo, non-policy route. Addresses the CodeRabbit finding on src/claude/inbound.ts.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(claude): stabilize predeclared tools and match settled route identity

Match the append-only allowlist against the resolved provider/model rather than the inbound alias or redirected source. Keep unused deferred definitions out of the initial catalog before discovery as well as after it, retaining forced and previously used tools. Add regression coverage for provider/model aliases, bare selectors, redirects, and predeclared deferred tools.

Co-Authored-By: Claude Code <noreply@anthropic.com>

* fix(claude): bind tool loading to the final physical adapter

Preserve the full original catalog until adapter request construction, then project only for the selected physical Responses destination. Add real collab_spawn fallback regressions in both opt-in directions, a Chat fallback case, and forward-auth coverage. Reconcile English and Korean ToolSearch guidance with the client-executed opt-in exception.

Co-Authored-By: Claude Code <noreply@anthropic.com>

* test(claude): preserve forced tools at physical dispatch

Carry explicit tool_choice with the trusted discovery evidence and exercise it at the real HTTP boundary. Split the tool-loading architecture contract into its own bounded document after integrating current dev.

Co-Authored-By: Claude Code <noreply@anthropic.com>

* test(layout): move tool-loading registration to a shard; keep structure docs under budget

Move the claude-inbound-tool-loading.test.ts registration from
scripts/test-layout/layout.json into layout-adapters.json so layout.json
stays under its 2,000-line ratchet (precedent: 03bcf78).

Restore structure/data-planes/inbound-compat.md to upstream dev (600
lines, its budget) and repoint the three links to the removed pointer
section at the dedicated data-planes/claude-tool-loading.md doc.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Xskw6ycGLZRjVPwNhTqwu

* fix(claude): preserve catalogs on incompatible discovery destinations

Exclude OpenCode Go and official xAI Responses destinations from append-only
client tool discovery at each physical build, using the actual transport URL.
Carry exact and wildcard discovery selectors through provider ID rewrites.
Cover key/forward sends, custom paths, lookalikes and combo target selection;
keep the English/Korean guidance and structure ownership contracts aligned.

Co-authored-by: gitrvc-hub <205301202+gitrvc-hub@users.noreply.github.com>

---------

Co-authored-by: Claude Code <noreply@anthropic.com>
Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
Co-authored-by: gitrvc-hub <205301202+gitrvc-hub@users.noreply.github.com>
…eckpoints (#7822)

After default routed compaction, Codex replays the completed request ahead of the proxy-minted ocx1/ocx2 checkpoint, while the active task survives only in the summary. Historical-request framing recognized only plaintext SUMMARY_PREFIX checkpoints and ran before the portable item was decoded, so the completed request reached the model as a live imperative. A readable portable checkpoint item now counts as the checkpoint; the decoders keep adding the continuation note once.

Refs #7816
* fix(combos): scope cooldown reprobes to reserving request

* fix(combos): lift a reprobed target's cooldown on serve

A request-scoped reprobe reserves cooled targets without clearing the
shared map, so nothing lifted the cooldown once the probe succeeded:
the target stayed cooled for everyone until expiry, and the next
reservation could not fire until the interval elapsed. A cooled target
only reaches dispatch through a reservation, so noteComboSuccess now
clears that target's cooldown — a serve disproves it — while the
mayCommitComboState generation guard still rejects stale writes.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(combos): bound reprobe bypass to the captured cooldown entry

A request-scoped reprobe bypassed the shared cooldown by bare key, so a
replacement entry written while the request was in flight — a
provider-scoped failure, or this request's own failed hop — was probed
through anyway. The reservation now captures each cooled target's expiry:
the bypass applies only while that exact entry is still recorded, and a
successful serve lifts it (settleComboReprobeSuccess) while leaving
unprobed and re-cooled targets recorded. The reservation also carries
through pickComboTargetWithWait, so the before-last-resort deferral and
in-flight retry paths no longer drop the request's recovery pass.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(combos): bind reprobes to cooldown revisions

* fix(combos): retain recovery reservations through waits and JEV

* test(responses): keep pool refresh fixtures on HTTP

* fix(combos): revalidate JEV recovery reservations after decisions

* test(cli): budget real npm-global identity inspection

* test(copilot): isolate discovery and inference wire fixtures

Separate valid catalog discovery from inference capture through the existing provider.fetch test seam. Reset the catalog cache per case and cancel the returned body before releasing its spend-home lease. Preserve model assertions, default timeouts and production policy.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: JUN <jun@lidgeai.com>
* test(providers): drain ASL fixtures and use server budgets

* test: preserve both fixture cleanup attempts and errors

Always attempt both temporary tree removals, restore the fixture environment,
and preserve the original single error or both causes when cleanup fails.
Cover first, second and combined cleanup failures without changing product
behavior or the existing HTTP test budget.

* test(providers): budget both ASL fixture cleanup sequences

---------

Co-authored-by: JUN <jun@lidgeai.com>
…ist ToS account ban (#7819)

* fix(google): treat Retry-After as the earliest resend

The Google-family retry wrapper clamped a provider Retry-After to its 2 s local backoff maximum and resent early. Honour it as a lower bound, and end with the upstream response when the instruction exceeds the shared 60 s wait deadline, matching fetchWithTransientRetry.

Refs #7802

* fix(oauth): recognize the Cloud Code Assist Terms of Service account ban

Classify the exact 403 PERMISSION_DENIED envelope Google returns when it disables Cloud Code Assist for an account as an account-scoped permanent refusal for the opt-in auto-pause policy. Project-scoped CONSUMER_SUSPENDED, service-enablement and model errors stay excluded.

Refs #7803

* fix(oauth): accept the complete Cloud Code Assist ban messages

Google returns the Terms of Service sentence alone and with a fixed contact or appeal sentence (gemini-cli #19501, #20813, #27199, #27388). Allowlist exactly those whole messages after whitespace normalization; prefixes, quotes and other suffixes still do not classify.

---------

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
…ction (#7536)

* fix(qoder): forward Qoder CN images through shared coding-agent projection

Remove the Qoder CN adapter-local blanket raw-image rejection in runTurn,
aligning Qoder CN with Qoder Global to use the shared coding-agent image
projection. Supported image inputs (data: base64) are forwarded to the
Qoder CN CLI, tool-result images are preserved as real image blocks with
provenance notes, and unsupported schemes are safely omitted without
crashing. Qoder CN preserves its existing sidecar classification so
text-only models continue to route through the vision sidecar.

Fixes #7516

* test(qoder): normalize assistant history fixture content parts

* fix(coding-agent): mark unsupported image references in single-turn and history

* fix(qoder): bound CN image input to verified stdin contract

Scope unsupported-reference markers to Qoder while preserving other coding-agent bytes. Keep existing sidecar and scaffold/replay guards; document the qoderclicn 1.1.70 evidence boundary.

Co-authored-by: WU, CHI-LUNG <215337896+chilung-cgu@users.noreply.github.com>

* docs(qoder): keep ownership updates with affected contracts

Preserve the canonical image contract and replay-owner updates; leave reviewed owners with unchanged local contracts untouched, as structure/AGENTS.md requires.

Co-authored-by: WU, CHI-LUNG <215337896+chilung-cgu@users.noreply.github.com>

* fix(qoder): validate bounded CN PNG bytes before CLI discovery

Require canonical base64 and minimal PNG signature/IHDR validation, with a
1 MiB decoded local resource ceiling. Preserve the fixed unsupported-input
event and cover malformed, mislabelled and oversized images before spawning.
Use real tiny PNG fixtures and document the validation and evidence boundary.

Co-authored-by: WU, CHI-LUNG <215337896+chilung-cgu@users.noreply.github.com>

---------

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
Co-authored-by: WU, CHI-LUNG <215337896+chilung-cgu@users.noreply.github.com>
…7586)

Adds confirmed POSIX Codex CLI updates with durable job status, a generation-owned selection gate and crash-safe recovery fences (base layer of the Codex CLI updater stack, issue #2811).

Exact head c061f78. Independent security review: PASS, 0 blocking. PR CI 40520432103 and lane=all 40524866481 passed on the exact head.

Co-authored-by: Epinephrine <luvs01@hanmail.net>
Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
* fix(startup): require desktop ownership before waiting

* fix(startup): verify native Desktop recovery before CLI cold start

* fix(startup): retain claimed Desktop waits on unsupported probes

* docs(desktop): align recovery limits across translations

* fix(desktop): bind recovery credit to active work and fresh process evidence

Track accepted startup generations and supervisor reservations separately from general runtime intent. Acquire reservations before publishing pending work, retain confirmed owned-child supervision, and revoke credit on terminal launch failure or guest-only attachment.

Classify failed macOS image-path reads with a separate signal-zero process observation; only ESRCH permits skipping a PID. Preserve unknown failures and scan cleanup.

Add focused regression coverage and update the recovery contracts.

* docs(structure): map Desktop recovery startup and supervisor sources

---------

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
Eligible native OpenAI models now also list a combined `<id>--fast[1m]` selector ("· Fast · 1M") in Claude discovery, for readable Claude Code ids and hashed Desktop ids, reusing the Fast row and 1M projection so eligibility, input ceilings and descriptions stay authoritative. Routed rows, tier policy and compaction policy are unchanged.

Co-authored-by: jbamlee <dev.jbam@gmail.com>
…ession/device IDs (#7838)

* docs(devlog): add 261028 oauth provider parity roadmap (wp0)

* fix(anthropic): align Claude Code 2.1.280 OAuth profile and isolate session/device IDs (wp1)
…unt switch, and align JSON token refresh (#7840)

* docs(devlog): add 261028 oauth provider parity roadmap (wp0)

* fix(anthropic): align Claude Code 2.1.280 OAuth profile and isolate session/device IDs (wp1)

* fix(codex): isolate pooled installation IDs, scrub turn-state on account switch, and align JSON token refresh (wp2)
…pool/JWT sub scope (#7842)

* docs(devlog): add 261028 oauth provider parity roadmap (wp0)

* fix(anthropic): align Claude Code 2.1.280 OAuth profile and isolate session/device IDs (wp1)

* fix(codex): isolate pooled installation IDs, scrub turn-state on account switch, and align JSON token refresh (wp2)

* fix(google,cursor): isolate Antigravity session/replay and Cursor H2 pool/JWT sub scope (wp3)
…nd deactivated exclusion (#7844)

* docs(devlog): add 261028 oauth provider parity roadmap (wp0)

* fix(anthropic): align Claude Code 2.1.280 OAuth profile and isolate session/device IDs (wp1)

* fix(codex): isolate pooled installation IDs, scrub turn-state on account switch, and align JSON token refresh (wp2)

* fix(google,cursor): isolate Antigravity session/replay and Cursor H2 pool/JWT sub scope (wp3)

* fix(oauth): harden multi-account pool cooldowns, affinity eviction, and deactivated exclusion (wp4)
…ence (#7599)

* fix(zed): relay OpenAI tool calls instead of ending on the first sentence

Zed's OpenAI delegate was parsed by the compaction-only Responses parser, which kept message text and dropped function and custom calls. Codex then stored that sentence as the final answer. Promote the current turn's additional_tools catalog into public tools so a follow-up is not rejected as an unknown input variant.

* fix(zed): dedupe completed messages and keep incomplete usage

A completed replay was compared with every message concatenated, so an earlier message was appended again. Incomplete responses also dropped usage that the adapter event already forwards.

* fix(zed): keep interleaved tool calls and promote current-turn tools

Adapter tool deltas are unkeyed, so starting a second streamed call ended the
first one and dropped every later delta plus its full arguments. That handed
Codex truncated JSON. Only the oldest open call is emitted now; newer calls stay
buffered and replay in order after the older call's own terminal event. EOF and
response.incomplete flush arguments that arrived, without inventing a tail from
a full field that no done item confirmed.

Zed configurations with statelessResponses or paired tool results run Responses
repair on the delegate body, which can drop a replayed reasoning item and slide
the current-turn additional_tools wrapper under the original prefix length.
Promote those wrappers on a detached copy of the raw body before the delegate
builds, so the caller's request stays untouched and the post-build lift is a
no-op.

The [OI] Zed stream also lost the compaction ciphertext the old parser carried.
Keep it on the done event with the same retained lease, and release it when the
terminal event is never yielded.

* fix(zed): charge retained stream buffers and correct the stream doc

Tool arguments, the optional full arguments field, and the text kept to suppress
a completed replay grew outside TranslatorBudget. A long or interleaved turn
could hold far more than the per-turn ceiling. Each call now opens a budget call
when it is first seen, every growth is charged, and closing the call releases
exactly what it still holds. Text is charged per item and per unscoped stream,
with superseded bytes released on every replacement. A finally block releases
the remaining calls, text and ciphertext when the consumer cancels or a read
throws.

The structure row said cancellation flushes buffered arguments. The code flushes
on end of stream and response.incomplete only, so the contract now says that.

* test(zed): cover cancellation with open tool calls

A consumer that stops mid-turn now has a regression: two calls are open, the
newer one's arguments are still buffered, and cancelling the iterator must
release both calls and every retained byte.

* fix(zed): preserve relay identity, truncation and bounded stream ownership

Keep semantic output behind active tools, reconcile call aliases, and stop
on terminal errors. Preserve partial tool status through all client encoders,
restore done-only text and shared usage projection, and scrub native diagnostics.
Budget argument snapshots, metadata and queued output with cancellation cleanup.

Co-authored-by: Andrew Wang <59988150+andrew05060414@users.noreply.github.com>

* style(zed): normalize relay file ending

* fix(zed): retain explicitly incomplete tool item status

* fix(zed): scrub native diagnostics and fence unfinished sidecar calls

* fix(zed): await authoritative tool status and terminate native errors

* fix(zed): filter failure usage and reject conflicting tool completion

Retain only known numeric usage counters on diagnostic terminals. Validate
authoritative function/custom snapshots against received and delivered bytes
before executable closure, including later speculative snapshots and deltas.
Close outstanding calls incomplete and replay queued semantic output before
the original failure. Port the independent review reproductions into the
registered suite and document the relay contracts.

Co-authored-by: Andrew Wang <59988150+andrew05060414@users.noreply.github.com>

* fix(zed): retain tool input authority and reconcile semantic arguments

Validate late custom input and function argument deltas against retained
authority regardless of parallel emission order. Preserve delivered bytes
while accepting equivalent JSON snapshots, fragmented late serialization,
and completed replays. Separate raw, custom, and semantic replay fingerprints.

Port independent review reproductions and add JSON/SSE, partial-prefix,
contradiction, numeric, replay, and budget regressions. Keep round-1 failure
usage filtering, queued output, and incomplete-call protections.

Co-authored-by: Andrew Wang <59988150+andrew05060414@users.noreply.github.com>

* fix(zed): compare ordered lossless JSON tokens incrementally

Replace parsed value equality with an iterative JSON scanner shared by
argument reconciliation, late-fragment validation and replay fingerprints.
Keep number literals exact, decode string escapes, preserve object key order,
and bound nesting at 65,536 containers with a clear failure above the limit.
Retain authoritative tokens and advance only over newly received fragments;
account for token and scanner storage and release it on every exit path.

Preserve empty parameter-free calls, custom input byte equality, diagnostic
usage filtering, queued failure output, and incomplete-call protections.
Add numeric precision, deep JSON, linear-work, escape, grammar and retention
regressions; document the conservative comparison contract.

Co-authored-by: Andrew Wang <59988150+andrew05060414@users.noreply.github.com>

---------

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
#7825)

* fix(service): explain elevated scheduler uninstall failures

* fix(tests): keep scheduler regression map below size limit

* docs(service): qualify the absent-task rule to the exit-code fallback

---------

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
…7830)

The WebSocket ingress finalizes its request log directly, so a proxy-generated upstream_reset_replay_refused 429 lost the replay-refusal provenance the HTTP deferred logger keeps and was recorded as a provider rate limit. The WebSocket handler now marks a replay-refusal response as transport-ambiguous with a synthetic terminal source before framing the error; a genuine upstream 429 keeps its rate-limit attribution. Documentation scopes this to direct provider routes; combo-rebuilt child failures do not yet carry the marker.

Refs #7720

Co-authored-by: Ingwannu <ingwannu@users.noreply.github.com>
Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
lidge-jun and others added 20 commits October 28, 2026 21:12
…7900)

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
…gation (#7903)

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
…7902)

* test: bound Windows recovery proof waits and drain failed fixtures

* test: require explicit Windows recovery cleanup proof

* test: retry Windows recovery probe exceptions

* test: give each Windows recovery probe only the remaining proof window

A probe that threw just before the deadline used to sleep and start another probe after it, which could block for 30s more and return proof after the 90s window. Check the deadline before every probe, cap the probe subprocess to the remaining time, and refuse proof that lands after the window. Clock injection replaces performance.now spies in the waiter tests.

---------

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
* fix(windows): reconcile proven pending CLI update children

* fix(windows): bound adopted child identities to native widths

---------

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
…7915)

* test: separate recovery PID evidence and budget cold Windows fetches

* test: make owner-evidence recovery read identity after the precondition warms the cache

---------

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
…canonicalize the history probe path (#7914)

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
…#7874)

* fix(restart): retire drained parent ownership and preserve bind scope

Restore replacement startup after completed drain without exempting live or unknown owners. Keep the responding probe address separate from integration bind policy.

Refs #7871

* fix(liveness): preserve default loopback bind across discovery

* test(server): preserve restart handoff diagnostics and descendant cleanup

* test(server): resolve restart fixture graph once before process handoff

* test(server): drain restart capture before fixture removal

* test(server): confine restart fixture cleanup to owned processes

Admit Windows fixture roles into a private Job before product loading and
terminate and join only its members. Retain the spawned parent handle and
output drain. POSIX roles stop themselves; recorded start identities are
used only for exit observation.

Add a controlled reused-PID refusal regression and an owned detached-child
cleanup control without changing the existing watchdog or role budgets.

* fix(grok): separate recovery probe destinations from bind policy

* test(restart): exercise stale identities and refused endpoints

* test(grok): assert ensure carries the observed bind scope and probe address

---------

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
…7875)

* fix(codex): preserve Windows updater release and observation contracts

Release owned locks after ACL-only verification failure while preserving identity fences. Retain exact directory identities, align private retention fixtures with OS temp, and correct the source map and localized managed conditions.

Partially addresses #7872; synchronous parent admission remains separate.

* fix(codex): release settled Windows apply owners after ACL diagnostics

* fix(codex): require verified lock absence before releasing owners

* fix(codex): bind Windows apply disposal to original held lock

* test(windows): report every failed review-fixture cleanup once without revisiting it

---------

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
…c budget (#7921)

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
)

* docs: generate the client support matrix from the client registries

Adds scripts/generate-client-support-matrix.ts, which builds a reference page for every docs locale from the export roster, the managed file integrations and the native integration union, and re-checks curated protocol and test claims against the code. A Bun test fails when a committed page drifts or a claim stops holding.

* docs: tighten client support matrix evidence checks

Test references ignore comments, every wildcard protocol branch must carry the field, native anchors must sit on code lines (Codex now anchors on the emitted base URL), and the curated definition says which rows make an endpoint claim.

* test: build the disabled-suite fixture at runtime

* test: check that every client support locale defines the root strings
Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
Keep rustup on the installed toolchain when HOME is sandboxed, retain compiler diagnostics, and use the existing bounded child-process budget.

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
* docs: generate the client support matrix from the client registries

Adds scripts/generate-client-support-matrix.ts, which builds a reference page for every docs locale from the export roster, the managed file integrations and the native integration union, and re-checks curated protocol and test claims against the code. A Bun test fails when a committed page drifts or a claim stops holding.

* docs: tighten client support matrix evidence checks

Test references ignore comments, every wildcard protocol branch must carry the field, native anchors must sit on code lines (Codex now anchors on the emitted base URL), and the curated definition says which rows make an endpoint claim.

* test: build the disabled-suite fixture at runtime

* test: check that every client support locale defines the root strings

* docs: lead with one local gateway for every coding tool

README hero and Connect your tool table, client-neutral docs home titles and JSON-LD in every locale, landing install scene and supported-tools link, and an English and Simplified Chinese quickstart that splits into a branch per tool.

* docs: translate the client-first README and quickstart

* docs: fix the Codex, Claude Desktop and landing connection steps

* docs: sync translated connection steps

* docs: drop the provider-first intro and add the Desktop and Grok refresh steps

* docs: note Grok integration and Codex autostart conditions for Grok Build refresh
…board (#7922)

* fix(gui): show provider connection and model tests on the served dashboard

The packaged dashboard talks to the proxy same-origin, so the provider workspace receives an empty API base. ProviderOverview and ProviderSettings treated that empty string as 'no server', which hid the Test connection button and the model completion test and skipped loading endpoint choices and request pacing status. Gate on an omitted base instead and cover the same-origin case.

* test(gui): assert the same-origin completion probe request body

* test(gui): assert same-origin settings render the loaded endpoint choices and pacing status
#7928)

* fix(claude): fail native Messages streams that end before message_stop

A native /v1/messages stream whose upstream closed cleanly after a partial turn was relayed as a finished 200 turn with no terminal or error event, and the request log recorded success. The stream tap now ends such a body with an Anthropic error event and logs a failed mid-stream turn, the same as a reset. A complete non-error stop_reason without message_stop still finishes the turn (as the translated adapter accepts), and providers with anthropicEofTolerance keep a content-only EOF. A done read after the client aborted is a cancel. The non-stream fold now handles CRLF and data-only frames.

* fix(claude): follow SSE last-event and CR-only framing in the native Messages tap and fold

* fix(claude): read SSE event names and multi-line data as clients dispatch them

* test: register the clean-EOF test in a layout shard

* docs(structure): clarify which Messages lane honors anthropicEofTolerance
* ci(macos): split suite across four weighted shards

* docs(ci): state macOS lane=all demand as at least six jobs that may queue

* docs(ci): only the setup-action leg follows a ci.yml change

---------

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • 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.

❤️ Share

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

@github-actions github-actions Bot added the intake: hygiene-blocked Deterministic PR hygiene checks failed label Oct 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Deterministic hygiene checks failed.

  • focused_or_skipped_test — A focused or skipped test was added. Restore the complete suite or obtain test-exception-approved. Paths: tests/helpers/codex-launch-private-fixture.ts.

@github-actions github-actions Bot changed the title release: promote frozen tip 9c33e4658 to main as 2.94.0 [WRONG BRANCH] release: promote frozen tip 9c33e4658 to main as 2.94.0 Oct 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⏳ DRAFT

  • wrong target branch (main); retarget to dev. UI screenshot required. hygiene: focused_or_skipped_test.

What to do

  • Retarget this PR to dev — all contributions go to dev.
  • Add a screenshot of the UI change to the PR description.
  • Fix focused_or_skipped_test — A focused or skipped test was added. Restore the complete suite or obtain test-exception-approved. Paths: tests/helpers/codex-launch-private-fixture.ts.

Its title has been prefixed with [WRONG BRANCH].
This pull request was already a draft. Its draft status will be preserved after every issue above is resolved.

expect(device.response.headers.get("Set-Cookie")).not.toContain(proof);
const record = JSON.parse(readFileSync(home.path("dashboard-sessions.json"), "utf8"))[0];
expect(Object.keys(record).sort()).toEqual(["credential", "digest", "expiresAt", "proof", "serverOrigin", "userAgent"]);
expect(record.proof).toBe(createHash("sha256").update(proof).digest("hex"));
type Scope = { home: string; rows: Map<string, Entry>; dirty: boolean; active: boolean; revision: number;
timer?: ReturnType<typeof setTimeout>; pending?: Promise<void> };
const owners = new Set<AnthropicSessionAffinityStore>();
const digest = (domain: string, value: string) => createHash("sha256").update(`${domain}\0${value}`).digest("hex");
Comment thread src/link/relay-auth.ts
export function linkConnectionProof(fingerprint: string, keyId: string, linkId: string, nonce: string, generation: string): string | null {
if (!isLinkConnectionGeneration(generation) || !linkRelayProof(fingerprint, "listener", keyId, linkId, nonce)) return null;
return createHmac("sha256", Buffer.from(fingerprint, "hex"))
.update(`opencodex-link-connection-v1\0${keyId}\0${linkId}\0${nonce}\0${generation}`).digest("hex");
Comment on lines +283 to +288
const masked = json.replace(JSON_STRING_OR_NUMBER, (raw: string, start: number) => {
if (raw.startsWith('"')) return raw;
const key = `${prefix}${numbers.size}`;
numbers.set(key, { start, raw });
return JSON.stringify(key);
});
// linear in the input, unlike growing the prefix and rescanning every string.
const base = "\u0000ocx-number:";
const usedTags = new Set<string>();
for (const [raw] of json.matchAll(JSON_STRING_OR_NUMBER)) {
@@ -226,11 +227,12 @@

let req: http2.ClientHttp2Stream;
try {
const credentialScope = createHash("sha256").update(opts.apiKey).digest("hex").slice(0, 16);
const h = createHash("sha256").update(`claude-code-session:${seed}`, "utf8").digest("hex");
const conv = typeof sessionKey === "string" ? sessionKey.trim() : "";
const input = conv ? `claude-code-session:${seed}:conv:${conv}` : `claude-code-session:${seed}`;
const h = createHash("sha256").update(input, "utf8").digest("hex");
}

function cell(text: string): string {
return text.replace(/\|/g, "\\|").replace(/\n/g, " ");
return raw.toLowerCase();
}
}
const h = createHmac("sha256", INSTALL_BODY_KEY).update(`${account}\0${raw}`).digest("hex");
const MAX_TURN_METADATA_BYTES = 32 * 1024;

function accountTagForUuidPrefix(account: string, prefix20Hex: string): string {
return createHmac("sha256", INSTALL_TAG_KEY).update(`${account}\0${prefix20Hex.toLowerCase()}`).digest("hex").slice(0, 12);
@lidge-jun

Copy link
Copy Markdown
Owner Author

Superseded by #7940 (new frozen tip dc75a3e including the #7938 ReDoS fix).

@lidge-jun lidge-jun closed this Oct 29, 2026
@lidge-jun
lidge-jun deleted the codex/promote-main-2.94.0 branch October 29, 2026 02:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

intake: hygiene-blocked Deterministic PR hygiene checks failed

Projects

None yet

Development

Successfully merging this pull request may close these issues.