Repository navigation
[WRONG BRANCH] release: promote frozen tip 47f9e2dc42 to main as 2.98.0 - #8267
Conversation
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* security(desktop): bump tauri-plugin-updater to 2.14.1 for zip CVE-2026-115905 zip 4.6.1 (critical Zip Cloaking / arbitrary file overwrite) reached the Windows update-extraction path via tauri-plugin-updater 2.9.0, which requires zip ^4. The fix needs updater >=2.14.1 (zip ^9) and tauri ^2.12, so the exact-pin chain moves together: tauri 2.12.5, tauri-build 2.7.4, tauri-utils 2.10.2. Lockfile regenerated; zip resolves to 9.1.3 and the refresh also picks up rustls 0.23.46 (dependabot alerts #5-#8). Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> * ci: run the full Ubuntu shards on this head --------- Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: JUN <jun@lidgeai.com>
* fix(service): pin resolved homes in service definitions * fix(service): address review findings on pinned homes * test(service): move pinned-home cases to a sibling file * fix(service): resolve systemd unit homes once * fix(doctor): read admission fields from any doctor error status * fix(service): escape pinned homes for each service definition syntax systemd ExecStart writes $ as $$ and % as %%; launchd live-job comparisons include the pinned home assignments; Task Scheduler quoted set values keep ^ literal. * fix(service): derive launchd expected homes from the installed plist and encode plist control characters Status and start now take the pinned homes from the installed plist, then install state, and fall back to the current environment only when neither records them. Plist strings write CR, LF and tab as character references and refuse characters XML 1.0 cannot represent. * test(service): tighten review coverage for pinned homes * fix(doctor): read native-main admission from a side-effect-free route The local read capability allowed GET /api/native-main-profiles/doctor so ocx doctor could report the proxy admission gate. That endpoint runs the profile doctor, whose staging sweep can remove expired stages, and returns the effective Codex home and active profile id. Add GET /api/native-main-profiles/admission, which returns only the startup gate admissionStatus and admissionBlockReason without constructing a profile manager, and allowlist that route instead of the doctor. ocx doctor reads it and treats any non-200 answer, including 404 from an older proxy, as unavailable. * fix(service): decode the tab and CR escapes the systemd writer emits The unit writer escapes tab and carriage return in Environment= values, but the ownership parser rejected both, so one such value anywhere in the unit (a home or a proxy variable) made the whole definition unknown and could fence native-main admission as ownership-unknown. Decode both, and keep the unsupported-escape case covered with a hex escape the writer never emits. * fix(service): compare loaded launchd jobs against the installed homes The expected launchd command took its pinned homes from the installed plist but still built the service token path from the caller OPENCODEX_HOME, so status and start from a shell exporting another home read a healthy job as stale. Restart compared against the caller homes outright, so a successful kickstart from such a shell was reported as a failure. Derive the token file from the pinned OpenCodex home, and resolve the homes for every comparison against a loaded job (status, start, restart) from the installed plist, then the recorded install state, then the current shell. * fix(service): keep the service token path under the pinned home The Windows task wrapper now writes OPENCODEX_HOME as an absolute literal, but still rendered OCX_API_TOKEN_FILE through profile-variable indirection, so a task running with another USERPROFILE could read its token from a different profile than the home the proxy is pinned to. Write the token path as a literal too. Derive the launchd token path through a definition.ts helper built on serviceApiTokenFilePath, so the secret-handling module stays untouched. * fix(service): pin the Windows wrapper log and sqlite paths to the homes The task wrapper writes CODEX_HOME and OPENCODEX_HOME as absolute literals, but still rendered OCX_SERVICE_LOG and CODEX_SQLITE_HOME through profile-variable indirection, so a task running with another profile could log, or keep Codex state, outside the pinned homes. Write both as literals. * fix(registry): exempt the admission route as a deferred verb The capability/route parity test requires every management route to be capability-covered, exempt, or ratcheted. GET /api/native-main-profiles/admission is read only by ocx doctor, which is not a registry verb, so record it as a deferred verb owned by native-main admission with structure/codex-home.md as its tracked doc. --------- Co-authored-by: Omar <13569609+omar391@users.noreply.github.com> Co-authored-by: JUN <jun@lidgeai.com>
…low dashboard tests (#8125) * fix(qoder): give live model discovery a 30 s bound (#8115) * fix(qoder): answer catalog requests within 8 s while a slow discovery finishes in the background * fix(qoder): keep the 30 s bound for background discovery and report a slow dashboard test as still discovering (#8115) * fix(qoder): bind shared discovery to the cache generation and let a late success replace a fresh roster (#8115) * fix(qoder): expire finished discovery flights so revoked generations do not accumulate (#8115) * fix(qoder): drop pre-eviction gathers and retry a busy re-sync after a late discovery (#8115) * fix(qoder): keep the cached roster until a late discovery is stored (#8115) * docs(qoder): running Codex sessions keep their model list until restarted (#8115) * docs(qoder): point running Codex sessions at ocx system codex-restart (#8115) * docs(qoder): discovery runs are shared per provider and token (#8115)
* fix(kiro): emulate structured output instead of refusing it Kiro has no schema-constrained response mode, so the adapter refused text.format json_schema/json_object. That broke every caller asking for a small JSON answer: T3 Code titles each thread through a Messages output_config.format request, and Claude Code's own structured-output calls take the same path. A structured-output turn now advertises a private terminal tool whose input schema is the caller's format, and relays the call's input as the assistant's JSON text. Non-object or composed roots are wrapped under value. The client receives JSON that parsed and passed a light root check, or a non-retryable error after one bounded retry; prose never reaches a structured-output caller. * fix(kiro): retry structured output only after a clean stop Review follow-up. A failed structured answer under MAX_TOKENS, a content filter or an exhausted context window now keeps that stop's own terminal instead of retrying into the same limit or verdict. The bounded retry accepts JSON text only after a clean stop as well, and an empty or reasoning-only retry ends with the non-retryable invalid_kiro_structured_output failure rather than a retryable empty fallback. Also maps src/adapters/kiro/ to the Kiro structure doc. * fix(kiro): end a malformed structured retry without a replay Review follow-up. A bounded retry whose structured tool input is malformed (for example truncated JSON) returned the retryable malformed_kiro_completion, so a client could replay a turn that had already used its one retry. Structured-output turns now end with the non-retryable invalid_kiro_structured_output; ordinary completion behavior is unchanged. * fix(kiro): retry a truncated structured answer like an invalid one Review follow-up. A first-attempt structured tool call whose input is truncated JSON failed the completeness check before structuredRetry was set, so it ended with a non-retryable invalid_kiro_completion after one request instead of the documented bounded retry. It now takes the same path as an input that fails to parse: one retry on a clean stop, and the stop's own handling (for example max_output_tokens) otherwise. * fix(kiro): retry a structured call left open at end of stream Review follow-up. When the stream ended with the private structured-output call still open and its input incomplete, the end-of-stream guard returned invalid_kiro_completion before flushOpen could schedule the bounded retry. A required-mode structured call now goes through flushOpen there, so it retries on a clean stop and keeps max_output_tokens under MAX_TOKENS. Every other open call keeps the guard's terminal, and the retry itself still ends non-retryably. * docs(kiro): document the functions the structured-output change touches CodeRabbit's docstring-coverage pre-merge check (80% of touched functions with branches) reported 52%. Adds doc comments to the touched adapter, stream, wire, conversation and structured-output functions and to the test helpers; no behavior change. * fix(kiro): validate strict structured output, keep wrapped refs and schema literals Strict json_schema formats are now validated against the whole schema (OpenAI strict subset plus simple bounds), and a strict schema with an assertion the emulation cannot check is refused before sending. Wrapping re-points root-relative $ref targets at #/properties/value, and Kiro schema sanitization copies const, enum, default and examples verbatim. * fix(kiro): bound strict structured-output validation to an exact subset Strict schemas are prepared once at the boundary into a validation graph. $ref is limited to root $defs/definitions, empty reference cycles are refused, and one visit budget and depth limit apply per value. Numbers are compared by their original text, multipleOf must be a positive integer, and pattern is compiled at the boundary with backreferences and repeated quantified or alternating groups refused. The wrapped strict form relays the original bytes of value. * fix(kiro): refuse strict numeric const/enum, multipleOf and regular expressions * test(kiro): use a string const in the strict rich-schema fixture * fix(kiro): bound strict schema preparation and literal checks, keep diagnostics content-free, relay wrapped bytes, drop prose on a filtered retry * fix(kiro): charge every per-node loop, decode $ref before matching, refuse nested $id and anchors * fix(kiro): charge number checks, refuse repeated types and schema-less strict formats, keep wrapped refs and depth exact * fix(kiro): linear decimal normalization, decoded wrapping pointers, nested $id boundaries, retry an empty clean first response * docs(kiro): an empty clean first response takes the bounded retry * fix(kiro): hold Messages schemas to full conformance, bound exponent work, keep definition-container refs, refuse invalid pointer escapes, fixed stop diagnostics --------- Co-authored-by: JUN <jun@lidgeai.com>
) * Serialize config ownership manifest updates * fix(config): record owned paths lock-free so concurrent processes keep each other's entries (#8093) * fix(config): serialize uninstall manifest updates under one cross-process lock (#8093) * docs(structure): document the config ownership lock and uninstall tombstone * fix(config): refuse cached registrations during uninstall and finish a lock-only home (#8093) * fix(config): keep the manifest under its byte limit and resume an uninstall stopped after the manifest (#8093) * fix(config): let a tombstoned manifest use the reserve so an upgraded near-limit home resumes uninstall (#8093) * fix(config): check ownership metadata size before reading it (#8093) * fix(config): clean abandoned manifest temp files and create the manifest before the owner marker (#8093) * fix(config): keep the config path out of the uninstall refusal and skip crash logging during uninstall (#8093) * fix(config): let the uninstaller register its own cleanup state on a tombstoned rerun (#8093) * fix(config): never cache a tombstoned manifest for the registration fast path (#8093) * fix(config): concurrent first registrations on an absent home load the winner metadata (#8093) * fix(config): fail the ownership lock fast instead of blocking, and finish a rerun whose cleanup recreated an owned file (#8093) * fix(config): keep late paths for a rerun, gate owner-only recovery on uninstall evidence, accept listed paths under a busy lock (#8093) * fix(config): hold the ownership lock for the whole uninstall, refuse registrations while it finishes, remove an unlisted OAuth backup (#8093) * fix(config): resume an interrupted uninstall from its tombstoned manifest, recover lock files under the lock, defer OAuth migration when its backup cannot be registered (#8093) * fix(config): refuse cached registrations once the owner marker is gone, record new teardown paths in a stopped uninstall, skip the OAuth backup on a full manifest (#8093) * fix(config): bounded recovery reserve and no adoption under any tombstone, unlink dangling listed symlinks, claim a cached-unowned home once empty, bound skipped log rotations (#8093) * fix(config): remove an abandoned manifest temp file only when its content is this home manifest (#8093) * fix(config): clear a lock-only leftover home only when its lock files are empty and the lock file is among them (#8093) * fix(config): unlink the ownership lock while holding it, remove only empty lock sidecars, qualify the teardown exception in docs (#8093)
* fix(config): remove owned paths relative to the config root Uninstall resolves each manifest entry from the canonical config root and removes it only while every directory on the way is a real directory at its root-relative location; otherwise the entry stays in place and is reported as a residual path. A recorded link is unlinked itself. When uninstall runs elevated, it requires the config root and the directories it removes from to belong to the running account, and otherwise refuses the whole run before its first teardown step. * docs(cli): describe uninstall's elevated-run refusal and remaining linked entries The uninstall reference now says that an elevated run stops before changing anything when another account can change the config directory or the directories above it, and how to proceed, and that an entry under a linked parent directory is left in place and listed as a remaining path. Translated pages carry the same note. * fix(config): check the whole config tree before an elevated uninstall An elevated uninstall now also refuses when another account can change any directory in the config tree, or when a link anywhere in the tree leads outside the config directory, because teardown steps that run before the remover read and write files throughout the tree. The remover uses the canonical root it resolved at the start for every step and confirms it is unchanged before temp cleanup, metadata removal and the final rmdir. * fix(config): keep uninstall on the config root it resolved first The remover records the config root's device and inode when it resolves the root and confirms the root is still that directory before the lock, the tombstone, each entry, temp cleanup, metadata removal and the final rmdir. A change found before the tombstone is refused with nothing written; a later one ends the run partial. For an elevated run, every link in the config tree is resolved the same way as the given path, so each directory and link on the way must be closed to other accounts; a link may also point at the config root itself. On Windows an elevated run accepts no link in the tree. * fix(config): accept links to files inside the config tree in elevated runs Resolving a link in the config tree now allows its final target to be a regular file inside the tree; directories along the way are still checked. * fix(config): follow longer link chains and read large Windows trees in batches An elevated uninstall now follows link chains up to the 40 links Linux resolves, and reads a Windows config tree's ACLs in batches of up to 256 paths with a deadline each, so neither a valid chain nor a large tree is refused. * fix(config): compare walked paths by their resolved spelling On a case- or normalization-insensitive volume, an elevated uninstall no longer refuses a config path or an in-tree link spelled differently from how the volume stores it: the path built by the trusted walk is compared after resolving its spelling. * test(config): cover every Windows ACL batch; correct the root-change refusal note Adds a case where the first ACL batch passes and a later one does not, and states in structure/config-ownership.md that a root change found under the lock can leave the ownership lock file in place.
* fix(codex): validate legacy shim restore paths before restoring The Windows Codex shim record (codex-shim.json without schema or mode) names the launcher files that uninstall, auto-restore and install refresh unlink, rename and rewrite. Those paths were used as stored. Every consumer now checks the record first, on every run: - paths are absolute, normalized drive paths in one directory; - launcher names and the .opencodex-real backup name match the layout an install writes, including the earliest codex.cmd-beside-original form; - the directory resolves through real directories only, launchers are regular files and a backup is a non-empty file that is not itself a shim. Uninstall acts inside the resolved directory and checks it again before each unlink and rename. A record that fails is reported as needing manual restore with its files left as they are; ocx uninstall then counts the step as failed and keeps the config, ocx codex-shim uninstall exits 1, and the machine API reports success false. A fresh install applies the same rules to the targets it discovers. A record from another platform changes no launcher file, as before. * fix(codex): keep Windows shim refresh inside the validated directory - Launchers in one record must share the exact directory spelling. - Every Windows shim rename, link, unlink and write made by install, auto-restore or refresh first checks that the recorded directory still resolves to the directory that was validated. - A launcher that shares its file with another path is refused, and the Windows wrapper writer never writes through a link or a shared file. - Explicit install refuses when a record is present but unreadable, instead of treating it as absent and installing over it. * fix(codex): guard every Windows shim rename, unlink and link The Windows shim modules now import guarded rename, unlink and link calls instead of the node:fs ones, so each mutation made during install, auto-restore, refresh, cleanup and rollback first checks that the record directory still resolves to the one that was validated. Outside a guarded operation the calls behave as before. * fix(codex): tighten Windows shim checks from review - Compare the launcher directory by device and inode as well as by path, so a directory replaced at the same path is refused. - A fresh install refuses an empty launcher instead of recording a backup that every later restore refuses. - Auto-restore returns the manual-restore message when the replacement path refuses the record, instead of a silent deferral. - Read the wrapper with a bigint lstat, as the file identity rules require. - Narrow the structure note about failed records.
* feat(providers): list Perch as a reference-only directory entry Perch's free Starter plan is reachable only through its own Web, Desktop and CLI clients, and no registered operating entity could be found for it. Per MAINTAINERS.md, incomplete evidence gets an inert reference row: no base URL, no adapter, no discovery, unverified. * test(providers): pin the Perch row to reference only The PR hygiene gate requires coverage when behavior under src/ changes. Assert the generated row keeps an empty base URL, no discovery and no verification date.
…rs (#8153) * Normalize Messages error responses and Anthropic headers * Normalize Messages overflow responses and success headers Restore compaction wording from original overflow evidence while retaining throughput exclusions and existing status, type and code decisions. Render successful passthrough media types from closed media and charset tables. Add executable baseline-versus-current native stream fixtures alongside buffered lane regressions and document the response contracts. * Refine Messages overflow verdicts and stream parity fixtures Use original error evidence for compaction presentation and preserve the existing status, type and code decisions. Retain original adapter fields separately from shared terminal classification. Compare native streams with a generated baseline golden during tests, keeping git history access in the explicit fixture generator only. * Preserve Messages overflow decisions in normalized errors Select compaction wording from the existing native, translated and direct path verdicts. Match the client phrase predicate for buffered passthrough Messages and count_tokens replies. Add a baseline decision golden across all Messages paths and bind the unchanged shared predicate and its behavior suite to their source bytes. * fix: preserve Messages client recovery outcomes Select normalized overflow wording from each path's baseline client message while retaining its status and internal decisions. Compare actual recovery recognition and status against regenerated baseline outcomes on every lane. * fix: normalize Messages envelope shapes and reset dates Preserve success bodies and baseline client recovery outcomes across relayed and incomplete error shapes. Retain millisecond precision in reset dates and extend the baseline comparison to cover the accepted envelope variants. * fix: preserve passthrough 2xx bodies and reset precision Normalize only non-2xx passthrough bodies and compare 2xx replies byte for byte with baseline. Record literal case classifications and retain full validated reset fractions through integer UTC calendar conversion. * fix: project collected Messages errors by event identity Record error-event dispatch independently of payload parsing and use it in native fold and raw collection. Preserve original status and recovery outcomes, and verify all payload shapes with literal baseline expectations. * fix: preserve Messages recovery in error responses * test: compact Messages base outcome fixture * fix: preserve Messages catch recovery and byte parity * Normalize Messages local refusals and partition overflow comparisons Select fixed Messages refusal guidance from local construction metadata while preserving the shared producer bodies and original decision evidence. Keep legacy error records only for buffered delivery, distinguish iterator read faults from writer faults, and return successful passthrough before error work. Partition the unchanged overflow comparison into bounded per-lane slices and cover local refusal and delivery behavior with isolated fixtures. * Preserve Messages failure origin and continuation presentation Distinguish converter reader failures from processing faults and carry local presentation metadata through Kiro continuation HTTP normalization. Exercise Copilot negotiation refusals through the production transport. * Keep large spend ceilings in refusal detail and clarify error-body bounds Drop the upper bound on spend ceiling values in the workflow refusal sentence, document the bounded terminal-frame accounting difference, and state the 64 KiB error-body bound in bytes.
* fix: native Messages SSE error-response normalization * fix: narrow Messages error-response normalization fields * Read top-level error fields for non-object stream errors and align guides Use the top-level type and code when a streamed error member is null, a scalar or an array, matching the buffered Messages paths. Update the French, Russian and Turkish Claude Code guides to the current error-response normalization wording. * fix: continue Messages error-response normalization after split CRLF
…erage (#8148) * fix(claude): normalize direct context overflow errors * test(claude): cover generic overflow parity and document direct errors Preserve the existing direct-encoder fix and cover four generic error codes across streaming and folded responses. Verified tree matches local commit 25f1104c7631e713199de631505c1dba01ff49d3. * test(messages): align generic overflow normalization expectations
Canonical ChatGPT and official OpenAI native /responses/compact sends forwarded OpenCodex-owned ocx1:/ocx2: compaction envelopes verbatim, so the upstream rejected them as invalid_encrypted_content. Only the custom gateway send lowered them. Run scrubOcxCompactionItems on the non-gateway send as well, so the envelopes become plain user summaries like on ordinary turns, while native blobs stay byte-identical for these decoding destinations. Co-authored-by: Ingwannu <ingwannu@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(codex): preserve pre-output hold across safe WS heartbeats * test(codex): cover heartbeat cancellation and sequence bounds * test(codex): assert the relayed refusal frame reaches the body The parameterised "relayed in the body" cases only checked the status, so a regression that dropped the frame would still pass. Assert the event marker and message, and say in the transport contract that sequence_number is also bounded to a non-negative safe integer.
…ts (#8154) * fix(terminal-guard): pass completion summaries that follow tool results The Anthropic terminal guard read the latest user text and ignored tool activity after it, so a normal turn (request -> tool calls -> tool results -> short "done" summary) was classified suspicious_no_tool. The relay then appended the plan-only nudge and re-asked the model, which re-ran tools it had already run and repeated the cycle on every client turn. Tool calls or results after the latest user message now mark the turn as already executed; only a renewed plan announcement (PLAN_INTENT_RE) is still continued. * fix(terminal-guard): stop the tool-activity pass at a stalled plan announcement A text-only plan announcement after the last tool activity means the turn stalled there, so a following completion is continued again, matching recentTurnHasToolActivity. Pin the boundary for next-step wording: first-person plans still continue, while a summary that suggests a next step to the user passes. --------- Co-authored-by: yazzang-homelab <278053055+yazzang-homelab@users.noreply.github.com>
#8174) Mistral rejects requests that carry more images than a model accepts, counting the whole replayed history: most vision models refuse a ninth image with HTTP 400, and DeepSeek V4.1 Flash answers an opaque HTTP 503 (code 3800) past 20. A screenshot-heavy session then fails on every turn. For the first-party Mistral destination, messagesToChatFormat now keeps the newest image_url parts within the model's cap and replaces older ones with a text note naming the cap, in the outbound copy only. The cap is the new modelCapabilities.<id>.mistralMaxImages axis: an operator declaration over the measured rows on the mistral registry entry, else the documented 8. Co-authored-by: Henry Fontanier <14199823+fontanierh@users.noreply.github.com>
…8163) * fix(openai-chat): flatten Claude gateway root tool schemas Apply the supplied Claude Chat gateway compatibility patch to current dev. Flatten root oneOf/anyOf/allOf by upstream model id while preserving nested schemas and literal values. Keep existing Zen and Azure sanitization intact. Cover root compositions, required fields, wire-model overrides, non-Claude exclusion, nested schema preservation and input immutability. Register the new suite in the existing providers layout shard and document the lossy root normalization contract. * fix(openai-chat): preserve Claude root reference arguments Preserve own __proto__ argument names and resolve local root-branch ref chains with a shared 64-dereference budget per tool schema. Keep nested schemas and existing Zen/Azure handling unchanged. Preserve the original composition for cyclic, missing, external, over-budget or nested-composition references instead of emitting an incomplete flattened argument catalog. Add regression coverage for local references, safety fallbacks, property precedence and non-final Claude name segments. Clarify allOf required-field promotion and reference limits in the public and architecture docs. * fix(openai-chat): retain unread inline composition arguments * fix(openai-chat): flatten empty nested property maps
Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com> Co-authored-by: Omar <13569609+omar391@users.noreply.github.com>
* fix(responses): join repeated tool outputs for one call Co-authored-by: tachyon6 <songjunjun62754@gmail.com> * fix(chat): preserve late tool output chronology * docs(chat): clarify repeated output folding boundary --------- Co-authored-by: tachyon6 <songjunjun62754@gmail.com>
…8203) Co-authored-by: youhuangla <71770193+youhuangla@users.noreply.github.com>
* fix(claude): avoid retries for definite context overflow Co-authored-by: gitrvc-hub <rvcalilap@gmail.com> * fix(retry): reject negated overflow verdicts * fix(claude): preserve overflow verdicts across sentences * fix(claude): preserve verdicts across separate sentences --------- Co-authored-by: gitrvc-hub <rvcalilap@gmail.com>
Preserve suffix-only requests when summaries are hidden and reject inherited effort-map keys. Co-authored-by: Andrew (agent) <59988150+andrew05060414@users.noreply.github.com>
* fix(claude): preserve translated system cache boundary Co-authored-by: Vadym O <bolein95@gmail.com> * fix(claude): retain cache boundary after identity normalization * test(claude): cover mismatched system cache prefix --------- Co-authored-by: Vadym O <bolein95@gmail.com>
* fix(web-search): omit lite marker from classic search Preserve classic search wire semantics for configured and selected headers. Co-authored-by: Ege Arhan <egearhany@gmail.com> * docs(web-search): explain classic sidecar header exception --------- Co-authored-by: Ege Arhan <egearhany@gmail.com>
* fix(web-search): report incomplete Anthropic search results * fix(web-search): reject malformed Anthropic search frames * fix(web-search): reject empty Anthropic stop reasons * test(web-search): complete routed Anthropic search fixture * fix(web-search): honor SSE controls and exact byte boundary * fix(web-search): honor clean EOF at exact byte cap
* fix(web-search): separate consumer and upstream inactivity * fix(web-search): yield on synchronous empty chunks * Preserve consumer timeout in image bridge
* test(messages): fix Windows fixture path matching * test(messages): prove sink and overlay execution --------- Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
Carries #8187 by @ismell0992-afk. Co-authored-by: ismell0992-afk <255305877+ismell0992-afk@users.noreply.github.com>
* Prioritize critical credits in quota headline Co-authored-by: Rafael Moreira Lima <rrmlima@gmail.com> * Fix quota headline selection for custom label collisions Co-authored-by: Rafael Moreira Lima <rrmlima@gmail.com> * Strengthen unlimited credits quota summary fixture Co-authored-by: Rafael Moreira Lima <rrmlima@gmail.com> * docs: record quota headline precedence Co-authored-by: Rafael Moreira Lima <rrmlima@gmail.com> * fix(gui): index quota headline windows by label Co-authored-by: Rafael Moreira Lima <rrmlima@gmail.com> * docs: clarify critical credit precedence in translations Co-authored-by: Rafael Moreira Lima <rrmlima@gmail.com> * docs: describe quota window projection Co-authored-by: Rafael Moreira Lima <rrmlima@gmail.com> --------- Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com> Co-authored-by: Rafael Moreira Lima <rrmlima@gmail.com>
* fix(ci): rebalance Ubuntu tests across five shards * test(ci): verify five-shard suite coverage
…sktop app (#8105) Design system v2: redesigned dashboard, navigation and desktop windows, revised to the owner's Paper design (sidebar search and shortcuts, Home, Usage source dropdown with privacy-bounded client/device attribution). Classic dashboard kept at /classic/. Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
…8240) * fix(cli): retain Desktop selection when its executable disappears * docs: record verified Desktop launcher fix and pending live recovery
* test(config): use supported conditional platform skips * test(config): cover log rotation under a busy ownership lock
* test(config): retry busy first ownership registrations * test(config): fail registration workers on barrier expiry Exit before ownership registration when the go signal is still absent after the barrier deadline. A child-local deterministic clock regression fails before the fix and passes afterward without a 20-second delay. Focused gated/cold/racing controls: 4 pass, 20 assertions; typecheck2322 and file-size/diff checks pass. No product change.
* fix(sync): report skipped connected children as partial * fix(sync): make update guidance installation neutral
* fix(sync): defer supervised client restart after apply * fix(sync): clarify deferred supervisor restart guidance
* fix(link): report stale child connection readiness * test(link): seed durable state for tunnel readiness * fix(link): fence stale client status reads
* fix(link): preserve confirmed orphan token files * test(skill): register disconnect capability domain * fix(link): close unknown liveness narrowing * fix(link): protect admission secrets in orphan recovery
…8243) (#8256) Remove a Windows identity pin on refusal while another name still holds the token, name a leftover .identity pin in the nlink refusal, read durable Child state once per /readyz and only for the status routes that report it, type client_state_changed as a LinkReadiness reason, and show the 503 reason with recovery guidance in the dashboard.
* fix(tests): use native homes in launchd fixture * fix(tests): isolate plist home fixtures * fix(tests): account for shell quoting in plist assertion * fix(tests): encode plist whitespace references --------- Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
* fix(tests): pair Windows CLI update plan session * fix(tests): isolate Windows plan fixture lifetime * fix(tests): retain plan fixtures until verifier exits * fix(tests): prove paired request reaches junction guard * test: report Windows toolchain refusal gate * fix(tests): contain Windows plan fixture process lifetime * fix(tests): retain ownership of Windows plan child * fix(tests): remove ambiguous descendant socket proof * test: prove Windows fixture job exit with owned handle --------- Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
#8265) Hosted Windows TEMP is an NTFS 8.3 alias (C:\Users\RUNNER~1). realpathSync keeps the short name while the sync process canonicalizes CODEX_HOME with realpathSync.native, so its catalog path hashed to a different backup and restoration stripped the catalog to [].
* test: quarantine hosted Windows CI failures for 2.98.0 * test: use Linux paths in systemd admission fixture
Codex Review Summary: ✅ CompletedThis 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 837 files, which is 537 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.
|
|
✅ Deterministic PR hygiene checks passed. |
⏳ DRAFT
What to do
Its title has been prefixed with |
Summary
Promotes the frozen
devcandidate47f9e2dc4268a0b24835ad12d571f0e2242fac93tomainas 2.98.0. The promotion head247ad32cb7merges inmainancestry with theoursstrategy, so its tree is exactly the candidate tree (git diff 47f9e2dc42 247ad32cb7is empty).devwas already moved to 2.99.0 by #8263 (e804cd418a) before publication.The candidate carries 54 commits since 2.97.0. Highlights:
Known limitation, tracked in #8262: a time-boxed quarantine skips a small set of tests only on hosted Windows CI (overflow network lanes, one client-link-stop case, two CLI-plan cases, the package ancestry guard, one quota-tag case). They still run on Linux, macOS and local Windows.
Verification
release.ymlwill be dispatched only after this branch's push-event Cross-platform CI and Service lifecycle succeed on the exact merge SHA.Checklist