Skip to content

[WRONG BRANCH] Fork を上流 v2.88.0 へ更新(refusal-terminal は上流取り込みにより撤去) - #4

Draft
nekonade wants to merge 7092 commits into
developfrom
fork/integration/v2.88.0
Draft

nekonade wants to merge 7092 commits into
developfrom
fork/integration/v2.88.0

Conversation

@nekonade

@nekonade nekonade commented Nov 8, 2026

Copy link
Copy Markdown
Owner

概要

necodex の開発経路(necodex-dev)で使う Fork を、上流 lidge-jun/opencodex の v2.88.0 にそろえます。中身は上流 v2.88.0(6936d9885d8a)そのもので、独自の変更はありません。

これまで Fork には独自パッチ refusal-terminal(拒否された依頼を Codex が 1 回+5 回送り直す問題の修正)を載せていました。上流が同等の修正を lidge-jun#7218 で取り込み、v2.87.0・v2.88.0 でリリースしたため、v2.88.0 を基点にしてパッチを撤去しました。撤去の記録は necodex の patches/manifest.json(台帳 v4)にあります。ローカルの検証済みタグは fork/v2.88.0-1 です。

このブランチの差分には、Fork の main(v2.15.0)以降に上流で入ったすべての変更が含まれます。

検証

  • 2026-10-18: 上流 v2.88.0 の取り込みと撤去の確認、necodex の契約テスト 18 件、隔離リハーサル S0〜S5 に合格しました。
  • 2026-11-05: この版の GUI を再ビルドし、lint と GUI テスト 3432 件に合格しました。necodex(develop)との組み合わせで、基本テスト 168 件・契約テスト 18 件・隔離リハーサルにも合格しています。
  • 2026-11-08: 実機の Codex を necodex-dev 経路へ切り替え、Fork の応答と Anthropic 経由の通常ターンを確認しました。

既知の問題

Antigravity 経由の claude-opus-5-5 が 404 になります。npm 版 2.98.0 でも発生するため、この版固有の問題ではありません。上流の最新 v2.99.0 を基点にした別ブランチ fork/work/antigravity-404 で対応します。

関連

  • necodex 側の PR: nekonade/necodex#2(中継の追加)、nekonade/necodex#3(Fork 更新の台帳と記録)

lidge-jun and others added 30 commits October 10, 2026 15:58
…ostic (lidge-jun#6806)

Adds .github/workflows/catalog-async-contracts.yml and the Rust contract crate under scripts/diagnostics/windows-version-control/, carrying the CI part of lidge-jun#6723. Portable contracts run the real Bun catalog modules on Linux, macOS and Windows; push runs are limited to dev/main/preview, PR runs cancel superseded runs, and the toolchain is pinned to 1.99.0.

Co-authored-by: mashfromband <matsumoto.yukuhashi@gmail.com>
…#6875)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* fix(config): serialize Grok and link writers under existing locks

Hold the canonical config lock through Grok injection and cleanup, validate publication destinations, and preserve refresh-only admission. Coordinate link store mutations and revalidate recorded links before activating a bound listener.

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

* fix(grok): retain refresh skip on destination drift

---------

Co-authored-by: Epinephrine <27862058+luvs01@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…-jun#6874)

Claude Code 2.1.294+ resolves the `sonnet` alias to claude-sonnet-5-5, but
the native tier table still pinned an unset Sonnet slot to claude-sonnet-5,
so subscription launches through `ocx claude` hid Sonnet 5.5 from the picker.

Refs lidge-jun#6873
…el (lidge-jun#6859)

* fix(codex): never discard a rotated native-main refresh token on cancel

A successful refresh_token exchange retires the token it sent. Two paths in
resolveMainAccountToken still lost the replacement when the caller went
away:

- the caller's signal was passed into the exchange, so a disconnect after
  the POST was sent aborted the request or its body read;
- after the exchange resolved, a caller-abort check threw before
  persistRefreshedMainAuthJson ran (added in lidge-jun#5268).

Either way auth.json kept the retired token and the account needed a
manual re-login. Caller cancellation now stops only the waits before the
exchange. The exchange observes the refresh's own 30-second timeout, the
result is published through the unchanged snapshot/identity guards, and the
caller's abort reason is thrown after the commit. An external writer that
replaced auth.json during the exchange still wins.

The claim and refresh-lock helpers await the callback through completion,
so a cancelled wait cannot release an acquired lock mid-exchange.

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

* test(codex): assert the persisted account identity after cancelled refresh publication

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: JUN <jun@lidgeai.com>
…#6850)

* fix: release turn admission on client cancellation

* fix: bind internal decision cancellation at admission

* fix: release pending Live upgrade admission on client abort

* test(layout): register active-turn-disconnect on an existing line to stay under the size threshold

---------

Co-authored-by: JUN <jun@lidgeai.com>
…lidge-jun#6858)

Ollama Cloud's mistral-large-4 streams several distinct tool calls in one
frame, each with its own id but all with function.index 0. The parser keyed
calls by index, so the second call collided with the first and the stream
failed with "changed a tool-call id for an existing index" (or "reused a
tool-call index for another function" when the names differ).

A valid native id is now the call's identity. Index, then position, is the
fallback only for entries without an id, and a later id adopts the call that
was first seen without one at the same index. Two entries in one frame share
a call only when they share an id. Budget keys follow first-seen order
instead of the index, so distinct calls at one index keep separate argument
and metadata accounting. The parallelToolCalls:false guard is unchanged: the
captured shape now reaches it and fails closed with the parallel-call error.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…_config.json store (lidge-jun#6828)

* fix(zcode): carry reasoning ladders and image input into the provider_config.json store

ZCode 3.14 moved custom providers to v2/provider_config.json (lidge-jun#5348), and the
store export carried over only each model's contextWindow — the reasoning
ladder lidge-jun#4147 added to the legacy v2/config.json block and the catalog's image
modality were both dropped, so every opencodex model showed no thought-level
picker and no attachment support in current ZCode builds.

Write the capabilities the client's own store schema accepts, extracted from
the ZCode CLI bundle's strict zod definitions: config.optionSpecs.reasoningLevel.
values (the same Codex-vocabulary ladder the legacy block emits, minus the none
sentinel; the chosen level is validated against values and forwarded verbatim
to reasoning.effort) and config.properties.inputFormat.supportsImage when the
catalog row declares image input. A model rule now ships when the row has any
of contextWindow, image input, or a selectable ladder; rows with none still
ship none, per the no-guessed-capability rule. Effort filtering is shared with
the legacy exporter via zcodeSelectableEfforts in model-metadata.

* chore: re-trigger review readiness gate after checklist attestation

---------

Co-authored-by: Blazetes <Blazetes@users.noreply.github.com>
…text reasoning (lidge-jun#6882)

* fix(responses): warn once when a custom provider drops replayed plaintext reasoning (lidge-jun#6675)

* fix(responses): treat Azure per-resource hosts as curated destinations in the reasoning notice
…x malformed call (lidge-jun#6881)

* fix(google): let the empty-completion retry replay a pre-output Vertex malformed call (lidge-jun#6876)

* fix(google): carry Vertex usage on truncation errors so a replay meters both attempts
…ts (lidge-jun#6883)

A raised inbound body reservation was released only on response EOF/error, a settled explicit cancel or a thrown handler error. If the client aborted and the response was never consumed, the reservation stayed held and later covered POSTs got 503 capacity exhausted until restart. Observe the request abort signal once work returns, cancel the producer through the shared idempotent path, and release once after cancellation settles. Closes lidge-jun#6793.
…dge-jun#6887)

A synthetic 429 upstream_reset_replay_refused was attributed like a provider throttle (rate-limit/permitted) because attribution treated every 429 as a rate limit. Read the in-process replay-refusal marker in the deferred logger and carry a synthetic transport-ambiguous cause hint into final request and attempt attribution. Client-visible refusal behavior is unchanged. Closes lidge-jun#6658.
…dge-jun#6888)

Read a fresh user environment block after the registry transaction and evaluate searchable PATH entries in order until the Desktop directory. Preserve the legacy registry probe only as a conservative fallback when the fresh PATH is unavailable. Cover UTF-16 parsing and PATH precedence with portable tests.
…lidge-jun#6472) (lidge-jun#6885)

* fix(copilot): support Auto-only accounts and plan-aware model selection

* fix(copilot): keep Auto visible with existing new-model Off policy

* fix(copilot): harden Auto renewal and refusal handling

Keep ephemeral session credentials redacted, preserve account-owned
snapshots through bounded OAuth renewal, and renegotiate expired queued
sessions without a nested concurrency lease. Add focused regressions,
pin public protocol evidence, and expose selection near the settings top.

* docs(copilot): document callback contracts and isolate GUI test globals

* docs(copilot): describe test fixtures and clarify Russian Auto hint

* Fix Copilot Auto OAuth refresh wire handoff and refusal mapping

* fix(copilot): preserve unknown permissions and shared selection policy

* refactor(copilot): limit Student fix to automatic negotiation

Defer configuration, GUI and CLI selection modes; preserve core recovery and operator policies. Scope API version to Auto requests and fix capacity cache eviction.

* fix(copilot): hand an Auto session renewed onto Chat back to the native owner

When a queued native Responses session for Copilot Auto expired and dispatch-time
renegotiation selected the Chat wire, the passthrough path rebuilt and sent
/chat/completions but still delivered the reply natively, so a Responses client
received Chat choices (JSON) or Chat chunks ending in adapter_eof (SSE). The
dispatch fence now signals the passthrough owner before the inference send and
reuses the existing 401/429 Chat handoff.

Co-authored-by: Zehua Kcriss Li <65699115+ZehuaKcrissLi@users.noreply.github.com>

* test(copilot): keep the renewed bearer assertion out of the privacy scan

---------

Co-authored-by: Zehua Kcriss Li <65699115+ZehuaKcrissLi@users.noreply.github.com>
Co-authored-by: Kcriss <jiafujun123@gmail.com>
… terminals (lidge-jun#6889)

* fix(logs): keep recognized bare upstream error classes in synthesized terminals

A bare upstream error that ended the WebSocket exchange was turned into a synthesized response.failed carrying upstream_server_error, and captureTerminalHttpStatus ignored bare errors, so structured rate-limit and overload codes were recorded as a generic 502. Preserve recognized rate-limit and overload classes in both relay modes, record them as 429/503 provisionally, let a genuine terminal supersede them, and record a bounded upstreamErrorType. Terminal-status diagnostics move to request-log-terminal-status.ts to keep request-log.ts under the size gate. No replay is added. Refs lidge-jun#6740.

* fix(logs): record status only for recognized bare upstream errors

Unrecognized bare errors recorded a provisional 502, which overrode explicit status fields that combo stream preflight reads (status/http_status on the event), and a completed terminal recorded 200. Record a provisional status only for recognized rate-limit and overload classes, and let response.completed only retire provisional evidence.
…jun#6864)

* test: isolate Windows host state and bound native enumeration

* test: scope native CIM ownership checks to the fixture PID

* test: key the trust fixture by the platform project path

The positive control added for the untrusted-project case wrote the trust key with a hard-coded Windows separator, so on Linux and macOS the trusted project never matched and the expected warning was absent (Cross-platform CI run 38007605487, test 1/4). A TOML literal string keeps the platform path verbatim, as the neighbouring uncached-collection test already does.

---------

Co-authored-by: JUN <jun@lidgeai.com>
…idge-jun#6880)

* fix(chat): promote caller x-session-id on Chat Completions ingress

Chat Completions passed the original request to admission and the ChatGPT bridge, which forwards only canonical session headers, so a caller x-session-id never reached ChatGPT-backed models and prompt-cache reuse was lost. Apply the same withCallerSessionIdentity promotion used by Responses and Messages before admission. Closes lidge-jun#6520.

* docs(structure): record Chat Completions x-session-id promotion

* test(server): pin the Chat Completions caller-session wiring

* test(server): pin the promoted Chat Completions request in the loopback CORS oracle
…ble observation (lidge-jun#6886)

* fix(codex): keep rediscovering main-account credits after an unavailable observation

The recovery sweep only renewed already spendable credit evidence, so one zero, null, restricted or retracted WHAM read stopped discovery and the main account stayed refused locally even after credits were usable again. Keep consented, unpaused accounts with an exhausted window eligible for paced lookups, keep admission gated on fresh positive evidence, and bound the consented refusal's Retry-After to the base metadata interval. Closes lidge-jun#6845.

* test(codex): pin recovery pacing when credit evidence is missing and WHAM refuses auth
…idge-jun#6890)

* fix(responses): report spend-ledger storage refusals as local 503s

A SpendLedgerFileRefusedError (for example an extra hard link from a sync daemon) was caught as a transport failure, returned as 502 Provider unreachable, attributed upstream, and charged to provider and account health. Map it, including nested retry causes, to 503 server_error spend_ledger_storage_unavailable before transport classification on passthrough, translated, compact and runTurn paths; log it as a local refusal and skip health penalties. The guard is unchanged. Refs lidge-jun#6314.

* test(responses): register the spend-storage-error owner in the core module inventory
…jun#6893)

The connected-sibling recycle case spawns a Bun child with piped stdout and stderr and, until the replacement wait, never looked at either. On Windows CI the child once wrote no readiness marker for 45.9 s and the test failed with a bare timeout, leaving no trace of what the child was doing (lidge-jun#4956 family). Drain both pipes from spawn into bounded buffers and append the child's pid, exit code and recent output to every wait's timeout. The replacement wait no longer opens a second reader on an already drained stream.

Refs lidge-jun#4956
…ertain outcomes (lidge-jun#6870)

* fix(grok): atomically claim coupon attempts and reconcile without respending

Persist one winning attempt before transport. Keep uncertain outcomes replay-only, refuse unreadable ledgers, replay existing records at capacity, and synchronize the route contracts and regression fixtures.

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

* fix(grok): guard coupon settlement and preserve unknown outcomes

* fix(grok): require explicit coupon RPC status confirmation

* Retry confirmed Grok coupon settlement under transient contention

Retry only local settlement for ConfigMutationLockError caused by SQLITE_BUSY, with five attempts and four short waits. Preserve changed-claim and terminal guards, stop on other errors, and never repeat redemption. Cover real process contention, exhaustion, refusal classes and identity drift; clarify structure contracts and repair the garbled separator.

* fix(grok): preserve coupon claims and unknown operation identity

Flush coupon claims before dispatch, quarantine ambiguous version-one records,
and retain unknown attempts across CLI errors and dashboard dialog reopen.
Keep remaining-coupon availability separate from redemption confirmation.

* fix(grok): preserve coupon identity and release definitive failures

* fix(grok): keep coupon recovery holds on operation_state_changed

A settlement race that returns operation_state_changed left the GUI and CLI
treating the redemption as definitively failed, dropping the hold and the
operation id the user needs to inspect the attempt. Treat it like the other
unresolved codes. The coupon modal now reads uncertainty only from the
controller, so a reopened modal clears once the original request is confirmed.

Adds GUI and CLI regressions for both paths.

* fix(grok): replay a durable terminal winner to concurrent coupon refusals

A preflight refusal that lost a race to a concurrent definitive outcome
returned operation_state_changed, which the GUI and CLI now hold as an
unresolved attempt; the hold could never clear because the operation was
already final. The refusal now settles or inspects the ledger inside one
config mutation transaction and replays the definitive winner when account
and token match; genuinely unresolved states still return
operation_state_changed. The GUI retires the active attempt as soon as an
outcome is definitive, before awaiting the refresh, so a reopened modal cannot
recreate a hold.

* fix(grok): replay a definitive winner to a lost coupon claim

A request that lost the atomic open -> attempted claim always answered
attempt_in_progress, even when the winning request had already settled, which
left the dashboard holding a finished operation. A lost claim now reads the
durable winner and replays a matching definitive outcome with the same
response as a late refusal; unresolved or mismatched operations, and a failed
read of the winner, still return attempt_in_progress so no caller is told it
may open a replacement operation.

---------

Co-authored-by: Epinephrine <27862058+luvs01@users.noreply.github.com>
Co-authored-by: JUN <jun@lidgeai.com>
…ach log rows (lidge-jun#6903)

* fix(logs): drop credential-shaped upstream diagnostics before they reach log rows

* fix(logs): record only known upstream error classes

* fix(logs): keep only known bare top-level error codes
…#6902)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
lidge-jun and others added 25 commits October 16, 2026 03:24
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 (lidge-jun#7238)

lidge-jun#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>
…#7241)

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>
lidge-jun#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>
…#7243)

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>
…n#7246)

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.
…e-jun#7244)

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 lidge-jun#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>
…#7248)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…-2.87.0

release: promote dev de315e7 to main as 2.87.0
…idge-jun#7252)

The carry-attribution window is capped at 80 characters and could cut a reference in half. The lidge-jun#7223 subject "carry ... (lidge-jun#7195, lidge-jun#6767" was read as lidge-jun#676, an unrelated PR, so the hygiene gate demanded a co-author trailer for the wrong person (seen on the 2.87.0 promotion lidge-jun#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.
lidge-jun#7230, lidge-jun#7231, lidge-jun#7232, lidge-jun#7233) (lidge-jun#7236)

Carries four vadymhimself follow-ups onto dev:

- lidge-jun#7230: the combo sibling check peeks the round-robin ring without advancing it, while the failed account's cooldown is still recorded.
- lidge-jun#7231: a Codex account move after a 402 is recorded as quota recovery, separate from 429 rate recovery, through persistence, metrics, analytics and Logs labels.
- lidge-jun#7232: the Anthropic server-tool input buffer is capped on the incoming fragment (4,096 code units), so one oversized fragment cannot exceed the bound.
- lidge-jun#7233: refused-then-served usage rows are priced from the served attempt, and client cancels keep an unknown cost. A usage-less refusal never changes a row's pricing classification. A row with a leading refusal summarizes exactly like the same row without it, under dev's existing partial-cost contract.

Co-authored-by: Vadym O <bolein95@gmail.com>
When the Codex startup intent gate is closed (Codex OFF, a sibling, or a hub without local integration), startup now skips the two native-Codex service-manager ownership inspections and native-main preparation. On Windows those inspections run synchronous Task Scheduler/service children before the runtime record is published, and the disabled lifecycle never uses their answers. Enabled startup keeps both ownership decisions, including the fresh second listing that detects a concurrent installer. ACL hardening, live-owner discovery and startup deadlines are unchanged. The claim is limited to removing unnecessary probes; the reported 45-second owner-start timeout is not shown to be resolved.
… lane (carry lidge-jun#7205) (lidge-jun#7251)

Carries vadymhimself lidge-jun#7205, including its newest head 53a3ca2. On the translated Claude lane, an Anthropic server-tool exchange (web search/fetch) from history is replayed only into the assistant turn that produced it. An anchor that occurs exactly once replays. An ambiguous (repeated) anchor drops the exchange, so a later identical turn can no longer take over an earlier exchange. A result is replayed only after its matching call with the same id and type earlier in the turn. A call must carry a plain-object input with a nonblank query or url. Orphan results never synthesize a call. Anything that cannot be proven valid is dropped, which is the pre-lidge-jun#7205 behaviour. The anchor turn's text is preserved byte-for-byte.

Co-authored-by: Vadym O <bolein95@gmail.com>
…yed history (lidge-jun#7254)

* fix(google): stop replayed Gemini progress text from spreading leaked planning

* fix(google): scope progress trimming to pre-call text and real sentence ends

* fix(google): end the progress lead at other scripts sentence terminators
…#7227)

Co-authored-by: Ingwannu <ingwannu@users.noreply.github.com>
)

Co-authored-by: Juan de Urtubey <juan@develophealth.io>
…dge-jun#7253)

successCostUsd passed the aggregate `unreported` status to
estimateRequestCost, so a usage-less 429 before a measured send stayed
unpriced in /api/routing-analytics while /api/usage priced it. It now
reuses computeEntryCost, the same attempt-aware pricing.

Co-authored-by: Claude Code <noreply@anthropic.com>
* fix(cli): skip unavailable loopback families during owner discovery

* fix(cli): retain owner probes after loopback route errors
* fix(chat): expose canonical request-history IDs

Return the existing gateway request ID on Chat replies owned by a handler or logged admission refusal, preserving unlogged rejection behavior.

Co-authored-by: daemons2000 <1758467+daemons2000@users.noreply.github.com>

* test(chat): preserve CORS policy guard with receipt wrapper

---------

Co-authored-by: daemons2000 <1758467+daemons2000@users.noreply.github.com>
lidge-jun#7095)

* fix(responses): reclaim oldest idle WebSocket at capacity

* fix(responses): preserve tool ownership during idle reclamation

* test(responses): track response tool ownership in core contracts

* test(responses): cover disconnect and reclaimed continuation recovery

* fix(responses): preserve WebSocket turn and client tool ownership

* test(responses): separate socket admission and close waits

* test(responses): retry capacity upgrades after close release

---------

Co-authored-by: GOAT <goat@localhost>
Co-authored-by: JUN <jun@lidgeai.com>
…#7235)

* fix(opencode-zen): route Claude through Anthropic Messages

* fix(messages): preserve Zen rate-limit guidance on native requests

* fix(opencode-zen): address rate-limit types and localized routing guidance

Co-authored-by: norths7ar <guicaitiandu@gmail.com>

* fix(opencode-zen): narrow quota exclusions for rate-limit guidance

* fix(opencode-zen): share structured errors across translated and native lanes

---------

Co-authored-by: JUN <jun@lidgeai.com>
…tion (lidge-jun#7147)

* fix(responses): recover Anthropic thinking-signature binding rejection

(cherry picked from commit 0150145)

* fix(responses): recover thinking signatures within hosted search iterations

(cherry picked from commit 8b801db)

* fix(search): preserve Anthropic thinking-bound conversation fidelity

(cherry picked from commit 98fc937)

* fix(anthropic): scope recovery memos to serialized opaque payloads

Carry the bounded payload memo from lidge-jun#7098 without its local prefix validator. Keep legal history edits upstream-owned, and preserve newly issued thinking after a repaired send.

Co-authored-by: lcxhh <lcxhh521@gmail.com>

* fix(responses): share thinking recovery across media and empty retries

Use each existing dispatch, pacing and send-budget owner. Retry only the current inference, keep completed media side effects, and retain structured replacement refusals. Ordinary continuations after output stay ineligible.

Co-authored-by: lcxhh <lcxhh521@gmail.com>

* docs(anthropic): document bounded thinking signature recovery

Describe serialized-payload memos, sidecar and empty-retry boundaries, and upstream-owned legal history edits.

Co-authored-by: lcxhh <lcxhh521@gmail.com>

* docs(anthropic): correct empty-answer tool catalog contract

* test(responses): register Anthropic thinking recovery module

* fix(anthropic): contain replay capture pressure and media budget refusals

---------

Co-authored-by: lcxhh <lcxhh521@gmail.com>
Co-authored-by: GOAT <goat@localhost>
…-2.88.0

[WRONG BRANCH] release: promote dev 7761e04 to main as 2.88.0
@github-actions github-actions Bot added the intake: hygiene-blocked Deterministic PR hygiene checks failed label Nov 8, 2026
@github-actions

github-actions Bot commented Nov 8, 2026

Copy link
Copy Markdown

⚠️ Deterministic hygiene checks failed.

  • orphan_lockfile — bun.lock changed without package.json. Revert accidental churn or obtain dependency-change-approved.

@github-actions github-actions Bot changed the title Fork を上流 v2.88.0 へ更新(refusal-terminal は上流取り込みにより撤去) [WRONG BRANCH] Fork を上流 v2.88.0 へ更新(refusal-terminal は上流取り込みにより撤去) Nov 8, 2026
@github-actions

github-actions Bot commented Nov 8, 2026

Copy link
Copy Markdown

⏳ DRAFT

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

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 orphan_lockfile — bun.lock changed without package.json. Revert accidental churn or obtain dependency-change-approved.

Its title has been prefixed with [WRONG BRANCH].
This pull request is being kept as a draft automatically. Once every issue above is resolved, it will be marked ready for review again.

@github-actions
github-actions Bot marked this pull request as draft November 8, 2026 11:45
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.