Repository navigation
[WRONG BRANCH] release: promote dev de315e76ad to main as 2.87.0 - #7249
Conversation
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…7085) Co-authored-by: GOAT <goat@localhost>
* fix(codex): expose last Windows desktop build assessment * fix(codex): retain build observation across runtime restarts --------- Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>
…paths (#7058) * fix(protocols): enforce explicit empty tool catalogs across delivery paths * fix(protocols): preserve native inline and hosted MCP tools --------- Co-authored-by: Epinephrine <27862058+luvs01@users.noreply.github.com> Co-authored-by: GOAT <goat@localhost>
Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>
… colliding (#7089) * fix(usage): keep usage-ledger file ids exact so Windows NTFS ids stop colliding UsageLogRevision carried dev and ino as JS Numbers. NTFS file ids put a sequence number in their high bits and routinely exceed 2^53, so two different ledger files could round to the same Number and pass every identity check: the history indexer, the ingest tail guard, the cooperative ledger scanner and ledger retention would all treat a replaced ledger as the recorded one. This is what made the stale-ledger build case fail on Windows CI (#7070). Read dev/ino through bigint fstat (exactFileIdentity) and carry them as exact decimal strings end to end, including the schema_meta source identity, following the Aside profile precedent in #3842. Indexes written by an older build stored rounded values and rebuild once on mismatch. The stale-ledger test goes back to perturbing ino, now exactly, and asserts the revision matches bigint stats. * docs(usage): describe exact ledger file identity and index rebuilds * test(usage): cover colliding NTFS ids and legacy metadata reuse --------- Co-authored-by: jun <jun@juns-Mac-Studio.local> Co-authored-by: GOAT <goat@localhost>
…tion (ETXTBSY) (#7106) * fix(desktop): close atomic writer before publishing CLI files * test(desktop): exclude executable writers from concurrent forks Share a Unix test read/write lock between executable fixture writes and every synchronous subprocess spawn. Close-on-exec does not prevent a forked child from temporarily retaining a writer, which made direct shim execution return ETXTBSY during the CLI record lock stress test. Keep non-executable record writes and all four stress spawners concurrent, and assert that executable writes wait until spawn protection ends. * test(desktop): tolerate a poisoned executable-IO lock so one panic cannot cascade * test(desktop): isolate command deadlines from fixture spawn contention * fix(desktop): coordinate executable publication with production forks --------- Co-authored-by: jun <jun@juns-Mac-Studio.local> Co-authored-by: GOAT <goat@localhost>
…7084) (#7129) * fix(claude): verify Desktop backup and optional metadata reads * fix(claude): back up and roll back Desktop profiles from one verified read The gateway writer read the profile for foreign-key preservation, reread it for the backup, and reread the backup for rollback. A .bak swapped between replacement and rollback made rollback refuse, leaving the new profile beside the old metadata. One verified snapshot now feeds all three, rollback restores those bytes, and a profile created by the failed apply is removed so retries cannot accumulate unreferenced profiles. Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com> * fix(claude): refuse stale Desktop snapshots and retain rollback errors Revalidate verified profile bytes before backup and in the no-follow publication hook, refusing drift without retries. Keep metadata publication errors primary when profile restoration or cleanup also fails, and report both failures. Cover concurrent edits and rollback failures with regression tests. Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com> * fix(claude): roll back a Desktop profile only while it still holds our bytes When metadata publication fails, restore or cleanup now re-reads the profile through the verified reader and acts only if it still equals the bytes this apply published, using the same compare-and-swap helper that guards publication (also enforced before the restore rename). A profile another writer changed is preserved and the metadata error is reported with the rollback skipped. Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com> * docs(claude): describe ownership-aware Desktop profile rollback Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com> --------- Co-authored-by: Epinephrine <27862058+luvs01@users.noreply.github.com> Co-authored-by: GOAT <goat@localhost>
Co-authored-by: GOAT <goat@localhost>
#7142) * fix(cli): refuse uncertain ownership before publishing sibling runtime Carries #7119 (commit c5e17b5). Co-authored-by: fwkyle <cv271010@gmail.com> * fix(cli): isolate default-home owner discovery under test home guard Co-authored-by: fwkyle <cv271010@gmail.com> * fix(test): isolate owner registry under the armed home guard Resolve the guarded registry beneath the selected config home when its override is absent. Pin the sandbox registry for inherited children and reject protected paths for reads and retirement as well as publication. Co-authored-by: fwkyle <cv271010@gmail.com> --------- Co-authored-by: fwkyle <cv271010@gmail.com> Co-authored-by: GOAT <goat@localhost>
…allback model (carry #7123) (#7146) * feat(codex): route hard-locked main-account traffic to a configured fallback model The main-account hard lock (#5694) refuses requests once the 5h window reads its 90% threshold or the weekly window reads 98%, and a monthly-only account governs on monthly. On a single-account setup that refusal is the whole session: Codex Desktop and CLI turns fail until the window resets even though another provider in the same config could serve the turn. Add extended settings to the same feature: codexMainAccountHardLockFallback names a model and an optional reasoning effort, and while the lock blocks, a qualifying request is rewritten to that selector instead of failing. The rewrite is bounded on every side so it never widens what the lock protects: - It fires only while the lock reads blocked; release stays the same fresh observation that admits, so the reroute ends with the lock, on its own. - getEligiblePoolAccounts is the dispatch's own eligibility choke point, so a usable Pool account keeps the request on Codex; an empty eligible list is what makes the fallback the only way through. - Only bare Codex-native selectors qualify. Provider-qualified rows, combos, account namespaces, policy routes and thread spawns name their own destination on purpose; Luna Reserve keeps its own admission. - A Codex-native fallback target never applies -- rerouting gpt-* to gpt-* would re-enter the same refusal, so the honest behavior is the refusal. - A malformed section disables the reroute entirely, the same disable-don't-widen reading the compaction override takes. The management API projects the section in GET /api/settings, validates PUTs against a strict schema before mutation, and null clears it. The dashboard's main-account protection card grows the model and effort fields with the same acknowledged-write contract as the toggle. The usage log keeps reporting the selector the client asked for. * fix(codex): harden main-account hard-lock fallback routing and credential boundaries Pass the model's quota scope and respect Direct account mode when consulting getEligiblePoolAccounts so a pool account in a shared reset-derived cooldown or an unused pool under Direct mode cannot suppress the hard-lock fallback. Exclude nativeAlias combo selectors from source rewriting, reject canonical openai/<native> fallback targets alongside bare native ids, yield to non-combo shadow-call targets and compaction_trigger turns, mark credential-domain rewrites so caller ChatGPT headers and native reasoning ciphertext are stripped on fallback routes, preserve requestedModel and lane combo recall when routing to a fallback combo, include codexMainAccountHardLockFallback in Desktop compatibility routing preflight, and re-enable paused GUI fallback settings when picking a model. Co-authored-by: Blazetes <Blazetes@users.noreply.github.com> * fix(codex): register main-hard-lock-routing in core inventory and lazy-load fallback models Register main-hard-lock-routing.ts in RESPONSES_CORE_MODULES so the Responses core owner boundary suite includes it, and lazy-load /api/models in MainAccountHardLockSetting on fallback-control interaction so mounting the protection setting does not issue an unrequested background catalog fetch. Co-authored-by: Blazetes <Blazetes@users.noreply.github.com> --------- Co-authored-by: Blazetes <Blazetes@users.noreply.github.com>
* feat(cli): configure human usage model row limits (carry #6436) Port the usage --top idea from #6436 (bfcba56) onto the capability shards and model-search formatter. Preserve existing JSON, report totals and the default search view. Co-authored-by: 정우철 <86232509+oocheol@users.noreply.github.com> * fix(cli): report one bounded message for invalid usage --top Every invalid --top value now reports '--top must be an integer between 1 and 1000' through the shared integer parser's optional max, instead of '>= 1' for low or non-numeric values and a separate range message for values above 1000. Co-authored-by: 정우철 <86232509+oocheol@users.noreply.github.com> --------- Co-authored-by: GOAT <goat@localhost> Co-authored-by: 정우철 <86232509+oocheol@users.noreply.github.com>
* feat(codex): opt in to remaining included quota (carry #6629) Port #6629 from 2a7add5 onto current dev, retaining account policy and native refresh changes. Add opt-in coverage for entitlement, round-robin, automatic pause, reauthentication, and paid-credit refusal. Co-authored-by: Yuxin Qiao <104957188+Yuxin-Qiao@users.noreply.github.com> * docs(structure): place use-remaining CLI note in the account-policy section --------- Co-authored-by: GOAT <goat@localhost> Co-authored-by: Yuxin Qiao <104957188+Yuxin-Qiao@users.noreply.github.com>
…) (#7159) * feat(combos): require explicit consent for metered targets (carry #6839) Port the metered target and subscription-chain regression work from #6839 at 5428b42 onto current dev. Require configured-key opt-in for all callers, retain metadata on dashboard saves, and preserve structured runTurn failures. Keep the newer fresh-read quota recovery; omit the timer cap and unrelated effort/tier changes. Co-authored-by: 001005HS <99410048+001005HS@users.noreply.github.com> * fix(combos): refuse metered picks on collapsed combo routes without consent A subagent model fallback that names a combo alias is resolved by the router into one combo pick and dispatched outside the combo loop, so its metered-target filter never ran: a caller without allowMeteredComboTargets reached the metered target once the subscription target was cooling. captureInboundRoutePolicy, which every route on the Responses path passes through, now refuses a metered collapsed pick without consent. Docs state that a loopback bind reads no key, so metered targets need a keyed listener. Co-authored-by: 001005HS <99410048+001005HS@users.noreply.github.com> * test(responses): pin structured combo-child preflight limits The carry now forwards a runTurn adapter's structured status, type and code at the combo preflight boundary, so a Devin pre-output limit inside a combo child reaches the combo loop as a 429 rate_limit_exceeded instead of a generic 502. #5890 pinned the 502 only to keep its own non-combo change out of combo children; the pin now states the new contract, still without a Retry-After header, which the combo loop owns. Co-authored-by: 001005HS <99410048+001005HS@users.noreply.github.com> * feat(combos): add explicit loopback metered consent * fix(combos): keep runTurn child verdicts through combo failover A runTurn combo child already classifies its pre-output failure with adapterFailureFromEvent, but formatErrorResponse re-derived the type and code from the status. insufficient_quota became rate_limit_exceeded, losing its provider-wide cooldown and the client's quota verdict, and a 400 unsupported_input_modality became invalid_request_error, which now stopped the combo where dev's flat 502 had hopped to the next target. formatErrorResponse gains a classified option that keeps the caller's type and code while its spend-ledger, cyber-policy and replay-refusal overrides still win. Only the two combo-child blocks use it; consumeComboFailure re-applies the client allowlist before anything reaches a caller. Combo failover treats unsupported_input_modality as a target-local hop that cools nothing. Docs: an earlier 429/402 quota refusal outranks a later 400/401/403 when a metered-consent combo exhausts, and the modality hop is listed in every locale's combo guide. Co-authored-by: 001005HS <99410048+001005HS@users.noreply.github.com> * fix(bridge): keep message-read verdicts over a classified child code formatErrorResponse's classified mode let a runTurn child's generic code replace a cyber_policy verdict classifyError read from the full message. consumeComboFailure sees only the first 500 characters, so a refusal phrase past that point became a 502 that hopped to another provider. Cyber-policy, context-length and client-closed verdicts read from the message now outrank the caller's code. Co-authored-by: 001005HS <99410048+001005HS@users.noreply.github.com> * fix(bridge): let a classified child code fill in only what the message leaves open The previous guard pinned only cyber-policy, context and client-closed verdicts, so a coding-agent CLI's "Account quota exhausted" reported as a generic 502 upstream_error still lost its insufficient_quota verdict and cooled one target instead of the provider. The caller's code now applies only when classifying the message adds nothing to the status and type, so every message-read verdict (quota, cyber policy, context overflow, catalog size) outranks a generic adapter code. Cyber-policy and client-closed stay pinned. Co-authored-by: 001005HS <99410048+001005HS@users.noreply.github.com> * docs(structure): describe when a classified combo-child code applies Co-authored-by: 001005HS <99410048+001005HS@users.noreply.github.com> * fix(bridge): compare a classified child code against the status alone An untyped adapter event reaches the formatter with a type adapterFailureFromEvent already inferred from its message, so comparing against an empty message with that same type hid the message's verdict: a 502 upstream_error ending in "Authentication failed." lost invalid_api_key and cooled one target instead of the provider. The baseline now uses a neutral type, so a type or message verdict outranks a generic adapter code. Co-authored-by: 001005HS <99410048+001005HS@users.noreply.github.com> --------- Co-authored-by: GOAT <goat@localhost> Co-authored-by: 001005HS <99410048+001005HS@users.noreply.github.com>
#7160) * feat(pricing): support per-model prompt-length overrides (carry #6738) Port f098a98 onto dev 7640a94, retaining current topology/API-key reconciliation and test inventory entries. Co-authored-by: Valerio Coltre <2657230+colthreepv@users.noreply.github.com> * test(gui): drop an unused import from the price-cost contract test Co-authored-by: Valerio Coltre <2657230+colthreepv@users.noreply.github.com> * fix(pricing): preserve legacy policies and contain modal comparisons Reuse pure shared model-cost validators during OpenAI tier migration, preserve valid policies, and retain strict rejection of malformed rows. Keep the pricing comparison menu inside the native dialog and cover policy migration, CLI initialization, and modal selection regressions. Co-authored-by: Valerio Coltre <2657230+colthreepv@users.noreply.github.com> * docs(structure): keep the integration-tested merge wording Align structure/config.md, structure/gui-and-management-api.md with the tree verified before merge. --------- Co-authored-by: GOAT <goat@localhost> Co-authored-by: Valerio Coltre <2657230+colthreepv@users.noreply.github.com>
#7162) * feat(combos): enroll text-only members in vision sidecar (carry #4932) Port c9cda1b onto current dev, preserving atomic enrollment, runtime consumer classification and rename rollback. Keep new regressions in a registered sibling file. Co-authored-by: x3M3x <98298256+x3M3x@users.noreply.github.com> * fix(combos): close enrollment gaps found in review (carry #4932) - Send no visionSidecarTargets while a blocked member forces the image switch off, so a save never declares the remaining members text-only. - Reject enrollment of a model whose provider modelInputModalities hint lacks text instead of overriding it with a text-only declaration. - Update the MiniMax combo picker test to the sidecar-coverage contract. - Align pt/vi unavailable hints with English, revert an unrelated fr apostrophe change, and style the disabled-sidecar warning with the amber warning token. Co-authored-by: x3M3x <98298256+x3M3x@users.noreply.github.com> * perf(models): share registry enrichment across sidecar-consumer rows GET /api/models classified every row with isVisionSidecarConsumer, which rebuilds the registry-enriched provider per call (~0.1 ms/row, ~170 ms for a 2000-row listing). A per-listing classifier reuses the eligibility module's existing enrichment cache, so verdicts are unchanged. Co-authored-by: x3M3x <98298256+x3M3x@users.noreply.github.com> * fix(gui): use hash navigation for the sidecar dashboard link and a single modality pass Co-authored-by: x3M3x <x3M3x@users.noreply.github.com> * test(gui): pin sidecar-eligible members keeping the combo Image switch on Text-only and mixed image/text members are covered by the Vision Sidecar, so the switch stays enabled; unknown and audio-only members still force it off. The cached capability rows now carry visionSidecarConsumer. Co-authored-by: x3M3x <x3M3x@users.noreply.github.com> * fix(combos): validate the merged modelCapabilities map before enrolling sidecar members A provider already at the modelCapabilities cap accepted a valid one-entry patch and persisted an oversized map that load-time sanitization then truncated, dropping the new text-only declaration. The route now validates the merged map (400, nothing written) and re-checks it under the config lock. Co-authored-by: x3M3x <x3M3x@users.noreply.github.com> --------- Co-authored-by: GOAT <goat@localhost> Co-authored-by: x3M3x <98298256+x3M3x@users.noreply.github.com> Co-authored-by: x3M3x <x3M3x@users.noreply.github.com>
… (#7167) * feat(oauth): reset-first strategy for generic OAuth pools (carry #5408) Generic OAuth pools (Antigravity, xAI, Cursor, Kiro and the rest) can store and run reset-first under pool.kernel: the first attempt and a 429 rotation prefer the non-exhausted account whose weekly (else 5-hour) quota resets soonest, with headroom breaking ties. A passive provider with partial evidence keeps headroom order. The Anthropic kind still refuses it. The first-attempt pick uses the same eligible set as round-robin, so an Antigravity account whose model roster omits the requested model is not chosen. ocx account pool --strategy now accepts reset-first for generic pools as the server already does for ocx account strategy. Carried from #5408 (source head 2db9838). Co-authored-by: agentHits <140916359+agentHits@users.noreply.github.com> * fix(oauth): retain Kiro evidence in reset-first ranking --------- Co-authored-by: GOAT <goat@localhost> Co-authored-by: agentHits <140916359+agentHits@users.noreply.github.com>
…7171) * fix(oauth): print fixed CLI login errors instead of provider bodies * fix(oauth): keep standard error codes and namespace errors in CLI login failures Print an allowlisted RFC 6749/8628 error code next to the HTTP status, label unreachable or timed-out token endpoints, and report a Codex account namespace collision before the login starts instead of as a generic authentication failure. * fix(oauth): report namespace collisions as configuration errors in login The default ocx login path now prints only the public OAuth vocabulary, so the plain Error thrown for a provider name that collides with a Codex account namespace read as a generic authentication failure and broke cli-provider's login collision test. Throw a typed fixed-text error that the public message allowlist admits and label it configuration_error. * fix(oauth): classify wrapped xAI connection failures as network errors * fix(oauth): report Pool 2 preflight configuration failures safely * fix(oauth): guard Pool 2 at the shared CLI entry point --------- Co-authored-by: GOAT <goat@localhost>
Bun drops a TLS write callback still pending when the peer resets the socket. The armed drop resets the uploading client, so a chunk in flight at that moment left the pump unsettled and stop() hung until the 60s test timeout (macos 1/3, run 38699018462). Settle the pump on close as well. Co-authored-by: GOAT <goat@localhost>
…64 (#7181) * fix(codex): protect the desktop authority key in-process on Windows x64 Every protect/unprotect spawned Windows PowerShell and loaded System.Security, which cost seconds of cold start and exceeded the 20s bound on a loaded Windows runner. Call CryptProtectData/CryptUnprotectData through bun:ffi instead, with crypt32 loaded from the GetSystemDirectoryW path. Windows ARM64 keeps the PowerShell helper. Blobs stay compatible in both directions. * fix(codex): zero every unprotected DPAPI buffer and load kernel32 from System32 * fix(codex): free the DPAPI output buffer on every path after a successful call * fix(codex): wipe unprotected DPAPI output natively before freeing it --------- Co-authored-by: GOAT <goat@localhost>
…7188) * test(google): cover Argon thought separation across client protocols * docs: record completed Argon protocol investigation * test(google): exercise client-only summary opt-outs
* fix(codex): honor canonical subagent limits across modes Read and write the canonical Codex thread limit consistently with supported aliases. Keep the subagent selector available across modes, normalize child-count units, and reject stale settings responses. Cover canonical settings, mode behavior, and response ordering with focused regressions and update the capacity documentation. * test(codex): require canonical limit after atomic feature toggle Carry #7125 from 4bc4630. The write-lock regression must assert the canonical agents table after V2-to-V1 conversion, including absence of a legacy alias. Correct the API field name in the capacity contract. Co-authored-by: Epinephrine <27862058+luvs01@users.noreply.github.com> * docs(codex): name the thread-limit API field consistently * fix(codex): identify both agents limit keys in conflict warnings --------- Co-authored-by: Epinephrine <luvs01@hanmail.net> Co-authored-by: GOAT <goat@localhost> Co-authored-by: Epinephrine <27862058+luvs01@users.noreply.github.com>
* fix(catalog): preserve uncapped native maximum context windows * fix(catalog): preserve native selector maximums during normalization --------- Co-authored-by: GOAT <goat@localhost>
#7131) * fix(responses): strip provider item metadata on native OpenAI outbounds * fix(responses): scrub Google replay metadata from native compact --------- Co-authored-by: GOAT <goat@localhost>
) * fix(startup): launch Desktop by its registered app bundle path Launch Desktop from the bundle path recorded in its login registration, with matching installation ownership and fail-closed manual-open guidance. Preserve the app-bundle suffix refusal and explicit ownership fixture types. Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(startup): bind registered bundle launch to its main executable Reject relative launch registrations and non-file executable targets. Match CFBundleExecutable to the canonical registered Desktop binary before opening the recorded bundle. Exercise the actual macOS plist conversion without launching an app, and document manual recovery for inconsistent evidence. Co-authored-by: Epinephrine <27862058+luvs01@users.noreply.github.com> Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> * docs(ko): match the registered-bundle reopen condition in the Desktop guide * docs(ko): keep the Start at Login menu label * fix(startup): validate LaunchAgent paths with POSIX semantics Keep the macOS registration contract independent of the test host. Place fixtures on the caller's drive so Windows relative() cannot return an absolute cross-drive target, and assert the rejected path is truly relative. Exercise Windows drive paths and non-macOS command refusal explicitly. Co-authored-by: Epinephrine <27862058+luvs01@users.noreply.github.com> Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: Epinephrine <luvs01@hanmail.net> Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: GOAT <goat@localhost> Co-authored-by: Epinephrine <27862058+luvs01@users.noreply.github.com>
* fix(responses): frame retained compaction requests as history Preserve canonical replay history and original request details while framing retained plaintext requests only in translated and routed provider prompts. Native OpenAI passthrough remains unchanged. Co-authored-by: Robin Bially <7304732+robin-bially@users.noreply.github.com> * fix(responses): exclude local compaction from history framing --------- Co-authored-by: GOAT <goat@localhost> Co-authored-by: Robin Bially <7304732+robin-bially@users.noreply.github.com>
#6759, #6930, #6603, #6758) (#7217) Carried from #6759, #6930, #6603, #6758 (one commit per source PR, original authors preserved). Retention across account/model switches is opt-in and defaults off. Remote validation (hosted GitHub Actions unreliable; local tests not run by maintainer rule): union candidate codex/prr-integ-8 = dev c03eafd + #7224 + #7223 + #7225 + #7217 + #6454 + #6594 plus a Gentle Shell import-cycle fix (integ-9 e1f289c: typecheck + full suite on mini (Windows) and lidge (Linux), compared with the same host's dev runs) and a test-only Windows path-escaping fix for the reasoning-retention routing test (integ-10 0d4cba7, tree a2b309a: that file re-run on both hosts). Co-authored-by: fliaping <269832017@qq.com> Co-authored-by: panyuanyuan <panyuanyuan@hetao101.com> Co-authored-by: yuanyuanlove <yuanyuanlove@users.noreply.github.com>
…modules) (#6454) Contributed by @lcxhh521; refreshed onto dev by the maintainer (dev merge, deferred quota account-row edge to keep the cycle baseline from growing). Remote validation (hosted GitHub Actions unreliable; local tests not run by maintainer rule): union candidate codex/prr-integ-8 = dev c03eafd + #7224 + #7223 + #7225 + #7217 + #6454 + #6594 plus a Gentle Shell import-cycle fix (integ-9 e1f289c: typecheck + full suite on mini (Windows) and lidge (Linux), compared with the same host's dev runs) and a test-only Windows path-escaping fix for the reasoning-retention routing test (integ-10 0d4cba7, tree a2b309a: that file re-run on both hosts). Co-authored-by: lcxhh <lcxhh521@gmail.com>
…59 -> 35) (#6594) Contributed by @lcxhh521 (stacked on #6454); refreshed onto dev by the maintainer. Remote validation (hosted GitHub Actions unreliable; local tests not run by maintainer rule): union candidate codex/prr-integ-8 = dev c03eafd + #7224 + #7223 + #7225 + #7217 + #6454 + #6594 plus a Gentle Shell import-cycle fix (integ-9 e1f289c: typecheck + full suite on mini (Windows) and lidge (Linux), compared with the same host's dev runs) and a test-only Windows path-escaping fix for the reasoning-retention routing test (integ-10 0d4cba7, tree a2b309a: that file re-run on both hosts). Co-authored-by: lcxhh <lcxhh521@gmail.com>
…trols (#7211, #7212, #6381, #7172, #6152) (#7222) Carried from #7211, #7212 (both opened against main; carried onto dev), #6381, #7172, #6152 (one commit per source PR, original authors preserved). Custom provider routing consent defaults to No and the CLI update plan is read-only. Remote validation (hosted test shards passed on the head; local tests not run by maintainer rule): exact head b4d6376 (contains dev 7a42860) typecheck + full suite on lidge (Linux) and mini (Windows), compared with the same host's dev 7a42860 runs. Security review of the #7172/#6152 carries: PASS. Co-authored-by: Matt Van Horn <mvanhorn@users.noreply.github.com> Co-authored-by: lcxhh <lcxhh521@gmail.com> Co-authored-by: xianlubird <xianlubird@gmail.com> Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>
Restore the keep-native row that #7220 removed, while keeping its uniform settings rows and the auto-review override. Standard rows span the grid. Only the v2 qualifier sits in the right column, with a single-column fallback below 1160px. The four keep-native-v1 GUI tests that fail on dev 4ed45e9 pass on this head. Co-authored-by: sechmachine <97589681+sechmachine727@users.noreply.github.com> Co-authored-by: Jonathan Li <47408717+jonathanli12@users.noreply.github.com>
API-key cooldown from a 401/429 is now charged only to the distributed key that was actually sent. Ownership is captured at the physical fetch on native Responses, compact, Chat and Messages. Requests whose credential was changed after selection no longer cool down a pooled key. Configured same-key 429 retries are unchanged. Co-authored-by: GSL-R <174104911+GSL-R@users.noreply.github.com>
On Windows, homedir() follows USERPROFILE. The owner-registry and service-state isolation fixtures changed that variable to a worker home while still expecting the registry and mirror seeded in the startup home. The fixtures now keep the default home stable while switching OPENCODEX_HOME, and every existing assertion is retained. Product behavior is unchanged.
…ns (#7238) #7216 added native wire pins for OpenCode Go Gemini and Qwen models. An existing config with a formerly valid override, such as modelAdapters["qwen3.7-plus"] = "openai-chat", then failed validation, and the whole saved config fell back to defaults. Both the runtime load path and diagnostics now normalize these overrides before validation, so the native pin wins and providers, accounts and routing survive. Strict validation still applies to new writes and malformed values. Co-authored-by: Georgiy Bukharov <souljorje@gmail.com> Co-authored-by: norths7ar <guicaitiandu@gmail.com>
The import-cycle scanner now canonicalizes its root before scanning. Bun resolves import targets to physical paths, so on macOS (/var -> /private/var) and under any symlinked root, cycle edges pointed at missing nodes and directory-index cycles went unreported. Adds symlinked-root coverage for ts, tsx and mts directory indexes. Co-authored-by: lcxhh <lcxhh521@gmail.com>
#7239) When a translated combo compaction fails over to a canonical native target, the readable reasoning withheld before compaction is now returned after the native compaction item, or as an archive notice whose file survives a successful replacement. Previously it was dropped and its archive deleted. Cleanup on failure and cancellation is unchanged. Co-authored-by: panyuanyuan <panyuanyuan@hetao101.com> Co-authored-by: yuanyuanlove <yuanyuanlove@users.noreply.github.com>
A Windows Claude Desktop picker that started with intent off previously returned 503 picker_proxy_unavailable on a later enable. The controller now stays dormant and binds the picker relay under its enable lock after the mode, integration and preference checks. Startup stays relay-, timer- and credential-free while intent is off. Concurrent enables share one relay, and shutdown closes it. Co-authored-by: hyuntae park <bluestar218ht@gmail.com>
Rust 1.99 clippy (-D warnings) rejects the hand-written no-op waker in the desktop process_spawn test, which failed the desktop shell job on main and dev. The test now uses std::task::Waker::noop(), stable since Rust 1.85, under the crate's Rust 1.88 minimum.
Approved custom Codex provider injection now rechecks the persisted integration intent under the Codex/config locks, so it can no longer undo integration OFF. Approval-record inspection, stale native-journal cleanup and URL publication share one write section, which fixes an unlocked read that #7222 added. The shared Codex config write lock now records the destination inode after acquiring the lock. Before, a writer that replaced the file just ahead of acquisition left a stale witness, and concurrent syncs failed. ocx usage compare binds both windows to one connection, usage owner, destination and credential fingerprint, and aborts with a retry message when they differ. Co-authored-by: Matt Van Horn <mvanhorn@users.noreply.github.com> Co-authored-by: xianlubird <xianlubird@gmail.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Important Review skippedToo many files! This PR contains 1000 files, which is 700 over the limit of 300. To get a review, reduce the PR to 300 files or fewer by splitting it into smaller PRs or changing its base branch. Usage-priced reviews support at most 300 files. ⚙️ Run configuration
⛔ Files ignored due to path filters: 1
📒 Files selected for processing: 1000
You can disable this status message by setting the
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
⏳ DRAFT
What to do
Its title has been prefixed with |
| if (provider.authMode === "oauth" || provider.authMode === "forward" || !provider.apiKey) return; | ||
| if (!provider.requestPacing?.enabled || (!provider.requestPacing.keys && provider.requestPacing.keySelection !== "round-robin")) return; | ||
| // Internal only: duplicate references share one bucket; never serialize a key or digest. | ||
| return createHash("sha256").update(provider._apiKeyAttempt?.reference ?? provider.apiKey).digest("hex"); |
| const MAX_ENTRIES = 2_000; | ||
| const bindings = new Map<string, { accountId: string; lastUsedAt: number; selection: OAuthAccountSelection }>(); | ||
| const prefix = (provider: string) => `${JSON.stringify([getConfigDir(), provider])}\u0000`; | ||
| const key = (provider: string, session: string) => prefix(provider) + "session:" + createHash("sha256").update(session).digest("hex"); |
| headers: { Location: "https://evil.example.com/steal" }, | ||
| }); | ||
| } | ||
| if (url.includes("evil.example.com")) { |
| headers: { Location: "https://evil.example.com/steal" }, | ||
| }); | ||
| } | ||
| if (url.includes("evil.example.com")) { |
| const priorWarnings = process.env.NODE_REDIRECT_WARNINGS; | ||
| process.env.NODE_OPTIONS = "--require=evil"; | ||
| process.env.NODE_PATH = "C:\\evil-modules"; | ||
| process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; |
| let url: string; | ||
| if (provider.authMode === "forward") { | ||
| const mayForwardCallerCredentials = isCanonicalOpenAiForwardProvider(provider); | ||
| const baseUrl = mayForwardCallerCredentials ? CODEX_FORWARD_BASE_URL : provider.baseUrl.replace(/\/+$/, ""); |
| } catch { /* Token fingerprint is the fallback when CLI has no account metadata. */ } | ||
| const seed = nonEmpty(account) ? account : nonEmpty(credential.refresh) ? credential.refresh : undefined; | ||
| if (!seed) return null; | ||
| return { key: createHash("sha256").update(seed).digest("hex"), access: credential.access }; |
|
Maintainer disposition before the owner-authorized promotion merge:
|
…7252) The carry-attribution window is capped at 80 characters and could cut a reference in half. The #7223 subject "carry ... (#7195, #6767" was read as #676, an unrelated PR, so the hygiene gate demanded a co-author trailer for the wrong person (seen on the 2.87.0 promotion #7249). When no sentence boundary falls inside the window, the window now finishes a number that started before the cap. Sentence and newline bounds, qualified-reference handling, and the exclusion of references that start after the cap are unchanged.
Summary
This promotes the frozen
devcandidatede315e76ada18b69753ff79b77572093c7097456tomainas stable 2.87.0. The promotion head447c58ab28merges inmainancestry with theoursstrategy, and its tree is exactly the candidate tree (ac68eedc51). The candidate already sets the version to 2.87.0 in package.json, desktop tauri.conf.json, and Cargo.toml. The dev pre-move is #7248 (dev → 2.88.0), merged before this promotion.2.87.0 carries the PR-reduction round (15 integration merges, 4ae4936..4ed45e9) plus the regression fixes found by post-release-candidate verification of that round:
ocx usage comparebinds both windows to one owner, and the shared Codex config write lock no longer fails concurrent syncs (feat(cli): carry usage comparison, log history, restart and Codex controls #7222 follow-up).manual_noop_wakerlint in the desktop shell.Round highlights (carried with contributor co-author credit): Zed/Qoder/OpenCode Gemini compatibility (#7216), catalog Ultra Fast discovery and vision sidecar (#7220), Advisor retention and adaptive consultation (#7219), opt-in API-key round-robin and per-key pacing (#7135), compaction capabilities and reasoning retention (#7217), Combo visibility, workspace panes, Windows picker and Gentle Shell (#7223), OAuth combo cooldown and rotation fixes (#7224), translated-lane Claude server tools (#7225), CLI usage comparison, log history and restart controls (#7222), and import-cycle reductions (#6454, #6594).
Verification
de315e76ad: manual Cross-platform CIlane=allrun 38893394441 completed with success (32 success, 3 skipped). That includes windows 1–9/9, macos 1–3/3, macos control, Linux test 1–4/4, gates (GUI) and desktop shell. Service lifecycle run 38893397839 succeeded on the same SHA.release.ymlruns as a dry run, then live withexpected-shaset to that SHA.Main-review disposition. Promotion from
devtomainand npm releases are maintainer-controlled (MAINTAINERS.md). The project owner authorized this release as 2.87.0, so the promotion merges with owner authority (--admin). The PR targetsmaindeliberately, so anenforce-targetwrong_base failure is expected (as in #7094 and #7110).Checklist