From 6044a9ab3839c4e98ffd0ec050353bac587678cb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 19 Sep 2026 01:24:37 +0900 Subject: [PATCH 01/97] chore(release): open dev at 2.60.0 before releasing 2.59.0 (#5072) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f97ab8794e4..14fc11e1a63 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@bitkyc08/opencodex", - "version": "2.59.0", + "version": "2.60.0", "description": "Universal provider proxy for OpenAI Codex & Claude Code — use any LLM with Codex CLI/App/SDK and Claude Code", "type": "module", "main": "./bin/package-main.mjs", From 3d5efc72554505c581b3af2a68d108e9221f14b7 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 03:08:19 +0900 Subject: [PATCH 02/97] fix(ci): classify the merged regression tests explicitly in the layout inventories (#5075) The regex seeds place a conventionally named file, so a regression test can sit in the tree, run in CI, and still be absent from the authoritative table. That is how the regression tests for #5050, #5051 and #5055 landed without ever entering scripts/test-layout/layout.json or tests/fixtures/test-layout-expected.json (#5059). The two inventories are two copies of one table and the membership oracle already compares them, so both sides get the same three entries. A new test names the three files so they cannot fall out again silently, and checks that each one actually sits in the directory its registration claims. No repository-wide explicit-registration policy is introduced here; the seeds keep carrying brand-new files as designed. --- scripts/test-layout/layout.json | 5 ++++- tests/fixtures/test-layout-expected.json | 5 ++++- tests/test-layout-tooling.test.ts | 23 +++++++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/scripts/test-layout/layout.json b/scripts/test-layout/layout.json index a9e14f2c28c..fb381ba4197 100644 --- a/scripts/test-layout/layout.json +++ b/scripts/test-layout/layout.json @@ -1531,7 +1531,10 @@ "ws-steering-smoke.test.ts": "responses", "combo-authoritative-reset.test.ts": "codex-integration", "devin-stated-reset-hardening.test.ts": "providers", - "devin-stated-reset-retry.test.ts": "providers" + "devin-stated-reset-retry.test.ts": "providers", + "ci-structure-gate.test.ts": "ci-workflows", + "responses-code-mode-patch-compile.test.ts": "responses", + "gui-codex-usage-score-parity.test.ts": "gui" }, "migrated": [ "adapters", diff --git a/tests/fixtures/test-layout-expected.json b/tests/fixtures/test-layout-expected.json index 1d4d47ceaef..263adc46197 100644 --- a/tests/fixtures/test-layout-expected.json +++ b/tests/fixtures/test-layout-expected.json @@ -1363,5 +1363,8 @@ "ws-steering-smoke.test.ts": "responses", "combo-authoritative-reset.test.ts": "codex-integration", "devin-stated-reset-hardening.test.ts": "providers", - "devin-stated-reset-retry.test.ts": "providers" + "devin-stated-reset-retry.test.ts": "providers", + "ci-structure-gate.test.ts": "ci-workflows", + "responses-code-mode-patch-compile.test.ts": "responses", + "gui-codex-usage-score-parity.test.ts": "gui" } diff --git a/tests/test-layout-tooling.test.ts b/tests/test-layout-tooling.test.ts index c7e17d30433..792859a3683 100644 --- a/tests/test-layout-tooling.test.ts +++ b/tests/test-layout-tooling.test.ts @@ -262,6 +262,29 @@ describe("membership oracle", () => { expect({ unresolvedNew, missingFromTree, wrongTarget }).toEqual({ unresolvedNew: [], missingFromTree: [], wrongTarget: [] }); }); + // The regex seeds place a conventionally named file, so a regression test can sit in the tree, + // run in CI, and never appear in the authoritative table — which is how these three landed with + // their subjects (#5050, #5051, #5055) and stayed invisible to the inventory (#5059). The seeds + // are deliberately allowed to carry a brand-new file; what they must not do is carry a merged + // regression test indefinitely. Naming them here is the difference between "something resolves + // it" and "the table says which domain owns it". + test("the merged regression tests are classified explicitly, not by seed", () => { + const owners = { + "ci-structure-gate.test.ts": "ci-workflows", + "responses-code-mode-patch-compile.test.ts": "responses", + "gui-codex-usage-score-parity.test.ts": "gui", + } as const; + const classified = Object.fromEntries( + Object.keys(owners).map(name => [name, layout.explicit[name] ?? null]), + ); + expect(classified).toEqual(owners); + // The file has to be where its registration says, or the registration is a claim about a + // tree that does not exist. + const live = new Set(listTestFiles(repoRoot())); + const placed = Object.entries(owners).map(([name, domain]) => `tests/${domain}/${name}`); + expect(placed.filter(rel => !live.has(rel))).toEqual([]); + }); + test("the fixture histogram never drops below the inventory in devlog 001 §2.B", () => { // 001 is a snapshot of 2026-09-05; files added on dev afterwards join the fixture and // raise a domain's count. A count that falls below the snapshot means a file was dropped From 735f915871f1165a0d9d6bad1dcf62fba6999105 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 11:23:20 +0900 Subject: [PATCH 03/97] fix(providers): stop the Antigravity rename migration re-announcing itself on every boot (#5077) * fix(providers): stop the Antigravity rename migration re-announcing itself The rename migration and the OAuth preset reconciliation disagreed about nine retired Antigravity Flash ids, and startServer runs both, in that order. ANTIGRAVITY_MODEL_CONTEXT_WINDOWS derives a window for every compatibility alias, so the google-antigravity preset carries a modelContextWindows key for each retired id. The migration renamed those keys and persisted, applyOAuthPresetCatalog copied the preset's record back over them in the same boot, and the next start found them again: nine [model-rename-migration] lines on every ocx start, for a user who never selected any of those nine models. Skip a field the registry's own seed still publishes keyed by the retired id. Those entries are deliberate (a request naming gemini-3.6-flash routes to 3.7 and needs a window under the id it asked for), and reconciliation owns that record anyway, so the migration has nothing to repair there. Every field the user owns (models, selectedModels, retainModels, defaultModel, disabledModels) is still renamed and still reported once. Closes #5066 * fix(providers): only skip registry residue, not a value still to carry The first cut skipped any field the registry seed published keyed by the retired id, which also skipped a row that saved only the retired key. That row needs the value carried onto the supported id, and dropping it blanks the record instead of moving it (test 4/4 caught it at gemini-37-flash-migration.test.ts:211). Require both conditions now: the registry seed still publishes the retired id in the field, AND the saved field already carries the supported id, so the rename would only delete a key reconciliation puts straight back. The reporter's post-reconcile row satisfies both for all nine ids; a row with just the retired key does not, and is still migrated and still reported. --- src/providers/model-rename-migration.ts | 56 ++++++- .../providers/model-rename-migration.test.ts | 140 ++++++++++++++++++ 2 files changed, 195 insertions(+), 1 deletion(-) diff --git a/src/providers/model-rename-migration.ts b/src/providers/model-rename-migration.ts index 89c9b6f577e..0606fe3dcd9 100644 --- a/src/providers/model-rename-migration.ts +++ b/src/providers/model-rename-migration.ts @@ -14,9 +14,12 @@ // This migration is deliberately NOT general reconciliation. It rewrites exactly // one thing: an id this file declares retired, on a provider that still carries // the registry's transport, and only when the registry currently seeds the -// replacement. Everything else in the row is left alone. +// replacement — and it skips a field where the retired entry is registry residue +// with nothing left to carry forward (see `isRegistryResidue`, issue #5066). +// Everything else in the row is left alone. import { PROVIDER_REGISTRY } from "./registry"; +import { providerConfigSeed } from "./derive"; import type { OcxConfig, OcxProviderConfig } from "../types"; export interface ModelRename { @@ -194,6 +197,54 @@ function registrySeedsTarget(rename: ModelRename): boolean { return !!entry?.models?.includes(rename.to); } +/** The row the registry contributes to a saved config, or `undefined` when it dropped the id. */ +function registrySeed(provider: string): Record | undefined { + const entry = PROVIDER_REGISTRY.find(row => row.id === provider); + return entry ? (providerConfigSeed(entry) as unknown as Record) : undefined; +} + +/** Whether a saved list or model-keyed record names this id at all. */ +function publishes(container: unknown, id: string): boolean { + if (Array.isArray(container)) return container.includes(id); + if (!container || typeof container !== "object") return false; + return id in (container as Record); +} + +/** + * Whether this field’s retired entry is registry residue rather than something to repair. + * + * Two things have to be true. The registry’s own seed — `providerConfigSeed`, the row both the + * OAuth preset (`deriveOAuthProviderConfig`) and `enrichProviderFromRegistry` contribute — must + * still publish the retired id in this field, so the entry arrives in the config on its own. And + * the saved field must already carry the supported id, so the rename would only DELETE a key, + * with nothing to carry forward. + * + * Under those two conditions the rewrite is worse than a no-op, because it never converges. + * `startServer` runs this migration and then `reconcileOAuthProviders`, and + * `applyOAuthPresetCatalog` copies the preset’s record over the saved one whenever the two + * differ. The deletion is undone inside the same boot, the config is written twice, and the user + * is told about a rename that never sticks on every single start. Issue #5066 is exactly that: + * `ANTIGRAVITY_MODEL_CONTEXT_WINDOWS` derives a window for every compatibility alias, so + * `modelContextWindows` holds a key for all nine retired Flash ids beside the live ones — the + * nine `[model-rename-migration]` lines the reporter saw at every `ocx start`, none of which + * required them to have selected any of those nine models. + * + * Those registry entries are deliberate and stay: a request that still names `gemini-3.6-flash` + * routes to 3.7 and needs a context window under the id it asked for. The second condition is + * what keeps this narrow. A row that saved `{ "gemini-3.6-flash": 1048576 }` and nothing else + * still gets the value carried onto the supported id, because dropping it there would blank the + * record instead of moving it (`tests/adapters/google/gemini-37-flash-migration.test.ts`). + */ +function isRegistryResidue( + seed: Record | undefined, + field: string, + saved: unknown, + rename: ModelRename, +): boolean { + if (!seed) return false; + return publishes(seed[field], rename.from) && publishes(saved, rename.to); +} + export interface ModelRenameProjection { config: OcxConfig; changed: boolean; @@ -226,14 +277,17 @@ export function projectModelRenames( // Provider config is a closed interface, so index through one unknown-cast // view rather than casting at each assignment. const row = prov as unknown as Record; + const seed = registrySeed(rename.provider); let touched = false; for (const field of MODEL_ID_LISTS) { + if (isRegistryResidue(seed, field, row[field], rename)) continue; const next = renameInList(row[field], rename.from, rename.to); if (!next) continue; row[field] = next; touched = true; } for (const field of MODEL_KEYED_RECORDS) { + if (isRegistryResidue(seed, field, row[field], rename)) continue; const next = rename.dropReasoningEffortMap && field === "modelReasoningEffortMap" ? dropFromRecord(row[field], rename.from) : renameInRecord(row[field], rename.from, rename.to); diff --git a/tests/providers/model-rename-migration.test.ts b/tests/providers/model-rename-migration.test.ts index 34801e8b21b..be52a3da6ab 100644 --- a/tests/providers/model-rename-migration.test.ts +++ b/tests/providers/model-rename-migration.test.ts @@ -9,6 +9,12 @@ import { } from "../../src/providers/model-rename-migration"; import { runModelRenameStartupMigration } from "../../src/providers/model-rename-startup"; import { PROVIDER_REGISTRY } from "../../src/providers/registry"; +import { providerConfigSeed } from "../../src/providers/derive"; +import { reconcileOAuthProviders } from "../../src/oauth"; +import { + ANTIGRAVITY_MODELS, + ANTIGRAVITY_MODEL_CONTEXT_WINDOWS, +} from "../../src/providers/antigravity-models"; import { getConfigPath, loadConfig, saveConfig, setPersistedConfigMutationBeforeCommitForTests } from "../../src/config"; import type { OcxConfig } from "../../src/types"; import { removeTreeWithRetry } from "../helpers/remove-tree"; @@ -276,3 +282,137 @@ describe("model rename startup persistence", () => { expect(live.providers.untouched).toBe(liveUntouched); }); }); + +// ── Issue #5066: the migration has to converge, not re-announce itself on every boot ── +// +// The reporter saw the same nine `[model-rename-migration]` lines at every `ocx start`. Nothing +// in the projection, the persistence or the in-memory fallback was broken; the migration was +// losing to the second half of its own boot. `startServer` runs it and then +// `reconcileOAuthProviders`, and the Antigravity OAuth preset carries +// `ANTIGRAVITY_MODEL_CONTEXT_WINDOWS`, which derives a window for every compatibility alias — +// all nine retired Flash ids among them. `applyOAuthPresetCatalog` copies that record over the +// saved one whenever the two differ, so reconciliation restored precisely the keys the rename +// had removed, and the next boot found them and said so again. +// +// It also explains the count: nine messages for a user who never chose nine models, because the +// ids came from the registry rather than from anything they had selected. +describe("registry-seeded metadata does not re-arm the rename (#5066)", () => { + const homes: string[] = []; + const originalHome = process.env.OPENCODEX_HOME; + + function isolate(prefix: string): void { + const home = mkdtempSync(join(tmpdir(), prefix)); + homes.push(home); + process.env.OPENCODEX_HOME = home; + } + + afterEach(() => { + if (originalHome === undefined) delete process.env.OPENCODEX_HOME; + else process.env.OPENCODEX_HOME = originalHome; + for (const home of homes.splice(0)) removeTreeWithRetry(home); + }); + + /** + * A saved Antigravity row carrying one genuinely stale user selection. + * + * `modelContextWindows` is deliberately absent. The point of the fixture is to watch + * reconciliation introduce it between the two boots rather than to assume it is there. + */ + function antigravityRow(): Record { + return { + adapter: "google", + baseUrl: "https://daily-cloudcode-pa.googleapis.com", + authMode: "oauth", + googleMode: "cloud-code-assist", + liveModels: true, + defaultModel: "gemini-3.8-flash", + models: [...ANTIGRAVITY_MODELS], + // Reconciliation does not carry `selectedModels`, so this one is the migration’s to fix + // — once. + selectedModels: ["gemini-3.6-flash-high"], + }; + } + + function antigravityConfig(): OcxConfig { + return { + port: 10100, + defaultProvider: "google-antigravity", + providers: { "google-antigravity": antigravityRow() }, + } as unknown as OcxConfig; + } + + /** The rename lines a boot prints, in order. */ + function renameLines(boot: () => void): string[] { + const warn = spyOn(console, "warn").mockImplementation(() => {}); + try { + boot(); + return warn.mock.calls + .map(([first]) => (typeof first === "string" ? first : "")) + .filter(line => line.startsWith("[model-rename-migration] renamed ")); + } finally { + warn.mockRestore(); + } + } + + // RED on dev, at the last assertion: the second boot reprints nine lines, and so does the + // third, and every one after it. + test("the second boot after reconciliation renames nothing and prints nothing", () => { + isolate("ocx-antigravity-rename-loop-"); + saveConfig(antigravityConfig()); + + // Boot one, in startServer’s order: migrate, then reconcile the OAuth presets. + const first = renameLines(() => { + reconcileOAuthProviders(runModelRenameStartupMigration(loadConfig())); + }); + expect(first).toHaveLength(1); + expect(first.join("\n")).toContain("google-antigravity/gemini-3.6-flash-high"); + + const afterFirstBoot = loadConfig().providers["google-antigravity"]!; + // The writer between the two boots, caught in the act: reconciliation put the registry’s + // own record on disk, retired keys and all. The next boot must not read that as a repair + // the user is still owed. + expect(Object.keys(afterFirstBoot.modelContextWindows ?? {})).toContain("gemini-3.6-flash"); + // What the migration did own stayed fixed. + expect(afterFirstBoot.selectedModels).toEqual(["gemini-3.7-flash"]); + + const second = renameLines(() => { runModelRenameStartupMigration(loadConfig()); }); + expect(second).toEqual([]); + }); + + test("a registry-published id survives in metadata while a user selection is still repaired", () => { + const reconciled = { + ...antigravityRow(), + modelContextWindows: { ...ANTIGRAVITY_MODEL_CONTEXT_WINDOWS }, + }; + const config = { providers: { "google-antigravity": reconciled } } as unknown as OcxConfig; + + const { config: out, changed, warnings } = projectModelRenames(config); + const prov = out.providers["google-antigravity"]!; + + expect(changed).toBe(true); + expect(warnings).toHaveLength(1); + expect(prov.selectedModels).toEqual(["gemini-3.7-flash"]); + // Left alone on purpose: a request that still names the retired id routes to 3.7 and needs + // a window under the id it asked for, and reconciliation would rewrite this record anyway. + expect(prov.modelContextWindows?.["gemini-3.6-flash"]).toBe(1_048_576); + }); + + // The general form of the defect, applied to every rename this file ships: a provider row the + // registry itself produced must never be something the migration wants to rewrite. When it is, + // the two halves of the boot disagree forever and the user pays for it in log noise. + const seedCases: [string, ModelRename][] = MODEL_RENAMES.map( + rename => [`${rename.provider}/${rename.from}`, rename], + ); + test.each(seedCases)("the registry seed for %s is not something the migration rewrites", (_label, rename) => { + const entry = PROVIDER_REGISTRY.find(row => row.id === rename.provider); + expect(entry, `registry entry missing for ${rename.provider}`).toBeDefined(); + const seeded = { + providers: { [rename.provider]: providerConfigSeed(entry!) }, + } as unknown as OcxConfig; + + const { changed, warnings } = projectModelRenames(seeded, [rename]); + + expect(warnings).toEqual([]); + expect(changed).toBe(false); + }); +}); From 4f3c22353bf4e407361924f1b77a8017b0730c83 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 12:16:47 +0900 Subject: [PATCH 04/97] diag(google): describe the Antigravity wire request without its contents (#5008) (#5079) * diag(google): project the structure of an Antigravity wire request (#5008) Adds a pure, content-free projection of the compiled Google wire body so a reporter can describe a failing request without pasting a conversation into a public issue. * test(google): pin the wire-shape projection and record the upstream contract (#5008) * diag(google): name the signature facts the projection can actually prove (#5008) Adversarial review found the two signature booleans claimed more than the call site knows: replayedCallIds conflates a client-supplied signature with a durable-store hit and misses the Antigravity session cache entirely, and a bound replay scope is not a complete one. They are now counts and a presence flag with the names they earn, and a call turn after an unrecognized role no longer reports a model turn. * test(google): stop a fixture thread id from shadowing the anchor class name (#5008) The leak assertion planted the parent thread id 'parent-a', which is a substring of the anchor class literal 'parent-and-own' the same line asserts is present. The diagnostic never carried the id; the marker collided with the class name. Both shards reported only this one failure. * diag(google): make the wire-shape projection unable to reach the request path (#5079 review) Four review defects. The projection was evaluated in argument position, so a throw inside it would have rejected buildRequest; it now goes through a lazy provider diagnostic that gates first and evaluates the builder inside its own try/catch. The item ceilings alone let a worst case serialize past the debug buffer's per-line cap, which cut the JSON while the retained prefix still claimed truncated:false; a serialized budget at half that cap now trims turn detail and the flag stays honest. The send-count assertion counted fetches around buildRequest, which never fetches, so it is replaced by a real fetchResponse exercise under a controlled executor, a send budget and onPhysicalSend. The timing claim is corrected rather than engineered away: with debug on the walk is synchronous on the dispatch path and linear in history length, and the docs say so. Also shares the session-anchor decision, the bypass sentinel and the two upstream error predicates instead of keeping second copies. * test(google): let the tighter of the two ceilings win in the long-session assertion (#5079 review) The serialized budget trims the long-session case below the turn ceiling, so pinning the retained detail to the turn ceiling alone was wrong once both bounds existed. The assertion now fixes what actually matters: exact totals, a head-anchored remainder, and a summary that fits a debug line. The dispatch comparison also stops claiming more than it checks and now compares the whole outbound body with only the per-build request id normalized out. --- .../000_upstream_contract_evidence.md | 107 +++ scripts/test-layout/layout.json | 1 + src/adapters/google-antigravity-replay.ts | 2 +- src/adapters/google-antigravity-wire.ts | 34 +- src/adapters/google-wire-compiler.ts | 19 +- src/adapters/google-wire-shape.ts | 461 +++++++++++++ src/adapters/google.ts | 19 +- src/lib/debug-log-buffer.ts | 7 +- src/lib/debug.ts | 23 + structure/providers/google.md | 37 ++ structure/transports/inventory.md | 2 +- .../adapters/google/google-wire-shape.test.ts | 622 ++++++++++++++++++ tests/fixtures/google-wire-shape-cases.ts | 113 ++++ tests/fixtures/test-layout-expected.json | 1 + tests/lib/debug.test.ts | 49 +- 15 files changed, 1484 insertions(+), 13 deletions(-) create mode 100644 devlog/_plan/260919_5008_antigravity_turn_ordering/000_upstream_contract_evidence.md create mode 100644 src/adapters/google-wire-shape.ts create mode 100644 tests/adapters/google/google-wire-shape.test.ts create mode 100644 tests/fixtures/google-wire-shape-cases.ts diff --git a/devlog/_plan/260919_5008_antigravity_turn_ordering/000_upstream_contract_evidence.md b/devlog/_plan/260919_5008_antigravity_turn_ordering/000_upstream_contract_evidence.md new file mode 100644 index 00000000000..ab8d9ba4d0e --- /dev/null +++ b/devlog/_plan/260919_5008_antigravity_turn_ordering/000_upstream_contract_evidence.md @@ -0,0 +1,107 @@ +# #5008 — what the upstream actually validates + +Evidence gathered for the intermittent first-send 400 on `google-antigravity/gemini-3.8-flash`: +"Please ensure that function call turn comes immediately after a user turn or after a function +response turn." Sources are public and primary where one exists. Nothing here is a fix, and one +finding contradicts an assumption the investigation started from. + +## Where the error comes from + +It is a Google service-layer `400 INVALID_ARGUMENT`, not a client-library check. The public Go, +Python and Node clients carry the content types and serializers but not this string or its +validator. + +- Direct Gemini API, same string: + +- Vertex/gRPC, `io.grpc.StatusRuntimeException: INVALID_ARGUMENT` then the same string: + +- The converse validator captured from `generativelanguage.googleapis.com/...:generateContent`: + "Please ensure that function response turn comes immediately after a function call turn." + +- The exact string captured from `daily-cloudcode-pa.googleapis.com/v1internal:streamGenerateContent`: + + +For ordinary `generateContent` the validated object is the submitted `contents[]`, which Google +describes as holding "the conversation history and the latest request" +(). + +## The ordering the upstream considers valid + +The canonical loop is `user` then `model` carrying `functionCall` then `user` carrying every +matching `functionResponse`. + +- A `user` turn carrying `functionResponse` parts counts as a function-response turn; current + Google examples use `role: "user"` for it, where older ones used `role: "function"`. That churn + explains contradictory cookbook examples. + +- Parallel calls need exactly one response each, together in the immediately following turn: + "Return exactly one `FunctionResponse` for each `FunctionCall` received." + +- Calls and responses must not interleave. Google documents `FC1 + signature, FC2, FR1, FR2` as + valid and `FC1, FR1, FC2, FR2` as a 400. + +- **A model text-only turn immediately followed by a separate model `functionCall` turn is + invalid**: the call turn then follows a model turn, which is exactly what the error rejects. + Same-role adjacency is not forbidden by the protobuf schema, which only constrains role values, + but it is unsafe around function calling. + +## The finding that contradicts the starting assumption + +The issue was narrowed on the grounds that the reporter's A-F matrix all returned 200, so the +translator's adjacency handling was unlikely to be at fault. Case A is exactly the shape above — +`model(text)` then `model(functionCall)` — and the upstream contract says that shape is invalid. +A near-identical report exists against another Antigravity proxy: Gemini 3.6/3.7 Flash failed +after several tool rounds because a converted reasoning carrier became a model turn immediately +before another model `functionCall`, while clean tool ordering and plain chat worked +(). + +`messagesToGeminiFormat` can emit that pair today: it pushes one `model` turn per assistant +message, so a text-only assistant message followed by an assistant message carrying tool calls +serializes as two adjacent model turns. That is a sourced structural candidate, and it is the +first one this investigation has. It is not proof: a 200 on the reporter's isolated case A is a +real observation too, and the two together suggest the rule is enforced conditionally rather than +uniformly. Nothing here establishes which condition. + +Related long-session corruption mechanisms, all of them client-side rather than server-state: + +- orphaned `functionResponse` after a model turn carrying a call plus empty text was dropped: + +- a projected request that began with model tool turns after MCP calls and large masked outputs: + +- checkpoint/resume during pending tool execution producing incomplete call/response batches: + + +Gemini 3.5 Flash has separate intermittent function-call failures with large arguments, but those +surface as `MAX_TOKENS` or `MALFORMED_FUNCTION_CALL`, not this ordering error +(). + +## The session-state hypothesis is unproven + +Cloud Code Assist demonstrably receives both the full history and a session identifier: Gemini +CLI sends `contents: toContents(req.contents)` alongside `session_id: sessionId` and comments +"Use sessionId as trajectoryId" +(, +). +A captured Antigravity request carries `contents`, `sessionId` and `requestType: "agent"` together +(). + +What no public source establishes is that `sessionId` indexes an authoritative server-side +conversation ledger, or that Cloud Code Assist validates `contents[]` against one. Google +documents the opposite default for stateless operation — "you must pass the full history of the +conversation" — and exposes server-side continuation separately through the Interactions API's +`previous_interaction_id` (). +"trajectoryId" is equally compatible with telemetry, agent association or routing. + +## Verdict + +Public evidence explains the error as validation of the serialized tool-call history, and it +supplies several long-session corruption mechanisms on the client side. It does not explain an +intermittent first-send 400 when the exact final Cloud Code Assist payload is independently +valid. Server/client state divergence remains a hypothesis. The issue should stay open. + +## What was built on this evidence + +`src/adapters/google-wire-shape.ts` (PR #5079) projects the structure of the compiled request +without its contents, so the next occurrence can be described from the request that actually +failed. Its `call-turn-after-model-turn` class is the shape named above; the projection reports +it and does not act on it. No translator change was made. diff --git a/scripts/test-layout/layout.json b/scripts/test-layout/layout.json index fb381ba4197..6ef25844349 100644 --- a/scripts/test-layout/layout.json +++ b/scripts/test-layout/layout.json @@ -778,6 +778,7 @@ "google-vertex-stream.test.ts": "adapters/google", "google-vertex-thought-signature.test.ts": "adapters/google", "google-wire-compiler.test.ts": "adapters/google", + "google-wire-shape.test.ts": "adapters/google", "grok-attribution.test.ts": "providers/xai", "grok-config-inject.test.ts": "providers/xai", "grok-effort-inject.test.ts": "providers/xai", diff --git a/src/adapters/google-antigravity-replay.ts b/src/adapters/google-antigravity-replay.ts index 9e3453aa590..d4ab5eb8728 100644 --- a/src/adapters/google-antigravity-replay.ts +++ b/src/adapters/google-antigravity-replay.ts @@ -629,7 +629,7 @@ export function antigravityUsesReplayCache(model: string): boolean { * neither the wire metadata nor the replay cache can supply a real one, this is the official * validator-bypass token. */ -const THOUGHT_SIGNATURE_BYPASS = "skip_thought_signature_validator"; +export const THOUGHT_SIGNATURE_BYPASS = "skip_thought_signature_validator"; /** * True when the model speaks the Gemini wire dialect that requires a thought signature on the diff --git a/src/adapters/google-antigravity-wire.ts b/src/adapters/google-antigravity-wire.ts index 8411c8262eb..a40703f8377 100644 --- a/src/adapters/google-antigravity-wire.ts +++ b/src/adapters/google-antigravity-wire.ts @@ -77,7 +77,7 @@ export function antigravitySessionId(parsed: OcxParsedRequest): string { // // Clients that send no thread header keep the text anchor and its instability; this is a scoped // repair, not a universal one. - const text = clientThreadAnchor(parsed) ?? firstUserText(parsed); + const text = codexThreadAnchor(parsed).preimage ?? firstUserText(parsed); if (!text) return `-${Math.floor(Math.random() * 9e18).toString()}`; const digest = createHash("sha256").update(text, "utf8").digest(); const masked = digest.readBigUInt64BE(0) & 0x7fffffffffffffffn; @@ -96,7 +96,10 @@ export function antigravitySessionId(parsed: OcxParsedRequest): string { * functionCall identity (name+args), so a shared id does not misattribute them. Instability, not * collision, is the failure mode this function exists to prevent. */ -function clientThreadAnchor(parsed: OcxParsedRequest): string | undefined { +function codexThreadAnchor(parsed: OcxParsedRequest): { + kind: "parent-and-own" | "parent-only" | "absent"; + preimage?: string; +} { // `_clientThreadId` carries `x-codex-parent-thread-id`, which every parallel child of one // parent presents identically, so anchoring on it alone collapsed concurrent children onto a // single upstream Cloud Code Assist session (#5033). @@ -113,9 +116,9 @@ function clientThreadAnchor(parsed: OcxParsedRequest): string | undefined { // survive both compaction and restart. const own = parsed._codexOwnThreadId?.trim(); const parent = parsed._clientThreadId?.trim(); - if (own && parent) return `codex-thread:${parent}\u0000${own}`; + if (own && parent) return { kind: "parent-and-own", preimage: `codex-thread:${parent}\u0000${own}` }; // Parent-only clients keep the anchor they already had. - if (parent) return `codex-thread:${parent}`; + if (parent) return { kind: "parent-only", preimage: `codex-thread:${parent}` }; // A parentless ROOT deliberately omits the parent header. `src/server/context-history.ts` says // so in as many words: root model requests use (session-id=root, thread-id=root) and do not // fabricate a parent key. It has no pair to key on, and #5054's claim that a root presents @@ -125,7 +128,28 @@ function clientThreadAnchor(parsed: OcxParsedRequest): string | undefined { // preference: durable Antigravity replay state is keyed by model plus session id, and moving a // root's anchor on upgrade strands every signature stored under the old session — the exact // instability this derivation exists to avoid, introduced while fixing sharing. - return undefined; + return { kind: "absent" }; +} + +/** + * Which class of anchor {@link antigravitySessionId} derives this request's session id from. + * + * The id itself identifies a live conversation and is a Google-visible wire value, so it is not + * something a user can paste into a public bug report. The class is: it distinguishes the four + * stability regimes above — a Codex parent/child pair, a parent-only client, the content-derived + * text anchor that compaction can move, and the random fallback that changes every turn — while + * carrying no identity at all. + * + * It reads the SAME decision the id derivation reads, so the two cannot disagree about which + * regime a request is in. What it does not do is change how the id itself is derived: nothing + * about a Google-visible wire value moves because a diagnostic wants to describe it. + */ +export type AntigravitySessionAnchor = "parent-and-own" | "parent-only" | "text" | "none"; + +export function antigravitySessionAnchor(parsed: OcxParsedRequest): AntigravitySessionAnchor { + const anchor = codexThreadAnchor(parsed); + if (anchor.kind !== "absent") return anchor.kind; + return firstUserText(parsed) ? "text" : "none"; } /** A Gemini content part as it appears in an Antigravity request body. */ diff --git a/src/adapters/google-wire-compiler.ts b/src/adapters/google-wire-compiler.ts index 03cb6de7a34..7b97c96f971 100644 --- a/src/adapters/google-wire-compiler.ts +++ b/src/adapters/google-wire-compiler.ts @@ -208,10 +208,25 @@ function functionDeclarations(root: JsonObject): JsonObject[] { }); } +/** + * Upstream INVALID_ARGUMENT text blaming a tool or function declaration schema. + * + * Shared with the diagnostic error classifier so the repair path and the description of why a + * request was rejected cannot drift into disagreeing about the same payload. + */ +export function isGoogleToolSchemaErrorText(errorPayload: string): boolean { + return /(?:input[_ ]schema|json schema|function[_ ]declarations?|x-mcp-header)/i.test(errorPayload); +} + +/** Upstream INVALID_ARGUMENT text blaming the thinking configuration. */ +export function isGoogleThinkingConfigErrorText(errorPayload: string): boolean { + return /thinking[_ ]?(?:config|level)/i.test(errorPayload); +} + /** Build a changed request for one known-safe replay of an INVALID_ARGUMENT response. */ export function repairGoogleInvalidRequestBody(body: string, errorPayload: string): string | undefined { - const schemaError = /(?:input[_ ]schema|json schema|function[_ ]declarations?|x-mcp-header)/i.test(errorPayload); - const thinkingError = /thinking[_ ]?(?:config|level)/i.test(errorPayload); + const schemaError = isGoogleToolSchemaErrorText(errorPayload); + const thinkingError = isGoogleThinkingConfigErrorText(errorPayload); if (!schemaError && !thinkingError) return undefined; let parsed: unknown; try { diff --git a/src/adapters/google-wire-shape.ts b/src/adapters/google-wire-shape.ts new file mode 100644 index 00000000000..47dfcbabce2 --- /dev/null +++ b/src/adapters/google-wire-shape.ts @@ -0,0 +1,461 @@ +import { MAX_DEBUG_LINE_BYTES } from "../lib/debug-log-buffer"; +import { THOUGHT_SIGNATURE_BYPASS } from "./google-antigravity-replay"; +import type { AntigravitySessionAnchor } from "./google-antigravity-wire"; +import { isGoogleThinkingConfigErrorText, isGoogleToolSchemaErrorText } from "./google-wire-compiler"; + +/** + * Content-free structural projection of a compiled Google-family wire request (#5008). + * + * Why this exists. The report behind #5008 is an intermittent HTTP 400 on the FIRST upstream + * send of a long, tool-heavy Antigravity session: "Please ensure that function call turn comes + * immediately after a user turn or after a function response turn." The reporter's own static + * matrix (A-F on the issue) exercised every adjacency hazard the translator can produce and all + * of them returned 200, so the failing wire cannot be reconstructed from the repro shapes. What + * is missing is a description of the request that actually failed, and the only description a + * user can attach to a public bug report is one that carries no conversation in it. + * + * This module is that description. It reads the request object AFTER compileGoogleWireBody and + * after Antigravity replay/signature adjustment — the exact object the envelope carries — and + * returns counts, positions, kinds and booleans. + * + * What it never retains, by construction rather than by redaction: prompt or system text, tool + * arguments, tool results, tool or function names, original or wire tool-call ids, thought + * signature text or any hash of it, inline file bytes, project or account identifiers, the + * request id, the Cloud Code Assist session id, the Codex thread or session ids, and the first + * user message. Tool-call identity survives only as a request-internal ordinal assigned in + * first-appearance order, which is enough to show pairing structure and is meaningless outside + * the single request that produced it. + * + * Totals are computed over the whole request; per-turn detail is cut at + * GOOGLE_WIRE_SHAPE_TURN_CEILING and the summary is marked truncated. A 440-message session + * therefore still reports its true turn and call counts. + * + * This is a projection, not a validator. It does not decide whether a request is acceptable to + * the upstream, and nothing in the request path consults its output. + * + * What it costs. With provider debug off the projection never runs: the call site passes a + * builder to debugProviderDiagnosticLazy, which returns before invoking it. With provider debug + * ON it runs synchronously on the dispatch path, before the request is sent, and it walks every + * turn, every part and every call id, then serializes, redacts and writes one line. The cost is + * linear in history length, which is largest for exactly the long sessions this exists to + * describe. That is the price of observing the real outbound body rather than a reconstruction, + * and an operator who turns provider debug on for a 440-message session is paying it on every + * turn. + */ + +/** Per-turn detail beyond this many turns is dropped; totals are unaffected. */ +export const GOOGLE_WIRE_SHAPE_TURN_CEILING = 64; + +/** Per-turn ordinal lists are cut here; the turn's own counts are unaffected. */ +export const GOOGLE_WIRE_SHAPE_ORDINAL_CEILING = 16; + +/** Longest error text inspected by classifyGoogleWireUpstreamError. */ +const UPSTREAM_ERROR_SCAN_LIMIT = 2048; + +/** + * Serialized ceiling for one summary, held at half the debug buffer's per-line cap so the event + * prefix and any redaction copy still fit under it. + * + * The item ceilings above are not sufficient on their own: 64 retained turns carrying 16 ordinals + * each serialize past the buffer's limit, and the buffer truncates at a byte boundary. That + * leaves a consumer with JSON it cannot parse whose retained prefix still says truncated is + * false — a cut that hides itself. Trimming here instead keeps the line parseable and keeps the + * flag honest. + */ +export const GOOGLE_WIRE_SHAPE_MAX_SERIALIZED_BYTES = Math.floor(MAX_DEBUG_LINE_BYTES / 2); + +export type GoogleWireTurnRole = "user" | "model" | "other"; + +export type GoogleWirePartKind = + | "text" + | "thought" + | "functionCall" + | "functionResponse" + | "inlineData" + | "other"; + +/** + * Ordering classes transcribed from the upstream error text, not inferred from it. + * + * The message names one relationship — a function-call turn must follow a user turn or a + * function-response turn — so call-turn-opens-request and call-turn-after-model-turn are the two + * ways a well-formed request can contradict it, call-turn-after-unknown-turn covers a predecessor + * that is neither, and response-turn-without-call-turn is its converse. + * request-ends-with-model-turn is a different upstream 400 that messagesToGeminiFormat already + * guards with its "(continue)" nudge; it is projected so a defeated guard is visible rather than + * silent. + * + * A flag is not a verdict. The reporter's case A produces call-turn-after-model-turn and + * returned 200, which is itself worth being able to observe in a real failing request. + */ +export type GoogleWireOrderingViolation = + | "call-turn-opens-request" + | "call-turn-after-model-turn" + | "call-turn-after-unknown-turn" + | "response-turn-without-call-turn" + | "request-ends-with-model-turn"; + +/** Bounded classes for an upstream rejection. The error text itself is never retained. */ +export type GoogleWireUpstreamErrorClass = + | "turn-adjacency" + | "thought-signature" + | "tool-schema" + | "thinking-config" + | "other"; + +export interface GoogleWireTurnShape { + /** Position in contents. */ + index: number; + role: GoogleWireTurnRole; + /** Number of parts in this turn. */ + parts: number; + /** Distinct part kinds, in first-appearance order. */ + kinds: GoogleWirePartKind[]; + /** Request-internal ordinals of the function calls in this turn. */ + calls: number[]; + /** Request-internal ordinals of the function responses in this turn. */ + responses: number[]; + /** Function calls carrying any thought signature. */ + signedCalls: number; + /** Of those, the ones carrying only the validator-bypass sentinel. */ + sentinelCalls: number; + violation?: GoogleWireOrderingViolation; +} + +/** Facts the caller knows and the wire body does not carry. */ +export interface GoogleWireShapeFacts { + /** Which anchor class produced the Antigravity session id. Never the id itself. */ + sessionAnchor?: AntigravitySessionAnchor; + /** + * Function calls the translator signed from client history or the durable replay store, + * counted before the Antigravity session cache runs. + */ + historySignedCalls?: number; + /** A durable replay scope was attached to this request. Its completeness is NOT asserted. */ + replayScopeBound?: boolean; + /** The real physical send this body belongs to, 1 for the first send. */ + sendOrdinal?: number; + /** Bounded class of the upstream rejection, when this body was rejected. */ + errorClass?: GoogleWireUpstreamErrorClass; +} + +export type GoogleWireShapeSummary = { + version: 1; + /** Per-turn detail was cut by a ceiling. Totals below remain exact. */ + truncated: boolean; + turns: number; + roles: Record; + functionCalls: number; + functionResponses: number; + /** Distinct tool-call ids seen anywhere in the request. */ + distinctCallIds: number; + /** Function calls that carried no id at all. */ + callsWithoutId: number; + /** Function responses that carried no id at all. */ + responsesWithoutId: number; + /** Call ordinals no response answers. */ + unansweredCalls: number; + /** Response ordinals no call introduced. */ + unmatchedResponses: number; + toolDeclarations: number; + hasSystemInstruction: boolean; + hasSessionId: boolean; + sessionAnchor: AntigravitySessionAnchor | "unknown"; + signature: { + /** At least one function call reaches the wire with a signature. */ + present: boolean; + /** Every signed call carries only the validator-bypass sentinel. */ + sentinelOnly: boolean; + signedCalls: number; + sentinelCalls: number; + /** Signed at translation time, from client history or the durable replay store. */ + historySignedCalls: number; + /** + * The remainder the Antigravity session cache supplied, clamped at zero. The cache never + * overwrites an existing signature, so the three counts partition the signed calls. + */ + sessionCacheSignedCalls: number; + /** + * A durable replay scope was attached. Whether it was COMPLETE enough to key a lookup is + * decided inside lookupReplayThoughtSignature and is deliberately not claimed here. + */ + replayScopeBound: boolean; + }; + orderingViolations: number; + firstOrderingViolation: { index: number; kind: GoogleWireOrderingViolation } | null; + /** Present only when the caller supplied send facts. */ + send: { ordinal: number; errorClass: GoogleWireUpstreamErrorClass | null } | null; + turnShapes: GoogleWireTurnShape[]; +}; + +function isRecord(value: unknown): value is Record { + return !!value && typeof value === "object" && !Array.isArray(value); +} + +function turnRole(content: Record): GoogleWireTurnRole { + const role = content.role; + return role === "user" || role === "model" ? role : "other"; +} + +function partKind(part: Record): GoogleWirePartKind { + if (part.thought === true) return "thought"; + if (isRecord(part.functionCall)) return "functionCall"; + if (isRecord(part.functionResponse)) return "functionResponse"; + if (isRecord(part.inline_data) || isRecord(part.inlineData)) return "inlineData"; + if (typeof part.text === "string") return "text"; + return "other"; +} + +/** + * A function call or response id, read only to be replaced by an ordinal. The value never + * leaves this function. + */ +function callIdOf(call: Record): string | undefined { + const id = call.id; + return typeof id === "string" && id.length > 0 ? id : undefined; +} + +function signatureOf(part: Record): string | undefined { + const camel = part.thoughtSignature; + if (typeof camel === "string" && camel.length > 0) return camel; + const snake = part.thought_signature; + if (typeof snake === "string" && snake.length > 0) return snake; + return undefined; +} + +/** Request-internal renumbering: first appearance wins, and the mapping dies with the call. */ +function ordinalAllocator(): (rawId: string) => number { + const ordinals = new Map(); + return rawId => { + const existing = ordinals.get(rawId); + if (existing !== undefined) return existing; + const next = ordinals.size + 1; + ordinals.set(rawId, next); + return next; + }; +} + +function countToolDeclarations(tools: unknown): number { + if (!Array.isArray(tools)) return 0; + let total = 0; + for (const tool of tools) { + if (!isRecord(tool) || !Array.isArray(tool.functionDeclarations)) continue; + total += tool.functionDeclarations.length; + } + return total; +} + +interface TurnFacts { + role: GoogleWireTurnRole; + hasFunctionCall: boolean; + hasFunctionResponse: boolean; +} + +/** + * The first ordering class this turn contradicts, judged against the turn before it. + * + * "Function response turn" is read as a user turn carrying at least one functionResponse, which + * is the shape messagesToGeminiFormat emits for a tool-result batch. A plain user turn satisfies + * the rule on its own, so a call turn after either one is unflagged. + */ +function violationFor(turn: TurnFacts, previous: TurnFacts | undefined, isLast: boolean): GoogleWireOrderingViolation | undefined { + if (turn.role === "model" && turn.hasFunctionCall) { + if (!previous) return "call-turn-opens-request"; + if (previous.role === "model") return "call-turn-after-model-turn"; + if (previous.role !== "user") return "call-turn-after-unknown-turn"; + } + if (turn.role === "user" && turn.hasFunctionResponse) { + if (!previous || previous.role !== "model" || !previous.hasFunctionCall) { + return "response-turn-without-call-turn"; + } + } + if (isLast && turn.role === "model") return "request-ends-with-model-turn"; + return undefined; +} + +function serializedBytes(summary: GoogleWireShapeSummary): number { + return new TextEncoder().encode(JSON.stringify(summary)).length; +} + +/** + * Drop per-turn detail from the tail until the summary serializes under its byte budget. + * + * Trimming from the tail rather than the head is deliberate: the opening turns of a request are + * where a first-send ordering violation lives, and they are what a reader needs most. + */ +function fitToSerializedBudget(summary: GoogleWireShapeSummary): GoogleWireShapeSummary { + if (serializedBytes(summary) <= GOOGLE_WIRE_SHAPE_MAX_SERIALIZED_BYTES) return summary; + let kept = summary.turnShapes.length; + let fitted: GoogleWireShapeSummary = { ...summary, truncated: true, turnShapes: summary.turnShapes }; + while (kept > 0 && serializedBytes(fitted) > GOOGLE_WIRE_SHAPE_MAX_SERIALIZED_BYTES) { + kept -= 1; + fitted = { ...summary, truncated: true, turnShapes: summary.turnShapes.slice(0, kept) }; + } + return fitted; +} + +/** + * Project the structure of a compiled Google wire request body. + * + * Pure and non-mutating: every field is read, nothing is written back, and the returned object + * shares no reference with the input. + */ +export function summarizeGoogleWireShape( + body: unknown, + facts: GoogleWireShapeFacts = {}, +): GoogleWireShapeSummary { + const root = isRecord(body) ? body : {}; + const contents: unknown[] = Array.isArray(root.contents) ? root.contents : []; + const ordinalFor = ordinalAllocator(); + const historySignedCalls = Math.max(0, facts.historySignedCalls ?? 0); + + const roles: Record = { user: 0, model: 0, other: 0 }; + const callOrdinals = new Set(); + const responseOrdinals = new Set(); + const turnShapes: GoogleWireTurnShape[] = []; + + let functionCalls = 0; + let functionResponses = 0; + let callsWithoutId = 0; + let responsesWithoutId = 0; + let signedCalls = 0; + let sentinelCalls = 0; + let orderingViolations = 0; + let truncated = false; + let firstOrderingViolation: GoogleWireShapeSummary["firstOrderingViolation"] = null; + let previous: TurnFacts | undefined; + + for (let index = 0; index < contents.length; index++) { + const rawContent: unknown = contents[index]; + const content = isRecord(rawContent) ? rawContent : {}; + const role = turnRole(content); + roles[role] += 1; + const parts: unknown[] = Array.isArray(content.parts) ? content.parts : []; + const kinds: GoogleWirePartKind[] = []; + const calls: number[] = []; + const responses: number[] = []; + let turnSignedCalls = 0; + let turnSentinelCalls = 0; + + for (const rawPart of parts) { + const part = isRecord(rawPart) ? rawPart : {}; + const kind = partKind(part); + if (!kinds.includes(kind)) kinds.push(kind); + if (kind === "functionCall") { + functionCalls += 1; + const id = callIdOf(part.functionCall as Record); + if (id === undefined) { + callsWithoutId += 1; + } else { + const ordinal = ordinalFor(id); + callOrdinals.add(ordinal); + if (calls.length < GOOGLE_WIRE_SHAPE_ORDINAL_CEILING) calls.push(ordinal); + else truncated = true; + } + const signature = signatureOf(part); + if (signature !== undefined) { + turnSignedCalls += 1; + if (signature === THOUGHT_SIGNATURE_BYPASS) turnSentinelCalls += 1; + } + } else if (kind === "functionResponse") { + functionResponses += 1; + const id = callIdOf(part.functionResponse as Record); + if (id === undefined) { + responsesWithoutId += 1; + } else { + const ordinal = ordinalFor(id); + responseOrdinals.add(ordinal); + if (responses.length < GOOGLE_WIRE_SHAPE_ORDINAL_CEILING) responses.push(ordinal); + else truncated = true; + } + } + } + + signedCalls += turnSignedCalls; + sentinelCalls += turnSentinelCalls; + const current: TurnFacts = { + role, + hasFunctionCall: kinds.includes("functionCall"), + hasFunctionResponse: kinds.includes("functionResponse"), + }; + const violation = violationFor(current, previous, index === contents.length - 1); + if (violation) { + orderingViolations += 1; + if (!firstOrderingViolation) firstOrderingViolation = { index, kind: violation }; + } + if (turnShapes.length < GOOGLE_WIRE_SHAPE_TURN_CEILING) { + turnShapes.push({ + index, + role, + parts: parts.length, + kinds, + calls, + responses, + signedCalls: turnSignedCalls, + sentinelCalls: turnSentinelCalls, + ...(violation ? { violation } : {}), + }); + } else { + truncated = true; + } + previous = current; + } + + let unansweredCalls = 0; + for (const ordinal of callOrdinals) if (!responseOrdinals.has(ordinal)) unansweredCalls += 1; + let unmatchedResponses = 0; + for (const ordinal of responseOrdinals) if (!callOrdinals.has(ordinal)) unmatchedResponses += 1; + + return fitToSerializedBudget({ + version: 1, + truncated, + turns: contents.length, + roles, + functionCalls, + functionResponses, + distinctCallIds: new Set([...callOrdinals, ...responseOrdinals]).size, + callsWithoutId, + responsesWithoutId, + unansweredCalls, + unmatchedResponses, + toolDeclarations: countToolDeclarations(root.tools), + hasSystemInstruction: isRecord(root.systemInstruction), + hasSessionId: typeof root.sessionId === "string" && root.sessionId.length > 0, + sessionAnchor: facts.sessionAnchor ?? "unknown", + signature: { + present: signedCalls > 0, + sentinelOnly: signedCalls > 0 && signedCalls === sentinelCalls, + signedCalls, + sentinelCalls, + historySignedCalls, + sessionCacheSignedCalls: Math.max(0, signedCalls - sentinelCalls - historySignedCalls), + replayScopeBound: facts.replayScopeBound === true, + }, + orderingViolations, + firstOrderingViolation, + send: facts.sendOrdinal === undefined + ? null + : { ordinal: facts.sendOrdinal, errorClass: facts.errorClass ?? null }, + turnShapes, + }); +} + +/** + * Classify an upstream rejection into one of a fixed set of classes. + * + * Bounded in both directions: at most UPSTREAM_ERROR_SCAN_LIMIT characters are inspected, and + * only the class is returned, so no upstream text reaches a caller through this function. + */ +export function classifyGoogleWireUpstreamError(message: unknown): GoogleWireUpstreamErrorClass { + if (typeof message !== "string" || message.length === 0) return "other"; + const scanned = message.slice(0, UPSTREAM_ERROR_SCAN_LIMIT); + if (/function\s+call\s+turn|function\s+response\s+turn|model\s+turn\s+are\s+not\s+supported|assistant\s+message\s+prefill/i.test(scanned)) { + return "turn-adjacency"; + } + if (/thought[_\s-]?signature|TYPE_BYTES/i.test(scanned)) return "thought-signature"; + // Shared with the wire compiler's repair path so a payload cannot be repaired as one class + // and described as another. + if (isGoogleToolSchemaErrorText(scanned)) return "tool-schema"; + if (isGoogleThinkingConfigErrorText(scanned)) return "thinking-config"; + return "other"; +} diff --git a/src/adapters/google.ts b/src/adapters/google.ts index 685cd2177cd..449870c0b3e 100644 --- a/src/adapters/google.ts +++ b/src/adapters/google.ts @@ -1,5 +1,5 @@ import type { AdapterFetchContext, AdapterRequest, ProviderAdapter } from "./base"; -import { debugDroppedFrame } from "../lib/debug"; +import { debugDroppedFrame, debugProviderDiagnosticLazy } from "../lib/debug"; import { createToolCallIdAllocator } from "./tool-call-id"; import { createImageBudget, materializeInlineImage, MAX_ENCODED_BYTES_PER_IMAGE, artifactHttpUrl } from "../images/artifacts"; import type { @@ -20,7 +20,8 @@ import { getVertexAccessToken } from "../lib/gcp-adc"; import { fetchAntigravityWithRetry, fetchVertexWithRetry } from "./google-http"; import { safeAntigravityHttpErrorMessage, safeVertexHttpErrorMessage } from "./google-errors"; import { isVertexTruncatedTurn, vertexTruncationErrorMessage } from "./google-truncation"; -import { ANTIGRAVITY_REQUEST_UA, antigravitySessionId, isLikelyRealThoughtSignature, sanitizeAntigravityClaudeSignatures } from "./google-antigravity-wire"; +import { ANTIGRAVITY_REQUEST_UA, antigravitySessionAnchor, antigravitySessionId, isLikelyRealThoughtSignature, sanitizeAntigravityClaudeSignatures } from "./google-antigravity-wire"; +import { summarizeGoogleWireShape } from "./google-wire-shape"; import { compileGoogleWireBody } from "./google-wire-compiler"; import { identifyRoutedModel } from "./identity"; import { @@ -989,6 +990,20 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte // Vertex and AI Studio share one decision. A second check here would append a // duplicate nudge whenever signature sanitization reshapes the tail afterwards. } + // Opt-in structural description of the request that is about to leave (#5008). + // + // Passed as a BUILDER, not a value: the lazy form gates before invoking it, so a session + // with provider debug off never pays the walk, and it evaluates the projection inside its + // own try/catch, so a throw in here cannot turn a built request into a rejected one. The + // projection only reads `request`, so the bytes below are the same either way. + debugProviderDiagnosticLazy("google", "antigravity-wire-shape", () => summarizeGoogleWireShape(request, { + sessionAnchor: antigravitySessionAnchor(parsed), + // Signed at translation time, from client history or the durable store. The + // Antigravity session cache signs afterwards, inside applyAntigravityReplay, and the + // projection attributes that remainder to the cache rather than to this count. + historySignedCalls: replayedCallIds.length, + replayScopeBound: parsed._reasoningReplayScope !== undefined, + })); const envelope = { model: wireModelId, // The envelope's `userAgent` field is a protocol constant ("antigravity"), distinct from diff --git a/src/lib/debug-log-buffer.ts b/src/lib/debug-log-buffer.ts index 17e0fc84bb0..df355ec2a93 100644 --- a/src/lib/debug-log-buffer.ts +++ b/src/lib/debug-log-buffer.ts @@ -9,7 +9,12 @@ export interface DebugLogEntry { const MAX_LINES = 2_000; const MAX_DEBUG_SUBSCRIBERS = 64; -const MAX_DEBUG_LINE_BYTES = 16 * 1024; +/** + * Per-line retention cap. Exported because a producer of a long structured line has to budget + * BELOW it: this buffer truncates at a byte boundary, so a JSON line cut here stops being + * parseable while its retained prefix still reads as complete. + */ +export const MAX_DEBUG_LINE_BYTES = 16 * 1024; const buffer: DebugLogEntry[] = []; interface DebugSubscriberRegistration { lease: AdmissionLease } const listeners = new Map<(entry: DebugLogEntry) => void, DebugSubscriberRegistration>(); diff --git a/src/lib/debug.ts b/src/lib/debug.ts index 5d4b54b050f..938e5737ea7 100644 --- a/src/lib/debug.ts +++ b/src/lib/debug.ts @@ -29,3 +29,26 @@ export function debugProviderDiagnostic(adapter: string, event: string, details: /* diagnostics must never affect request handling */ } } + +/** + * The same diagnostic for details that are expensive to compute or read live request state. + * + * The eager form takes an already-built object, so the build runs in ARGUMENT position: outside + * this module's gate, and outside its try/catch. For a projection that walks a whole request + * that is wrong twice over — it pays the walk while debug is off, and a throw inside it reaches + * the caller, which for an adapter means a built request becomes a rejected one and a send that + * would have happened does not. Pass the builder instead: it runs only when debug is on, and a + * throw inside it is swallowed exactly like a throw in the emit. + */ +export function debugProviderDiagnosticLazy( + adapter: string, + event: string, + details: () => Record, +): void { + if (!isDebugEnabled()) return; + try { + emitDebugLine(`[ocx:${adapter}:${event}] ${JSON.stringify(redactSecrets(details()))}`); + } catch { + /* diagnostics must never affect request handling */ + } +} diff --git a/structure/providers/google.md b/structure/providers/google.md index 21d22fc15c6..3da16fe08a3 100644 --- a/structure/providers/google.md +++ b/structure/providers/google.md @@ -72,3 +72,40 @@ a claim about what the upstream can do); an image-capable model, whose `response configuration contradicts JSON-constrained text; and a `json_schema` format carrying no schema, which would otherwise downgrade to bare JSON mode. An image-capable model with no structured-output request keeps its existing `responseModalities` behavior. + +## Google wire-shape projection + +`src/adapters/google-wire-shape.ts` describes a compiled Google request without carrying any of +it. `summarizeGoogleWireShape` reads the body after `compileGoogleWireBody` and after Antigravity +replay and signature adjustment, which is the object the envelope sends, and returns per-role turn +counts, function call and response counts and their pairing, the position and class of the first +ordering violation, signature presence and sentinel-only signing, the session anchor class, and a +bounded upstream error class. Tool-call identity survives only as a request-internal ordinal in +first-appearance order. + +What it must never retain is the point of the module: prompt or system text, tool arguments and +results, tool and function names, original or wire call ids, signature text or any hash of it, +inline file bytes, project and account identifiers, the request id, the Cloud Code Assist session +id, Codex thread and session ids, and the first user message. Totals stay exact for the whole +request while per-turn detail stops at a fixed ceiling and sets `truncated`, so a long agentic +session still reports its real counts. + +It is a projection, not a validator. Nothing in the request path consults its output. +`antigravitySessionAnchor` in `google-antigravity-wire.ts` is the matching content-free read of +the session boundary: it reports which of the four anchor classes produced the session id without +reporting the id, and it reads the same decision the id derivation reads, so the two cannot +disagree about which regime a request is in. + +The adapter passes a builder to `debugProviderDiagnosticLazy`, never a built object. That gates +before invoking it, so a request with provider debug off never pays the walk, and it evaluates +the projection inside the logger's own try/catch, so a throw in a diagnostic cannot turn a built +request into a rejected one. With provider debug ON the projection runs synchronously on the +dispatch path before the request is sent, and its cost is linear in history length — largest for +exactly the long sessions it exists to describe. Observing the real outbound body rather than a +reconstruction is what that buys. + +Two ceilings bound the output, and both are needed. The item ceilings cap retained turns and the +per-turn ordinal lists; the serialized ceiling, held at half `MAX_DEBUG_LINE_BYTES`, then trims +turn detail from the tail until the summary fits. Without the second, a worst case inside the +first serializes past the debug buffer's per-line cap, and the buffer truncates at a byte +boundary: the consumer gets unparseable JSON whose retained prefix still reads `truncated: false`. diff --git a/structure/transports/inventory.md b/structure/transports/inventory.md index b63b0f23a25..3e94190d1ca 100644 --- a/structure/transports/inventory.md +++ b/structure/transports/inventory.md @@ -26,7 +26,7 @@ surface is listed here so a maintainer can find the owner without grepping: | --- | --- | --- | | Azure OpenAI Responses | `src/adapters/azure.ts` | Deployment-shaped URLs on top of the Responses contract. | | Meta Muse Responses tool names | `src/responses/muse-tool-name-alias.ts`, `src/adapters/openai-responses.ts` | `api.meta.ai` only: function names over 64 characters or containing characters outside `[a-zA-Z0-9_-]` become collision-safe wire aliases and are restored before the client sees them. | -| Google / Vertex / Antigravity | `src/adapters/google.ts`, `src/adapters/google-http.ts`, `src/adapters/google-wire-compiler.ts`, `src/adapters/google-tool-schema.ts`, `src/adapters/google-truncation.ts`, `src/adapters/google-errors.ts`, `src/adapters/google-antigravity-wire.ts`, `src/adapters/google-antigravity-replay.ts` | Vertex and Antigravity install a Google-family `fetchResponse` and so own their retry policy, while AI Studio Gemini leaves it undefined and uses the default server fetch path. The Google-family wrapper reuses the shared abort/deadline helpers (`src/lib/upstream-retry.ts`), wire-body repair, and upstream error normalization. | +| Google / Vertex / Antigravity | `src/adapters/google.ts`, `src/adapters/google-http.ts`, `src/adapters/google-wire-compiler.ts`, `src/adapters/google-tool-schema.ts`, `src/adapters/google-truncation.ts`, `src/adapters/google-errors.ts`, `src/adapters/google-antigravity-wire.ts`, `src/adapters/google-antigravity-replay.ts`, `src/adapters/google-wire-shape.ts` | Vertex and Antigravity install a Google-family `fetchResponse` and so own their retry policy, while AI Studio Gemini leaves it undefined and uses the default server fetch path. The Google-family wrapper reuses the shared abort/deadline helpers (`src/lib/upstream-retry.ts`), wire-body repair, and upstream error normalization. `google-wire-shape.ts` sits outside that path entirely: it only reads the compiled body, and only when provider debug is on. | | Mimo Free | `src/adapters/mimo-free.ts` | Client identity and JWT handling are transport-local; the per-install client id lives in the opencodex state root. | | Anthropic image ingress | `src/adapters/anthropic-image-guard.ts`, `src/adapters/anthropic-image-normalize.ts`, `src/adapters/anthropic-image-codec.ts` | Oversized or unsupported images are normalized or rejected before reaching upstream. An image's ladder position is pinned to its own identity (content hash + media type) rather than recomputed from recency each request (#4532); appending a newer image therefore cannot demote and re-encode older images and bust Anthropic's prompt prefix cache. Unseen images still take the age-tier pyramid's first position, the total byte budget still binds, and a 413 `tierBias` retry still applies. Recorded positions only move down the ladder, so the store is monotonic. | | Adapter execution support | `src/adapters/run-turn-queue.ts`, `src/adapters/tool-catalog-nudge.ts`, `src/adapters/identity.ts`, `src/adapters/image.ts`, `src/adapters/upstream-http-error.ts` | Shared machinery: turn ordering, tool-catalog nudging, client fingerprinting, image conversion, upstream error normalization. | diff --git a/tests/adapters/google/google-wire-shape.test.ts b/tests/adapters/google/google-wire-shape.test.ts new file mode 100644 index 00000000000..82ac7eca358 --- /dev/null +++ b/tests/adapters/google/google-wire-shape.test.ts @@ -0,0 +1,622 @@ +import { afterEach, describe, expect, test } from "bun:test"; +import { createGoogleAdapter as createGoogleAdapterProduction } from "../../../src/adapters/google"; +import { antigravitySessionAnchor, antigravitySessionId } from "../../../src/adapters/google-antigravity-wire"; +import { + classifyGoogleWireUpstreamError, + GOOGLE_WIRE_SHAPE_MAX_SERIALIZED_BYTES, + GOOGLE_WIRE_SHAPE_TURN_CEILING, + summarizeGoogleWireShape, +} from "../../../src/adapters/google-wire-shape"; +import { debugProviderDiagnosticLazy } from "../../../src/lib/debug"; +import { getDebugLogEntries, MAX_DEBUG_LINE_BYTES, resetDebugLogBufferForTests } from "../../../src/lib/debug-log-buffer"; +import { resetDebugSettingsForTests, setDebugSettings } from "../../../src/lib/debug-settings"; +import { createRequestExecutionBudget, type RequestExecutionBudgetPolicy } from "../../../src/lib/request-execution-budget"; +import type { OcxParsedRequest, OcxProviderConfig } from "../../../src/types"; +import { + callId, + compactedToolSession, + compiledWireBody, + longToolSession, + modelCallTurn, + modelTextTurn, + THOUGHT_SIGNATURE_SENTINEL, + toolResultTurn, + toolRoundTrip, + unidentifiedCallTurn, + userTurn, + WIRE_MARKERS, + type WireTurn, +} from "../../fixtures/google-wire-shape-cases"; +import { withTestTranslatorBudget } from "../../helpers/translator-budget"; + +const createGoogleAdapter = (...args: Parameters) => + withTestTranslatorBudget(createGoogleAdapterProduction(...args)); + +const provider = { + adapter: "google", + baseUrl: "https://daily-cloudcode-pa.googleapis.com", + googleMode: "cloud-code-assist", + project: "proj-123", + apiKey: "ya29.token", +} as OcxProviderConfig; + +/** Exactly `sends` physical sends allowed, with no reserve and no alternate target. */ +function budgetOf(sends: number) { + const policy: RequestExecutionBudgetPolicy = { + maxTotalModelSends: sends, + baseSendAllowance: sends, + finalRecoveryAllowance: 0, + maxAlternateTargetSends: 0, + maxTargetTransitions: 0, + }; + return createRequestExecutionBudget(policy, "lr-google-wire-shape-test"); +} + +function parsedToolSession(rounds: number, threads: { parent?: string; own?: string } = {}): OcxParsedRequest { + const messages: unknown[] = [{ role: "user", content: "opening turn" }]; + for (let round = 1; round <= rounds; round++) { + messages.push({ + role: "assistant", + content: [{ type: "toolCall", id: `call-${round}`, name: "search", arguments: { q: "x" } }], + }); + messages.push({ role: "toolResult", toolCallId: `call-${round}`, toolName: "search", content: "ok" }); + } + messages.push({ role: "user", content: "next turn" }); + return { + modelId: "gemini-3-pro", + stream: false, + context: { messages, systemPrompt: [], tools: [] }, + options: {}, + ...(threads.parent === undefined ? {} : { _clientThreadId: threads.parent }), + ...(threads.own === undefined ? {} : { _codexOwnThreadId: threads.own }), + } as unknown as OcxParsedRequest; +} + +function parsedWithThreads(threads: { parent?: string; own?: string }, firstText = "opening turn"): OcxParsedRequest { + return { + modelId: "gemini-3-pro", + stream: false, + context: { messages: [{ role: "user", content: firstText }], systemPrompt: [], tools: [] }, + options: {}, + ...(threads.parent === undefined ? {} : { _clientThreadId: threads.parent }), + ...(threads.own === undefined ? {} : { _codexOwnThreadId: threads.own }), + } as unknown as OcxParsedRequest; +} + +/** Every marker the fixtures plant, so one assertion can prove none of them survives. */ +const ALL_MARKERS = [...Object.values(WIRE_MARKERS), callId(1), callId(2), callId(3)]; + +afterEach(() => { + resetDebugSettingsForTests(); + resetDebugLogBufferForTests(); +}); + +// The projection is a diagnostic. If it can move a byte, a send, or a signature, it is worse +// than the missing information it exists to supply — so this runs before anything about shape. +describe("google wire shape projection is inert", () => { + test("summarizing does not mutate the body it reads", () => { + const body = compiledWireBody(longToolSession(5, { signature: WIRE_MARKERS.signature }), { + toolDeclarations: 3, + }); + const before = JSON.stringify(body); + summarizeGoogleWireShape(body, { sessionAnchor: "parent-and-own", sendOrdinal: 1 }); + expect(JSON.stringify(body)).toBe(before); + }); + + test("provider debug changes neither the compiled request nor the headers", async () => { + const adapter = createGoogleAdapter(provider); + const request = parsedToolSession(4, { parent: "tp-9f31", own: "tc-4a02" }); + const realError = console.error; + console.error = () => {}; + try { + setDebugSettings({ debug: false }); + const off = await adapter.buildRequest(request); + setDebugSettings({ debug: true }); + const on = await adapter.buildRequest(request); + const offEnvelope = JSON.parse(off.body) as Record; + const onEnvelope = JSON.parse(on.body) as Record; + expect(JSON.stringify(onEnvelope.request)).toBe(JSON.stringify(offEnvelope.request)); + expect(on.url).toBe(off.url); + expect(on.method).toBe(off.method); + expect(JSON.stringify(on.headers)).toBe(JSON.stringify(off.headers)); + // The envelope requestId is a fresh uuid per build and is the only difference allowed. + expect(onEnvelope.requestId).not.toBe(offEnvelope.requestId); + } finally { + console.error = realError; + } + }); + + // buildRequest never calls fetch, so counting fetches around it proves nothing about the + // diagnostic. The send count worth pinning is the one the budget and the physical-send + // observer see on the real dispatch path, with the request the diagnostic just described. + test("provider debug changes neither the physical send count nor the bytes dispatched", async () => { + const adapter = createGoogleAdapter(provider); + const parsedRequest = parsedToolSession(4, { parent: "tp-9f31", own: "tc-4a02" }); + const realError = console.error; + console.error = () => {}; + try { + const run = async (debug: boolean) => { + setDebugSettings({ debug }); + const built = await adapter.buildRequest(parsedRequest); + const sends: number[] = []; + const dispatched: string[] = []; + const executor = (async (_input: unknown, init?: { body?: unknown }) => { + dispatched.push(typeof init?.body === "string" ? init.body : ""); + return new Response(JSON.stringify({ response: { candidates: [] } }), { + status: 200, headers: { "content-type": "application/json" }, + }); + }) as unknown as typeof globalThis.fetch; + const response = await adapter.fetchResponse!(built, { + executor, + sendBudget: budgetOf(3), + onPhysicalSend: send => { sends.push(send.ordinal); }, + timeoutMs: 5_000, + }); + expect(response.status).toBe(200); + const envelope = JSON.parse(dispatched[0]!) as Record; + const requestId = envelope.requestId; + // The envelope request id is a fresh uuid per build and has nothing to do with debug; + // normalizing it lets the rest of the dispatched body be compared byte for byte. + envelope.requestId = ""; + return { sends, requestId, body: JSON.stringify(envelope) }; + }; + const off = await run(false); + const on = await run(true); + // Exactly one physical send either way, and the budget saw the same single dispatch. + expect(off.sends).toEqual([1]); + expect(on.sends).toEqual(off.sends); + // And every byte that actually left is identical apart from that uuid — not merely the + // bytes that were built. + expect(on.body).toBe(off.body); + expect(on.requestId).not.toBe(off.requestId); + } finally { + console.error = realError; + } + }); + + // Proven by execution, not asserted: the exact expression google.ts hands to the lazy logger, + // given a body that throws when the projection reads it. + test("a projection that throws is swallowed and emits nothing", () => { + const hostile = { + get contents(): never { throw new Error("projection boom"); }, + }; + setDebugSettings({ debug: true }); + resetDebugLogBufferForTests(); + expect(() => debugProviderDiagnosticLazy( + "google", "antigravity-wire-shape", () => summarizeGoogleWireShape(hostile), + )).not.toThrow(); + expect(getDebugLogEntries()).toEqual([]); + }); + + test("the builder is never invoked while provider debug is off", () => { + let built = 0; + setDebugSettings({ debug: false }); + debugProviderDiagnosticLazy("google", "antigravity-wire-shape", () => { + built += 1; + return {}; + }); + expect(built).toBe(0); + }); + + test("the emitted diagnostic carries no prompt, argument, result, id or signature", async () => { + const adapter = createGoogleAdapter(provider); + const realError = console.error; + console.error = () => {}; + try { + setDebugSettings({ debug: true }); + resetDebugLogBufferForTests(); + await adapter.buildRequest(parsedToolSession(3, { parent: "tp-9f31", own: "tc-4a02" })); + const line = getDebugLogEntries().map(entry => entry.line).find(l => l.includes("antigravity-wire-shape")); + expect(line).toBeDefined(); + const emitted = line as string; + for (const secret of ["opening turn", "next turn", "search", "call-1", "call-2", "proj-123", "ya29.token", THOUGHT_SIGNATURE_SENTINEL, "tp-9f31", "tc-4a02"]) { + expect(emitted).not.toContain(secret); + } + expect(emitted).toContain("\"sessionAnchor\":\"parent-and-own\""); + } finally { + console.error = realError; + } + }); + + test("provider debug off emits nothing at all", async () => { + const adapter = createGoogleAdapter(provider); + setDebugSettings({ debug: false }); + resetDebugLogBufferForTests(); + await adapter.buildRequest(parsedToolSession(3, { parent: "tp-9f31", own: "tc-4a02" })); + expect(getDebugLogEntries()).toEqual([]); + }); +}); + +describe("google wire shape projection describes structure", () => { + test("a well-formed tool round trip projects its roles, counts and pairing", () => { + const summary = summarizeGoogleWireShape( + compiledWireBody([userTurn(), ...toolRoundTrip(1), userTurn()], { toolDeclarations: 37 }), + { sessionAnchor: "parent-and-own" }, + ); + expect(summary.turns).toBe(4); + expect(summary.roles).toEqual({ user: 3, model: 1, other: 0 }); + expect(summary.functionCalls).toBe(1); + expect(summary.functionResponses).toBe(1); + expect(summary.distinctCallIds).toBe(1); + expect(summary.unansweredCalls).toBe(0); + expect(summary.unmatchedResponses).toBe(0); + expect(summary.toolDeclarations).toBe(37); + expect(summary.hasSystemInstruction).toBe(true); + expect(summary.hasSessionId).toBe(true); + expect(summary.orderingViolations).toBe(0); + expect(summary.firstOrderingViolation).toBeNull(); + expect(summary.truncated).toBe(false); + expect(summary.turnShapes[1]).toEqual({ + index: 1, + role: "model", + parts: 1, + kinds: ["functionCall"], + calls: [1], + responses: [], + signedCalls: 0, + sentinelCalls: 0, + }); + expect(summary.turnShapes[2]?.responses).toEqual([1]); + }); + + test("call ids become request-internal ordinals, so unrelated ids project identically", () => { + const first = compiledWireBody([ + userTurn("first conversation"), + modelCallTurn(["alpha-7f3c", "beta-1"]), + toolResultTurn(["beta-1", "alpha-7f3c"]), + ]); + const second = compiledWireBody([ + userTurn("an entirely different conversation"), + modelCallTurn(["toolu_01QqRz", "fc_9928"]), + toolResultTurn(["fc_9928", "toolu_01QqRz"]), + ]); + expect(summarizeGoogleWireShape(first)).toEqual(summarizeGoogleWireShape(second)); + const summary = summarizeGoogleWireShape(first); + expect(summary.turnShapes[1]?.calls).toEqual([1, 2]); + // Responses keep their own order, and the ordinals show the answers were transposed. + expect(summary.turnShapes[2]?.responses).toEqual([2, 1]); + expect(JSON.stringify(summary)).not.toContain("alpha-7f3c"); + }); + + test("a call turn that opens the request is flagged with its position", () => { + const summary = summarizeGoogleWireShape(compiledWireBody([ + modelCallTurn([callId(1)]), + toolResultTurn([callId(1)]), + ])); + expect(summary.firstOrderingViolation).toEqual({ index: 0, kind: "call-turn-opens-request" }); + expect(summary.orderingViolations).toBe(1); + }); + + // The reporter's case A. It is flagged because the upstream error names this relationship, + // and it returned 200 upstream — which is why this projection reports rather than judges. + test("a call turn after a model text turn is flagged as such", () => { + const summary = summarizeGoogleWireShape(compiledWireBody([ + userTurn(), + modelTextTurn(), + modelCallTurn([callId(1)]), + toolResultTurn([callId(1)]), + ])); + expect(summary.firstOrderingViolation).toEqual({ index: 2, kind: "call-turn-after-model-turn" }); + expect(summary.roles).toEqual({ user: 2, model: 2, other: 0 }); + }); + + test("a response turn with no call turn before it is flagged", () => { + const summary = summarizeGoogleWireShape(compiledWireBody([ + userTurn(), + toolResultTurn([callId(1)]), + ])); + expect(summary.firstOrderingViolation).toEqual({ index: 1, kind: "response-turn-without-call-turn" }); + expect(summary.unmatchedResponses).toBe(1); + expect(summary.unansweredCalls).toBe(0); + }); + + test("a model tail is flagged, which is what the (continue) nudge exists to prevent", () => { + const summary = summarizeGoogleWireShape(compiledWireBody([userTurn(), modelTextTurn()])); + expect(summary.firstOrderingViolation).toEqual({ index: 1, kind: "request-ends-with-model-turn" }); + }); + + test("a call turn after an unrecognized role is not blamed on a model turn", () => { + const summary = summarizeGoogleWireShape(compiledWireBody([ + userTurn(), + { role: "function", parts: [{ text: WIRE_MARKERS.prompt }] }, + modelCallTurn([callId(1)]), + toolResultTurn([callId(1)]), + ])); + expect(summary.roles).toEqual({ user: 2, model: 1, other: 1 }); + expect(summary.firstOrderingViolation).toEqual({ index: 2, kind: "call-turn-after-unknown-turn" }); + }); + + // The exhaustive leak oracle: every marker the fixtures plant, checked against one projection. + test("no marker the fixture plants survives into a summary", () => { + const summary = summarizeGoogleWireShape( + compiledWireBody([ + userTurn(), + ...toolRoundTrip(1, { signature: WIRE_MARKERS.signature }), + ...toolRoundTrip(2), + modelCallTurn([callId(3)]), + toolResultTurn([callId(3)]), + ], { toolDeclarations: 4 }), + { sessionAnchor: "parent-and-own", historySignedCalls: 1, replayScopeBound: true, sendOrdinal: 1, errorClass: "turn-adjacency" }, + ); + const serialized = JSON.stringify(summary); + for (const marker of ALL_MARKERS) expect(serialized).not.toContain(marker); + // The projection is not vacuous: it did describe the request it refused to quote. + expect(summary.functionCalls).toBe(3); + expect(summary.toolDeclarations).toBe(4); + expect(summary.hasSessionId).toBe(true); + expect(summary.signature.present).toBe(true); + }); + + test("an unanswered call and an id-less call are counted separately", () => { + const summary = summarizeGoogleWireShape(compiledWireBody([ + userTurn(), + modelCallTurn([callId(1), callId(2)]), + toolResultTurn([callId(1)]), + unidentifiedCallTurn(), + userTurn(), + ])); + expect(summary.functionCalls).toBe(3); + expect(summary.callsWithoutId).toBe(1); + expect(summary.unansweredCalls).toBe(1); + expect(summary.distinctCallIds).toBe(2); + }); + + test("a long session keeps exact totals and truncates only its per-turn detail", () => { + const rounds = 60; + const summary = summarizeGoogleWireShape(compiledWireBody(longToolSession(rounds))); + expect(summary.turns).toBe(2 + rounds * 2); + expect(summary.functionCalls).toBe(rounds); + expect(summary.functionResponses).toBe(rounds); + expect(summary.distinctCallIds).toBe(rounds); + expect(summary.unansweredCalls).toBe(0); + expect(summary.orderingViolations).toBe(0); + expect(summary.truncated).toBe(true); + // Two ceilings bind, and the tighter one wins: the turn ceiling caps the retained detail, + // then the serialized budget trims further if the kept turns still do not fit a debug line. + expect(summary.turnShapes.length).toBeLessThanOrEqual(GOOGLE_WIRE_SHAPE_TURN_CEILING); + expect(summary.turnShapes.length).toBeGreaterThan(0); + expect(new TextEncoder().encode(JSON.stringify(summary)).length) + .toBeLessThanOrEqual(GOOGLE_WIRE_SHAPE_MAX_SERIALIZED_BYTES); + // The retained detail is still the head of the request, where a first-send violation lives. + expect(summary.turnShapes[0]?.index).toBe(0); + }); + + test("a parallel batch wider than the ordinal ceiling truncates the list, not the count", () => { + const ids = Array.from({ length: 20 }, (_unused, i) => callId(i + 1)); + const summary = summarizeGoogleWireShape(compiledWireBody([ + userTurn(), + modelCallTurn(ids), + toolResultTurn(ids), + ])); + expect(summary.functionCalls).toBe(20); + expect(summary.distinctCallIds).toBe(20); + expect(summary.turnShapes[1]?.calls).toHaveLength(16); + expect(summary.truncated).toBe(true); + }); + + // The item ceilings alone are not enough: 64 retained turns carrying 16 ordinals each serialize + // past the debug buffer's per-line cap, and the buffer cuts at a byte boundary. This drives the + // worst case through the REAL buffer and parses what comes back out of it. + test("the worst case inside the item ceilings still parses out of the real debug buffer", () => { + const contents: WireTurn[] = [userTurn()]; + for (let round = 0; round < 32; round++) { + const ids = Array.from({ length: 16 }, (_unused, i) => callId(round * 16 + i + 1)); + contents.push(modelCallTurn(ids, { signature: WIRE_MARKERS.signature }), toolResultTurn(ids)); + } + const summary = summarizeGoogleWireShape(compiledWireBody(contents, { toolDeclarations: 37 }), { + sessionAnchor: "parent-and-own", historySignedCalls: 32, replayScopeBound: true, + }); + expect(summary.turns).toBe(65); + expect(summary.functionCalls).toBe(512); + expect(summary.truncated).toBe(true); + // The size budget bit before the turn ceiling did, which is the whole point. + expect(summary.turnShapes.length).toBeLessThan(GOOGLE_WIRE_SHAPE_TURN_CEILING); + expect(new TextEncoder().encode(JSON.stringify(summary)).length) + .toBeLessThanOrEqual(GOOGLE_WIRE_SHAPE_MAX_SERIALIZED_BYTES); + + setDebugSettings({ debug: true }); + resetDebugLogBufferForTests(); + const realError = console.error; + console.error = () => {}; + try { + debugProviderDiagnosticLazy("google", "antigravity-wire-shape", () => summary); + } finally { + console.error = realError; + } + const entries = getDebugLogEntries(); + expect(entries).toHaveLength(1); + const line = entries[0]!.line; + expect(new TextEncoder().encode(line).length).toBeLessThanOrEqual(MAX_DEBUG_LINE_BYTES); + // Parseable, and still honest about having been cut. A buffer-truncated line would fail the + // parse, and its retained prefix would still have read truncated:false. + const roundTripped = JSON.parse(line.slice(line.indexOf("] ") + 2)) as + { truncated: boolean; turns: number; functionCalls: number; turnShapes: unknown[] }; + expect(roundTripped.truncated).toBe(true); + expect(roundTripped.turns).toBe(65); + expect(roundTripped.functionCalls).toBe(512); + expect(roundTripped.turnShapes.length).toBe(summary.turnShapes.length); + }); + + test("compaction shortens the request without changing what the projection reports about a turn", () => { + const full = summarizeGoogleWireShape(compiledWireBody(longToolSession(20))); + const compacted = summarizeGoogleWireShape(compiledWireBody(compactedToolSession(20, 4))); + expect(full.functionCalls).toBe(20); + expect(compacted.functionCalls).toBe(4); + expect(compacted.orderingViolations).toBe(0); + expect(compacted.turnShapes[1]).toEqual({ ...full.turnShapes[1]!, index: 1 }); + }); + + test("signature presence, sentinel-only signing and the two signing sources stay separable", () => { + const unsigned = summarizeGoogleWireShape(compiledWireBody([userTurn(), ...toolRoundTrip(1)])); + expect(unsigned.signature).toEqual({ + present: false, + sentinelOnly: false, + signedCalls: 0, + sentinelCalls: 0, + historySignedCalls: 0, + sessionCacheSignedCalls: 0, + replayScopeBound: false, + }); + + const signed = summarizeGoogleWireShape( + compiledWireBody([userTurn(), ...toolRoundTrip(1, { signature: WIRE_MARKERS.signature })]), + { historySignedCalls: 1, replayScopeBound: true }, + ); + expect(signed.signature).toEqual({ + present: true, + sentinelOnly: false, + signedCalls: 1, + sentinelCalls: 0, + historySignedCalls: 1, + sessionCacheSignedCalls: 0, + replayScopeBound: true, + }); + expect(JSON.stringify(signed)).not.toContain(WIRE_MARKERS.signature); + + // A signature the translator did not supply is attributed to the Antigravity session cache. + const fromCache = summarizeGoogleWireShape( + compiledWireBody([userTurn(), ...toolRoundTrip(1, { signature: WIRE_MARKERS.signature })]), + { historySignedCalls: 0, replayScopeBound: true }, + ); + expect(fromCache.signature.historySignedCalls).toBe(0); + expect(fromCache.signature.sessionCacheSignedCalls).toBe(1); + + // Sentinel-only is the shape a lookup miss reaches the wire as: signed, but by us. + const sentinel = summarizeGoogleWireShape( + compiledWireBody([userTurn(), ...toolRoundTrip(1, { signature: THOUGHT_SIGNATURE_SENTINEL })]), + { historySignedCalls: 0, replayScopeBound: true }, + ); + expect(sentinel.signature.present).toBe(true); + expect(sentinel.signature.sentinelOnly).toBe(true); + expect(sentinel.signature.sessionCacheSignedCalls).toBe(0); + expect(sentinel.signature.replayScopeBound).toBe(true); + }); + + test("send facts are carried only when the caller has them", () => { + const body = compiledWireBody([userTurn(), ...toolRoundTrip(1)]); + expect(summarizeGoogleWireShape(body).send).toBeNull(); + expect(summarizeGoogleWireShape(body, { sendOrdinal: 1, errorClass: "turn-adjacency" }).send) + .toEqual({ ordinal: 1, errorClass: "turn-adjacency" }); + expect(summarizeGoogleWireShape(body, { sendOrdinal: 3 }).send).toEqual({ ordinal: 3, errorClass: null }); + expect(summarizeGoogleWireShape(body).sessionAnchor).toBe("unknown"); + }); + + test("a body that is not a Google request degrades to an empty description", () => { + for (const input of [undefined, null, 42, "text", [], {}, { contents: "not-an-array" }]) { + const summary = summarizeGoogleWireShape(input); + expect(summary.turns).toBe(0); + expect(summary.turnShapes).toEqual([]); + expect(summary.truncated).toBe(false); + expect(summary.hasSessionId).toBe(false); + } + }); +}); + +describe("google wire upstream error classification", () => { + test("the reported 400 classifies as a turn-adjacency rejection", () => { + expect(classifyGoogleWireUpstreamError( + "Antigravity invalid request: Please ensure that function call turn comes immediately after a user turn or after a function response turn.", + )).toBe("turn-adjacency"); + }); + + test("the neighbouring Google 400 classes stay distinct", () => { + expect(classifyGoogleWireUpstreamError("Requests ending with a model turn are not supported")).toBe("turn-adjacency"); + expect(classifyGoogleWireUpstreamError("Invalid thought_signature: TYPE_BYTES decoding failed")).toBe("thought-signature"); + expect(classifyGoogleWireUpstreamError("tools[2].custom.input_schema is invalid")).toBe("tool-schema"); + expect(classifyGoogleWireUpstreamError("Unsupported thinkingLevel for this model")).toBe("thinking-config"); + expect(classifyGoogleWireUpstreamError("quota exceeded")).toBe("other"); + }); + + test("classification is bounded and never returns upstream text", () => { + expect(classifyGoogleWireUpstreamError(undefined)).toBe("other"); + expect(classifyGoogleWireUpstreamError("")).toBe("other"); + // Past the scan limit the marker is not read, so a huge payload cannot be walked in full. + expect(classifyGoogleWireUpstreamError(`${"x".repeat(4096)} function call turn`)).toBe("other"); + }); +}); + +// The session boundary is the other half of #5008: the reporter's hypothesis is that the +// upstream session diverged from what the proxy replays. The anchor class says which stability +// regime a request is in without naming the conversation. +describe("antigravity session anchor classification", () => { + test("the four anchor classes are distinguished", () => { + expect(antigravitySessionAnchor(parsedWithThreads({ parent: "p1", own: "c1" }))).toBe("parent-and-own"); + expect(antigravitySessionAnchor(parsedWithThreads({ parent: "p1" }))).toBe("parent-only"); + expect(antigravitySessionAnchor(parsedWithThreads({}))).toBe("text"); + expect(antigravitySessionAnchor(parsedWithThreads({}, ""))).toBe("none"); + }); + + test("a direct HTTP client with no Codex headers lands on the text anchor", () => { + const direct = parsedToolSession(2); + expect(antigravitySessionAnchor(direct)).toBe("text"); + }); + + test("an own-thread anchor keeps its class and its id when the first message is compacted", () => { + const before = parsedWithThreads({ parent: "p1", own: "c1" }, "the original first user message"); + const after = parsedWithThreads({ parent: "p1", own: "c1" }, "a compaction summary that replaced it"); + expect(antigravitySessionAnchor(before)).toBe(antigravitySessionAnchor(after)); + expect(antigravitySessionId(before)).toBe(antigravitySessionId(after)); + }); + + test("the text anchor keeps its class while its id moves under compaction", () => { + const before = parsedWithThreads({}, "the original first user message"); + const after = parsedWithThreads({}, "a compaction summary that replaced it"); + expect(antigravitySessionAnchor(before)).toBe("text"); + expect(antigravitySessionAnchor(after)).toBe("text"); + // The instability the anchor class exists to make visible. + expect(antigravitySessionId(before)).not.toBe(antigravitySessionId(after)); + }); + + test("the same own id under two parents stays one class and two sessions", () => { + const underP1 = parsedWithThreads({ parent: "p1", own: "shared-child" }); + const underP2 = parsedWithThreads({ parent: "p2", own: "shared-child" }); + expect(antigravitySessionAnchor(underP1)).toBe("parent-and-own"); + expect(antigravitySessionAnchor(underP2)).toBe("parent-and-own"); + expect(antigravitySessionId(underP1)).not.toBe(antigravitySessionId(underP2)); + }); + + test("two overlapping children of one parent are one class and two sessions", () => { + const childA = parsedWithThreads({ parent: "p1", own: "c1" }); + const childB = parsedWithThreads({ parent: "p1", own: "c2" }); + expect(antigravitySessionAnchor(childA)).toBe(antigravitySessionAnchor(childB)); + expect(antigravitySessionId(childA)).not.toBe(antigravitySessionId(childB)); + }); + + test("a restarted proxy re-derives the same class and the same id", () => { + // Both values come from Codex ids and message text alone; nothing process-random enters, + // which is what lets durable replay state survive a restart. + for (const threads of [{ parent: "p1", own: "c1" }, { parent: "p1" }, {}]) { + const first = parsedWithThreads(threads); + const second = parsedWithThreads(threads); + expect(antigravitySessionAnchor(first)).toBe(antigravitySessionAnchor(second)); + expect(antigravitySessionId(first)).toBe(antigravitySessionId(second)); + } + }); + + test("the anchorless request is the one whose id does not survive a second look", () => { + const first = parsedWithThreads({}, ""); + expect(antigravitySessionAnchor(first)).toBe("none"); + expect(antigravitySessionId(first)).not.toBe(antigravitySessionId(parsedWithThreads({}, ""))); + }); + + test("the adapter reports the anchor class it actually used", async () => { + const adapter = createGoogleAdapter(provider); + const realError = console.error; + console.error = () => {}; + try { + setDebugSettings({ debug: true }); + for (const [threads, expected] of [ + [{ parent: "p1", own: "c1" }, "parent-and-own"], + [{ parent: "p1" }, "parent-only"], + [{}, "text"], + ] as const) { + resetDebugLogBufferForTests(); + await adapter.buildRequest(parsedToolSession(1, threads)); + const line = getDebugLogEntries().map(entry => entry.line).find(l => l.includes("antigravity-wire-shape")); + expect(line).toContain(`"sessionAnchor":"${expected}"`); + } + } finally { + console.error = realError; + } + }); +}); diff --git a/tests/fixtures/google-wire-shape-cases.ts b/tests/fixtures/google-wire-shape-cases.ts new file mode 100644 index 00000000000..50177efee23 --- /dev/null +++ b/tests/fixtures/google-wire-shape-cases.ts @@ -0,0 +1,113 @@ +/** + * Synthetic compiled Google wire bodies for the #5008 structural projection. + * + * Builders rather than recorded traffic: a captured Antigravity request is exactly the artifact + * this projection exists so that nobody has to handle. Every string below is a marker, and the + * tests assert that none of them survives into a summary. + */ + +export const WIRE_MARKERS = { + prompt: "MARKER-PROMPT-TEXT", + systemText: "MARKER-SYSTEM-INSTRUCTION", + toolName: "MARKER_TOOL_NAME", + toolArgument: "MARKER-TOOL-ARGUMENT", + toolResult: "MARKER-TOOL-RESULT", + signature: "MARKERSIGNATUREBLOB0123456789", + sessionId: "-1234567890123456789", +} as const; + +/** Mirrors THOUGHT_SIGNATURE_BYPASS in src/adapters/google-antigravity-replay.ts. */ +export const THOUGHT_SIGNATURE_SENTINEL = "skip_thought_signature_validator"; + +export type WirePart = Record; +export type WireTurn = { role: string; parts: WirePart[] }; +export type WireBody = Record; + +export function callId(ordinal: number): string { + return `MARKER-CALL-ID-${ordinal}`; +} + +export function userTurn(text: string = WIRE_MARKERS.prompt): WireTurn { + return { role: "user", parts: [{ text }] }; +} + +export function modelTextTurn(text: string = WIRE_MARKERS.prompt): WireTurn { + return { role: "model", parts: [{ text }] }; +} + +export function modelCallTurn(ids: readonly string[], options: { signature?: string } = {}): WireTurn { + return { + role: "model", + parts: ids.map(id => ({ + functionCall: { name: WIRE_MARKERS.toolName, args: { query: WIRE_MARKERS.toolArgument }, id }, + ...(options.signature === undefined ? {} : { thoughtSignature: options.signature }), + })), + }; +} + +/** A function call the translator could not give a usable id, as an id-less wire part. */ +export function unidentifiedCallTurn(): WireTurn { + return { + role: "model", + parts: [{ functionCall: { name: WIRE_MARKERS.toolName, args: { query: WIRE_MARKERS.toolArgument } } }], + }; +} + +export function toolResultTurn(ids: readonly string[]): WireTurn { + return { + role: "user", + parts: ids.map(id => ({ + functionResponse: { name: WIRE_MARKERS.toolName, response: { result: WIRE_MARKERS.toolResult }, id }, + })), + }; +} + +export function compiledWireBody( + contents: readonly WireTurn[], + options: { toolDeclarations?: number; systemInstruction?: boolean; sessionId?: string } = {}, +): WireBody { + const body: WireBody = { contents: [...contents] }; + if (options.systemInstruction !== false) { + body.systemInstruction = { parts: [{ text: WIRE_MARKERS.systemText }] }; + } + const declarations = options.toolDeclarations ?? 0; + if (declarations > 0) { + body.tools = [{ + functionDeclarations: Array.from({ length: declarations }, (_unused, i) => ({ + name: `${WIRE_MARKERS.toolName}_${i}`, + description: WIRE_MARKERS.toolArgument, + parameters: { type: "object", properties: {} }, + })), + }]; + } + body.sessionId = options.sessionId ?? WIRE_MARKERS.sessionId; + return body; +} + +/** + * The shape a well-formed tool round trip reaches the wire as: user, then the model call turn, + * then the adjacent function-response turn. + */ +export function toolRoundTrip(round: number, options: { signature?: string } = {}): WireTurn[] { + const id = callId(round); + return [modelCallTurn([id], options), toolResultTurn([id])]; +} + +/** + * A long tool-heavy session of the kind #5008 reports: one opening user turn followed by + * `rounds` adjacent call/response pairs. Deterministic, so a projection of it is stable. + */ +export function longToolSession(rounds: number, options: { signature?: string } = {}): WireTurn[] { + const contents: WireTurn[] = [userTurn()]; + for (let round = 1; round <= rounds; round++) contents.push(...toolRoundTrip(round, options)); + contents.push(userTurn()); + return contents; +} + +/** Compaction keeps the tail and replaces the head; the structure survives, the text does not. */ +export function compactedToolSession(rounds: number, keptRounds: number): WireTurn[] { + const contents: WireTurn[] = [userTurn("MARKER-COMPACTION-SUMMARY")]; + for (let round = rounds - keptRounds + 1; round <= rounds; round++) contents.push(...toolRoundTrip(round)); + contents.push(userTurn()); + return contents; +} diff --git a/tests/fixtures/test-layout-expected.json b/tests/fixtures/test-layout-expected.json index 263adc46197..133ad1ada2f 100644 --- a/tests/fixtures/test-layout-expected.json +++ b/tests/fixtures/test-layout-expected.json @@ -606,6 +606,7 @@ "google-vertex-stream.test.ts": "adapters/google", "google-vertex-thought-signature.test.ts": "adapters/google", "google-wire-compiler.test.ts": "adapters/google", + "google-wire-shape.test.ts": "adapters/google", "grok-attribution.test.ts": "providers/xai", "grok-config-inject.test.ts": "providers/xai", "grok-effort-inject.test.ts": "providers/xai", diff --git a/tests/lib/debug.test.ts b/tests/lib/debug.test.ts index b80f7db41f5..2a9b8153cb5 100644 --- a/tests/lib/debug.test.ts +++ b/tests/lib/debug.test.ts @@ -3,7 +3,7 @@ import { appendDebugLogLine, debugBufferMetrics, getDebugLogEntries, resetDebugL import { ResourceAdmissionError, RETAINED_TRUNCATION_MARKER, retainedUtf8Bytes, truncateRetainedUtf8 } from "../../src/lib/admission"; import { getInjectionDebugLogEntries, injectionDebugLog, resetInjectionDebugLogBufferForTests } from "../../src/lib/injection-debug-log"; import { markActivity, activityBreadcrumb } from "../../src/lib/sidecar-tracker"; -import { debugDroppedFrame, debugProviderDiagnostic } from "../../src/lib/debug"; +import { debugDroppedFrame, debugProviderDiagnostic, debugProviderDiagnosticLazy } from "../../src/lib/debug"; import { resetDebugSettingsForTests, setDebugSettings } from "../../src/lib/debug-settings"; describe("retained UTF-8 sizing", () => { @@ -142,6 +142,53 @@ describe("debug frame logging", () => { } }); + // The eager form builds its details in argument position, so an expensive or fallible + // projection runs outside both the gate and the try/catch. The lazy form is what a caller on + // the request path has to use, and these are the two properties it exists for. + test("debugProviderDiagnosticLazy never invokes its builder while disabled", () => { + delete process.env.OCX_DEBUG; + delete process.env.OCX_DEBUG_FRAMES; + let built = 0; + const error = spyOn(console, "error").mockImplementation(() => {}); + try { + debugProviderDiagnosticLazy("google", "wire-shape", () => { built += 1; return { turns: 1 }; }); + expect(built).toBe(0); + expect(error).not.toHaveBeenCalled(); + } finally { + error.mockRestore(); + } + }); + + test("debugProviderDiagnosticLazy swallows a builder that throws", () => { + delete process.env.OCX_DEBUG; + setDebugSettings({ debug: true }); + resetDebugLogBufferForTests(); + const error = spyOn(console, "error").mockImplementation(() => {}); + try { + expect(() => debugProviderDiagnosticLazy("google", "wire-shape", () => { + throw new Error("projection boom"); + })).not.toThrow(); + // Nothing reached the console or the ring: a failed diagnostic is a silent one. + expect(error).not.toHaveBeenCalled(); + expect(getDebugLogEntries()).toEqual([]); + } finally { + error.mockRestore(); + } + }); + + test("debugProviderDiagnosticLazy emits the built details when enabled", () => { + delete process.env.OCX_DEBUG; + setDebugSettings({ debug: true }); + const error = spyOn(console, "error").mockImplementation(() => {}); + try { + debugProviderDiagnosticLazy("google", "wire-shape", () => ({ turns: 7 })); + expect(error).toHaveBeenCalledTimes(1); + expect(String(error.mock.calls[0]?.[0] ?? "")).toContain("[ocx:google:wire-shape] {\"turns\":7}"); + } finally { + error.mockRestore(); + } + }); + test("debugProviderDiagnostic emits when enabled via runtime settings API", () => { delete process.env.OCX_DEBUG; setDebugSettings({ debug: true }); From 7817cd57f74f3d90850d0ce559bc579c924ae69b Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 12:17:50 +0900 Subject: [PATCH 05/97] test(ci): split phase timing for the four #4997 budget overruns (#5081) * test(ci): split phase timing for the four #4997 budget overruns The four cases in #4997 exceed their own budgets only when the suite runs unsharded, and pass in the sharded lanes running the same files. Three control dispatches produced three disjoint failing sets, so a per-test duration cannot say whether the time went to cold fixture setup, to a wait the assertion needs, to slow contended execution, or to a teardown still reaping a child. This records those phases from inside the fixtures. tests/helpers/phase-timing.ts emits monotonic performance.now() boundaries plus exponential progress ticks, so a log truncated by a budget kill still distinguishes slow-but-advancing execution from a stall. The heartbeat case moved to a sibling file because web-search.test.ts sits exactly at its recorded cap. * test(ci): make the #4997 phase record say something a reader can act on Review of the first commit found the progress signal unwired in two of the three instrumented files, so every tick would have reported no movement and the hang-versus-slow distinction the record exists for would have been unavailable. The web-search case now probes its send count and the provider spine its observed-capture count; the image cases already probed the encode counter, but the per-build reset sat inside the measured segment and zeroing a probe mid-phase reports movement that did not happen. The spine also claimed to separate the server bind and did not. A phase now stops reporting after two minutes rather than after forty ticks, which is nine. --- scripts/test-layout/layout.json | 1 + .../openai-chat-image-normalization.test.ts | 48 ++-- .../openai/openai-provider-option-e2e.test.ts | 15 ++ tests/fixtures/test-layout-expected.json | 1 + tests/helpers/phase-timing.ts | 206 ++++++++++++++++++ .../web-search-retry-heartbeat.test.ts | 116 ++++++++++ tests/web-search/web-search.test.ts | 42 ---- 7 files changed, 371 insertions(+), 58 deletions(-) create mode 100644 tests/helpers/phase-timing.ts create mode 100644 tests/web-search/web-search-retry-heartbeat.test.ts diff --git a/scripts/test-layout/layout.json b/scripts/test-layout/layout.json index 6ef25844349..9f314978746 100644 --- a/scripts/test-layout/layout.json +++ b/scripts/test-layout/layout.json @@ -1464,6 +1464,7 @@ "web-search-parse.test.ts": "web-search", "web-search-passthrough-bridge.test.ts": "web-search", "web-search-progress-stream.test.ts": "web-search", + "web-search-retry-heartbeat.test.ts": "web-search", "web-search-sources.test.ts": "web-search", "web-search-timeout-contract.test.ts": "web-search", "web-search-timeout-plan.test.ts": "web-search", diff --git a/tests/adapters/openai/openai-chat-image-normalization.test.ts b/tests/adapters/openai/openai-chat-image-normalization.test.ts index 5fefeaed4ac..92ed9377bab 100644 --- a/tests/adapters/openai/openai-chat-image-normalization.test.ts +++ b/tests/adapters/openai/openai-chat-image-normalization.test.ts @@ -14,6 +14,7 @@ import { } from "../../../src/adapters/anthropic-image-normalize"; import type { OcxMessage, OcxParsedRequest, OcxProviderConfig } from "../../../src/types"; import { createTestTranslatorBudget } from "../../helpers/translator-budget"; +import { phaseTimer } from "../../helpers/phase-timing"; // Issue #4112 follow-up: chat-completions providers such as GitHub Copilot reject a body // over roughly 5.2MB with a bare 413 and no diagnostic content. Nothing downstream of the @@ -233,30 +234,37 @@ describe("openai-chat inline image normalization", () => { }); test("an image this wire cannot drop keeps counting toward the budget", async () => { + // Instrumented for #4997: this case and imageTierBias below both overran the lane's 60s + // ceiling in the unsharded control while passing in every shard that ran the same file. The + // probe is the normalizer's own encode counter, so a tick can tell a contended-but-advancing + // ladder walk apart from one that has stopped doing work. + const timing = phaseTimer("openai-chat non-droppable", () => getNormalizeStatsForTests().encodeCalls); // The drop callback here is a no-op, so an undecodable image stays on the wire. The // shared core normally stops counting a dropped target, which is only correct when // the bytes actually leave. If those bytes stopped counting, the demotion loop would // stop early and still ship an oversized body — the exact failure this file exists // to prevent. - const big = await noisyPngB64(1000, 1000); - // Truncated PNG: sniffs as an image, so it reaches the ladder, but cannot decode. - const corrupt = big.slice(0, 3_000_000); - const messages = [{ - role: "user", - content: [ - { type: "image_url", image_url: { url: dataUrl(corrupt) } }, - ...Array.from({ length: 3 }, () => ({ type: "image_url", image_url: { url: dataUrl(big) } })), - ], - }]; + const prepared = await timing.phase("prepare", async () => { + const big = await noisyPngB64(1000, 1000); + // Truncated PNG: sniffs as an image, so it reaches the ladder, but cannot decode. + const corrupt = big.slice(0, 3_000_000); + return { corrupt, messages: [{ + role: "user", + content: [ + { type: "image_url", image_url: { url: dataUrl(corrupt) } }, + ...Array.from({ length: 3 }, () => ({ type: "image_url", image_url: { url: dataUrl(big) } })), + ], + }] }; + }); resetNormalizeStateForTests(); - await normalizeOpenAIChatImages(messages); + await timing.phase("execute", () => normalizeOpenAIChatImages(prepared.messages)); - const parts = imageParts(messages as ChatMsg[]); + const parts = imageParts(prepared.messages as ChatMsg[]); const total = parts.reduce((sum, p) => sum + (p.image_url?.url.split(",")[1]?.length ?? 0), 0); expect(parts).toHaveLength(4); // The undecodable image is retained, unchanged. - expect(parts[0]?.image_url?.url).toBe(dataUrl(corrupt)); + expect(parts[0]?.image_url?.url).toBe(dataUrl(prepared.corrupt)); // And the turn as a whole still lands under budget. expect(total).toBeLessThanOrEqual(OPENAI_CHAT_IMAGE_BASE64_BUDGET); }); @@ -330,12 +338,12 @@ describe("openai-chat inline image normalization", () => { }); test("imageTierBias from incoming meta reaches the normalizer", async () => { - const big = await noisyPngB64(1000, 1000); + const timing = phaseTimer("openai-chat imageTierBias", () => getNormalizeStatsForTests().encodeCalls); + const big = await timing.phase("prepare", () => noisyPngB64(1000, 1000)); const urls = Array.from({ length: 4 }, () => dataUrl(big)); const adapter = createOpenAIChatAdapter(provider); const build = async (imageTierBias?: number) => { - resetNormalizeStateForTests(); const built = adapter.buildRequest(parsedWith([imageMessage(urls)]), { headers: new Headers(), translatorBudget: createTestTranslatorBudget(), @@ -346,7 +354,15 @@ describe("openai-chat inline image normalization", () => { .reduce((sum, part) => sum + (part.image_url?.url.length ?? 0), 0); }; - expect(await build(3)).toBeLessThan(await build()); + // Two cold walks of the ladder over four megapixel images: this is the contract, and the + // `execute` figure is what a disposition has to be argued against. + // The reset stays outside the measured segment: it zeroes the encode counter the ticks read, + // and a probe that drops to zero mid-phase reports movement that did not happen. + resetNormalizeStateForTests(); + const biased = await timing.phase("execute-biased", () => build(3)); + resetNormalizeStateForTests(); + const unbiased = await timing.phase("execute-default", () => build()); + expect(biased).toBeLessThan(unbiased); }); }); diff --git a/tests/adapters/openai/openai-provider-option-e2e.test.ts b/tests/adapters/openai/openai-provider-option-e2e.test.ts index 903d85c82a3..4ef0dbadfd6 100644 --- a/tests/adapters/openai/openai-provider-option-e2e.test.ts +++ b/tests/adapters/openai/openai-provider-option-e2e.test.ts @@ -17,6 +17,7 @@ import { homedir, tmpdir } from "node:os"; import { join, relative } from "node:path"; import { watchdogMs } from "../../helpers/ci-watchdog"; +import { phaseTimer } from "../../helpers/phase-timing"; import { removeTreeWithRetry } from "../../helpers/remove-tree"; import { repoPath } from "../../helpers/repo-root"; type Capture = { @@ -121,6 +122,14 @@ function responsesLifecycle(body: Record): string { describe("OpenAI provider-option integration spine", () => { test("keeps Pool, Direct, and API ownership stable across transports and management", async () => { + // Instrumented for #4997. This case missed its own 30s bound by 29ms in one control run and + // by 1.8s in another, and passes in the sharded lanes that run the same file, so the question + // is which part grew rather than whether the whole is too slow. The segments separate fixture + // setup, the server bind, the ownership assertions that are the actual contract, the migration + // child, and teardown including the reap. `captures` counts upstream requests this case has + // observed, which is the monotonic signal that tells a slow transport apart from a stalled one. + const timing = phaseTimer("openai provider-option ownership spine", () => captures.length); + timing.split("prepare"); const root = mkdtempSync(join(tmpdir(), "ocx-provider-option-e2e-")); const opencodexHome = join(root, "opencodex"); const codexHome = join(root, "codex"); @@ -350,8 +359,10 @@ describe("OpenAI provider-option integration spine", () => { expect(deriveModule.deriveProviderPresets().map(entry => entry.id)).not.toContain("openai-multi"); expect(sidecar.listOpenAiForwardSidecarCandidates(config).map(row => row.providerName)).toEqual(["openai"]); + timing.split("server-start"); server = serverModule.startServer(0); loopbackOrigin = new URL(server.url).origin; + timing.split("execute"); const local = (path: string, init?: RequestInit) => fetch(new URL(path, server!.url), init); const post = (path: string, body: unknown, headers: HeadersInit = {}) => local(path, { method: "POST", @@ -574,6 +585,7 @@ describe("OpenAI provider-option integration spine", () => { ]) expect(usageLines.some(row => Object.entries(expected).every(([key, value]) => row[key] === value))).toBe(true); const migrationRoot = mkdtempSync(join(tmpdir(), "ocx-provider-option-migration-")); + timing.split("migration-child"); try { const child = Bun.spawn([ process.execPath, @@ -623,6 +635,7 @@ describe("OpenAI provider-option integration spine", () => { } finally { removeTreeWithRetry(migrationRoot); } + timing.split("execute-tail"); expect(new Set(blockedUpstreamWebSocketUrls)).toEqual(new Set([ "wss://chatgpt.com/backend-api/codex/responses", @@ -651,6 +664,7 @@ describe("OpenAI provider-option integration spine", () => { }, null, 2) + "\n", { mode: 0o600 }); } } finally { + timing.split("teardown"); try { if (server) await server.stop(true); } finally { @@ -663,6 +677,7 @@ describe("OpenAI provider-option integration spine", () => { removeTreeWithRetry(root); expect(hashTree(realClaudeDir)).toBe(realClaudeHashBefore); } + timing.end(); } }, 30_000); }); diff --git a/tests/fixtures/test-layout-expected.json b/tests/fixtures/test-layout-expected.json index 133ad1ada2f..dac7ce37f5b 100644 --- a/tests/fixtures/test-layout-expected.json +++ b/tests/fixtures/test-layout-expected.json @@ -1292,6 +1292,7 @@ "web-search-parse.test.ts": "web-search", "web-search-passthrough-bridge.test.ts": "web-search", "web-search-progress-stream.test.ts": "web-search", + "web-search-retry-heartbeat.test.ts": "web-search", "web-search-sources.test.ts": "web-search", "web-search-timeout-contract.test.ts": "web-search", "web-search-timeout-plan.test.ts": "web-search", diff --git a/tests/helpers/phase-timing.ts b/tests/helpers/phase-timing.ts new file mode 100644 index 00000000000..02f0beaf749 --- /dev/null +++ b/tests/helpers/phase-timing.ts @@ -0,0 +1,206 @@ +import { cpus, release } from "node:os"; + +/** + * Monotonic phase timing for the cases in issue #4997. + * + * Those cases exceed their own budgets only when the suite runs unsharded, and pass in the + * sharded lanes running the same files. Three control dispatches produced three DISJOINT failing + * sets, so the shared factor is elapsed time in a process holding 1367 files rather than any one + * subsystem. A single per-test duration cannot separate the possibilities that implies: cold + * fixture setup, a wait the assertion actually needs, slow contended execution, and a teardown + * still reaping a child all arrive as one number. + * + * This splits that number. `prepare` is everything done before the contract is observable, + * `execute` is the part the assertion is about, and `teardown` is release plus child reap. A + * reader comparing a control log against a sharded log can then say WHICH phase grew, which is + * the question every disposition in that issue is blocked on. + * + * ## Why it also ticks + * + * A budget overrun kills the test, so the closing line of the phase that overran is exactly the + * line that never prints. With nothing emitted DURING a phase, an overrun and a wedge are the + * same observation: a log that stops mid-phase. So an open phase emits progress ticks on an + * exponential schedule, and each tick reports whether the case's own progress counter moved since + * the previous one. A truncated record ending in `moving=yes` is slow execution under contention; + * one ending in `moving=no` is a stall with no work happening. Those are different defects and + * the per-test duration cannot tell them apart. + * + * ## What it does not collect + * + * Runtime and host identity only. A control lane and a shard differ in load rather than in + * configuration, so an environment dump would be noise that still has to be audited; `privacy:scan` + * reads this tree, and a diagnostic needing redaction is one nobody will leave enabled. + * + * ## Reading it + * + * The job log is the only channel the `macos control` lane has: `.github/workflows/ci.yml` tees + * the suite and uploads no artifact. Grep a job log for `[test-phase]`. + * + * `at` is milliseconds since process start from `performance.now()`, monotonic and unaffected by a + * clock step, matching the timing convention already used across this suite. It doubles as + * position-in-run: sorting every emitted line by `at` recovers the order the runner selected these + * cases in, so no file has to restate an ordering it would then have to keep correct. + */ + +/** One prefix for the whole record, so a single grep over a job log finds all of it. */ +const TAG = "[test-phase]"; + +/** First tick delay; each later gap doubles until it reaches TICK_MAX_MS. */ +const TICK_FIRST_MS = 1_000; +const TICK_MAX_MS = 15_000; + +/** + * How long one phase may keep reporting. The bound matters because a phase killed by a test + * timeout never closes, and `unref` keeps the process from being held open without cancelling + * anything, so an unbounded chain would outlive its case and write into an unrelated part of the + * log. Two minutes is past every budget in #4997, the largest of which is 60s, and ends long + * before the job does. + */ +const TICK_WINDOW_MS = 120_000; + +let envEmitted = false; +let seq = 0; + +function emit(fields: string[]): void { + console.info([TAG, ...fields].join(" ")); +} + +/** Milliseconds since process start, monotonic, to a tenth of a millisecond. */ +function nowMs(): string { + return performance.now().toFixed(1); +} + +/** + * Runtime and host, once per isolate. `bun test --isolate` reclaims the realm at file boundaries, + * so this runs once per instrumented file rather than once per process, which is what makes it + * usable as a per-file anchor when lines from several files interleave in one log. + */ +function emitEnvOnce(): void { + if (envEmitted) return; + envEmitted = true; + emit([ + "env", + "bun=" + Bun.version, + "platform=" + process.platform, + "release=" + release(), + "arch=" + process.arch, + "cpus=" + cpus().length, + "pid=" + process.pid, + ]); +} + +/** + * A tick fires from the event loop while the case is parked on an `await`, so the case itself + * cannot push a count at that moment. A probe is therefore the only way a tick can observe work + * that is happening inside the awaited call: give it something externally readable and monotonic, + * such as the normalizer's encode counter, and a frozen reading becomes evidence of a stall rather + * than of the test simply not being scheduled. + */ +export type ProgressProbe = () => number; + +export interface PhaseTimer { + /** + * Run `fn` as a named phase. The opening line is emitted before `fn` starts, so a phase that + * never returns still appears in the log with the ticks that followed it. + */ + phase(name: string, fn: () => T): Promise>; + /** + * Close the open segment and start a named one. For a long linear case body, where wrapping + * each part in a closure would re-indent hundreds of lines of assertions and bury the real + * change, this marks the same boundaries in place. + */ + split(name: string): void; + /** Close the open segment without starting another. Safe to call when none is open. */ + end(): void; + /** Advance the built-in counter. Ignored when a probe was supplied. */ + progress(): void; +} + +/** + * Instrument one case. `label` should identify the case well enough to grep on its own, because + * these lines land in a log holding 26k other tests. + */ +export function phaseTimer(label: string, probe?: ProgressProbe): PhaseTimer { + emitEnvOnce(); + const base = ["case=" + JSON.stringify(label), "seq=" + seq++]; + let progressCount = 0; + const read = (): number => { + if (probe === undefined) return progressCount; + // A probe reaches into the code under test, so a throw here must never become the case's + // failure: the diagnostic reports what it can see and the assertion keeps its own verdict. + try { return probe(); } catch { return -1; } + }; + + /** Open a named segment and return the function that closes it. */ + const open = (name: string): (() => void) => { + const startedAt = performance.now(); + const openMs = (): string => (performance.now() - startedAt).toFixed(1); + emit([...base, "phase=" + name, "state=start", "at=" + nowMs()]); + + let gap = TICK_FIRST_MS; + let seenAtLastTick = read(); + let handle: ReturnType | undefined; + let closed = false; + + const scheduleTick = (): void => { + if (closed || performance.now() - startedAt >= TICK_WINDOW_MS) return; + handle = setTimeout(() => { + if (closed) return; + const seen = read(); + const moved = seen !== seenAtLastTick; + seenAtLastTick = seen; + emit([ + ...base, + "phase=" + name, + "state=tick", + "at=" + nowMs(), + "openMs=" + openMs(), + "progress=" + seen, + "moving=" + (moved ? "yes" : "no"), + ]); + gap = Math.min(gap * 2, TICK_MAX_MS); + scheduleTick(); + }, gap); + // A diagnostic must never be the reason a process stays alive. + (handle as unknown as { unref?: () => void }).unref?.(); + }; + scheduleTick(); + + return () => { + if (closed) return; + closed = true; + if (handle !== undefined) clearTimeout(handle); + emit([ + ...base, + "phase=" + name, + "state=end", + "at=" + nowMs(), + "durMs=" + openMs(), + "progress=" + read(), + ]); + }; + }; + + let closeCurrent: (() => void) | undefined; + const end = (): void => { + closeCurrent?.(); + closeCurrent = undefined; + }; + + return { + async phase(name: string, fn: () => T): Promise> { + const close = open(name); + try { + return await fn(); + } finally { + close(); + } + }, + split(name: string): void { + end(); + closeCurrent = open(name); + }, + end, + progress: () => { progressCount += 1; }, + }; +} diff --git a/tests/web-search/web-search-retry-heartbeat.test.ts b/tests/web-search/web-search-retry-heartbeat.test.ts new file mode 100644 index 00000000000..ff4d350a175 --- /dev/null +++ b/tests/web-search/web-search-retry-heartbeat.test.ts @@ -0,0 +1,116 @@ +import { afterEach, describe, expect, test } from "bun:test"; + +import { parseRequest } from "../../src/responses/parser"; +import { runWithWebSearch as runWithWebSearchProduction, type WebSearchLoopDeps } from "../../src/web-search/loop"; +import type { OcxProviderConfig } from "../../src/types"; +import type { ProviderAdapter } from "../../src/adapters/base"; +import { createTestTranslatorBudget } from "../helpers/translator-budget"; +import { phaseTimer } from "../helpers/phase-timing"; + +/** + * Moved out of `web-search.test.ts` for issue #4997, unchanged. + * + * That file sits at exactly its recorded cap in `tests/fixtures/file-size-baseline.json`, and caps + * only move downward, so instrumenting this case in place was not available: a sibling file is the + * remedy AGENTS.md names for precisely this situation. Nothing about the case itself changed here. + * + * The case overran its own 5s bound at 6233ms in the first completed unsharded `macos control` + * run while passing in every sharded lane. Its intrinsic wait is a 1.5s backoff, so roughly 4.7s + * is unaccounted for, and a single duration cannot say whether that went to setup, to the wait + * being served late by a loaded event loop, or to teardown. The phase record answers that. + */ + +const forwardProvider: OcxProviderConfig = { + adapter: "openai-responses", + baseUrl: "https://chatgpt.test/v1", + authMode: "forward", +}; + +/** Run the web-search loop with a default test translator budget. */ +function runWithWebSearch( + deps: Omit & { incomingMeta?: WebSearchLoopDeps["incomingMeta"] }, +): Promise { + return runWithWebSearchProduction({ + ...deps, + incomingMeta: deps.incomingMeta ?? { + headers: new Headers(), + translatorBudget: createTestTranslatorBudget(), + }, + }); +} + +async function collectSse(stream: ReadableStream): Promise<{ event?: string; data: Record }[]> { + const reader = stream.getReader(); + const decoder = new TextDecoder(); + let text = ""; + while (true) { + const { done, value } = await reader.read(); + if (done) break; + text += decoder.decode(value, { stream: true }); + } + return text.split("\n\n") + .map(frame => frame.trim()) + .filter(frame => frame.length > 0 && frame !== "data: [DONE]") + .map(frame => { + const lines = frame.split("\n"); + const event = lines.find(line => line.startsWith("event: "))?.slice(7); + const dataLine = lines.find(line => line.startsWith("data: ")); + return { event, data: JSON.parse(dataLine?.slice(6) ?? "{}") as Record }; + }); +} + +const originalFetch = globalThis.fetch; +afterEach(() => { globalThis.fetch = originalFetch; }); + +describe("web-search same-target 429 retry", () => { + test("retry wait longer than the stall budget still succeeds (heartbeats feed the watchdog)", async () => { + // `sends` is the only externally visible progress this case makes, so it is what separates a + // backoff being served late by a loaded event loop from a loop that stopped advancing. + let sends = 0; + const timing = phaseTimer("web-search heartbeat retry", () => sends); + timing.split("prepare"); + globalThis.fetch = (() => Promise.resolve(new Response( + 'event: response.completed\ndata: {"type":"response.completed"}\n\n', + { headers: { "Content-Type": "text/event-stream" } }, + ))) as typeof fetch; + + const retryingAdapter: ProviderAdapter = { + name: "mock-retry429", + buildRequest: () => ({ url: "https://routed.test/v1", method: "POST", headers: {}, body: "{}" }), + fetchResponse: async () => { + sends += 1; + if (sends === 1) { + return new Response("rate limited", { status: 429, headers: { "retry-after": "30" } }); + } + return new Response("{}", { status: 200 }); + }, + async *parseStream() { + yield { type: "text_delta", text: "answer after long backoff" }; + yield { type: "done" }; + }, + async parseResponse() { throw new Error("parseResponse must be unreachable"); }, + }; + + // `phase` closes its segment through its own finally, so a throw inside the measured window + // still produces a closing line rather than a record that just stops. + timing.end(); + const frames = await timing.phase("execute", async () => { + const response = await runWithWebSearch({ + parsed: parseRequest({ model: "routed/model", input: "hi", stream: true, tools: [{ type: "web_search" }] }), + adapter: retryingAdapter, + forwardProvider, + hostedTool: { type: "web_search" }, + selectedForwardHeaders: new Headers({ authorization: "Bearer token" }), + settings: { model: "gpt-5.6-luna", reasoning: "low", timeoutMs: 30_000 }, + maxSearches: 1, + stallTimeoutSec: 1, + retryOn429Policy: { enabled: true, attempts: 1, intervalMs: 1_500, maxIntervalMs: 60_000, respectRetryAfter: false }, + }); + return collectSse(response.body!); + }); + // A 1.5s backoff under a 1s stall budget must not trip upstream_stall_timeout. + expect(sends).toBe(2); + expect(frames.find(f => f.event === "response.completed")).toBeDefined(); + expect(frames.find(f => f.event === "response.failed")).toBeUndefined(); + }, 5_000); +}); diff --git a/tests/web-search/web-search.test.ts b/tests/web-search/web-search.test.ts index 1e5331da335..0041ff26462 100644 --- a/tests/web-search/web-search.test.ts +++ b/tests/web-search/web-search.test.ts @@ -1215,48 +1215,6 @@ describe("web-search sidecar native web_search_call emission", () => { expect(builds).toBe(1); }); - test("retry wait longer than the stall budget still succeeds (heartbeats feed the watchdog)", async () => { - globalThis.fetch = (() => Promise.resolve(new Response( - 'event: response.completed\ndata: {"type":"response.completed"}\n\n', - { headers: { "Content-Type": "text/event-stream" } }, - ))) as typeof fetch; - - let sends = 0; - const retryingAdapter: ProviderAdapter = { - name: "mock-retry429", - buildRequest: () => ({ url: "https://routed.test/v1", method: "POST", headers: {}, body: "{}" }), - fetchResponse: async () => { - sends += 1; - if (sends === 1) { - return new Response("rate limited", { status: 429, headers: { "retry-after": "30" } }); - } - return new Response("{}", { status: 200 }); - }, - async *parseStream() { - yield { type: "text_delta", text: "answer after long backoff" }; - yield { type: "done" }; - }, - async parseResponse() { throw new Error("parseResponse must be unreachable"); }, - }; - - const response = await runWithWebSearch({ - parsed: parseRequest({ model: "routed/model", input: "hi", stream: true, tools: [{ type: "web_search" }] }), - adapter: retryingAdapter, - forwardProvider, - hostedTool: { type: "web_search" }, - selectedForwardHeaders: new Headers({ authorization: "Bearer token" }), - settings: { model: "gpt-5.6-luna", reasoning: "low", timeoutMs: 30_000 }, - maxSearches: 1, - stallTimeoutSec: 1, - retryOn429Policy: { enabled: true, attempts: 1, intervalMs: 1_500, maxIntervalMs: 60_000, respectRetryAfter: false }, - }); - const frames = await collectSse(response.body!); - // A 1.5s backoff under a 1s stall budget must not trip upstream_stall_timeout. - expect(sends).toBe(2); - expect(frames.find(f => f.event === "response.completed")).toBeDefined(); - expect(frames.find(f => f.event === "response.failed")).toBeUndefined(); - }, 5_000); - test("retry wait longer than connectTimeoutMs restarts the header deadline (no 504)", async () => { globalThis.fetch = (() => Promise.resolve(new Response( 'event: response.completed\ndata: {"type":"response.completed"}\n\n', From d385a56e877edcfaf06070f6d0198a8716d5e89c Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 13:40:08 +0900 Subject: [PATCH 06/97] test(ci): move fixture and host-probe cost out of the #4997 measured windows (#5082) Three of the four cases spend most of their budget on work the assertion is not about. The image file builds the same 1000x1000 noise PNG seven times, once inside each of the two windows that overran; it is now built once per size and shared, which no case can observe because nothing writes to the result. The provider-option spine asked the host service manager who owns its sandboxed homes, which on macOS is up to four synchronous launchctl children at two seconds apiece, and it now uses the seam that exists for exactly this. Its WebSocket and migration child were reachable only from the success path and are now released on the failure path too. --- .../openai-chat-image-normalization.test.ts | 24 +++++++++++- .../openai/openai-provider-option-e2e.test.ts | 38 ++++++++++++++++++- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/tests/adapters/openai/openai-chat-image-normalization.test.ts b/tests/adapters/openai/openai-chat-image-normalization.test.ts index 92ed9377bab..c10bca3dd99 100644 --- a/tests/adapters/openai/openai-chat-image-normalization.test.ts +++ b/tests/adapters/openai/openai-chat-image-normalization.test.ts @@ -41,8 +41,30 @@ async function realPngB64(width: number, height: number): Promise { * A flat-colour PNG compresses to almost nothing, so budget behaviour needs incompressible * pixels. Deterministic noise is written as an uncompressed BMP and converted, which keeps * the fixture in-repo and the encoded size realistic. + * + * Built once per size and shared, for #4997. Seven cases in this file ask for the same 1000x1000 + * noise PNG, and producing one is a million-iteration fill followed by a PNG encode of pixels that + * are incompressible by construction. For every one of those cases that is preparation: none + * asserts anything about how the fixture was produced, only about what the normalizer does to it. + * Two of them overran the lane's 60s ceiling in the unsharded control while passing in the shards + * that ran the same file, and this build sat inside the window that was being measured. + * + * Sharing is safe because nothing writes to the result. The normalizer mutates freshly built wire + * objects rather than the base64 itself, and the one case that needs a truncated copy uses slice, + * which allocates. Per-case isolation is enforced by resetNormalizeStateForTests, not by fixture + * identity. The promise rather than the string is cached so two callers cannot both start a build. */ -async function noisyPngB64(width: number, height: number): Promise { +const noisyPngCache = new Map>(); +function noisyPngB64(width: number, height: number): Promise { + const key = width + "x" + height; + const cached = noisyPngCache.get(key); + if (cached !== undefined) return cached; + const built = buildNoisyPngB64(width, height); + noisyPngCache.set(key, built); + return built; +} + +async function buildNoisyPngB64(width: number, height: number): Promise { const rowSize = width * 3 + ((4 - ((width * 3) % 4)) % 4); const pixelBytes = rowSize * height; const bmp = Buffer.alloc(54 + pixelBytes); diff --git a/tests/adapters/openai/openai-provider-option-e2e.test.ts b/tests/adapters/openai/openai-provider-option-e2e.test.ts index 4ef0dbadfd6..707cde1ccdb 100644 --- a/tests/adapters/openai/openai-provider-option-e2e.test.ts +++ b/tests/adapters/openai/openai-provider-option-e2e.test.ts @@ -17,6 +17,7 @@ import { homedir, tmpdir } from "node:os"; import { join, relative } from "node:path"; import { watchdogMs } from "../../helpers/ci-watchdog"; +import { ownedServiceHomeInspection } from "../../helpers/owned-service-home-inspection"; import { phaseTimer } from "../../helpers/phase-timing"; import { removeTreeWithRetry } from "../../helpers/remove-tree"; import { repoPath } from "../../helpers/repo-root"; @@ -150,6 +151,11 @@ describe("OpenAI provider-option integration spine", () => { let principalSeamCalls = 0; let loopbackOrigin: string | null = null; let server: { url: URL; stop(closeActiveConnections?: boolean): Promise } | null = null; + // Hoisted so the outer finally can release them on the failure path too. Both used to be + // reachable only from the success path, so a case that threw mid-spine left a live socket and + // an unreaped child behind in a process that still had hundreds of files to run. + let openWebSocket: { close(): void } | null = null; + let migrationChild: { kill(): void; exited: Promise } | null = null; const loopbackTuples = new Set([ "GET /healthz", @@ -360,7 +366,15 @@ describe("OpenAI provider-option integration spine", () => { expect(sidecar.listOpenAiForwardSidecarCandidates(config).map(row => row.providerName)).toEqual(["openai"]); timing.split("server-start"); - server = serverModule.startServer(0); + // Without this seam startup asks the host's real service manager who owns these homes, which + // on macOS means up to four synchronous `launchctl print` children across two domains, each + // carrying a two-second subprocess budget (src/service-manager-probe.ts). That is machine + // interrogation, not provider-option ownership, and it lands inside a 30s bound this case + // missed by 29ms. The verdict is unchanged: `owned` means no persistent service claim was + // observed, which is what a runner with no installed service reports anyway. + server = serverModule.startServer(0, { + inspectNativeCodexOwnership: ownedServiceHomeInspection("provider-option spine fixture"), + }); loopbackOrigin = new URL(server.url).origin; timing.split("execute"); const local = (path: string, init?: RequestInit) => fetch(new URL(path, server!.url), init); @@ -416,13 +430,19 @@ describe("OpenAI provider-option integration spine", () => { const ws = new savedWebSocket(expectedWsUrl, { headers: { authorization: "Bearer fixture-caller-main" }, } as unknown as string[]); + openWebSocket = ws; await new Promise((resolve, reject) => { ws.addEventListener("open", () => resolve(), { once: true }); ws.addEventListener("error", () => reject(new Error("fixture websocket failed to open")), { once: true }); }); const wsTurn = (model: string) => new Promise((resolve, reject) => { const before = captures.length; - const timer = setTimeout(() => reject(new Error(`fixture websocket timeout: ${model}`)), watchdogMs(2_000)); + // Detaching on the timeout matters as much as rejecting: a turn that gives up while still + // subscribed leaves a listener that can resolve a later turn's capture count. + const timer = setTimeout(() => { + ws.removeEventListener("message", onMessage); + reject(new Error(`fixture websocket timeout: ${model}`)); + }, watchdogMs(2_000)); const onMessage = (event: MessageEvent) => { if (!String(event.data).includes('"type":"response.completed"')) return; clearTimeout(timer); @@ -544,6 +564,7 @@ describe("OpenAI provider-option integration spine", () => { const closed = new Promise(resolve => ws.addEventListener("close", () => resolve(), { once: true })); ws.close(); await closed; + openWebSocket = null; const selected = "openai-apikey/gpt-5.6-sol-pro"; expect((await put("/api/disabled-models", { models: [selected] })).status).toBe(200); @@ -593,6 +614,7 @@ describe("OpenAI provider-option integration spine", () => { join(migrationRoot, "opencodex"), join(migrationRoot, "codex"), ], { stdout: "pipe", stderr: "pipe", env: { ...process.env } }); + migrationChild = child; const [stdout, stderr, exitCode] = await Promise.all([ new Response(child.stdout).text(), new Response(child.stderr).text(), @@ -633,6 +655,13 @@ describe("OpenAI provider-option integration spine", () => { expect(receipt.principalSeamCalls).toBeGreaterThan(0); } } finally { + // Reap before the tree goes: a child still holding a descriptor under migrationRoot turns + // removal into a retry loop, and an orphan survives into whatever file runs next. + if (migrationChild !== null) { + migrationChild.kill(); + await migrationChild.exited; + migrationChild = null; + } removeTreeWithRetry(migrationRoot); } timing.split("execute-tail"); @@ -666,6 +695,11 @@ describe("OpenAI provider-option integration spine", () => { } finally { timing.split("teardown"); try { + try { openWebSocket?.close(); } catch { /* already closed or never opened */ } + if (migrationChild !== null) { + migrationChild.kill(); + await migrationChild.exited; + } if (server) await server.stop(true); } finally { globalThis.fetch = savedFetch; From d4ca4d914b13ee9d88c1bdc02a066b40f023083c Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 13:40:52 +0900 Subject: [PATCH 07/97] fix(tests): judge cold-spawn warm-up registration structurally (#5080) * fix(tests): judge cold-spawn warm-up registration structurally The coverage guard recorded a file as warmed when its text contained the substring helpers/cold-spawn-warmup, so a comment, a string literal, or an import left behind after the beforeAll call was deleted all satisfied it while the measured child paid the cold module-graph load again (#5060). tests/helpers/warmup-registration.ts replaces the substring with a structural judge over the file tokens: it follows the import binding from the exact helper module through aliases, finds the bun:test beforeAll registration and the scope of its inline callback, requires the call on that callback direct path, and requires the promise to reach the hook by await or return. A file it cannot read is reported unreadable rather than answered. Parsing uses the scanner from typescript/unstable/ast, the same entry point tests/responses/responses-fetch-helpers-boundary.test.ts already uses, because TypeScript 7.0.2 is the native port and publishes no in-process parser. * fix(tests): close the scopes a warm-up registration can hide in Four gaps the first pass left, each of which accepts a file that pays the cold load anyway: a namespace import warms without binding a name the judge follows, so an unwarmed disposition now requires no helper import at all rather than no binding; a hook registered in an uncalled helper or behind a false condition registers nothing, so a registration must sit at the top level or in a describe callback, unconditionally; a callback parameter of the same name shadows the import with no declaration keyword to find; and a warm-up that is one operand of the returned expression leaves the hook settling on something else. * fix(tests): end a guarded statement without needing its semicolon A semicolonless guarded registration left the conditional flag set for the next line, so the unconditional hook after it was refused too. Statement level now also ends at a line break after a token a statement can end on, with the token that begins a guarded statement exempted so if (false) on its own line still guards what follows it. * fix(tests): keep a guarded statement that the next line continues A line break only ends a statement when the next line cannot continue the previous expression. A line opening with a paren continues it, so drawing the boundary on the line break alone read the second half of one conditional consequent as unconditional and accepted it. * fix(tests): judge four warm-up shapes exactly and refuse the rest The token walker reconstructed scoping, statement and expression grammar by hand, and the gaps were false passes: an expression-bodied arrow created no scope, so a hook registered inside one read as top-level work, and a shadowed beforeAll took a correctly awaited callback while nothing ran. It now recognises four shapes - an awaited or returned statement in a beforeAll callback, a beforeAll expression body, and a module-level await - and every other occurrence of a warm-up binding is one refusal naming its line and its scope chain. Provenance is required for beforeAll and describe as well as for the warm-up name. TypeScript 7.0.2 publishes no in-process parser (typescript/unstable/ast exports the node FACTORY, and parsed trees come from the tsgo client), so the alternative to an exact accept-set is more hand-written grammar, where each wrong guess is a false pass. Refusing a legitimate file no longer blocks it: a disposition records the construct in unmodeled, and the judge must still see the warm-up and still refuse it for that reason, so deleting the call or dropping the await fails again. * fix(tests): require a suite call this judge can see running braceLayer read a block as a describe body from the callee name alone, so describe.skip and a describe behind a false condition both produced a suite scope and a hook inside one was recorded as a registration while nothing ran. A suite now counts only for a plain statement call of the bare imported name, and the refusal says which of the two it was. Adds fixtures for both, and one for warmColdSpawn, which no fixture pinned. * fix(tests): pin the member-call suite without tripping the focused-test gate The fixture named describe.skip in a string, which PR hygiene reads as a focused test in the diff. describe.each takes the same path through the judge - a callee that is not a bare identifier - so it pins the same property without the literal. --- scripts/test-layout/layout.json | 1 + tests/ci-workflows/cold-spawn-warmup.test.ts | 46 +- .../ci-workflows/warmup-registration.test.ts | 349 +++++++++ tests/fixtures/test-layout-expected.json | 1 + tests/helpers/warmup-registration.ts | 714 ++++++++++++++++++ tests/helpers/warmup-tokens.ts | 171 +++++ 6 files changed, 1270 insertions(+), 12 deletions(-) create mode 100644 tests/ci-workflows/warmup-registration.test.ts create mode 100644 tests/helpers/warmup-registration.ts create mode 100644 tests/helpers/warmup-tokens.ts diff --git a/scripts/test-layout/layout.json b/scripts/test-layout/layout.json index 9f314978746..87e441939ac 100644 --- a/scripts/test-layout/layout.json +++ b/scripts/test-layout/layout.json @@ -180,6 +180,7 @@ "chat-responses-control-integration.test.ts": "responses", "coding-agent-tool-result-images.test.ts": "adapters", "cold-spawn-warmup.test.ts": "ci-workflows", + "warmup-registration.test.ts": "ci-workflows", "hub-usage.test.ts": "server", "client-hub-usage.test.ts": "clients", "cli-usage-hub.test.ts": "cli", diff --git a/tests/ci-workflows/cold-spawn-warmup.test.ts b/tests/ci-workflows/cold-spawn-warmup.test.ts index 1cd9a933de3..7e969d8cf2a 100644 --- a/tests/ci-workflows/cold-spawn-warmup.test.ts +++ b/tests/ci-workflows/cold-spawn-warmup.test.ts @@ -11,9 +11,14 @@ import { } from "../helpers/cold-spawn-warmup"; import { repoPath, repoRoot } from "../helpers/repo-root"; import { SPAWN_BUDGET_MS } from "../helpers/test-budget"; +import { + analyzeWarmupRegistration, + dispositionComplaints, + type WarmupDisposition, +} from "../helpers/warmup-registration"; /** - * Two things are checked here, and they answer different questions. + * Three things are checked here, and they answer different questions. * * The scan answers "did anyone add another one". A test that hands `INTERNAL_DEADLINE_MS` to a child * process timeout is measuring that child's cold module-graph load inside the assertion, which is @@ -22,6 +27,17 @@ import { SPAWN_BUDGET_MS } from "../helpers/test-budget"; * appear below with a disposition, so the next one is classified when it lands rather than after it * fails on a Windows shard. * + * The dispositions answer "is the file recorded as warmed still warmed". That used to be a + * substring test for the helper's path, which #5060 showed accepts an unused import, a comment or a + * string literal as proof — each of them survives deleting the beforeAll call that did the work, so + * the measured child pays the cold load again with a green guard in front of it. + * tests/helpers/warmup-registration.ts replaces the substring with a judge that recognises four + * shapes exactly and refuses every other construct by name; its own regression set is + * tests/ci-workflows/warmup-registration.test.ts. A refused shape is not a blocked file: a + * disposition records the construct in `unmodeled` and the refusal itself stays under test. The + * judge reads shape, not execution — the execution oracle is the [cold-spawn-warmup] completion + * line the helper prints on every hosted run. + * * The unit tests answer "does the warm-up still warm the right thing". A warm-up that names its * modules by hand decays silently, so `moduleGraphSpecifiers` derives them from the child's own * source instead. These cases pin the properties that makes that derivation trustworthy: it follows @@ -29,7 +45,7 @@ import { SPAWN_BUDGET_MS } from "../helpers/test-budget"; * it fails closed when it finds nothing. */ -type Disposition = Readonly<{ warmed: boolean; why: string }>; +type Disposition = WarmupDisposition; /** * Every test file that bounds a spawned child with `INTERNAL_DEADLINE_MS`. @@ -99,24 +115,30 @@ function filesBoundingASpawnWithTheDeadline(): string[] { .sort(); } +function judgeWarmup(path: string) { + const file = repoPath(path); + return analyzeWarmupRegistration(file, readFileSync(file, "utf8")); +} + describe("cold-spawn warm-up coverage", () => { test("every file that times a spawned child against the deadline has a disposition", () => { expect(filesBoundingASpawnWithTheDeadline()).toEqual(Object.keys(DISPOSITIONS).sort()); }); - test("a file recorded as warmed consumes the shared warm-up", () => { - const missing = Object.entries(DISPOSITIONS) - .filter(([, disposition]) => disposition.warmed) - .filter(([path]) => !readFileSync(repoPath(path), "utf8").includes("helpers/cold-spawn-warmup")) - .map(([path]) => path); - expect(missing).toEqual([]); + test("every disposition still describes the file it is recorded against", () => { + // Warmed means one of the four accepted shapes is here and nothing on the binding path was + // refused; unwarmed means the file does not reach the helper at all, which is asked of the + // whole file rather than of its bindings, because a namespace import or a barrel binds no name + // this judge follows and would otherwise read as an absence. + const wrong = Object.entries(DISPOSITIONS) + .flatMap(([path, disposition]) => dispositionComplaints(path, disposition, judgeWarmup(path))); + expect(wrong).toEqual([]); }); - test("a file recorded as unwarmed says why, and does not quietly become warmed", () => { + test("anything other than a plainly warmed file says why, at length", () => { for (const [path, disposition] of Object.entries(DISPOSITIONS)) { - if (disposition.warmed) continue; - expect(disposition.why.length).toBeGreaterThan(80); - expect(readFileSync(repoPath(path), "utf8")).not.toInclude("helpers/cold-spawn-warmup"); + if (disposition.warmed && disposition.unmodeled === undefined) continue; + expect({ path, reason: disposition.why.length > 80 }).toEqual({ path, reason: true }); } }); }); diff --git a/tests/ci-workflows/warmup-registration.test.ts b/tests/ci-workflows/warmup-registration.test.ts new file mode 100644 index 00000000000..2a598c687fa --- /dev/null +++ b/tests/ci-workflows/warmup-registration.test.ts @@ -0,0 +1,349 @@ +import { describe, expect, test } from "bun:test"; +import { repoPath } from "../helpers/repo-root"; +import { + analyzeWarmupRegistration, + dispositionComplaints, + warmupIsRegistered, + warmupRegistrationComplaints, +} from "../helpers/warmup-registration"; + +/** + * The regression set for the invocation oracle in tests/helpers/warmup-registration.ts. + * + * #5060: the coverage guard accepted the substring "helpers/cold-spawn-warmup" as proof that a file + * pays its cold module-graph load in setup, so a comment, a string, or an import left behind after + * its call was deleted all passed. + * + * The judge answers that by recognising four shapes exactly and refusing everything else, so this + * file has to pin both halves. The first describe is the accepted grammar - if one of those stops + * being accepted, ordinary test files start failing for no reason. The second is the refusals, + * which are the point: each one is a construct that either does not warm, or does warm in a way + * this judge will not claim to have proved. The third is the disposition contract, which is how a + * refusal records a legitimate file instead of blocking it. + * + * The fixtures are source text, never imported and never run. The fixture path is a real directory + * under tests/, so the relative specifier resolves to the real helper module, which is what makes + * the same-name-from-another-file case fail rather than pass by spelling. + */ +const FIXTURE = repoPath("tests", "ci-workflows", "warmup-registration-fixture.test.ts"); + +const BUN_TEST = 'import { beforeAll, describe, test } from "bun:test";'; +const HELPER = 'import { warmModuleGraph } from "../helpers/cold-spawn-warmup";'; + +function judge(...lines: string[]) { + return analyzeWarmupRegistration(FIXTURE, lines.join("\n")); +} + +function registers(...lines: string[]): boolean { + return warmupIsRegistered(judge(...lines)); +} + +function why(...lines: string[]): string { + return warmupRegistrationComplaints(judge(...lines)).join(" | "); +} + +/** The registration shape every warmed file in this repository uses today. */ +function hook(...body: string[]): string[] { + return [ + 'describe("subject", () => {', + " beforeAll(async () => {", + ...body.map(line => " " + line), + " }, COLD_SPAWN_WARMUP_HOOK_BUDGET_MS);", + ' test("case", () => {});', + "});", + ]; +} + +describe("warm-up judge: the shapes it accepts", () => { + test("a describe, a beforeAll, and the warm-up as a whole awaited statement", () => { + const report = judge(BUN_TEST, HELPER, ...hook("await warmModuleGraph(options);")); + expect(warmupIsRegistered(report)).toBe(true); + expect(report.registrations).toEqual([ + { helper: "warmModuleGraph", local: "warmModuleGraph", shape: "hook-statement", line: 5 }, + ]); + }); + + test("the same hook at the top level, with no describe around it", () => { + expect(registers( + BUN_TEST, + HELPER, + "beforeAll(async () => {", + " await warmModuleGraph(options);", + "}, COLD_SPAWN_WARMUP_HOOK_BUDGET_MS);", + )).toBe(true); + }); + + test("return and a concise body connect the promise as well as await does", () => { + const shapes = (...lines: string[]): string[] => + judge(...lines).registrations.map(entry => entry.shape); + expect(shapes(BUN_TEST, HELPER, ...hook("return warmModuleGraph(options);"))).toEqual(["hook-return"]); + expect(shapes(BUN_TEST, HELPER, ...hook("return await warmModuleGraph(options);"))).toEqual(["hook-return"]); + expect(shapes( + BUN_TEST, + HELPER, + "beforeAll(() => warmModuleGraph(options), COLD_SPAWN_WARMUP_HOOK_BUDGET_MS);", + )).toEqual(["hook-expression"]); + expect(registers( + BUN_TEST, + HELPER, + "beforeAll(async () => await warmModuleGraph(options), COLD_SPAWN_WARMUP_HOOK_BUDGET_MS);", + )).toBe(true); + }); + + test("a function expression stands in for the arrow", () => { + expect(registers( + BUN_TEST, + HELPER, + "beforeAll(async function () {", + " await warmModuleGraph(options);", + "}, COLD_SPAWN_WARMUP_HOOK_BUDGET_MS);", + )).toBe(true); + }); + + test("an alias is followed, and an optional call is still a call", () => { + const aliased = judge( + BUN_TEST, + 'import { warmModuleGraph as warmUp } from "../helpers/cold-spawn-warmup";', + ...hook("await warmUp(options);"), + ); + expect(aliased.registrations).toEqual([ + { helper: "warmModuleGraph", local: "warmUp", shape: "hook-statement", line: 5 }, + ]); + expect(registers(BUN_TEST, HELPER, ...hook("await warmModuleGraph?.(options);"))).toBe(true); + }); + + test("both entry points are recognised, not only the one most files use", () => { + // warmColdSpawn is the replay form, used where an import scan cannot reach the cold cost. If + // it fell out of the recognised set, its files would be refused as never calling the helper. + const report = judge( + BUN_TEST, + 'import { warmColdSpawn } from "../helpers/cold-spawn-warmup";', + ...hook("await warmColdSpawn(graph, replay);"), + ); + expect(report.registrations).toEqual([ + { helper: "warmColdSpawn", local: "warmColdSpawn", shape: "hook-statement", line: 5 }, + ]); + }); + + test("a module-level await is a warm-up the file always pays", () => { + // No hook to register: the statement runs when the module loads, which is before any test in + // it is timed. It has to be the whole statement, exactly as it does inside a hook. + const report = judge(BUN_TEST, HELPER, "await warmModuleGraph(options);"); + expect(report.registrations.map(entry => entry.shape)).toEqual(["module-top-level"]); + expect(registers(BUN_TEST, HELPER, "const warmed = await warmModuleGraph(options);")).toBe(false); + }); + + test("a template substitution and a regular expression do not derail the token walk", () => { + // Both are scanner rescans rather than plain tokens. Read naively, the closing brace of a + // substitution leaks an unmatched brace and a regular expression is read as a division that + // swallows whatever delimiters sit inside it, and either one moves the rest of the file to a + // depth where the hook no longer looks like a hook. + expect(registers(BUN_TEST, HELPER, ...hook( + "const label = \`graph-\${options.graph}-\${JSON.stringify({ warm: true })}\`;", + 'const trimmed = label.replace(/[^a-z-]{1,4}/g, "");', + "await warmModuleGraph(options);", + ))).toBe(true); + }); +}); + +describe("warm-up judge: what it refuses, and says why", () => { + test("a comment or a string that names the warm-up binds nothing", () => { + // These two are the defect verbatim. Both contain every character the old substring check + // looked for, and neither loads a module. + const commented = judge(BUN_TEST, ...hook("// await warmModuleGraph(options); helpers/cold-spawn-warmup")); + const quoted = judge(BUN_TEST, ...hook('const note = "warmModuleGraph(options) helpers/cold-spawn-warmup";')); + expect([warmupIsRegistered(commented), warmupIsRegistered(quoted)]).toEqual([false, false]); + expect([commented.bindings, quoted.bindings, commented.mentionsEntryPoint]).toEqual([[], [], false]); + }); + + test("an import left behind after the call was deleted is not a warm-up", () => { + expect(why(BUN_TEST, HELPER, ...hook("const unrelated = 1;"))).toContain("never called"); + }); + + test("a helper reached without a direct named import is refused rather than guessed", () => { + // A namespace import and a barrel both warm at run time. Following either one means resolving + // a binding through another module, and a judge that guesses there is a judge that can be + // wrong in the direction that matters. The disposition table is where such a file is recorded. + const namespaced = judge( + BUN_TEST, + 'import * as warmup from "../helpers/cold-spawn-warmup";', + ...hook("await warmup.warmModuleGraph(options);"), + ); + expect([warmupIsRegistered(namespaced), namespaced.mentionsEntryPoint]).toEqual([false, true]); + expect(warmupRegistrationComplaints(namespaced).join(" ")).toContain("namespace"); + + const barrel = judge( + BUN_TEST, + 'import { warmModuleGraph } from "../helpers/test-helpers";', + ...hook("await warmModuleGraph(options);"), + ); + expect([warmupIsRegistered(barrel), barrel.mentionsEntryPoint]).toEqual([false, true]); + expect(warmupRegistrationComplaints(barrel).join(" ")).toContain("direct named import"); + }); + + test("a type-only import loads nothing, and a local function of the same name is not the import", () => { + expect(why( + BUN_TEST, + 'import type { warmModuleGraph } from "../helpers/cold-spawn-warmup";', + ...hook("await warmModuleGraph(options);"), + )).toContain("type only"); + expect(registers( + BUN_TEST, + "async function warmModuleGraph(options) { return options; }", + ...hook("await warmModuleGraph(options);"), + )).toBe(false); + }); + + test("a hook the file never reaches registers nothing", () => { + // Each of these calls beforeAll with a correct, awaited warm-up, and none of them runs: one + // sits in a helper nobody calls, one behind a false condition, and one inside an + // expression-bodied callback, which has no braces to give the scope away. + const uncalled = judge(BUN_TEST, HELPER, + "function installWarmUp() {", + " beforeAll(async () => {", + " await warmModuleGraph(options);", + " }, COLD_SPAWN_WARMUP_HOOK_BUDGET_MS);", + "}"); + const guarded = judge(BUN_TEST, HELPER, + "if (false) {", + " beforeAll(async () => {", + " await warmModuleGraph(options);", + " }, COLD_SPAWN_WARMUP_HOOK_BUDGET_MS);", + "}"); + const expressionBodied = judge(BUN_TEST, HELPER, + "register(() => beforeAll(async () => {", + " await warmModuleGraph(options);", + "}));"); + expect([uncalled, guarded, expressionBodied].map(warmupIsRegistered)).toEqual([false, false, false]); + expect(warmupRegistrationComplaints(expressionBodied).join(" ")).toContain("does not model"); + }); + + test("a suite that is not a plain describe statement does not make its hooks run", () => { + // A suite reached through a member - describe.each here, and describe.skip or describe.only by + // the same path - is a callee this judge cannot claim runs, and a describe behind a false + // condition is never called at all. Both leave a correctly written beforeAll inside a suite + // that is not there, which is a registration in shape only. + const member = judge(BUN_TEST, HELPER, + 'describe.each([1, 2])("subject %s", () => {', + " beforeAll(async () => {", + " await warmModuleGraph(options);", + " }, COLD_SPAWN_WARMUP_HOOK_BUDGET_MS);", + "});"); + const guardedSuite = judge(BUN_TEST, HELPER, + 'if (false) describe("subject", () => {', + " beforeAll(async () => {", + " await warmModuleGraph(options);", + " }, COLD_SPAWN_WARMUP_HOOK_BUDGET_MS);", + "});"); + expect([member, guardedSuite].map(warmupIsRegistered)).toEqual([false, false]); + expect(warmupRegistrationComplaints(guardedSuite).join(" ")).toContain("plain statement"); + }); + + test("an expression-bodied arrow is a scope, so a warm-up inside an uncalled one is refused", () => { + expect(registers(BUN_TEST, HELPER, "const warmUp = async () => await warmModuleGraph(options);")) + .toBe(false); + expect(registers(BUN_TEST, HELPER, "const warmUp = () => warmModuleGraph(options);")).toBe(false); + }); + + test("a rebound beforeAll or describe is not the bun:test one", () => { + // The shadowed hook takes a correct callback and runs nothing at all. Provenance has to hold + // for the hook name exactly as it does for the warm-up name. + const shadowedHook = judge(BUN_TEST, HELPER, + 'describe("subject", () => {', + " const beforeAll = (body) => body;", + " beforeAll(async () => {", + " await warmModuleGraph(options);", + " });", + "});"); + const shadowedSuite = judge(BUN_TEST, HELPER, + "const describe = (name, body) => body();", + ...hook("await warmModuleGraph(options);")); + expect([shadowedHook, shadowedSuite].map(warmupIsRegistered)).toEqual([false, false]); + expect(warmupRegistrationComplaints(shadowedHook).join(" ")).toContain("rebound"); + expect(warmupRegistrationComplaints(shadowedSuite).join(" ")).toContain("rebound"); + }); + + test("a parameter, a variable alias, and a callback reached by name are all refused", () => { + const parameter = judge(BUN_TEST, HELPER, + 'describe("subject", () => {', + " beforeAll(async (warmModuleGraph) => {", + " await warmModuleGraph(options);", + " });", + "});"); + const alias = judge(BUN_TEST, HELPER, "const warm = warmModuleGraph;", ...hook("await warm(options);")); + const byName = judge(BUN_TEST, HELPER, + "const warmUpHook = async () => {", + " await warmModuleGraph(options);", + "};", + "beforeAll(warmUpHook, COLD_SPAWN_WARMUP_HOOK_BUDGET_MS);"); + expect([parameter, alias, byName].map(warmupIsRegistered)).toEqual([false, false, false]); + expect(warmupRegistrationComplaints(alias).join(" ")).toContain("without being called"); + }); + + test("fire and forget, void, and a partial expression leave the hook settling first", () => { + expect(registers(BUN_TEST, HELPER, ...hook("warmModuleGraph(options);"))).toBe(false); + expect(registers(BUN_TEST, HELPER, ...hook("void warmModuleGraph(options);"))).toBe(false); + expect(registers(BUN_TEST, HELPER, ...hook("return warmModuleGraph(options), ready();"))).toBe(false); + expect(registers( + BUN_TEST, + HELPER, + "beforeAll(() => warmModuleGraph(options) && ready(), COLD_SPAWN_WARMUP_HOOK_BUDGET_MS);", + )).toBe(false); + }); + + test("a conditional call is refused even when every branch warms", () => { + // Refused rather than analysed. Deciding that two branches both warm means modelling control + // flow, and the judge that models control flow from tokens is the one that gets it wrong. + expect(registers(BUN_TEST, HELPER, ...hook( + "if (portable) {", + " await warmModuleGraph(portableOptions);", + "} else {", + " await warmModuleGraph(nativeOptions);", + "}", + ))).toBe(false); + expect(registers(BUN_TEST, HELPER, ...hook("if (false) await warmModuleGraph(options);"))).toBe(false); + }); + + test("a file this judge cannot read is a failure, never an absence", () => { + const report = judge(BUN_TEST, HELPER, 'describe("unclosed", () => {'); + expect(report.refusals.length).toBeGreaterThan(0); + expect(warmupIsRegistered(report)).toBe(false); + }); +}); + +describe("warm-up judge: what a disposition has to match", () => { + const warmed = { warmed: true, why: "the canonical hook" }; + const unwarmed = { warmed: false, why: "nothing here spawns a child that loads a repository graph" }; + const canonical = () => judge(BUN_TEST, HELPER, ...hook("await warmModuleGraph(options);")); + const dropped = () => judge(BUN_TEST, HELPER, ...hook("warmModuleGraph(options);")); + const namespaced = () => judge( + BUN_TEST, + 'import * as warmup from "../helpers/cold-spawn-warmup";', + ...hook("await warmup.warmModuleGraph(options);"), + ); + + test("warmed means an accepted shape and nothing refused", () => { + expect(dispositionComplaints("f.test.ts", warmed, canonical())).toEqual([]); + expect(dispositionComplaints("f.test.ts", warmed, dropped()).join(" ")).toContain("recorded warmed"); + }); + + test("unwarmed means the file does not reach the helper at all", () => { + expect(dispositionComplaints("f.test.ts", unwarmed, judge(BUN_TEST, ...hook("const x = 1;")))).toEqual([]); + expect(dispositionComplaints("f.test.ts", unwarmed, canonical()).join(" ")).toContain("recorded unwarmed"); + // A namespace import binds no name this judge follows, so bindings alone would read this as an + // absence. It is the reason the unwarmed test asks whether the helper is reached at all. + expect(dispositionComplaints("f.test.ts", unwarmed, namespaced()).join(" ")).toContain("reaches the warm-up helper"); + }); + + test("an unmodelled shape is recorded, and the record has to keep matching", () => { + // This is how a refusal records a legitimate file instead of blocking it. The escape is not a + // silence: the judge still has to see the warm-up and still has to refuse it for the stated + // reason, so deleting the call or dropping the await changes the refusal and fails again. + const recorded = { warmed: true, why: "warms through a namespace import", unmodeled: "namespace" }; + expect(dispositionComplaints("f.test.ts", recorded, namespaced())).toEqual([]); + expect(dispositionComplaints("f.test.ts", recorded, dropped()).join(" ")).toContain("not what was refused"); + expect(dispositionComplaints("f.test.ts", recorded, canonical()).join(" ")).toContain("drop the note"); + expect(dispositionComplaints("f.test.ts", recorded, judge(BUN_TEST, ...hook("const x = 1;"))).join(" ")) + .toContain("nothing here reaches"); + }); +}); diff --git a/tests/fixtures/test-layout-expected.json b/tests/fixtures/test-layout-expected.json index dac7ce37f5b..89ff7df6a5a 100644 --- a/tests/fixtures/test-layout-expected.json +++ b/tests/fixtures/test-layout-expected.json @@ -12,6 +12,7 @@ "chat-responses-control-integration.test.ts": "responses", "coding-agent-tool-result-images.test.ts": "adapters", "cold-spawn-warmup.test.ts": "ci-workflows", + "warmup-registration.test.ts": "ci-workflows", "hub-usage.test.ts": "server", "client-hub-usage.test.ts": "clients", "cli-usage-hub.test.ts": "cli", diff --git a/tests/helpers/warmup-registration.ts b/tests/helpers/warmup-registration.ts new file mode 100644 index 00000000000..4857bbd50f1 --- /dev/null +++ b/tests/helpers/warmup-registration.ts @@ -0,0 +1,714 @@ +import { dirname, isAbsolute, resolve } from "node:path"; +import { SyntaxKind } from "typescript/unstable/ast"; +import { helperPath } from "./repo-root"; +import { argumentEnd, at, CLOSERS, lineOf, OPENERS, tokenize, type Token } from "./warmup-tokens"; + +/** + * Decide, from a test file's source alone, whether it registers a cold-spawn warm-up and waits for + * it: by recognising a small set of exact shapes and refusing everything else. + * + * ## The defect this exists for + * + * The coverage guard in tests/ci-workflows/cold-spawn-warmup.test.ts recorded a file as warmed when + * its text contained the substring "helpers/cold-spawn-warmup" (#5060). A comment, a string literal, + * or an import left behind after the beforeAll call was deleted all satisfied it, and the measured + * child went back to paying its cold module-graph load with a green guard standing in front of it. + * + * ## The shapes this judge accepts + * + * W is a name bound by a DIRECT named import of tests/helpers/cold-spawn-warmup, aliases followed; + * the call may be W(...) or W?.(...). describe and beforeAll must be direct named imports of + * bun:test, and neither may be rebound anywhere in the file. + * + * hook-statement describe(...)* > beforeAll(async () => { ... await W(...); ... }, ...) + * hook-return describe(...)* > beforeAll(() => { return W(...); }, ...) + * hook-expression describe(...)* > beforeAll(() => W(...), ...) and its awaited form + * module-top-level await W(...); as a whole statement at the top level of the file + * +* In the two statement shapes the call is the whole statement: it begins right after a brace or a +* semicolon and ends on its own semicolon or on the closing brace of the hook. A function +* expression stands in for the arrow in any of them. Nesting is exact - every block between the +* file and the hook must be a describe callback, and the open calls must be exactly the calls that +* own those blocks, so an extra paren or an extra block is not the same shape. + * + * A describe callback counts only when the describe is a plain statement call of the bare imported + * name. describe.skip registers a suite that never runs and a describe behind a condition is never + * called, so a hook inside either one is a registration in shape only. + * + * ## What it refuses, by design + * + * Every other occurrence of W is a refusal naming its line, and one refusal anywhere on the binding + * path means the file is not proven. Shapes that do warm at run time are refused too: + * + * a namespace import of the helper, and any call made through it; + * a barrel or re-export path, because the specifier does not resolve to the helper module; + * an alias through a variable, const warm = W, and a callback the hook reaches by name; +* a call in a scope this judge does not model - a nested function, an uncalled helper, a bare +* block, a conditional branch, even when every branch warms; + * a hook inside a suite that is not a plain describe statement, such as describe.skip or + * describe.each; +* fire-and-forget, void, and a call that is one operand of a larger expression. + * + * That list is the design rather than a backlog. TypeScript 7.0.2 publishes no in-process parser + * (see tests/helpers/warmup-tokens.ts), so the alternative to an exact accept-set is reconstructing + * scoping and expression grammar from tokens, where every wrong guess is a FALSE PASS - the one + * failure this file exists to remove. A refusal is the opposite: loud, located, and cheap to answer. + * A legitimate file that needs a refused shape records it once in its disposition, which keeps the + * refusal itself under test; see WarmupDisposition. + * + * ## What no structural check can decide + * + * It reads the shape of a file, not the run. It does not prove the process reached the describe that + * holds the registration, and it does not prove the warm-up child loaded anything. That oracle is + * separate and unchanged: the helper prints one completion line per warmed graph on every hosted + * run, and a warm-up that throws fails its file as a setup failure. + */ + +/** The entry points in tests/helpers/cold-spawn-warmup.ts that pay a cold module graph. */ +const WARMUP_ENTRY_POINTS: ReadonlySet = new Set(["warmColdSpawn", "warmModuleGraph"]); + +/** The bun:test hook a warm-up belongs in, and the only call its scopes may be nested inside. */ +const REGISTRATION_HOOK = "beforeAll"; +const SUITE_CALL = "describe"; + +/** What a modelled statement may begin after. Anything else means it is part of something larger. */ +const STATEMENT_START: ReadonlySet = new Set([ + SyntaxKind.SemicolonToken, + SyntaxKind.OpenBraceToken, + SyntaxKind.CloseBraceToken, +]); + +/** Keywords that introduce a new binding for the name that follows them. */ +const DECLARATION_KEYWORDS: ReadonlySet = new Set([ + SyntaxKind.ConstKeyword, + SyntaxKind.LetKeyword, + SyntaxKind.VarKeyword, + SyntaxKind.FunctionKeyword, + SyntaxKind.ClassKeyword, +]); + +export type WarmupShape = "hook-statement" | "hook-return" | "hook-expression" | "module-top-level"; + +export type WarmupRegistration = Readonly<{ + /** The helper entry point the file waits for. */ + helper: string; + /** The local name it was called through, which is the alias when the import renames it. */ + local: string; + /** Which of the accepted shapes matched. */ + shape: WarmupShape; + /** 1-based line of the call, so a failure points at a place rather than a file. */ + line: number; +}>; + +export type WarmupRegistrationReport = Readonly<{ + /** Local names a direct named import bound to a warm-up entry point. */ + bindings: readonly string[]; + /** Whether any import specifier resolves to the helper module. */ + importsHelperModule: boolean; + /** + * Whether either entry-point name appears as an identifier at all, however it got here. A barrel + * import and a namespace call both bind nothing this judge follows, so bindings alone would read + * a real warm-up as an absence. + */ + mentionsEntryPoint: boolean; + /** Occurrences that matched an accepted shape. */ + registrations: readonly WarmupRegistration[]; + /** One channel for everything fatal: unreadable source, and every construct not modelled. */ + refusals: readonly string[]; +}>; + +export type WarmupDisposition = Readonly<{ + /** Whether the file is claimed to pay its cold module-graph load in setup. */ + warmed: boolean; + /** Why, in enough detail to survive review. */ + why: string; + /** + * For a file that really does warm in a shape this judge refuses: the text its refusal has to + * contain. The judge still has to see the warm-up and still has to refuse it for that stated + * reason, so deleting the call, or degrading it to fire-and-forget, changes the refusal and fails. + */ + unmodeled?: string; +}>; + +/** True only when an accepted shape matched and nothing on the binding path was refused. */ +export function warmupIsRegistered(report: WarmupRegistrationReport): boolean { + return report.refusals.length === 0 && report.registrations.length > 0; +} + +/** Everything the judge refused, for a failure message that names the construct and the line. */ +export function warmupRegistrationComplaints(report: WarmupRegistrationReport): string[] { + return [...report.refusals]; +} + +/** + * Where a file disagrees with the disposition recorded for it, empty when they agree. + * + * Three states rather than two. A file recorded as warmed has to show an accepted shape and nothing + * refused; a file recorded as unwarmed must not reach the helper at all; and a file recorded as + * warmed through an unmodelled shape has to still reach the helper and still be refused for the + * stated reason. That third state is what keeps a refusal from blocking a legitimate test file + * while keeping the refusal itself honest. + */ +export function dispositionComplaints( + path: string, + disposition: WarmupDisposition, + report: WarmupRegistrationReport, +): string[] { + const complaints: string[] = []; + const say = (what: string): number => complaints.push(path + ": " + what); + const refused = report.refusals.join("; "); + if (!disposition.warmed) { + if (report.mentionsEntryPoint || report.importsHelperModule) say("recorded unwarmed, but it reaches the warm-up helper"); + if (report.registrations.length > 0) say("recorded unwarmed, but it registers a warm-up"); + if (report.refusals.length > 0) say("recorded unwarmed, and " + refused); + return complaints; + } + const unmodeled = disposition.unmodeled; + if (unmodeled === undefined) { + if (report.registrations.length === 0) { + say("recorded warmed, but no accepted shape is here: " + (refused || "nothing reaches the warm-up helper")); + } else if (report.refusals.length > 0) { + say("recorded warmed, and " + refused); + } + return complaints; + } + if (!report.mentionsEntryPoint) say("recorded warmed through " + unmodeled + ", but nothing here reaches the warm-up helper"); + else if (report.registrations.length > 0) say("recorded warmed through " + unmodeled + ", but this judge accepts what it found; drop the note"); + else if (!report.refusals.some(refusal => refusal.includes(unmodeled))) { + say("recorded warmed through " + unmodeled + ", which is not what was refused: " + (refused || "nothing was refused")); + } + return complaints; +} + +export function analyzeWarmupRegistration(fileName: string, source: string): WarmupRegistrationReport { + const scan = tokenize(source); + if (scan.unreadable.length > 0) { + return { + bindings: [], importsHelperModule: false, mentionsEntryPoint: false, + registrations: [], refusals: scan.unreadable, + }; + } + const tokens = scan.tokens; + const refusals: string[] = []; + const clauses = importClauses(tokens); + + const bindings = new Map(); + let importsHelperModule = false; + for (const clause of clauses) { + if (!importsTheWarmupHelper(fileName, clause.specifier)) continue; + importsHelperModule = true; + if (clause.namespace !== undefined) { + refusals.push(at(source, clause.start) + "the warm-up helper is imported as a namespace (* as " + + clause.namespace + "), which this judge does not model"); + } + for (const name of clause.names) { + if (!WARMUP_ENTRY_POINTS.has(name.imported)) continue; + if (name.typeOnly) { + refusals.push(at(source, clause.start) + name.imported + + " is imported for its type only, which loads nothing at run time"); + continue; + } + bindings.set(name.local, name.imported); + } + } + const mentionsEntryPoint = importsHelperModule || tokens.some(token => + token.kind === SyntaxKind.Identifier && WARMUP_ENTRY_POINTS.has(token.text)); + + if (bindings.size === 0) { + if (mentionsEntryPoint && refusals.length === 0) { + refusals.push("the warm-up helper is reached without a direct named import of " + + "tests/helpers/cold-spawn-warmup, which this judge does not model"); + } + return { bindings: [], importsHelperModule, mentionsEntryPoint, registrations: [], refusals }; + } + + const hooks = importedLocals(clauses, "bun:test", REGISTRATION_HOOK); + const suites = importedLocals(clauses, "bun:test", SUITE_CALL); + const rebound = new Map(); + for (const name of [...hooks, ...suites]) { + const rebinding = rebindingOf(tokens, name); + if (rebinding !== undefined) rebound.set(name, rebinding); + } + + const registrations = judgeOccurrences({ tokens, source, bindings, hooks, suites, rebound, refusals, + imported: importedTokenRanges(clauses) }); + if (registrations.length === 0 && refusals.length === 0) { + refusals.push("the warm-up helper is imported here and never called"); + } + return { bindings: [...bindings.keys()], importsHelperModule, mentionsEntryPoint, registrations, refusals }; +} + +type CallFrame = Readonly<{ + /** The bare identifier being called, or empty when the call is anything more elaborate. */ + callee: string; + /** Token index of the paren that opened the call. */ + open: number; + /** Whether the callee itself starts a statement, which is what makes its callback run. */ + statement: boolean; +}>; + +/** How a scope reads in a refusal, so the message says where the call actually sits. */ +const LAYER_LABELS: Readonly> = { + suite: "a describe callback", + hook: "a beforeAll callback", + "hook-expression": "a beforeAll expression body", + other: "a scope this judge does not model", +}; + +/** + * A scope the judge tracks. Only two kinds are part of an accepted shape; everything else is + * "other" and refuses whatever sits inside it. A concise arrow body is a scope with no braces, and + * missing it is how a hook registered inside an uncalled callback reads as top-level work. + */ +type Layer = Readonly<{ + kind: "suite" | "hook" | "hook-expression" | "other"; + /** Token index where the scope ends: its closing brace, or the end of the arrow expression. */ + end: number; + /** Token index of the first token inside it. */ + bodyStart: number; + /** Why a scope that looks like one of the accepted kinds is not, for the refusal message. */ + reason?: string; +}>; + +type Judgement = Readonly<{ + tokens: readonly Token[]; + source: string; + bindings: ReadonlyMap; + hooks: ReadonlySet; + suites: ReadonlySet; + rebound: ReadonlyMap; + refusals: string[]; + imported: readonly { from: number; to: number }[]; +}>; + +/** + * One pass over the file, carrying the two stacks an accepted shape is defined in terms of: the + * calls that are open, and the scopes that are open. Every occurrence of a warm-up binding is + * classified against them, and an occurrence that matches no accepted shape is refused by name. + */ +function judgeOccurrences(j: Judgement): WarmupRegistration[] { + const { tokens } = j; + const matches = delimiterMatches(tokens); + const registrations: WarmupRegistration[] = []; + const layers: Layer[] = []; + const calls: CallFrame[] = []; + const acceptedHookCalls = new Set(); + for (let i = 0; i < tokens.length; i += 1) { + while (layers.length > 0 && layers[layers.length - 1].end <= i) layers.pop(); + const token = tokens[i]; + if (token.kind === SyntaxKind.CloseParenToken) { + calls.pop(); + continue; + } + if (token.kind === SyntaxKind.OpenParenToken) { + calls.push(callFrame(tokens, i)); + continue; + } + if (token.kind === SyntaxKind.OpenBraceToken) { + layers.push(braceLayer(j, i, calls, acceptedHookCalls, matches)); + continue; + } + if (token.kind === SyntaxKind.EqualsGreaterThanToken + && (tokens[i + 1] === undefined || tokens[i + 1].kind !== SyntaxKind.OpenBraceToken)) { + layers.push(conciseArrowLayer(j, i, calls, acceptedHookCalls, matches)); + continue; + } + if (token.kind !== SyntaxKind.Identifier) continue; + if (j.hooks.has(token.text) && !isMemberName(tokens, i)) { + const open = opensCall(tokens, i); + if (open !== undefined && hookCallIsVisible(j, i, layers, calls)) acceptedHookCalls.add(open); + continue; + } + if (!isBindingOccurrence(j, i)) continue; + const verdict = classifyOccurrence(j, i, layers, calls, matches); + if (typeof verdict === "string") j.refusals.push(verdict); + else registrations.push(verdict); + } + return registrations; +} + +/** Index of the delimiter each delimiter pairs with, computed once rather than scanned per call. */ +function delimiterMatches(tokens: readonly Token[]): number[] { + const matches = new Array(tokens.length).fill(-1); + const open: number[] = []; + for (let i = 0; i < tokens.length; i += 1) { + if (OPENERS.has(tokens[i].kind)) open.push(i); + else if (CLOSERS.has(tokens[i].kind)) { + const start = open.pop(); + if (start !== undefined) { + matches[start] = i; + matches[i] = start; + } + } + } + return matches; +} + +function braceLayer( + j: Judgement, + brace: number, + calls: readonly CallFrame[], + accepted: ReadonlySet, + matches: readonly number[], +): Layer { + const end = matches[brace] < 0 ? j.tokens.length : matches[brace]; + const bodyStart = brace + 1; + const owner = calls[calls.length - 1]; + if (!opensArgumentCallback(j.tokens, brace, matches)) return { kind: "other", end, bodyStart }; + if (owner !== undefined && accepted.has(owner.open)) return { kind: "hook", end, bodyStart }; + if (owner !== undefined && owner.statement && j.suites.has(owner.callee) && !j.rebound.has(owner.callee)) { + return { kind: "suite", end, bodyStart }; + } + const reason = braceLayerReason(j, owner); + return { kind: "other", end, bodyStart, reason }; +} + +/** + * Why a block that looks like a describe body is not one. A rebound name is not bun:test, and a + * describe that is not itself a plain statement - behind a condition, through a member such as + * describe.skip, or inside another callback - registers hooks that never run. + */ +function braceLayerReason(j: Judgement, owner: CallFrame | undefined): string | undefined { + if (owner === undefined) return undefined; + const rebinding = j.rebound.get(owner.callee); + if (rebinding !== undefined) { + return owner.callee + " is rebound at line " + lineOf(j.source, rebinding.start) + ", so this is not bun:test"; + } + if (j.suites.has(owner.callee) && !owner.statement) { + return owner.callee + " is not called as a plain statement here, so its callback is not known to run"; + } + return undefined; +} + +function conciseArrowLayer( + j: Judgement, + arrow: number, + calls: readonly CallFrame[], + accepted: ReadonlySet, + matches: readonly number[], +): Layer { + const owner = calls[calls.length - 1]; + const ownsHookBody = owner !== undefined && accepted.has(owner.open) + && arrowIsArgument(j.tokens, arrow, matches); + return { + kind: ownsHookBody ? "hook-expression" : "other", + end: argumentEnd(j.tokens, arrow + 1), + bodyStart: arrow + 1, + }; +} + +/** + * Whether a beforeAll call is one this judge can see running: the bun:test import itself, at the + * start of a statement, with describe callbacks and nothing else between it and the file. + */ +function hookCallIsVisible( + j: Judgement, + hook: number, + layers: readonly Layer[], + calls: readonly CallFrame[], +): boolean { + if (j.rebound.has(j.tokens[hook].text)) return false; + if (calls.length !== layers.length) return false; + if (!layers.every(layer => layer.kind === "suite")) return false; + const before = j.tokens[hook - 1]; + return before === undefined || STATEMENT_START.has(before.kind); +} + +function classifyOccurrence( + j: Judgement, + w: number, + layers: readonly Layer[], + calls: readonly CallFrame[], + matches: readonly number[], +): WarmupRegistration | string { + const token = j.tokens[w]; + const helper = j.bindings.get(token.text) ?? token.text; + const made = (shape: WarmupShape): WarmupRegistration => + ({ helper, local: token.text, shape, line: lineOf(j.source, token.start) }); + const refuse = (why: string): string => at(j.source, token.start) + token.text + " " + why; + const open = opensCall(j.tokens, w); + if (open === undefined) return refuse("is used without being called, which this judge does not model"); + const close = matches[open]; + if (close < 0) return refuse("opens a call this judge cannot close"); + if (calls.length !== layers.length) { + return chainRefusal(j, w, layers, " (the open calls do not match the open scopes)"); + } + if (layers.length === 0) { + const statement = wholeStatement(j.tokens, w, close, undefined); + if (statement === undefined || statement.keyword !== "await") { + return refuse("is not a whole awaited statement at the top level of the file"); + } + return made("module-top-level"); + } + const inner = layers[layers.length - 1]; + if (!layers.slice(0, layers.length - 1).every(layer => layer.kind === "suite")) return chainRefusal(j, w, layers); + if (inner.kind === "hook") { + const statement = wholeStatement(j.tokens, w, close, inner.end); + if (statement === undefined) { + return refuse("is not a whole awaited or returned statement of the hook callback"); + } + return made(statement.keyword === "return" ? "hook-return" : "hook-statement"); + } + if (inner.kind === "hook-expression") { + const head = inner.bodyStart; + const awaited = j.tokens[head] !== undefined && j.tokens[head].kind === SyntaxKind.AwaitKeyword; + if (w !== head && !(awaited && w === head + 1)) { + return refuse("is not the whole body of the hook callback"); + } + if (close + 1 !== inner.end) return refuse("is one part of a larger returned expression"); + return made("hook-expression"); + } + return chainRefusal(j, w, layers); +} + +function chainRefusal(j: Judgement, w: number, layers: readonly Layer[], extra = ""): string { + const chain = layers + .map(layer => LAYER_LABELS[layer.kind] + (layer.reason === undefined ? "" : " (" + layer.reason + ")")) + .join(" > "); + return at(j.source, j.tokens[w].start) + j.tokens[w].text + + " is not in a shape this judge models; enclosing scopes: " + + (chain === "" ? "the top level of the file" : chain) + extra; +} + +/** + * The call as a whole statement introduced by await or return, or undefined when it is part of + * something larger. A statement begins right after a brace or a semicolon and ends on its own + * semicolon or on the brace that closes the scope, which is what rules out fire-and-forget, void, + * a conditional consequent, and an operand of a larger expression without modelling any of them. + */ +function wholeStatement( + tokens: readonly Token[], + w: number, + close: number, + scopeEnd: number | undefined, +): { start: number; keyword: "await" | "return" } | undefined { + const pre = tokens[w - 1]; + if (pre === undefined) return undefined; + let start = w - 1; + let keyword: "await" | "return"; + if (pre.kind === SyntaxKind.AwaitKeyword) keyword = "await"; + else if (pre.kind === SyntaxKind.ReturnKeyword) keyword = "return"; + else return undefined; + const beforeKeyword = tokens[start - 1]; + if (keyword === "await" && beforeKeyword !== undefined && beforeKeyword.kind === SyntaxKind.ReturnKeyword) { + start -= 1; + keyword = "return"; + } + const before = tokens[start - 1]; + if (before !== undefined && !STATEMENT_START.has(before.kind)) return undefined; + const after = tokens[close + 1]; + const ends = after === undefined || after.kind === SyntaxKind.SemicolonToken + || (scopeEnd !== undefined && close + 1 === scopeEnd); + return ends ? { start, keyword } : undefined; +} + +/** Index of the paren that opens a call on the identifier at i, for W(...) and W?.(...). */ +function opensCall(tokens: readonly Token[], i: number): number | undefined { + const next = tokens[i + 1]; + if (next === undefined) return undefined; + if (next.kind === SyntaxKind.OpenParenToken) return i + 1; + if (next.kind === SyntaxKind.QuestionDotToken && tokens[i + 2] !== undefined + && tokens[i + 2].kind === SyntaxKind.OpenParenToken) return i + 2; + return undefined; +} + +function isMemberName(tokens: readonly Token[], i: number): boolean { + const before = tokens[i - 1]; + return before !== undefined + && (before.kind === SyntaxKind.DotToken || before.kind === SyntaxKind.QuestionDotToken); +} + +/** An identifier that IS the imported binding: not a property name, and not the import clause. */ +function isBindingOccurrence(j: Judgement, i: number): boolean { + const token = j.tokens[i]; + if (token.kind !== SyntaxKind.Identifier || !j.bindings.has(token.text)) return false; + if (isMemberName(j.tokens, i)) return false; + return !j.imported.some(range => i >= range.from && i <= range.to); +} + +type ImportedName = Readonly<{ imported: string; local: string; typeOnly: boolean }>; + +type ImportClause = Readonly<{ + specifier: string; + names: readonly ImportedName[]; + namespace: string | undefined; + /** Token index of the import keyword and of its specifier, so occurrences inside are not calls. */ + from: number; + to: number; + start: number; +}>; + +/** + * Every import DECLARATION and what it binds. A dynamic import(...) and import.meta are skipped: + * neither creates the top-level binding an accepted shape is written in terms of. + */ +function importClauses(tokens: readonly Token[]): ImportClause[] { + const clauses: ImportClause[] = []; + for (let i = 0; i < tokens.length; i += 1) { + if (tokens[i].kind !== SyntaxKind.ImportKeyword) continue; + const next = tokens[i + 1]; + if (next === undefined) break; + if (next.kind === SyntaxKind.OpenParenToken || next.kind === SyntaxKind.DotToken) continue; + if (next.kind === SyntaxKind.StringLiteral) { + clauses.push({ specifier: next.value, names: [], namespace: undefined, from: i, to: i + 1, start: tokens[i].start }); + i += 1; + continue; + } + let cursor = i + 1; + while (cursor < tokens.length + && tokens[cursor].kind !== SyntaxKind.FromKeyword + && tokens[cursor].kind !== SyntaxKind.SemicolonToken + && tokens[cursor].kind !== SyntaxKind.ImportKeyword) cursor += 1; + const specifier = tokens[cursor + 1]; + if (cursor >= tokens.length || tokens[cursor].kind !== SyntaxKind.FromKeyword) continue; + if (specifier === undefined || specifier.kind !== SyntaxKind.StringLiteral) continue; + const clauseIsTypeOnly = next.kind === SyntaxKind.TypeKeyword; + const names: ImportedName[] = []; + let namespace: string | undefined; + for (let k = i + 1; k < cursor; k += 1) { + if (tokens[k].kind === SyntaxKind.AsteriskToken && tokens[k + 1] !== undefined + && tokens[k + 1].kind === SyntaxKind.AsKeyword && tokens[k + 2] !== undefined) { + namespace = tokens[k + 2].text; + k += 2; + continue; + } + if (tokens[k].kind !== SyntaxKind.OpenBraceToken) continue; + let entry = k + 1; + while (entry < cursor && tokens[entry].kind !== SyntaxKind.CloseBraceToken) { + let entryIsTypeOnly = false; + const after = tokens[entry + 1]; + if (tokens[entry].kind === SyntaxKind.TypeKeyword && after !== undefined + && after.kind !== SyntaxKind.CommaToken && after.kind !== SyntaxKind.CloseBraceToken + && after.kind !== SyntaxKind.AsKeyword) { + entryIsTypeOnly = true; + entry += 1; + } + const imported = tokens[entry]; + if (imported === undefined) break; + let local = imported; + if (tokens[entry + 1] !== undefined && tokens[entry + 1].kind === SyntaxKind.AsKeyword + && tokens[entry + 2] !== undefined) { + local = tokens[entry + 2]; + entry += 2; + } + names.push({ imported: imported.text, local: local.text, typeOnly: entryIsTypeOnly || clauseIsTypeOnly }); + entry += 1; + if (tokens[entry] !== undefined && tokens[entry].kind === SyntaxKind.CommaToken) entry += 1; + } + k = entry; + } + clauses.push({ specifier: specifier.value, names, namespace, from: i, to: cursor + 1, start: tokens[i].start }); + i = cursor + 1; + } + return clauses; +} + +function importedLocals( + clauses: readonly ImportClause[], + specifier: string, + imported: string, +): Set { + const locals = new Set(); + for (const clause of clauses) { + if (clause.specifier !== specifier) continue; + for (const name of clause.names) if (name.imported === imported && !name.typeOnly) locals.add(name.local); + } + return locals; +} + +function importedTokenRanges(clauses: readonly ImportClause[]): { from: number; to: number }[] { + return clauses.map(clause => ({ from: clause.from, to: clause.to })); +} + +/** The module a binding has to come from. A same-named export of another file is not this one. */ +function warmupHelperModule(): string { + return withoutTsExtension(helperPath("cold-spawn-warmup.ts")); +} + +function withoutTsExtension(path: string): string { + return path.endsWith(".ts") ? path.slice(0, -3) : path; +} + +function importsTheWarmupHelper(fileName: string, specifier: string): boolean { + if (!specifier.startsWith(".") && !isAbsolute(specifier)) return false; + const resolved = isAbsolute(specifier) ? specifier : resolve(dirname(fileName), specifier); + return withoutTsExtension(resolved) === warmupHelperModule(); +} + +/** + * Where a name is bound to something other than its import: a declaration, an assignment, or a + * parameter. A shadowed beforeAll takes a correct callback and runs nothing, so the hook name has + * to be as provably the import as the warm-up name is. + */ +function rebindingOf(tokens: readonly Token[], name: string): Token | undefined { + for (let i = 0; i < tokens.length; i += 1) { + const token = tokens[i]; + if (token.kind !== SyntaxKind.Identifier || token.text !== name) continue; + if (isMemberName(tokens, i)) continue; + const before = tokens[i - 1]; + const after = tokens[i + 1]; + if (before !== undefined && DECLARATION_KEYWORDS.has(before.kind)) return token; + if (after === undefined) continue; + if (after.kind === SyntaxKind.EqualsToken) return token; + if (after.kind === SyntaxKind.EqualsGreaterThanToken) return token; + if (before !== undefined && before.kind === SyntaxKind.OpenParenToken + && after.kind === SyntaxKind.CloseParenToken && tokens[i + 2] !== undefined + && tokens[i + 2].kind === SyntaxKind.EqualsGreaterThanToken) return token; + } + return undefined; +} + +/** + * The call an open paren belongs to. Only a BARE identifier counts as the callee: describe.skip + * and describe.each reach a suite this judge cannot claim runs, and reading them as describe is + * how a hook inside a skipped suite would be recorded as a registration. + */ +function callFrame(tokens: readonly Token[], open: number): CallFrame { + const name = tokens[open - 1]; + if (name === undefined || name.kind !== SyntaxKind.Identifier || isMemberName(tokens, open - 1)) { + return { callee: "", open, statement: false }; + } + const before = tokens[open - 2]; + return { callee: name.text, open, statement: before === undefined || STATEMENT_START.has(before.kind) }; +} + +/** + * Whether an arrow is written directly as an argument of the call it sits in. A describe body and + * a hook body are arguments; a helper assigned to a name is not, and that difference is the whole + * distance between a hook that registers and one that never runs. + */ +function arrowIsArgument(tokens: readonly Token[], arrow: number, matches: readonly number[]): boolean { + let k = arrow - 1; + if (tokens[k] === undefined) return false; + if (tokens[k].kind === SyntaxKind.CloseParenToken) { + const open = matches[k]; + if (open < 0) return false; + k = open - 1; + } else if (tokens[k].kind === SyntaxKind.Identifier) { + k -= 1; + } else { + return false; + } + if (tokens[k] !== undefined && tokens[k].kind === SyntaxKind.AsyncKeyword) k -= 1; + const before = tokens[k]; + return before !== undefined + && (before.kind === SyntaxKind.OpenParenToken || before.kind === SyntaxKind.CommaToken); +} + +/** Whether a block brace opens a callback written directly as an argument, arrow or function. */ +function opensArgumentCallback(tokens: readonly Token[], brace: number, matches: readonly number[]): boolean { + const pre = tokens[brace - 1]; + if (pre === undefined) return false; + if (pre.kind === SyntaxKind.EqualsGreaterThanToken) return arrowIsArgument(tokens, brace - 1, matches); + if (pre.kind !== SyntaxKind.CloseParenToken) return false; + const open = matches[brace - 1]; + if (open < 0) return false; + let k = open - 1; + if (tokens[k] !== undefined && tokens[k].kind === SyntaxKind.Identifier) k -= 1; + if (tokens[k] === undefined || tokens[k].kind !== SyntaxKind.FunctionKeyword) return false; + k -= 1; + if (tokens[k] !== undefined && tokens[k].kind === SyntaxKind.AsyncKeyword) k -= 1; + const before = tokens[k]; + return before !== undefined + && (before.kind === SyntaxKind.OpenParenToken || before.kind === SyntaxKind.CommaToken); +} diff --git a/tests/helpers/warmup-tokens.ts b/tests/helpers/warmup-tokens.ts new file mode 100644 index 00000000000..473eadeac1a --- /dev/null +++ b/tests/helpers/warmup-tokens.ts @@ -0,0 +1,171 @@ +import { createScanner, LanguageVariant, SyntaxKind } from "typescript/unstable/ast"; + +/** + * A balanced token stream for one TypeScript file, and the positional helpers a structural check + * needs on top of it. + * + * ## Why tokens and not a parsed tree + * + * TypeScript here is 7.0.2, the native port, and it publishes no in-process parser. The + * "typescript/unstable/ast" entry point is a node factory, type guards, a visitor, navigation and + * this scanner: the createSourceFile it exports is the FACTORY, whose first parameter is an array + * of already-parsed statements. Parsed trees come from Program.getSourceFile on the + * "typescript/unstable/sync" client, which spawns the Go tsgo executable and loads a whole project + * over JSON-RPC. Reading one test file that way would start a compiler process on every shard of + * every platform. + * + * So the judge built on this module recognises an exact, small set of shapes and refuses everything + * else, rather than reconstructing the grammar by hand. Tokens are enough for that, and being + * wrong about a shape costs a refusal rather than a false pass. + * + * ## What the driver has to get right + * + * Two rescans, without which the stream does not balance. A template substitution closes on an + * ordinary brace, so every template in the file would otherwise leak one unmatched brace: the brace + * depth each substitution opened at is remembered, and the closing token is rescanned as the + * template middle or tail it is. A slash either opens a regular expression or divides, decided by + * the token before it, and a wrong guess swallows whichever delimiters sit between it and the next + * slash; an unterminated rescan is rewound and the slash stays a division. + * + * Whatever is left has to balance. A file that does not is reported unreadable, and unreadable is a + * failure rather than an absence of evidence. + */ + +export type Token = Readonly<{ + kind: SyntaxKind; + /** Source text of the token, which for an identifier is its name. */ + text: string; + /** Cooked value, filled for string literals so a module specifier can be read without its quotes. */ + value: string; + /** Offset of the token in the source, for line numbers in diagnostics. */ + start: number; +}>; + +/** + * A slash opens a regular expression unless the token before it ends a value. The one genuinely + * ambiguous case, a closing brace, is read as the end of a statement: a regular expression after a + * block is real code, and dividing by an object literal is not. + */ +const REGEX_CANNOT_FOLLOW: ReadonlySet = new Set([ + SyntaxKind.Identifier, + SyntaxKind.PrivateIdentifier, + SyntaxKind.NumericLiteral, + SyntaxKind.BigIntLiteral, + SyntaxKind.StringLiteral, + SyntaxKind.NoSubstitutionTemplateLiteral, + SyntaxKind.TemplateTail, + SyntaxKind.RegularExpressionLiteral, + SyntaxKind.CloseParenToken, + SyntaxKind.CloseBracketToken, + SyntaxKind.PlusPlusToken, + SyntaxKind.MinusMinusToken, + SyntaxKind.ThisKeyword, + SyntaxKind.SuperKeyword, + SyntaxKind.TrueKeyword, + SyntaxKind.FalseKeyword, + SyntaxKind.NullKeyword, +]); + +export const OPENERS: ReadonlyMap = new Map([ + [SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken], + [SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken], + [SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken], +]); + +export const CLOSERS: ReadonlySet = new Set([ + SyntaxKind.CloseBraceToken, + SyntaxKind.CloseParenToken, + SyntaxKind.CloseBracketToken, +]); + +/** The file as a balanced token stream, or the reason it could not be read as one. */ +export function tokenize(source: string): { tokens: Token[]; unreadable: string[] } { + const scanner = createScanner(true, LanguageVariant.Standard, source); + const tokens: Token[] = []; + const unreadable: string[] = []; + const templates: number[] = []; + let braces = 0; + let parens = 0; + let brackets = 0; + for (;;) { + let kind = scanner.scan(); + if (kind === SyntaxKind.EndOfFile) break; + let start = scanner.getTokenStart(); + let text = scanner.getTokenText(); + if (kind === SyntaxKind.SlashToken || kind === SyntaxKind.SlashEqualsToken) { + const afterSlash = scanner.getTokenEnd(); + const previous = tokens[tokens.length - 1]; + if (previous === undefined || !REGEX_CANNOT_FOLLOW.has(previous.kind)) { + const rescanned = scanner.reScanSlashToken(); + if (rescanned === SyntaxKind.RegularExpressionLiteral && !scanner.isUnterminated()) { + kind = rescanned; + start = scanner.getTokenStart(); + text = scanner.getTokenText(); + } else { + scanner.resetTokenState(afterSlash); + } + } + } + if (kind === SyntaxKind.CloseBraceToken && templates[templates.length - 1] === braces) { + templates.pop(); + kind = scanner.reScanTemplateToken(false); + start = scanner.getTokenStart(); + text = scanner.getTokenText(); + } + const value = kind === SyntaxKind.StringLiteral ? scanner.getTokenValue() : ""; + if (scanner.isUnterminated()) { + unreadable.push(at(source, start) + "an unterminated literal, so this judge is reading the file wrong"); + return { tokens, unreadable }; + } + if (kind === SyntaxKind.TemplateHead || kind === SyntaxKind.TemplateMiddle) templates.push(braces); + else if (kind === SyntaxKind.OpenBraceToken) braces += 1; + else if (kind === SyntaxKind.CloseBraceToken) braces -= 1; + else if (kind === SyntaxKind.OpenParenToken) parens += 1; + else if (kind === SyntaxKind.CloseParenToken) parens -= 1; + else if (kind === SyntaxKind.OpenBracketToken) brackets += 1; + else if (kind === SyntaxKind.CloseBracketToken) brackets -= 1; + if (braces < 0 || parens < 0 || brackets < 0) { + unreadable.push(at(source, start) + "a closing delimiter with nothing open, so this judge is reading the file wrong"); + return { tokens, unreadable }; + } + tokens.push({ kind, text, value: value ?? "", start }); + } + if (braces !== 0 || parens !== 0 || brackets !== 0 || templates.length > 0) { + unreadable.push("the file does not close every delimiter this judge opened (braces " + braces + + ", parens " + parens + ", brackets " + brackets + ", open template substitutions " + + templates.length + ")"); + } + return { tokens, unreadable }; +} + +/** + * Where the expression beginning at start ends: its comma, the closing delimiter around it, or its + * semicolon. The semicolon matters for a concise arrow body written outside a call, which would + * otherwise read as running to the end of the file and swallow every scope after it. + */ +export function argumentEnd(tokens: readonly Token[], start: number): number { + let depth = 0; + for (let i = start; i < tokens.length; i += 1) { + const kind = tokens[i].kind; + if (OPENERS.has(kind)) depth += 1; + else if (CLOSERS.has(kind)) { + if (depth === 0) return i; + depth -= 1; + } else if (depth === 0 + && (kind === SyntaxKind.CommaToken || kind === SyntaxKind.SemicolonToken)) return i; + } + return tokens.length; +} + +/** 1-based line of an offset. */ +export function lineOf(source: string, offset: number): number { + let line = 1; + const bound = Math.min(offset, source.length); + for (let i = 0; i < bound; i += 1) if (source.charCodeAt(i) === 10) line += 1; + return line; +} + +/** "line N: ", the prefix every diagnostic carries so a failure points at a place. */ +export function at(source: string, offset: number): string { + return "line " + lineOf(source, offset) + ": "; +} From 0429c0a81de3d715d12adee7cec61e241035b8d6 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 13:41:58 +0900 Subject: [PATCH 08/97] test(ci): give the Windows nested live-lock case its own lock owner (#5078) * test(ci): give the Windows nested live-lock case its own lock owner The nested live-lock regression registered only when OCX_TEST_NO_QUEUE was not 1, and the hosted Windows batch leg sets exactly that, so the case was skipped on the only platform it applies to. A controller child now owns the lock instead of borrowing the lane's: it runs with the opt-out removed for itself alone, resolves the user-scoped path through the ordinary safe path, acquires it for its own run id, and spawns the nested Bun children that must inherit it. The outer environment, the real home, and any pre-existing owner are left untouched. Closes #4991 * test(ci): bound the nested live-lock controller and harden its receipt Adversarial review of the first commit found three real weaknesses. The controller could spend more than the caller's 45s hard kill across four child spawns, so a failure path could terminate it inside a spawn with the lock still held and its teardown never reached. It is now handed an absolute deadline 10s short of that kill and bounds every child by what is left of it, minus a cleanup reserve. A join failure inside registerMember can carry a member filename, and that path runs before the controller learns its own token, so a redactor keyed on that token was blind exactly where a leak was possible. Diagnostics now strip every UUID-shaped substring, and receiptRedacted scans for one instead of being vacuously true on the green path. Two other receipts were weak: the acquire-timeout probe accepted the message without waiting, and release checked only that our own owner file was gone. They now require the elapsed floor and the planted foreign owner intact after release. childrenReaped requires the full spawn count so a skipped scenario cannot pass. lockOwned is renamed lockHeld because the controller joins an existing owner when a wrapped run already published one. * test(ci): keep the nested case's child deadline where the guard can see it Moving the per-child timeout into the controller removed this file's only spawn-options INTERNAL_DEADLINE_MS, so the cold-spawn warm-up guard stopped matching it and its disposition became an orphan. That failed test 3/4 on Linux and windows 7/9. The deadline that bounds four cold Bun starts belongs to the case that owns them, not to the helper, so the test now declares the child spawn options and hands them over; the controller only narrows them to what its own deadline still allows. The guard's inventory and its scan agree again, and the helper no longer re-derives a budget constant. --- tests/ci-workflows/test-runner.test.ts | 116 +++--- .../nested-test-run-lock-controller.ts | 342 ++++++++++++++++++ 2 files changed, 413 insertions(+), 45 deletions(-) create mode 100644 tests/helpers/nested-test-run-lock-controller.ts diff --git a/tests/ci-workflows/test-runner.test.ts b/tests/ci-workflows/test-runner.test.ts index a40a989ffe6..9ac74058420 100644 --- a/tests/ci-workflows/test-runner.test.ts +++ b/tests/ci-workflows/test-runner.test.ts @@ -26,7 +26,10 @@ import { selectChangedComparisonRef, SERIAL_FULL_SUITE_FILES, } from "../../scripts/test"; -import { repoPath, repoRoot } from "../helpers/repo-root"; +import { + NESTED_LIVE_LOCK_RECEIPT_KEY, +} from "../helpers/nested-test-run-lock-controller"; +import { helperPath, repoPath, repoRoot } from "../helpers/repo-root"; import { acquireTestRunLock, resolveBareTestRunIdentity, @@ -1059,53 +1062,76 @@ describe("bun test user lock", () => { expect(resolveCalls).toBe(0); }); - test.if(process.platform === "win32" && process.env[TEST_RUN_NO_QUEUE_ENV] !== "1")( - "nested Windows Bun tests inherit the acquired live lock and refuse an incomplete capability", + // Windows-only, and deliberately no longer gated on the no-queue opt-out. The hosted + // batch leg sets OCX_TEST_NO_QUEUE=1 for its own six-file processes, which skipped this + // case on the only platform it covers (#4991). The controller below holds a lock in its + // own right rather than borrowing the lane's, so the regression now runs either way. + // + // Two deadlines, not one. The controller is told to finish 10s before the hard kill so + // it always reaches its own teardown — releasing the lock and confirming its children + // were reaped — instead of being terminated inside a spawn with the lock still held. + // The spawnSync timeout stays the backstop for a controller that ignores its deadline. + // + // The nominal per-child timeout is declared here rather than inside the helper, so the + // deadline that bounds four cold Bun starts stays with the case that owns them and + // tests/ci-workflows/cold-spawn-warmup.test.ts keeps seeing this file. The controller + // narrows it to whatever its own deadline still allows. + test.if(process.platform === "win32")( + "a nested Windows Bun test inherits the live lock its controller holds and refuses an incomplete capability", () => { - const root = mkdtempSync(join(tmpdir(), "opencodex-nested-test-")); + const root = mkdtempSync(join(tmpdir(), "opencodex-nested-lock-")); + const controllerBudgetMs = SPAWN_BUDGET_MS - 10_000; + const childSpawn = { timeout: INTERNAL_DEADLINE_MS }; + const environmentBefore = JSON.stringify({ + noQueue: process.env[TEST_RUN_NO_QUEUE_ENV], + runId: process.env[TEST_RUN_ID_ENV], + lockPath: process.env[TEST_RUN_LOCK_PATH_ENV], + // Presence only. The token is never rendered, here or by the controller. + hasToken: process.env[TEST_RUN_LOCK_TOKEN_ENV] !== undefined, + }); try { - const lockPath = process.env[TEST_RUN_LOCK_PATH_ENV]; - expect(Boolean(lockPath && process.env[TEST_RUN_LOCK_TOKEN_ENV] && process.env[TEST_RUN_ID_ENV])).toBe(true); - const ownerBefore = readFileSync(join(lockPath!, "owner.json"), "utf8"); - const fixture = join(root, "nested.test.ts"); - writeFileSync(fixture, ` - import { test } from "bun:test"; - import { readFileSync, existsSync } from "node:fs"; - import { join } from "node:path"; - test("nested lock receipt", () => { - const path = process.env.OCX_TEST_RUN_LOCK_PATH; - const owner = JSON.parse(readFileSync(join(path, "owner.json"), "utf8")); - console.log(JSON.stringify({ nestedLockReceipt: { - samePath: path === ${JSON.stringify(lockPath)}, - sameRun: owner.runId === ${JSON.stringify(process.env[TEST_RUN_ID_ENV])}, - sameToken: owner.token === process.env.OCX_TEST_RUN_LOCK_TOKEN, - member: existsSync(join(path, "members", process.pid + "-" + owner.token)), - preloadRan: process.env.OCX_TEST_PRELOAD_PID === String(process.pid), - guardArmed: process.env.OCX_TEST_HOME_GUARD === "1", - } })); - }); - `); - const args = ["test", "--preload", repoPath("tests/preload.ts"), fixture]; - const child = spawnSync(process.execPath, args, { - cwd: root, env: { ...process.env }, encoding: "utf8", timeout: INTERNAL_DEADLINE_MS, - }); - // Keep process diagnostics bounded and never render the owner token or child output. - expect(child.status).toBe(0); - const marker = child.stdout.split("\n").find(line => line.startsWith('{"nestedLockReceipt":')); - expect(marker ? JSON.parse(marker).nestedLockReceipt : null).toEqual({ - samePath: true, sameRun: true, sameToken: true, member: true, preloadRan: true, guardArmed: true, - }); - expect(readFileSync(join(lockPath!, "owner.json"), "utf8") === ownerBefore).toBe(true); - - const incomplete = { ...process.env }; - delete incomplete[TEST_RUN_LOCK_TOKEN_ENV]; - const refused = spawnSync(process.execPath, args, { - cwd: root, env: incomplete, encoding: "utf8", timeout: INTERNAL_DEADLINE_MS, + // Only the controller's copy loses the opt-out, and its cwd stays outside the + // repository so Bun loads no bunfig preload into the lock holder itself. + const controllerEnv = { ...process.env }; + delete controllerEnv[TEST_RUN_NO_QUEUE_ENV]; + const controller = spawnSync( + process.execPath, + [ + helperPath("nested-test-run-lock-controller.ts"), + root, + String(Date.now() + controllerBudgetMs), + JSON.stringify(childSpawn), + ], + { cwd: root, env: controllerEnv, encoding: "utf8", timeout: SPAWN_BUDGET_MS }, + ); + const prefix = '{"' + NESTED_LIVE_LOCK_RECEIPT_KEY + '":'; + const line = (controller.stdout ?? "").split("\n").find(entry => entry.startsWith(prefix)); + const payload = line + ? JSON.parse(line) as { nestedLiveLockReceipt: Record; diagnostics: string[] } + : null; + // Booleans and redacted controller notes only; raw child output never surfaces here. + expect(payload?.diagnostics ?? ["the controller printed no receipt"]).toEqual([]); + expect(payload?.nestedLiveLockReceipt).toEqual({ + lockHeld: true, + healthyChildExited: true, + healthyReceiptComplete: true, + missingTokenRefused: true, + wrongTokenRefused: true, + wrongPathRefused: true, + foreignOwnerTimedOut: true, + foreignOwnerUntouched: true, + ownerContentUnchanged: true, + childrenReaped: true, + releasedOnlyOwnLock: true, + receiptRedacted: true, }); - expect(refused.status).toBe(1); - expect(refused.stderr.includes("capability is incomplete")).toBe(true); - expect(refused.stdout.includes('{"nestedLockReceipt":')).toBe(false); - expect(readFileSync(join(lockPath!, "owner.json"), "utf8") === ownerBefore).toBe(true); + expect(controller.status).toBe(0); + expect(JSON.stringify({ + noQueue: process.env[TEST_RUN_NO_QUEUE_ENV], + runId: process.env[TEST_RUN_ID_ENV], + lockPath: process.env[TEST_RUN_LOCK_PATH_ENV], + hasToken: process.env[TEST_RUN_LOCK_TOKEN_ENV] !== undefined, + })).toBe(environmentBefore); } finally { removeTreeWithRetry(root); } diff --git a/tests/helpers/nested-test-run-lock-controller.ts b/tests/helpers/nested-test-run-lock-controller.ts new file mode 100644 index 00000000000..964d8e951d5 --- /dev/null +++ b/tests/helpers/nested-test-run-lock-controller.ts @@ -0,0 +1,342 @@ +/** + * Lock owner for the Windows nested live-lock regression (issue #4991). + * + * The regression in tests/ci-workflows/test-runner.test.ts proves that a nested Bun test + * inherits the live test-run lock exactly and refuses an incomplete capability. It used + * to read that capability out of its own environment, so it could only run while the + * outer process already held a lock — and the hosted Windows batch leg sets + * OCX_TEST_NO_QUEUE=1 precisely so that it does not. The case was therefore skipped on + * the only platform it applies to, and the coverage existed on paper only. + * + * This controller supplies the missing holder instead of borrowing the lane's. It runs as + * a plain "bun " child with exactly one environment change — the no-queue opt-out + * removed for this process and its descendants — resolves the user-scoped lock through + * the ordinary safe path, and acquires it for its own run id. When a wrapped or bare + * Windows run has already published a complete capability it joins that owner instead, + * because a second owner for one path is the clobber this suite exists to prevent. + * Nothing here writes an owner file by hand: a fabricated capability would only prove + * that a child trusts what it is told, which is the inverse of the contract under test. + * + * Three things about how it is launched are load-bearing. It must be spawned with a cwd + * OUTSIDE the repository so Bun loads no bunfig preload into the holder itself; a + * preloaded controller would take the same lock in tests/preload.ts and then wait on + * itself. It must be handed a temporary root it may write into, because every fixture it + * generates and the foreign-owner probe it plants live there. And it must be handed both + * a deadline and the caller's spawn options: the nominal per-child timeout belongs to the + * case that owns these children, and the controller only narrows it to what is left of + * the deadline minus a cleanup reserve, so the controller always reaches its own teardown + * rather than being killed inside a spawn with the lock still held. + * + * Everything below runs only as an entry point. The test file imports the receipt key + * from here, and an import must not acquire a lock or spawn anything. + * + * Output is one JSON line of booleans plus diagnostics with every UUID-shaped substring + * removed. Child output is parsed, never echoed. + */ +import { randomUUID } from "node:crypto"; +import { spawnSync, type SpawnSyncReturns } from "node:child_process"; +import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"; +import { join, win32 } from "node:path"; +import { + acquireTestRunLock, + resolveWrappedTestRunLockPath, + TEST_RUN_ID_ENV, + TEST_RUN_LOCK_PATH_ENV, + TEST_RUN_LOCK_TOKEN_ENV, + TEST_RUN_NO_QUEUE_ENV, + type TestRunLock, +} from "../../scripts/test-run-lock"; +import { repoPath } from "./repo-root"; + +/** Shape the caller asserts on; every field must be true for the case to pass. */ +export interface NestedLiveLockReceipt { + lockHeld: boolean; + healthyChildExited: boolean; + healthyReceiptComplete: boolean; + missingTokenRefused: boolean; + wrongTokenRefused: boolean; + wrongPathRefused: boolean; + foreignOwnerTimedOut: boolean; + foreignOwnerUntouched: boolean; + ownerContentUnchanged: boolean; + childrenReaped: boolean; + releasedOnlyOwnLock: boolean; + receiptRedacted: boolean; +} + +export const NESTED_LIVE_LOCK_RECEIPT_KEY = "nestedLiveLockReceipt"; +const CHILD_MARKER = '{"nestedLockReceipt":'; +const CHILD_RECEIPT_KEYS = ["samePath", "sameRun", "sameToken", "member", "preloadRan", "guardArmed"] as const; +/** Healthy, missing token, foreign token, foreign path. A short count means one was skipped. */ +const EXPECTED_CHILD_SPAWNS = 4; +const ACQUIRE_POLL_MS = 250; +const ACQUIRE_MAX_WAIT_MS = 10_000; +const FOREIGN_POLL_MS = 100; +const FOREIGN_MAX_WAIT_MS = 300; +/** Time kept back from every child so teardown runs before the caller's hard kill. */ +const CLEANUP_RESERVE_MS = 4_000; +const MINIMUM_CHILD_ALLOWANCE_MS = 1_000; +/** + * Any UUID, not merely the token this process knows about. Several errors in + * scripts/test-run-lock.ts can carry a member filename, and one of them is reachable + * before acquire returns, so a redactor keyed on our own token would be blind exactly + * where a leak is possible. Built fresh per call because a global regex carries + * lastIndex between a replace and a test. + */ +const uuidPattern = (): RegExp => /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi; + +interface ChildSpawnOptions { + timeout: number; +} + +async function runNestedLiveLockController( + tempRoot: string | undefined, + deadlineAt: number, + childSpawn: ChildSpawnOptions | undefined, +): Promise { + const receipt: NestedLiveLockReceipt = { + lockHeld: false, + healthyChildExited: false, + healthyReceiptComplete: false, + missingTokenRefused: false, + wrongTokenRefused: false, + wrongPathRefused: false, + foreignOwnerTimedOut: false, + foreignOwnerUntouched: false, + ownerContentUnchanged: false, + childrenReaped: false, + releasedOnlyOwnLock: false, + receiptRedacted: false, + }; + const diagnostics: string[] = []; + const note = (message: string): void => { diagnostics.push(message); }; + const describeError = (error: unknown): string => (error instanceof Error ? error.message : String(error)); + const budgetLeftMs = (): number => deadlineAt - Date.now() - CLEANUP_RESERVE_MS; + let lock: TestRunLock | undefined; + let ownerFile: string | undefined; + let ownerBefore: string | undefined; + let ownerToken: string | undefined; + let foreignOwnerFile: string | undefined; + let foreignOwner: string | undefined; + // Whether each spawned child was waited on, which is what reaping means for spawnSync. + const settledChildren: boolean[] = []; + + try { + if (process.platform !== "win32") throw new Error("the nested live-lock controller is Windows-only"); + if (!tempRoot) throw new Error("the nested live-lock controller needs a temporary root argument"); + if (!Number.isFinite(deadlineAt)) throw new Error("the nested live-lock controller needs a deadline argument"); + if (!childSpawn || !Number.isFinite(childSpawn.timeout) || childSpawn.timeout <= 0) { + throw new Error("the nested live-lock controller needs the caller's child spawn options"); + } + if (process.env[TEST_RUN_NO_QUEUE_ENV] !== undefined) { + throw new Error("the controller environment must have the no-queue opt-out removed"); + } + + // A wrapped or bare Windows run already holds this lock and handed us its complete + // capability, so join it. The hosted no-queue lane has no such holder, and there we + // resolve and acquire one of our own. + const inheritedPath = process.env[TEST_RUN_LOCK_PATH_ENV]?.trim(); + const inheritedToken = process.env[TEST_RUN_LOCK_TOKEN_ENV]?.trim(); + const inheritedRunId = process.env[TEST_RUN_ID_ENV]?.trim(); + const joining = Boolean(inheritedPath && inheritedToken && inheritedRunId); + // Known before the join can fail, so a failure inside registerMember cannot reach the + // diagnostics with a live token the redactor has not been told about. + if (joining) ownerToken = inheritedToken; + const resolved = joining ? inheritedPath : resolveWrappedTestRunLockPath({ env: process.env }); + if (!resolved) throw new Error("the user-scoped Bun test lock path did not resolve"); + const lockPath = resolved; + const runId = joining && inheritedRunId ? inheritedRunId : "nested-live-lock-" + randomUUID(); + + lock = await acquireTestRunLock({ + runId, + lockPath, + validatedRuntimePath: true, + env: process.env, + joinExistingOwnerToken: joining ? inheritedToken : undefined, + pollMs: ACQUIRE_POLL_MS, + maxWaitMs: Math.max(ACQUIRE_POLL_MS, Math.min(ACQUIRE_MAX_WAIT_MS, budgetLeftMs())), + }); + const owner = lock.owner; + if (!owner) throw new Error("the run lock produced no owner record"); + ownerToken = owner.token; + receipt.lockHeld = true; + + // Publish the capability into our own environment so the children below inherit it the + // way any descendant of a real run does, rather than being handed a constructed one. + process.env[TEST_RUN_ID_ENV] = runId; + process.env[TEST_RUN_LOCK_PATH_ENV] = lockPath; + process.env[TEST_RUN_LOCK_TOKEN_ENV] = owner.token; + + const activeOwnerFile = join(lockPath, "owner.json"); + const activeOwnerBefore = readFileSync(activeOwnerFile, "utf8"); + ownerFile = activeOwnerFile; + ownerBefore = activeOwnerBefore; + receipt.ownerContentUnchanged = true; + const confirmOwnerUnchanged = (): void => { + const current = existsSync(activeOwnerFile) ? readFileSync(activeOwnerFile, "utf8") : null; + if (current === activeOwnerBefore) return; + receipt.ownerContentUnchanged = false; + note("the owner receipt changed while a nested child ran"); + }; + + const fixture = join(tempRoot, "nested-live-lock.test.ts"); + writeFileSync(fixture, [ + 'import { test } from "bun:test";', + 'import { existsSync, readFileSync } from "node:fs";', + 'import { join } from "node:path";', + 'test("nested lock receipt", () => {', + ' const path = process.env.OCX_TEST_RUN_LOCK_PATH ?? "";', + ' const owner = JSON.parse(readFileSync(join(path, "owner.json"), "utf8"));', + " console.log(JSON.stringify({ nestedLockReceipt: {", + " samePath: path === " + JSON.stringify(lockPath) + ",", + " sameRun: owner.runId === " + JSON.stringify(runId) + + " && process.env.OCX_TEST_RUN_ID === " + JSON.stringify(runId) + ",", + " sameToken: owner.token === process.env.OCX_TEST_RUN_LOCK_TOKEN,", + ' member: existsSync(join(path, "members", process.pid + "-" + owner.token)),', + " preloadRan: process.env.OCX_TEST_PRELOAD_PID === String(process.pid),", + ' guardArmed: process.env.OCX_TEST_HOME_GUARD === "1",', + " } }));", + "});", + "", + ].join("\n")); + + const args = ["test", "--preload", repoPath("tests", "preload.ts"), fixture]; + const runChild = (label: string, mutate?: (env: NodeJS.ProcessEnv) => void): SpawnSyncReturns => { + const allowance = Math.min(childSpawn.timeout, budgetLeftMs()); + if (allowance < MINIMUM_CHILD_ALLOWANCE_MS) { + throw new Error("the controller ran out of budget before spawning " + label); + } + const env = { ...process.env }; + // Drop the two receipts the child is supposed to produce for itself. Inherited, they + // would report a preload that never ran and a guard nobody armed. + delete env.OCX_TEST_PRELOAD_PID; + delete env.OCX_TEST_HOME_GUARD; + mutate?.(env); + const result = spawnSync(process.execPath, args, { + cwd: tempRoot, env, encoding: "utf8", timeout: Math.floor(allowance), + }); + // spawnSync returns only after the child has been waited on, so a settled status or + // signal IS the reap. A liveness probe on the pid would be a race against pid reuse. + settledChildren.push(result.status !== null || result.signal !== null); + return result; + }; + const refusal = (result: SpawnSyncReturns, needle: string, label: string): boolean => { + const refused = result.status !== 0 + && (result.stderr ?? "").includes(needle) + && !(result.stdout ?? "").includes(CHILD_MARKER); + if (!refused) note(label + " was not refused (status " + String(result.status) + ")"); + return refused; + }; + + const healthy = runChild("the healthy child"); + receipt.healthyChildExited = healthy.status === 0; + if (!receipt.healthyChildExited) { + note("the healthy child exited with status " + String(healthy.status) + " signal " + String(healthy.signal)); + } + const marker = (healthy.stdout ?? "").split("\n").find(line => line.startsWith(CHILD_MARKER)); + const nested = marker + ? (JSON.parse(marker) as { nestedLockReceipt?: Record }).nestedLockReceipt + : undefined; + receipt.healthyReceiptComplete = nested !== undefined + && CHILD_RECEIPT_KEYS.every(key => nested[key] === true); + if (!receipt.healthyReceiptComplete) note("nested receipt: " + JSON.stringify(nested ?? null)); + confirmOwnerUnchanged(); + + receipt.missingTokenRefused = refusal( + runChild("the tokenless child", env => { delete env[TEST_RUN_LOCK_TOKEN_ENV]; }), + "capability is incomplete", + "a child holding no token", + ); + confirmOwnerUnchanged(); + + receipt.wrongTokenRefused = refusal( + runChild("the foreign-token child", env => { env[TEST_RUN_LOCK_TOKEN_ENV] = randomUUID(); }), + "exact live owner no longer matches", + "a child holding a foreign token", + ); + confirmOwnerUnchanged(); + + receipt.wrongPathRefused = refusal( + runChild("the foreign-path child", env => { + env[TEST_RUN_LOCK_PATH_ENV] = win32.join(win32.dirname(lockPath), "opencodex-bun-test-not-this-host.lock"); + }), + "refusing inherited lock access", + "a child holding a foreign lock path", + ); + confirmOwnerUnchanged(); + + // The acquire path must wait out a live owner it does not own and then give up rather + // than reclaim it. Planted under the temporary root so the probe can never reach the + // real lock, and owned by this very pid so its liveness is a fact, not a fixture. + const foreignLock = join(tempRoot, "foreign-owner.lock"); + mkdirSync(foreignLock, { recursive: true, mode: 0o700 }); + const plantedFile = join(foreignLock, "owner.json"); + const planted = JSON.stringify({ + version: 1, + runId: "foreign-" + randomUUID(), + token: randomUUID(), + pid: process.pid, + acquiredAt: new Date().toISOString(), + }) + "\n"; + writeFileSync(plantedFile, planted, { encoding: "utf8", mode: 0o600 }); + foreignOwnerFile = plantedFile; + foreignOwner = planted; + const probeStartedAt = Date.now(); + try { + await acquireTestRunLock({ + runId: "timeout-probe-" + randomUUID(), + lockPath: foreignLock, + env: process.env, + pollMs: FOREIGN_POLL_MS, + maxWaitMs: FOREIGN_MAX_WAIT_MS, + }); + note("the controller took a lock a live foreign owner still held"); + } catch (error) { + // The elapsed floor is the point: an immediate refusal would satisfy the message + // alone while proving nothing about waiting for the holder. + receipt.foreignOwnerTimedOut = describeError(error).includes("timed out after") + && Date.now() - probeStartedAt >= FOREIGN_MAX_WAIT_MS; + if (!receipt.foreignOwnerTimedOut) note("unexpected foreign-owner failure: " + describeError(error)); + } + receipt.foreignOwnerUntouched = existsSync(plantedFile) + && readFileSync(plantedFile, "utf8") === planted; + confirmOwnerUnchanged(); + } catch (error) { + note("controller failure: " + describeError(error)); + } finally { + receipt.childrenReaped = settledChildren.length === EXPECTED_CHILD_SPAWNS + && settledChildren.every(Boolean); + try { + // Releasing must remove our own lock and nothing else, so the planted foreign owner + // is re-read afterwards rather than only before. + const foreignIntact = foreignOwnerFile === undefined + || (existsSync(foreignOwnerFile) && readFileSync(foreignOwnerFile, "utf8") === foreignOwner); + if (lock?.acquired) { + lock.release(); + receipt.releasedOnlyOwnLock = ownerFile !== undefined && !existsSync(ownerFile) && foreignIntact; + } else if (lock && ownerFile !== undefined && ownerBefore !== undefined) { + // Joined rather than acquired: leaving the other holder exactly as found IS the claim. + receipt.releasedOnlyOwnLock = existsSync(ownerFile) + && readFileSync(ownerFile, "utf8") === ownerBefore + && foreignIntact; + } + } catch (error) { + note("release failure: " + describeError(error)); + } + + const body = { + [NESTED_LIVE_LOCK_RECEIPT_KEY]: receipt, + diagnostics: diagnostics.map(entry => entry.replace(uuidPattern(), "")), + }; + receipt.receiptRedacted = !uuidPattern().test(JSON.stringify(body)); + process.stdout.write(JSON.stringify(body) + "\n"); + process.exitCode = diagnostics.length === 0 && Object.values(receipt).every(Boolean) ? 0 : 1; + } +} + +if (import.meta.main) { + const spawnOptions = process.argv[4] + ? JSON.parse(process.argv[4]) as ChildSpawnOptions + : undefined; + await runNestedLiveLockController(process.argv[2], Number(process.argv[3]), spawnOptions); +} From 6e5607b812625f607adb9127f2e704f990925a94 Mon Sep 17 00:00:00 2001 From: Mpayro <107719682+Mpayro@users.noreply.github.com> Date: Fri, 18 Sep 2026 23:39:46 -0600 Subject: [PATCH 09/97] fix(codex): keep routed rows from inheriting experimental context (#5085) * fix(codex): keep routed rows from inheriting experimental context Routed catalog rows are cloned from a native template, so they inherited supports_experimental_context from the account's native models. Codex reads that flag as "this model accepts experimental context history" and drives its context-management cadence from it, which on a routed third-party provider turns into a compact-after-every-step loop: a routed DeepSeek row compacted 1,600+ times in a single thread. Strip the field in normalizeRoutedCatalogEntry, next to the existing strips for supports_websockets and supports_reasoning_summaries. Validation: - bun run typecheck: clean - bun test tests/ci-workflows/file-size-ratchet.test.ts tests/e2e-style/phase100-native-parity.test.ts tests/codex-integration/codex-catalog.test.ts: 349 pass, 0 fail - bun run privacy:scan: pass - bun run structure:check: pass * docs(routing): note the native-only flags stripped from routed rows AGENTS.md asks src/ behavior changes to update docs-site/. Record the delivery flags a routed row never inherits, including supports_experimental_context and what inheriting it looked like. Validation: cd docs-site && bun install --frozen-lockfile && bun run build (465 pages built). --- docs-site/src/content/docs/guides/model-routing.md | 4 ++++ src/codex/catalog/parsing.ts | 7 +++++++ tests/e2e-style/phase100-native-parity.test.ts | 2 ++ 3 files changed, 13 insertions(+) diff --git a/docs-site/src/content/docs/guides/model-routing.md b/docs-site/src/content/docs/guides/model-routing.md index b9f1a6b34da..ac8e6ae62bb 100644 --- a/docs-site/src/content/docs/guides/model-routing.md +++ b/docs-site/src/content/docs/guides/model-routing.md @@ -91,6 +91,10 @@ Routing and catalog visibility are separate controls: deliberately inert for them. - `provider.disabled: true` removes that provider from catalog discovery. Explicit `provider/model` requests fail, and `defaultModel` / `models[]` scans skip it. +- Routed catalog rows are cloned from the Codex-native template, so native-only delivery flags are + stripped during normalization: `supports_websockets`, `supports_reasoning_summaries`, and + `supports_experimental_context`. A routed provider never inherits the experimental-context + contract; inheriting it made Codex compact after nearly every step on long routed threads. - `providerContextCaps` applies per-provider Codex-visible context caps. `contextCapValue` is the dashboard default (350,000 by default), but it does nothing by itself until a provider is present in `providerContextCaps`. Changing the dashboard value updates every enabled cap diff --git a/src/codex/catalog/parsing.ts b/src/codex/catalog/parsing.ts index fd9a4db1784..d802284aeef 100644 --- a/src/codex/catalog/parsing.ts +++ b/src/codex/catalog/parsing.ts @@ -803,6 +803,13 @@ export function normalizeRoutedCatalogEntry( delete entry.multi_agent_reasoning_effort; delete entry.use_responses_lite; delete entry.supports_websockets; + // Routed rows cloned from native templates must not inherit OpenAI-only experimental context + // delivery. Codex reads the flag as "this model accepts experimental context history" and drives + // its context-management cadence from it, so a third-party provider that never negotiated it gets + // a compact-after-every-step loop instead (observed on a routed DeepSeek row: 1,600+ compactions + // in a single thread). Nothing re-applies the field from provider metadata during this step, so + // the row leaves this normalization without it. + delete entry.supports_experimental_context; /* * Tier metadata is stripped from routed rows because a row cloned from a native template * would otherwise hand a third-party provider OpenAI's tiers. diff --git a/tests/e2e-style/phase100-native-parity.test.ts b/tests/e2e-style/phase100-native-parity.test.ts index 04088ace30d..abe4f8e51b2 100644 --- a/tests/e2e-style/phase100-native-parity.test.ts +++ b/tests/e2e-style/phase100-native-parity.test.ts @@ -18,6 +18,7 @@ function nativeTemplate(): Record { multi_agent_version: "v2", use_responses_lite: true, supports_websockets: true, + supports_experimental_context: true, web_search_tool_type: "text_and_image", supports_search_tool: true, supported_reasoning_levels: [ @@ -88,6 +89,7 @@ describe("Phase 100 Codex-native parity smoke", () => { expect(routed).not.toHaveProperty("model_messages"); expect(routed).not.toHaveProperty("use_responses_lite"); expect(routed).not.toHaveProperty("supports_websockets"); + expect(routed).not.toHaveProperty("supports_experimental_context"); const parsed = parseRequest({ model: "opencode-go/deepseek-v4-flash", From 8b41575de2f78ee5863d873de56b2cc2462d5e70 Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sat, 19 Sep 2026 14:39:50 +0900 Subject: [PATCH 10/97] fix(cli): shell-quote hub invite arguments (#5065) Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com> --- src/cli/hub.ts | 5 +++-- tests/cli/hub-invite.test.ts | 21 ++++++++++++++------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/cli/hub.ts b/src/cli/hub.ts index e3edcedc23b..dcb55073426 100644 --- a/src/cli/hub.ts +++ b/src/cli/hub.ts @@ -228,8 +228,9 @@ export function hubInviteCommand( managementUrl: string, clients: OcxConnectedClientId[], ): string { - const clientsFlag = clients.length > 0 ? ` --clients ${clients.join(",")}` : ""; - return `echo '${code}' | ocx connect ${dataUrl} --management-url ${managementUrl}${clientsFlag} --pairing-code-stdin`; + const shellQuote = (value: string): string => `'${value.replaceAll("'", `'"'"'`)}'`; + const clientsFlag = clients.length > 0 ? ` --clients ${shellQuote(clients.join(","))}` : ""; + return `echo ${shellQuote(code)} | ocx connect ${shellQuote(dataUrl)} --management-url ${shellQuote(managementUrl)}${clientsFlag} --pairing-code-stdin`; } async function runInvite(args: string[], deps: HubCommandDeps): Promise { diff --git a/tests/cli/hub-invite.test.ts b/tests/cli/hub-invite.test.ts index d5509459bdb..142dbd02f9e 100644 --- a/tests/cli/hub-invite.test.ts +++ b/tests/cli/hub-invite.test.ts @@ -179,9 +179,16 @@ describe("hub invite argument and origin helpers", () => { test("the printed command carries --clients only when the operator asked for it", () => { expect(hubInviteCommand(GRANT, "https://d.test:8443", "https://m.test", [])) - .toBe(`echo '${GRANT}' | ocx connect https://d.test:8443 --management-url https://m.test --pairing-code-stdin`); + .toBe(`echo '${GRANT}' | ocx connect 'https://d.test:8443' --management-url 'https://m.test' --pairing-code-stdin`); expect(hubInviteCommand(GRANT, "https://d.test:8443", "https://m.test", ["codex"])) - .toContain("--clients codex --pairing-code-stdin"); + .toContain("--clients 'codex' --pairing-code-stdin"); + }); + + test("shell-quotes every dynamic value in the printed command", () => { + expect(hubInviteCommand("code'word", "https://x$({touch,pwn})", "https://m.test/$HOME", ["codex"])) + .toBe( + `echo 'code'"'"'word' | ocx connect 'https://x$({touch,pwn})' --management-url 'https://m.test/$HOME' --clients 'codex' --pairing-code-stdin`, + ); }); }); @@ -192,7 +199,7 @@ describe("hub invite output", () => { expect(boundOrigin).toBe("http://localhost:10100"); expect(out.join("\n")).toContain("# Run on the other machine:"); expect(out.join("\n")).toContain( - `echo '${GRANT}' | ocx connect http://100.64.0.10:10100 --management-url https://hub.tailnet.ts.net --pairing-code-stdin`, + `echo '${GRANT}' | ocx connect 'http://100.64.0.10:10100' --management-url 'https://hub.tailnet.ts.net' --pairing-code-stdin`, ); // The warning is advice, not output a script should capture. expect(err.join("\n")).toContain("single-use"); @@ -222,10 +229,10 @@ describe("hub invite output", () => { hub: { managementPublicOrigin: "https://hub.tailnet.ts.net", dataPublicOrigin: "https://hub.tailnet.ts.net:8443" }, }); const fromConfig = await invite(["invite"], configured); - expect(fromConfig.out.join("\n")).toContain("ocx connect https://hub.tailnet.ts.net:8443 "); + expect(fromConfig.out.join("\n")).toContain("ocx connect 'https://hub.tailnet.ts.net:8443' "); const overridden = await invite(["invite", "--data-url", "https://front.test"], configured); - expect(overridden.out.join("\n")).toContain("ocx connect https://front.test "); + expect(overridden.out.join("\n")).toContain("ocx connect 'https://front.test' "); }); test("--json emits exactly the documented envelope", async () => { @@ -236,7 +243,7 @@ describe("hub invite output", () => { expiresAt: new Date(EXPIRES_AT).toISOString(), dataUrl: "http://100.64.0.10:10100", managementUrl: "https://hub.tailnet.ts.net", - command: `echo '${GRANT}' | ocx connect http://100.64.0.10:10100 --management-url https://hub.tailnet.ts.net --clients codex,claude --pairing-code-stdin`, + command: `echo '${GRANT}' | ocx connect 'http://100.64.0.10:10100' --management-url 'https://hub.tailnet.ts.net' --clients 'codex,claude' --pairing-code-stdin`, }); }); }); @@ -321,7 +328,7 @@ describe("hub invite refuses before burning a code", () => { hub: { managementPublicOrigin: "https://hub.tailnet.ts.net", dataPublicOrigin: "https://hub.tailnet.ts.net:8443" }, }), { live: { pid: 4242, port: 10100, hostname: "127.0.0.1", source: "runtime" } }); expect(viaConfig.code).toBe(0); - expect(viaConfig.out.join("\n")).toContain("ocx connect https://hub.tailnet.ts.net:8443 "); + expect(viaConfig.out.join("\n")).toContain("ocx connect 'https://hub.tailnet.ts.net:8443' "); }); test("no running hub, a malformed origin, and a refused mint each exit 1 with a reason", async () => { From c2899269f8230760cb0359597712c2854d2b251d Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sat, 19 Sep 2026 14:39:54 +0900 Subject: [PATCH 11/97] fix(gui): keep file clients unknown on a failed-cold client read (#5088) * fix(gui): keep file clients unknown on a failed-cold client read clientsSettled counted a failed-cold read as an answer, so the overview dropped the file-client rows as a server-side omission and showed the 'No installed clients were detected' panel next to the load error. Settle on the payload itself: undefined covers pre-response and cold failures while failed-with-stale keeps its real rows. * docs(pr): add the failed-cold integrations screenshot --------- Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com> --- .../5088-integrations-failed-cold.png | Bin 0 -> 175257 bytes .../integrations/IntegrationsOverview.tsx | 7 +++---- gui/tests/integrations-surfaces.test.tsx | 15 +++++++++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 .github/pr-assets/5088-integrations-failed-cold.png diff --git a/.github/pr-assets/5088-integrations-failed-cold.png b/.github/pr-assets/5088-integrations-failed-cold.png new file mode 100644 index 0000000000000000000000000000000000000000..f450e897a58a577e3db36f69feb278ce98d2a2be GIT binary patch literal 175257 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 z z4qlmMD9BDFMbaSAl$7^1aApcjVDgxzpp#&^e~3X?s##V=vn31Q!Uk7L`_yEP3K=%< z=dy^-=op|b1arG8e5^=sBjP_6hwbD}Wch!_K;xcs4nO*M;X?MeG$TP6hIA_KZE!^aS>k)Eso`c0-5-o# z8@?ly!Pt_jAG0`OPw1{FCC8Q>&> z2+dPKivFO~O;SMIyHF@K#`+RkjS9;$hugc|N72$Y+NeuCa*iOw%iFtP?j zZvOi_LPdTuQiyl`GMEvW|`?qm$r$#;m!3ROEFV>X)Ya^7*F)wG2{>X<11uuBcu9_BY8nKY;;# zTP$Am%@?(8t%co}T{=uKmK7%|JS8b^ASm9>B7+d~Yc_yi%Ue5}o{1C;r-g`~pkRIZ zg^HB`d-m#kz&p51X2aOU2 zLZ5n*$DF?i#nGMc?Rq>K#1?YJ7G%{|#dvy2Y~0&?-gArf-}=&TD_F08-)yw2rUqUL z>1$%5A-v>Te10&@7ldyOR#PqH4qthJ%ElkADIZ(cb_ zr!P)@-sHB7agGgl||a~5Yp5=Uo-{Y4#PL`qWZ z;h&xM<+FoZ(?S}QNIalm6ImjPSb(%+%uW-!k-A;$xfPD zpWQ{}oPZA|w{Q7~G@yF0xv18g?Y<@>fBWVR^S_6km4COMTneD3Z!EAI^?IS2r$}Y_ z8?KnFktb_mL{;PRsx>$KBrU@f5Z#+UMyZY%jp8tx1Qg#V6VYkAX!xux=}#efWmwow zgIOrI8MnG?tT~S@AJGI?4>}iBf2Zjs>B<%%{?z(#Zgf&oSUZK0fR2vHt@36OI=9uevvBme`G5){W9WeQ1;~D&GGb zj6#D9oqEuan)u_f-a~(?c7GAM6HaBC2WJz(+oexcORkgoT#4MaN!gW1{T%_etMe

enG)xfV;ki@_ynVM6V?*qD&U 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 ><`htY{~cn!#(TXp%LuSf)+l;|UsfbA0~#Gnsm z4^D=fCGQVx0s_kDZ{77IBaa2!G z)_V5zao=C_K=S|IKlvo%?V=uAM_a*Y%DPiAnmjLCN6Idk{SNJTd}y0L{+_HzvlS2! zA*Y~la7@!$wV8ka_et3`;pJ4Gg+N=$rlxEJtN3vtmtY=?g}y$^-%XDb-{c^m7%Ase zJUIndWPjp~{CbU-Jcr-sZ;FZ4E9X1!QYJqCvGB7nFC$?8I92%dlM@dO?T5Ga=04F) z?2o0>J#6~(VtaQr?yaw>TlW*M`MjwgtuswVADpv!QfxtD92rL&utEOlf#!$f%vtI? z=tcSvGe++{y3l-m>&LQfP1V`2J4d4Tm;cnw`wP0qQ9jiuW)Lr7l{BPQ=Y7$9uud~` zdWehM00;*mWCvX_{lg88jc=o)X!j{g6cUb3dnIvAEE^pL0~iVbLLR6(v*saUz$Gf z+q~z!khSmlwk!l&Kt*xLaCUFCsEz%)@B&j@_DH&Nh2#$7)5IlpHg$ zyp=E&^j9=e>eg=bj6S)Q?tL@BK%*l5&YioMMWN2NOVuwjtBdh)*}onWbA=k`T@!s! z{M&Ol2$e25Nhji4y6?$fza8Ss{j|yo-j)c2_8l60It6)`TB)iD17-b`?b)NnMRVuM zFi+2)Ur*arG+df}CaVH{`p+y(8qV6XLNN*crh1)tfIS?WspwM9;rz>iHOOP6O+Jv> z^Rl3V_cT8^oMb6rAdQB)J|>TPd`{=VW1tt=j-bi#SvuxzF%~?W6xWv73v0K4kZqzA zuI#-_X>0DqNs zMg_CV-+=k^!-Yo=mjIVf!i^bTTsE>q)GAeeHZ7aN z9Bw#U0;C#fBS}m~^S-kJ7;{t-c+m~OQ{MRdq?KMm-=oE@C-(OBIEL1<{DdM@9aY(+oeL0ax#vO9Fg(#iJN0?h-SZo;(~&{ zl^a2QexcS@(qg{1pwia82Sw{K1C$Y|X_3^j`$pEvaZNuCBn^sCfk#&`#Viz*+ z*F`BPEe+Ugux-rCzwWhVc+au2u{QNGk^LfeSub7bf>3`(dig7gFaMvbB4oMurO6?b zNtF%WOcs?QKwbOmzbdp8yP7QZ1Dxv!oLfuktpC^l8n^2t!-1;`#`@-6{+1FxYdqqz zL^IAzs2%*Wmi? z`)}cBbKq$I{-ez%F>$*}2oW(lhSQLnL$BdIzay*HPy=VzYC@^T6m_QV;o%`(X2axw zA%1@?3+Mh%PhEl6w{9d;J2+~>mpH>C2_%-2tKfX>U})zS>pAv1#Q5?<=rYcrfPFly zICtB`Up;4of_%m-PaUM3>u4d-QD>UZ&CCnOObg!6m>C*63tetu5d42GL;pn?h|vWu*X?o*qpnb2Zi;_aFZkL2zmIuf{dwy@SOAXA zWp?%mCmg}fu3BPHq|ceB7hM+;wP`JM4Id*^D}T(P<_IZcO(n=lDzKz_rP%V$C?_c@ z?GnyO1M^i}eEjDhZP=2rBkg>f>3OdbPhjdYzZ^)!l9fQwMLO+{*eTw&&?gb5LQC$O z5;E5(N#sI)=*WFn*-5}Ao7y;xNoLg_zm5&*|6a7McCg^~RLfqvK9yZ)QGC44K<%j=YdZxwloDEva#gcfoB7&gK| z#JEI+g{7-gl9rz{+86`*^}WfTE3S%TkP{PQSKE5OQX0QvBk)>1Z{Ow?d}Ivrx~>hu z-IeO4qar4L{YHo_S&c|nP$3f?6Vp$C4OXC=k1yIk_M5JnV)|{^hYr8M7sXqHIh!I# zR-xYK|Na(h20(&H)blE9YYi^{4%3_zb+WG7xD|3Cdw#*)9pWzlfQOw7$81t@{0fmB zmZ)}*jXp^Y74m!SNpVK^J^Fv&mE-Iuo|cr6Cc4RF&Q6r?xQq0@y^Wtaia=ryoFQ5@c2vl4V4=Pt@YoYJznJbYF(F6B4(6D zt{9u2Fc3l}kax^r7BhLjSeW|R(cL1^zGp3dPi~-9Y3g#`+GHfoC6ZJB8c%CSwmUpZ)fI67-eV+$F2LEqlX5Vkud#W5OYCxqo_heuSy@g}$|_ zvHmXpd;SPxQd0bJ)jk{cj?nuK<}kx}H1Q~(Kt46AR{8F|_s_A-yV{(XZ92%v+2qHa zPaY(y`YvzDVwr_M?N9ykl=HRP(E}5b8u9N~e?{-6;*y-QA6J zcb6dDC5?28puj_yw6q|dYv6l)-+!!~b^M!a$JY&CnDcq&9OEAMeO>1zKZ=d1+^?50 z&wBWCuc&xU>Ua!wj9Dd*8JG8nF+G%=kF@D;*)8N|qh9kx&Nag<0ukCST*5rqlDh+&aTRK9O+*sxzqPFI*YM%7hv<@$;k( z+OH--hV$i=KnWgQ()uU0;lZ`AZJe+iKJq43PzhBJ8LE$#p@={+1A1$F`=Uk1AlF+a z`ZRnwW?z|;-|a;euk^?qx$iK7YYe1IZJ1x#HK$5EGbJPUp>$s2x zz$$Ojt{&a8czFfp>OegUXhK-1LED2WcZ%PZVfk!9SM`jgH$FVqx#J48+;;H74U z4=7aIv6cQLImgO<2rBHaf*Z&*Co<5?0o7Vx7DG* zfhlNkzz7r|+p%`biAmz~Af-LM2COa3mp@)OBV zdTC15Il@mj^tD5q7O(R$_v7HV<^;J_!o|DJae^F(&IsPUiyxZ{z^aA>YHTNYuApdp& zb}k8tL7)%+105JSkSSR>Ix&G4yK|(EyX0&8Dh!B`0cFXSt^Oq|BO~^z%^92()KP!v zw*}P8-LFclgp12-_}4yEn&|&6IQYE{<0k$_QAjm zl$k{>pvgo6H0|J1Jq4B~#547&e)dM~^p<)}hE(aNHV0T^q~6}%@pFjb)*-MgvDwbE z4NsT>j@}yZL;%N$1T_Wz$JaD{9YNnZhye#U<2C@03tnc&FKcm*VGG( zJ%2$0z~H;$nh*%a{CKkoz_kWUQXqJ*9+1ZX3%L zgjSE^+|nW>Cct|cWb36Kwis|MbT{1=J7I&->?UvZ%sHdp*>?i14} zOU+m{O&GlTe(bh)Iw?V7x)f@D62SWxDGHB_J^S^5$1!LT#VeuXGN{5O=d&91xup88 zC#8R?RM^m}kDgsDcbOP}riy;s?)>17fJ4V8aWBg{`C=vU5D3Xz)dp8aEZ-eH=_50p z_&<|=1w&WE$PYJX$WJ%gve04ihopiGsx=z>@9{UIhg1}#*Baey z^}y9jT;y&vqS^lIyHP&3gesF5C$&6=>ecffGZod{@Cw8Q9agPS^dly4QJNYRQQvY7 ztIg4--xG%PB)P@bj`OnytYdRY9(*$OwXI~}OMyU=l2{3n>R*tgC*KPWGu zH9ehLcC5Umq>Y|fW#{AEwY9WQoVKE>28`cuU@&X}11?|*8cYD$s^4#cylThqY9$>Y zn%~KRwG$+HJYLiW$dG@g455L;5*}e+xZr372AoobY&=rZST$uu#fk2x2Zudl$s%XL zCeNKriv<5ZDUhLNkm!Q5)#?4l05pT8TRtq=0wsfFKM*3p5XGAR`PB;u!#5x;HsKOv zQNL^GwCvp&W?*4)&rvip+Xne9H7ez7p}@F7QGNx~Gst7i2mo3U<4X>2EFf~mLPv+t z*8QAb2Psp|c(w)?OIpdHb^Q{YF()`4gw}3O>J!=_d z>d?1masYR2cOVK#42+jh6Izu*>+LAvvb zguE0lN6{;^3-@fxnF_x+4YBpJ(rz!IF&s}!{UEFkIC9xd*A)-T^5-j=Z!mCLqI)P~ zL^Zf4;5^}TDL8f*o8dv3UE`4TU^7^)t;Afv82=%1GuW^+{JRt-?TD`+gRLh)m16k1 zCAM5{W#z469){lCjy100wIZqY^>zwXp^IJZ)*`Dre5&SH9m40V^}YY;1$arY_}ox3 z8x&fQ3m0hgKcAtzq)OgEw2Ab1gWgDn$kqn4Xvppf^&m@>zizCmXpo{+I7zvl>2R!h z`;Nb5;~Ps2$45l&o{^SFhl@NwZ9^qhIGhN>6~72=pMTIfiQjn&0e$N)#;8lh6YsiD$`S z)Orzkwjv@>SOd~jg-+2W)Etq+ain5F=m+YirbQ<37^=cp7@Iob`5^!*2@Kmq_>+7R z`$%F5^L_1sQ$Rc)s+)?cn%r^;qe4FZ+=-ur4CYUoE~=|JDccZaFHg90(vTkS+10cs z5j{+}WMP}lgv;u2hfUf7=id-A4O-E89%Gq>INsS;kSJ5eqc#Uf^igZjLTTqkIA1Z+ zI2l*>FTB4V0T&KHMSoO-o`t=S0Oqo5we}O*lD_~vLpCiQ2Hnl%e*g?{6bX~R@F7H| zHF=elF%Gp6NYi8jsych=ND_n0YjFzYIMi)#B@C2EmfuJa&M9IN)1#x;EIVoW{BGpn8R;kT;9$_uCz)L82OH910j1HY>tR6bzj8VQ9BfEwK1iD6SIBylMg^+(=SQmq(fu# z%Nn)qug&P={`CXFCTygzOxzWoPN1@&+*(;KhtW~ndhF}($DEi~;*Yh73B#v@X(q^U zFgB(V?4yS|5C_b;KU>a|uR=u7mLzgUsAMt;Wa#L}AFT>A^Zc zGm@X<5eB1{NyW4?H7lg9C0YbFi6Y75LOPo0E6J`+uLDCU!cY$F4{>xV(Kz0A&gq-Q z+CGq(IfdGa28fjssH)s8wqBO72B0iDi4#`gxeV_o8Osas&*5oCY%is}B3dXzF=-K> zZcEa(eKGrFOUC@B$z9w*OkCP-7p+N%T+{aP)$emSFG&l#xohqF4kZ?yhvWuHR!MV$ ztmc}CGDLP*&|T!GyxFa6e@&5&@4gjNVo`eU^Ce|ledNVrES{Pt`*C#M!~~gg>Zg1L z24n&E%lm=H30eXysudVTYn1ukb$%>%U@LuAd4iw?eGps*in(|Kc4OdI@C+35EwW8m z?9XuMyuibfpMpJQ=7djp@4Hu=o*;HVo%a}`3qNGg=4=L1kR-DO{k%b+`G?R`jAUqj zSVfcL8|W;%>!Yf1>Do^jM$a5c@H3ZM9LTlf!ERe`0}CW(!<;1M%wI6bl551%x(;r{ z{MipQx)FaJQz;miA+b`aN1;)QSj)}P7WWru{ziEzTM@uq^L^TK%xws(TIAri9wveU zLRL|*O4~@mc6tS3uSSS;!KyEPM47wT=3>F~KoyQk97aPi6(9#vAOOh@uz4bFgU%;` z2{z)8S^KcI>y{zwG+yA6pd`|j=FP`yiJf-Z+zJ;G&;l;3OI3H~ZMo1d_yNFOR9IN}oV%AJ*5_aJmgA#rJo%WihT8()heDn;v01B-6^<##2jTu( zfhZTVv+S^gm8vmJ%98FiRgZ#$bGQ#>-@M>4I_L}gQLpWZ3)8(Xt=vjRl>TbZu}gk^ zvRr}q3v4^r6y9dkiZ{#8n);tL4+mxVQ&_8`h=6f~BII}zt|b;p(2w$7TBH=6JKbR6 zW~1&?lToj_72@aN@s_}0^N~O{la=s38CKyS$1vg3QtID-69sGMi`)u zOB979NF+%%hq^KkiNIrI>T6Be=(_oy0C8g*ak$Nxy1cVPvi3tIVZ6K|8iEG8y}_z?kje9e&5>iCSl zy6z%A?W13N++|9>4Xc123*_6=B>be2In!Pz3FSU5QV38-_v;jLY`k{rG-~(S~ z_~3vS^zfeCowq#5GuxzN<9>b3()^D1hXpA>e#4U+@m{jdpZGLz*}MpzG&5%0t+M@z zYiw&ECesE^PJ7};D-27_qnukv{l6Je=lw{S6U^Lk=gzrFCeqQn3N%>0&yW#YF;u2h zFJY%78mqlTbW5P;Eo*KS^;f1oNwp=J9dkS`sA?ryQ&*cMK$0_ide8_>=_t|G(B4zt z=*U;oSBvV)NV7-fbC$#;)6LGUL_y{FOwhf>pka%iG$uYN@xe3$F_G_);XxvnsW95B zR7sgx$W0&oQr%9~wucA~dA;b`H8w4wujy82GhqcBA9Pbj$JKk_S;>AXh%3ZDPjt@W zD$1%>(8F2eiOTlW3BGs*Y_XR1q3xuj?(4g5QgAK0aeR)BOR%}vP*D`O7FKhYQ^QYd z&w9IBDgN!j)F6boj3-cF~ z=c4LzEAIe9FE1hCV@~clO#+}hAdD##x*sia0VfyGX(0+>CpCkVGIwkMCb0x)$K%c` z{l<-i3Ncws){t!rQV{q->6AIVJP7# zd5}4D$#}BZbxVDamQ02^$!;=~zwkj#?R=CrkK#j&8E|kV zF$+2RYxk;I>B^U#iXO)2%J}EZhK)}M4KDtkPQCA9U9019mN!4l-C1(gIDV&nc@r0< zuyABgfa7zQkyU6R?_GG8gq$}C&Oj@#nw@#w0#kDCP=0|}^PxD>=r0CoBwbNJca=K)D++r4JH$boADlYMk_U0a_ssh&as6UvqfJzdJ){NSObHJXV6M zgLP<7clzuC0WNmBchtqCI!UX)IAB_hY8&2LOdr~OFKu#0!eR7)#A+7fqARcq-I}O2 zZ!A5CG`+q7`u|7gFYYH!p|gg9;tNjFiJ8{EyS@84&~LGP#k?Uqx^}u<3Xi8ABIpWJ z%o!yT#>YYj>NXxPAFh`2v!#ANUE%$mI6mn77ErD3qhemIe|f2W5j`Zhb#>qN{+8NJMg5T2%BMB-jG@ z3U-=BaK2YC^&?P5Y@LA=2=B|o$T#=E)zT=O@P-J4)6}`X#^Ux8FdEgRm<(lilv1o{u4e5udPay83gZmc{aa|vwv9gHrBagk`RK<6u_;oQ;TlZow4 zPA*`eR_xR0F#IFVpp~WgA=KJ$cjT9>*wNo$75zn@9YZUwM`j`YLvt1B6{_x!Y~n+B zZw2?PV0czNsiA)!Up`G$cL9lyX5%V=C21f0Ri_~kVrR!>O-f3tVs;s5axLd7Aftb= z)PyjqQG}AvEPO2|5Kx{8YFI2-cEL- zz7P;TwGbDkxBu+w>jWm<%4a}~oaV)1pCWb}_kC)gsus&u`tjgit0rz*#vr6F_a5|s z_eZCD5+}vp&RDzo`#%D_mJ|1&m97bkG_v5$Rx*fZc;;m-fv$-E!>tUV@OQLfcxjF} zA}(t{nwsC+BzQrs)6IBvP;Ei4gg)gWO5#Iq!vA_@2C|o2LiFAt1t8q4Y9(0%PF0Jx z{Kvixif3q!-6Nkpd0n*x>Rd9O{y6U7kK?tfI1wsuJ;_Vg`_^gy9^(Oe z24XIVlpq|wl`O>Ed%L$|4?H!bi!i)Z0sG~pj;(9JUW0NER*FP6QL>lA=irnkngyQ; zcQ8%qcpiU00eY>V@%uPL>;SyM#igEcvvmK{3n+ayfdcGG=Xw}1m_+@dZ@>j`p@VfpjxF zx5oO(k5a25-XkCDbYH}=V`d;oZk?a%*@!|xX(=lQ!VZ8|7H04@h*_4t#lsqi(A}bV zW=q&9Sl6m_4)LBkOi)cWr`vMupx&jdV?1rh}Thn9dzyIRjK77 zk_@F-6<#i>GYzIO>(s3c`#Q93)R52FJ7WWKkV%*?z5-jV+N{FL=q;|{6yz=$U zoKWJfviQ9|-Mh;oX`Yv2bMe^=-*=+X6 z93d}8_VP357}9%>Tk1%IN~p7jXW>neh5NDSt!nYe$JO3n8m~&eYSd)B%9&&0Q&am~ z`{44VNaT0)bi_#TiGZ*wp_W&F`IV>uC;QpK*Qp%mqpz!{w2Y0R>fTq_K&tqCbX0_7 zaA1If&FN>vpAX&s0#pdq_TsO?3_oBbMZ6X#aeg@>l|N37hZi<<1L%Z*^k5A^Hdz`G zW^81B=u0wGkTCz+;IJHH=H>(xu(@lyXgw#^8PV=RoJs!Z}JlQ<$9POxr)`uCzGoyAk3pO z2-79F^aj(?k&N_|6vNu^9`UmSPzFcH(kx*5MKl1a=Ak1yY{vwMS0FPeuc`t_K-QH* z_0z;g)}aL8H8XA~3kM9V?QMW^+9VnkG%6AGw%vAccEGBEh>8P1BYS9N;%zEbA{oRm< zZlm&tZ7Uzd@H6RG2y)KD$M9mo@Tj64(9B332l0Tf89nrI^ZK|{QUL)`<6u*F5r?Mw zr%Gx~_Fs~$<4=c!L>Q?WVBAPdfPXp=myGW=WC8y=uXeWEFQ1J=`tb@=Z}RfCzd1RP zVXz4DJK)}VwjZ&;FD{og>l~aXo850joS|f3>1mYFr3Lb1W4D4t+(}0%(Vzm3 z)h@4U2)Cs07T-gPc8YF^CH`yeyGR~=woH^_qD-D8ngA5}Lp){MtsPqjgor@iH7!3gA(G&c1jAM8jkCjI)Fe+0h|`Ul5ggbIdFi7Kv5 zh}NP=ZS>sVXm)XHYSsxp|1PMS-I5^n`Zwt{e=+(5j4F^VqMt?O>feAWqTm1n*SA9Y zgGRBOWvxOS>RTt4%Y)9S{dV8An}eDPRF#3+Rc5-MGFQ%Lxl8L!FWPi#G%5wW9Ak5L z6gg4i;;-|%WZob0x)m(@np{8WFWKqo?+r_hGv832uE$>!NxG};owcO7$n;(0pZ3^i_>}m%NJ&>;{#9aa5Z9!N9 zu{E~Pg2oDcNr_8%R>)-(L-oF`mD}7k5V?er3l^fQYMK{i;6x3)_s4+1Q((Rp_&d3D zuz3%RK`IQXtCx>9gc38i-A8Yk%?SCV%G8l=2D94LM&ewu+{2?U@vLAI(-V~5q-l=! z2Mc^9X>H1Iq!Lx7J{R;j5rsGJshk{@We``(C{2fHAsy0I)}Wu>Ul2IdcA%@4l9H06W8J7}(x(k9Lp|tiys2s1ddsfN zM;Q7+3i@*PoJmU;Mt>jgop#kjQ*qQ{9wIr$MA($d;E?wmRu_^Au?{7K1R2a#gYAzC zqDcq$5-wP5Mb$!72R!Q9AH0g$5KEpSe4(GUeh^ctt30f`>{CJht<7_9Q-m1lWcpOu zdxM`Q*_>QMveit|lqpE}sr0x7>X|5# z$*Xil-LI1kiomaiLMg9_PHi}2NM?|RrT-qFZdcn|{RSbItQ5ucTIYaVL5LJmKB4PJ-*zD%34@BxWS>JZ>AjYy9n^`xPh9#T0=)gh3Z{!EeavW z76>%(oaAH^j?5xTRD><~2mlamn1etJyFhGi z4+-$b>8Pu}`nu(+?(l9{SWaFZkn!I!Q~;q~!kTq`&$*+{3V{|apt%VERRydv_%D!J zs;a6UpuP+tyHo;-8g+(Lggg+qNWayI+OxAXzHmx2RE->3!RxXU^CygzJX|YXuUN%P zWyE}ujGO1*f;{}}sNCWrk)q;P`tTt#_zlT6xYET3_E%V;K*=FZgcScdbp{+;fOy7; zr2v!7pfLzUjOl?~XQJM}d-+Ep*7c+u&RZj(iv!}yw6)MI*n=$L-QP5s>3H5Fc}5!y zxQ9GLFs}i;E#$p*1v&dK%4#;VZz<2gq(H$@GqeY)PLQ%UTdi}DodJS*`Cpr5&p4Bh zG#_|%=HS6tMFT2`k%D9xz)Sdo5Czb}&M4Gn!C!T0ui%jf497Z&TQJTI`64XlFHU6f zERy(*wG|I`?O8y+2!)%qHvRDo=i^!0F9}NK12|(q5)|L41<)3{VA}PMG?>Om&oRL0 z=-r^S#TWwtO18o;xYz6_;xv&%3vp_jl{d~dF&w&=maE3dFfrFhdsVRQ(IZD{|1A)! z&nZ+{$AF;J^O-G<9we?+?Fn&u{v4?vgWvcAInKvkLqbJ$%NrLdynUY7UN9?eYO1Th z9e-nd3n&EcVvcl7W-LF^WTd5g0&6!9*)RfZtgUrZm(w;~{}91&5yh^+l75Z?1Z4+) zSX8XRY5zewanLink=zJae!kMWcft532~= z2}+t%QAY@N+Eoe7Vz!%u3}8xzJ^JHE3+cEY#ZvWd93$2&#&^=UaHWF)Cr${Sxd}R7 z(3YEmC^48)9e#_~mGtszyIXaiirVM>ITLkc{?|CyN?tx@MR-a0nQy7W{QX4|b5+lj zzAfmmM2rJ&>4-gShh5X1K%q&_qJ6@VyAeU0Ew%oZ_Ad#5Nwq88an+xnGQQ0~;5Z@o z{R0&SGIN%2`_*6Y#d>rI1Wjl1#hG{5xL-(=vL81l%!Xo-*%lt|*!z%dw364R>*>8E zd(%oEHr-i04TIYe{L0}VDq@l7pZb~~3>yc*aJ=ZvIxki#OJ#5GDQFNEk@Ny*K6t*u z;{kRg>a_rx!0F;*q#*zrKT89Ah{Fc~<#Hd)E5PwR9VCBYUjV%rSD3U^jio1uBHac6 zwSmBE@R**uHEH{S=>|ajYGh3S2zz{?QKK~*NjT)0e)(t|2kzwl;jtw0Qt$}~{HDlE%E*ZLzV|JaF|@c4Pk%F?y9P=F(F4Fo8@VZQ?{OY*I!+M1j3P7K*slh`r*~W!X zk(od^_!o>}Je9SyBKE(HjXg&Tur(3ew?YY3rnr9v3>hV%Jl`|K*E0ZkT3OSM)FfaH zp|iQLpRa=w3g3*EcK;KdpH{bMas)b&&h0xSfc*)Q(zV2%VWpt`_^Y%r7T?AZQBK_C zC@HJ=6YLpancB{|e4o2iy^kXZvIIi@j1fRJg-0PUWF7*Ces&SlpLOowWTKGO<*Lxm z1@lba0KrP>tH#wm6=r%4>_i$?1N<5eI7}db(I}#|PQThpQ`;s4jgSKtZfL_~R!Eyy zgQyvX0F{-`nHXsBU$E7G?dd(L*|)qY>_)cN`b?X~bVD z5KlJW?pC?Nf^yJ}LqFg49O{ceVq0&wdkh|RI5}mnXCQMI8=AT43S5NT64W6n_`9`F zDYC8Pb4LkZdP^o7h-FAbVaz1G{$M5jIplQoJ)4{6qS0L5OMo zLNI-PXJDawQSx(7>U%xdbfibOcXu~=SG^r=AE?l3of!N+JQb$~T@TB?^?VWq z(k%l(>5Jkfz^bw|%txVSDndp%q9_ly7U4#n7UwE3PY@FkgJ!j5+ybI5C#H9c$y)AP z-pe{khr5(*#0M?-`86Z$o!l0-8p>d$>)=7+29r$NU?_qq|wsaAUK#YOUmw>YP{i2W~8v-S6_Q} zNTf>WhlDT--788TF%yAIYZ;X?z7g`p+K=eMx>IkBwS$ znmYJqtMw3OEAhwkV#$5)L#6k|$LEhjS<9fsm2ooR( z+SF?-PnhEcIj++jCMp?C(@Aqah2$jL)bx@4Hb#4%p`oH;XruJ>CMqYS(~}APRltB; z1Pv_Ah4(7;pkVk(lYsP*Qu>EXC*|^&Rj1J!QQg@1X2LWaRyG^X*s6Z^0}$m-5gnEJ z2=L_Y)f85HY=1y?I%P7jj8BXz(I@~yd86)0cOurGw=*%!Zhj5;@)vzmGsuI&(3sQ1 ztgS$_RNfzCcd@7+EnD-ebfEU*zQkYj4-ByBcc-~S(O{wcm0B~_Z}|zf;V6YvsJbCx zHUa)htd}TA6>dZ@Unbtnl@HB4HdP@DQ!}rlNWXUGyl@Uvx3XHa_56Hom~Ze zKCr`V2i zEmkmih(BV5T$W4U`r0`yf93bskkMgpzeJ4Rp(6PdeG?PU*u^&g8P-WgjFN~LhA$5VEr35upxOnii z{YR}_z{ZPos?)yQn;zzNu^Zm|wpY<;nOvCr)uX<(K*67DJi=_Vs{2xF-tmfV}d*ri#Zp$Np-koVHk3GFzDV}D_bCX05%@o;e| zvxDbG4%XG)Hi+`tOS+?ncT4l|+68XH@}5Bh?eznYTqKe@sSXWb4Ue|IqdOI>?B+zB%rxkeQs^p0>tRg2DDCR|SuzB7AiSJ?2d*!F>34al6 zEZ0WNgfL}c35Pf)AvscLbgP1z4}H1^3Pv#HYzO%erCxl)9FQgN0aNyesi`R-|Aa=~ z_T2R>Ppd1MCG)k95&&}kuRXQghCMHQk;%bvt_%n=GnhEqnhl0^?j0@hadB{dg_>M= zYdtoj>kcld`K_~@p=h@t%T+nXkKuu~9iRC9tvkXDdHrRF zQ#OFuqplAHfFW-`E7yS-z=Klol4R_FKHnin-xTR_;_C!HNlGksYI<8`Z7Y?y?ZmEV zcJ>c6)AbWNQts+j$Hc3^gXMkqg!OjY8aLH&JY}Mgf(nCL1x<0o8h`eeS6k3HoFas> zVd8_~ogu2x*FoRn*sqneimm`U-rnvF&YJVt9o`wOb+#559?}V5GUoFPhKK)F->7J! zyJ5{p>C_#IW&d_1-Xu7Z-jF{MKLc&bs|;Iyp`KvM?;$}bRdMda*iMCZ&aqvwDhKa* zU#ViA%*KBO#=j$IE->OyGJ5o*@<_{ME-&kHDt0|R-hrdv1JGahi!h+Mu%pGTIC1y_ z#u_MBCAp=nne!9lnR-B3K4~wKeFLVOJ(xmh>cCtPGdozOT=Fu z%AI-O`V%?N6sB_PoG^R=Ec`nfD;w*c5e_fqiDzKE$!KVCQ*dp5bttvZUV#LdJxqUS zvDY&;-mq&~3ERR!TL#K08z%a=u@jI1yvI(_>>@(^0+|%Tn*{Hao@`X49DeAt*GNkXLX6Y~vSWFYo0z}4&XlTJGW@a_tfkl6i@aI% zUj);Sdps592hhu%8Xwcc)oH)L($BZ`3~ZbL2a-@$S$yrqVy4q-5UPwq#AyjmD}4;FM?R{Y969~&7WC= zob}=abk#5!avBMgrh!q=YI`+MmDieL`R-whTtc%~v0zrC>QP%9tD$8=n zwmvL4<#zxNiTm;LUgKk8ka!W#OmJO!wNq1+EE{YkXAov39rwkQ7)@2qaUY3H3qp@M zl=6wWzIzo^1Y`zK;dlV_G^e6Brp~WUP!HBc{LBU%J?IEF>;Wq@Zo2mqsSdn2Mwg9G zd2Mb|64n+5rr-Po#h1urNpRF@VPuBq8*05ch|@u2?C`7KUH#rvrQKSQu=4irP`4LSG13`tlWzmf(gVo z*Dlcvwmh_X*+}2&Nfd{x*6Oxll`b!TpG($@IjT6m(VypjvGRSy@1wL!OiYaHMHxBb zlo2oe^&q~1;TD;IcMJjh29VfGQLR3&BFoyM!+tGCrS{Fr$6ih39!&6I6xh41dJUDJ zs;j=R>dv5WPHay7)p~SRQRABz{%m;t=VrC07%u79oD@O}AeHJ5EZ1zoICJ+Me%tuMRBWotxHNM;~H>x<8+?xIxZfZp-_bSc~l?A}mr=B98nkI-K`ab>% zjlAv0FVBYP`rM#hAN7uz)tQ)O*a)|{i{sKFJsoLjX^_)#rg6>_c^%tgXddEo< zBe@9@cqL;90NA+&L^CWM@MOd6I0H8CUP%b*G)N+~?c}jvw(NW%OI7^j4+M)3cURHP zBGno`4fr+}Wnf$;j+MZZREwXrjUZgD!8nq4V{TZWHWC5aoz0oXnI!N{$7w<(Kdr0xh%40Gu-H&h@mKrTQ)0e- zHdYe>q6uWn6PNA3#xWom{NIw={=d!0|2gEv|F10azR{zm&KHUD0CceR>VM7lBM$!| z0wZ+|{}%J>{;ygJBv(PQ)Sy5aJ1mcM)4?TV zmE`{}Mmq?Sq+G71U9ACp*h?riiXJU^<)1^RHXJ~!TT3fLu{1e~Ap$zOTfErNP(`P2 zyr}75y9~-t^uCAYf4e?QoUYIV9&|ehs^X^WTl`m8&u2DwYC{K~Jx!(PZ66un%aF zGf_ZerpeXLy3Bg z{P`>KkLVan>uoeN$;iRn%KPu~N@&u@%s4*$(lfU#ZERFCr;PB`CyoT48%=lLirIlN ze&3Lx=+F13ID~-mry0K>l*Q6Lw(z^4T@TlB{%jZ1;5)MOZ zMOBr2BNS2WYX*i2FvYnBFXe(YzcM{R#+FcP$2tDRYpBc@U*w?AIAebN!#NO%RL2C^ zW>Imd5n@w*4H=5(6To~rAH;3?@DQc{uw2B0a0W;b1K|J6K<}xVCCmQ;m?JGFF>3jILiSWfC(H8{RTLk4xXs^^OOiDHL4u z$u{@_8ySo%EC;!u@ofq;o(u?;F9)zU77WEa;~=)6^ftwdw#Na>3w3a4G-3@RRb?BMX$jUj(E6yT;z&lTM)Qd*1V{_(}Kcq+3Z(&7||flGWd*lgQ7Qw0Gz^H$0O`bt8gKX4r*E zIaXR~qE}X|k5=y8ERohnqlNq$U6;$UJmo=S$-e2`chk`hiYF@d55?^9RXEI%fihiH zfq{GDk5epIentU%jLLh-%UeCrf^SDc4COY|d$t0=8m^rD_tLvRL};zZmi+kUI_z84 zM()e_u7;}Sp;2A7I?ub>&w3kT$$WGW5z0;#h5%l=5p?=g@Z!q`_hu8T#roc^?3P?v zl``|`6d>r|5InVoc{_! zdN+2|&*ODQjaKUg_O{8v6_ADhd1ONzXOWyvV1O5 zt)?a2lnv$|4@0D8GuGVmIO!)}kN@-=Ax)MH%Uf=DDsEd61<#Yo_a7561U&XRHP^po zCI>H%W;>-?Y9=e9m<_%{7DSdDri!YLv#M?Ip4_Xk1wrn*^!2EK6ytXXu2LpHs&@2D zZhKP?r$&2yec@zyRExS2FWl9f91afja7fjc>a2-$#LPC~r- zT-XJ%I;&BjFoaDskdc$)_q%PRC@7f*{(LaIM3;)o;-)c{FVQ`+s+80$8GW*~Sxt() zh|A=#&^j;yCx&|=x~XPsiI{Jx!e8f-V-fh zDQpNZ4Rie3&dwY#$wal3fqR3GXNkv87R2cC@`QMJ%8p4bKqEaFc#47Sri$%yyV3?%B1mXLk0m~+M>en^LY2Za%SNguB zh)Vp_=J`JKchbciZgzV2-}5T}+=H<9-rMh!JJf6g+=u?G!#vg9njZdKxFYQg_+Cjc zw+u_j>-hZvnI)j(yU|p=9@hKE-PypMTI35{G4t&36(=bT{ENgNY%}Wt^GX!3`dNRm z3U7y_9>_DoC$9f~sePD^J}1vdq)l%*gTgIL(zOy+>$7?K;HN@7xqC(aP-j2Nh_1NL zf_n7sX>biamiKId9G*%|f2Hss$!(Z)qb(B#(|D%}n#yUXacos!m)DHeY2l=6LCl2J zHUJOG^Wf!OleFPGo4DUHVl@$T^JgznNIeg}1l+}I?g@cib!|4G=iE48;pD9K>zA$v zvvd~Y{yYnm93wKu=BHMx9i#EOZd+-!Z||<9YT(>oW!fT~p*-*FTcqmFRhpaGG5VZV z^6(}w<|6)wkcPXHoU8pXYJ4@l+xPyq>r!I|IUyS3t%-#71;2WT?5>FATcf$YC)-;Ex(d{=ys z4uXoEyw?tf?{gPB4oBaPiC@Y5ec}vo&#Uq|xw9SjZ+s_ym|*dVP=zN>!$*ZPu$Vti zJ}Z~~E|uSv_HKM4qHO+4|Gno_=X=4&B+uK`L`!9b$A?kWfV=)=o3EBLoQHxo3bD#E z6I^Tz>%X(+$Ugkl-u3_D|MdMt>LSx`nA9OxTubsi^HTmw&PvFx-V&OT=eW(|cbW3Z zxKJIJ?_wFtVsf4x8@m4e;TQJ5C)pveTV-wN$4|c;JUX}4@#>%g7f>pBVUlxfEDdk3 z9;bNR)6sMXm58OO7MQ&$nCtDZ67Z3ijGsYDXK^(>9o%{EqzPwV^(M2k6G;vs`-voT zGL{$1@Z4PPGZp|)qMIfM<(lJMTJi|nfGhqWt~Mo7v*5dX9+$`0L?@6>g%(YGlYX=J zGI~)hU9L~mZunxPdN*4+i2WAeh~}?{&sl!!^+tioxiZhrTrG(aHBuIcB#yrs(2$TB zc;}0jQS%|A_NjCPlq+bh{uz;-^t`*usrYGaGW75mM``>tW%2Z63XB|~l6NY<~l2$>wM7q0EN?Jm?ySr0FM7kRR=?3Xe z>F)0C?z#it_uW``-F43&9@g@lz31$iJ$vSTpZE9N-e=MYWn#=|(zWtyusfoZ|C8|( zO|+X>>!(mJm-{HU!h?mHuA?tmzmX#vD-d2B&dK6@8XPY3xadaE(6kl}n;ne9W;t_r zDdO;E=36?~-;PW!>41#z!Ft`sQQ1w;$PGUBUhdlU+LphxD2}l+0*+QZ^kx@1wC_YQ z_;_`$zT+IY+8WF=AsaT7uKl`>tPPYGy~J>H4SZZ&nzI$;RA!+NA*mS&!?AKmJ|EyB zXt->5lUekx#&znXDq|x0>l^9TZf16&kaH{PHHb@-b{ht}$w$ue(2w===ii4_PPLOC zU=I6>H+n0YG=IEzuh$_NciLsiNO%53bK1ZK5#0mLl#HoWStK5vBH1*B=P!SVT*|!QWfH3V7{sS8+dR^)RjcW!18L zXz9BRBt0W(5sxgGPk)P{qN6Ly%dZ}@RnltK|GvHJPT$~V=sD3;D_KvGNl2M?+o>UY z#5(P1NXJ)W-(fJh>aL0@oV%R{_8Zxk@wdYPHDpSIao2O}Ry=Wwr8KvP&gNUF1pBUO zmi+DEgUK2Nfj_%2&-+BnQgW$Unl9n#w8PbSh5<88X{hy>k+RXCeSL* z<*jlV{4=Rkjg@_S7k`|7OV#$R;(BwCr%E!6pw(N!+1VM$ufSRtEV?^$?At}F4tUnD zysO=vFW;|n=6mAkUryY+Z_r&ECs?jW243d(v2h;q-ul;g{Jn_nh%44-mLXHOGhGcy zZ{-3a1EDKt&m}-sTmEOukk%qgvGeUCyNGX@_Mg9b2O}lDi{pADRJ+OBo=ek{tj7Jo zPjaV`th6@i&U~q_iDU7lbIyD3_!O-}<6jYxSaD;{NGOuU7qO1vQ!}@{F#EK-p*;|9 zUe6D|%#zW7FoK+Z+I7@B9<$FTYFmW3kTn4@3+byHt-s1 z%aj{QR#e1Q6Fz>2ByG?nKtuc9r0H=ywosVO{jjtZ5-h6Gilr!De{)N{NZl4HNJI*?- zmc4RYUVCwvt>@z{##^-Py*>UgVyT>eK<7b5=@FF}aGdW(Hgi0hlv-h>y;S%ISXVsw zftf!csj4BEpV3q=`@dMgJX1}Z&t&ho0DefQMy`OohC@+?^?YbT64Mv5K^<-5*sG(n z5I9sAzYbBVHbGM}dyECme4ajtOFi2fT&aY#G@|85uyR{#?^epGP^FpBshDwx8*K}v zGy5DM@D})zT_h^SvarY#@VDd;W4Lou3U8`d)t^ocDcexc_D^CDT+b>Fzd}OnGu(nC z2YcFY#ju9*hjci#b>>VS5ImbHVk};V_?Yy${QpZP8)gRKa2SQ$ltL`u#j{8;v4iv@ zFG1C3Sf73|Su9JTD;nOwm|in=SpKXdcE*Q$?9|PeA}Ti4&1vxuI*G;%Iks*4;rcfp zAE5B3>Hk2-tOfI#p0XP{CA6nj0>`&VK(3w}MqKp7D9WeswXS0Js6R{&%NNhb{Kk@U#dMa#hcST@LYYH)vw{f##Zfx!rO|4t+AG^{ zT|1nF{fvjZlK#a9^`UXD`1kQlg_)mTBMkS%=bbazLu0TU`Dj5*DU1MRsDK8R5AaU0 z2SAg&_PuX8#VYbzEBx2#y*XhD)JGwq;4k;5Z~#3TyQI)0o(Yt9lg7+Mua}`rftnT) z^##p0Suw|#yp+O`u!c02Q8*qfigN6z7Jx{>mvxTNSLyCmJXkeT9j?SU6%Ma1f;`^ z4G_p6l}Yy;0`e6`74q!TriTL6of6*DUwaY#-CsDxuA$zoeN=Cfcy*&d8TO3YG^J%f zrHk$5vfp}*i%Wfni~a)PTf2@E%!!#d+EdKK`&*sFiSR=hs(vwl@zJwu#aIv`jE^KK z*sufy1=Twrr}0(7j+wIb&{5McYt<$Ak=qX3RCE+AwF^vH_&fs!ynMEDNsA$5(H>&uH+vxk4Pq&fcs0I9Bo*lF z*i4v+S85=QnkZxU!IazUDeja}`Mpj8M~X|pQNrA_G1je2&ClJ1#MoQm-y>)*I)$PD*q@6?dbpCpn+gc11p6;a4M6oy z^TS(g&5S!#+>5a8jzDAJGOx4Ki!9RD`1RBAK5d=564W1Z$u0?`x;TrH{cl*!5tQyY zRQpaNN|B9OzUb|@#f|Mxlufv87rSpDT=-Hdd-VSVXkxwAw|uP7X;ebuy>fGohJW^M z`L3A1ZXhK@1L3`)6Zzu_rAh6bd#*1DLn_;QLc6>hmAfgs959IpuZx^;QC+|jDx^8%dwm4GO|WtYGErEPAV+(qMuw} z(t6`0v%u3M$p;|K0D6`knF%}is`r)w)#c?AdG;MV^n*AG(vUH8nhj`4@ZVG$HvBt zD`rUddY^!_^iM!k0fil!*AcHIvj*-3Qpuov`-v)-S}XJ`7@rJq27Y@hSiJw)#YRt= z_+6%gNo|uT<7-2Cz5_b=EkYJ@{A5rT7_?tGVV*w?oNc~^u06z^o58>E@S!9kdR#Ru z+uQ7JQQXIzDnI?#Jm{rj;=m0Y=>yPHjCa4x@Y6Q4M>L;Fj`=4IBAaS58hZotDJH0! z7X-zZ?IRBcOFPVN^dp~YtO zJ#XK8xAG+`|0u&ou~_F{8SFh&xGFY+Vd}83!=2qrRS9#~6m4{ISpTJ`s`D z*bmP8YqOU>{6Fw@5QKKg@^eSTs9r3%No5L)_dktDj_l9m0CYKKTJc=ON^VZvQipcvJSB|&FC=nf z|GY;^j=*acuDJ4_sgNzx&V6&Yo@KcNLK%MoS|nOcu4noggdOPteBdb{xc1MNhKG^WP-%gHhiukiq_7-ib1Hq z6E_-cBp`i)Oa!!+$@soqLO+lDKJc&rfraT`-Z}A~THfK~A6zRvO)9}pQ$MKd@(wl; zAXqxBI5eJWOBueWoW# z*Qv(4pYDO@*Y$50EsO5H7$awt7Si#ae;(2~zB%KjPq|>e?sZ$=kMHkU;w3Hi54d4` z1V|&Xf;(nrRJV(dcwibDOG^v##PyiB=7X|6!}$LA;pZz%;S%Za*x7t`+>Fa%y9V41 z*TjePM8+opwWbgtuS8XlQecpl$ypd!ct@GgLBt7twD*8pqY)O{P%j~`p# zDXF(eBY9FXGoxjn#WxpL@PBzFk&ieo2MTuF1*N3M+ec2N`QQ;yIv2%*J1p64eXqnn zhpFP>5_O?4(33Rc#sRaxCIG)R2J9-y zj!zrz9yRC6P109iVM_rz{KHT0?WkgCQdu8p$)Kv}9DP3lj47TWxBf(-XJbBW>0AX+ zRl-L_C810!%i(-P7@`Qu=Rv_p*lpXeCcynJ0!=k2%@rw+TI>65vj3%aWOcUeRCrW8 z@vKhlxO0+v#u~R6Hb@*9BjJvwE|iPT`*iRQv9uPXd}&5r`uD|!MXQ$RI5^fEq2{0$ zD(-&Jz$sU~jrjsp$Dl4CJ|7k-e4+8a*vV_AW)cJ0<--kO2cF7yG?2K*&vLh!;cB|DoDvNHplgjZ?MW+!cz1ZKM-5DAV&3 zz$plVFa5PPo z8$%;iN}IFP5NPHOD)ybZ#G7hlpG9kX;NFezuyN!S-WUD`6ueu$QvyKxh?!^ag7K_y zTqR3!zq_2&q@bY*hrtg1;Yt>gaZxTd`on;ih$w;1-VPpJ2>#Yy`jNscH{2#KnufSIL4sFa3=aSzX-TTTE>Y$4?-pV)D4& z@Puv@cwRrSRo30BdV2mQeP4g%d_P?PK^WUR4DaA}`#UZJ(U<(SCA7~gbo{BZv%)!g zLI0{MF1dW4anmY2G;__1mVpc%CQ{M|R`bPJf;AW;$v7^4W^8OG0H1SM|1j?eibhUS zoG?NlEsUNHT*vAh^@Qhj2|At~i&=YAM0^6JPQYrmi)N89N7 zX?g6kB*9R0s}sK_iI3v)#KEGR06;jQZ6G=gh@gol3w88>|$$`5SjO=Jt@ zN?K8~0&0pp#Jc+Q#LD`docfW6ldP^jEV~XzB&7+5f|5SFRv!6VAqq2iFh_$Ugi$y9m2sRuR%2&TF zBp)l#p|WN>>`*&09fZv2c{GM(^^e7Wkk|W0<86{0XU*#K zV22*m&hPV^+G_XYi<@{5&D+?Gorq-N*UAxIml6it2S2{nvyf?92xE>spk&dnf%TXi#aN7yPY_k<;(l-l!y}_ zza!PUwd`TeR+ppToMtvKWg|<#RoUZnm%EJbK(eB;issDBc~y_3H&=Bm)#wT9%%?T% zcyDplN$?FR*1?~s5aE|7Mof-B13p=Vfb=5tCz|1j)%dQst*ytScFrK^9 zN?UJ48NSzv_pw|yl!nfQkrm%Y#%0@3=b{Qdr*M?M*VPJY*M)|(mn9G_#>soCZnO@= zQGRjTEf89`@xN^Hc8b(gJ>fUB7rU6XOIEhK#<_*QDr6?%aCu?vFVR3_q$ePtA~K1; zGQz%%N_OE-G23AK#b&X4wNs{n)aZDCj;{+(`(Uu_*2iHZMnoz;P)x-Yl48I1fjm;T zN73`hAO%bQ1`(&^y^~SjRKW|em8n>Xs`y*DiKusQg59MkwxR=Zan7K0&_ehVtpa)? z*~NS*$_4rOFxH1M7|Hmg$C&`gRwkWENxa1`xN1%IPGep1K4g;IXBVaxii#;Y34&Th z>`}}*x)Ii2@W3WwGJ(0waGuli?)#*s2VjuI&Un}x7%p~4THT#RW+qD-&FrVkD=24I zHSli6BW=8xs4k%UEOb#vjmdU6hLZ~&&-=8MsKgjrBpfC?>&NhJE~QN)Y1~PYzIuD0$4yNt zNg)nzi_7~e6rIarrSva@`N?Q@A8vdGPr2vzK#wIVsiQ=&Ji%3AqE2X(v20|DQKM>G zWb6d6HnVm6QuEII|KhYJ~OCNAJV?I{?0;oM&eOf+cIlQ`~;rm zV{{mYTTA|E1l^f^q6>a2o zS6Qekwp2oEeZy(9vl5~3H zcjsJ6r?QH^?7>c}u$>j5iGteZg+&(yXFU#TU{ITSz+g0%kbvhZ5@(b*fBvOQH-=4D$aSL;`QWHWt3cek98KE%*!_OtwN@fQS4Pl z`^#xb{kH+?RW_exb7+_KW~xFxAAFlUDs80>7qBYZQamn-@n!TznwjlT8|dBEVQxcr z5Td>(SADoAv#*V~6U-wchzsV1Nc(`YjGY`YF?!bw$;PmUd8ClN&}?2?%^XTD97iK{ zFu?OOyiJ&hyN5frj3kkxZRf5@x?j>e2(cDz7+;gOR{$9Fm=vi^)SYg8` z8psWFH&AeW#L}yUj>TIr?51{odzIXgn*KGoN0Hd>3L|xOivzz5_Wn}h!F~7o^OMLkE%kU`IZC3Cg8|)ybm4L%8 zi)}b>iLJBi9qWe7nrE{5c8dFPilxjDMVfida<=x=JhNq20xv>@mOgQsNj+yAf73=* zw$V=ML!Dq#P!KPHM}6y!V@F@2+xZR+H_z7?M%M&8KWyv6Uh6N*H`#BB*m(Xh(#(ux zZe8^l9ek`_;26XW?>_G+k!mh;3j1>JJ>6$x!q=UKbl6zoe(z26W?t`Z4|em+$yKZL zjKYre0x^HC%3-&W(Qf9q@XAQl%Q83;iJJ0=Rt;9jQwin`k3!13svC;Ai!&iRYcaQs zs6MgyS9K)Ff5-8Ei7FzQgTN87Vc;DndSO;jxByyN68c)4cH9yjeWp_-yrlhTVxlQzhtL)n2YPG8FgYyx0_Z zbPKW)rk_(HyM_6rb&}oeMx&nPsJX;T7D^8ZoKLSRgOiMW#^o8FJ!rAhfT~kj&U4~D z23Da=*8TdhL)KaFjgSxms77bY5Int5id4HCef8jO9yaWSDiCP`@;8Y%|J)BLs;k z$x5JMcH+dcHQOlWy7cu{UGU*g*$&10H=0Y_w%r8YT*%T9iGgz|WDJ9Lxk3yyGoisC zI3D;5!WQ{Rt+l;I`+yST(`YH3jTkXyb@ilccr7wLlB{e>3FN~&+A8C|v2Y3oo0xIZ zrd0JaN&E>u4?EAA*3T}i)RdCO0|&E??0gk!*7V4Bt@J8(Uc^4ve)!BA36?rURu${$ z;xQMJ>Y?3}ITbC@x2$^{NlupLa(y)(W^9L4!yJ1-EZy_QLDvie!>T3?M(% z+SDB(g-GRxg}vSuHddaxyGBqC-cWT`u0KlN7)p@Hy^Nkko=@hW=RWnmoE+$xuCSf1 z>pkK5sgwAXj0)vtng5C$9u~$sYU;~*1(EjlFN)|~9@PB$u2t2x-{+=L@3W`aXDqV->NRj?n>R7(cbn0Xt@#7PfsxGaXt7<+;N_G489&!Bf#$gO@>;YoJW5;oQ z_cjG3F^(^-2K>>g)!J;-blSqlavMuMZa1fcE|YoEh46|OFW#p`wuxWhIx;3imb@`F zN2obB@?u;gG>-Sd+k{qR zBKp8}c+daV>SmA7kl+`GYeXt1@K=41a6nGE+P_IjqEkAgLf+-FxVS>I(Y?<*%z%8n zJ7hhiL*8XFxR?V@2^5|Xnv&bQ_63c4{qimLBBUm#m6kJPNDE~; zX33whx%%%~;uON04v#nts!T#@;@C<{Q~AF;B{GiN+O^zSxSg1`)*)kZr>a#IIn2Xe zTFh#ZuDBuN&#`@Y=fBr;s94COfE%q7-&^kQ!9eb{Uwd!R!js+iD?u*luvU+Z5`LV- zeL=9v3#=F>60LCQ{!lyEi^mv8MayuXwHno(Fn@gai+3-%ss5&5cUvQ-UHf6so6LKf z*=E`)fMbr-5rNI=Z336mL>zH;dM0w5ZV2yRNtyE+!9|N+CsrTGTNz_r7{1b_KPuhA zKQpdg*p*VtP8HZpqj_&9{*t7f)tZQp(Z0r_JH*@y$jT^@#$VfX77WEZv|4RbI>4}4#94E2!280M(2X-K;-)eB)@|46JeP=0GlkK5qD+Nq{&F8D;kAWj$(H>@hrT^? zgtyt>q4JC6G|x^679tXE?na{xtNYlyU$cqld+H~pXGcSO2E{5EQ*m`V$BD@2>MqXn zD{Z^qxvujUJzXm9ad!;0uRpt1ST6StWXYG?P0v=!FwWOs_4iLqHc3^wZNXoG&-^*JM?~*o>Lh09 zJu5im*geHIRLS?82Oi^JU*9n6w6(L#OuV0t2WVg5OdE;;45LKu2R+m(jqh_}NwfVf zYmJs?Og7wN{m3$^@wsl>tWb~>=c!zm(o-6lc=@<#M(@Z&>n*6NlskuT7fX%XdITYv zQgD9J?M*%aGw=KGAgvhH@b9(c3?z@F7VXdZOZry z6(_=p_U1iXGK;$=)3JHfC@0D>bSIe_My*>-)c&H}c`I&Nxs^PQk4_nQ=M5d51noloeteR{h{O&doxFL?j~)=t;ZB_d74#T zH<~e--zT~a*m7Q5_-Xxh9*I*a>lZWf$zr$Kjn&$4zH4s|?%`i{MkgkWFzSPu2|IpL zxS6H`WRoW#0m*P5Lm_X28uRNurolN&2CId7Q2#3<{^)VF>^EEKazZ?~$9CYgHE-d9 zEg^zD)I9Xg(CcEEFo{4GrVtB2<>pq?hw>Hh(%O>+0e`~nS(#tky zRcI)PLE_buGX07SzCJtg1i&OV%{7(%>|@smzV*R_%@g{@3Wq|S$GEr zd4=`;p5sSR?>I@)q#Pv|dlsd{ACxD)YKgt?n&y`ps;^q*y{<>kQ9JL;?fjVa*Sdz= zeuOrwA-dn>l9`Ws!Ta7uwos)wZ>^tm#IB4aJuvyL6!k=Q+CDE!ALs{R}I0|MBUG zpiDtIo>=;u36JecC#`b*sRA7%|4#3Qx2r`S?zBvlP6x_@TAu-rsQAuj%GC9PrDC zry;LOr%pn1Y`W*=L7on;uux1?6frQo1t_iU(QJ@2`UMK0zbGg;pFbhY?DuER0qnGW zSIx3!9e9c%Bh>9>(E<0WYrvG4EY_l{k4)lVF66<+yjF9ZbYm&`ghNlsp|0fW?&cWj zNI);6_~lT6hGhI+QF^d(T?r`f0j0{hKZFY8F!wL=@+gZNfrTkh(e>r$Q1g0K*3O8n zxTsG!AfVq}+j}l_O2nGa9aXHpdjI<9xIP7>jyxfT;rhhuwPVE8(Nxk8;I)gSSI(W|)-s z!+*ZfGz~#aRaEnMP#3%i!dv0W9e@Ar4heEJx&tb!$pAv5#1P`pRXA)BJ_FNAQh}8n za_c8Yi{W4M)W?6+(pj~RmiP=g@(l+OhQPh`EAgky5V>Q4KNhbb zM=v2G8&-1}?if1mb)B|3lz3p{vCg7Wj36NokGr0e_pqo4e0+Xp#VAVvA;=%F!AX1L41qu z!-tj_&k~q_a+wLud#as*Kj)9zXdOKj^#A9Py0p541g|V@e{cwF7M!o}jW4e@{G*V1 zQYoc1Z@4U!oTIYWyI(OrOfU=?6`LDA*MfHW#Yu7>%YbtRxR=W$^DQzIZ15=Gs(Q z|DM^@pzj_u8#+g^&Uq50IMxFGp=^rA%Ypt`2?kivHGD)`6D6=AZ{O5Rz_VeQrw?LZ zL@H=YTxk81*UfoHe<`}=6L$jKfG3|mpoa2Jr?^?-$v&C9#9+YLStLto@zX%vmqWU$sNcQu=GieA^@d8QStDV58XN{S04d?r`UknZs3;(j%91)L z%MpjfGnH8>tNi&1H=uD2s+@qA%UJ2RoH61GMr9RZ2OfnC!~S1MZ%7b7ny{a(&+giy zcJ?Jtvkly7q8+L=>Yu8lJH){FpqJ59QHYlQu4bebuRHZ2sf*0wW$!3)UEY~n60kcs zu-Wrz=PEQ%BsJ)FW0wqW9bdChEhU<*ObHn!iRRR%=rQ=q0bF>Yt`+sLzec;*5$SPo}uP3Y< z4~br--%QhSLXmjeQ|(6}y>PQJ5CuybIBr!uP$g-qFKH0}GaytB`}3QpH11kt1Z-x0 zs6}IW4A$UA%DdR}#Ii=o3s7wQUOru(KR!-hjk@Pba3;DrtCmARkXvThjg=2SFUp;@gC!N6Y$0*1Jy{AX8 z7o#XJnZZjrLaxvKYPqy6pLc4pf85nVW2hTNKlc>LCU?U6wF;}*VII+K7bf$j_u5KC zb+XNjU_QD9J-g=~F(RH%m++q?k6E4DFw?r9fvn1GDK3lU&|~dolUwTGB11_y-}5vy1_5nWmC4KQ(ia-Ys)e1_l@u4PT(X0d zL5P+cxheH4&cztSA@)UEdREpEV&lpj^bQ&y6Le;6QBV>`(%su|0#R^;=f1nhcXrS) zXJh)LkNd^e*QBX47!T-q!20e_C-B;tx(?^Dq5sALT;d8$CvmOz0VgfN8(P~Tyh}+e zH|^ytpBh|7 z3+=ujER+ze#N-Cb&i#lE{eFC$%1${LUsalNA~9?>hm#}$-A&m1Us@q1O~#3tXxa}y zglAX6ie2Pu*BGYNzX<1}({h;!!E5h)#os-V=-|w!C}Xet_Sc}ltQeOpy0*(Pq?^K_ zT>_t#nwB8mPrX+%C_nDuR7Xs9*`PDTh1JqM&GuTYSmk6F!PK$o&lOi8Q0|Brh3l&n z7p!v0bs8XlQjFOXN~4@{{Hsp^Ve7bQD0PrXeR3*1l{!{3XEFW7=v0YLT`BF|Mzkrq z;>H)M7&Z9;Wi^e0$yon@JoVZmDKqwhQWdvfk^(=EqS(LxEwx>~)AOT8EJI2AV;Qhs z?O{8|J4L-h!YUAA65^n^pY|ZkW(9Wxzg@Q>HO}(wCwXdlVdod--{`Iv#VP9IvxJQe z=19_@LjGxE@JjDu29iimH|u<)EGlX%;m#w5*qgyg%Tr2y((>F>LB)0=LV=u5F#|3z zKrw^#huF)3`u}19?^D?Ju(#fjrme_j4)>hW{MrkGHo$gJF5h4Kt{6BcY^ts>tV7|U z)Oczwt6(btjuHhq@NJQ) zI6K;3m33zpBP!o-lP_W6`!laNN*;yAzSeC@9;6g7WBc|-w{tcYX6T@_%}2UnJJM>Y zPI`>n{Jr~C)1jXMK?B!(ckkCPtA!OC&*CtFC-3$nUda%rXmYoA+E?&izPen2mbVfC zrjyWCje2sH?3U)Y9c})+k1!iX#nq8zZjQmm!NAy<>Iys;(MeQauh&_kVev2iB4+|k zdaJ;W=b#JydLkRHoA$}yv@({o;R3f0nU#P++P0x|r6m<_jAqoo+*9A?*PFS0SU}zJ z*rwYm6fE#tfhcynJSF)f^BIiVG7nQL^129e!j#@(UYpeYryrz+6c{IL?n-A%Yc5Vv z{y8Npg%T&w*R*RXFeL9M?WYpyz8DrepIWPL#KFlE;98qs*O4r^S82~CCUZmN7|SHv zh%By^h!aCpZM=Hp(vN3X7j3T5U@9oP$bo32(al))+Q>)>g_V#J)2x}AyU7Vj1Y#9m=o3SW7{OC7|WZJ=h5f-cTHffG+Jc&j= z<3b9VmQ$yJXn0)|etS4NU@T~DDWd+Ro~5jcy11!SxQdO9P0hr%xdo|F^0(HL3Va`; z{=*Nj=Rc{a*gvZ%C}Jf?y)nWf;S{$xZBN!|cNnG1XV!Yp&6IAt+lpiqNhT@Tz&)C+ zptc~2y!A$2F>2TSVWRyHjnBD%5(^nCoyPro?cHC7i_xN#7K@!>2dQZcFkW8C_#*8R z#Ma%+8}u%CobLA?e*eTv=C!-rW2r})EwP)-d7mIKBA$(mP*yJ!V1JU?wPoyEN$xhk z((j_fAQr5uqE2~p5Xb7muUN|IRCO(WlT2|;0;_0*Vd8}#DN(fGj^5lx^A+b@vZV}* z9f>G3aNXU`$>hy${Jg<O<}KJBfA$8TgFa{Hw&WM5BI3nmla@QIMmrx)DXGG3yXH%nXJ;7N*F|Nq z>j%GDbia5SnC^lRQ$3eBHdCE^>Rq3u@$i-SoF9`l7Z)ZJvc(r$NOYq-(?55IF1waU)!6}0i__vw;2?-a|d#&yeY zkY*S^BwU(RMNi4pdHSKe3&Q0(JP3+_?2UQH?y0_3nuQC$qRfGx-$(PNESopZlwJ!> z!||f|2c1*0fzt=AFO4qOGbQn;1W9y=Fa?#uw~G5{u*mC3*c^w;h(49g?wJkuN@;G= zNletG1*weew0YXIoU#g|N73ySJ-<3B32<@iA0Z{kMj-v*VS?S4Lhw82WmPcZu3>H4 z_qtERZf0u#M$&xc5nBQ#!4Wuo=TS2gkGjd1^hMs0 zy=iKF&X(1pKauGo{Q3hDjD@VfqVq2%5+b5abrRVb@e~1+x+oVO;e3ePuB_thtmQoQ z(u@pZfi)$7pOa4ErTLk&ZND>?o0j&G8QMWVNmXsFJThor)M1cx9s`S_hmK&epLs4Q z^HpHTTLY5ljvLZ7eIX1qo$wZx^`_vTRzI-Bcd|CkSCVCBAn_&p45X&Ls&t@x2*cAKNt;!a2=JBO?pJQflbKu^|_YZucV~8)SPlHim~wF9&t84o(>cy^jP)E z1h#qAJ>3{&;o5?+WQ!MbgDv}L+zH--JkDRJJHvOcYa>mY%zaj+#B$%ij)OKD7~@iv z>kN^qs3Ru2?2}db?4?lI$ZC&gV@G4k|K+y~ZBWH$P-G?~BqgS%nQ^}J!NR2mW7L`{ z=1*zH-*h+*tYK(91DDKsw%&Q^xl=JW=1W(yjnb^WrrFeQ@9$p+jeYwVg^ARY^Qj`M znm=r?OpBs?okZ2D!)m5ts+}4yz+Q!dd-i2@iq9;CGc%;0>rtL^$cM>O2eNU`X_(Hs z;u{{UW_UrY-opQ}OW=SjzWe-9 z%8BuN(kRb7(|qKn8E&mxUVi9ycK+_R))$T`RojgRD3&eeBW&b~%w>p|5a7j*@9YKM zzCxO4y{2l_w#}O;u?Qn&{ak3&{-%i`O0Hk|gPmk`?ks%;12*5u}W9-!}MUj7D#7h<_ zS%nRz9JcZJe@U}B9n1lw+9>n1*V!~6W8H9rkPxui+1=fZ*GQem1bouz5I_h&;9LhT z<_-1r5s{HtPY3;a2O7-J!e0ad;cuNmmNS72mC4LFj)zG;j4!bVVOlYho$T7PxX1_c zyWHGKeJrZZz}Gq{DXF@;8Z`9*SXh;IK-HfPaDj3(>M~F$J6mayUsPnMxVpT|V6*ZU z(EY<9Kh?}TuLeI^RvQ``-bS6h+o%8cibA+@mfV5g)*7B1MR`x(9VB@U4I_T$CbkFB z(b)-Lq_+T8etCMD2yEbhDD-3U5{Sw-fkYnTDi9Cz0lU3h;2X8gno?3iA1q=A;9#DW zd3ilCOD%1FC>UsHYwPO_gnVbCqgF}^3V)w|G3Y*oqX!6xkhbuC$MN~kir<=>lTqK2 zXF}$TZj(yJ9Rbslh+8J$s*pY$myjUd3mDlT)>a3w;{ec2qg=97ci33gF+c_APU7M_ zM^rL0GNthWfq`nG&@j-@HMO;Xbiu~VTrQR}IBa+hs^&^dODDR?VR;!KS^1lKgRq#o zp!W7QpN7fvi{FUd(EiPr3w&|`?bMr>MC}Qca-3fQmbD;1|0&KV<>uxF3~YV1k`ohm zS62m5`R>m~>s?NXK;dSK$G2Aq2yRQ>u%JL26A!O&JmJzE;M>WhlL)yEfgum+ZD`EZ z?d{~m1U{dqJHTPayaPt`td4tAEM^m7>ukUZ3jksx?~Uj&joDbur}*LK=I2vfcXGde zg=o-}xh~eIo6u)uAdCSPqv3F$vav}C|7|veHrEB~));5fPmu_l@8kN=stv`U-KeCJ zpp?(~?zq#0lbHA~qtpQQwB4P(p57{epcmLcbjz$My;pj|%mPNKZqgUgfq9UG6^ZA& zn9^I@4Toem=s`>H*e$FA_%}fm9wFo}=`mRY(|$ zLC`0e85uzYd=Hhgmg!O{Tuvb`aF(Q+K_}e;{Js8vt%V3fb`veirI3^U=J6%+o$-02 z_%=jsb+!G)J3eyjQ_>1Wi}LzyHjT$tpklkJiEq`s1@IY5AB_|C z_&jy|J|}=4U2gNswo}G_gMp47aW9Gr`1$27kptkH~raeS=V&Ko8&cKMv#1%-wJv}|2%mk#KuE6#6wOW;B=62Klz7^=h64EN# zn-}JSA|f5-CZm9stor2(C?S!q8&(mI>^@6*yxRm8o6)_6N2_ zccy8tC&RnvNk!-@gV>ADZxdqpz|Dr2u=}`I#jvhB`jET&TBWm&+yIeK#SNhK8&^ZP zMn*?LRp{#KDl7{AUWd)j7=@RY*G&MaGu!8nfMzHmF3x+im2N2?A%KO7Y6m*yB)f|Z z5e22HRE+U8)E+ni1V8Z+Cd6lm*F+G_Du1-xbTXYX$W*kv147{IAC$tT9&doTS*#sk z8y|zI4|tM==I2vMfv3|PKqLe26X2SwXvmV_lTuVv^kmM?B_U?H8bKoQa5LF7F*!L( zZD9azDA2#4R0;4)K@zzvV-NV3(Evm}FjA8fKOq73qcSF#VF@W-5AiRaT10M*2Vspn zL;#TrtBaB-4UM-wT^_iD$@G0zLJC~tNVNYsV@Cqg{=q=?Fb5cU-LQ9{H>F5XBNJfp zoxfIAxLsQMw4@Fj1Cr_F)YR1g*J0T8*5RQHJ^|lSG4xElW`pant>@9}R8BA#0ElHP z1jNW2fNYSJ1#0$_)%|@B5~}?D5yu5VWo5pcw-9v#t$qF5jrnO|LyfOVAud|Pzr2hO zo9vSl&~jznPty&RxnV6?JGNM;zs^qaBuX?~>k5~Wk^+Lmdi(8>_1@Tc#H*VdP+3U8 zVVe;pSUeeducV^VU0s<2#_hgR?uPdBm=lNiE&BAw=eH*v73V=Y{LuLE>J3Wj3339AslasJeP-|;zN2|zBGa|pYafNEI$m-6{POHGEq}WhzuLyFZ z)0+o*bnUwr?WxvZ7~SAeA=>#Ph#5{!)+)NApyf3biR>Fo5t`qI)7-9Hrd)n_Lsz|rBZ zh;b>Si#OnBn%h_zMTty$ke+Qsxb^l%Tx4Y1)8$D0)TNu6Ct+e@qM?B&&+4ubSoIE6 zhG9*1{wXdlR?HVhX>B%Hx`(dFiEyBhWW+-=R(VPI(gCilfpUIs&h>mpSoFo0i`V*R zyHPlpxum<^*vnpS) zA5b<@#lv>9Ww&H#ZBzDKklJ2AfdhR#8%p$QM6lbiS5Qy@SyL$77vlmLK*=qgD-NUc za(v})Ylcs$N_0ZVBlE9BpMCX@OV(>ArqRX_v*j|5?AYvI!9gIxFdMBrjaaZTH(9`t z`>^yX=T)ux?#@ncifE4`HLEIAtA2dJEoyWM3n2Z(R~@ zuClYSaj+#n_n~j{cUswJvY`^j!WafRY05$PSFa<#!>5DDSqC0?Y&rS=-ZDOEOj7|) zf`>cCv|X8|aGR|CzW5&@Gy_xkl1%t6j<7fH@v+0eL;fQ)DxloXf*)pZx#w^(u)AjOTN#TpXPS4CltK)tk{Wdd{1bEIfkOB=Rru_lK;+-fd z48IPnX-8^o!A#h{<0raG%{LoCNa_L}G8xiGI05TKxP|L^9)s2w zxY-ns+0n<*!DnEcx4nro9js?|ht`9p0I!!;JW*s|kV9Ho#8oP|G(D)pZ_I(K!1UDk z#7vXcpcWcu9fpP10b}>y;o&eu0S8nXTU%Qw5K>TWu5xea+ozQkL ziv?MMzq51f&+R^a`c!7UvN$)_=S<({gOo*e4~TL-l_MG^kDCdlCvw2R?nKK$K0SrE6Bp^E0)w zT|ibGbl`cktTA#-a{;f`Tu@!jn8mEr3QdMP z2f;b6>)M>rB<}Y7@B53uV6|cGwq-s791@a=0i*Bu?c`n|@ARL`8MZ3}pQ@A|hK*{j zK}jzoW{O9jeR=Q{Tl=^e*7V-0J6;z--@@ZzsBqwMaaPNG|Knvft~J9(XpUbmZF9o~(8kC0wmIn(miR*|?m z{OkWSyGJ7NFQP+M?w^4nnHjh6KXJBZ_g92UjO|7{O`F(n6_Y$@d--~4cw%t(WuCKh z<1G;(U9i&Pq0E7?36>5?Mksr=Ef$D4Q}%ed6qc)AvKE*L3AxfdC+YlWi@$C<;%V$p z-uS^<3U71>iPfUL;dc7LeqWA=ifRZc4C(9Zqf;wqhWI!H1O}=of4Ps3`=@+?B7trL zf{MXNq(hEJAVX04{JHe_DJdOoZxWB-2bW-adO9c%{Jfg+O4{!=zY2*@WTbnw$?E6R zFj;uGS_Q0_7`XA%@jdiZli8Z9gSJU-2m70ustH*bd@1bE} zN=iz~WR5{Kv?Z1ii9t{#?IE}(yk-$x(X^| zeJ8--`G48(Sp7vBCP z)t}^xSQ&-R?p_E>rpQNF>mxUJEjzfMiMRE#?i}T=dbSqN+gqn4&&F0CyVq5aspJUn zFF5g_>d7BCEaz)EsmmIXSey=O4M(*FQ|1`=eZEJAq8|~MYp3l6hsrZEX;vE;1w1_% z4LEL0N-39RO4Tr7aPs)1-Ti5CSkF*xy{&`XN7!2Zno^@rMu6&njr;j=8)4PpZL7Xl z{nMIrMwu6jK#0zQclTg>bNBtjc0q5n@`@yf*wEMNfYw?Qda0oU+DJ^?;dZN|yen?! z%)z-;$|Xz%7Z)7FlQwxdy#9_ahN=z^H}6)s@6+@1^p74@-zT>Te^OoU9*iUzpT~)}#MbP4-iPqYbqOOQ4PCxQA}J=i9aK_iM9w$q0BC)QcIIO1=3?wpNa zSS;_a9#MSK!#%bP#TKsAiVg;4hCbAz%#`G}9N=Zb2%mDPN%(%_5wvKBzWeV;L;1-8Vy)HQ1BW6hBQH<9u=fZ}0a%Lv&6B=`g<;3EV9XFUl(p`@@BLpLU-Pn}+tF zP(l%er$)%XO|NwOK|{u&*WfI6hH-w9OEW5Xj^w^RPNSTYeBT_JtCr#A)$F4Y*5Eb6 z12uXj^zCDDwB+K`_SvEJRfN_?e>`b2~B{|5%0jAKHALLREa zk}s)eX17f}m%fCrU)2Hox0mYkm4EumO??y`-0e(mfq|dM-5<6vr~w}@t~LS*sEddY zGpqiOUcZ0ev-IhmM0^v&5%00P5@bKcziuC}pkn1_m^JyP_*3nV1ook~;r!WlkAkUY zdb{`4pFr;gn*nTLmEte&T%{HB6hD$-t;K?)3Eq!53 zI{rM~TCdKYmb<3QX@o7&YDY$A~)v+Y^0+XnD#-2K6N-1P=0S+t8Om)cF;|W%!SZD{7FR9Bo#!73LHkC3_x9%3 z=FZ6PR5>?p3MuMzUs7M=Dn`{ECCy_QkGkL7G7Rez(rZ7?C*zzd(z6~aN1ZS}SzeW% zuAv!xlo>64#H~=TdHP!c;1I+;yPoK2#NVyzdg4g#_U?9p0!E#^M!zZxPvy&9qAMO! zh+Z8>ji%iVnxmdB^f7}yqt&7fDmQOCnFuXw%@9+8 z<$VB6Ws615N3mFNJcXW9VwK&ae$-#LifYRd3V!EuZjuBCy2ZEgUUzb-Twof*D`)3x zMofTneP*Hbz(Of}T|D99>N*}_b%}pJTlOhL;{&JFp1ti-%Ln7t#nF`BgJF-o+xkZ} zLHzo&)`qx;vrum;E2(*p&4*aH51(eOHIh$pHKRAWhAbCEc94E=V61cq+3D_n;oV zh9VUo#gI~OhRz1Gc{1;VK&p(<&|7r$2*wF81Ly%@Aw@;d66esFI3P||t^BJV1hNMp z#FE0-CycYh!(}TnqMMn*&db~tKVvoPyc|F9FHcV|;4W`604%tvi3fh_N2hMz$cPd2 z9tkhSfQ~V(^kPQz{1dX%;~6No@Ak_X%vcvMom4&QyxL3$&-dl_hKSN6DER8xf{45f zlN%{=xJg6}x68>)W!{45oH8(#MWD65{yL6Mec8=hMCIjhR-!O}17}_l68@*lbb6}# z;I7f?yUyeCPsO5=6&aRf!#$$w#T_GY0}JBj-RbaSi0b>7Lsu(}0`=NEBNAX6l|*)i zl8K;gkfHW_DUcl;T&0T1Z@;V>{1R2k?k@QDtB!n|i zQ&TfB9luw%u{i+=a1CbD03e`+2P-WtQWT8sARsXJZavu-qz*>@9~RIft7){#5kqXS zn448R>%2;3__b;CAMKht7{Y}Y_I|+~Do>XssgLx{zjdShgVEZ%pS5Jo6FeD*(Wi=8 zZb}+*JznK$dden#+(GYH)olc3GwI^dlAtnm{}e?#GKPf5>r_n3Q7mIrVL%NjD^_{W zdL{1(l7$N(vwjZTnM6ViELu+!gpdbX&`0OK)kC6XTBNr(aqTaeaC$EHlqBF2-d{U1 zoDIV0eEXh=)K-$z{yWaxa2*jQ$!P>c$NL5|73{fVWS zNOOC7;;JqS@yUPQ5QFTtHtqhd*p`-B#W<}oJyx|jKdl^L-t`ev&%HS}Gs1bEFO%y* z;0A6xLz^t;MyYn|R+R=U&o=vi2chP~g7`)d-tj^~fTJE8hM!TPY+`wN*@TT_Dk+>$ zU}EYFrIX*0y|KyUYbkMhX!I#l@F{k-({3>-RRSZ5-edUu&qt~3ohRPD^7KHFXTY5+C7j0W z{HyyaTITPMQ?v?j4q3FCaoLOaPLKe^DQFc(97dU zvi*x=sZ?01OQ|pZh`>xu4PxAcgV9Okq@}axkK3QqS2UgUp7$=@UO+QP0GdtGQ&{B~ ztEs6C#H@G&KSlmlENgpqMh1zYm?^U)Hw5wpoxlA|oOs!*8THgkRG;px%^Mdo5Z<=} z_@E)zESOC#Yj~fHb(Q%NwF-a^Y)=U#3W<&Vl17)4)A>4)RxnNQEzgIv^Jr~ULaF50 z*WsP-ke)y$CXrCixManvz7(>Z@+>%c`BAEL7l3r?13Wf1h`wEd*mV=6TZ4|v)xkZF;`w&eyYKjuq+})`A0J;! zYis`{uk8jb1qihUn3k)nD|i3`_(U)epUV>lztcO|FPZh`%DJE4?U(u+O=LxFg>jK( zzIRcGpase(SPD0(q+0sf(%qWL&q^?Bm-W!|>wV}cV1m$d)FRH3_ z=CkF^M@{?Q&)42yj!cvBDDfF=e>5*3V1TWy4=Hy~*dJbT0L1Dp+mG@CkPv{$+<30q z+S;2(htBM>RW2Hs=mG_JVZhmw+zc2^);mejU2rU z4|TtaX?;)ZE6juM<~tDW%vb@^nhYH3(#H5@QvD+k)AorS^g-X|2{C*GV}BEzkl!dTwGZhSto*J zfUT;md@^Yu0Qi?k?mlo;5M2U5S`ZTxgCIyFIoQ^(4$jUJf9Swv6-oE7KLs-Ty4gzW zO{|Xz_ZLft;do5!rad|pAQ1OQ|QY@Q^VF3179b*|k2UmzFDU!~$NblHA75$1*!mKh;jw>VL0}dXdf=K^rCwh$9 zE?U+{;mjF5=qwQOFO_Q6ADwLtqP$$2Q$br>Ix$)i;q~b$7@wn}&ycoaGVydyruuhS z&<5H?<<6#1`2_%!3!cPI2xVo9%O5~{AcuZIO+}m_qKPWE zFD{RvmCDMM){aI}rZC5#tdIqaEGFflU;tt&N?Swjerm`kyGb)HY&sb#1w&);v@j}s z{}7WKr4l^`fD(R&xeNx z_~q8y?vKcRjcGB_(EPCGl8K-MAF2T~NYczO+7o9rn<@muCnv*#(zWE$`I6GpW{|C0 zFIDXxS6p|9>|kywF5LdCuC~_#?Q?)mLOKflCzAvd?*#)mWoZKggOu$R2!sF;898T% z10E7dVr^}0F8u*8OYS0FLxYEH1!n^9vi@V1N(WLc@|klTtK76*GH)L)hpY(5xlCwA zQs_VUY+iVtbRrBHEf6??O$$IrMMXtr!vZx7A&@>)#IQ{xS?T{sGL0I$13&Rs zSdiw9qKV>-YA}tDzCK5rB2@iAc-@zwcV^P6tSr-UL}T4@ta3Gf{> z@3Kz+zI8xWM)X-`My@FzNse{AyaZ3g$ww(qrQ7h@gy%Mf1d(%Y3ff+qjc~i8gLslR z8&)m5gI>W0T$1jCi#@<+S;^UA`VIbfIVC0a15l;G%utocGbNw-oNA#LEym)9Iez(Z zlP&d|UO}sm3i;8E|GWH8V#17GG<6P72Gao*IacZb$&!W~1YLIJ8vJ(=0jkC zuY||B8VO83Kx1H1FW;H{dr`0W$SB0Yx8g(TB1oD5PGTlEfEKEfAeTL6oVLO@U=L9b znp7}XI%ixPO*dGQcei3X1+x`nhe#~97ZvZ@Z!VJMiio#D;AxbCH`>&s0pg?}J{FOG zBu!KW+C}0Za|oZ+EiJ?1x-87h*k)!#5+Qvdq$&&O&9I1OuLPz*v40$wPs z4jDjn|8>*SgFx^|ZO8q&nAqriX`vzsv~|GDN!9!v<*$G(ff)E>sVT|+^4Xa9&}aQh zdV+2Kwp1t#?!I=$i5m09XBOt=zJyo-g8=po@LXZY8Kd7~y#jBiG_oz^CsMQAq(E|h zVdZPkRZ*5I=3!QSLhy@5dDoQ+9~Se=`3O6Ov3!5_zbnebbEE7V96Uce6ET5-V2b#$ zyhR~rq$C6@CTT5DT_JLHy?*&umia)t8xHtu8ZIht-h4GI7C&VOY;JBZ3N^>@<%gUi z%-ePUN88whfdCee778YE%7sHBVWTk-X?b~5{&atYQh_GrZegz2-s1R$l^^$O1I*cd zC~*a^@AG)}0O5Fd9;RXhLEn@-x+%WJ-|5Z&KekT*hU_Z)xVgAA05@2}nid8Gn)I-t zsj0~}(gTdJ1d;WL!^&zZjV5eI3KWoR6Ec~cs=AiaQb%Z8oVDbCX1HNLo11w95PcMQ zJ{!{5e>+&T&b*PCB9s#)ycDqG#ikP<0k*4j&1mA~eZ3)CR*8w^TEO*i(GurqA^VKE8r~;pBY6vm~nU z(cp!4BrkOhl}0J;vc4Oy&hQEsmzEV3#fip+bE*0+*3L36)Dcmk^DvX7|3e>-Z&nRP zSe=?PA@6Okiw7^naHx9=Fqj5-SOczzmRBTpDk-=P=Qb%y=>zW-Z~ z5J(i)ug8K{2euw)Ji(RE${#-+$}jg)N&U$%=(x0ZX#;~39@leg^x5nT52!b}NyFyo z)4Gr>5D^_#z6;TL3jH4oX+s|3k?Qau$8Gy6EYfnp_Ss@C7K;}l8NyZO$J zzxzoJr_GDod^f5sJb6`02jMs2ciJflg$lZ+r`fr<=7xvEVCU!N=ElZ4oY%HC zz7gjRO-{y;YpAIuWMnXn6vXhph}q19G4IjCym|kqYd+C_xInk`S{xs^-xuy7iFq(l z@vxO_+_!o3*_<=->wn{HV!VlHk8NwEvLcj7cgi-h2jlbx1>BSC?s9W|MTNDcrRBZV z{jG2OjVVw%cXhplYk@WUdUFKm-+VM|Dj%ts&{miVYM)a_@AU^-eY$gm$1=hS&uXPA zCo6A#M0fAHu)KJ8T@p$1Jq%vi9}MyRgJ#$Cl{0fx&G1gZchtrJ!KJXeM^-)+k32UE5mGl@UxgfPPqJu*%02$_A@IfOuX25p- zNE@4|y6(vzyaOZ%LJVA9CptS~WX`KW;jbRCCiXKX4h6$lwd<3&$1$dz4P*&rNb!rj zB*Fq*=b;d!phh)m-Hk_%vCoL)y66P-A zARn9e0N(>`&-8TM(64fW9kh#!+;&FHw_)M~0o9lZ-t`VqFS;I_^(p^np0j?r9!uVA z{A{k{h|YWSAmlqG9g@TF&>N+&edEc2lY59s*vAQlx~|+sCXD&QNhFIasI(3whs&!g zBcZf_fPks#X-9^19Djt>xsurxKR?C^uv5K72?EPX_;xbR9t1asf=t)lu`D(%EiGB2 zjEoE&3kwTX)p+*XpFwq>wY5jU#mpi1IzLm*k|p?)3~&8|y(vog=EP^YgFbko>{@eTE1Hf7GDV%!u7mzXyTEBlB-VmQNTSrHVt$&wp zX>tP0@0MiC&d!z)(g93{X3-EH1i(z7a5lK)EQ-q}B9C2pJs6X zkDfMvU>zpt6qS43KHOfFD5xqYm>iBdMm_J2=jiL}b6U(PXlR(JOJ1!4*&}Et7WEvo z@4@;;>Kz;$1pARycdm{dTT>VpJme(O4Dh>!Q)Jhv%A&^;JfVKLr-h%2FMMdBUc)iT zFmOBYw5lm7Sz5}nUstzmnN#AU%QLx6%c=_{LSAKy#Ti{MO_oa6&?mW>*e|}ObN|u8 zDHUm@6QJQsdjXYlUH9W&UW|GQiX60QG11W`e#Ds>E*pr|@$_h^{se>| zFX}QG84Js25D&f2*?x;k@?&hh^4;M%0)+Yv?I>U}@n$2aU?8sooT2FRvZy3d3b3=} z8*&FApa>xV2e~u4{2d)5tuBX9*TErf2Plv}j?2XnU#NXn?wk5y8I<{bjeFk2lN?hF z4(SXksTkBsw}R}g*NWvZCcXp8Zb{-jSh7^)dcL@z#aN9-efq2-2pCi3hzAlR5 z;?8z-Wa5L${l}UL-rJ>uO49Zs#c>9|GU3v^f=Z(TLH3bCZ-C|2(!lh-QJ$j3tiFmUzgd*F-T=#BAFPUV~WKw zG?9Jsyu0Wh9=5EBw3rzr1jM+(h(-*!S>LfmY!>|8Eu?>}5Xo1FAqHY_g+EUa)KNk8 z#COt#f`ar$<@XdUEW8S+oF$Peq%m>r-&+uOO5nlBOMWo={+(}%-K>&U99h*0MOQ{< zDDs`?O}fKK8n1*naXSc1H(qV?47G>9bbIXdN5H%8(FJdK6A~00th50DhM{!+6jedn zjgP9TKs|_o=l24ozKm4XP*fZ@s?=bgnE#DL^XJ#JTJs`%_>qi=CCdT5H&5&4MU`A; z3?Uw#>*+?f)yqPS?C9tKL$pD62!*L8q^s-OA@>PvF9v}ZTRXT4b4^ zPrt#puikSG&Xu9Oit6f8YC#1BRP9F>dz1YbP!0u|EpC z*Jc<8n0?O6z-&|5IrdbN1^;`~$ERX(-YIndwj@k+R{iOGdsuS`dX+mTP{8x<#Im-m zA1G3(`|@Y^FUM#g)glpWN5sVBoaUHHEY9Fty8VDWx%_(|UlTvIR(1edR?As4!_09TSp(lNs2d<3L|hq+QQeOlQebd6pB z_XYB9d}iGapq09^LjjZGrV15fxxm|KBjU9B>gviZ%X%rQZ5*ufosOOTSf}YiLuTmv z{$V4AfIvmhpVCH`56w9o$gwJ*x@Es@ZfqPE9SsCKXStT9s;ZItO1&ptKI{MauC%p< zXR!HUW_8lOA!1a}`|)z$$=~HfLDf>*$SLX>e4k(&iD%Th17p2G{&Z9{DluP!PP-SN zF!q@tmB0VHFA~-?D2PE&Kt5O?`3Ns~OS70lxVAxRqTYV&TSHA!NV} z1{4(R026^7S7J>hxPv!udYnDyI_oJXw^LJxRS7Gao85!`$($3P%e9(segMPS=B9xW zT-p{oL;($mQC~EX;3=+@>|Ls|bNmNxZ0Ks`d;d8+1dwB4CquY{|{J@NC; zs{G-^J{EtQ(zQBf3qONO>x4RpU$k!LXJmWp8WGRKp7YhU&oVHo|~Kd zn={D{)b|Q#7uh(&$&gAI@>(>61v7N8i}Tx7Nhjjt{`b#B>}{)x8*1Y?jG{I!8J1d= zgH}yN7meUa6nNYMU~U)??8RMz!)XyW=sDV)#@&R_d0(0a@Z+<#^dX~WL6e_*>RrY&ns8o_q_@&od_o?tR1vZFf#;f``x!h3^S zU)P#pAt-S$_`@yw6Jx;aE{(y-QfdKZ`n=@~=j;{&OAb!+wEs&xq$~jnFg-m*SJ%MH z@lFRAAR|S4b>eK>nL?!-R1Vujdm~RvQ>&3D7zz6O$#XodbBD+C3>iIT73G9CYKfsU zR|@%)&6j8AS7%oSkXndd9n1=e4YNYtXN3;x=H>U~UgLG*ji2=vD|=@u3Lad9&db?N z8_1%sC46CaQBJfqnZg$q7Rrxnl)W07n-lDq_ai~e>C*&wT1;9SH&}Wan!GMfF0M#l zV)Ryu4U(?iuELTMrB9a~f&LLT1)g&(~IvQQH5 zixWf&&Y&7uGuOkV@?AiyB?otF1-Nj~WH^*uo}8=+nsT?g6qS_$s3Z$isEJ=*dh1N2 zkL`X=>G7mO^vY%mdh4)6A5XT3yt!oT0t91cW~W&dziVS~VZF|0p9AwS?vM8hGKjfs zNbz_sW*z`-3HE~F;o;>r&wFqR?Cv#rKR+cUC80pj3agQ^58;b>$txZ0dXs$k&U#^J zXJHLm(EGfZfoT|Aog|S2K>K14UKVWOcL2_Ek(1{>o}HbAi2Xb=`Ya?LhK$RYi_mM` z{;2w<9&Qd9;QMY`n~`@Y)8)XM@b&X&5Czjk?uQm&b~Yga9pXl4X@TvkDpv6-6&?YJ zm701N&=S&ea+GADQURM?vBiG7J3G$6+W`J7HVzJOY~>deJcC)vxud_#XMw$;x2IkrshYI^zYXvZwGCW+SP#{XtLEe&NRfrIz)H(+@41G>~3WCtY!|s zWUXf9_tCVLZw&t_%@}jpZA#wxO6~zO3;_~klLj0_xw3jYZzmb|s*aS%w0yMY4OjPz>Ha?F7 zHKLLTLgcSkF=(>UE4}3JK$ZQ%f%Ze4g4Jyr`Cd|%jp)rA@m1iWnxJN6oY}urWxFNh z_ICBC%{n`{^0wlhpU2Gn)}%n8FYtS3h27Gol2>KJydwQ(yC(OJTb}%4aN%TxQyr+T zx1Fkub_>V-5vuP__!AgE6h(fFo5_hyzr!ZP?EB+@-A8D{_svsMc%O!cxU&BnytMt< ze~`HiAK)q}{|2RE4@Lv$jV_@6o`Jcr&`9!9)b0xl3(H#tDvyFSq8W=liHL{@bR;Am zn>8U&Cnur3A^Re7c785+yBRaGue^~pfTFUn*Qw~Ii~56DU_YruDu--v^p8UiC8w2! z`BXzv!dPvIxxaQt`O`YOcj5^~1fSn;yN+hdIHa ztZZ$}A~Y+cp^?1XX4ouL%WPN-4cIz9F0Mp5E0f@VkRIwG^Dr!Fo zqkKqVs6TudUtabElUY3;&q3pL%Y*=979`U;l74f4xjzdGVt;!hNO+w>jR3mQ$5b$= zJ6~-GJ_rK_VBB&JMdr#w_D}r|JbQK&h3{ooN0L~nfI~HXu3Wpd3DD>>+@O<w(Ej8Rr>Pel+q%mr!R~ z=|3f!j7Of|Jmor`x6{~|S;jb>$AuYQPTM0q`IdG}8VY96aZ6w6IBn6;)o1|WL0SEZ z^bR1I`2jtcnh8`MAaRNBVoY?D|2mZdb8L3j`CzW91%}IPirT+(OrYfP{(4fL&ti_5 zXY?Xx)wY+&20|opNN0IIu>>Yoz8HC6{SPS?#kJ?1j#s2M0nH@GYmY6 z3!v<71%B;0ZSL$yR0w7MB$i7!?hu#z&M~DucQ)^bd0UoYqC^#!I?u;F(2!t^`77Yq-DRPPi%c>q^&6M0|o9dPIM zry`-EJ_2KHaY;$P+WX#47EDiIpY-tX=%dR`hIf@0e12e6$1FQ9(BN#;*kqAOX8U15 zlbqkgIX%&zm(1tNf(30ETg=A6?Gr6vc0|WlI(rw6l4v@yTW46tR5+Z(y@r=8p!T3Y zkvHvEjW6iMr(R_M0d7$5znWVy7^2}QkBpo57K?RZ@sTv5?M!K+D}AKLZNG&Efl%$3 zd-rP;)uP^WR>z0~rA#!z<565(+=YGpZHR^Q9Y((pm0H@$SY)sm7AW5@o`M2I2VKje zy!vm*P@}ouzJ9H%p62D;#3%jf6U{k;X5E;YWq?#kq;9|Ab|6X53$;>4@mG5+v#^C3 zhed=4FCR!$TxDcJ`wg;j--2l-2DjrW=ys63I#EGbK_2G*U@2h(pf}`WaeQsut@hM( zo|d3S6(wBbF&wVGp5Xj+X>n0wkANp*ERcGx%-p_9vNtY2#6rcnMRa%4EgCiYHO2j? zn<2G+lIiGFkdMXLfW)4;kmh)E+ga7ifWyc7c9=k(el1}l{>rQ2ZtHLlWll)#IHu*H zwYHRNXVyvQ?ZezSDnUy=13sslbbHP!wtSoUjF6MwPEdwt0X;sa`-nQrF8p$piFD!V z!3e5E3H)d}tBX*iz-4lBP|$tVLh0bPz>2)Z{bscLSU{kCd9&C(ys5L!V#oM8tG3ep>FR#-Jord}Scg!ddDnHk@ zz!xBb`ekPLr){PQfGPtx+9^cWfxbgo^A$S!@p3b#H8!z;N21xFf#B`^eN3;!l`!Zz zNmxXQVgKGi8GMz*m)*U*12EI11x0W-;pRJ0-Xg`QDB9k$S0x>b^l?%-y%V8G_~}XoBRE~5l2{9m`zxq$ng8;Gv_|vJXRyqxldH_ zEujD^h}4oCppcIbRlD=$8LV^E_g?$*@f9oBJiod`Z_ZWe_oI@#hqo+~NrVG>*TDgA zOpRPf`uBBrKf-mCp**L}1U{ahgX`Bek0e`sDyB?X2OC@4Q(!aiCtVAaS0nwwMnMr6 zfAX)6STm4@W^>O2K!)CTlNq~|qLid0l|#-h0|=kae22!z$7kB*Y>+9*qB2n01^Hs)E|jwy-MP~kJ^t1Bqrfi&52^>h)wIxNGdZg9A7Wq| zM!b`8*=R*PSXg>Mkg#&SCEvfkIUi+wo2wt^n(#A8$0Z{QQJ(Mld_7_QT%J7i;5P&N z-b2@KvK)UrLZQXiS<Ey>(V}a{G{ovg{aB%%; z6)=A0+%{C-fBMzi@&=c`@REq_Zrjvz+voD$2>Vq1yE^ zSHh~z(Z{Dkb*~{a>^y1YkncnGl_c{}B6rLVe^#znTGR_ zItN*!d4N5Q!0LMy3s$wo#^1j?LrJUv#~jGY&D}hhuL0&Rl)_Z;aJ2UKe|^%+H6##E zYpvN2*4L{H`Z2wdTVPfsvlr}A3~CJ~a-~9RXzANjjNQ9)ea$joiPgml{HYnuKp@N2YW6 z{Mi01VMqMo8*Ey+j`w36l*D8b^PWV3PSW++LI6}<`xMPQmONjlys;rWC!EEqwJr(T zK+^RVuV@!q*B@jhj=tesccQ((j9;NS-PiX$642t};?dq_Vn#uF$WKdAR14O(9@Wot zTWQ{&E|+>e+wG^*SY!yxX9V##7}vi>I^^2U#|9Y62rO08J$9~Z13sBGc$Lc=5b9GI z3w)Tics|vs^cwYOaZ+`0c#w3O8U4DZmT&DEr3uj6__c9rA%Z4qMs*cM6@FwSqCa1n z?~QpUxf}*+M&;J2=q_6%3Z|QylXYJI>S1;ndFZ@2o_-8IQ&*dt85ToEQZ^(YJcg(3 zN5XDna$0o{>yzb{;LE(-O@YmT{*V5R^{cP1r^xj!PD|miyaWA{6;R&5E29ZwN(TSJ zuSNkgB>MTXjZ155+0I_w++=c`^eCB{?x71lC;%Opl9DK;uAbgHIGe!GX8=Fp0mb`+ zhdo?S+j65l)qG$Kl{{q)4LA4v>T1TnX%7?{Zlyy44i>8mvjtzp9B~yjH6`|VTe*#F zv7a)OSclxQ=V|a(%T00ggI5v-wGzL@^FN^9jZYmwW?UG*@b1HbSUHX1X+IHQpd}($ z>3xvDnG!rs9PsXMP|areDsU0OVCm7c(K7QXc_(}ehxH7maasaCWtQ`!;Mq#JM7bee ze;pyu{aRmDP?UV>a@EbOz9y!iOaP1tomOFV%UlMNY?7eMNOY2vyBs!ayO(x%{|=9& z)6v=VUe=SE{6VI&I0^rKoYxyqE6bs^6f8*6XYK-`1yR>R8+158S5) z{wq{{vuU@<4A5oP3JNMJiU@ywH)B<*cgO96w0SVFv2xi{{L5jCn9>ft*A+&55Mj>H z9}d{{{H}H!fAp&m5vGYqd_8=H(Ci!XO4dT$r6r9>6JfEEhUz;Y=@ersb^lM45Gw*m z$Xj;htsLob@D45Tj3I?YES@|i696>#e7u}h&ZE-N1+Cvj4yY!ZJz1(T`+mITv?6S@ zV{-?=E`SmNXzxoT+a_A%tkC5SXwzq+)A=Zi)h5+|1f_n}i&t-VG$R_! z>sazQ9|q_&S%NRR4Oy?RQ^Zy3znzP{t*vQ2WYxQ3SuFjM$ny`?!hgS6OeC`nr|YDt ziKb;KnxN#SD=njC==Anl{X8$QHf!t)nNqP)yM z%B^TaLExEa@{+u4$&_q2aQ6hu`|!MAsV}Mkc9UUZS`xn1_xI>%gn-oS#Y$n#2$UF- z5`3RvUJ7DT78?d0p6T9Lo%is0F`y0pPZ#j~1Ofo*4h0!@n#Xf7BMIestW^(O4e#QE z)vVSFQgW`#@0++Px=9SS)fmd!sz>t7GX|8C5}Xg=B>N4kgRc0m?>BlgTx@3MY}$pf zh;Qv3YLAX^W8PN!g5K<*>9B^#ep`;fOQMVV{JwlJ`19yit-Ok(?mpUTbFxxZHP*8$ z6HUU*lILtT&EIV%qS@-9>i!sBxlnZuqpnn_qE*=Cs#ua&0acy$@n{?b0aOcH8NdEE zD`h!%FI71RjcirB<(JVqU7ugG-`oVv+~Io=_=#M$!Ef)2@lH6&ZWVr}mbQf*zE?Rie}wq(RE5G>AUmLE6_cr8;Mp)X9o+?&r-l)5)@gTLllI7e$&awFl@s3@ z0aIZXH;ts8!3>n(jGHxo^e?GTZQF)e_h|`=<{w)L?Vtt5?zBu z-0fb~_!4^NNZ-;8>NH-mOuC;w!z2*o zPUyowiXUqFV1hhH5GqOuBb{xomv2+6{S9LNGw`*KMv{f*$ zn3v5S!`Yg!beg>7F5ninj~}U3ZD1Q#>O^2OEZB5eW3WAG-E~2;u<$9Nq}c26Kvv-R zxM7rkwF*r!oYt~4$|;o$ekJnTefWwsoeez67!UGmv`i&o-1n^*dEflo8C_>1bjr6f z5j7-n2yC^O$Fx$kpC(z6%H(dx`~^s|L^U^cEY67F$Inqcga9!1rcfbMO+scqvR}*! zH|`tQGJxQ@%Bxa@_C8kipH?~F^JTX;M?=%pRLbvDnRL|4pdRtGH4nhO%GQ0-)m{4= zA?O9-{eW~I)XS4F9pgC?w@_c`A3z@uaIxH3-%UKQe!`*HGd=VsemMi|U{aKl-zHkZ zd$SK?e^w=&Sqc{*CKoP*#KhWQ2z`kfQ_r#uXq9`+n?hj^QsW#}PVm*F|k4{pvf@!b3izHWDMdLmhI zdEaz~Vi|P#w+9CBMg2aqh1m@#X?0xh7KC^;)g4@)>nvxk{}p#^OuQj{^LBR^zUv#m z0>DsG>Ph<$lnr)#@MqFSVSq*|6E{>@S0OC#u>_|{NK@kL{oNhV+hq;!-=JlIz~#k? zxsFcx7=pK82#l(#c*O@iNXPs;T%Y5+R@oXfx30g78rxtX*4W?mpYPJ-jEQwW7k$}? zfE7j%3(l`CAFiR5o6InbkASkU!6I}OhV}+yn20?u6lv#gJH1Pai`xLl@4V_+?SLPQjDem-B-qVb37hUHv2X$yi*0cgYm#h8x@uXZFXt z+O7s78N&JnXe>;H2IIE$%gU*0MFdkVc&fMioFwJq5JG}5#0=qK&hCF7YV=BEzL?pC9#8ZQHCC&jSKl?o$zJWU{9CMN z`n#gXvcIMYF*G(Fv`r|uF8u%Oahd--gSDI;`)<#16TbwZ;0+1McLUYQ$~*4KNkPHy z!j6u=GJgRlNli^NQ}^8!PUgTTQ!T@rDILb77J`VQ+ul=4qC^^)?5;1)D0nQn0K7HO z%=DMr@ehzXc23JQO^0i<40)vo@bf(mbsNdT%PtF92L}fc5x-8|wcy_ZcAI?w78XIT zb=bcBz5s^iJOHd3z-E8dbUeGsN$q653c{2OEnM64#C-Q6v;J{V#u}GPB9Js~l$E;( zr9gpR#3ESXu0s0;f$xax0`b#SkKv;J50*L>0ys3xiTQI5LLuXh*;%!Z5NNG@2d26n zSaS1B$JmUx2D?7J=}stEAv;)Z9{|Dsbf?X8A6e^+Lb=fGV#8nb=#tyFxe0G=|Y*xg`?n!TDuA1Nhz3jp-6K za4hb>?6LMYfHv})SR=Q!LKj({sR_~#5^xS*yRyY&#lN%2|owiKe%od$!V$jTov zNDSmkoGqb4YM#G*5_(^TR*wdu@;@Q~2)PWGM=i^4zXDvxK}UjZ@NTQ0vw(6Uv*u@Ip_U;zh3w2em4Ug=^XA!RxLp6mwe#Up%C@!znVA!C63frag9wrk1)&) zVpqF)RTr7vm^gdHOD*$2>aB`zVCStYV{jcJ!@^GWTar`nod4ktwzTU1{eNDu0yR>Ha(@JGi*GV12@3&T95w%GImPuZ?~0FMeIRvBUdn z?ujsnO3tqAgJzlCQuMB4O8N1^uZv-J3p*|%i9lu;1cgCnJk(`g)ufp=sZ*sm4s4enuVJREYqMyA$O(Qp@F5 zYVVwXq|f0DUm@uT$J=fYsK8Tsz$NIgHu9E`lmXs7FAopvSp*3SGjk4{QsMOEfjFqe zY4KSh@pV2U7jY>qy6X04_FW_~I1Wo7o>7@Kr8`)LskZ_9oL5M*+sijrINXW3xw&A` z26rdIZL@+zUuMRxf!_rpHi))$;&$(?a{=dc3cMx0Exr$9qM#_Q^Fz^Z*ML?aiJZAU znlQmmgX950F|grVUS3{Ts^Fh^3(=s}LC*Yvl~sq}>yr(>u7xD_A^T~!3KjU`hs`cA zeV$>kq#Doer5ceiR)Y4Hq^J z_Cw<^^D+>V#uGts`=+PelP(hOONM!S^e5*ma60I3wYD6@=0FW;>Feuz&jF%0;K$bQ zQ6~9yCh^S9&T2eG-yGdAxb6}m`77g!T-6J2WqP^z-yV-t&)F&>S+Kzt=)Y36?Bk)@ zi?v(!YL*y$11>M%31@1wyt`wNLDX>+s#}8#mbtt>=(zgCBOy#BCYIt&=v(T*IAfhn(|X7|)zR9T z-8k~?#N|XhZYzt*q~!2$tQ`5@4}gIW(4y+LVszzRg)dE5EIsdM$#Hz&u))J~-&7{Z zSf=9{{M|MlCRIWJ%nZ0|_134y2RjEKfNlGj>*`V*=mq{I1XXQ*2!NR?-eL|p7|&PE zJU;v7d;LTXzx(4)#IM#gRlLRox)|xHS8;g`i(Vw=yiotTqT+eeSo&OsfnRo*N-EO! zd%$z8qP2VLu>iXCu*3>KBXiEvUPGE7?7}{^DkNk3^k4h}Kx6hZCpa@tiU$d+m}7r2 z>vVjfTE_EfNEjqIpE8KEFj)`wJpqCmX7IihsHfKVf@~rUr|7$K>Y^5SgqnbO6ELlb z)@Xs%11vWQuf5>B1o5D3NJa+J(3*^lSK5*FAUQaIE7=U;wdhK6F3pV3;?&3sPN1BD z9BKQYWq7#yM2N-ssX&on!;k*v0jIO-rj9z=i{kFv3F`Dmao!7v`VSwx2L_xpHG3dg zxW2fkNIO&y$tr7`pViFDuD6 z#~3k}PgKaK2?wHh7+Vex4|9SKS7FVP2|4}P{?YMb5Y?3{X=!QSy=CE1^m+tP!v>X4 zwa1Ns9;|Vm_@WK7X5v}>pnNn|QUe_i?m=ra1yW1sxPAy*5K0hHc{c)$OQ|3J)ou$} zDc6U|eotF6{XRH6A~5qV622Q}R{m4@_u)@IUf#Uv`1L!D=6w=3-M~C&mLtA+@%hF7 zymAIam7PEt7(R)S)08*7eIBr9`XA=e< zX(BCw`UrdD3JZLrGEU#i!G<4va)>>P{sXyELLRqE^=0+GQ8U2uuupde_2)+{4V$AD zA&Yn>ynHK-MW8!KSN#fy#s|H$81IwowL#UE}3gXYU$^<&mJfJ9vVFG5W9k>4GQWk3HP}; zxl?;lIyg`*!76X@(a#-Xtvh4RhE>G0N(7I?+$)059fU$ScGX95JFUiL^1*6ktm{Ts zY2o|#2_$7=F;-L;n%`u54;PJ!#o@I1Md?_7Y5WtrKQ0yOCA=FDbaWg}LaT6}Su#{K zJ2kb|W%5S-BmRmMP_>hC8}U@$xzIRAf zwGRh3cZBryY7znk-|qt5ol{dw$QI2Q&7M>z>%=dLLlgb0_^OKP^x?6+kHf<$M({c$RET(o&`ABs-Joo(%lyM*m z|Fb-Cbc?mxCeG80cpsO`eC|V?;OMTJ_~fDS#a&dXy1Pd_ZIXOX`&9}`^6TU-zt zlyN*c+fD}Ko-#WCQ;g^=t*+XfP12L`&4l|ox@Mk>w?i>m_%%MG|r zmB-kW@WE0hmquFuY#~NLCSb=t^JySg=!UWY6elw~o7Sy*UlaR(XtFHCRA3+Cj3)$u(E{vH(u*IHqu-6pJoJ ztqUoJjjYS4x;K+DvCeAC9uTGo$ z2@wZjyKOj{_rkj+;feB*i1-#^-Fx&_#(NldLSCD$?cW97rkARieS~n#RPSgI2#bh- zhrs@M5ljJPFcxED3xm@vSoIrLbgLj<*GbPQX`7VUUzS96;9KMML5;xCPJaA&f{Tod z%(Po7;Na$7UR5?CVZ-!a7-Ues?7@IOv&w~JP5nogFJG20CXq-^(=Q&FPh4rcT{e10 z-^(IWJ{jeaWst1FW@TvL%l(11#Rtp5<$U_maxqlyO`agRNql6MKrmf!E|~{WI`@9- z%hKol04toa0oV;J_9X=&*W~-P--8E#CXpL$8#V0i9i4*CBCqjQBGtW&?N^pG8aD+0jnSYLg6bcHne1HIbT> zB=H8Il_nP%Ss0OcC{Bq+-t_J^eM3t!H)^=AC|hf?M3FCaOHr$TKgov|@KK_PgmB(Y z(;sL+Bd{0o0XoojC%nhS8zZ-t2ild9xiE}NtH|2$=5q%sliP-P^k8qq9e7ZUOvJ2O zpRFPQ&v`2x18|Li2;Ov(HvPN#vNN}G>%3Uny!bU$avmw*a`yKA5?5n2txP52_7<|F zBuoU{rxtE{D7Xcox}YafA>yXxtZAaRo;nAsGxP=5eI&TlP#ErOSak48djFeKra{xI zjVhkLzIF)i7ccVFkl8|3$2cG4-B;ZhSUnX#8loM!E(c6kjmo}ey`s|3jS3_#Xp4KQMT5^hEAzX{voijNlCBfke#1?F+awKir-g@uNqt z_>X2}5e};kB{pK`DSzVm;I$XzU0O9Z{yo=`6BUzbCu|%>{D9J48LsRm&W00i8;+O4 z%3<-m<#vmmR+&2%j?hmWaATJJbNbB{zyqn}G_0x6RWb)kNHf;y_lR1e5DxC;ytMRU zPDVMhLBSyWg7@*h;AbN2Z~Iiy23Lpy?BV9-Q?RC{HKIS(B@taC4<0nKC*8wIFWm}# z&zRD(zG1Jb#z~`cqRX47zXbNh3({2+-pzZxlMjr%FXZH^{jSuqjOz) zV;4E?UHRwE$I~DDQ?&VC1p<=C5+S9~UgLy|%Hn-a2mo#{caWVw&yr~g)%x0K*>65u z9i4vY+XA5)n^+n*4h}i}lXLXlEKpxfEDV7uk8tz` z&QdQ$?d>_RcL9c%j7eH$2x_0-Kr>GQ#~)>PY_V4IqimTN{jJb8v8${e2i~3AI2%vd z9^;rbHa5~CO4|DR%9eNTUknY}+}gU9u0evB$mKeM{mn}LqMrHwW&!@S#%OS|BI6=% zyH~mpOTKpx3Fdmud^TD*9XA?O?jAx|IXsRQnjGV2X3$s*&V9)9vgjHtW@~W}%ZBC2 zB+{5^?ISF#`1kZx2Lq1Xh0gN~w9jA&C#3}Ylr(hlZ0tC=xQ5m*2!2G3 z%mU{D=s)%;hRsk2K>NvdnIMksiLt@h3AevFf$Mq7@3H5tNUsRZoSptY>u?r?vN%cz ziM$Wyf8|()RVS~nVrtkT7qV-$4nxRO)5oplpu-%djFFSWx>#aEjB2s3)%`-@_^L;% z|Jh>aonAbT?*~8WUK8@y4B*@%VZm0NuUgyN746qv{2xN+`xBE}H^1$3Zt0QG9{D<7 z3qRP6%bqLCFPIX!-z`K{U|SwBQhB5|xaTVVGqR4#^buZ6#nzTcKJQ;w3*WcSLP5Z$ zm_o;AeHqT+75Q+bt$6E?oyPNf4m}eTp--|abIIAz4CEyoNX-lzQ95wEHhL~=fte!% zYY5se>v)!S-I4kr2wD(zUaPt~IyxYjsp2*U>}E)M-ZwBvhFrC?sIYJXnFQN3dTMge zL;cfDlT?pf&Lm06=)fANA?PJNY+ytJV3%pn0a_yI0PZ2A_6v<*!e)NtIfn)D>P>+@K4NDZ;0VQP%7Ziq0UTE|oZsF`pyDjFfhzi?E7lkW zjD)$ldn3I1XdA5|WuVXm?hEB`IrzXp78vdc;G|s!fX?R*tG>-wjzd;&PrN_9lyx(C zl8``+0bS@`Vu|vvtU*3h&eB#jJvZ^4!HANMt`oSj`U%(=3l8EHJ0D+Zr7ysD;{cjs zAa^dtNy2*9Hzevphsxp5P+zUXvDD(z7{R`ne)<@VGP|eY(?&iVE*qT#{QNY$34aR} zHJz^?eW|j&O&`~@E3VD)zTI)JbUnwj^D;SQiFk;sbTa@rrn{Yz-`p-+ZnC1Cjy6lG zIc%72#}^gk|55v3Ph=u}ScfXAM0>DJA2ZdXXMa9ph{4mhy(S6_qn#*NfJ|S z6Nm%Yr}=HFplQuIwE8_~a~)41=k`1{wh3lg9Js!b=%8G%gQCF?4nW68(`QX^ECoc? zbq`|0wo{j?9l8n|hE31EG*ml(Fv1~PJZ|&lV|j~HrH+293)NSXX>vpq?Sdp*96V>iws*!04Jfd)4h)Vk>qjsU_(i}^o++s`m=DtS6k=FI(4{y{zIrD?TO8WVU@J|h z7!v(J0QNMj5KSAhfJ9d-?^zsW!Mu{D{kbTZ6Op-1L`Ie)>M)ok>3Q$oJ*-XEwlnGT z=UX0xvY;%&+ASz12Enj5ka?Veq|Yw=R^s<(X4lgK%(;YzHV5^hU-pWq(%F5wH*$<3YF`-W z-%rcG_&2BXt>sJBeE7yt%v5J=l4z&VJplr?)k`;QZn)j2hu*mcP%*7dYn=SS=YrAO z+}#a=86~o(`_|i+m0%5(>oUi(zBQ-NKgQbA+@j1bXS%W13;xy@(Si9kDYnKz0(!Dh|H`j$;qHfxNEMn+9UZw2!C&_WaDgtc@(0YdRiEH! z#!iS9y9Va&dO5T)95iuQC)|S#d}hQkgV(bgj~Wsu&m~P0Ry{~()Cnbu@F2%N7lWwe zOC^05NF_QoR0B^>Z&6b<&xIIreC`h1sm-j-VJnLL|4^zQN1R0w2x3DlFW~=TRpa@q zL>CY2%&i2aZ#-q__|V*?60p0vTzkO{r=39l0`4u}DSxgHh#T3z zpnBmFM{DaD8Fe@B z9`}h*SOPhhhA@uYoKcHNoQdBq6sdwa$I38S)%hAN) z>$q`MYYS|LBmcXPLn~L_t?Kq!aq&`0v%|!6pq~YS_0;L@(&Dxbqu$dZr1|{mo%9VG zWYHp>Cf|dt$o+`ClQKTjsULn4&Ru{0_Pwav)TY-;XX|(rO_jhU^N@(qo(j>xs+9c0 zjXAK(LU3mMI1#wyYj*{Po3 z3a9t37=hN%jJ2h2@}pcz_8ct#D7FZei#wO|Ml-(-l?TM|2!1@>zIzrOlv&GBVBq(a zHhUQ+`;g=i`{e6rVP9RI59R0LGMh zh?;lM-2eVq%E)V)vQs_*@vR>5+M;aU5*16_t2d4`gkURZ1aixkNA||Cklh$lGsdB8e4Qfrmo#wl{Gq_u6=p^Vq{hITttG~-h#c~FXe%AEI z2icg3hkiez)+o)LrXK&*OGCiv0DpL{9ujeAirEqyz|Bon+Gz&{9$UxBe35tq?W0{t z6tKq~IH0L5`C>+0pah22J{X;DLuQqdAlgF5=4RcDA;Y zt*x%HccZhVe1UCu1iOY=jT3D%o{h3Fs|vpcjI?+nRO>vUBzv@gNd%jmS|t=I*g66< z3(dqKU#NOY%^NccF;BTF;}}}R)HqDhw@$!P0h5=wkVv0~4=}R@uv=%(9=pp&K^+2( z;Y-d@A64q{`dQI?_!kF;5)H;GR=EnO?8z+D=lR~oGP-6&j^nBJMm{SIA_y&sh>m{c z+lx(!0w!YTT^f$1h}EeVX8N> zZ=_G$**|!aC)?i=UHoJ@WTWrD?`%v6Y}aocSP~ak#$^P_rtc#r(yjW%xU{X&3TK485IjIw_NMN1f7VsEQZX zj4AQzz`O>JvoGA2V`F2Y>SAoP3=8~C+nrYfWnnB(;Gdgo%=S zi4=?kT(0oGiEqnSN3{D}FaE9xZujryRSqKCepEM9BEgD#$f7;y+VTY|!|q zxOGs#AB}WsjO94&(l{vl6nM){aL(r|>=ssKMW6ieYrg%GXeq6^+otv4?k7tjh-`{r zPzV+@lY0q=pHyGQ;(`RMPhW)}K7VXX*!T#5nBd!h!j*+)KE>1p#N8eYhCD;t@f9@^ zG03i!mi;_0hCoUq@EQDb|G*vp#m;1i-Ginw30W3kaW(}S+sjhts$DR98lrlM%D%`F zwM23)+$J+!Jog>-H?bE~|DDc4qTYp6jQyKhXJv8R<$1^D#=aE0^^$Cw2_0k9r}p-z zq%hPiQWf!0j)kVvkaGf(ZeT;lNg z8$pw@Wcd8W2lhk6M%D*)OjWo96nTCI z8Om3HtH+l5QgcFy9MG`v-=*>ct+vf@(3)e$x5|?v3=8yXa9y+$H7(RXW+;dw&jv&# zd8u{Q?@O7MIWk|m7K&Yo&=dimA*2tC6#aBNwOfFAt?9=Bz09f@CztqgnHsXHsJRy= znnda}2|0_N`sH@ItRhJ@Y#6f4!W+t!OJ8({=gpEnnurK`i>e4884G~#$1E*W;2$9p zrMn`ZW4_-|UoXt1_-1$zM@>IR{>Z|TEXzDu;~vDZ$#m}GGHKRo5t07$@`oSbC8H@vw^3#&5Ep@{CMd1*H`7^$P720!Kw{Fn=d zJ9EgL)>fQ2T5N|o-yxQ;YW{Vlm7{{@f83`CG=9J`GtB9ODOg$OZ)E+49^qJTN`P{Z zDBz`iLZnX`sczX?l2|~#Kr6X){N{wyPF*OMm^AMKWqBi6L@<{3j$omIeFl8*(By&? zV<*F}{s72U1O^4cLJhW=htry=%~D#mI#RpC3>8CPlT+- z@%-i8$M|_`tZWpwmfLwWP=z+N)oU`9X`yF;$T~Yi<4m`}cS3-zF!2!5db2k>hh6^Z OsH%!ux85mOKKdW1Z(hCt literal 0 HcmV?d00001 diff --git a/gui/src/pages/integrations/IntegrationsOverview.tsx b/gui/src/pages/integrations/IntegrationsOverview.tsx index bc93e27b195..a0e4b1d0bd0 100644 --- a/gui/src/pages/integrations/IntegrationsOverview.tsx +++ b/gui/src/pages/integrations/IntegrationsOverview.tsx @@ -312,11 +312,10 @@ export default function IntegrationsOverview({ const installedFileClients = clients.filter(client => client.installed); /* * "Settled" is what separates a client the server omitted from one whose - * list has not answered yet. Only a cold state means we have never had an - * answer; a stale-with-error state still holds real rows. + * list has not answered yet. `undefined` covers both pre-response and cold + * failures, while a stale-with-error state still holds real rows. */ - const clientsSettled = statesResource.state.kind !== "cold" - && statesResource.state.kind !== "retrying-cold"; + const clientsSettled = statesResource.state.data !== undefined; const native = nativeResource.state.data ?? null; // `readOptional` returns null for a failed probe. Only an actual array is a // settled contract; an empty array is meaningful and removes both switches. diff --git a/gui/tests/integrations-surfaces.test.tsx b/gui/tests/integrations-surfaces.test.tsx index 7222d371f95..a2015ec0caf 100644 --- a/gui/tests/integrations-surfaces.test.tsx +++ b/gui/tests/integrations-surfaces.test.tsx @@ -646,6 +646,21 @@ test("the overview does not claim nothing is installed while it is still loading expect(container.textContent ?? "").toContain("No installed clients were detected"); }); +test("a failed first read does not claim nothing is installed either", async () => { + /* + * A failed-cold read carries no data, so it is not an answer: the error + * notice must stand alone, without the "nothing detected" panel, and the + * file clients stay as unknown rows rather than a server-side omission. + */ + stateResponse = () => json({ error: "nope" }, 500); + await mountOverview(); + + const text = container.textContent ?? ""; + expect(text).toContain("Could not load integration state."); + expect(text).not.toContain("No installed clients were detected"); + expect(text).toContain("Hermes"); +}); + test("bulk disable confirms the result with the server before claiming success", async () => { /* * The resource layer's `refresh()` is fire-and-forget, so awaiting it proves From 318f25b6a838919f3cf0a9c87a1416a5cfa600ef Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sat, 19 Sep 2026 14:40:26 +0900 Subject: [PATCH 12/97] fix(process-control): avoid sending management token to DNS-recorded stop hosts (#5086) Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com> --- src/lib/process-control.ts | 18 +++++++++++++----- tests/lib/process-control-graceful.test.ts | 20 ++++++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/lib/process-control.ts b/src/lib/process-control.ts index 165d21aeaa6..7c5bfbc115a 100644 --- a/src/lib/process-control.ts +++ b/src/lib/process-control.ts @@ -1,4 +1,5 @@ import { execFileSync } from "node:child_process"; +import { isIP } from "node:net"; import { loadConfig } from "../config"; import { readRuntimePort } from "../config/process-state"; import { configuredAdminToken } from "./admin-secrets"; @@ -50,9 +51,11 @@ export interface GracefulStopIo { } /** - * Host to POST /api/stop against: follow the recorded bind hostname when it names a - * concrete address (a proxy bound to ::1 or a LAN IP is unreachable on 127.0.0.1); - * loopback aliases and wildcard binds all answer on IPv4 loopback. + * Host to POST /api/stop against: follow the recorded bind hostname only when it is + * an IP literal (a proxy bound to ::1 or a LAN IP is unreachable on 127.0.0.1). + * DNS names are not safe here because resolution may change between bind and stop, + * while this request carries the management token. Loopback aliases, DNS names, and + * wildcard binds therefore all fall back to IPv4 loopback. */ export function gracefulStopHost(hostname: string | undefined): string { const trimmed = (hostname ?? "").trim(); @@ -61,8 +64,13 @@ export function gracefulStopHost(hostname: string | undefined): string { return "127.0.0.1"; } if (lower === "::1" || lower === "[::1]") return "[::1]"; - if (trimmed.startsWith("[") && trimmed.endsWith("]")) return trimmed; - return trimmed.includes(":") ? `[${trimmed}]` : trimmed; + const unbracketed = trimmed.startsWith("[") && trimmed.endsWith("]") + ? trimmed.slice(1, -1) + : trimmed; + const ipVersion = isIP(unbracketed); + if (ipVersion === 6) return `[${unbracketed}]`; + if (ipVersion === 4) return unbracketed; + return "127.0.0.1"; } /** diff --git a/tests/lib/process-control-graceful.test.ts b/tests/lib/process-control-graceful.test.ts index 9f1f2fe7fc0..da9983d7cbf 100644 --- a/tests/lib/process-control-graceful.test.ts +++ b/tests/lib/process-control-graceful.test.ts @@ -19,6 +19,11 @@ describe("gracefulStopHost", () => { expect(gracefulStopHost("2001:db8::5")).toBe("[2001:db8::5]"); expect(gracefulStopHost("[2001:db8::5]")).toBe("[2001:db8::5]"); }); + + test("DNS bind names fall back to loopback so credentials are never sent through DNS", () => { + expect(gracefulStopHost("proxy.internal.example")).toBe("127.0.0.1"); + expect(gracefulStopHost("attacker.invalid")).toBe("127.0.0.1"); + }); }); describe("stopProxyGracefully", () => { @@ -127,6 +132,21 @@ describe("stopProxyGracefully", () => { expect(headers?.["x-opencodex-api-key"]).toBe("admin-secret"); }); + test("never sends the management token to a recorded DNS hostname", async () => { + let requestedUrl = ""; + await stopProxyGracefully(1, { + readRuntime: () => ({ port: 10100, hostname: "attacker.invalid" }), + fetchFn: (async (url: string | URL | Request) => { + requestedUrl = String(url); + return okResponse(); + }) as typeof fetch, + waitExit: () => true, + env: { OPENCODEX_ADMIN_AUTH_TOKEN: "admin-secret" }, + }); + + expect(requestedUrl).toBe("http://127.0.0.1:10100/api/stop"); + }); + test("returns false when no runtime port is recorded (caller falls back to killProxy)", async () => { const result = await stopProxyGracefully(7, { readRuntime: () => null, From 5be4f9d9efb63220681ebff6586a3e28e2bcbe33 Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sat, 19 Sep 2026 14:40:30 +0900 Subject: [PATCH 13/97] fix(cursor): preserve mixed-case effort aliases (#5084) Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com> --- src/server/effort-row.ts | 14 +++- .../cursor/cursor-effort-rows.test.ts | 75 +++++++++++++++++++ 2 files changed, 86 insertions(+), 3 deletions(-) diff --git a/src/server/effort-row.ts b/src/server/effort-row.ts index 9ac49bf23cc..b7e4d7af96b 100644 --- a/src/server/effort-row.ts +++ b/src/server/effort-row.ts @@ -30,7 +30,9 @@ export interface EffortRowOptions { } export function isKnownId(knownIds: EffortRowKnownIds | undefined, id: string): boolean { - return typeof knownIds === "function" ? knownIds(id) : knownIds?.has(id) === true; + return typeof knownIds === "function" + ? knownIds(id) + : knownIds?.has(id) === true || knownIds?.has(id.toLowerCase()) === true; } export function effortRowId(baseId: string, effort: string): string { @@ -43,6 +45,12 @@ export function effortRowId(baseId: string, effort: string): string { */ export function knownEffortRowIds(config: OcxConfig): Set { const ids = new Set(); + const addAlias = (id: string): void => { + ids.add(id); + // Model aliases are resolved case-insensitively. Preserve that contract here so an + // alias cannot be mistaken for a synthetic effort row before ordinary routing runs. + ids.add(id.toLowerCase()); + }; for (const [providerName, provider] of Object.entries(config.providers)) { const known = knownModelIdsForProvider(providerName, provider, config); const namespaces = [providerName, provider.alias].filter((value): value is string => ( @@ -54,8 +62,8 @@ export function knownEffortRowIds(config: OcxConfig): Set { for (const namespace of namespaces) ids.add(`${namespace}/${id}`); } for (const alias of Object.values(provider.modelAliases ?? {})) { - ids.add(alias); - for (const namespace of namespaces) ids.add(`${namespace}/${alias}`); + addAlias(alias); + for (const namespace of namespaces) addAlias(`${namespace}/${alias}`); } } for (const [id, combo] of Object.entries(config.combos ?? {})) { diff --git a/tests/providers/cursor/cursor-effort-rows.test.ts b/tests/providers/cursor/cursor-effort-rows.test.ts index ea97860228b..e6296b9de87 100644 --- a/tests/providers/cursor/cursor-effort-rows.test.ts +++ b/tests/providers/cursor/cursor-effort-rows.test.ts @@ -282,6 +282,81 @@ describe("Cursor effort variant rows", () => { } }); + test("mixed-case aliases ending in an effort stay on their configured provider", async () => { + const intended = mockChatUpstream(); + const fallback = mockChatUpstream(); + try { + const config: OcxConfig = { + port: 0, + cursorEffortRows: true, + defaultProvider: "fallback", + providers: { + intended: { + adapter: "openai-chat", + baseUrl: `${intended.server.url.toString().replace(/\/$/u, "")}/v1`, + apiKey: "fixture-intended-key", + allowPrivateNetwork: true, + liveModels: false, + models: ["private-model"], + modelAliases: { "private-model": "Sensitive--high" }, + }, + fallback: { + adapter: "openai-chat", + baseUrl: `${fallback.server.url.toString().replace(/\/$/u, "")}/v1`, + apiKey: "fixture-fallback-key", + allowPrivateNetwork: true, + liveModels: false, + models: ["sensitive"], + }, + }, + }; + const logCtx = (): RequestLogContext => ({ model: "", provider: "" }); + const responses = await handleResponses(new Request("http://localhost/v1/responses", { + method: "POST", + headers: childHeaders, + body: JSON.stringify({ model: "sensitive--high", stream: false, input: "hello" }), + }), config, logCtx()); + expect(responses.status).toBe(200); + await responses.text(); + + const chat = await handleChatCompletions(new Request("http://localhost/v1/chat/completions", { + method: "POST", + headers: childHeaders, + body: JSON.stringify({ + model: "sensitive--high", + stream: false, + messages: [{ role: "user", content: "hello" }], + }), + }), config, logCtx()); + expect(chat.status).toBe(200); + await chat.text(); + + const messages = await handleClaudeMessages(new Request("http://localhost/v1/messages", { + method: "POST", + headers: { + ...childHeaders, + "x-api-key": "native-fixture-credential", + "anthropic-version": "2023-06-01", + }, + body: JSON.stringify({ + model: "sensitive--high", + max_tokens: 128, + stream: false, + messages: [{ role: "user", content: "hello" }], + }), + }), config, logCtx()); + expect(messages.status).toBe(200); + await messages.text(); + + expect(intended.captured).toHaveLength(3); + expect(intended.captured.every(body => body.model === "private-model")).toBe(true); + expect(fallback.captured).toHaveLength(0); + } finally { + intended.server.stop(true); + fallback.server.stop(true); + } + }); + test("Cursor integration status marks table-less bases and reports generated row ids", async () => { const config = discoveryConfig(true); const status = await buildCursorIntegrationStatus({ From 7864869c31c41cca9830d93540238f17df8faafb Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sat, 19 Sep 2026 14:40:34 +0900 Subject: [PATCH 14/97] fix(gui): validate Claude Desktop status payloads before trusting them (#5089) * fix(gui): validate Claude Desktop status payloads before trusting them The status poll accepted any JSON and cached it as DesktopStatus, so an error-shaped or malformed OK payload reached the render path where status.health dereferences crashed the page. Guard the wire response and the cached entry with isDesktopStatus: a non-conforming fetch now records a cold failure and shows the existing failure presentation, and a non-conforming cache entry is treated as absent. * docs(pr): add the malformed-status Desktop screenshot --------- Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com> --- .../5089-claude-desktop-malformed-status.png | Bin 0 -> 137420 bytes gui/src/pages/ClaudeDesktop.tsx | 30 +++++++++++++++--- gui/tests/claude-desktop-vertical.test.tsx | 24 +++++++++++++- 3 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 .github/pr-assets/5089-claude-desktop-malformed-status.png diff --git a/.github/pr-assets/5089-claude-desktop-malformed-status.png b/.github/pr-assets/5089-claude-desktop-malformed-status.png new file mode 100644 index 0000000000000000000000000000000000000000..324bf077f7d577684f674b209f5f2d4503e9462d GIT binary patch literal 137420 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%0ArWU8UJ<_EkQ)d3oz9u2*4#b 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 literal 0 HcmV?d00001 diff --git a/gui/src/pages/ClaudeDesktop.tsx b/gui/src/pages/ClaudeDesktop.tsx index 9c17a994da5..3878f7d5b42 100644 --- a/gui/src/pages/ClaudeDesktop.tsx +++ b/gui/src/pages/ClaudeDesktop.tsx @@ -56,6 +56,25 @@ interface DesktopStatus { health: { lastRequestAt: string | null; requestCount: number; errorCount: number }; } +/** + * The status poll accepts any JSON today, so an error-shaped or malformed OK + * payload would be cached and rendered as a real status until the next poll. + * Validate before trusting either the wire or the cache. + */ +function isDesktopStatus(value: unknown): value is DesktopStatus { + if (typeof value !== "object" || value === null) return false; + const v = value as Record; + const health = v.health as Record | null | undefined; + return typeof v.desiredEnabled === "boolean" + && typeof v.applied === "boolean" + && (v.appliedAt === null || typeof v.appliedAt === "string") + && typeof v.stale === "boolean" + && typeof health === "object" && health !== null + && (health.lastRequestAt === null || typeof health.lastRequestAt === "string") + && typeof health.requestCount === "number" + && typeof health.errorCount === "number"; +} + interface DesktopResponse { profile: DesktopProfile; models: DesktopModel[]; @@ -271,21 +290,24 @@ export default function ClaudeDesktop({ const statusCacheKey = `ocx.claude-desktop.status.v1:${apiBase}`; const statusResourceKey = `claude-desktop-status:${apiBase}`; const cachedStatusEntry = readSessionListCacheEntry(statusCacheKey); + const cachedStatus = cachedStatusEntry && isDesktopStatus(cachedStatusEntry.data) + ? cachedStatusEntry.data + : null; const statusResource = useDataSurface( statusResourceKey, [apiBase], async (signal) => { const response = await fetch(`${apiBase}/api/claude-desktop/status`, { signal }); - const next = await readJsonIfOk(response); - if (!next) throw new Error("Claude Desktop status unavailable"); + const next = await readJsonIfOk(response); + if (!isDesktopStatus(next)) throw new Error("Claude Desktop status unavailable"); writeSessionListCacheEntry(statusCacheKey, next); return next; }, // Polled, so no staleAfterMs: the cadence already keeps it fresh. - { isEmpty: () => false, pollMs: 5000, enabled: active, initialData: cachedStatusEntry?.data ?? undefined }, + { isEmpty: () => false, pollMs: 5000, enabled: active, initialData: cachedStatus ?? undefined }, ); const statusState = statusResource.state; - const status = statusState.data ?? cachedStatusEntry?.data ?? null; + const status = statusState.data ?? cachedStatus; const statusFailed = statusState.showError; const moveModel = (route: string, family: Family) => { diff --git a/gui/tests/claude-desktop-vertical.test.tsx b/gui/tests/claude-desktop-vertical.test.tsx index 6dc43b5872a..10241ab8e5c 100644 --- a/gui/tests/claude-desktop-vertical.test.tsx +++ b/gui/tests/claude-desktop-vertical.test.tsx @@ -61,7 +61,7 @@ beforeEach(() => { configurable: true, value: async (url: string) => { const body = String(url).includes("/status") - ? { applied: true, appliedAt: null, stale: false, health: { lastRequestAt: null, requestCount: 0, errorCount: 0 } } + ? { desiredEnabled: true, applied: true, appliedAt: null, stale: false, health: { lastRequestAt: null, requestCount: 0, errorCount: 0 } } : payload(); return { ok: true, status: 200, json: async () => body, text: async () => JSON.stringify(body) } as unknown as Response; }, @@ -205,3 +205,25 @@ test("a stored preference wins over the load-time default", async () => { expect(familyToggle("Opus").getAttribute("aria-expanded")).toBe("false"); expect(familyToggle("Fable").getAttribute("aria-expanded")).toBe("true"); }); + +test("a malformed status payload shows the failure state instead of crashing", async () => { + /* + * The status poll used to trust any JSON: an error-shaped OK body missing + * health would be cached and rendered, then status.health.requestCount + * threw inside the page. The guard rejects it, so the resource records a + * cold failure and the existing failure presentation shows. + */ + Object.defineProperty(globalThis, "fetch", { + configurable: true, + value: async (url: string) => { + const body = String(url).includes("/status") + ? { error: "malformed" } + : payload(); + return { ok: true, status: 200, json: async () => body, text: async () => JSON.stringify(body) } as unknown as Response; + }, + }); + + await mount(); + + expect(container.textContent ?? "").toContain("Failed to load Claude Desktop profile."); +}); From 04761a188281da4a2936fc4d8d9be5e02b33bb41 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 15:22:11 +0900 Subject: [PATCH 15/97] fix(responses): emit the tool name the undeclared-tool guard authorized (#5095) (#5100) A routed Command Code Muse turn reached Codex App carrying {"type":"function_call","name":"default.view_image"} and the same item for default.apply_patch. Codex has no handler for either name, answered "unsupported call", and stored both. Every later request that replayed that history was then refused before it could run: Invalid 'input[877].name': string does not match pattern '^[a-zA-Z0-9_-]+$'. A side chat opened from an 11h43m parent task hit it through automatic compaction, and no upgrade helps once the item is in stored history. The cause is two resolvers disagreeing, not a missing mechanism. undeclaredNameInItem resolves an emitted name through normalizeDeclaredToolName, which maps a default.-prefixed code-mode helper onto the declared exec (#4412) as well as a default.-prefixed bare tool (#4176), so default.view_image was ADMITTED as exec. The emit-side rewrite, normalizeDefaultNamespaceInItem, implemented only the bare-tool half, so it forwarded the name unchanged. The guard's own conclusion never reached the client. Fall back to the resolver in the rewrite, so a name good enough to admit is the name the client receives. Gated on isSchemaValidResponsesToolName rejecting the emitted name, so a name the upstream accepts cannot be reshaped by this branch no matter what the resolver would say about it. The routed-custom-tool and namespace restores run earlier in the same rewrite chain and keep owning the shapes they convert; this is the boundary check for names no restore claimed. A dotted name that resolves to nothing declared is left alone here and stays refused by the #1700 guard, which is the pre-existing behaviour and the right one: an unresolvable invalid name must end the turn visibly rather than enter stored history. A dotted name the caller itself declared is a real identity and passes through byte-identical. No local suite was run. Refs #5095 --- scripts/test-layout/layout.json | 1 + src/responses/tool-name-aliases.ts | 16 +- src/server/responses-undeclared-tool-guard.ts | 32 ++- structure/transports/responses.md | 13 ++ tests/fixtures/test-layout-expected.json | 1 + ...s-default-namespace-emit-normalize.test.ts | 211 ++++++++++++++++++ 6 files changed, 272 insertions(+), 2 deletions(-) create mode 100644 tests/responses/responses-default-namespace-emit-normalize.test.ts diff --git a/scripts/test-layout/layout.json b/scripts/test-layout/layout.json index 87e441939ac..65221ae9757 100644 --- a/scripts/test-layout/layout.json +++ b/scripts/test-layout/layout.json @@ -276,6 +276,7 @@ "azure-model-router-tool-schema.test.ts": "providers", "bare-echo-alias.test.ts": "responses", "responses-bare-echo-helper-fence.test.ts": "responses", + "responses-default-namespace-emit-normalize.test.ts": "responses", "responses-preview-main-read-fence.test.ts": "responses", "baseten-provider.test.ts": "providers", "bearer-admission-routed-provider.test.ts": "codex-integration", diff --git a/src/responses/tool-name-aliases.ts b/src/responses/tool-name-aliases.ts index 1943a686bfd..28464f284f1 100644 --- a/src/responses/tool-name-aliases.ts +++ b/src/responses/tool-name-aliases.ts @@ -19,6 +19,21 @@ export function dottedAliasIsUnambiguous(namespace: string, name: string): boole return !namespace.includes("__") && !name.includes("__"); } +/** + * Charset the Responses API enforces on a tool-call `name`. + * + * A name outside it is not merely rejected for the turn that carries it: Codex stores the item in + * the conversation, and every later request that replays that history is refused before it runs + * (`Invalid 'input[N].name': string does not match pattern '^[a-zA-Z0-9_-]+$'`). One relayed item + * therefore ends the conversation permanently, which is why the emit boundary treats an invalid + * name as a defect to repair rather than as a name to forward. See #5095. + */ +const RESPONSES_TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]+$/; + +export function isSchemaValidResponsesToolName(name: string): boolean { + return RESPONSES_TOOL_NAME_PATTERN.test(name); +} + export function wireToolInnerName(tool: unknown): string | undefined { if (!isPlainObject(tool)) return undefined; const nestedFunction = tool.type === "function" && isPlainObject(tool.function) @@ -76,4 +91,3 @@ export function collectAmbiguousDottedAliases(specGroups: readonly unknown[]): S for (const [alias, owner] of owners) if (owner === null) ambiguous.add(alias); return ambiguous; } - diff --git a/src/server/responses-undeclared-tool-guard.ts b/src/server/responses-undeclared-tool-guard.ts index 4cefb22784a..7b2a2a22c1c 100644 --- a/src/server/responses-undeclared-tool-guard.ts +++ b/src/server/responses-undeclared-tool-guard.ts @@ -1,4 +1,9 @@ -import { collectAmbiguousDottedAliases, dottedAliasIsUnambiguous, wireToolInnerName } from "../responses/tool-name-aliases"; +import { + collectAmbiguousDottedAliases, + dottedAliasIsUnambiguous, + isSchemaValidResponsesToolName, + wireToolInnerName, +} from "../responses/tool-name-aliases"; import { dottedToolName, NAMESPACED_BARE_ALIAS_EXCLUDED_NAMES, @@ -512,6 +517,31 @@ export function normalizeDefaultNamespaceInItem( return { value: { ...item, name: bare }, changed: true }; } } + // Authorization and emission were reading two different resolvers for the same question. + // `undeclaredNameInItem` resolves an emitted name through `normalizeDeclaredToolName`, which + // maps a `default.`-prefixed code-mode helper onto the declared `exec` (#4412) as well as a + // `default.`-prefixed bare tool (#4176); the rewrite above learned only the second case. So a + // routed Muse turn under a code-mode catalog had `default.view_image` ACCEPTED as `exec` and + // then relayed under the name the upstream schema rejects. Codex stored + // `{"type":"function_call","name":"default.view_image"}`, answered "unsupported call", and + // every later replay of that history — a side chat, a compaction — was refused on + // `input[N].name` for the lifetime of the conversation (#5095). + // + // Emit the name the guard authorized rather than a second, weaker opinion about it. The two + // must agree: a name good enough to admit is the name the client has to receive. + // + // Gated on the name actually being unusable, so this branch cannot touch a name the upstream + // accepts whatever the resolver would have said about it. The routed-custom-tool and + // namespace restores run earlier in the same chain and already rewrite the shapes they own, + // which leaves this as the boundary check for the names no restore claimed. + if (!isSchemaValidResponsesToolName(name)) { + const authorized = normalizeDeclaredToolName(name, declared, declaredBare); + if ( + authorized !== name + && declared.has(authorized) + && isSchemaValidResponsesToolName(authorized) + ) return { value: { ...item, name: authorized }, changed: true }; + } } return { value: item, changed: false }; } diff --git a/structure/transports/responses.md b/structure/transports/responses.md index 811d819bbf8..8b06c9c45c9 100644 --- a/structure/transports/responses.md +++ b/structure/transports/responses.md @@ -547,6 +547,19 @@ declared bare tool and to rewrite code-mode helper names into the declared `exec input unchanged when the set is absent, so the set reaches the bridge on every wire and enforcement is expressed by a separate flag rather than by withholding it. +The passthrough guard resolves an emitted name through that same `normalizeDeclaredToolName`, so +whatever it admits it must also EMIT under the resolved name. The two halves disagreed once: +`normalizeDefaultNamespaceInItem` implemented only the bare-tool case (#4176), so a +`default.`-prefixed code-mode helper was admitted as `exec` (#4412) and then relayed verbatim. +`default.view_image` is not a legal Responses tool name, and Codex stores what it receives, so the +one relayed item was refused by `^[a-zA-Z0-9_-]+$` on every later replay of that conversation and +the task could not be compacted or continued (#5095). The rewrite now falls back to the resolver +whenever `isSchemaValidResponsesToolName` (`src/responses/tool-name-aliases.ts`) rejects the emitted +name, and only then, so a name the upstream accepts is never reshaped by this branch. A name that +resolves to nothing declared stays refused by the #1700 guard, which is the pre-existing and +intended outcome: an invalid name that cannot be resolved must end the turn visibly rather than +reach stored history. + Membership enforcement is that flag, `enforceDeclaredToolNames`, and only the `responses` inbound wire enforces. A routed provider that names a tool the request never declared ends the turn there: `src/bridge/sse.ts` emits `response.failed` and `src/bridge/response-json.ts` returns a failed diff --git a/tests/fixtures/test-layout-expected.json b/tests/fixtures/test-layout-expected.json index 89ff7df6a5a..d647909da8b 100644 --- a/tests/fixtures/test-layout-expected.json +++ b/tests/fixtures/test-layout-expected.json @@ -1040,6 +1040,7 @@ "responses-context-overflow.test.ts": "responses", "responses-custom-tool-guidance.test.ts": "responses", "responses-custom-tool-repair.test.ts": "responses", + "responses-default-namespace-emit-normalize.test.ts": "responses", "responses-fetch-helpers-boundary.test.ts": "responses", "responses-hosted-tool-declaration.test.ts": "responses", "responses-field-backfill.test.ts": "responses", diff --git a/tests/responses/responses-default-namespace-emit-normalize.test.ts b/tests/responses/responses-default-namespace-emit-normalize.test.ts new file mode 100644 index 00000000000..5b7952468b9 --- /dev/null +++ b/tests/responses/responses-default-namespace-emit-normalize.test.ts @@ -0,0 +1,211 @@ +/** + * #5095: a routed Command Code Muse turn reached Codex App carrying + * `{"type":"function_call","name":"default.view_image"}`. Codex has no handler for that name, so + * it answered "unsupported call" and stored the item; every later request that replayed the + * history was then refused by the upstream name pattern + * (`Invalid 'input[877].name': string does not match pattern '^[a-zA-Z0-9_-]+$'`), which is what + * killed a side chat opened from an 11h43m parent task. One relayed item ends the conversation. + * + * The cause was two resolvers disagreeing rather than a missing mechanism. The passthrough guard + * RESOLVES an emitted name through `normalizeDeclaredToolName`, which maps a `default.`-prefixed + * code-mode helper onto the declared `exec` (#4412) as well as a `default.`-prefixed bare tool + * (#4176), so `default.view_image` was authorized. The emit-side rewrite + * (`normalizeDefaultNamespaceInItem`) knew only the bare-tool case, so it forwarded the name + * unchanged. These pin the agreement: the name the guard admits is the name the client receives. + * + * Kept out of `responses-undeclared-tool-guard.test.ts` because that file sits at its + * file-size-baseline cap, and caps only move down. + */ +import { describe, expect, test } from "bun:test"; +import { + collectDeclaredBareWireToolNames, + collectDeclaredWireToolNames, + createUndeclaredToolCallGuardBlockRewrite, + normalizeDefaultNamespaceInResponse, + undeclaredToolCallNameInResponse, + UNDECLARED_TOOL_CALL_ERROR_CODE, +} from "../../src/server/responses-undeclared-tool-guard"; +import { isSchemaValidResponsesToolName } from "../../src/responses/tool-name-aliases"; + +/** Codex code mode: the shell is one freeform `exec`; every helper lives inside it, undeclared. */ +const CODE_MODE_BODY = { + tools: [{ type: "custom", name: "exec", description: "code mode" }], +} as const; + +/** The classic Codex catalog, where `view_image` is a declared top-level function. */ +const CLASSIC_BODY = { + tools: [ + { type: "function", name: "view_image", parameters: { type: "object" } }, + { type: "custom", name: "apply_patch" }, + ], +} as const; + +function declarationsOf(body: unknown): { + declared: ReadonlySet; + declaredBare: ReadonlySet; +} { + return { + declared: collectDeclaredWireToolNames(body), + declaredBare: collectDeclaredBareWireToolNames(body), + }; +} + +function responseWith(...output: readonly unknown[]): Record { + return { id: "resp_1", status: "completed", output }; +} + +function normalizedNames(body: unknown, ...output: readonly unknown[]): unknown { + const { declared, declaredBare } = declarationsOf(body); + const result = normalizeDefaultNamespaceInResponse(responseWith(...output), declared, declaredBare); + return (result.value as { output: Array<{ name?: unknown }> }).output.map(item => item.name); +} + +function guardVerdict(body: unknown, item: unknown): string | undefined { + const { declared, declaredBare } = declarationsOf(body); + return undeclaredToolCallNameInResponse(responseWith(item), declared, undefined, undefined, declaredBare); +} + +describe("schema-valid Responses tool names", () => { + test("the pattern the upstream enforces is what the emit boundary reads", () => { + expect(isSchemaValidResponsesToolName("view_image")).toBe(true); + expect(isSchemaValidResponsesToolName("exec")).toBe(true); + expect(isSchemaValidResponsesToolName("mcp__ctx7__get-docs")).toBe(true); + expect(isSchemaValidResponsesToolName("default.view_image")).toBe(false); + expect(isSchemaValidResponsesToolName("mcp__ctx7.get_docs")).toBe(false); + expect(isSchemaValidResponsesToolName("view image")).toBe(false); + expect(isSchemaValidResponsesToolName("")).toBe(false); + }); +}); + +describe("default-namespaced helper names under a code-mode catalog", () => { + test("a dotted helper whose suffix resolves to the one declared tool is emitted as that tool", () => { + // The two names from the report, verbatim. + expect(normalizedNames( + CODE_MODE_BODY, + { type: "function_call", call_id: "c1", name: "default.view_image", arguments: "{}" }, + { type: "function_call", call_id: "c2", name: "default.apply_patch", arguments: "{}" }, + )).toEqual(["exec", "exec"]); + }); + + test("the guard already admitted these names, which is why they reached the client", () => { + expect(guardVerdict(CODE_MODE_BODY, { + type: "function_call", call_id: "c1", name: "default.view_image", arguments: "{}", + })).toBeUndefined(); + }); + + test("every emitted name is one the upstream schema accepts", () => { + const names = normalizedNames( + CODE_MODE_BODY, + { type: "function_call", call_id: "c1", name: "default.view_image", arguments: "{}" }, + { type: "function_call", call_id: "c2", name: "default.exec_command", arguments: "{}" }, + { type: "function_call", call_id: "c3", name: "default.write_stdin", arguments: "{}" }, + ) as string[]; + for (const name of names) expect(isSchemaValidResponsesToolName(name)).toBe(true); + }); + + test("a dotted suffix that matches no declared tool is refused, not renamed", () => { + const item = { type: "function_call", call_id: "c1", name: "default.lookup", arguments: "{}" }; + expect(normalizedNames(CODE_MODE_BODY, item)).toEqual(["default.lookup"]); + expect(guardVerdict(CODE_MODE_BODY, item)).toBe("default.lookup"); + }); +}); + +describe("names the emit boundary must not touch", () => { + test("a canonical declared name passes through byte-identical", () => { + const item = { type: "function_call", call_id: "c1", name: "view_image", arguments: "{}" }; + const { declared, declaredBare } = declarationsOf(CLASSIC_BODY); + const response = responseWith(item); + const result = normalizeDefaultNamespaceInResponse(response, declared, declaredBare); + expect(result.changed).toBe(false); + expect(result.value).toBe(response); + }); + + test("a declared bare tool keeps the #4176 rewrite to the bare name, not to exec", () => { + expect(normalizedNames( + CLASSIC_BODY, + { type: "function_call", call_id: "c1", name: "default.view_image", arguments: "{}" }, + )).toEqual(["view_image"]); + }); + + test("a dotted name the caller itself declared is a real identity and is left alone", () => { + // `default` here is a genuine namespace the request declared, so `default.view_image` is the + // flattened spelling of a tool the caller owns. Two declared identities claim the suffix + // `view_image`; rewriting either onto the other would dispatch a call the caller never made. + const ambiguous = { + tools: [ + { type: "function", name: "view_image", parameters: { type: "object" } }, + { type: "namespace", name: "default", tools: [{ type: "function", name: "view_image", parameters: { type: "object" } }] }, + ], + }; + const item = { type: "function_call", call_id: "c1", name: "default.view_image", arguments: "{}" }; + const { declared, declaredBare } = declarationsOf(ambiguous); + expect(declared.has("default.view_image")).toBe(true); + const response = responseWith(item); + const result = normalizeDefaultNamespaceInResponse(response, declared, declaredBare); + expect(result.changed).toBe(false); + expect(result.value).toBe(response); + }); + + test("a name invalid for a reason other than the namespace is refused rather than guessed at", () => { + for (const name of ["view image", "view_image!", "exec/apply_patch"]) { + const item = { type: "function_call", call_id: "c1", name, arguments: "{}" }; + expect(normalizedNames(CODE_MODE_BODY, item)).toEqual([name]); + expect(guardVerdict(CODE_MODE_BODY, item)).toBe(name); + } + }); + + test("a non-call item carrying a dotted name field is not a tool identity", () => { + const message = { type: "message", role: "assistant", content: [{ type: "output_text", text: "default.view_image" }] }; + const { declared, declaredBare } = declarationsOf(CODE_MODE_BODY); + const response = responseWith(message); + expect(normalizeDefaultNamespaceInResponse(response, declared, declaredBare).value).toBe(response); + }); +}); + +describe("a replay mixing damaged and undamaged items", () => { + test("only the damaged item changes and the rest are preserved value-identically", () => { + const undamagedOne = { type: "function_call", call_id: "c1", name: "view_image", arguments: "{\"path\":\"a.png\"}" }; + const damaged = { type: "function_call", call_id: "c2", name: "default.apply_patch", arguments: "{}" }; + const undamagedTwo = { type: "message", role: "assistant", content: [{ type: "output_text", text: "done" }] }; + const { declared, declaredBare } = declarationsOf(CLASSIC_BODY); + const response = responseWith(undamagedOne, damaged, undamagedTwo); + const result = normalizeDefaultNamespaceInResponse(response, declared, declaredBare); + expect(result.changed).toBe(true); + const output = (result.value as { output: unknown[] }).output; + expect(output[0]).toBe(undamagedOne); + expect(output[1]).toEqual({ type: "function_call", call_id: "c2", name: "apply_patch", arguments: "{}" }); + expect(output[2]).toBe(undamagedTwo); + }); +}); + +describe("the streaming boundary the report actually crossed", () => { + const blocks = (rewrite: (block: string) => readonly string[], items: readonly unknown[]): string[] => { + const out: string[] = []; + for (const item of items) { + const payload = JSON.stringify({ type: "response.output_item.added", output_index: 0, item }); + out.push(...rewrite(`event: response.output_item.added\ndata: ${payload}`)); + } + return out; + }; + + test("the streamed item is rewritten to the authorized name", () => { + const { declared, declaredBare } = declarationsOf(CODE_MODE_BODY); + const rewrite = createUndeclaredToolCallGuardBlockRewrite(declared, undefined, undefined, declaredBare); + const emitted = blocks(rewrite, [ + { type: "function_call", id: "fc_1", call_id: "c1", name: "default.view_image", arguments: "{}" }, + ]); + expect(emitted).toHaveLength(1); + expect(emitted[0]).toContain('"name":"exec"'); + expect(emitted[0]).not.toContain("default.view_image"); + }); + + test("an unresolvable dotted name ends the turn instead of reaching the client", () => { + const { declared, declaredBare } = declarationsOf(CODE_MODE_BODY); + const rewrite = createUndeclaredToolCallGuardBlockRewrite(declared, undefined, undefined, declaredBare); + const emitted = blocks(rewrite, [ + { type: "function_call", id: "fc_1", call_id: "c1", name: "default.lookup", arguments: "{}" }, + ]); + expect(emitted.join("\n")).toContain(UNDECLARED_TOOL_CALL_ERROR_CODE); + expect(emitted.join("\n")).toContain("response.failed"); + }); +}); From 4e45e1770f11576cf81bd9b7307d0cbdf628be65 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 16:07:28 +0900 Subject: [PATCH 16/97] fix(responses): repair legacy dotted call names on replay (#5095) (#5101) Stopping the emission is only half the report. Codex stores what it received, so a conversation that already contains a default.-prefixed function_call name is refused on EVERY later request that replays it: Invalid 'input[877].name': string does not match pattern '^[a-zA-Z0-9_-]+$'. The task cannot be compacted or continued, and upgrading does not reach it. That is the part of the report that actually hurts: a side chat opened from an 11h43m parent hit it on a plain OpenAI model, from history a routed provider had damaged. repairLegacyDottedToolCallNames repairs the replayed item on the way out, in buildRequest beside backfillWebSearchQueries and again in compact.ts, which forwards the caller's body directly. It runs before the canonical-destination split, because the destination that refused the request was plain OpenAI. What resolves is bounded on purpose: - a dotted spelling the caller's own catalog declares is a real tool identity and is never stripped; rewriting it would change which tool the history says was called; - a suffix claimed by two declared identities is ambiguous and is left alone; - a suffix naming exactly one declared tool resolves to it; - otherwise, only the code-mode helper spellings in CODE_MODE_HELPER_WIRE_NAMES resolve, because a code-mode catalog never declares them -- they exist solely as nested tools.* helpers inside exec, so a recorded call under one of those names can only be a provider echoing the helper. There is deliberately no "strip everything before the first dot" rule. A legitimate tool name may contain a dot in another provider's vocabulary, and a replayed item names a call that already happened, which is the worst possible place to guess. Anything unresolved is left exactly as it is; the upstream still refuses it, which is the pre-existing outcome rather than a new one. Only replayed input items are eligible. The caller's tool catalog is never rewritten, call_id is untouched so a repaired call still pairs with its stored output, and a body with nothing to repair is returned by reference. No local suite was run. Refs #5095 --- scripts/test-layout/layout.json | 1 + src/adapters/openai-responses/passthrough.ts | 7 + .../legacy-dotted-tool-name-repair.ts | 134 +++++++++++++++ src/server/responses/compact.ts | 8 +- src/types.ts | 1 + src/types/tools.ts | 14 ++ structure/transports/responses.md | 18 ++ tests/fixtures/test-layout-expected.json | 1 + ...ses-legacy-dotted-tool-name-repair.test.ts | 158 ++++++++++++++++++ 9 files changed, 341 insertions(+), 1 deletion(-) create mode 100644 src/responses/legacy-dotted-tool-name-repair.ts create mode 100644 tests/responses/responses-legacy-dotted-tool-name-repair.test.ts diff --git a/scripts/test-layout/layout.json b/scripts/test-layout/layout.json index 65221ae9757..6610565f8c0 100644 --- a/scripts/test-layout/layout.json +++ b/scripts/test-layout/layout.json @@ -1226,6 +1226,7 @@ "responses-inbound-store-default.test.ts": "responses", "responses-item-id-repair.test.ts": "responses", "responses-json-events.test.ts": "responses", + "responses-legacy-dotted-tool-name-repair.test.ts": "responses", "responses-muse-tool-name-alias.test.ts": "responses", "responses-native-main-refresh.test.ts": "responses", "responses-opaque-blob-recovery.test.ts": "responses", diff --git a/src/adapters/openai-responses/passthrough.ts b/src/adapters/openai-responses/passthrough.ts index 1184ac6a1c7..31130b5b783 100644 --- a/src/adapters/openai-responses/passthrough.ts +++ b/src/adapters/openai-responses/passthrough.ts @@ -18,6 +18,7 @@ import type { TranslatorBudget } from "../../lib/translator-budget"; import { rewriteRoutedCustomToolsForUpstream } from "../../responses/custom-tool-compat"; import { rewriteRoutedToolSearchForUpstream } from "../../responses/tool-search-compat"; import { rewriteRoutedNamespaceToolsForUpstream } from "../../responses/namespace-tool-compat"; +import { repairLegacyDottedToolCallNames } from "../../responses/legacy-dotted-tool-name-repair"; import { preparePlaintextV2AgentMessages } from "../../responses/plaintext-v2-agent-messages"; import { isMetaAiResponsesDestination, rewriteMuseToolNamesForUpstream } from "../../responses/muse-tool-name-alias"; import { openaiResponsesUrl } from "../openai-responses-url"; @@ -335,6 +336,12 @@ export function createResponsesPassthroughAdapter(provider: OcxProviderConfig): // every turn, and a strict parser rejects the whole request over the missing key — // `queries` for DeepSeek (#930), `query` for Console Go (#3071). outBody = backfillWebSearchQueries(outBody); + // #5095: a conversation that already contains a `default.`-prefixed call name is refused by + // the upstream `^[a-zA-Z0-9_-]+$` name pattern on every later turn that replays it, so the + // task cannot be compacted or continued at all. Repair the replayed item here, before the + // canonical-destination split below, because the reported failure was a side chat on a plain + // OpenAI model inheriting history a routed provider had damaged. + outBody = repairLegacyDottedToolCallNames(outBody); if (!isCanonicalOpenAiForwardProvider(provider)) { outBody = stripInternalChatMessageMetadataPassthrough(outBody); // The same class of private field, one level up, but keyed on the DESTINATION rather than diff --git a/src/responses/legacy-dotted-tool-name-repair.ts b/src/responses/legacy-dotted-tool-name-repair.ts new file mode 100644 index 00000000000..4346c1c0415 --- /dev/null +++ b/src/responses/legacy-dotted-tool-name-repair.ts @@ -0,0 +1,134 @@ +import { collectResponsesToolGroups } from "./tool-groups"; +import { isSchemaValidResponsesToolName, wireToolInnerName } from "./tool-name-aliases"; +import { CODE_MODE_HELPER_WIRE_NAMES, dottedToolName, namespacedToolName } from "../types"; + +/** + * The one invented namespace this proxy is known to have emitted. Routed providers flatten a + * namespaced call as `ns.name`, and a provider that invents the grouping picks `default`; #3402, + * #4176 and #4412 all repaired that spelling on the way IN, each on its own path. + * + * This is deliberately one literal prefix rather than a rule. "Strip everything before the first + * dot" would silently rewrite a legitimate tool name that happens to contain a dot in some other + * provider's vocabulary, and a replayed history item is the worst possible place to guess: it names + * a call that already happened. + */ +const LEGACY_INVENTED_NAMESPACE_PREFIX = "default."; + +/** Item types whose `name` the upstream validates against the tool-name pattern. */ +const NAMED_CALL_ITEM_TYPES = new Set(["function_call", "custom_tool_call"]); + +function isPlainObject(value: unknown): value is Record { + return !!value && typeof value === "object" && !Array.isArray(value); +} + +type DeclarationView = { + /** Wire spellings the caller's own catalog declares, including flattened namespace forms. */ + readonly spellings: ReadonlySet; + /** How many declared identities answer to a given inner name. */ + readonly ownersByInnerName: ReadonlyMap; +}; + +/** + * Read the request's own catalog. Namespace children contribute their inner name and both + * flattened spellings, which is what makes a declared `default` namespace distinguishable from an + * invented one. + */ +function readDeclarations(body: unknown): DeclarationView { + const spellings = new Set(); + const owners = new Map(); + const identities = new Map>(); + const claim = (innerName: string, identity: string): void => { + const seen = identities.get(innerName); + if (seen === undefined) identities.set(innerName, new Set([identity])); + else seen.add(identity); + }; + for (const group of collectResponsesToolGroups(body)) { + for (const spec of group) { + if (!isPlainObject(spec)) continue; + if (spec.type === "namespace" && Array.isArray(spec.tools)) { + const namespace = typeof spec.name === "string" ? spec.name : undefined; + if (namespace === undefined) continue; + for (const child of spec.tools) { + const inner = wireToolInnerName(child); + if (!inner) continue; + spellings.add(namespacedToolName(namespace, inner)); + spellings.add(dottedToolName(namespace, inner)); + claim(inner, JSON.stringify([namespace, inner])); + } + continue; + } + const name = wireToolInnerName(spec); + if (!name) continue; + spellings.add(name); + claim(name, JSON.stringify([null, name])); + } + } + for (const [inner, owning] of identities) owners.set(inner, owning.size); + return { spellings, ownersByInnerName: owners }; +} + +/** + * Canonical name a legacy dotted alias should be replayed under, or undefined to leave it alone. + * + * Fail-closed in both directions that matter. A dotted spelling the caller's catalog actually + * declares is a real tool identity, so it is never stripped — rewriting it would change which tool + * the history says was called. A suffix claimed by two declared identities is ambiguous and is + * left as it is. Only two things resolve: a suffix that names exactly one declared tool, and the + * bounded set of code-mode helper spellings, which a code-mode catalog never declares because they + * exist only as nested `tools.*` helpers inside `exec`. + */ +function repairedCallName(name: string, declarations: DeclarationView): string | undefined { + if (isSchemaValidResponsesToolName(name)) return undefined; + if (!name.startsWith(LEGACY_INVENTED_NAMESPACE_PREFIX)) return undefined; + if (declarations.spellings.has(name)) return undefined; + const suffix = name.slice(LEGACY_INVENTED_NAMESPACE_PREFIX.length); + if (!isSchemaValidResponsesToolName(suffix)) return undefined; + const owners = declarations.ownersByInnerName.get(suffix); + if (owners === 1) return suffix; + if (owners !== undefined) return undefined; + return CODE_MODE_HELPER_WIRE_NAMES.has(suffix) ? suffix : undefined; +} + +function repairedItem(item: unknown, declarations: DeclarationView): unknown { + if (!isPlainObject(item)) return item; + if (typeof item.type !== "string" || !NAMED_CALL_ITEM_TYPES.has(item.type)) return item; + // An item carrying an explicit namespace is a namespaced identity whose `name` is the inner + // name; it is not the flattened shape this repairs, and its own field is the authority. + if (item.namespace !== undefined) return item; + if (typeof item.name !== "string") return item; + const repaired = repairedCallName(item.name, declarations); + return repaired === undefined ? item : { ...item, name: repaired }; +} + +/** + * Make an already-damaged conversation replayable. + * + * A `function_call` whose name violates `^[a-zA-Z0-9_-]+$` is not a one-turn failure: Codex stores + * the item, and the upstream then refuses EVERY later request that replays it + * (`Invalid 'input[N].name': ...`) — including the automatic compaction a long task or a side chat + * triggers. The emit-side fix stops new items from being created; without this the conversations + * that already contain one stay permanently unusable, which is the part of #5095 that actually + * hurts. + * + * Only replayed input items are touched. The caller's tool catalog is never rewritten, and a body + * with nothing to repair is returned by reference. + */ +export function repairLegacyDottedToolCallNames(body: unknown): unknown { + if (!isPlainObject(body) || !Array.isArray(body.input)) return body; + if (!body.input.some(item => + isPlainObject(item) + && typeof item.type === "string" + && NAMED_CALL_ITEM_TYPES.has(item.type) + && typeof item.name === "string" + && item.name.startsWith(LEGACY_INVENTED_NAMESPACE_PREFIX) + )) return body; + + const declarations = readDeclarations(body); + let changed = false; + const input = body.input.map(item => { + const repaired = repairedItem(item, declarations); + if (repaired !== item) changed = true; + return repaired; + }); + return changed ? { ...body, input } : body; +} diff --git a/src/server/responses/compact.ts b/src/server/responses/compact.ts index ab16ce31b6e..a283dd3dfa6 100644 --- a/src/server/responses/compact.ts +++ b/src/server/responses/compact.ts @@ -10,6 +10,7 @@ import { parseRequest } from "../../responses/parser"; import { buildCompactV1Output, COMPACT_PROMPT, decodeCompactionSummary, extractCompactUserMessages } from "../../responses/compaction"; import { FORWARD_HEADERS, sanitizeReasoningInputContent } from "../../adapters/openai-responses"; import { expandPreviousResponseInput, previousResponseProviderState, rememberResponseState } from "../../responses/state"; +import { repairLegacyDottedToolCallNames } from "../../responses/legacy-dotted-tool-name-repair"; import { NoEligiblePolicyCandidateError, routeCompactionModel } from "../../router"; import { evidenceFromBody } from "../../routing/request-evidence"; import { @@ -845,7 +846,12 @@ export async function handleResponsesCompact( // The regular /v1/responses path applies sanitizeReasoningInputContent via the adapter's // buildRequest, but the compact endpoint forwards directly. Apply the same sanitizer here // so routed-model reasoning items (reasoning_text content) don't 400 the ChatGPT backend. - const compactBody = sanitizeReasoningInputContent(compactBodyRaw) as typeof compactBodyRaw; + // #5095: the compact endpoint forwards `raw` directly, so it needs the same legacy dotted + // call-name repair the adapter applies. A damaged item here refuses the compaction itself, + // which is the request a long task depends on to keep going. + const compactBody = repairLegacyDottedToolCallNames( + sanitizeReasoningInputContent(compactBodyRaw), + ) as typeof compactBodyRaw; { const binding = conversationStateBindingFromAuth(authCtx, codexPoolAffinityKey(req.headers)); if (binding) { diff --git a/src/types.ts b/src/types.ts index 9ef3936da97..93390ce6063 100644 --- a/src/types.ts +++ b/src/types.ts @@ -4,6 +4,7 @@ export type { OcxTool, OcxToolChoice } from "./types/tools"; export { CODE_MODE_EXEC_TOOL_NAME, + CODE_MODE_HELPER_WIRE_NAMES, dottedToolName, namespacedToolName, normalizeDeclaredToolName, diff --git a/src/types/tools.ts b/src/types/tools.ts index 06fe8589e1e..83decd85b14 100644 --- a/src/types/tools.ts +++ b/src/types/tools.ts @@ -67,6 +67,20 @@ const CODE_MODE_HELPER_TOOL_NAMES = [ */ export const CODE_MODE_EXEC_TOOL_NAME = "exec"; +/** + * The nested-helper spellings, as a membership view of the same list. + * + * A code-mode catalog never DECLARES any of them — they exist only as `tools.(...)` inside + * `exec` — so a recorded call under one of these names can only have come from a provider echoing + * the helper, which is what makes the set usable as a bounded recovery vocabulary for stored + * history (#5095). Kept beside the tuple it is built from so the two can never drift; this is a + * different question from `NAMESPACED_BARE_ALIAS_EXCLUDED_NAMES` below, which also covers `exec` + * itself because declaring THAT name is what turns normalization on. + */ +export const CODE_MODE_HELPER_WIRE_NAMES: ReadonlySet = new Set( + CODE_MODE_HELPER_TOOL_NAMES, +); + /** * Spellings that may never be MANUFACTURED as a bare alias for a namespaced tool. * diff --git a/structure/transports/responses.md b/structure/transports/responses.md index 8b06c9c45c9..1d954bcc442 100644 --- a/structure/transports/responses.md +++ b/structure/transports/responses.md @@ -560,6 +560,24 @@ resolves to nothing declared stays refused by the #1700 guard, which is the pre- intended outcome: an invalid name that cannot be resolved must end the turn visibly rather than reach stored history. +Stopping the emission is only half of it, because Codex stores what it received. A conversation +that already contains one `default.`-prefixed call name is refused on every later turn that +replays it, so the task cannot be compacted or continued at all and no upgrade reaches it. +`repairLegacyDottedToolCallNames` (`src/responses/legacy-dotted-tool-name-repair.ts`) repairs the +replayed item on the way out, in `buildRequest` beside `backfillWebSearchQueries` and again in +`src/server/responses/compact.ts`, which forwards the caller's body directly. It runs before the +canonical-destination split because the reported failure was a side chat on a plain OpenAI model +inheriting history a routed provider had damaged. + +What it will resolve is bounded on purpose, and only replayed `input` items are eligible — the +caller's tool catalog is never rewritten. A dotted spelling the catalog itself declares is a real +tool identity and is left alone; a suffix claimed by two declared identities is ambiguous and is +left alone; a suffix that names exactly one declared tool, or one of the code-mode helper spellings +in `CODE_MODE_HELPER_WIRE_NAMES` (which a code-mode catalog never declares), resolves to that name. +There is no rule that strips whatever precedes the first dot: a legitimate tool name may contain +one in another provider's vocabulary, and a replayed item names a call that already happened, which +is the worst place to guess. + Membership enforcement is that flag, `enforceDeclaredToolNames`, and only the `responses` inbound wire enforces. A routed provider that names a tool the request never declared ends the turn there: `src/bridge/sse.ts` emits `response.failed` and `src/bridge/response-json.ts` returns a failed diff --git a/tests/fixtures/test-layout-expected.json b/tests/fixtures/test-layout-expected.json index d647909da8b..558050f36cf 100644 --- a/tests/fixtures/test-layout-expected.json +++ b/tests/fixtures/test-layout-expected.json @@ -1053,6 +1053,7 @@ "responses-inbound-store-default.test.ts": "responses", "responses-item-id-repair.test.ts": "responses", "responses-json-events.test.ts": "responses", + "responses-legacy-dotted-tool-name-repair.test.ts": "responses", "responses-muse-tool-name-alias.test.ts": "responses", "responses-native-main-refresh.test.ts": "responses", "responses-opaque-blob-recovery.test.ts": "responses", diff --git a/tests/responses/responses-legacy-dotted-tool-name-repair.test.ts b/tests/responses/responses-legacy-dotted-tool-name-repair.test.ts new file mode 100644 index 00000000000..b0c3eed9946 --- /dev/null +++ b/tests/responses/responses-legacy-dotted-tool-name-repair.test.ts @@ -0,0 +1,158 @@ +/** + * #5095, recovery half. The emit-side fix stops new `default.`-prefixed call names from being + * created; a conversation that already contains one is still permanently unusable, because the + * upstream refuses EVERY later request that replays the item: + * + * Invalid 'input[877].name': string does not match pattern '^[a-zA-Z0-9_-]+$'. + * + * That is what killed a side chat opened from an 11h43m parent task, on a plain OpenAI model, from + * history a routed provider had damaged. These pin what may and may not be rewritten on the way + * out. The line is fail-closed in both directions: a dotted spelling the caller's own catalog + * declares is a real tool identity and is never stripped, an ambiguous suffix is left alone, and + * only a suffix naming exactly one declared tool or one of the bounded code-mode helper spellings + * resolves. There is deliberately no "strip everything before the first dot" rule. + */ +import { describe, expect, test } from "bun:test"; +import { repairLegacyDottedToolCallNames } from "../../src/responses/legacy-dotted-tool-name-repair"; + +const DAMAGED_VIEW_IMAGE = { type: "function_call", call_id: "call_a", name: "default.view_image", arguments: "{}" }; +const DAMAGED_APPLY_PATCH = { type: "function_call", call_id: "call_b", name: "default.apply_patch", arguments: "{}" }; + +/** Codex code mode: one freeform `exec`; the helpers are nested and never declared. */ +const CODE_MODE_TOOLS = [{ type: "custom", name: "exec", description: "code mode" }]; + +/** The classic Codex catalog, where both damaged names are declared top-level tools. */ +const CLASSIC_TOOLS = [ + { type: "function", name: "view_image", parameters: { type: "object" } }, + { type: "custom", name: "apply_patch" }, +]; + +function replay(tools: unknown[], input: unknown[]): Record { + return { model: "gpt-5.6-luna", tools, input }; +} + +function namesAfter(body: Record): unknown[] { + const repaired = repairLegacyDottedToolCallNames(body) as { input: Array<{ name?: unknown }> }; + return repaired.input.map(item => item.name); +} + +describe("replaying a damaged history", () => { + test("the two reported names are repaired under a code-mode catalog", () => { + expect(namesAfter(replay(CODE_MODE_TOOLS, [DAMAGED_VIEW_IMAGE, DAMAGED_APPLY_PATCH]))) + .toEqual(["view_image", "apply_patch"]); + }); + + test("a suffix naming exactly one declared tool resolves to it", () => { + expect(namesAfter(replay(CLASSIC_TOOLS, [DAMAGED_VIEW_IMAGE]))).toEqual(["view_image"]); + }); + + test("a declared bare tool is found through an additional_tools catalog too", () => { + const body = replay([], [ + { type: "additional_tools", tools: [{ type: "function", name: "lookup", parameters: { type: "object" } }] }, + { type: "function_call", call_id: "call_c", name: "default.lookup", arguments: "{}" }, + ]); + expect(namesAfter(body)).toEqual([undefined, "lookup"]); + }); + + test("the whole bounded helper vocabulary resolves without being declared", () => { + const helpers = ["exec_command", "shell_command", "write_stdin", "apply_patch", "view_image"]; + const input = helpers.map((helper, index) => ({ + type: "function_call", call_id: `call_${index}`, name: `default.${helper}`, arguments: "{}", + })); + expect(namesAfter(replay(CODE_MODE_TOOLS, input))).toEqual(helpers); + }); + + test("a call_id survives the rewrite, so the paired output still matches its call", () => { + const output = { type: "function_call_output", call_id: "call_a", output: "unsupported call: default.view_image" }; + const repaired = repairLegacyDottedToolCallNames( + replay(CODE_MODE_TOOLS, [DAMAGED_VIEW_IMAGE, output]), + ) as { input: Array> }; + expect(repaired.input[0]).toEqual({ type: "function_call", call_id: "call_a", name: "view_image", arguments: "{}" }); + expect(repaired.input[1]).toBe(output); + }); +}); + +describe("names the repair refuses to guess at", () => { + test("a suffix that names no declared tool and no helper is left alone", () => { + const damaged = { type: "function_call", call_id: "call_d", name: "default.lookup", arguments: "{}" }; + expect(namesAfter(replay(CODE_MODE_TOOLS, [damaged]))).toEqual(["default.lookup"]); + }); + + test("a suffix claimed by two declared identities is ambiguous and is left alone", () => { + const body = replay([ + { type: "namespace", name: "alpha", tools: [{ type: "function", name: "view_image", parameters: { type: "object" } }] }, + { type: "namespace", name: "beta", tools: [{ type: "function", name: "view_image", parameters: { type: "object" } }] }, + ], [DAMAGED_VIEW_IMAGE]); + expect(namesAfter(body)).toEqual(["default.view_image"]); + }); + + test("a dotted name the caller itself declared is a real identity, not damage", () => { + const body = replay([ + { type: "namespace", name: "default", tools: [{ type: "function", name: "view_image", parameters: { type: "object" } }] }, + ], [DAMAGED_VIEW_IMAGE]); + expect(repairLegacyDottedToolCallNames(body)).toBe(body); + }); + + test("a suffix that is itself still invalid is not a repair", () => { + const damaged = { type: "function_call", call_id: "call_e", name: "default.view.image", arguments: "{}" }; + expect(namesAfter(replay(CODE_MODE_TOOLS, [damaged]))).toEqual(["default.view.image"]); + }); + + test("an item carrying an explicit namespace is not the flattened shape", () => { + const body = replay(CODE_MODE_TOOLS, [ + { type: "function_call", call_id: "call_f", name: "default.view_image", namespace: "mcp__x", arguments: "{}" }, + ]); + expect(repairLegacyDottedToolCallNames(body)).toBe(body); + }); + + test("a name invalid for a reason other than the legacy namespace is left alone", () => { + for (const name of ["view image", "view_image!", "other.view_image"]) { + const damaged = { type: "function_call", call_id: "call_g", name, arguments: "{}" }; + expect(namesAfter(replay(CLASSIC_TOOLS, [damaged]))).toEqual([name]); + } + }); +}); + +describe("the undamaged path", () => { + test("a history with no legacy name is returned by reference", () => { + const body = replay(CLASSIC_TOOLS, [ + { type: "message", role: "user", content: [{ type: "input_text", text: "hi" }] }, + { type: "function_call", call_id: "call_h", name: "view_image", arguments: "{\"path\":\"a.png\"}" }, + { type: "function_call_output", call_id: "call_h", output: "ok" }, + ]); + expect(repairLegacyDottedToolCallNames(body)).toBe(body); + }); + + test("a body with no input array is returned by reference", () => { + const body = { model: "gpt-5.6-luna", tools: CLASSIC_TOOLS }; + expect(repairLegacyDottedToolCallNames(body)).toBe(body); + expect(repairLegacyDottedToolCallNames(undefined)).toBeUndefined(); + }); + + test("a mixed replay repairs only the damaged item and preserves the rest by reference", () => { + const message = { type: "message", role: "assistant", content: [{ type: "output_text", text: "done" }] }; + const healthy = { type: "function_call", call_id: "call_i", name: "view_image", arguments: "{\"path\":\"b.png\"}" }; + const body = replay(CLASSIC_TOOLS, [message, DAMAGED_APPLY_PATCH, healthy]); + const repaired = repairLegacyDottedToolCallNames(body) as Record; + const input = repaired.input as unknown[]; + expect(repaired).not.toBe(body); + expect(input[0]).toBe(message); + expect(input[1]).toEqual({ type: "function_call", call_id: "call_b", name: "apply_patch", arguments: "{}" }); + expect(input[2]).toBe(healthy); + }); + + test("the caller's tool catalog is never rewritten", () => { + const tools = [...CLASSIC_TOOLS, { type: "function", name: "default.reporting", parameters: { type: "object" } }]; + const body = replay(tools, [DAMAGED_VIEW_IMAGE]); + const repaired = repairLegacyDottedToolCallNames(body) as Record; + expect(repaired.tools).toBe(tools); + }); + + test("a call for a dotted tool the caller declared at top level stays that call", () => { + const tools = [{ type: "function", name: "default.reporting", parameters: { type: "object" } }]; + const body = replay(tools, [ + { type: "function_call", call_id: "call_j", name: "default.reporting", arguments: "{}" }, + ]); + expect(repairLegacyDottedToolCallNames(body)).toBe(body); + }); +}); From 4e7d7132d8f8a7d46e460b48c5104a6d5ced4567 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 17:07:26 +0900 Subject: [PATCH 17/97] fix(transport): return null bodies for 204 and 205 on raw outbound transports (#5125) * fix(transport): return null bodies for 204 and 205 on raw outbound transports Both raw outbound transports build a Response from a socket, so each applied the Fetch null-body rule on its own and the two disagreed. The SOCKS helper excluded 204 but not 205; the pinned direct helper attached a streaming body to every 2xx. A 204 or 205 therefore either raised a TypeError inside the response handler or waited for a peer that was entitled to keep the connection alive. The status set now lives in one place and both owners read it. Representation headers survive untouched: a 205 that advertises a coding it never sent is neither decoded nor refused, because there are no coded bytes to act on. * docs(transport): correct the null-body note on 101 and 103 The comment claimed an upgrade is refused before the shared predicate is consulted. It is not: the SOCKS helper stops its interim-response loop on 101 and carries that status into response construction. Describe 101 and 103 as statuses outside the final Response set these helpers support, which is what is actually true, without changing any runtime behavior. * test(transport): prove the SOCKS 205 case releases its tunnel The case was named for a release it did not check. It asserted status and body and then force-closed every socket in teardown, so the name claimed more than the assertions did. It now waits, under a bounded deadline rather than a fixed sleep, for the keep-alive peer's connection to be observably destroyed, which is the release the transport actually owes. --- scripts/test-layout/layout.json | 1 + src/lib/http-response-semantics.ts | 29 ++++ src/lib/pinned-http.ts | 16 ++ src/lib/socks5-fetch.ts | 5 +- structure/transports/inventory.md | 11 ++ tests/fixtures/test-layout-expected.json | 1 + tests/lib/transport-null-body.test.ts | 177 +++++++++++++++++++++++ 7 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 src/lib/http-response-semantics.ts create mode 100644 tests/lib/transport-null-body.test.ts diff --git a/scripts/test-layout/layout.json b/scripts/test-layout/layout.json index 6610565f8c0..5b3eef54f53 100644 --- a/scripts/test-layout/layout.json +++ b/scripts/test-layout/layout.json @@ -1403,6 +1403,7 @@ "tool-choice-performance.test.ts": "adapters", "transient-budget-scope-source.test.ts": "lib", "translator-budget.test.ts": "adapters", + "transport-null-body.test.ts": "lib", "tray-proxy-deadline.test.ts": "windows", "tray-proxy.test.ts": "windows", "types-barrel-identity.test.ts": "config", diff --git a/src/lib/http-response-semantics.ts b/src/lib/http-response-semantics.ts new file mode 100644 index 00000000000..0a2bb693b7b --- /dev/null +++ b/src/lib/http-response-semantics.ts @@ -0,0 +1,29 @@ +/** + * Response rules both raw outbound transports have to apply themselves. + * + * `fetch` applies them below the Response constructor. `src/lib/pinned-http.ts` and + * `src/lib/socks5-fetch.ts` assemble a Response from a socket instead, so each one answers the + * same questions on its own — and a rule written twice is a rule that drifts. It already had: + * the SOCKS helper excluded 204 and the pinned helper excluded nothing, so the same no-content + * upstream answer behaved differently depending on which transport carried the request. + */ + +/** + * Statuses the Fetch specification defines as null-body. + * + * `new Response(body, { status })` throws a TypeError for a non-null body on any of these, so a + * transport that attaches its stream unconditionally converts a valid no-content answer into a + * construction failure. There are no body bytes to wait for either, so a transport that streams + * one of these holds the caller until the peer closes a connection it is entitled to keep alive. + * + * 101 and 103 are null-body statuses too, but neither is a final Response status these helpers + * support. 103 and every other informational head is consumed while looking for the final one, + * and 101 hands the connection to a protocol neither helper speaks, which is outside what they + * construct a Response for at all. The three below are the statuses these transports actually + * have to answer for. + * + * https://fetch.spec.whatwg.org/#null-body-status + */ +export function isNullBodyStatus(status: number): boolean { + return status === 204 || status === 205 || status === 304; +} diff --git a/src/lib/pinned-http.ts b/src/lib/pinned-http.ts index b2b04c07054..e8f9de8d6f4 100644 --- a/src/lib/pinned-http.ts +++ b/src/lib/pinned-http.ts @@ -1,5 +1,6 @@ import http, { type ClientRequest, type IncomingMessage, type RequestOptions } from "node:http"; import https from "node:https"; +import { isNullBodyStatus } from "./http-response-semantics"; export type PinnedAddress = { address: string; family: number }; @@ -150,6 +151,21 @@ function pinnedHttpRequest( return; } + // A success status can still be null-body. `new Response(stream, { status: 204 })` throws a + // TypeError, so attaching the body below would turn a correct no-content answer into a + // construction failure raised inside this event handler rather than a resolved response. + // Nothing is coming on the socket either, so streaming one of these would hold the caller + // until the peer closed a connection it is entitled to keep alive. The headers still + // describe the representation the peer would have sent and are preserved as they arrived. + if (isNullBodyStatus(status)) { + try { response.destroy(); } catch { /* ignore */ } + try { req?.destroy(); } catch { /* ignore */ } + if (settled) return; + settled = true; + resolve(new Response(null, { status, headers: responseHeaders })); + return; + } + let received = 0; const stream = new ReadableStream({ start(controller) { diff --git a/src/lib/socks5-fetch.ts b/src/lib/socks5-fetch.ts index 725d0efb0e6..2e44505cf8f 100644 --- a/src/lib/socks5-fetch.ts +++ b/src/lib/socks5-fetch.ts @@ -1,5 +1,6 @@ import net, { type Socket } from "node:net"; import tls, { type TLSSocket } from "node:tls"; +import { isNullBodyStatus } from "./http-response-semantics"; const DEFAULT_SOCKS5_PORT = 1080; const SOCKS5_CONNECT_TIMEOUT_MS = 30_000; @@ -510,7 +511,9 @@ function responseBody( /** Statuses and methods that carry no response body, whatever the headers say about one. */ function bodylessResponse(method: string, status: number): boolean { - return method === "HEAD" || status === 204 || status === 304 || (status >= 100 && status < 200); + // 205 belongs here for the same reason 204 does, and leaving it out was not a judgement call: + // a peer that resets the caller's view sends no body, so the Response constructor rejects one. + return method === "HEAD" || isNullBodyStatus(status) || (status >= 100 && status < 200); } /** diff --git a/structure/transports/inventory.md b/structure/transports/inventory.md index 3e94190d1ca..f9e41691df7 100644 --- a/structure/transports/inventory.md +++ b/structure/transports/inventory.md @@ -247,4 +247,15 @@ for `identity` unless the caller chose an `accept-encoding` itself, a `gzip` or response is decoded and stops advertising the coding and the coded length, and any other coding is refused by name rather than surfaced as bytes no caller can read. +## Raw transport null-body statuses + +`src/lib/http-response-semantics.ts` holds the null-body status set both raw outbound transports +have to honor. `fetch` applies it below the Response constructor; `src/lib/pinned-http.ts` and +`src/lib/socks5-fetch.ts` build a Response from a socket, so each one applied the rule on its own +and the two disagreed — the SOCKS helper excluded 204 and the pinned helper excluded nothing. +204, 205 and 304 resolve with a null body and release the connection instead of waiting for a +peer that is entitled to keep it alive, and their representation headers are preserved as they +arrived rather than decoded or refused, because there are no coded bytes to act on. +`tests/lib/transport-null-body.test.ts` covers both transports against a keep-alive peer. + Dashboard Fast-row persistence and client refresh follow the [Fast selector rows setting contract](../gui-and-management-api.md#fast-selector-rows-setting). diff --git a/tests/fixtures/test-layout-expected.json b/tests/fixtures/test-layout-expected.json index 558050f36cf..da933378906 100644 --- a/tests/fixtures/test-layout-expected.json +++ b/tests/fixtures/test-layout-expected.json @@ -1231,6 +1231,7 @@ "tool-choice-performance.test.ts": "adapters", "transient-budget-scope-source.test.ts": "lib", "translator-budget.test.ts": "adapters", + "transport-null-body.test.ts": "lib", "tray-proxy-deadline.test.ts": "windows", "tray-proxy.test.ts": "windows", "types-barrel-identity.test.ts": "config", diff --git a/tests/lib/transport-null-body.test.ts b/tests/lib/transport-null-body.test.ts new file mode 100644 index 00000000000..b770d383585 --- /dev/null +++ b/tests/lib/transport-null-body.test.ts @@ -0,0 +1,177 @@ +import { describe, expect, test } from "bun:test"; +import { createConnection, createServer as createTcpServer, type AddressInfo, type Server as TcpServer, type Socket } from "node:net"; +import { pinnedHttpGet } from "../../src/lib/pinned-http"; +import { socks5Fetch } from "../../src/lib/socks5-fetch"; + +const openSockets = new WeakMap>(); + +async function listen(server: TcpServer): Promise { + const sockets = new Set(); + openSockets.set(server, sockets); + server.on("connection", socket => { + sockets.add(socket); + socket.once("error", () => { /* a destroyed transport resets its peer */ }); + socket.once("close", () => sockets.delete(socket)); + }); + await new Promise((resolve, reject) => { + server.once("error", reject); + server.listen(0, "127.0.0.1", resolve); + }); + return (server.address() as AddressInfo).port; +} + +async function close(server: TcpServer): Promise { + for (const socket of openSockets.get(server) ?? []) socket.destroy(); + await new Promise(resolve => server.close(() => resolve())); +} + +/** A no-auth SOCKS5 peer that connects to the loopback port the request names and pipes both ways. */ +function socksProxy(): TcpServer { + return createTcpServer(socket => { + let stage: "greeting" | "connect" = "greeting"; + let buffer = Buffer.alloc(0); + const onData = (chunk: Buffer) => { + buffer = Buffer.concat([buffer, chunk]); + while (true) { + if (stage === "greeting") { + if (buffer.length < 2 || buffer.length < 2 + buffer[1]!) return; + buffer = buffer.subarray(2 + buffer[1]!); + socket.write(Buffer.from([0x05, 0x00])); + stage = "connect"; + continue; + } + if (buffer.length < 7) return; + const hostnameLength = buffer[4]!; + const requestLength = 7 + hostnameLength; + if (buffer.length < requestLength) return; + const port = buffer.readUInt16BE(5 + hostnameLength); + buffer = buffer.subarray(requestLength); + const target = createConnection({ host: "127.0.0.1", port }, () => { + socket.write(Buffer.from([0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0, 1])); + socket.removeListener("data", onData); + if (buffer.length > 0) socket.unshift(buffer); + socket.pipe(target); + target.pipe(socket); + }); + target.once("error", error => socket.destroy(error)); + return; + } + }; + socket.on("data", onData); + socket.once("error", () => { /* the proxy is torn down with its peers */ }); + }); +} + +/** + * A peer that answers one fixed raw response head and then keeps the connection open. + * + * Keep-alive is the point of the fixture rather than an incidental detail: a transport that + * streams a null-body status settles only when the peer closes, so a peer that never closes is + * what separates "resolved with no body" from "resolved because the connection went away". + */ +function replyingTarget(reply: string, capture?: (socket: Socket) => void): TcpServer { + return createTcpServer(socket => { + capture?.(socket); + socket.once("error", () => { /* the caller may reset this peer */ }); + let request = Buffer.alloc(0); + socket.on("data", chunk => { + request = Buffer.concat([request, chunk]); + if (!request.toString("latin1").includes("\r\n\r\n")) return; + socket.write(reply); + }); + }); +} + +/** + * Wait for a socket to be observably destroyed, under a bounded deadline. + * + * The contract is that the transport releases the connection, not that it does so inside any + * particular window, so this waits for the state the contract promises and fails only when it + * never arrives. A fixed sleep would assert something about machine load instead. + */ +async function awaitDestroyed(socket: Socket | undefined, timeoutMs = 2_000): Promise { + const deadline = Date.now() + timeoutMs; + while (socket?.destroyed !== true && Date.now() < deadline) await Bun.sleep(5); + return socket?.destroyed === true; +} + +function pinnedGet(port: number, path: string): Promise { + return pinnedHttpGet( + `http://provider.invalid:${port}${path}`, + { address: "127.0.0.1", family: 4 }, + undefined, + // Bounded so a transport that waits for a body that is never coming fails as a timeout + // rather than hanging the suite for the sixty-second default. + { idleTimeoutMs: 5_000 }, + ); +} + +describe("null-body statuses on the raw outbound transports", () => { + test("the pinned transport answers 204 with a null body while the peer holds the connection", async () => { + const target = replyingTarget("HTTP/1.1 204 No Content\r\nConnection: keep-alive\r\n\r\n"); + const port = await listen(target); + try { + const response = await pinnedGet(port, "/no-content"); + expect(response.status).toBe(204); + expect(response.body).toBeNull(); + } finally { + await close(target); + } + }); + + test("the pinned transport answers 205 without decoding or refusing its representation headers", async () => { + // A 205 may still describe the representation it would have sent. There are no coded bytes + // to undo, so the coding is neither applied nor treated as an unreadable response. + const target = replyingTarget( + "HTTP/1.1 205 Reset Content\r\nContent-Encoding: br\r\nConnection: keep-alive\r\n\r\n", + ); + const port = await listen(target); + try { + const response = await pinnedGet(port, "/reset"); + expect(response.status).toBe(205); + expect(response.body).toBeNull(); + expect(response.headers.get("content-encoding")).toBe("br"); + } finally { + await close(target); + } + }); + + test("an ordinary pinned 200 still streams its body", async () => { + const target = replyingTarget( + "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: 11\r\n\r\n{\"ok\":true}", + ); + const port = await listen(target); + try { + const response = await pinnedGet(port, "/ok"); + expect(response.status).toBe(200); + expect(await response.json()).toEqual({ ok: true }); + } finally { + await close(target); + } + }); + + test("the SOCKS transport answers 205 with no body and releases the tunnel", async () => { + let targetConnection: Socket | undefined; + const target = replyingTarget( + "HTTP/1.1 205 Reset Content\r\nConnection: keep-alive\r\n\r\n", + socket => { targetConnection = socket; }, + ); + const proxy = socksProxy(); + const [targetPort, proxyPort] = await Promise.all([listen(target), listen(proxy)]); + try { + const response = await socks5Fetch( + `http://provider.invalid:${targetPort}/reset`, + undefined, + `socks5://127.0.0.1:${proxyPort}`, + ); + expect(response.status).toBe(205); + expect(response.body).toBeNull(); + // The peer asked to keep the connection alive, so an observed close is the transport + // releasing it rather than the fixture tearing it down. + expect(await awaitDestroyed(targetConnection)).toBe(true); + } finally { + targetConnection?.destroy(); + await Promise.all([close(proxy), close(target)]); + } + }); +}); From fe2b755267b5bdd1035e2aa35c6b13ca81ab1a8b Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sat, 19 Sep 2026 17:33:04 +0900 Subject: [PATCH 18/97] fix(gui): do not offer retry for the Grok coupon reset POST (#5103) * fix(gui): do not offer retry for the Grok coupon reset POST A transport rejection after the redemption POST is dispatched has an unknown outcome: the request may still reach the server and spend the coupon. Classifying it as a retryable network error let the operator re-submit an irreversible redemption with the same operation id. Return the aborted outcome for any post-dispatch rejection so the UI stops posting and forces a re-read of account state. * docs(pr): add the unknown-outcome coupon dialog screenshot --------- Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com> --- .github/pr-assets/508-grok-coupon-unknown.png | Bin 0 -> 102194 bytes gui/src/hooks/useGrokResetCoupons.ts | 15 +++++---------- gui/tests/grok-reset-coupons.test.tsx | 9 +++++---- 3 files changed, 10 insertions(+), 14 deletions(-) create mode 100644 .github/pr-assets/508-grok-coupon-unknown.png diff --git a/.github/pr-assets/508-grok-coupon-unknown.png b/.github/pr-assets/508-grok-coupon-unknown.png new file mode 100644 index 0000000000000000000000000000000000000000..7f56c37fdcca79ab1c96c5121633d84b04c7617a GIT binary patch literal 102194 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

@AZSkcdW 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 expiryRank(a) - expiryRank(b)); } -function wasAborted(error: unknown, signal: AbortSignal): boolean { - if (signal.aborted) return true; - return Boolean(error && typeof error === "object" && (error as { name?: unknown }).name === "AbortError"); -} - export function useGrokResetCoupons({ apiBase, accountIds, enabled }: { apiBase: string; accountIds: string[]; @@ -196,10 +191,10 @@ export function useGrokResetCoupons({ apiBase, accountIds, enabled }: { const code = settledCode(data); await read(accountId, epoch.current); return { ok: code === "redeemed", code, replayed }; - } catch (error) { - // An aborted redemption is an unknown outcome, not a failure: the route may - // still be executing it. The caller must stop posting, not retry. - return { ok: false, code: wasAborted(error, bounded.signal) ? "aborted" : "network", replayed: false }; + } catch { + // Any transport rejection after dispatch has an unknown outcome: the route + // may still be executing it. The caller must stop posting, not retry. + return { ok: false, code: "aborted", replayed: false }; } finally { bounded.clear(); } diff --git a/gui/tests/grok-reset-coupons.test.tsx b/gui/tests/grok-reset-coupons.test.tsx index 606c1840813..e8f10cff324 100644 --- a/gui/tests/grok-reset-coupons.test.tsx +++ b/gui/tests/grok-reset-coupons.test.tsx @@ -2,8 +2,9 @@ * The Grok reset-coupon surface on xAI account rows. * * These cases exist because the dangerous paths here are the quiet ones: a - * replayed *failure* arrives as HTTP 200, an aborted redemption may still be - * executing upstream, and a per-row retry used to cancel every sibling read. + * replayed *failure* arrives as HTTP 200, a rejected redemption request may + * still be executing upstream, and a per-row retry used to cancel every sibling + * read. */ import { afterEach, beforeEach, expect, test } from "bun:test"; import { Window } from "happy-dom"; @@ -262,9 +263,9 @@ test("ledger capacity gets its own retryable message", async () => { expect(dialogText(host)).toContain("journal is full"); }); -test("an aborted redemption stops posting, re-reads the account, and offers no retry", async () => { +test("a transport-rejected redemption stops posting, re-reads the account, and offers no retry", async () => { harness.coupons.set("acct-a", [COUPON("restok_a1", 10)]); - harness.consumeReply = async () => { throw Object.assign(new Error("aborted"), { name: "AbortError" }); }; + harness.consumeReply = async () => { throw new TypeError("connection reset after request dispatch"); }; const host = await mountPanel([ACCOUNT("acct-a")]); await openDialog(host); From 52c427a3d3ec41d813f28a6e394ca39584077a5c Mon Sep 17 00:00:00 2001 From: agentHits <140916359+agentHits@users.noreply.github.com> Date: Sat, 19 Sep 2026 04:33:18 -0400 Subject: [PATCH 19/97] feat(providers): patient same-target 429 fallback for OpenCode Go (#5067) Single-key pools cannot fail over, so a burst 429 on the Go destination surfaces immediately. Six 10s-paced attempts absorb a short burst window; Retry-After is still honored and capped, and an explicit retryOn429 always overrides. --- src/providers/key-failover.ts | 79 ++++++++++++++++++------ structure/transports/streaming-health.md | 2 + tests/providers/rate-limit-retry.test.ts | 62 +++++++++++++++++++ 3 files changed, 125 insertions(+), 18 deletions(-) diff --git a/src/providers/key-failover.ts b/src/providers/key-failover.ts index ba7193d2b57..693f8d61595 100644 --- a/src/providers/key-failover.ts +++ b/src/providers/key-failover.ts @@ -11,6 +11,7 @@ import { commitProviderApiKeySelection } from "./api-key-selection"; import type { ProviderApiKeySelection } from "../types/provider"; import { routedProviderConfig } from "../router"; +import { getProviderRegistryEntry } from "./registry"; import type { OcxConfig, OcxProviderConfig, RateLimitRetryPolicy, TransientRetryPolicy } from "../types"; import { OPENCODE_GO_SESSION_HEADER } from "./opencode-go-transport"; import { resolveProviderTransport, type OcxProviderTransport } from "./xai-transport"; @@ -278,6 +279,39 @@ const DEFAULT_RATE_LIMIT_RETRY = { respectRetryAfter: true, } as const satisfies Required; +/** + * Patient same-target 429 fallback for the OpenCode Go destination + * (https://opencode.ai/zen/go/v1), which serves subscription traffic such as Muse Spark. + * Single-key pools cannot fail over, so without this a burst 429 surfaces immediately and + * the client retry budget aborts the goal. Six 10s-paced attempts absorb a short burst + * window (effective replays are additionally bounded by the shared per-request send + * budget); Retry-After is still honored and capped. An explicit `retryOn429` (including + * `enabled: false`) always overrides this fallback. + */ +const OPENCODE_GO_RATE_LIMIT_RETRY = { + enabled: true, + attempts: 6, + intervalMs: 10_000, + maxIntervalMs: 60_000, + respectRetryAfter: true, +} as const satisfies Required; + +/** True when the provider row points at the OpenCode Go destination. */ +function isOpenCodeGoDestination( + provider: Partial>, +): boolean { + const raw = typeof provider.baseUrl === "string" ? provider.baseUrl : ""; + if (!raw.trim()) return false; + // Endpoint identity, not adapter identity: the runtime adapter is already overridden + // per model by the time the recovery loop runs (muse-spark rides `openai-responses` + // while the preset declares `openai-chat`), so an adapter-strict lookup misses it. + const endpoint = raw.trim().replace(/\/+$/, ""); + const entry = getProviderRegistryEntry("opencode-go"); + if (!entry) return false; + const candidates = [entry.baseUrl, ...(entry.destinationAliases ?? []).map(alias => alias.baseUrl)]; + return candidates.some(url => url.trim().replace(/\/+$/, "") === endpoint); +} + /** * Default transient-5xx retry used when a provider opts in with a bare * `transientRetryOn5xx: {}`. `attempts` is a TOTAL send budget, not extra retries. @@ -513,29 +547,38 @@ export function selectProactiveApiKeyTransport( } /** - * Normalize a provider's `retryOn429` policy, or return null when the knob is absent, - * explicitly disabled, or the provider is not key-auth (OAuth/forward credentials must not be - * replayed on the same token, forward passthrough never reaches the recovery loop anyway, and - * local runtimes have no remote key to preserve). The returned policy is fully defaulted so - * callers never re-check fields. + * Normalize a provider's `retryOn429` policy. An explicit object always wins (including + * `enabled: false` to opt out). When the knob is absent, the OpenCode Go destination + * (subscription traffic such as Muse Spark) falls back to a patient same-key policy so a + * burst 429 waits and replays instead of surfacing to the client and aborting a long + * session; every other provider without the knob keeps today's fail-fast behavior. + * OAuth/forward/local credentials are never replayed on the same token. The returned + * policy is fully defaulted so callers never re-check fields. */ export function rateLimitRetryPolicyFor( - provider: Pick, + provider: Pick & + Partial>, ): Required | null { const policy = provider.retryOn429; - if (!policy || policy.enabled === false) return null; - // Fail closed: only explicit key auth or the documented omitted-default (undefined == key for - // custom API-key providers) may use same-key replays. OAuth/forward are never replayed on the - // same token, local runtimes have no remote key to preserve, and unknown/custom values are - // rejected rather than guessed at. + if (policy) { + if (policy.enabled === false) return null; + // Fail closed: only explicit key auth or the documented omitted-default (undefined == key for + // custom API-key providers) may use same-key replays. OAuth/forward are never replayed on the + // same token, local runtimes have no remote key to preserve, and unknown/custom values are + // rejected rather than guessed at. + if (provider.authMode !== undefined && provider.authMode !== "key") return null; + return { + enabled: policy.enabled ?? DEFAULT_RATE_LIMIT_RETRY.enabled, + attempts: policy.attempts ?? DEFAULT_RATE_LIMIT_RETRY.attempts, + intervalMs: policy.intervalMs ?? DEFAULT_RATE_LIMIT_RETRY.intervalMs, + maxIntervalMs: policy.maxIntervalMs ?? DEFAULT_RATE_LIMIT_RETRY.maxIntervalMs, + respectRetryAfter: policy.respectRetryAfter ?? DEFAULT_RATE_LIMIT_RETRY.respectRetryAfter, + }; + } + // No explicit knob: patient fallback for the OpenCode Go destination only. if (provider.authMode !== undefined && provider.authMode !== "key") return null; - return { - enabled: policy.enabled ?? DEFAULT_RATE_LIMIT_RETRY.enabled, - attempts: policy.attempts ?? DEFAULT_RATE_LIMIT_RETRY.attempts, - intervalMs: policy.intervalMs ?? DEFAULT_RATE_LIMIT_RETRY.intervalMs, - maxIntervalMs: policy.maxIntervalMs ?? DEFAULT_RATE_LIMIT_RETRY.maxIntervalMs, - respectRetryAfter: policy.respectRetryAfter ?? DEFAULT_RATE_LIMIT_RETRY.respectRetryAfter, - }; + if (!isOpenCodeGoDestination(provider)) return null; + return { ...OPENCODE_GO_RATE_LIMIT_RETRY }; } /** diff --git a/structure/transports/streaming-health.md b/structure/transports/streaming-health.md index ca5ce00455f..ba387f403e5 100644 --- a/structure/transports/streaming-health.md +++ b/structure/transports/streaming-health.md @@ -159,6 +159,8 @@ once the server observes the client disconnect (Bun propagates it asynchronously cancelled with 499 before any replay; because the propagation is async, a replay may precede the cancel if the interval elapses first (bounded by the same `attempts` budget). +OpenCode Go (`https://opencode.ai/zen/go/v1`, serving subscription traffic such as Muse Spark) ships a patient same-target fallback when no explicit `retryOn429` is configured: same-key wait-and-replay with a 10s interval and a 60s cap, `Retry-After` honored. Replays draw from the shared per-request send budget, so a burst typically absorbs a couple of paced sends before the 429 surfaces — without this, a single-key pool surfaced the first 429 immediately and the client’s own retry budget aborted the goal (`exceeded retry limit, last status: 429`). An explicit `retryOn429` — including `enabled: false` — always overrides the fallback; every other provider without the knob keeps fail-fast behavior. + Provider-level `requestPacing` is the proactive companion to `retryOn429`. It reserves outbound request-start slots before transport work begins, so a known RPM ceiling does not have to fail once before the proxy reacts. One provider-wide lane enforces the aggregate ceiling. Exact model lanes diff --git a/tests/providers/rate-limit-retry.test.ts b/tests/providers/rate-limit-retry.test.ts index b351057055b..dab8ec84b98 100644 --- a/tests/providers/rate-limit-retry.test.ts +++ b/tests/providers/rate-limit-retry.test.ts @@ -45,6 +45,31 @@ describe("rateLimitRetryPolicyFor", () => { }); }); + test("falls back to a patient policy for the OpenCode Go destination without the knob", () => { + expect(rateLimitRetryPolicyFor({ + baseUrl: "https://opencode.ai/zen/go/v1", + adapter: "openai-chat", + } as OcxProviderConfig)).toEqual({ + enabled: true, + attempts: 6, + intervalMs: 10_000, + maxIntervalMs: 60_000, + respectRetryAfter: true, + }); + // Explicit opt-out still wins on the Go destination. + expect(rateLimitRetryPolicyFor({ + baseUrl: "https://opencode.ai/zen/go/v1", + adapter: "openai-chat", + retryOn429: { enabled: false }, + } as OcxProviderConfig)).toBeNull(); + // Explicit values normalize against the generic defaults, not the Go fallback. + expect(rateLimitRetryPolicyFor({ + baseUrl: "https://opencode.ai/zen/go/v1", + adapter: "openai-chat", + retryOn429: { attempts: 2 }, + } as OcxProviderConfig)).toMatchObject({ attempts: 2, intervalMs: 5_000 }); + }); + test("honors explicit values", () => { expect(rateLimitRetryPolicyFor({ retryOn429: { attempts: 10, intervalMs: 1_000, maxIntervalMs: 5_000, respectRetryAfter: false }, @@ -118,6 +143,43 @@ describe("retry loop client-abort handling", () => { globalThis.fetch = originalFetch; }); + test("opencode-go fallback replays burst 429s on the same key, then surfaces 429", async () => { + let sends = 0; + globalThis.fetch = (async (input) => { + const url = input instanceof Request ? input.url : String(input); + if (url.includes("opencode.ai/zen/go")) { + sends += 1; + return new Response(JSON.stringify({ error: { message: "rate limited" } }), { + status: 429, + headers: { "content-type": "application/json", "retry-after": "0" }, + }); + } + return originalFetch(input as never, undefined as never); + }) as typeof fetch; + + const config = { + port: 0, + defaultProvider: "opencode-go", + providers: { + "opencode-go": { + adapter: "openai-chat", + baseUrl: "https://opencode.ai/zen/go/v1", + authMode: "key", + apiKey: "key-alpha-000111222333", + }, + }, + } as OcxConfig; + + const response = await handleResponses(new Request("http://localhost/v1/responses", { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ model: "opencode-go/muse-spark-1.3-contributor", input: "hello", stream: false }), + }), config, { model: "opencode-go/muse-spark-1.3-contributor", provider: "opencode-go" }, {}); + + expect(sends).toBe(3); + expect(response.status).toBe(429); + }); + test("abort during the wait interrupts the sleep, cancels the 429 body, and returns 499 without replaying", async () => { let sends = 0; let upstreamBodyCancelled = false; From 1b54f2940b038e5aba0665fed2a606e30773dd35 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 18:01:25 +0900 Subject: [PATCH 20/97] docs(config): describe apiKeys as data-plane credentials only (#5134) The server-configuration table in English and all seven locale copies claimed generated apiKeys are accepted by management and data-plane auth. Runtime rejects data-plane credentials as management tokens (src/server/management-auth.ts). Correct each row to describe data-plane admission only, link the locale management reference, and record the row contract in the docs structure owner. Closes #5120 --- docs-site/src/content/docs/fr/reference/configuration/server.md | 2 +- docs-site/src/content/docs/ja/reference/configuration/server.md | 2 +- docs-site/src/content/docs/ko/reference/configuration/server.md | 2 +- docs-site/src/content/docs/reference/configuration/server.md | 2 +- docs-site/src/content/docs/ru/reference/configuration/server.md | 2 +- docs-site/src/content/docs/tr/reference/configuration/server.md | 2 +- .../src/content/docs/zh-cn/reference/configuration/server.md | 2 +- .../src/content/docs/zh-tw/reference/configuration/server.md | 2 +- structure/ops/docs-and-release.md | 2 ++ 9 files changed, 10 insertions(+), 8 deletions(-) diff --git a/docs-site/src/content/docs/fr/reference/configuration/server.md b/docs-site/src/content/docs/fr/reference/configuration/server.md index f0e4b9415a8..bc5970400db 100644 --- a/docs-site/src/content/docs/fr/reference/configuration/server.md +++ b/docs-site/src/content/docs/fr/reference/configuration/server.md @@ -19,7 +19,7 @@ exécute des fonctionnalités d'assistance autour des demandes du fournisseur. | `shutdownTimeoutMs?` | `number` | `5000` | Délai de vidange gracieux avant l’annulation des tours actifs. | | `websockets?` | `boolean` | `false` | Annonce et autorise la route WebSocket Responses destinée aux clients. La valeur false maintient les clients sur HTTP/SSE ; elle ne désactive pas une optimisation WebSocket canonique admissible vers ChatGPT en amont. | | `corsAllowOrigins?` | `string[]` | `[]` | Origines exactes supplémentaires autorisées par CORS. Les origines de bouclage sont toujours autorisées. Les origines d'extensions de navigateur basées sur l'autorité telles que `chrome-extension://` sont prises en charge ; `*` n'est pas un caractère générique. Firefox et Safari régénèrent l'extension UUID (par installation / par lancement de navigateur), mettez donc à jour l'entrée lorsque l'origine change. | -| `apiKeys?` | `OcxApiKey[]` | `[]` | Identifiants `ocx_…` générés, acceptés par l'API de gestion et l'authentification du plan de données sur les liaisons hors bouclage. Gérés depuis le tableau de bord. | +| `apiKeys?` | `OcxApiKey[]` | `[]` | Identifiants `ocx_…` générés pour l'admission au plan de données sur les liaisons hors bouclage. Ils n'autorisent pas les API de gestion ; l'accès à la gestion utilise l'identifiant distinct décrit dans la [référence de l'API de gestion](/fr/reference/management-api/). Gérés depuis le tableau de bord. | | `storageCleanupPolicy?` | `StorageCleanupPolicy` | désactivé | Politique facultative de nettoyage des sessions archivées. Elle n'est jamais activée implicitement. | | `appOwnedMemoryBudgetMb?` | `number` | `256` | Plafond en Mio pour les journaux, caches, objets binaires et charges utiles de continuation évincables qui appartiennent à l'application. Plage : 64–4096 ; il ne s'agit pas d'un plafond RSS. | | `codexAutoStart?` | `boolean` | `true` | Autorise le lanceur intermédiaire Codex à exécuter `ocx ensure` avant de démarrer Codex. Avec la valeur false, cette vérification ne fait rien. | diff --git a/docs-site/src/content/docs/ja/reference/configuration/server.md b/docs-site/src/content/docs/ja/reference/configuration/server.md index 96f3e618f42..761f7b8323c 100644 --- a/docs-site/src/content/docs/ja/reference/configuration/server.md +++ b/docs-site/src/content/docs/ja/reference/configuration/server.md @@ -19,7 +19,7 @@ description: リスナー、リモート アクセス、アドミッション | `shutdownTimeoutMs?` | `number` | `5000` |アクティブなターンが中止される前の正常な排出期限。 | | `websockets?` | `boolean` | `false` | クライアント向け Responses WebSocket パスを広告して許可します。false の場合クライアントは HTTP/SSE を使いますが、対象となる canonical ChatGPT upstream WS 最適化は無効にしません。 | | `corsAllowOrigins?` | `string[]` | `[]` | 追加の正確な CORS origin。ループバック origin は常に許可します。`chrome-extension://` など authority ベースのブラウザー拡張 origin に対応し、`*` はワイルドカードではありません。Firefox と Safari は拡張 UUID を(インストール/ブラウザー起動ごとに)再生成するため、origin が変わったらエントリを更新してください。 | -| `apiKeys?` | `OcxApiKey[]` | `[]` |生成された `ocx_…` 資格情報は、非ループバック バインドでの管理およびデータ プレーン認証によって受け入れられました。ダッシュボードで管理。 | +| `apiKeys?` | `OcxApiKey[]` | `[]` |生成された `ocx_…` データプレーン准入資格情報(非ループバック バインド向け)。管理 API の認可には使用できません。管理アクセスには [管理 API リファレンス](/ja/reference/management-api/) に記載された独立した資格情報を使用します。ダッシュボードで管理。 | | `storageCleanupPolicy?` | `StorageCleanupPolicy` |無効 |アーカイブされたセッションのクリーンアップ ポリシーをオプトインします。暗黙的に有効になることはありません。 | | `appOwnedMemoryBudgetMb?` | `number` | `256` |排除可能なアプリ所有のログ、キャッシュ、BLOB、および継続ペイロードの MiB の上限。範囲は 64 ~ 4096。 RSSキャップではありません。 | | `codexAutoStart?` | `boolean` | `true` | Codex を起動する前に、Codex シムで `ocx ensure` を実行させます。 False を指定すると、操作が行われないことが保証されます。 | diff --git a/docs-site/src/content/docs/ko/reference/configuration/server.md b/docs-site/src/content/docs/ko/reference/configuration/server.md index da43750851a..fcffd5690f0 100644 --- a/docs-site/src/content/docs/ko/reference/configuration/server.md +++ b/docs-site/src/content/docs/ko/reference/configuration/server.md @@ -19,7 +19,7 @@ description: 리스너, 원격 접근, admission 키, 타임아웃, 저장소, | `shutdownTimeoutMs?` | `number` | `5000` | 진행 중인 turn을 중단하기 전에 허용하는 정상 종료 드레인 기한입니다. | | `websockets?` | `boolean` | `false` | 클라이언트용 Responses WebSocket 경로를 광고하고 허용합니다. `false`이면 클라이언트는 HTTP/SSE를 사용하며, 적격 canonical ChatGPT 업스트림 WS 최적화는 비활성화하지 않습니다. | | `corsAllowOrigins?` | `string[]` | `[]` | CORS에서 추가로 허용할 정확한 origin입니다. 루프백 origin은 항상 허용됩니다. `chrome-extension://` 같은 authority 기반 브라우저 확장 origin을 지원하며, `*`는 와일드카드가 아닙니다. Firefox와 Safari는 확장 UUID를 (설치/브라우저 실행 때마다) 새로 만드므로 origin이 바뀌면 항목을 갱신하세요. | -| `apiKeys?` | `OcxApiKey[]` | `[]` | 비루프백 바인드에서 관리 API와 데이터 플레인 인증이 허용하는 생성된 `ocx_…` 자격 증명입니다. 대시보드에서 관리합니다. | +| `apiKeys?` | `OcxApiKey[]` | `[]` | 비루프백 바인드에서 데이터 플레인 요청만 허용하는 생성된 `ocx_…` 자격 증명입니다. 관리 API는 허가하지 않으며, 관리 접근에는 [관리 API 레퍼런스](/ko/reference/management-api/)에 설명된 별도의 자격 증명을 사용합니다. 대시보드에서 관리합니다. | | `storageCleanupPolicy?` | `StorageCleanupPolicy` | disabled | 선택적으로 활성화하는 보관 세션 정리 정책입니다. 절대 암묵적으로 활성화되지 않습니다. | | `appOwnedMemoryBudgetMb?` | `number` | `256` | 제거 가능한 앱 소유 로그, 캐시, blob, continuation payload에 대한 MiB 단위 상한입니다. 범위는 64–4096이며 RSS 상한은 아닙니다. | | `codexAutoStart?` | `boolean` | `true` | Codex shim이 Codex를 실행하기 전에 `ocx ensure`를 돌리도록 허용합니다. `false`이면 ensure는 아무 작업도 하지 않습니다. | diff --git a/docs-site/src/content/docs/reference/configuration/server.md b/docs-site/src/content/docs/reference/configuration/server.md index 779e0cee358..e243f5edd90 100644 --- a/docs-site/src/content/docs/reference/configuration/server.md +++ b/docs-site/src/content/docs/reference/configuration/server.md @@ -24,7 +24,7 @@ runs helper features around provider requests. | `codexNativeSteering?` | `boolean` | `false` | Experimental, native-only mid-turn steering on the Responses WebSocket endpoint. Requires `websockets: true`, a compatible upstream/client, and a pinned account/model/tool surface. Validated generation settings can change in explicit saved-result continuations. Does not enable translated models or HTTP fallback. See [native steering](/guides/codex-integration/#experimental-native-mid-turn-steering). | | `codexNativeInjection?` | `boolean` | `false` | Experimental saved function-result injection on compatible native multi-agent WebSocket turns. Requires `websockets: true`, explicit `multi_agent.enabled`, and an eligible provider. Separate from steering; no automatic tool rerun or recovery create. See [native injection](/guides/codex-integration/#experimental-native-function-result-injection). | | `corsAllowOrigins?` | `string[]` | `[]` | Additional exact origins allowed by CORS. Loopback origins are always allowed. Authority-based browser extension origins such as `chrome-extension://` are supported; `*` is not a wildcard. Firefox and Safari regenerate the extension UUID (per install / per browser launch), so update the entry when the origin changes. | -| `apiKeys?` | `OcxApiKey[]` | `[]` | Generated `ocx_…` credentials accepted by management and data-plane auth on non-loopback binds. Dashboard-managed. | +| `apiKeys?` | `OcxApiKey[]` | `[]` | Generated `ocx_…` data-plane admission credentials on non-loopback binds. They do not authorize management APIs; management access uses the separate credential documented in the [management reference](/reference/management-api/). Dashboard-managed. | | `storageCleanupPolicy?` | `StorageCleanupPolicy` | disabled | Opt-in archived-session cleanup policy. Never enabled implicitly. | | `appOwnedMemoryBudgetMb?` | `number` | `256` | Cap in MiB for evictable app-owned logs, caches, blobs, and continuation payloads. Range 64–4096; not an RSS cap. | | `spend?` | `{ root?: { maxTokens?: number }; identity?: { maxTokens?: number }; pool?: { maxTokens?: number }; retentionDays?: number }` | unset | Durable token ceilings, off unless you write one. Each scope bounds settled spend plus in-flight reservations plus unresolved spend: `root` is one task including its whole fan-out, `identity` is one account across every task it serves, and `pool` is one provider pool. They intersect, so a request is admitted only when all three have room — which is what holds a ceiling against a client that mints a new task id per request. A reservation is the request's whole input plus its enforceable output ceiling, counted as if every cached prefix misses. Spend survives a restart, so it does not roll forward the way the send-count window does; raising or removing the value is what grants more. `maxTokens` must be a positive integer (0 would refuse everything), `retentionDays` is 1–365 and defaults to 7, and an unknown key in this section is rejected rather than ignored. A refusal is a local HTTP 429 carrying `x-opencodex-local-refusal: workflow_spend_exhausted`, and its message names the scope and the ceiling; no provider is contacted. | diff --git a/docs-site/src/content/docs/ru/reference/configuration/server.md b/docs-site/src/content/docs/ru/reference/configuration/server.md index e7de12e052a..9239c896062 100644 --- a/docs-site/src/content/docs/ru/reference/configuration/server.md +++ b/docs-site/src/content/docs/ru/reference/configuration/server.md @@ -20,7 +20,7 @@ description: Listener, удалённый доступ, admission key, тайм | `shutdownTimeoutMs?` | `number` | `5000` | Дедлайн graceful-drain до принудительного прерывания активных turn'ов. | | `websockets?` | `boolean` | `false` | Объявляет и разрешает клиентский WebSocket-путь Responses. При false клиенты используют HTTP/SSE; это не отключает подходящую upstream WS-оптимизацию canonical ChatGPT. | | `corsAllowOrigins?` | `string[]` | `[]` | Дополнительные точные origin, разрешённые CORS. Loopback-origin разрешены всегда. Поддерживаются authority-based origin браузерных расширений, например `chrome-extension://`; `*` не является маской. Firefox и Safari пересоздают UUID расширения (при каждой установке/запуске браузера), поэтому обновляйте запись при смене origin. | -| `apiKeys?` | `OcxApiKey[]` | `[]` | Сгенерированные credentials `ocx_…`, принимаемые для management и data-plane auth на не-loopback bind'ах. Управляются через дашборд. | +| `apiKeys?` | `OcxApiKey[]` | `[]` | Сгенерированные credentials `ocx_…` для data-plane admission на не-loopback bind'ах. Они не авторизуют management API; доступ к management использует отдельный credential, описанный в [management reference](/ru/reference/management-api/). Управляются через дашборд. | | `storageCleanupPolicy?` | `StorageCleanupPolicy` | disabled | Opt-in policy очистки архивированных сессий. Никогда не включается неявно. | | `appOwnedMemoryBudgetMb?` | `number` | `256` | Лимит в MiB для eviction-friendly app-owned log'ов, cache'ей, blob'ов и continuation payload'ов. Это не RSS-cap. Диапазон 64–4096. | | `codexAutoStart?` | `boolean` | `true` | Разрешает shim'у Codex запускать `ocx ensure` перед стартом Codex. При false `ensure` становится no-op. | diff --git a/docs-site/src/content/docs/tr/reference/configuration/server.md b/docs-site/src/content/docs/tr/reference/configuration/server.md index 4472046cdc9..1f67f9c2aea 100644 --- a/docs-site/src/content/docs/tr/reference/configuration/server.md +++ b/docs-site/src/content/docs/tr/reference/configuration/server.md @@ -20,7 +20,7 @@ yardımcı özellikleri nasıl çalıştıracağını kontrol eder. | `shutdownTimeoutMs?` | `number` | `5000` | Aktif turlar iptal edilmeden önce zarif boşaltma süresi sınırı. | | `websockets?` | `boolean` | `false` | Responses WebSocket yolu için `supports_websockets` bildirin. False, HTTP/SSE'yi tutar. | | `corsAllowOrigins?` | `string[]` | `[]` | CORS tarafından izin verilen ek tam kaynaklar. Geri döngü kaynaklarına her zaman izin verilir. `chrome-extension://` gibi yetki tabanlı tarayıcı uzantısı kaynakları desteklenir; `*` bir joker karakter değildir. Firefox ve Safari uzantı UUID'sini yeniden oluşturur (yükleme başına / tarayıcı başlatma başına), bu nedenle kaynak değiştiğinde girdiyi güncelleyin. | -| `apiKeys?` | `OcxApiKey[]` | `[]` | Geri döngü olmayan bağlamalarda yönetim ve veri düzlemi kimlik doğrulaması tarafından kabul edilen oluşturulmuş `ocx_…` kimlik bilgileri. Kontrol paneli tarafından yönetilir. | +| `apiKeys?` | `OcxApiKey[]` | `[]` | Geri döngü olmayan bağlamalarda veri düzlemi kabulü için oluşturulmuş `ocx_…` kimlik bilgileri. Yönetim API'lerini yetkilendirmezler; yönetim erişimi [yönetim API referansında](/tr/reference/management-api/) açıklanan ayrı kimlik bilgisini kullanır. Kontrol paneli tarafından yönetilir. | | `storageCleanupPolicy?` | `StorageCleanupPolicy` | devre dışı | İsteğe bağlı arşivlenmiş oturum temizleme politikası. Asla örtük olarak etkinleştirilmez. | | `appOwnedMemoryBudgetMb?` | `number` | `256` | Çıkarılabilir uygulamaya ait günlükler, önbellekler, bloblar ve devam yükleri için MiB cinsinden sınır. Aralık 64–4096; bir RSS sınırı değildir. | | `codexAutoStart?` | `boolean` | `true` | Codex dolgusunun Codex'i başlatmadan önce `ocx ensure` çalıştırmasına izin verin. False, ensure'ı bir işlem yapmayan (no-op) hale getirir. | diff --git a/docs-site/src/content/docs/zh-cn/reference/configuration/server.md b/docs-site/src/content/docs/zh-cn/reference/configuration/server.md index ef0699f2045..03d689861bd 100644 --- a/docs-site/src/content/docs/zh-cn/reference/configuration/server.md +++ b/docs-site/src/content/docs/zh-cn/reference/configuration/server.md @@ -20,7 +20,7 @@ description: 监听、远程访问、准入密钥、超时、存储、侧车、 | `shutdownTimeoutMs?` | `number` | `5000` | 优雅停机截止时间,超过后会中止仍在进行中的请求。 | | `websockets?` | `boolean` | `false` | 声明并允许面向客户端的 Responses WebSocket 路径。设为 false 时客户端使用 HTTP/SSE;它不会禁用符合条件的 canonical ChatGPT 上游 WS 优化。 | | `corsAllowOrigins?` | `string[]` | `[]` | CORS 额外允许的精确 origin。loopback origin 始终允许;支持 `chrome-extension://<扩展 ID>` 等基于 authority 的浏览器扩展 origin,`*` 不是通配符。Firefox 和 Safari 会(每次安装/启动浏览器时)重新生成扩展 UUID,origin 变化后请更新该条目。 | -| `apiKeys?` | `OcxApiKey[]` | `[]` | 管理平面和非回环绑定上的数据平面身份验证可接受的已生成 `ocx_…` 凭据。由仪表板管理。 | +| `apiKeys?` | `OcxApiKey[]` | `[]` | 生成的 `ocx_…` 数据平面准入凭据(用于非回环绑定)。它们不授权管理 API;管理访问使用[管理 API 参考](/zh-cn/reference/management-api/)中说明的独立凭据。由仪表板管理。 | | `storageCleanupPolicy?` | `StorageCleanupPolicy` | disabled | 可选启用的归档会话清理策略。不会被隐式启用。 | | `appOwnedMemoryBudgetMb?` | `number` | `256` | 可逐出应用自有日志、缓存、blob 和续传载荷的内存上限,单位 MiB。范围 64–4096;不是 RSS 上限。 | | `codexAutoStart?` | `boolean` | `true` | 允许 Codex shim 在启动 Codex 之前运行 `ocx ensure`。设为 false 会让 ensure 变成无操作。 | diff --git a/docs-site/src/content/docs/zh-tw/reference/configuration/server.md b/docs-site/src/content/docs/zh-tw/reference/configuration/server.md index 5fb998fb33f..ab4da87099f 100644 --- a/docs-site/src/content/docs/zh-tw/reference/configuration/server.md +++ b/docs-site/src/content/docs/zh-tw/reference/configuration/server.md @@ -18,7 +18,7 @@ description: 監聽器、遠端存取、許可金鑰、逾時、儲存、sidecar | `shutdownTimeoutMs?` | `number` | `5000` | 在中止活躍回合前的優雅排空截止時間。 | | `websockets?` | `boolean` | `false` | 廣告並允許面向 client 的 Responses WebSocket 路徑。False 時 client 使用 HTTP/SSE;不會停用符合條件的 canonical ChatGPT upstream WS 最佳化。 | | `corsAllowOrigins?` | `string[]` | `[]` | 額外的精確 CORS 來源。回送來源恆被允許。 | -| `apiKeys?` | `OcxApiKey[]` | `[]` | 生成的 `ocx_…` 憑證,在非回送綁定上被管理與 data-plane 認證接受。由儀表板管理。 | +| `apiKeys?` | `OcxApiKey[]` | `[]` | 生成的 `ocx_…` data-plane 准入憑證(用於非回送綁定)。它們不授權管理 API;管理存取使用[管理 API 參考](/zh-tw/reference/management-api/)中說明的獨立憑證。由儀表板管理。 | | `storageCleanupPolicy?` | `StorageCleanupPolicy` | 停用 | 選擇加入的已封存 session 清理政策。永不隱含啟用。 | | `appOwnedMemoryBudgetMb?` | `number` | `256` | 以 MiB 為單位、可被驅逐的 app 擁有日誌、快取、blob 與 continuation payload 上限。範圍 64–4096;非 RSS 上限。 | | `codexAutoStart?` | `boolean` | `true` | 讓 Codex shim 在啟動 Codex 前執行 `ocx ensure`。False 使 ensure 為 no-op。 | diff --git a/structure/ops/docs-and-release.md b/structure/ops/docs-and-release.md index 5062cd7e310..9ad63ed256f 100644 --- a/structure/ops/docs-and-release.md +++ b/structure/ops/docs-and-release.md @@ -34,6 +34,8 @@ lists its required source/registry paths and preview/apply flags. The public documentation site lives in `docs-site/` and is built with Astro + Starlight. English is served at the site root, with Korean under `/ko`, Simplified Chinese under `/zh-cn`, Traditional Chinese under `/zh-tw`, Russian under `/ru`, and Japanese under `/ja`. `docs-site/astro.config.mjs` is the locale source of truth. +Server-configuration credential rows in English and every locale copy distinguish data-plane `apiKeys` from the independent management admin credential and link the matching locale management reference. Credential setup instructions themselves stay in the management reference; the rows only name the separation. + Manual navigation is defined in `docs-site/astro.config.mjs`. When adding a public page, update the sidebar and either add localized copies or intentionally accept Starlight fallback behavior. From e668aa1f2e1d31cf3618ae1e59d669345e7e082d Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 18:15:13 +0900 Subject: [PATCH 21/97] fix(cursor): state the T04 re-arming contract on an injectable clock (#5131) tests/providers/cursor/cursor-stream-health.test.ts asserted that meaningful frames keep resetting both stream-health deadlines by running a synthetic HTTP/2 server for three times the silence budget and requiring that no deadline expire. That is an assertion about how busy the machine is. In the unsharded macOS control lane it fails with "Cursor stream stalled: no inbound frames for 5s before turnEnded" while the watchdog is behaving correctly: under contention the fixture's own frames do not arrive inside the window. The budget is already CI-scaled, and scaling is what makes it worse. With the silence budget floored at 5s the case needs 15 consecutive seconds during which no 5s gap in frame decoding occurs, so raising the floor lengthens the exposure rather than reducing it. Add a T04-only clock seam (now, setTimeout, clearTimeout), matching StageLeaseClock in src/cli/account-api.ts. Production omits it and keeps the globals; the 30s and 90s budgets, the first-frame timer, the turn-ended grace and the outbound heartbeat are untouched. The test now advances virtual time by hand between frames whose arrival it awaits, so runner contention can delay a frame without any deadline passing, and it additionally asserts that exactly one timer is armed after each frame and none survives turnEnded. No production timeout changed, no budget widened, no retry added and no platform skipped. --- src/adapters/cursor/live-transport.ts | 35 ++-- src/adapters/cursor/transport.ts | 19 +++ structure/providers/cursor.md | 25 +++ .../cursor/cursor-stream-health.test.ts | 151 ++++++++++++++---- 4 files changed, 186 insertions(+), 44 deletions(-) diff --git a/src/adapters/cursor/live-transport.ts b/src/adapters/cursor/live-transport.ts index f5ad317d051..e0b6b527c42 100644 --- a/src/adapters/cursor/live-transport.ts +++ b/src/adapters/cursor/live-transport.ts @@ -87,7 +87,7 @@ import { type BackgroundShellTerminationReport, } from "./native-exec-shell"; import type { CursorClientMessage, CursorRunRequest, CursorServerMessage } from "./types"; -import type { CursorTransport, CursorTransportFactoryInput } from "./transport"; +import type { CursorStreamHealthClock, CursorTransport, CursorTransportFactoryInput } from "./transport"; import { CursorHttp1BidiConnection } from "./http1-bidi"; import { isPinnedHttp1 } from "../../lib/upstream-http-version"; @@ -107,6 +107,16 @@ const CURSOR_STREAM_SILENCE_FAIL_MS = 30_000; * Reset on every decoded frame that is not liveness-only. */ const CURSOR_STREAM_HEARTBEAT_ONLY_FAIL_MS = 90_000; +/** + * The production T04 clock. The watchdog reads time and schedules its one timer through this + * object so a test can supply a clock it advances by hand; nothing else about the transport's + * timers moves with it. + */ +const REAL_STREAM_HEALTH_CLOCK: CursorStreamHealthClock = { + now: () => Date.now(), + setTimeout: (callback, ms) => setTimeout(callback, ms), + clearTimeout: timer => clearTimeout(timer), +}; /** * After `turnEnded` is decoded, the application turn is complete. A server that keeps * HTTP/2 open past this point cannot hold the turn hostage (senpi #1062): we close our side @@ -494,6 +504,8 @@ class LiveCursorTransport implements CursorTransport { private lastInboundFrameAt = 0; private lastMeaningfulFrameAt = 0; private streamHealthFail?: (error: Error) => void; + /** Time source for the T04 watchdog only; the globals unless a test injects one. */ + private readonly streamHealthClock: CursorStreamHealthClock; private committed = false; private expectedClose = false; /** @@ -542,6 +554,7 @@ class LiveCursorTransport implements CursorTransport { // so the transport-level race test can drive it deterministically. this.clientToolFinalizeGraceMs = input.clientToolFinalizeGraceMs ?? CLIENT_TOOL_FINALIZE_GRACE_MS; this.activeClientToolFinalizeGraceMs = this.clientToolFinalizeGraceMs; + this.streamHealthClock = input.streamHealthClock ?? REAL_STREAM_HEALTH_CLOCK; // Desktop (computer-use / record-screen) executors are available even with no MCP servers. this.desktopDeps = desktopDepsFromConfig(input.provider.desktopExecutor); this.execContext = { @@ -847,7 +860,7 @@ class LiveCursorTransport implements CursorTransport { private clearStreamHealthTimer(): void { if (this.streamHealthTimer) { - clearTimeout(this.streamHealthTimer); + this.streamHealthClock.clearTimeout(this.streamHealthTimer); this.streamHealthTimer = undefined; } this.streamHealthFail = undefined; @@ -858,24 +871,28 @@ class LiveCursorTransport implements CursorTransport { * failAndClear; the timer owns nothing else. Never armed before the first decoded * frame (the first-frame timer covers dial + first response), and disarmed by * every settle / expected-close path alongside the other timers. + * + * Both clocks and the timer go through `streamHealthClock`, which is the globals in + * production. The `elapsedMs` diagnostic below deliberately stays on the wall clock, + * because `turnStartedAt` is stamped there and the pair has to subtract coherently. */ private armStreamHealthTimer(fail: (error: Error) => void): void { - if (this.streamHealthTimer) clearTimeout(this.streamHealthTimer); + if (this.streamHealthTimer) this.streamHealthClock.clearTimeout(this.streamHealthTimer); if (this.expectedClose) return; this.streamHealthFail = fail; const silenceMs = this.input.streamSilenceFailMs ?? CURSOR_STREAM_SILENCE_FAIL_MS; const heartbeatOnlyMs = this.input.streamHeartbeatOnlyFailMs ?? CURSOR_STREAM_HEARTBEAT_ONLY_FAIL_MS; - const now = Date.now(); + const now = this.streamHealthClock.now(); const deadline = Math.min( this.lastInboundFrameAt + silenceMs, this.lastMeaningfulFrameAt + heartbeatOnlyMs, ); - this.streamHealthTimer = setTimeout(() => { + this.streamHealthTimer = this.streamHealthClock.setTimeout(() => { this.streamHealthTimer = undefined; const failFn = this.streamHealthFail; if (!failFn || this.expectedClose) return; - const stalledFor = Date.now() - this.lastInboundFrameAt; - const meaningfulStalledFor = Date.now() - this.lastMeaningfulFrameAt; + const stalledFor = this.streamHealthClock.now() - this.lastInboundFrameAt; + const meaningfulStalledFor = this.streamHealthClock.now() - this.lastMeaningfulFrameAt; if (stalledFor < silenceMs && meaningfulStalledFor < heartbeatOnlyMs) { // A frame landed between arming and firing — re-arm for the fresh deadline. this.armStreamHealthTimer(failFn); @@ -906,7 +923,7 @@ class LiveCursorTransport implements CursorTransport { * heartbeat-only threshold. */ private noteInboundFrame(livenessOnly: boolean): void { - const now = Date.now(); + const now = this.streamHealthClock.now(); this.lastInboundFrameAt = now; if (!livenessOnly) this.lastMeaningfulFrameAt = now; if (this.streamHealthFail) this.armStreamHealthTimer(this.streamHealthFail); @@ -1288,7 +1305,7 @@ class LiveCursorTransport implements CursorTransport { const decodedUpdate = decoded.message.case === "interactionUpdate" ? decoded.message.value.message?.case : undefined; const livenessOnly = decodedUpdate === "heartbeat" || decoded.message.case === "conversationCheckpointUpdate"; if (!this.streamHealthFail) { - const now = Date.now(); + const now = this.streamHealthClock.now(); this.lastInboundFrameAt = now; this.lastMeaningfulFrameAt = now; this.streamHealthFail = failAndClear; diff --git a/src/adapters/cursor/transport.ts b/src/adapters/cursor/transport.ts index 79f241ca0e4..5cb3c099c8a 100644 --- a/src/adapters/cursor/transport.ts +++ b/src/adapters/cursor/transport.ts @@ -55,6 +55,25 @@ export interface CursorTransportFactoryInput { * client thread. Distinct from the per-transport native-exec/shell owner. */ sessionId?: string; + /** + * Test-only clock for the T04 inbound stream-health watchdog. Production omits it and the + * transport uses the global timers; injecting here must not change scheduling semantics. + * + * It exists because the watchdog's contract — a meaningful frame re-arms both deadlines — can + * only be asserted against real timers by keeping a synthetic server delivering frames faster + * than the silence budget for several multiples of it. That is an assertion about how busy the + * machine is, and it failed in the unsharded macOS lane for exactly that reason while the + * watchdog was working correctly. With the clock injected, virtual time advances only where + * the test says it does, so no amount of runner contention can expire a deadline. + */ + streamHealthClock?: CursorStreamHealthClock; +} + +/** The three time primitives the T04 watchdog uses. Production binds all three to the globals. */ +export interface CursorStreamHealthClock { + now(): number; + setTimeout(callback: () => void, ms: number): ReturnType; + clearTimeout(timer: ReturnType): void; } export type CursorTransportFactory = (input: CursorTransportFactoryInput) => CursorTransport; diff --git a/structure/providers/cursor.md b/structure/providers/cursor.md index 8be236cd916..af22677eb55 100644 --- a/structure/providers/cursor.md +++ b/structure/providers/cursor.md @@ -219,3 +219,28 @@ Canonical Responses identity sanitation and narrowly scoped pre-output combo rec Upstream API-key usage follows the [physical-attempt account attribution contract](../gui-and-management-api.md#upstream-key-account-attribution), independently of subscription quota observations. Unicode pattern normalization uses [copy-on-write traversal](../transports/byte-accounting.md#unicode-pattern-normalization) while preserving the existing schema and wire semantics. + +## Inbound stream-health clock ownership + +The T04 inbound stream-health watchdog in `src/adapters/cursor/live-transport.ts` fails a turn that +received its first frame and then went silent for `CURSOR_STREAM_SILENCE_FAIL_MS` (30s) or +produced only liveness frames for `CURSOR_STREAM_HEARTBEAT_ONLY_FAIL_MS` (90s), instead of waiting +out the 300s bridge stall watchdog. One timer covers both thresholds and re-arms on every +decoded frame, so the deadline is always recomputed from the newest frame. + +Those two budgets are the production contract and a test does not move them to make itself +pass. What a test may replace is the watchdog's time source: `streamHealthClock` on +`CursorTransportFactoryInput` supplies `now`, `setTimeout` and `clearTimeout`, defaulting to the +globals, and the seam is deliberately scoped to T04 alone — the first-frame timer, the +turn-ended close grace, the client-tool finalize grace and the outbound heartbeat all stay on +the global timers, as does the `elapsedMs` diagnostic, whose `turnStartedAt` is stamped on the +wall clock. + +The seam exists because the re-arming half of the contract cannot be stated against real +timers without also asserting that the machine keeps up: showing that a deadline did NOT expire +means keeping a synthetic server ahead of the silence budget for several multiples of it, which +is what failed in the unsharded macOS lane while the watchdog was correct. Scaling the budget +lengthens the window rather than shrinking the exposure. The firing half needs no seam and is +still covered on real timers in `tests/providers/cursor/cursor-stream-health.test.ts`: silence +after the first frame, heartbeat-only traffic reaching the progress threshold, and `turnEnded` +cancelling the watchdog while the server holds the stream open. diff --git a/tests/providers/cursor/cursor-stream-health.test.ts b/tests/providers/cursor/cursor-stream-health.test.ts index 27a6cdac432..56c829e5184 100644 --- a/tests/providers/cursor/cursor-stream-health.test.ts +++ b/tests/providers/cursor/cursor-stream-health.test.ts @@ -100,6 +100,52 @@ function runRequest(): CursorRunRequest { } as CursorRunRequest; } +/** + * A clock the test advances by hand, for the T04 watchdog only. + * + * The watchdog's re-arming contract cannot be stated against real timers without also + * asserting that the machine keeps up: the only way to show a deadline did NOT expire is to + * keep a synthetic server delivering frames faster than the silence budget for several + * multiples of it, and a loaded runner that pauses longer than one budget fails the assertion + * while the watchdog is behaving correctly. Virtual time removes that term. Timers fire only + * from `advanceTo`, so contention can delay a frame's arrival — which the test waits for — + * without any deadline passing. + */ +function manualStreamHealthClock() { + type Pending = { at: number; callback: () => void }; + const pending = new Map(); + let now = 0; + let nextHandle = 1; + return { + clock: { + now: () => now, + setTimeout: (callback: () => void, ms: number) => { + const handle = nextHandle++; + pending.set(handle, { at: now + Math.max(0, ms), callback }); + return handle as unknown as ReturnType; + }, + clearTimeout: (timer: ReturnType) => { + pending.delete(timer as unknown as number); + }, + }, + /** Move virtual time to `target`, running every timer due at or before it in deadline order. */ + advanceTo(target: number): void { + for (;;) { + const due = [...pending.entries()] + .filter(([, timer]) => timer.at <= target) + .sort((left, right) => left[1].at - right[1].at)[0]; + if (!due) break; + pending.delete(due[0]); + now = Math.max(now, due[1].at); + due[1].callback(); + } + now = Math.max(now, target); + }, + now: () => now, + armed: () => pending.size, + }; +} + async function drain( baseUrl: string, knobs: { streamSilenceFailMs?: number; streamHeartbeatOnlyFailMs?: number }, @@ -138,7 +184,6 @@ describe("Cursor inbound stream-health watchdog (T04)", () => { // would collapse the two clocks to the same value in CI. const silenceMs = isolationBudgetMs(1_000); const heartbeatOnlyMs = 2 * silenceMs; - const progressDurationMs = 3 * silenceMs; // Include the existing two-second first-frame allowance and leave time for cleanup. const fixtureLimitMs = 4 * silenceMs + 2_000; const timeoutMs = Math.max(watchdogMs(15_000), fixtureLimitMs + silenceMs); @@ -189,46 +234,82 @@ describe("Cursor inbound stream-health watchdog (T04)", () => { }, timeoutMs); test("meaningful frames keep resetting both clocks; turnEnded finishes cleanly", async () => { - let firstTextReceivedAt: number | undefined; - let completedProgressSpan = false; + // Virtual budgets: nothing here is scaled for CI, because no real interval has to beat them. + const virtualSilenceMs = 1_000; + const virtualHeartbeatOnlyMs = 2 * virtualSilenceMs; + const timing = manualStreamHealthClock(); + const connected = Promise.withResolvers(); + const messages: CursorServerMessage[] = []; + const armedAfterFrame: number[] = []; + let armedAfterTurnEnded: number | undefined; + let failure: Error | undefined; await withH2Server(stream => { stream.on("error", () => {}); stream.respond({ ":status": 200, "content-type": "application/connect+proto" }); - stream.write(Buffer.from(textDeltaFrame("part-0"))); - const latestEndAt = performance.now() + fixtureLimitMs; - let count = 0; - const tick = setInterval(() => { - count += 1; - try { - const now = performance.now(); - const progressComplete = firstTextReceivedAt !== undefined - && now - firstTextReceivedAt >= progressDurationMs; - if (progressComplete || now >= latestEndAt) { - completedProgressSpan = progressComplete; - stream.write(Buffer.from(turnEndedFrame())); - stream.end(); - clearInterval(tick); - } else { - stream.write(Buffer.from(textDeltaFrame(`part-${count}`))); + connected.resolve(stream); + }, async baseUrl => { + const transport = createLiveCursorTransport({ + provider: { adapter: "cursor", baseUrl, apiKey: "test-token" }, + translatorBudget: createTestTranslatorBudget(), + // Stays on the real clock: it owns dial and first response, not this contract. Generous + // so a slow local dial cannot pre-empt the case; a real hang is bounded by the timeout. + firstFrameTimeoutMs: watchdogMs(15_000), + streamSilenceFailMs: virtualSilenceMs, + streamHeartbeatOnlyFailMs: virtualHeartbeatOnlyMs, + streamHealthClock: timing.clock, + }); + const iterator = transport.run(runRequest())[Symbol.asyncIterator](); + try { + // The first next() dials and puts the request on the wire. + const opened = iterator.next(); + const server = await connected.promise; + const textFrame = async (label: string, pending?: Promise>) => { + server.write(Buffer.from(textDeltaFrame(label))); + let result = await (pending ?? iterator.next()); + while (!result.done && result.value.type !== "text") { + messages.push(result.value); + result = await iterator.next(); } - } catch { - clearInterval(tick); - stream.destroy(); + if (result.done) throw new Error(`stream ended before the ${label} text arrived`); + messages.push(result.value); + // Awaiting the yielded message is the synchronization: noteInboundFrame has run by the + // time the frame it decoded reaches the consumer, so the re-armed timer is observable. + armedAfterFrame.push(timing.armed()); + }; + await textFrame("part-0", opened); + // Every frame lands just under the deadline the previous one set, and the four of them + // carry virtual time past both non-resetting deadlines (S and 2S). That is the whole + // claim: each deadline is recomputed from the newest frame, not from the first one. + const landings = [900, 1_800, 2_700]; + for (let index = 0; index < landings.length; index += 1) { + timing.advanceTo(landings[index]!); + await textFrame(`part-${index + 1}`); } - }, 100); - stream.on("close", () => clearInterval(tick)); - }, async baseUrl => { - // Observe progress for 3S after receipt: both non-resetting deadlines (S and 2S) - // would expire before turnEnded, even when the first text reaches us late. - const { messages, failure } = await drain(baseUrl, { - streamSilenceFailMs: silenceMs, - streamHeartbeatOnlyFailMs: heartbeatOnlyMs, - }, () => { firstTextReceivedAt = performance.now(); }); - expect(failure).toBeUndefined(); - expect(completedProgressSpan).toBe(true); - expect(messages.some(message => message.type === "text")).toBe(true); - expect(messages.some(message => message.type === "done")).toBe(true); + server.write(Buffer.from(turnEndedFrame())); + server.end(); + for (;;) { + const result = await iterator.next(); + if (result.done) break; + messages.push(result.value); + } + // Read before close(), which would clear the timer on its own. + armedAfterTurnEnded = timing.armed(); + } catch (err) { + failure = err instanceof Error ? err : new Error(String(err)); + } finally { + await transport.close?.(); + } }); + expect(failure).toBeUndefined(); + // One timer after every frame: the previous one was cleared rather than left stacked. + expect(armedAfterFrame).toEqual([1, 1, 1, 1]); + expect(timing.now()).toBeGreaterThan(virtualHeartbeatOnlyMs); + expect(messages.some(message => message.type === "text")).toBe(true); + expect(messages.some(message => message.type === "done")).toBe(true); + // turnEnded disarmed the watchdog, so no deadline survives the turn to fail it later. + expect(armedAfterTurnEnded).toBe(0); + timing.advanceTo(timing.now() + 10 * virtualHeartbeatOnlyMs); + expect(failure).toBeUndefined(); }, timeoutMs); test("turnEnded disarms the watchdog even when the server holds the stream open", async () => { From 9824aa55bb0ed5fb27ca92ed0851a2fd5529123c Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 18:22:45 +0900 Subject: [PATCH 22/97] fix(transport): settle SOCKS5 uploads on abort and early final responses (#5127) * fix(transport): settle SOCKS5 uploads on abort and early final responses The upload loop awaited the caller's body reader before looking at the socket at all. Aborting destroyed the socket, which does nothing to a read owned by the caller's own stream, so a stalled body kept the fetch pending - including when the peer had already answered and the response was sitting in the receive buffer. One reader now consumes the socket for the whole exchange and starts before the upload finishes. Each body read and drain wait races the caller's abort and that pending answer, so an abort rejects with its own reason, an early final response ends the upload without writing a terminating chunk into a finished conversation, and a socket failure during a stalled read surfaces as that failure. The request body is cancelled without being awaited, because a caller's cancel algorithm is free to never settle; releasing the reader is what frees the pending read. * fix(transport): type each upload race by its own outcomes One union covering both races let the compiler accept reading a chunk value off a drain result, which is the mistake the type exists to prevent. The body race and the drain race now have separate result types, and the shared answered case is its own type. The abort regression also drove its abort from the body stream having produced a chunk. A caller's stream can be pulled before the tunnel is established, so that signal did not prove the fetch was parked mid-upload. The fake upstream now reports the first body byte it actually receives, and the abort follows that. * fix(transport): preserve a non-Error abort reason on the upload race AbortSignal.reason is whatever the caller passed, and the socket reader already hands a string or an object back unchanged. The upload race wrapped anything that was not an Error, so the same abort surfaced differently depending on which race won it. It now passes the reason through, with a regression that aborts with a string and asserts identity. The abort regression also now waits on the upstream observing the request head and its first body byte before aborting. Waiting on the caller's stream having produced a chunk did not prove the fetch was parked mid-upload, because a stream can be pulled before the tunnel is established. * fix(transport): give an aborted caller back its own abort reason The helper preserved a non-Error reason, but that was not the contract the caller saw. Several waiters inside this transport can win the race that settles an abort, and they disagree about a reason they consider absent: the socket reader substitutes an Error for null, others coerce anything that is not an Error. The same abort(null) therefore surfaced as an Error or as null depending on scheduling, and the comment claiming otherwise was wrong. An aborted request now rejects with the exact signal reason, decided in one place. undefined is left alone so a hand-built signal without a reason still reaches the underlying cause. The regression covers a string, null and a plain object, each asserted by identity. --- scripts/test-layout/layout.json | 1 + src/lib/socks5-fetch.ts | 148 ++++++++++-- structure/transports/inventory.md | 14 +- tests/fixtures/test-layout-expected.json | 1 + tests/lib/socks5-upload-lifecycle.test.ts | 279 ++++++++++++++++++++++ 5 files changed, 421 insertions(+), 22 deletions(-) create mode 100644 tests/lib/socks5-upload-lifecycle.test.ts diff --git a/scripts/test-layout/layout.json b/scripts/test-layout/layout.json index 5b3eef54f53..29f6bdb144d 100644 --- a/scripts/test-layout/layout.json +++ b/scripts/test-layout/layout.json @@ -171,6 +171,7 @@ "key-attribution.test.ts": "usage", "provider-send-path-import.test.ts": "server", "socks5-fetch.test.ts": "lib", + "socks5-upload-lifecycle.test.ts": "lib", "start-args.test.ts": "cli", "responses-core-modules.test.ts": "responses", "responses-passthrough-transient-policy.test.ts": "responses", diff --git a/src/lib/socks5-fetch.ts b/src/lib/socks5-fetch.ts index 2e44505cf8f..d26dfbbbd10 100644 --- a/src/lib/socks5-fetch.ts +++ b/src/lib/socks5-fetch.ts @@ -538,6 +538,117 @@ function contentCodingFormat(headers: Headers): "gzip" | "deflate" | undefined { throw new Socks5FetchError("SOCKS5 upstream returned an unsupported content-encoding: " + coding); } +/** Read response heads until the final one, consuming the interim informational answers. */ +async function finalResponseHead( + reader: SocketReader, + signal: AbortSignal, +): Promise<{ status: number; statusText: string; headers: Headers }> { + let head = parseResponseHead(await reader.readUntil(HEADER_END, MAX_RESPONSE_HEADER_BYTES, signal)); + while (head.status >= 100 && head.status < 200 && head.status !== 101) { + head = parseResponseHead(await reader.readUntil(HEADER_END, MAX_RESPONSE_HEADER_BYTES, signal)); + } + return head; +} + +/** + * A promise that rejects with the caller's abort reason, and a way to stop listening. + * + * Destroying the socket is not enough to end a pending `bodyReader.read()`: that promise belongs + * to the caller's body stream, which knows nothing about this socket. Racing it against this one + * is what turns an abort into a settled fetch instead of a permanently pending one. + */ +function abortRejection(signal: AbortSignal): { promise: Promise; dispose: () => void } { + let onAbort = (): void => { /* replaced below */ }; + const promise = new Promise((_resolve, reject) => { + // Reject with the caller's reason exactly, including `null` and `false`. A real + // `AbortSignal` always has one — `abort()` with no argument supplies an AbortError — so + // the fallback covers only a hand-built signal that exposes none. + onAbort = () => reject(signal.reason === undefined ? new Error("The operation was aborted") : signal.reason); + if (signal.aborted) onAbort(); + else signal.addEventListener("abort", onAbort, { once: true }); + }); + // The race below may settle on another branch first; this rejection must not be reported as + // unhandled when nobody is left waiting for it. + promise.catch(() => { /* surfaced by whoever loses the race */ }); + return { promise, dispose: () => signal.removeEventListener("abort", onAbort) }; +} + +/** + * The two races below have different possible outcomes, so they have different result types. + * One union covering both would let the compiler accept reading `value` off a drain result, + * which is the kind of mistake a type is supposed to catch rather than describe. + */ +type Answered = { kind: "answered" }; +type BodyStep = { kind: "chunk"; value: Uint8Array } | { kind: "end" } | Answered; +type DrainStep = { kind: "drained" } | Answered; + +/** + * Send the request body, settling on caller abort or on an answer that arrives first. + * + * A peer is entitled to answer a request it has not finished receiving — a 413 or a 401 lands + * while a large body is still going out — and a body stream is entitled to stall. Waiting for + * the upload to finish before looking at the socket made those two facts combine into a fetch + * that never settles, with the answer already sitting in the receive buffer. + * + * `answered` covers the head settling either way: a final response means the peer has stopped + * reading, and a terminal socket failure means nothing more can be written. Which of the two it + * was belongs to whoever awaits the head, so this only needs to know that it happened. + */ +async function uploadRequestBody( + socket: Socket, + request: Request, + chunked: boolean, + head: Promise, +): Promise { + const body = request.body; + if (!body) return; + const signal = request.signal; + const bodyReader = body.getReader(); + const abort = abortRejection(signal); + const answered: Promise = head.then( + (): Answered => ({ kind: "answered" }), + (): Answered => ({ kind: "answered" }), + ); + let completed = false; + try { + for (;;) { + const read: Promise = bodyReader.read().then( + (result): BodyStep => (result.done ? { kind: "end" } : { kind: "chunk", value: result.value }), + ); + // Releasing the lock below rejects a read still waiting on a source that stopped + // producing. That rejection is this function's own doing, not a failure to report. + read.catch(() => { /* settled by releasing the reader */ }); + const step = await Promise.race([read, answered, abort.promise]); + if (step.kind === "answered") break; + if (step.kind === "end") { + completed = true; + break; + } + const payload = chunked + ? Buffer.concat([Buffer.from(`${step.value.byteLength.toString(16)}\r\n`), Buffer.from(step.value), CRLF]) + : step.value; + if (socket.write(payload)) continue; + const drain: Promise = waitForDrain(socket, signal).then((): DrainStep => ({ kind: "drained" })); + if ((await Promise.race([drain, answered, abort.promise])).kind === "answered") break; + } + // A terminating chunk written after the peer has already answered goes into a conversation + // that is over, and a peer that has moved on may read it as the head of the next request. + if (completed && chunked && !socket.write("0\r\n\r\n")) { + const drain: Promise = waitForDrain(socket, signal).then((): DrainStep => ({ kind: "drained" })); + await Promise.race([drain, answered, abort.promise]); + } + } finally { + abort.dispose(); + if (!completed) { + // Cancelling runs the caller's own cancel algorithm, which is free to never settle, so it + // is started rather than awaited. Releasing the lock is what actually frees a read still + // waiting on a body that stopped producing. + void bodyReader.cancel().catch(() => { /* the caller's stream owns this outcome */ }); + } + try { bodyReader.releaseLock(); } catch { /* already released */ } + } +} + export async function socks5Fetch( input: RequestInfo | URL, init: RequestInit | undefined, @@ -573,26 +684,16 @@ export async function socks5Fetch( const headers = requestHeaders(request, target); const head = `${request.method} ${target.pathname}${target.search} HTTP/1.1\r\n${headers.text}\r\n`; socket.write(head); - if (request.body) { - const bodyReader = request.body.getReader(); - try { - while (true) { - const next = await bodyReader.read(); - if (next.done) break; - const body = headers.chunked - ? Buffer.concat([Buffer.from(`${next.value.byteLength.toString(16)}\r\n`), Buffer.from(next.value), CRLF]) - : next.value; - if (!socket.write(body)) await waitForDrain(socket, request.signal); - } - if (headers.chunked && !socket.write("0\r\n\r\n")) await waitForDrain(socket, request.signal); - } finally { - bodyReader.releaseLock(); - } - } - let responseHead = parseResponseHead(await reader.readUntil(HEADER_END, MAX_RESPONSE_HEADER_BYTES, request.signal)); - while (responseHead.status >= 100 && responseHead.status < 200 && responseHead.status !== 101) { - responseHead = parseResponseHead(await reader.readUntil(HEADER_END, MAX_RESPONSE_HEADER_BYTES, request.signal)); - } + // Start reading the answer before the upload finishes, and keep one consumer of the socket + // reader for the whole exchange. The upload races this promise so an early final response or + // a terminal socket failure ends it, instead of leaving it waiting on a body chunk that is + // never coming while the answer sits in the receive buffer. + const pendingHead = finalResponseHead(reader, request.signal); + // The upload observes this promise through a handler of its own; this one keeps a rejection + // from being reported as unhandled in the window before the await below. + pendingHead.catch(() => { /* rethrown by the await below */ }); + await uploadRequestBody(socket, request, headers.chunked, pendingHead); + const responseHead = await pendingHead; // A bodyless response has no coded bytes to undo, so its `content-encoding` describes the // representation it would have sent and must neither be decoded nor refused — a HEAD whose // peer advertises brotli is a correct answer, not an unreadable body. For everything else, @@ -629,6 +730,13 @@ export async function socks5Fetch( request.signal.removeEventListener("abort", onAbort); reader?.dispose(); socket.destroy(); + // An aborted caller gets its own reason back. Several waiters inside this transport can win + // the race that settles an abort, and they do not agree on what to do with a reason they + // consider absent: the socket reader substitutes an Error for a null reason, others coerce + // anything that is not an Error. Without this, the same `abort(null)` surfaces as an Error + // or as null depending on scheduling. `undefined` is left alone so a hand-built signal + // still reaches the thrown cause below. + if (request.signal.aborted && request.signal.reason !== undefined) throw request.signal.reason; throw error; } } diff --git a/structure/transports/inventory.md b/structure/transports/inventory.md index f9e41691df7..b49c6a6a89a 100644 --- a/structure/transports/inventory.md +++ b/structure/transports/inventory.md @@ -234,12 +234,22 @@ The tunnel reader keeps incomplete framing separate from queued socket bytes, waits for new input, and caps headers even when the terminating delimiter arrives in the same chunk. Cancellation removes the exact queued waiter; socket errors remain errors on later reads rather than turning into clean EOF. Buffered body -reads pause the socket at the local high-water mark, and upload errors are observed -before the response reader takes ownership. `tests/lib/socks5-fetch.test.ts` covers +reads pause the socket at the local high-water mark, and an upload failure is observed +by the caller rather than lost behind the answer. `tests/lib/socks5-fetch.test.ts` covers fragmented framing, header limits and explicit-route snapshot preservation. Explicit `http2` / `h2` pins reject before network I/O: this HTTP/1.1 tunnel cannot honor them and must not silently downgrade the provider contract. +The upload and the answer are read together. One reader consumes the socket for the whole +exchange, starting before the request body is finished, because a peer may answer a request it +has not finished receiving and a caller's body stream may stall. Each body read and drain wait +races the caller's abort and that pending answer, so an abort settles the fetch with its own +reason rather than leaving a read the transport does not own, an early final response ends the +upload without writing a terminating chunk into a finished conversation, and a socket failure +during a stalled read surfaces as the failure instead of a promise that never settles. The +request body is cancelled without being awaited, since a caller's cancel algorithm may itself +never settle. `tests/lib/socks5-upload-lifecycle.test.ts` covers these four outcomes. + Content-coding is this transport's own obligation. `fetch` decodes a coded body below the Response constructor; this tunnel assembles the body from a socket, so a response wrapped with its upstream headers hands the coded bytes to whatever parses them. The request therefore asks diff --git a/tests/fixtures/test-layout-expected.json b/tests/fixtures/test-layout-expected.json index da933378906..9405dc4a7ca 100644 --- a/tests/fixtures/test-layout-expected.json +++ b/tests/fixtures/test-layout-expected.json @@ -3,6 +3,7 @@ "key-attribution.test.ts": "usage", "provider-send-path-import.test.ts": "server", "socks5-fetch.test.ts": "lib", + "socks5-upload-lifecycle.test.ts": "lib", "start-args.test.ts": "cli", "responses-core-modules.test.ts": "responses", "responses-passthrough-transient-policy.test.ts": "responses", diff --git a/tests/lib/socks5-upload-lifecycle.test.ts b/tests/lib/socks5-upload-lifecycle.test.ts new file mode 100644 index 00000000000..13b9dcaa11a --- /dev/null +++ b/tests/lib/socks5-upload-lifecycle.test.ts @@ -0,0 +1,279 @@ +import { describe, expect, test } from "bun:test"; +import { createConnection, createServer as createTcpServer, type AddressInfo, type Server as TcpServer, type Socket } from "node:net"; +import { socks5Fetch } from "../../src/lib/socks5-fetch"; + +const openSockets = new WeakMap>(); + +async function listen(server: TcpServer): Promise { + const sockets = new Set(); + openSockets.set(server, sockets); + server.on("connection", socket => { + sockets.add(socket); + socket.once("error", () => { /* an abandoned upload resets its peer */ }); + socket.once("close", () => sockets.delete(socket)); + }); + await new Promise((resolve, reject) => { + server.once("error", reject); + server.listen(0, "127.0.0.1", resolve); + }); + return (server.address() as AddressInfo).port; +} + +async function close(server: TcpServer): Promise { + for (const socket of openSockets.get(server) ?? []) socket.destroy(); + await new Promise(resolve => server.close(() => resolve())); +} + +/** A no-auth SOCKS5 peer that connects to the loopback port the request names and pipes both ways. */ +function socksProxy(): TcpServer { + return createTcpServer(socket => { + let stage: "greeting" | "connect" = "greeting"; + let buffer = Buffer.alloc(0); + const onData = (chunk: Buffer) => { + buffer = Buffer.concat([buffer, chunk]); + while (true) { + if (stage === "greeting") { + if (buffer.length < 2 || buffer.length < 2 + buffer[1]!) return; + buffer = buffer.subarray(2 + buffer[1]!); + socket.write(Buffer.from([0x05, 0x00])); + stage = "connect"; + continue; + } + if (buffer.length < 7) return; + const hostnameLength = buffer[4]!; + const requestLength = 7 + hostnameLength; + if (buffer.length < requestLength) return; + const port = buffer.readUInt16BE(5 + hostnameLength); + buffer = buffer.subarray(requestLength); + const target = createConnection({ host: "127.0.0.1", port }, () => { + socket.write(Buffer.from([0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0, 1])); + socket.removeListener("data", onData); + if (buffer.length > 0) socket.unshift(buffer); + socket.pipe(target); + target.pipe(socket); + }); + target.once("error", error => socket.destroy(error)); + return; + } + }; + socket.on("data", onData); + socket.once("error", () => { /* the proxy is torn down with its peers */ }); + }); +} + +/** + * A request body that produces one chunk and then never produces another. + * + * This is the shape the transport could not settle: the caller's stream owns that pending read, + * so destroying the socket does nothing to it. `pull` returns a promise that never settles, which + * is how a stream legitimately says "not yet" without ending. + */ +function stallingBody(first: Uint8Array) { + let markDelivered: () => void = () => { /* replaced below */ }; + let markCancelled: () => void = () => { /* replaced below */ }; + const delivered = new Promise(resolve => { markDelivered = resolve; }); + const cancelled = new Promise(resolve => { markCancelled = resolve; }); + let sent = false; + const stream = new ReadableStream({ + pull(controller) { + if (sent) return new Promise(() => { /* the body stalls here */ }); + sent = true; + controller.enqueue(first); + markDelivered(); + return undefined; + }, + cancel() { markCancelled(); }, + }); + return { stream, delivered, cancelled }; +} + +/** True when the promise settles inside the deadline, without asserting anything about timing. */ +async function settlesWithin(promise: Promise, timeoutMs = 2_000): Promise { + return await Promise.race([ + promise.then(() => true, () => true), + Bun.sleep(timeoutMs).then(() => false), + ]); +} + +function post(port: number, proxyPort: number, body: ReadableStream, signal?: AbortSignal) { + const init = { + method: "POST", + body, + duplex: "half", + ...(signal ? { signal } : {}), + } satisfies RequestInit & { duplex: "half" }; + return socks5Fetch(`http://provider.invalid:${port}/upload`, init, `socks5://127.0.0.1:${proxyPort}`); +} + +/** A peer that completes the request head and then reports the first body byte it receives. */ +function uploadObserver(): { server: TcpServer; uploading: Promise } { + let markUploading: () => void = () => { /* replaced below */ }; + const uploading = new Promise(resolve => { markUploading = resolve; }); + const server = createTcpServer(socket => { + socket.once("error", () => { /* the caller resets this peer on abort */ }); + let head = Buffer.alloc(0); + let headComplete = false; + socket.on("data", chunk => { + if (headComplete) { + markUploading(); + return; + } + head = Buffer.concat([head, chunk]); + const end = head.indexOf("\r\n\r\n"); + if (end < 0) return; + headComplete = true; + if (head.byteLength > end + 4) markUploading(); + }); + // Never answer: a fetch here can only settle through the abort path. + }); + return { server, uploading }; +} + +// A peer may answer a request it has not finished receiving, and a request body may stall. The +// upload loop used to await the caller's body reader before looking at the socket at all, so +// those two facts together produced a fetch that never settled with the answer already buffered. +describe("SOCKS5 upload lifecycle", () => { + test("an early final response resolves and stops the upload", async () => { + const uploaded: Buffer[] = []; + let answered = false; + const target = createTcpServer(socket => { + socket.once("error", () => { /* the client stops writing once it has its answer */ }); + let head = Buffer.alloc(0); + socket.on("data", chunk => { + if (answered) { + uploaded.push(Buffer.from(chunk)); + return; + } + head = Buffer.concat([head, chunk]); + const end = head.indexOf("\r\n\r\n"); + if (end < 0) return; + answered = true; + const trailing = head.subarray(end + 4); + if (trailing.byteLength > 0) uploaded.push(Buffer.from(trailing)); + socket.write("HTTP/1.1 413 Payload Too Large\r\nContent-Length: 5\r\nConnection: close\r\n\r\nlarge"); + }); + }); + const proxy = socksProxy(); + const [targetPort, proxyPort] = await Promise.all([listen(target), listen(proxy)]); + const body = stallingBody(new TextEncoder().encode("first chunk")); + try { + const pending = post(targetPort, proxyPort, body.stream); + expect(await settlesWithin(pending)).toBe(true); + const response = await pending; + expect(response.status).toBe(413); + expect(await response.text()).toBe("large"); + // The stalled body is released rather than left holding the caller's stream open. + expect(await settlesWithin(body.cancelled)).toBe(true); + // A terminating chunk after the answer would be read as the head of the next request. + expect(Buffer.concat(uploaded).toString("latin1")).not.toContain("0\r\n\r\n"); + } finally { + await Promise.all([close(proxy), close(target)]); + } + }); + + test("a caller abort settles a fetch waiting on a body chunk that never arrives", async () => { + // Abort is driven by the upstream actually receiving a body byte, not by the caller's + // stream having produced one. A stream can be pulled before the tunnel is established, so + // aborting on that signal would not prove the fetch was parked mid-upload. + const { server: target, uploading } = uploadObserver(); + const proxy = socksProxy(); + const [targetPort, proxyPort] = await Promise.all([listen(target), listen(proxy)]); + const body = stallingBody(new TextEncoder().encode("first chunk")); + const controller = new AbortController(); + const reason = new Error("caller gave up"); + try { + const pending = post(targetPort, proxyPort, body.stream, controller.signal); + const outcome = pending.then(() => "resolved" as const, (error: unknown) => error); + // The upload is now parked on a read the caller's stream will never fulfil. + expect(await settlesWithin(uploading)).toBe(true); + controller.abort(reason); + expect(await settlesWithin(outcome)).toBe(true); + expect(await outcome).toBe(reason); + expect(await settlesWithin(body.cancelled)).toBe(true); + } finally { + await Promise.all([close(proxy), close(target)]); + } + }); + + // `AbortSignal.reason` is whatever the caller passed, and several waiters inside this + // transport can win the race that settles an abort. They disagree about a reason they consider + // absent - one substitutes an Error for null, others coerce anything that is not an Error - so + // without a single answer the same abort surfaces differently depending on scheduling. + test.each([ + ["a string", "caller gave up"], + ["null", null], + ["a plain object", { cancelled: true }], + ] as const)("an abort reason that is %s reaches the caller unchanged", async (_label, reason) => { + const { server: target, uploading } = uploadObserver(); + const proxy = socksProxy(); + const [targetPort, proxyPort] = await Promise.all([listen(target), listen(proxy)]); + const body = stallingBody(new TextEncoder().encode("first chunk")); + const controller = new AbortController(); + try { + const pending = post(targetPort, proxyPort, body.stream, controller.signal); + const outcome = pending.then(() => "resolved" as const, (error: unknown) => error); + expect(await settlesWithin(uploading)).toBe(true); + controller.abort(reason); + expect(await settlesWithin(outcome)).toBe(true); + expect(await outcome).toBe(reason); + } finally { + await Promise.all([close(proxy), close(target)]); + } + }); + + test("a peer that disappears during a stalled body read settles rather than hanging", async () => { + const target = createTcpServer(socket => { + socket.once("error", () => { /* this peer leaves deliberately */ }); + let head = Buffer.alloc(0); + socket.on("data", chunk => { + head = Buffer.concat([head, chunk]); + if (head.indexOf("\r\n\r\n") < 0) return; + socket.destroy(); + }); + }); + const proxy = socksProxy(); + const [targetPort, proxyPort] = await Promise.all([listen(target), listen(proxy)]); + const body = stallingBody(new TextEncoder().encode("first chunk")); + try { + const pending = post(targetPort, proxyPort, body.stream); + const outcome = pending.then(() => "resolved" as const, (error: unknown) => error); + expect(await settlesWithin(outcome)).toBe(true); + expect(await outcome).toBeInstanceOf(Error); + expect(await settlesWithin(body.cancelled)).toBe(true); + } finally { + await Promise.all([close(proxy), close(target)]); + } + }); + + test("an ordinary streamed POST still completes with its terminating chunk", async () => { + let received = ""; + const target = createTcpServer(socket => { + socket.once("error", () => { /* teardown may reset this peer */ }); + socket.on("data", chunk => { + received += chunk.toString("latin1"); + if (!received.includes("0\r\n\r\n")) return; + socket.write("HTTP/1.1 200 OK\r\nContent-Length: 6\r\nConnection: close\r\n\r\nposted"); + }); + }); + const proxy = socksProxy(); + const [targetPort, proxyPort] = await Promise.all([listen(target), listen(proxy)]); + const encoder = new TextEncoder(); + const stream = new ReadableStream({ + start(controller) { + controller.enqueue(encoder.encode("hello ")); + controller.enqueue(encoder.encode("socks")); + controller.close(); + }, + }); + try { + const response = await post(targetPort, proxyPort, stream); + expect(response.status).toBe(200); + expect(await response.text()).toBe("posted"); + expect(received).toContain("hello "); + expect(received).toContain("socks"); + expect(received).toContain("0\r\n\r\n"); + } finally { + await Promise.all([close(proxy), close(target)]); + } + }); +}); From af4f744c75e4dd0348b4e497e67db4ac80208e07 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 19:00:36 +0900 Subject: [PATCH 23/97] fix(transport): decode content-coded responses on the pinned direct route (#5126) * fix(transport): decode content-coded responses on the pinned direct route The SOCKS tunnel undoes gzip and deflate; the pinned direct helper returned the coded bytes unchanged. Provider outbound chooses between the two, so the same gzip JSON was readable on one route and a SyntaxError on the other depending on operator egress configuration. The pinned helper now asks for identity unless the caller chose an accept-encoding, decodes gzip and deflate, drops the coding and the coded length once the bytes no longer match them, and refuses any other coding under a named error instead of handing over bytes no caller can parse. Only the coding the response actually carries decides this, so a preference list naming an alternative this code cannot undo is not a refusal. maxBytes now binds the decoded body as well as the bytes that arrived, because a ceiling applied only to the coded side admits a body far larger than the caller agreed to hold. The classifier is shared with the tunnel, which keeps its own error type and message. * fix(transport): keep a pinned transport failure out of the decode taxonomy Review of the content-coding change found the decoded body rewriting every non-PinnedHttpError from the pipeline into content_decode_failed. A mid-body reset and a socket error reach a decoder as "the stream failed", so that told the caller the peer had sent unreadable bytes when the connection had actually died. The source stream's failure is now recorded as it passes and surfaced unchanged; only what the decompressor itself rejected is renamed. The two new error codes also had to be classified everywhere the union is read. Antigravity quota probing sent every code except the byte cap to "timeout", so an undecodable response was diagnosed as a timing failure; both new codes now join the byte cap under "response_unusable". The Lab pinned sender switched over the four codes that existed when it was written and let anything else fall through to a raw rethrow. Both consumers now use a total map, which makes a future code a compile error rather than a silent misdiagnosis. An unsupported coding deliberately maps to nothing in the Lab taxonomy: it is a deterministic contract mismatch, and borrowing a timeout or transient code would tell Lab to wait or retry for a failure that is neither. Adds regressions for a reset during a valid coded body, cancellation through the decoder, the socket-side byte ceiling alongside the decoded one, and observed connection release before teardown. * fix(transport): classify an unreadable pinned response in the Lab taxonomy Leaving the unsupported-coding case out of the Lab map was not the same as leaving it unclassified. The executor turns an unrecognized error into harness_failure / execution_error, so a response the peer coded in a format this transport cannot undo was attributed to the runner rather than to the upstream. Both unreadable answers now carry a new unreadable_response transport code, which Lab classifies as a protocol failure: deterministic, upstream-owned, and neither a timeout, a budget, nor a harness fault. The map stays total, so a future pinned error code cannot inherit the old misattribution by default. The quota and Lab mappings are now asserted directly. Two test oracles were also weaker than their names. The byte-ceiling case sat above both ceilings, so deleting the socket-side counter could still pass through the decoded one; it now uses a payload whose coded form is larger than its decoded form, with both sizes asserted, so only the socket-side counter can refuse it. The cancellation case sent a complete small body, so ordinary end-of-stream could release the peer; it now promises more than it sends, stays open, and is cancelled after the pipeline has produced output. * fix(transport): stop tearing down a decoded body that already ended Hosted CI showed the success-path assertion failing: the case demanded the peer connection be destroyed after a complete decoded body, and it was not. The oracle was wrong, and so was the code it was pinning. A response that ended has nothing left to release, and destroying it takes a connection the agent is entitled to reuse. The identity path only closes, so the decode path now does the same. Teardown stays where a response actually ends early: a decode failure, an exceeded ceiling, and a caller that cancels. Those three now assert an observed close rather than only the error they raise, and the success case asserts the connection is left intact. * test(transport): assert end of stream, not a pooling decision The success case asserted the connection was left intact, which pins a mechanism this transport does not own: Node documents a completed connection as destroyed or pooled depending on the agent's keepAlive setting, and the runtime's actual choice is not something a transport test should encode in either direction. What a completed decoded body owes is that it ends - the decoder flushes, the stream closes and the caller reads the whole value - so that is what the case now asserts. The cleanup this path does owe is still asserted where a response ends early, in the decode-failure, ceiling and cancellation cases. * test(transport): hold the failing responses open so the close is attributable The decode-failure and ceiling cases sent their whole declared length, so the response could complete before the failure surfaced and the connection could then be pooled rather than closed - the same agent behavior the success case above deliberately refuses to pin. Both fixtures now promise more than they send and stay open, so the close each case asserts is the one this path owes for a response that ended early. The inventory paragraph is narrowed to match: teardown belongs to responses that end early, while a completed one is left to the agent. * test(lab): classify the error the sender actually rejected with The unreadable-response case asserted the rejection shape and then classified a separately constructed TransportError. That second assertion would pass even if the sender raised something else entirely, which is the opposite of what it is there to prove. Both cases now capture the rejected value, assert it is a TransportError carrying the expected code, and classify that same instance. --- scripts/test-layout/layout.json | 1 + src/lab/live/transport.ts | 4 + src/lab/live/types.ts | 5 + src/lib/http-response-semantics.ts | 28 ++ src/lib/lab-live-pinned-sender.ts | 38 +- src/lib/pinned-http.ts | 130 ++++++- src/lib/socks5-fetch.ts | 11 +- src/providers/quota/antigravity.ts | 24 +- structure/transports/inventory.md | 19 + tests/fixtures/test-layout-expected.json | 1 + tests/lab/lab-live-pinned-timeouts.test.ts | 38 ++ tests/lib/pinned-http-content-coding.test.ts | 358 ++++++++++++++++++ .../providers/provider-account-quota.test.ts | 2 + 13 files changed, 636 insertions(+), 23 deletions(-) create mode 100644 tests/lib/pinned-http-content-coding.test.ts diff --git a/scripts/test-layout/layout.json b/scripts/test-layout/layout.json index 29f6bdb144d..c27ec99cb7c 100644 --- a/scripts/test-layout/layout.json +++ b/scripts/test-layout/layout.json @@ -1083,6 +1083,7 @@ "passthrough-override.test.ts": "responses", "phase100-native-parity.test.ts": "e2e-style", "pi-path-contract.test.ts": "clients", + "pinned-http-content-coding.test.ts": "lib", "pinned-http.test.ts": "lib", "pinned-https-get.test.ts": "images", "plaintext-v2-agent-messages-server.test.ts": "server", diff --git a/src/lab/live/transport.ts b/src/lab/live/transport.ts index f1dac8e2116..359a4b7c118 100644 --- a/src/lab/live/transport.ts +++ b/src/lab/live/transport.ts @@ -104,6 +104,10 @@ export function classifyTransportError(error: unknown): { classification: Failur case "network_blocked": return { classification: "network_failure", secondaryCode: code }; case "region_blocked": return { classification: "region_blocked", secondaryCode: code }; case "provider_transient": return { classification: "provider_transient", secondaryCode: code }; + // A response this transport cannot read is an upstream protocol failure. It is deterministic + // rather than transient, and attributing it to the harness would blame the runner for what + // the peer sent. + case "unreadable_response": return { classification: "protocol_failure", secondaryCode: code }; case "connect_timeout": case "first_byte_timeout": case "total_timeout": return { classification: "timeout", secondaryCode: code }; case "inactivity_timeout": diff --git a/src/lab/live/types.ts b/src/lab/live/types.ts index 8a30cfc799e..70408b4394e 100644 --- a/src/lab/live/types.ts +++ b/src/lab/live/types.ts @@ -89,6 +89,11 @@ export type TransportErrorCode = | "output_byte_limit" | "output_token_limit" | "tool_call_limit" + // The peer answered, and the answer cannot be read: a content coding this transport cannot + // undo, or coded bytes that did not decode. Neither is a timeout, a budget, or a fault of + // the harness, so none of those codes describes it and every one of them would send an + // operator looking in the wrong place. + | "unreadable_response" | "artifact_byte_limit" | "memory_limit" | "child_process_limit" diff --git a/src/lib/http-response-semantics.ts b/src/lib/http-response-semantics.ts index 0a2bb693b7b..ac56325c506 100644 --- a/src/lib/http-response-semantics.ts +++ b/src/lib/http-response-semantics.ts @@ -27,3 +27,31 @@ export function isNullBodyStatus(status: number): boolean { return status === 204 || status === 205 || status === 304; } + +/** What a transport must do with the coding a response declares. */ +export type ContentCoding = + | { kind: "identity" } + | { kind: "decodable"; format: "gzip" | "deflate" } + | { kind: "unsupported"; coding: string }; + +/** + * Classify the `content-encoding` a raw transport received. + * + * `fetch` undoes a content-coding below the Response constructor. A transport that assembles a + * body from a socket hands the coded bytes to whatever reads them instead: `response.json()` + * throws a SyntaxError on the gzip magic number and an SSE reader sees noise rather than frames. + * Only `gzip` and `deflate` can be undone with `DecompressionStream`, so anything else is + * reported as unsupported and each transport refuses it under its own error type rather than + * surfacing bytes no caller can parse. + * + * This reads the coding the response actually carries and nothing else. A caller whose + * `accept-encoding` names a coding this code cannot undo is not the problem; what the peer + * chose to send is. + */ +export function classifyContentCoding(headers: Headers): ContentCoding { + const coding = (headers.get("content-encoding") ?? "").trim().toLowerCase(); + if (coding === "" || coding === "identity") return { kind: "identity" }; + if (coding === "gzip" || coding === "x-gzip") return { kind: "decodable", format: "gzip" }; + if (coding === "deflate") return { kind: "decodable", format: "deflate" }; + return { kind: "unsupported", coding }; +} diff --git a/src/lib/lab-live-pinned-sender.ts b/src/lib/lab-live-pinned-sender.ts index 0c336511bdd..7961369c785 100644 --- a/src/lib/lab-live-pinned-sender.ts +++ b/src/lib/lab-live-pinned-sender.ts @@ -1,10 +1,32 @@ -import { PinnedHttpError, pinnedHttpGet, pinnedHttpPost } from "./pinned-http"; +import { PinnedHttpError, pinnedHttpGet, pinnedHttpPost, type PinnedHttpErrorCode } from "./pinned-http"; import { TransportError } from "../lab/live/transport"; -import type { LabCredentialLeaseV1, LabPinnedSender } from "../lab/live/types"; +import type { LabCredentialLeaseV1, LabPinnedSender, TransportErrorCode } from "../lab/live/types"; /** Only response metadata required by current live assertions crosses into Lab. */ const LAB_RESPONSE_HEADER_ALLOWLIST = ["content-type"] as const; +/** + * Every pinned-transport failure code, mapped to the Lab transport taxonomy or to nothing. + * + * A switch over the codes that existed when it was written silently let later ones fall through + * to a raw rethrow. That is not the same as leaving them unclassified: Lab's executor turns an + * unrecognized error into `harness_failure` / `execution_error`, so a response the peer coded + * in a format this transport cannot undo was reported as a fault of the runner. Both unreadable + * answers therefore carry `unreadable_response`, which Lab classifies as a protocol failure. + * A total map keeps a future code from acquiring that misattribution by default. + */ +const LAB_TRANSPORT_FAILURES = { + connect_timeout: { code: "connect_timeout", message: "pinned provider connection timed out" }, + first_byte_timeout: { code: "first_byte_timeout", message: "pinned provider first byte timed out" }, + inactivity_timeout: { code: "inactivity_timeout", message: "pinned provider response stalled" }, + output_byte_limit: { code: "output_byte_limit", message: "pinned provider response exceeded byte budget" }, + content_decode_failed: { code: "unreadable_response", message: "pinned provider response did not decode" }, + unsupported_content_encoding: { + code: "unreadable_response", + message: "pinned provider used a content-encoding this transport cannot decode", + }, +} satisfies Record; + /** * Trusted credential/transport owner. Secret headers exist only in this non-Lab module and are * consumed directly by the pinned HTTP primitive; they are never returned to Lab code. @@ -33,16 +55,8 @@ export function createLabAuthorizedPinnedSender( body = await response.text(); } catch (error) { if (error instanceof PinnedHttpError) { - switch (error.code) { - case "connect_timeout": - throw new TransportError("connect_timeout", "pinned provider connection timed out"); - case "first_byte_timeout": - throw new TransportError("first_byte_timeout", "pinned provider first byte timed out"); - case "inactivity_timeout": - throw new TransportError("inactivity_timeout", "pinned provider response stalled"); - case "output_byte_limit": - throw new TransportError("output_byte_limit", "pinned provider response exceeded byte budget"); - } + const mapped = LAB_TRANSPORT_FAILURES[error.code]; + throw new TransportError(mapped.code, mapped.message); } throw error; } diff --git a/src/lib/pinned-http.ts b/src/lib/pinned-http.ts index e8f9de8d6f4..6527dfd7d49 100644 --- a/src/lib/pinned-http.ts +++ b/src/lib/pinned-http.ts @@ -1,6 +1,6 @@ import http, { type ClientRequest, type IncomingMessage, type RequestOptions } from "node:http"; import https from "node:https"; -import { isNullBodyStatus } from "./http-response-semantics"; +import { classifyContentCoding, isNullBodyStatus } from "./http-response-semantics"; export type PinnedAddress = { address: string; family: number }; @@ -8,7 +8,9 @@ export type PinnedHttpErrorCode = | "connect_timeout" | "first_byte_timeout" | "inactivity_timeout" - | "output_byte_limit"; + | "output_byte_limit" + | "unsupported_content_encoding" + | "content_decode_failed"; export class PinnedHttpError extends Error { override readonly name = "PinnedHttpError"; @@ -33,6 +35,99 @@ export interface PinnedHttpRequestOptions { /** @deprecated Use {@link PinnedHttpRequestOptions}. */ export type PinnedHttpGetOptions = PinnedHttpRequestOptions; +/** + * Undo the content-coding this transport has to undo itself, under the caller's byte ceiling. + * + * `maxBytes` keeps its existing meaning for the bytes that arrive on the socket, and gains the + * same meaning for the bytes the caller ends up reading. Bounding only the coded side would let + * a small compressed response expand past a ceiling the caller set precisely so it would not + * have to hold an unbounded body in memory. + * + * A completed body is not torn down here. The response already ended, so there is nothing to + * release, and destroying it would take a connection the agent is entitled to reuse. That + * matches the identity path, which also only closes. Teardown belongs to the paths that end a + * response early: a decode failure, an exceeded ceiling, and a caller that cancels. + * + * Only a decoder failure is renamed. A mid-body reset, a stalled response and an exceeded + * socket-byte ceiling all reach this pipeline as "the stream failed", and calling any of them a + * decode failure would tell the caller the peer sent unreadable bytes when the truth is that the + * connection died. The source failure is recorded as it passes so the original error survives; + * what is left after that is the decompressor's own, and that one is named because the caller's + * alternative is a bare TypeError from a stream it never constructed. + */ +function decodedBody( + source: ReadableStream, + format: "gzip" | "deflate", + maxBytes: number | undefined, + context: string, + release: () => void, +): ReadableStream { + // Interposed purely to attribute failures. Once bytes enter the decompressor, a transport + // error and a corrupt trailer are indistinguishable from the far side of the pipe. + let sourceFailure: { error: unknown } | undefined; + const sourceReader = source.getReader(); + const attributed = new ReadableStream({ + async pull(controller) { + try { + const next = await sourceReader.read(); + if (next.done) { + controller.close(); + return; + } + controller.enqueue(next.value); + } catch (error) { + sourceFailure = { error }; + controller.error(error); + } + }, + cancel(reason) { + return sourceReader.cancel(reason); + }, + }); + // `DecompressionStream` declares its writable side as `WritableStream`, and + // TypeScript measures `WritableStream` as invariant in its chunk type, so the pair is not + // assignable to `ReadableWritablePair` even though every chunk this + // body produces is a valid `BufferSource`. The conversion states that relationship and + // nothing else; it does not widen what is actually written. + const decompressor = new DecompressionStream(format) as unknown as ReadableWritablePair; + const reader = attributed.pipeThrough(decompressor).getReader(); + let decoded = 0; + return new ReadableStream({ + async pull(controller) { + try { + const next = await reader.read(); + if (next.done) { + controller.close(); + return; + } + decoded += next.value.byteLength; + if (maxBytes !== undefined && decoded > maxBytes) { + throw new PinnedHttpError("output_byte_limit", `${context} exceeds ${maxBytes} byte cap`); + } + controller.enqueue(next.value); + } catch (error) { + // A failure the socket stream raised is the caller's answer, whatever shape it has. + // Only what the decompressor itself rejected is renamed. + const named = sourceFailure !== undefined + ? sourceFailure.error + : error instanceof PinnedHttpError + ? error + : new PinnedHttpError("content_decode_failed", `${context} could not decode its ${format} body`); + // Cancelling the decoded reader propagates back through the decompressor to the socket + // stream's own `cancel`, which destroys the request; `release` covers the case where + // that propagation is already finished. + await reader.cancel(named).catch(() => { /* already torn down */ }); + controller.error(named); + release(); + } + }, + async cancel(reason) { + await reader.cancel(reason).catch(() => { /* already torn down */ }); + release(); + }, + }); +} + function pinnedHttpRequest( url: string, pinned: PinnedAddress, @@ -56,6 +151,10 @@ function pinnedHttpRequest( const maxBytes = options?.maxBytes; const headers = new Headers(options?.headers); headers.set("host", parsed.host); + // This transport assembles the response itself, so a coding it did not ask for becomes its own + // problem to undo. Ask for none by default and leave an explicit caller choice alone, which is + // the same rule `src/lib/socks5-fetch.ts` applies to the other raw route. + if (!headers.has("accept-encoding")) headers.set("accept-encoding", "identity"); if (body !== undefined && !headers.has("content-length")) { headers.set("content-length", String(Buffer.byteLength(body))); } @@ -166,6 +265,24 @@ function pinnedHttpRequest( return; } + // The peer may have coded the body whatever this request asked for. Classify before the + // stream takes the socket so a coding this transport cannot undo fails on the ordinary + // error path rather than reaching the caller as bytes its parser cannot read. + const coding = classifyContentCoding(responseHeaders); + if (coding.kind === "unsupported") { + try { response.destroy(); } catch { /* ignore */ } + fail(new PinnedHttpError( + "unsupported_content_encoding", + `${context} returned an unsupported content-encoding: ${coding.coding}`, + )); + return; + } + if (coding.kind === "decodable") { + responseHeaders.delete("content-encoding"); + // The declared length counted the coded bytes, not what the caller now reads. + responseHeaders.delete("content-length"); + } + let received = 0; const stream = new ReadableStream({ start(controller) { @@ -207,7 +324,14 @@ function pinnedHttpRequest( if (settled) return; settled = true; - resolve(new Response(stream, { status, headers: responseHeaders })); + const release = () => { + try { response.destroy(); } catch { /* ignore */ } + try { req?.destroy(); } catch { /* ignore */ } + }; + const payload = coding.kind === "decodable" + ? decodedBody(stream, coding.format, maxBytes, context, release) + : stream; + resolve(new Response(payload, { status, headers: responseHeaders })); }; const requestFn = parsed.protocol === "https:" ? https.request : http.request; diff --git a/src/lib/socks5-fetch.ts b/src/lib/socks5-fetch.ts index d26dfbbbd10..f4000925cf0 100644 --- a/src/lib/socks5-fetch.ts +++ b/src/lib/socks5-fetch.ts @@ -1,6 +1,6 @@ import net, { type Socket } from "node:net"; import tls, { type TLSSocket } from "node:tls"; -import { isNullBodyStatus } from "./http-response-semantics"; +import { classifyContentCoding, isNullBodyStatus } from "./http-response-semantics"; const DEFAULT_SOCKS5_PORT = 1080; const SOCKS5_CONNECT_TIMEOUT_MS = 30_000; @@ -531,11 +531,10 @@ function bodylessResponse(method: string, status: number): boolean { * the coded path would fail responses that succeed uncompressed. */ function contentCodingFormat(headers: Headers): "gzip" | "deflate" | undefined { - const coding = (headers.get("content-encoding") ?? "").trim().toLowerCase(); - if (coding === "" || coding === "identity") return undefined; - if (coding === "gzip" || coding === "x-gzip") return "gzip"; - if (coding === "deflate") return "deflate"; - throw new Socks5FetchError("SOCKS5 upstream returned an unsupported content-encoding: " + coding); + const coding = classifyContentCoding(headers); + if (coding.kind === "identity") return undefined; + if (coding.kind === "decodable") return coding.format; + throw new Socks5FetchError("SOCKS5 upstream returned an unsupported content-encoding: " + coding.coding); } /** Read response heads until the final one, consuming the interim informational answers. */ diff --git a/src/providers/quota/antigravity.ts b/src/providers/quota/antigravity.ts index bafdc1eee02..928b10e2570 100644 --- a/src/providers/quota/antigravity.ts +++ b/src/providers/quota/antigravity.ts @@ -1,6 +1,6 @@ import { antigravityUserAgent } from "../../adapters/client-fingerprint"; import { DestinationDnsResolutionError } from "../../lib/destination-policy"; -import { PinnedHttpError } from "../../lib/pinned-http"; +import { PinnedHttpError, type PinnedHttpErrorCode } from "../../lib/pinned-http"; import { ProviderOutboundPolicyError, providerOutboundPost, providerRedirectError, type ProviderOutboundDependencies } from "../../lib/provider-outbound"; import { getValidAccessToken } from "../../oauth"; import { getAccountCredential, getCredential } from "../../oauth/store"; @@ -193,10 +193,30 @@ type AntigravityQuotaProbeResult = | { kind: "available"; quota: ProviderQuota; source: "google-antigravity:retrieveUserQuotaSummary" | "google-antigravity:fetchAvailableModels" } | { kind: "unavailable"; failure: QuotaFailureCode; legacy: { kind: "null" } | { kind: "throw"; error: unknown } }; +/** + * Every pinned-transport failure code, classified once. + * + * A conditional that named one code and sent the rest to `timeout` was correct only for as long + * as the union held exactly the codes it was written against. When the transport learned to + * report a coding it cannot undo, that answer was reported as a timeout, which is a different + * operational story entirely. A total map makes a new code a compile error here rather than a + * quiet misdiagnosis. + */ +const PINNED_QUOTA_FAILURES = { + connect_timeout: "timeout", + first_byte_timeout: "timeout", + inactivity_timeout: "timeout", + // The response arrived and cannot be used: too large, coded in a format this transport cannot + // undo, or coded bytes that did not decode. None of these is a timing failure. + output_byte_limit: "response_unusable", + unsupported_content_encoding: "response_unusable", + content_decode_failed: "response_unusable", +} satisfies Record; + function quotaTransportFailure(error: unknown): QuotaFailureCode { if (error instanceof ProviderOutboundPolicyError) return "destination_blocked"; if (error instanceof DestinationDnsResolutionError) return "dns_failed"; - if (error instanceof PinnedHttpError) return error.code === "output_byte_limit" ? "response_unusable" : "timeout"; + if (error instanceof PinnedHttpError) return PINNED_QUOTA_FAILURES[error.code]; if (error instanceof DOMException && error.name === "TimeoutError") return "timeout"; return "transport_error"; } diff --git a/structure/transports/inventory.md b/structure/transports/inventory.md index b49c6a6a89a..3bcf76ab709 100644 --- a/structure/transports/inventory.md +++ b/structure/transports/inventory.md @@ -268,4 +268,23 @@ peer that is entitled to keep it alive, and their representation headers are pre arrived rather than decoded or refused, because there are no coded bytes to act on. `tests/lib/transport-null-body.test.ts` covers both transports against a keep-alive peer. +## Raw transport content coding + +Content coding is each raw transport's own obligation, and the pinned direct helper now carries +the same one the tunnel does. Provider outbound picks between these two routes, so decoding on +only one of them made the same gzip JSON readable or unreadable depending on operator egress +configuration. Both ask for `identity` unless the caller chose an `accept-encoding` itself, +decode `gzip` and `deflate`, drop the coding and the coded length once the bytes no longer match +them, and refuse any other coding by name instead of surfacing bytes no caller can parse. Only +the coding the response actually carries decides this; a preference list that mentions an +alternative this code cannot undo is not a refusal. + +The pinned helper's `maxBytes` binds both sides of that decode: the bytes that arrive on the +socket keep their existing meaning, and the decoded bytes are bounded by the same ceiling, so a +small coded response cannot expand past the limit a caller set to bound what it holds. A decoder +failure surfaces as a named `PinnedHttpError`. Connection teardown belongs to the responses that +end early — a decode failure, an exceeded ceiling, a cancelled read; a response that completed +is left to the HTTP agent, which may pool or destroy it. +`tests/lib/pinned-http-content-coding.test.ts` covers both routes on the same payload. + Dashboard Fast-row persistence and client refresh follow the [Fast selector rows setting contract](../gui-and-management-api.md#fast-selector-rows-setting). diff --git a/tests/fixtures/test-layout-expected.json b/tests/fixtures/test-layout-expected.json index 9405dc4a7ca..a52a560f34d 100644 --- a/tests/fixtures/test-layout-expected.json +++ b/tests/fixtures/test-layout-expected.json @@ -908,6 +908,7 @@ "passthrough-override.test.ts": "responses", "phase100-native-parity.test.ts": "e2e-style", "pi-path-contract.test.ts": "clients", + "pinned-http-content-coding.test.ts": "lib", "pinned-http.test.ts": "lib", "pinned-https-get.test.ts": "images", "plaintext-v2-agent-messages-server.test.ts": "server", diff --git a/tests/lab/lab-live-pinned-timeouts.test.ts b/tests/lab/lab-live-pinned-timeouts.test.ts index a3a4757c9c9..3af1c038642 100644 --- a/tests/lab/lab-live-pinned-timeouts.test.ts +++ b/tests/lab/lab-live-pinned-timeouts.test.ts @@ -1,6 +1,7 @@ import { createServer, type IncomingMessage, type Server, type ServerResponse } from "node:http"; import { afterEach, describe, expect, test } from "bun:test"; import { createLabAuthorizedPinnedSender } from "../../src/lib/lab-live-pinned-sender"; +import { TransportError, classifyTransportError } from "../../src/lab/live/transport"; import type { LabCredentialLeaseV1, LabDestinationV1, LiveRunConfig } from "../../src/lab/live/types"; const SERVERS: Server[] = []; @@ -124,6 +125,43 @@ describe("CL-03 pinned live transport failure classification", () => { }); }); + // An answer the transport cannot read is the peer's doing. Before this was classified, it + // reached Lab as an unrecognized error, and the executor's fallback reported it as + // harness_failure / execution_error - the runner blamed for what the upstream sent. + test("reports a coding this transport cannot undo as an unreadable response", async () => { + const port = await listen((_req, res) => { + res.writeHead(200, { "content-type": "application/json", "content-encoding": "br" }); + res.end("not really brotli"); + }); + + // Classify the error the sender actually rejected with. Building a second TransportError and + // classifying that would pass even if the sender raised something else entirely. + const error = await send(port, { firstByteTimeoutMs: 1_000, inactivityTimeoutMs: 1_000 }) + .then(() => undefined, (caught: unknown) => caught); + expect(error).toBeInstanceOf(TransportError); + expect(error).toMatchObject({ name: "TransportError", code: "unreadable_response" }); + expect(classifyTransportError(error)).toEqual({ + classification: "protocol_failure", + secondaryCode: "unreadable_response", + }); + }); + + test("reports coded bytes that do not decode as an unreadable response", async () => { + const port = await listen((_req, res) => { + res.writeHead(200, { "content-type": "application/json", "content-encoding": "gzip" }); + res.end("this is not gzip at all"); + }); + + const error = await send(port, { firstByteTimeoutMs: 1_000, inactivityTimeoutMs: 1_000 }) + .then(() => undefined, (caught: unknown) => caught); + expect(error).toBeInstanceOf(TransportError); + expect(error).toMatchObject({ name: "TransportError", code: "unreadable_response" }); + expect(classifyTransportError(error)).toEqual({ + classification: "protocol_failure", + secondaryCode: "unreadable_response", + }); + }); + test("allows a response exactly at the output byte ceiling", async () => { const port = await listen((_req, res) => { res.writeHead(200, { "content-type": "text/plain" }); diff --git a/tests/lib/pinned-http-content-coding.test.ts b/tests/lib/pinned-http-content-coding.test.ts new file mode 100644 index 00000000000..0f2f5953bcc --- /dev/null +++ b/tests/lib/pinned-http-content-coding.test.ts @@ -0,0 +1,358 @@ +import { describe, expect, test } from "bun:test"; +import { createConnection, createServer as createTcpServer, type AddressInfo, type Server as TcpServer, type Socket } from "node:net"; +import { randomBytes } from "node:crypto"; +import { gzipSync, deflateSync } from "node:zlib"; +import { PinnedHttpError, pinnedHttpGet } from "../../src/lib/pinned-http"; +import { socks5Fetch } from "../../src/lib/socks5-fetch"; + +const openSockets = new WeakMap>(); + +async function listen(server: TcpServer): Promise { + const sockets = new Set(); + openSockets.set(server, sockets); + server.on("connection", socket => { + sockets.add(socket); + socket.once("error", () => { /* a refused coding resets its peer */ }); + socket.once("close", () => sockets.delete(socket)); + }); + await new Promise((resolve, reject) => { + server.once("error", reject); + server.listen(0, "127.0.0.1", resolve); + }); + return (server.address() as AddressInfo).port; +} + +async function close(server: TcpServer): Promise { + for (const socket of openSockets.get(server) ?? []) socket.destroy(); + await new Promise(resolve => server.close(() => resolve())); +} + +/** A no-auth SOCKS5 peer that connects to the loopback port the request names and pipes both ways. */ +function socksProxy(): TcpServer { + return createTcpServer(socket => { + let stage: "greeting" | "connect" = "greeting"; + let buffer = Buffer.alloc(0); + const onData = (chunk: Buffer) => { + buffer = Buffer.concat([buffer, chunk]); + while (true) { + if (stage === "greeting") { + if (buffer.length < 2 || buffer.length < 2 + buffer[1]!) return; + buffer = buffer.subarray(2 + buffer[1]!); + socket.write(Buffer.from([0x05, 0x00])); + stage = "connect"; + continue; + } + if (buffer.length < 7) return; + const hostnameLength = buffer[4]!; + const requestLength = 7 + hostnameLength; + if (buffer.length < requestLength) return; + const port = buffer.readUInt16BE(5 + hostnameLength); + buffer = buffer.subarray(requestLength); + const target = createConnection({ host: "127.0.0.1", port }, () => { + socket.write(Buffer.from([0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0, 1])); + socket.removeListener("data", onData); + if (buffer.length > 0) socket.unshift(buffer); + socket.pipe(target); + target.pipe(socket); + }); + target.once("error", error => socket.destroy(error)); + return; + } + }; + socket.on("data", onData); + socket.once("error", () => { /* the proxy is torn down with its peers */ }); + }); +} + +/** A peer that answers one coded body and records the request head it was asked with. */ +function codedTarget( + coding: string, + payload: Uint8Array, + options?: { truncateAfter?: number; holdAfter?: number; declaredLength?: number }, +) { + let requestText = ""; + let connection: Socket | undefined; + const server = createTcpServer(socket => { + connection = socket; + socket.once("error", () => { /* the caller may reset this peer */ }); + let request = Buffer.alloc(0); + socket.on("data", chunk => { + request = Buffer.concat([request, chunk]); + requestText = request.toString("latin1"); + if (!requestText.includes("\r\n\r\n")) return; + const head = "HTTP/1.1 200 OK\r\ncontent-type: application/json\r\ncontent-encoding: " + + coding + + "\r\ncontent-length: " + (options?.declaredLength ?? payload.byteLength) + "\r\n\r\n"; + const hold = options?.holdAfter; + if (hold !== undefined) { + // Promise more than is sent and then stay open. The response is still in flight, so a + // cancellation has to travel backwards to close it; an already-finished body would be + // released by ordinary end-of-stream and prove nothing about cancellation. + socket.write(Buffer.concat([Buffer.from(head, "latin1"), Buffer.from(payload.subarray(0, hold))])); + return; + } + const truncate = options?.truncateAfter; + if (truncate === undefined) { + socket.write(Buffer.concat([Buffer.from(head, "latin1"), Buffer.from(payload)])); + return; + } + // Announce the whole coded length, send a valid prefix of it, then vanish. The decoder + // sees a truncated stream; the caller's real problem is the connection. + socket.write(Buffer.concat([Buffer.from(head, "latin1"), Buffer.from(payload.subarray(0, truncate))])); + socket.destroy(); + }); + }); + return { server, requestHead: () => requestText, connection: () => connection }; +} + +/** + * Wait for a socket to be observably destroyed, under a bounded deadline. + * + * The contract is that the transport releases the connection, not that it does so inside any + * particular window, so this waits for the state the contract promises rather than sleeping for + * a fixed time and asserting something about machine load. + */ +async function awaitDestroyed(socket: Socket | undefined, timeoutMs = 2_000): Promise { + const deadline = Date.now() + timeoutMs; + while (socket?.destroyed !== true && Date.now() < deadline) await Bun.sleep(5); + return socket?.destroyed === true; +} + +function pinnedGet(port: number, path: string, options?: { maxBytes?: number; headers?: HeadersInit }): Promise { + return pinnedHttpGet( + `http://provider.invalid:${port}${path}`, + { address: "127.0.0.1", family: 4 }, + undefined, + { idleTimeoutMs: 5_000, context: "provider response", ...options }, + ); +} + +// The pinned direct helper and the SOCKS tunnel are chosen by the same provider outbound +// decision, so a body that is readable on one route and compressed on the other makes the +// provider's behavior depend on the operator's egress configuration. These pin the parity. +describe("pinned direct content coding", () => { + test("a gzip body is decoded and stops advertising a coding it no longer carries", async () => { + const body = JSON.stringify({ ok: true, note: "compressed" }); + const { server: target } = codedTarget("gzip", gzipSync(Buffer.from(body, "utf8"))); + const port = await listen(target); + try { + const response = await pinnedGet(port, "/gzip"); + expect(response.headers.get("content-encoding")).toBeNull(); + // The declared length counted the coded bytes; keeping it would misdescribe the body. + expect(response.headers.get("content-length")).toBeNull(); + expect(await response.json()).toEqual({ ok: true, note: "compressed" }); + } finally { + await close(target); + } + }); + + test("a deflate body is decoded the same way", async () => { + // HTTP `deflate` is the zlib container, not raw DEFLATE, and that is what + // `DecompressionStream("deflate")` reads. + const { server: target } = codedTarget("deflate", deflateSync(Buffer.from(JSON.stringify({ ok: true }), "utf8"))); + const port = await listen(target); + try { + const response = await pinnedGet(port, "/deflate"); + expect(await response.json()).toEqual({ ok: true }); + } finally { + await close(target); + } + }); + + test("both raw transports produce the same logical JSON for the same coded payload", async () => { + const body = JSON.stringify({ route: "parity", values: [1, 2, 3] }); + const direct = codedTarget("gzip", gzipSync(Buffer.from(body, "utf8"))); + const tunneled = codedTarget("gzip", gzipSync(Buffer.from(body, "utf8"))); + const proxy = socksProxy(); + const [directPort, tunneledPort, proxyPort] = await Promise.all([ + listen(direct.server), + listen(tunneled.server), + listen(proxy), + ]); + try { + const pinned = await pinnedGet(directPort, "/parity"); + const tunneledResponse = await socks5Fetch( + `http://provider.invalid:${tunneledPort}/parity`, + undefined, + `socks5://127.0.0.1:${proxyPort}`, + ); + expect(await pinned.json()).toEqual(JSON.parse(body)); + expect(await tunneledResponse.json()).toEqual(JSON.parse(body)); + } finally { + await Promise.all([close(proxy), close(direct.server), close(tunneled.server)]); + } + }); + + test("a coding this transport cannot undo is refused by name before the body is handed over", async () => { + // Brotli is not a format `DecompressionStream` implements. Returning the bytes anyway is the + // behavior being removed: the caller would get a SyntaxError from its own parser with + // nothing naming the cause. + const { server: target } = codedTarget("br", new TextEncoder().encode("not really brotli")); + const port = await listen(target); + try { + const error = await pinnedGet(port, "/brotli").catch((caught: unknown) => caught); + expect(error).toBeInstanceOf(PinnedHttpError); + expect(error).toMatchObject({ code: "unsupported_content_encoding" }); + expect(String(error)).toContain("unsupported content-encoding: br"); + } finally { + await close(target); + } + }); + + test("a corrupt coded body fails with a named decode error rather than a bare stream failure", async () => { + // Promise more than is sent and keep the socket open. A fixture that delivers its whole + // declared length lets the response complete before the decoder rejects, and then the + // connection may be pooled rather than closed - which would make this assert the same + // agent behavior the success case above deliberately does not pin. Holding the response + // unfinished is what makes the close attributable to this path. + const corrupt = new TextEncoder().encode("this is not gzip at all"); + const { server: target, connection } = codedTarget("gzip", corrupt, { + holdAfter: corrupt.byteLength, + declaredLength: corrupt.byteLength + 1_024, + }); + const port = await listen(target); + try { + const response = await pinnedGet(port, "/corrupt"); + const error = await response.text().catch((caught: unknown) => caught); + expect(error).toBeInstanceOf(PinnedHttpError); + expect(error).toMatchObject({ code: "content_decode_failed" }); + // The response never finished, so closing it is this path's obligation. + expect(await awaitDestroyed(connection())).toBe(true); + } finally { + connection()?.destroy(); + await close(target); + } + }); + + test("maxBytes bounds the decoded body, not only the bytes that arrived", async () => { + // The coded payload is tiny and the decoded one is not: a ceiling applied only to the socket + // would admit a body far larger than the caller agreed to hold. + const expanded = Buffer.alloc(64 * 1024, 0x61); + const { server: target } = codedTarget("gzip", gzipSync(expanded)); + const port = await listen(target); + try { + const response = await pinnedGet(port, "/expanded", { maxBytes: 1024 }); + const error = await response.text().catch((caught: unknown) => caught); + expect(error).toBeInstanceOf(PinnedHttpError); + expect(error).toMatchObject({ code: "output_byte_limit" }); + } finally { + await close(target); + } + }); + + test("a reset during a valid coded body reports the transport failure, not a decode failure", async () => { + // The decoder sees a truncated stream either way, so this is the case where naming every + // pipeline failure a decode failure would tell the caller the peer sent unreadable bytes + // when what actually happened is that the connection died mid-body. + const gzipped = gzipSync(Buffer.from(JSON.stringify({ ok: true, note: "half sent" }), "utf8")); + const { server: target } = codedTarget("gzip", gzipped, { truncateAfter: Math.max(1, gzipped.byteLength - 4) }); + const port = await listen(target); + try { + const response = await pinnedGet(port, "/reset"); + const error = await response.text().catch((caught: unknown) => caught); + expect(error).toBeInstanceOf(Error); + expect(error).not.toMatchObject({ code: "content_decode_failed" }); + } finally { + await close(target); + } + }); + + test("cancelling a coded body propagates through the decoder and releases the peer", async () => { + const coded = gzipSync(Buffer.alloc(256 * 1024, 0x62)); + // Send almost all of it, promise more than that, and never finish: the body is still open + // when the caller gives up. + const { server: target, connection } = codedTarget("gzip", coded, { + holdAfter: coded.byteLength - 16, + declaredLength: coded.byteLength + 1_024, + }); + const port = await listen(target); + try { + const response = await pinnedGet(port, "/cancel"); + const reader = response.body!.getReader(); + // Read once so the pipeline is actually running before cancellation, rather than + // cancelling a body nothing has started to consume. + const first = await reader.read(); + expect(first.done).toBe(false); + // A caller's own reason must travel the decode pipeline without the transport turning it + // into a failure of its own. + await reader.cancel(new Error("caller stopped reading")); + // Cancellation propagates through the decoder to the socket rather than stopping at it. + expect(await awaitDestroyed(connection())).toBe(true); + } finally { + connection()?.destroy(); + await close(target); + } + }); + + test("the byte ceiling still binds the bytes that arrive, not only the decoded ones", async () => { + // Deliberately inverted: gzip framing costs more than these bytes save, so the coded body is + // larger than the decoded one. With the ceiling above the decoded size, only the socket-side + // counter can refuse this, which is what makes the case an oracle for that counter rather + // than one the decoded guard could also satisfy. The sizes are asserted, not assumed. + const tiny = randomBytes(8); + const coded = gzipSync(tiny); + const limit = coded.byteLength - 1; + expect(coded.byteLength).toBeGreaterThan(limit); + expect(tiny.byteLength).toBeLessThanOrEqual(limit); + // Unfinished for the same reason the corrupt case is: the ceiling must be what closes this + // connection, not the response having completed. + const { server: target, connection } = codedTarget("gzip", coded, { + holdAfter: coded.byteLength, + declaredLength: coded.byteLength + 1_024, + }); + const port = await listen(target); + try { + const response = await pinnedGet(port, "/inverted", { maxBytes: limit }); + const error = await response.text().catch((caught: unknown) => caught); + expect(error).toBeInstanceOf(PinnedHttpError); + expect(error).toMatchObject({ code: "output_byte_limit" }); + expect(await awaitDestroyed(connection())).toBe(true); + } finally { + connection()?.destroy(); + await close(target); + } + }); + + test("a decoded response settles at end of stream", async () => { + // What a completed body owes is that it ends: the decoder flushes, the stream closes, and + // the caller sees the whole value. What happens to the connection afterwards is the HTTP + // agent's decision - Node documents a completed connection as destroyed or pooled + // depending on keepAlive - so asserting either outcome here would pin a mechanism this + // transport does not own. Cleanup this path does owe is asserted where a response ends + // early: the decode-failure, ceiling and cancellation cases above each observe a close. + const { server: target, connection } = codedTarget("gzip", gzipSync(Buffer.from('{"ok":true}', "utf8"))); + const port = await listen(target); + try { + const response = await pinnedGet(port, "/complete"); + const reader = response.body!.getReader(); + let decoded = ""; + for (;;) { + const next = await reader.read(); + if (next.done) break; + decoded += new TextDecoder().decode(next.value); + } + expect(JSON.parse(decoded)).toEqual({ ok: true }); + } finally { + connection()?.destroy(); + await close(target); + } + }); + + test("the request asks for identity by default and keeps an explicit caller preference", async () => { + const payload = gzipSync(Buffer.from(JSON.stringify({ ok: true }), "utf8")); + const bare = codedTarget("identity", new TextEncoder().encode("{}")); + // A preference list that mentions a coding this transport cannot undo is not a reason to + // refuse the response: what matters is the coding the peer actually chose. + const chosen = codedTarget("gzip", payload); + const [barePort, chosenPort] = await Promise.all([listen(bare.server), listen(chosen.server)]); + try { + await pinnedGet(barePort, "/default"); + expect(bare.requestHead().toLowerCase()).toContain("accept-encoding: identity"); + const response = await pinnedGet(chosenPort, "/explicit", { headers: { "accept-encoding": "gzip, br" } }); + expect(chosen.requestHead().toLowerCase()).toContain("accept-encoding: gzip, br"); + expect(await response.json()).toEqual({ ok: true }); + } finally { + await Promise.all([close(bare.server), close(chosen.server)]); + } + }); +}); diff --git a/tests/providers/provider-account-quota.test.ts b/tests/providers/provider-account-quota.test.ts index 2ac6489e839..2ddae55d6dd 100644 --- a/tests/providers/provider-account-quota.test.ts +++ b/tests/providers/provider-account-quota.test.ts @@ -829,6 +829,8 @@ describe("google-antigravity per-account quota (#1082)", () => { test.each([ [new PinnedHttpError("connect_timeout", "private-error"), "timeout"], [new PinnedHttpError("output_byte_limit", "private-error"), "response_unusable"], + [new PinnedHttpError("unsupported_content_encoding", "private-error"), "response_unusable"], + [new PinnedHttpError("content_decode_failed", "private-error"), "response_unusable"], [new DOMException("private-error", "TimeoutError"), "timeout"], [new Error("private-error"), "transport_error"], ] as const)("typed fallback failure maps to %s", async (error, failure) => { From bb2fa5ab25d65a4e5fbab9253f5cc750cbbf2dcf Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 19:03:29 +0900 Subject: [PATCH 24/97] fix(responses): share one progressive freeform decoder with routed restoration (#5129) * fix(responses): share one progressive freeform decoder with routed restoration Routed custom-tool restoration decoded the string inside the input wrapper and emitted it immediately, while completion strips a complete outer Markdown fence for exec and apply_patch. A delta consumer could therefore receive fence bytes that do not belong to the authoritative final input, and no SSE event can take a published prefix back. The decoder the bridge already grew for this now lives in src/responses/progressive-freeform-input.ts and both paths call it. Bridge behavior is unchanged: the same function with the same arguments at the same call site, with its separate patch-envelope hold left where it was. Routed restoration keeps its stricter holds for an unrecognized JSON object and for a code-mode patch envelope, and keeps owning its retained bytes - the shared decoder is pure and leases no translator budget. Duplicate input keys and a wrapper that only becomes invalid after a valid prefix was emitted stay bounded exceptions rather than an invariant this cannot keep: completion remains authoritative, and the new sibling test documents both. * fix(responses): hold a routed apply_patch envelope the way the bridge does The shared decoder made ordinary raw input progressive on the routed path, which is the intended behavior and is what the bridge already does. It also exposed a case the older routed decoder never reached: a raw decorated `*** Begin Patch ***` envelope now streamed, while completion rewrites those markers through normalizeApplyPatchDelimiters. The decorated bytes would be published and then replaced, which is exactly the rewind this path forbids. The routed hold now covers both reasons completion rewrites an envelope, as the bridge's does: an exec body that compiles into an apply_patch helper call, and an apply_patch body whose delimiters are normalized. Namespaced tools are unchanged, since neither reason applies to a foreign grammar. The regression drives a raw decorated envelope across every chunk split and asserts no preview alongside agreeing normalized done, item and terminal input. * fix(responses): stop previewing a wrapper with a literal control character A JSON string cannot contain a raw character below U+0020, so a wrapper carrying one never parses and completion keeps the whole wrapper as the input. The decoder was appending those characters to the preview, which publishes a decoded value the authoritative item does not contain - the same disagreement a fenced body causes, reached through a different invalid spelling. It now stops instead. --- scripts/test-layout/layout.json | 1 + src/bridge/sse.ts | 154 +----------- src/responses/progressive-freeform-input.ts | 158 +++++++++++++ src/server/responses-custom-tool-repair.ts | 81 +++---- structure/transports/byte-accounting.md | 6 + structure/transports/inventory.md | 1 + structure/transports/responses.md | 10 + tests/fixtures/test-layout-expected.json | 1 + ...ses-custom-tool-stream-consistency.test.ts | 220 ++++++++++++++++++ 9 files changed, 427 insertions(+), 205 deletions(-) create mode 100644 src/responses/progressive-freeform-input.ts create mode 100644 tests/responses/responses-custom-tool-stream-consistency.test.ts diff --git a/scripts/test-layout/layout.json b/scripts/test-layout/layout.json index c27ec99cb7c..906114492db 100644 --- a/scripts/test-layout/layout.json +++ b/scripts/test-layout/layout.json @@ -1216,6 +1216,7 @@ "responses-context-overflow.test.ts": "responses", "responses-custom-tool-guidance.test.ts": "responses", "responses-custom-tool-repair.test.ts": "responses", + "responses-custom-tool-stream-consistency.test.ts": "responses", "responses-fetch-helpers-boundary.test.ts": "responses", "responses-hosted-tool-declaration.test.ts": "responses", "responses-field-backfill.test.ts": "responses", diff --git a/src/bridge/sse.ts b/src/bridge/sse.ts index 66d15f58fce..0466963eb57 100644 --- a/src/bridge/sse.ts +++ b/src/bridge/sse.ts @@ -17,11 +17,10 @@ import { } from "../lib/errors"; import { redactSecretString } from "../lib/redact"; import { - freeformFallbackKeys, mayBecomePatchEnvelope, repairFreeformToolInput, - unwrapFreeformToolInput, } from "../responses/apply-patch-envelope"; +import { progressiveFreeformInput } from "../responses/progressive-freeform-input"; import { encodeCompactionSummary } from "../responses/compaction"; import { compileCodeModeHelperInput, resolveCodeModeHelperName } from "../responses/code-mode-helper-compat"; import { isTruncatedStopReason, truncationReasonFor } from "../responses/truncated-stop-reason"; @@ -153,153 +152,6 @@ export function bridgeToResponsesSSE( ? compileCodeModeHelperInput(args, helper, codeModeHelperName ?? toolName) : repairFreeformToolInput(args, toolName, namespace); }; - // Best-effort unwrap of a PARTIAL freeform arg buffer for live input streaming - // (`response.custom_tool_call_input.delta` — codex-rs uses it for UI preview only; - // the completed custom_tool_call item stays authoritative). Compact `{"input":"...` - // buffers get their string value progressively unescaped; anything else streams raw. - const JSON_WHITESPACE = new Set([" ", "\t", "\n", "\r"]); - type WrapperOpening = - | { state: "none" } - | { state: "prefix" } - | { state: "open"; valueStart: number }; - /** - * Where the string value of `{"":"` begins, tolerating the insignificant whitespace - * `JSON.parse` accepts. - * - * The earlier form of this compared the buffer against the compact literal `{"key":"`, so a - * wrapper written with spaces or newlines matched no prefix at all, streamed as raw JSON - * deltas and then completed as the unwrapped body. That is the same delta/completion - * disagreement #5047 closed for compact wrappers, reached through a different spelling: - * `unwrapFreeformToolInput` reads the completed text with `JSON.parse`, which does not care - * how the object is laid out, so neither can the streaming side. - */ - const wrapperOpening = (args: string, key: string): WrapperOpening => { - let index = 0; - for (const token of ["{", `"${key}"`, ":", '"']) { - while (index < args.length && JSON_WHITESPACE.has(args[index]!)) index++; - if (index >= args.length) return { state: "prefix" }; - for (const expected of token) { - if (index >= args.length) return { state: "prefix" }; - if (args[index] !== expected) return { state: "none" }; - index++; - } - } - return { state: "open", valueStart: index }; - }; - /** - * Whether a body could still grow into one complete outer Markdown fence. - * - * `stripMarkdownCodeFence` removes such a fence at completion for exactly the two tools that - * own the grammar, so a fenced body's streamed bytes and its completed input disagree unless - * the stream holds. A buffer that does not open with a fence can never acquire one, so - * ordinary bodies are unaffected; a buffer that does keeps its preview suppressed for the - * whole call, because a closing fence can still be followed by more text that withdraws it. - */ - const mayBecomeFencedBody = (text: string, toolName: string): boolean => { - if (toolName !== "exec" && toolName !== "apply_patch") return false; - const head = text.trimStart(); - if (head === "") return true; - return head.startsWith("```") || "```".startsWith(head); - }; - /** The two-character escapes JSON defines, and nothing else. */ - const JSON_ESCAPES = new Map([ - ['"', '"'], ["\\", "\\"], ["/", "/"], - ["b", "\b"], ["f", "\f"], ["n", "\n"], ["r", "\r"], ["t", "\t"], - ]); - const LOW_SURROGATE_ESCAPE = /^\\u[dD][c-fC-F][0-9a-fA-F]{2}$/; - /** - * The decoded prefix of a JSON string body, stopping at the first byte it cannot resolve. - * - * Every stop is a hold rather than a guess, because `JSON.parse` decides the completed value - * and anything invented here would be retracted. Three of them are not obvious: - * - * An escape JSON does not define makes the whole wrapper unparseable no matter what arrives - * next, so completion falls back to the raw text. Returning `null` for that case stops the - * preview rather than continuing to decode a value the completed item will never carry. - * `\\b` and `\\f` are defined, and were previously decoded to the letters b and f. - * - * A lone high surrogate is not a character. Emitting one alone puts an unpaired code unit in a - * delta the client has to decode by itself, so the pair is emitted together or not at all. - */ - const decodeJsonStringPrefix = (body: string): string | null => { - let out = ""; - for (let i = 0; i < body.length; i++) { - const c = body[i]; - if (c === '"') break; // unescaped closing quote: value complete - if (c !== "\\") { out += c; continue; } - const n = body[i + 1]; - if (n === undefined) break; // escape split across chunks: wait for more - if (n === "u") { - const hex = body.slice(i + 2, i + 6); - if (hex.length < 4) break; // split across chunks: wait for more - if (!/^[0-9a-fA-F]{4}$/.test(hex)) return null; // never parses - const code = parseInt(hex, 16); - if (code >= 0xd800 && code <= 0xdbff) { - const low = body.slice(i + 6, i + 12); - if (!LOW_SURROGATE_ESCAPE.test(low)) break; - out += String.fromCharCode(code, parseInt(low.slice(2), 16)); - i += 11; - continue; - } - out += String.fromCharCode(code); - i += 5; - continue; - } - const escaped = JSON_ESCAPES.get(n); - if (escaped === undefined) return null; // never parses - out += escaped; - i += 1; - } - return out; - }; - /** - * The value to stream so far, or `null` to HOLD because nothing can be decided yet. - * - * `input` is decidable from its prefix: `unwrapFreeformToolInput` returns it whenever the - * key is present, whatever else the object carries, so its value can be unescaped - * progressively and never retracted. - * - * One case escapes that claim and is accepted rather than fixed: a duplicate `input` key. - * `JSON.parse` keeps the last one, so `{"input":"a","input":"b"}` streams a and completes with - * b. Closing it means holding every canonical wrapper until its object parses, which is the - * progressive streaming this path exists to provide. The completed item stays authoritative, - * and no model emits a duplicate key in practice. - * - * A wrapper that turns invalid AFTER streaming has committed has the same shape and the same - * answer. `{"input":"a` followed by `\\qb"}` has already published a when the undefined escape - * arrives, and completion returns the raw text because nothing parses. The preview stops - * there: no rewind, and no decoded text the completed item does not contain. Bounding the - * damage is what is available without giving up progressive streaming, and the args are - * unusable in that case whichever representation wins. - * - * A fallback key is not. It only unwraps when it is the SINGLE string field, and a second - * key can still arrive — so a value emitted early would have to be taken back. That is the - * rewind this holds instead: stream nothing until the object closes, then publish the one - * repaired body. The routed passthrough in `responses-custom-tool-repair.ts` already holds - * any object prefix for the same reason (#5047). - */ - const freeformPartialInput = (args: string, toolName: string): string | null => { - const openings = ["input", ...freeformFallbackKeys(toolName)] - .map(key => ({ key, opening: wrapperOpening(args, key) })); - const canonical = openings[0]!.opening; - if (canonical.state === "open") { - const decoded = decodeJsonStringPrefix(args.slice(canonical.valueStart)); - if (decoded === null) return null; - return mayBecomeFencedBody(decoded, toolName) ? null : decoded; - } - if (openings.some(entry => entry.opening.state === "open")) { - // Committed to a fallback wrapper. Undecidable until the object is complete. - try { - JSON.parse(args); - } catch { - return null; - } - return unwrapFreeformToolInput(args, toolName); - } - // Still an ambiguous prefix of some wrapper: which wrapper, if any, is not known yet. - if (openings.some(entry => entry.opening.state === "prefix")) return null; - return mayBecomeFencedBody(args, toolName) ? null : args; - }; // tool_search_call carries arguments as a JSON object ({query, limit}); parse the model's arg string. const parseArgsObj = (args: string): Record => { try { const o = JSON.parse(args); return o && typeof o === "object" ? o : {}; } catch { return {}; } @@ -1199,7 +1051,7 @@ export function bridgeToResponsesSSE( }); } if (currentToolCall.freeform && !currentToolCall.codeModeHelperName) { - // `freeformPartialInput` holds while the buffer is still an ambiguous prefix + // `progressiveFreeformInput` holds while the buffer is still an ambiguous prefix // of a JSON wrapper; otherwise stream only the unwrapped input suffix, never // rewinding on a mode flip. // @@ -1209,7 +1061,7 @@ export function bridgeToResponsesSSE( // is the same disagreement in the other direction. const ownsFreeformGrammar = currentToolCall.namespace === undefined || currentToolCall.namespace === "functions"; - const full = freeformPartialInput( + const full = progressiveFreeformInput( currentToolCall.args, ownsFreeformGrammar ? currentToolCall.name : "", ); diff --git a/src/responses/progressive-freeform-input.ts b/src/responses/progressive-freeform-input.ts new file mode 100644 index 00000000000..eb080598b92 --- /dev/null +++ b/src/responses/progressive-freeform-input.ts @@ -0,0 +1,158 @@ +import { freeformFallbackKeys, unwrapFreeformToolInput } from "./apply-patch-envelope"; + +const JSON_WHITESPACE = new Set([" ", "\t", "\n", "\r"]); + +type WrapperOpening = + | { state: "none" } + | { state: "prefix" } + | { state: "open"; valueStart: number }; + +/** + * Where the string value of `{"":"` begins, tolerating the insignificant whitespace + * `JSON.parse` accepts. + * + * The earlier form of this compared the buffer against the compact literal `{"key":"`, so a + * wrapper written with spaces or newlines matched no prefix at all, streamed as raw JSON + * deltas and then completed as the unwrapped body. That is the same delta/completion + * disagreement #5047 closed for compact wrappers, reached through a different spelling: + * `unwrapFreeformToolInput` reads the completed text with `JSON.parse`, which does not care + * how the object is laid out, so neither can the streaming side. + */ +function wrapperOpening(args: string, key: string): WrapperOpening { + let index = 0; + for (const token of ["{", `"${key}"`, ":", '"']) { + while (index < args.length && JSON_WHITESPACE.has(args[index]!)) index++; + if (index >= args.length) return { state: "prefix" }; + for (const expected of token) { + if (index >= args.length) return { state: "prefix" }; + if (args[index] !== expected) return { state: "none" }; + index++; + } + } + return { state: "open", valueStart: index }; +} + +/** + * Whether a body could still grow into one complete outer Markdown fence. + * + * `stripMarkdownCodeFence` removes such a fence at completion for exactly the two tools that + * own the grammar, so a fenced body's streamed bytes and its completed input disagree unless + * the stream holds. A buffer that does not open with a fence can never acquire one, so + * ordinary bodies are unaffected; a buffer that does keeps its preview suppressed for the + * whole call, because a closing fence can still be followed by more text that withdraws it. + */ +function mayBecomeFencedBody(text: string, toolName: string): boolean { + if (toolName !== "exec" && toolName !== "apply_patch") return false; + const head = text.trimStart(); + if (head === "") return true; + return head.startsWith("```") || "```".startsWith(head); +} + +/** The two-character escapes JSON defines, and nothing else. */ +const JSON_ESCAPES = new Map([ + ['"', '"'], ["\\", "\\"], ["/", "/"], + ["b", "\b"], ["f", "\f"], ["n", "\n"], ["r", "\r"], ["t", "\t"], +]); +const LOW_SURROGATE_ESCAPE = /^\\u[dD][c-fC-F][0-9a-fA-F]{2}$/; + +/** + * The decoded prefix of a JSON string body, stopping at the first byte it cannot resolve. + * + * Every stop is a hold rather than a guess, because `JSON.parse` decides the completed value + * and anything invented here would be retracted. Three of them are not obvious: + * + * An escape JSON does not define makes the whole wrapper unparseable no matter what arrives + * next, so completion falls back to the raw text. Returning `null` for that case stops the + * preview rather than continuing to decode a value the completed item will never carry. + * `\\b` and `\\f` are defined, and were previously decoded to the letters b and f. + * + * A lone high surrogate is not a character. Emitting one alone puts an unpaired code unit in a + * delta the client has to decode by itself, so the pair is emitted together or not at all. + */ +function decodeJsonStringPrefix(body: string): string | null { + let out = ""; + for (let i = 0; i < body.length; i++) { + const c = body[i]; + if (c === '"') break; // unescaped closing quote: value complete + if (c !== "\\") { + // A literal control character is not legal inside a JSON string, so `JSON.parse` will + // reject this wrapper and completion will return the raw text. Emitting the decoded value + // first is the disagreement this decoder exists to prevent, so stop instead. + if (c!.charCodeAt(0) <= 0x1f) return null; + out += c; + continue; + } + const n = body[i + 1]; + if (n === undefined) break; // escape split across chunks: wait for more + if (n === "u") { + const hex = body.slice(i + 2, i + 6); + if (hex.length < 4) break; // split across chunks: wait for more + if (!/^[0-9a-fA-F]{4}$/.test(hex)) return null; // never parses + const code = parseInt(hex, 16); + if (code >= 0xd800 && code <= 0xdbff) { + const low = body.slice(i + 6, i + 12); + if (!LOW_SURROGATE_ESCAPE.test(low)) break; + out += String.fromCharCode(code, parseInt(low.slice(2), 16)); + i += 11; + continue; + } + out += String.fromCharCode(code); + i += 5; + continue; + } + const escaped = JSON_ESCAPES.get(n); + if (escaped === undefined) return null; // never parses + out += escaped; + i += 1; + } + return out; +} + +/** + * The value to stream so far, or `null` to HOLD because nothing can be decided yet. + * + * `input` is decidable from its prefix: `unwrapFreeformToolInput` returns it whenever the + * key is present, whatever else the object carries, so its value can be unescaped + * progressively and never retracted. + * + * One case escapes that claim and is accepted rather than fixed: a duplicate `input` key. + * `JSON.parse` keeps the last one, so `{"input":"a","input":"b"}` streams a and completes with + * b. Closing it means holding every canonical wrapper until its object parses, which is the + * progressive streaming this path exists to provide. The completed item stays authoritative, + * and no model emits a duplicate key in practice. + * + * A wrapper that turns invalid AFTER streaming has committed has the same shape and the same + * answer. `{"input":"a` followed by `\\qb"}` has already published a when the undefined escape + * arrives, and completion returns the raw text because nothing parses. The preview stops + * there: no rewind, and no decoded text the completed item does not contain. Bounding the + * damage is what is available without giving up progressive streaming, and the args are + * unusable in that case whichever representation wins. + * + * A fallback key is not. It only unwraps when it is the SINGLE string field, and a second + * key can still arrive — so a value emitted early would have to be taken back. That is the + * rewind this holds instead: stream nothing until the object closes, then publish the one + * repaired body. The routed passthrough in `responses-custom-tool-repair.ts` already holds + * any object prefix for the same reason (#5047). + */ +export function progressiveFreeformInput(args: string, toolName: string): string | null { + const openings = ["input", ...freeformFallbackKeys(toolName)] + .map(key => ({ key, opening: wrapperOpening(args, key) })); + const canonical = openings[0]!.opening; + if (canonical.state === "open") { + const decoded = decodeJsonStringPrefix(args.slice(canonical.valueStart)); + if (decoded === null) return null; + return mayBecomeFencedBody(decoded, toolName) ? null : decoded; + } + if (openings.some(entry => entry.opening.state === "open")) { + // Committed to a fallback wrapper. Undecidable until the object is complete. + try { + JSON.parse(args); + } catch { + return null; + } + return unwrapFreeformToolInput(args, toolName); + } + // Still an ambiguous prefix of some wrapper: which wrapper, if any, is not known yet. + if (openings.some(entry => entry.opening.state === "prefix")) return null; + return mayBecomeFencedBody(args, toolName) ? null : args; +} diff --git a/src/server/responses-custom-tool-repair.ts b/src/server/responses-custom-tool-repair.ts index 1cb167b9f4f..3b4130ae7f9 100644 --- a/src/server/responses-custom-tool-repair.ts +++ b/src/server/responses-custom-tool-repair.ts @@ -1,6 +1,7 @@ import type { TranslatorBudget } from "../lib/translator-budget"; import { mayBecomePatchEnvelope, normalizeApplyPatchDelimiters } from "../responses/apply-patch-envelope"; import { compileCodeModeHelperInput, resolveCodeModeHelperName } from "../responses/code-mode-helper-compat"; +import { progressiveFreeformInput } from "../responses/progressive-freeform-input"; import { declaresCodeModeExec } from "../types/tools"; import { customToolItemId, @@ -15,50 +16,10 @@ import { type SseBlockRewrite, } from "./sse-payload-rewrite"; -/** Exact compact prefix used by our upstream rewriter; progressive matching also - * tolerates insignificant JSON whitespace via FREEFORM_WRAP_PREFIX_RE. */ -const FREEFORM_WRAP_PREFIX = '{"input":"'; -const FREEFORM_WRAP_PREFIX_RE = /^\s*\{\s*"input"\s*:\s*"/; - function isPlainObject(value: unknown): value is Record { return !!value && typeof value === "object" && !Array.isArray(value); } -/** - * Progressive decode of the freeform `{ "input": "…" }` wrapper. - * Returns null when the accumulated text does not (yet) match that wrapper so - * callers suppress deltas and rely on `response.custom_tool_call_input.done`. - */ -function partialCustomToolInput(argumentsText: string): string | null { - const match = FREEFORM_WRAP_PREFIX_RE.exec(argumentsText); - if (!match) return null; - const body = argumentsText.slice(match[0]!.length); - let output = ""; - for (let index = 0; index < body.length; index++) { - const char = body[index]; - if (char === '"') break; - if (char !== "\\") { - output += char; - continue; - } - const escaped = body[index + 1]; - if (escaped === undefined) break; - index += 1; - if (escaped === "n") output += "\n"; - else if (escaped === "t") output += "\t"; - else if (escaped === "r") output += "\r"; - else if (escaped === "b") output += "\b"; - else if (escaped === "f") output += "\f"; - else if (escaped === "u") { - const hex = body.slice(index + 1, index + 5); - if (hex.length !== 4 || !/^[0-9a-fA-F]{4}$/.test(hex)) break; - output += String.fromCharCode(Number.parseInt(hex, 16)); - index += 4; - } else output += escaped; - } - return output; -} - function replaceSseEventName(block: string, type: string): string { const newline = block.includes("\r\n") ? "\r\n" : "\n"; const lines = block.split(/\r?\n/); @@ -332,21 +293,33 @@ export function createRoutedCustomToolRestoreBlockRewrite( openCalls.set(upstreamItemId, open); // A helper alias will become JavaScript at completion, never raw patch/JSON. if (itemNames.get(upstreamItemId)?.aliased) return []; - // Still accumulating toward the compact wrapper, or an unrecognized shape: - // suppress progressive emission and let the done event carry input. - if (FREEFORM_WRAP_PREFIX.startsWith(open.argumentsText)) return []; - const fullInput = partialCustomToolInput(open.argumentsText); + const itemName = itemNames.get(upstreamItemId); + const ownsFreeformGrammar = itemName?.namespace === undefined + || itemName?.namespace === "functions"; + const fullInput = progressiveFreeformInput( + open.argumentsText, + ownsFreeformGrammar ? itemName?.name ?? "" : "", + ); if (fullInput === null) return []; - // Hold a buffer that could still become a complete patch envelope. The done event - // recompiles such a body into an apply_patch helper call, so streaming the envelope - // bytes first and replacing them at completion is the rewind this path forbids. - // Mirrors the same hold in `src/bridge.ts`. - if ( - declaresCodeModeExec(declaredNames) - && itemNames.get(upstreamItemId)?.namespace === undefined - && itemNames.get(upstreamItemId)?.name === "exec" - && mayBecomePatchEnvelope(fullInput) - ) return []; + // This routed path historically holds every unrecognized JSON object until done. + // The shared decoder streams ordinary raw input, so retain the stricter routed rule + // when no recognized wrapper transformed the accumulated object. + if (fullInput === open.argumentsText && open.argumentsText.trimStart().startsWith("{")) return []; + // Hold a buffer that could still become a complete patch envelope, for either of the two + // reasons completion rewrites one. Both are the same rewind this path forbids, and both + // mirror `src/bridge/sse.ts`. + // + // `exec`: the done event recompiles such a body into an apply_patch helper call. + // `apply_patch`: `normalizeApplyPatchDelimiters` rewrites a decorated + // `*** Begin Patch ***` envelope at completion, so the decorated markers would be + // published and then replaced by the normalized ones. Before the shared decoder, this + // path held every non-canonical shape and so never reached that case; now that ordinary + // raw input streams, the second reason has to be stated explicitly. + const mayCompile = declaresCodeModeExec(declaredNames) + && itemName?.namespace === undefined + && itemName?.name === "exec"; + const mayNormalize = ownsFreeformGrammar && itemName?.name === "apply_patch"; + if ((mayCompile || mayNormalize) && mayBecomePatchEnvelope(fullInput)) return []; if (!fullInput.startsWith(open.emittedInput) || fullInput.length === open.emittedInput.length) return []; const inputDelta = fullInput.slice(open.emittedInput.length); open.emittedInput = fullInput; diff --git a/structure/transports/byte-accounting.md b/structure/transports/byte-accounting.md index 97b8268e726..dc1fe383b01 100644 --- a/structure/transports/byte-accounting.md +++ b/structure/transports/byte-accounting.md @@ -64,6 +64,12 @@ maintaining a second implementation. Empty byte results across the relay and `src/server/sse-frame-buffer.ts` reuse one immutable zero-length view; non-empty frame ownership, frame limits, cancellation, terminal detection, and wire bytes are unchanged. +`src/server/responses-custom-tool-repair.ts` continues to own retained routed argument bytes and +their charge/release lifecycle while it asks the pure progressive decoder in +`src/responses/progressive-freeform-input.ts` which prefix is safe to publish. The decoder neither +charges nor releases translator budget; extracting it from `src/bridge/sse.ts` does not create a +second retention owner or change terminal, failure, incomplete, or disposal release behavior. + `src/adapters/openai-responses.ts` counts new compaction fragments, including surrogate pairs formed across deltas, while retaining snapshot/done/delta precedence and existing terminal ownership. Serialized request and buffered-response observations use byte counts without measurement arrays. diff --git a/structure/transports/inventory.md b/structure/transports/inventory.md index 3bcf76ab709..5f35e4d81c0 100644 --- a/structure/transports/inventory.md +++ b/structure/transports/inventory.md @@ -25,6 +25,7 @@ surface is listed here so a maintainer can find the owner without grepping: | Transport | Owner | Invariant worth knowing | | --- | --- | --- | | Azure OpenAI Responses | `src/adapters/azure.ts` | Deployment-shaped URLs on top of the Responses contract. | +| Responses custom-tool preview | `src/bridge/sse.ts`, `src/server/responses-custom-tool-repair.ts`, `src/responses/progressive-freeform-input.ts` | Direct adapter events and routed function restoration share one progressive wrapper decoder. Fence-shaped `exec`/`apply_patch` prefixes stay held until authoritative completion normalization, while each caller retains its own patch-envelope and byte-budget policy. | | Meta Muse Responses tool names | `src/responses/muse-tool-name-alias.ts`, `src/adapters/openai-responses.ts` | `api.meta.ai` only: function names over 64 characters or containing characters outside `[a-zA-Z0-9_-]` become collision-safe wire aliases and are restored before the client sees them. | | Google / Vertex / Antigravity | `src/adapters/google.ts`, `src/adapters/google-http.ts`, `src/adapters/google-wire-compiler.ts`, `src/adapters/google-tool-schema.ts`, `src/adapters/google-truncation.ts`, `src/adapters/google-errors.ts`, `src/adapters/google-antigravity-wire.ts`, `src/adapters/google-antigravity-replay.ts`, `src/adapters/google-wire-shape.ts` | Vertex and Antigravity install a Google-family `fetchResponse` and so own their retry policy, while AI Studio Gemini leaves it undefined and uses the default server fetch path. The Google-family wrapper reuses the shared abort/deadline helpers (`src/lib/upstream-retry.ts`), wire-body repair, and upstream error normalization. `google-wire-shape.ts` sits outside that path entirely: it only reads the compiled body, and only when provider debug is on. | | Mimo Free | `src/adapters/mimo-free.ts` | Client identity and JWT handling are transport-local; the per-install client id lives in the opencodex state root. | diff --git a/structure/transports/responses.md b/structure/transports/responses.md index 1d954bcc442..0525041379f 100644 --- a/structure/transports/responses.md +++ b/structure/transports/responses.md @@ -125,6 +125,16 @@ Function-call wrappers around freeform bodies are restored by is recoverable because the wrapper is otherwise unusable; two alternate fields are ambiguous and therefore remain untouched. Foreign freeform grammars never receive that compatibility rewrite. +Progressive preview for those wrappers is decoded by +`src/responses/progressive-freeform-input.ts` in both the adapter-event bridge and routed +function-call restoration. A prefix that can still become a complete outer fence stays held so +completion never removes bytes already published in a delta; ordinary raw input remains +progressive, fallback fields wait for a complete parse, and JSON escapes emit only complete +decoded units. Routed restoration additionally keeps its existing hold for an unrecognized JSON +object and its separate code-mode patch-envelope hold. Duplicate `input` keys and wrappers that +become invalid only after a valid prefix was emitted remain bounded exceptions: completion is +authoritative because preserving progressive canonical input leaves no rewind mechanism. + Codex-private tool fields are removed at the same boundary from one table (`CANONICAL_ONLY_TOOL_FIELDS`) rather than one bespoke pass each: `external_web_access` on either web-search variant, and `defer_loading` on any declaration, which `activateDeferredTool` clears only diff --git a/tests/fixtures/test-layout-expected.json b/tests/fixtures/test-layout-expected.json index a52a560f34d..ade9fea9a71 100644 --- a/tests/fixtures/test-layout-expected.json +++ b/tests/fixtures/test-layout-expected.json @@ -1042,6 +1042,7 @@ "responses-context-overflow.test.ts": "responses", "responses-custom-tool-guidance.test.ts": "responses", "responses-custom-tool-repair.test.ts": "responses", + "responses-custom-tool-stream-consistency.test.ts": "responses", "responses-default-namespace-emit-normalize.test.ts": "responses", "responses-fetch-helpers-boundary.test.ts": "responses", "responses-hosted-tool-declaration.test.ts": "responses", diff --git a/tests/responses/responses-custom-tool-stream-consistency.test.ts b/tests/responses/responses-custom-tool-stream-consistency.test.ts new file mode 100644 index 00000000000..c2144e57fc1 --- /dev/null +++ b/tests/responses/responses-custom-tool-stream-consistency.test.ts @@ -0,0 +1,220 @@ +import { describe, expect, test } from "bun:test"; +import { createRoutedCustomToolRestoreBlockRewrite } from "../../src/server/responses-custom-tool-repair"; + +function dataPayload(block: string): Record { + const line = block.split(/\r?\n/).find(entry => entry.startsWith("data:")); + if (!line) throw new Error("missing SSE data line"); + return JSON.parse(line.slice(5).trim()) as Record; +} + +function frame(event: string, payload: Record): string { + return `event: ${event}\ndata: ${JSON.stringify({ type: event, ...payload })}`; +} + +type StreamResult = { + preview: string; + doneInput: string; + itemInput: string; + terminalInput: string; + identity: string[]; +}; + +function restoreExecStream(argumentsText: string, fragments: readonly string[], tool = "exec"): StreamResult { + const rewrite = createRoutedCustomToolRestoreBlockRewrite(new Set([tool])); + try { + const added = rewrite(frame("response.output_item.added", { + output_index: 0, + item: { + type: "function_call", + id: `fc_${tool}`, + call_id: `call_${tool}`, + name: tool, + arguments: "", + status: "in_progress", + }, + })); + const addedItem = dataPayload(added[0]!).item as Record; + let preview = ""; + for (const delta of fragments) { + const blocks = rewrite(frame("response.function_call_arguments.delta", { + output_index: 0, + item_id: `fc_${tool}`, + delta, + })); + for (const block of blocks) { + const payload = dataPayload(block); + if (payload.type === "response.custom_tool_call_input.delta") { + preview += String(payload.delta ?? ""); + } + } + } + + const done = rewrite(frame("response.function_call_arguments.done", { + output_index: 0, + item_id: `fc_${tool}`, + arguments: argumentsText, + })); + const itemDone = rewrite(frame("response.output_item.done", { + output_index: 0, + item: { + type: "function_call", + id: `fc_${tool}`, + call_id: `call_${tool}`, + name: tool, + arguments: argumentsText, + status: "completed", + }, + })); + const terminal = rewrite(frame("response.completed", { + response: { + id: "resp_1", + status: "completed", + output: [{ + type: "function_call", + id: `fc_${tool}`, + call_id: `call_${tool}`, + name: tool, + arguments: argumentsText, + status: "completed", + }], + }, + })); + const donePayload = dataPayload(done[0]!); + const doneItem = dataPayload(itemDone[0]!).item as Record; + const terminalResponse = dataPayload(terminal[0]!).response as { output: Array> }; + const terminalItem = terminalResponse.output[0] ?? {}; + return { + preview, + doneInput: String(donePayload.input), + itemInput: String(doneItem.input), + terminalInput: String(terminalItem.input), + identity: [ + String(addedItem.id), String(donePayload.item_id), + String(doneItem.id), String(doneItem.call_id), String(doneItem.name), + String(terminalItem.id), String(terminalItem.call_id), String(terminalItem.name), + ], + }; + } finally { + rewrite.dispose?.(); + } +} + +describe("routed Responses custom-tool stream consistency", () => { + test("holds a raw decorated apply_patch envelope at every split boundary", () => { + // Completion rewrites a decorated envelope through `normalizeApplyPatchDelimiters`, so any + // decorated marker published as a delta is a byte the authoritative item does not contain. + // Raw input reaches this path only because ordinary raw bodies now stream; the older routed + // decoder held every non-canonical shape and so never exposed this case. + const argumentsText = "*** Begin Patch ***\n*** Update File: a.txt ***\n+one\n*** End Patch ***"; + for (let split = 0; split <= argumentsText.length; split++) { + const result = restoreExecStream( + argumentsText, + [argumentsText.slice(0, split), argumentsText.slice(split)], + "apply_patch", + ); + expect(result.preview, `split ${split}`).toBe(""); + expect(result.doneInput, `split ${split}`).toBe(result.itemInput); + expect(result.itemInput, `split ${split}`).toBe(result.terminalInput); + // The authoritative input is the normalized envelope, not the decorated bytes. + expect(result.doneInput, `split ${split}`).not.toBe(argumentsText); + expect(result.doneInput, `split ${split}`).toContain("*** Begin Patch"); + expect(result.doneInput, `split ${split}`).not.toContain("*** Begin Patch ***"); + } + }); + + test("publishes nothing for a wrapper carrying a literal control character", () => { + // A raw newline inside a JSON string makes the object unparseable, so completion keeps the + // whole wrapper as the input. Previewing the decoded value first would be the same + // disagreement a fenced body causes, reached through a different invalid spelling. + const argumentsText = '{"input":"one\ntwo"}'; + const result = restoreExecStream(argumentsText, [argumentsText]); + expect(result.preview).toBe(""); + expect(result.doneInput).toBe(argumentsText); + expect(result.itemInput).toBe(argumentsText); + expect(result.terminalInput).toBe(argumentsText); + }); + + test("holds a wrapped fenced exec body at every split boundary", () => { + const argumentsText = JSON.stringify({ input: "```js\ntext(1)\n```" }); + for (let split = 0; split <= argumentsText.length; split++) { + const result = restoreExecStream(argumentsText, [ + argumentsText.slice(0, split), + argumentsText.slice(split), + ]); + // Completion strips the outer fence, so publishing even one fence byte would make + // the preview impossible to reconcile with the authoritative item. + expect(result.preview, `split ${split}`).toBe(""); + expect(result.doneInput, `split ${split}`).toBe("text(1)"); + expect(result.itemInput, `split ${split}`).toBe("text(1)"); + expect(result.terminalInput, `split ${split}`).toBe("text(1)"); + expect(result.identity, `split ${split}`).toEqual([ + "ctc_exec", "ctc_exec", + "ctc_exec", "call_exec", "exec", + "ctc_exec", "call_exec", "exec", + ]); + } + }); + + test("keeps ordinary raw exec input progressive", () => { + const result = restoreExecStream("text(1)", ["te", "xt", "(1)"]); + expect(result.preview).toBe("text(1)"); + expect(result.doneInput).toBe("text(1)"); + expect(result.itemInput).toBe("text(1)"); + expect(result.terminalInput).toBe("text(1)"); + }); + + test.each([ + { + label: "single fallback key", + argumentsText: '{"code":"line\\nnext"}', + fragments: ['{"code":"line', '\\nnext"}'], + expected: "line\nnext", + }, + { + label: "whitespace around the canonical wrapper", + argumentsText: ' \n { \t "input" \r : "spaced" }', + fragments: [' \n { \t "in', 'put" \r : "spa', 'ced" }'], + expected: "spaced", + }, + { + label: "JSON escapes", + argumentsText: '{"input":"quote: \\\" slash: \\\\ tab: \\t"}', + fragments: ['{"input":"quote: \\', '\" slash: \\\\ tab: \\', 't"}'], + expected: 'quote: " slash: \\ tab: \t', + }, + { + label: "split surrogate pair", + argumentsText: '{"input":"before \\uD83D\\uDE00 after"}', + fragments: ['{"input":"before \\uD83D', '\\uDE00 after"}'], + expected: "before 😀 after", + }, + ])("keeps $label preview aligned with completion", ({ argumentsText, fragments, expected }) => { + const result = restoreExecStream(argumentsText, fragments); + expect(result.preview).toBe(expected); + expect(result.doneInput).toBe(expected); + expect(result.itemInput).toBe(expected); + expect(result.terminalInput).toBe(expected); + }); + + test("documents the duplicate input-key preview limit", () => { + const argumentsText = '{"input":"first","input":"second"}'; + const result = restoreExecStream(argumentsText, ['{"input":"first', '","input":"second"}']); + // JSON.parse chooses the last duplicate key after the first value was already streamed. + // Avoiding this mismatch would require buffering every valid canonical wrapper. + expect(result.preview).toBe("first"); + expect(result.doneInput).toBe("second"); + expect(result.itemInput).toBe("second"); + expect(result.terminalInput).toBe("second"); + }); + + test("documents the late-invalid-wrapper preview limit", () => { + const argumentsText = '{"input":"safe\\q"}'; + const result = restoreExecStream(argumentsText, ['{"input":"safe', '\\q"}']); + // Once a valid prefix is published there is no rewind. The undefined escape stops + // further preview, while completion preserves the raw unparseable argument text. + expect(result.preview).toBe("safe"); + expect(result.doneInput).toBe(argumentsText); + expect(result.itemInput).toBe(argumentsText); + expect(result.terminalInput).toBe(argumentsText); + }); +}); From acd43bf442c62b115cb2d1f24da9a3f6239d7826 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 19:06:09 +0900 Subject: [PATCH 25/97] fix(responses): refuse a continuation whose task scope does not match (#5130) * fix(responses): refuse a continuation whose task scope does not match A task-scope mismatch correctly refused to replay another task's state, then stripped previous_response_id and continued with whatever input the request carried. When that input was only a delta, the proxy silently turned a continuation into a fresh conversation and the model answered without the history the client believed it had. Missing or corrupt state already asks the client to replay in full; a mismatch now does the same. The refusal is the existing generic previous_response_not_found response, byte for byte, emitted before any upstream send. It is returned even when the input looks complete, because this process cannot prove that it is; a caller that really has the whole conversation retries without previous_response_id and succeeds. The response reveals neither the stored scope nor whether foreign state exists, and the internal reason stays internal. Same-scope continuation is unchanged, and two absent scopes remain the legacy unscoped cohort that still replays together. This is a deliberate change to the historical fresh-start behavior, recorded in the transport contract and in the client-facing guides. * fix(responses): answer a scope mismatch exactly as an unusable id is answered The refusal was correct but distinguishable. A continuation this process has never seen records no replay failure and reaches the route-dependent refusals, while a mismatch answered earlier with a different message. That difference is itself the disclosure the issue asks to avoid: a caller could tell "state exists and belongs to another task" from "no state at all". A mismatch now falls through to those same route-dependent refusals, so both answers are byte-identical on any given route, and a destination that genuinely owns the continuation chain keeps behaving as it does today for an unknown id rather than being rejected for lacking local state. The regressions compare the two envelopes on the same route and assert neither reaches the model. * test(responses): cover the WebSocket path for a task-scope mismatch The existing WebSocket coverage exercises expired and missing replay state. A scope mismatch is the third way local replay becomes unusable, and the client has to see the same frame or Codex terminates the task instead of reconnecting with its full input. The case stores state under one task, reconnects as another, asserts the generic refusal frame with no upstream request, and then replays complete input without the id and succeeds. * fix(responses): refuse a resolved foreign continuation before native forwarding Letting a scope mismatch fall through to the route-dependent handling was wrong. An id this process cannot resolve is the destination's business, and a destination that owns the continuation chain is entitled to receive it. An id this process CAN resolve, to another task's retained state, is not the same thing: forwarding it continues that task's conversation for a different caller. The refusal now happens before that exception, on both the ordinary and combo paths, and uses the one generic local-unavailable envelope. The paired regression asserts a resolved foreign id is refused with no upstream request while an unknown id on the identical native route is still forwarded. * fix(responses): answer every local replay failure with one envelope A resolved foreign continuation is still refused unconditionally, before any route-dependent handling, so another task's conversation is never forwarded. What changed is the two remaining local-unavailable answers: the canonical forward and routed-continuation refusals carried their own message text, so which local failure had occurred was readable from the response even though all three mean the same thing to a client. They now use the message the early failures already use. Genuine upstream-owned continuation is untouched: an id with no local state at all still reaches a destination that owns the chain. The added case compares missing and mismatched state on one route and asserts identical status, type, code and message. * test(responses): produce all three local replay failures for the equality check The equality case compared a mismatch against expired state and inferred the corrupt answer from the source string. It now produces each condition for real on one route - a spill deleted, a spill overwritten with bytes that do not parse, and an entry retained under a different task - and asserts byte-identical responses with no upstream request. * test(responses): follow the unified local replay failure message Unifying the local-unavailable answers changed the canonical-forward text this assertion matched on. It now matches the single message every local replay failure uses. * test(responses): state the local replay envelope once A second assertion matched the retired canonical-forward text through /continuation state.*expired/i, which is why unifying the message turned shard four red as well. The expected envelope now lives in one constant that every local-replay assertion in this file uses, so a future change to that contract fails one place rather than several written from memory. Status, error code, upstream-send counts and retention assertions are all unchanged; nothing was relaxed to a truthy check. --- .../content/docs/guides/codex-integration.md | 6 + .../docs/ko/guides/codex-integration.md | 6 + src/responses/state.ts | 17 +- src/server/responses/core-combo.ts | 12 +- src/server/responses/request-prepare.ts | 14 +- structure/transports/responses.md | 7 +- .../issue-702-expired-replay-state.test.ts | 239 +++++++++++++++++- tests/responses/responses-state.test.ts | 23 +- ...plaintext-v2-agent-messages-server.test.ts | 3 +- .../server/server-combo-failover-e2e.test.ts | 29 ++- 10 files changed, 297 insertions(+), 59 deletions(-) diff --git a/docs-site/src/content/docs/guides/codex-integration.md b/docs-site/src/content/docs/guides/codex-integration.md index 1039979e57f..66e28cb9ab2 100644 --- a/docs-site/src/content/docs/guides/codex-integration.md +++ b/docs-site/src/content/docs/guides/codex-integration.md @@ -370,6 +370,12 @@ disk, and entry ceilings; this does not recover history the client no longer has must handle the error explicitly and resend their full context without `previous_response_id`. Retrying only the same ID cannot recover missing state. +The same refusal applies when the referenced state belongs to a different client task scope, +including when the new request appears to carry complete input. The proxy cannot prove that input +is complete, so it does not silently remove `previous_response_id` or reveal whether matching state +exists. Retry with the complete conversation and omit `previous_response_id`; matching scopes and +legacy continuations where both scopes are absent or blank continue to replay normally. + The same recovery signal applies to every routed destination, because only the native Responses passthrough can answer a turn whose history this proxy lost — it forwards `previous_response_id` to a backend that stored the chain. Every other wire rebuilds the conversation from each request's diff --git a/docs-site/src/content/docs/ko/guides/codex-integration.md b/docs-site/src/content/docs/ko/guides/codex-integration.md index f1de9ec20ac..fa172286f18 100644 --- a/docs-site/src/content/docs/ko/guides/codex-integration.md +++ b/docs-site/src/content/docs/ko/guides/codex-integration.md @@ -211,6 +211,12 @@ upstream 요청 전에 `previous_response_not_found`를 반환합니다. Codex W HTTP 클라이언트는 이 오류를 직접 처리하고 `previous_response_id` 없이 전체 컨텍스트를 다시 보내야 합니다. 같은 ID만 재시도해서는 누락된 상태를 복구할 수 없습니다. +참조한 상태의 client task scope가 현재 요청과 다를 때도 같은 거부 응답을 반환합니다. 새 요청이 +전체 입력처럼 보여도 프록시는 그것이 완전한 대화인지 증명할 수 없으므로 +`previous_response_id`를 조용히 제거하거나 일치하는 상태의 존재 여부를 노출하지 않습니다. +전체 대화를 담고 `previous_response_id`를 뺀 요청으로 명시적으로 다시 시도하세요. 정규화된 +scope가 같거나 양쪽 scope가 모두 없거나 비어 있는 기존 unscoped continuation은 계속 replay합니다. + routed 목적지에는 모두 같은 복구 신호가 적용됩니다. 프록시가 잃어버린 기록을 대신 볼 수 있는 것은 네이티브 Responses 패스스루뿐입니다. 체인을 저장해 둔 백엔드로 `previous_response_id`를 그대로 넘기기 때문입니다. 나머지 wire는 매 턴 요청에 담긴 입력만으로 대화를 다시 구성하므로, diff --git a/src/responses/state.ts b/src/responses/state.ts index 35237de6db7..1037f0d28f0 100644 --- a/src/responses/state.ts +++ b/src/responses/state.ts @@ -135,11 +135,10 @@ export type ResidentInput = Omit; export type PreviousResponseReplayFailure = { code: "previous_response_not_found"; - reason: "spill_missing" | "spill_corrupt" | "spill_failed" | "spill_too_large"; + reason: "spill_missing" | "spill_corrupt" | "spill_failed" | "spill_too_large" | "scope_mismatch"; }; const states = new Map(); -const replayScopeMismatches = new WeakSet(); let storedResponseBytes = 0; let residentResponseBytes = 0; let oldestResidentId: string | undefined; @@ -1044,11 +1043,6 @@ function normalizedClientThreadId(value: unknown): string | undefined { return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined; } -function withoutPreviousResponseId(request: Record): Record { - const { previous_response_id: _previousResponseId, ...freshRequest } = request; - return freshRequest; -} - export function expandPreviousResponseInput(body: unknown, clientThreadId?: string): unknown { if (!body || typeof body !== "object" || Array.isArray(body)) return body; const request = body as Record; @@ -1068,10 +1062,9 @@ export function expandPreviousResponseInput(body: unknown, clientThreadId?: stri // A Codex task must never inherit another task's continuation, nor a legacy unscoped entry. // Unscoped callers retain backward-compatible replay only with other unscoped entries. if (requestThreadId !== storedThreadId) { - const freshRequest = withoutPreviousResponseId(request); - replayScopeMismatches.add(freshRequest); + replayFailures.set(request, { code: "previous_response_not_found", reason: "scope_mismatch" }); replayScopeMismatchDrops += 1; - return freshRequest; + return body; } // The client already replayed this history verbatim. Prepending the stored copy would // double it, and the doubled turn is stored again, so the next turn triples (#1412 saw @@ -1136,9 +1129,9 @@ export function copyPreviousResponseReplayProvenance(source: unknown, target: un replayedInputPrefixLengths.set(target, prefixLength); } -/** True when a stale or foreign previous_response_id was removed from this exact request body. */ +/** True when this exact request could not replay because its task scope did not match. */ export function previousResponseScopeMismatch(body: unknown): boolean { - return !!body && typeof body === "object" && replayScopeMismatches.has(body as object); + return previousResponseReplayFailure(body)?.reason === "scope_mismatch"; } export function previousResponseConversationId(responseId: string | undefined): string | undefined { diff --git a/src/server/responses/core-combo.ts b/src/server/responses/core-combo.ts index 8cb50db8210..81b74274991 100644 --- a/src/server/responses/core-combo.ts +++ b/src/server/responses/core-combo.ts @@ -29,7 +29,6 @@ import { import { formatErrorResponse } from "../../bridge"; import { expandPreviousResponseInput, - previousResponseScopeMismatch, previousResponseReplayFailure, previousResponseProviderState, } from "../../responses/state"; @@ -201,11 +200,12 @@ export async function executeComboResponses( // imageInput is disabled (and so targets see the full replayed input). const inboundClientThreadId = req.headers.get("x-codex-parent-thread-id")?.trim() || undefined; const body = expandPreviousResponseInput(rawBody, inboundClientThreadId); - const scopeMismatch = previousResponseScopeMismatch(body); - if (scopeMismatch) { - console.warn("[opencodex] dropped a previous_response_id with a mismatched client task scope; continuing fresh"); + const replayFailure = previousResponseReplayFailure(body); + if (replayFailure?.reason === "scope_mismatch") { + console.warn("[opencodex] refusing continuation because the client task scope does not match replay state"); } - if (previousResponseReplayFailure(body)) { + // Local replay failures require full client replay. + if (replayFailure) { return formatErrorResponse( 400, "previous_response_not_found", @@ -235,7 +235,7 @@ export async function executeComboResponses( sourceBody: body, previousResponseInputExpanded: body !== rawBody && typeof (body as { previous_response_id?: unknown }).previous_response_id === "string", - providerContinuation: !scopeMismatch && body !== rawBody && requestedPreviousId + providerContinuation: body !== rawBody && requestedPreviousId ? previousResponseProviderState(requestedPreviousId) : undefined, recoveredPlaintext: false, diff --git a/src/server/responses/request-prepare.ts b/src/server/responses/request-prepare.ts index 08f001ac078..bee8357350d 100644 --- a/src/server/responses/request-prepare.ts +++ b/src/server/responses/request-prepare.ts @@ -41,7 +41,6 @@ import { import { copyPreviousResponseReplayProvenance, expandPreviousResponseInput, - previousResponseScopeMismatch, previousResponseReplayFailure, markBodyNonPersistable, previousResponseProviderState, @@ -243,10 +242,13 @@ export async function prepareResponsesRequest( copyPreviousResponseReplayProvenance(options.comboReplaySnapshot.sourceBody, body); } else { body = expandPreviousResponseInput(body, inboundClientThreadId); - if (previousResponseScopeMismatch(body)) { - console.warn("[opencodex] dropped a previous_response_id with a mismatched client task scope; continuing fresh"); + const replayFailure = previousResponseReplayFailure(body); + if (replayFailure?.reason === "scope_mismatch") { + // Bounded and content-free: no task scope and nothing about the retained entry. + console.warn("[opencodex] refusing continuation because the client task scope does not match replay state"); } - if (previousResponseReplayFailure(body)) { + // Local replay failures require full client replay. + if (replayFailure) { return formatErrorResponse( 400, "previous_response_not_found", @@ -925,7 +927,7 @@ export async function prepareResponsesRequest( return formatErrorResponse( 400, "previous_response_not_found", - "OpenAI forward continuation state is unavailable or expired; resend the full conversation without previous_response_id.", + "Continuation state is unavailable or corrupt; resend the full conversation without previous_response_id.", ); } @@ -951,7 +953,7 @@ export async function prepareResponsesRequest( return formatErrorResponse( 400, "previous_response_not_found", - "Routed continuation requires unavailable local history; resend the full conversation without previous_response_id.", + "Continuation state is unavailable or corrupt; resend the full conversation without previous_response_id.", ); } } diff --git a/structure/transports/responses.md b/structure/transports/responses.md index 0525041379f..a449d3d149b 100644 --- a/structure/transports/responses.md +++ b/structure/transports/responses.md @@ -490,7 +490,12 @@ receive `previous_response_not_found` before upstream dispatch and must resend c without `previous_response_id`. That refusal is not specific to the stateless flag: it covers every destination that cannot see the prefix this process failed to restore, which is every destination except the native Responses passthrough. The passthrough forwards the id and keeps its -upstream-owned state. `PROVIDER_OWNED_CONTINUATION_WIRES` in +upstream-owned state. A task-scope mismatch uses the same generic refusal even when the supplied +input appears complete, because the proxy cannot prove that it contains the full conversation. +The internal mismatch reason, stored scope and state contents never enter the client response; +the caller retries explicitly with complete history and no `previous_response_id`. Matching +normalized scopes replay, and two absent or blank scopes remain the legacy unscoped cohort. +`PROVIDER_OWNED_CONTINUATION_WIRES` in `src/responses/continuation-ownership.ts` is deliberately empty and records why the three candidates do not qualify: devin re-sends the whole conversation each turn, cursor reads its `checkpointRef` out of the same expired store and otherwise falls back to `full-replay`, and kiro diff --git a/tests/codex-integration/issue-702-expired-replay-state.test.ts b/tests/codex-integration/issue-702-expired-replay-state.test.ts index afc233754d0..59657cfd870 100644 --- a/tests/codex-integration/issue-702-expired-replay-state.test.ts +++ b/tests/codex-integration/issue-702-expired-replay-state.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, test } from "bun:test"; -import { mkdtempSync, readdirSync, unlinkSync } from "node:fs"; +import { mkdtempSync, readdirSync, unlinkSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { saveConfig } from "../../src/config"; @@ -53,6 +53,19 @@ interface ForwardScenario { type ForwardScenarioMode = "expired" | "fresh" | "ordinary"; +/** + * The one answer every local replay failure gives a client. + * + * Missing, corrupt and task-scope-mismatched state all mean "replay in full", so they share a + * response rather than each describing which one happened. Stated once here so a drift shows up + * as one failing constant instead of several assertions written from memory. + */ +const LOCAL_REPLAY_UNAVAILABLE = { + message: "Continuation state is unavailable or corrupt; resend the full conversation without previous_response_id.", + type: "invalid_request_error", + code: "previous_response_not_found", +} as const; + function forwardConfig(): OcxConfig { return { port: 0, @@ -649,13 +662,7 @@ describe("Issue #702 expired forward replay state", () => { }), }); expect(response.status).toBe(400); - expect(await response.json()).toEqual({ - error: { - message: "Continuation state is unavailable or corrupt; resend the full conversation without previous_response_id.", - type: "invalid_request_error", - code: "previous_response_not_found", - }, - }); + expect(await response.json()).toEqual({ error: LOCAL_REPLAY_UNAVAILABLE }); } finally { await server.stop(true); } @@ -685,11 +692,7 @@ describe("Issue #702 expired forward replay state", () => { expect(scenario.upstreamRequests).toHaveLength(1); expect(scenario.secondStatus).toBe(400); expect(JSON.parse(scenario.secondResponseText)).toMatchObject({ - error: { - message: expect.stringMatching(/continuation state.*expired/i), - type: "invalid_request_error", - code: "previous_response_not_found", - }, + error: LOCAL_REPLAY_UNAVAILABLE, }); }); @@ -786,6 +789,145 @@ describe("Issue #702 expired forward replay state", () => { expect(serialized).toContain(CURRENT_USER_SENTINEL); }); + test("a task-scope mismatch refuses the delta before ordinary HTTP upstream I/O", async () => { + const scenario = await runForwardScenario("fresh", { "x-codex-parent-thread-id": "other-task" }); + + expect(scenario.firstStatus).toBe(200); + expect(scenario.secondStatus).toBe(400); + expect(JSON.parse(scenario.secondResponseText)).toEqual({ error: LOCAL_REPLAY_UNAVAILABLE }); + expect(scenario.upstreamRequests).toHaveLength(1); + }); + + test("missing, corrupt and mismatched local state answer identically on one route", async () => { + // All three mean the same thing to a client: replay in full. Each is produced for real here + // rather than inferred from the source strings - one spill deleted, one overwritten with + // bytes that do not parse, and one entry retained under a different task. + setResponseStateByteCapForTests(1_024); + const stored = async (id: string, threadId?: string): Promise => { + rememberResponseState( + { model: "gpt-5.5", input: "x".repeat(8_000), store: false }, + { id, status: "completed", output: [{ role: "assistant", content: "done" }] }, + undefined, + { force: true, ...(threadId ? { clientThreadId: threadId } : {}) }, + ); + await flushPendingResponseSpillsForTests(); + const spillDir = responseSpillDirectory(testHome); + const spill = readdirSync(spillDir).find(name => name.includes(id)); + expect(spill, `spill for ${id}`).toBeDefined(); + return join(spillDir, spill!); + }; + + const missingPath = await stored("resp_local_missing"); + unlinkSync(missingPath); + const corruptPath = await stored("resp_local_corrupt"); + writeFileSync(corruptPath, "{ this is not valid json", "utf8"); + await stored("resp_local_foreign", "task-a"); + + let upstreamCalls = 0; + globalThis.fetch = (async () => { + upstreamCalls += 1; + throw new Error("upstream must not be called"); + }) as typeof fetch; + saveConfig(forwardConfig()); + const server = startServer(0); + const token = fakeChatGptJwt({ chatgpt_account_id: "acct-issue-702" }); + const ask = async (previousResponseId: string, threadId: string): Promise<{ status: number; body: string }> => { + const response = await originalFetch(new URL("/v1/responses", server.url), { + method: "POST", + headers: { + "content-type": "application/json", + authorization: `Bearer ${token}`, + "chatgpt-account-id": "acct-issue-702", + "x-codex-parent-thread-id": threadId, + }, + body: JSON.stringify({ + model: "gpt-5.5", + previous_response_id: previousResponseId, + input: [inputMessage(CURRENT_USER_SENTINEL)], + stream: true, + store: false, + }), + }); + return { status: response.status, body: await response.text() }; + }; + + try { + const missing = await ask("resp_local_missing", "task-a"); + const corrupt = await ask("resp_local_corrupt", "task-a"); + const mismatch = await ask("resp_local_foreign", "task-b"); + const expected = { error: LOCAL_REPLAY_UNAVAILABLE }; + for (const [label, outcome] of [["missing", missing], ["corrupt", corrupt], ["mismatch", mismatch]] as const) { + expect(outcome.status, label).toBe(400); + expect(JSON.parse(outcome.body), label).toEqual(expected); + } + // Byte-identical, not merely equivalent once parsed. + expect(corrupt.body).toBe(missing.body); + expect(mismatch.body).toBe(missing.body); + expect(upstreamCalls).toBe(0); + } finally { + await server.stop(true); + } + }); + + test("a WebSocket client whose task scope changed is refused and recovers by replaying in full", async () => { + // The existing WebSocket coverage exercises expired and missing state. A scope mismatch is + // the third way local replay becomes unusable, and it has to reach the client as the same + // frame so Codex reconnects with its full input instead of terminating the task. + const upstreamRequests: Record[] = []; + const upstream = Bun.serve({ + port: 0, + async fetch(request) { + upstreamRequests.push(await request.json() as Record); + return new Response(completedSse("resp_scope_ws", "replayed"), { + headers: { "content-type": "text/event-stream" }, + }); + }, + }); + let server: ReturnType | null = null; + let socket: WebSocket | null = null; + try { + rememberResponseState( + { input: [inputMessage(HISTORICAL_USER_SENTINEL)], store: false }, + { id: FIRST_RESPONSE_ID, status: "completed", output: [] }, + undefined, + { force: true, clientThreadId: "task-a" }, + ); + saveConfig({ + port: 0, hostname: "127.0.0.1", websockets: true, defaultProvider: "routed-test", + providers: { + "routed-test": { + adapter: "openai-responses", baseUrl: upstream.url.toString(), allowPrivateNetwork: true, + authMode: "key", apiKey: "synthetic-key", defaultModel: "test-model", statelessResponses: true, + }, + }, + } as OcxConfig); + server = startServer(0); + socket = await openResponseSocket(server.url, { "x-codex-parent-thread-id": "task-b" }); + const refused = await sendSocketTurn(socket, { + model: "routed-test/test-model", previous_response_id: FIRST_RESPONSE_ID, + input: [inputMessage(CURRENT_USER_SENTINEL)], store: false, + }); + expect(refused).toMatchObject({ + type: "error", status: 400, + error: { type: "invalid_request_error", code: "previous_response_not_found" }, + }); + expect(upstreamRequests).toHaveLength(0); + + const recovered = await sendSocketTurn(socket, { + model: "routed-test/test-model", + input: [inputMessage(HISTORICAL_USER_SENTINEL), inputMessage(CURRENT_USER_SENTINEL)], + store: false, + }); + expect(recovered.type).toBe("response.completed"); + expect(upstreamRequests).toHaveLength(1); + expect(upstreamRequests[0]!.previous_response_id).toBeUndefined(); + } finally { + socket?.close(); + await server?.stop(true); + await upstream.stop(true); + } + }); + test("forward mode still sends an ordinary request without previous_response_id", async () => { const scenario = await runForwardScenario("ordinary"); @@ -796,6 +938,77 @@ describe("Issue #702 expired forward replay state", () => { expect(JSON.stringify(scenario.upstreamRequests[0]!.body)).toContain(HISTORICAL_USER_SENTINEL); }); + test("a destination that owns continuations still gets an unknown id, but never a foreign one", async () => { + // An id this process cannot resolve is the destination's business, and forwarding it is the + // behavior the case below pins. An id this process CAN resolve, to another task's state, is + // not: forwarding it would continue that task's conversation for a different caller. The + // refusal therefore comes before the native exception, not after it. + const upstreamRequests: Record[] = []; + let upstream: ReturnType | null = null; + let server: ReturnType | null = null; + try { + upstream = Bun.serve({ + port: 0, + async fetch(request) { + upstreamRequests.push(await request.json() as Record); + return new Response(completedSse("resp_native_forwarded", "forwarded"), { + headers: { "content-type": "text/event-stream" }, + }); + }, + }); + saveConfig({ + port: 0, + hostname: "127.0.0.1", + defaultProvider: "test-openai", + providers: { + "test-openai": { + adapter: "openai-responses", + baseUrl: `${upstream.url.toString().replace(/\/$/, "")}/v1`, + allowPrivateNetwork: true, + apiKey: "provider-key", + defaultModel: "gpt-5.5", + statelessResponses: false, + }, + }, + } as OcxConfig); + server = startServer(0); + rememberResponseState( + { input: [inputMessage(HISTORICAL_USER_SENTINEL)], store: false }, + { id: FIRST_RESPONSE_ID, status: "completed", output: [] }, + undefined, + { force: true, clientThreadId: "task-a" }, + ); + const send = (previousResponseId: string, threadId: string) => originalFetch( + new URL("/v1/responses", server!.url), + { + method: "POST", + headers: { "content-type": "application/json", "x-codex-parent-thread-id": threadId }, + body: JSON.stringify({ + model: "test-openai/gpt-5.5", + previous_response_id: previousResponseId, + input: [inputMessage(CURRENT_USER_SENTINEL)], + stream: true, + store: false, + }), + }, + ); + + const foreign = await send(FIRST_RESPONSE_ID, "task-b"); + expect(foreign.status).toBe(400); + expect(await foreign.json()).toMatchObject({ error: { code: "previous_response_not_found" } }); + expect(upstreamRequests).toHaveLength(0); + + const unknown = await send("resp_never_seen_here", "task-b"); + expect(unknown.status).toBe(200); + await unknown.text(); + expect(upstreamRequests).toHaveLength(1); + expect(upstreamRequests[0]!.previous_response_id).toBe("resp_never_seen_here"); + } finally { + await server?.stop(true); + await upstream?.stop(true); + } + }); + test.each(["message", "function", "custom"] as const)("API-key Responses providers can still forward native %s continuation state", async kind => { const upstreamRequests: Record[] = []; const realNow = Date.now; diff --git a/tests/responses/responses-state.test.ts b/tests/responses/responses-state.test.ts index c1eaa5770cd..ec801d5109d 100644 --- a/tests/responses/responses-state.test.ts +++ b/tests/responses/responses-state.test.ts @@ -356,7 +356,7 @@ describe("Responses previous_response_id state", () => { model: "cursor/auto", previous_response_id: first.id, input: [{ type: "function_call_output", call_id: "call_1", output: "ok" }], - }) as { input: unknown[] }; + }, " ") as { input: unknown[] }; expect(expanded.input).toEqual([ { role: "user", content: "use ping" }, @@ -376,13 +376,10 @@ describe("Responses previous_response_id state", () => { model: "cursor/auto", previous_response_id: first.id, input: "continue task A", - }, "task-a") as { previous_response_id?: string; input: unknown[] }; + }, " task-a ") as { previous_response_id?: string; input: unknown[] }; expect(sameTask.previous_response_id).toBe(first.id); - expect(sameTask.input).toEqual([ - { role: "user", content: "private task A history" }, - first.output[0], - { role: "user", content: "continue task A" }, - ]); + expect(sameTask.input).toEqual([{ role: "user", content: "private task A history" }, first.output[0], + { role: "user", content: "continue task A" }]); expect(previousResponseScopeMismatch(sameTask)).toBe(false); const foreignTask = expandPreviousResponseInput({ @@ -390,10 +387,12 @@ describe("Responses previous_response_id state", () => { previous_response_id: first.id, input: "brand-new task B", }, "task-b") as { previous_response_id?: string; input: string }; - expect(foreignTask).toEqual({ model: "cursor/auto", input: "brand-new task B" }); + expect(foreignTask).toEqual({ model: "cursor/auto", previous_response_id: first.id, input: "brand-new task B" }); expect(previousResponseScopeMismatch(foreignTask)).toBe(true); - expect(previousResponseReplayPrefixLength(foreignTask)).toBe(0); - expect(responseStateMetrics().replayScopeMismatchDrops).toBe(1); + expect(previousResponseReplayFailure(foreignTask)?.reason).toBe("scope_mismatch"); + const unscopedTask = expandPreviousResponseInput({ previous_response_id: first.id, input: "unscoped" }); + expect(previousResponseReplayFailure(unscopedTask)?.reason).toBe("scope_mismatch"); + expect(responseStateMetrics().replayScopeMismatchDrops).toBe(2); }); test("scoped tasks reject legacy unscoped continuation state", () => { @@ -406,7 +405,7 @@ describe("Responses previous_response_id state", () => { previous_response_id: first.id, input: "new task", }, "task-new"); - expect(freshTask).toEqual({ input: "new task" }); + expect(freshTask).toEqual({ previous_response_id: first.id, input: "new task" }); expect(previousResponseScopeMismatch(freshTask)).toBe(true); }); @@ -1961,7 +1960,7 @@ describe("Responses previous_response_id state", () => { { previous_response_id: "resp_spill_restart", input: "foreign" }, "task-other", ); - expect(foreign).toEqual({ input: "foreign" }); + expect(foreign).toEqual({ previous_response_id: "resp_spill_restart", input: "foreign" }); }); test("spill references bind the expected response id and use the locked digest basename", () => { diff --git a/tests/server/plaintext-v2-agent-messages-server.test.ts b/tests/server/plaintext-v2-agent-messages-server.test.ts index cfbba40249c..4de9f24bfc1 100644 --- a/tests/server/plaintext-v2-agent-messages-server.test.ts +++ b/tests/server/plaintext-v2-agent-messages-server.test.ts @@ -540,7 +540,8 @@ describe("plaintext v2 agent messages at the Responses server boundary", () => { const secondBody = await second.text(); expect({ status: second.status, body: secondBody, sends: sentBodies.length }).toEqual({ status: 400, - body: expect.stringContaining("continuation state is unavailable or expired"), + // One message for every local replay failure, so which one occurred is not readable here. + body: expect.stringContaining("Continuation state is unavailable or corrupt"), sends: 1, }); }); diff --git a/tests/server/server-combo-failover-e2e.test.ts b/tests/server/server-combo-failover-e2e.test.ts index 19c344003f8..afbfc5ecacd 100644 --- a/tests/server/server-combo-failover-e2e.test.ts +++ b/tests/server/server-combo-failover-e2e.test.ts @@ -2444,23 +2444,36 @@ describe("server combo failover 030 activation matrix", () => { }); const config = comboConfig({ a: provider("openai-chat", baseUrl(a), "key-a") }); const headers = { "x-codex-parent-thread-id": "combo-task" }; - const legacyResponse = await post(config, { previous_response_id: "resp_combo_legacy_unscoped", input: "fresh scoped input", }, {}, headers); + const fullInput = [{ role: "user", content: "complete history" }, { role: "user", content: "current turn" }]; + const fullMismatch = await post(config, { + previous_response_id: "resp_combo_scoped", + input: fullInput, + }, {}, { "x-codex-parent-thread-id": "other-task" }); + const genericError = { + error: { message: "Continuation state is unavailable or corrupt; resend the full conversation without previous_response_id.", + type: "invalid_request_error", code: "previous_response_not_found" }, + }; + expect(legacyResponse.status).toBe(400); + expect(await legacyResponse.json()).toEqual(genericError); + expect(fullMismatch.status).toBe(400); + expect(await fullMismatch.json()).toEqual(genericError); + expect(bodies).toHaveLength(0); + const retried = await post(config, { input: fullInput }, {}, { "x-codex-parent-thread-id": "other-task" }); const scopedResponse = await post(config, { previous_response_id: "resp_combo_scoped", input: "continue scoped task", }, {}, headers); - - expect(legacyResponse.status).toBe(200); - expect(scopedResponse.status).toBe(200); - expect(bodies).toHaveLength(2); - expect(JSON.stringify(bodies[0])).not.toContain("legacy private history"); - expect(JSON.stringify(bodies[0])).toContain("fresh scoped input"); + const legacyUnscoped = await post(config, { previous_response_id: "resp_combo_legacy_unscoped", + input: "legacy continuation" }); + expect([retried.status, scopedResponse.status, legacyUnscoped.status]).toEqual([200, 200, 200]); + expect(bodies).toHaveLength(3); + expect(JSON.stringify(bodies[0])).toContain("complete history"); expect(JSON.stringify(bodies[1])).toContain("scoped private history"); - expect(JSON.stringify(bodies[1])).toContain("continue scoped task"); + expect(JSON.stringify(bodies[2])).toContain("legacy private history"); }); test("combo child preserves replay provenance for compaction and generated guidance", async () => { From 5ce51cb554b333c9b369baf1b15b5d04047c85b4 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 19:07:44 +0900 Subject: [PATCH 26/97] docs(structure): bind the Lab isolation invariant (#5138) * docs(structure): bind the Lab isolation invariant Add INV-LAB-01 covering both existing guarantees -- protected core entrypoints cannot reach optional Lab runtime imports, and gated Lab activation stays synchronous until startServer returns -- bind it to the existing core/Lab boundary guard, add the reverse test-side identifier, and document the contract in the Compatibility Lab structure owner. No runtime mechanism changes. Closes #5121 * docs(structure): scope INV-LAB-01 to the guard's actual coverage Review resolution: the guard walks load-time edges (static, side-effect, re-export) transitively but deliberately does not follow deferred dynamic import() specifiers; it separately forbids a protected file from naming Lab in a direct dynamic import. Restate the invariant and the Lab contract section to distinguish load-time isolation, the direct dynamic-import ban, and the sanctioned lazy /api/lab routing pattern, without broadening the runtime guard. Also record src/server/index.ts in the Compatibility Lab documents list (the activation contract lives there) and regenerate structure/INDEX.md with the canonical generator. --- structure/INDEX.md | 1 + structure/adapters/compatibility-lab.md | 18 ++++++++++++++++++ structure/manifest.json | 15 ++++++++------- structure/overview.md | 6 ++++++ tests/lab/core-lab-boundary.test.ts | 2 ++ 5 files changed, 35 insertions(+), 7 deletions(-) diff --git a/structure/INDEX.md b/structure/INDEX.md index eb711acb5c3..161cc18e132 100644 --- a/structure/INDEX.md +++ b/structure/INDEX.md @@ -124,6 +124,7 @@ for it; see [`AGENTS.md`](AGENTS.md). | `src/router.ts` | [`runtime.md`](runtime.md) | | `src/routing/` | [`catalog.md`](catalog.md) | | `src/server/` | [`runtime.md`](runtime.md)
    [`catalog.md`](catalog.md)
    [`subagents.md`](subagents.md)
    [`transports/byte-accounting.md`](transports/byte-accounting.md)
    [`transports/responses.md`](transports/responses.md)
    [`transports/streaming-health.md`](transports/streaming-health.md)
    [`transports/inventory.md`](transports/inventory.md)
    [`data-planes/images.md`](data-planes/images.md)
    [`data-planes/inbound-compat.md`](data-planes/inbound-compat.md)
    [`providers-and-adapters.md`](providers-and-adapters.md)
    [`providers/xai-grok.md`](providers/xai-grok.md)
    [`adapters/registry.md`](adapters/registry.md)
    [`gui-and-management-api.md`](gui-and-management-api.md)
    [`clients/claude-desktop.md`](clients/claude-desktop.md)
    [`ops/service-and-sidecars.md`](ops/service-and-sidecars.md) | +| `src/server/index.ts` | [`adapters/compatibility-lab.md`](adapters/compatibility-lab.md) | | `src/service.ts` | [`runtime.md`](runtime.md)
    [`ops/docs-and-release.md`](ops/docs-and-release.md) | | `src/service/` | [`runtime.md`](runtime.md) | | `src/stall-timeout.ts` | [`runtime.md`](runtime.md) | diff --git a/structure/adapters/compatibility-lab.md b/structure/adapters/compatibility-lab.md index a1633860a0e..840e00007db 100644 --- a/structure/adapters/compatibility-lab.md +++ b/structure/adapters/compatibility-lab.md @@ -1,5 +1,23 @@ # Compatibility Lab +## Core isolation and synchronous activation + +The protected core request-path files carry no load-time import chain into Lab runtime code: +the guard in `tests/lab/core-lab-boundary.test.ts` walks static imports, side-effect imports, +and re-exports transitively from the guard-owned `PROTECTED` list and prints the offending +chain on failure. A dynamic `import()` is a deferred edge the walk deliberately does not +follow, because lazy loading behind a namespace or activation check is the sanctioned remedy — +so the same guard separately forbids a protected file from naming Lab even in a direct dynamic +import. The ordinary no-Lab path therefore executes no Lab code, while the management plane can +still route `/api/lab` lazily through a non-Lab module without weakening the rule. + +`src/server/index.ts` is deliberately exempt as the composition root: Lab activation stays +behind `labActivationRequired`, and the window from `Bun.serve` through the `startServer` +return contains no suspension, so a policy route can never be evaluated before its evidence +provider is registered and the subagent fallback chain keeps the operator-configured model. +This contract is [INV-LAB-01](../overview.md#non-negotiable-invariants), bound to the same +guard test. + ## CL-03 live-route execution boundary CL-03 live-route evidence is generated only for an exact `RouteSubjectV1` and remains separate from protocol-conformance and task-effectiveness evidence. diff --git a/structure/manifest.json b/structure/manifest.json index 29efddd156e..1337f774e5c 100644 --- a/structure/manifest.json +++ b/structure/manifest.json @@ -310,13 +310,14 @@ ] }, { - "path": "adapters/compatibility-lab.md", - "tier": 4, - "title": "Compatibility Lab", - "scope": "Optional Lab evidence, automation, and its core-runtime isolation boundary.", - "documents": [ - "src/lab/" - ] + "path": "adapters/compatibility-lab.md", + "tier": 4, + "title": "Compatibility Lab", + "scope": "Optional Lab evidence, automation, and its core-runtime isolation boundary.", + "documents": [ + "src/lab/", + "src/server/index.ts" + ] }, { "path": "gui-and-management-api.md", diff --git a/structure/overview.md b/structure/overview.md index 3e2c7395683..dc28991c5ed 100644 --- a/structure/overview.md +++ b/structure/overview.md @@ -108,6 +108,12 @@ still cover the rule, which is a judgement only review makes. - **INV-AUTH-01** — The management plane (`/api/*`) and the data plane (`/v1/*`) never share an admission credential. Enforced by `tests/server/server-management-auth.test.ts`. +- **INV-LAB-01** — The protected core entrypoints carry no load-time import chain into optional + Lab code (static, side-effect, and re-export edges are walked transitively) and never name + Lab even in a direct dynamic import; deferred lazy edges through non-Lab modules behind + activation checks are the sanctioned pattern. Gated Lab activation also stays synchronous + until `startServer` returns; see [`compatibility-lab.md`](adapters/compatibility-lab.md). + Enforced by `tests/lab/core-lab-boundary.test.ts`. - **INV-RESTORE-01** — `ocx restore` restores native Codex from the pristine catalog with retired bare/account-qualified native rows omitted from the output; the original backup stays unchanged. The service-stop and uninstall paths of the same promise are covered diff --git a/tests/lab/core-lab-boundary.test.ts b/tests/lab/core-lab-boundary.test.ts index 82c97190bf8..4e54e4ec5cb 100644 --- a/tests/lab/core-lab-boundary.test.ts +++ b/tests/lab/core-lab-boundary.test.ts @@ -15,6 +15,8 @@ import { repoRoot as resolveRepoRoot } from "../helpers/repo-root"; * job is to know which optional subsystems exist. It is covered by a behavioral assertion * instead (see below). * + * Invariant binding: INV-LAB-01 (structure/overview.md#non-negotiable-invariants). + * * Design and rationale: devlog/_fin/260814_lab_core_decoupling/ */ const PROTECTED = [ From f39ba5aad94fe019f2ee9c57398c9f9a436b8116 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 19:10:54 +0900 Subject: [PATCH 27/97] fix(test): raise the native passthrough reset from a requested pull (#5073) (#5128) The reset fixture in tests/server/server-auth.test.ts leaked its stream controller out of start() and errored it from the test body. Whether that rejection had a consumer depended on where Bun's server-side response sink happened to be: between its reads there is no pending read request to reject, so on a loaded runner the fixture's own error escaped as an unhandled error and failed the whole file. It fired on four unrelated heads (#4989, #5024, dev at ecd3adae75, and #5085). Raise it from inside pull() on a stream whose high-water mark is zero instead. shouldCallPull is then true only while a read request is outstanding, so pull() runs if and only if a consumer is waiting for the next chunk, and throwing there rejects that read request. The reset now has a consumer no matter when the test calls it. What the code under test sees is unchanged: one SSE chunk, then a mid-stream body error. Closes #5073 --- tests/helpers/deferred-reset-sse-upstream.ts | 73 ++++++++++++++++++++ tests/server/server-auth.test.ts | 16 ++--- 2 files changed, 77 insertions(+), 12 deletions(-) create mode 100644 tests/helpers/deferred-reset-sse-upstream.ts diff --git a/tests/helpers/deferred-reset-sse-upstream.ts b/tests/helpers/deferred-reset-sse-upstream.ts new file mode 100644 index 00000000000..00a3bfa3078 --- /dev/null +++ b/tests/helpers/deferred-reset-sse-upstream.ts @@ -0,0 +1,73 @@ +/** + * An SSE upstream body that resets mid-stream on demand, where the reset is raised somewhere + * the stream itself observes rather than somewhere nothing is listening (#5073). + * + * The direct way to write this fixture is to leak the stream's controller out of `start()` + * and call `controller.error()` from the test body. That is what + * `tests/server/server-auth.test.ts` did, and under load the fixture's own error escaped as + * an unhandled error instead of being delivered to the code under test, failing the whole + * file on four unrelated heads (#4989, #5024, `dev` at ecd3adae75, #5085). + * + * The reason is that a leaked controller can be errored at a moment of the test's choosing, + * which is not necessarily a moment when anything is reading. Between the server sink's + * reads there is no pending read request to reject, so the rejection's only subscriber is + * whatever the runtime attaches next — and on a busy runner the unhandled-rejection report + * can win that race. The test cannot see or control that window from outside the stream. + * + * So the reset is raised from inside `pull()` instead. Two properties come from that, and + * they are worth separating because only the first one is absolute: + * + * The pull algorithm's promise is always observed. `CallPullIfNeeded` attaches its own + * rejection handler and routes the failure into `ReadableStreamDefaultControllerError`, so a + * throw from `pull()` cannot be an orphaned rejection whatever the consumer is doing. That is + * the guarantee this fixture rests on. + * + * `highWaterMark: 0` then keeps the reset in a faithful place. The queue is never stocked + * ahead of demand, so `shouldCallPull` is true only while a read request is outstanding, and + * `pull()` runs if and only if a consumer has asked for the next chunk. The stream is never + * errored before anything has attached to it, which is the state where the error has nowhere + * to go. It is not a promise that a read request is still pending at the instant of the + * throw — a consumer that cancels in between removes its own request — only that the error is + * raised in response to demand and is consumed by the stream either way. + * + * The enqueued opening chunks are unaffected: `enqueue()` ignores the high-water mark, and the + * first read is still served from the queue. + * + * What the code under test sees is unchanged: one SSE chunk, then a mid-stream body error. + */ + +/** The reset every body from this helper raises, so assertions can name it. */ +export const DEFERRED_RESET_MESSAGE = "fixture upstream connection reset"; + +export type DeferredResetSseUpstream = { + /** A fresh body for one upstream attempt; a retried dispatch gets its own stream. */ + response: (init?: ResponseInit) => Response; + /** Reset every body this helper has handed out, and every later one. */ + reset: () => void; +}; + +/** + * Build an SSE upstream that emits `chunks` and then resets when `reset()` is called. + * + * `reset()` is idempotent and order-independent: calling it before the first attempt is + * dispatched arms the reset for that attempt rather than losing it. + */ +export function deferredResetSseUpstream(...chunks: string[]): DeferredResetSseUpstream { + const encoder = new TextEncoder(); + const requested = Promise.withResolvers(); + return { + reset: () => requested.resolve(), + response: (init = { headers: { "content-type": "text/event-stream" } }) => new Response( + new ReadableStream({ + start(controller) { + for (const chunk of chunks) controller.enqueue(encoder.encode(chunk)); + }, + async pull() { + await requested.promise; + throw new Error(DEFERRED_RESET_MESSAGE); + }, + }, { highWaterMark: 0 }), + init, + ), + }; +} diff --git a/tests/server/server-auth.test.ts b/tests/server/server-auth.test.ts index 1e226dd0b83..ad8d5b48bf1 100644 --- a/tests/server/server-auth.test.ts +++ b/tests/server/server-auth.test.ts @@ -52,6 +52,7 @@ import { getDebugLogEntries, resetDebugLogBufferForTests } from "../../src/lib/d import { resetDebugSettingsForTests, setDebugSettings } from "../../src/lib/debug-settings"; import { watchdogMs } from "../helpers/ci-watchdog"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { deferredResetSseUpstream } from "../helpers/deferred-reset-sse-upstream"; const previousApiToken = process.env.OPENCODEX_API_AUTH_TOKEN; const previousOpencodexHome = process.env.OPENCODEX_HOME; const originalGlobalFetch = globalThis.fetch; @@ -4245,23 +4246,14 @@ describe("server local API auth", () => { }, { timeout: SERVER_BUDGET_MS }); test("native passthrough upstream reset still logs 502 and penalizes the pool", async () => { - const enc = new TextEncoder(); - const source = Promise.withResolvers>(); - const harness = await startPoolRetryHarness(() => new Response( - new ReadableStream({ - start(controller) { - source.resolve(controller); - controller.enqueue(enc.encode('data: {"type":"response.output_text.delta","delta":"hello"}\n\n')); - }, - }), - { headers: { "content-type": "text/event-stream" } }, - ), { secondAccount: false, streamMode: "legacy-tee" }); + const upstream = deferredResetSseUpstream('data: {"type":"response.output_text.delta","delta":"hello"}\n\n'); + const harness = await startPoolRetryHarness(() => upstream.response(), { secondAccount: false, streamMode: "legacy-tee" }); try { const response = await harness.request({ stream: true }); const requestId = response.headers.get("x-opencodex-request-id"); const reader = response.body!.getReader(); expect((await reader.read()).done).toBe(false); - (await source.promise).error(new Error("fixture upstream connection reset")); + upstream.reset(); while (!(await reader.read()).done) { /* drain the synthetic failed terminal */ } const deadline = Date.now() + INTERNAL_DEADLINE_MS; while (!getRequestLogEntries().some(entry => entry.requestId === requestId) && Date.now() < deadline) { From f117c20d1244bf20d8cf5bd35de5bb7c71003799 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 19:20:22 +0900 Subject: [PATCH 28/97] docs(proxy): align SOCKS5 HTTP/SSE routing documentation (#5153) * docs(proxy): align SOCKS5 HTTP/SSE routing documentation The proxy-format, adapter, provider-configuration, and provider-guide pages claimed HTTP/SSE never uses ALL_PROXY. Configured outbound fetch actually selects the built-in SOCKS5 tunnel for an explicit SOCKS5 proxy or a SOCKS5 ALL_PROXY when NO_PROXY does not exempt the target (src/lib/proxy-env.ts). Correct the four English pages and the seven translated provider-configuration copies that carry the claim, link the server configuration reference, and record the alignment contract in the docs structure owner. Coordinated with open draft #3901, which owns provider-specific proxy fields untouched here. Closes #5119 * docs(proxy): correct NO_PROXY and fake-IP gate semantics in SOCKS5 docs Review resolution on the SOCKS5 documentation alignment: - A server SOCKS5 proxy configured with config.proxy is written to ALL_PROXY at startup (src/config/proxy-env.ts), so both configured and inherited SOCKS5 routes honor NO_PROXY; only the per-request RequestInit.proxy override skips it. Stop conflating the two. - The fake-IP accommodation gate counts a SOCKS5 ALL_PROXY because effectiveProxyFor selects it; only a non-SOCKS ALL_PROXY does not count. Corrected in all four English pages and all seven locale copies. DNS/pinning and private-address guard caveats preserved. --- .../docs/fr/reference/configuration/providers.md | 6 ++---- docs-site/src/content/docs/guides/providers.md | 7 +++++-- .../docs/ja/reference/configuration/providers.md | 4 ++-- .../docs/ko/reference/configuration/providers.md | 4 ++-- docs-site/src/content/docs/reference/adapters.md | 7 +++++-- .../docs/reference/configuration/providers.md | 16 +++++++++++----- .../src/content/docs/reference/proxy-formats.md | 15 ++++++++++----- .../docs/ru/reference/configuration/providers.md | 13 ++++++++----- .../docs/tr/reference/configuration/providers.md | 10 ++++++---- .../zh-cn/reference/configuration/providers.md | 4 ++-- .../zh-tw/reference/configuration/providers.md | 4 ++-- structure/ops/docs-and-release.md | 2 ++ 12 files changed, 57 insertions(+), 35 deletions(-) diff --git a/docs-site/src/content/docs/fr/reference/configuration/providers.md b/docs-site/src/content/docs/fr/reference/configuration/providers.md index cb6601775d7..c4efe840231 100644 --- a/docs-site/src/content/docs/fr/reference/configuration/providers.md +++ b/docs-site/src/content/docs/fr/reference/configuration/providers.md @@ -168,9 +168,7 @@ proxy sortant, opencodex résout le nom d'hôte une seule fois et se connecte ex HTTPS conserve l'hôte d'origine, le SNI et la vérification du certificat ; la configuration du fournisseur ne peut pas désactiver ces contrôles. -Lorsque `HTTP_PROXY`, `HTTPS_PROXY` ou `ALL_PROXY` s'applique, ces opérations conservent la fonction de récupération native de Bun. -Les vérifications de l'URL et de l'adresse littérale sont toujours exécutées, mais le proxy choisit la route finale, la réponse DNS et l'homologue ; -opencodex ne peut donc ni épingler ni vérifier cet homologue. Il s'agit d'une limitation de sécurité explicite. +Ces opérations utilisent le [fetch sortant configuré du serveur](/fr/reference/configuration/server/). Un proxy SOCKS5 du serveur — défini avec `config.proxy` ou hérité d'un `ALL_PROXY` SOCKS5 — utilise le tunnel intégré d'OpenCodex lorsque la cible ne correspond pas à `NO_PROXY`. `HTTP_PROXY` et `HTTPS_PROXY` conservent le traitement HTTP(S) natif de Bun, tandis qu'un `ALL_PROXY` non SOCKS n'est pas une route du fetch HTTP natif. Les vérifications de l'URL et de l'adresse littérale sont toujours exécutées, mais le proxy sélectionné choisit la route finale, la réponse DNS et l'homologue ; opencodex ne peut donc ni épingler ni vérifier cet homologue. Il s'agit d'une limitation de sécurité explicite. Les destinations privées ou locales nécessitent `allowPrivateNetwork: true` et, lorsqu'un proxy sortant est actif, une entrée `NO_PROXY` correspondante. Le bouclage est ajouté automatiquement ; indiquez explicitement chaque hôte du réseau local, car @@ -179,7 +177,7 @@ les adresses IPv6 entre crochets et `*` ; par exemple, indiquez explicitement ` restent bloquées. Les requêtes de diagnostic rejettent les redirections et signalent une cible dont les identifiants ont été retirés. L'examen des redirections des requêtes ordinaires vers les fournisseurs reste distinct de cette protection de diagnostic. -Deux accommodements fake-IP DNS existent pour les utilisateurs de Clash / Surge / Mihomo, et tous deux ne s'appliquent qu'aux *réponses* DNS — une adresse littérale dans l'URL reste rejetée. La plage de benchmark IANA `198.18.0.0/15` (et ses écritures IPv6 IPv4-mapped) est acceptée dès qu'un proxy sortant s'applique à l'hôte. La plage IPv6 fake-IP par défaut de Mihomo `fdfe:dcba:9876::/48` est acceptée sous une condition plus stricte : la variable de proxy correspondant au schéma de l'URL (`HTTPS_PROXY` pour `https:`, `HTTP_PROXY` pour `http:` ; `ALL_PROXY` ne compte pas) doit être définie, l'hôte ne doit pas correspondre à `NO_PROXY`, et la requête est alors explicitement liée à ce proxy. Tout autre ULA, un préfixe adjacent ou une réponse fake-IP mélangée à une vraie réponse privée exige toujours `allowPrivateNetwork: true`. La validation à l'enregistrement du fournisseur n'applique jamais l'accommodement IPv6. +Deux accommodements fake-IP DNS existent pour les utilisateurs de Clash / Surge / Mihomo, et tous deux ne s'appliquent qu'aux *réponses* DNS — une adresse littérale dans l'URL reste rejetée. La plage de benchmark IANA `198.18.0.0/15` (et ses écritures IPv6 IPv4-mapped) est acceptée dès qu'un proxy sortant s'applique à l'hôte. La plage IPv6 fake-IP par défaut de Mihomo `fdfe:dcba:9876::/48` est acceptée sous une condition plus stricte : la variable de proxy correspondant au schéma de l'URL (`HTTPS_PROXY` pour `https:`, `HTTP_PROXY` pour `http:`) ou un `ALL_PROXY` SOCKS5 doit être définie (un `ALL_PROXY` non SOCKS ne compte pas), l'hôte ne doit pas correspondre à `NO_PROXY`, et la requête est alors explicitement liée à ce proxy. Tout autre ULA, un préfixe adjacent ou une réponse fake-IP mélangée à une vraie réponse privée exige toujours `allowPrivateNetwork: true`. La validation à l'enregistrement du fournisseur n'applique jamais l'accommodement IPv6. ## Groupe de comptes Codex diff --git a/docs-site/src/content/docs/guides/providers.md b/docs-site/src/content/docs/guides/providers.md index 90e192a97ae..9bcf40cbf64 100644 --- a/docs-site/src/content/docs/guides/providers.md +++ b/docs-site/src/content/docs/guides/providers.md @@ -971,8 +971,11 @@ is not supported directly. Provider configuration selects the adapter; upstream transport selection is separate. Eligible Responses traffic can use WSS with [explicit proxy routing](/reference/proxy-formats/#json-and-sse-output). -Invalid or unsupported WebSocket proxy settings fall back to HTTP/SSE, which uses Bun's HTTP -proxy rules rather than the WSS-specific `ALL_PROXY` fallback. +Invalid or unsupported WebSocket proxy settings fall back to HTTP/SSE, which uses the +[server's configured outbound fetch](/reference/configuration/server/). A server SOCKS5 proxy from +`config.proxy` or an inherited SOCKS5 `ALL_PROXY` uses the built-in tunnel when `NO_PROXY` does +not exempt the target. Scheme-specific HTTP(S) proxy variables retain their separate native handling; non-SOCKS +`ALL_PROXY` is not a native HTTP fetch route. **GitHub Copilot** is an OAuth provider (`ocx login github-copilot`) that exchanges a GitHub device-flow login for a short-lived Copilot API token — not a pasted API key. **GitLab Duo** remains diff --git a/docs-site/src/content/docs/ja/reference/configuration/providers.md b/docs-site/src/content/docs/ja/reference/configuration/providers.md index 844dca71278..a80f27ff51d 100644 --- a/docs-site/src/content/docs/ja/reference/configuration/providers.md +++ b/docs-site/src/content/docs/ja/reference/configuration/providers.md @@ -155,11 +155,11 @@ API キープロバイダーは、リテラルキーまたは環境参照を保 ダッシュボード接続テストとライブ モデル検出では、制限された GET 専用トランスポートが使用されます。送信プロキシを使用しない場合、opencodex はホスト名を一度解決し、その検証されたアドレスにのみ接続します。 HTTPS は元のホスト、SNI、および証明書の検証を保持します。プロバイダー設定では証明書チェックを無効にすることはできません。 -`HTTP_PROXY`、`HTTPS_PROXY`、または `ALL_PROXY` が適用される場合、これらの操作は Bun のネイティブ フェッチを維持します。 URL とリテラル アドレスのチェックは引き続き実行されますが、プロキシが最終ルート、DNS 応答、ピアを選択するため、opencodex はそのピアを固定したり検証したりできません。これは明示的なセキュリティ制限です。 +これらの操作は[サーバーで設定された送信 fetch](/ja/reference/configuration/server/)を使用します。`config.proxy` で設定された、または SOCKS5 `ALL_PROXY` から継承したサーバーの SOCKS5 プロキシは、宛先が `NO_PROXY` に一致しない場合に OpenCodex の組み込みトンネルを使用します。`HTTP_PROXY` と `HTTPS_PROXY` は Bun のネイティブ HTTP(S) 処理を維持しますが、SOCKS 以外の `ALL_PROXY` はネイティブ HTTP fetch の経路にはなりません。URL とリテラル アドレスのチェックは引き続き実行されますが、選択されたプロキシが最終ルート、DNS 応答、ピアを決めるため、opencodex はそのピアを固定したり検証したりできません。これは明示的なセキュリティ制限です。 プライベート/ローカル宛先には `allowPrivateNetwork: true` が必要で、送信プロキシがアクティブな場合は、一致する `NO_PROXY` エントリが必要です。ループバックは自動的に追加されます。 CIDR エントリは解釈されないため、各 LAN ホストを明示的にリストします。マッチャーは、正確なホスト、ドメイン サフィックス、オプションのポート、括弧で囲まれた IPv6、および `*` をサポートします。たとえば、`192.168.1.50` を明示的にリストします。メタデータとリンクローカル宛先はブロックされたままになります。診断リクエストはリダイレクトを拒否し、資格情報が剥奪されたターゲットを報告します。通常のプロバイダー要求のリダイレクト レビューは、この診断ガードとは独立したままになります。 -Clash / Surge / Mihomo 利用者向けの fake-IP DNS 例外は 2 種類あり、いずれも DNS の*応答*にのみ適用されます。URL に書かれたリテラルアドレスは引き続き拒否されます。IANA ベンチマーク範囲 `198.18.0.0/15`(IPv4-mapped IPv6 表記を含む)は、そのホストにアウトバウンドプロキシが適用される場合に許可されます。Mihomo の既定 IPv6 fake-IP 範囲 `fdfe:dcba:9876::/48` はより厳しい条件でのみ許可されます。URL スキームに一致するプロキシ変数(`https:` は `HTTPS_PROXY`、`http:` は `HTTP_PROXY`、`ALL_PROXY` は対象外)が設定されていること、ホストが `NO_PROXY` に一致しないことが必要で、その場合リクエストはそのプロキシに明示的に固定されます。それ以外の ULA、隣接プレフィックス、実際のプライベート応答と混在した fake-IP 応答には引き続き `allowPrivateNetwork: true` が必要です。プロバイダー保存時の検証には IPv6 例外は適用されません。 +Clash / Surge / Mihomo 利用者向けの fake-IP DNS 例外は 2 種類あり、いずれも DNS の*応答*にのみ適用されます。URL に書かれたリテラルアドレスは引き続き拒否されます。IANA ベンチマーク範囲 `198.18.0.0/15`(IPv4-mapped IPv6 表記を含む)は、そのホストにアウトバウンドプロキシが適用される場合に許可されます。Mihomo の既定 IPv6 fake-IP 範囲 `fdfe:dcba:9876::/48` はより厳しい条件でのみ許可されます。URL スキームに一致するプロキシ変数(`https:` は `HTTPS_PROXY`、`http:` は `HTTP_PROXY`)または SOCKS5 の `ALL_PROXY` が設定されていること(SOCKS 以外の `ALL_PROXY` は対象外)、ホストが `NO_PROXY` に一致しないことが必要で、その場合リクエストはそのプロキシに明示的に固定されます。それ以外の ULA、隣接プレフィックス、実際のプライベート応答と混在した fake-IP 応答には引き続き `allowPrivateNetwork: true` が必要です。プロバイダー保存時の検証には IPv6 例外は適用されません。 ## Codexアカウントプール diff --git a/docs-site/src/content/docs/ko/reference/configuration/providers.md b/docs-site/src/content/docs/ko/reference/configuration/providers.md index 61cd0de052b..505c56b5557 100644 --- a/docs-site/src/content/docs/ko/reference/configuration/providers.md +++ b/docs-site/src/content/docs/ko/reference/configuration/providers.md @@ -155,11 +155,11 @@ API 키 공급자는 리터럴 키나 환경 참조를 둘 수 있습니다. OAu 대시보드 연결 테스트와 라이브 모델 발견은 범위가 제한된 GET 전용 전송을 사용합니다. 아웃바운드 프록시가 없으면 opencodex는 호스트 이름을 한 번만 확인하고, 검증된 주소로만 연결합니다. HTTPS는 원래 Host, SNI, 인증서 검증을 유지하며, 공급자 설정으로 인증서 검사를 끌 수는 없습니다. -`HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`가 적용되면 이 작업들은 Bun의 네이티브 fetch를 그대로 사용합니다. URL과 리터럴 주소 검사는 계속 실행되지만, 최종 경로, DNS 응답, 피어는 프록시가 고르므로 opencodex는 그 피어를 고정하거나 검증할 수 없습니다. 이는 명시적인 보안 한계입니다. +이 작업들은 [서버에 설정된 아웃바운드 fetch](/ko/reference/configuration/server/)를 사용합니다. `config.proxy`로 설정했거나 SOCKS5 `ALL_PROXY`에서 상속된 서버 SOCKS5 프록시는 대상이 `NO_PROXY`에 걸리지 않을 때 OpenCodex의 내장 터널을 사용합니다. `HTTP_PROXY`와 `HTTPS_PROXY`는 Bun의 네이티브 HTTP(S) 처리를 그대로 사용하지만, SOCKS가 아닌 `ALL_PROXY`는 네이티브 HTTP fetch 경로가 아닙니다. URL과 리터럴 주소 검사는 계속 실행되지만, 선택된 프록시가 최종 경로, DNS 응답, 피어를 고르므로 opencodex는 그 피어를 고정하거나 검증할 수 없습니다. 이는 명시적인 보안 한계입니다. 사설/로컬 목적지는 `allowPrivateNetwork: true`가 필요하며, 아웃바운드 프록시가 활성화된 경우에는 일치하는 `NO_PROXY` 항목도 필요합니다. loopback은 자동으로 추가됩니다. CIDR 항목은 해석하지 않으므로 각 LAN 호스트는 따로 적어야 합니다. matcher는 정확한 호스트, 도메인 접미사, 선택적 포트, 괄호로 감싼 IPv6, `*`를 지원합니다. 예를 들면 `192.168.1.50`은 따로 적어야 합니다. 메타데이터와 link-local 목적지는 계속 차단됩니다. 진단 요청은 리디렉션을 거부하고, 자격 증명이 제거된 대상만 보고합니다. 일반적인 공급자 요청의 리디렉션 검토는 이 진단 가드와 별도로 유지됩니다. -Clash / Surge / Mihomo 사용자를 위한 fake-IP DNS 예외는 두 가지이며, 둘 다 DNS *응답*에만 적용됩니다. URL에 적힌 리터럴 주소는 그대로 거부됩니다. IANA 벤치마크 대역 `198.18.0.0/15`(IPv4-mapped IPv6 표기 포함)은 해당 호스트에 아웃바운드 프록시가 적용될 때 허용됩니다. Mihomo 기본 IPv6 fake-IP 대역 `fdfe:dcba:9876::/48`은 더 엄격한 조건에서만 허용됩니다. URL 스킴에 맞는 프록시 변수(`https:`는 `HTTPS_PROXY`, `http:`는 `HTTP_PROXY`, `ALL_PROXY`는 해당 없음)가 설정되어 있어야 하고, 호스트가 `NO_PROXY`에 걸리지 않아야 하며, 그 경우 요청은 해당 프록시에 명시적으로 묶여 나갑니다. 그 밖의 ULA, 인접 프리픽스, 실제 사설 응답과 섞인 fake-IP 응답은 여전히 `allowPrivateNetwork: true`가 필요합니다. 프로바이더 저장 시점 검증에는 IPv6 예외가 적용되지 않습니다. +Clash / Surge / Mihomo 사용자를 위한 fake-IP DNS 예외는 두 가지이며, 둘 다 DNS *응답*에만 적용됩니다. URL에 적힌 리터럴 주소는 그대로 거부됩니다. IANA 벤치마크 대역 `198.18.0.0/15`(IPv4-mapped IPv6 표기 포함)은 해당 호스트에 아웃바운드 프록시가 적용될 때 허용됩니다. Mihomo 기본 IPv6 fake-IP 대역 `fdfe:dcba:9876::/48`은 더 엄격한 조건에서만 허용됩니다. URL 스킴에 맞는 프록시 변수(`https:`는 `HTTPS_PROXY`, `http:`는 `HTTP_PROXY`) 또는 SOCKS5 `ALL_PROXY`가 설정되어 있어야 하고(SOCKS가 아닌 `ALL_PROXY`는 해당 없음), 호스트가 `NO_PROXY`에 걸리지 않아야 하며, 그 경우 요청은 해당 프록시에 명시적으로 묶여 나갑니다. 그 밖의 ULA, 인접 프리픽스, 실제 사설 응답과 섞인 fake-IP 응답은 여전히 `allowPrivateNetwork: true`가 필요합니다. 프로바이더 저장 시점 검증에는 IPv6 예외가 적용되지 않습니다. ## Codex 계정 풀 diff --git a/docs-site/src/content/docs/reference/adapters.md b/docs-site/src/content/docs/reference/adapters.md index 4da02652ae7..793a4522fe6 100644 --- a/docs-site/src/content/docs/reference/adapters.md +++ b/docs-site/src/content/docs/reference/adapters.md @@ -131,8 +131,11 @@ exception. Adapter selection does not select the upstream transport. Eligible requests can use the [upstream WebSocket proxy route](/reference/proxy-formats/#json-and-sse-output); invalid or unsupported -WebSocket proxy settings fall back to HTTP/SSE. HTTP fetch-based Responses handling uses Bun's -HTTP proxy rules and does not inherit the WSS-specific `ALL_PROXY` fallback. +WebSocket proxy settings fall back to HTTP/SSE. HTTP fetch-based Responses handling uses the +[configured outbound fetch](/reference/configuration/server/#server-fields): a server SOCKS5 proxy from +`config.proxy` or a SOCKS5 `ALL_PROXY` uses the built-in tunnel when `NO_PROXY` does not exempt +the target. Scheme-specific HTTP(S) proxy variables retain their separate native handling; +non-SOCKS `ALL_PROXY` is not a native HTTP fetch route. Noncanonical Responses gateways receive Codex's client-executed `tool_search` declaration as a collision-safe public function tool. Matching request history and JSON/SSE function calls are diff --git a/docs-site/src/content/docs/reference/configuration/providers.md b/docs-site/src/content/docs/reference/configuration/providers.md index e218f7ff36f..1ec22ffae41 100644 --- a/docs-site/src/content/docs/reference/configuration/providers.md +++ b/docs-site/src/content/docs/reference/configuration/providers.md @@ -516,9 +516,14 @@ outbound proxy, opencodex resolves the hostname once and connects only to that v HTTPS retains the original Host, SNI, and certificate verification; provider config cannot disable certificate checks. -When `HTTP_PROXY`, `HTTPS_PROXY`, or `ALL_PROXY` applies, these operations keep Bun's native fetch. -URL and literal-address checks still run, but the proxy chooses the final route, DNS answer, and peer, -so opencodex cannot pin or verify that peer. This is an explicit security limitation. +These operations use the [server's configured outbound fetch](/reference/configuration/server/). +A server SOCKS5 proxy — set with +`config.proxy` or inherited from a SOCKS5 `ALL_PROXY` — uses OpenCodex's built-in tunnel when +`NO_PROXY` does not exempt the target. Scheme-specific `HTTP_PROXY` and +`HTTPS_PROXY` retain Bun's native HTTP(S) handling, while a non-SOCKS `ALL_PROXY` is not a native +HTTP fetch route. URL and literal-address checks still run, but a selected proxy chooses the final +route, DNS answer, and peer, so opencodex cannot pin or verify that peer. This is an explicit +security limitation. Private/local destinations require `allowPrivateNetwork: true` and, when an outbound proxy is active, a matching `NO_PROXY` entry. Loopback is added automatically; list each LAN host explicitly because @@ -532,8 +537,9 @@ Two fake-IP DNS accommodations exist for Clash / Surge / Mihomo users, and both *answers* only — a literal address in the URL is still rejected. The IANA benchmark range `198.18.0.0/15` (and its IPv4-mapped IPv6 spellings) is accepted whenever an outbound proxy applies to the host. Mihomo's default IPv6 fake-IP range `fdfe:dcba:9876::/48` is accepted on a stricter -gate: the proxy variable that matches the URL scheme (`HTTPS_PROXY` for `https:`, `HTTP_PROXY` for -`http:`; `ALL_PROXY` does not count) must be set, the host must not match `NO_PROXY`, and the +gate: the proxy variable that matches the URL scheme (`HTTPS_PROXY` for +`https:`, `HTTP_PROXY` for `http:`) or a SOCKS5 `ALL_PROXY` must be set (a non-SOCKS `ALL_PROXY` does +not count), the host must not match `NO_PROXY`, and the request is then bound to that proxy explicitly. Any other ULA, an adjacent prefix, or a fake-IP answer mixed with a real private answer still requires `allowPrivateNetwork: true`. Provider save-time validation never applies the IPv6 accommodation. diff --git a/docs-site/src/content/docs/reference/proxy-formats.md b/docs-site/src/content/docs/reference/proxy-formats.md index f10e232f571..eda4190dee6 100644 --- a/docs-site/src/content/docs/reference/proxy-formats.md +++ b/docs-site/src/content/docs/reference/proxy-formats.md @@ -255,11 +255,16 @@ uses an unsupported protocol, opencodex skips the WebSocket attempt and uses HTT dialing the upstream directly. These rules belong to the upstream WebSocket transport, independently of the selected provider -adapter. HTTP fetch-based Responses requests, including SSE fallback, use Bun's HTTP proxy rules -and do not use `ALL_PROXY`. `config.proxy` fills missing `HTTP_PROXY`/`HTTPS_PROXY` values; the -resulting scheme-specific value also takes precedence over an existing `ALL_PROXY` for WebSocket. -For an HTTPS upstream that requires a proxy, set `HTTPS_PROXY` or `config.proxy`; `HTTP_PROXY` -alone leaves both WSS and its HTTPS fallback without a scheme-matched proxy. +adapter. HTTP fetch-based Responses requests, including SSE fallback, use the +[configured outbound fetch](/reference/configuration/server/#server-fields). A server SOCKS5 proxy — set +with `config.proxy` or inherited from a SOCKS5 `ALL_PROXY` — uses OpenCodex's built-in tunnel when +`NO_PROXY`/`no_proxy` does not exempt the target. Scheme-specific +`HTTP_PROXY`/`HTTPS_PROXY` values retain Bun's native HTTP(S) handling, while a non-SOCKS +`ALL_PROXY` is not a native HTTP fetch route. `config.proxy` fills missing +`HTTP_PROXY`/`HTTPS_PROXY` values; the resulting scheme-specific value also takes precedence over +an existing `ALL_PROXY` for WebSocket. For an HTTPS upstream that requires a proxy, set +`HTTPS_PROXY` or `config.proxy`; `HTTP_PROXY` alone leaves both WSS and its HTTPS fallback without +a scheme-matched proxy. Every terminal Responses usage object includes both detail objects, even when the provider did not report those details: diff --git a/docs-site/src/content/docs/ru/reference/configuration/providers.md b/docs-site/src/content/docs/ru/reference/configuration/providers.md index f30de5b380e..05a21c86ac7 100644 --- a/docs-site/src/content/docs/ru/reference/configuration/providers.md +++ b/docs-site/src/content/docs/ru/reference/configuration/providers.md @@ -174,10 +174,13 @@ GET-запросов. Если outbound-proxy не настроен, opencodex подключается только к этому проверенному адресу. Для HTTPS сохраняются исходные Host, SNI и проверка сертификата; отключить проверку сертификата конфигурация провайдера не может. -Если активны `HTTP_PROXY`, `HTTPS_PROXY` или `ALL_PROXY`, эти операции оставляют встроенный fetch -Bun. Проверки URL и literal-address всё равно выполняются, но итоговый маршрут, DNS-ответ и peer -всё же выбирает прокси, поэтому opencodex не может зафиксировать или проверить этого peer'а. Это -осознанное ограничение безопасности. +Эти операции используют [настроенный исходящий fetch сервера](/ru/reference/configuration/server/). +SOCKS5-прокси сервера — заданный через `config.proxy` или унаследованный из SOCKS5 `ALL_PROXY` — +использует встроенный туннель OpenCodex, если цель не совпадает с `NO_PROXY`. +`HTTP_PROXY` и `HTTPS_PROXY` сохраняют нативную обработку HTTP(S) в Bun, а `ALL_PROXY` не-SOCKS +не является маршрутом нативного HTTP fetch. Проверки URL и literal-address всё равно выполняются, +но выбранный прокси определяет итоговый маршрут, DNS-ответ и peer, поэтому opencodex не может +зафиксировать или проверить этого peer'а. Это осознанное ограничение безопасности. Private/local destination требуют `allowPrivateNetwork: true` и, если активен outbound-proxy, подходящей записи в `NO_PROXY`. Loopback добавляется автоматически; каждый LAN-host нужно @@ -187,7 +190,7 @@ domain suffix, необязательные порты, IPv6 в квадратн не следуют redirect'ам и в результатах показывают только credential-stripped target. Проверка redirect'ов для обычных provider-request'ов реализована отдельно и к этому guard не относится. -Для пользователей Clash / Surge / Mihomo предусмотрены два исключения fake-IP DNS, и оба применяются только к DNS-*ответам* — литеральный адрес в URL по-прежнему отклоняется. Диапазон IANA benchmark `198.18.0.0/15` (включая IPv4-mapped IPv6 записи) принимается, когда к хосту применяется исходящий прокси. Диапазон IPv6 fake-IP по умолчанию в Mihomo `fdfe:dcba:9876::/48` принимается при более строгом условии: должна быть задана переменная прокси, соответствующая схеме URL (`HTTPS_PROXY` для `https:`, `HTTP_PROXY` для `http:`; `ALL_PROXY` не учитывается), хост не должен совпадать с `NO_PROXY`, и тогда запрос явно привязывается к этому прокси. Любой другой ULA, соседний префикс или fake-IP ответ вперемешку с реальным приватным ответом по-прежнему требуют `allowPrivateNetwork: true`. Валидация при сохранении провайдера никогда не применяет IPv6-исключение. +Для пользователей Clash / Surge / Mihomo предусмотрены два исключения fake-IP DNS, и оба применяются только к DNS-*ответам* — литеральный адрес в URL по-прежнему отклоняется. Диапазон IANA benchmark `198.18.0.0/15` (включая IPv4-mapped IPv6 записи) принимается, когда к хосту применяется исходящий прокси. Диапазон IPv6 fake-IP по умолчанию в Mihomo `fdfe:dcba:9876::/48` принимается при более строгом условии: должна быть задана переменная прокси, соответствующая схеме URL (`HTTPS_PROXY` для `https:`, `HTTP_PROXY` для `http:`) или SOCKS5 `ALL_PROXY` (`ALL_PROXY` не-SOCKS не учитывается), хост не должен совпадать с `NO_PROXY`, и тогда запрос явно привязывается к этому прокси. Любой другой ULA, соседний префикс или fake-IP ответ вперемешку с реальным приватным ответом по-прежнему требуют `allowPrivateNetwork: true`. Валидация при сохранении провайдера никогда не применяет IPv6-исключение. ## Пул аккаунтов Codex diff --git a/docs-site/src/content/docs/tr/reference/configuration/providers.md b/docs-site/src/content/docs/tr/reference/configuration/providers.md index b29dcdcf44f..110c69be3c6 100644 --- a/docs-site/src/content/docs/tr/reference/configuration/providers.md +++ b/docs-site/src/content/docs/tr/reference/configuration/providers.md @@ -177,9 +177,11 @@ kez çözer ve yalnızca bu doğrulanmış adrese bağlanır. HTTPS orijinal Hos ve sertifika doğrulamasını korur; sağlayıcı yapılandırması sertifika denetimlerini devre dışı bırakamaz. -`HTTP_PROXY`, `HTTPS_PROXY` veya `ALL_PROXY` geçerli olduğunda bu işlemler -Bun'ın yerel getirmesini korur. URL ve değişmez adres denetimleri hala çalışır, -ancak proxy son rotayı, DNS yanıtını ve eşi seçer, bu nedenle opencodex bu eşi +Bu işlemler [sunucunun yapılandırılmış giden fetch yolunu](/tr/reference/configuration/server/) +kullanır. `config.proxy` ile ayarlanan veya SOCKS5 `ALL_PROXY`'den devralınan sunucu SOCKS5 proxy'si, +hedef `NO_PROXY` ile eşleşmediğinde OpenCodex'in yerleşik tünelini kullanır. `HTTP_PROXY` ve `HTTPS_PROXY`, Bun'ın yerel HTTP(S) işlemesini korur; SOCKS olmayan bir +`ALL_PROXY` ise yerel HTTP fetch rotası değildir. URL ve değişmez adres denetimleri hâlâ çalışır, +ancak seçilen proxy son rotayı, DNS yanıtını ve eşi belirler; bu nedenle opencodex bu eşi sabitleyemez veya doğrulayamaz. Bu açık bir güvenlik sınırlamasıdır. Özel/yerel hedefler `allowPrivateNetwork: true` ve giden bir proxy etkin @@ -192,7 +194,7 @@ hedefleri engellenmiş olarak kalır. Teşhis istekleri yönlendirmeleri reddede kimlik bilgisi kaldırılmış bir hedef bildirir. Sıradan sağlayıcı isteği yeniden yönlendirme incelemesi bu teşhis korumasından ayrı kalır. -Clash / Surge / Mihomo kullanıcıları için iki fake-IP DNS istisnası vardır ve ikisi de yalnızca DNS *yanıtlarına* uygulanır; URL'deki literal adres yine reddedilir. IANA benchmark aralığı `198.18.0.0/15` (IPv4-mapped IPv6 yazımları dahil), ana bilgisayara bir giden proxy uygulandığında kabul edilir. Mihomo'nun varsayılan IPv6 fake-IP aralığı `fdfe:dcba:9876::/48` daha sıkı bir koşulla kabul edilir: URL şemasıyla eşleşen proxy değişkeni (`https:` için `HTTPS_PROXY`, `http:` için `HTTP_PROXY`; `ALL_PROXY` sayılmaz) ayarlı olmalı, ana bilgisayar `NO_PROXY` ile eşleşmemeli ve istek daha sonra açıkça o proxy'ye bağlanır. Diğer tüm ULA'lar, komşu önekler veya gerçek bir özel yanıtla karışık fake-IP yanıtları hâlâ `allowPrivateNetwork: true` gerektirir. Sağlayıcı kaydetme zamanı doğrulaması IPv6 istisnasını hiçbir zaman uygulamaz. +Clash / Surge / Mihomo kullanıcıları için iki fake-IP DNS istisnası vardır ve ikisi de yalnızca DNS *yanıtlarına* uygulanır; URL'deki literal adres yine reddedilir. IANA benchmark aralığı `198.18.0.0/15` (IPv4-mapped IPv6 yazımları dahil), ana bilgisayara bir giden proxy uygulandığında kabul edilir. Mihomo'nun varsayılan IPv6 fake-IP aralığı `fdfe:dcba:9876::/48` daha sıkı bir koşulla kabul edilir: URL şemasıyla eşleşen proxy değişkeni (`https:` için `HTTPS_PROXY`, `http:` için `HTTP_PROXY`) veya bir SOCKS5 `ALL_PROXY` ayarlı olmalı (SOCKS olmayan `ALL_PROXY` sayılmaz), ana bilgisayar `NO_PROXY` ile eşleşmemeli ve istek daha sonra açıkça o proxy'ye bağlanır. Diğer tüm ULA'lar, komşu önekler veya gerçek bir özel yanıtla karışık fake-IP yanıtları hâlâ `allowPrivateNetwork: true` gerektirir. Sağlayıcı kaydetme zamanı doğrulaması IPv6 istisnasını hiçbir zaman uygulamaz. ## Codex hesap havuzu diff --git a/docs-site/src/content/docs/zh-cn/reference/configuration/providers.md b/docs-site/src/content/docs/zh-cn/reference/configuration/providers.md index a529fb0eab8..653f0a54d78 100644 --- a/docs-site/src/content/docs/zh-cn/reference/configuration/providers.md +++ b/docs-site/src/content/docs/zh-cn/reference/configuration/providers.md @@ -155,11 +155,11 @@ API key 提供者可以持有字面量 key,或环境引用。OAuth 提供者 仪表板连接测试和实时模型发现使用受限的、仅 GET 传输。没有出站代理时,opencodex 只会解析一次主机名,并仅连接到该已验证地址。HTTPS 仍会保留原始 Host、SNI 和证书验证;提供者配置不能关闭证书检查。 -当 `HTTP_PROXY`、`HTTPS_PROXY` 或 `ALL_PROXY` 生效时,这些操作会继续使用 Bun 的原生 fetch。URL 和字面量地址检查仍会执行,但最终路由、DNS 解析结果和对端由代理决定,因此 opencodex 无法固定或验证该对端。这是一个明确的安全限制。 +这些操作使用[服务器配置的出站 fetch](/zh-cn/reference/configuration/server/)。通过 `config.proxy` 设置或继承自 SOCKS5 `ALL_PROXY` 的服务器 SOCKS5 代理,在目标不匹配 `NO_PROXY` 时使用 OpenCodex 的内置隧道。`HTTP_PROXY` 和 `HTTPS_PROXY` 保留 Bun 的原生 HTTP(S) 处理,而非 SOCKS 的 `ALL_PROXY` 不是原生 HTTP fetch 路由。URL 和字面量地址检查仍会执行,但所选代理会决定最终路由、DNS 解析结果和对端,因此 opencodex 无法固定或验证该对端。这是一个明确的安全限制。 私有/本地目标需要 `allowPrivateNetwork: true`,并且在出站代理启用时,还需要匹配的 `NO_PROXY` 条目。回环地址会自动加入;每个 LAN 主机都必须显式列出,因为 CIDR 条目不会被解释。匹配器支持精确主机、域后缀、可选端口、带方括号的 IPv6 以及 `*`;例如,应显式列出 `192.168.1.50`。元数据和链路本地目标仍会被阻止。诊断请求会拒绝重定向,并报告一个已剥离凭据的目标。普通提供者请求的重定向审查仍然独立于这个诊断保护。 -面向 Clash / Surge / Mihomo 用户的 fake-IP DNS 例外有两种,且都只作用于 DNS *应答*——URL 中的字面地址仍会被拒绝。IANA 基准段 `198.18.0.0/15`(含 IPv4-mapped IPv6 写法)在该主机适用出站代理时被接受。Mihomo 默认的 IPv6 fake-IP 段 `fdfe:dcba:9876::/48` 采用更严格的门槛:必须设置与 URL 协议匹配的代理变量(`https:` 对应 `HTTPS_PROXY`,`http:` 对应 `HTTP_PROXY`,`ALL_PROXY` 不算),主机不能命中 `NO_PROXY`,随后请求会被显式绑定到该代理。其他 ULA、相邻前缀,或与真实私网应答混合的 fake-IP 应答仍需要 `allowPrivateNetwork: true`。提供方保存时的校验不应用该 IPv6 例外。 +面向 Clash / Surge / Mihomo 用户的 fake-IP DNS 例外有两种,且都只作用于 DNS *应答*——URL 中的字面地址仍会被拒绝。IANA 基准段 `198.18.0.0/15`(含 IPv4-mapped IPv6 写法)在该主机适用出站代理时被接受。Mihomo 默认的 IPv6 fake-IP 段 `fdfe:dcba:9876::/48` 采用更严格的门槛:必须设置与 URL 协议匹配的代理变量(`https:` 对应 `HTTPS_PROXY`,`http:` 对应 `HTTP_PROXY`)或 SOCKS5 的 `ALL_PROXY`(非 SOCKS 的 `ALL_PROXY` 不算),主机不能命中 `NO_PROXY`,随后请求会被显式绑定到该代理。其他 ULA、相邻前缀,或与真实私网应答混合的 fake-IP 应答仍需要 `allowPrivateNetwork: true`。提供方保存时的校验不应用该 IPv6 例外。 ## Codex 账户池 diff --git a/docs-site/src/content/docs/zh-tw/reference/configuration/providers.md b/docs-site/src/content/docs/zh-tw/reference/configuration/providers.md index ca3868f66e4..80b8e415291 100644 --- a/docs-site/src/content/docs/zh-tw/reference/configuration/providers.md +++ b/docs-site/src/content/docs/zh-tw/reference/configuration/providers.md @@ -125,11 +125,11 @@ API-key 供應商可持有字面值金鑰或環境參考。OAuth 供應商使用 儀表板連線測試與即時模型探索使用有界的 GET-only 傳輸。在沒有對外代理的情況下,opencodex 解析主機名稱一次並僅連接到該已驗證位址。HTTPS 保留原始 Host、SNI 與憑證驗證;供應商設定無法停用憑證檢查。 -當 `HTTP_PROXY`、`HTTPS_PROXY` 或 `ALL_PROXY` 適用時,這些操作保留 Bun 的原生 fetch。URL 與字面位址檢查仍會執行,但代理選擇最終路由、DNS 答案與對等端,因此 opencodex 無法 pin 或驗證該對等端。這是明確的安全限制。 +這些操作使用[伺服器設定的對外 fetch](/zh-tw/reference/configuration/server/)。以 `config.proxy` 設定或繼承自 SOCKS5 `ALL_PROXY` 的伺服器 SOCKS5 代理,在目標不符合 `NO_PROXY` 時使用 OpenCodex 的內建通道。`HTTP_PROXY` 與 `HTTPS_PROXY` 保留 Bun 的原生 HTTP(S) 處理,而非 SOCKS 的 `ALL_PROXY` 不是原生 HTTP fetch 路由。URL 與字面位址檢查仍會執行,但所選代理會決定最終路由、DNS 答案與對等端,因此 opencodex 無法 pin 或驗證該對等端。這是明確的安全限制。 私有/本機目的地需要 `allowPrivateNetwork: true`,且當對外代理活躍時需要相符的 `NO_PROXY` 項目。回送會自動加入;請明確列出每個 LAN 主機,因為 CIDR 項目不被解讀。比對器支援精確主機、網域後綴、可選連接埠、方括號 IPv6 與 `*`;例如,明確列出 `192.168.1.50`。中繼資料與 link-link 目標保持被封鎖。診斷請求拒絕重新導向並回報已剝離憑證的目標。普通供應商請求的重新導向審查與此診斷防護分開。 -針對 Clash / Surge / Mihomo 使用者的 fake-IP DNS 例外有兩種,且都只作用於 DNS *回應*——URL 中的字面位址仍會被拒絕。IANA 基準區段 `198.18.0.0/15`(含 IPv4-mapped IPv6 寫法)在該主機適用對外代理時被接受。Mihomo 預設的 IPv6 fake-IP 區段 `fdfe:dcba:9876::/48` 採更嚴格的門檻:必須設定與 URL 協定相符的代理變數(`https:` 對應 `HTTPS_PROXY`,`http:` 對應 `HTTP_PROXY`,`ALL_PROXY` 不算),主機不得命中 `NO_PROXY`,之後請求會被明確綁定到該代理。其他 ULA、相鄰前綴,或與真實私網回應混合的 fake-IP 回應仍需要 `allowPrivateNetwork: true`。提供者儲存時的驗證不套用此 IPv6 例外。 +針對 Clash / Surge / Mihomo 使用者的 fake-IP DNS 例外有兩種,且都只作用於 DNS *回應*——URL 中的字面位址仍會被拒絕。IANA 基準區段 `198.18.0.0/15`(含 IPv4-mapped IPv6 寫法)在該主機適用對外代理時被接受。Mihomo 預設的 IPv6 fake-IP 區段 `fdfe:dcba:9876::/48` 採更嚴格的門檻:必須設定與 URL 協定相符的代理變數(`https:` 對應 `HTTPS_PROXY`,`http:` 對應 `HTTP_PROXY`)或 SOCKS5 的 `ALL_PROXY`(非 SOCKS 的 `ALL_PROXY` 不算),主機不得命中 `NO_PROXY`,之後請求會被明確綁定到該代理。其他 ULA、相鄰前綴,或與真實私網回應混合的 fake-IP 回應仍需要 `allowPrivateNetwork: true`。提供者儲存時的驗證不套用此 IPv6 例外。 ## Codex 帳號池 diff --git a/structure/ops/docs-and-release.md b/structure/ops/docs-and-release.md index 9ad63ed256f..c2ba4401ec2 100644 --- a/structure/ops/docs-and-release.md +++ b/structure/ops/docs-and-release.md @@ -36,6 +36,8 @@ served at the site root, with Korean under `/ko`, Simplified Chinese under `/zh- Server-configuration credential rows in English and every locale copy distinguish data-plane `apiKeys` from the independent management admin credential and link the matching locale management reference. Credential setup instructions themselves stay in the management reference; the rows only name the separation. +Proxy-format, adapter, and provider documentation distinguishes server-level SOCKS5 configured outbound fetch from scheme-specific HTTP(S) routing, and every locale copy carrying that claim stays aligned. The public pages own the runtime detail rather than duplicating it here. + Manual navigation is defined in `docs-site/astro.config.mjs`. When adding a public page, update the sidebar and either add localized copies or intentionally accept Starlight fallback behavior. From 6d4272338701a15b0ed2adc3f422f5a7c33fef11 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 20:05:56 +0900 Subject: [PATCH 29/97] Add versioned structure contract authority (#5155) * feat(structure): add versioned contract authority to the manifest Add an optional, versioned contracts registry to structure/manifest.json so each cross-cutting contract has one authoritative document anchor while the many-to-many source review map is preserved unchanged. The checker validates declared topology (unique ids, existing owner documents/anchors, dependent links) without claiming semantic correctness, and the generated index publishes the registry. Migrate the duplicated paginated-history writer paragraph in seven dependent documents to one authority link, and register the existing request-copy and stream-buffer accounting contracts. structure/AGENTS.md now distinguishes mandatory review fan-out from the smaller set of documents whose content actually changes. Closes #5116 * fix(structure): validate the manifest before rewriting the index The --fix path parsed and cast the manifest, then rendered, before any schema validation: a malformed contracts section crashed the renderer with a TypeError instead of failing with an actionable diagnostic, and could write a broken index first. Route generation through loadManifest and add regression coverage proving the named schema failure and an unchanged INDEX.md for malformed input. * test(structure): drive the real --fix CLI in the malformed-manifest regression The seam-level tests prove writeGeneratedIndex, but the original defect lived in the CLI tail. Spawn the copied script in the synthetic scaffold: malformed contracts exit nonzero with the named schema diagnostic and no TypeError, INDEX.md unchanged; a valid manifest with a stale index exits zero and regenerates it. Authored for hosted execution; not run locally per campaign restriction. --- scripts/structure-ssot.ts | 131 +++++++++++- structure/AGENTS.md | 27 ++- structure/INDEX.md | 13 +- structure/catalog.md | 4 +- structure/config.md | 4 +- structure/gui-and-management-api.md | 4 +- structure/manifest.json | 71 +++++++ structure/ops/docs-and-release.md | 10 +- structure/overview.md | 5 + structure/providers/openai-tiers.md | 3 +- structure/runtime.md | 4 +- structure/subagents.md | 4 +- tests/ci-workflows/structure-ssot.test.ts | 235 +++++++++++++++++++++- 13 files changed, 479 insertions(+), 36 deletions(-) diff --git a/scripts/structure-ssot.ts b/scripts/structure-ssot.ts index ddc61e09940..fb783434f2a 100644 --- a/scripts/structure-ssot.ts +++ b/scripts/structure-ssot.ts @@ -35,6 +35,14 @@ export type Manifest = { absentPaths: { path: string; reason: string }[]; tiers: { id: number; name: string; purpose: string }[]; docs: { path: string; tier: number; title: string; scope: string; documents: string[] }[]; + contracts?: { + version: 1; + entries: { + id: string; + owner: { document: string; anchor: string }; + dependents: string[]; + }[]; + }; grace: { undocumentedSourceAreas: { path: string; reason: string }[]; unboundInvariants: { id: string; reason: string }[]; @@ -87,6 +95,34 @@ export function loadManifest(raw: string): { manifest: Manifest } | { error: str if (!isArray(doc?.documents)) problems.push("docs[" + i + "].documents must be an array"); }); } + if (m.contracts !== undefined) { + if (typeof m.contracts !== "object" || m.contracts === null || isArray(m.contracts)) { + problems.push("contracts must be an object"); + } else { + const contracts = m.contracts as Partial>; + if (contracts.version !== 1) problems.push("contracts.version must be 1"); + if (!isArray(contracts.entries)) problems.push("contracts.entries must be an array"); + else { + contracts.entries.forEach((entry, i) => { + if (typeof entry?.id !== "string" || !/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(entry.id)) { + problems.push("contracts.entries[" + i + "].id must be a kebab-case string"); + } + if (typeof entry?.owner !== "object" || entry.owner === null || isArray(entry.owner)) { + problems.push("contracts.entries[" + i + "].owner must be an object"); + } else { + if (typeof entry.owner.document !== "string") problems.push("contracts.entries[" + i + "].owner.document must be a string"); + if (typeof entry.owner.anchor !== "string") problems.push("contracts.entries[" + i + "].owner.anchor must be a string"); + } + if (!isArray(entry?.dependents)) problems.push("contracts.entries[" + i + "].dependents must be an array"); + else { + entry.dependents.forEach((dependent, j) => { + if (typeof dependent !== "string") problems.push("contracts.entries[" + i + "].dependents[" + j + "] must be a string"); + }); + } + }); + } + } + } const grace = m.grace as Partial | undefined; if (!grace) problems.push("grace must be an object"); else { @@ -210,8 +246,7 @@ export function renderIndex(manifest: Manifest): string { lines.push("## Which doc describes which source"); lines.push(""); lines.push("A source area can be described by more than one doc, because these docs are organised by topic and"); - lines.push(BT + "src/" + BT + " is organised by module. Changing an area obliges the same change to update every doc listed"); - lines.push("for it; see [" + BT + "AGENTS.md" + BT + "](AGENTS.md)."); + lines.push(BT + "src/" + BT + " is organised by module. Changing an area requires review of every listed document. Edit only the documents whose local explanation changes; named cross-cutting authorities and dependents are listed below."); lines.push(""); lines.push("| Source path | Described by |"); lines.push("| --- | --- |"); @@ -232,6 +267,23 @@ export function renderIndex(manifest: Manifest): string { lines.push("| " + BT + row.path + BT + " | " + row.reason + " |"); } lines.push(""); + if (manifest.contracts?.entries.length) { + lines.push("## Cross-cutting contracts"); + lines.push(""); + lines.push("Source review remains defined by the source-to-doc map above. This registry names each authoritative statement and the documents that review it. Link validation proves declared topology, not behavioral correctness."); + lines.push(""); + lines.push("| Contract | Authority | Review dependents |"); + lines.push("| --- | --- | --- |"); + for (const contract of [...manifest.contracts.entries].sort((a, b) => a.id.localeCompare(b.id))) { + const owner = contract.owner.document + "#" + contract.owner.anchor; + const dependents = [...contract.dependents] + .sort((a, b) => a.localeCompare(b)) + .map((document) => "[" + BT + document + BT + "](" + document + ")") + .join("
    ") || "—"; + lines.push("| " + BT + contract.id + BT + " | [" + BT + owner + BT + "](" + owner + ") | " + dependents + " |"); + } + lines.push(""); + } lines.push("## Decision records"); lines.push(""); lines.push("Superseded reasoning lives in " + BT + "decisions/" + BT + " as numbered records. A doc states the contract that holds now and"); @@ -376,7 +428,54 @@ export function runStructureChecks(repoRoot: string): string[] { if (isTracked(absent.path)) fail(absent.path + " is declared absent in manifest.json but is tracked; the docs describing its absence are wrong"); } - // 4. decision records + // 4. cross-cutting contract authority + const contractIds = new Set(); + for (const contract of manifest.contracts?.entries ?? []) { + if (contractIds.has(contract.id)) fail("contract " + contract.id + " is declared twice"); + contractIds.add(contract.id); + + const owner = contract.owner.document; + const ownerAbs = join(structureDir, owner); + if (!declared.includes(owner)) fail("contract " + contract.id + " owner " + owner + " is not a declared structure document"); + if (!present.includes(owner)) fail("contract " + contract.id + " owner structure/" + owner + " is missing"); + else if (!headingAnchors(readFileSync(ownerAbs, "utf8")).has(contract.owner.anchor)) { + fail("contract " + contract.id + " owner structure/" + owner + " has no #" + contract.owner.anchor + " heading anchor"); + } + + const dependents = new Set(); + for (const dependent of contract.dependents) { + if (dependents.has(dependent)) fail("contract " + contract.id + " lists dependent " + dependent + " twice"); + dependents.add(dependent); + if (dependent === owner) fail("contract " + contract.id + " lists its owner " + owner + " as a dependent"); + if (!declared.includes(dependent)) fail("contract " + contract.id + " dependent " + dependent + " is not a declared structure document"); + if (!present.includes(dependent)) { + fail("contract " + contract.id + " dependent structure/" + dependent + " is missing"); + continue; + } + const dependentAbs = join(structureDir, dependent); + const body = withoutFences(readFileSync(dependentAbs, "utf8")); + let linked = false; + let hit: RegExpExecArray | null; + linkRe.lastIndex = 0; + while ((hit = linkRe.exec(body))) { + const separator = hit[1].indexOf("#"); + if (separator === -1) continue; + const file = hit[1].slice(0, separator); + const fragment = hit[1].slice(separator + 1); + const resolved = file === "" ? dependentAbs : resolve(dirname(dependentAbs), file); + const target = toPosix(relative(structureDir, resolved)); + if (target === owner && fragment === contract.owner.anchor) { + linked = true; + break; + } + } + if (!linked) { + fail("contract " + contract.id + " dependent structure/" + dependent + " does not link " + owner + "#" + contract.owner.anchor); + } + } + } + + // 5. decision records const adrFiles = present.filter((p) => p.startsWith("decisions/")); const referenced = new Map>(); // Ownership is the declared link form, read with fences removed. A record path mentioned in prose @@ -417,7 +516,7 @@ export function runStructureChecks(repoRoot: string): string[] { } for (const key of referenced.keys()) if (!adrFiles.includes(key)) fail("a doc links structure/" + key + ", which does not exist"); - // 5. invariant-to-test bindings + // 6. invariant-to-test bindings const overviewPath = join(structureDir, "overview.md"); if (!existsSync(overviewPath)) { fail("structure/overview.md is missing; it is the invariant index, and its absence would silence every binding check"); @@ -472,7 +571,7 @@ export function runStructureChecks(repoRoot: string): string[] { } } - // 6. source-to-doc map + // 7. source-to-doc map const described = new Map(); // What a doc actually names, so a manifest claim cannot invent coverage the prose does not have. const namedByDoc = new Map(); @@ -530,7 +629,7 @@ export function runStructureChecks(repoRoot: string): string[] { fail(area + " is described by no doc; add it to a doc's " + BT + "documents" + BT + " list or record it in grace.undocumentedSourceAreas with a reason"); } - // 7. generated index parity + // 8. generated index parity const indexPath = join(structureDir, "INDEX.md"); const expected = renderIndex(manifest); if (!existsSync(indexPath)) fail("structure/INDEX.md is missing; run bun run structure:index"); @@ -541,11 +640,27 @@ export function runStructureChecks(repoRoot: string): string[] { return failures; } +/** + * Rewrite the generated index only after the manifest validates. The renderer trusts the typed + * shape, so a malformed manifest (for example a string where `contracts.entries` belongs) would + * otherwise crash the renderer with a TypeError and could write a broken index before the checker + * ever ran. Validation failure is an actionable schema diagnostic and leaves INDEX.md untouched. + */ +export function writeGeneratedIndex(repoRoot: string): { wrote: true } | { error: string } { + const loaded = loadManifest(readFileSync(join(repoRoot, "structure", "manifest.json"), "utf8")); + if ("error" in loaded) return { error: loaded.error }; + writeFileSync(join(repoRoot, "structure", "INDEX.md"), renderIndex(loaded.manifest), "utf8"); + return { wrote: true }; +} + if (import.meta.main) { const repoRoot = resolve(import.meta.dir, ".."); if (process.argv.includes("--fix")) { - const manifest = JSON.parse(readFileSync(join(repoRoot, "structure/manifest.json"), "utf8")) as Manifest; - writeFileSync(join(repoRoot, "structure/INDEX.md"), renderIndex(manifest), "utf8"); + const fixed = writeGeneratedIndex(repoRoot); + if ("error" in fixed) { + console.error(fixed.error); + process.exit(1); + } console.log("wrote structure/INDEX.md"); } const failures = runStructureChecks(repoRoot); diff --git a/structure/AGENTS.md b/structure/AGENTS.md index bcab24189b7..8856d5219cc 100644 --- a/structure/AGENTS.md +++ b/structure/AGENTS.md @@ -46,8 +46,10 @@ the inverse. the Responses transport doc and the Images doc. An earlier revision of this folder demanded exactly one owner per area, and that rule was simply false here — a false rule is worse than none, because the gate reports green while the map sends a maintainer to the wrong doc. -- **Changing an area obliges the same change to update every doc listed for it.** Not a follow-up, - not a later cleanup pass. +- **Changing an area obliges the same change to review every doc listed for it.** Review fan-out is + unchanged by contract authority: update the authority when the shared contract changes, and update + a dependent only when its local explanation or consequence changes. A reviewed document whose + content remains accurate does not need copied unchanged prose. - Describing an area means naming a path inside it. If a doc explains a subsystem without ever citing a path, the map cannot see it, and the area lands in `grace.undocumentedSourceAreas` instead — which is a signal to add the path reference, not a place to park work. @@ -62,6 +64,16 @@ What the map still does not do: it cannot tell you that two docs describe the sa contradictory words. Avoiding that is a review judgement. Prefer one statement and a link over two statements that will drift apart. +Cross-cutting authority is declared by the optional versioned `contracts` object in +[`manifest.json`](manifest.json). Each entry has a stable kebab-case `id`, one `owner` with a +manifest-declared document and heading anchor, and a `dependents` array of manifest-declared +documents. Every dependent links the exact owner anchor. The registry supplements the source map; +it never narrows which documents a source change requires review of. + +The gate proves declared topology: identifiers are unique, files and anchors exist, and each +dependent carries the declared link. It does not compare prose or prove that the owner statement is +behaviorally correct. Those remain review judgements. + ## Decision records `decisions/ADR-NNNN-.md` holds the reasoning: intent, prior constraints, alternatives, the @@ -103,8 +115,10 @@ violated is worse than admitting the gap: it converts an open question into fals 1. Write or move the file. 2. Add or update its `manifest.json` entry: `path`, `tier`, `title`, `scope`, `documents`. -3. `bun run structure:index` to regenerate [`INDEX.md`](INDEX.md). -4. `bun run structure:check` until it is green. +3. Add or update any affected contract authority and dependent links in `manifest.json`; review every + document mapped to the changed source area even when its text remains accurate. +4. `bun run structure:index` to regenerate [`INDEX.md`](INDEX.md). +5. `bun run structure:check` until it is green. ## What the gate checks @@ -128,12 +142,17 @@ verifies that: - every bound invariant names an existing test that names the id back, and every unbound one is recorded with a reason; - every `src/` directory and top-level module is described by a doc or recorded as undescribed; +- contract ids are unique, owner and dependent documents exist in the manifest, owner anchors exist, + and every dependent links its declared authority without listing the owner as a dependent; - the manifest itself parses and has the shape the gate expects, reported as a failure rather than a stack trace; - `overview.md` exists, because its absence would otherwise silence every invariant check at once; - `INDEX.md` matches what the manifest generates, compared after newline normalisation so a CRLF checkout is not a failure. +Contract checks establish declared authority and links only. They make no automatic claim that an +owner's prose is semantically complete or that a dependent's explanation is behaviorally correct. + Checks are scanned with fenced code blocks removed, so an example inside a fence does not trip a rule it is only illustrating. diff --git a/structure/INDEX.md b/structure/INDEX.md index 161cc18e132..cd101960def 100644 --- a/structure/INDEX.md +++ b/structure/INDEX.md @@ -85,8 +85,7 @@ Background service, docs, release, and design discipline. ## Which doc describes which source A source area can be described by more than one doc, because these docs are organised by topic and -`src/` is organised by module. Changing an area obliges the same change to update every doc listed -for it; see [`AGENTS.md`](AGENTS.md). +`src/` is organised by module. Changing an area requires review of every listed document. Edit only the documents whose local explanation changes; named cross-cutting authorities and dependents are listed below. | Source path | Described by | | --- | --- | @@ -147,6 +146,16 @@ for it; see [`AGENTS.md`](AGENTS.md). | `src/sidecar/` | no doc names a path here; ops/service-and-sidecars.md describes sidecar behavior in prose only | | `src/types/` | shared declarations plus the tool-name and wire-pin resolvers, which no doc currently describes | +## Cross-cutting contracts + +Source review remains defined by the source-to-doc map above. This registry names each authoritative statement and the documents that review it. Link validation proves declared topology, not behavioral correctness. + +| Contract | Authority | Review dependents | +| --- | --- | --- | +| `paginated-history-writer` | [`codex-home.md#paginated-history-writer-boundary`](codex-home.md#paginated-history-writer-boundary) | [`catalog.md`](catalog.md)
    [`config.md`](config.md)
    [`gui-and-management-api.md`](gui-and-management-api.md)
    [`ops/docs-and-release.md`](ops/docs-and-release.md)
    [`providers/openai-tiers.md`](providers/openai-tiers.md)
    [`runtime.md`](runtime.md)
    [`subagents.md`](subagents.md) | +| `request-copy-accounting` | [`transports/byte-accounting.md#request-copy-accounting`](transports/byte-accounting.md#request-copy-accounting) | [`adapters/registry.md`](adapters/registry.md)
    [`catalog.md`](catalog.md)
    [`clients/claude-desktop.md`](clients/claude-desktop.md)
    [`clients/integrations.md`](clients/integrations.md)
    [`data-planes/images.md`](data-planes/images.md)
    [`data-planes/inbound-compat.md`](data-planes/inbound-compat.md)
    [`ops/docs-and-release.md`](ops/docs-and-release.md)
    [`ops/service-and-sidecars.md`](ops/service-and-sidecars.md)
    [`overview.md`](overview.md)
    [`providers/chat-compat.md`](providers/chat-compat.md)
    [`providers/cursor.md`](providers/cursor.md)
    [`providers/xai-grok.md`](providers/xai-grok.md)
    [`runtime.md`](runtime.md)
    [`subagents.md`](subagents.md)
    [`transports/inventory.md`](transports/inventory.md)
    [`transports/streaming-health.md`](transports/streaming-health.md) | +| `stream-buffer-accounting` | [`transports/byte-accounting.md#stream-buffer-accounting`](transports/byte-accounting.md#stream-buffer-accounting) | [`adapters/registry.md`](adapters/registry.md)
    [`catalog.md`](catalog.md)
    [`clients/claude-desktop.md`](clients/claude-desktop.md)
    [`clients/integrations.md`](clients/integrations.md)
    [`data-planes/images.md`](data-planes/images.md)
    [`data-planes/inbound-compat.md`](data-planes/inbound-compat.md)
    [`ops/docs-and-release.md`](ops/docs-and-release.md)
    [`ops/service-and-sidecars.md`](ops/service-and-sidecars.md)
    [`overview.md`](overview.md)
    [`providers/chat-compat.md`](providers/chat-compat.md)
    [`providers/cursor.md`](providers/cursor.md)
    [`providers/xai-grok.md`](providers/xai-grok.md)
    [`runtime.md`](runtime.md)
    [`subagents.md`](subagents.md)
    [`transports/inventory.md`](transports/inventory.md)
    [`transports/streaming-health.md`](transports/streaming-health.md) | + ## Decision records Superseded reasoning lives in `decisions/` as numbered records. A doc states the contract that holds now and diff --git a/structure/catalog.md b/structure/catalog.md index 0e3fe224dd6..dfa424ea1b5 100644 --- a/structure/catalog.md +++ b/structure/catalog.md @@ -448,9 +448,7 @@ its defaults and exclusions are owned by [Responses transport](transports/respon Provider `showThinkingSummary` is a Responses request default; it does not rewrite catalog summary defaults or client configuration. See [Google summaries](providers/google.md). -## Paginated history writer boundary - -`src/codex/history-provider.ts` refuses external writes to paginated or migration-capable history. `src/codex/inject.ts` checks affected rows and manifest-owned restore targets before and after config/profile/journal changes, including successful journal and fallback restores, and compensates refused restore/removal transitions. Failed config restore stops later catalog/history work and rolls back a coordinated remove transition. Apply retains an existing provider definition before candidate admission even when history preflight passes, so migration after artifact commit or during worker startup cannot leave earlier conversations without their provider. See the [history writer contract](codex-home.md#paginated-history-writer-boundary) for guarantees and concurrent-writer limits. +Paginated and migration-capable history follows the [authoritative writer contract](codex-home.md#paginated-history-writer-boundary); this document adds no independent writer guarantee. Codex pool settings and their consumers follow the [reset-first ordering contract](providers/openai-tiers.md#reset-first-account-ordering), including independent-quota fallback, preserved affinity, strategy-specific threshold summaries, and shared short-observation freshness for switch warnings. diff --git a/structure/config.md b/structure/config.md index 04520f2cd07..5046d6e9ed0 100644 --- a/structure/config.md +++ b/structure/config.md @@ -408,9 +408,7 @@ so any not-served-here answer stays legible rather than printing a bare token. ` `src/cli/models-runtime.ts` narrows the opposite case: only a 404 without those keys is the management handler's own unknown-id answer, and it names the id and `ocx models list-custom`. -## Paginated history writer boundary - -`src/codex/history-provider.ts` refuses external writes to paginated or migration-capable history. `src/codex/inject.ts` checks affected rows and manifest-owned restore targets before and after config/profile/journal changes, including successful journal and fallback restores, and compensates detected migration. Failed config restore stops later catalog/history work and rolls back a coordinated remove transition. See the [history writer contract](codex-home.md#paginated-history-writer-boundary) for guarantees and concurrent-writer limits. +Paginated and migration-capable history follows the [authoritative writer contract](codex-home.md#paginated-history-writer-boundary); this document adds no independent writer guarantee. Private pool credential metadata follows the [quota-history publication identity contract](providers/openai-tiers.md#quota-history-publication-identity); credential-only and account DTO projections omit it. diff --git a/structure/gui-and-management-api.md b/structure/gui-and-management-api.md index f5340bcfad0..9935ba95946 100644 --- a/structure/gui-and-management-api.md +++ b/structure/gui-and-management-api.md @@ -683,9 +683,7 @@ its defaults and exclusions are owned by [Responses transport](transports/respon The provider editor field policy exposes `showThinkingSummary` as a boolean provider option; it controls Responses summary defaults without a dashboard rendering change. See [Google provider](providers/google.md). -## Paginated history writer boundary - -`src/codex/history-provider.ts` refuses external writes to paginated or migration-capable history. `src/codex/inject.ts` checks affected rows and manifest-owned restore targets before and after config/profile/journal changes, including successful journal and fallback restores, and compensates refused restore/removal transitions. Failed config restore stops later catalog/history work and rolls back a coordinated remove transition. Apply retains an existing provider definition before candidate admission even when history preflight passes, so migration after artifact commit or during worker startup cannot leave earlier conversations without their provider. See the [history writer contract](codex-home.md#paginated-history-writer-boundary) for guarantees and concurrent-writer limits. +Paginated and migration-capable history follows the [authoritative writer contract](codex-home.md#paginated-history-writer-boundary); this document adds no independent writer guarantee. Codex pool settings and their consumers follow the [reset-first ordering contract](providers/openai-tiers.md#reset-first-account-ordering), including independent-quota fallback, preserved affinity, strategy-specific threshold summaries, and shared short-observation freshness for switch warnings. Codex account DTOs and cards expose the routing-plan exclusion separately from credential health; the [plan exclusion contract](providers/openai-tiers.md#automatic-pool-plan-exclusions) also governs CLI projection. Private pool credential metadata follows the [quota-history publication identity contract](providers/openai-tiers.md#quota-history-publication-identity); credential-only and account DTO projections omit it. diff --git a/structure/manifest.json b/structure/manifest.json index 1337f774e5c..cbd3c7da0fc 100644 --- a/structure/manifest.json +++ b/structure/manifest.json @@ -401,6 +401,77 @@ ] } ], + "contracts": { + "version": 1, + "entries": [ + { + "id": "paginated-history-writer", + "owner": { + "document": "codex-home.md", + "anchor": "paginated-history-writer-boundary" + }, + "dependents": [ + "catalog.md", + "config.md", + "gui-and-management-api.md", + "ops/docs-and-release.md", + "providers/openai-tiers.md", + "runtime.md", + "subagents.md" + ] + }, + { + "id": "request-copy-accounting", + "owner": { + "document": "transports/byte-accounting.md", + "anchor": "request-copy-accounting" + }, + "dependents": [ + "adapters/registry.md", + "catalog.md", + "clients/claude-desktop.md", + "clients/integrations.md", + "data-planes/images.md", + "data-planes/inbound-compat.md", + "ops/docs-and-release.md", + "ops/service-and-sidecars.md", + "overview.md", + "providers/chat-compat.md", + "providers/cursor.md", + "providers/xai-grok.md", + "runtime.md", + "subagents.md", + "transports/inventory.md", + "transports/streaming-health.md" + ] + }, + { + "id": "stream-buffer-accounting", + "owner": { + "document": "transports/byte-accounting.md", + "anchor": "stream-buffer-accounting" + }, + "dependents": [ + "adapters/registry.md", + "catalog.md", + "clients/claude-desktop.md", + "clients/integrations.md", + "data-planes/images.md", + "data-planes/inbound-compat.md", + "ops/docs-and-release.md", + "ops/service-and-sidecars.md", + "overview.md", + "providers/chat-compat.md", + "providers/cursor.md", + "providers/xai-grok.md", + "runtime.md", + "subagents.md", + "transports/inventory.md", + "transports/streaming-health.md" + ] + } + ] + }, "grace": { "undocumentedSourceAreas": [ { diff --git a/structure/ops/docs-and-release.md b/structure/ops/docs-and-release.md index c2ba4401ec2..cf6de0f2317 100644 --- a/structure/ops/docs-and-release.md +++ b/structure/ops/docs-and-release.md @@ -167,6 +167,12 @@ invariants belong in `structure/`, not the README. manual. When an investigation graduates into a maintained invariant, summarize it here under `structure/` and link public workflows from `docs-site/`. +Cross-cutting structure contracts are maintained by editing `structure/manifest.json`, the authority +statement, and any dependent whose local explanation changes. Regenerate `structure/INDEX.md` with +the owning command and require the structure check in hosted CI. The +[structure rules](../AGENTS.md#the-source-to-doc-map) retain review of every document mapped to a +changed source area even when no text edit is needed. + ## Branch and devlog policy [`AGENTS.md`](../../AGENTS.md) and [`MAINTAINERS.md`](../../MAINTAINERS.md) are authoritative; this section @@ -414,9 +420,7 @@ its defaults and exclusions are owned by [Responses transport](../transports/res Provider configuration documents distinguish actual summaries from raw reasoning content. The test layout registers the summary-default contract cases and removes the obsolete content-rewrite test with its implementation. -## Paginated history writer boundary - -`src/codex/history-provider.ts` refuses external writes to paginated or migration-capable history. `src/codex/inject.ts` checks affected rows and manifest-owned restore targets before and after config/profile/journal changes, including successful journal and fallback restores, and compensates refused restore/removal transitions. Failed config restore stops later catalog/history work and rolls back a coordinated remove transition. Apply retains an existing provider definition before candidate admission even when history preflight passes, so migration after artifact commit or during worker startup cannot leave earlier conversations without their provider. See the [history writer contract](../codex-home.md#paginated-history-writer-boundary) for guarantees and concurrent-writer limits. +Paginated and migration-capable history follows the [authoritative writer contract](../codex-home.md#paginated-history-writer-boundary); this document adds no independent writer guarantee. Private pool credential metadata follows the [quota-history publication identity contract](../providers/openai-tiers.md#quota-history-publication-identity); credential-only and account DTO projections omit it. diff --git a/structure/overview.md b/structure/overview.md index dc28991c5ed..fb5b287d5e7 100644 --- a/structure/overview.md +++ b/structure/overview.md @@ -140,6 +140,11 @@ processes are one logical runner, while each process still installs its own isol guards. The workflow contract and process bounds live in [`ops/docs-and-release.md`](ops/docs-and-release.md#cross-platform-ci). +`structure/manifest.json` declares both source-review coverage and cross-cutting contract authority. +`scripts/structure-ssot.ts` validates that topology, and generated `structure/INDEX.md` publishes it. +The [structure rules](AGENTS.md#the-source-to-doc-map) define when review requires a content edit; +contract authority never reduces the source map's many-to-many review fan-out. + Two invariants are stated here without a binding, and `grace.unboundInvariants` in [`manifest.json`](manifest.json) carries the reason for each. They are true statements about the system; no test in this repository currently pins them, and saying so is more useful than naming a test that diff --git a/structure/providers/openai-tiers.md b/structure/providers/openai-tiers.md index 9ef2da5fa63..c9479b1b051 100644 --- a/structure/providers/openai-tiers.md +++ b/structure/providers/openai-tiers.md @@ -599,8 +599,7 @@ Listener startup diagnostics follow [the runtime lifecycle contract](../runtime. `src/codex/routing/selection.ts` applies optional `codexPool.excludedPlans` to both candidate selection and existing active/affined accounts. An all-excluded pool returns no automatic candidate, including preview and configured-account fallback. Native main remains exempt and unknown plans remain eligible. Explicit account-qualified routes retain pause, credential and entitlement checks while bypassing only this automatic policy. `src/codex/auth-api/account-list.ts` projects `selectionExcludedReason: "plan_excluded"` and `selectionExcludedPlan` from the routing config, even when a newer display-only WHAM plan could not be persisted. The dashboard and account CLI show the policy reason separately from credential health; renewal clears the derived fields. The automatic next-session action and badge are omitted for excluded rows. -## Paginated history writer boundary -`src/codex/history-provider.ts` refuses external writes to paginated or migration-capable history. `src/codex/inject.ts` checks affected rows and manifest-owned restore targets before and after config/profile/journal changes, including successful journal and fallback restores, and compensates refused restore/removal transitions. Failed config restore stops later catalog/history work and rolls back a coordinated remove transition. Apply retains an existing provider definition before candidate admission even when history preflight passes, so migration after artifact commit or during worker startup cannot leave earlier conversations without their provider. See the [history writer contract](../codex-home.md#paginated-history-writer-boundary) for guarantees and concurrent-writer limits. +Paginated and migration-capable history follows the [authoritative writer contract](../codex-home.md#paginated-history-writer-boundary); this document adds no independent writer guarantee. The [explicit model-capability contract](../config.md#explicit-per-model-capability-declarations) preserves operator declarations through provider storage and catalog capture; it does not infer upstream capability or change this surface's routing behavior. diff --git a/structure/runtime.md b/structure/runtime.md index fc99bb89ded..983881c21fe 100644 --- a/structure/runtime.md +++ b/structure/runtime.md @@ -355,9 +355,7 @@ The relay is transparent in both directions, and that includes the close: a down `OCX_LIVE_FRAME_LOG` records both frame metadata and sideband lifecycle stages (`upstream-open`, `upstream-failed`, `relay-attached`, `relay-closed`) in one JSONL, content-free in both shapes. The lifecycle half is what separates a join that never reached this proxy from one whose upstream handshake was refused and from a live relay that carried nothing; frame records alone leave all three as an empty file. `tests/server/server-live-realtime-fixtures.test.ts` drives each sideband stage against de-identified Frameless v3 fixtures in `tests/fixtures/realtime-voice-sideband/` so a failure names the stage. -## Paginated history writer boundary - -`src/codex/history-provider.ts` refuses external writes to paginated or migration-capable history. `src/codex/inject.ts` checks affected rows and manifest-owned restore targets before and after config/profile/journal changes, including successful journal and fallback restores, and compensates refused restore/removal transitions. Failed config restore stops later catalog/history work and rolls back a coordinated remove transition. Apply retains an existing provider definition before candidate admission even when history preflight passes, so migration after artifact commit or during worker startup cannot leave earlier conversations without their provider. See the [history writer contract](codex-home.md#paginated-history-writer-boundary) for guarantees and concurrent-writer limits. +Paginated and migration-capable history follows the [authoritative writer contract](codex-home.md#paginated-history-writer-boundary); this document adds no independent writer guarantee. Codex pool settings and their consumers follow the [reset-first ordering contract](providers/openai-tiers.md#reset-first-account-ordering), including independent-quota fallback, preserved affinity, strategy-specific threshold summaries, and shared short-observation freshness for switch warnings. diff --git a/structure/subagents.md b/structure/subagents.md index 527b2b37523..a607de463e3 100644 --- a/structure/subagents.md +++ b/structure/subagents.md @@ -361,9 +361,7 @@ its defaults and exclusions are owned by [Responses transport](transports/respon Final-route summary visibility is recomputed after fallback from the original Responses preference; an earlier provider opt-in does not carry into a later provider. See [reasoning presentation](providers/chat-compat.md). -## Paginated history writer boundary - -`src/codex/history-provider.ts` refuses external writes to paginated or migration-capable history. `src/codex/inject.ts` checks affected rows and manifest-owned restore targets before and after config/profile/journal changes, including successful journal and fallback restores, and compensates refused restore/removal transitions. Failed config restore stops later catalog/history work and rolls back a coordinated remove transition. Apply retains an existing provider definition before candidate admission even when history preflight passes, so migration after artifact commit or during worker startup cannot leave earlier conversations without their provider. See the [history writer contract](codex-home.md#paginated-history-writer-boundary) for guarantees and concurrent-writer limits. +Paginated and migration-capable history follows the [authoritative writer contract](codex-home.md#paginated-history-writer-boundary); this document adds no independent writer guarantee. Codex pool settings and their consumers follow the [reset-first ordering contract](providers/openai-tiers.md#reset-first-account-ordering), including independent-quota fallback, preserved affinity, strategy-specific threshold summaries, and shared short-observation freshness for switch warnings. diff --git a/tests/ci-workflows/structure-ssot.test.ts b/tests/ci-workflows/structure-ssot.test.ts index 4783842bca1..6f3d3c7de5a 100644 --- a/tests/ci-workflows/structure-ssot.test.ts +++ b/tests/ci-workflows/structure-ssot.test.ts @@ -1,8 +1,8 @@ import { afterEach, describe, expect, test } from "bun:test"; -import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs"; +import { copyFileSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { dirname, join } from "node:path"; -import { loadManifest, renderIndex, runStructureChecks, type Manifest } from "../../scripts/structure-ssot"; +import { loadManifest, renderIndex, runStructureChecks, writeGeneratedIndex, type Manifest } from "../../scripts/structure-ssot"; import { repoRoot } from "../helpers/repo-root"; /** @@ -82,6 +82,30 @@ function scaffold(): string { return root; } +/** Add one valid authority and a second doc that preserves many-to-many source review. */ +function contractScaffold(): string { + const root = scaffold(); + const manifest = manifestOf(root); + manifest.docs.push({ path: "second.md", tier: 1, title: "Second", scope: "second scope", documents: ["src/alpha/"] }); + manifest.contracts = { + version: 1, + entries: [ + { + id: "alpha-contract", + owner: { document: "overview.md", anchor: "non-negotiable-invariants" }, + dependents: ["second.md"], + }, + ], + }; + write( + root, + "structure/second.md", + "# Second\n\nAlpha uses " + BT + "src/alpha/keep.ts" + BT + ".\n\nSee the [alpha contract](overview.md#non-negotiable-invariants).\n", + ); + saveManifest(root, manifest); + return root; +} + const fires = (root: string, needle: string): void => { expect(runStructureChecks(root).join("\n")).toContain(needle); }; @@ -111,6 +135,12 @@ describe("structure/ SSOT", () => { expect(runStructureChecks(scaffold())).toEqual([]); }); + test("contracts are optional", () => { + const root = scaffold(); + expect(manifestOf(root).contracts).toBeUndefined(); + expect(runStructureChecks(root)).toEqual([]); + }); + test("a doc on disk that the manifest does not list", () => { const root = scaffold(); write(root, "structure/orphan.md", "# Orphan\n"); @@ -329,6 +359,140 @@ describe("structure/ SSOT", () => { expect(runStructureChecks(root)).toEqual([]); }); + test("contract manifest shapes fail with actionable errors", () => { + const valid = manifestOf(scaffold()); + const cases: [unknown, string][] = [ + [[], "contracts must be an object"], + [{ version: 2, entries: [] }, "contracts.version must be 1"], + [{ version: 1, entries: {} }, "contracts.entries must be an array"], + [{ version: 1, entries: [{ id: "Not Kebab", owner: {}, dependents: [] }] }, "id must be a kebab-case string"], + [{ version: 1, entries: [{ id: "valid-id", owner: null, dependents: [] }] }, "owner must be an object"], + [{ version: 1, entries: [{ id: "valid-id", owner: { document: 1, anchor: 2 }, dependents: [] }] }, "owner.document must be a string"], + [{ version: 1, entries: [{ id: "valid-id", owner: { document: "overview.md", anchor: "overview" }, dependents: {} }] }, "dependents must be an array"], + [{ version: 1, entries: [{ id: "valid-id", owner: { document: "overview.md", anchor: "overview" }, dependents: [1] }] }, "dependents[0] must be a string"], + ]; + for (const [contracts, needle] of cases) { + const loaded = loadManifest(JSON.stringify({ ...valid, contracts })); + expect(loaded).toHaveProperty("error"); + expect((loaded as { error: string }).error).toContain(needle); + } + }); + + test("duplicate contract ids are rejected", () => { + const root = contractScaffold(); + const manifest = manifestOf(root); + manifest.contracts!.entries.push({ + id: "alpha-contract", + owner: { document: "overview.md", anchor: "non-negotiable-invariants" }, + dependents: [], + }); + saveManifest(root, manifest); + fires(root, "contract alpha-contract is declared twice"); + }); + + test("contract owners must be declared files with real anchors", () => { + const undeclared = contractScaffold(); + const undeclaredManifest = manifestOf(undeclared); + undeclaredManifest.contracts!.entries[0]!.owner.document = "ghost.md"; + saveManifest(undeclared, undeclaredManifest); + fires(undeclared, "owner ghost.md is not a declared structure document"); + + const missing = contractScaffold(); + const missingManifest = manifestOf(missing); + missingManifest.docs.push({ path: "ghost.md", tier: 1, title: "Ghost", scope: "ghost", documents: [] }); + missingManifest.contracts!.entries[0]!.owner.document = "ghost.md"; + saveManifest(missing, missingManifest); + fires(missing, "owner structure/ghost.md is missing"); + + const anchor = contractScaffold(); + const anchorManifest = manifestOf(anchor); + anchorManifest.contracts!.entries[0]!.owner.anchor = "missing-heading"; + saveManifest(anchor, anchorManifest); + fires(anchor, "owner structure/overview.md has no #missing-heading heading anchor"); + }); + + test("contract dependents must be unique declared files distinct from the owner", () => { + const duplicate = contractScaffold(); + const duplicateManifest = manifestOf(duplicate); + duplicateManifest.contracts!.entries[0]!.dependents.push("second.md"); + saveManifest(duplicate, duplicateManifest); + fires(duplicate, "lists dependent second.md twice"); + + const owner = contractScaffold(); + const ownerManifest = manifestOf(owner); + ownerManifest.contracts!.entries[0]!.dependents = ["overview.md"]; + saveManifest(owner, ownerManifest); + fires(owner, "lists its owner overview.md as a dependent"); + + const undeclared = contractScaffold(); + const undeclaredManifest = manifestOf(undeclared); + undeclaredManifest.contracts!.entries[0]!.dependents = ["ghost.md"]; + saveManifest(undeclared, undeclaredManifest); + fires(undeclared, "dependent ghost.md is not a declared structure document"); + + const missing = contractScaffold(); + const missingManifest = manifestOf(missing); + missingManifest.docs.push({ path: "ghost.md", tier: 1, title: "Ghost", scope: "ghost", documents: [] }); + missingManifest.contracts!.entries[0]!.dependents = ["ghost.md"]; + saveManifest(missing, missingManifest); + fires(missing, "dependent structure/ghost.md is missing"); + }); + + test("a contract dependent must link the exact owner anchor", () => { + const root = contractScaffold(); + write(root, "structure/second.md", "# Second\n\nAlpha uses " + BT + "src/alpha/keep.ts" + BT + ".\n\nSee [Overview](overview.md).\n"); + fires(root, "dependent structure/second.md does not link overview.md#non-negotiable-invariants"); + }); + + test("a valid contract keeps many-to-many source review", () => { + const root = contractScaffold(); + expect(runStructureChecks(root)).toEqual([]); + expect(renderIndex(manifestOf(root))).toContain( + "| " + BT + "src/alpha/" + BT + " | [" + BT + "overview.md" + BT + "](overview.md)
    [" + BT + "second.md" + BT + "](second.md) |", + ); + }); + + test("contract navigation has deterministic ordering and placement", () => { + const root = contractScaffold(); + const manifest = manifestOf(root); + manifest.docs.push({ path: "third.md", tier: 1, title: "Third", scope: "third scope", documents: [] }); + manifest.contracts!.entries = [ + { + id: "zeta-contract", + owner: { document: "overview.md", anchor: "non-negotiable-invariants" }, + dependents: [], + }, + { + id: "alpha-contract", + owner: { document: "overview.md", anchor: "non-negotiable-invariants" }, + dependents: ["third.md", "second.md"], + }, + ]; + const rendered = renderIndex(manifest); + const contracts = rendered.indexOf("## Cross-cutting contracts"); + const decisions = rendered.indexOf("## Decision records"); + const alpha = rendered.indexOf("| " + BT + "alpha-contract" + BT + " |"); + const zeta = rendered.indexOf("| " + BT + "zeta-contract" + BT + " |"); + expect(contracts).toBeGreaterThan(rendered.indexOf("### Not described by any doc")); + expect(decisions).toBeGreaterThan(contracts); + expect(alpha).toBeGreaterThan(contracts); + expect(zeta).toBeGreaterThan(alpha); + expect(rendered.slice(alpha, zeta)).toContain( + "[" + BT + "second.md" + BT + "](second.md)
    [" + BT + "third.md" + BT + "](third.md)", + ); + expect(rendered).toContain( + "[" + BT + "overview.md#non-negotiable-invariants" + BT + "](overview.md#non-negotiable-invariants)", + ); + expect(rendered.slice(zeta, decisions)).toContain("| — |"); + }); + + test("contract checks validate topology rather than owner prose", () => { + const root = contractScaffold(); + const owner = readFileSync(join(root, "structure/overview.md"), "utf8").replace("alpha keeps working", "alpha remains available"); + write(root, "structure/overview.md", owner); + expect(runStructureChecks(root)).toEqual([]); + }); + test("a malformed manifest is an actionable failure, not a stack trace", () => { expect(loadManifest("{not json")).toHaveProperty("error"); const shapeless = loadManifest(JSON.stringify({ sizeBudgetLines: 600 })); @@ -401,4 +565,71 @@ describe("structure/ SSOT", () => { write(root, "structure/manifest.json", JSON.stringify(manifest, null, 2) + "\n"); fires(root, "absentPaths[0].path must be a string"); }); + + test("index generation validates the manifest before writing", () => { + const root = scaffold(); + const before = readFileSync(join(root, "structure/INDEX.md"), "utf8"); + const manifest = manifestOf(root) as unknown as { contracts: unknown }; + manifest.contracts = { version: 1, entries: "not-an-array" }; + write(root, "structure/manifest.json", JSON.stringify(manifest, null, 2) + "\n"); + const result = writeGeneratedIndex(root); + expect(result).toHaveProperty("error"); + expect((result as { error: string }).error).toContain("contracts.entries must be an array"); + expect(readFileSync(join(root, "structure/INDEX.md"), "utf8")).toBe(before); + }); + + test("index generation rejects a malformed contract entry without a renderer crash", () => { + const root = scaffold(); + const before = readFileSync(join(root, "structure/INDEX.md"), "utf8"); + const manifest = manifestOf(root) as unknown as { contracts: unknown }; + // A bare string entry used to reach the renderer's id comparator and throw a TypeError. + manifest.contracts = { version: 1, entries: ["oops"] }; + write(root, "structure/manifest.json", JSON.stringify(manifest, null, 2) + "\n"); + const result = writeGeneratedIndex(root); + expect(result).toHaveProperty("error"); + expect((result as { error: string }).error).toContain("id must be a kebab-case string"); + expect(readFileSync(join(root, "structure/INDEX.md"), "utf8")).toBe(before); + }); + + // The seam-level tests above prove the helper; these two drive the real CLI tail, which is + // where the original bug lived (parse + cast + render before validation). The script is + // copied into the scaffold so its import.meta.dir resolves to the synthetic root. + function scaffoldCli(root: string): void { + mkdirSync(join(root, "scripts"), { recursive: true }); + copyFileSync(join(repoRoot(), "scripts/structure-ssot.ts"), join(root, "scripts/structure-ssot.ts")); + } + + test("CLI --fix fails malformed contracts with a named diagnostic and an unchanged index", () => { + const root = scaffold(); + scaffoldCli(root); + const before = readFileSync(join(root, "structure/INDEX.md"), "utf8"); + const manifest = manifestOf(root) as unknown as { contracts: unknown }; + manifest.contracts = { version: 1, entries: "not-an-array" }; + write(root, "structure/manifest.json", JSON.stringify(manifest, null, 2) + "\n"); + const result = Bun.spawnSync([process.execPath, "scripts/structure-ssot.ts", "--fix"], { + cwd: root, + stdout: "pipe", + stderr: "pipe", + }); + expect(result.exitCode).not.toBe(0); + const stderr = result.stderr.toString(); + expect(stderr).toContain("contracts.entries must be an array"); + expect(stderr).not.toContain("TypeError"); + expect(readFileSync(join(root, "structure/INDEX.md"), "utf8")).toBe(before); + }); + + test("CLI --fix regenerates a stale index for a valid manifest", () => { + const root = scaffold(); + scaffoldCli(root); + write(root, "structure/INDEX.md", "# stale\n"); + const result = Bun.spawnSync([process.execPath, "scripts/structure-ssot.ts", "--fix"], { + cwd: root, + stdout: "pipe", + stderr: "pipe", + }); + expect(result.exitCode).toBe(0); + const regenerated = readFileSync(join(root, "structure/INDEX.md"), "utf8"); + expect(regenerated).not.toBe("# stale\n"); + expect(regenerated).toBe(renderIndex(manifestOf(root))); + }); }); From 26d3a862d6ebfa406701c76a6fbe25570a58ac76 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 20:06:06 +0900 Subject: [PATCH 30/97] feat(devin): admit every inference send through the shared budget (#5152) * feat(devin): admit every inference send through the shared budget PR #5041 shipped a pre-output replay of a stated rate-limit reset and recorded what it left undone: those inner sends never reached the request-wide send budget, the provider fetch wrapper, or physical-attempt accounting. A turn could therefore make three real inference requests while the shared cap, the pacing slot and the request log each saw one. All three now go through the existing shared physical-send primitive, so a permit is reserved once per actual send, confirmed at the wire boundary, and refunded when admission succeeded but no request followed. Nothing increments a counter directly and no second counter exists. The initial send is not double-charged: the adapter reserves it as ordinal 1, and the request observer already ignores ordinal 1 because the caller records the entry send itself. A replay the budget refuses makes no inference request, records why recovery was withheld, and surfaces the provider's original 429 rather than a local budget error, so the server-stated reset and any outer cooldown behavior survive. Reservation still happens after the stated wait, not before it, so a one-hour wait does not hold a spend booking open for an hour. Catalog and JWT calls are not inference sends and keep the global fetch. * test(responses): admit the Devin row so the counted send actually happens The case asserted one GetChatMessage call and got none, in thirteen milliseconds with no adapter output: the turn was refused before the adapter ran. The devin registry entry declares authKind "oauth", and an omitted authMode inherits it, so the fixture's row demanded an OAuth credential while supplying an apiKey. It now states authMode "key", which is what the working sibling fixture in this file does and what the supplied credential actually is. Both numbers are now asserted together and carry the response status and body in the failure message, so a turn that never reaches the adapter says so instead of presenting as an empty URL list. * test(responses): route the Devin count case through a stored credential The authMode guess was wrong: the case still recorded no send. Devin is an OAuth-kind provider, and the key its adapter uses is injected onto the row from the stored credential, so a config carrying only apiKey never routes and the turn ends before the adapter. The case now seeds the credential the same way the working Devin fixture does, which is the path production takes, and the catalog is keyed to that same value. The assertion is unchanged: one GetChatMessage call and one recorded send, reported together with the response status and body so the next failure is self-describing. * fix(devin): count the first inference send where it is admitted Review found the accounting still describing an intention rather than a send. runTurnAttempt logs the attempt's first send before handing control to the adapter, which is right for a transport whose sends the caller performs. Devin now admits its own sends through the shared budget, so that first send can be refused - and once earlier combo or empty-recovery sends have spent the allowance, the log claimed a request the wire never made. An adapter that reports every physical send now says so, and for those the caller stops pre-logging and the observer counts ordinal 1 at the executor boundary that actually dispatched it. Every other adapter and call site is unchanged, including the ordinal-1 skip they rely on. An attempt-level recovery kind still labels that first send when the adapter supplies none of its own. * test(devin): pin that a refused first send is neither made nor counted The accounting fix needs the case that exposed it: an allowance already spent before this turn starts, which is what an earlier combo fan-out or empty-response recovery leaves behind. Nothing reaches GetChatMessage, nothing is observed as a physical send, and the budget records nothing - where the previous ordering would have logged a send the wire never made. The admitted case beside it still asserts exactly one call, one observation at ordinal 1, and one charged send, so the fix cannot be satisfied by counting less. * test(responses): pin the refused Devin send at the request boundary The direct-adapter case cannot see the defect it was written for. The phantom send was logged by executeResponsesRunTurn before the adapter ran, so only a case that goes through handleResponses with a RequestLogContext can prove the attempt records nothing. This one puts Devin last in a failover combo behind a chat target that spends the allowance first, which is the shape that leaves nothing for Devin's initial send. It asserts no GetChatMessage request and a Devin attempt sendCount of zero, and that the members which did send still account for themselves - so the fix removes a phantom rather than suppressing real counts. The status and body travel in the failure message. The direct-adapter case stays for what it does cover, the executor side, and no longer carries the claim that it pins the outer behavior. * test(responses): force the refusal instead of arranging it through a combo Review traced the arithmetic: a two-target combo has five total sends against a base of four, the first target settles a counted booking leaving three, the transition books the fourth, and Devin's initial send was still admitted at five. The case therefore never reached the denied path, and an optional attempt lookup let an absent attempt satisfy a zero count. The budget is now handed to handleResponses already spent, built by the real factory rather than inferred from combo behaviour. The assertions are the ones that prove a refusal: exactly one attempt, that attempt is Devin's and its sendCount is zero, no GetChatMessage request, zero total sends, and the response carries request_send_budget_exhausted. Status and body travel in the failure message. This row fails against the eager pre-log it was written for: that path recorded the attempt's send before the adapter ran, so sendCount would read one. --- src/adapters/base.ts | 23 +++ src/adapters/devin.ts | 15 ++ src/adapters/devin/cloud-direct/chat.ts | 4 +- .../devin/cloud-direct/stated-reset-retry.ts | 47 +++++- src/server/responses/request-send-budget.ts | 6 +- src/server/responses/run-turn-execution.ts | 27 +++- structure/adapters/registry.md | 3 + structure/providers-and-adapters.md | 1 + structure/transports/responses.md | 13 +- .../adapter-inner-send-budget-wiring.test.ts | 117 ++++++++++++++ .../adapter-inner-send-budget.test.ts | 21 +++ tests/providers/devin-adapter.test.ts | 5 +- .../devin-stated-reset-hardening.test.ts | 20 ++- .../devin-stated-reset-retry.test.ts | 72 +++++++++ .../responses-send-budget-counts.test.ts | 148 ++++++++++++++++++ 15 files changed, 504 insertions(+), 18 deletions(-) diff --git a/src/adapters/base.ts b/src/adapters/base.ts index fff735ed98a..0efce92e5b7 100644 --- a/src/adapters/base.ts +++ b/src/adapters/base.ts @@ -31,11 +31,34 @@ export interface IncomingMeta { * behind it (#4546). */ sendBudget?: RequestExecutionBudget; + /** + * Physical-send observations for runTurn adapters. Without the same callback carried by + * AdapterFetchContext, an adapter-owned replay spends the shared budget but remains absent + * from the request's sendCount. + */ + onPhysicalSend?: (send: { ordinal: number; recovery?: AttemptRecoveryKind }) => void; + /** + * Recovery refusals for runTurn adapters. A refused replay is not a send, so this separate + * channel explains why recovery stopped without inflating physical-send telemetry. + */ + onRecoveryWithheld?: (withheld: { reason: AttemptRecoveryWithheld }) => void; } export interface ProviderAdapter { name: string; + /** + * This adapter reports every physical inference send through `IncomingMeta.onPhysicalSend`, + * including its first. + * + * The caller normally logs the first send before handing control over, which is correct for a + * transport whose sends it can see. An adapter that admits its own sends through the shared + * budget can have that first send refused, and a send logged before admission is a send the + * log claims and the wire never made. Setting this moves the first send's accounting to the + * boundary where it is actually dispatched. + */ + reportsPhysicalSends?: boolean; + /** * Convert an already-read provider HTTP error into client-safe text. This hook must be pure and * return fully redacted output: callers may pass untrusted provider headers and payload text. diff --git a/src/adapters/devin.ts b/src/adapters/devin.ts index 0ff3b7da335..082cde39d0d 100644 --- a/src/adapters/devin.ts +++ b/src/adapters/devin.ts @@ -15,6 +15,7 @@ import { getCachedCatalog, type CacheEntry } from "./devin/cloud-direct/catalog" import { collapseDevinModelUid } from "./devin/live-models"; import { buildNonOpenAIToolCatalogNudgeForTools } from "./tool-catalog-nudge"; import { DEVIN_DEFAULT_API_SERVER, resolveDevinApiServer } from "../oauth/devin"; +import { SendBudgetExhaustedError } from "../lib/upstream-retry"; /** * Combine two usage frames from one turn by keeping the larger count per field. @@ -490,6 +491,10 @@ export function createDevinAdapter( return { name: "devin", + // Every GetChatMessage send, including the first, is admitted through the shared budget and + // reported from the executor that dispatches it. The caller therefore leaves the first + // send's accounting here rather than logging it before admission can refuse it. + reportsPhysicalSends: true, buildRequest() { return { @@ -584,6 +589,13 @@ export function createDevinAdapter( ...(typeof parsed.options.topP === "number" ? { topP: parsed.options.topP } : {}), }, signal: incoming.abortSignal, + }, { + execution: { + executor: incoming.providerFetch, + sendBudget: incoming.sendBudget, + onPhysicalSend: incoming.onPhysicalSend, + onRecoveryWithheld: incoming.onRecoveryWithheld, + }, })) { if (incoming.abortSignal?.aborted) { // Emitting nothing here left the bridge to synthesize adapter_eof. @@ -662,6 +674,9 @@ export function createDevinAdapter( emit({ type: "error", message: DEVIN_CLIENT_CLOSED_MESSAGE, status: 499, retryable: false, ...(usage ? { usage } : {}) }); return; } + // The Responses boundary already maps this local refusal to its structured 429 code. + // Converting it to an adapter event would make it an ordinary untyped upstream error. + if (error instanceof SendBudgetExhaustedError) throw error; const message = error instanceof CloudChatError ? ("Devin cloud error" + (error.code ? " " + error.code : "") + ": " + error.message) : error instanceof Error ? error.message : String(error); diff --git a/src/adapters/devin/cloud-direct/chat.ts b/src/adapters/devin/cloud-direct/chat.ts index 794c5cddf22..34547ecc193 100644 --- a/src/adapters/devin/cloud-direct/chat.ts +++ b/src/adapters/devin/cloud-direct/chat.ts @@ -1055,6 +1055,8 @@ export interface CloudChatRequest { catalog?: CacheEntry | null; /** Abort signal — closes the fetch stream. */ signal?: AbortSignal; + /** Executor for the inference POST only; catalog and JWT RPCs retain their own transport. */ + executor?: typeof globalThis.fetch; } export class CloudChatError extends Error { @@ -1216,7 +1218,7 @@ export async function* streamChatEvents(req: CloudChatRequest): AsyncGenerator; } function replayLimit(value: number | undefined): number { @@ -59,15 +66,34 @@ export async function* streamChatEventsWithResetRetry( const sleep = options?.sleep ?? sleepWithAbort; const maxReplays = replayLimit(options?.maxReplays); const maxWaitMs = waitLimit(options?.maxWaitMs); + const execution = options?.execution; + // One sender owns the whole invocation so ordinals span the initial POST and both replays. + // Its executor remains lazy: replay admission happens after the provider-stated wait, never + // while a reservation could be held for up to an hour. + const send = execution + ? createAdapterPhysicalSend({ ...execution, abortSignal: req.signal }) + : undefined; let replays = 0; let waitedMs = 0; + let replaySourceError: CloudChatError | undefined; while (true) { // Check again after sleeping: cancellation can race with timer completion. // A pre-aborted request must not even enter a custom transport. if (req.signal?.aborted) throw abortError(req.signal); let yielded = false; try { - for await (const event of stream(req)) { + const recovery = replays > 0 ? "rate-limit-429" as const : undefined; + const attemptRequest = send + ? { + ...req, + executor: ((input, init) => send({ + url: typeof input === "string" ? input : input instanceof URL ? input.href : input.url, + ...(recovery ? { sendClass: "auth-recovery" as const, recovery } : {}), + dispatch: executor => executor(input, init), + })) as typeof globalThis.fetch, + } + : req; + for await (const event of stream(attemptRequest)) { // Latch before yielding, so a consumer-injected error is post-output. yielded = true; yield event; @@ -75,14 +101,24 @@ export async function* streamChatEventsWithResetRetry( return; } catch (error) { if (req.signal?.aborted) throw abortError(req.signal); - const waitSec = !yielded + if (!yielded && error instanceof SendBudgetExhaustedError && replaySourceError) { + // The provider's refusal is the real upstream answer. A local cap can withhold its + // recovery, but replacing the 429 would erase the status and stated reset metadata. + execution?.onRecoveryWithheld?.({ reason: "retry-send-budget" }); + throw replaySourceError; + } + const retryableError = !yielded && error instanceof CloudChatError && error.status === 429 - ? parseRetryAfterFromMessage(error.message) + ? error + : undefined; + const waitSec = retryableError + ? parseRetryAfterFromMessage(retryableError.message) : undefined; const waitMs = waitSec === undefined ? undefined : waitSec * 1000; if ( - waitMs === undefined + retryableError === undefined + || waitMs === undefined || replays >= maxReplays || waitMs > maxWaitMs - waitedMs ) { @@ -91,6 +127,7 @@ export async function* streamChatEventsWithResetRetry( throw error; } replays += 1; + replaySourceError = retryableError; // Charge the complete scheduled wait once, before sleeping. This is a // sleep allowance, not a wall-clock deadline on generation or timer // scheduling: waking a few milliseconds late must not reject an already diff --git a/src/server/responses/request-send-budget.ts b/src/server/responses/request-send-budget.ts index 7af8b255988..9250162da26 100644 --- a/src/server/responses/request-send-budget.ts +++ b/src/server/responses/request-send-budget.ts @@ -109,8 +109,12 @@ export function createResponsesSendBudget( const noteAdapterPhysicalSend = ( inputTokens: number | undefined, send: { ordinal: number; recovery?: AttemptRecoveryKind }, + options: { readonly includeFirst?: boolean } = {}, ): void => { - if (send.ordinal <= 1) return; + // Ordinal 1 is skipped because the caller normally records it before dispatch. An adapter + // that reports every send asks for it to be counted here instead, so that the first send is + // logged where it actually happens rather than before admission could still refuse it. + if (send.ordinal <= 1 && options.includeFirst !== true) return; noteAttemptSend(logCtx.activeAttempt, inputTokens, send.recovery); }; /** diff --git a/src/server/responses/run-turn-execution.ts b/src/server/responses/run-turn-execution.ts index 0eda0918797..dd693a3013f 100644 --- a/src/server/responses/run-turn-execution.ts +++ b/src/server/responses/run-turn-execution.ts @@ -79,7 +79,11 @@ export async function executeResponsesRunTurn( >, sendBudgetState: Pick< ResponsesSendBudget, - "adapterDispatchBudget" | "reserveCredentialHop" | "pendingHopPermit" + | "adapterDispatchBudget" + | "noteAdapterPhysicalSend" + | "noteAdapterRecoveryWithheld" + | "reserveCredentialHop" + | "pendingHopPermit" >, completionPolicy: Pick, ): Promise { @@ -100,7 +104,12 @@ export async function executeResponsesRunTurn( rememberKiroDeliveredFinalAnswer, responseStateOptions, } = requestState; - const { adapterDispatchBudget, reserveCredentialHop } = sendBudgetState; + const { + adapterDispatchBudget, + noteAdapterPhysicalSend, + noteAdapterRecoveryWithheld, + reserveCredentialHop, + } = sendBudgetState; const { emptyCompletionGuardEnabled } = completionPolicy; const { cancelResponseCompletion, @@ -146,7 +155,11 @@ export async function executeResponsesRunTurn( await waitForProviderRequestSlot(route.providerName, route.provider, route.modelId, runTurnAbort.signal); } await refreshRunTurnSelection(); - transportState.noteRoutedAttemptSend(logCtx.usageLogInputTokens, recovery); + // An adapter that reports its own sends accounts for the first one at the boundary that + // dispatches it. Logging here would claim a send that the adapter's own budget can still + // refuse, which is exactly what happens once earlier recovery has spent the allowance. + const reportsOwnSends = transportState.runTurnAdapter.reportsPhysicalSends === true; + if (!reportsOwnSends) transportState.noteRoutedAttemptSend(logCtx.usageLogInputTokens, recovery); const runTurnProviderFetch = providerFetch( route.provider, options.codexWsRuntimeIdentity, @@ -169,6 +182,14 @@ export async function executeResponsesRunTurn( // The only way the request budget reaches a transport the adapter owns. Without it // a Cursor turn's inner ladder was three physical sends the cap read as one. ...(adapterDispatchBudget ? { sendBudget: adapterDispatchBudget } : {}), + onPhysicalSend: send => noteAdapterPhysicalSend( + logCtx.usageLogInputTokens, + // The attempt's own recovery kind still labels its first send when the adapter + // does not supply one of its own. + { ...send, ...(send.recovery ?? recovery ? { recovery: send.recovery ?? recovery } : {}) }, + { includeFirst: reportsOwnSends }, + ), + onRecoveryWithheld: noteAdapterRecoveryWithheld, }, targetQueue.push, ); diff --git a/structure/adapters/registry.md b/structure/adapters/registry.md index 34d04d9eb66..75238008dfe 100644 --- a/structure/adapters/registry.md +++ b/structure/adapters/registry.md @@ -39,6 +39,9 @@ Some adapters share another adapter's routed-tool semantics while retaining inde does not. `devin-cli` survives only as a deprecated alias — `ocx login devin-cli` routes to `devin`, and a startup merge migration rewrites any saved row still keyed under the old provider id, so the registry carries one Devin provider, not two. + Its `GetChatMessage` inference POSTs, including the two bounded pre-output stated-reset + replays, pass through the request's provider executor and shared physical-send budget. + Catalog and JWT RPCs remain adapter support traffic rather than inference sends. `AdapterFactoryContext.providerId` still tells the shared adapter which configured row it is serving: the Cognition tenant is recorded on the credential, not in the registry, so the adapter has to know the row before it can resolve a host. That adapter advertises bare local diff --git a/structure/providers-and-adapters.md b/structure/providers-and-adapters.md index 1bc9a86aaf4..cf5000eb151 100644 --- a/structure/providers-and-adapters.md +++ b/structure/providers-and-adapters.md @@ -17,6 +17,7 @@ the [bounded ingestion contract](transports/inventory.md#bounded-response-ingest | `src/adapters/google.ts` | Gemini bridge. | | `src/adapters/azure.ts` | Azure OpenAI bridge. | | `src/adapters/cursor.ts`, `src/adapters/cursor/` | Cursor protobuf transport: discovery, request builder, event decoding, MCP, thread continuity, native-exec policy. | +| `src/adapters/devin.ts`, `src/adapters/devin/cloud-direct/` | Devin runTurn transport over Cognition Connect-RPC. `GetChatMessage` uses the Responses provider executor and shared physical-send budget; catalog and JWT support RPCs remain outside inference-send accounting. | | `src/adapters/kiro.ts` and `src/adapters/kiro/` | Kiro event/tool/thinking/truncation/retry handling. The original path is a facade over leaves for wire identity, reasoning, conversation state, token estimation, payload assembly, streaming, and the adapter. | | `src/adapters/mimo-free.ts` | Mimo Free transport (client identity + JWT). | | `src/adapters/image.ts`, `src/adapters/anthropic-image-guard.ts`, `src/adapters/anthropic-image-normalize.ts`, `src/adapters/anthropic-image-codec.ts` | Image conversion for adapter ingress and Anthropic-specific normalization/limits. An image's ladder position is pinned to its own identity (content hash + media type), so appending a newer image cannot re-encode older ones and bust Anthropic's prompt prefix cache (#4532). | diff --git a/structure/transports/responses.md b/structure/transports/responses.md index a449d3d149b..48fc1fb9867 100644 --- a/structure/transports/responses.md +++ b/structure/transports/responses.md @@ -956,14 +956,23 @@ The hop pays for a replay that some *other* layer dispatches, so which layer set reservation follows the dispatcher, not the ladder. A helper-routed replay reports the same physical send back through `onSendsConsumed`; that is what `countedExternally: true` names, and the reporter's first send settles the pending booking instead of adding a second charge. An adapter -that owns its transport — Kiro's reset ladder, Cursor's transport ladder — reserves once per -physical send instead, so no reporter ever arrives. Those ladders are handed +that owns its transport — Kiro's reset ladder, Cursor's transport ladder, or Devin's bounded +pre-output stated-reset replay — reserves once per physical send instead, so no reporter ever +arrives. Those ladders are handed `adapterDispatchBudget`, a live delegating view of the same budget that spends a permit passed down through `pendingHopPermit` on the adapter's first reservation and closes the booking through `permit.assumeCharge()`. Letting both charge is how one physical send became two charges, and how a spent allowance answered a 429 with a synthetic error instead of the rate limit it was recovering from (#4709). +`run-turn-execution.ts` passes the same physical-send and recovery-withheld observers used by the +request-building adapter path. Devin builds one `createAdapterPhysicalSend` for the whole +`GetChatMessage` invocation, so its initial POST and at most two same-target replays report ordinals +1, 2, and 3. The outer runTurn attempt already records ordinal 1, and the shared observer therefore +adds only ordinals above 1 to `sendCount`; the execution budget still reserves every ordinal. A +replay reserves only after its server-stated wait. If admission is refused, no inference I/O occurs, +`retry-send-budget` is recorded, and the preceding provider 429 remains the returned error. + Confirmation happens at the dispatch boundary rather than at the rotation. `adapter-dispatch.ts` passes an `onDispatch` callback that the rebuild invokes immediately before the wire, and skips it when the adapter owns dispatch: settling there first would hand that adapter a dead permit, which diff --git a/tests/adapters/adapter-inner-send-budget-wiring.test.ts b/tests/adapters/adapter-inner-send-budget-wiring.test.ts index 4b86734113b..9885c73af93 100644 --- a/tests/adapters/adapter-inner-send-budget-wiring.test.ts +++ b/tests/adapters/adapter-inner-send-budget-wiring.test.ts @@ -9,6 +9,8 @@ import { } from "../../src/adapters/cursor/thread-continuity"; import type { CursorTransport } from "../../src/adapters/cursor/transport"; import { createKiroAdapter } from "../../src/adapters/kiro"; +import { createDevinAdapter, DEVIN_API_SERVER } from "../../src/adapters/devin"; +import { setCachedCatalogForTests } from "../../src/adapters/devin/cloud-direct/catalog"; import { resetKiroThrottleStateForTests } from "../../src/adapters/kiro-retry"; import type { AdapterFetchContext } from "../../src/adapters/base"; import { encodeMessage } from "../../src/lib/eventstream-decoder"; @@ -122,6 +124,121 @@ describe("Cursor runTurn and the request send budget", () => { }); }); +describe("Devin runTurn execution wiring", () => { + test("forwards the provider executor, shared budget, and physical-send observer", async () => { + const previousHome = process.env.OPENCODEX_HOME; + const previousJwtFlag = process.env.OPENCODEX_DEVIN_SEND_USER_JWT; + const home = mkdtempSync(join(tmpdir(), "devin-send-wiring-")); + process.env.OPENCODEX_HOME = home; + delete process.env.OPENCODEX_DEVIN_SEND_USER_JWT; + const apiKey = "devin-test-key"; + setCachedCatalogForTests({ + apiKey, + host: DEVIN_API_SERVER, + fetchedAt: Date.now(), + byUid: new Map([["swe-2", { modelUid: "swe-2", label: "SWE-2", disabled: false }]]), + }); + const budget = budgetOf(1); + const observed: Array<{ ordinal: number; recovery?: string }> = []; + const urls: string[] = []; + const events: AdapterEvent[] = []; + const adapter = createDevinAdapter({ + adapter: "devin", baseUrl: DEVIN_API_SERVER, apiKey, + } as unknown as OcxProviderConfig); + + try { + await adapter.runTurn?.( + { + modelId: "swe-2", stream: true, options: {}, + context: { messages: [{ role: "user", content: "hi" }] }, + } as unknown as OcxParsedRequest, + { + headers: new Headers(), + translatorBudget: createTestTranslatorBudget(), + sendBudget: budget, + providerFetch: (async input => { + urls.push(String(input)); + return new Response("busy", { status: 500 }); + }) as typeof fetch, + onPhysicalSend: send => { observed.push(send); }, + }, + event => events.push(event), + ); + } finally { + setCachedCatalogForTests(null); + if (previousHome === undefined) delete process.env.OPENCODEX_HOME; + else process.env.OPENCODEX_HOME = previousHome; + if (previousJwtFlag === undefined) delete process.env.OPENCODEX_DEVIN_SEND_USER_JWT; + else process.env.OPENCODEX_DEVIN_SEND_USER_JWT = previousJwtFlag; + removeTreeWithRetry(home); + } + + expect(urls).toHaveLength(1); + expect(urls[0]).toContain("GetChatMessage"); + expect(budget.used).toBe(1); + expect(observed).toEqual([{ ordinal: 1 }]); + expect(events.at(-1)).toMatchObject({ type: "error", status: 500 }); + }); + + test("a first send the budget refuses makes no request and reports no send", async () => { + // The accounting defect this pins: the caller used to log this turn's first send before the + // adapter ran, so an allowance already spent by earlier recovery produced a logged send the + // wire never made. Nothing is dispatched here, so nothing may be observed either. + const previousHome = process.env.OPENCODEX_HOME; + const previousJwtFlag = process.env.OPENCODEX_DEVIN_SEND_USER_JWT; + const home = mkdtempSync(join(tmpdir(), "devin-send-denied-")); + process.env.OPENCODEX_HOME = home; + delete process.env.OPENCODEX_DEVIN_SEND_USER_JWT; + const apiKey = "devin-denied-key"; + setCachedCatalogForTests({ + apiKey, + host: DEVIN_API_SERVER, + fetchedAt: Date.now(), + byUid: new Map([["swe-2", { modelUid: "swe-2", label: "SWE-2", disabled: false }]]), + }); + // Nothing left to spend: the same state an earlier combo fan-out or empty-response recovery + // leaves behind before this turn starts. + const budget = budgetOf(0); + const observed: Array<{ ordinal: number; recovery?: string }> = []; + const urls: string[] = []; + const events: AdapterEvent[] = []; + const adapter = createDevinAdapter({ + adapter: "devin", baseUrl: DEVIN_API_SERVER, apiKey, + } as unknown as OcxProviderConfig); + + try { + await adapter.runTurn?.( + { + modelId: "swe-2", stream: true, options: {}, + context: { messages: [{ role: "user", content: "hi" }] }, + } as unknown as OcxParsedRequest, + { + headers: new Headers(), + translatorBudget: createTestTranslatorBudget(), + sendBudget: budget, + providerFetch: (async input => { + urls.push(String(input)); + return new Response("busy", { status: 500 }); + }) as typeof fetch, + onPhysicalSend: send => { observed.push(send); }, + }, + event => events.push(event), + ).catch(() => { /* the refusal escapes the adapter for the caller to map */ }); + } finally { + setCachedCatalogForTests(null); + if (previousHome === undefined) delete process.env.OPENCODEX_HOME; + else process.env.OPENCODEX_HOME = previousHome; + if (previousJwtFlag === undefined) delete process.env.OPENCODEX_DEVIN_SEND_USER_JWT; + else process.env.OPENCODEX_DEVIN_SEND_USER_JWT = previousJwtFlag; + removeTreeWithRetry(home); + } + + expect(urls.filter(url => url.includes("GetChatMessage"))).toHaveLength(0); + expect(observed).toEqual([]); + expect(budget.used).toBe(0); + }); +}); + const kiroProvider = { adapter: "kiro", baseUrl: "https://runtime.us-east-1.kiro.dev", diff --git a/tests/adapters/adapter-inner-send-budget.test.ts b/tests/adapters/adapter-inner-send-budget.test.ts index 09406cb506b..2da2597c03a 100644 --- a/tests/adapters/adapter-inner-send-budget.test.ts +++ b/tests/adapters/adapter-inner-send-budget.test.ts @@ -6,6 +6,8 @@ import type { CursorRunRequest, CursorServerMessage } from "../../src/adapters/c import type { CursorTransport } from "../../src/adapters/cursor/transport"; import { createRequestExecutionBudget, type RequestExecutionBudgetPolicy } from "../../src/lib/request-execution-budget"; import { SendBudgetExhaustedError } from "../../src/lib/upstream-retry"; +import { CloudChatError, type CloudChatEvent, type CloudChatRequest } from "../../src/adapters/devin/cloud-direct"; +import { streamChatEventsWithResetRetry } from "../../src/adapters/devin/cloud-direct/stated-reset-retry"; /** * Adapters that retry INSIDE one adapter call are the layer a per-request cap cannot see from @@ -145,3 +147,22 @@ describe("Cursor inner retries and the request send budget", () => { expect(observed.map(send => send.recovery)).toEqual([undefined, "connection-reset"]); }); }); + +describe("Devin inner retries and the request send budget", () => { + test("an exhausted initial send escapes as the local budget error", async () => { + const request = { + apiKey: "test", apiServerUrl: "https://example.invalid", modelUid: "swe-2", messages: [], + } as unknown as CloudChatRequest; + const stream = (req: CloudChatRequest) => (async function* (): AsyncGenerator { + await req.executor!("https://example.invalid/GetChatMessage"); + throw new CloudChatError("must not replace the budget refusal", undefined, undefined, 429); + })(); + + await expect((async () => { + for await (const _event of streamChatEventsWithResetRetry(request, { + stream, + execution: { sendBudget: budgetOf(0) }, + })) { /* drain */ } + })()).rejects.toBeInstanceOf(SendBudgetExhaustedError); + }); +}); diff --git a/tests/providers/devin-adapter.test.ts b/tests/providers/devin-adapter.test.ts index a50a3d96e4d..7407252db2a 100644 --- a/tests/providers/devin-adapter.test.ts +++ b/tests/providers/devin-adapter.test.ts @@ -483,9 +483,8 @@ describe("devin adapter api-server host resolution (#4503)", () => { home = mkdtempSync(join(tmpdir(), "ocx-devin-host-")); process.env.OPENCODEX_HOME = home; seenUrls = []; - // This adapter's transport fetches through the global fetch — it does not - // consume IncomingMeta.providerFetch — so the stub observes every upstream - // URL the turn dispatches to. + // No providerFetch is supplied by this direct adapter test, so inference falls back to the + // global fetch alongside catalog/JWT RPCs and this stub observes every upstream URL. globalThis.fetch = (async (input: RequestInfo | URL) => { seenUrls.push(String(input)); return new Response("down", { status: 500 }); diff --git a/tests/providers/devin-stated-reset-hardening.test.ts b/tests/providers/devin-stated-reset-hardening.test.ts index 0dac8ed0e32..2618b920414 100644 --- a/tests/providers/devin-stated-reset-hardening.test.ts +++ b/tests/providers/devin-stated-reset-hardening.test.ts @@ -74,14 +74,20 @@ describe("Devin cumulative stated-reset allowance", () => { test("cancellation at the sleep-completion boundary prevents replay", async () => { const controller = new AbortController(); let calls = 0; - const stream = async function* (): AsyncGenerator { + let inferenceSends = 0; + const stream = async function* (req: CloudChatRequest): AsyncGenerator { calls += 1; + await req.executor!("https://example.invalid/GetChatMessage"); throw cap("reset in 1 second"); }; await expect(drain(streamChatEventsWithResetRetry({ ...request, signal: controller.signal }, { stream, sleep: async () => { controller.abort(); }, + execution: { + executor: (async () => { inferenceSends += 1; return new Response(); }) as typeof fetch, + }, }))).rejects.toHaveProperty("name", "AbortError"); expect(calls).toBe(1); + expect(inferenceSends).toBe(1); }); test.each([ @@ -91,13 +97,21 @@ describe("Devin cumulative stated-reset allowance", () => { { kind: "reasoning_signature", signature: "sig" }, ] as CloudChatEvent[])("never retries after an event: %j", async event => { let calls = 0; - const stream = async function* (): AsyncGenerator { + let inferenceSends = 0; + const stream = async function* (req: CloudChatRequest): AsyncGenerator { calls += 1; + await req.executor!("https://example.invalid/GetChatMessage"); yield event; throw cap("reset in 1 second"); }; - await expect(drain(streamChatEventsWithResetRetry(request, { stream }))).rejects.toThrow("reset in 1 second"); + await expect(drain(streamChatEventsWithResetRetry(request, { + stream, + execution: { + executor: (async () => { inferenceSends += 1; return new Response(); }) as typeof fetch, + }, + }))).rejects.toThrow("reset in 1 second"); expect(calls).toBe(1); + expect(inferenceSends).toBe(1); }); test("explicit zero disables waiting; overlarge overrides stay bounded", () => { diff --git a/tests/providers/devin-stated-reset-retry.test.ts b/tests/providers/devin-stated-reset-retry.test.ts index 18e7ef9ce6b..305372ad0ee 100644 --- a/tests/providers/devin-stated-reset-retry.test.ts +++ b/tests/providers/devin-stated-reset-retry.test.ts @@ -7,6 +7,7 @@ import { describe, expect, test } from "bun:test"; import { CloudChatError, type CloudChatEvent, type CloudChatRequest } from "../../src/adapters/devin/cloud-direct"; import { streamChatEventsWithResetRetry } from "../../src/adapters/devin/cloud-direct/stated-reset-retry"; +import { createRequestExecutionBudget } from "../../src/lib/request-execution-budget"; const REQ = { apiKey: "k", apiServerUrl: "https://example.invalid", modelUid: "swe-2", messages: [] } as unknown as CloudChatRequest; @@ -27,6 +28,77 @@ async function drain(source: AsyncGenerator): Promise { + test("admits and reports every inference POST through one shared budget", async () => { + let spendReservations = 0; + let spendRefunds = 0; + const budget = createRequestExecutionBudget({ + maxTotalModelSends: 3, baseSendAllowance: 3, finalRecoveryAllowance: 0, + maxAlternateTargetSends: 0, maxTargetTransitions: 0, + }, "devin-reset-accounting", { + charge: () => { spendReservations += 1; return true; }, + refund: () => { spendRefunds += 1; }, + }); + const sends: number[] = []; + const usedDuringWait: number[] = []; + const observed: Array<{ ordinal: number; recovery?: string }> = []; + let attempts = 0; + const stream = (req: CloudChatRequest) => (async function* (): AsyncGenerator { + attempts += 1; + await req.executor!("https://example.invalid/GetChatMessage"); + if (attempts < 3) throw new CloudChatError("reset in 1 second", "resource_exhausted", "t", 429); + yield { kind: "finish", reason: "stop" } as CloudChatEvent; + })(); + + await drain(streamChatEventsWithResetRetry(REQ, { + stream, + sleep: async () => { usedDuringWait.push(budget.used); }, + execution: { + executor: (async () => { sends.push(sends.length + 1); return new Response(); }) as typeof fetch, + sendBudget: budget, + onPhysicalSend: send => { observed.push(send); }, + }, + })); + + expect(sends).toEqual([1, 2, 3]); + expect(budget.used).toBe(3); + expect(usedDuringWait).toEqual([1, 2]); + expect(spendReservations).toBe(3); + expect(spendRefunds).toBe(0); + expect(observed).toEqual([ + { ordinal: 1 }, + { ordinal: 2, recovery: "rate-limit-429" }, + { ordinal: 3, recovery: "rate-limit-429" }, + ]); + }); + + test("a refused replay performs no inference I/O and preserves the provider 429", async () => { + const budget = createRequestExecutionBudget({ + maxTotalModelSends: 1, baseSendAllowance: 1, finalRecoveryAllowance: 0, + maxAlternateTargetSends: 0, maxTargetTransitions: 0, + }, "devin-reset-refusal"); + const refusal = new CloudChatError("Your limit will reset in 1 second", "resource_exhausted", "trace", 429); + const withheld: string[] = []; + let inferenceSends = 0; + const stream = (req: CloudChatRequest) => (async function* (): AsyncGenerator { + await req.executor!("https://example.invalid/GetChatMessage"); + throw refusal; + })(); + + await expect(drain(streamChatEventsWithResetRetry(REQ, { + stream, + sleep: async () => {}, + execution: { + executor: (async () => { inferenceSends += 1; return new Response(); }) as typeof fetch, + sendBudget: budget, + onRecoveryWithheld: event => { withheld.push(event.reason); }, + }, + }))).rejects.toBe(refusal); + + expect(inferenceSends).toBe(1); + expect(budget.used).toBe(1); + expect(withheld).toEqual(["retry-send-budget"]); + }); + test("waits the stated delay and replays a zero-event 429", async () => { const waits: number[] = []; let calls = 0; diff --git a/tests/responses/responses-send-budget-counts.test.ts b/tests/responses/responses-send-budget-counts.test.ts index 10b08864f36..d6119caa0fd 100644 --- a/tests/responses/responses-send-budget-counts.test.ts +++ b/tests/responses/responses-send-budget-counts.test.ts @@ -8,6 +8,14 @@ import { handleResponses } from "../../src/server/responses/core"; import { COMBO_TARGET_BASE_SENDS, comboExecutionBudgetPolicy } from "../../src/server/responses/core-combo"; import type { RequestLogContext } from "../../src/server/request-log"; import type { OcxConfig } from "../../src/types"; +import { DEVIN_API_SERVER } from "../../src/adapters/devin"; +import { setCachedCatalogForTests } from "../../src/adapters/devin/cloud-direct/catalog"; +import { mkdtempSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { saveCredential } from "../../src/oauth/store"; +import { createRequestExecutionBudget } from "../../src/lib/request-execution-budget"; /** * One logical request, one send budget -- asserted as a COUNT, because the defect in #4546 is a @@ -31,6 +39,7 @@ beforeEach(() => { afterEach(() => { globalThis.fetch = originalFetch; + setCachedCatalogForTests(null); clearComboSelectionState(); clearComboTargetCooldowns(); clearKeyCooldowns(); @@ -91,6 +100,145 @@ const totalSends = (logCtx: RequestLogContext): number => sendCounts(logCtx).reduce((sum, count) => sum + count, 0); describe("upstream sends per logical request", () => { + test("Devin's initial inner send is recorded once, not omitted or double-counted", async () => { + const previousHome = process.env.OPENCODEX_HOME; + const previousJwtFlag = process.env.OPENCODEX_DEVIN_SEND_USER_JWT; + const home = mkdtempSync(join(tmpdir(), "devin-send-count-")); + process.env.OPENCODEX_HOME = home; + delete process.env.OPENCODEX_DEVIN_SEND_USER_JWT; + const apiKey = "devin-count-test"; + // Devin is an OAuth-kind provider: the key the adapter ends up using is injected onto the + // row from the stored credential, so a config that only carries `apiKey` never routes. The + // credential is what makes this the path production takes. + await saveCredential("devin", { + access: apiKey, + refresh: apiKey, + expires: Number.MAX_SAFE_INTEGER, + source: "oauth", + apiBaseUrl: DEVIN_API_SERVER, + }); + setCachedCatalogForTests({ + apiKey, + host: DEVIN_API_SERVER, + fetchedAt: Date.now(), + byUid: new Map([["swe-2", { modelUid: "swe-2", label: "SWE-2", disabled: false }]]), + }); + const urls: string[] = []; + globalThis.fetch = (async input => { + urls.push(String(input)); + return new Response("busy", { status: 500 }); + }) as typeof fetch; + const logCtx: RequestLogContext = { model: "", provider: "" }; + const config = { + defaultProvider: "devin", + providers: { + devin: { + adapter: "devin", baseUrl: DEVIN_API_SERVER, models: ["swe-2"], + }, + }, + } as unknown as OcxConfig; + + try { + const response = await handleResponses(responsesRequest("devin/swe-2"), config, logCtx); + const body = await response.text(); + + // Reported together, with the status, so a turn that never reaches the adapter says so + // instead of presenting as an empty URL list. + expect({ + chatCalls: urls.filter(url => url.includes("GetChatMessage")).length, + totalSends: totalSends(logCtx), + }, `status ${response.status}: ${body.slice(0, 200)}`).toEqual({ chatCalls: 1, totalSends: 1 }); + } finally { + if (previousHome === undefined) delete process.env.OPENCODEX_HOME; + else process.env.OPENCODEX_HOME = previousHome; + if (previousJwtFlag === undefined) delete process.env.OPENCODEX_DEVIN_SEND_USER_JWT; + else process.env.OPENCODEX_DEVIN_SEND_USER_JWT = previousJwtFlag; + removeTreeWithRetry(home); + } + }); + + test("a Devin turn the budget refuses logs no send at the request boundary", async () => { + // The defect this pins lives in the outer runTurn path, not in the adapter: the attempt's + // first send was logged before the adapter ran, so a request with nothing left to spend + // recorded a send Devin never made. The direct-adapter case in tests/adapters covers the + // executor side; only this one can see `sendCount`. The budget is handed in already spent + // rather than arranged through combo arithmetic, which is how an earlier attempt at this + // case ended up admitting the send it meant to refuse. + const previousHome = process.env.OPENCODEX_HOME; + const previousJwtFlag = process.env.OPENCODEX_DEVIN_SEND_USER_JWT; + const home = mkdtempSync(join(tmpdir(), "devin-send-denied-")); + process.env.OPENCODEX_HOME = home; + delete process.env.OPENCODEX_DEVIN_SEND_USER_JWT; + const apiKey = "devin-denied-test"; + await saveCredential("devin", { + access: apiKey, + refresh: apiKey, + expires: Number.MAX_SAFE_INTEGER, + source: "oauth", + apiBaseUrl: DEVIN_API_SERVER, + }); + setCachedCatalogForTests({ + apiKey, + host: DEVIN_API_SERVER, + fetchedAt: Date.now(), + byUid: new Map([["swe-2", { modelUid: "swe-2", label: "SWE-2", disabled: false }]]), + }); + const urls: string[] = []; + globalThis.fetch = (async input => { + urls.push(String(input)); + return new Response(JSON.stringify({ error: { message: "busy", type: "server_error" } }), { + status: 502, + headers: { "content-type": "application/json" }, + }); + }) as typeof fetch; + const logCtx: RequestLogContext = { model: "", provider: "" }; + const config = { + defaultProvider: "devin", + providers: { devin: { adapter: "devin", baseUrl: DEVIN_API_SERVER, models: ["swe-2"] } }, + } as unknown as OcxConfig; + // The real budget factory with nothing to give: the state an earlier combo fan-out or + // empty-response recovery leaves behind, stated directly instead of inferred. + const spent = createRequestExecutionBudget({ + maxTotalModelSends: 0, + baseSendAllowance: 0, + finalRecoveryAllowance: 0, + maxAlternateTargetSends: 0, + maxTargetTransitions: 0, + }, "devin-denied-initial-send"); + + try { + const response = await handleResponses( + responsesRequest("devin/swe-2"), config, logCtx, { sendBudget: spent }, + ); + const body = await response.text(); + const attempts = logCtx.attempts ?? []; + + // The attempt must EXIST and be empty. An absent attempt would satisfy a zero count + // without proving the refusal was recorded against the turn that was refused. + expect(attempts).toHaveLength(1); + expect({ + adapter: attempts[0]?.adapter, + sendCount: attempts[0]?.sendCount, + chatCalls: urls.filter(url => url.includes("GetChatMessage")).length, + totalSends: totalSends(logCtx), + refused: body.includes("request_send_budget_exhausted"), + }, `status ${response.status}: ${body.slice(0, 240)}`).toEqual({ + adapter: "devin", + sendCount: 0, + chatCalls: 0, + totalSends: 0, + refused: true, + }); + } finally { + if (previousHome === undefined) delete process.env.OPENCODEX_HOME; + else process.env.OPENCODEX_HOME = previousHome; + if (previousJwtFlag === undefined) delete process.env.OPENCODEX_DEVIN_SEND_USER_JWT; + else process.env.OPENCODEX_DEVIN_SEND_USER_JWT = previousJwtFlag; + setCachedCatalogForTests(null); + removeTreeWithRetry(home); + } + }); + test("a 5xx streak on a single target spends the base allowance and stops", async () => { const upstream = alwaysFailing(502, "upstream busy"); const logCtx: RequestLogContext = { model: "", provider: "" }; From 46195ac09b8b4fd2de2351dd0c653f954fe18830 Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sat, 19 Sep 2026 20:23:26 +0900 Subject: [PATCH 31/97] fix(ci): defuse bot-authored mentions at punctuation and Markdown boundaries (#5105) * fix(ci): defuse bot-authored mentions at punctuation and Markdown boundaries The translated-body sanitizer only treated whitespace and an open paren as mention boundaries, so a bot-authored translation could emit a live @mention after a comma, bracket, or blockquote marker and ping a user who never consented to the notification. Widen the boundary class to any non-token character while still refusing to rewrite emails, scoped packages, and other mid-token at-signs. * fix(ci): treat a colon as a mention boundary while preserving npm: scopes Status:@user stayed a live mention because the delimiter class excluded the colon. Include it as a boundary and keep npm:@scope intact through a negative lookbehind. --------- Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com> --- .github/scripts/issue-translation.cjs | 5 +++-- .github/scripts/issue-translation.test.cjs | 10 ++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/scripts/issue-translation.cjs b/.github/scripts/issue-translation.cjs index c7d546bc237..242e63bba2e 100644 --- a/.github/scripts/issue-translation.cjs +++ b/.github/scripts/issue-translation.cjs @@ -805,9 +805,10 @@ function sanitizeTranslationBody(raw, maxChars = 60000) { .split(MARKER).join("") .split(END_MARKER).join("") .replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/g, "") - // Defuse pings only: @login / @org/team — not emails, scopes, or decorators. + // Defuse pings at Markdown/punctuation boundaries — a colon is a boundary + // too — but not emails, npm: scopes, or other mid-token at-signs. .replace( - /(^|[\s(])@([A-Za-z0-9](?:[A-Za-z0-9-]{0,38})(?:\/[A-Za-z0-9._-]+)?)/g, + /(^|[^A-Za-z0-9._%+-])(? { assert.equal(decision.reason, "rate_limited_interval"); }); - it("defuses mention-shaped tokens without rewriting emails or mid-token at-signs", () => { - const out = sanitizeTranslationBody("see @octocat and user@example.com and npm:@scope"); + it("defuses mention-shaped tokens at Markdown and punctuation boundaries", () => { + const out = sanitizeTranslationBody( + "see @octocat, comma,@team, [@user], >@org/team, Status:@maintainer, user@example.com, npm:@scope", + ); assert.match(out, /@\u200boctocat/); + assert.match(out, /,@\u200bteam/); + assert.match(out, /\[@\u200buser\]/); + assert.match(out, />@\u200borg\/team/); + assert.match(out, /Status:@\u200bmaintainer/); assert.ok(out.includes("user@example.com")); assert.ok(out.includes("npm:@scope")); }); From f6b59da1919ba7a73ef6a76d265b119a43eec0d1 Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sat, 19 Sep 2026 21:27:10 +0900 Subject: [PATCH 32/97] fix(doctor): tolerate a malformed CODEX_HOME/agents path during the role scan (#5106) * fix(doctor): tolerate a malformed CODEX_HOME/agents path during the role scan The agent-role scan threw when the agents path existed but was not a readable directory, aborting the whole diagnostic instead of degrading to a warning. scanCodexAgentRolesWithTomlModelFallback now accepts an optional onListError callback and returns an empty list on failure; the doctor report emits a [WARN] with the cause instead of crashing. * test(doctor): cover the malformed agents-path warning end to end Extend the same tolerance to the derived-role scan, which shares the directory listing: scanOpencodexDerivedCodexAgentRolesWithoutModelPin accepts the onListError callback, and the report skips the second scan when the first already reported the listing failure instead of printing a false ok. * test(doctor): assert the malformed agents-path warning fires exactly once The dependent derived-role scan shares the same directory listing; without the roleScanError guard a malformed path would warn twice. Pin the count so a regression that drops the guard is caught. --------- Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com> --- src/cli/doctor.ts | 37 +++++++++++++---- src/codex/subagent-model-fallback.ts | 26 ++++++++++-- tests/codex-integration/doctor.test.ts | 41 +++++++++++++++++++ tests/routing/subagent-model-fallback.test.ts | 14 ++++++- 4 files changed, 104 insertions(+), 14 deletions(-) diff --git a/src/cli/doctor.ts b/src/cli/doctor.ts index dc90ece81aa..fc3b5347f72 100644 --- a/src/cli/doctor.ts +++ b/src/cli/doctor.ts @@ -1505,8 +1505,16 @@ export async function runDoctor(args: string[] = []): Promise { // cannot break a legitimately green pipeline. console.log("\nCodex agent role files"); - const tomlFallbackRoles = scanCodexAgentRolesWithTomlModelFallback(resolveCodexHomeDirImpl()); - if (tomlFallbackRoles.length === 0) { + let roleScanError: unknown; + const tomlFallbackRoles = scanCodexAgentRolesWithTomlModelFallback( + resolveCodexHomeDirImpl(), + cause => { + roleScanError = cause; + }, + ); + if (roleScanError) { + console.log(` [WARN] unable to scan $CODEX_HOME/agents/*.toml: ${String(roleScanError)}`); + } else if (tomlFallbackRoles.length === 0) { console.log(" ok no per-role model_fallback fields in $CODEX_HOME/agents/*.toml"); } else { console.log(` [WARN] ${tomlFallbackRoles.length} agent role file${tomlFallbackRoles.length === 1 ? "" : "s"} contain${tomlFallbackRoles.length === 1 ? "s" : ""} \`model_fallback\`: ${tomlFallbackRoles.join(", ")}`); @@ -1514,13 +1522,24 @@ export async function runDoctor(args: string[] = []): Promise { } // opencodex does not write these files; the Codex desktop external-agent import does, and it // drops the model pin on the way in. Observe-only: doctor never repairs or removes them. - const unpinnedDerivedRoles = scanOpencodexDerivedCodexAgentRolesWithoutModelPin(resolveCodexHomeDirImpl()); - if (unpinnedDerivedRoles.length === 0) { - console.log(" ok every opencodex-derived role file in $CODEX_HOME/agents/*.toml pins a model"); - } else { - console.log(` [WARN] ${unpinnedDerivedRoles.length} opencodex-derived role file${unpinnedDerivedRoles.length === 1 ? "" : "s"} without a \`model\` pin: ${unpinnedDerivedRoles.map(role => `${role}.toml`).join(", ")}`); - console.log(" Codex runs these roles on the parent model, so a spawn records one role and another model. The `ocx-route` directive in the file cannot pin them: it is honoured only on the Claude Code `/v1/messages` path and is inert on `/v1/responses`."); - console.log(" Add `model = \"\"` to each file, or remove them. They usually come from the Codex desktop external-agent import of ~/.claude/agents/ocx-*.md; set `[desktop] external-agent-import-sync-item-types` with `SUBAGENTS = false` to stop it recreating them."); + // Both role scans share the same directory listing, so a failure above already reported the + // cause; skip the second scan rather than warn twice or print a false "ok". + if (!roleScanError) { + const unpinnedDerivedRoles = scanOpencodexDerivedCodexAgentRolesWithoutModelPin( + resolveCodexHomeDirImpl(), + cause => { + roleScanError = cause; + }, + ); + if (roleScanError) { + console.log(` [WARN] unable to scan $CODEX_HOME/agents/*.toml: ${String(roleScanError)}`); + } else if (unpinnedDerivedRoles.length === 0) { + console.log(" ok every opencodex-derived role file in $CODEX_HOME/agents/*.toml pins a model"); + } else { + console.log(` [WARN] ${unpinnedDerivedRoles.length} opencodex-derived role file${unpinnedDerivedRoles.length === 1 ? "" : "s"} without a \`model\` pin: ${unpinnedDerivedRoles.map(role => `${role}.toml`).join(", ")}`); + console.log(" Codex runs these roles on the parent model, so a spawn records one role and another model. The `ocx-route` directive in the file cannot pin them: it is honoured only on the Claude Code `/v1/messages` path and is inert on `/v1/responses`."); + console.log(" Add `model = \"\"` to each file, or remove them. They usually come from the Codex desktop external-agent import of ~/.claude/agents/ocx-*.md; set `[desktop] external-agent-import-sync-item-types` with `SUBAGENTS = false` to stop it recreating them."); + } } const dual = collectWslDualInstall(); diff --git a/src/codex/subagent-model-fallback.ts b/src/codex/subagent-model-fallback.ts index ef9903b4ad9..42d289c7e00 100644 --- a/src/codex/subagent-model-fallback.ts +++ b/src/codex/subagent-model-fallback.ts @@ -905,8 +905,16 @@ export function hasCodexAgentModelFallbackField(role: string, codexHome = CODEX_ } /** Roles whose TOML still carries `model_fallback`, including empty arrays. */ -export function scanCodexAgentRolesWithTomlModelFallback(codexHome = CODEX_HOME): string[] { - return listCodexAgentRoles(codexHome).filter(role => hasCodexAgentModelFallbackField(role, codexHome)); +export function scanCodexAgentRolesWithTomlModelFallback( + codexHome = CODEX_HOME, + onListError?: (cause: unknown) => void, +): string[] { + try { + return listCodexAgentRoles(codexHome).filter(role => hasCodexAgentModelFallbackField(role, codexHome)); + } catch (cause) { + onListError?.(cause); + return []; + } } const TOML_MODEL_KEY = /^\s*(?:model|"model"|'model')\s*=/; @@ -984,9 +992,19 @@ const OPENCODEX_DERIVED_ROLE_MARKERS = ["generated-by: opencodex", "ocx-route:"] * authorizes writing to, repairing, or removing these files, and the marker-based ownership rules * that govern the files opencodex does write are unchanged. */ -export function scanOpencodexDerivedCodexAgentRolesWithoutModelPin(codexHome = CODEX_HOME): string[] { +export function scanOpencodexDerivedCodexAgentRolesWithoutModelPin( + codexHome = CODEX_HOME, + onListError?: (cause: unknown) => void, +): string[] { const findings: string[] = []; - for (const role of listCodexAgentRoles(codexHome)) { + let roles: string[]; + try { + roles = listCodexAgentRoles(codexHome); + } catch (cause) { + onListError?.(cause); + return []; + } + for (const role of roles) { let content: string; try { content = readFileSync(join(codexHome, "agents", `${role}.toml`), "utf8"); diff --git a/tests/codex-integration/doctor.test.ts b/tests/codex-integration/doctor.test.ts index fe07a6a797c..2280a9224f1 100644 --- a/tests/codex-integration/doctor.test.ts +++ b/tests/codex-integration/doctor.test.ts @@ -879,6 +879,47 @@ describe("doctor version skew projection", () => { removeTreeWithRetry(home); } }, STORE_BUDGET_MS); + + test("a malformed CODEX_HOME/agents path warns instead of aborting the report", async () => { + const home = mkdtempSync(join(tmpdir(), "ocx-doctor-agents-")); + const codexHome = join(home, "codex"); + const previousHome = process.env.OPENCODEX_HOME; + const previousCodexHome = process.env.CODEX_HOME; + const previousExitCode = process.exitCode; + const restore: Array<() => void> = []; + try { + mkdirSync(codexHome, { recursive: true }); + process.env.OPENCODEX_HOME = home; + process.env.CODEX_HOME = codexHome; + writeFileSync(join(home, "config.json"), JSON.stringify({ ...getDefaultConfig(), port: 9, codexAutoStart: false })); + // A regular file where the role scan expects a readable directory. + writeFileSync(join(codexHome, "agents"), "not a directory"); + const logged: string[] = []; + const log = spyOn(console, "log").mockImplementation((...args: unknown[]) => { logged.push(args.map(String).join(" ")); }); + restore.push(() => log.mockRestore()); + // Other doctor sections probe upstream health; this diagnostic fixture must stay offline. + const fetch = spyOn(globalThis, "fetch").mockImplementation(async () => new Response(null, { status: 503 })); + restore.push(() => fetch.mockRestore()); + const live = spyOn(proxyLiveness, "findLiveProxy").mockResolvedValue({ + pid: null, port: 9, hostname: "127.0.0.1", source: "config", + }); + restore.push(() => live.mockRestore()); + await runDoctor([]); + const output = logged.join("\n"); + expect(output).toContain("[WARN] unable to scan $CODEX_HOME/agents/*.toml:"); + expect(output).not.toContain("no per-role model_fallback fields"); + // The dependent derived-role scan shares the listing; a missing guard would warn twice. + expect(output.match(/\[WARN\] unable to scan \$CODEX_HOME\/agents\/\*\.toml:/g) ?? []).toHaveLength(1); + } finally { + for (const cleanup of restore.reverse()) cleanup(); + process.exitCode = previousExitCode; + if (previousHome === undefined) delete process.env.OPENCODEX_HOME; + else process.env.OPENCODEX_HOME = previousHome; + if (previousCodexHome === undefined) delete process.env.CODEX_HOME; + else process.env.CODEX_HOME = previousCodexHome; + removeTreeWithRetry(home); + } + }, STORE_BUDGET_MS); }); describe("doctor reclaim wiring (end to end)", () => { diff --git a/tests/routing/subagent-model-fallback.test.ts b/tests/routing/subagent-model-fallback.test.ts index 7834db68efb..d68330dc83c 100644 --- a/tests/routing/subagent-model-fallback.test.ts +++ b/tests/routing/subagent-model-fallback.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, setDefaultTimeout, test } from "bun:test"; -import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs"; +import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { @@ -1337,6 +1337,18 @@ test("the native-main drain sentinel covers the flagships without widening to gp expect(readCodexAgentModelFallback("empty_fallback", dir)).toEqual([]); }); + test("scanCodexAgentRolesWithTomlModelFallback tolerates a malformed agents path", () => { + const dir = codexHomeFixture(); + rmSync(join(dir, "agents"), { recursive: true }); + writeFileSync(join(dir, "agents"), "not a directory", "utf8"); + let scanError: unknown; + + expect(scanCodexAgentRolesWithTomlModelFallback(dir, cause => { + scanError = cause; + })).toEqual([]); + expect(scanError).toBeInstanceOf(Error); + }); + test("scanCodexAgentRolesWithTomlModelFallback recognizes quoted model_fallback keys", () => { const dir = codexHomeFixture(); writeFileSync(join(dir, "agents", "quoted_key.toml"), [ From dfb76e77a8eeec7bde1c14bb326196a70c8c7f23 Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sat, 19 Sep 2026 21:31:20 +0900 Subject: [PATCH 33/97] fix(devin): bound remote image prompt references (#5139) mapOcxContentToWire copied every non-data image_url into literal prompt text, so an attacker-controlled long URL bypassed the fixed image admission charge and amplified memory during protobuf construction. Accept only bounded https: references (<= 8192 chars) and emit a fixed-size omission marker otherwise. Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com> --- src/adapters/devin.ts | 26 ++++++++++++++++--- structure/adapters/registry.md | 4 +++ .../providers/devin-image-passthrough.test.ts | 11 ++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/adapters/devin.ts b/src/adapters/devin.ts index 082cde39d0d..2f96545c790 100644 --- a/src/adapters/devin.ts +++ b/src/adapters/devin.ts @@ -254,6 +254,17 @@ function textFromParts(content: string | OcxContentPart[] | undefined): string { return content.map((part) => (part.type === "text" ? part.text : "")).filter(Boolean).join("\n"); } +const MAX_DEVIN_REMOTE_IMAGE_URL_CHARS = 8_192; + +function boundedDevinRemoteImageReference(imageUrl: string): string | undefined { + if (imageUrl.length > MAX_DEVIN_REMOTE_IMAGE_URL_CHARS) return undefined; + try { + return new URL(imageUrl).protocol === "https:" ? imageUrl : undefined; + } catch { + return undefined; + } +} + /** * Convert inbound content parts to the multimodal shape the wire encoder accepts. * @@ -262,9 +273,10 @@ function textFromParts(content: string | OcxContentPart[] | undefined): string { * text-only string and a message whose only content was an image was dropped * entirely, which is why a pasted screenshot killed the turn and the only * workaround was running OCR before sending. A data: URL carries everything - * field #10 needs; a remote https URL cannot be inlined without a fetch, so it - * stays as an explicit text reference rather than pretending the model can see - * a picture it cannot. Video has no Devin field and is skipped. + * field #10 needs; a bounded remote https URL cannot be inlined without a fetch, + * so it stays as an explicit text reference rather than pretending the model can + * see a picture it cannot. Unsupported and oversized references become a fixed + * omission marker, never attacker-sized prompt text. Video has no Devin field. */ function mapOcxContentToWire(content: string | OcxContentPart[] | undefined): string | ContentPart[] { if (typeof content === "string" || !Array.isArray(content)) return content ?? ""; @@ -275,7 +287,13 @@ function mapOcxContentToWire(content: string | OcxContentPart[] | undefined): st } else if (part.type === "image") { const m = part.imageUrl.match(/^data:([^;]+);base64,(.+)$/); if (m) out.push({ type: "image", mimeType: m[1]!, base64Data: m[2]! }); - else out.push({ type: "text", text: `[image url: ${part.imageUrl}]` }); + else { + const remoteReference = boundedDevinRemoteImageReference(part.imageUrl); + out.push({ + type: "text", + text: remoteReference ? `[image url: ${remoteReference}]` : "[image omitted: unsupported or oversized URL]", + }); + } } } return out; diff --git a/structure/adapters/registry.md b/structure/adapters/registry.md index 75238008dfe..478a41f1c41 100644 --- a/structure/adapters/registry.md +++ b/structure/adapters/registry.md @@ -209,3 +209,7 @@ Native steering generation overrides, explicit public-API eligibility and the co Unicode pattern normalization uses [copy-on-write traversal](../transports/byte-accounting.md#unicode-pattern-normalization) while preserving the existing schema and wire semantics. Dashboard Fast-row persistence and client refresh follow the [Fast selector rows setting contract](../gui-and-management-api.md#fast-selector-rows-setting). + +## Devin image boundary + +The registered Devin implementation in `src/adapters/devin.ts` maps data URLs to its native image field. Its textual fallback accepts only bounded HTTPS references and emits a fixed-size omission marker for unsupported or oversized values. diff --git a/tests/providers/devin-image-passthrough.test.ts b/tests/providers/devin-image-passthrough.test.ts index e9445abe2f4..b9a5ec57e54 100644 --- a/tests/providers/devin-image-passthrough.test.ts +++ b/tests/providers/devin-image-passthrough.test.ts @@ -53,6 +53,17 @@ describe("user image passthrough", () => { const user = items.find(i => i.role === "user")!; expect(user.content).toEqual([{ type: "text", text: "[image url: https://example.com/pic.png]" }]); }); + + test("an oversized remote image URL is not copied into prompt text", () => { + const attackerControlledSuffix = "a".repeat(9_000); + const items = mapOcxMessagesToDevin(parsedWith([{ + role: "user", + content: [{ type: "image", imageUrl: `https://example.com/${attackerControlledSuffix}` }], + }])); + const user = items.find(i => i.role === "user")!; + expect(user.content).toEqual([{ type: "text", text: "[image omitted: unsupported or oversized URL]" }]); + expect(JSON.stringify(user.content)).not.toContain(attackerControlledSuffix); + }); }); describe("tool-result image passthrough", () => { From 118c66a8f4a5b25dc6d97268557368dc61a5be78 Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sat, 19 Sep 2026 21:31:24 +0900 Subject: [PATCH 34/97] fix(responses): keep custom websocket upstreams on bounded HTTP SSE (#5141) Bun's client WebSocket API assembles complete messages before handlers run and has no enforceable inbound payload limit, so a malicious configured upstream could force unbounded allocations. Restrict the WS lane to the first-party endpoints: the canonical ChatGPT backend unconditionally and api.openai.com under the existing upstreamWebsocket opt-in. Arbitrary provider endpoints stay on bounded HTTP/SSE. Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com> --- .../docs/reference/configuration/providers.md | 2 +- src/server/responses/ws-upstream.ts | 41 ++++++---------- tests/responses/ws-upstream.test.ts | 48 ++++++++----------- 3 files changed, 34 insertions(+), 57 deletions(-) diff --git a/docs-site/src/content/docs/reference/configuration/providers.md b/docs-site/src/content/docs/reference/configuration/providers.md index 1ec22ffae41..a8b6f0c7333 100644 --- a/docs-site/src/content/docs/reference/configuration/providers.md +++ b/docs-site/src/content/docs/reference/configuration/providers.md @@ -146,7 +146,7 @@ Providers can expose a built-in shorthand, such as `agy` for `google-antigravity | `responsesPath?` | `string` | Relative resource path for key-auth `openai-responses` requests. It must start with `/` and contain no scheme, query, or fragment. | | `chatCompletionsPath?` | `string` | Relative resource path for `openai-chat` requests, the mirror of `responsesPath` and subject to the same shape rules. Needed when one upstream serves Chat Completions and Responses under different prefixes: a per-model wire override changes the adapter and leaves `baseUrl` alone, so without this an opted-in Chat request would be sent to the Responses base. Z.AI is the shipped example. | | `allowEncryptedV2AgentTasks?` | `boolean` | Disabled by default. Trust a direct key-auth `openai-responses` provider to consume or relay opaque encrypted V2 sub-agent tasks unchanged. Eligible routes skip `agentTaskRecovery`; all other routes keep the existing recovery or fail-closed behavior. OpenCodex does not decrypt, translate, or recover tasks sent through this opt-in. | -| `upstreamWebsocket?` | `boolean` | Opt-in upstream Responses WebSocket transport for `openai-responses` requests (default false). When the upstream supports the Responses WebSocket protocol, streaming POST requests to the configured Responses path (default `/v1/responses`) are dialed as WSS over an HTTPS base URL and re-encoded to SSE for the usual pipeline. Forward providers use `{baseUrl}/responses`; key-auth providers use `responsesPath`, or the legacy `/v1/responses` fallback. This mirrors the canonical ChatGPT backend optimization for OpenAI-compatible gateways (for example sub2api) whose WebSocket ingress is measurably faster than its SSE queue. Plain HTTP remains on SSE; non-Responses paths and `openai-chat` requests stay on HTTP. | +| `upstreamWebsocket?` | `boolean` | Opt-in upstream Responses WebSocket transport for `openai-responses` requests (default false). Honored only for the first-party `https://api.openai.com/v1` upstream; custom-provider endpoints always use bounded HTTP/SSE because Bun cannot enforce an inbound WebSocket message limit before allocating the complete message. The canonical ChatGPT transport is unaffected. Plain HTTP remains on SSE; non-Responses paths and `openai-chat` requests stay on HTTP. | | `supportsServiceTier?` | `boolean` | Tri-state canonical Fast capability fallback. `true` publishes Fast in the catalog, satisfies service-tier routing requirements, contributes a supported fingerprint, and lets fast mode inject the provider's canonical wire value on a compatible final adapter. `false` strips the field and never injects, and exact model declarations cannot reopen it. Absent leaves the provider unclassified: fast mode does not inject or normalize a canonical caller value, and caller values obey the final wire's forwarding permission (`chatServiceTier` on Chat; passthrough on Responses). The registry classifies canonical OpenAI (`true`), DeepSeek, and Volcengine Ark (`false`); set it explicitly only for custom gateways that genuinely support tiers. | | `modelSupportsServiceTier?` | `Record` | Exact upstream model capability overrides. Exact `true` enables canonical Fast for that model; exact `false` narrows provider defaults. An explicit provider-level `supportsServiceTier: false` remains fail-closed and cannot be reopened. Exact `true` does not authorize foreign caller-tier forwarding on Chat. Undeclared models fall back to provider-wide behavior. Management `PATCH /api/providers` merges entries and accepts `null` to clear one. | | `chatServiceTier?` | `boolean` | Provider-wide Chat-wire opt-in for forwarding caller `service_tier` values. On a classified route it governs foreign values such as `flex`, not proxy-owned canonical Fast after capability validation; on an unclassified route it governs every caller value because no Fast capability has been validated. Exact model capability does not authorize foreign forwarding. Responses routes retain their capability-based caller forwarding behavior. | diff --git a/src/server/responses/ws-upstream.ts b/src/server/responses/ws-upstream.ts index 41296bf08d4..4348bd48cf9 100644 --- a/src/server/responses/ws-upstream.ts +++ b/src/server/responses/ws-upstream.ts @@ -29,33 +29,14 @@ export { CODEX_WS_LIVENESS_PING_INTERVAL_MS, CODEX_WS_RESPONSE_PRELUDE_TIMEOUT_M export const MIN_BOUNDED_CODEX_WS_BUN_VERSION = "1.4.0"; /** - * Dial URL for a request URL. The canonical ChatGPT backend keeps its constant; - * an operator-opted OpenAI-compatible upstream swaps https for wss on the same - * path so gateways that serve the Responses WebSocket protocol on their - * /v1/responses path get the same fast lane. Plain HTTP remains on SSE because - * a provider WS handshake would otherwise send credentials and request data - * without transport encryption. + * Dial URL for a first-party Responses endpoint. The canonical ChatGPT backend + * keeps its constant; the api.openai.com Responses endpoint swaps https for wss + * on the same path. No other upstream may enter the WebSocket lane. */ function wsUpstreamUrlFor(httpUrl: string): string { if (httpUrl === CODEX_RESPONSES_HTTP_URL) return CODEX_RESPONSES_WS_URL; - return httpUrl.replace(/^http(s?):/, "ws$1:"); -} - -/** - * An operator-opted OpenAI-compatible upstream only joins the WS lane for - * Responses endpoints: the WebSocket path speaks the Responses event protocol, - * and every downstream consumer (adapter parsers, usage sniffing, SSE relay) - * assumes that wire. Other paths (chat completions, images, search) stay HTTP. - */ -function isResponsesWebsocketEligibleUrl(url: string): boolean { - let parsed: URL; - try { - parsed = new URL(url); - } catch { - return false; - } - return parsed.protocol === "https:" - && parsed.pathname.endsWith("/responses"); + if (httpUrl === OPENAI_API_RESPONSES_URL) return httpUrl.replace(/^http(s?):/, "ws$1:"); + throw new Error("unsupported Codex WebSocket upstream"); } export type BunRuntimeIdentity = { version: string; @@ -108,8 +89,13 @@ export function shouldUseCodexWsUpstream( ): boolean { if (!bunSupportsBoundedCodexWsRelay(runtime)) return false; if (socks5ProxyFromEnv()) return false; - if (url !== CODEX_RESPONSES_HTTP_URL && !upstreamWebsocketConfigured) return false; - if (upstreamWebsocketConfigured && !isResponsesWebsocketEligibleUrl(url)) return false; + // Bun's client WebSocket API delivers only fully assembled messages and has + // no enforceable inbound payload limit. Keep arbitrary provider endpoints on + // bounded HTTP/SSE until the client can reject fragmented text and binary + // messages during ingestion rather than after allocation. The first-party + // api.openai.com lane still requires the operator opt-in. + if (url !== CODEX_RESPONSES_HTTP_URL + && !(upstreamWebsocketConfigured && url === OPENAI_API_RESPONSES_URL)) return false; if ((init?.method ?? "GET").toUpperCase() !== "POST") return false; const body = init?.body; if (typeof body !== "string") return false; @@ -139,7 +125,8 @@ export function codexWsUpstreamFetch( const prepared = prepareCodexWsRequest(url, init); if (!prepared) return sseFallback(url, prepareCodexHttpInit(url, init)); init = prepared.httpInit; - if (!bunSupportsBoundedCodexWsRelay(runtime)) { + if ((url !== CODEX_RESPONSES_HTTP_URL && url !== OPENAI_API_RESPONSES_URL) + || !bunSupportsBoundedCodexWsRelay(runtime)) { return sseFallback(url, init); } const signal = init.signal ?? undefined; diff --git a/tests/responses/ws-upstream.test.ts b/tests/responses/ws-upstream.test.ts index c9afb0cd7d9..62a00888dc3 100644 --- a/tests/responses/ws-upstream.test.ts +++ b/tests/responses/ws-upstream.test.ts @@ -150,11 +150,15 @@ describe("shouldUseCodexWsUpstream", () => { expect(shouldUseCodexWsUpstream(CODEX_URL, { method: "POST", body: "{\"stream\":true" })).toBe(false); }); - test("opt-in upstream WebSocket only for configured OpenAI-compatible Responses endpoints", () => { + test("keeps configured provider endpoints on bounded HTTP SSE", () => { // The canonical backend ignores the flag. expect(shouldUseCodexWsUpstream(CODEX_URL, streamingInit(), false)).toBe(true); - // Configured providers join the WS lane on their own /v1/responses path. - expect(shouldUseCodexWsUpstream("https://sub2api.example.com/v1/responses", streamingInit(), true)).toBe(true); + // Bun cannot reject oversized messages before assembling them, so even an + // opted-in provider cannot join the WebSocket lane. + expect(shouldUseCodexWsUpstream("https://sub2api.example.com/v1/responses", streamingInit(), true)).toBe(false); + // The first-party api.openai.com lane still honors the operator opt-in. + expect(shouldUseCodexWsUpstream("https://api.openai.com/v1/responses", streamingInit(), true)).toBe(true); + expect(shouldUseCodexWsUpstream("https://api.openai.com/v1/responses", streamingInit(), false)).toBe(false); // Plain HTTP stays on SSE; never send credentials or request data through ws://. expect(shouldUseCodexWsUpstream("http://10.0.0.5:8080/v1/responses", streamingInit(), true)).toBe(false); expect(shouldUseCodexWsUpstream("https://sub2api.example.com/v1/responses", streamingInit(), false)).toBe(false); @@ -297,11 +301,7 @@ describe("providerFetch routing", () => { expect(FakeWebSocket.instances).toHaveLength(1); }); - test("routes an opt-in provider's Responses streams over its upstream WS", async () => { - installFake(ws => { - ws.emit("open", {}); - ws.emit("message", { data: JSON.stringify({ type: "response.completed", response: { id: "r1" } }) }); - }); + test("routes an opt-in provider's Responses streams over bounded HTTP SSE", async () => { const baseCalls: string[] = []; const sentinel = new Response("base"); const provider = { @@ -313,16 +313,15 @@ describe("providerFetch routing", () => { } as unknown as OcxProviderConfig; const wrapped = providerFetch(provider, BOUNDED_WS_RUNTIME); - const wsResponse = await wrapped("https://sub2api.example.com/v1/responses", streamingInit()); - expect(wsResponse.headers.get("content-type")).toContain("text/event-stream"); - expect(baseCalls).toHaveLength(0); - expect(FakeWebSocket.instances).toHaveLength(1); - expect(FakeWebSocket.instances[0]!.url).toBe("wss://sub2api.example.com/v1/responses"); + const response = await wrapped("https://sub2api.example.com/v1/responses", streamingInit()); + expect(await response.text()).toBe("base"); + expect(baseCalls).toHaveLength(1); + expect(FakeWebSocket.instances).toHaveLength(0); // The same provider's non-Responses paths (images/search/chat) stay on the base fetch. await wrapped("https://sub2api.example.com/v1/images", streamingInit()); - expect(baseCalls).toHaveLength(1); - expect(FakeWebSocket.instances).toHaveLength(1); + expect(baseCalls).toHaveLength(2); + expect(FakeWebSocket.instances).toHaveLength(0); }); }); @@ -1064,12 +1063,12 @@ describe("codexWsUpstreamFetch", () => { }); test("keeps noncanonical providers on the stream path", async () => { - const response = await receive(refusal, [], "https://gateway.example/v1/responses"); + const response = await receive(refusal, [], "https://api.openai.com/v1/responses"); expect(response.status).toBe(200); expect(await response.text()).toContain("event: error"); }); - test.each([CODEX_URL, "https://gateway.example/v1/responses"])( + test.each([CODEX_URL, "https://api.openai.com/v1/responses"])( "settles synchronous error/send-throw/close races and detaches deadlines for %s", async url => { jest.useFakeTimers(); const abort = new AbortController(); @@ -1953,24 +1952,15 @@ describe("oversized Codex create frames", () => { expect(stage?.relayedEvents).toBeGreaterThan(0); }); - test("dials the configured provider's own wss URL for an opt-in upstream", async () => { - process.env.HTTPS_PROXY = "http://proxy.example:8080"; - process.env.NO_PROXY = "sub2api.example.com:443"; - installFake(ws => { - ws.emit("open", {}); - ws.emit("message", { data: JSON.stringify({ type: "response.completed", response: { id: "r-ws" } }) }); - }); + test("falls back before dialing a custom upstream URL", async () => { const sentinel = new Response("fallback"); const response = await codexWsUpstreamFetch( "https://sub2api.example.com/v1/responses", streamingInit(), (async () => sentinel) as typeof fetch, ); - expect(FakeWebSocket.instances).toHaveLength(1); - expect(FakeWebSocket.instances[0]!.url).toBe("wss://sub2api.example.com/v1/responses"); - expect(FakeWebSocket.instances[0]!.options?.proxy).toBeUndefined(); - expect(response.headers.get("content-type")).toContain("text/event-stream"); - expect(await response.text()).toContain("response.completed"); + expect(FakeWebSocket.instances).toHaveLength(0); + expect(response).toBe(sentinel); }); test("response.done normalization keeps unknown usage fields (#41980 parity)", async () => { From d1745ee7e8d2189e496f0d8ccdf3580a434791f0 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 21:40:33 +0900 Subject: [PATCH 35/97] test(server): report what the sideband peer saw at the 50MiB frame ceiling (#5161) * test(server): let the sideband ceiling case report what the peer saw This case's only symptom on failure is its own deadline. It names neither the slow leg nor whether the peer's echo was ever handed to the socket, and both are knowable. The mock peer moves into a helper that records what it observed: the upgrade, the bytes it received, what ServerWebSocket.send reported for the reply, drain with the buffered amount, and an early peer close. Bun documents that send returns a positive byte count when the payload went out, -1 when it was enqueued behind backpressure and 0 when it was dropped, so a 50MiB echo that never left is distinguishable from one still in flight - which is the ambiguity at a frame ceiling. That count is also the progress probe the phase timer reads, so a tick can say whether anything moved rather than reporting no movement by construction. The legs are named separately - upgrade, echo round trip, allocation, awaiting the ceiling echo - and an early close is now its own failure rather than reading as a deadline. Every failure message carries the peer's record. The case also leaves its timer and client behind on a failing run, which is a resource leak on its own terms; they now settle in a finally. That is a cleanup fix, not a claimed cause of any particular duration: the log shows a timeout and a later unhandled rejection, which does not establish what consumed the time. The 50MiB exact bidirectional assertion, the forwarded-header assertions, both deadlines and the platform coverage are unchanged. The upgrade assertions moved beside the peer that records them, which is also what keeps the case file at its ratchet cap without compressing control flow. * test(server): correct four overclaims in the sideband ceiling diagnostics Review found the first cut said more than it could see. A close is now a failure in every pre-settlement state, not only before the first echo. The old guard keyed on the ping, which left the harder half silent: a close after the ping and before the ceiling echo is exactly the disconnect a 50MiB frame provokes, and it fell through to the 15s deadline and read as a slow peer. The case carries an explicit stage, so the message names where it died. The send boundary is its own segment. client.send returns synchronously, so allocating the frame, handing it to the socket and waiting for the reply are three costs; timing the first two together with the wait reported allocation time as wait time. Both doc claims are narrowed to what the instrument measures. The event counter counts milestones, so a tick with no movement means no milestone was reached - not that the transport stalled, which partial delivery and CPU-bound work also look like. And the peer's reply is a short bytes: acknowledgement rather than a 50MiB echo: send= describes that acknowledgement only, and its return is bytes written to the socket, never proof the client received them. What shows the peer saw the whole frame is the recv= count. The redirect that points sideband targets at the local mock moved beside the peer. This case is at its size cap and the corrections add lines; the repo answer to that is a sibling helper rather than compressed control flow. The neighbouring relay cases keep their inline redirects: theirs target a different path, and a behaviour-preserving edit to a case this branch is not about is not worth a CI cycle here. Time bounds, the exact 50MiB assertion, the forwarded-header assertions and the platform coverage are unchanged. Local checks: NOT RUN. * test(server): create the sideband case's resources inside its own try The peer, the saved config and the global WebSocket override were all taken before the try that cleans them up, so a throw from startServer left the peer listening on its port and the override installed for every case after it. The case would have reported the throw and then poisoned its neighbours. Everything except the peer now starts inside the try, and the finally handles a server that never came up. The peer itself stays outside because the case cannot name it otherwise, and its stop is unconditional. No change to the 50MiB assertion, the 15s internal deadline, the 20s case timeout, the forwarded-header assertions or the phase instrumentation. Local checks: NOT RUN. * test(server): attempt every sideband cleanup even when one of them fails Two gaps left by the previous commit, both about a failure during teardown rather than during the case. Stopping the peer is now nested under stopping the proxy, so a throw from one shutdown no longer leaves the other listener bound for every case after this one. The restore of the global WebSocket still runs first. The inner try now opens one statement after the client exists, so the phase recorder and the deadline timer are both created inside the block that closes them. Previously a throw from phaseTimer would have left the client open. That is hygiene rather than an observed failure, and it is written as such: both are optional, and the teardown handles a recorder that was never created. The client construction moved into the sideband helper, beside the function that asserts those same forwarded headers on the peer's side, so the request and the assertion about it cannot drift apart. That is also what pays for the added lines: the case is at its size cap and the repo answer is an extraction. No change to the 50MiB assertion, the 15s internal deadline, the 20s case timeout, the forwarded-header assertions or the phase boundaries. Local checks: NOT RUN. --- tests/helpers/sideband-relay-probe.ts | 169 ++++++++++++++++++++++++++ tests/server/server-live.test.ts | 165 +++++++++++++------------ 2 files changed, 251 insertions(+), 83 deletions(-) create mode 100644 tests/helpers/sideband-relay-probe.ts diff --git a/tests/helpers/sideband-relay-probe.ts b/tests/helpers/sideband-relay-probe.ts new file mode 100644 index 00000000000..049f27c32ef --- /dev/null +++ b/tests/helpers/sideband-relay-probe.ts @@ -0,0 +1,169 @@ +import type { Server, ServerWebSocket } from "bun"; +import { expect } from "bun:test"; + +/** + * Observable state of the mock sideband peer, for a case whose only symptom is a deadline. + * + * A relay case that exceeds its ceiling reports the ceiling and nothing else: not which leg was + * slow, and not whether the peer's reply was actually handed to the socket. The second one is + * knowable. `ServerWebSocket.send` reports what it did with the payload: a positive byte count + * when it was written, `-1` when it was enqueued behind backpressure, `0` when it was dropped. + * That separates a reply this peer never handed to the socket from one it did. It is not proof + * of delivery -- nothing on this side can observe what the client received. + * + * Note what the large frame actually is. The 50MiB payload travels client to peer; the reply is + * a short `bytes:` acknowledgement, so `send=` on the reply says nothing about the big + * frame. What proves the peer saw all of it is the `recv=` count it recorded. + * See https://bun.com/docs/runtime/http/websockets. + * + * This records; it diagnoses nothing on its own and asserts nothing. + */ +export interface SidebandRelayProbe { + /** + * Monotonic count of observable relay events. + * + * Handed to `phaseTimer` as its progress probe so a tick can say whether anything moved since + * the last one. Without it every tick reads "no movement" and a stalled leg looks the same as + * a slow runner. + * + * It counts milestones and nothing finer. A frame is one event whatever its size, so a tick + * that reports no movement means no further milestone was reached -- not that the transport + * stalled. A partially delivered frame and a runner busy with CPU work both look like this. + */ + progress(): number; + /** Advance from the client side of the relay, which this module cannot observe directly. */ + noteClient(event: string): void; + /** One line naming what the peer saw, for a failure message. */ + summary(): string; +} + +export interface SidebandRelayUpstream { + readonly server: Server; + readonly seenPaths: string[]; + readonly seenUpgradeHeaders: Headers[]; + readonly probe: SidebandRelayProbe; +} + +/** + * A mock sideband peer that echoes what it receives and remembers how that went. + * + * Behaviorally identical to the inline peer it replaces: same upgrade handling, same echo + * payloads, same `maxPayloadLength`. + */ +export function sidebandRelayUpstream(maxPayloadLength: number): SidebandRelayUpstream { + const seenPaths: string[] = []; + const seenUpgradeHeaders: Headers[] = []; + const events: string[] = []; + let ticks = 0; + const note = (event: string): void => { + ticks += 1; + // Bounded: a failure message is evidence, not a transcript. + if (events.length < 24) events.push(event); + }; + const probe: SidebandRelayProbe = { + progress: () => ticks, + noteClient: event => note("client:" + event), + summary: () => events.join(" "), + }; + const server = Bun.serve({ + port: 0, + fetch(req, server) { + const url = new URL(req.url); + if (req.headers.get("upgrade")?.toLowerCase() === "websocket") { + seenPaths.push(url.pathname); + seenUpgradeHeaders.push(req.headers); + note("upgrade"); + if (server.upgrade(req, { data: {} })) return undefined as unknown as Response; + return new Response("upgrade failed", { status: 500 }); + } + return new Response("not found", { status: 404 }); + }, + websocket: { + maxPayloadLength, + message(ws: ServerWebSocket, message: string | Buffer) { + const bytes = typeof message === "string" ? message.length : message.byteLength; + note("recv=" + bytes); + const sent = ws.send(typeof message === "string" ? `echo:${message}` : `bytes:${message.byteLength}`); + // The reply is a short acknowledgement, not an echo of a large frame, and this number is + // about that reply only: negative is queued behind backpressure, zero is dropped, and a + // positive count is bytes written to the socket rather than bytes the client received. + note("send=" + sent); + }, + drain(ws: ServerWebSocket) { + note("drain=" + ws.getBufferedAmount()); + }, + close(_ws: ServerWebSocket, code: number) { + note("peerclose=" + code); + }, + }, + }); + return { server, seenPaths, seenUpgradeHeaders, probe }; +} + +/** + * What the peer must have received to have been reached as itself. + * + * Lives beside the peer because it asserts the peer's own record: the path it was opened on and + * the headers the relay forwarded, including the caller's authorization. + */ +export function expectSidebandUpgrade( + upstream: Pick, + path: string, + token: string, +): void { + expect(upstream.seenPaths).toContain(path); + expect(upstream.seenUpgradeHeaders).toHaveLength(1); + expect(upstream.seenUpgradeHeaders[0]?.get("openai-alpha")).toBe("quicksilver=v2"); + expect(upstream.seenUpgradeHeaders[0]?.get("x-session-id")).toBe("rts_side"); + expect(upstream.seenUpgradeHeaders[0]?.get("authorization")).toBe(`Bearer ${token}`); +} + +/** + * Point ChatGPT sideband WebSocket targets at a local mock for the duration of one case. + * + * The configuration stays canonical: the relay still resolves api.openai.com, and only the + * socket the runtime opens on that host is redirected. The untouched constructor comes back + * with it because the case needs one that is NOT redirected to open its own client against the + * proxy under test. + */ +export function redirectSidebandWebSocket(port: number): { + readonly OriginalWebSocket: typeof WebSocket; + restore(): void; +} { + const OriginalWebSocket = globalThis.WebSocket; + globalThis.WebSocket = class extends OriginalWebSocket { + constructor(url: string | URL, protocols?: string | string[] | Record) { + const parsed = new URL(String(url)); + const target = parsed.hostname === "api.openai.com" && parsed.pathname.startsWith("/v1/live/") + ? `ws://127.0.0.1:${port}${parsed.pathname}${parsed.search}` + : String(url); + super(target, protocols as string[]); + } + } as typeof WebSocket; + return { OriginalWebSocket, restore: () => { globalThis.WebSocket = OriginalWebSocket; } }; +} + +/** + * Open a sideband client against the proxy under test, with the headers the relay must forward. + * + * Beside `expectSidebandUpgrade` deliberately: that function asserts these exact values on the + * peer's side, so the request and the assertion about it cannot drift apart in separate files. + * The constructor is passed in because it has to be the one that was NOT redirected. + */ +export function openSidebandClient( + WebSocketCtor: typeof WebSocket, + serverUrl: string | URL, + path: string, + token: string, +): WebSocket { + const wsUrl = new URL(path, serverUrl); + wsUrl.protocol = "ws:"; + return new WebSocketCtor(wsUrl.toString(), { + headers: { + authorization: `Bearer ${token}`, + "chatgpt-account-id": "acct-123", + "openai-alpha": "quicksilver=v2", + "x-session-id": "rts_side", + }, + } as unknown as string[]); +} diff --git a/tests/server/server-live.test.ts b/tests/server/server-live.test.ts index fe38564001c..96ef76625ff 100644 --- a/tests/server/server-live.test.ts +++ b/tests/server/server-live.test.ts @@ -33,6 +33,8 @@ import type { OcxConfig } from "../../src/types"; import { fakeChatGptJwt } from "../helpers/fake-chatgpt-jwt"; import { installIsolatedCodexHome, type IsolatedCodexHome } from "../helpers/isolated-codex-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { phaseTimer } from "../helpers/phase-timing"; +import { expectSidebandUpgrade, openSidebandClient, redirectSidebandWebSocket, sidebandRelayUpstream } from "../helpers/sideband-relay-probe"; const previousApiToken = process.env.OPENCODEX_API_AUTH_TOKEN; const previousOpencodexHome = process.env.OPENCODEX_HOME; @@ -607,94 +609,91 @@ test("call-create and its sideband join bind to the same pool account (openai/co }, { timeout: 20_000 }); test("sideband GET /v1/live/{callId} relays the exact frame ceiling bidirectionally", async () => { - const seenPaths: string[] = []; - const seenUpgradeHeaders: Headers[] = []; - const upstream = Bun.serve({ - port: 0, - fetch(req, server) { - const url = new URL(req.url); - if (req.headers.get("upgrade")?.toLowerCase() === "websocket") { - seenPaths.push(url.pathname); - seenUpgradeHeaders.push(req.headers); - if (server.upgrade(req, { data: {} })) return undefined as unknown as Response; - return new Response("upgrade failed", { status: 500 }); - } - return new Response("not found", { status: 404 }); - }, - websocket: { - maxPayloadLength: MAX_WS_FRAME_BYTES, - message(ws, message) { - ws.send(typeof message === "string" ? `echo:${message}` : `bytes:${message.byteLength}`); - }, - }, - }); + // The peer is a helper so it can report what it saw: this case's only symptom on failure is + // its own deadline, which names neither the slow leg nor whether the reply was ever sent. + const { server: upstream, seenPaths, seenUpgradeHeaders, probe } = sidebandRelayUpstream(MAX_WS_FRAME_BYTES); - saveConfig(forwardConfig()); - - // Redirect ChatGPT sideband WebSocket targets to the local mock (config stays canonical). - const RealWebSocket = globalThis.WebSocket; - const upstreamPort = upstream.port; - globalThis.WebSocket = class extends RealWebSocket { - constructor(url: string | URL, protocols?: string | string[] | Record) { - const parsed = new URL(String(url)); - const target = - parsed.hostname === "api.openai.com" && parsed.pathname.startsWith("/v1/live/") - ? `ws://127.0.0.1:${upstreamPort}${parsed.pathname}${parsed.search}` - : String(url); - super(target, protocols as string[]); - } - } as typeof WebSocket; - - const server = startServer(0); + // Created inside the try: a startServer throw used to leak the peer and the socket override. + let restoreWebSocket: (() => void) | undefined; + let live: ReturnType | undefined; try { - const wsUrl = new URL(`/v1/live/rtc_sideband`, server.url); - wsUrl.protocol = "ws:"; - const client = new RealWebSocket(wsUrl.toString(), { - headers: { - authorization: `Bearer ${DIRECT_CHATGPT_TOKEN}`, - "chatgpt-account-id": "acct-123", - "openai-alpha": "quicksilver=v2", - "x-session-id": "rts_side", - }, - } as unknown as string[]); - - await new Promise((resolve, reject) => { - const timer = setTimeout(() => reject(new Error("sideband timeout")), 15_000); - let sawPing = false; - client.addEventListener("open", () => { - client.send("ping-sideband"); - }); - client.addEventListener("message", (event) => { - try { - if (!sawPing) { - expect(String(event.data)).toBe("echo:ping-sideband"); - sawPing = true; - client.send(Buffer.alloc(MAX_WS_FRAME_BYTES)); - return; + saveConfig(forwardConfig()); + // Redirect ChatGPT sideband targets to the local mock; the config stays canonical. A sibling + // helper because this case is at its size cap and the repo answer is not to compress. + const { OriginalWebSocket, restore } = redirectSidebandWebSocket(upstream.port); + restoreWebSocket = restore; + const server = live = startServer(0); + const client = openSidebandClient(OriginalWebSocket, server.url, "/v1/live/rtc_sideband", DIRECT_CHATGPT_TOKEN); + // The try opens here, one statement after the client exists, so the timer and the phase + // recorder are both created inside the block that closes them. + let phase: ReturnType | undefined; + let timer: ReturnType | undefined; + try { + // Each leg is its own segment and the timer's ticks read the peer's event count, so a + // segment that reaches no further milestone is visible as such. That is weaker than proof + // of a stall: a tick without movement says no milestone was reached, not that nothing moved. + phase = phaseTimer("sideband 50MiB exact frame ceiling", probe.progress); + const leg = phase; + await new Promise((resolve, reject) => { + const fail = (reason: string): void => reject(new Error(`${reason}; peer: ${probe.summary()}`)); + timer = setTimeout(() => fail("sideband timeout"), 15_000); + let stage: "echo-roundtrip" | "await-ceiling-echo" | "done" = "echo-roundtrip"; + leg.split("upgrade"); + client.addEventListener("open", () => { + probe.noteClient("open"); + leg.split("echo-roundtrip"); + client.send("ping-sideband"); + }); + client.addEventListener("close", event => { + probe.noteClient("close=" + event.code); + // ANY close before this case settles is its own outcome, not a deadline. Keying that + // on the first echo left the harder half unreported: a close after the ping and + // before the ceiling echo -- the disconnect a 50MiB frame is most likely to cause -- + // fell through to the 15s timeout and read as a slow peer. + if (stage !== "done") fail(`sideband closed during ${stage}`); + }); + client.addEventListener("message", (event) => { + try { + probe.noteClient("message"); + if (stage === "echo-roundtrip") { + expect(String(event.data)).toBe("echo:ping-sideband"); + leg.split("allocate-ceiling-frame"); + const frame = Buffer.alloc(MAX_WS_FRAME_BYTES); + // The send is synchronous, so allocating the frame, handing it to the socket and + // waiting for the acknowledgement are three separate costs. Timing them as one + // segment reported allocation time as wait time. + leg.split("send-ceiling-frame"); + client.send(frame); + stage = "await-ceiling-echo"; + leg.split("await-ceiling-echo"); + return; + } + expect(String(event.data)).toBe(`bytes:${MAX_WS_FRAME_BYTES}`); + expectSidebandUpgrade({ seenPaths, seenUpgradeHeaders }, "/v1/live/rtc_sideband", DIRECT_CHATGPT_TOKEN); + stage = "done"; + resolve(); + } catch (err) { + reject(err); } - expect(String(event.data)).toBe(`bytes:${MAX_WS_FRAME_BYTES}`); - expect(seenPaths).toContain("/v1/live/rtc_sideband"); - expect(seenUpgradeHeaders).toHaveLength(1); - expect(seenUpgradeHeaders[0].get("openai-alpha")).toBe("quicksilver=v2"); - expect(seenUpgradeHeaders[0].get("x-session-id")).toBe("rts_side"); - expect(seenUpgradeHeaders[0].get("authorization")).toBe(`Bearer ${DIRECT_CHATGPT_TOKEN}`); - clearTimeout(timer); - resolve(); - } catch (err) { - clearTimeout(timer); - reject(err); - } - }); - client.addEventListener("error", () => { - clearTimeout(timer); - reject(new Error("client websocket error")); + }); + client.addEventListener("error", () => fail("client websocket error")); }); - }); - client.close(); + } finally { + // The case owns both: leaving them for the runner to collect is a resource leak whatever + // it did or did not contribute to any particular deadline. + phase?.end(); + clearTimeout(timer); + client.close(); + } } finally { - globalThis.WebSocket = RealWebSocket; - await server.stop(true); - await upstream.stop(true); + restoreWebSocket?.(); + // Nested so the peer is stopped even when stopping the proxy throws: one failed shutdown + // must not leave the other listener running for every case after this one. + try { + if (live) await live.stop(true); + } finally { + await upstream.stop(true); + } } }, { timeout: 20_000 }); From 962e8a35e51784bc622a0be0cba3159d61175017 Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sat, 19 Sep 2026 21:48:53 +0900 Subject: [PATCH 36/97] fix(codex): preserve legacy history manifest targets for history jobs (#5107) * fix(codex): preserve legacy history manifest targets for history jobs resolveCodexHistoryJobTarget passed only the normalized canonical backup filename to the Worker. On Windows installs whose state DB path was recorded with the extended-length prefix, pre-normalization manifests hash to a different name, so a Worker given the canonical-only path could not see the existing backup and an upgrade looked like an empty manifest. Resolve through the provider canonical-first, legacy-fallback rule instead. * docs(structure): keep the Worker-boundary note in codex-home/config only The same sentence was repeated across eight structure docs. Per review, leave the canonical wording in codex-home.md and the dedicated fallback paragraph in config.md, and drop the boilerplate copies elsewhere. --------- Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com> --- src/codex/history-job.ts | 12 ++++---- structure/codex-home.md | 2 +- structure/config.md | 2 +- .../codex-sqlite-home.test.ts | 29 +++++++++++++++++-- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/codex/history-job.ts b/src/codex/history-job.ts index cfbabb5b62a..134550f478c 100644 --- a/src/codex/history-job.ts +++ b/src/codex/history-job.ts @@ -23,7 +23,7 @@ import type { CodexHistoryWorkerOperation, HistoryWorkerResult, } from "./history-worker"; -import { currentHistoryDbBusyTimeoutMs, historyBackupPathFor } from "./history-provider"; +import { currentHistoryDbBusyTimeoutMs, resolveExistingHistoryBackupPath } from "./history-provider"; import type { CodexHistoryFailureReason, CodexHistoryVerifiedNoopProof } from "./history-provider"; import { getCodexHome, resolveCodexStateDbPath } from "./paths"; @@ -32,7 +32,7 @@ import { getCodexHome, resolveCodexStateDbPath } from "./paths"; * * The SQLite root can differ from CODEX_HOME and both environment/config inputs * can change between invocations. The parent resolves one exact target and hands - * those canonical paths to the Worker rather than asking the Worker to infer a + * those resolved paths to the Worker rather than asking the Worker to infer a * possibly different environment. */ export function resolveCodexHistoryJobTarget(): { @@ -45,10 +45,10 @@ export function resolveCodexHistoryJobTarget(): { return { canonicalCodexHome: home, canonicalStateDbPath: stateDb, - // Derived by the provider's own rule rather than guessed: the manifest lives - // in the config directory under a hash of the state database, so a - // hand-built path would address a different file entirely. - canonicalBackupPath: historyBackupPathFor(stateDb), + // Resolve through the provider's canonical-first compatibility rule. Passing + // only the newly normalized name would hide a pre-#4442 Windows manifest from + // the Worker and make an upgrade look like an empty backup. + canonicalBackupPath: resolveExistingHistoryBackupPath(stateDb), }; } diff --git a/structure/codex-home.md b/structure/codex-home.md index 940aa57afeb..c7a6ef5248f 100644 --- a/structure/codex-home.md +++ b/structure/codex-home.md @@ -311,7 +311,7 @@ management read degrades instead of returning an error page. ## Paginated history writer boundary -`src/codex/history-provider.ts` rejects provider-history changes with `history_paginated_requires_native_writer` when a target begins with an ordinal-bearing record, later contains a paginated record after a legacy start (#4311), or declares `history_mode=paginated`. The first line alone is not sufficient: a rollout that started unnumbered and was later migrated is also refused. Apply, manifest-backed restore, and explicit legacy recovery preflight all selected targets before changing database rows or manifests. The append boundary checks again. Codex owns ordinal allocation and the live projection cursor; reading the last ordinal and appending N+1 is not safe concurrent coordination. Legacy unnumbered rollouts retain their existing behavior. This guard prevents the observed stable-format corruption; it does not implement native-writer integration. +`src/codex/history-provider.ts` rejects provider-history changes with `history_paginated_requires_native_writer` when a target begins with an ordinal-bearing record, later contains a paginated record after a legacy start (#4311), or declares `history_mode=paginated`. The first line alone is not sufficient: a rollout that started unnumbered and was later migrated is also refused. Apply, manifest-backed restore, and explicit legacy recovery preflight all selected targets before changing database rows or manifests. The append boundary checks again. Codex owns ordinal allocation and the live projection cursor; reading the last ordinal and appending N+1 is not safe concurrent coordination. Legacy unnumbered rollouts retain their existing behavior. History Worker targets resolve the canonical manifest first and an existing pre-normalization Windows filename second, so passing an explicit target cannot bypass upgrade recovery. This guard prevents the observed stable-format corruption; it does not implement native-writer integration. Injection preflights affected history using the normalized config candidate before writing config/profile/journal, then checks again after the complete artifact write. Native restore also rechecks after successful journal restoration or fallback removal, while exact config/profile/journal preimages and any coordinated remove transaction remain available for compensation. diff --git a/structure/config.md b/structure/config.md index 5046d6e9ed0..6effde95004 100644 --- a/structure/config.md +++ b/structure/config.md @@ -191,7 +191,7 @@ that prefix hashed to a different backup filename before the normalization, so t (`history-provider.ts` for mutation, `native-residue.ts` for observation) fall back to the legacy filename when no canonical manifest exists. When both names exist the canonical manifest wins and the legacy file is left in place; a conflict is never resolved by silently replacing -either file. +either file. History Worker job targets use that same canonical-first lookup rather than passing a canonical-only filename that would bypass the provider's legacy fallback. `history-provider.ts` remains the strict mutation owner and maps shared validation failures to its restore/no-op integrity states. `native-residue.ts` remains a read-only observer and maps the same diff --git a/tests/codex-integration/codex-sqlite-home.test.ts b/tests/codex-integration/codex-sqlite-home.test.ts index f8f7c088bb0..7fcfd94c88d 100644 --- a/tests/codex-integration/codex-sqlite-home.test.ts +++ b/tests/codex-integration/codex-sqlite-home.test.ts @@ -4,12 +4,13 @@ import { tmpdir } from "node:os"; import { join, resolve } from "node:path"; import { resolveCodexHistoryJobTarget } from "../../src/codex/history-job"; -import { historyBackupPathFor } from "../../src/codex/history-provider"; +import { legacyHistoryBackupPathFor, resolveExistingHistoryBackupPath } from "../../src/codex/history-provider"; import { resolveCodexLogsDbPath, resolveCodexSqliteHome, resolveCodexStateDbPath } from "../../src/codex/paths"; import { removeTreeWithRetry } from "../helpers/remove-tree"; const originalCodexHome = process.env.CODEX_HOME; const originalSqliteHome = process.env.CODEX_SQLITE_HOME; +const originalOpenCodexHome = process.env.OPENCODEX_HOME; const roots: string[] = []; afterEach(() => { @@ -17,6 +18,8 @@ afterEach(() => { else process.env.CODEX_HOME = originalCodexHome; if (originalSqliteHome === undefined) delete process.env.CODEX_SQLITE_HOME; else process.env.CODEX_SQLITE_HOME = originalSqliteHome; + if (originalOpenCodexHome === undefined) delete process.env.OPENCODEX_HOME; + else process.env.OPENCODEX_HOME = originalOpenCodexHome; for (const root of roots.splice(0)) removeTreeWithRetry(root); }); @@ -108,11 +111,31 @@ describe("Codex SQLite home resolution", () => { const configured = resolveCodexHistoryJobTarget(); expect(configured.canonicalStateDbPath).toBe(join(configSqliteHome, "state_5.sqlite")); - expect(configured.canonicalBackupPath).toBe(historyBackupPathFor(configured.canonicalStateDbPath)); + expect(configured.canonicalBackupPath).toBe(resolveExistingHistoryBackupPath(configured.canonicalStateDbPath)); unlinkSync(join(codexHome, "config.toml")); const fromEnv = resolveCodexHistoryJobTarget(); expect(fromEnv.canonicalStateDbPath).toBe(join(envSqliteHome, "state_5.sqlite")); - expect(fromEnv.canonicalBackupPath).toBe(historyBackupPathFor(fromEnv.canonicalStateDbPath)); + expect(fromEnv.canonicalBackupPath).toBe(resolveExistingHistoryBackupPath(fromEnv.canonicalStateDbPath)); + }); + + test.skipIf(process.platform !== "win32")("history jobs preserve a pre-normalization extended-path manifest", () => { + const root = mkdtempSync(join(tmpdir(), "ocx-sqlite-home-legacy-")); + roots.push(root); + const codexHome = join(root, "codex"); + const configHome = join(root, "opencodex"); + const sqliteHome = join(root, "sqlite"); + mkdirSync(codexHome); + mkdirSync(configHome); + mkdirSync(sqliteHome); + process.env.CODEX_HOME = codexHome; + process.env.OPENCODEX_HOME = configHome; + process.env.CODEX_SQLITE_HOME = `\\\\?\\${sqliteHome}`; + + const stateDb = resolveCodexStateDbPath({ codexHome }); + const legacyBackup = legacyHistoryBackupPathFor(stateDb); + writeFileSync(legacyBackup, "{}\n"); + + expect(resolveCodexHistoryJobTarget().canonicalBackupPath).toBe(legacyBackup); }); }); From ef7e59f9304b9cb3194ed09fe4ad37fbfcbd1853 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 22:08:01 +0900 Subject: [PATCH 37/97] test(cursor): state the T04 heartbeat-only contract on the injectable clock (#5169) * test(cursor): state the T04 heartbeat-only contract on the injectable clock The heartbeat-only case was the last T04 assertion that still contained a term for elapsed real time. It kept a real 40ms interval writing liveness frames and required no decoded-frame gap longer than the silence budget for the whole heartbeat-only window, so a runner that paused longer than one budget made the SILENCE watchdog win while both watchdogs behaved correctly. #3940 had already scaled that budget once; scaling it again only lengthens the exposure. Move the case onto the streamHealthClock seam #5131 added, advancing virtual time by hand between liveness frames whose arrival it awaits. Production budgets (30s silence, 90s heartbeat-only), the first-frame timer and the outbound heartbeat are untouched, and the silence watchdog's real-timer firing case is unchanged. * test(cursor): pin the T04 deadline selection that no real-timer case can state Adversarial review of the previous commit found two gaps it had left. The min(silence, progress) rule was not red-capable anywhere. A watchdog that read only the progress deadline would relax production silence detection from 30s to 90s, and every real-timer case would stay green: a later deadline still produces the same no-inbound-frames message inside the case timeout. Add a virtual-clock case that requires the turn to fail at exactly S with nothing left armed, which that mutation fails immediately. Moving the heartbeat-only case onto the seam also removed the only coverage of the progress branch firing through the production default clock, which structure/providers/cursor.md claimed was still there. Restore it with a real-timer case whose silence budget is two orders of magnitude beyond its progress budget, so load can make it later but never wrong, and correct the document to say which half of the contract lives where and why. * test(cursor): bound the manual stream-health clock and pin the stall prefix Third review round. Widening the manual clock from one case to three made its unbounded drain loop worth fixing: a watchdog that re-armed an already expired deadline would schedule a zero-delay timer forever, and because advanceTo is synchronous, Bun's per-test timeout could never interrupt it. That mutation would wedge the lane instead of reddening one case, so the loop now throws after 1000 callbacks and names the cause. Also assert the shared Cursor stream stalled prefix, which no case pinned, and correct the real-timer comment: ordinary load delays that case, and a pause long enough to also cross the 60s silence budget has already blown the case's own 15s limit, which is why its outcome cannot change rather than merely being unlikely to. --- structure/providers/cursor.md | 14 +- .../cursor/cursor-stream-health.test.ts | 214 +++++++++++++++--- 2 files changed, 192 insertions(+), 36 deletions(-) diff --git a/structure/providers/cursor.md b/structure/providers/cursor.md index af22677eb55..5278df9ead2 100644 --- a/structure/providers/cursor.md +++ b/structure/providers/cursor.md @@ -240,7 +240,13 @@ The seam exists because the re-arming half of the contract cannot be stated agai timers without also asserting that the machine keeps up: showing that a deadline did NOT expire means keeping a synthetic server ahead of the silence budget for several multiples of it, which is what failed in the unsharded macOS lane while the watchdog was correct. Scaling the budget -lengthens the window rather than shrinking the exposure. The firing half needs no seam and is -still covered on real timers in `tests/providers/cursor/cursor-stream-health.test.ts`: silence -after the first frame, heartbeat-only traffic reaching the progress threshold, and `turnEnded` -cancelling the watchdog while the server holds the stream open. +lengthens the window rather than shrinking the exposure. Every claim of that shape therefore lives +under the seam in `tests/providers/cursor/cursor-stream-health.test.ts`: that meaningful frames +re-arm both clocks, that liveness-only frames refresh the silence clock while the progress clock +still expires, and that the silence deadline is the one that fires when it is the earlier of the +two. That last one is load-bearing: a watchdog that dropped the `min()` and read only the progress +deadline would relax silence detection from 30s to 90s while every real-timer case stayed green, +because a later deadline still produces the same message. The firing half needs no seam and stays +on real timers in the same file: silence after the first frame, the progress budget alone failing a +turn when the silence budget is out of reach, and `turnEnded` cancelling the watchdog while the +server holds the stream open. diff --git a/tests/providers/cursor/cursor-stream-health.test.ts b/tests/providers/cursor/cursor-stream-health.test.ts index 56c829e5184..b36bb036646 100644 --- a/tests/providers/cursor/cursor-stream-health.test.ts +++ b/tests/providers/cursor/cursor-stream-health.test.ts @@ -12,7 +12,7 @@ import { import { encodeConnectFrame } from "../../../src/adapters/cursor/framing"; import { createLiveCursorTransport } from "../../../src/adapters/cursor/live-transport"; import { createTestTranslatorBudget } from "../../helpers/translator-budget"; -import { isolationBudgetMs, watchdogMs } from "../../helpers/ci-watchdog"; +import { watchdogMs } from "../../helpers/ci-watchdog"; import type { CursorRunRequest, CursorServerMessage } from "../../../src/adapters/cursor/types"; /** @@ -130,7 +130,13 @@ function manualStreamHealthClock() { }, /** Move virtual time to `target`, running every timer due at or before it in deadline order. */ advanceTo(target: number): void { - for (;;) { + // The bound is deliberate. A watchdog that re-armed an ALREADY expired deadline would keep + // scheduling a zero-delay timer, and this loop is synchronous, so Bun's per-test timeout could + // never interrupt it: one mutation would wedge the whole lane instead of reddening one case. + for (let fired = 0; ; fired += 1) { + if (fired > 1_000) { + throw new Error("stream-health clock fired 1000 timers without draining: an expired deadline is being re-armed"); + } const due = [...pending.entries()] .filter(([, timer]) => timer.at <= target) .sort((left, right) => left[1].at - right[1].at)[0]; @@ -180,13 +186,9 @@ async function drain( } describe("Cursor inbound stream-health watchdog (T04)", () => { - // Scale once: the load helper applies a floor, so scaling each deadline separately - // would collapse the two clocks to the same value in CI. - const silenceMs = isolationBudgetMs(1_000); - const heartbeatOnlyMs = 2 * silenceMs; - // Include the existing two-second first-frame allowance and leave time for cleanup. - const fixtureLimitMs = 4 * silenceMs + 2_000; - const timeoutMs = Math.max(watchdogMs(15_000), fixtureLimitMs + silenceMs); + // Bounds a hung case; no assertion here is stated against elapsed real time, so this + // never has to cover a synthetic server outrunning a deadline. + const caseTimeoutMs = watchdogMs(15_000); test("silence after the first frame fails the turn with the stall error", async () => { await withH2Server(stream => { @@ -201,37 +203,185 @@ describe("Cursor inbound stream-health watchdog (T04)", () => { }); }, 15_000); - test("heartbeat-only traffic survives the silence threshold but fails at the heartbeat-only threshold", async () => { + test("the silence deadline wins when it is the earlier of the two", async () => { + // The case above proves a genuine stall fails the turn on real timers; it cannot prove WHICH + // deadline did it, because a longer one arriving later still produces the same message inside + // the case timeout. That distinction is the `min(silence, progress)` rule, and dropping it + // would relax production silence detection from 30s to 90s while every real-timer case stayed + // green. Virtual time pins it: the turn must fail exactly at S, with nothing left armed. + const virtualSilenceMs = 1_000; + const virtualHeartbeatOnlyMs = 10 * virtualSilenceMs; + const timing = manualStreamHealthClock(); + const connected = Promise.withResolvers(); + let armedBeforeDeadline: number | undefined; + let armedAtDeadline: number | undefined; + let failure: Error | undefined; await withH2Server(stream => { stream.on("error", () => {}); stream.respond({ ":status": 200, "content-type": "application/connect+proto" }); - stream.write(Buffer.from(textDeltaFrame("hi"))); - // Frequent heartbeats/checkpoints keep the silence clock fresh while the - // longer heartbeat-only clock must still expire under a loaded test runner. - const ping = setInterval(() => { - try { - stream.write(Buffer.from(heartbeatFrame())); - stream.write(Buffer.from(checkpointFrame())); - } catch { clearInterval(ping); } - }, 40); - const limit = setTimeout(() => stream.close(), fixtureLimitMs); - stream.on("close", () => { - clearInterval(ping); - clearTimeout(limit); + connected.resolve(stream); + }, async baseUrl => { + const transport = createLiveCursorTransport({ + provider: { adapter: "cursor", baseUrl, apiKey: "test-token" }, + translatorBudget: createTestTranslatorBudget(), + firstFrameTimeoutMs: watchdogMs(15_000), + streamSilenceFailMs: virtualSilenceMs, + streamHeartbeatOnlyFailMs: virtualHeartbeatOnlyMs, + streamHealthClock: timing.clock, }); + const iterator = transport.run(runRequest())[Symbol.asyncIterator](); + try { + const opened = iterator.next(); + const server = await connected.promise; + server.write(Buffer.from(textDeltaFrame("hi"))); + let first = await opened; + while (!first.done && first.value.type !== "text") first = await iterator.next(); + if (first.done) throw new Error("stream ended before the first text arrived"); + // then: silence. One frame stamped both clocks, so S is strictly the earlier deadline. + timing.advanceTo(virtualSilenceMs - 1); + armedBeforeDeadline = timing.armed(); + timing.advanceTo(virtualSilenceMs); + armedAtDeadline = timing.armed(); + // Cross the progress deadline too, so a watchdog that ignored S reports itself instead of + // leaving this case to hang to its own timeout. + timing.advanceTo(virtualHeartbeatOnlyMs + 1); + for (;;) { + const result = await iterator.next(); + if (result.done) break; + } + } catch (err) { + failure = err instanceof Error ? err : new Error(String(err)); + } finally { + await transport.close?.(); + } + }); + expect(failure).toBeDefined(); + expect(failure!.message).toContain("no inbound frames"); + expect(failure!.message).not.toContain("heartbeat-only"); + // The watchdog identifies itself: the two branches share this prefix. + expect(failure!.message).toContain("Cursor stream stalled"); + // Armed one tick before S and gone at S: the deadline was S, not the progress budget. + expect(armedBeforeDeadline).toBe(1); + expect(armedAtDeadline).toBe(0); + }, caseTimeoutMs); + + test("liveness-only traffic keeps the silence clock fresh and still fails at the heartbeat-only threshold", async () => { + // Which clock expires is the contract. Stating it against real timers also states that a real + // interval outran a real deadline: the case had to keep liveness frames arriving with no gap + // longer than the silence budget for the whole heartbeat-only window, and a runner that pauses + // longer than one budget made the SILENCE watchdog win while both watchdogs behaved correctly. + // Virtual time removes that term — timers fire only from `advanceTo`, so contention can delay a + // frame's arrival (which this case waits for) without any deadline passing. Same seam #5131 used + // for the re-arming case below; production budgets and every other timer are untouched. + const virtualSilenceMs = 1_000; + const virtualHeartbeatOnlyMs = 2 * virtualSilenceMs; + const timing = manualStreamHealthClock(); + const connected = Promise.withResolvers(); + const messages: CursorServerMessage[] = []; + const armedAfterLiveness: number[] = []; + let armedAfterDeadline: number | undefined; + let failure: Error | undefined; + await withH2Server(stream => { + stream.on("error", () => {}); + stream.respond({ ":status": 200, "content-type": "application/connect+proto" }); + connected.resolve(stream); }, async baseUrl => { - const { failure } = await drain(baseUrl, { - streamSilenceFailMs: silenceMs, - streamHeartbeatOnlyFailMs: heartbeatOnlyMs, + const transport = createLiveCursorTransport({ + provider: { adapter: "cursor", baseUrl, apiKey: "test-token" }, + translatorBudget: createTestTranslatorBudget(), + // Stays on the real clock: it owns dial and first response, not this contract. + firstFrameTimeoutMs: watchdogMs(15_000), + streamSilenceFailMs: virtualSilenceMs, + streamHeartbeatOnlyFailMs: virtualHeartbeatOnlyMs, + streamHealthClock: timing.clock, }); + const iterator = transport.run(runRequest())[Symbol.asyncIterator](); + try { + // The first next() dials and puts the request on the wire. + const opened = iterator.next(); + const server = await connected.promise; + const nextOfType = async ( + type: CursorServerMessage["type"], + pending?: Promise>, + ) => { + let result = await (pending ?? iterator.next()); + while (!result.done && result.value.type !== type) { + messages.push(result.value); + result = await iterator.next(); + } + if (result.done) throw new Error(`stream ended before a ${type} message arrived`); + messages.push(result.value); + }; + // One meaningful frame stamps both clocks and arms the watchdog. + server.write(Buffer.from(textDeltaFrame("hi"))); + await nextOfType("text", opened); + // Advance BEFORE writing so each pair lands at that virtual instant, just under the silence + // deadline the previous frame set. A checkpoint is a progress frame, so it yields a + // `heartbeat` message; the bare heartbeat frame yields nothing outward. The frame chain is + // serialized, so awaiting the checkpoint's message proves both were decoded and the + // watchdog re-armed from the later of them. + for (const landing of [900, 1_800]) { + timing.advanceTo(landing); + server.write(Buffer.from(heartbeatFrame())); + server.write(Buffer.from(checkpointFrame())); + await nextOfType("heartbeat"); + armedAfterLiveness.push(timing.armed()); + } + // Silence was refreshed at 1800 and the progress clock never was, so 2S can only be the + // heartbeat-only deadline. + timing.advanceTo(virtualHeartbeatOnlyMs); + armedAfterDeadline = timing.armed(); + // Had liveness frames wrongly refreshed the progress clock, nothing fires at 2S and the only + // surviving deadline is silence at 1800 + S. Cross it so this case reports which watchdog won + // instead of hanging to its own timeout. + timing.advanceTo(1_800 + virtualSilenceMs + 100); + for (;;) { + const result = await iterator.next(); + if (result.done) break; + messages.push(result.value); + } + } catch (err) { + failure = err instanceof Error ? err : new Error(String(err)); + } finally { + await transport.close?.(); + } + }); + expect(failure).toBeDefined(); + // Say which watchdog won. A bare toContain reported only the expected substring, which reads as + // "the heartbeat-only watchdog is broken" when the real story was the silence watchdog firing first. + expect(failure!.message).toContain("heartbeat-only"); + expect(failure!.message).not.toContain("no inbound frames"); + expect(failure!.message).toContain("Cursor stream stalled"); + // The heartbeat-only deadline fired at exactly 2S: nothing was left armed behind it. + expect(armedAfterDeadline).toBe(0); + // Liveness frames refreshed the silence clock and left one timer armed, never a stacked pair. + expect(armedAfterLiveness).toEqual([1, 1]); + expect(messages.some(message => message.type === "heartbeat")).toBe(true); + }, caseTimeoutMs); + + test("the progress clock fires on real timers when the silence budget is out of reach", async () => { + // The firing half needs no seam. With a silence budget two orders of magnitude beyond the + // progress budget, the only deadline in reach is the progress one, so ordinary load delays this + // case rather than changing its outcome: a pause long enough to cross 60s of silence as well, + // and so be reported as silence instead, has already blown the case's own 15s limit. The + // production default clock (Date.now plus the global timers) stays on the heartbeat-only path. + // What this pins is that the progress budget alone can fail a turn through that clock, and that + // the reported branch is selected by which budget was crossed + // rather than by whether liveness frames were seen. What it cannot state is stated under the + // injected clock above: that the deadline is the minimum of both clocks, and that liveness + // frames refresh the silence clock. Both of those are "a deadline did not expire" claims. + await withH2Server(stream => { + stream.on("error", () => {}); + stream.respond({ ":status": 200, "content-type": "application/connect+proto" }); + stream.write(Buffer.from(textDeltaFrame("hi"))); + // then: silence — never end the stream + }, async baseUrl => { + const { failure } = await drain(baseUrl, { streamSilenceFailMs: 60_000, streamHeartbeatOnlyFailMs: 600 }); expect(failure).toBeDefined(); - // Assert on the message, and say which watchdog won when the wrong one does. - // A bare toContain here reported only the expected substring, which reads as - // "the heartbeat-only watchdog is broken" when the real story is that the - // silence watchdog fired first on a loaded runner. expect(failure!.message).toContain("heartbeat-only"); + expect(failure!.message).not.toContain("no inbound frames"); }); - }, timeoutMs); + }, 15_000); test("meaningful frames keep resetting both clocks; turnEnded finishes cleanly", async () => { // Virtual budgets: nothing here is scaled for CI, because no real interval has to beat them. @@ -310,7 +460,7 @@ describe("Cursor inbound stream-health watchdog (T04)", () => { expect(armedAfterTurnEnded).toBe(0); timing.advanceTo(timing.now() + 10 * virtualHeartbeatOnlyMs); expect(failure).toBeUndefined(); - }, timeoutMs); + }, caseTimeoutMs); test("turnEnded disarms the watchdog even when the server holds the stream open", async () => { await withH2Server(stream => { From 766e0aa1ffd4b06183d935d0bac47770a2b37ac4 Mon Sep 17 00:00:00 2001 From: agentHits <140916359+agentHits@users.noreply.github.com> Date: Sat, 19 Sep 2026 09:08:08 -0400 Subject: [PATCH 38/97] fix(web-search): replay burst 429s on the forward sidecar search (#5158) * fix(web-search): replay burst 429s on the forward sidecar search The forward backend throttles burst sidecar traffic, and a single 429 became a failed tool result that poisoned the query for the whole turn via failedQueries. 1 initial send + 2 replays; Retry-After is honored as a lower bound and capped by RETRY_AFTER_CEILING_MS, with an over-ceiling instruction ending in the 429 instead of parking the search. * fix(web-search): move sidecar 429 tests to a sibling file, drop query from retry log The appended cases pushed web-search.test.ts past its file-size ratchet cap, so they move byte-for-byte to web-search-sidecar-429.test.ts with entries in layout.json and test-layout-expected.json. The retry warning no longer carries the raw query (CodeRabbit privacy finding on #5158); the terminal-failure line keeps it for diagnosis, as before. --- scripts/test-layout/layout.json | 3 +- src/web-search/executor.ts | 43 ++++++++++- tests/fixtures/test-layout-expected.json | 3 +- .../web-search/web-search-sidecar-429.test.ts | 75 +++++++++++++++++++ 4 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 tests/web-search/web-search-sidecar-429.test.ts diff --git a/scripts/test-layout/layout.json b/scripts/test-layout/layout.json index 906114492db..a610f9e2eb1 100644 --- a/scripts/test-layout/layout.json +++ b/scripts/test-layout/layout.json @@ -1543,7 +1543,8 @@ "devin-stated-reset-retry.test.ts": "providers", "ci-structure-gate.test.ts": "ci-workflows", "responses-code-mode-patch-compile.test.ts": "responses", - "gui-codex-usage-score-parity.test.ts": "gui" + "gui-codex-usage-score-parity.test.ts": "gui", + "web-search-sidecar-429.test.ts": "web-search" }, "migrated": [ "adapters", diff --git a/src/web-search/executor.ts b/src/web-search/executor.ts index d6514acfd49..33b6a1eb6cc 100644 --- a/src/web-search/executor.ts +++ b/src/web-search/executor.ts @@ -3,7 +3,14 @@ import { FORWARD_HEADERS } from "../adapters/openai-responses"; import { signalWithTimeout, cancelBodyOnAbort } from "../lib/abort"; import { redactSecretString } from "../lib/redact"; import { sidecarEnter } from "../lib/sidecar-tracker"; -import { applyUpstreamRecoveryInit, fetchWithResetRetry } from "../lib/upstream-retry"; +import { + applyUpstreamRecoveryInit, + fetchWithResetRetry, + releaseResponseBodyBestEffort, + retryBackoffDelayMs, + sleepWithAbort, + RETRY_AFTER_CEILING_MS, +} from "../lib/upstream-retry"; import { withUpstreamHttpVersion } from "../lib/upstream-http-version"; import { parseSidecarSSE, type WebSearchResult } from "./parse"; import type { CodexUpstreamOutcome } from "../codex/routing"; @@ -35,6 +42,22 @@ export const IMAGE_INSTRUCTION = /** A search result, or an `error` string when the search couldn't run (surfaced as a tool result). */ export type SidecarOutcome = WebSearchResult & { error?: string }; + +/** + * Bounded same-search 429 replays for the sidecar POST. + * + * The forward backend throttles burst sidecar traffic, and without a replay the 429 becomes a + * failed tool result that poisons the query for the whole turn (see failedQueries in loop.ts). + * 1 initial send + 2 replays; Retry-After is honored as a lower bound and capped by + * RETRY_AFTER_CEILING_MS (an instruction past the ceiling ends with the 429 instead of + * parking the search). Each wait releases the unread 429 body first so sockets do not + * accumulate under a rate-limit storm. Abort or timeout ends the wait through the existing + * catch, exactly like an abort during the SSE parse. + */ +const SIDECAR_429_MAX_ATTEMPTS = 3; +const SIDECAR_429_BASE_DELAY_MS = 1_000; +const SIDECAR_429_MAX_DELAY_MS = 10_000; + export type SidecarOutcomeRecorder = (outcome: CodexUpstreamOutcome) => void; /** @@ -79,7 +102,7 @@ export async function runWebSearch( const sidecarExit = sidecarEnter("web-search"); const t0 = Date.now(); try { - const res = await fetchWithResetRetry( + const sendOnce = () => fetchWithResetRetry( // Recovery nests INSIDE the version helper: applyUpstreamRecoveryInit then always receives a // defined init, and withUpstreamHttpVersion spreads the result, so `protocol` and the // recovery fields (`connection: close` + Bun's transport-level `keepalive: false`) survive @@ -96,6 +119,22 @@ export async function runWebSearch( }, recovery), forwardProvider)), { replaySafe: true, abortSignal: linkedSignal.signal, label: "web-search-sidecar" }, ); + let res = await sendOnce(); + for (let attempt = 0; res.status === 429 && attempt + 1 < SIDECAR_429_MAX_ATTEMPTS; attempt++) { + const delay = retryBackoffDelayMs(attempt, { + baseDelayMs: SIDECAR_429_BASE_DELAY_MS, + maxDelayMs: SIDECAR_429_MAX_DELAY_MS, + headers: res.headers, + retryAfterIsLowerBound: true, + }); + // A deadline, not a clamp: an instruction past the ceiling ends the search with the + // 429 instead of parking it at a provider that already said it would refuse. + if (delay > RETRY_AFTER_CEILING_MS) break; + console.warn(`[web-search] sidecar HTTP 429 — retrying (${attempt + 2}/${SIDECAR_429_MAX_ATTEMPTS}) after ${delay}ms`); + await releaseResponseBodyBestEffort(res.body, linkedSignal.signal); + await sleepWithAbort(delay, linkedSignal.signal); + res = await sendOnce(); + } // Attach the body guard before ANY branch reads it. The success path guarded itself below, // but the failure branch's `res.text()` runs first, so a cancel landing between fetch // resolution and reader attach orphaned the internal rejection (found investigating #1419). diff --git a/tests/fixtures/test-layout-expected.json b/tests/fixtures/test-layout-expected.json index ade9fea9a71..c4bd7f4bceb 100644 --- a/tests/fixtures/test-layout-expected.json +++ b/tests/fixtures/test-layout-expected.json @@ -1375,5 +1375,6 @@ "devin-stated-reset-retry.test.ts": "providers", "ci-structure-gate.test.ts": "ci-workflows", "responses-code-mode-patch-compile.test.ts": "responses", - "gui-codex-usage-score-parity.test.ts": "gui" + "gui-codex-usage-score-parity.test.ts": "gui", + "web-search-sidecar-429.test.ts": "web-search" } diff --git a/tests/web-search/web-search-sidecar-429.test.ts b/tests/web-search/web-search-sidecar-429.test.ts new file mode 100644 index 00000000000..6956b855333 --- /dev/null +++ b/tests/web-search/web-search-sidecar-429.test.ts @@ -0,0 +1,75 @@ +import { describe, expect, test } from "bun:test"; +import { runWebSearch as runOpenAiWebSearch } from "../../src/web-search/executor"; +import { listOpenAiForwardSidecarCandidates } from "../../src/providers/openai-sidecar"; +import type { OcxConfig } from "../../src/types"; + +function testConfig(overrides: Partial = {}): OcxConfig { + return { + port: 10100, + defaultProvider: "routed", + providers: {}, + ...overrides, + }; +} + +describe("web-search sidecar 429 replays", () => { + function sidecarProvider() { + const cfg = testConfig({ + providers: { + openai: { + adapter: "openai-responses", + baseUrl: "https://chatgpt.com/backend-api/codex", + authMode: "forward", + codexAccountMode: "direct", + }, + }, + }); + return listOpenAiForwardSidecarCandidates(cfg)[0]!.provider; + } + + function sseDone(): Response { + return new Response("data: [DONE]\n\n", { headers: { "content-type": "text/event-stream" } }); + } + + function searchWith(fetchImpl: () => Promise) { + globalThis.fetch = fetchImpl as unknown as typeof fetch; + return runOpenAiWebSearch( + "current docs", + { type: "web_search" }, + sidecarProvider(), + new Headers({ authorization: "Bearer selected-token" }), + { model: "gpt-5.6-luna", reasoning: "low", timeoutMs: 30_000 }, + ); + } + + test("a burst 429 is replayed and the recovered answer is returned", async () => { + let calls = 0; + const outcome = await searchWith(async () => { + calls += 1; + if (calls === 1) return new Response("rate limited", { status: 429 }); + return sseDone(); + }); + expect(calls).toBe(2); + expect(outcome.error).toBeUndefined(); + }); + + test("a persistent 429 ends with the 429 after bounded attempts", async () => { + let calls = 0; + const outcome = await searchWith(async () => { + calls += 1; + return new Response("rate limited", { status: 429 }); + }); + expect(calls).toBe(3); + expect(outcome.error).toContain("429"); + }); + + test("a Retry-After past the ceiling ends with the 429 without parking", async () => { + let calls = 0; + const outcome = await searchWith(async () => { + calls += 1; + return new Response("slow down", { status: 429, headers: { "retry-after": "120" } }); + }); + expect(calls).toBe(1); + expect(outcome.error).toContain("429"); + }); +}); From dfbcf2b6ff0265c3aa27dd8b10a83ca9fc305ff7 Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sat, 19 Sep 2026 22:08:17 +0900 Subject: [PATCH 39/97] fix(cursor): persist and enforce tool-suspended checkpoint snapshots (#5133) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(cursor): persist and enforce tool-suspended checkpoint snapshots A checkpoint committed after a client tool call is only safe to resume from a trailing toolResult request. The runtime guard already forced that via checkpointUsable on the provider continuation, but the flag never reached the stored snapshot, so a ref-less prefix lookup — which has no continuation state — could resume bytes upstream serialized mid-tool-call. Persist toolSuspended on the snapshot and let the guard fire on either source. * docs(cursor): note both resume-guard inputs in checkpoint commit comment --------- Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com> --- src/adapters/cursor.ts | 4 +++- src/adapters/cursor/checkpoint-store.ts | 3 +++ src/adapters/cursor/request-builder.ts | 8 ++++++- .../cursor-tool-suspended-checkpoint.test.ts | 21 ++++++++++++++++++- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/adapters/cursor.ts b/src/adapters/cursor.ts index 65f4393877b..17f9fd45fd7 100644 --- a/src/adapters/cursor.ts +++ b/src/adapters/cursor.ts @@ -254,6 +254,7 @@ export function createCursorAdapter(provider: OcxProviderConfig, deps: CursorAda coveredMessageCount, prefixDigest: cursorCoveredPrefixDigest(_parsed, coveredMessageCount), systemDigest: cursorInstructionDigest(_parsed), + toolSuspended: toolSuspendedCommit, }); if (!checkpointRef) return; if (previousRef && previousRef !== checkpointRef) invalidateCursorCheckpoint(previousRef); @@ -263,7 +264,8 @@ export function createCursorAdapter(provider: OcxProviderConfig, deps: CursorAda ...(_parsed._providerContinuation?.cursor ?? {}), conversationId: activeRequest.conversationId, // A tool-suspended checkpoint is only usable by the immediate trailing-toolResult - // continuation; the request-builder guard keys on checkpointUsable=false for that. + // continuation; the request-builder guard keys on this checkpointUsable=false and + // the snapshot's persisted toolSuspended flag for that. checkpointUsable: !toolSuspendedCommit, checkpointRef, }, diff --git a/src/adapters/cursor/checkpoint-store.ts b/src/adapters/cursor/checkpoint-store.ts index 758430064f3..b5ddaa60ef8 100644 --- a/src/adapters/cursor/checkpoint-store.ts +++ b/src/adapters/cursor/checkpoint-store.ts @@ -42,6 +42,7 @@ export interface CursorCheckpointSnapshot { coveredMessageCount?: number; prefixDigest?: string; systemDigest?: string; + toolSuspended?: boolean; } interface CursorCheckpointStore { @@ -229,6 +230,7 @@ export function commitCursorCheckpoint(input: { coveredMessageCount?: number; prefixDigest?: string; systemDigest?: string; + toolSuspended?: boolean; }): string | undefined { if (!input.conversationId || !input.modelId || input.checkpointBytes.byteLength === 0) return undefined; if (input.checkpointBytes.byteLength > CURSOR_CHECKPOINT_MAX_TOTAL_BYTES) return undefined; @@ -258,6 +260,7 @@ export function commitCursorCheckpoint(input: { ...(input.coveredMessageCount !== undefined ? { coveredMessageCount: input.coveredMessageCount } : {}), ...(input.prefixDigest ? { prefixDigest: input.prefixDigest } : {}), ...(input.systemDigest ? { systemDigest: input.systemDigest } : {}), + ...(input.toolSuspended ? { toolSuspended: true } : {}), }; const blobIds = collectCheckpointBlobIds(input.checkpointBytes); if (blobIds === undefined) return undefined; diff --git a/src/adapters/cursor/request-builder.ts b/src/adapters/cursor/request-builder.ts index 3eb922b9689..065f971afa3 100644 --- a/src/adapters/cursor/request-builder.ts +++ b/src/adapters/cursor/request-builder.ts @@ -476,7 +476,13 @@ function resolveCursorCheckpoint( if (cursorCheckpointModelAffinityId(snapshot.modelId) !== cursorCheckpointModelAffinityId(request.modelId)) { return { reason: "model_changed" }; } - if (parsed.context.messages.at(-1)?.role !== "toolResult" && cursorState?.checkpointUsable === false) { + // The continuation state only exists on the ref path; a ref-less prefix hit carries + // the suspension on the snapshot itself, or a non-toolResult request could resume + // bytes upstream serialized mid-tool-call. + if ( + parsed.context.messages.at(-1)?.role !== "toolResult" + && (snapshot.toolSuspended === true || cursorState?.checkpointUsable === false) + ) { return { reason: "trailing_tool_result" }; } const lineage = lineageMismatch(parsed, snapshot); diff --git a/tests/providers/cursor/cursor-tool-suspended-checkpoint.test.ts b/tests/providers/cursor/cursor-tool-suspended-checkpoint.test.ts index a365327a067..85c92eb8eb9 100644 --- a/tests/providers/cursor/cursor-tool-suspended-checkpoint.test.ts +++ b/tests/providers/cursor/cursor-tool-suspended-checkpoint.test.ts @@ -1,6 +1,7 @@ import { describe, expect, test } from "bun:test"; import { createCursorAdapter as createCursorAdapterProduction } from "../../../src/adapters/cursor"; import { clearCursorCheckpointsForTests, cursorCheckpointShape, getCursorCheckpoint } from "../../../src/adapters/cursor/checkpoint-store"; +import { createCursorRequest } from "../../../src/adapters/cursor/request-builder"; import { create, toBinary } from "@bufbuild/protobuf"; import { ConversationStateStructureSchema } from "../../../src/adapters/cursor/gen/agent_pb"; import type { AdapterEvent, OcxParsedRequest, OcxProviderConfig } from "../../../src/types"; @@ -55,7 +56,25 @@ describe("tool-suspended checkpoint commit (devlog 260826 050)", () => { if (done?.type !== "done") throw new Error("expected done"); expect(done.providerState?.cursor?.checkpointRef).toBeDefined(); expect(done.providerState?.cursor?.checkpointUsable).toBe(false); - expect(getCursorCheckpoint(done.providerState?.cursor?.checkpointRef)).toBeDefined(); + expect(getCursorCheckpoint(done.providerState?.cursor?.checkpointRef)?.toolSuspended).toBe(true); + + // A ref-less prefix lookup sees the suspension on the snapshot itself: a request + // whose trailing message is not a toolResult must not resume bytes that upstream + // serialized mid-tool-call. + const retry = createCursorRequest(body("cursor/grok-4.6")); + expect(retry.continuationMode).toBe("full-replay"); + expect(retry.checkpointInvalidationReason).toBe("trailing_tool_result"); + + const continuation = body("cursor/grok-4.6"); + continuation.context.messages.push({ + role: "toolResult", + toolCallId: "call_x", + content: "sunny", + timestamp: 2, + }); + const resumed = createCursorRequest(continuation); + expect(resumed.continuationMode).toBe("checkpoint"); + expect(resumed.checkpointBytes).toEqual(checkpointBytes); clearCursorCheckpointsForTests(); }); From 45a5ca53ddd2539da0afb14d08aa53738e58d6b6 Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sat, 19 Sep 2026 22:08:22 +0900 Subject: [PATCH 40/97] fix(gui): distinguish unmapped prompt layers from the unprintable base prompt (#5102) * fix(gui): distinguish unmapped prompt layers from the unprintable base prompt UNMAPPED_LAYER_IDS reused the base prompt's not-exposed reason, so the dialog showed a base-prompt-specific explanation (model_instructions_file) for unrelated layers. Give them a distinct unmapped reason, render dedicated copy in the read-only dialog, and localize it across all ten locales. * docs(pr): add the unmapped-layer dialog screenshot * fix(gui): correct stale prompt-layer comments and route-test the unmapped split --------- Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com> --- .../pr-assets/364-prompt-layer-unmapped.png | Bin 0 -> 108505 bytes .../codex-set/PromptLayerDialog.tsx | 8 ++-- gui/src/i18n/de.ts | 1 + gui/src/i18n/en.ts | 1 + gui/src/i18n/fr.ts | 1 + gui/src/i18n/ja.ts | 1 + gui/src/i18n/ko.ts | 1 + gui/src/i18n/ru.ts | 1 + gui/src/i18n/tr.ts | 1 + gui/src/i18n/vi.ts | 1 + gui/src/i18n/zh-TW.ts | 1 + gui/src/i18n/zh.ts | 1 + gui/tests/codex-set-prompt-layers.test.tsx | 20 +++++++++ src/codex/prompt-text-probe.ts | 15 ++++--- .../codex-prompt-route.test.ts | 41 ++++++++++++++++++ .../codex-prompt-text-probe.test.ts | 32 ++++++++++++++ 16 files changed, 117 insertions(+), 9 deletions(-) create mode 100644 .github/pr-assets/364-prompt-layer-unmapped.png diff --git a/.github/pr-assets/364-prompt-layer-unmapped.png b/.github/pr-assets/364-prompt-layer-unmapped.png new file mode 100644 index 0000000000000000000000000000000000000000..ff1b5ee15b533d23539d1e407fa1bcb5f8434282 GIT binary patch literal 108505 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

    %$ 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 BM-Bi0 literal 0 HcmV?d00001 diff --git a/gui/src/components/codex-set/PromptLayerDialog.tsx b/gui/src/components/codex-set/PromptLayerDialog.tsx index 3b8ae51920a..98d2bc1d779 100644 --- a/gui/src/components/codex-set/PromptLayerDialog.tsx +++ b/gui/src/components/codex-set/PromptLayerDialog.tsx @@ -154,9 +154,11 @@ export default function PromptLayerDialog({ ? t("codexSet.dialog.emptySource", { path: text.sourcePath ?? "" }) : text?.reason === "not-rendered" ? t("codexSet.dialog.notRendered") - : text?.reason === "not-exposed" - ? t("codexSet.dialog.notExposed") - : t("codexSet.dialog.textUnavailable")} + : text?.reason === "unmapped" + ? t("codexSet.dialog.unmapped") + : text?.reason === "not-exposed" + ? t("codexSet.dialog.notExposed") + : t("codexSet.dialog.textUnavailable")}

    )} diff --git a/gui/src/i18n/de.ts b/gui/src/i18n/de.ts index 8a48248ba7e..3c12b24a2d8 100644 --- a/gui/src/i18n/de.ts +++ b/gui/src/i18n/de.ts @@ -1084,6 +1084,7 @@ export const de: Record = { "codexSet.dialog.notRendered": "In der gelesenen Runde hat diese Ebene nichts gesendet. Abschnitte werden nur bei Änderungen erneut gesendet, daher kann eine einzelne Stichprobe sie nicht enthalten.", "codexSet.dialog.emptySource": "Die Datei unter {path} existiert, ist aber leer, daher sendet diese Ebene nichts.", "codexSet.dialog.notExposed": "Der Basis-Prompt läuft außerhalb der Nachrichtenliste, die Codex ausgeben kann, und lässt sich hier nicht anzeigen. Ersetzen ist über model_instructions_file möglich.", + "codexSet.dialog.unmapped": "Für diese Ebene gibt es noch keine bestätigte Zuordnung in der Prompt-Ausgabe, daher kann ihr Text hier noch nicht angezeigt werden.", "codexSet.dialog.textUnavailable": "Der Codex-Prompt konnte auf diesem Rechner nicht gelesen werden, daher ist der Text nicht verfügbar.", "codexSet.class.base": "Basisanweisungen", "codexSet.class.config-toggle": "Hier umschaltbar", diff --git a/gui/src/i18n/en.ts b/gui/src/i18n/en.ts index 9be7b42263b..c66a5e993be 100644 --- a/gui/src/i18n/en.ts +++ b/gui/src/i18n/en.ts @@ -1631,6 +1631,7 @@ export const en = { "codexSet.dialog.notRendered": "This layer sent nothing on the turn we read. Sections are only re-sent when they change, so an unchanged layer is absent from a single sample.", "codexSet.dialog.emptySource": "The file at {path} exists but is empty, so this layer sends nothing.", "codexSet.dialog.notExposed": "The base prompt travels outside the message list Codex can print, so it cannot be shown here. Replacing it is possible through model_instructions_file.", + "codexSet.dialog.unmapped": "This layer has no confirmed mapping in the prompt output, so its text cannot be shown here yet.", "codexSet.dialog.textUnavailable": "The Codex prompt could not be read on this machine, so the text is unavailable.", "codexSet.class.base": "Base instructions", "codexSet.class.config-toggle": "Switchable here", diff --git a/gui/src/i18n/fr.ts b/gui/src/i18n/fr.ts index 9c119d17d3b..6af22a0e9dc 100644 --- a/gui/src/i18n/fr.ts +++ b/gui/src/i18n/fr.ts @@ -1604,6 +1604,7 @@ export const fr: Record = { "codexSet.dialog.notRendered": "Lors du tour que nous avons lu, cette couche n'a rien envoyé. Les sections ne sont renvoyées qu'en cas de changement : un seul échantillon peut donc ne pas la contenir.", "codexSet.dialog.emptySource": "Le fichier {path} existe mais il est vide : cette couche n'envoie donc rien.", "codexSet.dialog.notExposed": "L'invite de base circule en dehors de la liste de messages que Codex peut afficher ; elle ne peut donc pas être montrée ici. On peut la remplacer via model_instructions_file.", + "codexSet.dialog.unmapped": "Cette couche n'a pas encore de correspondance confirmée dans la sortie de l'invite ; son texte ne peut donc pas encore être affiché ici.", "codexSet.dialog.textUnavailable": "L'invite Codex n'a pas pu être lue sur cette machine, le texte est donc indisponible.", "codexSet.class.base": "Instructions de base", "codexSet.class.config-toggle": "Modifiable ici", diff --git a/gui/src/i18n/ja.ts b/gui/src/i18n/ja.ts index dd283a9299c..19ee0ddc00d 100644 --- a/gui/src/i18n/ja.ts +++ b/gui/src/i18n/ja.ts @@ -1529,6 +1529,7 @@ export const ja: Record = { "codexSet.dialog.notRendered": "確認したターンでは、このレイヤーは何も送信していません。各セクションは内容が変わったときだけ再送されるため、一度の確認では欠けて見えることがあります。", "codexSet.dialog.emptySource": "{path} のファイルは存在しますが空のため、このレイヤーは何も送信しません。", "codexSet.dialog.notExposed": "基本プロンプトは Codex が出力するメッセージ一覧の外を通るため、ここには表示できません。model_instructions_file で置き換えることは可能です。", + "codexSet.dialog.unmapped": "このレイヤーにはプロンプト出力内で確認済みの対応付けがまだないため、ここにはテキストを表示できません。", "codexSet.dialog.textUnavailable": "このマシンでは Codex のプロンプトを読み取れず、原文を表示できません。", "codexSet.class.base": "基本指示", "codexSet.class.config-toggle": "ここで切り替え可能", diff --git a/gui/src/i18n/ko.ts b/gui/src/i18n/ko.ts index 1a1909a74f1..f71338a352a 100644 --- a/gui/src/i18n/ko.ts +++ b/gui/src/i18n/ko.ts @@ -1122,6 +1122,7 @@ export const ko: Record = { "codexSet.dialog.notRendered": "확인한 턴에서는 이 레이어가 아무것도 보내지 않았습니다. 각 섹션은 내용이 바뀔 때만 다시 전송되므로, 한 번 확인한 것만으로는 빠져 보일 수 있습니다.", "codexSet.dialog.emptySource": "{path} 파일은 있지만 비어 있어서 이 레이어는 아무것도 보내지 않습니다.", "codexSet.dialog.notExposed": "기본 프롬프트는 Codex가 출력하는 메시지 목록 밖으로 전달되어 여기서 보여줄 수 없습니다. 대신 model_instructions_file로 교체할 수 있습니다.", + "codexSet.dialog.unmapped": "이 레이어는 프롬프트 출력에서 확인된 매핑이 아직 없어 여기에서 텍스트를 표시할 수 없습니다.", "codexSet.dialog.textUnavailable": "이 컴퓨터에서 Codex 프롬프트를 읽지 못해 원문을 표시할 수 없습니다.", "codexSet.class.base": "기본 지침", "codexSet.class.config-toggle": "여기서 전환 가능", diff --git a/gui/src/i18n/ru.ts b/gui/src/i18n/ru.ts index 485c0b302a7..a7e402cdf0d 100644 --- a/gui/src/i18n/ru.ts +++ b/gui/src/i18n/ru.ts @@ -1599,6 +1599,7 @@ export const ru: Record = { "codexSet.dialog.notRendered": "На прочитанном нами шаге этот слой ничего не отправил. Разделы пересылаются только при изменении, поэтому в одной выборке слой может отсутствовать.", "codexSet.dialog.emptySource": "Файл {path} существует, но пуст, поэтому этот слой ничего не отправляет.", "codexSet.dialog.notExposed": "Базовый промпт передаётся вне списка сообщений, который Codex может напечатать, поэтому показать его здесь нельзя. Заменить его можно через model_instructions_file.", + "codexSet.dialog.unmapped": "Для этого слоя пока нет подтверждённого сопоставления в выводе промпта, поэтому его текст ещё нельзя показать здесь.", "codexSet.dialog.textUnavailable": "На этой машине не удалось прочитать промпт Codex, поэтому текст недоступен.", "codexSet.class.base": "Базовые инструкции", "codexSet.class.config-toggle": "Переключается здесь", diff --git a/gui/src/i18n/tr.ts b/gui/src/i18n/tr.ts index a1d59281c99..f491c7f5277 100644 --- a/gui/src/i18n/tr.ts +++ b/gui/src/i18n/tr.ts @@ -1618,6 +1618,7 @@ export const tr: Record = { "codexSet.dialog.notRendered": "Okuduğumuz turda bu katman hiçbir şey göndermedi. Bölümler yalnızca değiştiklerinde yeniden gönderilir, bu yüzden tek bir örnekte görünmeyebilir.", "codexSet.dialog.emptySource": "{path} konumundaki dosya var ancak boş, bu yüzden bu katman hiçbir şey göndermiyor.", "codexSet.dialog.notExposed": "Temel istem, Codex'in yazdırabildiği mesaj listesinin dışından geçtiği için burada gösterilemez. model_instructions_file ile değiştirilebilir.", + "codexSet.dialog.unmapped": "Bu katmanın istem çıktısında henüz doğrulanmış bir eşlemesi yok, bu nedenle metni burada henüz gösterilemiyor.", "codexSet.dialog.textUnavailable": "Bu makinede Codex istemi okunamadı, bu yüzden metin kullanılamıyor.", "codexSet.class.base": "Temel talimatlar", "codexSet.class.config-toggle": "Buradan değiştirilebilir", diff --git a/gui/src/i18n/vi.ts b/gui/src/i18n/vi.ts index a6ef50b7f8e..b26ec1ea95a 100644 --- a/gui/src/i18n/vi.ts +++ b/gui/src/i18n/vi.ts @@ -1580,6 +1580,7 @@ export const vi: Record = { "codexSet.dialog.sourceBytes": "{bytes} byte", "codexSet.dialog.emptySource": "Tệp tại {path} tồn tại nhưng không có dữ liệu, vì vậy layer này không gửi đi nội dung nào cả.", "codexSet.dialog.notExposed": "Base prompt di chuyển bên ngoài danh sách tin nhắn mà Codex có thể in ra, vì vậy không thể hiển thị ở đây. Tuy nhiên có thể thay thế nó thông qua model_instructions_file.", + "codexSet.dialog.unmapped": "Lớp này chưa có ánh xạ được xác nhận trong đầu ra prompt, vì vậy chưa thể hiển thị văn bản của nó ở đây.", "codexSet.dialog.textUnavailable": "Không thể đọc prompt Codex trên máy này, do đó văn bản không khả dụng.", "codexSet.class.base": "Base instructions", "codexSet.class.config-toggle": "Có thể chuyển đổi tại đây", diff --git a/gui/src/i18n/zh-TW.ts b/gui/src/i18n/zh-TW.ts index 0ca62560f43..f23791fee87 100644 --- a/gui/src/i18n/zh-TW.ts +++ b/gui/src/i18n/zh-TW.ts @@ -1375,6 +1375,7 @@ export const zhTW: Record = { "codexSet.dialog.notRendered": "在我們讀取的那一輪中,此層沒有傳送任何內容。各區段只在內容變更時才會重新傳送,因此單次取樣可能看不到它。", "codexSet.dialog.emptySource": "{path} 檔案存在但為空,因此此層不會傳送任何內容。", "codexSet.dialog.notExposed": "基礎提示詞不在 Codex 可列印的訊息清單中傳遞,因此無法在此顯示。可以透過 model_instructions_file 取代它。", + "codexSet.dialog.unmapped": "此層在提示詞輸出中尚無已確認的對應,因此暫時無法在此顯示其文字。", "codexSet.dialog.textUnavailable": "本機無法讀取 Codex 提示詞,因此無法顯示原文。", "codexSet.class.base": "基礎指令", "codexSet.class.config-toggle": "可在此切換", diff --git a/gui/src/i18n/zh.ts b/gui/src/i18n/zh.ts index 277cda2e64b..4a8dcbf7274 100644 --- a/gui/src/i18n/zh.ts +++ b/gui/src/i18n/zh.ts @@ -1103,6 +1103,7 @@ export const zh: Record = { "codexSet.dialog.notRendered": "在我们读取的那一轮中,此层没有发送任何内容。各部分仅在内容变化时才会重新发送,因此单次采样可能看不到它。", "codexSet.dialog.emptySource": "{path} 文件存在但为空,因此此层不会发送任何内容。", "codexSet.dialog.notExposed": "基础提示词不在 Codex 可打印的消息列表中传递,因此无法在此显示。可以通过 model_instructions_file 替换它。", + "codexSet.dialog.unmapped": "此层在提示词输出中尚无已确认的映射,因此暂时无法在此显示其文本。", "codexSet.dialog.textUnavailable": "本机无法读取 Codex 提示词,因此无法显示原文。", "codexSet.class.base": "基础指令", "codexSet.class.config-toggle": "可在此切换", diff --git a/gui/tests/codex-set-prompt-layers.test.tsx b/gui/tests/codex-set-prompt-layers.test.tsx index 3d654b16aa0..42963d353c0 100644 --- a/gui/tests/codex-set-prompt-layers.test.tsx +++ b/gui/tests/codex-set-prompt-layers.test.tsx @@ -258,6 +258,26 @@ test("9. the dialog names WHY text is missing rather than omitting it silently", await act(async () => { root.unmount(); }); }); +test("9b. an unmapped layer does not receive the base-prompt explanation", async () => { + // A probe that succeeded but has no confirmed tag for a layer is neither + // "unavailable" nor the base prompt's "not-exposed": the not-exposed copy + // names the base prompt and model_instructions_file, which would mislead an + // operator reading it for an unrelated layer. + stubRoutes(call => call.url.endsWith("/api/codex-prompt/text") + ? json({ ok: true, layers: { personality: { text: null, reason: "unmapped", bytes: 0 } } }) + : json(snapshot())); + const { container, root } = await mount(); + await act(async () => { + (row(container, "personality")!.querySelector("button") as HTMLButtonElement).click(); + }); + const dialog = document.querySelector("dialog.modal-overlay")!; + const notice = dialog.querySelector(".codex-set-layer-dialog__no-text")!; + expect(notice.textContent).toContain("no confirmed mapping"); + expect(notice.textContent).not.toContain("base prompt"); + expect(notice.textContent).not.toContain("model_instructions_file"); + await act(async () => { root.unmount(); }); +}); + test("the prompt-text request is aborted when the panel unmounts", async () => { let textSignal: AbortSignal | null = null; globalThis.fetch = (async (input: RequestInfo | URL, init?: RequestInit) => { diff --git a/src/codex/prompt-text-probe.ts b/src/codex/prompt-text-probe.ts index 8af11f00f5e..444b7bb763f 100644 --- a/src/codex/prompt-text-probe.ts +++ b/src/codex/prompt-text-probe.ts @@ -75,7 +75,7 @@ const UNMAPPED_LAYER_IDS = [ // The Rust source names a marker pair, but a world-state section is // DIFF-rendered: it emits nothing on a turn where its state has not changed. Live // `codex debug prompt-input` (codex-cli 0.145.0, 32978 bytes) showed no such block and - // no attribution text. Listing the id here reports "not exposed" honestly instead of + // no attribution text. Listing the id here reports "unmapped" honestly instead of // claiming a tag this extractor has never actually matched - the same mistake the // header above records for permissions. "git-attribution", @@ -85,7 +85,7 @@ export interface LayerText { /** Rendered text, when this layer produced a section on the probed turn. */ text: string | null; /** Why the text is absent, when it is. */ - reason: "ok" | "empty-source" | "not-rendered" | "not-exposed" | "unavailable"; + reason: "ok" | "empty-source" | "not-rendered" | "not-exposed" | "unmapped" | "unavailable"; bytes: number; /** * `expanded` is text Codex sends as written. `template` is a catalog @@ -103,7 +103,7 @@ export interface LayerText { /** * Why the base prompt is or is not readable, at the granularity a reader can act - * on. `LayerText.reason` has five coarse values and cannot express any of this, + * on. `LayerText.reason` has six coarse values and cannot express any of this, * which is why the detailed answer travels on its own record. */ export type BasePromptReason = @@ -374,7 +374,7 @@ function readBasePrompt(codexHome: string): BasePromptText { /** * Project the base prompt onto the legacy `base-instructions` layer slot. * - * The slot is lossy by construction - five coarse reasons, no renderer that reads + * The slot is lossy by construction - six coarse reasons, no renderer that reads * `representation` - so it carries only what it can carry honestly: published text * when the source is text Codex sends, and otherwise no text at all. A template is * deliberately NOT `ok` here, because the dialog labels every `ok` layer "Text @@ -944,9 +944,12 @@ export async function probePromptText( // Layers whose rendered tag we have not confirmed against live output. Leaving // them absent made the GUI fall through to "unavailable", which claims the probe - // failed when it succeeded. Saying we have no mapping is the smaller claim. + // failed when it succeeded. Keep this distinct from the base prompt's + // "not-exposed", which is confirmed to travel outside the printable message + // list - reusing it showed a base-prompt-specific explanation for unrelated + // layers. for (const id of UNMAPPED_LAYER_IDS) { - layers[id] ??= { text: null, reason: "not-exposed", bytes: 0 }; + layers[id] ??= { text: null, reason: "unmapped", bytes: 0 }; } return { ok: true, codexHome, layers, base, ...(reportedRuntime ? { runtime: reportedRuntime } : {}) }; } diff --git a/tests/codex-integration/codex-prompt-route.test.ts b/tests/codex-integration/codex-prompt-route.test.ts index feb38632db2..ec90891f2a5 100644 --- a/tests/codex-integration/codex-prompt-route.test.ts +++ b/tests/codex-integration/codex-prompt-route.test.ts @@ -1520,5 +1520,46 @@ describe("020 coverage completions", () => { expect(res.body.code).toBe("invalid_body"); }); + test("41. unmapped layers stay distinct from the unprintable base prompt", async () => { + // "not-exposed" is the base prompt's contract: it is confirmed to travel + // outside the printable message list, and the GUI renders a + // base-prompt-specific explanation for it. Reusing that reason for layers + // whose tag the extractor has not verified showed that explanation on + // unrelated layers. + const fx = fixture(""); + // The probe reads the base prompt from CODEX_HOME - the decoy here, whose + // sentinel config selects model "sentinel". A catalog row that publishes + // only an instructions_template makes the base confirmed unprintable, so + // base-instructions must report "not-exposed" while the tag-less layers + // report "unmapped". + writeFileSync(join(fx.decoyHome, "opencodex-catalog.json"), JSON.stringify({ + models: [{ slug: "sentinel", model_messages: { instructions_template: "template {{unprintable}}" } }], + }), "utf8"); + const probeOutput = JSON.stringify([{ + type: "message", + role: "developer", + content: [{ type: "input_text", text: "Skill text." }], + }]); + setPromptTextProbeCommandForTests({ + binary: process.execPath, + args: ["-e", `process.stdout.write(${JSON.stringify(probeOutput)});`], + }); + + const res = await call("GET", "/api/codex-prompt/text", fx); + expect(res.status).toBe(200); + expect(res.body.ok).toBe(true); + expect(res.body.base.representation).toBe("template"); + expect(res.body.layers["base-instructions"].reason).toBe("not-exposed"); + // Mirrors UNMAPPED_LAYER_IDS in prompt-text-probe.ts. + for (const id of [ + "model-switch", "context-window-guidance", "environments-instructions", + "tools", "multi-agent-mode", "personality", "realtime", "collaboration", + "git-attribution", + ]) { + expect(res.body.layers[id]?.reason).toBe("unmapped"); + } + expectDecoyUntouched(fx); + }); + }); diff --git a/tests/codex-integration/codex-prompt-text-probe.test.ts b/tests/codex-integration/codex-prompt-text-probe.test.ts index 58df48c1c11..3d7b756dfa5 100644 --- a/tests/codex-integration/codex-prompt-text-probe.test.ts +++ b/tests/codex-integration/codex-prompt-text-probe.test.ts @@ -613,6 +613,38 @@ describe("prompt probe process lifecycle", () => { }); }); +describe("unmapped layers", () => { + test("a layer with no confirmed tag reports unmapped, not the base prompt's not-exposed", async () => { + // UNMAPPED_LAYER_IDS used to reuse "not-exposed", which is the base prompt's + // contract: the GUI renders a base-prompt-specific explanation for it. A + // layer the extractor simply has no verified tag for is a smaller claim. + const home = promptHome({ + "config.toml": "model = \"gpt-test\"\n", + "opencodex-catalog.json": catalogJson([{ slug: "gpt-test", base_instructions: "Base prompt body." }]), + }); + const previousHome = process.env.CODEX_HOME; + process.env.CODEX_HOME = home; + setPromptTextProbeCommandForTests({ + binary: process.execPath, + args: ["-e", `process.stdout.write(${JSON.stringify(VALID_PROBE_OUTPUT)})`], + }); + try { + const result = await probePromptText(2_000); + expect(result.ok).toBe(true); + if (result.ok) { + expect(result.layers["personality"]).toMatchObject({ text: null, reason: "unmapped", bytes: 0 }); + expect(result.layers["tools"]).toMatchObject({ text: null, reason: "unmapped", bytes: 0 }); + // The base prompt keeps its own contract: readable text stays "ok" and an + // unexpanded template stays "not-exposed" - never "unmapped". + expect(result.layers["base-instructions"]).toMatchObject({ text: "Base prompt body.", reason: "ok" }); + } + } finally { + if (previousHome === undefined) delete process.env.CODEX_HOME; + else process.env.CODEX_HOME = previousHome; + } + }); +}); + describe("runtime resolution and failure classification", () => { test("a runtime the shared resolver finds is spawned, not reported missing", async () => { // Issue 4458: the old four-path POSIX check reported "codex binary not From ff8c337194455c8cb601cb32b283a0f71786545a Mon Sep 17 00:00:00 2001 From: shawn-kim-ai Date: Sat, 19 Sep 2026 22:08:28 +0900 Subject: [PATCH 41/97] feat(meta-muse): expose max reasoning effort to routed clients (#5094) --- .../src/content/docs/guides/providers.md | 6 +++++ src/providers/registry/entries-core.ts | 15 +++++++---- src/providers/registry/model-seeds.ts | 9 +++++++ structure/providers-and-adapters.md | 4 +++ structure/providers/xai-grok.md | 2 ++ structure/runtime.md | 2 ++ structure/subagents.md | 1 + structure/transports/inventory.md | 2 ++ tests/providers/meta-muse-oauth.test.ts | 27 ++++++++++++++++--- tests/providers/muse-key-quota.test.ts | 24 ++++++++++++++--- .../providers/xai/grok-effort-inject.test.ts | 14 ++++++++++ 11 files changed, 94 insertions(+), 12 deletions(-) diff --git a/docs-site/src/content/docs/guides/providers.md b/docs-site/src/content/docs/guides/providers.md index 9bcf40cbf64..6df5252c04f 100644 --- a/docs-site/src/content/docs/guides/providers.md +++ b/docs-site/src/content/docs/guides/providers.md @@ -686,6 +686,12 @@ instead, where the same key is visible. A pasted key faces the same format check same live validation against the Model API as an imported one. See [Platform support](/reference/platform-support/) for the full per-platform picture. +Both seeded `meta-muse` models expose `minimal`/`low`/`medium`/`high`/`xhigh`/`max` to +routed clients, including Grok's effort picker. Requests use +`User-Agent: muse-build/1.3.0 (opencodex compatibility)` so Meta accepts the Muse Code +effort contract. An explicit provider User-Agent overrides this default and may cause +`max` to be rejected. The `meta-model` and OpenCode Go effort ladders remain unchanged. + **Read this before enabling it.** Meta scopes that credential to the Muse Code CLI, so using it here is an *unsupported* path. Meta does not authorize subscription coverage outside its own client, how these calls settle is not observable from the API, and you diff --git a/src/providers/registry/entries-core.ts b/src/providers/registry/entries-core.ts index 1c36394256c..c67b510828f 100644 --- a/src/providers/registry/entries-core.ts +++ b/src/providers/registry/entries-core.ts @@ -30,6 +30,8 @@ import { OPENAI_API_GPT56_REASONING_EFFORTS, META_MUSE_REASONING_EFFORTS, META_MUSE_REASONING_EFFORT_MAP, + META_MUSE_CODE_REASONING_EFFORTS, + META_MUSE_CODE_REASONING_EFFORT_MAP, META_MUSE_CONTEXT_WINDOW, META_MUSE_MODELS, OPENAI_DAYBREAK_MODELS, @@ -599,12 +601,15 @@ export const PROVIDER_REGISTRY_CORE: readonly ProviderRegistryEntry[] = [ label: "Meta Muse Code (CLI credential)", adapter: "openai-responses", baseUrl: "https://api.meta.ai/v1", - // Meta own client sends this on every Muse Code call. We never have, so a future - // server-side requirement would break every Muse request with no local signal. + // Meta's own client sends these on every Muse Code call. The compatibility marker + // is transparent while selecting the credential surface that accepts `max`. // Declared here rather than in a transport hook so it also covers model discovery // (src/oauth/index.ts:1176) and still yields to a user-set header // (mergeRegistryStaticHeaders, src/providers/registry.ts:3494). - staticHeaders: { "x-api-version": "1.0.0" }, + staticHeaders: { + "User-Agent": "muse-build/1.3.0 (opencodex compatibility)", + "x-api-version": "1.0.0", + }, authKind: "oauth", oauthId: "meta-muse", dashboardUrl: "https://dev.meta.ai", @@ -615,8 +620,8 @@ export const PROVIDER_REGISTRY_CORE: readonly ProviderRegistryEntry[] = [ liveModels: false, modelContextWindows: Object.fromEntries(META_MUSE_MODELS.map(id => [id, META_MUSE_CONTEXT_WINDOW])), modelInputModalities: Object.fromEntries(META_MUSE_MODELS.map(id => [id, ["text", "image"] as ["text", "image"]])), - modelReasoningEfforts: Object.fromEntries(META_MUSE_MODELS.map(id => [id, META_MUSE_REASONING_EFFORTS])), - modelReasoningEffortMap: Object.fromEntries(META_MUSE_MODELS.map(id => [id, META_MUSE_REASONING_EFFORT_MAP])), + modelReasoningEfforts: Object.fromEntries(META_MUSE_MODELS.map(id => [id, META_MUSE_CODE_REASONING_EFFORTS])), + modelReasoningEffortMap: Object.fromEntries(META_MUSE_MODELS.map(id => [id, META_MUSE_CODE_REASONING_EFFORT_MAP])), note: "Signs in to Meta with a browser device code on any platform, then mints the Muse Code subscription key. That grant is reimplemented from the one the Muse Code CLI performs and has NOT been exercised against Meta from OpenCodex, so treat the first login as unverified. If the Muse Code CLI is already signed in on macOS, the existing key is imported instead of starting a new grant. A pasted key from https://dev.meta.ai still works as a fallback when a device login cannot complete, and faces the same format check and live validation. A device login authenticates as Meta own Muse Code client, which is a stronger claim than reusing a key the CLI already minted. Meta scopes that credential to the Muse Code CLI, so this is an UNSUPPORTED use: Meta does not authorize subscription coverage outside its own CLI, how these calls settle is not observable from the API, and you should treat every call as billable against your account. The key, imported or pasted, is copied into OpenCodex's auth store. For an account signed in with the device login, OpenCodex refreshes Meta's subscription windows on demand from the same key endpoint the login uses, at most once every five minutes. For an imported or pasted key there is no endpoint to query them on demand, so OpenCodex reads them from streaming responses and shows the last observed value with its age; refreshing one then requires another streaming turn, and translated (non-passthrough) turns report none. Rate limits apply per team, not per key. For a supported path use the meta-model provider with your own key (export it as META_MODEL_API_KEY).", }, { diff --git a/src/providers/registry/model-seeds.ts b/src/providers/registry/model-seeds.ts index 62517025e53..a1d9661395a 100644 --- a/src/providers/registry/model-seeds.ts +++ b/src/providers/registry/model-seeds.ts @@ -177,6 +177,15 @@ export const META_MUSE_REASONING_EFFORTS = ["minimal", "low", "medium", "high", export const META_MUSE_REASONING_EFFORT_MAP: Record = Object.fromEntries( META_MUSE_REASONING_EFFORTS.map(effort => [effort, effort]), ); +/* + * Muse Code credentials have a separate capability contract. Meta's authenticated + * /muse-code/models roster advertises max for both 1.3 models, and the Responses API + * accepts it when the request identifies the Muse client surface. + */ +export const META_MUSE_CODE_REASONING_EFFORTS = [...META_MUSE_REASONING_EFFORTS, "max"]; +export const META_MUSE_CODE_REASONING_EFFORT_MAP: Record = Object.fromEntries( + META_MUSE_CODE_REASONING_EFFORTS.map(effort => [effort, effort]), +); /** Both Muse Spark 1.3 tiers publish a 1,048,576-token window (dev.meta.ai/docs/models). */ export const META_MUSE_CONTEXT_WINDOW = 1_048_576; export const META_MUSE_MODELS = ["muse-spark-1.3", "muse-spark-1.3-contributor"]; diff --git a/structure/providers-and-adapters.md b/structure/providers-and-adapters.md index cf5000eb151..beb442a4dc3 100644 --- a/structure/providers-and-adapters.md +++ b/structure/providers-and-adapters.md @@ -57,6 +57,10 @@ Provider-scoped capability hints remain authoritative when discovery returns an capabilities. In particular, `src/providers/registry/entries-core.ts` assigns OpenCode Go's live `deepseek-v4.1-flash` route the official 1,048,576-token window instead of the conservative 128k routed-model fallback. +Meta's two direct surfaces keep separate reasoning contracts: `meta-model` remains capped at +`xhigh`, while `meta-muse` advertises `max` and sends the transparent Muse compatibility +User-Agent required by that credential surface. The existing registry header merge keeps an +operator-supplied User-Agent authoritative. The same registry declares the first-party `deepseek-flash` model with `text` and `image` input, so it bypasses the vision sidecar by default; explicit `noVisionModels` or text-only declarations remain authoritative. First-party `deepseek-chat`, `deepseek-reasoner`, and `deepseek-v4-flash` diff --git a/structure/providers/xai-grok.md b/structure/providers/xai-grok.md index 37815ed04d1..a9317bc4dda 100644 --- a/structure/providers/xai-grok.md +++ b/structure/providers/xai-grok.md @@ -1,5 +1,7 @@ # xAI Grok Provider +The Grok client picker forwards the `meta-muse` catalog's `max` effort through its existing managed-block export; this follows the [Muse provider contract](../providers-and-adapters.md). + Native result continuations and function-result injection follow [the mode-specific result and control contract](../transports/streaming-health.md#experimental-native-function-result-injection); this surface does not infer upstream support or alter its defaults. Native steering follows [the shared WebSocket contract](../transports/streaming-health.md#experimental-native-mid-turn-steering); this surface's defaults remain unchanged. diff --git a/structure/runtime.md b/structure/runtime.md index 983881c21fe..3a8f5228077 100644 --- a/structure/runtime.md +++ b/structure/runtime.md @@ -1,5 +1,7 @@ # Runtime +Routed Meta Muse requests use the registry-owned [Muse effort and header contract](providers-and-adapters.md); `max` reaches the provider through the existing reasoning mapper. + Native result continuations and function-result injection follow [the mode-specific result and control contract](transports/streaming-health.md#experimental-native-function-result-injection); this surface does not infer upstream support or alter its defaults. Native steering follows [the shared WebSocket contract](transports/streaming-health.md#experimental-native-mid-turn-steering); this surface's defaults remain unchanged. diff --git a/structure/subagents.md b/structure/subagents.md index a607de463e3..fe034027c12 100644 --- a/structure/subagents.md +++ b/structure/subagents.md @@ -149,6 +149,7 @@ featured or picker rank. Canonical `opencode-go` rows retain their configured re and provider-scoped context metadata both when generated and when merged from retained catalog state; `deepseek-v4.1-flash` therefore keeps its 1,048,576-token window, while synthetic max/ultra choices are not added to that provider's declared ladder. +`meta-muse` declares `max` for both seeded models under the [Muse provider contract](providers-and-adapters.md), so routed-client catalogs can expose it without extending OpenCode Go's ladder. The first-party DeepSeek `deepseek-flash` row declares native `text` and `image` input and therefore does not require the vision sidecar by default; explicit `noVisionModels` or text-only declarations remain authoritative. First-party `deepseek-chat`, `deepseek-reasoner`, and `deepseek-v4-flash` diff --git a/structure/transports/inventory.md b/structure/transports/inventory.md index 5f35e4d81c0..b20317932dc 100644 --- a/structure/transports/inventory.md +++ b/structure/transports/inventory.md @@ -1,5 +1,7 @@ # Transport Inventory +Meta Muse's registry-owned compatibility User-Agent takes precedence over an incoming client User-Agent; explicit provider headers still win. See the [Muse provider contract](../providers-and-adapters.md). + Native result continuations and function-result injection follow [the mode-specific result and control contract](streaming-health.md#experimental-native-function-result-injection); this surface does not infer upstream support or alter its defaults. Native steering follows [the shared WebSocket contract](streaming-health.md#experimental-native-mid-turn-steering); this surface's defaults remain unchanged. diff --git a/tests/providers/meta-muse-oauth.test.ts b/tests/providers/meta-muse-oauth.test.ts index 08f824fc531..c70c4b2a76b 100644 --- a/tests/providers/meta-muse-oauth.test.ts +++ b/tests/providers/meta-muse-oauth.test.ts @@ -9,12 +9,18 @@ * reaches a message or a status object. */ import { describe, expect, test } from "bun:test"; +import { createResponsesPassthroughAdapter as createResponsesPassthroughAdapterProduction } from "../../src/adapters/openai-responses"; import { OAUTH_PROVIDERS } from "../../src/oauth"; import { loginMetaMuse, refreshMetaMuseToken } from "../../src/oauth/meta-muse"; +import { providerConfigSeed } from "../../src/providers/derive"; import { getProviderRegistryEntry } from "../../src/providers/registry"; import { supportsPerAccountQuota } from "../../src/providers/quota"; import { routeModel } from "../../src/router"; -import type { OcxConfig } from "../../src/types"; +import type { OcxConfig, OcxProviderConfig } from "../../src/types"; +import { withTestTranslatorBudget } from "../helpers/translator-budget"; + +const createResponsesPassthroughAdapter = (...args: Parameters) => + withTestTranslatorBudget(createResponsesPassthroughAdapterProduction(...args)); const MODELS = ["muse-spark-1.3", "muse-spark-1.3-contributor"] as const; @@ -54,15 +60,30 @@ describe("meta-muse registry entry", () => { expect(entry().oauthId).toBe("meta-muse"); }); - test("reuses the ladder, window, modalities and identity wire map from the key provider", () => { + test("adds max to the Muse credential ladder while reusing the model metadata", () => { for (const id of MODELS) { - expect(entry().modelReasoningEfforts?.[id]).toEqual(["minimal", "low", "medium", "high", "xhigh"]); + expect(entry().modelReasoningEfforts?.[id]).toEqual(["minimal", "low", "medium", "high", "xhigh", "max"]); expect(entry().modelReasoningEffortMap?.[id]?.minimal).toBe("minimal"); + expect(entry().modelReasoningEffortMap?.[id]?.max).toBe("max"); expect(entry().modelContextWindows?.[id]).toBe(1_048_576); expect(entry().modelInputModalities?.[id]).toEqual(["text", "image"]); } }); + test("max reaches the Responses wire unchanged", () => { + const provider = { ...providerConfigSeed(entry()), apiKey: "meta-test-key" } as OcxProviderConfig; + const request = createResponsesPassthroughAdapter(provider).buildRequest({ + modelId: "muse-spark-1.3-contributor", + context: { messages: [] }, + stream: false, + options: { reasoning: "max" }, + _rawBody: { model: "muse-spark-1.3-contributor", input: "ping", reasoning: { effort: "max" } }, + }, { headers: new Headers({ "user-agent": "grok-build/test" }) }); + const body = JSON.parse(request.body) as { reasoning?: { effort?: string } }; + expect(body.reasoning?.effort).toBe("max"); + expect(new Headers(request.headers).get("user-agent")).toBe("muse-build/1.3.0 (opencodex compatibility)"); + }); + test("keeps live discovery off — the real roster carries image and voice models", () => { expect(entry().liveModels).toBeFalsy(); expect(entry().models).toEqual([...MODELS]); diff --git a/tests/providers/muse-key-quota.test.ts b/tests/providers/muse-key-quota.test.ts index 5908483c98c..7fda5b485fd 100644 --- a/tests/providers/muse-key-quota.test.ts +++ b/tests/providers/muse-key-quota.test.ts @@ -155,19 +155,35 @@ describe("muse key quota probe", () => { }); describe("muse model api version header", () => { - test("the registry row declares it", () => { - expect(getProviderRegistryEntry("meta-muse")?.staticHeaders).toEqual({ "x-api-version": "1.0.0" }); + test("the registry row declares the Muse compatibility headers", () => { + expect(getProviderRegistryEntry("meta-muse")?.staticHeaders).toEqual({ + "User-Agent": "muse-build/1.3.0 (opencodex compatibility)", + "x-api-version": "1.0.0", + }); }); test("a user-set header of the same name still wins", () => { const entry = getProviderRegistryEntry("meta-muse"); const merged = mergeRegistryStaticHeaders(entry?.staticHeaders, { "X-Api-Version": "9.9.9" }); - expect(merged).toEqual({ "X-Api-Version": "9.9.9" }); + expect(merged).toEqual({ + "User-Agent": "muse-build/1.3.0 (opencodex compatibility)", + "X-Api-Version": "9.9.9", + }); }); test("it is merged in when the user sets an unrelated header", () => { const entry = getProviderRegistryEntry("meta-muse"); const merged = mergeRegistryStaticHeaders(entry?.staticHeaders, { "X-Trace": "1" }); - expect(merged).toEqual({ "X-Trace": "1", "x-api-version": "1.0.0" }); + expect(merged).toEqual({ + "User-Agent": "muse-build/1.3.0 (opencodex compatibility)", + "X-Trace": "1", + "x-api-version": "1.0.0", + }); + }); + + test("a user-set User-Agent still wins", () => { + const entry = getProviderRegistryEntry("meta-muse"); + const merged = mergeRegistryStaticHeaders(entry?.staticHeaders, { "user-agent": "custom-client/1.0" }); + expect(merged).toEqual({ "user-agent": "custom-client/1.0", "x-api-version": "1.0.0" }); }); }); diff --git a/tests/providers/xai/grok-effort-inject.test.ts b/tests/providers/xai/grok-effort-inject.test.ts index 179bfc5dae8..64764fd22d8 100644 --- a/tests/providers/xai/grok-effort-inject.test.ts +++ b/tests/providers/xai/grok-effort-inject.test.ts @@ -109,6 +109,20 @@ describe("Grok inject model catalog", () => { expect(sol?.contextWindow).toBe(500_000); expect(sol?.reasoningEfforts).toEqual(nativeReasoningEfforts(NATIVE_SOL)); }); + + test("forwards Meta Muse max into the Grok picker", () => { + const routed: CatalogModel = { + provider: "meta-muse", + id: "muse-spark-1.3-contributor", + contextWindow: 1_048_576, + reasoningEfforts: ["minimal", "low", "medium", "high", "xhigh", "max"], + }; + const block = buildGrokManagedBlock(10100, buildGrokInjectModels(baseConfig(), [routed])); + const table = tableByModelId(parseModels(block), "meta-muse/muse-spark-1.3-contributor"); + expect(table.reasoning_efforts?.map(row => row.value)).toEqual([ + "minimal", "low", "medium", "high", "xhigh", "max", + ]); + }); }); describe("Grok managed-block thinking-intensity injection", () => { From 7fd629f74657fea3176c27a41ad1008694fd2053 Mon Sep 17 00:00:00 2001 From: shawn-kim-ai Date: Sat, 19 Sep 2026 22:08:33 +0900 Subject: [PATCH 42/97] fix(grok): normalize integral Responses timestamps (#5071) * test(grok): cover float response timestamps * fix(grok): normalize integral response timestamps * fix(grok): preserve timestamp rewrite boundaries Restrict lexical timestamp matches to event.response and retain data prefixes when rewriting multi-line SSE payloads. * fix(grok): ignore nested timestamp collisions Match timestamp tokens only on direct response properties so nested metadata cannot block or redirect normalization. * test(windows): allow bounded ACL child teardown * test(windows): bound sequential ACL watchdogs --- src/server/grok-responses-control-frame.ts | 161 +++++++++++++++++- src/server/responses/passthrough-delivery.ts | 8 +- src/server/sse-payload-rewrite.ts | 2 +- structure/providers/xai-grok.md | 5 + structure/transports/responses.md | 5 + .../responses-snapshot-repair-server.test.ts | 76 ++++++++- tests/responses/responses-state.test.ts | 4 +- 7 files changed, 250 insertions(+), 11 deletions(-) diff --git a/src/server/grok-responses-control-frame.ts b/src/server/grok-responses-control-frame.ts index e910daf99d6..4d10340bfc9 100644 --- a/src/server/grok-responses-control-frame.ts +++ b/src/server/grok-responses-control-frame.ts @@ -1,10 +1,137 @@ -import { sseDataPayload, type SseBlockRewrite } from "./sse-payload-rewrite"; +import { replaceSseDataPayload, sseDataPayload, type SseBlockRewrite } from "./sse-payload-rewrite"; const GROK_CONTROL_FRAME_TYPES: Record = { "codex.rate_limits": true, "codex.response.metadata": true, }; +const GROK_RESPONSE_INTEGER_TIMESTAMP_FIELDS = ["created_at", "completed_at"] as const; + +type JsonRange = { start: number; end: number }; + +function skipJsonWhitespace(payload: string, index: number): number { + while (index < payload.length && /[\t\n\r ]/.test(payload[index] ?? "")) index += 1; + return index; +} + +function findJsonStringEnd(payload: string, start: number): number | undefined { + for (let index = start + 1; index < payload.length; index += 1) { + if (payload[index] === "\\") index += 1; + else if (payload[index] === '"') return index + 1; + } + return undefined; +} + +function findJsonValueEnd(payload: string, start: number): number | undefined { + if (payload[start] === '"') return findJsonStringEnd(payload, start); + if (payload[start] !== "{" && payload[start] !== "[") { + let index = start; + while (index < payload.length && !",}]".includes(payload[index] ?? "")) index += 1; + return index; + } + + let depth = 0; + let inString = false; + for (let index = start; index < payload.length; index += 1) { + const char = payload[index]; + if (inString) { + if (char === "\\") index += 1; + else if (char === '"') inString = false; + continue; + } + if (char === '"') inString = true; + else if (char === "{" || char === "[") depth += 1; + else if (char === "}" || char === "]") { + depth -= 1; + if (depth === 0) return index + 1; + } + } + return undefined; +} + +function findResponseObjectRange(payload: string): JsonRange | null { + let cursor = skipJsonWhitespace(payload, 0); + if (payload[cursor] !== "{") return null; + cursor += 1; + let responseRange: JsonRange | null = null; + + while (cursor < payload.length) { + cursor = skipJsonWhitespace(payload, cursor); + if (payload[cursor] === "}") return responseRange; + if (payload[cursor] !== '"') return null; + const keyEnd = findJsonStringEnd(payload, cursor); + if (keyEnd === undefined) return null; + let key: unknown; + try { + key = JSON.parse(payload.slice(cursor, keyEnd)); + } catch { + return null; + } + + cursor = skipJsonWhitespace(payload, keyEnd); + if (payload[cursor] !== ":") return null; + const valueStart = skipJsonWhitespace(payload, cursor + 1); + const valueEnd = findJsonValueEnd(payload, valueStart); + if (valueEnd === undefined) return null; + if (key === "response" && payload[valueStart] === "{") { + responseRange = { start: valueStart, end: valueEnd }; + } + + cursor = skipJsonWhitespace(payload, valueEnd); + if (payload[cursor] === "}") return responseRange; + if (payload[cursor] !== ",") return null; + cursor += 1; + } + return null; +} + +function rewriteIntegralTimestamp(payload: string, field: string, value: number, event: unknown): string | null { + const responseRange = findResponseObjectRange(payload); + if (responseRange === null) return null; + let cursor = responseRange.start + 1; + let candidate: { start: number; length: number } | null = null; + while (cursor < responseRange.end) { + cursor = skipJsonWhitespace(payload, cursor); + if (payload[cursor] === "}") break; + if (payload[cursor] !== '"') return null; + const keyEnd = findJsonStringEnd(payload, cursor); + if (keyEnd === undefined) return null; + let key: unknown; + try { + key = JSON.parse(payload.slice(cursor, keyEnd)); + } catch { + return null; + } + cursor = skipJsonWhitespace(payload, keyEnd); + if (payload[cursor] !== ":") return null; + const valueStart = skipJsonWhitespace(payload, cursor + 1); + const valueEnd = findJsonValueEnd(payload, valueStart); + if (valueEnd === undefined || valueEnd > responseRange.end) return null; + const valueToken = payload.slice(valueStart, valueEnd).trimEnd(); + if ( + key === field && + /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(valueToken) && + valueToken !== String(value) && + Number(valueToken) === value + ) { + if (candidate !== null) return null; + candidate = { start: valueStart, length: valueToken.length }; + } + cursor = skipJsonWhitespace(payload, valueEnd); + if (payload[cursor] === "}") break; + if (payload[cursor] !== ",") return null; + cursor += 1; + } + if (candidate === null) return payload; + + const rewritten = `${payload.slice(0, candidate.start)}${value}${payload.slice(candidate.start + candidate.length)}`; + try { + return JSON.stringify(JSON.parse(rewritten)) === JSON.stringify(event) ? rewritten : null; + } catch { + return null; + } +} + /** * Hide Codex-only control frames from Grok's strict Responses decoder. * @@ -41,3 +168,35 @@ export function createGrokResponsesControlFrameBlockRewrite(): SseBlockRewrite { : [block]; }; } + +/** Normalize safe integer response timestamps for Grok's strict Responses decoder. */ +export function createGrokResponsesTimestampBlockRewrite(): SseBlockRewrite { + return (block) => { + const payload = sseDataPayload(block); + if (payload === null || payload === "[DONE]") return [block]; + + let event: unknown; + try { + event = JSON.parse(payload); + } catch { + return [block]; + } + if (!event || typeof event !== "object" || Array.isArray(event)) return [block]; + const eventRecord = event as Record; + if (typeof eventRecord.type !== "string" || !eventRecord.type.startsWith("response.")) return [block]; + if (!eventRecord.response || typeof eventRecord.response !== "object" || Array.isArray(eventRecord.response)) { + return [block]; + } + const response = eventRecord.response as Record; + let rewrittenPayload = payload; + for (const field of GROK_RESPONSE_INTEGER_TIMESTAMP_FIELDS) { + const value = response[field]; + if (value === undefined) continue; + if (typeof value !== "number" || value < 0 || !Number.isSafeInteger(value)) return [block]; + const rewritten = rewriteIntegralTimestamp(rewrittenPayload, field, value, event); + if (rewritten === null) return [block]; + rewrittenPayload = rewritten; + } + return rewrittenPayload === payload ? [block] : [replaceSseDataPayload(block, rewrittenPayload)]; + }; +} diff --git a/src/server/responses/passthrough-delivery.ts b/src/server/responses/passthrough-delivery.ts index a6252733565..5aaaca54c35 100644 --- a/src/server/responses/passthrough-delivery.ts +++ b/src/server/responses/passthrough-delivery.ts @@ -83,7 +83,10 @@ import { import { createRoutedCustomToolRestoreBlockRewrite } from "../responses-custom-tool-repair"; import { createRoutedToolSearchRestoreBlockRewrite } from "../responses-tool-search-repair"; import { createGithubCopilotResponsesBlockRewrite } from "../github-copilot-responses-repair"; -import { createGrokResponsesControlFrameBlockRewrite } from "../grok-responses-control-frame"; +import { + createGrokResponsesControlFrameBlockRewrite, + createGrokResponsesTimestampBlockRewrite, +} from "../grok-responses-control-frame"; import { createGrokResponsesSparseTerminalBlockRewrite } from "../grok-responses-snapshot-repair"; import { createPlaintextV2AgentMessageCallRestoreRewrite, @@ -498,6 +501,9 @@ export async function deliverPassthroughResponse( grokClientCompatibilityEnabled ? createGrokResponsesControlFrameBlockRewrite() : undefined, + grokClientCompatibilityEnabled + ? createGrokResponsesTimestampBlockRewrite() + : undefined, grokClientCompatibilityEnabled ? createGrokResponsesSparseTerminalBlockRewrite(translatorBudget) : undefined, diff --git a/src/server/sse-payload-rewrite.ts b/src/server/sse-payload-rewrite.ts index 0d6b0261d06..5f3a1ad0aa3 100644 --- a/src/server/sse-payload-rewrite.ts +++ b/src/server/sse-payload-rewrite.ts @@ -230,7 +230,7 @@ export function replaceSseDataPayload(block: string, payload: string): string { continue; } if (!replaced) { - rewritten.push(`data: ${payload}`); + rewritten.push(...payload.split(/\r?\n/).map(line => `data: ${line}`)); replaced = true; } } diff --git a/structure/providers/xai-grok.md b/structure/providers/xai-grok.md index a9317bc4dda..eda8ec31ae8 100644 --- a/structure/providers/xai-grok.md +++ b/structure/providers/xai-grok.md @@ -79,6 +79,11 @@ snapshot. It never promotes locally synthesized or merely repaired items. Unmark to treat an explicit empty array as authoritative. Within this marked client-facing repair, malformed, gapped, oversized, contradictory, failed, or incomplete streams stay fail-closed. +The same marked client-facing chain normalizes lexical floating-point `response.created_at` and +`response.completed_at` values to their JSON integer spelling only for `response.*` events whose +nested values are nonnegative safe integers. Missing, malformed, fractional, negative, unsafe, and +byte-identical payloads pass through unchanged. + > Decision record: [ADR-0059](../decisions/ADR-0059-xai-grok-hardening-official-grok-build-contract.md) ### Grok Reset Coupons (Billing API Parity) diff --git a/structure/transports/responses.md b/structure/transports/responses.md index 48fc1fb9867..17b57dcdf5b 100644 --- a/structure/transports/responses.md +++ b/structure/transports/responses.md @@ -742,6 +742,11 @@ terminal observer. Native Responses, Chat Completions, Claude Messages, and WebS request logs must therefore finalize through the context-aware terminal mapper; recognized `cyber_policy` terminals stay `400 / cyber_policy` rather than collapsing to a generic 502. +Raw SSE inspection remains upstream-first: client-facing block rewrites run after the original +bytes are observed. The Grok-only `response.created_at` and `response.completed_at` compatibility +rewrite is limited to `response.*` events with nonnegative safe integer values and leaves invalid or +byte-identical payloads unchanged. + The client-facing boundary treats the first Responses terminal as authoritative in both relay shapes. High-confidence policy errors carried as `response.incomplete`, `response.failed`, or a top-level `error` are normalized to one `response.failed / cyber_policy` event without changing the diff --git a/tests/responses/responses-snapshot-repair-server.test.ts b/tests/responses/responses-snapshot-repair-server.test.ts index f6e4ac0e92b..26aeabb8e98 100644 --- a/tests/responses/responses-snapshot-repair-server.test.ts +++ b/tests/responses/responses-snapshot-repair-server.test.ts @@ -6,7 +6,10 @@ import { saveConfig } from "../../src/config"; import { startServer } from "../../src/server"; import { handleResponses } from "../../src/server/responses"; import { isEagerRelaySseResponse } from "../../src/server/relay"; -import { createGrokResponsesControlFrameBlockRewrite } from "../../src/server/grok-responses-control-frame"; +import { + createGrokResponsesControlFrameBlockRewrite, + createGrokResponsesTimestampBlockRewrite, +} from "../../src/server/grok-responses-control-frame"; import type { OcxConfig } from "../../src/types"; import { installIsolatedCodexHome, type IsolatedCodexHome } from "../helpers/isolated-codex-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; @@ -70,15 +73,16 @@ const GROK_CONTROL_FRAME_EVENTS = [ ]; function sparseSseBody( - events: readonly Record[] = SPARSE_EVENTS, + events: readonly (Record | string)[] = SPARSE_EVENTS, includeEventNames = false, ): ReadableStream { return new ReadableStream({ start(controller) { const encoder = new TextEncoder(); for (const event of events) { - const eventLine = includeEventNames ? `event: ${event.type}\n` : ""; - controller.enqueue(encoder.encode(`${eventLine}data: ${JSON.stringify(event)}\n\n`)); + const eventLine = includeEventNames && typeof event !== "string" ? `event: ${event.type}\n` : ""; + const payload = typeof event === "string" ? event : JSON.stringify(event); + controller.enqueue(encoder.encode(`${eventLine}data: ${payload}\n\n`)); } controller.enqueue(encoder.encode("data: [DONE]\n\n")); controller.close(); @@ -88,7 +92,7 @@ function sparseSseBody( function stubSparseGateway( origin: string, - events: readonly Record[] = SPARSE_EVENTS, + events: readonly (Record | string)[] = SPARSE_EVENTS, includeEventNames = false, ): void { globalThis.fetch = (async (input: RequestInfo | URL, init?: RequestInit) => { @@ -174,6 +178,59 @@ for (const controlType of ["codex.rate_limits", "codex.response.metadata"]) { }); } +test("Grok receives integer response timestamps from Responses streams", () => { + const block = "event: response.created\ndata: { \"type\": \"response.created\", \"response\": {\"id\":\"resp_float_timestamp\",\"created_at\":1789740485.0}, \"unrelated\": 9007199254740993 }"; + expect(createGrokResponsesTimestampBlockRewrite()(block)).toEqual([ + "event: response.created\ndata: { \"type\": \"response.created\", \"response\": {\"id\":\"resp_float_timestamp\",\"created_at\":1789740485}, \"unrelated\": 9007199254740993 }", + ]); +}); + +test("Grok normalizes timestamps in JSON split across data fields", () => { + const block = [ + "event: response.created", + 'data: {"type":"response.created","response":{"id":"resp_split",', + 'data: "created_at":1789740485.0},"unrelated":9007199254740993}', + "id: split", + ].join("\r\n"); + expect(createGrokResponsesTimestampBlockRewrite()(block)).toEqual([[ + "event: response.created", + 'data: {"type":"response.created","response":{"id":"resp_split",', + 'data: "created_at":1789740485},"unrelated":9007199254740993}', + "id: split", + ].join("\r\n")]); +}); + +test("Grok leaves an unrelated same-valued floating timestamp unchanged", () => { + const block = 'data: {"type":"response.created","response":{"created_at":1789740485},"metadata":{"created_at":1789740485.0}}'; + expect(createGrokResponsesTimestampBlockRewrite()(block)).toEqual([block]); +}); + +test("Grok normalizes only the direct timestamp when a nested timestamp shares its value", () => { + const block = 'data: {"type":"response.created","response":{"created_at":1789740485.0,"metadata":{"created_at":1789740485.0}}}'; + expect(createGrokResponsesTimestampBlockRewrite()(block)).toEqual([ + 'data: {"type":"response.created","response":{"created_at":1789740485,"metadata":{"created_at":1789740485.0}}}', + ]); +}); + +test.each([ + "data: not-json", + "data: {\"type\":\"response.output_text.delta\",\"delta\":\"1789740485.0\"}", + "data: {\"type\":\"response.created\",\"response\":{\"created_at\":1789740485}}", + "data: {\"type\":\"response.created\",\"response\":{\"created_at\":1789740485.5}}", + "data: {\"type\":\"response.created\",\"response\":{\"created_at\":-1.0}}", + "data: {\"type\":\"response.created\",\"response\":{\"created_at\":9007199254740992.0}}", + "data: {\"type\":\"response.created\",\"response\":{\"created_at\":1789740485},\"text\":\"\\\"created_at\\\":1789740485.0\"}", +])("Grok timestamp normalization preserves unsupported payload %s", block => { + expect(createGrokResponsesTimestampBlockRewrite()(block)).toEqual([block]); +}); + +test("Grok receives an integer completed_at timestamp", () => { + const block = 'data: {"type":"response.completed","response":{"created_at":1789740485,"completed_at":1789740486.0}}'; + expect(createGrokResponsesTimestampBlockRewrite()(block)).toEqual([ + 'data: {"type":"response.completed","response":{"created_at":1789740485,"completed_at":1789740486}}', + ]); +}); + describe("responsesSnapshotRepair through /v1/responses", () => { test.skipIf(process.platform !== "darwin")( "Darwin eager-relay applies snapshot repair inline before bytes reach the client", @@ -399,7 +456,12 @@ describe("responsesSnapshotRepair through /v1/responses", () => { }); test.each([true, false])("the Grok marker filters Codex control frames at the client boundary (event names: %s)", async includeEventNames => { const gateway = "https://grok-control-frame.example.test"; - stubSparseGateway(gateway, GROK_CONTROL_FRAME_EVENTS, includeEventNames); + const floatTimestampEvent = '{"type":"response.created","response":{"id":"resp_float_timestamp","created_at":1789740485.0}}'; + stubSparseGateway(gateway, [ + ...GROK_CONTROL_FRAME_EVENTS.slice(0, -1), + floatTimestampEvent, + GROK_CONTROL_FRAME_EVENTS.at(-1)!, + ], includeEventNames); saveConfig({ port: 0, defaultProvider: "sparse", @@ -430,12 +492,14 @@ describe("responsesSnapshotRepair through /v1/responses", () => { expect(grokText).not.toContain("codex.rate_limits"); expect(grokText).not.toContain("codex.response.metadata"); expect(grokText).toContain('"type":"response.completed"'); + expect(grokText).toContain('"created_at":1789740485}'); const ordinaryResponse = await request(false); expect(ordinaryResponse.status).toBe(200); const ordinaryText = await ordinaryResponse.text(); expect(ordinaryText).toContain("codex.rate_limits"); expect(ordinaryText).toContain("codex.response.metadata"); + expect(ordinaryText).toContain('"created_at":1789740485.0}'); } finally { await server.stop(true); } diff --git a/tests/responses/responses-state.test.ts b/tests/responses/responses-state.test.ts index ec801d5109d..12ed243b5bb 100644 --- a/tests/responses/responses-state.test.ts +++ b/tests/responses/responses-state.test.ts @@ -235,7 +235,7 @@ async function runShutdownBudgetChild( async function runNeverSettlingAclChild( mode: "principal" | "icacls", ): Promise { - const timeoutMs = watchdogMs(1_500); + const timeoutMs = watchdogMs(8_000); const child = Bun.spawn([ process.execPath, helperPath("responses-state-never-settling-acl-child.ts"), @@ -1245,7 +1245,7 @@ describe("Responses previous_response_id state", () => { metrics: { tombstoneCount: 2 }, }); } - }, { timeout: (2 * watchdogMs(1_500)) + 2_000 }); + }, { timeout: (2 * watchdogMs(8_000)) + 2_000 }); test("Windows pending spill publication cannot overwrite a newer same-id generation", async () => { forceWindowsAclLane(); From 19b42c5b08f56a309a1b54f2ceb2c188bcfd71cf Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sat, 19 Sep 2026 22:09:20 +0900 Subject: [PATCH 43/97] fix(codex): bound destroyed-shim diagnostics to the stable probe (#5136) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(codex): bound destroyed-shim diagnostics to the stable probe destroyedShimMessage called isShim() on the wrapper path, which opens and reads the file unbounded — a FIFO or other non-regular launcher at that path blocks the diagnostic instead of reporting it. Use stableShimPathProbe (bounded read) and keep the same marker check. * test(codex): move the destroyed-shim probe case out of a capped file The file-size ratchet rejected this branch: src/codex/shim.ts reached 1247 lines against a committed cap of 1246, and tests/codex-integration/codex-shim.test.ts reached 2413 against 2388. The ratchet only ever lowers a cap, so raising either one is not available and a baseline edit would fail the same gate. The source overage was one line. Calling stableShimPathProbe inline in the ternary it already feeds keeps the original three-line shape and the same single call, so the behaviour this branch introduced is unchanged. The test overage is answered by extracting rather than trimming. withInstalledShim and prependPath move to tests/helpers/codex-shim-install-fixture.ts, which is what let the new probe case live in its own file instead of a copy of a forty-line fixture. The new case reads the repository through repoPath and repoRoot rather than import.meta.dir, which is the convention for a file sitting inside a domain directory. It is registered in scripts/test-layout/layout.json and tests/fixtures/test-layout-expected.json. No local suite, focused test, typecheck or build was run for this change. Exact-head hosted CI is the execution evidence. --------- Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com> Co-authored-by: lidge-jun --- scripts/test-layout/layout.json | 4 +- src/codex/shim.ts | 2 +- .../codex-shim-destroyed-probe.test.ts | 32 ++++++++++ tests/codex-integration/codex-shim.test.ts | 49 +-------------- tests/fixtures/test-layout-expected.json | 4 +- tests/helpers/codex-shim-install-fixture.ts | 62 +++++++++++++++++++ 6 files changed, 101 insertions(+), 52 deletions(-) create mode 100644 tests/codex-integration/codex-shim-destroyed-probe.test.ts create mode 100644 tests/helpers/codex-shim-install-fixture.ts diff --git a/scripts/test-layout/layout.json b/scripts/test-layout/layout.json index a610f9e2eb1..2812bc20100 100644 --- a/scripts/test-layout/layout.json +++ b/scripts/test-layout/layout.json @@ -376,7 +376,6 @@ "cleanup-orphaned-workflows.test.ts": "ci-workflows", "clearable-deadline.test.ts": "lib", "cli-account-orca-import.test.ts": "cli", - "cli-account-pin-drain.test.ts": "cli", "cli-account-pool-verbs.test.ts": "cli", "cli-account.test.ts": "cli", @@ -1544,7 +1543,8 @@ "ci-structure-gate.test.ts": "ci-workflows", "responses-code-mode-patch-compile.test.ts": "responses", "gui-codex-usage-score-parity.test.ts": "gui", - "web-search-sidecar-429.test.ts": "web-search" + "web-search-sidecar-429.test.ts": "web-search", + "codex-shim-destroyed-probe.test.ts": "codex-integration" }, "migrated": [ "adapters", diff --git a/src/codex/shim.ts b/src/codex/shim.ts index 6eebf8d61f5..2fa48ab88e8 100644 --- a/src/codex/shim.ts +++ b/src/codex/shim.ts @@ -241,7 +241,7 @@ function backupPathFor(path: string): string { */ function destroyedShimMessage(file: ShimFileState): string { const wrapper = existsSync(file.wrapperPath) - ? isShim(file.wrapperPath) ? "present but unusable" : "present but not an opencodex shim" + ? stableShimPathProbe(file.wrapperPath)?.prefix.includes(SHIM_MARKER) ? "present but unusable" : "present but not an opencodex shim" : "missing"; const backup = existsSync(file.backupPath) ? "present" : "missing"; const base = `Codex autostart shim not restored: wrapper ${wrapper} at ${file.wrapperPath}; original backup ${backup} at ${file.backupPath}.`; diff --git a/tests/codex-integration/codex-shim-destroyed-probe.test.ts b/tests/codex-integration/codex-shim-destroyed-probe.test.ts new file mode 100644 index 00000000000..1263b676898 --- /dev/null +++ b/tests/codex-integration/codex-shim-destroyed-probe.test.ts @@ -0,0 +1,32 @@ +import { describe, expect, test } from "bun:test"; +import { spawnSync } from "node:child_process"; +import { rmSync } from "node:fs"; +import { repoPath, repoRoot } from "../helpers/repo-root"; +import { withInstalledShim } from "../helpers/codex-shim-install-fixture"; + +describe("version-manager shim destruction (#2412)", () => { + test("a destroyed shim diagnostic does not open a non-file launcher", () => { + if (process.platform === "win32") return; + withInstalledShim(({ home, wrappers, backups }) => { + rmSync(wrappers[0]); + expect(spawnSync("mkfifo", [wrappers[0]]).status).toBe(0); + rmSync(backups[0]); + const shimModule = repoPath("src", "codex", "shim.ts"); + const script = ` + const { autoRestoreCodexShim } = await import(${JSON.stringify(shimModule)}); + console.log(JSON.stringify(autoRestoreCodexShim({ enabled: () => true, stabilitySleep: () => {} }))); + `; + + const child = spawnSync(process.execPath, ["-e", script], { + cwd: repoRoot(), + env: { ...process.env, OPENCODEX_HOME: home }, + encoding: "utf8", + timeout: 1_000, + }); + + expect(child.error).toBeUndefined(); + expect(child.status).toBe(0); + expect(JSON.parse(child.stdout)).toMatchObject({ status: "ineligible" }); + }); + }); +}); diff --git a/tests/codex-integration/codex-shim.test.ts b/tests/codex-integration/codex-shim.test.ts index 3178a7ed3ab..f684fa8de91 100644 --- a/tests/codex-integration/codex-shim.test.ts +++ b/tests/codex-integration/codex-shim.test.ts @@ -1,9 +1,10 @@ import { afterAll, describe, expect, spyOn, test } from "bun:test"; import { spawnSync } from "node:child_process"; import { chmodSync, copyFileSync, existsSync, linkSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, renameSync, rmSync, statSync, symlinkSync, utimesSync, writeFileSync } from "node:fs"; -import { delimiter, dirname, join } from "node:path"; +import { dirname, join } from "node:path"; import { tmpdir } from "node:os"; import { autoRestoreCodexShim, buildUnixCodexShim, buildWindowsCodexShim, buildWindowsPowerShellCodexShim, diagnoseCodexShim, findCodexOnPath, inspectCodexShimBackingForCommand, installCodexShim, isLocalAbsoluteInspectionPath, isVersionManagerOwnedCodexPath, isWindowsInteropDir, lastCodexDiscoveryError, setCodexShimFreshWriteHookForTests, setCodexShimGuardedWriteHookForTests, setCodexShimProbeHookForTests, setCodexShimProbeObservationMsForTests, setCodexShimProbeShellForTests, setCodexShimRollbackRestoreHookForTests, uninstallCodexShim } from "../../src/codex/shim"; +import { prependPath, withInstalledShim } from "../helpers/codex-shim-install-fixture"; import { removeTreeWithRetry } from "../helpers/remove-tree"; import { repoPath, repoRoot } from "../helpers/repo-root"; import { INTERNAL_DEADLINE_MS, SPAWN_BUDGET_MS } from "../helpers/test-budget"; @@ -41,10 +42,6 @@ setCodexShimProbeObservationMsForTests(20); afterAll(() => setCodexShimProbeObservationMsForTests(null)); const psPath = process.platform !== "win32" && existsSync("/bin/ps") ? "/bin/ps" : ""; -function prependPath(dir: string, current: string | undefined): string { - return [dir, current].filter(Boolean).join(delimiter); -} - function successfulLauncher(label: string): string { return process.platform === "win32" ? `${label}\r\n` : `#!/bin/sh\n# ${label}\nexit 0\n`; } @@ -85,48 +82,6 @@ function expectProcessGroupMissing(groupId: number): void { expect(code).toBe("ESRCH"); } -function withInstalledShim(run: (paths: { - binDir: string; - home: string; - wrappers: string[]; - backups: string[]; - statePath: string; -}) => void): void { - const binDir = mkdtempSync(join(tmpdir(), "ocx-shim-bin-")); - const home = mkdtempSync(join(tmpdir(), "ocx-shim-home-")); - const oldPath = process.env.PATH; - const oldHome = process.env.OPENCODEX_HOME; - const wrappers = process.platform === "win32" - ? [join(binDir, "codex.cmd"), join(binDir, "codex.ps1"), join(binDir, "codex")] - : [join(binDir, "codex")]; - try { - process.env.PATH = prependPath(binDir, oldPath); - process.env.OPENCODEX_HOME = home; - for (const wrapper of wrappers) { - writeFileSync(wrapper, process.platform === "win32" ? `real ${wrapper}\n` : "#!/bin/sh\necho real\n", "utf8"); - if (process.platform !== "win32") chmodSync(wrapper, 0o755); - } - const installed = installCodexShim(); - expect(installed.installed, installed.message).toBe(true); - const statePath = join(home, "codex-shim.json"); - const state = JSON.parse(readFileSync(statePath, "utf8")) as { wrappers: Array<{ wrapperPath: string; backupPath: string }> }; - run({ - binDir, - home, - wrappers: state.wrappers.map(file => file.wrapperPath), - backups: state.wrappers.map(file => file.backupPath), - statePath, - }); - } finally { - if (oldPath === undefined) delete process.env.PATH; - else process.env.PATH = oldPath; - if (oldHome === undefined) delete process.env.OPENCODEX_HOME; - else process.env.OPENCODEX_HOME = oldHome; - removeTreeWithRetry(binDir); - removeTreeWithRetry(home); - } -} - describe("Codex autostart shim", () => { test("builds a Unix shim that starts ocx before execing Codex", () => { const script = buildUnixCodexShim("/usr/local/bin/codex-real", "/usr/local/bin/bun", "/opt/opencodex/src/cli.ts", "bundled"); diff --git a/tests/fixtures/test-layout-expected.json b/tests/fixtures/test-layout-expected.json index c4bd7f4bceb..71096d8e8fb 100644 --- a/tests/fixtures/test-layout-expected.json +++ b/tests/fixtures/test-layout-expected.json @@ -207,7 +207,6 @@ "cleanup-orphaned-workflows.test.ts": "ci-workflows", "clearable-deadline.test.ts": "lib", "cli-account-orca-import.test.ts": "cli", - "cli-account-pin-drain.test.ts": "cli", "cli-account-pool-verbs.test.ts": "cli", "cli-account.test.ts": "cli", @@ -1376,5 +1375,6 @@ "ci-structure-gate.test.ts": "ci-workflows", "responses-code-mode-patch-compile.test.ts": "responses", "gui-codex-usage-score-parity.test.ts": "gui", - "web-search-sidecar-429.test.ts": "web-search" + "web-search-sidecar-429.test.ts": "web-search", + "codex-shim-destroyed-probe.test.ts": "codex-integration" } diff --git a/tests/helpers/codex-shim-install-fixture.ts b/tests/helpers/codex-shim-install-fixture.ts new file mode 100644 index 00000000000..72582434156 --- /dev/null +++ b/tests/helpers/codex-shim-install-fixture.ts @@ -0,0 +1,62 @@ +import { expect } from "bun:test"; +import { chmodSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { delimiter, join } from "node:path"; +import { installCodexShim } from "../../src/codex/shim"; +import { removeTreeWithRetry } from "./remove-tree"; + +/** + * Installs a real Codex shim over a throwaway PATH entry and a throwaway OPENCODEX_HOME, hands + * the resolved wrapper and backup paths to the caller, and restores both environment variables + * and removes both temporary trees afterwards. + * + * This lived inside tests/codex-integration/codex-shim.test.ts until a second file needed it. + * Copying it would have been the cheaper edit and the wrong one: the fixture owns the contract + * that every shim test starts from a clean install, and two copies drift the moment one of them + * learns something about Windows wrappers that the other does not. + */ +export function prependPath(dir: string, current: string | undefined): string { + return [dir, current].filter(Boolean).join(delimiter); +} + +export function withInstalledShim(run: (paths: { + binDir: string; + home: string; + wrappers: string[]; + backups: string[]; + statePath: string; +}) => void): void { + const binDir = mkdtempSync(join(tmpdir(), "ocx-shim-bin-")); + const home = mkdtempSync(join(tmpdir(), "ocx-shim-home-")); + const oldPath = process.env.PATH; + const oldHome = process.env.OPENCODEX_HOME; + const wrappers = process.platform === "win32" + ? [join(binDir, "codex.cmd"), join(binDir, "codex.ps1"), join(binDir, "codex")] + : [join(binDir, "codex")]; + try { + process.env.PATH = prependPath(binDir, oldPath); + process.env.OPENCODEX_HOME = home; + for (const wrapper of wrappers) { + writeFileSync(wrapper, process.platform === "win32" ? `real ${wrapper}\n` : "#!/bin/sh\necho real\n", "utf8"); + if (process.platform !== "win32") chmodSync(wrapper, 0o755); + } + const installed = installCodexShim(); + expect(installed.installed, installed.message).toBe(true); + const statePath = join(home, "codex-shim.json"); + const state = JSON.parse(readFileSync(statePath, "utf8")) as { wrappers: Array<{ wrapperPath: string; backupPath: string }> }; + run({ + binDir, + home, + wrappers: state.wrappers.map(file => file.wrapperPath), + backups: state.wrappers.map(file => file.backupPath), + statePath, + }); + } finally { + if (oldPath === undefined) delete process.env.PATH; + else process.env.PATH = oldPath; + if (oldHome === undefined) delete process.env.OPENCODEX_HOME; + else process.env.OPENCODEX_HOME = oldHome; + removeTreeWithRetry(binDir); + removeTreeWithRetry(home); + } +} From 49c79f366c571bad47a59faca230164b9da40d88 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 22:38:57 +0900 Subject: [PATCH 44/97] test(devin): assert which error the refused send raises and what the caller sees (#5170) Two follow-ups to #5152, both test-only. Nothing in production changes and the merged branch is untouched. The adapter-direct case caught the refusal with a bare catch that discarded it, so it passed for any error at all. If the adapter had thrown an ordinary upstream failure instead of the budget refusal, the case would still have been green while the turn was reported to the operator as a provider problem rather than a budget decision. It now pins SendBudgetExhaustedError. The outer case reported the HTTP status only inside its failure message. It is now asserted: the refusal reaches the client as an error code on a buffered failed response, so the status is 200. That is worth stating, because the obvious guess is 429 and this path does not use it. Local checks: NOT RUN. Hosted CI on this PR is the executable evidence. --- tests/adapters/adapter-inner-send-budget-wiring.test.ts | 9 ++++++++- tests/responses/responses-send-budget-counts.test.ts | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/adapters/adapter-inner-send-budget-wiring.test.ts b/tests/adapters/adapter-inner-send-budget-wiring.test.ts index 9885c73af93..c5341a759fa 100644 --- a/tests/adapters/adapter-inner-send-budget-wiring.test.ts +++ b/tests/adapters/adapter-inner-send-budget-wiring.test.ts @@ -13,6 +13,7 @@ import { createDevinAdapter, DEVIN_API_SERVER } from "../../src/adapters/devin"; import { setCachedCatalogForTests } from "../../src/adapters/devin/cloud-direct/catalog"; import { resetKiroThrottleStateForTests } from "../../src/adapters/kiro-retry"; import type { AdapterFetchContext } from "../../src/adapters/base"; +import { SendBudgetExhaustedError } from "../../src/lib/upstream-retry"; import { encodeMessage } from "../../src/lib/eventstream-decoder"; import { createRequestExecutionBudget, type RequestExecutionBudgetPolicy } from "../../src/lib/request-execution-budget"; import type { AdapterEvent, OcxParsedRequest, OcxProviderConfig } from "../../src/types"; @@ -206,6 +207,7 @@ describe("Devin runTurn execution wiring", () => { adapter: "devin", baseUrl: DEVIN_API_SERVER, apiKey, } as unknown as OcxProviderConfig); + let refusal: unknown; try { await adapter.runTurn?.( { @@ -223,7 +225,7 @@ describe("Devin runTurn execution wiring", () => { onPhysicalSend: send => { observed.push(send); }, }, event => events.push(event), - ).catch(() => { /* the refusal escapes the adapter for the caller to map */ }); + ).catch((error: unknown) => { refusal = error; }); } finally { setCachedCatalogForTests(null); if (previousHome === undefined) delete process.env.OPENCODEX_HOME; @@ -233,6 +235,11 @@ describe("Devin runTurn execution wiring", () => { removeTreeWithRetry(home); } + // The refusal escapes the adapter for the caller to map, and WHICH error escapes is the + // contract: a bare catch here passed even when the adapter threw something else entirely, + // which would have left the turn reported as an ordinary upstream failure instead of a + // budget refusal. + expect(refusal).toBeInstanceOf(SendBudgetExhaustedError); expect(urls.filter(url => url.includes("GetChatMessage"))).toHaveLength(0); expect(observed).toEqual([]); expect(budget.used).toBe(0); diff --git a/tests/responses/responses-send-budget-counts.test.ts b/tests/responses/responses-send-budget-counts.test.ts index d6119caa0fd..7585db3728e 100644 --- a/tests/responses/responses-send-budget-counts.test.ts +++ b/tests/responses/responses-send-budget-counts.test.ts @@ -217,12 +217,17 @@ describe("upstream sends per logical request", () => { // without proving the refusal was recorded against the turn that was refused. expect(attempts).toHaveLength(1); expect({ + // Pinned, not merely reported in the failure message. The refusal reaches the client as + // an error code on a buffered FAILED response, so the outer HTTP status stays 200; a + // reader who assumes 429 here would be describing a transport this path never uses. + status: response.status, adapter: attempts[0]?.adapter, sendCount: attempts[0]?.sendCount, chatCalls: urls.filter(url => url.includes("GetChatMessage")).length, totalSends: totalSends(logCtx), refused: body.includes("request_send_budget_exhausted"), }, `status ${response.status}: ${body.slice(0, 240)}`).toEqual({ + status: 200, adapter: "devin", sendCount: 0, chatCalls: 0, From 8a030721b3ffc909ca7d8b05ca0b7c873c1493a1 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 22:48:18 +0900 Subject: [PATCH 45/97] Report endpoint-scoped Google tool-schema loss (#5162) * feat(providers): report Google tool-schema loss by endpoint class Add a bounded, content-free loss report to the Google tool-declaration sanitizer and aggregate it at the wire compiler, with an explicit endpoint profile derived from googleMode. Reports carry only the endpoint class, fixed loss categories, saturating counts, and a truncation flag, and surface only through opt-in provider diagnostics. The default request body is unchanged for every endpoint class, native output schemas stay outside sanitation, and no rejection policy is introduced in this layer. Part of #5112 * docs(providers): make the schema-loss diagnostic discoverable Review fold: name the exact enable/tail commands (ocx debug provider on, ocx debug provider logs -f, OCX_DEBUG=1, dashboard Logs toggle), the [ocx:google:google-tool-schema-loss] record name, and the report version and lossy indicator, and link the CLI debug reference, in English and all seven locale guides. Part of #5112 * fix(providers): complete schema-loss classification and endpoint coverage Review fold on the report-only layer: - Classify every output-changing sanitizer branch: multi-type and unsupported types, nullability conflicts, conditionals, tuple prefixes, ref overlays, root object coercion, and empty enums now report bounded categories, while inert annotations are explicitly excluded from loss counts. - Count a lost constraint once when a referenced target's const flows through the overlay merge (pre-scan only merge-excluded fields). - Prove all three endpoint modes at the real adapter boundary: profile derivation, opt-in-only diagnostic emission, privacy canaries absent, native output schemas untouched, and default wire bytes identical. Part of #5112 * fix(providers): name union collapse neutrally in schema-loss reports Review fold: a multi-type array collapsing to one supported type is a narrowing, not a widening, so the category is type-union-collapsed. Guide prose now says schema loss during compatibility conversion rather than compatibility widening, in English and all seven locales, so narrower losses are not excluded by the wording. Part of #5112 * fix(providers): classify union sibling replacement and bound overlay comparison Review fold on the report-only layer: - An anyOf resolution that overwrites an explicit sibling type is now reported as union-sibling-replaced instead of passing silently. - Ref-overlay comparison uses bounded structural equality over enum/properties/required/items/anyOf instead of identity, so separately allocated equivalent constraints no longer count as loss; comparison exhaustion is reported as unknown and never counted as proven loss. - Default-equivalent constraints (additionalProperties:true, uniqueItems:false, minLength:0, minItems:0, minProperties:0, prefixItems:[]) are known-inert and add no loss. - The structure contract documents the exact five-field report shape and the 255 count saturation. Part of #5112 * fix(providers): report bounded comparison uncertainty honestly Review fold: an exhausted bounded comparison previously vanished, so a late-difference enum pair could read as lossless. The report gains a saturating uncertainComparisons count (uncertainty never sets lossy or a proven-loss category), and overlay comparison now applies the sanitizer's own supported normalizations before comparing: enum and required as deduped order-insensitive sets, and type case-folded including scalar/single-array equivalence. properties/items/anyOf keep bounded exact JSON comparison; exhaustion stays unknown. Compatible wire bytes are unchanged; strict refusal on uncertainty is wired in the stacked child. Part of #5112 * fix(providers): emit uncertainty diagnostics and prove late-difference exhaustion Review fold on the report-only layer: - reportToolSchemaLoss no longer drops uncertain-only reports: the gate is lossy or uncertainComparisons > 0, so report-only mode honestly emits indeterminate comparisons, not just proven loss. - The exhaustion fixture's overlay now differs from the ref target only after the comparison budget (late-difference enum), asserting uncertainComparisons: 1, lossy: false, no proven-loss category, and preserved overlay bytes that differ from the target. - An adapter-boundary case proves one content-free uncertainty diagnostic with no canary strings. Part of #5112 * test(providers): fix the uncertainty fixture and cover all endpoints Hosted CI found the fixture omitted options, so buildRequest threw before compilation. Add options and run the indeterminate-diagnostic case across all three endpoint modes. Red-to-green evidence: shard test 1/4 failed on the missing options field at the previous head. Part of #5112 * fix(providers): account enum overlays by effective intersection Review fold: ref-overlay enum comparison now filters and deduplicates target and overlay string values, treats their intersection as the effective accepted set, and reports ref-overlay-replaced only when the emitted set widens beyond the target; non-string overlay values count only when present in the target, and a per-merged-node override prevents later double counting. Comparison exhaustion remains uncertain, never proven loss. The structure contract states the assumed 2020-12-style conjunctive sibling semantics while preserving the overlay-wins wire transform. Default request bytes unchanged. Part of #5112 --- .../src/content/docs/fr/guides/providers.md | 13 + .../src/content/docs/guides/providers.md | 11 + .../src/content/docs/ja/guides/providers.md | 12 + .../src/content/docs/ko/guides/providers.md | 11 + .../src/content/docs/ru/guides/providers.md | 12 + .../src/content/docs/tr/guides/providers.md | 11 + .../content/docs/zh-cn/guides/providers.md | 9 + .../content/docs/zh-tw/guides/providers.md | 10 + scripts/test-layout/layout.json | 1 + src/adapters/google-tool-schema.ts | 624 ++++++++++++++- src/adapters/google-wire-compiler.ts | 30 +- src/adapters/google.ts | 17 +- structure/adapters/registry.md | 4 + structure/data-planes/inbound-compat.md | 4 + structure/providers-and-adapters.md | 2 +- structure/providers/chat-compat.md | 4 + structure/providers/cursor.md | 3 + structure/providers/google.md | 29 + structure/runtime.md | 4 + structure/transports/byte-accounting.md | 4 + structure/transports/inventory.md | 6 +- structure/transports/responses.md | 5 + .../google-tool-schema-contract.test.ts | 752 ++++++++++++++++++ tests/fixtures/test-layout-expected.json | 1 + 24 files changed, 1537 insertions(+), 42 deletions(-) create mode 100644 tests/adapters/google/google-tool-schema-contract.test.ts diff --git a/docs-site/src/content/docs/fr/guides/providers.md b/docs-site/src/content/docs/fr/guides/providers.md index 1024ca801ed..e5a52f40c34 100644 --- a/docs-site/src/content/docs/fr/guides/providers.md +++ b/docs-site/src/content/docs/fr/guides/providers.md @@ -131,6 +131,19 @@ ocx logout Les vérifications de quota Google Antigravity utilisent des points de terminaison Google fixes, y compris le repli vers la liste des modèles. Elles prennent en charge le DNS Fake-IP transparent pour ces destinations en conservant la vérification TLS, le refus des redirections et les contrôles des adresses privées. Une URL de base personnalisée ne modifie que les requêtes de modèles ; `NO_PROXY` conserve la politique de connexion directe. +### Diagnostic de perte du schéma d’outil Google + +Les déclarations d’outils Google sont compilées selon la classe du point de terminaison sélectionné. +Lorsque le débogage du fournisseur est activé — avec `ocx debug provider on`, le bouton Logs du +tableau de bord ou `OCX_DEBUG=1` — la perte de schéma lors de la conversion de compatibilité émet un enregistrement +`[ocx:google:google-tool-schema-loss]` (à suivre avec `ocx debug provider logs -f`) ne contenant que +la version du rapport, la classe du point de terminaison, un indicateur `lossy`, des catégories de +perte fixes avec des compteurs bornés et un indicateur de troncature. Les noms d’outils et de +propriétés, les chemins, les valeurs et le texte du schéma ne sont jamais inclus. Ce diagnostic +observe la conversion compatible existante sans rejeter la requête. Les schémas de sortie natifs +n’entrent pas dans ce diagnostic. Consultez la +[référence des commandes de débogage](/fr/reference/cli/agents/). + Après un échec définitif d'actualisation de Nous, exécutez `ocx login nous` pour vous réauthentifier. diff --git a/docs-site/src/content/docs/guides/providers.md b/docs-site/src/content/docs/guides/providers.md index 6df5252c04f..1701da603f9 100644 --- a/docs-site/src/content/docs/guides/providers.md +++ b/docs-site/src/content/docs/guides/providers.md @@ -209,6 +209,17 @@ ocx logout Google Antigravity account and provider quota probes use fixed Google accounting endpoints, including the models fallback. They support transparent Fake-IP DNS for those destinations while retaining TLS verification, redirect rejection and private-address checks. A custom provider base URL changes model requests, not quota destinations; `NO_PROXY` continues to select the direct-route policy. +### Google tool-schema loss diagnostics + +Google tool declarations are compiled against the selected endpoint class. When provider debug is +on — `ocx debug provider on`, the dashboard Logs toggle, or `OCX_DEBUG=1` — schema loss during compatibility +conversion emits a `[ocx:google:google-tool-schema-loss]` record (tail with `ocx debug provider logs -f`) +carrying only the report version, endpoint class, a `lossy` indicator, fixed loss categories with +bounded counts, and a truncation flag. Tool and property names, paths, values, and schema text are +never included. This diagnostic observes the existing compatible conversion and does not reject +the request. Native output schemas are outside this diagnostic. See the +[debug command reference](/reference/cli/agents/). + After a terminal Nous refresh failure, run `ocx login nous` to reauthenticate. diff --git a/docs-site/src/content/docs/ja/guides/providers.md b/docs-site/src/content/docs/ja/guides/providers.md index f8c8e553119..4d00948cf16 100644 --- a/docs-site/src/content/docs/ja/guides/providers.md +++ b/docs-site/src/content/docs/ja/guides/providers.md @@ -120,6 +120,18 @@ ocx logout Google Antigravity のアカウント・プロバイダーのクォータ確認は、モデル一覧へのフォールバックも含め、固定の Google エンドポイントを使用します。その宛先では透過 Fake-IP DNS に対応し、TLS 検証、リダイレクト拒否、プライベートアドレス検査を維持します。カスタム base URL はモデル要求にのみ適用されます。`NO_PROXY` は直接接続のポリシーを維持します。 +### Google ツールスキーマ損失診断 + +Google のツール宣言は、選択されたエンドポイントクラスに合わせてコンパイルされます。 +`ocx debug provider on`、ダッシュボードの Logs トグル、または `OCX_DEBUG=1` でプロバイダー +デバッグを有効にすると、互換性変換でのスキーマ損失は +`[ocx:google:google-tool-schema-loss]` レコードを出力します(`ocx debug provider logs -f` で +追跡できます)。レコードに含まれるのは、レポートのバージョン、エンドポイントクラス、 +`lossy` インジケーター、上限付き件数を伴う固定の損失カテゴリ、切り詰めフラグだけです。 +ツール名、プロパティ名、パス、値、スキーマ本文は含まれません。この診断は既存の互換変換を +観測するだけで、要求を拒否しません。ネイティブ出力スキーマは診断対象外です。 +[デバッグコマンドのリファレンス](/ja/reference/cli/agents/)も参照してください。 + Nous の refresh が終端失敗した場合は、再認証に `ocx login nous` を実行してください。 diff --git a/docs-site/src/content/docs/ko/guides/providers.md b/docs-site/src/content/docs/ko/guides/providers.md index 31ebaeb17b0..aaaecb8fcc9 100644 --- a/docs-site/src/content/docs/ko/guides/providers.md +++ b/docs-site/src/content/docs/ko/guides/providers.md @@ -118,6 +118,17 @@ ocx logout Google Antigravity 계정·제공자 할당량 확인은 모델 목록 폴백을 포함해 고정된 Google 회계 엔드포인트를 사용합니다. 해당 목적지의 투명 Fake-IP DNS를 지원하며 TLS 검증, 리다이렉트 거부, 사설 주소 검사는 유지합니다. 사용자 지정 base URL은 모델 요청에만 적용되며 할당량 목적지는 바꾸지 않습니다. `NO_PROXY`는 기존 직접 연결 정책을 유지합니다. +### Google 도구 스키마 손실 진단 + +Google 도구 선언은 선택된 엔드포인트 클래스에 맞춰 컴파일됩니다. `ocx debug provider on`, +대시보드 Logs 토글 또는 `OCX_DEBUG=1`로 프로바이더 디버그를 켜면 호환성 변환 중 스키마 손실이 +발생하면 `[ocx:google:google-tool-schema-loss]` 레코드를 기록합니다 +(`ocx debug provider logs -f`로 tail할 수 있습니다). 이 레코드에는 보고서 버전, 엔드포인트 +클래스, `lossy` 표시, 상한이 있는 개수를 포함한 고정 손실 범주, 잘림 여부만 들어갑니다. +도구명과 속성명, 경로, 값, 스키마 본문은 포함하지 않습니다. 이 진단은 기존 호환 변환을 +관찰할 뿐 요청을 거부하지 않습니다. 네이티브 출력 스키마는 이 진단의 대상이 아닙니다. +[디버그 명령어 참고 문서](/ko/reference/cli/agents/)도 확인하세요. + Nous refresh가 종료 실패한 경우, `ocx login nous`로 재인증하세요. diff --git a/docs-site/src/content/docs/ru/guides/providers.md b/docs-site/src/content/docs/ru/guides/providers.md index ef8a0289fff..edc995c1d8c 100644 --- a/docs-site/src/content/docs/ru/guides/providers.md +++ b/docs-site/src/content/docs/ru/guides/providers.md @@ -129,6 +129,18 @@ ocx logout Проверки квот аккаунтов и провайдера Google Antigravity используют фиксированные адреса Google, включая резервный запрос списка моделей. Для этих адресов поддерживается прозрачный Fake-IP DNS с сохранением проверки TLS, запрета перенаправлений и проверки частных адресов. Пользовательский base URL меняет только запросы моделей; `NO_PROXY` сохраняет политику прямого подключения. +### Диагностика потерь схем инструментов Google + +Объявления инструментов Google компилируются для выбранного класса конечной точки. Когда отладка +провайдера включена командой `ocx debug provider on`, переключателем Logs в дашборде или переменной +`OCX_DEBUG=1`, потеря схемы при преобразовании совместимости записывает событие +`[ocx:google:google-tool-schema-loss]` (следите за ним через `ocx debug provider logs -f`). Оно +содержит только версию отчёта, класс конечной точки, индикатор `lossy`, фиксированные категории +потерь с ограниченными счётчиками и признак усечения. Имена инструментов и свойств, пути, значения +и текст схемы не включаются. Диагностика только наблюдает существующее совместимое преобразование +и не отклоняет запрос. Нативные схемы вывода в неё не входят. См. +[справочник команд отладки](/ru/reference/cli/agents/). + После терминального сбоя обновления Nous выполните `ocx login nous`, чтобы пройти повторную аутентификацию. diff --git a/docs-site/src/content/docs/tr/guides/providers.md b/docs-site/src/content/docs/tr/guides/providers.md index 7bdb43d7928..81380857c91 100644 --- a/docs-site/src/content/docs/tr/guides/providers.md +++ b/docs-site/src/content/docs/tr/guides/providers.md @@ -144,6 +144,17 @@ ocx logout Google Antigravity hesap ve sağlayıcı kota sorguları, model listesine geri dönüş dahil sabit Google uç noktalarını kullanır. Bu hedefler için şeffaf Fake-IP DNS desteklenirken TLS doğrulaması, yönlendirme reddi ve özel adres kontrolleri korunur. Özel base URL yalnızca model isteklerini değiştirir; `NO_PROXY` doğrudan bağlantı politikasını korur. +### Google araç şeması kayıp tanılaması + +Google araç bildirimleri seçilen uç nokta sınıfına göre derlenir. Sağlayıcı hata ayıklaması +`ocx debug provider on`, kontrol panelindeki Logs anahtarı veya `OCX_DEBUG=1` ile açıldığında, +uyumluluk dönüşümü sırasında şema kaybı bir `[ocx:google:google-tool-schema-loss]` kaydı yayınlar +(`ocx debug provider logs -f` ile takip edin). Kayıt yalnızca rapor sürümünü, uç nokta sınıfını, +bir `lossy` göstergesini, sınırlı sayımlara sahip sabit kayıp kategorilerini ve kesilme işaretini +taşır. Araç ve özellik adları, yollar, değerler ve şema metni hiçbir zaman dahil edilmez. Bu +tanılama mevcut uyumlu dönüşümü gözlemler ve isteği reddetmez. Yerel çıktı şemaları bu tanılamanın +dışındadır. [Hata ayıklama komutu başvurusuna](/tr/reference/cli/agents/) bakın. + Uç bir Nous yenileme hatasından sonra yeniden kimlik doğrulamak için `ocx login nous` çalıştırın. diff --git a/docs-site/src/content/docs/zh-cn/guides/providers.md b/docs-site/src/content/docs/zh-cn/guides/providers.md index f5a2ce23584..9f652287309 100644 --- a/docs-site/src/content/docs/zh-cn/guides/providers.md +++ b/docs-site/src/content/docs/zh-cn/guides/providers.md @@ -112,6 +112,15 @@ ocx logout Google Antigravity 账户和提供方的配额查询(包括模型列表回退)使用固定的 Google 计量端点。这些目标支持透明 Fake-IP DNS,同时保留 TLS 验证、重定向拒绝和私有地址检查。自定义 base URL 仅改变模型请求,不改变配额目标;`NO_PROXY` 仍使用直连策略。 +### Google 工具架构损失诊断 + +Google 工具声明会按所选端点类别进行编译。通过 `ocx debug provider on`、仪表盘 Logs 开关或 +`OCX_DEBUG=1` 启用提供方调试后,兼容性转换中的架构损失会输出一条 +`[ocx:google:google-tool-schema-loss]` 记录(可用 `ocx debug provider logs -f` 持续查看), +其中仅包含报告版本、端点类别、`lossy` 指示器、带有上限计数的固定损失类别和截断标志, +绝不包含工具名、属性名、路径、值或架构文本。此诊断只观察现有的兼容转换,不会拒绝请求。 +原生输出架构不属于此诊断范围。请参阅[调试命令参考](/zh-cn/reference/cli/agents/)。 + Nous refresh 发生终止性失败后,请运行 `ocx login nous` 重新认证。 diff --git a/docs-site/src/content/docs/zh-tw/guides/providers.md b/docs-site/src/content/docs/zh-tw/guides/providers.md index 0eb613864a5..16f6b356510 100644 --- a/docs-site/src/content/docs/zh-tw/guides/providers.md +++ b/docs-site/src/content/docs/zh-tw/guides/providers.md @@ -117,6 +117,16 @@ ocx logout Google Antigravity 帳戶與供應商的配額查詢(包括模型清單備援)使用固定的 Google 計量端點。這些目標支援透明 Fake-IP DNS,同時保留 TLS 驗證、重新導向拒絕與私有位址檢查。自訂 base URL 只改變模型請求,不改變配額目標;`NO_PROXY` 仍使用直連政策。 +### Google 工具結構描述損失診斷 + +Google 工具宣告會依所選端點類別進行編譯。透過 `ocx debug provider on`、儀表板 Logs 開關或 +`OCX_DEBUG=1` 啟用供應商偵錯後,相容性轉換中的結構描述損失會輸出一筆 +`[ocx:google:google-tool-schema-loss]` 記錄(可用 `ocx debug provider logs -f` 持續查看), +其中只包含報告版本、端點類別、`lossy` 指標、帶有上限計數的固定損失類別與截斷旗標, +絕不包含工具名稱、屬性名稱、路徑、值或結構描述文字。此診斷只觀察既有的相容轉換, +不會拒絕請求。原生輸出結構描述不屬於此診斷範圍。請參閱 +[偵錯命令參考](/zh-tw/reference/cli/agents/)。 + 終端 Nous refresh 失敗後,執行 `ocx login nous` 重新認證。 diff --git a/scripts/test-layout/layout.json b/scripts/test-layout/layout.json index 2812bc20100..2e1b9066903 100644 --- a/scripts/test-layout/layout.json +++ b/scripts/test-layout/layout.json @@ -775,6 +775,7 @@ "google-signature-history-roundtrip.test.ts": "adapters/google", "google-structured-output.test.ts": "adapters/google", "google-tool-result-adjacency.test.ts": "adapters/google", + "google-tool-schema-contract.test.ts": "adapters/google", "google-tool-schema.test.ts": "adapters/google", "google-vertex-http.test.ts": "adapters/google", "google-vertex-stream.test.ts": "adapters/google", diff --git a/src/adapters/google-tool-schema.ts b/src/adapters/google-tool-schema.ts index aad7d96bb4f..944314a2732 100644 --- a/src/adapters/google-tool-schema.ts +++ b/src/adapters/google-tool-schema.ts @@ -8,7 +8,38 @@ const ALLOWED_TYPES = new Set(["string", "integer", "number", "boolean", "array" const MAX_SCHEMA_DEPTH = 24; // Google's documented nesting limit is 32; leave headroom for CCA. const MAX_DEREF_DEPTH = 16; const MAX_SCHEMA_NODES = 1_024; +export const GOOGLE_TOOL_SCHEMA_LOSS_COUNT_LIMIT = 255; const BUDGET_EXHAUSTED = Symbol("schema-budget-exhausted"); +const NUMERIC_BOUND_KEYS = ["minimum", "maximum", "exclusiveMinimum", "exclusiveMaximum"] as const; +const SIZE_BOUND_KEYS = ["minLength", "maxLength", "minItems", "maxItems", "minProperties", "maxProperties"] as const; +const UNSUPPORTED_CONSTRAINT_KEYS = [ + "allOf", + "oneOf", + "not", + "multipleOf", + "pattern", + "$dynamicRef", + "$recursiveRef", + "additionalProperties", + "additionalItems", + "uniqueItems", + "contains", + "minContains", + "maxContains", + "dependencies", + "dependentRequired", + "dependentSchemas", + "patternProperties", + "propertyNames", + "unevaluatedProperties", + "unevaluatedItems", +] as const; +const CONDITIONAL_KEYS = ["if", "then", "else"] as const; +const BOUNDED_VALUE_KEYS = new Set(["enum", "properties", "required", "items", "anyOf"]); +const RETAINED_UNION_KEYS = ["type", "nullable", "format", "enum", "properties", "items", "required"] as const; +// Annotation-only keywords do not change the accepted value set. The sanitizer intentionally +// drops title, default, examples, $comment, deprecated, readOnly, writeOnly, contentEncoding, +// contentMediaType, contentSchema, externalDocs, and example without loss. const MERGED_SCHEMA_KEYS = [ "type", "nullable", @@ -24,9 +55,148 @@ const MERGED_SCHEMA_KEYS = [ type SanitizeResult = Schema | typeof BUDGET_EXHAUSTED; +export type GoogleToolSchemaEndpointClass = "ai-studio" | "vertex" | "cloud-code-assist"; + +export interface GoogleToolSchemaProfile { + endpointClass: GoogleToolSchemaEndpointClass; +} + +export type GoogleToolSchemaLossCategory = + | "enum-value-filtered" + | "enum-constraint-dropped" + | "const-value-filtered" + | "numeric-bound-dropped" + | "size-bound-dropped" + | "type-union-collapsed" + | "unsupported-type-widened" + | "nullability-overridden" + | "conditional-dropped" + | "tuple-prefix-dropped" + | "ref-overlay-replaced" + | "union-sibling-replaced" + | "root-object-coerced" + | "union-widened" + | "recursive-ref-widened" + | "dereference-limit-widened" + | "depth-limit-widened" + | "node-budget-widened" + | "unsupported-constraint-dropped" + | "invalid-schema-widened"; + +export interface GoogleToolSchemaLossReport { + version: 1; + endpointClass: GoogleToolSchemaEndpointClass; + lossy: boolean; + truncated: boolean; + /** Bounded comparisons that exhausted their allowance; uncertainty is not proven loss. */ + uncertainComparisons: number; + /** Saturating proven-loss counts only; capped/unknown structural comparisons add no category. */ + categories: Partial>; +} + +export interface GoogleToolSchemaSanitizeResult { + parameters: Record; + lossReport: GoogleToolSchemaLossReport; +} + interface SanitizeState { activeRefs: Set; remainingNodes: number; + budgetReported: boolean; + enumFilterLossOverrides: WeakMap; + report: GoogleToolSchemaLossReport; +} + +export function createGoogleToolSchemaLossReport( + profile: GoogleToolSchemaProfile, +): GoogleToolSchemaLossReport { + return { + version: 1, + endpointClass: profile.endpointClass, + lossy: false, + truncated: false, + uncertainComparisons: 0, + categories: {}, + }; +} + +function addGoogleToolSchemaUncertainty(report: GoogleToolSchemaLossReport): void { + if (report.uncertainComparisons >= GOOGLE_TOOL_SCHEMA_LOSS_COUNT_LIMIT) { + report.truncated = true; + return; + } + report.uncertainComparisons++; +} + +export function addGoogleToolSchemaLoss( + report: GoogleToolSchemaLossReport, + category: GoogleToolSchemaLossCategory, + amount = 1, +): void { + if (!Number.isFinite(amount) || amount <= 0) return; + report.lossy = true; + const increment = Math.floor(amount); + const current = report.categories[category] ?? 0; + const next = current + increment; + if (next >= GOOGLE_TOOL_SCHEMA_LOSS_COUNT_LIMIT) { + report.categories[category] = GOOGLE_TOOL_SCHEMA_LOSS_COUNT_LIMIT; + if (next > GOOGLE_TOOL_SCHEMA_LOSS_COUNT_LIMIT) report.truncated = true; + return; + } + report.categories[category] = next; +} + +export function mergeGoogleToolSchemaLossReport( + target: GoogleToolSchemaLossReport, + source: GoogleToolSchemaLossReport, +): void { + for (const [category, count] of Object.entries(source.categories)) { + addGoogleToolSchemaLoss(target, category as GoogleToolSchemaLossCategory, count); + } + const uncertainty = target.uncertainComparisons + source.uncertainComparisons; + target.uncertainComparisons = Math.min(uncertainty, GOOGLE_TOOL_SCHEMA_LOSS_COUNT_LIMIT); + if (uncertainty > GOOGLE_TOOL_SCHEMA_LOSS_COUNT_LIMIT) target.truncated = true; + if (source.truncated) target.truncated = true; +} + +function reportBudgetExhausted(state: SanitizeState): void { + if (state.budgetReported) return; + state.budgetReported = true; + addGoogleToolSchemaLoss(state.report, "node-budget-widened"); +} + +function reportDroppedConstraints(node: Schema, state: SanitizeState): void { + let numericBounds = 0; + for (const key of NUMERIC_BOUND_KEYS) { + if (Object.hasOwn(node, key)) numericBounds++; + } + addGoogleToolSchemaLoss(state.report, "numeric-bound-dropped", numericBounds); + + let sizeBounds = 0; + for (const key of SIZE_BOUND_KEYS) { + if (!Object.hasOwn(node, key)) continue; + if ((key === "minLength" || key === "minItems" || key === "minProperties") && node[key] === 0) continue; + sizeBounds++; + } + addGoogleToolSchemaLoss(state.report, "size-bound-dropped", sizeBounds); + + let unsupported = 0; + for (const key of UNSUPPORTED_CONSTRAINT_KEYS) { + if (!Object.hasOwn(node, key)) continue; + if (key === "additionalProperties" && node[key] === true) continue; + if (key === "uniqueItems" && node[key] === false) continue; + unsupported++; + } + addGoogleToolSchemaLoss(state.report, "unsupported-constraint-dropped", unsupported); + + let conditionals = 0; + for (const key of CONDITIONAL_KEYS) { + if (Object.hasOwn(node, key)) conditionals++; + } + addGoogleToolSchemaLoss(state.report, "conditional-dropped", conditionals); + if (Object.hasOwn(node, "prefixItems") && !(Array.isArray(node.prefixItems) && node.prefixItems.length === 0)) { + addGoogleToolSchemaLoss(state.report, "tuple-prefix-dropped"); + } } function isRecord(value: unknown): value is Schema { @@ -55,39 +225,308 @@ function collectDefs(root: unknown, defs: Map): void { } } -function mergeRefTarget(target: Schema, overlay: Schema): Schema { +interface BoundedEqualityState { + remainingNodes: number; +} + +/** + * Exact JSON-value comparison with the sanitizer's own depth/node ceilings. + * `unknown` means the cap prevented a proof; report-only mode does not count it as proven loss. + */ +type BoundedEquality = "equal" | "different" | "unknown"; + +function boundedJsonEqual( + left: unknown, + right: unknown, + state: BoundedEqualityState = { remainingNodes: MAX_SCHEMA_NODES }, + depth = 0, +): BoundedEquality { + if (Object.is(left, right)) return "equal"; + if (depth >= MAX_SCHEMA_DEPTH || state.remainingNodes <= 0) return "unknown"; + state.remainingNodes--; + + if (Array.isArray(left) || Array.isArray(right)) { + if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length) return "different"; + for (let index = 0; index < left.length; index++) { + if (state.remainingNodes <= 0) return "unknown"; + state.remainingNodes--; + const comparison = boundedJsonEqual(left[index], right[index], state, depth + 1); + if (comparison !== "equal") return comparison; + } + return "equal"; + } + if (!isRecord(left) || !isRecord(right)) return "different"; + + let leftCount = 0; + for (const key in left) { + if (!Object.hasOwn(left, key)) continue; + if (state.remainingNodes <= 0) return "unknown"; + state.remainingNodes--; + leftCount++; + if (!Object.hasOwn(right, key)) return "different"; + const comparison = boundedJsonEqual(left[key], right[key], state, depth + 1); + if (comparison !== "equal") return comparison; + } + let rightCount = 0; + for (const key in right) { + if (!Object.hasOwn(right, key)) continue; + if (state.remainingNodes <= 0) return "unknown"; + state.remainingNodes--; + rightCount++; + if (rightCount > leftCount) return "different"; + } + return leftCount === rightCount ? "equal" : "different"; +} + +function boundedStringSetEqual( + left: unknown, + right: unknown, + normalize: (value: string) => string, + state: BoundedEqualityState = { remainingNodes: MAX_SCHEMA_NODES }, +): BoundedEquality { + const leftValues = Array.isArray(left) ? left : [left]; + const rightValues = Array.isArray(right) ? right : [right]; + const collect = (values: unknown[]): Set | undefined => { + const result = new Set(); + for (const value of values) { + if (state.remainingNodes <= 0) return undefined; + state.remainingNodes--; + if (typeof value === "string") result.add(normalize(value)); + } + return result; + }; + const leftSet = collect(leftValues); + const rightSet = collect(rightValues); + if (!leftSet || !rightSet) return "unknown"; + if (leftSet.size !== rightSet.size) return "different"; + for (const value of leftSet) { + if (!rightSet.has(value)) return "different"; + } + return "equal"; +} + +function boundedJsonSetEqual( + left: unknown[], + right: unknown[], + state: BoundedEqualityState = { remainingNodes: MAX_SCHEMA_NODES }, +): BoundedEquality { + const unique = (values: unknown[]): { comparison: BoundedEquality; values: unknown[] } => { + const result: unknown[] = []; + for (const value of values) { + if (state.remainingNodes <= 0) return { comparison: "unknown", values: result }; + state.remainingNodes--; + let duplicate = false; + for (const candidate of result) { + const comparison = boundedJsonEqual(value, candidate, state); + if (comparison === "unknown") return { comparison, values: result }; + if (comparison === "equal") { + duplicate = true; + break; + } + } + if (!duplicate) result.push(value); + } + return { comparison: "equal", values: result }; + }; + const leftUnique = unique(left); + if (leftUnique.comparison !== "equal") return leftUnique.comparison; + const rightUnique = unique(right); + if (rightUnique.comparison !== "equal") return rightUnique.comparison; + if (leftUnique.values.length !== rightUnique.values.length) return "different"; + const unmatched = [...rightUnique.values]; + for (const value of leftUnique.values) { + let matched = -1; + for (let index = 0; index < unmatched.length; index++) { + const comparison = boundedJsonEqual(value, unmatched[index], state); + if (comparison === "unknown") return comparison; + if (comparison === "equal") { + matched = index; + break; + } + } + if (matched < 0) return "different"; + unmatched.splice(matched, 1); + } + return "equal"; +} + +interface BoundedEnumOverlayAccounting { + comparison: BoundedEquality; + emittedWidensIntersection: boolean; + filteredIntersectionValues: number; +} + +function boundedEnumOverlayAccounting( + target: unknown[], + overlay: unknown[], +): BoundedEnumOverlayAccounting { + const state: BoundedEqualityState = { remainingNodes: MAX_SCHEMA_NODES }; + const stringSet = (values: unknown[]): Set | undefined => { + const result = new Set(); + for (const value of values) { + if (state.remainingNodes <= 0) return undefined; + state.remainingNodes--; + if (typeof value === "string") result.add(value); + } + return result; + }; + const targetStrings = stringSet(target); + const emittedStrings = stringSet(overlay); + if (!targetStrings || !emittedStrings) { + return { comparison: "unknown", emittedWidensIntersection: false, filteredIntersectionValues: 0 }; + } + + let emittedWidensIntersection = false; + for (const value of emittedStrings) { + if (!targetStrings.has(value)) { + emittedWidensIntersection = true; + break; + } + } + + const uniqueFiltered: unknown[] = []; + for (const value of overlay) { + if (typeof value === "string") continue; + if (state.remainingNodes <= 0) { + return { comparison: "unknown", emittedWidensIntersection: false, filteredIntersectionValues: 0 }; + } + state.remainingNodes--; + let duplicate = false; + for (const candidate of uniqueFiltered) { + const comparison = boundedJsonEqual(value, candidate, state); + if (comparison === "unknown") { + return { comparison, emittedWidensIntersection: false, filteredIntersectionValues: 0 }; + } + if (comparison === "equal") { + duplicate = true; + break; + } + } + if (!duplicate) uniqueFiltered.push(value); + } + + let filteredIntersectionValues = 0; + for (const value of uniqueFiltered) { + for (const candidate of target) { + const comparison = boundedJsonEqual(value, candidate, state); + if (comparison === "unknown") { + return { comparison, emittedWidensIntersection: false, filteredIntersectionValues: 0 }; + } + if (comparison === "equal") { + filteredIntersectionValues++; + break; + } + } + } + return { comparison: "equal", emittedWidensIntersection, filteredIntersectionValues }; +} + +function compareMergedValue(key: string, left: unknown, right: unknown): BoundedEquality { + if (key === "enum" && Array.isArray(left) && Array.isArray(right)) { + return boundedJsonSetEqual(left, right); + } + if (key === "required" && Array.isArray(left) && Array.isArray(right)) { + if (left.every(value => typeof value === "string") && right.every(value => typeof value === "string")) { + return boundedStringSetEqual(left, right, value => value); + } + return boundedJsonEqual(left, right); + } + if (key === "type") { + const leftValues = Array.isArray(left) ? left : [left]; + const rightValues = Array.isArray(right) ? right : [right]; + if (leftValues.every(value => typeof value === "string") + && rightValues.every(value => typeof value === "string")) { + return boundedStringSetEqual(left, right, value => value.toLowerCase()); + } + return boundedJsonEqual(left, right); + } + if (BOUNDED_VALUE_KEYS.has(key)) return boundedJsonEqual(left, right); + return Object.is(left, right) ? "equal" : "different"; +} + +function mergeRefTarget(target: Schema, overlay: Schema, state: SanitizeState): Schema { const merged: Schema = {}; if (Object.hasOwn(target, "$ref")) merged.$ref = target.$ref; for (const key of MERGED_SCHEMA_KEYS) { - if (Object.hasOwn(overlay, key)) merged[key] = overlay[key]; - else if (Object.hasOwn(target, key)) merged[key] = target[key]; + if (Object.hasOwn(overlay, key)) { + if (key !== "description" && Object.hasOwn(target, key)) { + if (key === "enum" && Array.isArray(target[key]) && Array.isArray(overlay[key])) { + const accounting = boundedEnumOverlayAccounting(target[key], overlay[key]); + if (accounting.comparison === "unknown") { + addGoogleToolSchemaUncertainty(state.report); + } else { + if (accounting.emittedWidensIntersection) { + addGoogleToolSchemaLoss(state.report, "ref-overlay-replaced"); + } + addGoogleToolSchemaLoss( + state.report, + "enum-value-filtered", + accounting.filteredIntersectionValues, + ); + } + // The intersection-aware accounting above owns this merged enum's filtering report. + state.enumFilterLossOverrides.set(merged, 0); + } else { + const comparison = compareMergedValue(key, overlay[key], target[key]); + if (comparison === "different") addGoogleToolSchemaLoss(state.report, "ref-overlay-replaced"); + else if (comparison === "unknown") addGoogleToolSchemaUncertainty(state.report); + } + } + merged[key] = overlay[key]; + } else if (Object.hasOwn(target, key)) merged[key] = target[key]; } return merged; } -function normalizeType(value: unknown, out: Schema, preserveNullType: boolean): void { +function normalizeType( + value: unknown, + out: Schema, + preserveNullType: boolean, + state: SanitizeState, +): void { const candidates = Array.isArray(value) ? value : [value]; let sawNull = false; + const nonNullTypes = new Set(); + let unsupported = 0; + if (Array.isArray(value) && value.length === 0) unsupported++; for (const candidate of candidates) { - if (typeof candidate !== "string") continue; + if (typeof candidate !== "string") { + if (candidate !== undefined) unsupported++; + continue; + } const type = candidate.toLowerCase(); if (type === "null") { sawNull = true; - } else if (out.type === undefined && ALLOWED_TYPES.has(type)) { - out.type = type; + } else if (ALLOWED_TYPES.has(type)) { + nonNullTypes.add(type); + if (out.type === undefined) out.type = type; + } else { + unsupported++; } } + addGoogleToolSchemaLoss(state.report, "unsupported-type-widened", unsupported); + if (nonNullTypes.size > 1) addGoogleToolSchemaLoss(state.report, "type-union-collapsed"); + if (!sawNull) return; if (out.type !== undefined) out.nullable = true; else if (preserveNullType) out.type = "null"; - else out.nullable = true; + else { + out.nullable = true; + addGoogleToolSchemaLoss(state.report, "unsupported-type-widened"); + } } -function sanitizeEnum(value: unknown): string[] | undefined { +function sanitizeEnum(value: unknown, state?: SanitizeState, filteredLossOverride?: number): string[] | undefined { if (!Array.isArray(value)) return undefined; - const values = [...new Set(value.filter((item): item is string => typeof item === "string"))]; + const stringValues = value.filter((item): item is string => typeof item === "string"); + if (state) addGoogleToolSchemaLoss( + state.report, + "enum-value-filtered", + filteredLossOverride ?? (value.length - stringValues.length), + ); + const values = [...new Set(stringValues)]; return values.length > 0 ? values : undefined; } @@ -98,10 +537,16 @@ function normalizeAnyOf( refDepth: number, state: SanitizeState, ): Schema { - if (!Array.isArray(value) || value.length === 0) return {}; + if (!Array.isArray(value) || value.length === 0) { + addGoogleToolSchemaLoss(state.report, "invalid-schema-widened"); + return {}; + } const schemas: Schema[] = []; for (let index = 0; index < value.length; index++) { - if (state.remainingNodes <= 0) return {}; + if (state.remainingNodes <= 0) { + reportBudgetExhausted(state); + return {}; + } const schema = sanitizeSchema(value[index], defs, depth + 1, refDepth, true, state); if (schema === BUDGET_EXHAUSTED) return {}; schemas.push(schema); @@ -130,6 +575,7 @@ function normalizeAnyOf( // CCA's Claude bridge turns typed anyOf branches into an invalid input_schema. Widen only this // node when a union cannot be collapsed losslessly; parent annotations and structure survive. + addGoogleToolSchemaLoss(state.report, "union-widened"); return {}; } @@ -144,7 +590,10 @@ function sanitizeProperties( const properties: Record = Object.create(null) as Record; for (const name in value) { if (!Object.hasOwn(value, name)) continue; - if (state.remainingNodes <= 0) break; + if (state.remainingNodes <= 0) { + reportBudgetExhausted(state); + break; + } // Property names form a name bag and must never be interpreted as schema keywords. const schema = sanitizeSchema(value[name], defs, depth + 1, refDepth, false, state); if (schema === BUDGET_EXHAUSTED) break; @@ -161,78 +610,191 @@ function sanitizeSchema( preserveNullType: boolean, state: SanitizeState, ): SanitizeResult { - if (state.remainingNodes <= 0) return BUDGET_EXHAUSTED; + if (state.remainingNodes <= 0) { + reportBudgetExhausted(state); + return BUDGET_EXHAUSTED; + } state.remainingNodes -= 1; - if (depth >= MAX_SCHEMA_DEPTH || !isRecord(node)) return {}; + if (depth >= MAX_SCHEMA_DEPTH) { + addGoogleToolSchemaLoss(state.report, "depth-limit-widened"); + return {}; + } + if (!isRecord(node)) { + addGoogleToolSchemaLoss(state.report, "invalid-schema-widened"); + return {}; + } + + reportDroppedConstraints(node, state); - if (typeof node.$ref === "string" && refDepth < MAX_DEREF_DEPTH) { + if (Object.hasOwn(node, "$ref") && typeof node.$ref !== "string") { + addGoogleToolSchemaLoss(state.report, "invalid-schema-widened"); + } else if (typeof node.$ref === "string" && refDepth >= MAX_DEREF_DEPTH) { + addGoogleToolSchemaLoss(state.report, "dereference-limit-widened"); + } else if (typeof node.$ref === "string") { const target = resolveRef(node.$ref, defs); if (isRecord(target)) { - if (state.activeRefs.has(node.$ref)) return {}; + if (state.activeRefs.has(node.$ref)) { + addGoogleToolSchemaLoss(state.report, "recursive-ref-widened"); + return {}; + } state.activeRefs.add(node.$ref); + // Constraints outside the merge allowlist are discarded here and must be counted before + // selecting the safe view. Copied keys are deliberately excluded to avoid double counting. + reportDroppedConstraints(target, state); // Select only inputs the sanitizer can consume. Spreading an untrusted definition here would // enumerate and allocate every unsupported annotation before the node budget can stop work. - const merged = mergeRefTarget(target, node); + const merged = mergeRefTarget(target, node, state); try { return sanitizeSchema(merged, defs, depth, refDepth + 1, preserveNullType, state); } finally { state.activeRefs.delete(node.$ref); } + } else { + addGoogleToolSchemaLoss(state.report, "invalid-schema-widened"); } } const out: Schema = {}; - normalizeType(node.type, out, preserveNullType); + if (Object.hasOwn(node, "type") && node.type === undefined) { + addGoogleToolSchemaLoss(state.report, "unsupported-type-widened"); + } + normalizeType(node.type, out, preserveNullType, state); + const typeIncludesNull = (Array.isArray(node.type) ? node.type : [node.type]) + .some(candidate => typeof candidate === "string" && candidate.toLowerCase() === "null"); + if (node.nullable === false && typeIncludesNull) { + addGoogleToolSchemaLoss(state.report, "nullability-overridden"); + } if (typeof node.nullable === "boolean") out.nullable = node.nullable; + else if (Object.hasOwn(node, "nullable")) addGoogleToolSchemaLoss(state.report, "invalid-schema-widened"); if (typeof node.description === "string") out.description = node.description; if (typeof node.format === "string") out.format = node.format; + else if (Object.hasOwn(node, "format")) addGoogleToolSchemaLoss(state.report, "invalid-schema-widened"); - const enumValues = sanitizeEnum(node.enum ?? (typeof node.const === "string" ? [node.const] : undefined)); + if (Object.hasOwn(node, "enum") && !Array.isArray(node.enum)) { + addGoogleToolSchemaLoss(state.report, "invalid-schema-widened"); + } else if (Array.isArray(node.enum) && node.enum.length === 0) { + addGoogleToolSchemaLoss(state.report, "enum-constraint-dropped"); + } + if (Object.hasOwn(node, "const")) { + if (typeof node.const !== "string") { + addGoogleToolSchemaLoss(state.report, "const-value-filtered"); + } else if (Object.hasOwn(node, "enum")) { + const enumValues = Array.isArray(node.enum) + ? [...new Set(node.enum.filter((item): item is string => typeof item === "string"))] + : []; + if (enumValues.length !== 1 || enumValues[0] !== node.const) { + addGoogleToolSchemaLoss(state.report, "const-value-filtered"); + } + } + } + const enumValues = sanitizeEnum( + node.enum ?? (typeof node.const === "string" ? [node.const] : undefined), + state, + state.enumFilterLossOverrides.get(node), + ); if (enumValues) out.enum = enumValues; + if (Object.hasOwn(node, "properties") && !isRecord(node.properties)) { + addGoogleToolSchemaLoss(state.report, "invalid-schema-widened"); + } const properties = sanitizeProperties(node.properties, defs, depth, refDepth, state); if (properties) out.properties = properties; if (properties && Array.isArray(node.required)) { - const required = [...new Set(node.required.filter((item): item is string => ( - typeof item === "string" && Object.hasOwn(properties, item) - )))]; + const stringRequired = node.required.filter((item): item is string => typeof item === "string"); + const uniqueRequired = [...new Set(stringRequired)]; + const required = uniqueRequired.filter(item => Object.hasOwn(properties, item)); + addGoogleToolSchemaLoss( + state.report, + "unsupported-constraint-dropped", + uniqueRequired.length - required.length, + ); + addGoogleToolSchemaLoss(state.report, "invalid-schema-widened", node.required.length - stringRequired.length); if (required.length > 0) out.required = required; + } else if (!properties && Array.isArray(node.required)) { + const stringRequired = node.required.filter((item): item is string => typeof item === "string"); + const required = new Set(stringRequired); + addGoogleToolSchemaLoss(state.report, "unsupported-constraint-dropped", required.size); + addGoogleToolSchemaLoss(state.report, "invalid-schema-widened", node.required.length - stringRequired.length); + } else if (Object.hasOwn(node, "required") && !Array.isArray(node.required)) { + addGoogleToolSchemaLoss(state.report, "invalid-schema-widened"); } - if (state.remainingNodes <= 0) return out; + if (state.remainingNodes <= 0) { + if (Object.hasOwn(node, "items") || Object.hasOwn(node, "anyOf")) reportBudgetExhausted(state); + return out; + } - if (isRecord(node.items)) { + if (Array.isArray(node.items)) { + addGoogleToolSchemaLoss(state.report, "tuple-prefix-dropped"); + } else if (isRecord(node.items)) { const items = sanitizeSchema(node.items, defs, depth + 1, refDepth, false, state); if (items !== BUDGET_EXHAUSTED) out.items = items; + } else if (Object.hasOwn(node, "items")) { + addGoogleToolSchemaLoss(state.report, "invalid-schema-widened"); } - if (state.remainingNodes <= 0) return out; - if (node.anyOf !== undefined) { - Object.assign(out, normalizeAnyOf(node.anyOf, defs, depth, refDepth, state)); + if (state.remainingNodes <= 0) { + if (Object.hasOwn(node, "anyOf")) reportBudgetExhausted(state); + return out; + } + if (Object.hasOwn(node, "anyOf")) { + const normalized = normalizeAnyOf(node.anyOf, defs, depth, refDepth, state); + for (const key of RETAINED_UNION_KEYS) { + if (Object.hasOwn(out, key) && Object.hasOwn(normalized, key) + ) { + const comparison = compareMergedValue(key, out[key], normalized[key]); + if (comparison === "different") addGoogleToolSchemaLoss(state.report, "union-sibling-replaced"); + else if (comparison === "unknown") addGoogleToolSchemaUncertainty(state.report); + } + } + Object.assign(out, normalized); } return out; } -export function sanitizeGeminiToolParameters(parameters: unknown): Record { +export function sanitizeGeminiToolParametersWithReport( + parameters: unknown, + profile: GoogleToolSchemaProfile, +): GoogleToolSchemaSanitizeResult { + const report = createGoogleToolSchemaLossReport(profile); + if (parameters === undefined) { + return { parameters: { type: "object", properties: {} }, lossReport: report }; + } try { const defs = new Map(); collectDefs(parameters, defs); const state: SanitizeState = { activeRefs: new Set(), remainingNodes: MAX_SCHEMA_NODES, + budgetReported: false, + enumFilterLossOverrides: new WeakMap(), + report, }; + if (isRecord(parameters)) { + for (const bag of ["$defs", "definitions"] as const) { + if (Object.hasOwn(parameters, bag) && !isRecord(parameters[bag])) { + addGoogleToolSchemaLoss(report, "invalid-schema-widened"); + } + } + } const sanitized = sanitizeSchema(parameters, defs, 0, 0, false, state); const root = sanitized === BUDGET_EXHAUSTED ? {} : sanitized; // Function arguments are always an object. Claude additionally rejects root composition and a // missing root type even when those forms are valid general-purpose JSON Schema. + if (root.type !== "object") addGoogleToolSchemaLoss(report, "root-object-coerced"); root.type = "object"; if (!isRecord(root.properties)) root.properties = {}; - return root; + return { parameters: root, lossReport: report }; } catch { // Last-resort containment: no third-party schema may break every tool in the request. - return { type: "object", properties: {} }; + addGoogleToolSchemaLoss(report, "invalid-schema-widened"); + return { parameters: { type: "object", properties: {} }, lossReport: report }; } } + +export function sanitizeGeminiToolParameters(parameters: unknown): Record { + return sanitizeGeminiToolParametersWithReport(parameters, { endpointClass: "ai-studio" }).parameters; +} diff --git a/src/adapters/google-wire-compiler.ts b/src/adapters/google-wire-compiler.ts index 7b97c96f971..38540597119 100644 --- a/src/adapters/google-wire-compiler.ts +++ b/src/adapters/google-wire-compiler.ts @@ -1,5 +1,11 @@ import { createHash } from "node:crypto"; -import { sanitizeGeminiToolParameters } from "./google-tool-schema"; +import { + createGoogleToolSchemaLossReport, + mergeGoogleToolSchemaLossReport, + sanitizeGeminiToolParametersWithReport, + type GoogleToolSchemaLossReport, + type GoogleToolSchemaProfile, +} from "./google-tool-schema"; type JsonObject = Record; @@ -94,16 +100,23 @@ function compileContents(value: unknown, toWireName: (name: string) => string): }); } -function compileTools(value: unknown, toWireName: (name: string) => string): unknown[] | undefined { +function compileTools( + value: unknown, + toWireName: (name: string) => string, + profile: GoogleToolSchemaProfile, + lossReport: GoogleToolSchemaLossReport, +): unknown[] | undefined { if (!Array.isArray(value)) return undefined; const tools = value.flatMap(rawTool => { if (!isObject(rawTool) || !Array.isArray(rawTool.functionDeclarations)) return []; const functionDeclarations = rawTool.functionDeclarations.flatMap(rawDeclaration => { if (!isObject(rawDeclaration) || typeof rawDeclaration.name !== "string") return []; + const sanitized = sanitizeGeminiToolParametersWithReport(rawDeclaration.parameters, profile); + mergeGoogleToolSchemaLossReport(lossReport, sanitized.lossReport); return [{ name: toWireName(rawDeclaration.name), ...(typeof rawDeclaration.description === "string" ? { description: rawDeclaration.description } : {}), - parameters: sanitizeGeminiToolParameters(rawDeclaration.parameters), + parameters: sanitized.parameters, }]; }); return functionDeclarations.length > 0 ? [{ functionDeclarations }] : []; @@ -180,24 +193,29 @@ function compileToolConfig(value: unknown, toWireName: (name: string) => string) * Final trust boundary for every Google-family request. The adapter may build a convenient * Gemini-shaped object; only this compiler is allowed to decide what reaches the wire. */ -export function compileGoogleWireBody(input: unknown): { +export function compileGoogleWireBody( + input: unknown, + profile: GoogleToolSchemaProfile = { endpointClass: "ai-studio" }, +): { body: JsonObject; restoreToolName: (name: string) => string; + toolSchemaLossReport: GoogleToolSchemaLossReport; } { const source = isObject(input) ? input : {}; const names = toolNameCodec(collectToolNames(source)); const body: JsonObject = {}; + const toolSchemaLossReport = createGoogleToolSchemaLossReport(profile); const contents = compileContents(source.contents, names.toWire); if (contents) body.contents = contents; if (isObject(source.systemInstruction)) body.systemInstruction = source.systemInstruction; - const tools = compileTools(source.tools, names.toWire); + const tools = compileTools(source.tools, names.toWire, profile, toolSchemaLossReport); if (tools) body.tools = tools; const generationConfig = compileGenerationConfig(source.generationConfig); if (generationConfig) body.generationConfig = generationConfig; const toolConfig = compileToolConfig(source.toolConfig, names.toWire); if (toolConfig) body.toolConfig = toolConfig; if (typeof source.sessionId === "string" && source.sessionId.length > 0) body.sessionId = source.sessionId; - return { body, restoreToolName: names.fromWire }; + return { body, restoreToolName: names.fromWire, toolSchemaLossReport }; } function functionDeclarations(root: JsonObject): JsonObject[] { diff --git a/src/adapters/google.ts b/src/adapters/google.ts index 449870c0b3e..6d3e39eed75 100644 --- a/src/adapters/google.ts +++ b/src/adapters/google.ts @@ -23,6 +23,7 @@ import { isVertexTruncatedTurn, vertexTruncationErrorMessage } from "./google-tr import { ANTIGRAVITY_REQUEST_UA, antigravitySessionAnchor, antigravitySessionId, isLikelyRealThoughtSignature, sanitizeAntigravityClaudeSignatures } from "./google-antigravity-wire"; import { summarizeGoogleWireShape } from "./google-wire-shape"; import { compileGoogleWireBody } from "./google-wire-compiler"; +import type { GoogleToolSchemaLossReport, GoogleToolSchemaProfile } from "./google-tool-schema"; import { identifyRoutedModel } from "./identity"; import { antigravityUsesReplayCache, @@ -738,6 +739,13 @@ function invalidGoogleShapeEvent( } export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapter { + const toolSchemaProfile = { + endpointClass: provider.googleMode ?? "ai-studio", + } satisfies GoogleToolSchemaProfile; + const reportToolSchemaLoss = (report: GoogleToolSchemaLossReport): void => { + if (!report.lossy && report.uncertainComparisons === 0) return; + debugProviderDiagnosticLazy("google", "google-tool-schema-loss", () => ({ ...report })); + }; // Per-request closure: resolveAdapter builds a fresh adapter per request (server.ts), so buildRequest // can stash the CCA model/session for parseStream's reasoning-replay observation. let antigravityModel: string | undefined; @@ -971,7 +979,8 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte const fcc = (existing.functionCallingConfig ?? {}) as Record; draftRequest.toolConfig = { ...existing, functionCallingConfig: { ...fcc, mode: "VALIDATED" } }; } - const compiled = compileGoogleWireBody(draftRequest); + const compiled = compileGoogleWireBody(draftRequest, toolSchemaProfile); + reportToolSchemaLoss(compiled.toolSchemaLossReport); const request = compiled.body; restoreGoogleToolName = compiled.restoreToolName; // Compile names before replay: signatures are keyed by the exact provider-visible name. @@ -1021,7 +1030,8 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte } if (provider.googleMode === "vertex") { - const compiled = compileGoogleWireBody(body); + const compiled = compileGoogleWireBody(body, toolSchemaProfile); + reportToolSchemaLoss(compiled.toolSchemaLossReport); restoreGoogleToolName = compiled.restoreToolName; const vertexProject = provider.project || process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT || "api-key"; const vertexLocation = provider.location || process.env.GOOGLE_CLOUD_LOCATION || "global"; @@ -1067,7 +1077,8 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte if (!apiKey) throw new Error("google (AI Studio) requires a non-empty API key"); headers["x-goog-api-key"] = apiKey; - const compiled = compileGoogleWireBody(body); + const compiled = compileGoogleWireBody(body, toolSchemaProfile); + reportToolSchemaLoss(compiled.toolSchemaLossReport); restoreGoogleToolName = compiled.restoreToolName; return { url, method: "POST", headers, body: JSON.stringify(compiled.body) }; }, diff --git a/structure/adapters/registry.md b/structure/adapters/registry.md index 478a41f1c41..a5e18ac408f 100644 --- a/structure/adapters/registry.md +++ b/structure/adapters/registry.md @@ -105,6 +105,10 @@ Do not add a second switch/list of adapter factories in request routing. Focused This decision does not change routed `apply_patch` behavior, Cursor structured-edit conversion, Azure/MiMo request construction, or provider wire selection. Those behaviors remain owned by their existing modules and focused tests. The registry exposes the universe and semantic relationships; the next stack layer consumes that metadata for generic conformance. +Registry selection neither derives nor consumes Google's endpoint-scoped +[tool-schema loss report](../providers/google.md#google-tool-schema-loss-reporting). That report is +owned by the selected adapter's final compiler and cannot affect adapter selection. + The shared Responses path follows the [bounded multipart recovery contract](../subagents.md#multipart-encrypted-task-recovery); credential admission and retry policy remain unchanged. ## Moonshot `$ref`-with-siblings normalization diff --git a/structure/data-planes/inbound-compat.md b/structure/data-planes/inbound-compat.md index f0e5ce5c656..e3b754f91ae 100644 --- a/structure/data-planes/inbound-compat.md +++ b/structure/data-planes/inbound-compat.md @@ -292,6 +292,10 @@ never fetched. ## Translated Chat control fidelity +Translated Chat ingress does not reshape schemas for Google's +[endpoint-scoped loss report](../providers/google.md#google-tool-schema-loss-reporting). The report +is produced only at the final Google adapter boundary and does not alter the ingress body. + A translated Chat turn keeps the controls the caller sent. The Chat ingress pins `store:false` for every `openai-responses` route and strips nothing else: the sampling and output-cap restrictions that the canonical ChatGPT backend requires are diff --git a/structure/providers-and-adapters.md b/structure/providers-and-adapters.md index beb442a4dc3..91ec48f0130 100644 --- a/structure/providers-and-adapters.md +++ b/structure/providers-and-adapters.md @@ -14,7 +14,7 @@ the [bounded ingestion contract](transports/inventory.md#bounded-response-ingest | `src/responses/muse-tool-name-alias.ts` | Host-gated Meta Muse 64-char tool-name alias/restore used by the Responses passthrough. | | `src/adapters/openai-chat.ts`, `src/adapters/openai-chat/` | OpenAI-compatible Chat Completions bridge, split into leaves (`wire.ts`, `messages.ts`, `response-events.ts`, `passthrough.ts`, `tool-call-validation.ts`, `tool-schema.ts`, `errors.ts`). Its client delivery shapes in `src/chat/outbound.ts` and `src/server/chat-native-sse.ts` relay the upstream `service_tier` echo on non-stream, folded-stream, and synthesized-SSE bodies, never inventing the key when the upstream omits it. | | `src/adapters/anthropic.ts` | Anthropic Messages bridge. A `refusal` or `content_filter` stop reason yields an explicit `incomplete` event with `retryable: false` rather than `done` with that stopReason (#4312); `max_tokens` remains `done`. | -| `src/adapters/google.ts` | Gemini bridge. | +| `src/adapters/google.ts` | Gemini bridge. The final wire compiler owns [endpoint-scoped, content-free tool-schema loss reporting](providers/google.md#google-tool-schema-loss-reporting); reporting does not change routing or request bytes. | | `src/adapters/azure.ts` | Azure OpenAI bridge. | | `src/adapters/cursor.ts`, `src/adapters/cursor/` | Cursor protobuf transport: discovery, request builder, event decoding, MCP, thread continuity, native-exec policy. | | `src/adapters/devin.ts`, `src/adapters/devin/cloud-direct/` | Devin runTurn transport over Cognition Connect-RPC. `GetChatMessage` uses the Responses provider executor and shared physical-send budget; catalog and JWT support RPCs remain outside inference-send accounting. | diff --git a/structure/providers/chat-compat.md b/structure/providers/chat-compat.md index f6d4349cf2f..67fb6ba62ac 100644 --- a/structure/providers/chat-compat.md +++ b/structure/providers/chat-compat.md @@ -26,6 +26,10 @@ Shared parsing and streaming follow the [request-copy](../transports/byte-accoun ## Reasoning and tool-result compatibility +Google tool-declaration narrowing is observed by the Google final compiler, not this shared Chat +compatibility layer. Its endpoint profile and privacy boundary are specified in the +[Google provider contract](google.md#google-tool-schema-loss-reporting). + Chat models sometimes return a freeform call body under a common alternate field or wrap the whole body in a Markdown fence. Restoration in `src/responses/apply-patch-envelope.ts` is deliberately narrow: only bare `exec` and `apply_patch` accept one recognized alternate field or one complete diff --git a/structure/providers/cursor.md b/structure/providers/cursor.md index 5278df9ead2..5663726e14c 100644 --- a/structure/providers/cursor.md +++ b/structure/providers/cursor.md @@ -135,6 +135,9 @@ on the freeform path. Namespaced tools do not acquire bare-shell behavior. Regression coverage lives in `tests/providers/cursor/cursor-tool-definitions.test.ts`. +Google's [tool-schema loss report](google.md#google-tool-schema-loss-reporting) is confined to the +Google final compiler and does not change Cursor's advertised or normalized schema ownership. + Canonical Spark Lite metadata follows the final serialized model and surviving nonempty Lite tool catalog; see [Responses transport](../transports/responses.md). Shared raw-reasoning events retain content-channel presentation; provider-authored thinking keeps its existing summary path. See [bridge contract](chat-compat.md). diff --git a/structure/providers/google.md b/structure/providers/google.md index 3da16fe08a3..a583a8a9289 100644 --- a/structure/providers/google.md +++ b/structure/providers/google.md @@ -73,6 +73,35 @@ configuration contradicts JSON-constrained text; and a `json_schema` format carr no schema, which would otherwise downgrade to bare JSON mode. An image-capable model with no structured-output request keeps its existing `responseModalities` behavior. +## Google tool-schema loss reporting + +`src/adapters/google-tool-schema.ts` compiles tool declarations against an explicit `ai-studio`, +`vertex`, or `cloud-code-assist` endpoint profile. All three profiles currently use the same +conservative documented subset. Compilation returns the compatible parameters plus a versioned +loss report with exactly six fields: `version`, `endpointClass`, `lossy`, `truncated`, +`uncertainComparisons`, and `categories`. Category values and the content-free uncertainty count +saturate at 255; saturation beyond either cap sets `truncated`. Bounded structural comparisons that +exhaust their 24-level or 1,024-node allowance increment `uncertainComparisons` rather than +`lossy` or a proven-loss category. The report never retains tool or property names, paths, descriptions, +schema or enum values, references, hashes, request ids, project ids, or account ids. +Every sanitizer branch that widens or drops an accepted-value constraint has a closed category, +including type unions and unsupported types, conditional and tuple constraints, reference-overlay +replacement, and root object coercion. Lossless normalization does not set `lossy`: accepted type +case folding, duplicate enum/required removal, nullable-union collapse, and string-const conversion +preserve the accepted value set. Annotation-only fields such as title, default, examples, comments, +deprecated, read-only/write-only, external documentation and examples are omitted without loss. +Local-reference siblings use 2020-12-style conjunctive semantics for loss accounting, while the +wire transform retains its implemented overlay-wins merge; enum reports compare that intersection +with the post-filter set actually emitted. + +This layer observes loss and does not reject it. The emitted request body remains the same as +before reporting. The existing limits remain 24 schema levels, 16 local-reference dereferences, +and 1,024 visited nodes; reporting stops with those limits and does not inspect omitted content. +`src/adapters/google-wire-compiler.ts` aggregates reports across declarations, and +`src/adapters/google.ts` emits a `google-tool-schema-loss` provider diagnostic only when provider +debug is enabled. `generationConfig.responseMimeType` and `generationConfig.responseJsonSchema` +are output-schema fields and never enter tool-schema sanitation or loss accounting. + ## Google wire-shape projection `src/adapters/google-wire-shape.ts` describes a compiled Google request without carrying any of diff --git a/structure/runtime.md b/structure/runtime.md index 3a8f5228077..acd30379cb0 100644 --- a/structure/runtime.md +++ b/structure/runtime.md @@ -411,6 +411,10 @@ Renamed fixed-key providers receive [missing reasoning metadata](catalog.md#rena Translated audio/file admission follows the [final-adapter input contract](adapters/registry.md#untranslated-input-media); native raw passthrough remains separate. ## Request-local target compatibility +Google's final adapter compiler may emit an opt-in, content-free +[tool-schema loss diagnostic](providers/google.md#google-tool-schema-loss-reporting). It observes +adapter-local narrowing only and changes neither provider routing nor the serialized request body. + `src/adapters/openai-responses.ts` omits only top-level `user` at the canonical ChatGPT Codex forward destination. Claude translation retains its original identity and prompt-cache key; public API and noncanonical gateways retain their `user` field. Input roles, tool-schema properties, safety identifiers and original replay bodies are not changed. `src/combos/failover.ts` treats three intact HTTP 400 invalid-request envelopes as request-local incompatibilities: exactly `Unsupported parameter: user`; `unsupported_value` naming `reasoning.effort` or `reasoning_effort` with an explicit unsupported-value message; and `param: input` with a bounded model-scoped `does not support image inputs` message. A null provider code is accepted only for that observed image envelope. Only the exact proxy wrapper is unwrapped, within three envelopes and 16,384 characters; conflicting codes, malformed/truncated envelopes and reflected JSON do not gain hop permission. diff --git a/structure/transports/byte-accounting.md b/structure/transports/byte-accounting.md index dc1fe383b01..60cfd444bd7 100644 --- a/structure/transports/byte-accounting.md +++ b/structure/transports/byte-accounting.md @@ -13,6 +13,10 @@ the translator budget, which is why so many documents link here rather than rest ## Request-copy accounting +The Google tool-schema loss report retains fixed categories, bounded counts, and endpoint class +only. It copies no request content and adds no bytes to the upstream wire; see the +[Google provider contract](../providers/google.md#google-tool-schema-loss-reporting). + `src/server/request-decompress.ts` observes the UTF-8 sizes of decoded text and reserialized JSON without allocating encoded byte arrays solely to count them. Parsed-body accounting still uses `JSON.stringify(parsed)`: numeric normalization can make it larger than the input text. These diff --git a/structure/transports/inventory.md b/structure/transports/inventory.md index b20317932dc..9dbe612b559 100644 --- a/structure/transports/inventory.md +++ b/structure/transports/inventory.md @@ -29,7 +29,7 @@ surface is listed here so a maintainer can find the owner without grepping: | Azure OpenAI Responses | `src/adapters/azure.ts` | Deployment-shaped URLs on top of the Responses contract. | | Responses custom-tool preview | `src/bridge/sse.ts`, `src/server/responses-custom-tool-repair.ts`, `src/responses/progressive-freeform-input.ts` | Direct adapter events and routed function restoration share one progressive wrapper decoder. Fence-shaped `exec`/`apply_patch` prefixes stay held until authoritative completion normalization, while each caller retains its own patch-envelope and byte-budget policy. | | Meta Muse Responses tool names | `src/responses/muse-tool-name-alias.ts`, `src/adapters/openai-responses.ts` | `api.meta.ai` only: function names over 64 characters or containing characters outside `[a-zA-Z0-9_-]` become collision-safe wire aliases and are restored before the client sees them. | -| Google / Vertex / Antigravity | `src/adapters/google.ts`, `src/adapters/google-http.ts`, `src/adapters/google-wire-compiler.ts`, `src/adapters/google-tool-schema.ts`, `src/adapters/google-truncation.ts`, `src/adapters/google-errors.ts`, `src/adapters/google-antigravity-wire.ts`, `src/adapters/google-antigravity-replay.ts`, `src/adapters/google-wire-shape.ts` | Vertex and Antigravity install a Google-family `fetchResponse` and so own their retry policy, while AI Studio Gemini leaves it undefined and uses the default server fetch path. The Google-family wrapper reuses the shared abort/deadline helpers (`src/lib/upstream-retry.ts`), wire-body repair, and upstream error normalization. `google-wire-shape.ts` sits outside that path entirely: it only reads the compiled body, and only when provider debug is on. | +| Google / Vertex / Antigravity | `src/adapters/google.ts`, `src/adapters/google-http.ts`, `src/adapters/google-wire-compiler.ts`, `src/adapters/google-tool-schema.ts`, `src/adapters/google-truncation.ts`, `src/adapters/google-errors.ts`, `src/adapters/google-antigravity-wire.ts`, `src/adapters/google-antigravity-replay.ts`, `src/adapters/google-wire-shape.ts` | Vertex and Antigravity install a Google-family `fetchResponse` and so own their retry policy, while AI Studio Gemini leaves it undefined and uses the default server fetch path. The Google-family wrapper reuses the shared abort/deadline helpers (`src/lib/upstream-retry.ts`), wire-body repair, and upstream error normalization. The final compiler also produces the [content-free tool-schema loss report](../providers/google.md#google-tool-schema-loss-reporting). `google-wire-shape.ts` sits outside that path entirely: it only reads the compiled body, and only when provider debug is on. | | Mimo Free | `src/adapters/mimo-free.ts` | Client identity and JWT handling are transport-local; the per-install client id lives in the opencodex state root. | | Anthropic image ingress | `src/adapters/anthropic-image-guard.ts`, `src/adapters/anthropic-image-normalize.ts`, `src/adapters/anthropic-image-codec.ts` | Oversized or unsupported images are normalized or rejected before reaching upstream. An image's ladder position is pinned to its own identity (content hash + media type) rather than recomputed from recency each request (#4532); appending a newer image therefore cannot demote and re-encode older images and bust Anthropic's prompt prefix cache. Unseen images still take the age-tier pyramid's first position, the total byte budget still binds, and a 413 `tierBias` retry still applies. Recorded positions only move down the ladder, so the store is monotonic. | | Adapter execution support | `src/adapters/run-turn-queue.ts`, `src/adapters/tool-catalog-nudge.ts`, `src/adapters/identity.ts`, `src/adapters/image.ts`, `src/adapters/upstream-http-error.ts` | Shared machinery: turn ordering, tool-catalog nudging, client fingerprinting, image conversion, upstream error normalization. | @@ -118,6 +118,10 @@ invalid-JSON message described above. ## Provider diagnostic outbound safety +Google tool-schema loss diagnostics follow the same outbound boundary. The compiler retains only +an endpoint class, closed category counts, and bounded flags; provider debug controls emission, +and the diagnostic adds no field or byte to the upstream request. + Provider connection tests and live model discovery share the GET-only provider outbound wrapper. Direct HTTP(S) resolves once and pins the validated address; HTTPS preserves the original Host/SNI and always verifies certificates. HTTP(S)-proxy requests stay on Bun fetch; configured SOCKS5 diff --git a/structure/transports/responses.md b/structure/transports/responses.md index 17b57dcdf5b..2066d636411 100644 --- a/structure/transports/responses.md +++ b/structure/transports/responses.md @@ -553,6 +553,11 @@ Arguments, user text, and schema property names are never rewritten. ### Declared-tool membership by inbound wire +Inbound declaration membership and schemas remain unchanged by Google's +[tool-schema loss report](../providers/google.md#google-tool-schema-loss-reporting). Only the final +Google wire compiler observes and reports compatibility narrowing; the Responses bridges neither +derive nor consume that report. + `declaredToolNames` carries the request's tool catalog into both bridges, and it does two separate jobs that are separately controlled. diff --git a/tests/adapters/google/google-tool-schema-contract.test.ts b/tests/adapters/google/google-tool-schema-contract.test.ts new file mode 100644 index 00000000000..8959b8d4b39 --- /dev/null +++ b/tests/adapters/google/google-tool-schema-contract.test.ts @@ -0,0 +1,752 @@ +import { afterEach, describe, expect, test } from "bun:test"; +import { createGoogleAdapter as createGoogleAdapterProduction } from "../../../src/adapters/google"; +import { + GOOGLE_TOOL_SCHEMA_LOSS_COUNT_LIMIT, + sanitizeGeminiToolParametersWithReport, + type GoogleToolSchemaEndpointClass, +} from "../../../src/adapters/google-tool-schema"; +import { compileGoogleWireBody } from "../../../src/adapters/google-wire-compiler"; +import { getDebugLogEntries, resetDebugLogBufferForTests } from "../../../src/lib/debug-log-buffer"; +import { resetDebugSettingsForTests, setDebugSettings } from "../../../src/lib/debug-settings"; +import type { OcxParsedRequest, OcxProviderConfig } from "../../../src/types"; +import { withTestTranslatorBudget } from "../../helpers/translator-budget"; + +const createGoogleAdapter = (...args: Parameters) => + withTestTranslatorBudget(createGoogleAdapterProduction(...args)); + +const ENDPOINTS: GoogleToolSchemaEndpointClass[] = ["ai-studio", "vertex", "cloud-code-assist"]; +const ENDPOINT_CASES: Array<{ + endpointClass: GoogleToolSchemaEndpointClass; + provider: OcxProviderConfig; +}> = [ + { + endpointClass: "ai-studio", + provider: { + adapter: "google", + baseUrl: "https://generativelanguage.googleapis.com", + apiKey: "test-key", + googleMode: "ai-studio", + } as OcxProviderConfig, + }, + { + endpointClass: "vertex", + provider: { + adapter: "google", + baseUrl: "https://aiplatform.googleapis.com", + apiKey: "test-key", + googleMode: "vertex", + } as OcxProviderConfig, + }, + { + endpointClass: "cloud-code-assist", + provider: { + adapter: "google", + baseUrl: "https://daily-cloudcode-pa.googleapis.com", + apiKey: "test-token", + googleMode: "cloud-code-assist", + project: "test-project", + } as OcxProviderConfig, + }, +]; + +function sanitize(parameters: unknown, endpointClass: GoogleToolSchemaEndpointClass = "ai-studio") { + return sanitizeGeminiToolParametersWithReport(parameters, { endpointClass }); +} + +function nestedObject(depth: number): Record { + let node: Record = { type: "string" }; + for (let index = 0; index < depth; index++) { + node = { type: "object", properties: { child: node } }; + } + return node; +} + +function dereferenceChain(length: number): Record { + const defs: Record = {}; + for (let index = length - 1; index >= 0; index--) { + defs[`Node${index}`] = index === length - 1 + ? { type: "string" } + : { $ref: `#/$defs/Node${index + 1}` }; + } + return { + type: "object", + properties: { value: { $ref: "#/$defs/Node0" } }, + $defs: defs, + }; +} + +function endpointRequestUncertain(): OcxParsedRequest { + const values = Array.from({ length: 1_100 }, (_, index) => `value-${index}`); + return { + modelId: "gemini-test-model", + stream: false, + options: {}, + context: { + messages: [{ role: "user", content: "use the tool", timestamp: 0 }], + tools: [{ + name: "ENDPOINT_TOOL_CANARY_5112", + description: "endpoint profile fixture", + parameters: { + type: "object", + properties: { + ENDPOINT_PROPERTY_CANARY_5112: { + $ref: "#/$defs/Value", + enum: [...values.slice(0, -1), "value-late-difference"], + }, + }, + $defs: { Value: { type: "string", enum: [...values] } }, + }, + }], + }, + } as unknown as OcxParsedRequest; +} + +function endpointRequest(lossy: boolean): OcxParsedRequest { + return { + modelId: "gemini-test-model", + stream: false, + options: { + textFormat: { + type: "json_schema", + schema: { + type: "object", + properties: { OUTPUT_SCHEMA_CANARY_5112: { type: "integer", minimum: 1 } }, + }, + }, + }, + context: { + messages: [{ role: "user", content: "use the tool", timestamp: 0 }], + tools: [{ + name: "ENDPOINT_TOOL_CANARY_5112", + description: "endpoint profile fixture", + parameters: { + type: "object", + properties: { + ENDPOINT_PROPERTY_CANARY_5112: { + type: "string", + enum: lossy ? ["ENDPOINT_VALUE_CANARY_5112", 7] : ["ENDPOINT_VALUE_CANARY_5112"], + }, + }, + }, + }], + }, + } as OcxParsedRequest; +} + +function stableWireBody(body: string, endpointClass: GoogleToolSchemaEndpointClass): string { + const parsed = JSON.parse(body) as Record; + if (endpointClass === "cloud-code-assist") parsed.requestId = ""; + return JSON.stringify(parsed); +} + +function compiledRequest(body: string, endpointClass: GoogleToolSchemaEndpointClass): Record { + const parsed = JSON.parse(body) as Record; + return endpointClass === "cloud-code-assist" + ? parsed.request as Record + : parsed; +} + +afterEach(() => { + resetDebugSettingsForTests(); + resetDebugLogBufferForTests(); +}); + +describe("Google tool-schema loss report", () => { + test("uses an explicit endpoint profile without changing compatible wire bytes", () => { + const input = { + tools: [{ functionDeclarations: [{ + name: "calculate", + parameters: { + type: "object", + properties: { amount: { type: "integer", enum: [1, 2, "other"] } }, + }, + }] }], + }; + const compiled = ENDPOINTS.map(endpointClass => compileGoogleWireBody(input, { endpointClass })); + const bytes = compiled.map(result => JSON.stringify(result.body)); + expect(new Set(bytes).size).toBe(1); + expect(compiled.map(result => result.toolSchemaLossReport)).toEqual(ENDPOINTS.map(endpointClass => ({ + version: 1, + endpointClass, + lossy: true, + truncated: false, + uncertainComparisons: 0, + categories: { "enum-value-filtered": 2 }, + }))); + }); + + test("reports filtered enum members and dropped numeric and size bounds", () => { + const result = sanitize({ + type: "object", + properties: { + amount: { type: "number", enum: [1, "fixed", 2], minimum: 0, exclusiveMaximum: 10 }, + label: { type: "string", minLength: 1, maxLength: 20 }, + list: { type: "array", minItems: 1, maxItems: 3, items: { type: "string" } }, + }, + }); + expect(result.parameters).toEqual({ + type: "object", + properties: { + amount: { type: "number", enum: ["fixed"] }, + label: { type: "string" }, + list: { type: "array", items: { type: "string" } }, + }, + }); + expect(result.lossReport.categories).toEqual({ + "numeric-bound-dropped": 2, + "enum-value-filtered": 2, + "size-bound-dropped": 4, + }); + }); + + test("reports a mixed union only when it widens the node", () => { + const result = sanitize({ + type: "object", + properties: { value: { anyOf: [{ type: "string" }, { type: "number" }] } }, + }); + expect(result.parameters).toEqual({ + type: "object", + properties: { value: {} }, + }); + expect(result.lossReport.categories).toEqual({ "union-widened": 1 }); + }); + + test("reports when nullable anyOf resolution replaces an explicit sibling type", () => { + const result = sanitize({ + type: "object", + properties: { + value: { type: "number", anyOf: [{ type: "string" }, { type: "null" }] }, + }, + }); + expect(result.parameters).toEqual({ + type: "object", + properties: { value: { type: "string", nullable: true } }, + }); + expect(result.lossReport.categories).toEqual({ "union-sibling-replaced": 1 }); + }); + + test("classifies type unions and unsupported type values", () => { + const result = sanitize({ + type: "object", + properties: { + union: { type: ["string", "number"] }, + unknown: { type: "future-type" }, + empty: { type: [] }, + nullConflict: { type: ["string", "null"], nullable: false }, + }, + }); + expect(result.parameters).toEqual({ + type: "object", + properties: { + union: { type: "string" }, + unknown: {}, + empty: {}, + nullConflict: { type: "string", nullable: false }, + }, + }); + expect(result.lossReport.categories).toEqual({ + "type-union-collapsed": 1, + "unsupported-type-widened": 2, + "nullability-overridden": 1, + }); + }); + + test("classifies conditionals, tuple prefixes, and closed-list semantic constraints", () => { + const result = sanitize({ + type: "object", + properties: { + conditional: { + type: "string", + if: { const: "a" }, + then: { minLength: 2 }, + else: { maxLength: 4 }, + }, + tuple: { type: "array", prefixItems: [{ type: "string" }] }, + patterned: { type: "string", pattern: "^[a-z]+$" }, + }, + }); + expect(result.lossReport.categories).toEqual({ + "conditional-dropped": 3, + "tuple-prefix-dropped": 1, + "unsupported-constraint-dropped": 1, + }); + }); + + test("does not classify inert annotations or lossless normalization as loss", () => { + const result = sanitize({ + type: "object", + title: "annotation", + default: {}, + examples: [{}], + $comment: "annotation", + contentEncoding: "base64", + contentMediaType: "application/json", + readOnly: true, + properties: { + normalized: { type: "STRING", const: "fixed", enum: ["fixed", "fixed"] }, + constOnly: { type: "string", const: "fixed" }, + nullable: { anyOf: [{ type: "string" }, { type: "null" }] }, + }, + required: ["normalized", "normalized"], + }); + expect(result.lossReport).toEqual({ + version: 1, + endpointClass: "ai-studio", + lossy: false, + truncated: false, + uncertainComparisons: 0, + categories: {}, + }); + }); + + test("classifies root object coercion and malformed supported constraints", () => { + const root = sanitize({ type: "string" }); + expect(root.parameters).toEqual({ type: "object", properties: {} }); + expect(root.lossReport.categories).toEqual({ "root-object-coerced": 1 }); + + const malformed = sanitize({ + type: "object", + properties: { + value: { type: "string", enum: [], format: 7 }, + }, + required: "value", + }); + expect(malformed.lossReport.categories).toEqual({ + "invalid-schema-widened": 2, + "enum-constraint-dropped": 1, + }); + }); + + test("reports recursive-reference widening without losing an ordinary sibling", () => { + const result = sanitize({ + type: "object", + properties: { tree: { $ref: "#/$defs/Tree" } }, + $defs: { + Tree: { + type: "object", + properties: { + left: { $ref: "#/$defs/Tree" }, + label: { type: "string" }, + }, + }, + }, + }); + const tree = (result.parameters.properties as Record>).tree; + expect(tree).toEqual({ type: "object", properties: { left: {}, label: { type: "string" } } }); + expect(result.lossReport.categories).toEqual({ "recursive-ref-widened": 1 }); + }); + + test("counts a numeric const inside a local reference exactly once", () => { + const result = sanitize({ + type: "object", + properties: { value: { $ref: "#/$defs/NumericConst" } }, + $defs: { NumericConst: { type: "integer", const: 7 } }, + }); + expect(result.parameters).toEqual({ + type: "object", + properties: { value: { type: "integer" } }, + }); + expect(result.lossReport.categories).toEqual({ "const-value-filtered": 1 }); + }); + + test("reports when a reference sibling replaces a target constraint", () => { + const result = sanitize({ + type: "object", + properties: { value: { $ref: "#/$defs/Value", type: "number" } }, + $defs: { Value: { type: "string" } }, + }); + expect(result.parameters).toEqual({ + type: "object", + properties: { value: { type: "number" } }, + }); + expect(result.lossReport.categories).toEqual({ "ref-overlay-replaced": 1 }); + }); + + test("separately allocated equal ref overlays are not classified as loss", () => { + const result = sanitize({ + type: "object", + properties: { + enumValue: { $ref: "#/$defs/EnumValue", enum: ["b", "a", "a"] }, + typeValue: { $ref: "#/$defs/TypeValue", type: "STRING" }, + objectValue: { + $ref: "#/$defs/ObjectValue", + properties: { name: { type: "string" } }, + }, + requiredValue: { $ref: "#/$defs/RequiredValue", required: ["other", "name", "name"] }, + }, + $defs: { + EnumValue: { type: "string", enum: ["a", "b"] }, + TypeValue: { type: "string" }, + ObjectValue: { type: "object", properties: { name: { type: "string" } } }, + RequiredValue: { + type: "object", + properties: { name: { type: "string" }, other: { type: "string" } }, + required: ["name", "other"], + }, + }, + }); + expect(result.lossReport).toEqual({ + version: 1, + endpointClass: "ai-studio", + lossy: false, + truncated: false, + uncertainComparisons: 0, + categories: {}, + }); + }); + + test.each([ + { + name: "target filtering excluded by overlay", + target: ["a", 1], + overlay: ["a"], + expectedEnum: ["a"], + expectedCategories: {}, + }, + { + name: "same filtered value in both schemas", + target: ["a", 1], + overlay: ["a", 1], + expectedEnum: ["a"], + expectedCategories: { "enum-value-filtered": 1 }, + }, + { + name: "overlay-only filtered value", + target: ["a"], + overlay: ["a", 1], + expectedEnum: ["a"], + expectedCategories: {}, + }, + { + name: "overlay widens beyond target", + target: ["a"], + overlay: ["a", "b"], + expectedEnum: ["a", "b"], + expectedCategories: { "ref-overlay-replaced": 1 }, + }, + ] as const)("enum ref overlay uses effective intersection: $name", ({ target, overlay, expectedEnum, expectedCategories }) => { + const result = sanitize({ + type: "object", + properties: { value: { $ref: "#/$defs/Value", enum: [...overlay] } }, + $defs: { Value: { enum: [...target] } }, + }); + const value = (result.parameters.properties as Record>).value; + expect(value.enum).toEqual(expectedEnum); + expect(result.lossReport.categories).toEqual(expectedCategories); + expect(result.lossReport.uncertainComparisons).toBe(0); + }); + + test("a referenced enum without an overlay keeps its existing filtered-loss report", () => { + const result = sanitize({ + type: "object", + properties: { value: { $ref: "#/$defs/Value" } }, + $defs: { Value: { enum: ["a", 1] } }, + }); + const value = (result.parameters.properties as Record>).value; + expect(value.enum).toEqual(["a"]); + expect(result.lossReport.categories).toEqual({ "enum-value-filtered": 1 }); + expect(result.lossReport.uncertainComparisons).toBe(0); + }); + + test.each([ + [ + "enum", + { type: "string", enum: ["a"] }, + { enum: ["b"] }, + ], + [ + "properties", + { type: "object", properties: { name: { type: "string" } } }, + { properties: { name: { type: "number" } } }, + ], + [ + "required", + { + type: "object", + properties: { name: { type: "string" }, other: { type: "string" } }, + required: ["name"], + }, + { required: ["other"] }, + ], + ] as const)("a genuinely different %s ref overlay reports exactly one loss", (_name, target, overlay) => { + const result = sanitize({ + type: "object", + properties: { value: { $ref: "#/$defs/Value", ...overlay } }, + $defs: { Value: target }, + }); + expect(result.lossReport.categories).toEqual({ "ref-overlay-replaced": 1 }); + }); + + test("comparison budget exhaustion is unknown and is not counted as proven loss", () => { + // The overlay differs only AFTER the bounded comparison budget: identical prefixes exhaust + // the cap, so the late difference is indeterminate rather than proven loss. + const values = Array.from({ length: 1_100 }, (_, index) => `value-${index}`); + const overlayValues = [...values.slice(0, -1), "value-late-difference"]; + const result = sanitize({ + type: "object", + properties: { value: { $ref: "#/$defs/Value", enum: [...overlayValues] } }, + $defs: { Value: { type: "string", enum: [...values] } }, + }); + expect(result.lossReport).toEqual({ + version: 1, + endpointClass: "ai-studio", + lossy: false, + truncated: false, + uncertainComparisons: 1, + categories: {}, + }); + // Compatible mode keeps the overlay bytes, which genuinely differ from the target. + // The stacked strict child must refuse uncertainty. + const value = (result.parameters.properties as Record>).value; + expect(value.enum).toEqual(overlayValues); + expect(value.enum).not.toEqual(values); + const compiled = compileGoogleWireBody({ + tools: [{ functionDeclarations: [{ + name: "uncertain_comparison", + parameters: { + type: "object", + properties: { value: { $ref: "#/$defs/Value", enum: [...overlayValues] } }, + $defs: { Value: { type: "string", enum: [...values] } }, + }, + }] }], + }, { endpointClass: "ai-studio" }); + expect(compiled.toolSchemaLossReport.uncertainComparisons).toBe(1); + expect(compiled.toolSchemaLossReport.lossy).toBe(false); + const declaration = (compiled.body.tools as Array<{ + functionDeclarations: Array<{ parameters: Record }>; + }>)[0]!.functionDeclarations[0]!; + expect(declaration.parameters).toEqual(result.parameters); + }); + + test("default-equivalent constraints are neutral", () => { + const result = sanitize({ + type: "object", + additionalProperties: true, + minProperties: 0, + properties: { + text: { type: "string", minLength: 0 }, + list: { type: "array", minItems: 0, uniqueItems: false, prefixItems: [] }, + }, + }); + expect(result.lossReport).toEqual({ + version: 1, + endpointClass: "ai-studio", + lossy: false, + truncated: false, + uncertainComparisons: 0, + categories: {}, + }); + }); + + test("reports depth and dereference ceilings at their existing boundaries", () => { + const depth = sanitize(nestedObject(25)); + expect(depth.lossReport.categories).toEqual({ "depth-limit-widened": 1 }); + + const dereference = sanitize(dereferenceChain(18)); + expect(dereference.lossReport.categories).toEqual({ "dereference-limit-widened": 1 }); + }); + + test("reports node-budget widening without reading the first omitted property", () => { + const properties = Object.fromEntries(Array.from( + { length: 1_024 }, + (_, index) => [`field_${index}`, { type: "string" }], + )); + let readPastBudget = false; + Object.defineProperty(properties, "field_1023", { + enumerable: true, + configurable: true, + get() { + readPastBudget = true; + throw new Error("read past node budget"); + }, + }); + const result = sanitize({ type: "object", properties }); + expect(readPastBudget).toBe(false); + expect(Object.keys(result.parameters.properties as object)).toHaveLength(1_023); + expect(result.lossReport.categories).toEqual({ "node-budget-widened": 1 }); + }); + + test("saturates aggregate category counts across declarations", () => { + const declarations = Array.from({ length: GOOGLE_TOOL_SCHEMA_LOSS_COUNT_LIMIT + 2 }, (_, index) => ({ + name: `tool_${index}`, + parameters: { type: "object", pattern: `value-${index}` }, + })); + const compiled = compileGoogleWireBody( + { tools: [{ functionDeclarations: declarations }] }, + { endpointClass: "vertex" }, + ); + expect(compiled.toolSchemaLossReport).toEqual({ + version: 1, + endpointClass: "vertex", + lossy: true, + truncated: true, + uncertainComparisons: 0, + categories: { "unsupported-constraint-dropped": GOOGLE_TOOL_SCHEMA_LOSS_COUNT_LIMIT }, + }); + }); + + test("preserves the current body and never treats native output schemas as tool input", () => { + const outputCanary = "OUTPUT_SCHEMA_CANARY_5112"; + const compiled = compileGoogleWireBody({ + tools: [{ functionDeclarations: [{ + name: "lookup", + parameters: { type: "object", properties: { count: { type: "integer", enum: [1, 2] } } }, + }] }], + generationConfig: { + responseMimeType: "application/json", + responseJsonSchema: { + type: "object", + properties: { [outputCanary]: { type: "integer", minimum: 1 } }, + }, + }, + }, { endpointClass: "ai-studio" }); + expect(JSON.stringify(compiled.body)).toBe(JSON.stringify({ + tools: [{ functionDeclarations: [{ + name: "lookup", + parameters: { type: "object", properties: { count: { type: "integer" } } }, + }] }], + generationConfig: { + responseMimeType: "application/json", + responseJsonSchema: { + type: "object", + properties: { [outputCanary]: { type: "integer", minimum: 1 } }, + }, + }, + })); + expect(compiled.toolSchemaLossReport.categories).toEqual({ "enum-value-filtered": 2 }); + }); + + test("retains no tool, property, description, enum, reference, or constraint value", () => { + const canaries = { + tool: "TOOL_CANARY_5112", + property: "PROPERTY_CANARY_5112", + description: "DESCRIPTION_CANARY_5112", + enumValue: "ENUM_CANARY_5112", + reference: "REFERENCE_CANARY_5112", + constraint: "CONSTRAINT_CANARY_5112", + }; + const compiled = compileGoogleWireBody({ + tools: [{ functionDeclarations: [{ + name: canaries.tool, + description: canaries.description, + parameters: { + type: "object", + properties: { + [canaries.property]: { + type: "string", + description: canaries.description, + enum: [canaries.enumValue, 7], + pattern: canaries.constraint, + }, + recursive: { $ref: `#/$defs/${canaries.reference}` }, + }, + $defs: { + [canaries.reference]: { + type: "object", + properties: { next: { $ref: `#/$defs/${canaries.reference}` } }, + }, + }, + }, + }] }], + }, { endpointClass: "cloud-code-assist" }); + const report = JSON.stringify(compiled.toolSchemaLossReport); + for (const canary of Object.values(canaries)) expect(report).not.toContain(canary); + expect(compiled.toolSchemaLossReport).toEqual({ + version: 1, + endpointClass: "cloud-code-assist", + lossy: true, + truncated: false, + uncertainComparisons: 0, + categories: { + "unsupported-constraint-dropped": 1, + "enum-value-filtered": 1, + "recursive-ref-widened": 1, + }, + }); + }); + + test.each(ENDPOINT_CASES)("derives and consumes the $endpointClass profile at the adapter boundary", async ({ endpointClass, provider }) => { + const adapter = createGoogleAdapter(provider); + const realError = console.error; + console.error = () => {}; + try { + setDebugSettings({ debug: true }); + resetDebugLogBufferForTests(); + await adapter.buildRequest(endpointRequest(false)); + expect(getDebugLogEntries().some(entry => entry.line.includes("google-tool-schema-loss"))).toBe(false); + + resetDebugLogBufferForTests(); + setDebugSettings({ debug: false }); + const off = await adapter.buildRequest(endpointRequest(true)); + expect(getDebugLogEntries().some(entry => entry.line.includes("google-tool-schema-loss"))).toBe(false); + + setDebugSettings({ debug: true }); + const on = await adapter.buildRequest(endpointRequest(true)); + const lines = getDebugLogEntries().map(entry => entry.line) + .filter(entry => entry.includes("google-tool-schema-loss")); + expect(lines).toHaveLength(1); + const line = lines[0]!; + expect(stableWireBody(on.body, endpointClass)).toBe(stableWireBody(off.body, endpointClass)); + expect(on.url).toBe(off.url); + expect(on.headers).toEqual(off.headers); + for (const canary of [ + "ENDPOINT_TOOL_CANARY_5112", + "ENDPOINT_PROPERTY_CANARY_5112", + "ENDPOINT_VALUE_CANARY_5112", + "OUTPUT_SCHEMA_CANARY_5112", + ]) { + expect(getDebugLogEntries().map(entry => entry.line).join("\n")).not.toContain(canary); + } + expect(line).toContain(`"endpointClass":"${endpointClass}"`); + expect(line).toContain('"enum-value-filtered":1'); + + const request = compiledRequest(on.body, endpointClass); + const declarations = (request.tools as Array<{ functionDeclarations: Array> }>)[0]! + .functionDeclarations; + expect(declarations[0]!.parameters).toEqual({ + type: "object", + properties: { + ENDPOINT_PROPERTY_CANARY_5112: { + type: "string", + enum: ["ENDPOINT_VALUE_CANARY_5112"], + }, + }, + }); + const generationConfig = request.generationConfig as Record; + expect(generationConfig.responseMimeType).toBe("application/json"); + expect(generationConfig.responseJsonSchema).toEqual({ + type: "object", + properties: { OUTPUT_SCHEMA_CANARY_5112: { type: "integer", minimum: 1 } }, + }); + } finally { + console.error = realError; + } + }); + + test.each(ENDPOINT_CASES)("report-only mode emits one content-free $endpointClass diagnostic for an indeterminate comparison", async ({ endpointClass, provider }) => { + const adapter = createGoogleAdapter(provider); + const realError = console.error; + console.error = () => {}; + try { + setDebugSettings({ debug: true }); + resetDebugLogBufferForTests(); + const built = await adapter.buildRequest(endpointRequestUncertain()); + const lines = getDebugLogEntries().map((entry) => entry.line) + .filter((entry) => entry.includes("google-tool-schema-loss")); + expect(lines).toHaveLength(1); + expect(lines[0]!).toContain(`"uncertainComparisons":1`); + expect(lines[0]!).toContain(`"lossy":false`); + expect(lines[0]!).toContain(`"endpointClass":"` + `${endpointClass}` + `"`); + expect(built.body).toBeDefined(); + for (const canary of [ + "ENDPOINT_TOOL_CANARY_5112", + "ENDPOINT_PROPERTY_CANARY_5112", + "value-late-difference", + ]) { + expect(getDebugLogEntries().map((entry) => entry.line).join("\n")).not.toContain(canary); + } + } finally { + console.error = realError; + } + }); +}); diff --git a/tests/fixtures/test-layout-expected.json b/tests/fixtures/test-layout-expected.json index 71096d8e8fb..1de550d1e05 100644 --- a/tests/fixtures/test-layout-expected.json +++ b/tests/fixtures/test-layout-expected.json @@ -602,6 +602,7 @@ "google-provider-metadata-roundtrip.test.ts": "adapters/google", "google-signature-history-roundtrip.test.ts": "adapters/google", "google-tool-result-adjacency.test.ts": "adapters/google", + "google-tool-schema-contract.test.ts": "adapters/google", "google-tool-schema.test.ts": "adapters/google", "google-vertex-http.test.ts": "adapters/google", "google-vertex-stream.test.ts": "adapters/google", From 57b1df792ef7e66e17b0110727eefdd5387e164d Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 23:13:29 +0900 Subject: [PATCH 46/97] docs: record contract gap analysis and delivery evidence (#5175) * docs: checkpoint contract gap analysis and delivery evidence * docs: refresh ownership and scope regression requirements --- .../260919_contract_gap_analysis/000_plan.md | 50 +++++++ .../001_source_research.md | 45 ++++++ .../002_candidate_dispositions.md | 52 +++++++ .../003_consensus.md | 46 +++++++ .../004_source_fingerprints.md | 20 +++ .../005_existing_issue_followups.md | 31 +++++ .../010_issue_implementation_paths.md | 22 +++ .../011_delivery.md | 45 ++++++ .../020_issue_t1.md | 66 +++++++++ .../021_issue_t2.md | 66 +++++++++ .../022_issue_t3.md | 67 +++++++++ .../023_issue_g1.md | 56 ++++++++ .../024_issue_s1.md | 68 ++++++++++ .../025_issue_p1.md | 54 ++++++++ .../026_issue_p2.md | 53 ++++++++ .../027_issue_v1.md | 54 ++++++++ .../028_issue_o1.md | 55 ++++++++ .../029_issue_o2.md | 54 ++++++++ .../030_issue_d1.md | 34 +++++ .../031_issue_d2.md | 32 +++++ .../032_issue_d3.md | 32 +++++ .../033_issue_r1.md | 55 ++++++++ .../034_issue_r2.md | 56 ++++++++ .../035_issue_r3.md | 69 ++++++++++ .../260919_contract_resolution/000_plan.md | 51 +++++++ .../260919_contract_resolution/001_status.md | 128 ++++++++++++++++++ .../010_dispatch.md | 12 ++ .../020_integration.md | 76 +++++++++++ .../260919_contract_resolution/021_pr_5125.md | 39 ++++++ .../260919_contract_resolution/022_pr_5126.md | 52 +++++++ .../260919_contract_resolution/023_pr_5127.md | 25 ++++ .../260919_contract_resolution/024_pr_5129.md | 23 ++++ .../260919_contract_resolution/025_pr_5130.md | 15 ++ .../260919_contract_resolution/026_pr_5134.md | 15 ++ .../260919_contract_resolution/027_pr_5138.md | 13 ++ .../260919_contract_resolution/028_pr_5152.md | 31 +++++ .../260919_contract_resolution/029_pr_5153.md | 14 ++ .../260919_contract_resolution/030_pr_5155.md | 17 +++ .../260919_contract_resolution/031_pr_5157.md | 11 ++ .../032_ci_sideband.md | 29 ++++ .../033_schema_report_review.md | 33 +++++ .../034_strict_schema_policy.md | 25 ++++ .../035_static_policy_resolver.md | 23 ++++ .../036_send_assertion_followup.md | 11 ++ .../037_acceptance_ledger.md | 26 ++++ 45 files changed, 1851 insertions(+) create mode 100644 devlog/_fin/260919_contract_gap_analysis/000_plan.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/001_source_research.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/002_candidate_dispositions.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/003_consensus.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/004_source_fingerprints.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/005_existing_issue_followups.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/010_issue_implementation_paths.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/011_delivery.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/020_issue_t1.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/021_issue_t2.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/022_issue_t3.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/023_issue_g1.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/024_issue_s1.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/025_issue_p1.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/026_issue_p2.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/027_issue_v1.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/028_issue_o1.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/029_issue_o2.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/030_issue_d1.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/031_issue_d2.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/032_issue_d3.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/033_issue_r1.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/034_issue_r2.md create mode 100644 devlog/_fin/260919_contract_gap_analysis/035_issue_r3.md create mode 100644 devlog/_plan/260919_contract_resolution/000_plan.md create mode 100644 devlog/_plan/260919_contract_resolution/001_status.md create mode 100644 devlog/_plan/260919_contract_resolution/010_dispatch.md create mode 100644 devlog/_plan/260919_contract_resolution/020_integration.md create mode 100644 devlog/_plan/260919_contract_resolution/021_pr_5125.md create mode 100644 devlog/_plan/260919_contract_resolution/022_pr_5126.md create mode 100644 devlog/_plan/260919_contract_resolution/023_pr_5127.md create mode 100644 devlog/_plan/260919_contract_resolution/024_pr_5129.md create mode 100644 devlog/_plan/260919_contract_resolution/025_pr_5130.md create mode 100644 devlog/_plan/260919_contract_resolution/026_pr_5134.md create mode 100644 devlog/_plan/260919_contract_resolution/027_pr_5138.md create mode 100644 devlog/_plan/260919_contract_resolution/028_pr_5152.md create mode 100644 devlog/_plan/260919_contract_resolution/029_pr_5153.md create mode 100644 devlog/_plan/260919_contract_resolution/030_pr_5155.md create mode 100644 devlog/_plan/260919_contract_resolution/031_pr_5157.md create mode 100644 devlog/_plan/260919_contract_resolution/032_ci_sideband.md create mode 100644 devlog/_plan/260919_contract_resolution/033_schema_report_review.md create mode 100644 devlog/_plan/260919_contract_resolution/034_strict_schema_policy.md create mode 100644 devlog/_plan/260919_contract_resolution/035_static_policy_resolver.md create mode 100644 devlog/_plan/260919_contract_resolution/036_send_assertion_followup.md create mode 100644 devlog/_plan/260919_contract_resolution/037_acceptance_ledger.md diff --git a/devlog/_fin/260919_contract_gap_analysis/000_plan.md b/devlog/_fin/260919_contract_gap_analysis/000_plan.md new file mode 100644 index 00000000000..39395a61d27 --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/000_plan.md @@ -0,0 +1,50 @@ +# OpenCodex contract gap analysis and issue delivery + +Sixteen source-grounded issues and two existing-issue implementation comments were delivered after unanimous independent review. The refreshed tree already contained several fixes from the supplied report; the remaining proposals preserve existing routing, tool, state and documentation authorities. See [verified delivery](011_delivery.md), [dispositions](002_candidate_dispositions.md) and [implementation plans](010_issue_implementation_paths.md). + +## Scope and loop specification + +- Class: C3 research and documentation. +- Archetype: satisfy-spec, one analysis/publication cycle. +- Trigger: user-requested source-grounded analysis of one supplied report and two shared conversations, followed by unanimous review and issue publication. +- Goal: a complete disposition ledger, implementation plans and verified tracking issues appropriate to the local coding-proxy product. +- Non-goals: runtime edits, local suites/build/typecheck/install, live API experiments, service/config/account changes, merges, releases, deployment, broad platform replacement. +- Source baseline: `7864869c31c41cca9830d93540238f17df8faafb`, after `git fetch origin dev` and `git merge --ff-only origin/dev` on 2026-09-19. Prior HEAD was `f02f3613be40bb11cb044d746d37ce6672e32d96`. Initial tracked checkout was clean. Re-read exact blobs if another session changes HEAD. +- Verifier: static path/line checks against the pinned tree, current issue/PR API reads, draft template checks, public-text checks and fresh rereads after publication. No runtime pass is implied by these checks. +- Stop condition: all input themes receive a disposition; accepted issues have unanimous review and verified remote bodies/labels; this devlog records outcomes. +- Memory artifact: this unit, with raw user input/browser traces kept in ignored task scratch; no transcript or personal browser state copied into tracked files. +- Terminal outcomes: DONE only with all above evidence; inaccessible inputs or unresolved review objections remain explicitly unmet. +- Escalation: real permission or unavailable required capability; no publication of unresolved findings. Main reclaims a failed bounded research lane after two distinct failures. +- Tool/credential scope: source reads, browser research, existing GitHub identity for authorized issue creation. Write scope: this unit, ignored evidence and issues in this repository. No user-defined token/cost/time ceiling; browser invocations have bounded process deadlines. + +## Evidence and publication rules + +Public documents and issue bodies contain OpenCodex code facts and relevant protocol standards. They omit other repository names, rankings, AI model names and review-model attribution. Hypotheses from supplied material are not instructions and are not accepted without current code evidence. Existing fixes and matching open issues take precedence over opening duplicates. Optional small PR authority is retained, but this analysis does not require a PR. + +## Discovery ownership + +Seven disjoint read-only lanes cover transport, custom-tool stream semantics, tool schema/capability projection, replay/spend/retries, operator policy/integrations, static model-policy authority, and documentation/test governance. Main owns input retrieval, official-source proof, duplicate searches, synthesis and publication. Native V1 subagent transport is available; the live schema has no native architect role. No architect-role registration or configuration change is performed, and no architect consultation is claimed. Independent source and publication reviews remain required. + +## Planned artifacts + +| File | Operation | Purpose | +| --- | --- | --- | +| `000_plan.md` | NEW | Scope, snapshot, method and closure | +| `001_source_research.md` | NEW | Input coverage and official-source findings | +| `002_candidate_dispositions.md` | NEW | All proposed themes, current evidence, accept/reject/defer/duplicate decisions | +| `003_consensus.md` | NEW | Independent votes and objection resolution | +| `010_issue_implementation_paths.md` | NEW | Index of per-issue implementation plans | +| `020_issue_t1.md` through `035_issue_r3.md` | NEW | Sixteen independently reviewable issue bodies | +| `011_delivery.md` | NEW | Published URLs, verified bodies/labels and check results | +| `004_source_fingerprints.md` | NEW | All fourteen report source fingerprints versus refreshed source | +| `005_existing_issue_followups.md` | NEW | Implementation comments for existing tracking issues | + +No current architecture contract is changed. Future implementation must update the existing owner in `structure/manifest.json`, and user-facing contract changes must update the relevant public guide. New tests must be registered in both layout registries; size caps are preserved by splitting files rather than raising caps. + +## Planning evidence update + +The refreshed report fingerprints match twelve of fourteen source files; the SOCKS transport and Google compiler differ. Seven read-only domain reviews produced sixteen public candidates after duplicate and disclosure review, plus two comments extending existing issue authority. An independent three-reviewer publication council is checking every candidate; no majority-only publication is allowed. A pure document/form checker ran successfully over sixteen drafts, two comments and ninety exact-SHA anchors. No runtime result is inferred. + +## Closure + +Analysis and publication are complete. All sixteen issue bodies and two comments were reread from GitHub and match approved content. The next action belongs to each open implementation issue; this unit claims no runtime fix. The useful change in direction was rejecting broad missing-feature claims in favor of concrete residuals. A future patch or counterexample at the cited owner can supersede a candidate; the exact source snapshot makes that reassessment possible. diff --git a/devlog/_fin/260919_contract_gap_analysis/001_source_research.md b/devlog/_fin/260919_contract_gap_analysis/001_source_research.md new file mode 100644 index 00000000000..a963ceae87f --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/001_source_research.md @@ -0,0 +1,45 @@ +# Source coverage and evidence limits + +## Inputs + +The supplied 23-page report was extracted in full. Its findings are treated as hypotheses because its source acquisition did not establish a repository commit and its small mechanism examples did not execute the complete proxy. The two supplied shared conversations were opened with the authenticated browser on 2026-09-19. A welcome dialog was dismissed; no sign-in or account change was required. Browser traces and original text stay in ignored scratch because they contain material outside the requested publication scope. + +The report contributes twelve themes: content decoding, custom-input stream consistency, isolated conformance fixtures, schema-loss policy, detailed capability projection, physical-send admission, terminal diagnostics, replay ownership, spend writer topology, key policy, observability export, and client configuration reconciliation. + +The first conversation adds: static model-policy authority versus dynamic evidence; registry-derived metadata; explicit precedence; source-of-truth document ownership; behavioral versus structural verification; centralized hardened utilities; canonical history versus projections; executor/translator boundaries; and embedding. The second conversation summarizes the supplied report and its limitations; it adds no independent source execution evidence. + +## Fixed source snapshot + +`git fetch --no-recurse-submodules origin dev` followed by `git merge --ff-only origin/dev` advanced the initially clean `dev` checkout from `f02f3613be40bb11cb044d746d37ce6672e32d96` to `7864869c31c41cca9830d93540238f17df8faafb`. All line anchors in this unit refer to that final SHA unless explicitly stated otherwise. No live service restart or source test invocation was performed. + +## Existing work discovered before publication + +- #5070 is merged. Its source and regressions cover SOCKS gzip/deflate decoding, unsupported-coding refusal and bodyless responses, plus multiple freeform preview/completion mismatches. The report's broad decoding and fence claims require narrowing or rejection. +- #5047 is closed and already covers fallback-wrapper streaming disagreement. +- #5056 is merged and adds withheld-recovery attribution; a generic claim that budget refusals have no diagnostics is stale. +- #5032 is merged and makes the durable token ceiling configurable and refusal visible. +- #2358 remains an open umbrella for compatibility evidence and isolated core work. New proposals must be bounded follow-ups with specific missing behavior, not another umbrella. +- #3377 remains open for model capability declarations. Its exact axes must be distinguished from any new resolved-policy consumer consistency proposal. + +Issue/PR state was read from GitHub, not inferred from old notes. A second targeted search will precede final publication. + +## Research method + +A read-only research pass was also dispatched for a read-only official-standard ledger covering Fetch/HTTP content codings, custom-tool grammar and argument streaming, function declaration schema subsets, and telemetry conventions. Standards establish contract vocabulary and constraints; only the pinned OpenCodex source establishes present behavior. No performance ranking, competitor behavior, model-quality claim, live API success rate or runtime test result is inferred. + +## Official-source findings verified with the authenticated browser + +Sources below were opened on 2026-09-19. These are contract constraints and design inferences, not proof of a proxy runtime test. + +| Source | Supported finding | Limitation for this unit | +| --- | --- | --- | +| [Fetch Standard](https://fetch.spec.whatwg.org/), HTTP-network fetch and Response constructor | Network fetch processes content codings before exposing body bytes; constructing a Response around raw bytes is not network decoding. Null-body statuses constrain the constructor. | Does not prescribe a provider retry or tool replay owner. | +| [HTTP Semantics](https://www.rfc-editor.org/rfc/rfc9110.html), sections 6.4, 8.4, 9.3.2 and 15.3.6 | Content coding is a representation transformation; no-content methods/statuses need separate treatment. A 205 response must not generate content. | HTTP rules do not prove a particular local transport is correct. | +| [Function calling guide](https://developers.openai.com/api/docs/guides/function-calling), strict mode, streaming and custom tools | Schema-constrained functions and grammar-constrained freeform calls are distinct contracts. Stream fragments need aggregation. | It does not mandate a new proxy-side universal validator or make lowering grammar to a string lossless. | +| [Telemetry metric conventions](https://opentelemetry.io/docs/specs/semconv/general/metrics/) | Consistent metric naming, meaningful aggregation and balanced attribute sets are documented. | Does not define OpenCodex-specific fields or justify collecting raw content. | + +The supplied GenAI telemetry URL now displays a relocation notice; no current GenAI privacy contract is claimed from that page. This analysis uses the repository's explicit no-body/no-credential logging contract for any proposed metadata-only diagnostics. Original-schema validation before downstream delivery is a design option, not a requirement established by the provider docs; tool execution remains client-owned. + +## Publication-time freshness check + +During publication, remote `dev` advanced one commit to `04761a188281da4a2936fc4d8d9be5e02b33bb41` via #5100. The complete comparison from the pinned analysis SHA was read. Its runtime changes are confined to `src/responses/tool-name-aliases.ts` and `src/server/responses-undeclared-tool-guard.ts`, aligning emitted tool names with authorization. It does not change the custom-input progressive decoder/completion normalization, raw transports, static-policy merges, spend/replay paths or other candidate owners. The issue evidence therefore remains anchored to the reviewed SHA, with no candidate invalidated by this intervening commit. The associated test-layout and Responses documentation changes should be retained when implementing future fixes. diff --git a/devlog/_fin/260919_contract_gap_analysis/002_candidate_dispositions.md b/devlog/_fin/260919_contract_gap_analysis/002_candidate_dispositions.md new file mode 100644 index 00000000000..119f2b24989 --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/002_candidate_dispositions.md @@ -0,0 +1,52 @@ +# Keep bounded contract fixes and reuse existing authorities + +The refreshed tree disproves several broad gaps from the supplied material. The candidates retained below address concrete residual behavior or narrowly defined maintainer/operator workflows. They do not justify a new universal runtime, a model-policy language, or a replacement test framework. + +## Report themes + +| Theme | Current evidence | Disposition | +| --- | --- | --- | +| A1 content decoding | `src/lib/socks5-fetch.ts:530` decodes gzip/deflate after #5070; pinned direct still returns raw bytes at `src/lib/pinned-http.ts:194` | T3 residual; reject original broad SOCKS defect | +| A1 no-body/cancellation parity | `src/lib/socks5-fetch.ts:512` omits 205; `pinned-http.ts:144` streams all 2xx; upload waits on body reader at `socks5-fetch.ts:577` | T1/T2 concrete residuals | +| A2 custom delta/done | Bridge fence/escape handling exists after #5070; routed restore at `responses-custom-tool-repair.ts:338` differs from completion at :363 | S1 residual; patch-envelope claim already covered | +| A3 isolated conformance skeleton | Existing fixture manifests and assertion-bound tests in `src/compatibility/manifest.ts:3` and `tests/codex-integration/compatibility-manifest.test.ts` | Extend focused fixtures in each issue; no duplicate framework | +| B1 schema loss | `google-tool-schema.ts:88,120` and `google-wire-compiler.ts:97` widen constraints without a report | G1 endpoint-profile/report-first proposal | +| B2 detailed tool capability | `src/compatibility/manifest.ts:3` already models passthrough/translated/degraded/unsupported; custom format is lowered at `custom-tool-compat.ts:187` | Existing #2358 follow-up: exact-route grammar fixture claims; no second ToolContract | +| B3 physical sends | Shared send budget and telemetry exist in `request-send-budget.ts:49`, `usage/log.ts:205` | Reject broad absence claim. R1 follows explicitly disclosed integration work in #5041 | +| B4 terminal diagnostics | `src/usage/log.ts:274`, analytics and #1217/#5056 already provide terminal/recovery facts | O1 export-only proposal; schema repair attribution included in G1 report path | +| B5 replay ownership | `continuation-ownership.ts:3` and `request-prepare.ts:916` enforce missing/expired-state refusal | Existing contract retained; R3 explicitly changes historical fresh-start behavior; compatibility review required | +| C1 writer topology | Public ledger contract explicitly scopes supported topology | R2 aligns already-public sibling and ledger topology contracts; no distributed-store roadmap | +| C2 key policy | Existing key identity and scoped hub usage; #5049 open | Reuse #5049, broader tenancy remains #95 | +| C3 standard observability | Durable facts and management JSON analytics exist | O1 bounded exporter; no new raw-content collection | +| C4 takeover/restore | Transactional snapshot/reconcile/recovery exists in `structure/clients/integrations.md:5` | O2 pure preview enhancement; reject missing rollback claim | + +## Shared-conversation themes + +| Theme | Current evidence | Disposition | +| --- | --- | --- | +| One static policy result | Repeated merges in `derive.ts:221,473`, `router.ts:300`, `model-hints.ts:105` | P1 parity-first resolver, live evidence kept separate | +| Registry-derived identity | `knownModelIdsForProvider` at `router.ts:107` enumerates only some identity maps | P2 classified decode-hint proposal; no current incident claimed | +| New provider/adapter registries | Existing authorities in `providers/derive.ts:290`, `adapters/registry.ts:71` | Already implemented; no new registry | +| Numeric universal precedence | Existing typed wire authority in `server/adapter-resolve.ts:7` | Reject; retain field-specific pins/opt-outs | +| Document authority | `scripts/structure-ssot.ts:31`, `structure/AGENTS.md:45` conflate review fan-out and normative ownership | V1 additive authority map | +| Contract tests versus source inspection | Lab guard is transitive and mutation-tested; structure checker validates real topology | Reject blanket replacement; D3 binds existing guarantee in index | +| Central hardened utilities | Must start from one proven shared contract, not general deduplication | Narrow stream/transport helpers in T3/S1 | +| Canonical history/projection | Replay storage and ownership already exist | No new session-event subsystem without a concrete client need | +| Executor/translator split | `src/adapters/base.ts:36` already supports build/transport/parse and stateful runTurn | Preserve interface; no forced universal executor rewrite | +| Embeddable core/package split | `src/index.ts:1` already exports runtime functions | Defer until a concrete embedding consumer/lifecycle contract exists; #2358 covers broader core work | + +## Additional source-confirmed documentation gaps + +- D1: HTTP/SSE SOCKS guidance contradicts `src/lib/proxy-env.ts:89` in two public reference pages. +- D2: `reference/configuration/server.md:27` incorrectly says data keys authorize management. Runtime and `server-management-auth.test.ts:780` prove separation. +- D3: `structure/overview.md:90` lacks the existing core/Lab guarantee in its stable invariant map. + +## Duplicate and scope decisions + +The current bodies of #2358, #3377, #5049, #95 and #4579 were read. #4579 is about receiver-owned execution authorization, not static catalog/routing metadata; it does not duplicate P1. #3377 owns modality/context declarations, not P2's decode-hint completeness. #2894 is the existing SOCKS support umbrella; T1/T2/D1 are bounded residuals after shipped transport support. + +No competitor rankings, repository comparisons, review-model identity, personal browser state or raw user transcript are published. + +## Public provenance review for residual state work + +The exact body of public #5041 states that physical inner replays still need shared send-budget, pacing/fetch and physical-attempt integration. R1 tracks only that disclosed residual. Public #3188 explicitly allows a separately ported sibling; `src/lib/spend-reservation-ledger.ts:27` expressly excludes two live processes sharing a journal. R2 makes that already-published topology boundary actionable without a new bypass reproduction. R3 preserves task isolation and requests explicit full replay rather than continuing with insufficient history. diff --git a/devlog/_fin/260919_contract_gap_analysis/003_consensus.md b/devlog/_fin/260919_contract_gap_analysis/003_consensus.md new file mode 100644 index 00000000000..6bef84e3b80 --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/003_consensus.md @@ -0,0 +1,46 @@ +# Unanimous publication review + +Seven independent source-analysis lanes informed the candidate set. Three fresh-context reviewers then audited every proposed issue and both existing-issue comments. The coordinating reviewer also inspected the critical source spans and duplicate records. Publication requires all four judgments to agree; majority approval is insufficient. + +## Review lenses + +- Code correctness: source reachability, exact owners, conditional behavior and focused verification paths. +- Product and scope: usefulness for a local coding proxy, overlap with existing issues/PRs and authority preservation. +- Adversarial publication: evidence strength, misleading claims, public-content constraints and fresh-reader comprehension. +- Coordinator: accept/rebut decisions, exact source snapshot, synchronization of approved drafts and published bodies. + +## Amendments before approval + +- T3 preserves explicit Accept-Encoding preferences and checks the actual response coding; it does not reject a preference list just because one alternative is unsupported. +- S1 preserves safe progressive input and explicitly acknowledges duplicate-key/late-invalid-wrapper limits instead of claiming a universal equality guarantee. +- D1 identifies all four contradictory English reference pages, requires the locale scan, narrows SOCKS selection wording, and coordinates with open #3901. +- R1 lists the complete source paths and five exact existing test files; first-send accounting must not be duplicated. +- R2 requires every process that initializes/appends/compacts the shared journal to participate, including observe-only writers and enforcement transitions. +- R3 explicitly rejects all scope mismatches, including apparently full input, and requires retry-without-ID coverage. Its fixture description now matches continuation storage rather than transport configuration. +- Candidate bodies were split into individual files and staged for review. The plan artifact map and all links were corrected. +- Public prose was narrowed to relevant source facts and implementation decisions, with no review-model attribution or unrelated project comparisons. + +## Decision matrix + +| Candidate | Code | Product | Adversarial | Coordinator | +| --- | --- | --- | --- | --- | +| T1 | APPROVE | APPROVE | APPROVE | APPROVE | +| T2 | APPROVE | APPROVE | APPROVE | APPROVE | +| T3 | APPROVE | APPROVE | APPROVE | APPROVE | +| S1 | APPROVE | APPROVE | APPROVE | APPROVE | +| G1 | APPROVE | APPROVE | APPROVE | APPROVE | +| P1 | APPROVE | APPROVE | APPROVE | APPROVE | +| P2 | APPROVE | APPROVE | APPROVE | APPROVE | +| V1 | APPROVE | APPROVE | APPROVE | APPROVE | +| O1 | APPROVE | APPROVE | APPROVE | APPROVE | +| O2 | APPROVE | APPROVE | APPROVE | APPROVE | +| D1 | APPROVE | APPROVE | APPROVE | APPROVE | +| D2 | APPROVE | APPROVE | APPROVE | APPROVE | +| D3 | APPROVE | APPROVE | APPROVE | APPROVE | +| R1 | APPROVE | APPROVE | APPROVE | APPROVE | +| R2 | APPROVE | APPROVE | APPROVE | APPROVE | +| R3 | APPROVE | APPROVE | APPROVE | APPROVE | +| Existing #2358 comment | APPROVE | APPROVE | APPROVE | APPROVE | +| Existing #5049 comment | APPROVE | APPROVE | APPROVE | APPROVE | + +The reviewers checked the fixed source `7864869c31c41cca9830d93540238f17df8faafb`, staged candidate bodies, exact template sections, source anchors and relevant current issue/PR bodies. Every candidate remains labeled as source analysis with proposed runtime reproduction, not an executed test. The fresh-reader check found the product gap, authority, implementation boundary and negative cases understandable after the amendments above. diff --git a/devlog/_fin/260919_contract_gap_analysis/004_source_fingerprints.md b/devlog/_fin/260919_contract_gap_analysis/004_source_fingerprints.md new file mode 100644 index 00000000000..5a976c6b1e3 --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/004_source_fingerprints.md @@ -0,0 +1,20 @@ +# Report source fingerprints versus refreshed source + +Pinned source: `7864869c31c41cca9830d93540238f17df8faafb`. A matching fingerprint confirms the file contents only, not the report interpretation. + +| Source | Supplied SHA-256 | Refreshed SHA-256 | Result | +| --- | --- | --- | --- | +| `src/lib/socks5-fetch.ts` | `e62a9909c9ffc5db85604a3f8431576d46fcdd771a657b2bf769c8577172f0d1` | `fc1c5b7780f36f61fce0c6104cd46700ffca9a5c05e32174c9ccf437fc188974` | changed | +| `src/lib/proxy-env.ts` | `646e25f58a37082f4c5cfba9e668aae338e16d6c9746ab9f873b3bb4bed41fa7` | `646e25f58a37082f4c5cfba9e668aae338e16d6c9746ab9f873b3bb4bed41fa7` | same | +| `src/responses/custom-tool-compat.ts` | `010f07666c0b18abd2889bf51cb2f084affd966d956358d16c919caeb511b356` | `010f07666c0b18abd2889bf51cb2f084affd966d956358d16c919caeb511b356` | same | +| `src/responses/parser-tools.ts` | `2fe62848231819b9f4b19491d608729198a353d051e22662993d71c36fa56673` | `2fe62848231819b9f4b19491d608729198a353d051e22662993d71c36fa56673` | same | +| `src/server/responses-custom-tool-repair.ts` | `b0ad4a9ddfe34582250aa867c0229ea47f1f3c4082b841d1d61a8ec4ae2088ec` | `b0ad4a9ddfe34582250aa867c0229ea47f1f3c4082b841d1d61a8ec4ae2088ec` | same | +| `src/responses/apply-patch-envelope.ts` | `2fc968e8640c0805ad119234adac653f6ea7bfd78496d425924ddb8f77267f5d` | `2fc968e8640c0805ad119234adac653f6ea7bfd78496d425924ddb8f77267f5d` | same | +| `src/adapters/google-tool-schema.ts` | `d5bcf65418bfade8a3d98a26c7ffc1b657f943eca0e44528e8817a9ef4f5e4ac` | `d5bcf65418bfade8a3d98a26c7ffc1b657f943eca0e44528e8817a9ef4f5e4ac` | same | +| `src/adapters/google-wire-compiler.ts` | `3b6c3360ee5e81ffd8cf784954e131ad2a53e8d8ba1492345cbe7c8cd882904f` | `691dac9507c47d931b5000208779fd4e0181118f7027e795d0a5dd3731116bd1` | changed | +| `src/lib/spend-reservation-ledger.ts` | `acfd1b79fcb4760cb9facc0558c6e1819d2fb72845e922900dc4e51cdffae5f8` | `acfd1b79fcb4760cb9facc0558c6e1819d2fb72845e922900dc4e51cdffae5f8` | same | +| `src/types/config.ts` | `1f83bb55b02e16a2ef5fcf9741172d98eccd95a7d58f8ad50db182b67b0a61ed` | `1f83bb55b02e16a2ef5fcf9741172d98eccd95a7d58f8ad50db182b67b0a61ed` | same | +| `src/lib/provider-outbound.ts` | `dd823e0b5b00ebe4285149a83a13aa9bb30abe914b7765f0b416ec85620f3d9e` | `dd823e0b5b00ebe4285149a83a13aa9bb30abe914b7765f0b416ec85620f3d9e` | same | +| `src/server/models-capabilities.ts` | `8e0135baf9f6660ec9409f71cae73c1f0d868e9c4e7b5a2b78b71019ea840262` | `8e0135baf9f6660ec9409f71cae73c1f0d868e9c4e7b5a2b78b71019ea840262` | same | +| `src/responses/continuation-ownership.ts` | `5a173b7a767fc915569a6213ad621148b9b9f7345aa0e13547bf19e0854ddc9b` | `5a173b7a767fc915569a6213ad621148b9b9f7345aa0e13547bf19e0854ddc9b` | same | +| `src/server/management/api-access.ts` | `68cd2e74097bda829a44e605c9acf9957b95d0a4e5d0925cdd9e05d42d075e9a` | `68cd2e74097bda829a44e605c9acf9957b95d0a4e5d0925cdd9e05d42d075e9a` | same | diff --git a/devlog/_fin/260919_contract_gap_analysis/005_existing_issue_followups.md b/devlog/_fin/260919_contract_gap_analysis/005_existing_issue_followups.md new file mode 100644 index 00000000000..e0324a4bfe9 --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/005_existing_issue_followups.md @@ -0,0 +1,31 @@ +# Reuse existing issue authority + +These are proposed comments, subject to the same unanimous publication review as new issues. + +## #2358 + +Source-grounded follow-up at `7864869c31c41cca9830d93540238f17df8faafb`: custom-tool representation and grammar can extend the existing passive compatibility manifest rather than introducing another contract registry. + +Current path: `src/responses/custom-tool-compat.ts:187` lowers custom format into a string-input function; `src/responses/parser-tools.ts:67` also represents freeform calls without grammar provenance. The existing `src/compatibility/manifest.ts` already has passthrough/translated/degraded/unsupported dispositions and exact-subject assertion evidence. + +Implementation path: + +1. Add secret-free fixtures under `tests/fixtures/compatibility/` for the exact destination/auth/inbound/upstream subject, with separate custom representation and grammar assertions. +2. Classify native preservation as passthrough, useful string-wrapper representation as translated, removed grammar as degraded with a concrete limitation, and refusal as unsupported. +3. Extend the matching manifest and `tests/codex-integration/compatibility-manifest.test.ts` so every claim names live assertion IDs, not only test filenames. +4. Update `structure/adapters/compatibility-contracts.md`. Keep manifests passive and optional Lab code outside core runtime imports. +5. Add richer CLI/catalog output only after its consumer contract exists; leave current binary tool-availability fields unchanged. + +Acceptance: native and lowered fixtures are distinguishable, grammar loss cannot be labeled lossless, missing assertion evidence fails manifest validation, and no runtime behavior changes from adding evidence. This is static analysis and an implementation proposal; no local runtime suite was run. The broader universal IR/package rewrite is not needed for this bounded slice. + +## #5049 + +Implementation-path refinement from source review at `7864869c31c41cca9830d93540238f17df8faafb`. This issue already owns the narrow per-admission-key authorization gap; no duplicate proposal is needed. + +- Extend `OcxApiKeyEntry` in `src/types/config.ts:245` with optional policy fields and wire their full chain: config/management input validation, persistence, reload/default handling, key rename/rotation preservation, management/CLI projection, catalog projection and request consumers. +- Reuse the authenticated key identity from `src/server/auth-cors.ts:395`; caller-supplied informational identity headers are not policy authority. Keep management credentials independent. +- Evaluate policy against canonical resolved provider/model identity, then re-evaluate after fallback/combo route changes. `src/server/responses/request-prepare.ts:404` is one repeated resolution point; inventory HTTP, WebSocket, translated inbound, combo and retry entrypoints before implementation. +- Define aliases explicitly: an allowed combo alias must not implicitly authorize an otherwise forbidden resolved destination. Catalog filtering and actual admission must consume the same policy evaluator. +- Refuse before upstream I/O, preserve key-scoped hub usage (`src/server/hub-usage.ts:8`), and expose bounded denial metadata without secret material. + +Acceptance fixtures: unset policy preserves current behavior; allowed/denied direct models; aliases; fallback and combo re-resolution; key rotation/rename; invalid policy input; data-vs-management auth separation; and zero physical sends on denial. Register new tests in both layout manifests, update config/catalog/management/Responses structure owners, and document operator behavior. Broader tenant roles and administration remain in #95. No runtime tests or live account calls were performed for this analysis. diff --git a/devlog/_fin/260919_contract_gap_analysis/010_issue_implementation_paths.md b/devlog/_fin/260919_contract_gap_analysis/010_issue_implementation_paths.md new file mode 100644 index 00000000000..e1e40450531 --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/010_issue_implementation_paths.md @@ -0,0 +1,22 @@ +# Proposed issue implementation paths + +Reader: an OpenCodex maintainer selecting a bounded implementation PR. These are proposals, not completed fixes. Bodies include exact source evidence, proposed file changes, negative cases and verification limits. Publication awaits consensus. + +## Candidate implementation files + +- [T1: [Bug]: Return null bodies for 204 and 205 in raw outbound transports](020_issue_t1.md) +- [T2: [Bug]: Settle SOCKS5 streaming uploads on cancellation and early final responses](021_issue_t2.md) +- [T3: [Bug]: Decode content-coded responses on the pinned direct provider transport](022_issue_t3.md) +- [G1: [Feature]: Report endpoint-scoped tool-schema loss before applying stricter policy](023_issue_g1.md) +- [S1: [Bug]: Keep routed custom-tool preview consistent with fence-normalized completion](024_issue_s1.md) +- [P1: [Feature]: Resolve static model policy once for catalog and routing consumers](025_issue_p1.md) +- [P2: [Feature]: Derive model selector decode hints from all classified registry identity maps](026_issue_p2.md) +- [V1: [Feature]: Separate contract authority from source review fan-out in the structure manifest](027_issue_v1.md) +- [O1: [Feature]: Export existing request telemetry through an opt-in metadata-only scrape endpoint](028_issue_o1.md) +- [O2: [Feature]: Preview integration mutations using the server ownership plan](029_issue_o2.md) +- [D1: [Docs]: Align SOCKS5 HTTP/SSE routing documentation with configured outbound fetch](030_issue_d1.md) +- [D2: [Docs]: Correct apiKeys documentation to preserve management/data-plane separation](031_issue_d2.md) +- [D3: [Docs]: Bind core/Lab isolation and synchronous activation in the invariant index](032_issue_d3.md) +- [R1: [Feature]: Complete cross-layer send accounting for pre-output rate-limit replay](033_issue_r1.md) +- [R2: [Feature]: Make explicit sibling instances honor the spend-ledger topology contract](034_issue_r2.md) +- [R3: [Bug]: Request full replay when a task-scoped continuation cannot be used](035_issue_r3.md) diff --git a/devlog/_fin/260919_contract_gap_analysis/011_delivery.md b/devlog/_fin/260919_contract_gap_analysis/011_delivery.md new file mode 100644 index 00000000000..a903fadb985 --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/011_delivery.md @@ -0,0 +1,45 @@ +# Delivered: sixteen issues and two existing-issue implementation comments + +The approved source analysis is now tracked in sixteen new issues: five defects, eight feature proposals and three documentation corrections. Each published body includes the implementation path and acceptance cases. Two existing issues received bounded implementation comments instead of duplicate issues. No runtime code was changed and no implementation is claimed. + +## Verified issue delivery + +| Candidate | Issue | Type | Verified state | +| --- | --- | --- | --- | +| T1 | [#5109: [Bug]: Return null bodies for 204 and 205 in raw outbound transports](https://github.com/lidge-jun/opencodex/issues/5109) | bug | OPEN | +| T2 | [#5110: [Bug]: Settle SOCKS5 streaming uploads on cancellation and early final responses](https://github.com/lidge-jun/opencodex/issues/5110) | bug | OPEN | +| T3 | [#5111: [Bug]: Decode content-coded responses on the pinned direct provider transport](https://github.com/lidge-jun/opencodex/issues/5111) | bug | OPEN | +| G1 | [#5112: [Feature]: Report endpoint-scoped tool-schema loss before applying stricter policy](https://github.com/lidge-jun/opencodex/issues/5112) | enhancement | OPEN | +| S1 | [#5113: [Bug]: Keep routed custom-tool preview consistent with fence-normalized completion](https://github.com/lidge-jun/opencodex/issues/5113) | bug | OPEN | +| P1 | [#5114: [Feature]: Resolve static model policy once for catalog and routing consumers](https://github.com/lidge-jun/opencodex/issues/5114) | enhancement | OPEN | +| P2 | [#5115: [Feature]: Derive model selector decode hints from all classified registry identity maps](https://github.com/lidge-jun/opencodex/issues/5115) | enhancement | OPEN | +| V1 | [#5116: [Feature]: Separate contract authority from source review fan-out in the structure manifest](https://github.com/lidge-jun/opencodex/issues/5116) | enhancement | OPEN | +| O1 | [#5117: [Feature]: Export existing request telemetry through an opt-in metadata-only scrape endpoint](https://github.com/lidge-jun/opencodex/issues/5117) | enhancement | OPEN | +| O2 | [#5118: [Feature]: Preview integration mutations using the server ownership plan](https://github.com/lidge-jun/opencodex/issues/5118) | enhancement | OPEN | +| D1 | [#5119: [Docs]: Align SOCKS5 HTTP/SSE routing documentation with configured outbound fetch](https://github.com/lidge-jun/opencodex/issues/5119) | documentation | OPEN | +| D2 | [#5120: [Docs]: Correct apiKeys documentation to preserve management/data-plane separation](https://github.com/lidge-jun/opencodex/issues/5120) | documentation | OPEN | +| D3 | [#5121: [Docs]: Bind core/Lab isolation and synchronous activation in the invariant index](https://github.com/lidge-jun/opencodex/issues/5121) | documentation | OPEN | +| R1 | [#5122: [Feature]: Complete cross-layer send accounting for pre-output rate-limit replay](https://github.com/lidge-jun/opencodex/issues/5122) | enhancement | OPEN | +| R2 | [#5123: [Feature]: Make explicit sibling instances honor the spend-ledger topology contract](https://github.com/lidge-jun/opencodex/issues/5123) | enhancement | OPEN | +| R3 | [#5124: [Bug]: Request full replay when a task-scoped continuation cannot be used](https://github.com/lidge-jun/opencodex/issues/5124) | bug | OPEN | + +## Existing authority extended + +- [Implementation comment on #2358](https://github.com/lidge-jun/opencodex/issues/2358#issuecomment-5740122588) +- [Implementation comment on #5049](https://github.com/lidge-jun/opencodex/issues/5049#issuecomment-5740122723) + +## Fresh verification + +- All sixteen issues were reread using `gh issue view --json number,title,body,state,labels,url`. Titles and full bodies match the approved drafts; each issue is open with its matching template label. Result: `REMOTE_ISSUE_VERIFICATION_PASS`. +- Both comments were reread through their exact issue-comment API IDs. Their bodies match the approved drafts. +- The pure documentation checker validates all sixteen issue forms, the two comments, publication text constraints and ninety source permalinks. Result: `DOCUMENT_CONTRACT_CHECK_PASS`. +- `git diff --cached --check` passed after the final document cleanup. +- Source analysis remains pinned to `7864869c31c41cca9830d93540238f17df8faafb`. The one intervening `dev` commit was checked as recorded in 001 and invalidates none of these candidates. +- Publication used the repository template chooser and the matching form. Generated field ordering and code fences were normalized to the exact approved body through the issue API. One post-submit browser read and one search-index delay were reconciled by reading the actual existing issue; neither was resubmitted. +- Runtime suites, typecheck, builds, installs, live provider experiments and service changes were not run. Future implementation owns its focused regression and exact-head CI proof. + +## Implementation ordering and boundaries + +Transport/body lifecycle fixes and the routed input-stream consistency fix can be independent focused changes. Schema diagnostics precede opt-in stricter policy. Static-policy consolidation starts with parity fixtures; decode-hint completeness remains separate from catalog availability. Shared-journal ownership must cover every writer before any enforcement claim. Document corrections and invariant binding reuse existing runtime guards. Standard metrics export and integration preview are optional operator features; neither expands the proxy into a tool executor or tenant platform. + +The task ends at verified analysis and issue delivery. No PR, push, merge, release, deployment or source patch was performed. The local devlog is retained as the complete decision and delivery record. Implementation issues remain open for future work. diff --git a/devlog/_fin/260919_contract_gap_analysis/020_issue_t1.md b/devlog/_fin/260919_contract_gap_analysis/020_issue_t1.md new file mode 100644 index 00000000000..0ffb06ab5a6 --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/020_issue_t1.md @@ -0,0 +1,66 @@ +# T1: [Bug]: Return null bodies for 204 and 205 in raw outbound transports + +### Client or integration + +Direct HTTP/API client + +### Area + +Proxy and routing + +### Summary + +The pinned direct helper constructs a streaming Response for every 2xx response, including 204 and 205. The SOCKS helper excludes 204 but misses 205. These statuses require a null body at the Fetch Response boundary, so a valid no-content upstream response can fail during response construction instead of resolving normally. + +### Reproduction + +Static source trace at `7864869c31c41cca9830d93540238f17df8faafb`; the following fake-upstream regression is the proposed executable reproduction, not a claimed local test result. + +1. Have a fake HTTP upstream return 204 or 205 with no content and keep its connection alive. +2. Invoke `pinnedHttpGet` against its pinned loopback address. Separately return 205 through a fake SOCKS tunnel. +3. Assert the call resolves promptly with the original status and `body === null`, even when representation headers describe an unsupported coding. Current source attaches a stream in those cases. + +### Version + +7864869c31c41cca9830d93540238f17df8faafb + +### Operating system + +Source review on macOS 27.0; the transport logic is cross-platform. Runtime reproduction has not been executed in this analysis. + +### Provider and model + +Not provider- or model-specific. Use a local fake upstream and no real credentials. + +### Logs or error output + +No live traffic or runtime logs collected. Evidence is the exact source path below. + +### Screenshots and supporting files + +[src/lib/pinned-http.ts:144](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/lib/pinned-http.ts#L144); [src/lib/pinned-http.ts:194](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/lib/pinned-http.ts#L194); [src/lib/socks5-fetch.ts:512](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/lib/socks5-fetch.ts#L512). Related #2894 and merged #5070; neither covers this residual status set. [Fetch null-body status](https://fetch.spec.whatwg.org/#null-body-status) and [HTTP 205](https://www.rfc-editor.org/rfc/rfc9110.html#name-205-reset-content). + +### Redacted configuration + +Use a test-owned loopback upstream and SOCKS tunnel or the pinned direct helper as specified above. No user home, provider credentials or running proxy is needed. + +### Implementation path + +1. MODIFY `src/lib/socks5-fetch.ts`: include 205 in `bodylessResponse`; keep HEAD/204/304 behavior. +2. MODIFY `src/lib/pinned-http.ts`: branch on null-body status before creating the success stream and safely terminate the underlying response/request. Preserve response headers. +3. Share a small eligibility predicate only if it simplifies these two owners; do not introduce a broad transport framework. Keep unsupported upgrade behavior outside this issue. +4. ADD a focused sibling `tests/lib/transport-null-body.test.ts` or extend uncapped existing tests. + +### Acceptance criteria and verification + +- 204/205 settle with null body without waiting for connection close. +- HEAD/304 existing behavior remains covered where the transport supports those request/status paths. +- 205 carrying `Content-Encoding: br` is not decoded or rejected for nonexistent body bytes. +- Ordinary 200 JSON and cleanup/cancellation still work. + +New test files must be registered in `scripts/test-layout/layout.json` and `tests/fixtures/test-layout-expected.json`; split tests rather than raise file-size caps. Update `structure/transports/inventory.md` and any other owner declared by the manifest. Run focused regressions and exact-head hosted CI in the implementation PR; no passing runtime result is claimed here. + +### Checks + +- [x] I searched existing issues and documentation. +- [x] I removed secrets, tokens, account details, request credentials, and personal data. diff --git a/devlog/_fin/260919_contract_gap_analysis/021_issue_t2.md b/devlog/_fin/260919_contract_gap_analysis/021_issue_t2.md new file mode 100644 index 00000000000..b900715363a --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/021_issue_t2.md @@ -0,0 +1,66 @@ +# T2: [Bug]: Settle SOCKS5 streaming uploads on cancellation and early final responses + +### Client or integration + +Direct HTTP/API client + +### Area + +Proxy and routing + +### Summary + +The upload loop awaits the caller body reader before parsing any response head. Aborting destroys the socket but does not settle a pending `bodyReader.read()`. A stalled upload can therefore keep the fetch promise pending, including when the peer has already returned a final response. + +### Reproduction + +Static source trace at `7864869c31c41cca9830d93540238f17df8faafb`; the following fake-upstream regression is the proposed executable reproduction, not a claimed local test result. + +1. Use a fake SOCKS peer and a Request body stream that produces one chunk and then leaves its next read pending. +2. Abort after the headers/chunk arrive, or have the upstream send a final response without waiting for the upload to finish. +3. Assert bounded settlement, request-body cancellation, no further upload writes and no orphaned socket/listeners. Do not use a production endpoint. + +### Version + +7864869c31c41cca9830d93540238f17df8faafb + +### Operating system + +Source review on macOS 27.0; the transport logic is cross-platform. Runtime reproduction has not been executed in this analysis. + +### Provider and model + +Not provider- or model-specific. Use a local fake upstream and no real credentials. + +### Logs or error output + +No live traffic or runtime logs collected. Evidence is the exact source path below. + +### Screenshots and supporting files + +[src/lib/socks5-fetch.ts:559](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/lib/socks5-fetch.ts#L559); [src/lib/socks5-fetch.ts:573](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/lib/socks5-fetch.ts#L573); [src/lib/socks5-fetch.ts:589](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/lib/socks5-fetch.ts#L589). Existing handshake/response abort support is retained; this is a request-body lifecycle gap, not a claim that cancellation is absent. Related #2894. + +### Redacted configuration + +Use a test-owned loopback upstream and SOCKS tunnel or the pinned direct helper as specified above. No user home, provider credentials or running proxy is needed. + +### Implementation path + +1. MODIFY `src/lib/socks5-fetch.ts`: observe the final response head concurrently with upload, skipping informational responses. +2. Race body reads/drain waits with caller abort and early final response. On termination, cancel/release the body reader without allowing a hanging cancel callback to block settlement. +3. Preserve the first terminal cause and caller abort reason; do not send a terminating chunk after an early final response. Avoid concurrent consumers of the same socket reader. +4. ADD focused `tests/lib/socks5-upload-lifecycle.test.ts` regressions. + +### Acceptance criteria and verification + +- Pending body read + caller abort rejects with the original reason and releases resources. +- Early final response resolves and stops upload. +- Socket error/timeout during a stalled body read settles rather than hanging. +- Backpressure, normal POST completion and informational response handling remain correct. + +New test files must be registered in `scripts/test-layout/layout.json` and `tests/fixtures/test-layout-expected.json`; split tests rather than raise file-size caps. Update `structure/transports/inventory.md` and any other owner declared by the manifest. Run focused regressions and exact-head hosted CI in the implementation PR; no passing runtime result is claimed here. + +### Checks + +- [x] I searched existing issues and documentation. +- [x] I removed secrets, tokens, account details, request credentials, and personal data. diff --git a/devlog/_fin/260919_contract_gap_analysis/022_issue_t3.md b/devlog/_fin/260919_contract_gap_analysis/022_issue_t3.md new file mode 100644 index 00000000000..f7bf699a1fa --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/022_issue_t3.md @@ -0,0 +1,67 @@ +# T3: [Bug]: Decode content-coded responses on the pinned direct provider transport + +### Client or integration + +Direct HTTP/API client + +### Area + +Proxy and routing + +### Summary + +SOCKS responses now decode gzip/deflate, but `pinnedHttpRequest` returns raw encoded success bytes. Provider outbound chooses between these transports, so the same gzip JSON response is readable on one route and still compressed on the pinned direct route. + +### Reproduction + +Static source trace at `7864869c31c41cca9830d93540238f17df8faafb`; the following fake-upstream regression is the proposed executable reproduction, not a claimed local test result. + +1. Fake upstream returns gzip or deflate JSON with matching Content-Encoding and coded Content-Length. +2. Read the response through pinned direct and SOCKS routes. +3. Compare logical JSON, coding/length headers, decoder errors and cleanup. Current pinned direct code forwards raw bytes into a Response. + +### Version + +7864869c31c41cca9830d93540238f17df8faafb + +### Operating system + +Source review on macOS 27.0; the transport logic is cross-platform. Runtime reproduction has not been executed in this analysis. + +### Provider and model + +Not provider- or model-specific. Use a local fake upstream and no real credentials. + +### Logs or error output + +No live traffic or runtime logs collected. Evidence is the exact source path below. + +### Screenshots and supporting files + +[src/lib/pinned-http.ts:153](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/lib/pinned-http.ts#L153); [src/lib/pinned-http.ts:194](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/lib/pinned-http.ts#L194); [src/lib/provider-outbound.ts:209](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/lib/provider-outbound.ts#L209); [src/lib/socks5-fetch.ts:530](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/lib/socks5-fetch.ts#L530). This is the pinned direct residual after #5070, not a duplicate request to decode SOCKS gzip. + +### Redacted configuration + +Use a test-owned loopback upstream and SOCKS tunnel or the pinned direct helper as specified above. No user home, provider credentials or running proxy is needed. + +### Implementation path + +1. MODIFY `src/lib/pinned-http.ts`: apply an explicit content-coding policy to success bodies; default identity requests can reduce unnecessary coding but are not the complete fix. +2. EXTRACT only the narrow shared gzip/deflate decoding policy from `src/lib/socks5-fetch.ts` if useful; leave injected executors under their existing contract. +3. Remove stale coded length/encoding after decoding and preserve byte ceilings, cancellation, deadlines and connection cleanup. Define encoded/decoded accounting explicitly for the bounded pinned consumer. +4. Do not reject an entire Accept-Encoding preference list merely because it mentions an unsupported alternative; validate the actual response coding. Brotli and multiple-coding support are separate policy decisions. +5. ADD `tests/lib/pinned-http-content-coding.test.ts` and route-parity fixtures. + +### Acceptance criteria and verification + +- Identity/gzip/deflate produce identical logical JSON across owned raw transports. +- Corrupt/unsupported coding returns a named error and closes the socket. +- Decoded body size remains bounded when `maxBytes` is configured; existing encoded-byte behavior is explicitly preserved or versioned. +- Abort/bodyless behavior remains intact; no direct-network fallback around operator egress policy. + +New test files must be registered in `scripts/test-layout/layout.json` and `tests/fixtures/test-layout-expected.json`; split tests rather than raise file-size caps. Update `structure/transports/inventory.md` and any other owner declared by the manifest. Run focused regressions and exact-head hosted CI in the implementation PR; no passing runtime result is claimed here. + +### Checks + +- [x] I searched existing issues and documentation. +- [x] I removed secrets, tokens, account details, request credentials, and personal data. diff --git a/devlog/_fin/260919_contract_gap_analysis/023_issue_g1.md b/devlog/_fin/260919_contract_gap_analysis/023_issue_g1.md new file mode 100644 index 00000000000..ef61b66c77f --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/023_issue_g1.md @@ -0,0 +1,56 @@ +# G1: [Feature]: Report endpoint-scoped tool-schema loss before applying stricter policy + +### Area + +Provider adapters + +### What are you trying to accomplish? + +Let an operator distinguish lossless normalization from compatibility widening for a tool declaration, while keeping current working requests compatible by default. + +### What prevents this today? + +All Google endpoint modes currently use the same sanitizer. [src/adapters/google-tool-schema.ts:88](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/adapters/google-tool-schema.ts#L88) drops non-string enums; [src/adapters/google-tool-schema.ts:120](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/adapters/google-tool-schema.ts#L120) widens mixed unions; [src/adapters/google-wire-compiler.ts:97](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/adapters/google-wire-compiler.ts#L97) has no endpoint profile or loss report. Existing tests intentionally expect several constraints to be removed. A request passing upstream does not establish original-schema fidelity. + +### What should OpenCodex do? + +Compile against an explicit endpoint profile and return bounded, content-free loss categories. Preserve the conservative current behavior initially. Add opt-in reject-lossy behavior only after the report is wired through initial compilation and compatibility repair. Do not claim a broader accepted dialect until that endpoint has evidence. + +### Example usage or interface + +Given an integer enum or a mixed union, diagnostics identify a bounded category such as `enum-value-filtered` or `union-widened`, plus counts and endpoint class. Default mode sends the existing compatible shape. Opt-in reject-lossy refuses before the changed physical send. Names are illustrative, not an existing API. + +### Alternatives or workarounds + +Forwarding arbitrary keywords would remove current request-containment guarantees. Globally turning off tool support confuses availability with fidelity. A mandatory universal argument validator is outside this proposal because client tool execution and inbound-protocol contracts differ. + +### Additional context + +Source snapshot: `7864869c31c41cca9830d93540238f17df8faafb` after fast-forwarding `dev` on 2026-09-19. This is source-grounded analysis, not a runtime test result. + +Bounded follow-up to #2358; distinct from the input-modality/context axes in #3377. [src/adapters/google-http.ts:73](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/adapters/google-http.ts#L73) and [src/adapters/google-http.ts:149](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/adapters/google-http.ts#L149) establish repair scope. Official endpoint docs do not prove one universal schema dialect. + +### Implementation path + +1. MODIFY `src/adapters/google-tool-schema.ts`: return parameters plus loss report; retain traversal limits. +2. MODIFY `src/adapters/google-wire-compiler.ts`: consume endpoint profile and aggregate reports without names/property paths/schema text. +3. MODIFY `src/adapters/google.ts`: derive profile from the existing `googleMode`; update all three call sites. +4. Carry the selected policy to `src/adapters/google-http.ts` so a 400 repair cannot silently bypass it; direct mode already disables that repair. +5. If policy becomes persisted, wire type in `src/types/provider.ts`, provider config validation/persistence, management and CLI creation, hydration/default handling and every compiler/retry consumer in one change. Start report-only if that full chain is not in scope. +6. Update `structure/providers/google.md` and all adapter owners; add focused `tests/adapters/google/google-tool-schema-contract.test.ts`. + +### Acceptance criteria and verification + +- Profile matrix: numeric enum, bounds, mixed union, recursion, depth/node budget loss. +- Unset policy stays byte-compatible; explicit reject-lossy sends zero initial requests for initial loss and zero repaired sends when a repair would erase constraints. +- Indexed and unindexed 400 repair are reported; direct mode still does not repair. +- Output `responseMimeType`/`responseJsonSchema` stay untouched. +- Privacy fixtures use canary tool/property/value strings and assert none appear in report output. + +Register new tests in both layout inventories, preserve size caps, and update the existing structure owners. User-facing policy changes need corresponding public documentation and non-contradictory translations. Run focused tests and exact-head hosted CI during implementation; no local suite was run for this analysis. + +### Checks + +- [x] I searched existing issues and documentation. +- [x] This request describes a concrete OpenCodex workflow rather than merely naming a desired technology. +- [x] I removed secrets and personal data. diff --git a/devlog/_fin/260919_contract_gap_analysis/024_issue_s1.md b/devlog/_fin/260919_contract_gap_analysis/024_issue_s1.md new file mode 100644 index 00000000000..1e12d981ce4 --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/024_issue_s1.md @@ -0,0 +1,68 @@ +# S1: [Bug]: Keep routed custom-tool preview consistent with fence-normalized completion + +### Client or integration + +Direct HTTP/API client + +### Area + +Proxy and routing + +### Summary + +On routed Responses custom-tool restoration, the progressive decoder emits the string inside the input wrapper immediately. Completion strips a complete outer Markdown fence for exec/apply_patch. A delta consumer can therefore receive fence bytes that do not belong to the authoritative final input. The bridge fix in #5070 does not cover this restoration module. + +### Reproduction + +Static source trace at `7864869c31c41cca9830d93540238f17df8faafb`; the following fake-upstream regression is the proposed executable reproduction, not a claimed local test result. + +1. Declare a custom exec tool and route it through function lowering. +2. Feed output_item.added and function argument deltas whose full argument object is `{"input":"```js\ntext(1)\n```"}`. +3. Complete the argument/item/response events. +4. Compare every emitted prefix with the canonical `text(1)` input. Current restoration can emit fence bytes before completion removes them. + +### Version + +7864869c31c41cca9830d93540238f17df8faafb + +### Operating system + +Source review on macOS 27.0; the transport logic is cross-platform. Runtime reproduction has not been executed in this analysis. + +### Provider and model + +Not provider- or model-specific. Use a local fake upstream and no real credentials. + +### Logs or error output + +No live traffic or runtime logs collected. Evidence is the exact source path below. + +### Screenshots and supporting files + +[src/server/responses-custom-tool-repair.ts:32](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/server/responses-custom-tool-repair.ts#L32); [src/server/responses-custom-tool-repair.ts:338](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/server/responses-custom-tool-repair.ts#L338); [src/server/responses-custom-tool-repair.ts:363](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/server/responses-custom-tool-repair.ts#L363); [src/responses/apply-patch-envelope.ts:31](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/responses/apply-patch-envelope.ts#L31); [src/bridge/sse.ts:198](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/bridge/sse.ts#L198). Related #5047/#5070; this is a remaining routed path. + +### Redacted configuration + +Use a fake Responses upstream with a caller-owned custom exec declaration lowered to a function. Feed the event fixture through the routed restoration helper; no live provider credentials, SOCKS tunnel or user home are needed. + +### Implementation path + +1. Add a small shared progressive freeform-input helper under `src/responses/`, used by `src/bridge/sse.ts` and `src/server/responses-custom-tool-repair.ts`. Preserve current completion normalization. +2. Hold only prefixes that can still become a fence, patch envelope or fallback wrapper; do not strip arbitrary backticks from executable input. +3. Keep ordinary safe input progressive, retain stable call/item identity and common TranslatorBudget charging/release. +4. Add sibling `tests/responses/responses-custom-tool-stream-consistency.test.ts`; the existing large repair test is at its cap. Update `structure/transports/responses.md` and adapter/byte-accounting owners. + +### Acceptance criteria and verification + +- Wrapped fenced exec across every split emits no prefix inconsistent with final input. +- Done/item/terminal input and identity agree; when preview is suppressed, the final input remains authoritative. Do not incorrectly require empty preview to equal a nonempty done payload. +- Plain input stays progressive; fallback keys, JSON whitespace/escapes and split surrogate pairs are covered. +- Existing patch normalization and buffer release on done/failure/incomplete/disposal remain intact. +- Define and document duplicate-key or late-invalid-wrapper preview limits rather than claiming an impossible general invariant without a buffering policy. + +New test files must be registered in `scripts/test-layout/layout.json` and `tests/fixtures/test-layout-expected.json`; split tests rather than raise file-size caps. Update `structure/transports/inventory.md` and any other owner declared by the manifest. Run focused regressions and exact-head hosted CI in the implementation PR; no passing runtime result is claimed here. + +### Checks + +- [x] I searched existing issues and documentation. +- [x] I removed secrets, tokens, account details, request credentials, and personal data. diff --git a/devlog/_fin/260919_contract_gap_analysis/025_issue_p1.md b/devlog/_fin/260919_contract_gap_analysis/025_issue_p1.md new file mode 100644 index 00000000000..1b2640975ed --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/025_issue_p1.md @@ -0,0 +1,54 @@ +# P1: [Feature]: Resolve static model policy once for catalog and routing consumers + +### Area + +Multiple areas + +### What are you trying to accomplish? + +Keep client-advertised capabilities and runtime static policy consistent when provider registry defaults or operator overrides change. + +### What prevents this today? + +Policy fields are merged independently during preset materialization, enrichment, routing and catalog correction: [src/providers/derive.ts:221](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/providers/derive.ts#L221), [src/providers/derive.ts:473](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/providers/derive.ts#L473), [src/router.ts:300](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/router.ts#L300), [src/codex/catalog/model-hints.ts:105](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/codex/catalog/model-hints.ts#L105). The catalog correction documents prior drift. This is repeated authority, not proof of a currently failing model. + +### What should OpenCodex do? + +Introduce one immutable resolved static-policy result with explicit field-level precedence. Catalog and routing consume it; late account, credential, quota, health and observed transport evidence remain separate. Preserve existing wire pins and explicit operator opt-outs. + +### Example usage or interface + +A registry default and explicit per-model override produce the same supported effort/window/semantic policy in catalog and route projections. Later credential changes may rebind transport but must not silently replace unrelated static policy. Unknown capabilities remain unknown. + +### Alternatives or workarounds + +A universal numeric priority or a static copy of account health would erase distinct authority rules. A descriptor-driven shared merge is a valid smaller alternative to a rich request-wide object. + +### Additional context + +Source snapshot: `7864869c31c41cca9830d93540238f17df8faafb` after fast-forwarding `dev` on 2026-09-19. This is source-grounded analysis, not a runtime test result. + +#3377 owns additional user-declared capability axes; this issue owns consistent consumption of existing static policy. #4579 was read and concerns execution authorization, not this metadata merge. #2358 remains the wider compatibility roadmap. + +### Implementation path + +1. Inventory each duplicated static field and its current precedence; add parity fixtures before changing consumers. +2. Add `src/providers/resolved-model-policy.ts` or a shared field-descriptor resolver; do not introduce a new policy language. +3. Migrate `src/providers/derive.ts`, `src/router.ts`, `src/codex/catalog/model-hints.ts` and `gather-capture.ts` incrementally. Preserve gather-flight authority capture. +4. Route adapter static selection through the result in `src/server/adapter-resolve.ts`, preserving late binding in `src/server/responses/request-transport.ts`. If adding a RouteResult field, enumerate builder, every consumer and snapshots; no persistence serializer is needed unless persistence is explicitly added. +5. Add `tests/providers/resolved-model-policy.test.ts` and parity/cold-catalog cases. Update `structure/providers-and-adapters.md`, `structure/catalog.md`, `structure/config.md` and routing owners. + +### Acceptance criteria and verification + +- Existing precedence is byte/behavior-equivalent for current fixtures before cleanup. +- Registry default, explicit override, custom row, unknown and discovered hints are compared across catalog and route consumers. +- Live evidence cannot widen a static hard limit; credentials/health do not become frozen request policy. +- Hard pins, aliases and explicit false values retain their meaning. + +Register new tests in both layout inventories, preserve size caps, and update the existing structure owners. User-facing policy changes need corresponding public documentation and non-contradictory translations. Run focused tests and exact-head hosted CI during implementation; no local suite was run for this analysis. + +### Checks + +- [x] I searched existing issues and documentation. +- [x] This request describes a concrete OpenCodex workflow rather than merely naming a desired technology. +- [x] I removed secrets and personal data. diff --git a/devlog/_fin/260919_contract_gap_analysis/026_issue_p2.md b/devlog/_fin/260919_contract_gap_analysis/026_issue_p2.md new file mode 100644 index 00000000000..68b7985a5ec --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/026_issue_p2.md @@ -0,0 +1,53 @@ +# P2: [Feature]: Derive model selector decode hints from all classified registry identity maps + +### Area + +Catalog / models + +### What are you trying to accomplish? + +Allow an encoded provider/model selector to round-trip when its native model ID is declared only in an authoritative policy map, without falsely publishing that model as available. + +### What prevents this today? + +[src/router.ts:107](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/router.ts#L107) gathers known native IDs from a hand-written subset of model-keyed registry maps. [src/providers/registry/types.ts:169](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/providers/registry/types.ts#L169) declares additional identity-bearing maps. The type system permits an ID to exist only in an omitted map. No specific current production failure is claimed. + +### What should OpenCodex do? + +Classify every registry field whose keys are native model IDs and derive selector decode hints from that classification. Keep decode hints separate from catalog availability and retain ambiguous-selector rejection. + +### Example usage or interface + +A synthetic registry entry contains `vendor/model-a` only in its wire-default map. Its client-safe encoded selector decodes to that native ID. The hint alone creates no new visible catalog row. + +### Alternatives or workarounds + +Requiring every policy key in the static models list would interfere with live discovery. Retaining a partial hand-maintained list leaves future fields easy to omit. + +### Additional context + +Source snapshot: `7864869c31c41cca9830d93540238f17df8faafb` after fast-forwarding `dev` on 2026-09-19. This is source-grounded analysis, not a runtime test result. + +Adjacent closed #4730 concerns catalog slug collisions, not completeness of registry decode hints. Treat this as a bounded robustness proposal, not a live incident. + +### Implementation path + +1. Add `src/providers/registry/model-ids.ts` with a typed classification/helper. +2. Replace the manual map list in `knownModelIdsForProvider` while retaining config IDs, transport identity checks and stale discovered hints. +3. Classify maps carefully: not every object key is a model ID. Make new model-keyed fields require an explicit classification decision. +4. Extend `tests/codex-integration/slug-codec.test.ts` and registry parity coverage using a model present only in each formerly omitted map. Update `structure/catalog.md` and `structure/providers-and-adapters.md`. + +### Acceptance criteria and verification + +- Each classified map independently supplies decode hints. +- Unknown/ambiguous encoded IDs retain current fail-closed or pass-through behavior as applicable. +- Transport-mismatched custom providers do not inherit unrelated registry IDs. +- Decode hints never create catalog rows or availability claims. + +Register new tests in both layout inventories, preserve size caps, and update the existing structure owners. User-facing policy changes need corresponding public documentation and non-contradictory translations. Run focused tests and exact-head hosted CI during implementation; no local suite was run for this analysis. + +### Checks + +- [x] I searched existing issues and documentation. +- [x] This request describes a concrete OpenCodex workflow rather than merely naming a desired technology. +- [x] I removed secrets and personal data. diff --git a/devlog/_fin/260919_contract_gap_analysis/027_issue_v1.md b/devlog/_fin/260919_contract_gap_analysis/027_issue_v1.md new file mode 100644 index 00000000000..f0546dcb67c --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/027_issue_v1.md @@ -0,0 +1,54 @@ +# V1: [Feature]: Separate contract authority from source review fan-out in the structure manifest + +### Area + +Documentation + +### What are you trying to accomplish? + +Let maintainers find one authoritative statement for each cross-cutting contract while still reviewing all documents affected by a source-area change. + +### What prevents this today? + +[scripts/structure-ssot.ts:31](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/scripts/structure-ssot.ts#L31) represents related source paths but no contract owner/dependent distinction. [structure/AGENTS.md:45](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/structure/AGENTS.md#L45) makes every mapped document an update obligation; [structure/INDEX.md:126](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/structure/INDEX.md#L126) maps the broad server area to many documents. Repeated cross-cutting preambles already appear in runtime/config/transport documents. + +### What should OpenCodex do? + +Keep many-to-many source review coverage, add stable contract authority links and distinguish review obligations from actual content changes. Consumer docs link to the owner instead of repeating the same normative prose. + +### Example usage or interface + +A change under `src/server/` still lists every relevant document for review. A named streaming contract points to one owner anchor; only changed dependent explanations need edits. No automatic claim of semantic proof is made from link validation. + +### Alternatives or workarounds + +A prose-only cleanup is smaller but leaves authority navigation manual. One owner per source directory is explicitly wrong for this repository and is not proposed. + +### Additional context + +Source snapshot: `7864869c31c41cca9830d93540238f17df8faafb` after fast-forwarding `dev` on 2026-09-19. This is source-grounded analysis, not a runtime test result. + +This preserves the existing checker and mutation-tested structural guards. It does not replace structural invariants with runtime-only tests. + +### Implementation path + +1. Add a versioned optional `contracts` section in `structure/manifest.json`: stable ID, owner document+anchor, dependent documents. +2. Update `scripts/structure-ssot.ts` parsing, validation and index generation; reject duplicate IDs, missing files/anchors and invalid dependents. +3. Regenerate `structure/INDEX.md`; never hand-edit generated output. +4. Amend `structure/AGENTS.md` to require review of all mapped documents and updates to the owner plus affected dependents. +5. Migrate a few existing duplicated contracts with preserved links before expanding coverage. Extend `tests/ci-workflows/structure-ssot.test.ts` with malformed-manifest and generated-output cases. + +### Acceptance criteria and verification + +- Existing many-to-many source ownership remains accepted. +- Duplicate/missing authority entries fail the checker; valid consumer links appear in generated navigation. +- Unrelated source changes do not require copied unchanged-behavior prose. +- The checker continues to claim topology and declared binding only, not behavioral correctness. + +Register new tests in both layout inventories, preserve size caps, and update the existing structure owners. User-facing policy changes need corresponding public documentation and non-contradictory translations. Run focused tests and exact-head hosted CI during implementation; no local suite was run for this analysis. + +### Checks + +- [x] I searched existing issues and documentation. +- [x] This request describes a concrete OpenCodex workflow rather than merely naming a desired technology. +- [x] I removed secrets and personal data. diff --git a/devlog/_fin/260919_contract_gap_analysis/028_issue_o1.md b/devlog/_fin/260919_contract_gap_analysis/028_issue_o1.md new file mode 100644 index 00000000000..bde55537fc9 --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/028_issue_o1.md @@ -0,0 +1,55 @@ +# O1: [Feature]: Export existing request telemetry through an opt-in metadata-only scrape endpoint + +### Area + +Multiple areas + +### What are you trying to accomplish? + +Integrate existing logical-request, physical-send, terminal and latency facts with operator monitoring without reading raw request history or exporting private identifiers. + +### What prevents this today? + +[src/usage/log.ts:274](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/usage/log.ts#L274) already stores bounded operational facts, and [src/server/management/routing-analytics-routes.ts:24](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/server/management/routing-analytics-routes.ts#L24) serves JSON analytics. The pinned tree has no standard scrape exporter. The gap is export format and bounded aggregation, not absent observability. + +### What should OpenCodex do? + +Add an opt-in management-plane text exposition endpoint with documented counter/histogram lifecycle. Reuse existing completion/attempt facts, keep labels closed and bounded, and preserve independent management authentication. + +### Example usage or interface + +An operator scrapes aggregate logical requests, physical sends, terminal outcome counts, duration and TTFT. Protocol/result/recovery class may be labels; request/key/account/model IDs, raw errors, prompts and tool bodies never are. Metric names and route are design proposals. + +### Alternatives or workarounds + +Existing JSON analytics remains valid for interactive use. Raw request labels or scraping historical logs on every poll would make cardinality and cost unbounded. New timing instrumentation is outside this issue. + +### Additional context + +Source snapshot: `7864869c31c41cca9830d93540238f17df8faafb` after fast-forwarding `dev` on 2026-09-19. This is source-grounded analysis, not a runtime test result. + +Closed #1217 owns durable stream-stage attribution and is not reopened. This proposal exports existing facts only; standard GenAI field mapping is deferred until verified. + +### Implementation path + +1. Add `src/server/metrics-registry.ts` with bounded in-memory counters/histograms and explicit restart semantics. +2. Feed it from existing lifecycle/completion/attempt seams in `src/server/request-log.ts`; avoid rescanning logs on scrape. Define incomplete/aborted and missing-TTFT denominators. +3. Add management route in `src/server/management/metrics-routes.ts` and register it in `route-registry.ts`. +4. Wire opt-in config type, validation/defaults, persistence/hydration and startup consumers; default remains off. +5. Add `tests/server/management-metrics-export.test.ts`; update management/config structure owners and `docs-site/src/content/docs/reference/management-api.md`. + +### Acceptance criteria and verification + +- One logical request with retries increments logical count once and physical sends by actual sends. +- HTTP 200 with failed terminal event is not counted as successful completion. +- Management credential required; data credentials do not grant access. +- Canary private strings and arbitrary IDs never appear in output; label series stay bounded. +- Disabled mode adds no exporter timer/network activity; restart/reset semantics and units are documented. + +Register new tests in both layout inventories, preserve size caps, and update the existing structure owners. User-facing policy changes need corresponding public documentation and non-contradictory translations. Run focused tests and exact-head hosted CI during implementation; no local suite was run for this analysis. + +### Checks + +- [x] I searched existing issues and documentation. +- [x] This request describes a concrete OpenCodex workflow rather than merely naming a desired technology. +- [x] I removed secrets and personal data. diff --git a/devlog/_fin/260919_contract_gap_analysis/029_issue_o2.md b/devlog/_fin/260919_contract_gap_analysis/029_issue_o2.md new file mode 100644 index 00000000000..310240ef0f2 --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/029_issue_o2.md @@ -0,0 +1,54 @@ +# O2: [Feature]: Preview integration mutations using the server ownership plan + +### Area + +Dashboard + +### What are you trying to accomplish? + +Review which managed configuration fields will change before applying, overwriting, disabling or restoring a client integration. + +### What prevents this today? + +Existing writers already snapshot, classify foreign edits, publish atomically and journal recovery. [src/server/management/integration-routes.ts:108](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/server/management/integration-routes.ts#L108) exposes mutation controls, while [gui/src/pages/integrations/RestoreDialog.tsx:137](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/gui/src/pages/integrations/RestoreDialog.tsx#L137) shows generic consequences rather than the exact bounded planned paths. + +### What should OpenCodex do? + +Offer a read-only plan from the same server-owned classifier/writer used by mutation. Show change kinds and safe managed paths, never raw before/after values. Bind confirmation to a fingerprint and re-read at commit. + +### Example usage or interface + +Preview reports that a managed provider URL field will be changed and a snapshot will be created, with a foreign-edit status. If a user edits the file before confirmation, mutation rejects or requires a fresh preview instead of applying the stale plan. + +### Alternatives or workarounds + +Raw unified diffs can expose credentials/private settings. Client-side inference duplicates server authority. Existing status remains useful but cannot show operation-specific consequences. + +### Additional context + +Source snapshot: `7864869c31c41cca9830d93540238f17df8faafb` after fast-forwarding `dev` on 2026-09-19. This is source-grounded analysis, not a runtime test result. + +This is a reviewability enhancement, not a claim that takeover/restore or transactional recovery is missing. + +### Implementation path + +1. Extract a pure planning seam in `src/integrations/plan.ts` around existing ownership classification. +2. Add authenticated preview routes and bounded response types in `src/server/management/integration-routes.ts`/`route-registry.ts`. +3. Carry operation+fingerprint from preview response through `gui/src/pages/integrations/integration-api.ts` into existing confirmation dialogs, then validate on mutation. +4. Reuse existing snapshot/rollback/foreign-edit code; do not create a second client-side planner. +5. Add read-only, privacy and stale-preview regressions; update `structure/clients/integrations.md`, management owners and the existing integration guide. + +### Acceptance criteria and verification + +- Preview performs no config writes, snapshot creation, secret rotation or journal mutation. +- Returned paths are from an allowlisted managed schema, bounded and value-free. +- Unchanged state: confirmed plan matches applied mutation. Changed state: safe refusal/recompute. +- Existing rollback, restore, overwrite and foreign-edit semantics stay intact; dialogs explain the state. + +Register new tests in both layout inventories, preserve size caps, and update the existing structure owners. User-facing policy changes need corresponding public documentation and non-contradictory translations. Run focused tests and exact-head hosted CI during implementation; no local suite was run for this analysis. + +### Checks + +- [x] I searched existing issues and documentation. +- [x] This request describes a concrete OpenCodex workflow rather than merely naming a desired technology. +- [x] I removed secrets and personal data. diff --git a/devlog/_fin/260919_contract_gap_analysis/030_issue_d1.md b/devlog/_fin/260919_contract_gap_analysis/030_issue_d1.md new file mode 100644 index 00000000000..fb02c2460cf --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/030_issue_d1.md @@ -0,0 +1,34 @@ +# D1: [Docs]: Align SOCKS5 HTTP/SSE routing documentation with configured outbound fetch + +### Documentation problem type + +Incorrect documentation + +### Documentation location + +`docs-site/src/content/docs/reference/proxy-formats.md:257` and `docs-site/src/content/docs/reference/configuration/providers.md:514` + +### What is wrong or missing? + +The proxy-format guide says HTTP/SSE does not use ALL_PROXY, and provider configuration says applicable ALL_PROXY retains native fetch. [src/lib/proxy-env.ts:89](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/lib/proxy-env.ts#L89) selects the built-in SOCKS tunnel for SOCKS5 ALL_PROXY. The server configuration guide already describes that behavior. + +### What should the documentation explain instead? + +Distinguish HTTP(S) proxy handling from the SOCKS5 selection branch. Describe NO_PROXY exclusions, existing precedence and supported coding/protocol limits accurately. + +### Suggested wording or example + +“When configured outbound fetch selects an explicit SOCKS5 proxy or SOCKS5 ALL_PROXY and NO_PROXY does not exempt the target, HTTP/SSE uses OpenCodex’s built-in tunnel. Scheme-specific HTTP(S) proxy settings retain their separate documented behavior.” Verify surrounding precedence text against the actual resolver. + +### Additional context or attachments + +Pinned source: `7864869c31c41cca9830d93540238f17df8faafb`. Static documentation/source comparison only; no runtime test result is claimed. + +Update all four English source pages: `docs-site/src/content/docs/reference/proxy-formats.md`, `docs-site/src/content/docs/reference/configuration/providers.md`, `docs-site/src/content/docs/reference/adapters.md:135`, and `docs-site/src/content/docs/guides/providers.md:975`, plus every translated copy of the contradicted statements; cross-link the correct server configuration section. No runtime change or new behavioral test is needed. Use a text consistency scan plus docs build/hosted checks during implementation. Related #2894 and merged #4986/#5070. + +### Checks + +- [x] I searched existing documentation issues. +- [x] No secrets or personal information are included. + +Coordination: inspect open #3901 before implementation because it touches provider documentation and transport. Preserve its applicable changes and avoid a conflicting duplicate patch. diff --git a/devlog/_fin/260919_contract_gap_analysis/031_issue_d2.md b/devlog/_fin/260919_contract_gap_analysis/031_issue_d2.md new file mode 100644 index 00000000000..a3413e80f74 --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/031_issue_d2.md @@ -0,0 +1,32 @@ +# D2: [Docs]: Correct apiKeys documentation to preserve management/data-plane separation + +### Documentation problem type + +Incorrect documentation + +### Documentation location + +`docs-site/src/content/docs/reference/configuration/server.md:27` and translated copies + +### What is wrong or missing? + +The apiKeys row says generated credentials authorize management and data-plane auth. Runtime rejects data credentials as management tokens: [src/server/management-auth.ts:207](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/server/management-auth.ts#L207). The canonical management reference and [tests/server/server-management-auth.test.ts:780](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/tests/server/server-management-auth.test.ts#L780) already establish independent planes. + +### What should the documentation explain instead? + +Describe generated apiKeys as data-plane admission credentials only and link the separate management credential instructions. This corrects prose; no authentication behavior changes. + +### Suggested wording or example + +“Generated data-plane admission credentials. They do not authorize management APIs; management access uses its separate credential.” Preserve documented local listener exceptions rather than broadening either plane. + +### Additional context or attachments + +Pinned source: `7864869c31c41cca9830d93540238f17df8faafb`. Static documentation/source comparison only; no runtime test result is claimed. + +Correct the English row and all seven translated copies carrying the same statement; link `reference/management-api.md`. Confirm by text scan and documentation checks. Existing runtime integration coverage is sufficient; do not alter auth code or add implementation-mirroring tests. + +### Checks + +- [x] I searched existing documentation issues. +- [x] No secrets or personal information are included. diff --git a/devlog/_fin/260919_contract_gap_analysis/032_issue_d3.md b/devlog/_fin/260919_contract_gap_analysis/032_issue_d3.md new file mode 100644 index 00000000000..86da7f3211a --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/032_issue_d3.md @@ -0,0 +1,32 @@ +# D3: [Docs]: Bind core/Lab isolation and synchronous activation in the invariant index + +### Documentation problem type + +Incorrect documentation + +### Documentation location + +`structure/overview.md:90`, `structure/adapters/compatibility-lab.md`, `tests/lab/core-lab-boundary.test.ts` + +### What is wrong or missing? + +The root agent guidance declares core/Lab import isolation and synchronous activation non-negotiable, and a transitive mutation-tested guard exists, but the overview invariant index has no corresponding stable binding. [tests/lab/core-lab-boundary.test.ts:20](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/tests/lab/core-lab-boundary.test.ts#L20) and [tests/lab/core-lab-boundary.test.ts:991](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/tests/lab/core-lab-boundary.test.ts#L991) already own enforcement. + +### What should the documentation explain instead? + +Add a stable invariant ID tying both guarantees to the existing guard, with a backlink in the test and a link from the Lab contract document. Preserve the guard and its current negative coverage. + +### Suggested wording or example + +“INV-LAB-01: the protected core entrypoints cannot reach optional Lab runtime imports; gated Lab activation remains synchronous before startServer returns.” Check that this ID is unused before implementation. + +### Additional context or attachments + +Pinned source: `7864869c31c41cca9830d93540238f17df8faafb`. Static documentation/source comparison only; no runtime test result is claimed. + +Update `structure/overview.md`, `structure/adapters/compatibility-lab.md` and an existing test comment/describe label. Use the existing invariant binding checker and focused guard in implementation; no new runtime mechanism is needed. Closed #4704 hardened the guard, not this documentation binding. + +### Checks + +- [x] I searched existing documentation issues. +- [x] No secrets or personal information are included. diff --git a/devlog/_fin/260919_contract_gap_analysis/033_issue_r1.md b/devlog/_fin/260919_contract_gap_analysis/033_issue_r1.md new file mode 100644 index 00000000000..4e9ce64a8d6 --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/033_issue_r1.md @@ -0,0 +1,55 @@ +# R1: [Feature]: Complete cross-layer send accounting for pre-output rate-limit replay + +### Area + +Proxy and routing + +### What are you trying to accomplish? + +Finish the explicitly deferred integration between adapter-local pre-output replay and OpenCodex request-wide send accounting, provider pacing and recovery telemetry. + +### What prevents this today? + +Public PR #5041 explicitly lists physical inner replay integration with the shared send budget, provider fetch wrapper and physical-attempt accounting as remaining work. At the pinned source, [src/server/responses/run-turn-execution.ts:162](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/server/responses/run-turn-execution.ts#L162) passes the budget/fetch seam, while [src/adapters/devin.ts:570](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/adapters/devin.ts#L570) does not thread it into the reset-retry wrapper. + +### What should OpenCodex do? + +Admit every actual inference send through the existing shared permit/observer path and count it once. Keep the zero-yielded-output replay boundary, cancellation and server-stated wait semantics unchanged. Reuse current spend reservation/refund and usage settlement semantics rather than adding another local counter. + +### Example usage or interface + +With a fake reset response followed by another attempt, the request-level used-send count and recorded physical attempts match actual fake-upstream sends. A refused next permit emits the existing withheld-recovery reason and makes no further inference request. + +### Alternatives or workarounds + +Removing safe replay discards the shipped recovery behavior. Incrementing budget.used directly misses reservation/observer/refund semantics. An adapter-only cap would preserve separate authorities. + +### Additional context + +Source snapshot: `7864869c31c41cca9830d93540238f17df8faafb` after fast-forwarding `dev` on 2026-09-19. This is source-grounded analysis, not a runtime test result. + +This tracks a remaining item already disclosed in [#5041](https://github.com/lidge-jun/opencodex/pull/5041), not a new broad retry system. #5044/#5056 handle attribution when recovery is withheld and do not complete this adapter integration. Long-wait keep-alives and a cross-transition scheduled-wait allowance remain separate work. + +### Implementation path + +1. Thread `IncomingMeta.sendBudget` and `providerFetch` through `src/adapters/devin.ts`, `src/adapters/devin/cloud-direct/stated-reset-retry.ts` and the inference send in `src/adapters/devin/cloud-direct/chat.ts`. Inventory each actual inference send before choosing permit placement. +2. Acquire/commit/refund through existing `reserveDispatch` semantics exactly once per physical send; do not double-charge the initial outer slot. +3. Extend `src/adapters/base.ts` IncomingMeta callbacks only if needed to share the existing physical-send/recovery contract; wire caller, adapter, callback consumer and usage aggregation together. +4. Preserve auth, selected-account, pacing and no-replay-after-output boundaries. +5. Extend `tests/providers/devin-stated-reset-retry.test.ts`, `tests/providers/devin-stated-reset-hardening.test.ts`, `tests/adapters/adapter-inner-send-budget.test.ts`, `tests/adapters/adapter-inner-send-budget-wiring.test.ts`, and `tests/responses/responses-send-budget-counts.test.ts`; update `structure/adapters/registry.md`, `structure/transports/responses.md` and the adapter reference. + +### Acceptance criteria and verification + +- Shared cap, actual fake sends, per-attempt telemetry and spend settlement agree. +- Refused send performs no inference I/O and records why recovery was withheld. +- Aborted waits and post-output failures never replay. +- Initial send is neither omitted nor counted twice. +- Tests use fake send seams and isolated state; no live account calls. + +Register new tests in both layout inventories, preserve size caps, and update the existing structure owners. User-facing policy changes need corresponding public documentation and non-contradictory translations. Run focused tests and exact-head hosted CI during implementation; no local suite was run for this analysis. + +### Checks + +- [x] I searched existing issues and documentation. +- [x] This request describes a concrete OpenCodex workflow rather than merely naming a desired technology. +- [x] I removed secrets and personal data. diff --git a/devlog/_fin/260919_contract_gap_analysis/034_issue_r2.md b/devlog/_fin/260919_contract_gap_analysis/034_issue_r2.md new file mode 100644 index 00000000000..e795d186847 --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/034_issue_r2.md @@ -0,0 +1,56 @@ +# R2: [Feature]: Make explicit sibling instances honor the spend-ledger topology contract + +### Area + +Service lifecycle + +### What are you trying to accomplish? + +Align the supported local sibling-process workflow with the documented single-writer spend-ledger guarantee when a token ceiling is enabled. + +### What prevents this today? + +Public sibling-start work in #3188 allows an explicitly different port, while [src/lib/spend-reservation-ledger.ts:27](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/lib/spend-reservation-ledger.ts#L27) explicitly limits journal guarantees to one live proxy process. [src/cli/index.ts:413](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/cli/index.ts#L413) retains sibling support. These public topology contracts need an explicit product boundary. + +### What should OpenCodex do? + +Require every process that may initialize, append or compact the shared journal to participate in a state-directory writer lease, or provide a proven cross-process transaction boundary. Prefer a local single-writer lease first. Give a clear second-writer refusal and scalar ownership/health diagnostics. Do not suggest a shared database is necessary for ordinary local use. + +### Example usage or interface + +An operator starts a second explicitly ported instance under the same state directory. With an active enforced ledger owner it is refused clearly; an isolated state directory remains independent. An observe-only process must not write into an enforced owner’s journal merely because its own local config has no ceiling. + +### Alternatives or workarounds + +An append-only lock does not serialize in-memory reservation state and compaction. Silent per-process ceilings weaken the shared-directory meaning. Distributed state is deferred until a real multi-host requirement exists. + +### Additional context + +Source snapshot: `7864869c31c41cca9830d93540238f17df8faafb` after fast-forwarding `dev` on 2026-09-19. This is source-grounded analysis, not a runtime test result. + +This is a supported-topology follow-up to [#3188](https://github.com/lidge-jun/opencodex/pull/3188) and the public single-process limitation in the ledger. #5032 made ceilings configurable but did not change topology. No new bypass reproduction is included. + +### Implementation path + +1. Add `src/lib/spend-ledger-owner.ts` or reuse a compatible process-identity lease primitive after source review. +2. Enforce ownership at the ledger construction/use boundary, covering CLI and exported startServer paths; CLI preflight supplies readable diagnostics but is not the only check. +3. Cover every shared-journal writer, including observe-only mode: permit only one writer unless cross-process serialization is proven. Siblings can retain independent journals/state directories, or explicitly non-writing observation. Enabling a ceiling after observe-only operation must retain or acquire valid ownership before any enforced dispatch. +4. Validate stale process identity beyond PID; refuse uncertain ownership; release on shutdown and every partial-start failure. +5. Expose only initialized/configured/degraded and bounded error counters, never scope/account/request IDs or journal paths. A diagnostic read must not initialize or prune the ledger. +6. Add isolated multiprocess ownership/rollback tests; update runtime/config/Responses structure owners and server configuration docs. + +### Acceptance criteria and verification + +- Two processes cannot simultaneously own an enforced journal. +- Two observe-only siblings and mixed observe-only/enforced siblings obey the same journal ownership rule; enabling a ceiling after observation cannot skip ownership. +- Independent state directories, stale-owner recovery and ambiguous-owner refusal behave explicitly. +- Shutdown and partial startup release ownership; config changes cannot enable enforcement without acquiring it. +- Public guidance distinguishes process restart durability from host power-loss guarantees. + +Register new tests in both layout inventories, preserve size caps, and update the existing structure owners. User-facing policy changes need corresponding public documentation and non-contradictory translations. Run focused tests and exact-head hosted CI during implementation; no local suite was run for this analysis. + +### Checks + +- [x] I searched existing issues and documentation. +- [x] This request describes a concrete OpenCodex workflow rather than merely naming a desired technology. +- [x] I removed secrets and personal data. diff --git a/devlog/_fin/260919_contract_gap_analysis/035_issue_r3.md b/devlog/_fin/260919_contract_gap_analysis/035_issue_r3.md new file mode 100644 index 00000000000..6be879f11f7 --- /dev/null +++ b/devlog/_fin/260919_contract_gap_analysis/035_issue_r3.md @@ -0,0 +1,69 @@ +# R3: [Bug]: Request full replay when a task-scoped continuation cannot be used + +### Client or integration + +Direct HTTP/API client + +### Area + +Proxy and routing + +### Summary + +A task-scope mismatch correctly avoids replaying another task’s state, but removes previous_response_id and continues with the current input. If that input is only a delta, the proxy silently turns it into a fresh conversation. Missing or corrupt state instead asks the client to replay the full conversation. The proposed policy rejects every scope mismatch, including requests that appear to contain full input, because the proxy cannot prove the supplied input is complete. This deliberately changes the historical fresh-start behavior; a caller can retry explicitly without previous_response_id. + +### Reproduction + +Static source trace at `7864869c31c41cca9830d93540238f17df8faafb`; the following fake-upstream regression is the proposed executable reproduction, not a claimed local test result. + +1. In an isolated state fixture, store a response under task scope A. +2. Submit its previous_response_id with task scope B and a delta-only input. +3. Trace expandPreviousResponseInput into the ordinary/combo request paths. Current code strips the ID and continues fresh. Expected: the generic continuation-unavailable response before upstream I/O, allowing explicit full client replay. + +### Version + +7864869c31c41cca9830d93540238f17df8faafb + +### Operating system + +Source review on macOS 27.0; the transport logic is cross-platform. Runtime reproduction has not been executed in this analysis. + +### Provider and model + +Not provider- or model-specific. Use a local fake upstream and no real credentials. + +### Logs or error output + +No live traffic or runtime logs collected. Evidence is the exact source path below. + +### Screenshots and supporting files + +[src/responses/state.ts:1066](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/responses/state.ts#L1066); [src/server/responses/request-prepare.ts:245](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/server/responses/request-prepare.ts#L245); [src/server/responses/core-combo.ts:203](https://github.com/lidge-jun/opencodex/blob/7864869c31c41cca9830d93540238f17df8faafb/src/server/responses/core-combo.ts#L203). Related closed #702 covers expired-state context loss. The mismatch fresh-start behavior was intentional historically; this residual applies the current fail-closed replay principle without replaying foreign state. + +### Redacted configuration + +Use a test-owned continuation store and fake upstream. Set different client-task scopes in the stored entry and request. Do not use a live user home, credentials, SOCKS tunnel or running proxy. + +### Implementation path + +1. MODIFY `src/responses/state.ts`: represent scope mismatch as unavailable replay provenance rather than silently turning the body into a fresh request. Keep foreign state inaccessible. +2. MODIFY ordinary `request-prepare.ts` and `core-combo.ts` consumers to reuse the generic 400 previous_response_not_found shape, preserving the internal reason only for bounded diagnostics. +3. Update current tests that intentionally expect fresh-start behavior; preserve same-scope and valid unscoped compatibility. +4. Cover HTTP/WS/combo entrypoints through the existing replay tests or new sibling files. Update Responses transport and client replay guidance. +5. Record this as an intentional change to the historical fresh-start policy; validate affected client behavior before merge. + +### Acceptance criteria and verification + +- Mismatched continuation + delta returns generic previous_response_not_found with zero upstream sends. +- Response reveals neither stored scope nor foreign-state existence/details. +- A mismatched request carrying apparently full input also gets the same generic refusal; retrying that full input without previous_response_id succeeds. Update the deliberate fresh-start cases in `tests/responses/responses-state.test.ts` and `tests/server/server-combo-failover-e2e.test.ts`. +- Explicit full replay without previous_response_id succeeds normally. +- Same-scope continuation and documented legacy unscoped behavior remain valid. +- HTTP, WS and combo paths produce consistent semantics. + +New test files must be registered in `scripts/test-layout/layout.json` and `tests/fixtures/test-layout-expected.json`; split tests rather than raise file-size caps. Update `structure/transports/inventory.md` and any other owner declared by the manifest. Run focused regressions and exact-head hosted CI in the implementation PR; no passing runtime result is claimed here. + +### Checks + +- [x] I searched existing issues and documentation. +- [x] I removed secrets, tokens, account details, request credentials, and personal data. diff --git a/devlog/_plan/260919_contract_resolution/000_plan.md b/devlog/_plan/260919_contract_resolution/000_plan.md new file mode 100644 index 00000000000..7f8ac58ac9d --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/000_plan.md @@ -0,0 +1,51 @@ +# Resolve the reviewed contract gaps through isolated implementation lanes + +The analysis unit delivered sixteen source-grounded issues and implementation paths. The user now authorizes implementation, scoped no-verify pushes, ordinary dependent PRs, coordinator-owned integration, closure after merge, and heartbeat follow-through. This campaign preserves the accepted boundaries and revalidates each issue against current source before changing it. + +## Loop specification + +Class C3 campaign, with C4 review for affected authentication, spend ownership and enforcement changes. Satisfy-spec loop; no numeric optimization target. First cycle locks this roadmap, audits the two-owner split, creates isolated implementation tasks and registers a real heartbeat. Second host cycle coordinates execution and integration until every scoped issue has a verified outcome. Each implementation owner performs its own docs-first PABCD cycles. + +No local suite, focused test, typecheck, build, installation, or live proxy/service invocation is permitted. Write regressions but execute them through hosted CI. Static text/source inspection, git diff checks, GitHub reads, browser research and no-verify commit/push are allowed. No releases, deployment, branch-protection changes, native-stack registration, unrelated issue expansion or live credential/config changes. + +Tool scope: repository/GitHub operations needed for these issues, isolated worktree tasks and read-only browser convention research. No user-defined resource ceiling; useful parallel review/implementation rounds remain bounded by actual tool capacity and non-overlapping file ownership. No persistent model-routing settings are changed. + +Verifier: task creation receipts and observed startup for handoff; saved current-task automation; later exact-head check-runs, per-layer ancestry, inspected diffs and actual dev landing for integration. A skipped/cancelled/missing check is not a pass. Stop only after all sixteen acceptance contracts are met or a documented issue-specific decision is genuinely needed; never shrink scope to make completion easier. + +Evidence lives in this unit; previous implementation specifications remain in `devlog/_fin/260919_contract_gap_analysis/020_issue_t1.md` through `035_issue_r3.md`. Those documents are a reviewed starting point, not permission to skip fresh source reads. Initial refreshed origin/dev: `4e45e1770f11576cf81bd9b7307d0cbdf628be65`. No matching open PR referenced #5109-#5124 in the refreshed inventory. + +## Ownership and dependencies + +| Lane | Sole issue ownership | File domains and sequence | +| --- | --- | --- | +| Runtime | #5109 #5110 #5111 #5113 #5115 #5122 #5123 #5124 | Raw transport contract, custom input consistency, send accounting, journal ownership and continuation policy. Stack null-body/coding only if a real shared helper dependency exists; upload can stay independent. Keep stream and state changes separate. | +| Policy and operator | #5112 #5114 #5116 #5117 #5118 #5119 #5120 #5121 | Schema reports before reject-lossy policy, static merge parity before consolidation, identity hints separate from availability, authority-map/tooling, optional metrics and pure preview, documentation alignment. Stack by these dependencies; independent docs can land separately. | +| Coordinator | Review, CI, base/merge judgment and issue closure | Workers never merge or close issues. Cross-lane shared test-layout/structure changes are serialized at integration, with no cap increases or dropped regressions. | + +The user chose two different main-task models and a specific subagent model. Runtime/model selection provenance stays in task records rather than public repository artifacts. Workers may use unlimited useful subagent rounds; concurrent workers have disjoint writes and never perform branch-level git operations in parallel on one checkout. + +## Integration policy + +Ordinary PRs/manual chains only. Per-PR CI remains required; the referenced task does not grant a new tip-only skip exception. No blanket skip-ci commits. A simple standalone PR normally squashes; dependent children must be retargeted/restacked after parent landing, retain parent refs while needed, and get fresh head/base evidence. Avoid rebase when the current base is already sufficient. Any required rewrite uses an exact lease on the owned branch, never bare force. + +Follow MAINTAINERS.md. Validate actor/base/head, technical review, required CI and any security review; preserve objections and attribution. The coordinator integrates one lane at a time and checks dev after each landing before landing the next conflicting change. Close an issue only when the accepted behavior is fully on dev, not when a child merged into its parent or a PR merely opened. + +## Files and work phases + +- `010_dispatch.md`: exact handoff scope, acceptance and scheduler behavior for wp1. +- `020_integration.md`: event-driven execution/review/merge/closure procedure for wp2. +- `001_status.md`: actual task IDs, PRs and issue states; updated from live evidence. + +Runtime architecture is unchanged by the coordinator roadmap. Each implementation PR must update all applicable current structure owners and public documentation. Public prose remains English, source-grounded, and free of other repository or review-model attribution. + +## Dispatch audit and current convention proof + +Independent roadmap audit passed after preserving the existing staged analysis, binding exact lane routing in private task configuration, and requiring a reviewed-SHA precondition on every merge write. Public documents intentionally omit routing model attribution. The official [merge command reference](https://cli.github.com/manual/gh_pr_merge) was retrieved with the requested browser research surface on 2026-09-19 (HTTP 200); its `--match-head-commit` description confirms the head precondition. The same reference documents merge/squash and administrator behavior. The flag does not replace required CI, security review, current-base validation or user scope. + +## First-cycle conclusion and next direction + +The roadmap is locked, the two isolated implementation owners are active, and the coordinator heartbeat is registered and verified. First-cycle completion certifies dispatch and continued coordination only; no implementation issue is claimed resolved. The next host cycle consumes this roadmap and the per-issue specifications to review, integrate and close proven fixes. The overall goal remains active, with the user-requested heartbeat providing subsequent wakes between meaningful events. + +Ownership amendment: #5115 moved to the runtime owner after the policy owner confirmed no implementation writer or commit existed. Independent preparation can proceed on current dev because its known-model hint region is unchanged by #5174; final landing remains after #5171 and #5174, with a fresh integration base, reviewed delta and exact-head hosted CI. The two-owner limit, acceptance criteria and execution restrictions are unchanged. + +Independent preparation audit accepted the #5115 ownership amendment: `knownModelIdsForProvider` is byte-identical across #5174, the registry entry type is unchanged by that layer, and the new helper has no static-policy dependency. Expected later overlap is import ordering and line movement; integration must retain both independent changes and obtain new-head hosted proof. diff --git a/devlog/_plan/260919_contract_resolution/001_status.md b/devlog/_plan/260919_contract_resolution/001_status.md new file mode 100644 index 00000000000..3b18bd361f4 --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/001_status.md @@ -0,0 +1,128 @@ +# Campaign status + +Status: ACTIVE. Ten of the sixteen original issues are resolved and closed. Remaining: #5112, #5114, #5115, #5117, #5118, #5123. Supplementary sideband recovery #5161 and send-assertion follow-up #5170 are merged. Runtime ownership #5157, strict-policy child #5167 (report parent #5162 merged), and static-policy resolver/consumer stack #5171/#5174 are under exact-head hosted verification and static review. Latest integration recorded here: #5162 at `8a030721b3ffc909ca7d8b05ca0b7c873c1493a1`. + +## Owners + +| Lane | State | Issues | +| --- | --- | --- | +| Runtime | Active in an isolated worktree | #5109 #5110 #5111 #5113 #5115 #5122 #5123 #5124 | +| Policy and operator | Active in an isolated worktree | #5112 #5114 #5116 #5117 #5118 #5119 #5120 #5121 | + +Private orchestration records retain the actual task handles, model-selection evidence and wake cursors. The current coordinator heartbeat is ACTIVE at a 20-minute interval. It follows the two existing implementation owners; it must not duplicate them. The coordinator owns integration and issue closure. + +## Current evidence + +- The original 24 staged analysis documents remain intact. +- Local suites, focused tests, typecheck, build, install and runtime/service execution remain prohibited. +- The original issue states and every closed issue's landing ancestry were rechecked; see [the acceptance ledger](037_acceptance_ledger.md). +- Remaining work is current-head verification, issue-specific implementation, integration and closure. Dispatch alone is not completion. + +## Issue outcomes + +Closed: #5109, #5110, #5111, #5113, #5116, #5119, #5120, #5121, #5122, #5124. +Open: #5112, #5114, #5115, #5117, #5118, #5123. + +The entries below are chronological historical checkpoints. Their earlier open/closed states do not override the current summary or acceptance ledger. + +## Integration-cycle opening + +Runtime owner has completed its transport source orientation and is reading existing test conventions while independent audits cover larger issues. Policy owner registered a thirteen-phase roadmap, including report-before-enforcement and server-preview-before-client wiring dependencies, and entered its own plan phase. Its one shell quoting failure was corrected by the owner; it is not a blocker. No runtime test was run or claimed. No PR had been reported at that opening observation. + +Independent integration-procedure audit: PASS, no concrete blockers. This authorizes collecting/reviewing delivered PRs under the recorded gates, not merging a future PR without its own proof. Latest scoped PR lookup returned no linked open PR. Both owners remain active; the coordinator awaits their deliverables under the registered heartbeat rather than repeatedly polling GitHub. + +## First delivered PR + +#5125 addresses #5109 at `303e731d04eb00950922ba7d9749875e0a643551`, base dev. It is an ordinary standalone PR. Main diff review and independent regression audit are underway; exact-head hosted CI is running. See `021_pr_5125.md`. Issue remains open. + +#5125 coordinator feedback: fix the new 101 reachability comment/PR prose without expanding upgrade scope; dependent #5111 branch must include the parent correction. Independent regression review remains pending; no repeat CI poll until a new head/actionable result. + +## Current transport stack + +- #5125 / #5109: latest observed head `6557add72b48e91f8fdb5805a82192777b7d3286`, dev base. Parent prose correction is in; test now observes target connection close before fixture teardown. Current-head CI still needs a later result read. Old-head cancellations are supersession, not current failure. +- #5126 / #5111: observed head `161f724361753fb2ad80863ceadb41990b0f024c`, parent base at `4c7fe1e...`; coding review underway. Owner notified to propagate latest parent before merge readiness. Ordinary/manual membership confirmed empty native-stack lookup. +- Both PRs attached to coordinator. No merge/close. Full regression execution remains hosted only. + +#5126 is now REVIEW-BLOCKED at the reviewed head: source/socket errors are relabeled as decoder failures, and two downstream error-category consumers need updates. The owner received exact source locations, distinctions from pre-existing abort debt, and regression requirements. The same independent reviewer is retained for interdiff review after a corrected head. #5125 remains separately eligible for exact-head verification; neither issue is closed. + +Policy lane acknowledged its complete dependency-aware twelve-PR roadmap across the nine owned issues and is drafting detailed per-PR designs with six parallel workers. Runtime lane has source specifications for the remaining state issues and awaits the custom-input implementation. These are observed progress statements, not delivered/verified fixes. + +A targeted pre-publication scan of the policy lane's new convention document found review-routing attribution inconsistent with the user's public-prose constraint. The owner was asked to replace it with neutral role wording and scan incoming worker plans before committing; exact routing remains private task configuration. No main-side edit was made in the owner's checkout. + +Verified wait checkpoint: both native task handles remain active, not stopped. Runtime owner reports custom-input work returned for review and is now correcting both error-category consumers for #5126. Policy owner reports its static-policy designs complete with remaining operator designs under review. These reports do not satisfy merge/issue-close criteria; exact updated heads and hosted results remain required. + +## Verified completed issue + +#5109 CLOSED: #5125 MERGED into dev as `4e7d7132d8f8a7d46e460b48c5104a6d5ced4567`, after all applicable exact-head CI passed and regression execution was confirmed in hosted logs. Closure reread succeeded. Progress: 1 of 16 issues resolved; 15 remain open. Dev post-merge CI is queued in the initial snapshot, so no next overlapping merge is allowed yet. #5126 requires parent alignment plus remaining review fixes. #5127 is independently open for #5110 and has review fixes pending at a newer head. + +## Review and hosted verification checkpoint + +- #5126 at76b226: static corrections passed independent review, but exact-head hosted test2/4 failed one new successful-completion peer-destruction assertion. Owner is investigating lifecycle-versus-oracle semantics with primary evidence; no blind rerun or timeout change accepted. +- #5127 atf18c: type/oracle fixes reviewed; exact null abort reason still needs correction. +- #5129 at641f407: High introduced raw apply_patch prefix mismatch found; owner asked to preserve grammar-specific hold and add the missing routed patch regression. +- #5130 at2e4681: acceptance corrections and explicit WS mismatch/recovery coverage requested; no merge approval. +- CI producers for several campaign PRs and dev remain queued. Runtime owner acknowledged holding additional pushes while continuing static implementation. Policy owner continues audited roadmap work; both task handles are active. + +No further issue has closed. Overall goal remains active in integration/build; no C/D completion claim is justified for the full campaign yet. + +Both owners remain active. Runtime owner is batching received review corrections without adding new CI launches; policy owner completed its audit amendments and is correcting orchestration argument serialization. Coordinator supplied safe argv/attest-file guidance for that tooling friction without altering the child's FSM or verdicts. No stopped-task claim or duplicate task creation was made. + +Policy owner completed its audited roadmap cycle and started the #5120 documentation correction cycle. Coordinator clarified that a genuine docs-only PR may use its normal event-applicable documentation/lightweight checks while full runtime launches are throttled; no CI skip override is involved. Runtime owner is completing coherent review-fix batches, including the missing WebSocket regression, before updated pushes. + +#5134 MERGED to dev as `1b54f2940b038e5aba0665fed2a606e30773dd35` after all applicable docs/structure/aggregate and separate control gates passed at44f8fa1. #5120 closure completed and state reread. Progress: 2 of 16 resolved (#5109, #5120), 14 still open. Prepared #5122 commit90b646c passed independent static fourteen-file review; hosted execution proof and publication remain pending scheduling. #5123 prepared commit remains under independent core/lifecycle review. + +Prepared send-accounting commit90b646c independently passed all fourteen-file static review; publication awaits capacity. Prepared writer-ownership commitbf5feb02 received changes-requested from both private core and lifecycle reviews; owner is amending it before publication. No new claim of enforcement readiness is made. PR #5138 for #5121 is now attached; its three-file diff adds the invariant declaration, Lab contract link and existing test backlink without changing runtime code. + +Current prepared-change review checkpoint: send-accounting commit90b646c is statically approved; writer-ownership commitbf5feb02 remains private and changes-requested pending corrections. PR #5138's invariant binding is source-reviewed and running its applicable checks. Coordinator has explicitly prohibited further partial-job reruns; the existing #5129 attempt2 is observed live/queued and is not restarted merely because observation times out. Runtime owner follow-up instructions are queued through task messaging; a queued message is not claimed as acknowledged until reflected in task progress. + +Runtime dev run35432310593 at52c427 is live and has only macOS2/2 remaining in the current job snapshot. #5130 received a further corrected head a863c4b; same reviewer is checking acceptance and negative cases. #5127 remains exact-head green and statically merge-compatible, pending the prior dev guard. #5138 remains on hosted verification. + +Integration collision observation: dev52c427 run35432310593 was cancelled when another authorized integration advanced dev toe668aa (#5131); new run35434188285 is live/queued. This supersession is not a test failure, but repeated dev movement prevents the recorded post-merge guard from completing. Coordinator read the reference task's idle state and sent one question-only merge-slot coordination message, preserving its work/automation ownership. Requested the current dev run finish before the next overlapping runtime landing. No stale run rerun or other task cancellation was performed. + +#5127 MERGED to dev9824aa55bb0ed5fb27ca92ed0851a2fd5529123c; #5110 CLOSED after proof reread. Progress is now 3/16 (#5109, #5110, #5120), thirteen open. Next merge slot was coordinated with the reference integrator and returned after landing. Only actual acceptance/merge/closure is counted, never prepared commits or queued CI. + +## Monitor recovery + +A peer task reported accidentally deleting this campaign's previous heartbeat. Read-only host inspection confirmed only the reference task monitor remained. The coordinator restored the saved campaign prompt, actual owner IDs and 20-minute schedule using the automation tool. New ID `opencodex-01a0b850`, target this coordinator, ACTIVE status and saved fields were reread successfully. Existing implementation tasks were not restarted. Monitor mutation now explicitly requires checking name, kind and target identity; another task's monitor is never treated as a duplicate by directory order. + +Current reviewer disposition: #5126 c109586 and #5129 b1b604 passed exact interdiff review; both require their own new-head hosted proof and resolved GitHub findings. #5130 hosted old-message expectations were identified exactly and owner is updating only those contract assertions, retaining behavior checks. #5138 6986fc documentation amendments accepted by coordinator; hosted proof and GitHub thread resolution pending. No additional issue closure is claimed. + +Scheduling exception reported by runtime owner: two previously held branches were pushed without a PR, and the writer branch triggered Service lifecycle run35435244324 because that workflow has path-scoped push triggers without a branch restriction. Coordinator did not authorize that hold exception and corrected the assumption that a public branch push is unpublished or required for reviewing local commits. No remote deletion/cancellation was authorized; existing run may finish as evidence, while further writer-branch publication remains held pending exact-commit review. All matching workflows must be inspected before future push scheduling. Reviewers can read unpushed commits from the shared Git object database. + +## Current integration checkpoint + +Independent review accepted #5130 head4209818 as a test-only correction preserving the shared public error contract. #5126 c109586, #5129 b1b604, #5130 4209818 and #5138 6986fc still need current-head applicable macOS/aggregate results; current GitHub review threads are resolved except one documented pre-existing direct-stream grammar limitation on #5129, under coordinator scope disposition. No additional merge or closure is claimed. + +Writer ownership commit1661a920 remains changes-requested after private core and lifecycle review. Concrete corrective requirements were sent to the owner; details remain in ignored scratch. The policy owner was instructed to advance the next audited independent documentation slice while hosted work waits, preserving the current invariant PR head. + +New follow-up #5151 tracks the verified pre-existing direct-SSE reordered/escaped wrapper-key limitation. It is separate from the original sixteen implementation commitments. #5129 review disposition is accepted for its routed scope; exact-head hosted proof still pending. The bug-form chooser was inspected in the browser; submission used the matching form headings and bug label through CLI after the browser radio interaction failed. No duplicate issue was created. + +CI scheduling update: with existing Linux producers drained, one new send-accounting PR for statically reviewed90b646c is authorized for its normal hosted checks. The writer-ownership branch remains review-blocked. Both implementation tasks retain the original no-local-execution restriction and no merge/closure authority. Coordinator verified the current heartbeat remains ACTIVE at a20-minute interval with the correct task target. + +#5126 MERGED as af4f744c75 and #5111 CLOSED after exact-head CI, review and landing checks. Progress:4/16 resolved (#5109,#5110,#5111,#5120). New owned PRs #5152 (send accounting, head90b646c) and #5153 (SOCKS5 documentation, head4a576ba0) are attached and under hosted verification; documentation review dispatched. Corrected writer ownership head5328a723 is under two independent private interdiff reviews. #5129 final independent review is being refreshed before integration despite green hostedCI. + +#5129 MERGED asbb2fa5ab25; #5113 CLOSED after landing verification. Progress5/16. #5130 runtime CI passed; its only current control execution was cancelled, so coordinator verified no live duplicate and reran only run35435033238; attempt2 succeeded. #5138 runtime CI now success. #5153 has two source-confirmed documentation blockers (configured NO_PROXY semantics and adjacent SOCKS fake-IP wording), returned to the owner. + +#5130 MERGED asacd43bf442; #5124 CLOSED after verification. Progress6/16; current cumulative dev tipacd43bf442 is being tracked. #5138 has completed green proof and is undergoing final integration. + +#5138 MERGED as5ce51cb554; #5121 CLOSED after verification. Progress7/16 (#5109,#5110,#5111,#5113,#5120,#5121,#5124). The policy owner may proceed with the next audited authority/policy slice while fixing #5153; one new full-CI lane launch is authorized. #5152 has an actual hosted test3 failure under investigation; no merge approved. + +The reference integrator requested the next slot for #5128 and #5107. Coordinator confirmed no immediate merge candidate remains in this campaign and will revalidate the resulting dev before the next integration. Our current #5152 failure is independently traced to a zero-dispatch fixture and is not attributed to the referenced server-auth fixture issue. + +#5153 MERGED asf117c20d12; #5119 CLOSED after verification. Progress8/16 (#5109,#5110,#5111,#5113,#5119,#5120,#5121,#5124). Remaining #5112/#5114/#5115/#5116/#5117/#5118/#5122/#5123 remain open. Policy owner is moving into contract-authority implementation; runtime owner is investigating fresh #5152 CI and the private ownership API corrections. + +Writer-ownership head86eb1d06 passed the final private identity-boundary review; the owner may publish it for hosted verification. Runtime integration remains held pending the separately assigned sideband failure. #5152 fullCI at225e885 and #5155 fullCI at7d17f497 passed, but each has a valid newer review blocker requiring a corrected head and fresh proof; green old-head CI is not treated as merge readiness. + +Verifiedstate now10/16 CLOSED: #5109,#5110,#5111,#5113,#5116,#5119,#5120,#5121,#5122,#5124. #5116 closed by coordinator after5155 merge6d427233; #5122 closed by otherintegrator after5152 merge26d3a862, thenindependentlyreverifiedandretained. Sixoriginalissues remainopen:#5112,#5114,#5115,#5117,#5118,#5123. Cumulative sidebandruntimefailure and small5152 testfollowup remainseparaterequiredwork. Leasefixtureinventory deliveredforbatchmigration; runtimeowner authorized to rebaseleasebranch onlatestdev beforecoherentverification. + +Verifiedwait: runtimeowner reports fourdisjoint fixturegroups active and firstgroup placementreviewed; policyowner applies the remaining schema-categorysemanticrename aftercorefixreview. CurrentnewPR5161/5162 jobs are live/queued, notcomplete. No additionalissueclosure claimed. + +Sidebanddiagnostic/cleanup PR5161 merged d1745ee7 afterexacthead fullapplicableCI andfinalreview; originalissuecountstill10/16. Campaignsidebandrecoverydeliverablecomplete, broader4997 rootcause remainsseparatelyopen. Currentleasecf496 asyncfinalization/responsecleanup underindependentreview; strictschema parent/child awaitfreshhostedproof. + +2026-09-19T13:40Z: #5170 merged after all applicable hosted checks passed and current dev/head/actor were revalidated; its required follow-up task is complete. #5171 corrected the failing substring assertion at `2fdd21004eb256890ae9d7a54baab6c00653c65d`; this proves whole-policy non-mutation and preserves the legitimate registry-only value. Child #5174 at `7b25d449d9828019de8a9799f51539863d2eec68` migrates actual consumers; two disjoint independent reviews are active. #5157 at `271139883a552f1aac9ce3f847eb94e3327e5efc` cleanup re-review has no blocking finding; one conditional teardown improvement was sent to its owner. Hosted checks are still pending. Heartbeat ownership and ACTIVE state rechecked; no original issue closure claimed. + +Report parent #5162 merged at `8a030721b3ffc909ca7d8b05ca0b7c873c1493a1` after current-head CI and reviews passed. Child #5167 still requires retarget/restack and fresh verification. Original resolved count remains 10/16; #5112 remains open. + +Runtime owner pushed `9e789c1613b22109dd0398e9619be8902bff9662` for #5157: management ACL failure injection is restricted to the token file, the stream retry fixture uses its narrow relay-platform seam, and the direct combo fixture holds a writer lease and drains its response. Assertions and production ownership rules are unchanged in this delta. Independent review and fresh hosted CI are required. Policy owner is implementing #5117 in its isolated checkout while repairing #5174; #5115 and #5118 remain required scope. + +Ownership amendment: #5115 moved to the runtime owner after the policy owner confirmed no implementation writer or commit existed. Independent preparation can proceed on current dev because its known-model hint region is unchanged by #5174; final landing remains after #5171 and #5174, with a fresh integration base, reviewed delta and exact-head hosted CI. The two-owner limit, acceptance criteria and execution restrictions are unchanged. diff --git a/devlog/_plan/260919_contract_resolution/010_dispatch.md b/devlog/_plan/260919_contract_resolution/010_dispatch.md new file mode 100644 index 00000000000..37904afcd95 --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/010_dispatch.md @@ -0,0 +1,12 @@ +# Dispatch two isolated implementation owners and register continued coordination + +Depends on: the completed analysis and current GitHub duplicate scan. No production code changes in this host cycle. + +1. Create two saved-project tasks with environment=worktree, starting at refreshed origin/dev. The existing staged analysis remains untouched in the source checkout. Tasks may read that analysis by absolute path but copy only their relevant sanitized plan into their own worktree before implementation. +2. Pass the exact lane issue roster, ownership, no-local-run restriction, no-verify commit/push authorization, template and attribution rules, cxc-loop requirement, mandatory source/convention research and shared-checkout subagent constraints. Require independent regression review and report exact task worktree/branch and first planned PR boundaries. +3. Name one runtime owner and one policy/operator owner. Each owns its own goal/FSM. The coordinator cannot advance a child FSM. Workers do not merge/close issues or create their own competing coordinator monitors. +4. Register a current-task heartbeat at 20-minute intervals. Preserve the separate reference task's existing monitor. The prompt reads this status record, inspects both tasks through compact snapshots and then current PR heads once per actionable wake. +5. Verify each creation request against the exact private dispatch-routing manifest and record the tool-accepted model plus initial task identity. The runtime/policy assignments and medium-effort worker setting are explicit in that manifest; do not put routing model names in public documents, per user constraint. +6. Confirm actual initial progress with wait_threads, not only creation responses. Record returned IDs/host IDs and observed worktree paths in 001_status.md. If a requested model cannot start, report the exact failure; never silently substitute. + +Acceptance: both requested main-task model selections accepted, separate worktrees exist, initial bounded plans/progress observed, current-task heartbeat created and saved, and source checkout staged analysis preserved. Verification is tool receipts and read-only state inspection; no runtime tests/build are justified for this coordination cycle. diff --git a/devlog/_plan/260919_contract_resolution/020_integration.md b/devlog/_plan/260919_contract_resolution/020_integration.md new file mode 100644 index 00000000000..2909611e5b0 --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/020_integration.md @@ -0,0 +1,76 @@ +# Integrate reviewed issue fixes with hosted proof and close only completed contracts + +Depends on: verified dispatch/heartbeat wp1. Consume the sixteen exact implementation proposals from the completed analysis. Implementers re-read each owned source and nested instructions before modification; they record concrete diff-level plans in their own unit before B. + +On each wake: + +1. Read 001_status and the bound goalplan. Fetch compact task snapshots once and current PR metadata once. An idle owner with actionable assigned work receives a specific follow-up; a running owner is not repeatedly interrupted. +2. Associate every PR with issue, lane, source worktree, base, exact head and scope. Check existing remote work before a new issue implementation. Avoid overlap with the reference task or unrelated authors; coordinate only when a concrete collision appears. +3. Require independent source review and meaningful regression tests for runtime or contract behavior changes. Documentation-only changes use applicable documentation and structure checks. Compare test deletions/names before commits. Check file-size caps, test-layout registrations, exhaustive unions, structure ownership, public docs and attribution. Record forbidden local checks as NOT RUN, never as green. +4. Read direct check-runs on the exact head and applicable workflow graph. Record all required tests/platforms/aggregate jobs and event/ref. Do not treat UI rollup, missing tests, skip or cancellation as success. Diagnose real assertion failures from logs; no arbitrary timeout widening, platform skipping or regression deletion. If cancelled legs poison the aggregate, inspect the workflow and rerun the complete relevant run only when justified; do not repeatedly rerun partial jobs or stale heads. +5. Limit hosted-CI launch pressure. At most one new full run per lane at a time; do not cancel another task's CI. Poll once per PR/head per heartbeat, not every 30 seconds. On rate limit, honor reset/backoff and continue independent static work. +6. Coordinator validates merge policy and exact head immediately before integration. Every merge write MUST use `--match-head-commit ` (or the equivalent API sha precondition), and revalidate that the current base is dev immediately before the write. A changed head/base invalidates the previous decision. Inspect native membership read-only; ordinary/manual chain is the intended topology. Unknown or unexpected membership is a real blocker, not license to dissolve it. Integrate a standalone PR with squash when appropriate; preserve dependent ancestry, retarget/restack children and require new evidence after parent landing. Never delete a parent branch still needed by a child. +7. After each dev landing, verify merged state/SHA and dev CI before the next overlapping landing. Close only issues whose full acceptance list is satisfied on dev, with the PR/commit and verification evidence. Partial fixes stay open. No issue closes on a worker's report alone. +8. Update status/devlog and notify only on meaningful completion, real failure, blocking collision or necessary user decision. If nothing changed, remain silent and wait for the next scheduled wake. When all sixteen issues have verified final dispositions, close the host cycle/goal and pause the heartbeat through its tool. + +Research: existing source and structure owners determine local conventions; missing/current protocol or workflow conventions must be searched and source-opened using the requested browser research skill. Public documentation is evidence only after the relevant page is read. Keep private source material out of public artifacts. + +## Current integration-cycle plan + +Previous cycle concluded that the two owners and heartbeat are active, with no implementation completion claimed. This cycle retains that direction. The runtime owner is examining transport tests while independent audits cover its larger state issues; the policy owner is comparing the nine assigned proposals with current source. No mergeable PR has been delivered yet. + +The coordinator's concrete write set is this unit's status/evidence files plus scoped GitHub PR review/merge and issue-close operations. Source changes remain confined to each owner's worktree and exact issue plan. For each delivered PR, add a record with issue IDs, changed source/test/doc paths, base/head, native membership observation, independent findings/dispositions, applicable CI jobs/run IDs, integration SHA and post-merge state. Refuse the write if any prerequisite is absent. No planned merge is pre-approved by this procedural audit. + +Transport body eligibility precedes shared coding normalization only if the owner actually extracts a shared primitive; upload cancellation is separately reviewable. Source-policy parity precedes static merge consolidation. Schema reports precede stricter admission. Metadata-only export and preview consume existing operational seams and remain separate changes. Document fixes can proceed independently with their source-truth checks. Review every returned layer against the corresponding archived exact-path proposal rather than accepting a batch success summary. + +Current failure signal review: the coordinator friction log contains historical entries from unrelated sessions, not a new repeated failure in this campaign. Do not run any recovery command from those old records. A single failed marker in a running child is not yet a blocker; inspect the actual error only if progress stops or the child reports it. + +## Applicable hosted jobs, observed workflow + +Current `ci.yml:1150-1237` aggregate derives requested jobs from event and path outputs, then requires success for requested jobs and skipped only for jobs the event did not request. For a runtime PR, inspect four general shards, two macOS shards, storage/api/gates/keyring/docker and applicable packaging/structure jobs. The full Windows shard matrix and macOS control are workflow-dispatch lanes in this snapshot, not ordinary-PR jobs; their skipped PR placeholders are not evidence they passed. A docs-only PR may correctly omit runtime jobs while requiring docs/structure and a successful aggregate. Follow the live workflow at the reviewed head and record requested-versus-not-requested explicitly, rather than using a universal name checklist or accepting every skip. + +CI-pressure interpretation: defer additional independent full-run PR launches while capacity is saturated. A statically reviewed batch correcting an already failed or review-blocked PR may still be pushed as one coherent new head, allowing the existing workflow's normal same-ref supersession to retire stale evidence. Do not wait for known-bad old-head jobs merely to free capacity, manually cancel unrelated work, skip checks, or push each small finding separately. This changes scheduling only; exact-head verification requirements are unchanged. + +Current-source correction: never infer rerun requirements solely from the reference task. Exact-head workflow code now explicitly supports latest-job evidence across partial retries. A full rerun is required only if current aggregate/provenance rules demand it or the existing attempt cannot produce valid evidence. In all cases require successful applicable jobs and aggregate at the actual head; cancelled/pending is never success. + +Pre-merge scheduling correction after coordinator agreement and live workflow inspection: push-event dev runs deliberately supersede on later dev commits; cancelled superseded runs are neither passing nor failing regression evidence. Do not make every intermediate dev SHA's full completion an indefinite global merge barrier when reviewed exact-head PR checks are all green and intervening integration changes are inspected. Track each new dev run, stop on genuine regression failures, and require final cumulative tip proof. If a specific integration SHA needs immutable full coverage, use the existing workflow_dispatch isolation after verifying the dispatch ref resolves to that SHA; no CI guarantee is waived. This policy is recorded before the next merge, with no failing regression excused. + +## Cumulative dev proof + +The exact dev9824aa55bb0ed5fb27ca92ed0851a2fd5529123c check-runs endpoint now confirms run35434532056 completed with all applicable producer jobs and aggregate ci successful. The skipped docs/macOS-control/full-Windows entries are event applicability, not execution passes. This closes the previously pending cumulative integration observation after #5127. A branch-filtered runs query returned historical commits, so the coordinator used the exact-commit endpoint rather than treating its branch list as current proof. + +## Latest cumulative integration observation + +Reference integration #5128 advanced dev from5ce51cb554 tof39ba5aad94fe019f2ee9c57398c9f9a436b8116. Its two-file diff changes only the server-auth reset fixture and helper. Prior cohort run35436552876 was superseded: its aggregate log explicitly rejects cancelled requested test/macOS jobs, not a newly observed assertion failure. It is neither passing evidence nor a runtime-regression diagnosis. Current cumulative run35436695398 atf39ba5aad9 is live; no historical rerun was launched. + +## Actual cumulative runtime failure + +Run35436695398 atdevf39ba5aa failed macOS2 job105880533745 on the exact50MiB sideband frame case, server-live.test.ts:662,15.308s (13251pass/23skip/1fail). This is an assertion timeout, not supersession. Docs-only #5153 landed asf117c20d12 before the runtime result completed and changes no runtime code. Further runtime integration is held while ownership of the narrow repair is coordinated. No timeout increase, test deletion, or blind rerun substitutes for a diagnosis. + +Sideband ownership resolved: no duplicate repair exists in the reference campaign. Runtime owner receives this scoped integration blocker with existing phase-timing helper, retained50MiB assertion and unchanged timeout/production limits. Existing issue4997 comments5727773831/5732577461 corroborate prior occurrences in both control and sharded lanes; introductionPR1398 is a distinct history fact. New implementation will be reviewed and verified through hosted diagnostics only. + +## Integration ownership deviation + +Another integrator merged campaign PR5152 at00666fea as26d3a862d6ebfa406701c76a6fbe25570a58ac76 at2026-09-19T11:06:07Z and closed5122 before the coordinator stopmessage arrived. This bypassed this campaigns sole-integration ownership and recordedruntimehold. Coordinator reverifiedactualmerge/issue and independentlyreviewedhead. Retainedthechange because it had scopedreview/exactheadCI and revertingunrelatedsendaccounting would notfix the pre-existing sidebandcase. No rollback or extraissue manipulation requested. Integrator acknowledged futurecampaignPR/issueownership; cumulativeCI and sidebandrecovery remainopen. + +## Fresh cumulative runtime gate recovery + +Exactdev26d3a862d6 completed run35439183186 with allapplicableLinux/macOS/packaging/structure/producers andaggregateCI success. Coordinator re-read exactcommitchecks and macOS2log ratherthan relyingonpeerreport. Latestdev46195ac09b changesonlyissue-translation automation anditstest, so runtimecontentmatches theverified26d3cohort. The earlierf39 sidebandfailure remainsvalidhistorical evidence; currentgreen is not a rootcausefixclaim. + +Decision updatedfromnewexecutionproof: the cumulative red gate has cleared, so eligiblefuture runtimePRs canagain beconsidered ontheir exactheadreview/CI andinspectedunion. DiagnosticPR5161 and issue4997 remainopen forobservability/recoverywork; no failedcheck skipped or oldrun blindlyrerun. Freshfailureswillstopintegrationagain. + +Latestdev118c66a8f4 includesindependentlyowned5141canonical-onlyWSselection and5139imagebounds. LeasebranchsharesWSfixturefile; staticmerge-tree isclean but finalunionneedssemanticreview/hostedproof. No silentoverwrite oroldheadgreen-as-unionclaim. + +Branchprovenanceclarification: referenceintegrator deniescampaignrebase/push; sharedlinkedworktrees sharebranch/stashrefs andGitHubactorisaccount-wide, nottaskidentity. Reflog551a->45bcrebaseconfirmed; exactscopedblobs/ancestryalreadyverified. No rollback/stashoperationperformed; sourcestageddevlogintact. Identityofwriter remainsunprovenfromactoralone, no attributionclaim. + +Background notification reconciliation: four rebase receipts (#4942/#5068/#5069/#5098) report clean replay. The #3025 receipt reports an unresolved Logs.tsx conflict despite command exit 0; the live result file has progressed further than the old completion receipt and still records a conflict. These are separate integration-lane artifacts, outside the sixteen-issue campaign. No branch/ref/worktree mutation was made by this coordinator. Current campaign blocker is instead the new exact-head #5157 Linux failure documented in031_pr_5157.md. + +Further background receipts: #4989 and #4597 report clean replay. #5009 and #2366 report remaining conflicts despite exit 0; these are not completion proofs. The separate publish pass reports remote-SHA verification for #3709/#4663/#4942/#5068/#5069/#5098, and #5107 closed during replay. These notices do not authorize or establish campaign integration; no unrelated branch mutation was performed. + +Next background receipts: #2366 now reports clean replay at `eec3a8a4663020c4a732ed6a6b6ed04bef32eceb`. #3901 and #4872 remain in documentation conflicts; #3025 progressed to another Logs.tsx conflict. #3983 replay has no content conflict but its diff check reports an extra EOF blank line in src/bridge/diagnostic.ts. These receipts are recorded without conflating replay, push, CI, or integration. No unrelated edits or branch mutations were made. + +Background receipt update: #5009 advanced from a relocated-test conflict to clean replay at `4f338311c4b3bcdb69b490f6dac4500358833978`. #2366 and #4597 publish receipts verify matching remote heads. #4872 advanced to a remaining provider documentation conflict. The remote-state snapshot is timestamped 2026-09-19T12:55:13Z and is historical, not current campaign proof; its old #5157 head must not replace the current reviewed head. No unrelated writes were performed. + +Background receipts now record clean replay for #3901 at `d0da0264e8092f65575b6eb69aa9bc2ee067e9d8` and #3983 at `c25e79ea0d076859aa43f09fd97802e3e7cd79ee` after the whitespace correction. #4989 publication matched remote head `7a8cb1ad286355c5aaefcdd84b16752daad8e849`. The separate consolidation command reports #3389 closed as superseded by #4989, not merged. #3025 still reports a Logs.tsx conflict at a later replay step. These are external lane receipts rather than campaign completion evidence. + +Final background batch in this notification: #4056 reports clean replay at `5eb0d1e311a1c2d5986bcd701711cd007f2090b8`; #4225 still has a compatibility-facade conflict. An older pinned-base check detected concurrent remote changes for #5157 and #5136, and verified an externally updated #5016. The historical pinned-base mismatch is not current mergeability evidence and triggers no automatic overwrite/rebase by this coordinator. Both campaign implementation owners remain active, repairing the separately observed exact-head CI failures. diff --git a/devlog/_plan/260919_contract_resolution/021_pr_5125.md b/devlog/_plan/260919_contract_resolution/021_pr_5125.md new file mode 100644 index 00000000000..5b959850882 --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/021_pr_5125.md @@ -0,0 +1,39 @@ +# PR 5125: raw outbound null-body responses + +Status: review in progress, hosted CI running; no merge authorization yet. + +- Issue: #5109. +- PR: https://github.com/lidge-jun/opencodex/pull/5125 +- Head: `303e731d04eb00950922ba7d9749875e0a643551`. +- Base: `dev` at `4e45e1770f11576cf81bd9b7307d0cbdf628be65`. +- Native membership lookup succeeded with an empty array: ordinary standalone PR. +- Seven changed files inspected: new shared response status helper, two raw transports, a focused new fake-peer regression file, both layout inventories and transport owner documentation. +- Main runtime read confirms the new branch runs before the pinned success stream, adds 205 to SOCKS bodyless handling, preserves representation headers and leaves ordinary 200 behavior unchanged. +- Independent regression-oracle review pending. Verify comments about informational/upgrade reachability separately from the scoped 204/205 fix. +- Current direct exact-head check-run read: all four test shards, both macOS shards, gates, storage policy, packaging smoke and docker smoke still in progress. Several lightweight/structure/keyring/api-usage checks passed. Event-specific skipped jobs are not represented as test passes; applicability follows the actual workflow. Aggregate completion is not yet available. +- Repository permission read confirms maintain/admin capability; current dev ruleset is PR-only with protected deletion/non-fast-forward rules and merge/squash methods. This is not permission to skip technical/CI/security duties. +- Local runtime tests/typecheck/build/install: NOT RUN under user restriction. + +Next: collect independent review, send any concrete corrections to the runtime owner, and reread hosted results on a later actionable wake. Do not repeatedly poll unchanged checks or merge while proof is incomplete. + +## Coordinator finding + +At the reviewed head, new `http-response-semantics.ts:19-21` claims a 101 upgrade is refused before the final decision. `socks5-fetch.ts:592-624` actually stops the informational loop on 101 and reaches the Response construction path. The scoped helper need only define supported final statuses; upgrade support is not requested. Sent the runtime owner a correction to the new comment and repeated PR-body claim, preserving runtime scope and requiring propagation into the dependent coding branch. This is a documentation correctness correction, not a demonstrated new runtime regression. Any updated parent head needs fresh interdiff/CI evidence before merge. + +Independent exact-head regression review returned GO-WITH-FIXES with zero runtime blockers. It confirmed all seven changed files, meaningful real-transport keep-alive fixtures, preserved existing regressions and no runtime execution. The new SOCKS 205 test's title claims tunnel release while assertions only establish status/null body and teardown force-closes peers; requested an accurate title or a real pre-teardown observed-close assertion without fixed sleeps. Existing 204 coverage observes close separately. Both prose corrections were sent to the owner; no CI green claim or merge follows from this static review. + +Parent head advanced to `4c7fe1e7e3491a858d5308aa30cfa7a47dcbce7d`. Exact interdiff from the reviewed head changes only the informational/upgrade explanatory comment; the earlier false early-refusal claim is removed. Runtime and regression logic are unchanged. Fresh CI at this head is required. Child #5126 at `161f724361753fb2ad80863ceadb41990b0f024c` contains this parent (comparison is ahead=1, behind=0) and correctly names the parent branch as its base. + +The direct check-run read for `4c7fe1e...` showed a failed aggregate and cancelled required legs. Before any rerun, PR metadata was refreshed: head had already advanced to `6557add72b48e91f8fdb5805a82192777b7d3286`. The run at the old head is superseded, not evidence of a failing regression on the current head. No stale run was restarted. All prior passing/failed results remain tied to their own SHA; current-head evidence must be collected separately. + +Current-head `6557add...` check-run snapshot: all four general test shards, gates, storage policy, api usage, structure gate, docker smoke, three packaging smokes, keyring legs and lightweight gates succeeded. Both macOS shards remain in progress; aggregate ci has not completed. The event did not request macOS control/full Windows shards/docs build, so their skips are applicability facts rather than passes. Merge remains pending until required macOS and aggregate evidence is complete. No further same-head polling is scheduled before the next actionable heartbeat. + +Read-only review-state snapshot at current head `6557add...`: base dev, not draft, mergeable, reviewDecision REVIEW_REQUIRED, no submitted reviews and no unresolved review threads (pagination complete). Maintainer integration remains an explicit coordinator decision under MAINTAINERS.md, not self-approval. Applicable hosted CI is still a separate unmet prerequisite in the last snapshot; no merge was issued. + +## Landed and closed + +Final preflight confirmed actor maintain/admin permission, current dev base, reviewed head `6557add...`, mergeable/non-draft state and no unresolved review or maintainer objection. All applicable exact-head checks including both macOS shards and aggregate ci succeeded in run `35430059298`. Logs explicitly show transport-null-body regressions passing in Linux test 4/4 and macOS 2/2. + +Coordinator recorded maintainer integration in PR comment `https://github.com/lidge-jun/opencodex/pull/5125#issuecomment-5740379633`, then used squash with the reviewed SHA precondition. Actual merged state and dev tip confirmed merge commit `4e7d7132d8f8a7d46e460b48c5104a6d5ced4567` at 2026-09-19T08:07:26Z. Parent branch retained for #5126. + +Issue #5109 was closed as completed at 2026-09-19T08:08:28Z after landing verification, with proof comment `https://github.com/lidge-jun/opencodex/issues/5109#issuecomment-5740385524`. Initial dev check-runs are queued; hold the next overlapping integration until dev CI outcome is known. Local runtime suites remained NOT RUN. diff --git a/devlog/_plan/260919_contract_resolution/022_pr_5126.md b/devlog/_plan/260919_contract_resolution/022_pr_5126.md new file mode 100644 index 00000000000..25f84d921ce --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/022_pr_5126.md @@ -0,0 +1,52 @@ +# PR 5126: pinned direct content-coding parity + +Status: exact-head source/test review in progress; not approved for integration. + +- Issue #5111; PR https://github.com/lidge-jun/opencodex/pull/5126. +- Head `161f724361753fb2ad80863ceadb41990b0f024c`. +- Base `codex/raw-transport-null-body` at `4c7fe1e7e3491a858d5308aa30cfa7a47dcbce7d`, parent #5125. +- Exact comparison proves child includes the updated parent, ahead 1/behind 0. This is a real null-body-before-coding dependency; native membership is checked separately. +- Seven files: shared coding classifier, pinned decoder/dual byte ceilings, SOCKS classification reuse, focused fake-upstream tests, both layout maps and transport owner documentation. +- Main source review confirms explicit Accept-Encoding preferences survive; actual response coding determines behavior; null-body branch precedes coding; encoded-byte accounting remains and decoded-byte accounting is added. +- Focused tests cover gzip/deflate, logical route parity, stale headers, unsupported/corrupt coding, expansion over the ceiling and explicit preference preservation. No runtime suite was executed locally. +- Independent review is examining source-error/abort classification and cancellation/cleanup. In particular, generic source failures pass through a decoder catch that assigns content_decode_failed; caller behavior must be checked before accepting the new error taxonomy. + +Next: consume independent review; require exact-head hosted proof. Parent landing will change this PR's base, so retarget/restack and fresh evidence are required before dev integration. Do not close #5111 on a merge into the parent branch alone. + +Native membership lookup returned an empty array, confirming an ordinary manual chain. Initial exact-head CI for `161f724...` was running with no failed non-skipped producer observed. Parent subsequently advanced again; old ancestry evidence must not be reused for a merge until the child is rechecked against that latest parent. + +## Blocking review at 161f724 + +Independent review FAIL; coordinator accepts the new source-error regression. `src/lib/pinned-http.ts:78-81` converts any non-PinnedHttpError passing through the decoder pipeline into content_decode_failed, including ordinary socket/source errors that previously surfaced unchanged. The separate post-header abort-identity weakness is pre-existing and is not wholly attributed to this change. + +The extended error union also requires consumer updates: `src/providers/quota/antigravity.ts:199` currently labels every non-output-limit PinnedHttpError as timeout, and `src/lib/lab-live-pinned-sender.ts:35` only maps the old four categories. Sent owner exact findings and asked for complete consumer analysis, preservation of source-error identity, coded reset/cancellation/encoded-cap tests and observed cleanup before teardown. No separate resource leak was proven statically. All seven changed files were covered; tests were not run locally. No merge while this blocker is unresolved, regardless of aggregate CI color. + +## Revised head under re-review + +Head `d7b5c83a018827dcbd86417300ea2e3f55e71c6f` now includes current parent `6557add...` (ahead 2/behind 0). It adds a source-failure attribution stream before decompression and compile-exhaustive quota/Lab mappings. The original-versus-new branch comparison is diverged after parent propagation, so review uses exact old/new blob differences and the full current parent-to-head layer, not a merge-base-relative patch mislabeled as an interdiff. + +Main identified two remaining oracle weaknesses and sent them to the owner for batching: the encoded-cap case has both encoded and decoded sizes above its limit and thus does not isolate the encoded counter; the cancellation case sends the entire coded body and can conflate normal completion with cancellation. Requested deterministic encoded>limit>=decoded fixture and an intentionally unfinished coded response for cancellation. Both are static test-adequacy findings, not executed failures. + +Latest reported head `76b226f40b7baa8d0862c3013b301dcb96733c93` is retargeted to dev at the parent squash merge. It expands the deterministic Lab error taxonomy and adds direct quota/Lab mapping fixtures, plus stronger coded-limit/cancellation cases. Same reviewer is rechecking the full changed value chain and previous findings at this head. No integration verdict yet. + +Independent review of exact dev-to-`76b226...` layer: PASS, all thirteen changed files covered, no remaining findings. Deterministic unreadable_response now maps to existing protocol_failure results; type/serialization/classification consumers were traced. Direct quota/Lab tests cover both new coding cases, encoded-only cap fixture distinguishes its guard, and cancellation holds an incomplete coded response open before observing peer release. Local execution remains NOT RUN. Hosted current-head and post-merge dev proof remain separate gates. + +## Hosted failure after static approval + +Current-head run `35431301737`, test 2/4 job `105866388278`, failed one new case: `tests/lib/pinned-http-content-coding.test.ts:303`, decoded-response successful completion followed by `awaitDestroyed(connection())`, expected true/received false after its bounded wait. The batch reports 94 pass/1 fail. This is genuine hosted evidence, not an old-head cancellation, and prevents integration. + +Owner received the exact assertion/log and must determine whether the source failed its required cleanup or the test incorrectly equates successful HTTP-agent release with peer destruction. Successful keep-alive reuse and mandatory failure/cancellation teardown are distinct contracts. No timeout increase, blind rerun or assertion deletion is accepted without source/primary-contract evidence and a replacement meaningful oracle. Local runtime probes remain prohibited. + +Primary-contract research: the official [HTTP Agent reference](https://nodejs.org/api/http.html#class-httpagent) was searched and retrieved using the requested browser research surface (HTTP 200, 2026-09-19). Its success lifecycle permits either socket destruction or pooling depending on keep-alive policy; `agent: false` changes reuse behavior. This supports separating successful body settlement from mandatory failure/cancellation teardown. It does not prove the exact runtime-specific failure mechanism, and is not authority to alter pooling merely to turn a test green. Owner received the source and that limitation. + +Re-review at `89a8b9b5de8ffa3dbafa0b8fdca683fbf5947e38`: PASS. The invalid gzip and encoded-limit fixtures now keep HTTP responses incomplete before asserting peer destruction. Documentation distinguishes premature termination from normal agent-owned completion. Interdiff is two files, no production changes and no timeout widening. Hosted checks at this corrected head remain required. + +Latest89a8 head now has successful full applicable runtime CI (run35433104226), and clean static merge-tree onto dev9824 preserves the merged upload/null-body behavior. Final review-thread inspection found one unresolved valid test-oracle comment at tests/lab/lab-live-pinned-timeouts:137-141: actual send rejection is matched by shape, but classification uses a separately constructed error. Coordinator requested classifying the captured actual TransportError for unsupported and corrupt cases, then resolving the thread with evidence. No merge while that review item remains open; corrected head needs fresh hosted evidence. A cancelled duplicate enforce-target execution is retained separately from the successful same-head control run, not counted as a pass. + +Review-thread correction head `c10958672e51c50b0966b93f7917d2981553913b` independently passed exact interdiff review: unsupported and corrupt cases now capture the actual sender rejection, verify TransportError identity and classify that same instance. Only the test changed; previous production fixes remain intact. Current-head hosted CI/review-thread closure still required before integration. + +At c109586, hosted Linux test2 job105875367464 and macOS2 job105875367428 logs explicitly show content-coding regressions passing. Full current-head aggregation still waits for macOS1. Static merge-tree onto dev9824aa succeeds with tree6d87698e81077ba4bc600792da6ff77e8082de67; native membership is empty and all review threads resolved. This is preflight evidence, not merge authorization without final green. + +## Verified integration + +#5126 MERGED into dev as af4f744c75e4dd0348b4e497e67db4ac80208e07 at2026-09-19T10:00:37Z, pinned to reviewed c109586. Exact-head run35434708658 and current control checks succeeded; all review threads resolved; maintainer-integration validation passed. Actual dev ancestry and issue5111 CLOSED were reread. All issue acceptance conditions map to the reviewed implementation and observed hosted regressions. No local suite ran. Post-merge cumulative dev execution remains monitored. diff --git a/devlog/_plan/260919_contract_resolution/023_pr_5127.md b/devlog/_plan/260919_contract_resolution/023_pr_5127.md new file mode 100644 index 00000000000..dfe3f147a8b --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/023_pr_5127.md @@ -0,0 +1,25 @@ +# PR 5127: SOCKS upload lifecycle + +Issue #5110, head `4b85ecde0ff3c03c38a66ba523edc4560369d2ce`, base dev `4e45e1770f11576cf81bd9b7307d0cbdf628be65`. Five changed files: SOCKS helper, focused lifecycle regressions, two layout maps and transport owner docs. PR attached to coordinator; no merge approval. + +Main source inspection confirms the response-head read is moved before upload, keeping one socket reader, and stalled body reads/drain waits race the head/abort. The cancel algorithm is invoked without awaiting a potentially non-settling caller hook. Independent lifecycle/oracle review is underway. + +Main identified a likely type-narrowing defect without running typecheck: UploadStep includes drained; read/answered promises are annotated with the full union, so after excluding answered/end, step.value still has a drained alternative. Sent owner exact lines and advised precise race result unions. Also requested upstream-observed first uploaded chunk before triggering the abort fixture, since a source's delivered promise can resolve during initial stream pre-pull rather than actual upload. Await independent source falsification and hosted CI; no local runtime execution. + +Independent review confirmed non-Error abort reasons are replaced by the new helper and the abort fixture does not establish pending-upload state. Coordinator requires both medium findings fixed before integration, alongside the type-narrowing correction. Old-head CI has a failed gates job and superseded/cancelled producers; PR head has already advanced to `606f76bdf9c3af4d02acb1ede627da19fcb7b0e7`, so old results are not applied to the new head and no stale rerun was issued. + +Interdiff to `606f76bd...` fixes the broad UploadStep type by separating body/read and drain race results. It also adds an upstream-observed upload latch before the Error-reason abort case. The valid non-Error reason preservation finding is not addressed by this interdiff and remains pending. This is static re-review, not a claim that current hosted checks passed. + +Independent re-review at `f18c488...` confirms correct type narrowing and upstream-observed abort activation. Strings/objects now pass through, but `signal.reason ?? fallback` still replaces a deliberate null reason, contradicting the new comment. Coordinator requested exact reason preservation and a null regression, including competing socket-reader race semantics. No merge while the declared preservation contract is incomplete. + +Final static interdiff review at `cc8eeab585a7ce175cecf73268a325497c26eaf4`: PASS. Defined abort reasons including null are preserved across competing upload/reader/drain paths; upstream-observed abort activation and string/null/object identity cases are present. Type narrowing remains correct. No local runtime result claimed; applicable exact-head hosted CI and integration with current dev remain prerequisites. + +Exact-head hosted CI for `cc8eeab...` completed with aggregate success (run35432240251); no failed/pending check remained in the final read. Current PR review threads are resolved, no maintainer changes requested, head unchanged and base dev. A static merge-tree against current dev `1b54f294...` resolves cleanly to tree `83070a0c0047a26d8bf155b6a27becef5e049158`, preserving the already-landed shared 204/205 bodyless rule together with the new upload helpers; its dev delta remains only the five scoped files. + +Coordinator still holds runtime integration because the preceding current runtime dev run at52c427 remains live/queued. This is the recorded post-merge guard, not a defect in this now-green PR. No unnecessary rebase, merge or issue closure has occurred while that evidence is pending. + +## Landed and closed + +After explicit merge-slot coordination with the reference integrator, current dev e668aa and its supersession behavior were rechecked. Static integration tree31112244 preserves both existing null-body and new upload behavior, with only five scoped files changed. Final exact-head CI, actor/base/head, no unresolved objections and ordinary membership checks passed; GitHub's temporary UNKNOWN mergeability was re-read as MERGEABLE before any merge command. + +Coordinator recorded decision at `https://github.com/lidge-jun/opencodex/pull/5127#issuecomment-5740735857`, squash-merged with exact SHA precondition, and reread actual dev landing `9824aa55bb0ed5fb27ca92ed0851a2fd5529123c` at2026-09-19T09:22:46Z. Issue #5110 was closed only after that verification, with proof comment `https://github.com/lidge-jun/opencodex/issues/5110#issuecomment-5740742948`. Cumulative dev CI is monitored, not claimed complete. No local runtime checks. diff --git a/devlog/_plan/260919_contract_resolution/024_pr_5129.md b/devlog/_plan/260919_contract_resolution/024_pr_5129.md new file mode 100644 index 00000000000..dd49b8bcbfa --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/024_pr_5129.md @@ -0,0 +1,23 @@ +# PR 5129: shared progressive tool input + +Issue #5113; head `641f407cfb3d13d2a0518d194ea859ea3338059b`; base dev at `4e7d7132d8f8a7d46e460b48c5104a6d5ced4567`. Nine files. Adds a shared freeform-input module, replaces bridge-local implementation and routed decoder, adds focused consistency tests, updates both layout maps and three structure owners. Independent exact-head review assigned. Main is checking whether fallback/raw streaming newly enabled on routed restoration preserves completion semantics, without treating the already documented canonical duplicate-key/late-invalid debt as newly introduced. Hosted proof and review required; no local runtime execution. + +Independent review FAIL at `641f407...`: the shared decoder newly returns raw arguments on routed apply_patch, while the restore hold only covers code-mode exec. Decorated patch delimiter bytes therefore stream before completion normalizes them, violating the prefix contract. Existing new test helper constructs exec only and misses this introduced path. Coordinator accepted the finding and requested a grammar-scoped apply_patch hold plus split-input done/item/terminal regressions. The fallback valid-JSON concern was falsified: another field cannot be appended inside an already parsed complete valid object, so the remaining case is the explicitly documented late-invalid class. + +Base metadata and head are siblings after #5125 landed; the actual nine-file PR layer is measured from merge-base `4e45e177...`. Do not interpret sibling-base null-body changes as deleted by this PR. Integration later must preserve them explicitly. + +CI attempt integrity: run `35432239071` atbb430bf is now attempt2 after the owner reran only cancelled macOS 2/2. Job inventory shows attempt1 macOS cancellation and aggregate failure, with only macOS queued in attempt2. Coordinator instructed no further partial retries and is diagnosing the cancelled job. A partial retry is not accepted as complete current-attempt coverage; any final full rerun decision remains bound to this unchanged head and actual workflow rules. + +Cancelled-job log inspection: the first macOS 2/2 attempt ran about twenty minutes and stopped emitting output in an unrelated client-connect test after 08:38:40Z, then reported operation cancelled at08:56:07Z. No assertion failure appeared. This is a running-test/subprocess stall observation, not a mere runner-queue delay. Owner was told not to alter unrelated tests or widen timeouts; partial-attempt results remain insufficient for final aggregate proof. + +Correction after exact-head workflow inspection: the historical reference-task claim that every partial retry requires a full workflow rerun is stale. `ci.yml` atbb430bf explicitly uses latest-job results to support partial reruns. Attempt2 is not intrinsically invalid; accept only fresh successful applicable latest jobs plus successful aggregate on the same head. No extra full rerun will be launched merely to satisfy the earlier incorrect coordinator assumption. The original cancellation/stall still needs diagnosis if it recurs. + +Latest control-character correction head `b1b604e14cfacf7f1efe5f5b6566b89f165a08bc` independently passed exact interdiff review. Literal JSON U+0000-U+001F controls cause the shared preview decoder to hold; escaped controls and external whitespace remain unchanged. The one-chunk malformed wrapper fixture proves this case only, not a universal partition-independent no-preview guarantee. Previously documented late-invalid-prefix limits remain explicit; the earlier apply_patch hold remains fixed. + +## Pre-existing direct-bridge limitation disposition + +Independent exact-base review confirmed reordered/escaped wrapper property names already behaved this way at4e7d713: the bridge literal matcher/raw return differs from completion JSON parsing. The routed restoration suppresses these unchanged object prefixes, so this does not invalidate #5113 acceptance. Follow-up #5151 records bounded object-scanning implementation and split/ambiguous-object/budget acceptance; the review thread is resolved as separately tracked, not falsely fixed. Official RFC8259 was retrieved with HTTP200 through the requested browser research surface on2026-09-19. + +## Verified integration + +Final independent nine-file review PASS atb1b604; hosted run35434780189 applicable producers and aggregate success with all10 new cases observed in macOS logs. All threads resolved, maintainer preflight passed, merge-tree on devaf4f744c was clean, native membership absent. PR5129 MERGED asbb2fa5ab25d65a4e5fbab9253f5cc750cbbf2dcf at2026-09-19T10:03:30Z. Dev ancestry and issue5113 CLOSED reread. PR description corrected to acknowledge the intentional literal-control rejection rather than claiming byte-identical extraction. diff --git a/devlog/_plan/260919_contract_resolution/025_pr_5130.md b/devlog/_plan/260919_contract_resolution/025_pr_5130.md new file mode 100644 index 00000000000..7bef1704004 --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/025_pr_5130.md @@ -0,0 +1,15 @@ +# PR 5130: explicit full replay for scope mismatch + +Issue #5124; head `2e4681f0d15e3683f367b7773ce6a87abe4c7d59`; base dev at `4e7d7132d8f8a7d46e460b48c5104a6d5ced4567`. Nine files. Records internal scope_mismatch failure rather than removing the continuation ID, ordinary/combo consumers return the generic replay error, and EN/KO/structure documents describe the intentional all-mismatch policy change. HTTP delta refusal and combo full-input retry/same-scope/legacy cases are added. Independent review assigned; main asks whether WS activates the same mismatch in actual regression coverage and whether shortened existing assertions preserve all prior isolation/projection guarantees. No foreign scope enters response text in the inspected diff. No merge or test pass claimed. + +Independent review requires additional acceptance corrections before integration. The owner received the required changes and will return a revised exact head. Explicit WebSocket scope-mismatch activation and no-ID recovery coverage are still required; existing expired/missing WS cases do not activate this new path. The removed shorter assertions were traced to equivalent remaining behavior checks and were not treated as lost regression coverage. No merge approval or issue closure. + +Final static review at `110ea92ea1f828c124196a18ef8d346959c2127b`: PASS. Real missing spill, corrupt spill and mismatched live-state cases traverse the same public route with exact envelope/body equality and zero upstream requests. Known mismatch refusal, legitimate unknown native continuation, explicit WS mismatch/recovery, combo and legacy behavior remain covered. No runtime test result is claimed until exact-head hosted CI is read. + +Hosted run35434598909 at110ea failed two existing message assertions: issue-702-expired-replay-state:687 expected an expired-specific regex, and plaintext-v2-agent-messages-server:541 expected the previous expired wording. Both received the intentionally unified generic local-replay response. Owner was told to update all exact old-message consumers while preserving status/code/send-count/retention checks; no deletion or vague assertion weakening. New hosted proof is required after the contract-aligned fixture update. No local runtime execution. + +Head4209818e998d716273fe44382278a0f5f002a739 independently passed interdiff review: old-message fixtures now use one literal expected public envelope, preserving original status/code/send/retention/WS behavior assertions. Static merge-tree against dev9824aa is clean (tree46fb12e52fcb08fc81ba0023075539e639c11f92). All GitHub review threads are resolved. Exact-head macOS1 remains pending, so no merge/closure yet. + +## Verified integration + +Head4209818 completed run35435034056 successfully. Only current-head control run35435033238 had been cancelled; no live duplicate existed, and its targeted rerun attempt2 passed. All review threads resolved and explicit technical/security review accepted. Static merge onto devbb2fa5ab was clean; native membership absent; maintainer preflight passed. PR5130 MERGED asacd43bf442c62b115cb2d1f24da9a3f6239d7826 at2026-09-19T10:06:09Z. Actual dev ancestry and issue5124 CLOSED were reread; HTTP/WS/combo and explicit full-replay acceptance mapped to the reviewed regressions. diff --git a/devlog/_plan/260919_contract_resolution/026_pr_5134.md b/devlog/_plan/260919_contract_resolution/026_pr_5134.md new file mode 100644 index 00000000000..07c32813ac4 --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/026_pr_5134.md @@ -0,0 +1,15 @@ +# PR 5134: data/management credential documentation + +Issue #5120. Head `44f8fa1fdc2e0b0a1047feac21acba6dd691fa77`, dev base `52c427a3d3ec41d813f28a6e394ca39584077a5c`. + +Nine files inspected: exactly the apiKeys table row in English and seven locale copies, plus the docs/release owner sentence. All eight edited rows state data-plane-only admission, preserve the existing non-loopback context and link to separate management credentials. Every linked locale management page exists at this exact tree. Main static review found no actionable defect; no runtime behavior changed. Local docs build/tests were NOT RUN. Initial hosted snapshot has lightweight/changes producers queued; docs build and aggregate must complete before integration. + +The dev base advanced through two separately owned integrations after #5125: coupon reset UI and same-target key retry. Source paths do not overlap this docs-only patch. No reference task's PR or monitor was modified by this campaign. + +Later exact-head snapshot: changes succeeded and normal runtime matrices/storage/gates/docker/keyring/packaging were event-inapplicable and skipped. Required docs site build, structure gate and producer/aggregate work remain queued. Those skips are not runtime pass evidence. The documentation correction remains merge-pending until requested checks finish. + +Run `35432368404` completed successfully: docs build, structure gate, both producers and aggregate ci passed at the exact head. Final merge preflight also verified current actor admin permission, current dev base/head, non-draft mergeability and no unresolved reviews. It nevertheless stopped: the separate PR-control workflow still has resolve-pr pending and has not produced enforce-target. No pending/missing gate was treated as passing; no merge or issue closure was attempted. + +## Landed and closed + +Separate enforce-target also passed. Final actor/base/head/review/thread/native-membership preflight passed; current head remained `44f8fa1...`, ordinary PR, dev base, no unresolved objections. Coordinator recorded maintainer integration at `https://github.com/lidge-jun/opencodex/pull/5134#issuecomment-5740638509` and squash-merged with the SHA precondition. Actual merged state and dev tip confirm `1b54f2940b038e5aba0665fed2a606e30773dd35` at 2026-09-19T09:01:26Z. Issue #5120 closure was performed only after that verification. No local runtime execution. diff --git a/devlog/_plan/260919_contract_resolution/027_pr_5138.md b/devlog/_plan/260919_contract_resolution/027_pr_5138.md new file mode 100644 index 00000000000..a5249cac074 --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/027_pr_5138.md @@ -0,0 +1,13 @@ +# PR 5138: core/Lab invariant binding + +Issue #5121; head `48f615f1e3eadd15bf26a6e2aec7d99604b6a2cb`; dev base `1b54f2940b038e5aba0665fed2a606e30773dd35`. + +Three-file static review: `structure/overview.md` adds unused stable ID INV-LAB-01 covering transitive protected-core isolation and synchronous activation; `structure/adapters/compatibility-lab.md` points to the same guard and invariant; `tests/lab/core-lab-boundary.test.ts` adds only the reverse identifier comment. Existing runtime guard/assertions and layout registration remain intact, and no maintained file cap was raised. Hosted structure binding and applicable runtime jobs are required because the test file changed. Local runtime/structure scripts were NOT RUN. No merge decision yet. + +Exact-head CI completed successfully, but final review-thread inspection found two valid unresolved documentation defects. The new wording claims all transitive runtime reachability is prohibited although firstLabPath skips deferred dynamic edges and the management API intentionally loads Lab handlers by namespace; wording must match eager/static closure plus direct dynamic-import checks. The new server activation contract also lacks src/server ownership in this document's manifest entry. Owner was asked to correct wording, update ownership and regenerate the index canonically, preserving runtime scope and guard behavior. No merge despite green CI until findings and new-head verification are resolved. + +Revised head `6986fc6b2391f9b07dc6587e094aea95377c6ca8` addresses both findings. The invariant distinguishes static/side-effect/re-export load-time closure, separate direct dynamic imports and sanctioned deferred namespace activation. The Lab manifest now explicitly owns `src/server/index.ts` (precise source path), and generated INDEX reflects that link. Main read the exact diff and corresponding guard; no runtime guard/assertion was weakened. New exact-head hosted checks and resolved review state remain prerequisites. + +## Verified integration + +All applicable head6986fc6 checks and aggregate passed in run35434996760; both review threads resolved; source/test/manifest/index final diff reviewed with no runtime guard change. Maintainer preflight and clean merge-tree onto devacd43bf passed. #5138 MERGED as5ce51cb554b333c9b369baf1b15b5d04047c85b4 at2026-09-19T10:07:45Z. Actual dev ancestry and #5121 CLOSED reread. diff --git a/devlog/_plan/260919_contract_resolution/028_pr_5152.md b/devlog/_plan/260919_contract_resolution/028_pr_5152.md new file mode 100644 index 00000000000..99b34104181 --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/028_pr_5152.md @@ -0,0 +1,31 @@ +# PR 5152: physical inference-send accounting + +Issue #5122; ordinary dev PR, head90b646c21c694b585dfed319af705075b8e578b4. Fourteen-file independent static review passed before publication. The adapter physical-send observer reaches initial and internal replay sends, shares existing permit/refund/pacing and identity accounting, and preserves prior retry response on denied replay. No new budget owner is introduced. Tests cover refusal, permits, retry safety and accounting wiring. + +Current exact-head hosted test3/4 failed. The coordinator is inspecting its assertion log; runtime macOS checks remain in flight. No local execution, merge approval or issue closure is claimed. + +Failure located in run35435976658/job105878594551: responses-send-budget-counts.test.ts:133 expected one GetChatMessage dispatch, observed zero (295pass/1skip/1fail). The owner received exact evidence and must trace admission/route/fixture activation before the fake executor, preserving the physical-send assertion. No assertion deletion or blind rerun is accepted. + +macOS2 job105878594526 confirmed the same zero-dispatch failure and a second exact-frame sideband timeout (20s limit,23.884s observed). Coordinator assigned a separate static lifecycle/oracle RCA. The newly landed server-auth reset fixture fix does not address this sideband case, and no timeout widening or flaky-test label substitutes for verification. + +Fixture correction head1d92134160c47625cf71804fa327986e7e115b5f adds explicit authMode:key, matching the test-owned API credential instead of inheriting the registry OAuth requirement. The observed13ms zero-send failure occurred before adapter entry. Both chatCalls1 and totalSends1 are retained in one equality assertion with bounded status/body diagnostics. Only the test fixture changed; fresh hosted proof and independent interdiff review pending. + +Independent interdiff review at1d921341 PASS: explicit key auth overrides the registry OAuth default correctly for the fake credential, and both exact count assertions remain. New-head hosted CI remains required. + +Hosted run35436798014/job105880777459 at1d921341 disproved the fixture activation assumption: same exact count assertion still sees zero sends, and the new diagnostic identifies HTTP401 authentication refusal. The explicit key-auth change was insufficient to reach the adapter. Owner is tracing the real isolated OAuth fixture path before the next update. Independent static approval did not prove runtime activation; the failure remains blocking. + +Second correction225e88536938c8eeea71df98119a9985f86fe2f1 uses the actual stored test credential in isolated OPENCODEX_HOME. Independent review traced registry OAuth resolution into the adapter, catalog identity and fake fetch interception; cleanup and exact count assertions remain. Static PASS, hosted activation proof still pending. + +Fresh execution evidence: run35437138983/test1 job105881685464 at225e885 explicitly reports the initial-send exact-count case PASS(43.21ms). This confirms the corrected stored-credential fixture reaches the intended send path. Full current-head/macOS/aggregate proof and the separate cumulative sideband blocker remain open. + +Final GitHub review surfaced a separate production accounting blocker: run-turn-execution observes the logical first send before physical budget admission, while the inner observer ignores ordinal1. A denied initial reservation can therefore increment physical-send accounting without invoking the executor. Coordinator confirmed ordering and requested admission-bound first-send observation plus a zero-additional-send exhausted-budget regression; independent value-chain review pending. Green fixture/CI does not dismiss this finding. + +Interdiff225e885..c4cdd005 source deferral is statically well placed: only adapters declaring physical-send reporting suppress eager first observation. However independent review FAILs test adequacy: new directadapter zero-callback test bypasses the original outer counting path and can pass with the old bug. Owner must exercise actual request/runTurn logging and exact refusal, not a blanket-catch zero-only assertion. + +Outer-test revision14cdcc765 reaches handleResponses but does not actually exhaust the two-target combo allowance: one admission remains for the first inner send. It also permits an absent attempt through optional fallback and does not assert exact refusal. Independent review requests explicit exhausted realbudget injection at the request boundary, a present zero-send attempt, exact429/code and zero executor calls. Production deferral remains accepted; test activation remains blocking. + +00666fea independent interdiffPASS: explicit exhausted realbudget flows through public handleroptions, knownDevinattempt exists and remains0, executor0,total0; old225e eagerly logs1 and wouldfail. Correct nonstream contract is HTTP200 carrying failedresponse and request_send_budget_exhausted, not an assumed HTTP429. Auth fixture cleanup preserved. Newhead hostedproof pending. + +## Verified external integration + +Another integrator merged reviewed00666fea as26d3a862d6ebfa406701c76a6fbe25570a58ac76 andclosed5122 before the coordinator stopmessage arrived. Coordinator re-read actualmerge/devancestry/issueclosure and exactheadCI35438374391 success; hostedlogs show initialcount and exhaustedfirstsend regressions passing. Retainedimplementation after verifying its separation from sidebandfailure; see020_integration.md for ownership/holddeviation. Initialphantomcount reviewthread resolved withfixevidence. Separateminor directadapter rejectionassertion strengthening remains as a test-onlyfollowup; HTTP429 suggestion was rejected because actualbufferednonstreamcontract isHTTP200 failedbody. No unresolved productionaccounting defect is claimed. diff --git a/devlog/_plan/260919_contract_resolution/029_pr_5153.md b/devlog/_plan/260919_contract_resolution/029_pr_5153.md new file mode 100644 index 00000000000..53486cd7635 --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/029_pr_5153.md @@ -0,0 +1,14 @@ +# PR 5153: SOCKS5 documentation alignment + +Issue #5119; ordinary dev PR, head4a576ba0ac619552dd8a0f136ef4a87eb2ef118d. Twelve files: four English pages, seven localized provider-configuration pages and existing structure owner. Independent review returned two blockers, both accepted after source verification. + +1. Server config.proxy is projected into ALL_PROXY, so configured and inherited server SOCKS5 routes both honor NO_PROXY. The wording incorrectly applies that condition only to inherited configuration. RequestInit.proxy is a different per-request override. +2. Adjacent Mihomo IPv6 fake-IP guidance still says ALL_PROXY never counts. Effective routing admits SOCKS5 ALL_PROXY when the host is not exempt; only non-SOCKS ALL_PROXY is excluded. Correct the adjacent paragraph in English and every locale. + +DNS/peer pinning limitations, HTTP/SSE support, WebSocket fallback, config types and translated links were otherwise source-correct. Owner received corrections. No local build/tests ran, and no merge approval is claimed. + +Correction commit7bc014a5a5d39ca81978c0ec2b90772eb03c1a81 is under same-reviewer interdiff review against4a576ba0, covering all affected locales and adjacent fake-IP text. Fresh hosted documentation proof required; no merge yet. + +## Verified integration + +Final interdiff7bc014a5 passed independent review; source spans and all11 corrected pages checked. Remaining fixed review thread was answered with commit/run evidence and resolved. Exact-head35436860842 documentation build, structure and aggregate succeeded; applicable controls succeeded; runtime skips were event-inapplicable. Native membership empty, maintainer validation and clean merge-tree onto devf39ba5aa passed. PR5153 MERGED asf117c20d1244bf20d8cf5bd35de5bb7c71003799 at2026-09-19T10:20:23Z. Actual ancestry and #5119 CLOSED reread. diff --git a/devlog/_plan/260919_contract_resolution/030_pr_5155.md b/devlog/_plan/260919_contract_resolution/030_pr_5155.md new file mode 100644 index 00000000000..64591a8ec2f --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/030_pr_5155.md @@ -0,0 +1,17 @@ +# PR 5155: contract authority registry + +Issue #5116; ordinary dev PR, head7d17f49746c289b46835e0e14495985a4d9b7741. Thirteen files: structure manifest/index/guidance and dependent documents, checker and its existing regression file. The proposal adds optional versioned contract authority separately from source-review fan-out, consolidates repeated paginated-history text and registers byte-accounting authorities. + +Independent review assigned to inspect complete acceptance, authority/anchor/dependent topology validation, generated-index parity, preservation of many-to-many review ownership, regression strength and removal of duplicate normative text. Hosted CI required. Coordinator has not run local generator or suites; owner's canonical-generation claim is distinct from hosted executable verification. No merge approved. + +Independent full13-file review PASS after requirement-based synthesis. Initial reverse-link completeness suggestion was retracted: #5116 explicitly validates declared topology/bindings, while ordinary hyperlinks are not automatically normative dependent membership. All current migrated normative consumers are declared and linked, and source-review fan-out stays separate. Automatically deriving obligations from informational links would expand the contract. No code change was made merely to satisfy that unsupported condition. Hosted current-head proof and final external review remain separate gates. + +Final GitHub review surfaced a valid malformed-generation issue: CLI--fix parses/casts unchecked JSON and invokes renderIndex before loadManifest. Malformed contracts.entries can throw a raw TypeError instead of an actionable schema diagnostic. Owner was asked to validate before render/write and cover invalid--fix with unchanged INDEX plus diagnostic/nonzero assertions. This is separate from the retracted reverse-link policy proposal. No merge while unresolved. + +Correction982ad809 production validation/write order accepted. Independent review still requires a subprocess regression through the actual--fix CLI; helper-only tests do not protect the entrypoint where the original defect occurred. Owner received exact malformed/valid scaffold assertions. No local execution. + +CLI regression36be9dbe passed independent static review: production script copied into isolated scaffold, actualprocess.execPath--fix invoked, malformed contracts produce nameddiagnostic/nonzero/noTypeError withunchangedindex, validcase regeneratesexactindex andexitszero. New-head hostedproof stillrequired. + +## Verified integration + +36be9dbe completed all applicable checks in35438419328; actualCLI regressions passed in job105885044981. Atomicwrite suggestion independently dispositioned as unchanged pre-existing optionalhardening; currentdeclaredtopology contract met. Allthreads resolved, maintainerpreflight/cleanmerge/no-native-stack checked. PR5155 MERGED as6d4272338701a15b0ed2adc3f422f5a7c33fef11 at2026-09-19T11:05:57Z; ancestry and issue5116 CLOSED reread. This tooling/docsintegration did not claim the separate sidebandruntime blocker resolved. diff --git a/devlog/_plan/260919_contract_resolution/031_pr_5157.md b/devlog/_plan/260919_contract_resolution/031_pr_5157.md new file mode 100644 index 00000000000..64884c8a1c0 --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/031_pr_5157.md @@ -0,0 +1,11 @@ +# PR 5157: spend-ledger writer ownership + +Issue #5123 is open. [PR #5157](https://github.com/lidge-jun/opencodex/pull/5157) targets `dev`; its current head is `647dc675019a995b97c73c7b7ce02fe4cebaf5f4`. It has not been integrated and is not approved for merge until exact-head hosted verification and remaining public reviews pass. + +The proposed control requires a single writer for each state directory. Implementation and regression changes have received independent static reviews, including storage, startup/shutdown, fixture lifetime, and current integration compatibility. Detailed security review and historical repair reasoning are retained in ignored task scratch pending a final published outcome. + +The preceding head `271139883a552f1aac9ce3f847eb94e3327e5efc` failed Linux shard 1 in [run 35446241123](https://github.com/lidge-jun/opencodex/actions/runs/35446241123/job/105905603621). The latest two-file fixture correction received independent static PASS. This does not establish runtime success; new-head hosted CI remains required. No assertion, production ownership gate, or file-size limit was relaxed in that correction. + +Local suites, individual tests, typecheck, builds, installation and runtime execution were NOT RUN. Static syntax screens performed during earlier review are not compiler or runtime proof. No issue closure or completion claim is made. + +A subsequent three-file fixture correction addresses platform-specific hosted failures. Independent delta review and current-head hosted CI are running; previous-head successes do not establish the new head. Public status remains open and unmerged. diff --git a/devlog/_plan/260919_contract_resolution/032_ci_sideband.md b/devlog/_plan/260919_contract_resolution/032_ci_sideband.md new file mode 100644 index 00000000000..70083a2883c --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/032_ci_sideband.md @@ -0,0 +1,29 @@ +# Cumulative CI blocker: exact-ceiling sideband relay + +The current integration cohort exposed a repeatable hosted timeout in the exact50MiB sideband frame case. Initial campaign observation: #5152 run35435976658/macOS2 job105878594526, followed by devf39ba5aa run35436695398/macOS2 job105880533745. The latter reports one failure among13251passes, at the test's internal15s bound. Historical occurrence evidence is recorded in issue4997 comments5727773831 and5732577461; introductionPR1398 is separate history. + +The relevant sideband test/relay/handler blobs are unchanged by physical-send accounting. That source trace separates the work scopes but does not dismiss the failed integration gate. Runtime owner owns a narrow diagnostic/repair branch; no duplicate repair exists in the reference integration task. + +Keep the real50MiB bidirectional assertion, production limits and cancellation semantics. Use existing tests/helpers/phase-timing.ts to observe setup, ping, allocation/send, relay/upstream reception, echo and teardown. Always clear the inner timer and client in final cleanup. A diagnostic-only change is not proof the underlying timeout is fixed. Do not increase timeouts, skip platforms or delete assertions merely to get green. + +Primary reference: [Bun WebSocket documentation](https://bun.com/docs/runtime/http/websockets), retrieved HTTP200 through the requested browser research surface on2026-09-19. It distinguishes server-side send backpressure, dropped messages and bytes sent. Instrument send result and drain/close state rather than equating a successful call with peer delivery. This server API distinction does not by itself explain the client-WebSocket relay delay or establish the pinned runtime's exact failure mechanism; hosted stage evidence remains required. No local runtime/probe/suite was executed. + +Initial diagnostic96316e14 rejected beforepublication: phaseTimer had no probe/progressupdates and alwaysreported moving=no; ceilingphase conflatedallocation/send/relay/echo; earlyclose had noguard. Cleanup direction preserved, but comments claiming23s cause were unsupported. Owner is rebuilding with a focused helper and observable progress, preserving originalassertion/limits. Independent review confirms these findings; no diagnosticCI launched on inadequate evidence. + +Rebuilt2a3b3a9 adds a boundedpeerprobe/helper and preserves50MiB/time/headerassertions. Beforehosteddiagnostics, review requires send-return boundary, earlyclose detection through finalACK and precise event-progress limits. Whole-eventcount cannot prove absenceofpartialtransfer. Mockserver sends a short byte-countACK ratherthan50MiBoutboundecho; documentation mustnameactualmeasurement. No runtimefailurefix claimed. + +8d34fc77 passes independentdiagnosticreadinessreview: separateallocation/sendreturn/ACKwait, earlyclose untilfinalsuccess, milestone-onlyinterpretation, boundedprivacy-safeprobes and unchanged50MiB/15s/20s. Onehosteddiagnosticrun authorized. This approval is not rootcauseorperformancefixproof. + +DiagnosticPR5161 published at8d34fc77 andattached, ordinarydevbase, explicitlyRelates4997 withoutclaimingafix. Exactheadhostedtiming evidence nowpending. + +Firsthosteddiagnostic at8d34fc77/run35439343947 succeeded. macOS2: upgrade4.8ms,echo0.5ms,allocation49.7ms,synchronoussend20.3ms,ACKwait6039.4ms,total6220.25ms. One tickappearedat5927ms withoutnewmilestone beforecompletionprogress8. This localizesthatpassingrun toawait/relay/eventloopwindow, notallocation/send; itdoesnotexplainallpriorfailures orproveperformancefix. Finalreviewrequiresoutercleanupboundary include startServerstartupfailure soWebSocketoverride/mockcannotleak. Ownerreceivedcorrectionbeforemerge. + +Startup-boundarycorrectione34aab04 fixes startServerthrowleak. Finalcleanupreviewrequests independentupstreamstop eveniflivestopthrows and movingphasecreationinsideclientcleanupscope. The latterisboundedhygiene, notanobservedruntimecause. Preserveexistingtimings/assertions; consolidatebeforefreshhostedrun. + +Final1f0ab934 cleanupinterdiffPASS: clientphase/timerwithincleanupscope, proxyshutdownfailurestillattemptspeerstop, actualframe/headerassertions/privacy/limitsunchanged. FreshhostedCI authorized. Combinedwithindependentlygreen cumulative26d3runtime, landingtheseproveddiagnostics/cleanup willcompletecampaignintegration-recoverywork; broader4997performancecause remainsopenandisnotclaimedfixedornewunboundedoptimizationgoal. + +Current1f0run35441351500 wascancelledatmacOS1job20mdeadline, after17m44sofnooutputinunchangedcodex-inject-write-lock.test.ts. Noassertionfailureprinted; sidebanddiffonlytest/helperandnotthatpath. Allotherproducerssucceeded. Afterinspectingrun/job/log/sourceequality andconfirmingnolivererun, coordinatorrequestedoneboundedjob-onlyrerun105892583094 withdependentaggregate. Recurrentstallrequiresdedicateddiagnosis,norepeatedblindrerunsorbudgetwidening. Cancelledattemptisnotapass. + +## Delivered diagnostic and integration recovery + +PR5161 MERGED asd1745ee7e8d2189e496f0d8ccdf3580a434791f0 at2026-09-19T12:40:33Z, exactreviewedhead1f0ab934. Currentattempt2 run35441351500 applicableproducers+aggregateSUCCESS, resolvedreviewthreads, maintainerpreflight/cleanunion/no-native-stack verified; actualdevancestryreread. FinalheadmacOSlog shows50MiBcasePASS6810.83ms withphaseevidence (allocation20.6ms,send106.2ms,ACKwait6509.5ms). Broader4997 remainsopen; diagnostic/cleanupdelivery+priorcumulativegreen closescampaignrecoverytaskwithoutclaiminggeneralperformancecausefixed. diff --git a/devlog/_plan/260919_contract_resolution/033_schema_report_review.md b/devlog/_plan/260919_contract_resolution/033_schema_report_review.md new file mode 100644 index 00000000000..462d6c5b2c5 --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/033_schema_report_review.md @@ -0,0 +1,33 @@ +# Initial tool-schema loss report review + +Prepared commitdaae0ee29bf3246f95c7b49f5f5bda8aaf36f90f is the report-only first layer for #5112. It does not complete strict opt-in rejection or compatibility-repair reporting. Source/compiler/tests and documentation are reviewed separately. + +Documentation review covered all18changed docs. Endpoint profiles, privacy boundaries, nativeoutput separation and no broaderdialect claims were accepted. Two corrections requested beforepublication: link/names for existing debug enable/read workflow and diagnosticrecord, and include version/lossy fields in the otherwise-exhaustive reportshape description across8locales. Source review pending; no localexecution or hostedpass claimed. + +Core audit daae0ee2 FAIL: multi-type/unsupportedtype and omitted constraint keywords can change schemas while report remainslossyfalse; numericconst reachedthroughref canbe countedtwice; actualadapter integration matrix coversonlyone endpointmode. Coordinator verifiedcited sanitizerbranches and requested comprehensive bounded semanticloss accounting, exactlyonce refcounts and allthree adapterentry tests, preserving wirecompatibility/privacy/nativeoutput. Avoid unboundednewtraversal solelyforunknownkeywordreporting. No broaderdialect or completedstrictpolicy claim. + +Report-only PR5162 published atdbdbc573 afterrebasingcurrentdev; corecorrectionchanges sanitizer/report tests, andfinalendpoint/docs claims underre-review. Docsfe39eb2f passed8locale discovery/payloadshapereview. Sourcepartialstage doesnotclose5112. CI/publication is not acceptanceproof. + +Corecorrectiondbdbc573 re-review accepts previousmissingclassification/refdoublecount/realendpointmatrix fixes, boundedfixedkeywordprobes, unchangedwirebytes/nativeoutput. Remainingsemanticcategoryissue: a multi-type union collapsing toonesubtype narrowsacceptedvalues, so type-union-widened misdescribesit. Ownerasked torenamecollapsed/narrowed beforecontractestablished andkeepproseaccurate. No need changetransform. + +Final6ce0819958 scopedrename/docsinterdiffPASS. Categorytype/emission/testexpectation agree; transform/compiler/adapter/registries unchanged; eightlocaleguides retainobservation-onlyprivacy/nativeoutput boundaries. CurrentheadCI pending. Owner may prepare auditedstrictpolicy manualchild onthishead, preservingparentandperPRproof; initialreport acceptance doesnotclose5112. + +G1b roadmap revalidation after5155: all source-mapped docs remainreviewobligations, but oldplaninstructions toadd unchanged-boundaryprose everywhere are superseded. Ownerasked toeditactualcanonicalcontracts/affecteddependents and recordreviewed-unchanged evidence, preservingneededlocaleoperatorpolicy updates. Fullstrictconfig/initial/repairchain acceptance remainsunchanged. + +Current6ce0819 had onlycancelledcontrolgate executions andno liveone; coordinator targetedlatest35439892314 forcontrol-onlyrerun. No runtime rerunorcancel requested. Current5161 successfulcontrolruns distinguishitsoldcancelledduplicates. + +FinalGHreview raised newsemanticcases: anyOf canoverwrite siblingconstraintswithoutloss; referenceidentitycomparisonmislabels structurallyequivalentsiblings; inertdefault-valuedconstraints canbespuriouslylossy. Sentownerboundedcomparison/value-awarereportrequirementsandregressions; coreindependentvalidationpending. Strictchildmustinheritcorrectparentreport, withmanualcascadeandfreshproof. No diagnosticsorCIcoloroverrides theseacceptancegaps. + +Independent5ea56 review confirms late-differinglargeenum counterexample: boundedcomparison returnsunknown beforedifference; schema-nodebudgetdoesnotcoverenumvalues; reporthasno uncertaintyflag andstrictchildadmitssilently. Ownerreceivedbounded explicituncertaintyreport/aggregation andstrictrefusalrequirement, withminimalnormalizedtype/enum/required equivalences. No fullJSONSchemaequivalence solver orwirebehaviorchange requested. + +Parent76bbc600 introducesbounded uncertainComparisons count andaggregation pluscanonicalcomparisonchanges. Re-reviewassigned forcomparisonbudget/privacy/semanticaccuracy; strictchild mustexplicitlyrejectnonzero uncertainty beforedispatch. Currentpublicationdoesnotconstituteapproval. + +76bbc parent implementationreview accepts explicitboundeduncertaintyandcanonicalcomparison. Requiredfinishinggaps: late-differing(notidentical) oversizedenumregression andparentdebugconsumer emittinguncertainty-onlyreports. Child11581 addsstrictlossy-or-uncertaincheck/typedindeterminateerror andisunderre-review. Parentmuststandalone exposeitsdiagnostics beforechildlands. + +Parentenumreviewadjudication: target/overlayenumcomparisons mustconsiderdeclaredref+siblingintersection, notmerelyrawidentityorindependentfiltering. Exactnumericexcluded-by-overlayexampleislossless, whilenumericpresentinintersectionmustreportonceandwidenedoverlaystringsmustreport. Ownerasked boundedfocusedenumaccounting withuncertainty, preservingdefaultwirebehavior; nogeneralJSONschemaequivalencesolver. + +cf4c59 enumintersection re-reviewPASS: requiredlossless/restrictive/numeric-exactonce matrix, boundedunknowncount andunchangedwire transformationverified. Strictchild374dada descendant/coreblobsunchanged. ActualcurrentheadhostedCI remainsrequired. + +Four remaining parent review threads were answered with exact implementation evidence and resolved: anyOf sibling loss, structured/ref equality, enum intersection accounting, and docs-build proof. Hosted docs job105902238280/run35444918425 succeeded atcf4c59. No localbuild/install performed; current runtime/platform proof stillpending. + +Parent #5162 merged as `8a030721b3ffc909ca7d8b05ca0b7c873c1493a1` at 2026-09-19T13:48:19Z. Head `cf4c59bd5f2002d9df9f9427843701451c36fb1e` passed all applicable hosted jobs and aggregate in [35444918425](https://github.com/lidge-jun/opencodex/actions/runs/35444918425), plus target enforcement35444917556. Current maintainer identity/base/head, empty native-stack membership, no unresolved threads or maintainer objections, and clean merge-tree were checked. Refreshed origin/dev contains the merge. #5112 remains open because strict-policy child #5167 has not landed. Parent branch retained; child owner requested to retarget/restack and obtain fresh exact-head proof. diff --git a/devlog/_plan/260919_contract_resolution/034_strict_schema_policy.md b/devlog/_plan/260919_contract_resolution/034_strict_schema_policy.md new file mode 100644 index 00000000000..f3eeccfed11 --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/034_strict_schema_policy.md @@ -0,0 +1,25 @@ +# Opt-in strict schema policy review + +Preparedmanualchildc150640b376fe700be49f7fbff4fb69cec03d055 builds onreportparent6ce0819958. Implements persistedgoogleToolSchemaPolicy, CLI/config/editorfieldchain, initialcompilerrejection and changedrepairwithholding, pluspubliclocaleguidance. + +Threeindependentreviewsassigned: Googlecompiler/retry/testsemantics; config/CLI/managementpersistenceandregistries; all23public/structuredocs. Strictacceptance mustcoverzeroinitialsend, zerolossyrepairdispatch indexed/unindexed, original400preserved, directno-repair, omittedcompatiblebehavior andcontent-free diagnostics. No localexecution oracceptanceclaim. Parentandchild needseparateexactheadhostedproof; issue5112 staysopenuntilfulllanding. + +G1b c150640b config/CLI/editor/securityreviewPASS: closedoptionalunion, actualCLIrejectionwithoutconfigmutation, persistence/hydration/editorreadwrite, redactedcredentialfields preserved, registriesconsistent. Coreinitial/repair controlflowacceptedconditionallybutparentreportoraclefalsepositive/negativeblockersstillpreventapproval. Docs23filesPASS withsmallrepairrecordfieldlistcorrectionrequested. No localexecution. + +Child11581 strictuncertaintyinterdiff independentPASS: all3adaptercasesrejectloss-or-nonzerouncertainty beforephysicalsend; typederrorstayscontent-free; previousrepair/default/directbehavior preserved. Parentdebugconsumer visibilityandlate-difference regression remainparent-ownedfinishingwork; report-onlyparentmustnotdependonchildforcorrectdiagnostics. + +Finalparent551a7209/childbc68b2c9 sourcechainPASS andancestryverified. Coordinatorauthorizesordinarymanualchildpublication withitsownfullCI whileparentwaits (schedulingexceptiononly,no tip-onlyskip), andindependentnextlocalimplementation. Subsequentparentchange stillrequirescascadeandre-review. + +ChildPR5167 openedagainstreportparent5162 andattached. This ismanualbranchdependency, notnative-stackoptin. Currentparentchildexactheads/ancestryandperPRCI trackedseparately; no issue5112closeuntilbothfullacceptedchangeslandondev. Ownercontinuesnextauditedindependentstatic-policyphase. + +Parent45bc664d/childa361aa7a arebaseupdatesoverprevious551a/bc68: scopedGoogle/configtest blobs checkedbyte-identical, parentancestorverified. Diffconsistsonlyupstreamdoctor/subagentfallback/issue-translation changes. CurrentheadCIstillrequired; priorstaticreviewretainedonlyforunchangedscopedblobs. + +Hostedchilda361 run35443168272/job105898238238 failsoneVertexrepairtest: clientresponse retainsoriginalupstreamerrorcanary whiletestexpectsabsence. Newlossdiagnosticprivacy andexistingoriginal400normalization aredistinctcontracts; ownerandindependentreviewer tracingbeforechangingassertionorproduction. Other195casespassed; fullchildacceptance remainsopen. + +Independenthostedfailureadjudication: Vertexclientcanaryassertion misappliesnewdiagnosticprivacy toexistingnormalizedupstream400 surface. Withheldrepair usespreexistingclassification+sanitizeddetail; ordinaryprovidercanarytext isnotasecret. Ownerrequested exactoriginalformattedresponse assertion whilekeepingnewreportcanaryexclusion andstatus/send/refusalchecks. Productionnormalizerchangewouldcontradictexistingoriginal400retention. + +Secondchildhostedfailure: test2job105898238282 layoutseed resolvesgoogle-tool-schema-policy-config.test.ts toadapters/google ratherthanserver despiteexplicitinventory. Ownerrequested narrowcorrectseed/filenameconventionandbothinventories; membershiporaclepreserved. Batchwithcontract-correctclient400testfix beforefreshheadCI. + +Child745f6b6 test-onlycorrectionindependentPASS: originalVertex400literalexpected, newdiagnosticprivacyretained, renamedmanagement-configtestbody100%unchangedandseed/explicit/expectedagree. Parsedregistrydiffhasnoothermappingchanges. Latestchild60516397 requiresinterdiffconfirmation beforeusingearlierevidence. + +Latestchild60516397 onlyrestoresregistryformatting over745f6b6; parsedfullJSONsemanticsequalforbothlayoutfiles. Previousscopedtest/code reviewsremainvalid; currentheadCIrequired. diff --git a/devlog/_plan/260919_contract_resolution/035_static_policy_resolver.md b/devlog/_plan/260919_contract_resolution/035_static_policy_resolver.md new file mode 100644 index 00000000000..3a08cfb1b16 --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/035_static_policy_resolver.md @@ -0,0 +1,23 @@ +# Resolved static model policy review + +Prepared25019c8ae765b317aa732d90b6df94a8232d45f1 isfirstlayerfor5114: staticresolverandparityfixtures, notyetconsumer migration. Sevenfilesindependentreviewassigned. Verifyfieldprecedence/explicitfalse/hardpins/aliases/customunknownmetadata, pureimmutabledata, nofrozencredentials/health/quota andparityagainstexistingconsumers. Latermigrationmustretain captureauthorityandlatebinding. No localexecution; nofullissuecompletionclaim. + +25019 reviewrequires3paritycorrections beforeconsumer migration: explicitmodelCapabilities modalities precedence, admittedkey-auth override authority withoutfreezingcredentials, andmodelidentitynormalization/virtualalias/idempotence fixtures. Existingimmutable/detachedresult, lateobservedlimitsandhardpinparityaccepted. Ownerreceivedsourceanchorsandscopedalternatives; no newpolicy language. + +cbafc6 correctionreview accepts explicitcapabilities precedence, credential-freecaptured auth, realmodelalias/virtualnormalization andidempotence. One parityfixturegap remains: effectiveauthmanuallysupplied instead ofderivedfromexistingroutingauthority. Ownerrequested usablekey/unresolvedreference fixtures capturedthroughactualroutedProviderConfig beforepassingstaticresolver, preventingimplementation-mirrortest. + +9eecc2b finalauth-oracle testreviewPASS. Latest64b7196 rebasescurrentdev; resolverandfocusedtest blobs byte-identical toreviewedhead. P1aparentpublication authorized withperPRhostedCI; consumer migration stillrequired for5114closure. + +PR5171 publishedat64b7196c73039b8ed13d9ac07941d4c91a1aebf3 andattached. Resolver+parityfirstlayerreviewaccepted; actualconsumermigration remainsnextmanualchildand5114staysopen. + +Hosted64b test4run35445279670/job105903138954 failsglobalJSONsubstring90000absence. Sourcefixturealreadycontains registry-only:90000, soassertioncollideswithlegitimatepreservedstaticdata. Actualclampandmodelcapassertionspass. Ownerrequested exactbefore/afterwholepolicycomparison plusunchangedmodelcaps/registry-onlyentry, retainingexistingconsumeroracle; no productionchange orblindrerun. + +Parent fixture corrected at `2fdd21004eb256890ae9d7a54baab6c00653c65d`: whole-policy equality across repeated observed clamps, exact static caps, preserved registry-only entry and no observed projection field. Child #5174 at `7b25d449d9828019de8a9799f51539863d2eec68` now performs the consumer migration. Base is the parent branch; native-stack lookup returned empty. Independent reviews split provider/catalog authority from router/server transitions. Hosted CI is pending, so neither layer nor issue #5114 is declared complete. + +Independent provider/catalog subset review of `7b25d449d9828019de8a9799f51539863d2eec68` passed field precedence, explicit false, frozen gather capture, late observed limits, and virtual wire identity. The parent fixture correction also passed. Existing hosted suites remain necessary for consumers not directly exercised by the new focused file. Latest child CI failed Linux shards and the gates job; its owner has already begun diagnosis of four reported failure classes. Static subset PASS is not whole-PR approval, and no merge is permitted pending corrected source and exact-head hosted proof. + +Second independent review passed router/server source tracing at `7b25d449d9828019de8a9799f51539863d2eec68`: admission-before-capture ordering, inbound and virtual identity recapture, dynamic credential rebuilds, repeated body-size admission, and stream/terminal decisions. This complements the provider/catalog review but does not override the observed hosted failures. Owner was explicitly told to retain CI as a blocking gate and use concrete failures to identify review or test-coverage gaps. No local execution was performed. + +Final parent preflight at `2fdd21004eb256890ae9d7a54baab6c00653c65d`: applicable hosted CI and aggregate35446324533 passed, but thirteen public review threads remain unresolved. Merge is held. Findings concern legacy policy parity, limit projection and provenance/documentation; independent source adjudication is split between legacy compatibility and the other projection findings. Owner must reconcile any valid findings in the parent and cascade its child, with fresh exact-head evidence. A green run and earlier subset reviews do not override concrete unresolved findings. + +Independent source adjudication of thirteen parent threads accepted eleven and rejected two. Accepted work includes raw-input legacy parity, shared family-limit resolution, cross-field input bounds, selected-destination validation/provenance, captured-auth capability overlays, output-default fallback and two documentation scope corrections. Existing callers already repair three legacy cases, so these must not be misreported as observed runtime failures. The explicit captured-auth boundary and existing supported custom-header policy support rejecting two proposed changes. Owner received precise source evidence and minimum regression cases; no blanket header-name heuristic or weakened shared-policy objective was accepted. Corrections must be reviewed at the new parent head and cascaded to the child. diff --git a/devlog/_plan/260919_contract_resolution/036_send_assertion_followup.md b/devlog/_plan/260919_contract_resolution/036_send_assertion_followup.md new file mode 100644 index 00000000000..38119159d28 --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/036_send_assertion_followup.md @@ -0,0 +1,11 @@ +# PR 5170: exact send-budget refusal assertions + +PR #5170 is a test-only follow-up to merged #5152, at head `825d4ed9c72233bc862668fec6010862bcddadea`, targeting dev. It captures the actual adapter rejection and requires `SendBudgetExhaustedError`, while preserving zero executor calls and zero spent permits. The outer request case now asserts its existing HTTP 200 buffered-failure contract explicitly, alongside the refusal code and zero send counts. + +Both changed files were inspected and independent review was assigned. No production behavior changes, assertions removed, or limits raised. Local tests, typecheck, build and runtime execution were NOT RUN. Exact-head hosted CI remains required; the campaign follow-up task stays open until verified landing. + +Independent two-file review PASS at825d4ed9: actualtypedrefusal, presentouterattempt, explicitHTTP200 failedbody andzerocount/executors areallpreserved. No productionchange or weakenedassertion. Exactheadhostedproofstillrequired. + +Controlcheckinspection: samehead825d4ed9 has successfulenforce-target35443894094 andcancelledduplicate35443954318. No rerunnecessaryforthisduplicate; currentruntime/macOS proofstillpending. + +Merged as `49c79f366c571bad47a59faca230164b9da40d88` at 2026-09-19T13:38:58Z. Exact-head hosted run [35443894116](https://github.com/lidge-jun/opencodex/actions/runs/35443894116) passed all applicable jobs and aggregate; target enforcement passed in 35443894094. Current actor, dev base, empty native-stack membership, absence of open review threads, and clean merge tree were checked before integration. The merge is an ancestor of refreshed origin/dev. The remaining review thread on merged #5152 was resolved, and the campaign follow-up task is complete. Original issue count remains 10/16; #5122 was already closed. diff --git a/devlog/_plan/260919_contract_resolution/037_acceptance_ledger.md b/devlog/_plan/260919_contract_resolution/037_acceptance_ledger.md new file mode 100644 index 00000000000..61fde8b1965 --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/037_acceptance_ledger.md @@ -0,0 +1,26 @@ +# Sixteen-issue acceptance ledger + +This checkpoint does not declare the campaign complete. On 2026-09-19, a fresh GitHub query confirmed ten closed issues and six open issues. Every recorded closed-issue merge below was checked as an ancestor of `origin/dev` at `8a030721b3ffc909ca7d8b05ca0b7c873c1493a1`. Acceptance/review and exact-head hosted receipts are in the linked per-PR records; this checkpoint does not re-run or replace those checks. + +| Issue | Current disposition | Evidence / remaining requirement | +| --- | --- | --- | +| #5109 | Closed; landed through #5125 | [`4e7d7132d8`](021_pr_5125.md); closure at 2026-09-19T08:08:28Z. | +| #5110 | Closed; landed through #5127 | [`9824aa55bb`](023_pr_5127.md); closure at 2026-09-19T09:23:33Z. | +| #5111 | Closed; landed through #5126 | [`af4f744c75`](022_pr_5126.md); closure at 2026-09-19T10:01:05Z. | +| #5112 | Open; incomplete | Report parent #5162 landed; strict-policy child #5167 requires new-base review, hosted verification and landing. [Record](033_schema_report_review.md). | +| #5113 | Closed; landed through #5129 | [`bb2fa5ab25`](024_pr_5129.md); closure at 2026-09-19T10:04:15Z. | +| #5114 | Open; incomplete | Resolver #5171 passed hosted CI but has unresolved review findings; consumer #5174 has hosted failures under repair. Both layers must land. [Record](035_static_policy_resolver.md). | +| #5115 | Open; incomplete | Runtime owner now owns registry identity-map classification and selector/availability regressions; final landing follows #5174. [Record](000_plan.md). | +| #5116 | Closed; landed through #5155 | [`6d42723387`](030_pr_5155.md); closure at 2026-09-19T11:07:05Z. | +| #5117 | Open; incomplete | Opt-in metadata-only exporter is being implemented; full privacy/auth/counting/lifecycle acceptance remains unverified. [Record](000_plan.md). | +| #5118 | Open; incomplete | Server-owned read-only preview, fingerprint validation and dialog integration still required. [Record](000_plan.md). | +| #5119 | Closed; landed through #5153 | [`f117c20d12`](029_pr_5153.md); closure at 2026-09-19T10:21:08Z. | +| #5120 | Closed; landed through #5134 | [`1b54f2940b`](026_pr_5134.md); closure at 2026-09-19T09:02:10Z. | +| #5121 | Closed; landed through #5138 | [`5ce51cb554`](027_pr_5138.md); closure at 2026-09-19T10:08:29Z. | +| #5122 | Closed; landed through #5152 | [`26d3a862d6`](028_pr_5152.md); closure at 2026-09-19T11:06:36Z. | +| #5123 | Open; incomplete | Writer ownership #5157 at 9e789c1613 passed latest fixture-delta review; fresh hosted proof and landing remain required. [Record](031_pr_5157.md). | +| #5124 | Closed; landed through #5130 | [`acd43bf442`](025_pr_5130.md); closure at 2026-09-19T10:06:43Z. | + +Supplementary requirements: sideband diagnostic/cleanup #5161 and send-assertion follow-up #5170 landed and their goalplan tasks are complete. The broader sideband root-cause issue is not claimed resolved. Public devlog publication, final cumulative dev verification, all remaining acceptance checks, final PABCD closure and heartbeat shutdown remain outstanding. No local test, typecheck, build, installation or proxy execution has been performed. + +Publication review checkpoint: independent re-review accepted the corrected English owner/status summary, neutral pre-integration ownership record, and this ledger. The complete historical working records were preserved in ignored scratch; no implementation evidence was discarded. This is documentation readiness for the reviewed files, not permission to declare or publish the campaign as complete. From 40670044146adc714f06d8b2e29f9114f8393df5 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 19 Sep 2026 23:35:23 +0900 Subject: [PATCH 47/97] feat(spend): require one writer lease per state directory for the spend journal (#5157) * feat(spend): require one writer lease per state directory for the spend journal The ledger documented a guarantee covering one live proxy process, while the CLI deliberately supports starting a sibling on a different port under the same state directory. Nothing serialized the two. That is not a theoretical overlap: every Responses-serving process is a potential journal writer, including one with no configured ceiling, because a ceiling decides whether to refuse rather than whether to write. Two processes could mint different salts, interleave appends and compaction, and a second process's construction replay declares the first one's open reservations lost while it is still settling them. Startup now takes a state-directory writer lease before any listener can serve, so the exported startServer path is covered rather than only the CLI preflight, and the ledger asserts that lease before replay, append or compaction. Siblings remain supported with independent state directories; a second writer on the same one is refused with a clear message. Ownership is an OS-held SQLite write transaction for the process lifetime, which is the pattern this repository already uses for its other cross-process locks. There is deliberately no stale-owner reclamation: PID reuse, container PID namespaces, restarts and power loss all defeat a PID or timestamp check, and a TTL can evict a live process that was merely paused. Busy means a live owner; any other failure to establish the lock is ambiguous and fails closed. Diagnostics are scalar only on the authenticated health route - ownership, initialized, configured, degraded and bounded counters - and reading them constructs nothing. /healthz is unchanged. * fix(spend): bind journal mutations to a live lease, not to the handle Pre-publication review found three gaps in the writer lease. The guard sat where the shared ledger was handed out, so a caller holding an existing ledger or journal facade could keep mutating after the final release, once another process legitimately owned the home. Ownership is now asserted at the mutations themselves: every reservation state change, every file-backed append and compaction rewrite, and salt creation. A retained handle refuses to write, which the new negative case pins with a second owner in place. Two differently configured homes could alias one journal or salt through a link while holding separate owner databases, so both could write the same file. The backing files must now be regular, single-link, self-owned files; links, owner files and unusable owner databases are refused. This is the cooperative configuration contract, not a claim of isolation against a hostile same-UID process. The unsupervised restart starts its replacement before the parent exits. With a zero busy timeout and every owner error terminal, the child would exit busy while the parent still owned the home, and the parent would then exit leaving nothing serving. The deferred restart child now carries a one-use parent marker, accepted only when it matches its actual parent, and waits a bounded five seconds for ownership. An ordinary sibling still fails closed immediately. * fix(spend): release the ledger singleton with the lease that owned it The binding outlived ownership, so a process that served one state directory and then legitimately served another was refused for a conflict it no longer had. Every test process that starts servers against per-test homes is that shape, and so is a restart handoff inside one process. Releasing the last lease now discards the in-memory ledger along with the binding. Nothing is lost: the journal on disk is the durable record and the next construction replays it, which is what a restart already does. Two homes owned at the same time are still refused, which is the invariant that matters. * fix(spend): prove exact ownership on every accounting read and change Review found a retained ledger coming back to life. The guard compared the state directory, which cannot tell "still the ownership I was built under" from "the same directory, owned again since" - so a handle kept across a release and a reacquire resumed with totals from before the gap, over a journal another writer may have appended to. Ownership now has an identity: each acquisition that takes the lock mints one, the ledger captures it at construction, and every accounting read and change proves that exact value. A handle from the previous ownership is refused; a fresh handle replays what happened in between. Reads are covered as well as writes, because reporting figures from a journal this process no longer owns is the same error with a quieter symptom. The file-backed journal and salt writers no longer accept an absent owner check. The parameter is required, so a caller that owns its own temporary file writes that decision down instead of inheriting it by omission. A link whose target does not exist read as "no file" through existsSync, so the safety check was skipped and the append created that target elsewhere. Entry presence is now decided with lstat, which sees the link itself. * fix(spend): make ownership proof something only the owner module can mint The previous round kept adding checks at each caller, and the review was right that this converged on one boundary rather than a set of gaps. A required guard supplied by the caller proves nothing, because the caller can supply one that does nothing - which is exactly what the fixtures here did. Production journal and salt storage is now minted by the owner module from the directory it actually owns. The mint takes a file name rather than a path, so nothing outside chooses the destination; the returned value carries the exact ownership it was minted under and re-proves it on every read, append, rewrite, salt read and salt create; and a brand means a look-alike object is refused on identity rather than on shape. There is no longer an exported entrypoint that writes a caller-chosen path. Every ledger member now proves ownership too, including knows and the policy, degraded, persistFailures and corruptRecords getters. Reporting a figure from a journal this process no longer owns is the same error as writing one. The generic in-memory and injected factory stays usable without any of this and does not pretend to enforce process ownership. The file-journal cases that cover real persistence, hardening and compaction now take a real lease over a throwaway state directory and go through the production entrypoints, rather than being replaced by a stand-in. Also corrects the reserve request shape in the reacquire regression to scopes with input and output-ceiling tokens, and the stale comment claiming production never discards the singleton. * fix(spend): key ownership proof on identity, not on a marker the token carries A marker on the object was still forgeable. Spreading a real token copies its own symbol, so { ...minted, path: elsewhere, assert() {} } passed the brand check and then ran the caller's replacement guard against the caller's path - the same no-op guard the required-callback version allowed, reached another way. The token now carries nothing at all. Its path and the ownership it was minted under live in a module-private table keyed by the token's identity, which a copy cannot reproduce because a copy is a different object. Callers ask this module for the path and for the check rather than reading either off the value they were handed. The negative case covers all three shapes: a bare look-alike, a hand-built object with the right fields, and a spread of a genuine token with the path redirected and the guard replaced. It also asserts the redirected file was never created, and that a genuine token still works so the refusal is about identity rather than refusing everything. A separate case pins that a real token stops working once its ownership ends. * fix(spend): take ownership on demand instead of refusing to serve Hosted CI showed the guard was asserting the wrong rule. Requiring ownership to touch the journal is right; requiring it to have been taken by startServer is not, and handleResponses is an equally supported entry point that never calls startServer - 72 test files exercise exactly that shape, and an embedder can too. The result was a 502 wherever a turn reached its first physical send without a server having started. The shared ledger now takes the lease itself when nobody holds one. The guarantee becomes "no unowned writer" rather than "no writer outside one entry point", and it is not weakened: a directory another process owns is refused exactly as before, and the call fails closed with it. The lease lives as long as a server's would and returns through the same release path. Applying a policy no longer demands ownership either. Recording a value touches no journal; only reconfiguring a ledger that already exists does, because that ledger is a live view of an owned directory. * fix(spend): drop the implicit lease and own the directory in the fixtures instead The on-demand lease was wrong twice over. Its premise - that handleResponses is an equally supported entry point - does not hold: the package exports only the root, src/index.ts exports startServer and not this handler, and every production caller is server-internal beneath that lease. A direct import of an internal module in a test is not a public contract. It also leaked: the lease took its own reference, so server.stop left one behind, blocking final cleanup and the sequential directory switch the design allows. Ownership is required again, with no exception carved for callers that skipped startServer. The cases that dispatch without a server now take the real lease through a shared helper and release it after each case, so the production rule is exercised rather than relaxed for tests. The exact-token, startup and restart boundaries are unchanged. * test(spend): order the lease release ahead of each fixture's cleanup Hook registration order differed between the two fixtures, so neither FIFO nor LIFO execution could guarantee the lease closed before the directory holding it was removed - a failed removal on Windows, an unlinked live database on POSIX. The helper now returns an idempotent release and each fixture calls it first in its own teardown, so the ordering is stated where it matters instead of inferred from where a hook happened to be registered. Adds the same treatment to the Claude native-affinity fixture, which CI showed reaching the ledger through combo dispatch. * test(spend): let a failed lease release fail the case The release swallowed whatever lease.release() threw. A rollback or close that fails is a defect in the thing under test, and hiding it leaves a green run over a lease that never let go - the exact state the single-writer rule exists to prevent. The reset stays in finally so the next case still starts from a discarded singleton. * test(spend): own the state directory in the six fixtures CI named Every dispatch charges the ledger: reserveDispatch consults the spend observer before it books, so any case that reaches prepareAdapterExchange touches the shared journal. These six call the internal handler directly and never take the lease startServer takes, so the ledger refused and the cases saw 502/529 instead of their own contract. Each one takes the real lease at the end of its own beforeEach, after its home is in place, and releases it at the top of its own afterEach, before that home is removed. Ordering is stated at the call site because hook registration order differs between these fixtures and is a contract in neither direction. Diagnosed from the hosted shard logs at 654bcee, not guessed: claude-inbound- cache-stabilize (shard 1), main-account-hard-lock-auth (shard 2), reserve-auth- context and reserve-dispatch (shard 3), github-copilot-account-origin and kiro-auth-context-continuation (shard 4). Shards stop at the first failed batch, so this is a partial view by construction and the remaining fixtures are being inventoried rather than discovered one run at a time. * test(spend): own the state directory in the merged send-budget count rows These rows arrived with #5152 after this branch was cut, so no CI run has ever seen them against the ownership rule. Every one of them dispatches through the handler directly and therefore charges the shared ledger. The lease is taken per row, not per file. Two rows install their own OPENCODEX_HOME and the rest inherit the preload sandbox, and a lease is bound to the directory in effect when it was taken, so a block-level hook would either bind the wrong directory or conflict with the rows that swap one in. The two own-home rows drop it inside their existing finally, ahead of the environment restore and the directory removal. The file's afterEach drops it as a backstop. Without that, a row that throws mid-assertion leaves the lease behind and the next row's different home reports an ownership conflict instead of the failure that actually happened. Local checks: NOT RUN. * test(spend): take the writer lease in every fixture that dispatches directly Thirty-one fixtures call a response handler without going through startServer, so none of them held the spend-journal writer lease and every dispatch came back as "Spend-ledger ownership is required before the shared ledger can be used". CI could only ever show a handful of these at a time, because a shard stops at its first failed batch, so the set was derived by tracing the dispatching call blocks rather than by re-running until the next one appeared. Placement is stated at each call site, never inferred from hook order: - A fixture that installs its own OPENCODEX_HOME takes the lease after that assignment and drops it before the environment is restored and the directory removed. An open lease inside a directory being deleted fails the removal on Windows and leaves an unlinked live database on POSIX. - A fixture that inherits the preload sandbox home takes the lease at the dispatch and drops it in the file's afterEach, so a row that throws mid-assertion cannot leave a lease behind and make the next row's different home read as an ownership conflict. - Files that mix both shapes get neither a file-level nor a block-level lease. Each dispatching case owns its own. Cases that never reach a physical dispatch are deliberately untouched: admission refusals, management-API rows, in-memory ledger rows and direct persistence rows. No assertion, expected value, mock, fixture or timeout is changed anywhere in this commit, and no file-size cap moves. Five fixtures sit at exactly their ratchet cap and are NOT in this batch: openai-responses-passthrough, responses-compaction-routing, usage/request-log, responses-custom-tool-repair and responses-undeclared-tool-guard. A cap only moves down, so they cannot take an additive lease and need an extraction first. That is its own change rather than blank-line churn smuggled into this one. Local checks: NOT RUN. * test(spend): finish the lease migration and remove the image suite's own home Twenty more fixtures dispatch directly and inherit the preload sandbox home, so each takes the writer lease at its dispatch and drops it in its own afterEach. Three files that had no afterEach get one whose only job is that drop: a case that throws mid-assertion would otherwise leave the lease behind and make the next case's home read as an ownership conflict instead of reporting its own failure. Cases that never reach a physical dispatch stay lease-free, and the boundary is drawn at the seam rather than by file. v2-agent-message-failfast keeps its bare post() for the two rows that assert dispatch never happens and routes the rest through a dispatchPost() that takes the lease; abort-race leaves the build-time abort and buildRequest-throw rows alone; opencode-go-session-header leaves the policy-fallback rows, whose injected runCore answers without an adapter. The image activation suite also now removes the home it owns. Taking the lease creates the state directory, and that suite names a fresh one per run, so before this it left a directory behind on every run. Release, then remove, then restore: the removal has to happen while OPENCODEX_HOME still names it. No assertion, expected value, mock, fixture or timeout changes, and no cap moves. Local checks: NOT RUN. * test(spend): make room for the lease in the five fixtures at their cap A file-size cap only ever moves down, so these five could not take an additive lease. The repository answer to that is an extraction, not deleted blank lines or two statements on one line, and each one here removes more than the lease costs. Four move a helper to a sibling module, verbatim, so the cases that called it read the same behaviour through a different name: the SSE stream reader and builder out of the undeclared-tool guard (nine files had written their own copy of readAll), the request-log row builder, the key-auth URL builder out of the Responses passthrough, and the config/request/upstream fixtures out of compaction routing. responses-custom-tool-repair is split instead, because its twelve dispatching cases are one contiguous block and no helper in it is worth enough lines. They move to responses-custom-tool-repair-dispatch.test.ts unchanged, registered in both scripts/test-layout/layout.json and tests/fixtures/test-layout-expected.json, with the fixtures both halves need in a shared helper so the two copies cannot drift. The original keeps the cases that drive the compat functions directly and no longer dispatches at all, so it needs no lease. Compaction routing takes the lease per dispatching describe rather than per file: five of its cases install a home inside the case body, and each of those drops the block lease and takes one for its own directory, then drops that before the directory is removed. The one describe that only exercises a pure function takes no lease. One placement is worth naming. In the passthrough file the shared call arrow takes the lease inside its body, not beside it: beside it the acquire would run while the describe was being collected, and the first case's teardown would drop it for every case after. No assertion, expected value, mock, fixture or timeout changes, and no cap moves. Local checks: NOT RUN. * test(spend): release each turn's body before the lease that served it Review found cases that dispatched, asserted on headers or on what the upstream stub recorded, and then discarded the Response without touching its body. The body is a live stream, so the case finished with a reader still attached and the lease was dropped underneath it. That is the state the single-writer rule exists to keep from happening, and it is invisible until something downstream reports a pending handle instead of the assertion that actually failed. Each of these now consumes or cancels the body after its assertions and before it returns: the annotation and DeepSeek inbound drive helpers, the two FastWire characterization paths, both service-tier paths, and the six image-bridge cases that only ever read a header. The 400 case is untouched because it already reads its body. No assertion, expected value, mock, fixture or timeout changes. Local checks: NOT RUN. * test(spend): read the gateway attempt row's body before its lease is released The row asserts on the request-log metadata only, so the turn's body was still attached when the finally released the lease that served it. Reading it keeps the case's own assertions untouched and leaves nothing pending behind them. Bounded fixture hygiene. Nothing about the production body lifetime changes, and no claim is made that the static buffer leaks on its own. Local checks: NOT RUN. * test(spend): repair the three failures the first hosted run found Hosted CI at 4de35b43 reported three distinct problems, and only one of them was a missing lease. The Lab activation guard was the serious one. Its SERVE_ANCHOR is the literal text of the statement that creates the listener, and this branch assigns that listener from spendLedgerLifecycle.track(Bun.serve(...)) so the lease can roll the listener back on a failed start. The anchor stopped matching, indexOf returned -1, and the guard failed loudly rather than measuring an empty string, which is exactly what it was written to do. The anchor now names the real statement, so it starts the same window it always did, and the new body-level call is registered for review rather than skipped: track binds the listener's stop, records a rollback closure and returns the same server, with no await. The lifecycle's release() is not registered because it is called inside the async stop wrapper, which this scan skips as a nested function. Nothing in the guard is relaxed. The second was a regression this branch introduced. main-account-hard-lock-auth took the lease in a file-level beforeEach, and two of its describes spawn a child that runs startServer against the same home. The child then failed with SPEND_LEDGER_OWNER_BUSY, which is the ownership contract working correctly and the case failing for a reason it is not about. The lease is now taken only by the two cases that dispatch in-process. No other fixture in this batch spawns a child; that was checked rather than assumed. The third was an inventory gap. The first pass searched for handleResponses and its compact and policy-fallback siblings, and missed handleChatCompletions and handleNativeChatCompletions, so the chat fixtures were never leased. Eight more files take it now, and the search is by the full handler set rather than by one of them. ws-upstream needed room first: its runtime pin and the two wrappers that bind it move to a sibling helper, verbatim, because the file was at its cap. Files whose handler calls stop before a physical dispatch are deliberately untouched: OAuth admission refusals, unknown-provider routing, the policy fallback rows with an injected runCore, and the reasoning-envelope rows that answer 404 for a deliberately absent model. Assertion counts are unchanged in every file; the deletions in this diff are re-indentation where a body was wrapped in try/finally. No cap moves. Local checks: NOT RUN. * test(spend): lease the four mixed fixtures the transitive audit found All four run a real server in most of their cases and dispatch directly in a few, so none of them can take a file-wide lease: the lease is taken by the cases that dispatch in-process and by nothing else. cursor-effort-rows takes it per case, inside the try that already stops the mock upstream, and releases it first in that finally. claude-messages-endpoint takes it inside invokeMessages, beside the turn-admission lease it already holds, and releases it in the same finally. chat-completions-endpoint and server-combo-failover-e2e take it at each direct dispatch and drop it at the top of the afterEach they already have, ahead of the home restore and removal. Where a case here also starts a server, the acquire is a second reference on the same directory rather than a competing owner, so the server keeps serving and the release only drops the reference this case added. That is different from a CHILD process, which cannot acquire at all while the parent holds the lease; the one fixture in that shape was repaired separately. server-combo-failover-e2e needed room first: it was one line under its cap, so its five upstream response builders move to a sibling helper, verbatim. Assertion counts are unchanged in all four files. No cap moves. Local checks: NOT RUN. * test(spend): lease the websocket steering path at its shared fixture The steering rows did not fail with an ownership message. They failed with 'fixture condition timed out' after roughly a second, because the websocket handler dispatches through the real request path: the turn was refused, the response.created frame never arrived, and the wait expired naming nothing. Two dozen rows across three files reported it that way. The lease is taken where the turn begins, not row by row. beginInjection in the shared native-injection fixture covers ws-native-result-continuations and ws-steering-stability, and installInjectionFixture drops it in the afterEach it already registers. ws-native-steering has its own begin() and hooks and gets the same treatment there. responses-snapshot-repair-server has one row that calls the handler directly while every other row starts a real server, so that row takes the lease itself and the file drops it in teardown. Assertion counts unchanged. No cap moves. Local checks: NOT RUN. * test(spend): fix the audit batch and the two ownership-identity traps The critical one first: a scripted insertion put takeSpendHome() between a ternary's condition and its question mark in server-combo-failover-e2e, which is not valid TypeScript. It now sits above the statement. An AST syntax screen over every changed file finds no remaining parse error. Two failures had the same root and neither announced itself as an ownership problem. The websocket fixtures took the lease in begin() and beginInjection(), but the failing rows call downstream() and injectionClient() directly, so the lease moved down to the seam where the client actually dispatches. And the subagent streaming rows force process.platform to win32 to reach the eager-relay path; ownership identity lowercases the state directory on win32, so the lease taken under the real platform stopped matching the directory the dispatch checks the moment the override landed, and the turn was refused with no terminal at all. Those rows now retake the lease under the platform they are pretending to run on and give it back before restoring the descriptor. Release ordering is corrected wherever teardown can still settle a turn. The steering fixtures close their synthetic clients, then the upstream sockets, then run the shutdown hooks, and only then release. The cursor rows stop their fake upstreams first. The combo suite stops its listeners and flushes response state first, and still releases before its home is removed. The Claude endpoint case now holds one lease across both of its turns instead of taking a fresh one per invocation, and drops it after both upstreams are down. Six files that dispatch through the shared agent-task-recovery post() helper take the lease too. One of them installs its own OPENCODEX_HOME inside a describe, so its lease is taken there rather than at file level, for the same reason as the platform case: a lease binds the directory in effect when it was taken. The sparse-JSON snapshot-repair row was still missing one. No assertion, expected value, mock, fixture or timeout changes; no cap moves. Local checks: NOT RUN. The syntax screen is a pure AST read and is not a substitute for hosted typecheck or tests. * test(codex): give the overlapping successor its own state directory Both hard-kill cases launch the successor while the owner is still listening, on purpose: that overlap is what proves the contended snapshot, the denied main admission, the takeover after the kill and the auth-temp scrub. They shared one OPENCODEX_HOME, and the spend journal allows one writer per state directory, so the successor was refused before it ever bound and the case reported a startup failure instead of the transition it is about. The successor now gets its own config directory under the same fixture root, written with the same helper and the same account shape. CODEX_HOME is unchanged, and the native-main lock, the recovery journal and the vault all derive from that, so every assertion still observes the same shared native state. This is the pattern the file already uses for its other deliberately overlapping child a few cases earlier; it is now a named helper that also restores the parent's OPENCODEX_HOME after writing. The launch stays before the kill and the lease stays required. Nothing about the cross-process ownership contract changes. Local checks: NOT RUN. * test(spend): wait for the turns to finish before giving the lease back Two lifetime gaps the review found, both about teardown racing a turn that is still accounting. handler.close only STARTS the websocket pump cancellation. The fixtures closed their synthetic clients and released immediately, so a reader could still be settling against a journal nobody owned. Both fixtures now wait, on the bounded seam they already use, until the socket has dropped its stream cancel and its native control, then run the shutdown hooks, then release, then restore. The teardowns are async for that reason. The combo suite leases every dispatch but its status-only rows never read the transformed body they get back. The shared helpers now hand each turn through a tracker, and teardown cancels every body that is still unread and unlocked before the listeners stop, the response state is flushed and the lease is given back. Rows that do read their body are unaffected, because a consumed or locked body is skipped. Pure in-memory rows that never dispatch are deliberately still lease-free. Assertion counts unchanged, no cap moves, and an AST syntax screen over every changed file is clean. Local checks: NOT RUN. * test(spend): track the wrapper each logged helper returns, not the raw turn The three logged helpers tracked the response they got from the handler and then returned a deferred-request-log wrapper built around it. The wrapper locks the raw body, so teardown skipped the raw as locked and never saw the wrapper at all: the body that rows actually hold was the one left unread. Each helper now tracks what it returns. The cancellation no longer swallows its error. A body that refuses to cancel is a real defect and fails the case, but only after every other turn and every listener has still been given its chance to close, so one bad body cannot leave the rest of the suite holding ports or a lease. Assertion counts unchanged, no cap moves, AST syntax screen clean. Local checks: NOT RUN. * test(routing): narrow the eager-relay platform claim to the relay decision The four streaming rows reported an empty terminal list and read as a relay defect. They were not. The eager relay is reachable only on win32 and darwin, so the rows overwrote process.platform globally to reach it, and that redirects far more than the relay: every filesystem, ACL and state-directory decision in the process follows it. The spend-ledger owner lowercases its home on win32, and on a case-sensitive filesystem the lowercased temp directory is a DIFFERENT directory, so the send could not be reserved and the turn delivered no terminal at all. Retaking the lease under the fake platform could not fix that, because the directory it then owned was not the one the case was using. The claim is now narrowed to the two calls that actually choose the relay path, through an internal test seam in the delivery module. No config key reaches it, and ownership, home casing and the win32 policy itself are untouched. The rows also say more than they did. The status, the event-stream content type and the relay path itself are asserted before the callback is inspected, so a turn that never delivered now says so instead of presenting as a missing callback, and the legacy-tee and eager-relay variants each prove which path they actually took rather than assuming the streamMode was honoured. Assertion coverage grows; nothing is relaxed. AST syntax screen clean, no cap moves. Local checks: NOT RUN. * fix(spend): close three failure paths in the ledger's own storage All three are on paths the happy case never reaches, which is why a green suite said nothing about them. A fresh state directory was never claimed. Config ownership refuses to claim a directory that already has contents, and the owner database lives inside that directory, so creating the database first left a new home with no owner marker and no manifest at all. Nothing recorded the database or its sidecars, and a later uninstall could not remove them. The paths are now registered while the directory is still empty, and the regression proves an uninstall takes the whole directory back afterwards. An entry that could not be inspected read as absent. Only ENOENT means absent; a permission denial or an I/O error means we do not know, and answering no file skipped the file-safety assertion and appended to whatever was actually there. It now refuses, and it refuses in the module's own vocabulary rather than handing a client the errno and path of a state file. The ledger already treats a journal it cannot make durable as a degradation rather than an outage, so this surfaces as reserve-not-durable and does not fail the request. A failed compaction left its temp behind. The name carries random bytes, so a validate, harden or rename that threw left a uniquely named file and the next attempt made another: repeated failures accumulated rather than overwriting one fixed name. Only that exact temp is removed, only on the failure path, so the original journal and the primary error both survive. The failed-start rollback also stopped waiting for its own listeners. Bun's Server.stop(true) resolves once connections are closed, and the rollback discarded that promise, so the state directory was handed back while a listener could still be serving. It now holds the lease until every stop has settled, while staying synchronous and returning void, because startServer must not become async. Rollback failures stay contained so the startup error that caused them is still the one reported. Not covered by a test: the compaction failure path has no deterministic lever without an injection seam, so the cleanup is asserted by inspection only. Local checks: NOT RUN. AST syntax screen clean, no cap moves. * test(spend): prove the storage and rollback failure paths instead of asserting them The previous commit fixed three failure paths and shipped one of them with no test, which is how a failure path stays broken. These are the regressions. Compaction now has a narrow fault seam for its own filesystem steps, because there is no portable way to make a validate, harden or rename fail on demand. It is an internal test contract: no config key reaches it and it defaults to absent. Four cases drive it. A failure at validate, harden or rename, repeated three times, leaves no compaction residue and an unchanged journal; a write that stops partway leaves neither residue nor a truncated journal; and a candidate name that already belongs to something else is left exactly as it was. That last case drove a real change. The temp was created by a combined write, so whether the entry was ours had to be inferred from which error the write threw. It is now an exclusive open first, so ownership is a fact: EEXIST means the name is not ours and is never removed, and every failure after the open is cleaned because the entry is provably ours, including a short write. The descriptor is closed on the failure path too. The rollback has its own file now. Two listeners whose stops stay pending prove the lease is still held after both are asked, still held when only one has settled, and returned once both have; a listener whose stop rejects proves the others are still stopped and the directory is still returned. Both also pin the newest-first order. failedStartStops is typed as returning void or a promise, which is what the rollback awaits. The old annotation compiled while statically erasing the promise; the runtime closure returned it either way, so this corrects the contract rather than a behaviour. New file registered in both layout maps. Local checks: NOT RUN. * test: repair the two source-anchor and platform assumptions CI found Both are test-side. No production guard moves. The F4 bind oracle pinned the public serve call by its exact old text, and the listener is now handed to a lifecycle registrar as it is created. The assertion is wrapper-aware without giving anything up: the serve call's argument object is still pinned exactly, so the public bind takes bindHost and nothing else, and server is still what that call is assigned to, through at most one registrar call. Both negative assertions about a hardcoded loopback host are unchanged. The streaming pair claimed win32, and on win32 a turn needing a client rewrite takes the eager relay unconditionally under #864. So the legacy half could never be legacy there, and the marker assertion I added last round was reporting that honestly: status and content type passed, the path was eager either way. The pair now claims darwin, which is the platform where the configured mode actually decides: legacy-tee resolves to tee, eager-relay to the eager relay, and both halves keep their health and terminal-callback coverage. The alternative would have been to weaken the marker assertion, which would have hidden exactly the thing it was added to prove. AST syntax screen clean; the new anchor was checked against the current source and still rejects a hardcoded 127.0.0.1 bind. Local checks: NOT RUN. * test(spend): close the three fixture gaps the review named The startup rollback case asserted ownership was returned in the same turn as the throw, which only held while the rollback discarded its stop promise. It now waits for the directory to come back, then reacquires, and awaits the blocking listener's own stop in its teardown. The assertion that the start actually threw is unchanged. The partial-write case was not partial. The fault threw before any byte landed, so it proved cleanup of an empty file rather than of a short write. The fault now writes a real prefix into the entry the exclusive create already made, and asserts the prefix is there, before failing with ENOSPC. That is the residue the cleanup has to remove, and the journal and the absence of residue are still asserted across repeated attempts. The unreadable-entry contract had only a POSIX chmod case, which is skipped on Windows and proves nothing as root. A narrow stat step on the same internal fault seam now proves it everywhere, for both EACCES and EIO, with only the journal's own inspection failing: the salt stays readable and every other filesystem step is real. It checks the refusal is the module's typed error and that nothing was reset - no truncation, no new entries, and the salt still mints. The chmod case stays as real-filesystem evidence where it can run. Also worth recording: the enforce-target failure on the previous head was a concurrency cancellation, not a gate refusal. AST syntax screen clean. Local checks: NOT RUN. * test: keep websocket teardown failure-safe and drain the store-default turns Two public review findings, both correct against the current source. The websocket fixtures awaited a bounded completion wait before the rest of their teardown. When that wait gave up, the hook stopped there: remaining sockets stayed open, the shutdown hooks never ran, the writer lease was never returned and the replaced globals were never restored, so one slow turn poisoned every case after it. The wait is now inside a try and everything else is in the finally, in the same order as before. The failure still propagates, and the comment says why that matters: a wait that expired is not evidence the turn settled, only that the fixture could not prove it settled. No timeout moved. The store-default rows ask for a stream and then read only the captured upstream request, so the turn's own body was left live while the teardown handed back the lease. They drain it now. An earlier review of mine reported every body as consumed; that was wrong, and the source is what settles it. AST syntax screen clean. Local checks: NOT RUN. * test: finish the websocket teardown so one failure cannot strand the rest My previous attempt wrapped the whole client loop in one try, which left two gaps the review caught. A wait that gave up aborted the loop, so every client after it kept its socket open for the next case to inherit. And the lease release can itself throw, which took the global restore down with it. Each step is attempted now and the first failure is kept: every client is closed and waited on, every upstream socket is closed, the shutdown hooks run, and the lease is released, each guarded so a failure in one does not skip the others. Restoring the replaced globals sits in an outer finally, so it happens whatever else went wrong. The collected failure is thrown afterwards. That last part is the point: a collected failure still fails the case. It means the fixture could not prove the turn settled, not that it settled. No timeout moved and the bounded completion assertion is unchanged. AST syntax screen clean. Local checks: NOT RUN. * test(server): fix the three late-batch failures the shard finally reached These were not new. A shard stops at its first failed batch, so batch 26 only became visible once the earlier batches passed. All three are fixture-side. The management-auth ACL case timed out icacls for the state directory as well as the management token file. Only the token file was ever load-bearing for its claim, and the assertion that the state's source is "environment" is what proves which path answered. The directory is hardened with required: true by the spend-journal owner during startServer, which refuses rather than soft-failing, because an unverified ACL on a directory holding a secret is not something to proceed past. The stub is narrowed to the token file and the claim is unchanged. Activation E overwrote process.platform globally to reach the relay path. That also changes state-directory identity, which is lowercased on win32 and so names a different directory on a case-sensitive filesystem, and the harness server's own writer lease stopped matching. The retry was refused before it could reach the second account, which is why the case saw acct-pool-a alone. It uses the narrow relay seam now, so the platform claim reaches the relay decision and nothing else. Same root cause as the subagent rows, different file. The combo failover row dispatches through the handler rather than the harness server, so it takes the lease itself and drains its response before releasing. No production policy moved. Assertions are unchanged; the drain is the only addition. Local checks: NOT RUN. * test(spend): fix two macOS-only failures in my own storage regressions All four Linux shards passed; macOS found two things Linux could not. The seam-driven case compared the faulted entry against a path it built itself. The owned home is the REAL path of the directory, and on macOS the temp root is a symlink, so the equality never held and the fault silently did nothing: the read succeeded and the case failed asking why nothing threw. It matches on the entry name now, which is path-shape independent and still leaves the salt alone. The chmod case asserted the exact refusal message. Which gate notices first is platform-dependent: where the directory cannot be traversed at all, the ownership check cannot resolve it before the entry is ever inspected, so the refusal arrives from there instead. Both are the same module's refusal, so the case pins the type and the absence of a leaked path, and the seam-driven case below it pins the exact message on every platform. That is what the seam was added for. Also batched, since the review asked for it conditionally and the condition holds: client close and the completion wait now have separate guards in both websocket teardowns. close() runs the production handler, so a throw there would have skipped that client's wait as well as reporting its own failure. Local checks: NOT RUN. * test(spend): make the contention matrix test the modes it names The acceptance mapping found a labelling gap and it was real. The matrix iterated holder/contender mode pairs, but contenderMode reached only the test name and the marker suffix: busyError() acquired with nothing configured, so the contender had no mode at all. Both rows varied only the holder. No other fixture covered it either; every other spawned holder in this suite is observe and none configures a contender. The contender now records its own policy before it tries to acquire, which is exactly the state a second instance starts in: configured one way or the other and not yet a writer. Recording a policy touches no journal while this process owns nothing, so this adds configuration without adding a second writer. The matrix is all four combinations. The rule under test is that ownership does not depend on either side's ceiling, and a matrix missing observe/observe and enforced/enforced was not testing the claim its names made. One case is new rather than restored: a ceiling turned on while another process still owns the directory. It proves the transition changes what would be refused, never who may write, and that the ownership refusal is identical on both sides of it. Every real-process and timeout assertion is unchanged, and no production code moves. The gate was already unconditional; what was missing was the proof. Local checks: NOT RUN. --- .../docs/fr/reference/cli/lifecycle.md | 2 +- .../docs/ja/reference/cli/lifecycle.md | 2 +- .../docs/ko/reference/cli/lifecycle.md | 6 +- .../content/docs/reference/cli/lifecycle.md | 10 +- .../docs/reference/configuration/server.md | 2 +- .../docs/ru/reference/cli/lifecycle.md | 6 +- .../docs/tr/reference/cli/lifecycle.md | 8 +- .../docs/zh-cn/reference/cli/lifecycle.md | 2 +- .../docs/zh-tw/reference/cli/lifecycle.md | 2 +- scripts/test-layout/layout.json | 4 + src/cli/dispatch.ts | 6 +- src/cli/index.ts | 9 +- src/lib/spend-ledger-owner.ts | 364 +++++++ src/lib/spend-reservation-ledger.ts | 245 ++++- src/server/index.ts | 29 +- src/server/index/spend-ledger-lifecycle.ts | 66 ++ src/server/management/system-restart.ts | 9 +- src/server/management/system-routes.ts | 2 + src/server/responses/passthrough-delivery.ts | 23 +- structure/config.md | 2 +- structure/gui-and-management-api.md | 2 +- structure/runtime.md | 12 + structure/transports/responses.md | 21 + tests/adapters/abort-race.test.ts | 11 + .../anthropic-quota-dispatch.test.ts | 7 + ...anthropic-sidecar-account-failover.test.ts | 7 + .../empty-tool-output-annotation.test.ts | 16 +- .../openai/openai-chat-native-policy.test.ts | 62 +- ...rminal-continuation-owner-rotation.test.ts | 7 + ...laude-code-thought-signature-scope.test.ts | 9 + .../claude-inbound-cache-stabilize.test.ts | 9 + .../claude-messages-endpoint.test.ts | 7 + .../claude-native-affinity.test.ts | 7 + .../main-account-hard-lock-auth.test.ts | 14 + .../model-pinned-effort.test.ts | 7 + .../native-main-owner-lifetime.test.ts | 24 +- .../reserve-auth-context.test.ts | 10 + .../reserve-dispatch.test.ts | 10 + tests/fixtures/test-layout-expected.json | 4 + tests/helpers/combo-failover-upstream.ts | 60 ++ tests/helpers/compaction-routing-fixtures.ts | 107 ++ tests/helpers/custom-tool-repair-fixtures.ts | 20 + tests/helpers/native-injection-fixture.ts | 49 +- tests/helpers/owned-spend-home.ts | 34 + tests/helpers/passthrough-key-url.ts | 26 + tests/helpers/request-log-entry.ts | 21 + tests/helpers/spend-ledger-owner-child.ts | 45 + tests/helpers/sse-stream.ts | 35 + tests/helpers/ws-upstream-fixtures.ts | 34 + tests/images/z-handler-activation.test.ts | 25 +- tests/lab/core-lab-boundary.test.ts | 7 +- tests/lib/spend-ceiling-enforcement.test.ts | 5 + tests/lib/spend-ledger-file-journal.test.ts | 222 +++- tests/lib/spend-ledger-owner.test.ts | 532 ++++++++++ .../adapter-event-oauth-failover.test.ts | 7 + tests/oauth/oauth-account-attribution.test.ts | 5 + .../cursor/cursor-effort-rows.test.ts | 13 + .../cyber-policy-error-fidelity.test.ts | 6 +- tests/providers/deepseek-inbound-wire.test.ts | 26 +- .../deepseek-responses-item-id-repair.test.ts | 11 +- .../github-copilot-account-origin.test.ts | 10 + .../github-copilot-stream-contract.test.ts | 8 + .../github-copilot-wire-defaults.test.ts | 12 +- .../kiro-auth-context-continuation.test.ts | 10 + tests/providers/opencode-go-luna-wire.test.ts | 19 +- .../opencode-go-session-header.test.ts | 16 +- tests/providers/rate-limit-retry.test.ts | 10 + .../upstream-transient-retry.test.ts | 42 +- .../chat-completions-endpoint.test.ts | 20 + .../chat-conversation-affinity.test.ts | 7 + .../responses/chat-json-sse-fallback.test.ts | 16 +- tests/responses/chat-refusal.test.ts | 7 + tests/responses/empty-completion-core.test.ts | 20 + .../responses/fresh-connection-optout.test.ts | 5 + .../openai-responses-passthrough.test.ts | 46 +- .../responses/responses-account-label.test.ts | 15 + ...esponses-compact-handoff-admission.test.ts | 39 +- .../responses-compaction-routing.test.ts | 149 +-- .../responses-console-go-upload-retry.test.ts | 7 + ...ponses-custom-tool-repair-dispatch.test.ts | 979 ++++++++++++++++++ .../responses-custom-tool-repair.test.ts | 962 +---------------- ...responses-forward-incomplete-quota.test.ts | 5 + .../responses-function-tool-repair.test.ts | 15 +- .../responses-image-gen-repair.test.ts | 17 +- .../responses-inbound-store-default.test.ts | 17 +- .../responses-muse-tool-name-alias.test.ts | 18 +- .../responses-native-main-refresh.test.ts | 7 + .../responses-opaque-blob-recovery.test.ts | 7 + .../responses-pool-401-refresh.test.ts | 7 + .../responses-preview-main-read-fence.test.ts | 26 +- ...sponses-reasoning-effort-downgrade.test.ts | 7 + ...nses-reasoning-summary-passthrough.test.ts | 12 +- ...sponses-self-named-namespace-scrub.test.ts | 20 +- .../responses-send-budget-counts.test.ts | 27 + .../responses-shadow-intercept.test.ts | 15 + .../responses-show-thinking-summary.test.ts | 19 +- .../responses-snapshot-repair-server.test.ts | 12 + ...ses-stateless-dangling-call-repair.test.ts | 11 +- .../responses-tool-search-repair.test.ts | 15 +- .../responses-undeclared-tool-guard.test.ts | 48 +- tests/responses/ws-native-steering.test.ts | 52 +- tests/responses/ws-upstream.test.ts | 39 +- tests/routing/combo-management-api.test.ts | 47 +- .../fastwire-characterization-wire.test.ts | 17 +- tests/routing/fastwire-observability.test.ts | 12 +- .../probe-lease-dispatch-wiring.test.ts | 5 + .../routing-policy-surface-parity.test.ts | 10 + ...subagent-fallback-handle-responses.test.ts | 29 +- .../server/agent-task-recovery-cache.test.ts | 11 + .../server/agent-task-recovery-combo.test.ts | 11 + .../agent-task-recovery-fallback.test.ts | 11 + .../agent-task-recovery-security.test.ts | 11 + tests/server/agent-task-recovery.test.ts | 11 + tests/server/cancel-body-on-abort.test.ts | 13 +- .../server/context-history-ownership.test.ts | 7 + ...plaintext-v2-agent-messages-server.test.ts | 29 + tests/server/response-model-identity.test.ts | 7 + .../server-agent-task-recovery-replay.test.ts | 13 +- tests/server/server-auth.test.ts | 14 +- .../server/server-combo-failover-e2e.test.ts | 127 +-- ...combo-reasoning-replay-eligibility.test.ts | 11 + .../server-combo-zero-output-failover.test.ts | 7 + tests/server/server-management-auth.test.ts | 14 +- tests/server/spend-ledger-lifecycle.test.ts | 101 ++ .../server/spend-ledger-owner-startup.test.ts | 106 ++ tests/server/terminal-guard-server.test.ts | 25 + .../server/v2-agent-message-failfast.test.ts | 49 +- tests/service/service-tier-capability.test.ts | 22 +- tests/usage/request-log.test.ts | 22 +- .../web-search-passthrough-bridge.test.ts | 5 + tests/web-search/web-search.test.ts | 11 +- .../windows-deploy-close-regressions.test.ts | 9 +- 132 files changed, 4463 insertions(+), 1434 deletions(-) create mode 100644 src/lib/spend-ledger-owner.ts create mode 100644 src/server/index/spend-ledger-lifecycle.ts create mode 100644 tests/helpers/combo-failover-upstream.ts create mode 100644 tests/helpers/compaction-routing-fixtures.ts create mode 100644 tests/helpers/custom-tool-repair-fixtures.ts create mode 100644 tests/helpers/owned-spend-home.ts create mode 100644 tests/helpers/passthrough-key-url.ts create mode 100644 tests/helpers/request-log-entry.ts create mode 100644 tests/helpers/spend-ledger-owner-child.ts create mode 100644 tests/helpers/sse-stream.ts create mode 100644 tests/helpers/ws-upstream-fixtures.ts create mode 100644 tests/lib/spend-ledger-owner.test.ts create mode 100644 tests/responses/responses-custom-tool-repair-dispatch.test.ts create mode 100644 tests/server/spend-ledger-lifecycle.test.ts create mode 100644 tests/server/spend-ledger-owner-startup.test.ts diff --git a/docs-site/src/content/docs/fr/reference/cli/lifecycle.md b/docs-site/src/content/docs/fr/reference/cli/lifecycle.md index 148febbf448..c134193f422 100644 --- a/docs-site/src/content/docs/fr/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/fr/reference/cli/lifecycle.md @@ -15,7 +15,7 @@ Assistant de configuration interactif (`setup` est un alias de `init`). Il deman ### `ocx start [--port ] [--socks5 [host:port] | --socks5-off]` -Démarre le serveur proxy, de préférence sur le port `10100`. La commande écrit l’état du PID et du port d’exécution, et refuse de démarrer une deuxième instance active. Lorsque le port préféré est occupé, `start` interroge le processus qui l’occupe puis s’arrête dans tous les cas : elle refuse de démarrer si un processus opencodex y répond et signale sinon que le processus est inconnu. Elle ne déplace jamais l’écouteur vers un autre port d’elle-même, car cela laisserait le premier proxy en cours d’exécution et redirigerait Codex vers le second. Indiquez un autre port avec `--port`, ou définissez `port: 0` dans la configuration pour demander au système d’exploitation d’en attribuer un. Au démarrage, elle synchronise dans le catalogue Codex les modèles de chaque fournisseur. À l’arrêt, elle rétablit le fonctionnement natif de Codex, sauf si le proxy a été lancé comme service géré (`OCX_SERVICE=1`). +Démarre le serveur proxy, de préférence sur le port `10100`. La commande écrit l’état du PID et du port d’exécution, et refuse de démarrer une deuxième instance active. Lorsque le port préféré est occupé, `start` interroge le processus qui l’occupe puis s’arrête dans tous les cas : elle refuse de démarrer si un processus opencodex y répond et signale sinon que le processus est inconnu. Elle ne déplace jamais l’écouteur vers un autre port d’elle-même, car cela laisserait le premier proxy en cours d’exécution et redirigerait Codex vers le second. Un autre `--port` explicite est également refusé avec le même `OPENCODEX_HOME`, car les modes d’observation et de plafond écrivent tous deux dans le même journal de dépenses. Utilisez un `OPENCODEX_HOME` distinct pour une instance sœur indépendante ; `port: 0` ne sépare que l’attribution du port, pas l’état. Au démarrage, elle synchronise dans le catalogue Codex les modèles de chaque fournisseur. À l’arrêt, elle rétablit le fonctionnement natif de Codex, sauf si le proxy a été lancé comme service géré (`OCX_SERVICE=1`). `--socks5` (par défaut `127.0.0.1:10808`) enregistre l’URL SOCKS5 dans `config.proxy` et achemine les requêtes HTTP(S) sortantes dans un véritable tunnel SOCKS5. `--socks5-off` supprime uniquement diff --git a/docs-site/src/content/docs/ja/reference/cli/lifecycle.md b/docs-site/src/content/docs/ja/reference/cli/lifecycle.md index 6939c537d00..bf37bc911b6 100644 --- a/docs-site/src/content/docs/ja/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/ja/reference/cli/lifecycle.md @@ -15,7 +15,7 @@ description: セットアップ、開始、停止、サービス、診断、同 ### `ocx start [--port ] [--socks5 [host:port] | --socks5-off]` -プロキシ サーバー (優先ポート `10100`) を起動します。PID/ランタイムポートの状態を書き込み、2 番目のライブインスタンスの起動を拒否します。優先ポートが使用中の場合、`start` はそのポートを使用しているプロセスを確認して、どちらの場合も停止します。opencodex が応答していれば起動を拒否し、それ以外は使用しているプロセスを特定できないと報告します。最初のプロキシを実行したまま Codex を 2 番目のプロキシへ向けることになるため、自動でリスナーを別のポートへ移すことはありません。別のポートは `--port` で指定するか、設定で `port: 0` を指定して OS に割り当てを依頼してください。開始時に、各プロバイダーのモデルを Codex のカタログに同期します。マネージド サービス (`OCX_SERVICE=1`) として起動されていない限り、シャットダウン時にネイティブ Codex が復元されます。 +プロキシ サーバー (優先ポート `10100`) を起動します。PID/ランタイムポートの状態を書き込み、2 番目のライブインスタンスの起動を拒否します。優先ポートが使用中の場合、`start` はそのポートを使用しているプロセスを確認して、どちらの場合も停止します。opencodex が応答していれば起動を拒否し、それ以外は使用しているプロセスを特定できないと報告します。最初のプロキシを実行したまま Codex を 2 番目のプロキシへ向けることになるため、自動でリスナーを別のポートへ移すことはありません。同じ `OPENCODEX_HOME` では別の `--port` を明示しても拒否されます。監視のみの構成も上限を適用する構成も同じ支出ジャーナルへ書き込むためです。独立した sibling には別の `OPENCODEX_HOME` を使用してください。`port: 0` はポートだけを OS に割り当てさせ、状態を分離しません。開始時に、各プロバイダーのモデルを Codex のカタログに同期します。マネージド サービス (`OCX_SERVICE=1`) として起動されていない限り、シャットダウン時にネイティブ Codex が復元されます。 `--socks5`(デフォルト `127.0.0.1:10808`)は SOCKS5 URL を `config.proxy` に保存し、送信 HTTP(S) リクエストを実際の SOCKS5 トンネル経由で送信します。`--socks5-off` は保存された SOCKS5 プロキシだけを削除し、HTTP プロキシは削除しません。値は設定に保存されるため、`ocx update` 後も保持されます。URL にユーザー名とパスワードを含めることはできますが、起動ログでは非表示になります。 diff --git a/docs-site/src/content/docs/ko/reference/cli/lifecycle.md b/docs-site/src/content/docs/ko/reference/cli/lifecycle.md index 4db8c09b695..e4f2913c6f6 100644 --- a/docs-site/src/content/docs/ko/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/ko/reference/cli/lifecycle.md @@ -22,8 +22,10 @@ Codex 자동 시작 shim도 설치합니다. 인스턴스는 시작하지 않습니다. 권장 포트가 이미 사용 중이면 `start`가 점유자를 확인한 뒤 어느 경우든 실행을 멈춥니다. opencodex가 응답하면 시작을 거부하고, 그렇지 않으면 점유자를 식별할 수 없다고 알립니다. 첫 번째 프록시를 실행한 채 Codex가 두 번째 프록시를 가리키게 되므로, 리스너를 다른 포트로 -자동 이동하지 않습니다. 다른 포트는 `--port`로 지정하거나, OS에 포트 할당을 요청하려면 구성에서 -`port: 0`을 설정하세요. 시작할 때는 각 공급자의 모델을 Codex 카탈로그로 동기화합니다. 종료할 때는 +자동 이동하지 않습니다. 활성 프록시와 같은 `OPENCODEX_HOME`을 사용하면 다른 `--port`를 명시해도 +시작을 거부합니다. 관찰 전용과 제한 적용 모드 모두 같은 지출 저널에 기록하기 때문입니다. 독립된 형제 +인스턴스에는 별도의 `OPENCODEX_HOME`을 사용하세요. `port: 0`은 포트만 OS에 맡기며 상태를 분리하지 +않습니다. 시작할 때는 각 공급자의 모델을 Codex 카탈로그로 동기화합니다. 종료할 때는 기본 Codex를 복원합니다. 단, 관리형 서비스로 실행한 경우(`OCX_SERVICE=1`)는 예외입니다. `--socks5`(기본값 `127.0.0.1:10808`)는 SOCKS5 URL을 `config.proxy`에 저장하고 실제 SOCKS5 diff --git a/docs-site/src/content/docs/reference/cli/lifecycle.md b/docs-site/src/content/docs/reference/cli/lifecycle.md index 54c42a9d68b..e8380c73ca6 100644 --- a/docs-site/src/content/docs/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/reference/cli/lifecycle.md @@ -22,10 +22,12 @@ Start the proxy server (preferred port `10100`). It writes PID/runtime-port stat start a second live instance. When the preferred port is occupied, `start` asks the holder who it is and stops either way: it refuses outright when an opencodex answers there, and reports an unidentified holder otherwise. It never moves the listener to another port on its own, because that -would leave the first proxy running and re-point Codex at the second. Name a different port with -`--port`, or set `port: 0` in the config to ask the OS for one. On start it syncs each provider's -models into Codex's catalog. On shutdown it restores native Codex — unless it was launched as a -managed service (`OCX_SERVICE=1`). +would leave the first proxy running and re-point Codex at the second. An explicit different +`--port` is still refused when the live proxy shares this `OPENCODEX_HOME`, because observe-only +and enforced spend accounting both write the same journal. Use a separate `OPENCODEX_HOME` for an +independent sibling; `port: 0` only asks the OS for that instance's port and does not separate its +state. On start it syncs each provider's models into Codex's catalog. On shutdown it restores +native Codex — unless it was launched as a managed service (`OCX_SERVICE=1`). `--socks5` (default `127.0.0.1:10808`) saves `config.proxy` as a SOCKS5 URL and routes outbound HTTP(S) through a real SOCKS5 tunnel. `--socks5-off` clears only that saved SOCKS5 proxy; it diff --git a/docs-site/src/content/docs/reference/configuration/server.md b/docs-site/src/content/docs/reference/configuration/server.md index e243f5edd90..8a596e2a966 100644 --- a/docs-site/src/content/docs/reference/configuration/server.md +++ b/docs-site/src/content/docs/reference/configuration/server.md @@ -27,7 +27,7 @@ runs helper features around provider requests. | `apiKeys?` | `OcxApiKey[]` | `[]` | Generated `ocx_…` data-plane admission credentials on non-loopback binds. They do not authorize management APIs; management access uses the separate credential documented in the [management reference](/reference/management-api/). Dashboard-managed. | | `storageCleanupPolicy?` | `StorageCleanupPolicy` | disabled | Opt-in archived-session cleanup policy. Never enabled implicitly. | | `appOwnedMemoryBudgetMb?` | `number` | `256` | Cap in MiB for evictable app-owned logs, caches, blobs, and continuation payloads. Range 64–4096; not an RSS cap. | -| `spend?` | `{ root?: { maxTokens?: number }; identity?: { maxTokens?: number }; pool?: { maxTokens?: number }; retentionDays?: number }` | unset | Durable token ceilings, off unless you write one. Each scope bounds settled spend plus in-flight reservations plus unresolved spend: `root` is one task including its whole fan-out, `identity` is one account across every task it serves, and `pool` is one provider pool. They intersect, so a request is admitted only when all three have room — which is what holds a ceiling against a client that mints a new task id per request. A reservation is the request's whole input plus its enforceable output ceiling, counted as if every cached prefix misses. Spend survives a restart, so it does not roll forward the way the send-count window does; raising or removing the value is what grants more. `maxTokens` must be a positive integer (0 would refuse everything), `retentionDays` is 1–365 and defaults to 7, and an unknown key in this section is rejected rather than ignored. A refusal is a local HTTP 429 carrying `x-opencodex-local-refusal: workflow_spend_exhausted`, and its message names the scope and the ceiling; no provider is contacted. | +| `spend?` | `{ root?: { maxTokens?: number }; identity?: { maxTokens?: number }; pool?: { maxTokens?: number }; retentionDays?: number }` | unset | Durable token ceilings, off unless you write one. Each scope bounds settled spend plus in-flight reservations plus unresolved spend: `root` is one task including its whole fan-out, `identity` is one account across every task it serves, and `pool` is one provider pool. They intersect, so a request is admitted only when all three have room — which is what holds a ceiling against a client that mints a new task id per request. A reservation is the request's whole input plus its enforceable output ceiling, counted as if every cached prefix misses. Observe-only mode still journals, so every server owns the state directory's single-writer lease; an explicit sibling must use a separate `OPENCODEX_HOME`. Spend survives an ordinary process restart when its writes reached the filesystem, but the journal does not promise survival across host power loss because each append is not fsynced. Raising or removing the value is what grants more. `maxTokens` must be a positive integer (0 would refuse everything), `retentionDays` is 1–365 and defaults to 7, and an unknown key in this section is rejected rather than ignored. A refusal is a local HTTP 429 carrying `x-opencodex-local-refusal: workflow_spend_exhausted`, and its message names the scope and the ceiling; no provider is contacted. | | `codexAutoStart?` | `boolean` | `true` | Let the Codex shim run `ocx ensure` before launching Codex. False makes ensure a no-op. | | `codexShimAutoRestore?` | `boolean` | `true` | Restore an installed shim after a completed external Codex update replaces it. Environment opt-out: `OPENCODEX_CODEX_SHIM_AUTO_RESTORE=0`. | | `codexDesktopAuthless?` | `boolean` | `false` | Opt-in authless Codex Desktop routing on a loopback bind: inject the dedicated `opencodex` provider with `requires_openai_auth = false` so Desktop opens without a ChatGPT login. Ignored on non-loopback binds. `ocx system settings --desktop-authless on`. See [Codex integration](/guides/codex-integration/#authless-codex-desktop-opt-in). | diff --git a/docs-site/src/content/docs/ru/reference/cli/lifecycle.md b/docs-site/src/content/docs/ru/reference/cli/lifecycle.md index 5bdde33ae2d..f338d75388f 100644 --- a/docs-site/src/content/docs/ru/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/ru/reference/cli/lifecycle.md @@ -25,8 +25,10 @@ PID/runtime-port, а попытка поднять второй живой эк занят, `start` проверяет, кто его удерживает, и в любом случае останавливается: он отказывается от запуска, если там отвечает opencodex, а иначе сообщает о неопознанном владельце порта. Прокси никогда сам не переносит listener на другой порт, поскольку тогда первый прокси продолжил бы -работать, а Codex был бы перенаправлен на второй. Укажите другой порт через `--port` или задайте -`port: 0` в конфигурации, чтобы порт назначила ОС. На старте прокси синхронизирует модели каждого +работать, а Codex был бы перенаправлен на второй. Явно указанный другой `--port` также отклоняется +при общем `OPENCODEX_HOME`: режим наблюдения и режим с лимитами оба пишут в один журнал расходов. +Для независимого соседнего экземпляра используйте отдельный `OPENCODEX_HOME`; `port: 0` поручает +ОС выбрать только порт и не разделяет состояние. На старте прокси синхронизирует модели каждого провайдера в каталог Codex. При shutdown он восстанавливает native Codex — если только прокси не был запущен как managed service (`OCX_SERVICE=1`). diff --git a/docs-site/src/content/docs/tr/reference/cli/lifecycle.md b/docs-site/src/content/docs/tr/reference/cli/lifecycle.md index f2b72af51c0..ffa5b19df50 100644 --- a/docs-site/src/content/docs/tr/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/tr/reference/cli/lifecycle.md @@ -26,9 +26,11 @@ durumunu yazar ve ikinci bir canlı örneği başlatmayı reddeder. Tercih edile doluysa `start`, portu tutan süreci sorgular ve her iki durumda da durur: orada bir opencodex yanıt veriyorsa başlatmayı reddeder, aksi halde portu tutan sürecin tanımlanamadığını bildirir. İlk proxy'yi çalışır durumda bırakıp Codex'i ikinciye -yönlendireceği için dinleyiciyi kendiliğinden başka bir porta taşımaz. `--port` ile -farklı bir port belirtin veya işletim sisteminden bir port istemek için yapılandırmada -`port: 0` ayarlayın. Başlangıçta her sağlayıcının modellerini Codex'in kataloğuna +yönlendireceği için dinleyiciyi kendiliğinden başka bir porta taşımaz. Aynı +`OPENCODEX_HOME` kullanılırken farklı bir `--port` açıkça verilse de başlangıç reddedilir; +yalnızca gözlem ve sınır uygulama kiplerinin ikisi de aynı harcama günlüğüne yazar. Bağımsız +bir kardeş örnek için ayrı bir `OPENCODEX_HOME` kullanın. `port: 0` yalnızca port seçimini +işletim sistemine bırakır, durumu ayırmaz. Başlangıçta her sağlayıcının modellerini Codex'in kataloğuna senkronize eder. Kapatıldığında — yönetilen bir servis olarak başlatılmadığı sürece (`OCX_SERVICE=1`) — yerel Codex'i geri yükler. diff --git a/docs-site/src/content/docs/zh-cn/reference/cli/lifecycle.md b/docs-site/src/content/docs/zh-cn/reference/cli/lifecycle.md index f482b1701e2..30687e2b81e 100644 --- a/docs-site/src/content/docs/zh-cn/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/zh-cn/reference/cli/lifecycle.md @@ -15,7 +15,7 @@ description: 安装、启动、停止、服务、诊断、同步和更新命令 ### `ocx start [--port ] [--socks5 [host:port] | --socks5-off]` -启动代理服务器(首选端口 `10100`)。它会写入 PID/运行时端口状态,并拒绝启动第二个存活实例。当首选端口已被占用时,`start` 会探测占用者,并且无论结果如何都会停止:如果那里响应的是 opencodex,它会直接拒绝启动;否则会报告无法识别的占用者。它绝不会自行把监听地址移到其他端口,因为那会让第一个代理继续运行,并将 Codex 重新指向第二个代理。使用 `--port` 指定其他端口,或在配置中设置 `port: 0`,让操作系统分配端口。启动时,它会把每个提供方的模型同步到 Codex 的目录中。关闭时,它会恢复原生 Codex,除非它是作为受管服务启动的(`OCX_SERVICE=1`)。 +启动代理服务器(首选端口 `10100`)。它会写入 PID/运行时端口状态,并拒绝启动第二个存活实例。当首选端口已被占用时,`start` 会探测占用者,并且无论结果如何都会停止:如果那里响应的是 opencodex,它会直接拒绝启动;否则会报告无法识别的占用者。它绝不会自行把监听地址移到其他端口,因为那会让第一个代理继续运行,并将 Codex 重新指向第二个代理。即使显式指定不同的 `--port`,共用同一个 `OPENCODEX_HOME` 时也会拒绝启动,因为仅观察模式和启用上限的模式都会写入同一个支出日志。独立的同级实例必须使用单独的 `OPENCODEX_HOME`;`port: 0` 只让操作系统分配端口,并不会隔离状态。启动时,它会把每个提供方的模型同步到 Codex 的目录中。关闭时,它会恢复原生 Codex,除非它是作为受管服务启动的(`OCX_SERVICE=1`)。 `--socks5`(默认 `127.0.0.1:10808`)会将 SOCKS5 URL 保存到 `config.proxy`,并通过真正的 SOCKS5 隧道转发出站 HTTP(S) 请求。`--socks5-off` 只会清除已保存的 SOCKS5 代理,不会删除 HTTP 代理。该值保存在配置中,因此会在 `ocx update` 后保留。URL 可以包含用户名和密码,但启动日志会将其隐藏。 diff --git a/docs-site/src/content/docs/zh-tw/reference/cli/lifecycle.md b/docs-site/src/content/docs/zh-tw/reference/cli/lifecycle.md index da2a7e08479..d9c104d3c91 100644 --- a/docs-site/src/content/docs/zh-tw/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/zh-tw/reference/cli/lifecycle.md @@ -15,7 +15,7 @@ description: 安裝、啟動、停止、服務、診斷、同步與更新指令 ### `ocx start [--port ] [--socks5 [host:port] | --socks5-off]` -啟動代理伺服器(偏好連接埠 `10100`)。它寫入 PID/runtime-port 狀態,並拒絕啟動第二個即時實例。偏好連接埠被佔用時,`start` 會探測佔用者,且無論結果如何都會停止:若回應的是 opencodex,它會直接拒絕啟動;否則會回報無法識別的佔用者。它絕不會自行將監聽位置移到其他連接埠,因為這會讓第一個代理繼續執行,並將 Codex 重新指向第二個代理。請用 `--port` 指定其他連接埠,或在設定中設為 `port: 0`,讓作業系統指派連接埠。啟動時它將每個供應商的模型同步到 Codex 目錄。關閉時它還原原生 Codex——除非它是作為受管服務啟動的(`OCX_SERVICE=1`)。 +啟動代理伺服器(偏好連接埠 `10100`)。它寫入 PID/runtime-port 狀態,並拒絕啟動第二個即時實例。偏好連接埠被佔用時,`start` 會探測佔用者,且無論結果如何都會停止:若回應的是 opencodex,它會直接拒絕啟動;否則會回報無法識別的佔用者。它絕不會自行將監聽位置移到其他連接埠,因為這會讓第一個代理繼續執行,並將 Codex 重新指向第二個代理。即使明確指定不同的 `--port`,共用同一個 `OPENCODEX_HOME` 時仍會拒絕啟動,因為僅觀察模式和啟用上限的模式都會寫入同一份支出日誌。獨立的同層實例必須使用不同的 `OPENCODEX_HOME`;`port: 0` 只讓作業系統指派連接埠,不會隔離狀態。啟動時它將每個供應商的模型同步到 Codex 目錄。關閉時它還原原生 Codex——除非它是作為受管服務啟動的(`OCX_SERVICE=1`)。 `--socks5`(預設 `127.0.0.1:10808`)會將 SOCKS5 URL 儲存到 `config.proxy`,並透過真正的 SOCKS5 通道轉送對外 HTTP(S) 請求。`--socks5-off` 只會清除已儲存的 SOCKS5 代理,不會刪除 HTTP 代理。此值儲存在設定中,因此會在 `ocx update` 後保留。URL 可以包含使用者名稱和密碼,但啟動記錄會隱藏它們。 diff --git a/scripts/test-layout/layout.json b/scripts/test-layout/layout.json index 2e1b9066903..32615632839 100644 --- a/scripts/test-layout/layout.json +++ b/scripts/test-layout/layout.json @@ -1215,6 +1215,7 @@ "responses-console-go-upload-retry.test.ts": "responses", "responses-context-overflow.test.ts": "responses", "responses-custom-tool-guidance.test.ts": "responses", + "responses-custom-tool-repair-dispatch.test.ts": "responses", "responses-custom-tool-repair.test.ts": "responses", "responses-custom-tool-stream-consistency.test.ts": "responses", "responses-fetch-helpers-boundary.test.ts": "responses", @@ -1345,6 +1346,9 @@ "sponsor-presets.test.ts": "providers", "spend-ceiling-enforcement.test.ts": "lib", "spend-ledger-file-journal.test.ts": "lib", + "spend-ledger-lifecycle.test.ts": "server", + "spend-ledger-owner-startup.test.ts": "server", + "spend-ledger-owner.test.ts": "lib", "spend-reservation-ledger.test.ts": "lib", "sse-client-frame-bounds.test.ts": "responses", "sse-decoder.test.ts": "responses", diff --git a/src/cli/dispatch.ts b/src/cli/dispatch.ts index d152d673f52..029336f66c9 100644 --- a/src/cli/dispatch.ts +++ b/src/cli/dispatch.ts @@ -945,9 +945,9 @@ export type StartOwnerDecision = "refuse" | "service-stay-out" | "sibling"; * * The #3106 guard exists so a bare `start` cannot shadow a healthy configured-port * proxy with an ephemeral-port copy. An interactive `--port X` naming a DIFFERENT - * port than the live proxy's is an explicit sibling request, not that shadow — and - * refusing it also broke every spawned-launcher test on a machine running a real - * proxy, because the probe reaches the machine-global port across sandbox homes. + * port than the live proxy's is an explicit sibling request, not that shadow. The + * state-directory spend-ledger lease makes the final same-home refusal; keeping this + * decision allows isolated homes on one machine to remain independent. * The service wrapper always passes the configured port and keeps its exact * stay-out-of-the-way semantics: it never takes the sibling path. */ diff --git a/src/cli/index.ts b/src/cli/index.ts index fb68ae09f2d..00d89469fd3 100755 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -78,6 +78,7 @@ import { } from "./tray-proxy"; import { requestBoundSystemRestart } from "./system-restart-client"; import { installCrashGuards } from "../lib/crash-guard"; +import { SpendLedgerOwnerError } from "../lib/spend-ledger-owner"; import { redactUrlForLog } from "../lib/redact"; import { dispatchCommand, decideBusyPreferredPort, decideStartWithLiveOwner } from "./dispatch"; import { AuxiliaryListenerBindError, findAvailablePort, isAddrInUse, PortUnavailableError, shouldPersistSelectedPort, waitForPortAvailable } from "../server/ports"; @@ -418,8 +419,8 @@ async function handleStart(options: { block?: boolean } = {}) { // to bake the service (observed: a probe on 10198 left the service pinned there). siblingStart = true; console.warn( - `Proxy already running on port ${owner.live.port}; starting a second instance on requested port ${requestedPort}. ` - + `The new instance takes over this home's pid/runtime records and Codex config while it runs.`, + `Proxy already running on port ${owner.live.port}; requested a second instance on port ${requestedPort}. ` + + `Startup continues only for an independent OPENCODEX_HOME; one state directory has one spend-ledger writer.`, ); } @@ -463,6 +464,10 @@ async function handleStart(options: { block?: boolean } = {}) { scheduleCatalogPrewarm(); break; } catch (err) { + if (err instanceof SpendLedgerOwnerError) { + console.error(`❌ ${err.message}`); + process.exit(1); + } if (err instanceof AuxiliaryListenerBindError || !isAddrInUse(err) || attempt >= 2) throw err; if (requestedPort !== undefined) { console.log(`⚠️ Port ${port} was taken while starting; waiting to retry the same port...`); diff --git a/src/lib/spend-ledger-owner.ts b/src/lib/spend-ledger-owner.ts new file mode 100644 index 00000000000..40cf6dd07b4 --- /dev/null +++ b/src/lib/spend-ledger-owner.ts @@ -0,0 +1,364 @@ +/** Process-lifetime single-writer ownership for the shared spend journal. */ +import { Database } from "bun:sqlite"; +import { chmodSync, closeSync, lstatSync, mkdirSync, openSync, realpathSync } from "node:fs"; +import { join, resolve } from "node:path"; +import { getConfigDir } from "../config/paths"; +import { recordOwnedConfigPath } from "./config-ownership"; +import { assertNotRealHomeUnderTest } from "./test-home-guard"; +import { hardenSecretDir, hardenSecretPath } from "./windows-secret-acl"; + +export const SPEND_LEDGER_OWNER_FILENAME = "spend-ledger-owner.sqlite"; +export const SPEND_LEDGER_RESTART_PARENT_ENV = "OCX_SPEND_LEDGER_RESTART_PARENT_PID"; +export const SPEND_LEDGER_RESTART_WAIT_MS = 5_000; +const OWNER_SIDECARS = ["-journal", "-wal", "-shm"] as const; + +export type SpendLedgerOwnerErrorCode = + | "SPEND_LEDGER_OWNER_BUSY" + | "SPEND_LEDGER_OWNER_UNAVAILABLE" + | "SPEND_LEDGER_OWNER_HOME_CONFLICT" + | "SPEND_LEDGER_OWNER_NOT_HELD"; + +export class SpendLedgerOwnerError extends Error { + constructor(readonly code: SpendLedgerOwnerErrorCode, message: string, options?: ErrorOptions) { + super(message, options); + this.name = "SpendLedgerOwnerError"; + } +} + +export interface SpendLedgerOwnerLease { + release(): void; +} + +interface ActiveOwner { + readonly home: string; + readonly database: Database; + references: number; +} + +let activeOwner: ActiveOwner | null = null; +let boundLedgerHome: string | null = null; +/** + * Identity of the current ownership, not just of the home it covers. + * + * A home name alone cannot tell "still the lease I was built under" from "the same directory, + * owned again since". A ledger that only checked the home therefore came back to life across a + * release and a reacquire, writing totals it had accumulated before another writer owned the + * journal. Every acquisition that actually takes the lock mints a new value. + */ +let ownerGeneration = 0; +const releaseHooks: Array<() => void> = []; + +/** + * Run when the last lease on a state directory goes away. + * + * The ledger singleton is bound to the home it was built for, so it has to go when ownership + * does; otherwise a process that starts a second server against a different state directory + * either writes the old home's journal or is refused for a conflict it no longer has. The + * journal on disk is the durable record and construction replays it, so nothing is lost. + */ +export function onSpendLedgerOwnerReleased(hook: () => void): void { + releaseHooks.push(hook); +} + +function errorCode(error: unknown): unknown { + return error !== null && typeof error === "object" && "code" in error ? error.code : undefined; +} + +function assertPrivateFile(path: string): void { + const stat = lstatSync(path); + if (!stat.isFile() || stat.isSymbolicLink() || stat.nlink !== 1) { + throw new SpendLedgerOwnerError( + "SPEND_LEDGER_OWNER_UNAVAILABLE", + "Spend-ledger ownership could not be established safely.", + ); + } + if (process.platform !== "win32" && stat.uid !== process.getuid!()) { + throw new SpendLedgerOwnerError( + "SPEND_LEDGER_OWNER_UNAVAILABLE", + "Spend-ledger ownership could not be established safely.", + ); + } +} + +function prepareOwnerPath(configDir: string): { home: string; path: string } { + const requested = resolve(configDir); + // First statement before mutation: tests must never acquire against the real user home. + assertNotRealHomeUnderTest(requested); + mkdirSync(requested, { recursive: true, mode: 0o700 }); + const home = realpathSync.native(requested); + if (process.platform !== "win32") chmodSync(home, 0o700); + hardenSecretDir(home, { required: true }); + const path = join(home, SPEND_LEDGER_OWNER_FILENAME); + // Registered while the directory is still EMPTY. Config ownership refuses to claim a + // directory that already has contents, so creating the database first meant a fresh home + // never got an ownership marker at all: the manifest was never written, and the database and + // its sidecars were left behind by a later uninstall because nothing recorded them. + recordOwnedConfigPath(home, path); + for (const suffix of OWNER_SIDECARS) recordOwnedConfigPath(home, `${path}${suffix}`); + try { closeSync(openSync(path, "wx", 0o600)); } + catch (error) { if (errorCode(error) !== "EEXIST") throw error; } + assertPrivateFile(path); + if (process.platform !== "win32") chmodSync(path, 0o600); + hardenSecretPath(path, { required: true }); + assertPrivateFile(path); + return { home: process.platform === "win32" ? home.toLowerCase() : home, path }; +} + +function isBusy(error: unknown): boolean { + const code = errorCode(error); + const message = error instanceof Error ? error.message : ""; + return code === "SQLITE_BUSY" || code === "SQLITE_LOCKED" + || /database (?:is|table is) locked/i.test(message); +} + +function stateDirectoryIdentity(configDir: string): string { + const requested = resolve(configDir); + assertNotRealHomeUnderTest(requested); + let canonical = requested; + try { canonical = realpathSync.native(requested); } catch { /* acquisition owns creation */ } + return process.platform === "win32" ? canonical.toLowerCase() : canonical; +} + +function restartHandoffWaitMs(): number { + const markedParent = process.env[SPEND_LEDGER_RESTART_PARENT_ENV]; + delete process.env[SPEND_LEDGER_RESTART_PARENT_ENV]; + return markedParent === String(process.ppid) ? SPEND_LEDGER_RESTART_WAIT_MS : 0; +} + +/** Mark only a parent-exit restart child for bounded lease acquisition. */ +export function spendLedgerRestartEnvironment( + source: NodeJS.ProcessEnv, + parentPid?: number, +): NodeJS.ProcessEnv { + const env = { ...source }; + if (parentPid === undefined) delete env[SPEND_LEDGER_RESTART_PARENT_ENV]; + else env[SPEND_LEDGER_RESTART_PARENT_ENV] = String(parentPid); + return env; +} + +/** + * Hold one SQLite write transaction until the final in-process reference releases it. + * SQLite and the OS release a crashed process; no PID, timestamp, TTL or lock-file unlink + * can evict a live owner or mistake a reused process identity for this lease. + */ +export function acquireSpendLedgerOwner(configDir = getConfigDir()): SpendLedgerOwnerLease { + const requestedHome = stateDirectoryIdentity(configDir); + const busyTimeout = restartHandoffWaitMs(); + if (boundLedgerHome !== null && boundLedgerHome !== requestedHome) { + throw new SpendLedgerOwnerError( + "SPEND_LEDGER_OWNER_HOME_CONFLICT", + "This process already owns the spend ledger for a different state directory.", + ); + } + if (activeOwner) { + if (activeOwner.home !== requestedHome) { + throw new SpendLedgerOwnerError( + "SPEND_LEDGER_OWNER_HOME_CONFLICT", + "This process already owns the spend ledger for a different state directory.", + ); + } + activeOwner.references += 1; + return leaseFor(activeOwner); + } + + let prepared: { home: string; path: string }; + try { + prepared = prepareOwnerPath(configDir); + } catch (cause) { + if (cause instanceof SpendLedgerOwnerError) throw cause; + throw new SpendLedgerOwnerError( + "SPEND_LEDGER_OWNER_UNAVAILABLE", + "Spend-ledger ownership could not be established safely.", + { cause }, + ); + } + + let database: Database | undefined; + try { + database = new Database(prepared.path, { create: true }); + database.exec(`PRAGMA locking_mode = NORMAL; PRAGMA busy_timeout = ${busyTimeout}; BEGIN IMMEDIATE`); + } catch (cause) { + try { database?.close(); } catch { /* preserve acquisition failure */ } + if (isBusy(cause)) { + throw new SpendLedgerOwnerError( + "SPEND_LEDGER_OWNER_BUSY", + "Another OpenCodex process already owns this spend ledger. Use a separate OPENCODEX_HOME for an independent instance.", + ); + } + throw new SpendLedgerOwnerError( + "SPEND_LEDGER_OWNER_UNAVAILABLE", + "Spend-ledger ownership could not be established safely.", + { cause }, + ); + } + + activeOwner = { home: prepared.home, database, references: 1 }; + ownerGeneration += 1; + return leaseFor(activeOwner); +} + +function leaseFor(owner: ActiveOwner): SpendLedgerOwnerLease { + let released = false; + return Object.freeze({ + release(): void { + if (released) return; + released = true; + if (activeOwner !== owner || owner.references < 1) return; + owner.references -= 1; + if (owner.references > 0) return; + activeOwner = null; + boundLedgerHome = null; + for (const hook of releaseHooks) { + try { hook(); } catch { /* a discard hook must not mask a release failure */ } + } + let failure: unknown; + try { owner.database.exec("ROLLBACK"); } catch (error) { failure = error; } + try { owner.database.close(); } catch (error) { failure ??= error; } + if (failure !== undefined) { + throw new SpendLedgerOwnerError( + "SPEND_LEDGER_OWNER_UNAVAILABLE", + "Spend-ledger ownership could not be released cleanly.", + { cause: failure }, + ); + } + }, + }); +} + +/** The ownership a ledger was built under, to be handed back on every later use. */ +export function currentSpendLedgerOwnerGeneration(): number { + return ownerGeneration; +} + +/** + * Permission to touch one file under the owned state directory, for as long as this exact + * ownership lasts. + * + * A callback supplied by the caller cannot be this proof: the caller can pass one that does + * nothing, which is how a "required guard" still allowed an unowned write. A marker carried ON + * the object is not proof either, because an object spread copies it: `{ ...minted, path: + * elsewhere, assert() {} }` would look minted while pointing somewhere else. So the token + * carries nothing. The path and the ownership it was minted under live in a table only this + * module can read, keyed by the token's identity, and a copy is simply not that key. + */ +export interface SpendLedgerStorage { + readonly __spendLedgerStorage: unique symbol; +} + +const mintedStorage = new WeakMap(); + +function trustedStorage(storage: SpendLedgerStorage): { readonly path: string; readonly generation: number; readonly home: string } { + const entry = typeof storage === "object" && storage !== null ? mintedStorage.get(storage) : undefined; + if (!entry) { + throw new SpendLedgerOwnerError( + "SPEND_LEDGER_OWNER_NOT_HELD", + "Spend-ledger ownership is required before the shared ledger can be used.", + ); + } + return entry; +} + +/** + * Mint storage permission for one file name directly under the owned state directory. + * + * The name is a file name, never a path: joining a caller-supplied path would let the caller + * choose the destination, which is the thing ownership is supposed to decide. + */ +export function mintSpendLedgerStorage(fileName: string): SpendLedgerStorage { + if (fileName.includes("/") || fileName.includes("\\") || fileName === "." || fileName === "..") { + throw new SpendLedgerOwnerError( + "SPEND_LEDGER_OWNER_UNAVAILABLE", + "Spend-ledger storage could not be established safely.", + ); + } + assertSpendLedgerOwnerHeld(); + const owner = activeOwner; + if (!owner) { + throw new SpendLedgerOwnerError( + "SPEND_LEDGER_OWNER_NOT_HELD", + "Spend-ledger ownership is required before the shared ledger can be used.", + ); + } + const generation = ownerGeneration; + const home = owner.home; + // The token is deliberately empty: everything trustworthy about it is held here, under its + // identity, where a spread cannot reach. + const token = Object.freeze({}) as unknown as SpendLedgerStorage; + mintedStorage.set(token, { path: join(home, fileName), generation, home }); + return token; +} + +/** The file this token stands for, as this module recorded it at mint time. */ +export function spendLedgerStoragePath(storage: SpendLedgerStorage): string { + return trustedStorage(storage).path; +} + +/** + * Refuse unless this exact token was minted here and its ownership is still current. + * + * Both halves matter: identity rules out a copy or a look-alike, and the generation rules out a + * token minted before the lock was dropped and taken again. + */ +export function assertStorageOwned(storage: SpendLedgerStorage): void { + const entry = trustedStorage(storage); + assertSpendLedgerOwnerGeneration(entry.generation, entry.home); +} + +/** + * Refuse a handle built under an ownership that has since ended. + * + * The state directory may be the same one; what matters is that the lock was dropped and taken + * again in between, because another process could have written the journal while it was free. + */ +export function assertSpendLedgerOwnerGeneration(generation: number, configDir = getConfigDir()): void { + assertSpendLedgerOwnerHeld(configDir); + if (generation !== ownerGeneration) { + throw new SpendLedgerOwnerError( + "SPEND_LEDGER_OWNER_NOT_HELD", + "Spend-ledger ownership is required before the shared ledger can be used.", + ); + } +} + +/** The singleton journal may be touched only while its matching state directory is owned. */ +export function assertSpendLedgerOwnerHeld(configDir = getConfigDir()): void { + let home: string; + try { + const canonical = realpathSync.native(resolve(configDir)); + home = process.platform === "win32" ? canonical.toLowerCase() : canonical; + } catch (cause) { + throw new SpendLedgerOwnerError( + "SPEND_LEDGER_OWNER_NOT_HELD", + "Spend-ledger ownership is required before the shared ledger can be used.", + { cause }, + ); + } + if (!activeOwner || activeOwner.home !== home || activeOwner.references < 1) { + throw new SpendLedgerOwnerError( + "SPEND_LEDGER_OWNER_NOT_HELD", + "Spend-ledger ownership is required before the shared ledger can be used.", + ); + } +} + +/** Permanently bind the live process-wide singleton to its first constructed home. */ +export function bindSpendLedgerOwnerHome(configDir = getConfigDir()): void { + assertSpendLedgerOwnerHeld(configDir); + const home = stateDirectoryIdentity(configDir); + if (boundLedgerHome !== null && boundLedgerHome !== home) { + throw new SpendLedgerOwnerError( + "SPEND_LEDGER_OWNER_HOME_CONFLICT", + "This process already owns the spend ledger for a different state directory.", + ); + } + boundLedgerHome = home; +} + +export function spendLedgerOwnerSnapshot(): { readonly ownership: "held" | "unheld" } { + return { ownership: activeOwner ? "held" : "unheld" }; +} + +/** Test seam paired with discarding the process-wide ledger singleton. */ +export function resetSpendLedgerOwnerBindingForTest(): void { + boundLedgerHome = null; +} diff --git a/src/lib/spend-reservation-ledger.ts b/src/lib/spend-reservation-ledger.ts index 5c10efca770..1a7ff2b4c64 100644 --- a/src/lib/spend-reservation-ledger.ts +++ b/src/lib/spend-reservation-ledger.ts @@ -24,11 +24,10 @@ * released. Minting a new root id mints no new budget because the identity and pool scopes * still hold the spend. * - * SUPPORTED TOPOLOGY: this guarantees a single proxy process against its own journal. The - * file is append-friendly, but nothing here serializes two live processes writing it, so a - * second proxy sharing the same OPENCODEX_HOME is explicitly outside the guarantee -- that - * needs a shared store with cross-process atomicity and is declared out of scope rather - * than implied. + * SUPPORTED TOPOLOGY: one live writer owns one OPENCODEX_HOME journal. Every server and + * direct shared-ledger caller must hold the state-directory SQLite lease before replay, + * append or compaction. Independent homes remain independent; multi-host shared storage + * still needs a distributed transaction boundary and is outside this local lease. * * Five properties this file owes its callers. Each one was absent in the first draft, and a * budget that can be bypassed is worse than no budget because it looks like protection: @@ -54,7 +53,7 @@ * that are re-applied to an EXISTING file rather than trusted from its creation. */ -import { appendFileSync, chmodSync, existsSync, mkdirSync, readFileSync, renameSync, statSync, writeFileSync } from "node:fs"; +import { appendFileSync, chmodSync, closeSync, lstatSync, mkdirSync, openSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync } from "node:fs"; import { createHash, randomBytes } from "node:crypto"; import { dirname, join } from "node:path"; // Definition-site import, not the ../config barrel -- same reasoning as @@ -66,6 +65,12 @@ import type { OcxSpendConfig, OcxSpendScopeConfig } from "../types/config"; import { assertNotRealHomeUnderTest } from "./test-home-guard"; // Windows chmod does not remove inherited ACEs; this is the repository's icacls path. import { hardenSecretPath } from "./windows-secret-acl"; +import { assertSpendLedgerOwnerHeld, assertStorageOwned, bindSpendLedgerOwnerHome, mintSpendLedgerStorage, onSpendLedgerOwnerReleased, resetSpendLedgerOwnerBindingForTest, SpendLedgerOwnerError, spendLedgerOwnerSnapshot, spendLedgerStoragePath, type SpendLedgerStorage } from "./spend-ledger-owner"; + +// The singleton belongs to the state directory it was built for. Releasing ownership hands that +// directory to whoever comes next, so the in-memory copy goes with it and the next construction +// replays the journal. +onSpendLedgerOwnerReleased(() => { sharedLedger = undefined; }); export const SPEND_LEDGER_JOURNAL_FILENAME = "spend-ledger.jsonl"; /** @@ -391,7 +396,70 @@ function hardenLedgerFile(path: string, options: { readonly force?: boolean } = } catch { /* best-effort: a non-owner cannot chmod */ } } -export function createFileSpendJournal(path: string): SpendJournal { +/** + * Fault injection for the journal's own filesystem steps. Internal test contract, not config. + * + * The compaction cleanup only runs when a step after the exclusive create fails, and there is no + * portable way to make a validate, harden or rename fail on demand. Without a seam the cleanup + * would ship asserted by reading alone, which is how a failure path stays broken. + */ +export type SpendJournalFaultStep = "stat" | "create" | "write" | "validate" | "harden" | "rename"; + +let journalFaultForTests: ((step: SpendJournalFaultStep, temp: string) => void) | undefined; + +export function setSpendJournalFaultForTests( + fault: ((step: SpendJournalFaultStep, temp: string) => void) | undefined, +): void { + journalFaultForTests = fault; +} + +/** + * Does a directory entry exist here, whatever it points at? + * + * `existsSync` follows the link, so a symlink whose target is absent reads as "no file" and an + * append then creates that target somewhere else entirely. The entry itself is what decides + * whether the safety check runs. + */ +function ledgerEntryExists(path: string): boolean { + try { + journalFaultForTests?.("stat", path); + lstatSync(path); + return true; + } catch (error) { + // Only a genuinely absent entry is absent. Treating every failure as "no file" meant a + // permission denial or an I/O error skipped assertSafeLedgerFile entirely and let the + // append proceed against whatever is actually there, which is the case that check exists + // for. An entry we cannot inspect is a refusal, not an empty slot. + // + // Raised as the module's typed error rather than the raw fs error: the path and errno of a + // state file are not something a client should be handed. + if ((error as NodeJS.ErrnoException | null)?.code === "ENOENT") return false; + throw new SpendLedgerOwnerError( + "SPEND_LEDGER_OWNER_UNAVAILABLE", + "Spend-ledger storage could not be inspected safely.", + { cause: error }, + ); + } +} + +function assertSafeLedgerFile(path: string): void { + const stat = lstatSync(path); + if (!stat.isFile() || stat.isSymbolicLink() || stat.nlink !== 1 + || (process.platform !== "win32" && stat.uid !== process.getuid!())) { + throw new SpendLedgerOwnerError( + "SPEND_LEDGER_OWNER_UNAVAILABLE", + "Spend-ledger storage could not be opened safely.", + ); + } +} + +/** + * The production journal. Its location comes from the owned state directory and every touch + * proves that ownership, so there is no entrypoint here that writes a caller-chosen path. + */ +export function createOwnedFileSpendJournal(storage: SpendLedgerStorage): SpendJournal { + assertStorageOwned(storage); + const path = spendLedgerStoragePath(storage); const ensureDir = (): string => { const dir = dirname(path); // The guard runs before any mutation so a rejected write leaves nothing behind. @@ -401,26 +469,66 @@ export function createFileSpendJournal(path: string): SpendJournal { }; return { read(): string[] { - if (!existsSync(path)) return []; + assertStorageOwned(storage); + if (!ledgerEntryExists(path)) return []; + assertSafeLedgerFile(path); // Replay is once per process and is the moment a journal inherited from an older build // or a restored backup first passes through here. hardenLedgerFile(path, { force: true }); return readFileSync(path, "utf8").split("\n").filter((line) => line.length > 0); }, append(line: string): void { + assertStorageOwned(storage); ensureDir(); - const created = !existsSync(path); + const created = !ledgerEntryExists(path); + if (!created) assertSafeLedgerFile(path); appendFileSync(path, line + "\n", { encoding: "utf8", mode: 0o600 }); + assertSafeLedgerFile(path); hardenLedgerFile(path, { force: created }); }, rewrite(lines: string[]): void { + assertStorageOwned(storage); ensureDir(); // Same directory, so the rename is atomic on the same filesystem: a crash mid-compaction // leaves either the old journal or the new one, never a half-written ledger. - const temp = `${path}.compact-${process.pid}`; - writeFileSync(temp, lines.map((line) => line + "\n").join(""), { encoding: "utf8", mode: 0o600 }); - hardenLedgerFile(temp, { force: true }); - renameSync(temp, path); + if (ledgerEntryExists(path)) assertSafeLedgerFile(path); + const temp = `${path}.compact-${process.pid}-${randomBytes(6).toString("hex")}`; + // The creation is INSIDE the cleanup, not before it. The name carries random bytes, so a + // failure anywhere after the entry exists used to leave a uniquely named file and the next + // attempt made another: repeated failures accumulated instead of overwriting one fixed + // name. Only an entry this call created is removed, so a name that turned out to belong to + // something else is left alone, and the original journal and the primary error survive. + let fd: number | undefined; + let created = false; + let renamed = false; + try { + // Exclusive create FIRST, so "this entry is ours" is a fact rather than a guess about + // which error a combined write threw. EEXIST leaves created false and the name is left + // alone; every failure after this point is cleaned because the entry is provably ours, + // including a write that stopped partway through. + journalFaultForTests?.("create", temp); + fd = openSync(temp, "wx", 0o600); + created = true; + journalFaultForTests?.("write", temp); + writeFileSync(fd, lines.map((line) => line + "\n").join(""), { encoding: "utf8" }); + closeSync(fd); + fd = undefined; + journalFaultForTests?.("validate", temp); + assertSafeLedgerFile(temp); + journalFaultForTests?.("harden", temp); + hardenLedgerFile(temp, { force: true }); + journalFaultForTests?.("rename", temp); + renameSync(temp, path); + renamed = true; + } finally { + if (fd !== undefined) { + try { closeSync(fd); } catch { /* the compaction failure is the one to report */ } + } + if (created && !renamed) { + try { unlinkSync(temp); } catch { /* same */ } + } + } + assertSafeLedgerFile(path); hardenLedgerFile(path, { force: true }); }, }; @@ -433,17 +541,26 @@ export function createFileSpendJournal(path: string): SpendJournal { * recorded spend, which would hand every scope a fresh allowance -- so it is a file, not a * per-process value. */ -export function loadOrCreateSpendLedgerSalt(path: string): string { - if (existsSync(path)) { +export function loadOrCreateSpendLedgerSalt(storage: SpendLedgerStorage): string { + assertStorageOwned(storage); + const path = spendLedgerStoragePath(storage); + if (ledgerEntryExists(path)) { + assertSafeLedgerFile(path); hardenLedgerFile(path, { force: true }); const existing = readFileSync(path, "utf8").trim(); if (/^[0-9a-f]{32,}$/.test(existing)) return existing; + throw new SpendLedgerOwnerError( + "SPEND_LEDGER_OWNER_UNAVAILABLE", + "Spend-ledger storage could not be opened safely.", + ); } const dir = dirname(path); + assertStorageOwned(storage); assertNotRealHomeUnderTest(dir); mkdirSync(dir, { recursive: true, mode: 0o700 }); const salt = randomBytes(32).toString("hex"); - writeFileSync(path, salt + "\n", { encoding: "utf8", mode: 0o600 }); + writeFileSync(path, salt + "\n", { encoding: "utf8", mode: 0o600, flag: "wx" }); + assertSafeLedgerFile(path); hardenLedgerFile(path, { force: true }); return salt; } @@ -529,6 +646,12 @@ export function createSpendReservationLedger(options: { * no file anyone could correlate. */ readonly salt?: string; + /** + * Shared production ledgers prove their exact ownership before reading or changing + * accounting. Identity, not just the directory name: a handle kept across a release and a + * reacquire describes a journal another writer may have changed in between. + */ + readonly assertOwnedAccounting?: () => void; } = {}): SpendReservationLedger { // Mutable because the ceilings are operator configuration, and configuration is reloadable. // The three bounds below are read through functions for the same reason: a value captured @@ -538,6 +661,7 @@ export function createSpendReservationLedger(options: { const journal = options.journal; const now = options.now ?? (() => Date.now()); const salt = options.salt ?? ""; + const assertOwnedAccounting = options.assertOwnedAccounting; const maxTrackedScopes = (): number => policy.maxTrackedScopes ?? DEFAULT_MAX_TRACKED_SCOPES; const maxTrackedSends = (): number => policy.maxTrackedSends ?? DEFAULT_MAX_TRACKED_SENDS; const compactAfterRecords = (): number => policy.compactAfterRecords ?? DEFAULT_COMPACT_AFTER_RECORDS; @@ -592,7 +716,8 @@ export function createSpendReservationLedger(options: { journal.append(JSON.stringify(record)); recordsOnDisk += 1; return true; - } catch { + } catch (error) { + if (error instanceof SpendLedgerOwnerError) throw error; // In-memory state still bounds this process; the counter is how a caller learns the // restart guarantee degraded instead of discovering it after the fact. persistFailures += 1; @@ -819,7 +944,8 @@ export function createSpendReservationLedger(options: { try { rewrite.call(journal, [JSON.stringify(checkpoint)]); recordsOnDisk = 1; - } catch { + } catch (error) { + if (error instanceof SpendLedgerOwnerError) throw error; // Compaction is maintenance, not accounting: a failed rewrite leaves the previous // journal intact and every figure in it still replayable. persistFailures += 1; @@ -844,12 +970,15 @@ export function createSpendReservationLedger(options: { }; return { - get persistFailures() { return persistFailures; }, - get corruptRecords() { return corruptRecords; }, - get degraded() { return persistFailures > 0 || corruptRecords > 0; }, - get policy() { return policy; }, + // Every figure this ledger reports describes a journal it must still own. Reporting one + // after ownership ended is the same error as writing then, with a quieter symptom. + get persistFailures() { assertOwnedAccounting?.(); return persistFailures; }, + get corruptRecords() { assertOwnedAccounting?.(); return corruptRecords; }, + get degraded() { assertOwnedAccounting?.(); return persistFailures > 0 || corruptRecords > 0; }, + get policy() { assertOwnedAccounting?.(); return policy; }, reserve(request: SpendReservationRequest): SpendReservationDecision { + assertOwnedAccounting?.(); const tokens = sanitizeTokens(request.inputTokens) + sanitizeTokens(request.outputCeilingTokens); const at = request.at ?? now(); const send = aliasFor("send", request.sendId); @@ -904,6 +1033,7 @@ export function createSpendReservationLedger(options: { }, markDispatched(sendId: string): boolean { + assertOwnedAccounting?.(); const send = aliasFor("send", sendId); const reservation = reservations.get(send); if (!reservation || reservation.status !== "open") return false; @@ -914,6 +1044,7 @@ export function createSpendReservationLedger(options: { }, abandon(sendId: string): boolean { + assertOwnedAccounting?.(); const send = aliasFor("send", sendId); const reservation = reservations.get(send); // Only an UNDISPATCHED reservation may be released for free. Once bytes have left for @@ -926,6 +1057,7 @@ export function createSpendReservationLedger(options: { }, settle(sendId: string, usage: SpendUsage): boolean { + assertOwnedAccounting?.(); const send = aliasFor("send", sendId); const reservation = reservations.get(send); if (!reservation || !isLive(reservation.status)) return false; @@ -937,6 +1069,7 @@ export function createSpendReservationLedger(options: { }, markLost(sendId: string): boolean { + assertOwnedAccounting?.(); const send = aliasFor("send", sendId); const reservation = reservations.get(send); if (!reservation || !isLive(reservation.status)) return false; @@ -947,10 +1080,14 @@ export function createSpendReservationLedger(options: { }, knows(sendId: string): boolean { + assertOwnedAccounting?.(); return reservations.has(aliasFor("send", sendId)); }, snapshot(scope: SpendScope, scopeId: string): ScopeSpendSnapshot | undefined { + // Reading accounting from a handle whose ownership has ended is as wrong as writing it: + // the figures describe a journal this process no longer owns. + assertOwnedAccounting?.(); const state = scopes.get(scopeKey(scope, aliasFor(scope, scopeId))); if (!state) return undefined; return { @@ -962,11 +1099,13 @@ export function createSpendReservationLedger(options: { }, exhausted(scope: SpendScope, scopeId: string): boolean { + assertOwnedAccounting?.(); const state = scopes.get(scopeKey(scope, aliasFor(scope, scopeId))); return state !== undefined && isExhausted(scope, state); }, prune(at: number = now()): void { + assertOwnedAccounting?.(); // Removal requires BOTH inactive and not exhausted inside the window. An // exhausted-but-idle scope that was dropped would be recreated fresh under the // same id -- the exact laundering the ceiling exists to stop. @@ -975,6 +1114,7 @@ export function createSpendReservationLedger(options: { }, reconfigure(next: SpendReservationPolicy): void { + assertOwnedAccounting?.(); policy = next; }, }; @@ -1036,6 +1176,12 @@ export function spendPolicyFromConfig(spend: OcxSpendConfig | undefined): SpendR * configures no ceiling must not open a journal merely because the server started. */ export function configureSharedSpendLedger(policy: SpendReservationPolicy): void { + // Recording a policy value touches no journal, so it needs no ownership. Changing a ledger + // that already exists does, because that ledger is a live view of an owned directory. + if (sharedLedger) { + assertSpendLedgerOwnerHeld(); + bindSpendLedgerOwnerHome(); + } sharedPolicy = policy; sharedLedger?.reconfigure(policy); } @@ -1043,22 +1189,67 @@ export function configureSharedSpendLedger(policy: SpendReservationPolicy): void /** * Process-wide ledger backed by the journal under OPENCODEX_HOME. Created lazily so * importing the module -- or running a request path that never reserves -- touches no - * disk. + * disk. One directory at a time, not one directory for the life of the process: the singleton + * is discarded when its ownership ends, so a later directory replays its own journal rather + * than inheriting figures from the previous one. */ export function sharedSpendLedger(): SpendReservationLedger { + assertSpendLedgerOwnerHeld(); + bindSpendLedgerOwnerHome(); if (!sharedLedger) { - const home = getConfigDir(); + // Minted by the owner module from the directory it actually owns, and carrying the exact + // ownership they were minted under. Nothing here chooses a path or supplies its own guard. + const journalStorage = mintSpendLedgerStorage(SPEND_LEDGER_JOURNAL_FILENAME); + const saltStorage = mintSpendLedgerStorage(SPEND_LEDGER_SALT_FILENAME); + const journalPath = spendLedgerStoragePath(journalStorage); + const saltPath = spendLedgerStoragePath(saltStorage); + const assertOwnedAccounting = (): void => { + assertStorageOwned(journalStorage); + if (ledgerEntryExists(journalPath)) assertSafeLedgerFile(journalPath); + if (ledgerEntryExists(saltPath)) assertSafeLedgerFile(saltPath); + }; sharedLedger = createSpendReservationLedger({ - journal: createFileSpendJournal(join(home, SPEND_LEDGER_JOURNAL_FILENAME)), - salt: loadOrCreateSpendLedgerSalt(join(home, SPEND_LEDGER_SALT_FILENAME)), + journal: createOwnedFileSpendJournal(journalStorage), + salt: loadOrCreateSpendLedgerSalt(saltStorage), policy: sharedPolicy, + assertOwnedAccounting, }); } return sharedLedger; } -/** Test seam. Production never discards the ledger: that would reset a spent budget. */ +const MAX_DIAGNOSTIC_ERROR_COUNT = 1_000_000; + +/** Scalar-only and side-effect-free: reading diagnostics never constructs or replays. */ +export function spendLedgerDiagnosticsSnapshot(): { + readonly ownership: "held" | "unheld"; + readonly initialized: boolean; + readonly configured: boolean; + readonly degraded: boolean; + readonly persistFailures: number; + readonly corruptRecords: number; +} { + const ledger = sharedLedger; + const bounded = (value: number): number => Math.min(MAX_DIAGNOSTIC_ERROR_COUNT, Math.max(0, value)); + return { + ...spendLedgerOwnerSnapshot(), + initialized: ledger !== undefined, + configured: spendCeilingsConfigured(sharedPolicy), + degraded: ledger?.degraded ?? false, + persistFailures: bounded(ledger?.persistFailures ?? 0), + corruptRecords: bounded(ledger?.corruptRecords ?? 0), + }; +} + +/** + * Test seam for discarding the singleton outright. + * + * Production discards it too, but only with the ownership it belongs to, which is what + * `onSpendLedgerOwnerReleased` does. Neither path resets a spent budget: the journal is the + * durable record and the next construction replays it. + */ export function resetSharedSpendLedgerForTest(): void { sharedLedger = undefined; sharedPolicy = DEFAULT_SPEND_RESERVATION_POLICY; + resetSpendLedgerOwnerBindingForTest(); } diff --git a/src/server/index.ts b/src/server/index.ts index 47323e0f681..af20051d9eb 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -116,7 +116,6 @@ import { type RequestLogEntry, } from "./request-log"; import { sessionLaneIdFromRequest } from "./request-log-conversation"; -import { configureSharedSpendLedger, spendPolicyFromConfig } from "../lib/spend-reservation-ledger"; import { admitHttpWorkflowTurn, workflowDecisionRefusalResponse, type WorkflowRefusalLog } from "./workflow-refusal"; export { addFinalRequestLog, @@ -205,8 +204,15 @@ import { import { detectInstall } from "../update/index"; import { createServeOptions, type ServerIngress } from "./index/serve-options"; import { inspectStartupOwnership, setStartupCacheInvalidationWrite, warnAgentTaskRecoveryStartup, warnPlaintextV2AgentMessagesStartup, type StartServerDeps } from "./index/startup-warnings"; +import { acquireSpendLedgerServerLifecycle, type SpendLedgerServerLifecycle } from "./index/spend-ledger-lifecycle"; export function startServer(port?: number, deps: StartServerDeps = {}): Server { + const spendLedgerLifecycle = acquireSpendLedgerServerLifecycle(getConfigDir()); + try { return startServerWithSpendLedgerOwner(port, deps, spendLedgerLifecycle); } + catch (error) { spendLedgerLifecycle.releaseAfterFailedStart(); throw error; } +} + +function startServerWithSpendLedgerOwner(port: number | undefined, deps: StartServerDeps, spendLedgerLifecycle: SpendLedgerServerLifecycle): Server { const localAttestationSecret = deps.localAttestationSecret ?? createLocalAttestationSecret(); // Captured before loadConfig() starts the optional ACL flight so stop() drains the same dir // even if OPENCODEX_HOME changes underneath a long-lived process. @@ -299,12 +305,8 @@ export function startServer(port?: number, deps: StartServerDeps = {}): Server({ ...serveOptions, port: listenPort, hostname: bindHost }); + server = spendLedgerLifecycle.track(Bun.serve({ ...serveOptions, port: listenPort, hostname: bindHost })); // Both binds are one startup transaction (#1102). If the loopback bind fails after the // public one succeeded, leaving the public listener up would strand it: the CLI's port @@ -711,11 +713,11 @@ export function startServer(port?: number, deps: StartServerDeps = {}): Server({ + loopbackServer = spendLedgerLifecycle.track(Bun.serve({ ...serveOptions, port: loopbackListenerPort, hostname: "127.0.0.1", - }); + })); } catch (error) { try { // startServer is synchronous, so this rollback cannot await. Bun begins closing the @@ -731,11 +733,11 @@ export function startServer(port?: number, deps: StartServerDeps = {}): Server({ + managementIngressServer = spendLedgerLifecycle.track(Bun.serve({ ...serveOptions, port: managementIngressPort, hostname: "127.0.0.1", - }); + })); } catch (error) { // Preserve the management bind failure while synchronously initiating rollback of every // listener already opened in this startup transaction. startServer must not become async. @@ -792,7 +794,8 @@ export function startServer(port?: number, deps: StartServerDeps = {}): Server }>(server: T): T; + release(): void; + releaseAfterFailedStart(): void; +} + +/** Acquire before config loading so every later startup failure has one rollback owner. */ +export function acquireSpendLedgerServerLifecycle(configDir: string): SpendLedgerServerLifecycle { + const owner: SpendLedgerOwnerLease = acquireSpendLedgerOwner(configDir); + // Each entry returns whatever the listener's own stop returned. Typed as void-or-promise + // because the rollback below has to WAIT on it: declaring it `() => void` let the call site + // compile while statically erasing the promise it needs to await. + const failedStartStops: Array<() => void | Promise> = []; + let released = false; + const release = (): void => { + if (released) return; + released = true; + owner.release(); + }; + return { + configure(spend): void { + configureSharedSpendLedger(spendPolicyFromConfig(spend)); + }, + track }>(server: T): T { + // Capture the raw stop before startServer replaces the public method with full teardown. + const stop = server.stop.bind(server); + failedStartStops.push(() => stop(true)); + return server; + }, + release, + releaseAfterFailedStart(): void { + // Every listener that came up is stopped, newest first, and the lease is held until those + // stops have actually SETTLED. Bun's Server.stop(true) returns a promise that resolves + // once connections are closed, so discarding it handed the state directory back while a + // listener could still be serving, which is the one thing single-writer ownership exists + // to prevent. + // + // This stays synchronous and returns void on purpose: startServer must not become async, + // so the wait is a continuation rather than an await. Rollback failures are contained + // because the startup error that brought us here is the one worth reporting. + const settling: Promise[] = []; + for (const stop of failedStartStops.splice(0).reverse()) { + try { + const pending = stop(); + if (pending !== undefined) settling.push(Promise.resolve(pending)); + } catch { /* a rollback failure must not replace the startup error that caused it */ } + } + const finish = (): void => { + try { release(); } catch { /* same: the startup error is the one that matters */ } + }; + if (settling.length === 0) { finish(); return; } + void Promise.allSettled(settling).then(finish); + }, + }; +} diff --git a/src/server/management/system-restart.ts b/src/server/management/system-restart.ts index cfcc9ca416c..f88c4209b2f 100644 --- a/src/server/management/system-restart.ts +++ b/src/server/management/system-restart.ts @@ -36,6 +36,7 @@ import { isServiceViable } from "../../service"; import { readRuntimePort } from "../../config/process-state"; import { withProcessRuntimeProvenance } from "../../lib/bun-runtime"; import { selfLaunchArgv } from "../../lib/self-launch-argv"; +import { spendLedgerRestartEnvironment } from "../../lib/spend-ledger-owner"; import { MEMORY_DRAIN_RESTART_MS, REPLACEMENT_READY_TIMEOUT_MS, @@ -225,8 +226,12 @@ function spawnDetachedStart( return new Promise((resolve, reject) => { let child: ReturnType; try { - const env: NodeJS.ProcessEnv = { ...process.env }; - delete env.OCX_SERVICE; + const sourceEnv: NodeJS.ProcessEnv = { ...process.env }; + delete sourceEnv.OCX_SERVICE; + const env = spendLedgerRestartEnvironment( + sourceEnv, + waitForHealthBeforeParentExit ? undefined : process.pid, + ); child = spawn(process.execPath, launchArgs, { detached: true, stdio: "ignore", diff --git a/src/server/management/system-routes.ts b/src/server/management/system-routes.ts index 3819a8e52d6..04d9f566210 100644 --- a/src/server/management/system-routes.ts +++ b/src/server/management/system-routes.ts @@ -39,6 +39,7 @@ import { } from "../../lib/codex-restart-contract"; import { jsonResponse } from "../auth-cors"; import { getInspectionCounters } from "../relay"; +import { spendLedgerDiagnosticsSnapshot } from "../../lib/spend-reservation-ledger"; import type { performCodexRestart, readCodexAppServerState, @@ -60,6 +61,7 @@ export async function handleSystemRoutes(ctx: ManagementContext): Promise ProviderAdapter) | undefined; @@ -13,8 +14,15 @@ mock.module("../../src/server/adapter-resolve", () => ({ })); const { handleResponses } = await import("../../src/server/responses"); +let releaseSpendHome: (() => void) | undefined; + +// Direct physical dispatch needs the writer lease to prevent spend-ledger ownership failures. +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; afterEach(() => { + // Release first so a failed dispatch cannot leak ownership into the next case. + releaseSpendHome?.(); + releaseSpendHome = undefined; adapterFactory = undefined; }); @@ -63,6 +71,7 @@ describe("Responses abort guards", () => { }, }); + takeSpendHome(); const response = await post("test-run-turn", false); const body = await response.text(); @@ -107,6 +116,7 @@ describe("Responses abort guards", () => { }, }); + takeSpendHome(); const response = await post("test-fetch", true, clientAbort.signal); await response.text(); await new Promise(resolve => setImmediate(resolve)); @@ -175,6 +185,7 @@ describe("Responses abort guards", () => { }, }); + takeSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, diff --git a/tests/adapters/anthropic/anthropic-quota-dispatch.test.ts b/tests/adapters/anthropic/anthropic-quota-dispatch.test.ts index 19eeed80a17..3e641d93713 100644 --- a/tests/adapters/anthropic/anthropic-quota-dispatch.test.ts +++ b/tests/adapters/anthropic/anthropic-quota-dispatch.test.ts @@ -1,5 +1,6 @@ /** Physical response attribution through the real adapter and response/search loops. */ import { afterEach, beforeEach, expect, mock, test } from "bun:test"; +import { acquireOwnedSpendHome } from "../../helpers/owned-spend-home"; import { mkdtempSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; @@ -37,6 +38,7 @@ const originalHome = process.env.OPENCODEX_HOME; let originalFetch: typeof globalThis.fetch; let unexpectedGlobalFetches = 0; let home: string; +let releaseSpendHome: (() => void) | undefined; let sent: { authorization: string | null; apiKey: string | null; body: Record }[]; beforeEach(() => { @@ -57,9 +59,14 @@ beforeEach(() => { clearAccountQuotaCache(); resetProviderQuotaReconcileStateForTests(); clearResponseStateForTests(); + // Dispatching without starting a server means taking the spend-journal lease here, and + // releasing it before this case's directory is removed. + releaseSpendHome = acquireOwnedSpendHome(); }); afterEach(() => { + releaseSpendHome?.(); + releaseSpendHome = undefined; adapterRequestsFollow = false; try { // Provider code may catch the guard's rejection; the attempted network call still fails the test. diff --git a/tests/adapters/anthropic/anthropic-sidecar-account-failover.test.ts b/tests/adapters/anthropic/anthropic-sidecar-account-failover.test.ts index 8d094db631b..7328d081f42 100644 --- a/tests/adapters/anthropic/anthropic-sidecar-account-failover.test.ts +++ b/tests/adapters/anthropic/anthropic-sidecar-account-failover.test.ts @@ -15,9 +15,11 @@ import { getAccountSet, saveCredential, setActiveAccount } from "../../../src/oa import { clearAccountQuotaCache, getCachedProviderAccountQuota, resetProviderQuotaReconcileStateForTests } from "../../../src/providers/quota"; import type { OcxConfig, OcxParsedRequest, OcxProviderConfig } from "../../../src/types"; import { removeTreeWithRetry } from "../../helpers/remove-tree"; +import { acquireOwnedSpendHome } from "../../helpers/owned-spend-home"; const previousHome = process.env.OPENCODEX_HOME; let testHome = ""; +let releaseSpendHome: (() => void) | undefined; let handleResponses: typeof import("../../../src/server/responses")["handleResponses"]; let observedKeys: string[] = []; let sidecarMode = false; @@ -100,9 +102,14 @@ beforeEach(() => { clearGenericFailoverHealth(); clearAccountQuotaCache(); resetProviderQuotaReconcileStateForTests(); + releaseSpendHome = acquireOwnedSpendHome(); }); afterEach(() => { + // Released before the directory below is removed: an open lease inside a directory being + // deleted fails the removal on Windows and leaves an unlinked live database on POSIX. + releaseSpendHome?.(); + releaseSpendHome = undefined; clearAnthropicAccountPoolState(); clearGenericFailoverHealth(); clearAccountQuotaCache(); diff --git a/tests/adapters/empty-tool-output-annotation.test.ts b/tests/adapters/empty-tool-output-annotation.test.ts index d0acc8213b6..7114836bd42 100644 --- a/tests/adapters/empty-tool-output-annotation.test.ts +++ b/tests/adapters/empty-tool-output-annotation.test.ts @@ -5,6 +5,7 @@ import { getProviderRegistryEntry } from "../../src/providers/registry"; import { routedProviderConfig } from "../../src/router"; import { handleResponses } from "../../src/server/responses/core"; import type { OcxConfig, OcxMessage, OcxParsedRequest, OcxProviderConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; const ANNOTATION = "[ocx] empty tool output: the tool ran but produced no stdout or return value; do not treat this as success, failure, or user-provided input."; @@ -148,7 +149,13 @@ describe("openai-chat empty tool output annotation", () => { describe("openai-responses empty tool output annotation", () => { const originalFetch = globalThis.fetch; - afterEach(() => { globalThis.fetch = originalFetch; }); + let releaseSpendHome: (() => void) | undefined; + afterEach(() => { + // Release first so a failed dispatch cannot leak writer ownership into the next case. + releaseSpendHome?.(); + releaseSpendHome = undefined; + globalThis.fetch = originalFetch; + }); async function drive(config: OcxConfig, input: unknown[]): Promise<{ body: Record }> { const requests: Array<{ body: Record }> = []; @@ -156,7 +163,9 @@ describe("openai-responses empty tool output annotation", () => { requests.push({ body: JSON.parse(String(init?.body ?? "{}")) as Record }); return Response.json({ id: "resp_test", object: "response", status: "completed", output: [] }); }) as typeof fetch; - await handleResponses( + // Direct dispatch needs the writer lease to prevent spend-ledger ownership failures. + releaseSpendHome = acquireOwnedSpendHome(); + const turn = await handleResponses( new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -165,6 +174,9 @@ describe("openai-responses empty tool output annotation", () => { config, { model: "", provider: "" }, ); + // The turn's body is a live stream. Releasing it here means no reader is still attached + // when the lease is dropped, which is what turns a finished case into a pending one. + await turn.body?.cancel(); return requests[0] ?? { body: {} }; } diff --git a/tests/adapters/openai/openai-chat-native-policy.test.ts b/tests/adapters/openai/openai-chat-native-policy.test.ts index 9357cf22154..d5ef745abee 100644 --- a/tests/adapters/openai/openai-chat-native-policy.test.ts +++ b/tests/adapters/openai/openai-chat-native-policy.test.ts @@ -15,13 +15,25 @@ import { clearKeyCooldowns } from "../../../src/providers/key-failover"; import { fastPolicyForModel } from "../../../src/providers/service-tier"; import { handleChatCompletions } from "../../../src/server/chat-completions"; import type { OcxConfig, OcxParsedRequest, OcxProviderConfig } from "../../../src/types"; +import { acquireOwnedSpendHome } from "../../helpers/owned-spend-home"; import { removeTreeWithRetry } from "../../helpers/remove-tree"; const PROVIDER_NAME = "native-tier-fixture"; const MODEL_ID = "model"; const originalFetch = globalThis.fetch; +let releaseSpendHome: (() => void) | undefined; +const takeSpendHome = (): void => { + // Taken only for direct Chat dispatches so pure policy cases do not open the journal. + releaseSpendHome ??= acquireOwnedSpendHome(); +}; +const dropSpendHome = (): void => { + releaseSpendHome?.(); + releaseSpendHome = undefined; +}; afterEach(() => { + // Released first so a failed assertion cannot leave the active home lease live. + dropSpendHome(); globalThis.fetch = originalFetch; clearKeyCooldowns(PROVIDER_NAME); }); @@ -219,6 +231,7 @@ describe("native Chat passthrough service-tier policy", () => { providers: { [PROVIDER_NAME]: target }, } as OcxConfig; + takeSpendHome(); const response = await handleChatCompletions( new Request("http://localhost/v1/chat/completions", { method: "POST", @@ -233,9 +246,13 @@ describe("native Chat passthrough service-tier policy", () => { { model: "", provider: "" }, ); - expect(response.status).toBe(200); - expect(captured).toHaveLength(1); - expect(captured[0]).not.toHaveProperty("service_tier"); + try { + expect(response.status).toBe(200); + expect(captured).toHaveLength(1); + expect(captured[0]).not.toHaveProperty("service_tier"); + } finally { + await response.body?.cancel(); + } }); test("forced Fast injects the policy wire value and forced default drops the caller tier", () => { @@ -250,6 +267,8 @@ describe("native Chat passthrough service-tier policy", () => { const previousHome = process.env.OPENCODEX_HOME; const home = mkdtempSync(join(tmpdir(), "ocx-native-tier-failover-")); process.env.OPENCODEX_HOME = home; + // Taken after this case installs its home so key-failover dispatch owns that journal. + takeSpendHome(); const captured: Array<{ authorization: string | null; body: Record }> = []; globalThis.fetch = (async (_input: RequestInfo | URL, init?: RequestInit) => { captured.push({ @@ -301,11 +320,17 @@ describe("native Chat passthrough service-tier policy", () => { { model: "", provider: "" }, ); - expect(response.status).toBe(200); - expect(captured.map(entry => entry.authorization)).toEqual(["Bearer key-one", "Bearer key-two"]); - expect(captured).toHaveLength(2); - for (const entry of captured) expect(entry.body).not.toHaveProperty("service_tier"); + try { + expect(response.status).toBe(200); + expect(captured.map(entry => entry.authorization)).toEqual(["Bearer key-one", "Bearer key-two"]); + expect(captured).toHaveLength(2); + for (const entry of captured) expect(entry.body).not.toHaveProperty("service_tier"); + } finally { + await response.body?.cancel(); + } } finally { + // Released before this case restores and removes its home so no live database is unlinked. + dropSpendHome(); if (previousHome === undefined) delete process.env.OPENCODEX_HOME; else process.env.OPENCODEX_HOME = previousHome; removeTreeWithRetry(home); @@ -420,6 +445,7 @@ describe("main and native Chat tier authorization parity", () => { const target = provider({ modelCapabilities: { [MODEL_ID]: { inputModalities: ["text", "image"] } }, }); + takeSpendHome(); const response = await handleChatCompletions( new Request("http://localhost/v1/chat/completions", { method: "POST", @@ -439,15 +465,19 @@ describe("main and native Chat tier authorization parity", () => { { model: "", provider: "" }, ); - expect(response.status).toBe(200); - expect(captured).toHaveLength(1); - const parts = (JSON.parse(captured[0]!) as { messages: Array<{ content: unknown }> }) - .messages.flatMap(m => (Array.isArray(m.content) ? m.content : [])) - .filter((p): p is { type: string; image_url: { url: string } } => - typeof p === "object" && p !== null && (p as { type?: unknown }).type === "image_url"); - // Well over the 3.5MiB image budget, and still byte-identical on the wire. - expect(parts).toHaveLength(4); - for (const part of parts) expect(part.image_url.url).toBe(url); + try { + expect(response.status).toBe(200); + expect(captured).toHaveLength(1); + const parts = (JSON.parse(captured[0]!) as { messages: Array<{ content: unknown }> }) + .messages.flatMap(m => (Array.isArray(m.content) ? m.content : [])) + .filter((p): p is { type: string; image_url: { url: string } } => + typeof p === "object" && p !== null && (p as { type?: unknown }).type === "image_url"); + // Well over the 3.5MiB image budget, and still byte-identical on the wire. + expect(parts).toHaveLength(4); + for (const part of parts) expect(part.image_url.url).toBe(url); + } finally { + await response.body?.cancel(); + } }); }); diff --git a/tests/adapters/terminal-continuation-owner-rotation.test.ts b/tests/adapters/terminal-continuation-owner-rotation.test.ts index 458f8237b61..69ce097aca4 100644 --- a/tests/adapters/terminal-continuation-owner-rotation.test.ts +++ b/tests/adapters/terminal-continuation-owner-rotation.test.ts @@ -16,6 +16,7 @@ import type { OcxParsedRequest, OcxProviderConfig, } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; interface BuildObservation { @@ -110,18 +111,24 @@ describe("terminal continuation provider-owner rotation", () => { let originalFetch: typeof fetch; let previousHome: string | undefined; let testHome = ""; + let releaseSpendHome: (() => void) | undefined; beforeEach(() => { originalFetch = globalThis.fetch; previousHome = process.env.OPENCODEX_HOME; testHome = mkdtempSync(join(tmpdir(), "ocx-terminal-owner-")); process.env.OPENCODEX_HOME = testHome; + // Take the writer lease after this case installs its home so direct handler dispatch can open the spend journal. + releaseSpendHome = acquireOwnedSpendHome(); builds = []; clearKeyCooldowns(); clearResponseStateForTests(); }); afterEach(() => { + // Release before restoring or removing the home to prevent Windows removal failures and POSIX unlinked databases. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; if (previousHome === undefined) delete process.env.OPENCODEX_HOME; else process.env.OPENCODEX_HOME = previousHome; diff --git a/tests/claude-integration/claude-code-thought-signature-scope.test.ts b/tests/claude-integration/claude-code-thought-signature-scope.test.ts index b3d981c3277..814ce7ceb4a 100644 --- a/tests/claude-integration/claude-code-thought-signature-scope.test.ts +++ b/tests/claude-integration/claude-code-thought-signature-scope.test.ts @@ -11,6 +11,7 @@ import { afterEach, describe, expect, mock, test } from "bun:test"; import type { ProviderAdapter } from "../../src/adapters/base"; import type { AdapterEvent, OcxConfig, OcxParsedRequest, OcxProviderConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; const actualResolver = await import("../../src/server/adapter-resolve"); @@ -24,8 +25,15 @@ mock.module("../../src/server/adapter-resolve", () => ({ })); const { handleResponses } = await import("../../src/server/responses"); +let releaseSpendHome: (() => void) | undefined; + +// Direct physical dispatch needs the writer lease to prevent spend-ledger ownership failures. +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; afterEach(() => { + // Release first so a failed dispatch cannot leak ownership into the next case. + releaseSpendHome?.(); + releaseSpendHome = undefined; adapterFactory = undefined; }); @@ -72,6 +80,7 @@ async function drive(options: { }; if (options.promptCacheKey !== undefined) body.prompt_cache_key = options.promptCacheKey; + takeSpendHome(); const response = await handleResponses( new Request("http://localhost/v1/responses", { method: "POST", diff --git a/tests/claude-integration/claude-inbound-cache-stabilize.test.ts b/tests/claude-integration/claude-inbound-cache-stabilize.test.ts index b11cbe3aaae..09b55cc3290 100644 --- a/tests/claude-integration/claude-inbound-cache-stabilize.test.ts +++ b/tests/claude-integration/claude-inbound-cache-stabilize.test.ts @@ -7,6 +7,7 @@ import { handleClaudeMessages } from "../../src/server/claude-messages"; import type { OcxConfig, OcxClaudeCodeConfig } from "../../src/types"; import { installIsolatedCodexHome, type IsolatedCodexHome } from "../helpers/isolated-codex-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { beforeEach, afterEach, describe, expect, test } from "bun:test"; import { stabilizeClaudeInstructionsForPromptCache } from "../../src/claude/inbound-cache-stabilize"; import { anthropicToResponsesTranslation } from "../../src/claude/inbound"; @@ -404,14 +405,22 @@ describe("Messages operator opt-in at the outbound boundary", () => { let isolatedHome: IsolatedCodexHome | undefined; let previousHome: string | undefined; let configHome: string | undefined; + let releaseSpendHome: (() => void) | undefined; beforeEach(() => { previousHome = process.env.OPENCODEX_HOME; isolatedHome = installIsolatedCodexHome("ocx-prefix-contract-"); configHome = mkdtempSync(join(tmpdir(), "ocx-prefix-config-")); process.env.OPENCODEX_HOME = configHome; + // Dispatches without starting a server, so it takes the spend-journal lease itself. Taken + // last because the lease binds the home in effect at the moment it is taken. + releaseSpendHome = acquireOwnedSpendHome(); }); afterEach(() => { + // Released before this case's home is removed: an open lease inside a directory being + // deleted fails the removal on Windows and leaves an unlinked live database on POSIX. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; isolatedHome?.restore(); if (previousHome === undefined) delete process.env.OPENCODEX_HOME; diff --git a/tests/claude-integration/claude-messages-endpoint.test.ts b/tests/claude-integration/claude-messages-endpoint.test.ts index a84e09a8782..ad5fadf5abc 100644 --- a/tests/claude-integration/claude-messages-endpoint.test.ts +++ b/tests/claude-integration/claude-messages-endpoint.test.ts @@ -31,6 +31,7 @@ import { estimateTokens } from "../../src/lib/token-estimate"; import type { OcxConfig } from "../../src/types"; import { installIsolatedCodexHome, type IsolatedCodexHome } from "../helpers/isolated-codex-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { SERVER_BUDGET_MS } from "../helpers/test-budget"; import { createTestTranslatorBudget } from "../helpers/translator-budget"; import { @@ -1132,6 +1133,10 @@ test("routed Claude requests give OpenAI sidecars main auth without leaking it t turnAdmissionLease.release(); } }; + // One lease for the whole case rather than one per invocation: both turns run against the same + // home, and re-taking it between them would discard the ledger this case is still accounting + // into. File-wide would be wrong the other way, since most cases here start a real server. + const releaseSpendHome = acquireOwnedSpendHome(); try { expect(await invokeMessages()).toBe(200); @@ -1161,6 +1166,8 @@ test("routed Claude requests give OpenAI sidecars main auth without leaking it t } finally { await forward.stop(true); await routed.stop(true); + // After both upstreams are down, so nothing is still settling against the journal. + releaseSpendHome(); } }); diff --git a/tests/claude-integration/claude-native-affinity.test.ts b/tests/claude-integration/claude-native-affinity.test.ts index d3cb071e5b8..b646e6bef78 100644 --- a/tests/claude-integration/claude-native-affinity.test.ts +++ b/tests/claude-integration/claude-native-affinity.test.ts @@ -13,6 +13,7 @@ import type { OcxConfig } from "../../src/types"; import { fakeChatGptJwt } from "../helpers/fake-chatgpt-jwt"; import { installIsolatedCodexHome, type IsolatedCodexHome } from "../helpers/isolated-codex-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; const originalFetch = globalThis.fetch; const metadata = "user_test_account__session_conversation-native"; @@ -23,6 +24,7 @@ let isolated: IsolatedCodexHome; let home: string; let previousHome: string | undefined; let token: string; +let releaseSpendHome: (() => void) | undefined; beforeEach(() => { previousHome = process.env.OPENCODEX_HOME; @@ -33,8 +35,13 @@ beforeEach(() => { writeFileSync(join(isolated.path, "auth.json"), JSON.stringify({ tokens: { access_token: token, account_id: "fixture-native-main" } })); clearComboSelectionState(); clearComboTargetCooldowns(); + // Dispatches without starting a server, so the spend-journal lease is taken here. + releaseSpendHome = acquireOwnedSpendHome(); }); afterEach(() => { + // Released before the directory is removed, so no live database sits inside it. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; clearComboSelectionState(); clearComboTargetCooldowns(); diff --git a/tests/codex-integration/main-account-hard-lock-auth.test.ts b/tests/codex-integration/main-account-hard-lock-auth.test.ts index 6b25b58abbb..3e0bb6a7994 100644 --- a/tests/codex-integration/main-account-hard-lock-auth.test.ts +++ b/tests/codex-integration/main-account-hard-lock-auth.test.ts @@ -35,6 +35,7 @@ import { setIcaclsRunnerForTests } from "../../src/lib/windows-secret-acl"; import type { OcxConfig } from "../../src/types"; import { COLD_SPAWN_WARMUP_HOOK_BUDGET_MS, warmModuleGraph } from "../helpers/cold-spawn-warmup"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { helperPath, repoRoot } from "../helpers/repo-root"; import { INTERNAL_DEADLINE_MS, SPAWN_BUDGET_MS } from "../helpers/test-budget"; @@ -106,6 +107,14 @@ function addAlternative(cfg: OcxConfig): void { }); } +let releaseSpendHome: (() => void) | undefined; +// Taken by the two cases that dispatch in-process, never for the whole file. Two describes here +// spawn a child that runs startServer against this same home, and that child takes the real +// lease: a parent holding one turns the child's startup into SPEND_LEDGER_OWNER_BUSY, which is +// the contract working and the case failing for a reason it is not about. +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; +const dropSpendHome = (): void => { releaseSpendHome?.(); releaseSpendHome = undefined; }; + beforeEach(() => { tokenExpiry = Math.floor(Date.now() / 1000) + 86_400; previousHome = process.env.OPENCODEX_HOME; @@ -125,6 +134,9 @@ beforeEach(() => { }); afterEach(() => { + // Released before this case's home is removed: an open lease inside a directory being + // deleted fails the removal on Windows and leaves an unlinked live database on POSIX. + dropSpendHome(); mock.restore(); clearAccountQuota(); clearThreadAccountMap(); @@ -493,6 +505,7 @@ describe("main quota policy at native admission", () => { model: "fixture-model", output: [], usage: { input_tokens: 1, output_tokens: 0, total_tokens: 1 }, }); }, { preconnect() {} })); + takeSpendHome(); const post = (model: string) => handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { ...Object.fromEntries(caller()), "content-type": "application/json" }, @@ -532,6 +545,7 @@ describe("main quota policy at native admission", () => { sends.push({ url: request.url, authorization: request.headers.get("authorization") }); return Response.json({ id: "cmp_policy_transport", object: "response.compaction", output: [] }); }, { preconnect() {} })); + takeSpendHome(); const post = (model: string) => handleResponsesCompact(new Request("http://localhost/v1/responses/compact", { method: "POST", headers: { ...Object.fromEntries(caller()), "content-type": "application/json" }, diff --git a/tests/codex-integration/model-pinned-effort.test.ts b/tests/codex-integration/model-pinned-effort.test.ts index a808b867675..9aa8063f57b 100644 --- a/tests/codex-integration/model-pinned-effort.test.ts +++ b/tests/codex-integration/model-pinned-effort.test.ts @@ -12,6 +12,7 @@ import { parseRequest } from "../../src/responses/parser"; import { routeModel } from "../../src/router"; import { createTestTranslatorBudget, withTestTranslatorBudget } from "../helpers/translator-budget"; import { installIsolatedCodexHome, type IsolatedCodexHome } from "../helpers/isolated-codex-home"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; import type { OcxConfig, OcxParsedRequest, OcxProviderConfig } from "../../src/types"; @@ -265,11 +266,14 @@ describe("operator pins on the actual request wire", () => { let failFirst: boolean; let failureStatus: number; let onFirstSend: (() => void) | undefined; + let releaseSpendHome: (() => void) | undefined; beforeEach(() => { savedHome = process.env.OPENCODEX_HOME; home = mkdtempSync(join(tmpdir(), "ocx-pin-wire-")); process.env.OPENCODEX_HOME = home; + // Take the writer lease after this block installs its home so direct handler dispatch can open the spend journal. + releaseSpendHome = acquireOwnedSpendHome(); codexHome = installIsolatedCodexHome("ocx-pin-wire-codex-"); captured = []; failFirst = false; @@ -309,6 +313,9 @@ describe("operator pins on the actual request wire", () => { }); afterEach(() => { + // Release before restoring or removing the home to prevent Windows removal failures and POSIX unlinked databases. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; if (savedHome === undefined) delete process.env.OPENCODEX_HOME; else process.env.OPENCODEX_HOME = savedHome; diff --git a/tests/codex-integration/native-main-owner-lifetime.test.ts b/tests/codex-integration/native-main-owner-lifetime.test.ts index 1bca364f8b1..96fe8fb4249 100644 --- a/tests/codex-integration/native-main-owner-lifetime.test.ts +++ b/tests/codex-integration/native-main-owner-lifetime.test.ts @@ -133,6 +133,26 @@ function fixture(configName = "opencodex", includePool = true): Fixture { return { root, codexHome, configDir, key, manager }; } +/** + * The same fixture with its own state directory, for a successor launched while the owner still + * listens. + * + * These cases deliberately overlap two live proxies to prove the contended, admission-denied, + * hard-kill and takeover sequence. They cannot share one OPENCODEX_HOME: the spend journal + * allows one writer per state directory, so the successor would be refused before it ever bound + * and the case would report a startup failure instead of the transition it is about. CODEX_HOME + * is unchanged, and the native-main lock, recovery journal and vault all derive from that, so + * every assertion in these cases still observes the same shared native state. + */ +function successorConfig(f: Fixture, configName: string, includePool: boolean): Fixture { + const configDir = join(f.root, configName); + const parentConfigDir = process.env.OPENCODEX_HOME; + writeConfig(f.codexHome, configDir, MAIN_CODEX_ACCOUNT_ID, includePool); + if (parentConfigDir === undefined) delete process.env.OPENCODEX_HOME; + else process.env.OPENCODEX_HOME = parentConfigDir; + return { ...f, configDir }; +} + // Each wait bounds a real child proxy doing real work: spawning Bun, opening the // owner SQLite database, and acquiring or releasing the lease. On the Windows // shards four Bun pools share one runner, so the fixed 10s bounds were reporting @@ -465,7 +485,7 @@ describe("native-main process owner lease", () => { const target = await f.manager.finishStage(stage.stageId, stage.writerToken, "target"); expect(source.profile.state).toBe("active"); - const successorFixture = { ...f }; + const successorFixture = successorConfig(f, "crash-a-successor", false); const owner = new ChildHarness(f, { NATIVE_OWNER_HOLD_SWITCH_BOUNDARY: "auth-replaced" }); let successor: ChildHarness | undefined; try { @@ -532,7 +552,7 @@ describe("native-main process owner lease", () => { expect(readFileSync(tempPath, "utf8")).toContain("access-target"); expect(probeNativeProfileRecoveryState(f.manager.context)).toBe("journal"); - successor = new ChildHarness(f, { NATIVE_OWNER_HOLD_RECOVERY: "1" }); + successor = new ChildHarness(successorConfig(f, "temp-crash-successor", false), { NATIVE_OWNER_HOLD_RECOVERY: "1" }); await successor.waitFor(event => event.event === "listening"); await successor.snapshot(isContended); await owner.hardKill(); diff --git a/tests/codex-integration/reserve-auth-context.test.ts b/tests/codex-integration/reserve-auth-context.test.ts index b66c2377bf6..c5ab020d0d8 100644 --- a/tests/codex-integration/reserve-auth-context.test.ts +++ b/tests/codex-integration/reserve-auth-context.test.ts @@ -25,6 +25,7 @@ import type { DataPlaneAdmission } from "../../src/server/auth-cors"; import type { WhamUsageResponse } from "../../src/codex/quota-types"; import type { OcxConfig } from "../../src/types"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; const MAIN = mainAccount.MAIN_CODEX_ACCOUNT_ID; const accountId = "reserve-workspace-fixture"; @@ -88,6 +89,8 @@ function prohibitPhysicalReads(): void { spyOn(mainAccount, "getValidMainAccountToken").mockImplementation(fail); } +let releaseSpendHome: (() => void) | undefined; + beforeEach(() => { oldHome = process.env.OPENCODEX_HOME; oldCodexHome = process.env.CODEX_HOME; @@ -133,9 +136,16 @@ beforeEach(() => { } throw new Error("unexpected outbound fixture destination"); }, { preconnect() {} })); + // Dispatches without starting a server, so it takes the spend-journal lease itself. Taken + // last because the lease binds the home in effect at the moment it is taken. + releaseSpendHome = acquireOwnedSpendHome(); }); afterEach(async () => { + // Released before this case's home is removed: an open lease inside a directory being + // deleted fails the removal on Windows and leaves an unlinked live database on POSIX. + releaseSpendHome?.(); + releaseSpendHome = undefined; mock.restore(); clearAccountQuota(); // Cancels this fixture's pending persistence timer before deleting its home. clearMainAccountInfoCache(); diff --git a/tests/codex-integration/reserve-dispatch.test.ts b/tests/codex-integration/reserve-dispatch.test.ts index f8da3b4af03..bd75b0af64f 100644 --- a/tests/codex-integration/reserve-dispatch.test.ts +++ b/tests/codex-integration/reserve-dispatch.test.ts @@ -27,6 +27,7 @@ import { flushConfigDirHardeningForTests } from "../../src/config/paths"; import type { DataPlaneAdmission } from "../../src/server/auth-cors"; import type { OcxConfig, OcxProviderConfig } from "../../src/types"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; const accountId = "reserve-dispatch-workspace"; const accessToken = "reserve-dispatch-owned-fixture"; @@ -68,6 +69,8 @@ async function authorize() { return { ctx, cfg, guard }; } +let releaseSpendHome: (() => void) | undefined; + beforeEach(() => { oldHome = process.env.OPENCODEX_HOME; oldCodexHome = process.env.CODEX_HOME; @@ -113,9 +116,16 @@ beforeEach(() => { } throw new Error("unexpected dispatch fixture destination"); }, { preconnect() {} })); + // Dispatches without starting a server, so it takes the spend-journal lease itself. Taken + // last because the lease binds the home in effect at the moment it is taken. + releaseSpendHome = acquireOwnedSpendHome(); }); afterEach(async () => { + // Released before this case's home is removed: an open lease inside a directory being + // deleted fails the removal on Windows and leaves an unlinked live database on POSIX. + releaseSpendHome?.(); + releaseSpendHome = undefined; mock.restore(); clearAccountQuota(); clearMainAccountInfoCache(); diff --git a/tests/fixtures/test-layout-expected.json b/tests/fixtures/test-layout-expected.json index 1de550d1e05..242d3b21983 100644 --- a/tests/fixtures/test-layout-expected.json +++ b/tests/fixtures/test-layout-expected.json @@ -1041,6 +1041,7 @@ "responses-console-go-upload-retry.test.ts": "responses", "responses-context-overflow.test.ts": "responses", "responses-custom-tool-guidance.test.ts": "responses", + "responses-custom-tool-repair-dispatch.test.ts": "responses", "responses-custom-tool-repair.test.ts": "responses", "responses-custom-tool-stream-consistency.test.ts": "responses", "responses-default-namespace-emit-normalize.test.ts": "responses", @@ -1173,6 +1174,9 @@ "sponsor-presets.test.ts": "providers", "spend-ceiling-enforcement.test.ts": "lib", "spend-ledger-file-journal.test.ts": "lib", + "spend-ledger-lifecycle.test.ts": "server", + "spend-ledger-owner-startup.test.ts": "server", + "spend-ledger-owner.test.ts": "lib", "spend-reservation-ledger.test.ts": "lib", "sse-client-frame-bounds.test.ts": "responses", "sse-decoder.test.ts": "responses", diff --git a/tests/helpers/combo-failover-upstream.ts b/tests/helpers/combo-failover-upstream.ts new file mode 100644 index 00000000000..ff9d0ee62bb --- /dev/null +++ b/tests/helpers/combo-failover-upstream.ts @@ -0,0 +1,60 @@ +/** + * Upstream response shapes for the combo failover suite. + * + * Moved verbatim out of tests/server/server-combo-failover-e2e.test.ts: that file is one line + * under its file-size cap and needed room to take the spend-journal lease. These builders + * decide nothing; each returns exactly the payload its callers were already constructing. + */ +export function chatSuccess(text: string, model = "model"): Response { + return Response.json({ + id: `chatcmpl-${model}`, + object: "chat.completion", + model, + choices: [{ index: 0, message: { role: "assistant", content: text }, finish_reason: "stop" }], + usage: { prompt_tokens: 2, completion_tokens: 1, total_tokens: 3 }, + }); +} + +export function chatStream(text: string): Response { + const frames = [ + `data: ${JSON.stringify({ choices: [{ index: 0, delta: { content: text }, finish_reason: null }] })}\n\n`, + `data: ${JSON.stringify({ choices: [{ index: 0, delta: {}, finish_reason: "stop" }], usage: { prompt_tokens: 2, completion_tokens: 1, total_tokens: 3 } })}\n\n`, + "data: [DONE]\n\n", + ].join(""); + return new Response(frames, { headers: { "content-type": "text/event-stream" } }); +} + +export function chatTruncatedZeroOutputStream(): Response { + const frames = [ + `data: ${JSON.stringify({ choices: [{ index: 0, delta: {}, finish_reason: null }] })}\n\n`, + ].join(""); + return new Response(frames, { headers: { "content-type": "text/event-stream" } }); +} + +export function chatErrorStream(message: string, prefix?: string): Response { + const frames = [ + ...(prefix + ? [`data: ${JSON.stringify({ choices: [{ index: 0, delta: { content: prefix }, finish_reason: null }] })}\n\n`] + : []), + `data: ${JSON.stringify({ error: { type: "server_error", code: "upstream_server_error", message } })}\n\n`, + "data: [DONE]\n\n", + ].join(""); + return new Response(frames, { headers: { "content-type": "text/event-stream" } }); +} + +export function responsesSuccess(text: string, model = "responses-model"): Record { + return { + id: `resp-${model}`, + object: "response", + status: "completed", + model, + output: [{ + id: "msg_backup", + type: "message", + role: "assistant", + status: "completed", + content: [{ type: "output_text", text, annotations: [] }], + }], + usage: { input_tokens: 2, output_tokens: 1, total_tokens: 3 }, + }; +} diff --git a/tests/helpers/compaction-routing-fixtures.ts b/tests/helpers/compaction-routing-fixtures.ts new file mode 100644 index 00000000000..fb4db7b627b --- /dev/null +++ b/tests/helpers/compaction-routing-fixtures.ts @@ -0,0 +1,107 @@ +import type { OcxConfig, OcxProviderConfig } from "../../src/types"; + +/** + * Config, request and upstream-response fixtures for the compaction-routing suite. + * + * Moved verbatim out of tests/responses/responses-compaction-routing.test.ts: that file sits at + * its file-size cap, and the repository answer to a cap is a sibling helper rather than + * compressed control flow. Nothing here decides anything; every value is the one its callers + * were already building inline. + */ +export function keyProviderConfig(overrides: Partial = {}): OcxConfig { + return { + defaultProvider: "gw", + providers: { + gw: { + adapter: "openai-responses", + baseUrl: "https://gateway.example/v1", + authMode: "key", + apiKey: "test-key", + ...overrides, + }, + }, + } as unknown as OcxConfig; +} + +export function nativePoolConfig(): OcxConfig { + return { + defaultProvider: "openai", + activeCodexAccountId: "pool-a", + providers: { + openai: { + adapter: "openai-responses", + baseUrl: "https://chatgpt.com/backend-api/codex", + authMode: "forward", + codexAccountMode: "pool", + }, + }, + codexAccounts: [{ + id: "pool-a", + email: "pool@example.test", + isMain: false, + chatgptAccountId: "pool_acc", + }], + } as OcxConfig; +} + +/** Two-account pool: the alternate-attempt tests need somewhere for the retry to go. */ +export function twoAccountPoolConfig(): OcxConfig { + const config = nativePoolConfig(); + config.codexAccounts = [ + { id: "pool-a", email: "a@example.test", isMain: false, chatgptAccountId: "pool_acc_a" }, + { id: "pool-b", email: "b@example.test", isMain: false, chatgptAccountId: "pool_acc_b" }, + ] as OcxConfig["codexAccounts"]; + return config; +} + +export function compactionRequest( + body: Record, + signal?: AbortSignal, + extraHeaders: Record = {}, +): Request { + return new Request("http://localhost/v1/responses", { + method: "POST", + headers: { "content-type": "application/json", ...extraHeaders }, + body: JSON.stringify(body), + signal, + }); +} + +export function baseCompactionBody(extra: Record = {}): Record { + return { + model: "gw/some-model", + stream: false, + input: [ + { type: "message", role: "user", content: [{ type: "input_text", text: "earlier turn" }] }, + { type: "compaction_trigger" }, + ], + tools: [{ type: "function", name: "shell" }], + tool_choice: "auto", + parallel_tool_calls: true, + ...extra, + }; +} + +export function jsonResponse(payload: unknown): Response { + return new Response(JSON.stringify(payload), { + status: 200, + headers: { "content-type": "application/json" }, + }); +} + +export function completedPayload(text: string): Record { + return { + id: "resp_1", + status: "completed", + output: [{ type: "message", role: "assistant", content: [{ type: "output_text", text }] }], + usage: { input_tokens: 10, output_tokens: 5, total_tokens: 15 }, + }; +} + +export function sseResponse(events: Array>): Response { + const body = events.map(e => `event: ${String(e.type)}\ndata: ${JSON.stringify(e)}\n\n`).join(""); + return new Response(body, { + status: 200, + headers: { "content-type": "text/event-stream" }, + }); +} diff --git a/tests/helpers/custom-tool-repair-fixtures.ts b/tests/helpers/custom-tool-repair-fixtures.ts new file mode 100644 index 00000000000..cedd3094903 --- /dev/null +++ b/tests/helpers/custom-tool-repair-fixtures.ts @@ -0,0 +1,20 @@ +/** + * Shared fixtures for the routed custom-tool repair suites. + * + * Both halves of that suite read the same SSE data line, build the same event block and compare + * the same decorated and canonical apply_patch bodies. They live here because the suite was split + * in two and duplicating a fixture is how two copies of it drift apart. + */ +export function dataPayload(block: string): Record { + const line = block.split(/\r?\n/).find(entry => entry.startsWith("data:")); + if (!line) throw new Error("missing SSE data line"); + return JSON.parse(line.slice(5).trim()) as Record; +} + +export function frame(event: string, payload: Record): string { + return `event: ${event}\ndata: ${JSON.stringify({ type: event, ...payload })}`; +} + +export const DECORATED_PATCH = "*** Begin Patch ***\n*** Update File: README.md\n@@\n-old\n+new\n*** End Patch ***"; +export const CANONICAL_PATCH = "*** Begin Patch\n*** Update File: README.md\n@@\n-old\n+new\n*** End Patch"; +export const WRAPPED_DECORATED_PATCH = JSON.stringify({ input: DECORATED_PATCH }); diff --git a/tests/helpers/native-injection-fixture.ts b/tests/helpers/native-injection-fixture.ts index 07f2703334c..c7d3a10b31d 100644 --- a/tests/helpers/native-injection-fixture.ts +++ b/tests/helpers/native-injection-fixture.ts @@ -6,6 +6,15 @@ import type { ServeOptionsContext } from "../../src/server/index/serve-options"; import type { WsData } from "../../src/server/ws-bridge"; import { clearRequestLogsForTests } from "../../src/server/request-log"; import { runOptionalShutdownHooks } from "../../src/lib/optional-shutdown-hooks"; +import { acquireOwnedSpendHome } from "./owned-spend-home"; + +// The websocket handler dispatches through the real request path, so it reaches the shared spend +// journal and needs the writer lease startServer would have taken. Without it the turn is refused +// and the symptom is the fixture's own wait timing out, which names nothing. +let releaseSpendHome: (() => void) | undefined; +// Every synthetic client this fixture opens, so teardown can close them before the lease is +// given back rather than leaving a handler mid-turn against a journal nobody owns. +const clients: Array> = []; export type Frame = Record; const realSocket = globalThis.WebSocket; @@ -50,12 +59,14 @@ export const waitForInjection = async (condition: () => boolean) => { throw new Error("injection fixture condition timed out"); }; export function injectionClient(fields: Frame = {}, settings = injectionConfig(), credential = "test") { + releaseSpendHome ??= acquireOwnedSpendHome(); const handler = createWebsocketHandler({ config: settings, deps: {} } as ServeOptionsContext); const sent: Frame[] = []; const ws = { readyState: 1, data: { headers: new Headers({ authorization: `Bearer ${credential}`, "thread-id": `injection-fixture-${++nextId}`, "openai-beta": "fixture_beta=v1" }) } as WsData, send: (text: string) => { sent.push(JSON.parse(text)); return 1; }, close() { handler.close(ws, 1000, "fixture close"); }, } as unknown as ServerWebSocket; const send = (frame: Frame) => handler.message(ws, JSON.stringify(frame)); + clients.push(ws); send({ type: "response.create", model: settings.defaultProvider === "api" ? "api/gpt-5.6-sol" : "gpt-5.6-sol", input: "initial", multi_agent: { enabled: true }, tools: [{ type: "function", name: "get_value", parameters: { type: "object", properties: {} } }], ...fields }); return { ws, sent, send, handler }; @@ -98,10 +109,38 @@ export function installInjectionFixture() { globalThis.fetch = (async () => { fallbackCalls++; throw new Error("network disabled in injection fixture"); }) as typeof fetch; clearRequestLogsForTests(); }); - afterEach(() => { - for (const socket of InjectionSocket.all) socket.close(); - InjectionSocket.all = []; runOptionalShutdownHooks(); - globalThis.WebSocket = realSocket; globalThis.fetch = realFetch; - for (const key of proxyKeys) { delete process.env[key]; if (savedProxy[key] !== undefined) process.env[key] = savedProxy[key]; } + afterEach(async () => { + // handler.close only STARTS the pump cancellation. Waiting for the socket to drop its stream + // cancel and its native control is what proves the turn finished accounting; releasing the + // lease before that leaves a reader settling against a journal nobody owns. + // + // The rest runs even when that wait gives up, and the failure still propagates. A wait that + // expired is NOT evidence the turn settled: it means this fixture could not prove it, and + // the case should say so while still handing back the lease and the globals it replaced. + let failure: unknown; + const note = (error: unknown): void => { failure ??= error; }; + try { + // Every client gets its close and its wait even after an earlier one gave up. Stopping at + // the first failure left the rest open for the next case to inherit. + for (const client of clients.splice(0)) { + // Separate guards: close() runs the production handler, so a throw there would otherwise + // skip this client's completion wait as well as its own failure. + try { client.close(); } catch (error) { note(error); } + try { + await waitForInjection(() => client.data.cancel === undefined && client.data.nativeControl === undefined); + } catch (error) { note(error); } + } + for (const socket of InjectionSocket.all) { + try { socket.close(); } catch (error) { note(error); } + } + InjectionSocket.all = []; + try { runOptionalShutdownHooks(); } catch (error) { note(error); } + // The release itself can throw, and it used to take the global restore down with it. + try { releaseSpendHome?.(); } catch (error) { note(error); } finally { releaseSpendHome = undefined; } + } finally { + globalThis.WebSocket = realSocket; globalThis.fetch = realFetch; + for (const key of proxyKeys) { delete process.env[key]; if (savedProxy[key] !== undefined) process.env[key] = savedProxy[key]; } + } + if (failure !== undefined) throw failure; }); } diff --git a/tests/helpers/owned-spend-home.ts b/tests/helpers/owned-spend-home.ts new file mode 100644 index 00000000000..f954d1d0b27 --- /dev/null +++ b/tests/helpers/owned-spend-home.ts @@ -0,0 +1,34 @@ +import { acquireSpendLedgerOwner, type SpendLedgerOwnerLease } from "../../src/lib/spend-ledger-owner"; +import { resetSharedSpendLedgerForTest } from "../../src/lib/spend-reservation-ledger"; + +/** + * Hold the spend-journal writer lease for a case that dispatches without starting a server. + * + * `startServer` takes this lease before anything can serve, so production traffic always + * reaches the ledger owning its state directory. A case that calls an internal handler directly + * skips that step, and the ledger refuses to write for a process that owns nothing. Taking the + * real lease here keeps the production rule intact instead of teaching the ledger to make an + * exception for tests. + * + * Returns an idempotent release. Call it FIRST in the case's own teardown, before the state + * directory is removed and before the home variable is restored: an open SQLite lease inside a + * directory being deleted fails the removal on Windows and leaves an unlinked live database on + * POSIX. Ordering is stated by the caller rather than inferred from hook registration order, + * which differs between these fixtures and is not a contract either way. + */ +export function acquireOwnedSpendHome(): () => void { + resetSharedSpendLedgerForTest(); + const lease: SpendLedgerOwnerLease = acquireSpendLedgerOwner(); + let released = false; + return () => { + if (released) return; + released = true; + // A rollback or close failure is a real defect in the thing under test, so it is allowed to + // fail the case. Swallowing it would leave a green run over a lease that never let go. + try { + lease.release(); + } finally { + resetSharedSpendLedgerForTest(); + } + }; +} diff --git a/tests/helpers/passthrough-key-url.ts b/tests/helpers/passthrough-key-url.ts new file mode 100644 index 00000000000..15716abdd63 --- /dev/null +++ b/tests/helpers/passthrough-key-url.ts @@ -0,0 +1,26 @@ +import { createResponsesPassthroughAdapter } from "../../src/adapters/openai-responses"; +import { withTestTranslatorBudget } from "./translator-budget"; + +/** + * The upstream URL a key-auth Responses passthrough adapter would actually request. + * + * Moved out of tests/responses/openai-responses-passthrough.test.ts verbatim, including the + * test translator budget its local adapter wrapper applied: that file is at its file-size cap, + * and the repository answer to a cap is a sibling helper rather than compressed control flow. + */ +export function buildKeyAuthUrl(baseUrl: string, responsesPath?: string): string { + const adapter = withTestTranslatorBudget(createResponsesPassthroughAdapter({ + adapter: "openai-responses", + baseUrl, + authMode: "key" as const, + apiKey: "sk-test", + ...(responsesPath === undefined ? {} : { responsesPath }), + })); + return adapter.buildRequest({ + modelId: "test-model", + context: { messages: [] }, + stream: true, + options: {}, + _rawBody: { model: "test-model", input: "ping" }, + }, { headers: new Headers() }).url; +} diff --git a/tests/helpers/request-log-entry.ts b/tests/helpers/request-log-entry.ts new file mode 100644 index 00000000000..4ccafb3ed4c --- /dev/null +++ b/tests/helpers/request-log-entry.ts @@ -0,0 +1,21 @@ +import type { RequestLogEntry } from "../../src/server"; + +/** + * One request-log row with every required field already filled in. + * + * Moved out of tests/usage/request-log.test.ts verbatim: that file sits at its file-size cap, and + * the repository answer to a cap is a sibling helper rather than compressed control flow. The + * defaults are the ones its twenty-seven call sites were already relying on. + */ +export function log(overrides: Partial): RequestLogEntry { + return { + requestId: "ocx-test", + timestamp: 1, + model: "gpt-test", + provider: "openai", + status: 200, + durationMs: 10, + usageStatus: "unreported", + ...overrides, + }; +} diff --git a/tests/helpers/spend-ledger-owner-child.ts b/tests/helpers/spend-ledger-owner-child.ts new file mode 100644 index 00000000000..5731b23b913 --- /dev/null +++ b/tests/helpers/spend-ledger-owner-child.ts @@ -0,0 +1,45 @@ +/** Real-process holder for spend-ledger single-writer tests. */ +import { existsSync, writeFileSync } from "node:fs"; +import { acquireSpendLedgerOwner, SpendLedgerOwnerError } from "../../src/lib/spend-ledger-owner"; +import { + configureSharedSpendLedger, + sharedSpendLedger, + type SpendReservationPolicy, +} from "../../src/lib/spend-reservation-ledger"; + +const payload = JSON.parse(process.env.OCX_SPEND_OWNER_CHILD ?? "{}") as { + holdMarker?: string; + releaseMarker?: string; + mode?: "observe" | "enforced"; +}; + +try { + const lease = acquireSpendLedgerOwner(); + const policy: SpendReservationPolicy = { + root: payload.mode === "enforced" ? { maxTokens: 1_000 } : {}, + identity: {}, + pool: {}, + retentionMs: 60_000, + }; + configureSharedSpendLedger(policy); + const ledger = sharedSpendLedger(); + ledger.reserve({ + sendId: `child-${payload.mode ?? "observe"}`, + scopes: { rootId: "child-root" }, + inputTokens: 1, + outputCeilingTokens: 1, + }); + if (payload.holdMarker) writeFileSync(payload.holdMarker, "held"); + const waiter = new Int32Array(new SharedArrayBuffer(4)); + while (payload.releaseMarker && !existsSync(payload.releaseMarker)) { + Atomics.wait(waiter, 0, 0, 20); + } + lease.release(); + console.log(JSON.stringify({ status: "acquired" })); +} catch (error) { + console.log(JSON.stringify({ + status: "refused", + code: error instanceof SpendLedgerOwnerError ? error.code : "UNKNOWN", + message: error instanceof Error ? error.message : String(error), + })); +} diff --git a/tests/helpers/sse-stream.ts b/tests/helpers/sse-stream.ts new file mode 100644 index 00000000000..63e5ccb6399 --- /dev/null +++ b/tests/helpers/sse-stream.ts @@ -0,0 +1,35 @@ +/** + * Read one SSE body end to end, and build one from a string. + * + * Both are the same two functions nine test files had written out for themselves, which is how + * they came to live here: a case at its file-size cap needed room for one more line, and the + * repository answer to that is a sibling helper rather than compressed control flow. Moved + * verbatim from tests/responses/responses-undeclared-tool-guard.test.ts, so a case that used the + * local copies is reading exactly the same behaviour through a different name. + */ +export function streamFromText(text: string): ReadableStream { + const chunk = new TextEncoder().encode(text); + let sent = false; + return new ReadableStream({ + pull(controller) { + if (sent) { + controller.close(); + return; + } + sent = true; + controller.enqueue(chunk); + }, + }); +} + +export async function readAll(stream: ReadableStream): Promise { + const reader = stream.getReader(); + const decoder = new TextDecoder(); + let text = ""; + for (;;) { + const { done, value } = await reader.read(); + if (done) break; + text += decoder.decode(value, { stream: true }); + } + return text; +} diff --git a/tests/helpers/ws-upstream-fixtures.ts b/tests/helpers/ws-upstream-fixtures.ts new file mode 100644 index 00000000000..8fd6c719558 --- /dev/null +++ b/tests/helpers/ws-upstream-fixtures.ts @@ -0,0 +1,34 @@ +import { + codexWsUpstreamFetch as rawCodexWsUpstreamFetch, + shouldUseCodexWsUpstream as rawShouldUseCodexWsUpstream, +} from "../../src/server/responses/ws-upstream"; + +/** + * Runtime pin and request shapes for the Codex WebSocket upstream suite. + * + * Moved verbatim out of tests/responses/ws-upstream.test.ts: that file sits at its file-size + * cap, and the repository answer to a cap is a sibling helper rather than compressed control + * flow. The two wrappers exist only to bind the pinned runtime identity, which is what makes + * the suite read the bounded-relay path instead of whatever the host Bun reports. + */ +export const BOUNDED_WS_RUNTIME = "1.4.0"; + +export function shouldUseCodexWsUpstream(url: string, init?: RequestInit, upstreamWebsocket = false): boolean { + return rawShouldUseCodexWsUpstream(url, init, BOUNDED_WS_RUNTIME, upstreamWebsocket); +} + +export function codexWsUpstreamFetch( + url: string, + init: RequestInit, + fallback: typeof fetch, +): Promise { + return rawCodexWsUpstreamFetch(url, init, fallback, BOUNDED_WS_RUNTIME); +} + +export function streamingInit(body: Record = {}): RequestInit { + return { + method: "POST", + headers: { "content-type": "application/json", authorization: "Bearer test" }, + body: JSON.stringify({ model: "gpt-5.5", stream: true, ...body }), + }; +} diff --git a/tests/images/z-handler-activation.test.ts b/tests/images/z-handler-activation.test.ts index 5b6f578a79d..a2227dc8b1f 100644 --- a/tests/images/z-handler-activation.test.ts +++ b/tests/images/z-handler-activation.test.ts @@ -4,6 +4,8 @@ import { join } from "node:path"; import { randomUUID } from "node:crypto"; import type { OcxConfig, OcxProviderConfig } from "../../src/types"; import type { ProviderAdapter } from "../../src/adapters/base"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; +import { removeTreeWithRetry } from "../helpers/remove-tree"; /** * Dispatch-priority regression test for the image bridge (PR #424). @@ -39,9 +41,16 @@ let runTurnCalled = false; let mockWsPlan: unknown = undefined; let handleResponses: typeof import("../../src/server/responses")["handleResponses"]; +let releaseSpendHome: (() => void) | undefined; +// Retained so teardown can remove it. Nothing created this directory before the lease did: +// taking ownership mkdirs the state directory, so the suite now owns its removal too. +let ownedHome = ""; beforeAll(async () => { - process.env.OPENCODEX_HOME = join(tmpdir(), "ocx-test-" + randomUUID()); + ownedHome = join(tmpdir(), "ocx-test-" + randomUUID()); + process.env.OPENCODEX_HOME = ownedHome; + // Take the writer lease after this suite installs its home so direct handler dispatch can open the spend journal. + releaseSpendHome = acquireOwnedSpendHome(); const actualResolver = await import("../../src/server/adapter-resolve"); mock.module("../../src/server/adapter-resolve", () => ({ @@ -112,6 +121,12 @@ beforeAll(async () => { }); afterAll(() => { + // Release, then remove, then restore. An open lease inside a directory being deleted fails + // the removal on Windows and leaves an unlinked live database on POSIX, and the removal has + // to happen while OPENCODEX_HOME still names the directory being removed. + releaseSpendHome?.(); + releaseSpendHome = undefined; + if (ownedHome) removeTreeWithRetry(ownedHome); if (PREV_HOME === undefined) delete process.env.OPENCODEX_HOME; else process.env.OPENCODEX_HOME = PREV_HOME; mock.restore(); @@ -155,6 +170,9 @@ describe("image bridge dispatch priority (handler activation)", () => { const res = await post(true, [{ type: "image_generation" }]); expect(imageBridgeRun).toBe(true); expect(res.headers.get("content-type")).toBe("text/event-stream"); + // The bridge answers with a live SSE stream. Releasing it here means no reader is + // still attached when this suite drops its lease in afterAll. + await res.body?.cancel(); }); test("alias-only image tool_choice keeps canonical bridge interception armed", async () => { @@ -176,6 +194,7 @@ describe("image bridge dispatch priority (handler activation)", () => { expect(imageBridgeToolNames).toContain("generate_image"); expect(imageBridgeToolNames).toContain("image_gen"); expect(res.headers.get("content-type")).toBe("text/event-stream"); + await res.body?.cancel(); }); test("stream=false + image_generation tool → 400 (bridge requires stream=true)", async () => { @@ -193,6 +212,7 @@ describe("image bridge dispatch priority (handler activation)", () => { expect(webSearchRun).toBe(true); expect(imageBridgeRun).toBe(false); expect(res.headers.get("content-type")).toBe("text/event-stream"); + await res.body?.cancel(); }); test("routed compaction with image_generation tool → image bridge does NOT hijack compaction (#424)", async () => { @@ -214,6 +234,7 @@ describe("image bridge dispatch priority (handler activation)", () => { ); expect(imageBridgeRun).toBe(false); expect(res.headers.get("content-type")).toBe("text/event-stream"); + await res.body?.cancel(); }); test("dual-tool on a runTurn adapter → image bridge wins (web-search loop has no runTurn support)", async () => { @@ -226,6 +247,7 @@ describe("image bridge dispatch priority (handler activation)", () => { expect(imageBridgeRun).toBe(true); expect(runTurnCalled).toBe(false); expect(res.headers.get("content-type")).toBe("text/event-stream"); + await res.body?.cancel(); } finally { useRunTurnAdapter = false; } @@ -241,6 +263,7 @@ describe("image bridge dispatch priority (handler activation)", () => { expect(webSearchRun).toBe(false); expect(runTurnCalled).toBe(false); expect(res.headers.get("content-type")).toBe("text/event-stream"); + await res.body?.cancel(); } finally { useRunTurnAdapter = false; } diff --git a/tests/lab/core-lab-boundary.test.ts b/tests/lab/core-lab-boundary.test.ts index 4e54e4ec5cb..32a5a9758fc 100644 --- a/tests/lab/core-lab-boundary.test.ts +++ b/tests/lab/core-lab-boundary.test.ts @@ -138,7 +138,11 @@ export function namesLabDirectly(source: string): boolean { * routes subagents to a different model than the operator configured. Nothing goes red; * the wrong model simply answers. */ -const SERVE_ANCHOR = "server = Bun.serve({ ...serveOptions, port: listenPort, hostname: bindHost });"; +// The anchor carries the spend-ledger wrapper because the listener is registered for rollback +// at the moment it is created. It is still the same statement and still the start of the same +// window; what changed is the expression the listener is assigned from. An anchor that no +// longer matches makes every scan below measure an empty string, which is why they assert on it. +const SERVE_ANCHOR = "server = spendLedgerLifecycle.track(Bun.serve({ ...serveOptions, port: listenPort, hostname: bindHost }));"; const ACTIVATION_ANCHOR = "if (labActivationRequired(config, labConfigDir)) {"; /** * The window ends at the RETURN, not at the activation check. @@ -1017,6 +1021,7 @@ describe("activation window stays synchronous", () => { "(...).then()": "Promise.then on the fire-and-forget `import('../codex/plan-from-token')` chain. then() registers a callback and returns immediately; the callback is a nested function this scan skips. Awaiting the import would already fail Guard 3.", "(...).catch()": "Promise.catch on that same dynamic-import chain. Same fire-and-forget: it cannot suspend startServer.", "backgroundLifecycle.scheduleStartupRun()": "src/server/background-lifecycle.ts owns this object method. The call site cannot resolve the declaration statically; scheduleStartupRun is declared `(): void` and is documented as never blocking listen.", + "spendLedgerLifecycle.track()": "Instance method on the lifecycle from acquireSpendLedgerServerLifecycle in src/server/index/spend-ledger-lifecycle.ts, called on each listener as it is created. It binds the listener's stop, records a rollback closure and returns the same server; it is declared `(server: T): T` and contains no await. An `await spendLedgerLifecycle.track(...)` would already fail Guard 3. The lifecycle's release() is not here because it is called inside the async stop wrapper, which this scan skips as a nested function.", }; /** diff --git a/tests/lib/spend-ceiling-enforcement.test.ts b/tests/lib/spend-ceiling-enforcement.test.ts index 1e8b988118d..91acd121efe 100644 --- a/tests/lib/spend-ceiling-enforcement.test.ts +++ b/tests/lib/spend-ceiling-enforcement.test.ts @@ -42,6 +42,7 @@ import { import { workflowDecisionRefusalResponse, workflowRefusalResponse } from "../../src/server/workflow-refusal"; import { getConfigDir } from "../../src/config/paths"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { acquireSpendLedgerOwner, type SpendLedgerOwnerLease } from "../../src/lib/spend-ledger-owner"; const memoryJournal = (): SpendJournal & { lines: string[] } => { const lines: string[] = []; @@ -80,17 +81,21 @@ const watched = (inner: SpendReservationLedger, asked: string[]): SpendReservati let home = ""; let previousHome: string | undefined; +let owner: SpendLedgerOwnerLease | null = null; beforeEach(() => { previousHome = process.env.OPENCODEX_HOME; home = mkdtempSync(join(tmpdir(), "ocx-spend-ceiling-")); process.env.OPENCODEX_HOME = home; + owner = acquireSpendLedgerOwner(); resetSharedSpendLedgerForTest(); resetWorkflowBudgetsForTest(); }); afterEach(() => { resetSharedSpendLedgerForTest(); + owner?.release(); + owner = null; if (previousHome === undefined) delete process.env.OPENCODEX_HOME; else process.env.OPENCODEX_HOME = previousHome; removeTreeWithRetry(home); diff --git a/tests/lib/spend-ledger-file-journal.test.ts b/tests/lib/spend-ledger-file-journal.test.ts index f2c10952fd0..ea45233c3a0 100644 --- a/tests/lib/spend-ledger-file-journal.test.ts +++ b/tests/lib/spend-ledger-file-journal.test.ts @@ -1,22 +1,134 @@ -import { describe, expect, test } from "bun:test"; -import { chmodSync, mkdtempSync, readFileSync, readdirSync, statSync } from "node:fs"; +import { afterEach, describe, expect, test } from "bun:test"; +import { appendFileSync, chmodSync, existsSync, mkdtempSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; -import { join } from "node:path"; +import { basename, join } from "node:path"; import { - createFileSpendJournal, + createOwnedFileSpendJournal, loadOrCreateSpendLedgerSalt, + SPEND_LEDGER_JOURNAL_FILENAME, + SPEND_LEDGER_SALT_FILENAME, + resetSharedSpendLedgerForTest, + setSpendJournalFaultForTests, } from "../../src/lib/spend-reservation-ledger"; +import { + acquireSpendLedgerOwner, + mintSpendLedgerStorage, + SpendLedgerOwnerError, + type SpendLedgerOwnerLease, +} from "../../src/lib/spend-ledger-owner"; +import { removeTreeWithRetry } from "../helpers/remove-tree"; /** POSIX mode bits do not describe a Windows ACL, where hardenSecretPath does the work. */ const posixModes = process.platform !== "win32"; const modeOf = (path: string): number => statSync(path).mode & 0o777; const line = (send: string): string => JSON.stringify({ v: 1, kind: "lost", send, at: 1 }); +const homes: string[] = []; +const leases: SpendLedgerOwnerLease[] = []; +let previousHome: string | undefined; + +/** + * A real lease over a throwaway state directory. + * + * These cases cover the production persistence, hardening and compaction paths, so they use the + * production entrypoints rather than a stand-in: storage is minted by the owner module from the + * directory it owns, which is the only way to obtain it. + */ +function ownedHome(prefix: string): string { + const home = mkdtempSync(join(tmpdir(), prefix)); + homes.push(home); + previousHome ??= process.env.OPENCODEX_HOME; + process.env.OPENCODEX_HOME = home; + resetSharedSpendLedgerForTest(); + leases.push(acquireSpendLedgerOwner()); + return home; +} + +afterEach(() => { + setSpendJournalFaultForTests(undefined); + for (const lease of leases.splice(0)) { + try { lease.release(); } catch { /* a failed release must not mask the case's result */ } + } + resetSharedSpendLedgerForTest(); + if (previousHome === undefined) delete process.env.OPENCODEX_HOME; + else process.env.OPENCODEX_HOME = previousHome; + previousHome = undefined; + for (const home of homes.splice(0)) removeTreeWithRetry(home); +}); + describe("spend ledger file journal", () => { + test.skipIf(!posixModes || process.getuid?.() === 0)( + "an entry that cannot be read is refused rather than reported absent", () => { + const dir = ownedHome("ocx-spend-journal-unreadable-"); + const journal = createOwnedFileSpendJournal(mintSpendLedgerStorage(SPEND_LEDGER_JOURNAL_FILENAME)); + journal.append(line("alias-one")); + + const before = readdirSync(dir).sort(); + // Deny traversal of the owned directory, so the entry's lstat fails with EACCES instead of + // ENOENT. Answering "absent" for that is what this pins: the file-safety assertion is + // skipped for an entry that reads as missing, so a journal nobody can inspect would have + // been appended to as though the slot were empty. + chmodSync(dir, 0o000); + try { + // Refused, and refused in the module's own vocabulary rather than with the errno and path + // of a state file. WHICH gate notices first is platform-dependent: where the directory + // cannot be traversed at all, the ownership check cannot resolve it before the entry is + // ever inspected. Both are the same refusal, so the type and the absence of a leaked path + // are what this pins; the seam-driven case below pins the exact message everywhere. + let refusal: unknown; + try { journal.read(); } catch (error) { refusal = error; } + expect(refusal).toBeInstanceOf(SpendLedgerOwnerError); + expect((refusal as Error).message).not.toContain(dir); + } finally { + chmodSync(dir, 0o700); + } + // Nothing was created or reset while the directory was unreadable. + expect(readdirSync(dir).sort()).toEqual(before); + // The same entry is readable again once the directory is, so the refusal was about the + // failed inspection and not about the journal's own contents. + expect(journal.read()).toHaveLength(1); + }); + + test("a genuinely absent entry still reads as empty", () => { + ownedHome("ocx-spend-journal-absent-"); + // The ENOENT control for the case above: absent is still absent, and only absent is. + expect(createOwnedFileSpendJournal(mintSpendLedgerStorage(SPEND_LEDGER_JOURNAL_FILENAME)).read()).toEqual([]); + }); + + test("a journal whose entry cannot be inspected refuses on every platform", () => { + const dir = ownedHome("ocx-spend-journal-stat-fault-"); + const journalPath = join(dir, SPEND_LEDGER_JOURNAL_FILENAME); + const journal = createOwnedFileSpendJournal(mintSpendLedgerStorage(SPEND_LEDGER_JOURNAL_FILENAME)); + journal.append(line("alias-one")); + const original = readFileSync(journalPath, "utf8"); + const before = readdirSync(dir).sort(); + + // The chmod case above is real but POSIX-only and meaningless as root. This one is the same + // contract proved everywhere: only the JOURNAL's own inspection fails, the salt stays + // readable, and every other filesystem step is real. + for (const code of ["EACCES", "EIO"] as const) { + // Matched by entry name, not by full path: the owned home is the REAL path of the + // directory, and on macOS the temp root is a symlink, so an equality check against the + // path this case built never fired and the fault silently did nothing. + setSpendJournalFaultForTests((step, target) => { + if (step !== "stat" || basename(target) !== SPEND_LEDGER_JOURNAL_FILENAME) return; + throw Object.assign(new Error(`injected ${code}`), { code }); + }); + expect(() => journal.read()).toThrowError(SpendLedgerOwnerError); + expect(() => journal.append(line("alias-two"))).toThrow(/could not be inspected safely/); + setSpendJournalFaultForTests(undefined); + } + + // Refused, not reset: no truncation, no new entries, and the salt is still mintable. + expect(readFileSync(journalPath, "utf8")).toBe(original); + expect(readdirSync(dir).sort()).toEqual(before); + expect(loadOrCreateSpendLedgerSalt(mintSpendLedgerStorage(SPEND_LEDGER_SALT_FILENAME))).toMatch(/^[0-9a-f]{32,}$/); + }); + test.skipIf(!posixModes)("a journal that already exists is re-hardened, not trusted", () => { - const dir = mkdtempSync(join(tmpdir(), "ocx-spend-journal-")); - const path = join(dir, "spend-ledger.jsonl"); - const journal = createFileSpendJournal(path); + const dir = ownedHome("ocx-spend-journal-"); + const path = join(dir, SPEND_LEDGER_JOURNAL_FILENAME); + const journal = createOwnedFileSpendJournal(mintSpendLedgerStorage(SPEND_LEDGER_JOURNAL_FILENAME)); journal.append(line("alias-one")); expect(modeOf(path)).toBe(0o600); @@ -34,9 +146,9 @@ describe("spend ledger file journal", () => { }); test("compaction replaces the journal atomically and leaves no temp behind", () => { - const dir = mkdtempSync(join(tmpdir(), "ocx-spend-compact-")); - const path = join(dir, "spend-ledger.jsonl"); - const journal = createFileSpendJournal(path); + const dir = ownedHome("ocx-spend-compact-"); + const path = join(dir, SPEND_LEDGER_JOURNAL_FILENAME); + const journal = createOwnedFileSpendJournal(mintSpendLedgerStorage(SPEND_LEDGER_JOURNAL_FILENAME)); journal.append(line("alias-one")); journal.append(line("alias-two")); @@ -46,20 +158,98 @@ describe("spend ledger file journal", () => { expect(readFileSync(path, "utf8")).toBe(line("checkpoint-stand-in") + "\n"); expect(journal.read()).toHaveLength(1); - // The temp file is renamed over the journal, never left in the home directory. - expect(readdirSync(dir)).toEqual(["spend-ledger.jsonl"]); + // The temp file is renamed over the journal, never left in the home directory. Asserted as + // the absence of a compaction temp rather than an exact listing, because the owned state + // directory also holds the lease database this case had to acquire to write at all. + expect(readdirSync(dir).filter(name => name.includes(".compact-"))).toEqual([]); + expect(readdirSync(dir)).toContain(SPEND_LEDGER_JOURNAL_FILENAME); if (posixModes) expect(modeOf(path)).toBe(0o600); }); + /** + * Compaction failure paths, driven through the journal's own fault seam. + * + * The temp name carries random bytes, so a failure that leaves it behind is not one stale file + * but one per attempt. Each case below drives the same compaction repeatedly and asserts the + * directory holds no compaction residue and the original journal is untouched. + */ + for (const step of ["validate", "harden", "rename"] as const) { + test(`a compaction that fails at ${step} leaves no temp behind`, () => { + const dir = ownedHome(`ocx-spend-compact-${step}-`); + const path = join(dir, SPEND_LEDGER_JOURNAL_FILENAME); + const journal = createOwnedFileSpendJournal(mintSpendLedgerStorage(SPEND_LEDGER_JOURNAL_FILENAME)); + journal.append(line("alias-one")); + const original = readFileSync(path, "utf8"); + + setSpendJournalFaultForTests((actual) => { + if (actual === step) throw new Error(`fault injected at ${step}`); + }); + for (let attempt = 0; attempt < 3; attempt += 1) { + expect(() => journal.rewrite?.call(journal, [line("checkpoint")])).toThrow(/fault injected/); + } + setSpendJournalFaultForTests(undefined); + + expect(readdirSync(dir).filter(name => name.includes(".compact-"))).toEqual([]); + expect(readFileSync(path, "utf8")).toBe(original); + }); + } + + test("a compaction whose write stops partway leaves neither residue nor a truncated journal", () => { + const dir = ownedHome("ocx-spend-compact-partial-"); + const path = join(dir, SPEND_LEDGER_JOURNAL_FILENAME); + const journal = createOwnedFileSpendJournal(mintSpendLedgerStorage(SPEND_LEDGER_JOURNAL_FILENAME)); + journal.append(line("alias-one")); + const original = readFileSync(path, "utf8"); + + // The entry already exists by the time the write runs, which is the case the exclusive + // create exists to make unambiguous. A real prefix goes in first, so this is a SHORT write + // rather than a failure before any byte landed: the residue that must be cleaned is a file + // with content in it. + setSpendJournalFaultForTests((actual, temp) => { + if (actual !== "write") return; + expect(existsSync(temp)).toBe(true); + appendFileSync(temp, line("half-written").slice(0, 12), { encoding: "utf8" }); + expect(readFileSync(temp, "utf8").length).toBeGreaterThan(0); + throw Object.assign(new Error("no space left on device"), { code: "ENOSPC" }); + }); + for (let attempt = 0; attempt < 3; attempt += 1) { + expect(() => journal.rewrite?.call(journal, [line("checkpoint")])).toThrow(/no space left/); + } + setSpendJournalFaultForTests(undefined); + + expect(readdirSync(dir).filter(name => name.includes(".compact-"))).toEqual([]); + expect(readFileSync(path, "utf8")).toBe(original); + }); + + test("a compaction candidate that already exists is left exactly as it was", () => { + const dir = ownedHome("ocx-spend-compact-eexist-"); + const journal = createOwnedFileSpendJournal(mintSpendLedgerStorage(SPEND_LEDGER_JOURNAL_FILENAME)); + journal.append(line("alias-one")); + + // Occupy the exact candidate name before the exclusive create reaches it. The create then + // fails EEXIST, and because this call never created the entry it must not remove it. + let occupied: string | undefined; + setSpendJournalFaultForTests((actual, temp) => { + if (actual !== "create" || occupied !== undefined) return; + occupied = temp; + writeFileSync(temp, "not ours\n", { encoding: "utf8", mode: 0o600, flag: "wx" }); + }); + expect(() => journal.rewrite?.call(journal, [line("checkpoint")])).toThrow(); + setSpendJournalFaultForTests(undefined); + + expect(occupied).toBeDefined(); + expect(readFileSync(occupied!, "utf8")).toBe("not ours\n"); + }); + test("the alias salt is minted once and reused, so replay still matches live requests", () => { - const dir = mkdtempSync(join(tmpdir(), "ocx-spend-salt-")); - const path = join(dir, "spend-ledger.salt"); + const dir = ownedHome("ocx-spend-salt-"); + const path = join(dir, SPEND_LEDGER_SALT_FILENAME); - const minted = loadOrCreateSpendLedgerSalt(path); + const minted = loadOrCreateSpendLedgerSalt(mintSpendLedgerStorage(SPEND_LEDGER_SALT_FILENAME)); expect(minted).toMatch(/^[0-9a-f]{64}$/); // Stability is the whole contract: a salt that changed per process would alias the same // root id differently after a restart and hand every scope a fresh allowance. - expect(loadOrCreateSpendLedgerSalt(path)).toBe(minted); + expect(loadOrCreateSpendLedgerSalt(mintSpendLedgerStorage(SPEND_LEDGER_SALT_FILENAME))).toBe(minted); if (posixModes) expect(modeOf(path)).toBe(0o600); }); }); diff --git a/tests/lib/spend-ledger-owner.test.ts b/tests/lib/spend-ledger-owner.test.ts new file mode 100644 index 00000000000..25584deb8bb --- /dev/null +++ b/tests/lib/spend-ledger-owner.test.ts @@ -0,0 +1,532 @@ +/** Cross-process ownership for the process-wide spend journal (#5123). */ +import { afterEach, beforeEach, describe, expect, test } from "bun:test"; +import { existsSync, linkSync, mkdirSync, mkdtempSync, readFileSync, statSync, symlinkSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { + acquireSpendLedgerOwner, + SPEND_LEDGER_OWNER_FILENAME, + mintSpendLedgerStorage, + SPEND_LEDGER_RESTART_PARENT_ENV, + SpendLedgerOwnerError, + spendLedgerRestartEnvironment, + spendLedgerOwnerSnapshot, + type SpendLedgerOwnerLease, +} from "../../src/lib/spend-ledger-owner"; +import { + SPEND_LEDGER_JOURNAL_FILENAME, + SPEND_LEDGER_SALT_FILENAME, + configureSharedSpendLedger, + createOwnedFileSpendJournal, + loadOrCreateSpendLedgerSalt, + resetSharedSpendLedgerForTest, + sharedSpendLedger, + spendLedgerDiagnosticsSnapshot, + type SpendReservationPolicy, +} from "../../src/lib/spend-reservation-ledger"; +import { helperPath } from "../helpers/repo-root"; +import { CONFIG_OWNER_FILE, CONFIG_UNINSTALL_MANIFEST, removeOwnedConfigState } from "../../src/lib/config-ownership"; +import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { INTERNAL_DEADLINE_MS, SPAWN_BUDGET_MS } from "../helpers/test-budget"; + +const childPath = helperPath("spend-ledger-owner-child.ts"); +/** The shape the ledger actually takes: scopes plus the two token figures it books against. */ +const reserveRequest = (sendId: string) => ({ + sendId, + scopes: { rootId: "r1" }, + inputTokens: 1, + outputCeilingTokens: 1, +}); +let root = ""; +let home = ""; +let previousHome: string | undefined; +const children = new Set>(); + +beforeEach(() => { + root = mkdtempSync(join(tmpdir(), "ocx-spend-owner-")); + home = join(root, "state-a"); + previousHome = process.env.OPENCODEX_HOME; + process.env.OPENCODEX_HOME = home; + resetSharedSpendLedgerForTest(); +}); + +afterEach(async () => { + for (const child of children) { + if (child.exitCode === null && child.signalCode === null) child.kill("SIGKILL"); + await child.exited; + } + children.clear(); + resetSharedSpendLedgerForTest(); + if (previousHome === undefined) delete process.env.OPENCODEX_HOME; + else process.env.OPENCODEX_HOME = previousHome; + removeTreeWithRetry(root); +}); + +function spawnHolder( + targetHome: string, + mode: "observe" | "enforced", + suffix: string, + extraEnv: Record = {}, +) { + const holdMarker = join(root, `held-${suffix}`); + const releaseMarker = join(root, `release-${suffix}`); + const child = Bun.spawn([process.execPath, childPath], { + env: { + ...process.env, + ...extraEnv, + OPENCODEX_HOME: targetHome, + OCX_SPEND_OWNER_CHILD: JSON.stringify({ holdMarker, releaseMarker, mode }), + }, + stdout: "pipe", + stderr: "pipe", + }); + children.add(child); + return { child, holdMarker, releaseMarker }; +} + +async function waitForMarker(path: string, child: ReturnType): Promise { + const deadline = Date.now() + INTERNAL_DEADLINE_MS; + while (Date.now() < deadline) { + if (existsSync(path)) return; + if (child.exitCode !== null || child.signalCode !== null) { + throw new Error(`owner child exited before holding: ${await new Response(child.stderr).text()}`); + } + await Bun.sleep(10); + } + throw new Error("timed out waiting for spend-ledger owner child"); +} + +async function childResult(child: ReturnType) { + const [stdout] = await Promise.all([new Response(child.stdout).text(), child.exited]); + children.delete(child); + return JSON.parse(stdout.trim().split("\n").filter(Boolean).at(-1) ?? "{}") as { + status: string; + code?: string; + message?: string; + }; +} + +function busyError(): SpendLedgerOwnerError { + try { acquireSpendLedgerOwner(); } + catch (error) { + if (error instanceof SpendLedgerOwnerError) return error; + throw error; + } + throw new Error("expected spend-ledger ownership refusal"); +} + +/** + * The contender's own spend configuration, in this process, before it tries to acquire. + * + * Recording a policy touches no journal while this process owns nothing, so this is exactly the + * state a second instance is in when it starts: configured one way or the other, and not yet a + * writer. Without it the matrix below named a contender mode it never activated. + */ +function contenderPolicy(mode: "observe" | "enforced"): SpendReservationPolicy { + return { + root: mode === "enforced" ? { maxTokens: 1_000 } : {}, + identity: {}, + pool: {}, + retentionMs: 60_000, + }; +} + +describe("real process ownership", () => { + test("only a parent-exit restart environment carries the handoff marker", () => { + const source = { OCX_SPEND_LEDGER_RESTART_PARENT_PID: "stale", KEEP_ME: "yes" }; + expect(spendLedgerRestartEnvironment(source)).toEqual({ KEEP_ME: "yes" }); + expect(spendLedgerRestartEnvironment(source, 4242)).toEqual({ + KEEP_ME: "yes", + OCX_SPEND_LEDGER_RESTART_PARENT_PID: "4242", + }); + }); + + // All four combinations, not the two mixed ones. The rule under test is that ownership does + // not depend on either side's ceiling, so a matrix missing observe/observe and + // enforced/enforced was not testing the claim its names made. + for (const [holderMode, contenderMode] of [ + ["observe", "observe"], + ["observe", "enforced"], + ["enforced", "observe"], + ["enforced", "enforced"], + ] as const) { + test(`${holderMode} and ${contenderMode} configurations contend identically`, async () => { + const holder = spawnHolder(home, holderMode, `${holderMode}-${contenderMode}`); + await waitForMarker(holder.holdMarker, holder.child); + configureSharedSpendLedger(contenderPolicy(contenderMode)); + const refusal = busyError(); + expect(refusal.code).toBe("SPEND_LEDGER_OWNER_BUSY"); + writeFileSync(holder.releaseMarker, "release"); + expect((await childResult(holder.child)).status).toBe("acquired"); + }, SPAWN_BUDGET_MS); + } + + test("turning a ceiling on after an observe-only start does not change contention", async () => { + const holder = spawnHolder(home, "observe", "ceiling-transition"); + await waitForMarker(holder.holdMarker, holder.child); + + configureSharedSpendLedger(contenderPolicy("observe")); + expect(busyError().code).toBe("SPEND_LEDGER_OWNER_BUSY"); + + // The operator enables a ceiling while another process still owns the directory. A policy + // is a recorded value until a ledger exists, so this changes what WOULD be refused, never + // who may write, and the ownership refusal is identical either side of the transition. + configureSharedSpendLedger(contenderPolicy("enforced")); + expect(busyError().code).toBe("SPEND_LEDGER_OWNER_BUSY"); + + writeFileSync(holder.releaseMarker, "release"); + expect((await childResult(holder.child)).status).toBe("acquired"); + }, SPAWN_BUDGET_MS); + + test("independent state directories are independent", async () => { + const holder = spawnHolder(home, "observe", "independent"); + await waitForMarker(holder.holdMarker, holder.child); + const other = acquireSpendLedgerOwner(join(root, "state-b")); + expect(spendLedgerOwnerSnapshot().ownership).toBe("held"); + other.release(); + writeFileSync(holder.releaseMarker, "release"); + await childResult(holder.child); + }, SPAWN_BUDGET_MS); + + test("graceful release lets the next process acquire", async () => { + const holder = spawnHolder(home, "observe", "graceful"); + await waitForMarker(holder.holdMarker, holder.child); + writeFileSync(holder.releaseMarker, "release"); + await childResult(holder.child); + const next = acquireSpendLedgerOwner(); + next.release(); + }, SPAWN_BUDGET_MS); + + test("a marked restart child waits for the parent lease while an ordinary sibling fails immediately", async () => { + const parent = acquireSpendLedgerOwner(); + const ordinary = spawnHolder(home, "observe", "ordinary-sibling"); + expect((await childResult(ordinary.child)).code).toBe("SPEND_LEDGER_OWNER_BUSY"); + + const restart = spawnHolder(home, "observe", "restart-child", { + [SPEND_LEDGER_RESTART_PARENT_ENV]: String(process.pid), + }); + await Bun.sleep(25); + expect(restart.child.exitCode).toBeNull(); + parent.release(); + await waitForMarker(restart.holdMarker, restart.child); + writeFileSync(restart.releaseMarker, "release"); + expect((await childResult(restart.child)).status).toBe("acquired"); + }, SPAWN_BUDGET_MS); + + test("an abruptly killed owner is reacquirable without replacing the lock file", async () => { + const holder = spawnHolder(home, "observe", "killed"); + await waitForMarker(holder.holdMarker, holder.child); + const lockPath = join(home, SPEND_LEDGER_OWNER_FILENAME); + const journalPath = join(home, SPEND_LEDGER_JOURNAL_FILENAME); + const saltPath = join(home, SPEND_LEDGER_SALT_FILENAME); + const before = [lockPath, journalPath, saltPath].map(path => ({ path, stat: statSync(path) })); + holder.child.kill("SIGKILL"); + await holder.child.exited; + children.delete(holder.child); + const next = acquireSpendLedgerOwner(); + for (const entry of before) { + const after = statSync(entry.path); + expect(after.size).toBe(entry.stat.size); + if (process.platform !== "win32") expect(after.ino).toBe(entry.stat.ino); + } + next.release(); + }, SPAWN_BUDGET_MS); +}); + +describe("in-process references and privacy", () => { + let leases: SpendLedgerOwnerLease[] = []; + afterEach(() => { + for (const lease of leases.splice(0).reverse()) lease.release(); + }); + + test("two leases share ownership and one release does not free it", async () => { + const first = acquireSpendLedgerOwner(); + const second = acquireSpendLedgerOwner(); + leases.push(first, second); + first.release(); + const holder = spawnHolder(home, "observe", "references"); + expect((await childResult(holder.child)).code).toBe("SPEND_LEDGER_OWNER_BUSY"); + second.release(); + expect(spendLedgerOwnerSnapshot().ownership).toBe("unheld"); + }, SPAWN_BUDGET_MS); + + test("one process refuses a second different state directory", () => { + leases.push(acquireSpendLedgerOwner()); + let failure: unknown; + try { acquireSpendLedgerOwner(join(root, "state-b")); } catch (error) { failure = error; } + expect(failure).toBeInstanceOf(SpendLedgerOwnerError); + expect((failure as SpendLedgerOwnerError).code).toBe("SPEND_LEDGER_OWNER_HOME_CONFLICT"); + }); + + test("releasing the final lease frees the process to own a different state directory", () => { + // The refusal above is about two homes owned at once. Once ownership is gone the singleton + // has no directory to belong to, so it is discarded with the lease: the next home builds its + // own ledger by replaying its own journal. Keeping the old binding instead would strand a + // process that legitimately serves one home and then another. + const first = acquireSpendLedgerOwner(); + sharedSpendLedger(); + first.release(); + expect(spendLedgerDiagnosticsSnapshot()).toMatchObject({ ownership: "unheld", initialized: false }); + + process.env.OPENCODEX_HOME = join(root, "state-b"); + const second = acquireSpendLedgerOwner(); + leases.push(second); + sharedSpendLedger(); + expect(spendLedgerDiagnosticsSnapshot()).toMatchObject({ ownership: "held", initialized: true }); + expect(existsSync(join(root, "state-b", SPEND_LEDGER_OWNER_FILENAME))).toBe(true); + }); + + test("a retained ledger stays refused after the same home is owned again", () => { + // The dangerous case is not a different directory, it is the same one owned again. The + // retained handle carries totals from before the gap, and another writer may have appended + // to the journal while nobody held the lock. + const first = acquireSpendLedgerOwner(); + const retained = sharedSpendLedger(); + first.release(); + + const second = acquireSpendLedgerOwner(); + leases.push(second); + let failure: unknown; + try { retained.snapshot("root", "r1"); } catch (error) { failure = error; } + expect(failure).toBeInstanceOf(SpendLedgerOwnerError); + expect((failure as SpendLedgerOwnerError).code).toBe("SPEND_LEDGER_OWNER_NOT_HELD"); + + let mutation: unknown; + try { retained.reserve(reserveRequest("s1")); } catch (error) { mutation = error; } + expect(mutation).toBeInstanceOf(SpendLedgerOwnerError); + + // Reads are refused for the same reason writes are: the figures describe a journal this + // handle no longer owns. + for (const read of [ + () => retained.knows("s1"), + () => retained.exhausted("root", "r1"), + () => retained.policy, + () => retained.degraded, + () => retained.persistFailures, + () => retained.corruptRecords, + ]) { + expect(read).toThrow(SpendLedgerOwnerError); + } + + // A handle taken under the new ownership works and sees the journal as it is now. + expect(() => sharedSpendLedger().snapshot("root", "r1")).not.toThrow(); + }); + + test("storage this module did not mint is not accepted as proof", () => { + // Three ways to try: a bare look-alike, and - the one a marker on the object cannot stop - + // a spread of a real token with the path redirected and the guard replaced. Identity is the + // only thing a copy cannot reproduce. + const lease = acquireSpendLedgerOwner(); + leases.push(lease); + const elsewhere = join(root, "elsewhere.jsonl"); + const minted = mintSpendLedgerStorage(SPEND_LEDGER_JOURNAL_FILENAME); + const forgeries = [ + {} as unknown as typeof minted, + { path: elsewhere, assert(): void { /* proves nothing */ } } as unknown as typeof minted, + { ...minted, path: elsewhere, assert(): void { /* proves nothing */ } } as unknown as typeof minted, + ]; + + for (const forged of forgeries) { + expect(() => createOwnedFileSpendJournal(forged)).toThrow(SpendLedgerOwnerError); + expect(() => loadOrCreateSpendLedgerSalt(forged)).toThrow(SpendLedgerOwnerError); + } + expect(existsSync(elsewhere)).toBe(false); + + // A token this module did mint keeps working, so the refusal is about identity and not + // about refusing everything. + expect(() => createOwnedFileSpendJournal(minted)).not.toThrow(); + }); + + test("a minted token stops working once its ownership ends", () => { + const first = acquireSpendLedgerOwner(); + const minted = mintSpendLedgerStorage(SPEND_LEDGER_JOURNAL_FILENAME); + const journal = createOwnedFileSpendJournal(minted); + first.release(); + + const second = acquireSpendLedgerOwner(); + leases.push(second); + expect(() => journal.append("{}")).toThrow(SpendLedgerOwnerError); + expect(() => journal.read()).toThrow(SpendLedgerOwnerError); + }); + + test("minting refuses a name that is not a plain file in the owned directory", () => { + const lease = acquireSpendLedgerOwner(); + leases.push(lease); + for (const name of ["../escape.jsonl", "nested/child.jsonl", ".."]) { + expect(() => mintSpendLedgerStorage(name)).toThrow(SpendLedgerOwnerError); + } + }); + + test("a dangling journal symlink is refused rather than followed", () => { + const lease = acquireSpendLedgerOwner(); + leases.push(lease); + const journal = join(home, SPEND_LEDGER_JOURNAL_FILENAME); + const target = join(root, "elsewhere.jsonl"); + symlinkSync(target, journal); + + let failure: unknown; + try { sharedSpendLedger().reserve(reserveRequest("s1")); } catch (error) { failure = error; } + expect(failure).toBeInstanceOf(SpendLedgerOwnerError); + // The point of the case: the link's target must not have been created by following it. + expect(existsSync(target)).toBe(false); + }); + + test("a retained shared ledger refuses mutation after its final lease releases", async () => { + const lease = acquireSpendLedgerOwner(); + const retained = sharedSpendLedger(); + lease.release(); + const holder = spawnHolder(home, "observe", "retained-handle"); + await waitForMarker(holder.holdMarker, holder.child); + let failure: unknown; + try { + retained.reserve({ + sendId: "retained", + scopes: { rootId: "retained-root" }, + inputTokens: 1, + outputCeilingTokens: 1, + }); + } catch (error) { + failure = error; + } + expect(failure).toBeInstanceOf(SpendLedgerOwnerError); + expect((failure as SpendLedgerOwnerError).code).toBe("SPEND_LEDGER_OWNER_NOT_HELD"); + writeFileSync(holder.releaseMarker, "release"); + await childResult(holder.child); + }, SPAWN_BUDGET_MS); + + test("busy refusal contains no private identity or filesystem data", async () => { + const holder = spawnHolder(home, "observe", "privacy"); + await waitForMarker(holder.holdMarker, holder.child); + const refusal = busyError(); + const text = `${refusal.name} ${refusal.code} ${refusal.message}`.toLowerCase(); + for (const secret of [home.toLowerCase(), String(process.pid), "spend-ledger.jsonl", "child-root", "account", "scope", "request"]) { + expect(text).not.toContain(secret); + } + writeFileSync(holder.releaseMarker, "release"); + await childResult(holder.child); + }, SPAWN_BUDGET_MS); + + test("diagnostics do not construct or create ledger files", () => { + leases.push(acquireSpendLedgerOwner()); + expect(spendLedgerDiagnosticsSnapshot()).toEqual({ + ownership: "held", + initialized: false, + configured: false, + degraded: false, + persistFailures: 0, + corruptRecords: 0, + }); + expect(existsSync(join(home, SPEND_LEDGER_JOURNAL_FILENAME))).toBe(false); + expect(existsSync(join(home, SPEND_LEDGER_SALT_FILENAME))).toBe(false); + }); +}); + +describe("backing file identity", () => { + test("a fresh state directory is claimed before its database exists, so it stays removable", () => { + // Config ownership refuses to claim a directory that already has contents, and the owner + // database lives inside that directory. Creating the database first therefore left a fresh + // home with no owner marker and no manifest at all, so nothing recorded the database or its + // sidecars and a later uninstall could not remove them. + expect(existsSync(home)).toBe(false); + acquireSpendLedgerOwner().release(); + + expect(existsSync(join(home, CONFIG_OWNER_FILE))).toBe(true); + const manifest = JSON.parse( + readFileSync(join(home, CONFIG_UNINSTALL_MANIFEST), "utf8"), + ) as { paths: string[] }; + expect(manifest.paths).toContain(SPEND_LEDGER_OWNER_FILENAME); + for (const sidecar of ["-journal", "-wal", "-shm"]) { + expect(manifest.paths).toContain(`${SPEND_LEDGER_OWNER_FILENAME}${sidecar}`); + } + + // The point of recording them: an uninstall can now take the whole directory back. + expect(removeOwnedConfigState(home).status).toBe("removed"); + expect(existsSync(home)).toBe(false); + }); + + const expectBackingAliasesRefused = (kind: "hardlink" | "symlink"): void => { + const first = acquireSpendLedgerOwner(home); + sharedSpendLedger().reserve({ + sendId: "first", + scopes: { rootId: "first-root" }, + inputTokens: 1, + outputCeilingTokens: 1, + }); + first.release(); + resetSharedSpendLedgerForTest(); + + for (const filename of [SPEND_LEDGER_JOURNAL_FILENAME, SPEND_LEDGER_SALT_FILENAME]) { + const otherHome = join(root, `${kind}-${filename}`); + const prepared = acquireSpendLedgerOwner(otherHome); + prepared.release(); + const source = join(home, filename); + const destination = join(otherHome, filename); + if (kind === "hardlink") linkSync(source, destination); + else symlinkSync(source, destination); + const owner = acquireSpendLedgerOwner(otherHome); + process.env.OPENCODEX_HOME = otherHome; + let failure: unknown; + try { sharedSpendLedger(); } catch (error) { failure = error; } + expect(failure).toBeInstanceOf(SpendLedgerOwnerError); + expect((failure as SpendLedgerOwnerError).code).toBe("SPEND_LEDGER_OWNER_UNAVAILABLE"); + owner.release(); + resetSharedSpendLedgerForTest(); + } + }; + + test("hard-linked owner files fail closed", () => { + const linkedHome = join(root, "owner-hardlink"); + mkdirSync(linkedHome, { recursive: true }); + const target = join(root, "owner-hardlink-target"); + writeFileSync(target, "owner"); + linkSync(target, join(linkedHome, SPEND_LEDGER_OWNER_FILENAME)); + let failure: unknown; + try { acquireSpendLedgerOwner(linkedHome); } catch (error) { failure = error; } + expect(failure).toBeInstanceOf(SpendLedgerOwnerError); + expect((failure as SpendLedgerOwnerError).code).toBe("SPEND_LEDGER_OWNER_UNAVAILABLE"); + }); + + test.skipIf(process.platform === "win32")("symbolically linked owner files fail closed", () => { + const linkedHome = join(root, "owner-symlink"); + mkdirSync(linkedHome, { recursive: true }); + const target = join(root, "owner-symlink-target"); + writeFileSync(target, "owner"); + symlinkSync(target, join(linkedHome, SPEND_LEDGER_OWNER_FILENAME)); + let failure: unknown; + try { acquireSpendLedgerOwner(linkedHome); } catch (error) { failure = error; } + expect(failure).toBeInstanceOf(SpendLedgerOwnerError); + expect((failure as SpendLedgerOwnerError).code).toBe("SPEND_LEDGER_OWNER_UNAVAILABLE"); + }); + + test("invalid or unusable owner databases fail closed", () => { + const invalidHome = join(root, "owner-invalid"); + mkdirSync(invalidHome, { recursive: true }); + writeFileSync(join(invalidHome, SPEND_LEDGER_OWNER_FILENAME), "not sqlite"); + let invalid: unknown; + try { acquireSpendLedgerOwner(invalidHome); } catch (error) { invalid = error; } + expect(invalid).toBeInstanceOf(SpendLedgerOwnerError); + expect((invalid as SpendLedgerOwnerError).code).toBe("SPEND_LEDGER_OWNER_UNAVAILABLE"); + + const unusableHome = join(root, "owner-unusable"); + mkdirSync(join(unusableHome, SPEND_LEDGER_OWNER_FILENAME), { recursive: true }); + let unusable: unknown; + try { acquireSpendLedgerOwner(unusableHome); } catch (error) { unusable = error; } + expect(unusable).toBeInstanceOf(SpendLedgerOwnerError); + expect((unusable as SpendLedgerOwnerError).code).toBe("SPEND_LEDGER_OWNER_UNAVAILABLE"); + }); + + test("linked journals and salts cannot cross independent homes", () => { + expectBackingAliasesRefused("hardlink"); + }); + + test.skipIf(process.platform === "win32")("symbolically linked journals and salts fail closed", () => { + expectBackingAliasesRefused("symlink"); + }); + + test("the shared ledger requires a live lease", () => { + let failure: unknown; + try { sharedSpendLedger(); } catch (error) { failure = error; } + expect(failure).toBeInstanceOf(SpendLedgerOwnerError); + expect((failure as SpendLedgerOwnerError).code).toBe("SPEND_LEDGER_OWNER_NOT_HELD"); + }); +}); diff --git a/tests/oauth/adapter-event-oauth-failover.test.ts b/tests/oauth/adapter-event-oauth-failover.test.ts index 35fe353d455..2cd12caf122 100644 --- a/tests/oauth/adapter-event-oauth-failover.test.ts +++ b/tests/oauth/adapter-event-oauth-failover.test.ts @@ -6,6 +6,7 @@ import type { ProviderAdapter } from "../../src/adapters/base"; import { clearGenericFailoverHealth } from "../../src/oauth/generic-account-failover"; import { getAccountSet, getCredential, saveCredential, setActiveAccount } from "../../src/oauth/store"; import type { AdapterEvent, OcxConfig, OcxProviderConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; const actualResolver = await import("../../src/server/adapter-resolve"); @@ -57,6 +58,7 @@ mock.module("../../src/server/adapter-resolve", () => ({ const { handleResponses } = await import("../../src/server/responses"); const originalHome = process.env.OPENCODEX_HOME; let home = ""; +let releaseSpendHome: (() => void) | undefined; /** * `enabled: undefined` is the case that matters after #2568d — the key absent entirely, which is @@ -100,6 +102,8 @@ async function seedAccounts(count: number): Promise { beforeEach(() => { home = mkdtempSync(join(tmpdir(), "ocx-adapter-event-failover-")); process.env.OPENCODEX_HOME = home; + // Take the writer lease after this case installs its home so direct handler dispatch can open the spend journal. + releaseSpendHome = acquireOwnedSpendHome(); clearGenericFailoverHealth(); attempts = []; attemptKeys = []; @@ -111,6 +115,9 @@ beforeEach(() => { }); afterEach(() => { + // Release before restoring or removing the home to prevent Windows removal failures and POSIX unlinked databases. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; clearGenericFailoverHealth(); if (originalHome === undefined) delete process.env.OPENCODEX_HOME; diff --git a/tests/oauth/oauth-account-attribution.test.ts b/tests/oauth/oauth-account-attribution.test.ts index ff6a838462c..68b444a983e 100644 --- a/tests/oauth/oauth-account-attribution.test.ts +++ b/tests/oauth/oauth-account-attribution.test.ts @@ -14,6 +14,7 @@ import { summarizeUsage } from "../../src/usage/summary"; import type { RequestLogContext } from "../../src/server/request-log"; import { handleResponses } from "../../src/server/responses"; import type { OcxConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; /** @@ -66,9 +67,13 @@ async function withHome(run: (home: string) => Promise): Promise { const prevCodex = process.env.CODEX_HOME; process.env.OPENCODEX_HOME = home; process.env.CODEX_HOME = home; + // Take the writer lease after this helper installs its home so direct handler dispatch can open the spend journal. + const releaseSpendHome = acquireOwnedSpendHome(); try { return await run(home); } finally { + // Release before restoring or removing the home to prevent Windows removal failures and POSIX unlinked databases. + releaseSpendHome(); globalThis.fetch = originalFetch; removeTreeWithRetry(home); if (prevOpencodex === undefined) delete process.env.OPENCODEX_HOME; diff --git a/tests/providers/cursor/cursor-effort-rows.test.ts b/tests/providers/cursor/cursor-effort-rows.test.ts index e6296b9de87..d3f4f922365 100644 --- a/tests/providers/cursor/cursor-effort-rows.test.ts +++ b/tests/providers/cursor/cursor-effort-rows.test.ts @@ -21,6 +21,7 @@ import { startServer } from "../../../src/server"; import type { RequestLogContext } from "../../../src/server/request-log"; import type { OcxConfig } from "../../../src/types"; import { removeTreeWithRetry } from "../../helpers/remove-tree"; +import { acquireOwnedSpendHome } from "../../helpers/owned-spend-home"; import { SERVER_BUDGET_MS } from "../../helpers/test-budget"; setDefaultTimeout(SERVER_BUDGET_MS); @@ -206,6 +207,9 @@ describe("Cursor effort variant rows", () => { test("Responses effort rows route the base model and pass through the existing cap", async () => { const upstream = mockChatUpstream(); + // Case-local, never file-wide: this file also starts a real server elsewhere, and that + // server takes the same lease. A lease held across those cases would refuse their startup. + const releaseSpendHome = acquireOwnedSpendHome(); try { const config = ingressConfig(`${upstream.server.url.toString().replace(/\/$/u, "")}/v1`); const response = await handleResponses(new Request("http://localhost/v1/responses", { @@ -225,11 +229,15 @@ describe("Cursor effort variant rows", () => { }); } finally { upstream.server.stop(true); + // The fake upstreams stop first: a turn still settling against the journal must not + // outlive the lease that owns it. + releaseSpendHome(); } }); test("Chat effort rows use Responses normalization instead of the native-chat shortcut", async () => { const upstream = mockChatUpstream(); + const releaseSpendHome = acquireOwnedSpendHome(); try { const config = ingressConfig(`${upstream.server.url.toString().replace(/\/$/u, "")}/v1`); const response = await handleChatCompletions(new Request("http://localhost/v1/chat/completions", { @@ -249,11 +257,13 @@ describe("Cursor effort variant rows", () => { }); } finally { upstream.server.stop(true); + releaseSpendHome(); } }); test("Messages effort rows resolve after route directives and before native passthrough", async () => { const upstream = mockChatUpstream(); + const releaseSpendHome = acquireOwnedSpendHome(); try { const config = ingressConfig(`${upstream.server.url.toString().replace(/\/$/u, "")}/v1`); const response = await handleClaudeMessages(new Request("http://localhost/v1/messages", { @@ -279,12 +289,14 @@ describe("Cursor effort variant rows", () => { }); } finally { upstream.server.stop(true); + releaseSpendHome(); } }); test("mixed-case aliases ending in an effort stay on their configured provider", async () => { const intended = mockChatUpstream(); const fallback = mockChatUpstream(); + const releaseSpendHome = acquireOwnedSpendHome(); try { const config: OcxConfig = { port: 0, @@ -354,6 +366,7 @@ describe("Cursor effort variant rows", () => { } finally { intended.server.stop(true); fallback.server.stop(true); + releaseSpendHome(); } }); diff --git a/tests/providers/cyber-policy-error-fidelity.test.ts b/tests/providers/cyber-policy-error-fidelity.test.ts index bff86a295ac..7adc39f3f22 100644 --- a/tests/providers/cyber-policy-error-fidelity.test.ts +++ b/tests/providers/cyber-policy-error-fidelity.test.ts @@ -17,6 +17,7 @@ import { formatPassthroughUpstreamError } from "../../src/server/responses/passt import { consumeComboFailure } from "../../src/server/responses/core"; import { handleResponses } from "../../src/server/responses"; import type { AdapterEvent, OcxConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { createTestTranslatorBudget, withTestTranslatorBudget } from "../helpers/translator-budget"; const createOpenAIChatAdapter = (...args: Parameters) => @@ -219,6 +220,8 @@ describe("cyber_policy error fidelity", () => { }, }, } as OcxConfig; + // Taken after the inherited test home is in effect so physical dispatch can open its ledger. + const releaseSpendHome = acquireOwnedSpendHome(); try { const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", @@ -235,6 +238,8 @@ describe("cyber_policy error fidelity", () => { }, }); } finally { + // Released before surrounding teardown can replace the home and strand its live ledger. + releaseSpendHome(); upstream.stop(true); } }); @@ -475,4 +480,3 @@ describe("#2488 nested policy identity is not hidden by an outer envelope", () = expect(failure.response.status).toBe(502); }); }); - diff --git a/tests/providers/deepseek-inbound-wire.test.ts b/tests/providers/deepseek-inbound-wire.test.ts index fa2b686a2df..0db58c6a6f6 100644 --- a/tests/providers/deepseek-inbound-wire.test.ts +++ b/tests/providers/deepseek-inbound-wire.test.ts @@ -25,6 +25,7 @@ import { MAX_SYNTHESIZED_OUTPUT_ITEMS } from "../../src/server/responses-json-ev import type { ResponsesTerminalRepairScheduler } from "../../src/server/responses-terminal-repair"; import { sendResponseToWebSocket } from "../../src/server/ws-bridge"; import type { OcxConfig, OcxProviderConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { withTestTranslatorBudget } from "../helpers/translator-budget"; const createResponsesPassthroughAdapter = (...args: Parameters) => @@ -33,6 +34,13 @@ const createResponsesPassthroughAdapter = (...args: Parameters void) | undefined; + +// Direct physical dispatch needs the writer lease to prevent spend-ledger ownership failures. +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; + +// Release before the next case so a failed dispatch cannot leave an ownership conflict. +const dropSpendHome = (): void => { releaseSpendHome?.(); releaseSpendHome = undefined; }; class ManualTerminalScheduler implements ResponsesTerminalRepairScheduler { private current = 0; @@ -165,7 +173,10 @@ describe("DeepSeek wire selection is scoped to the inbound protocol", () => { describe("the inbound scope survives the handleResponses replay", () => { const originalFetch = globalThis.fetch; - afterEach(() => { globalThis.fetch = originalFetch; }); + afterEach(() => { + dropSpendHome(); + globalThis.fetch = originalFetch; + }); function captureUpstreamRequests(): Array<{ url: string; body: Record }> { const requests: Array<{ url: string; body: Record }> = []; @@ -190,7 +201,8 @@ describe("the inbound scope survives the handleResponses replay", () => { ): Promise<{ url: string; body: Record }> { const requests = captureUpstreamRequests(); const config = { providers: { deepseek: deepseekProvider() } } as unknown as OcxConfig; - await handleResponses( + takeSpendHome(); + const turn = await handleResponses( new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -203,6 +215,9 @@ describe("the inbound scope survives the handleResponses replay", () => { ...(inboundTransport === undefined ? {} : { inboundTransport }), }, ); + // The turn's body is a live stream. Releasing it here means no reader is still attached + // when the lease is dropped, which is what turns a finished case into a pending one. + await turn.body?.cancel(); return requests[0] ?? { url: "", body: {} }; } @@ -250,6 +265,7 @@ describe("the inbound scope survives the handleResponses replay", () => { abortSignal: testAbort.signal, responsesTerminalRepairScheduler: scheduler, } as Parameters[3]; + takeSpendHome(); const response = await handleResponses( new Request("http://localhost/v1/responses", { method: "POST", @@ -329,6 +345,7 @@ describe("the inbound scope survives the handleResponses replay", () => { }) as typeof fetch; const config = { providers: { deepseek: deepseekProvider() } } as unknown as OcxConfig; const abort = new AbortController(); + takeSpendHome(); const response = await handleResponses( new Request("http://localhost/v1/responses", { method: "POST", @@ -441,6 +458,7 @@ describe("the inbound scope survives the handleResponses replay", () => { const config = { providers: { deepseek: deepseekProvider() } } as unknown as OcxConfig; const deadline = AbortSignal.timeout(5_000); + takeSpendHome(); const response = await handleResponses( new Request("http://localhost/v1/responses", { method: "POST", @@ -498,6 +516,7 @@ describe("the inbound scope survives the handleResponses replay", () => { // The plain provider seed carries no explicit repair config; the registry's // { repairInvalidIds: true } policy must reach the live route via backfill. const config = { providers: { deepseek: deepseekProvider() } } as unknown as OcxConfig; + takeSpendHome(); const response = await handleResponses( new Request("http://localhost/v1/responses", { method: "POST", @@ -525,6 +544,7 @@ describe("the inbound scope survives the handleResponses replay", () => { })) as typeof fetch; const config = { providers: { deepseek: deepseekProvider() } } as unknown as OcxConfig; const abort = new AbortController(); + takeSpendHome(); const response = await handleResponses( new Request("http://localhost/v1/responses", { method: "POST", @@ -610,6 +630,7 @@ describe("the bounded-JSON mechanism stays alive behind a synthetic registry ent }); }); afterEach(() => { + dropSpendHome(); globalThis.fetch = originalFetch; const index = mutableRegistry.findIndex(entry => entry.id === FIXTURE_ID); if (index >= 0) mutableRegistry.splice(index, 1); @@ -655,6 +676,7 @@ describe("the bounded-JSON mechanism stays alive behind a synthetic registry ent options: { stream?: boolean; websocket?: boolean } = {}, ): Promise { const config = { providers: { [FIXTURE_ID]: provider } } as unknown as OcxConfig; + takeSpendHome(); return handleResponses( new Request("http://localhost/v1/responses", { method: "POST", diff --git a/tests/providers/deepseek-responses-item-id-repair.test.ts b/tests/providers/deepseek-responses-item-id-repair.test.ts index ed95f2394ce..fad25426610 100644 --- a/tests/providers/deepseek-responses-item-id-repair.test.ts +++ b/tests/providers/deepseek-responses-item-id-repair.test.ts @@ -8,6 +8,7 @@ import { } from "../../src/server/responses-item-id-repair"; import { handleResponses } from "../../src/server/responses/core"; import type { OcxConfig, OcxProviderConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { createTestTranslatorBudget } from "../helpers/translator-budget"; const UUID_MSG = "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"; @@ -166,7 +167,13 @@ describe("registry-derived DeepSeek repair policy (#938)", () => { describe("streamed HTTP path carries canonical ids (#938)", () => { const originalFetch = globalThis.fetch; - afterEach(() => { globalThis.fetch = originalFetch; }); + let releaseSpendHome: (() => void) | undefined; + afterEach(() => { + // Release first so a failed stream cannot leak writer ownership into the next case. + releaseSpendHome?.(); + releaseSpendHome = undefined; + globalThis.fetch = originalFetch; + }); test("the relayed SSE contains no upstream UUID item ids (un-enriched saved seed)", async () => { // The live path must backfill the registry policy through routedProviderConfig — @@ -199,6 +206,8 @@ describe("streamed HTTP path carries canonical ids (#938)", () => { }) as typeof fetch; const config = { providers: { deepseek: plainSeed } } as unknown as OcxConfig; + // Direct dispatch needs the writer lease to prevent spend-ledger ownership failures. + releaseSpendHome = acquireOwnedSpendHome(); const response = await handleResponses( new Request("http://localhost/v1/responses", { method: "POST", diff --git a/tests/providers/github-copilot/github-copilot-account-origin.test.ts b/tests/providers/github-copilot/github-copilot-account-origin.test.ts index 4da89c816ee..845d3e29cb5 100644 --- a/tests/providers/github-copilot/github-copilot-account-origin.test.ts +++ b/tests/providers/github-copilot/github-copilot-account-origin.test.ts @@ -9,6 +9,7 @@ import { saveConfig } from "../../../src/config"; import { setActiveProviderApiKey } from "../../../src/providers/api-keys"; import type { OcxConfig } from "../../../src/types"; import { removeTreeWithRetry } from "../../helpers/remove-tree"; +import { acquireOwnedSpendHome } from "../../helpers/owned-spend-home"; const ACCOUNT_A_ORIGIN = "https://a.githubcopilot.com"; const ACCOUNT_B_ORIGIN = "https://b.githubcopilot.com"; @@ -187,15 +188,24 @@ function installFetch(options: { return { dispatches }; } +let releaseSpendHome: (() => void) | undefined; + beforeEach(() => { beforeBuildReturns = undefined; beforePacingReturns = undefined; home = mkdtempSync(join(tmpdir(), "ocx-copilot-origin-")); process.env.OPENCODEX_HOME = home; clearGenericFailoverHealth(); + // Dispatches without starting a server, so it takes the spend-journal lease itself. Taken + // last because the lease binds the home in effect at the moment it is taken. + releaseSpendHome = acquireOwnedSpendHome(); }); afterEach(() => { + // Released before this case's home is removed: an open lease inside a directory being + // deleted fails the removal on Windows and leaves an unlinked live database on POSIX. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; clearGenericFailoverHealth(); if (originalHome === undefined) delete process.env.OPENCODEX_HOME; diff --git a/tests/providers/github-copilot/github-copilot-stream-contract.test.ts b/tests/providers/github-copilot/github-copilot-stream-contract.test.ts index 21ba36336e7..29340342b28 100644 --- a/tests/providers/github-copilot/github-copilot-stream-contract.test.ts +++ b/tests/providers/github-copilot/github-copilot-stream-contract.test.ts @@ -11,6 +11,9 @@ import { providerConfigSeed } from "../../../src/providers/derive"; import { getProviderRegistryEntry } from "../../../src/providers/registry"; import { handleResponses } from "../../../src/server/responses/core"; import type { OcxConfig, OcxProviderConfig } from "../../../src/types"; +import { acquireOwnedSpendHome } from "../../helpers/owned-spend-home"; + +let releaseSpendHome: (() => void) | undefined; interface SseEvent { event?: string; @@ -164,6 +167,9 @@ describe("GitHub Copilot Responses client stream contract", () => { const originalFetch = globalThis.fetch; afterEach(() => { + // Release the preload-home lease before later teardown can replace or remove that home. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; }); @@ -177,6 +183,8 @@ describe("GitHub Copilot Responses client stream contract", () => { providers: { "github-copilot": copilotProvider() }, } as unknown as OcxConfig; + // Direct dispatch needs the writer lease that startServer normally owns for this home. + releaseSpendHome = acquireOwnedSpendHome(); const response = await handleResponses( new Request("http://localhost/v1/responses", { method: "POST", diff --git a/tests/providers/github-copilot/github-copilot-wire-defaults.test.ts b/tests/providers/github-copilot/github-copilot-wire-defaults.test.ts index 50019d02cf7..bdf8a6e2dbc 100644 --- a/tests/providers/github-copilot/github-copilot-wire-defaults.test.ts +++ b/tests/providers/github-copilot/github-copilot-wire-defaults.test.ts @@ -17,6 +17,9 @@ import { getProviderRegistryEntry } from "../../../src/providers/registry"; import { resolveWireProtocolOverride } from "../../../src/server/adapter-resolve"; import { handleResponses } from "../../../src/server/responses/core"; import type { OcxConfig, OcxProviderConfig } from "../../../src/types"; +import { acquireOwnedSpendHome } from "../../helpers/owned-spend-home"; + +let releaseSpendHome: (() => void) | undefined; const RESPONSES_ONLY = [ "gpt-5.3-codex", @@ -137,7 +140,12 @@ describe("the registry default is isolated to the copilot provider", () => { describe("the wire default survives the handleResponses replay", () => { const originalFetch = globalThis.fetch; - afterEach(() => { globalThis.fetch = originalFetch; }); + afterEach(() => { + // Release the preload-home lease before later teardown can replace or remove that home. + releaseSpendHome?.(); + releaseSpendHome = undefined; + globalThis.fetch = originalFetch; + }); function captureUpstreamUrl(): string[] { const urls: string[] = []; @@ -154,6 +162,8 @@ describe("the wire default survives the handleResponses replay", () => { async function drive(model: string, inboundWire?: "responses" | "chat" | "anthropic"): Promise { const urls = captureUpstreamUrl(); const config = { providers: { "github-copilot": copilotProvider() } } as unknown as OcxConfig; + // Direct dispatch needs the writer lease that startServer normally owns for this home. + releaseSpendHome = acquireOwnedSpendHome(); await handleResponses( new Request("http://localhost/v1/responses", { method: "POST", diff --git a/tests/providers/kiro/kiro-auth-context-continuation.test.ts b/tests/providers/kiro/kiro-auth-context-continuation.test.ts index 83e22d0b48f..567ce21ffde 100644 --- a/tests/providers/kiro/kiro-auth-context-continuation.test.ts +++ b/tests/providers/kiro/kiro-auth-context-continuation.test.ts @@ -15,6 +15,7 @@ import { clearGenericFailoverHealth } from "../../../src/oauth/generic-account-f import { getAccountSet, saveCredential, setActiveAccount } from "../../../src/oauth/store"; import type { AdapterEvent, OcxConfig, OcxParsedRequest, OcxProviderConfig } from "../../../src/types"; import { removeTreeWithRetry } from "../../helpers/remove-tree"; +import { acquireOwnedSpendHome } from "../../helpers/owned-spend-home"; const previousHome = process.env.OPENCODEX_HOME; let testHome = ""; @@ -84,15 +85,24 @@ beforeAll(async () => { ({ handleResponses } = await import("../../../src/server/responses")); }); +let releaseSpendHome: (() => void) | undefined; + beforeEach(() => { testHome = mkdtempSync(join(tmpdir(), "ocx-kiro-continuation-auth-")); process.env.OPENCODEX_HOME = testHome; kiroBuilds = []; clearAnthropicAccountPoolState(); clearGenericFailoverHealth(); + // Dispatches without starting a server, so it takes the spend-journal lease itself. Taken + // last because the lease binds the home in effect at the moment it is taken. + releaseSpendHome = acquireOwnedSpendHome(); }); afterEach(() => { + // Released before this case's home is removed: an open lease inside a directory being + // deleted fails the removal on Windows and leaves an unlinked live database on POSIX. + releaseSpendHome?.(); + releaseSpendHome = undefined; clearAnthropicAccountPoolState(); clearGenericFailoverHealth(); removeTreeWithRetry(testHome); diff --git a/tests/providers/opencode-go-luna-wire.test.ts b/tests/providers/opencode-go-luna-wire.test.ts index 7866ec94150..a07c66ff2de 100644 --- a/tests/providers/opencode-go-luna-wire.test.ts +++ b/tests/providers/opencode-go-luna-wire.test.ts @@ -13,9 +13,15 @@ import type { OcxConfig, OcxProviderConfig } from "../../src/types"; import { createResponsesPassthroughAdapter } from "../../src/adapters/openai-responses"; import { parseRequest } from "../../src/responses/parser"; import { withTestTranslatorBudget } from "../helpers/translator-budget"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; const MODEL = "gpt-5.6-luna"; const GO_RESPONSES_MODELS = [MODEL, "grok-4.6", "muse-spark-1.3-contributor"]; +let releaseSpendHome: (() => void) | undefined; + +// Direct dispatch needs the writer lease that startServer normally owns for this home. +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; +const dropSpendHome = (): void => { releaseSpendHome?.(); releaseSpendHome = undefined; }; function opencodeGo(overrides: Partial = {}): OcxProviderConfig { const entry = getProviderRegistryEntry("opencode-go"); @@ -102,7 +108,11 @@ describe("OpenCode Go stateless Responses", () => { describe("OpenCode Go stateless reasoning and continuation routes", () => { const originalFetch = globalThis.fetch; - afterEach(() => { globalThis.fetch = originalFetch; }); + afterEach(() => { + // Release the preload-home lease before later teardown can replace or remove that home. + dropSpendHome(); + globalThis.fetch = originalFetch; + }); const continuations = [ { id: "full", name: "full history", fullHistory: true, summary: "auto" }, @@ -147,6 +157,7 @@ describe("OpenCode Go stateless reasoning and continuation routes", () => { }) as typeof fetch; const config = { providers: { "opencode-go": opencodeGo() } } as unknown as OcxConfig; const drive = async (body: Record) => { + takeSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ model: `opencode-go/${model}`, stream: streaming, reasoning: { summary: continuation.summary }, @@ -214,7 +225,10 @@ describe("OpenCode Go stateless reasoning and continuation routes", () => { describe("OpenCode Go Luna Responses route (#1482)", () => { const originalFetch = globalThis.fetch; - afterEach(() => { globalThis.fetch = originalFetch; }); + afterEach(() => { + dropSpendHome(); + globalThis.fetch = originalFetch; + }); test("handleResponses sends Luna to the documented /responses endpoint", async () => { const requests: Array<{ url: string; body: Record }> = []; @@ -234,6 +248,7 @@ describe("OpenCode Go Luna Responses route (#1482)", () => { const config = { providers: { "opencode-go": opencodeGo() }, } as unknown as OcxConfig; + takeSpendHome(); const response = await handleResponses( new Request("http://localhost/v1/responses", { method: "POST", diff --git a/tests/providers/opencode-go-session-header.test.ts b/tests/providers/opencode-go-session-header.test.ts index 4f51b581c02..d972344803d 100644 --- a/tests/providers/opencode-go-session-header.test.ts +++ b/tests/providers/opencode-go-session-header.test.ts @@ -9,6 +9,7 @@ import { getOrAllocateRequestSessionLane } from "../../src/server/request-log-co import { handleChatCompletions } from "../../src/server/chat-completions"; import { handleClaudeMessages } from "../../src/server/claude-messages"; import type { OcxConfig, OcxProviderConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; const MUSE_MODEL = "muse-spark-1.3-contributor"; const CHAT_MODEL = "glm-5.2"; @@ -28,6 +29,13 @@ const RESPONSES_SESSION_VECTORS = { prefixed: "ocx_c974cef031af8717276b933929f0c073", codex: "ocx_a0cfe09ee92e4bfa2e560579bc46c50e", } as const; +let releaseSpendHome: (() => void) | undefined; + +// Direct physical dispatch needs the writer lease to prevent spend-ledger ownership failures. +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; + +// Release before the next case so a failed dispatch cannot leave an ownership conflict. +const dropSpendHome = (): void => { releaseSpendHome?.(); releaseSpendHome = undefined; }; function opencodeGo(overrides: Partial = {}): OcxProviderConfig { const entry = getProviderRegistryEntry("opencode-go"); @@ -96,6 +104,7 @@ async function captureRequest(input: { const config = { providers: { [providerName]: input.provider ?? opencodeGo() }, } as unknown as OcxConfig; + takeSpendHome(); const response = input.claude ? await handleClaudeMessages( new Request("http://localhost/v1/messages", { method: "POST", @@ -136,7 +145,10 @@ async function captureRequest(input: { describe("OpenCode Go session affinity (#3344)", () => { const originalFetch = globalThis.fetch; - afterEach(() => { globalThis.fetch = originalFetch; }); + afterEach(() => { + dropSpendHome(); + globalThis.fetch = originalFetch; + }); for (const model of [CHAT_MODEL, MUSE_MODEL]) { // The policy target is deliberately renamed, so provider-name wire defaults do not apply; @@ -183,6 +195,7 @@ describe("OpenCode Go session affinity (#3344)", () => { // Preliminary route checks the first target; dispatch independently picks Go. entropy.mockReturnValueOnce(0); try { + takeSpendHome(); const response = await handleClaudeMessages(new Request("http://localhost/v1/messages", { method: "POST", headers: { "content-type": "application/json", ...identity.headers } as Record, body: JSON.stringify({ model: "combo/affinity", max_tokens: 64, stream: false, @@ -243,6 +256,7 @@ describe("OpenCode Go session affinity (#3344)", () => { } as unknown as OcxConfig; const entropy = spyOn(Math, "random").mockReturnValue(0.9).mockReturnValueOnce(0); try { + takeSpendHome(); const response = await handleClaudeMessages(new Request("http://localhost/v1/messages", { method: "POST", headers: { "content-type": "application/json", [SESSION_HEADER]: "client-session-a" }, body: JSON.stringify({ model: "combo/affinity", max_tokens: 64, stream: false, diff --git a/tests/providers/rate-limit-retry.test.ts b/tests/providers/rate-limit-retry.test.ts index dab8ec84b98..861929f72e3 100644 --- a/tests/providers/rate-limit-retry.test.ts +++ b/tests/providers/rate-limit-retry.test.ts @@ -5,6 +5,9 @@ import { } from "../../src/providers/key-failover"; import { handleResponses } from "../../src/server/responses"; import type { OcxConfig, OcxProviderConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; + +let releaseSpendHome: (() => void) | undefined; describe("rateLimitRetryPolicyFor", () => { test("null when absent or explicitly disabled", () => { @@ -140,6 +143,9 @@ describe("retry loop client-abort handling", () => { const originalFetch = globalThis.fetch; afterEach(() => { + // Release the preload-home lease before later teardown can replace or remove that home. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; }); @@ -170,6 +176,8 @@ describe("retry loop client-abort handling", () => { }, } as OcxConfig; + // Direct dispatch needs the writer lease that startServer normally owns for this home. + releaseSpendHome = acquireOwnedSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -217,6 +225,7 @@ describe("retry loop client-abort handling", () => { } as OcxConfig; const abort = new AbortController(); + releaseSpendHome = acquireOwnedSpendHome(); const pending = handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -273,6 +282,7 @@ describe("retry loop client-abort handling", () => { } as OcxConfig; const abort = new AbortController(); + releaseSpendHome = acquireOwnedSpendHome(); const pending = handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, diff --git a/tests/providers/upstream-transient-retry.test.ts b/tests/providers/upstream-transient-retry.test.ts index 956496e44e4..516f31850a6 100644 --- a/tests/providers/upstream-transient-retry.test.ts +++ b/tests/providers/upstream-transient-retry.test.ts @@ -9,6 +9,7 @@ import { import { transientRetryPolicyFor } from "../../src/providers/key-failover"; import { handleChatCompletions } from "../../src/server/chat-completions"; import type { OcxConfig, OcxProviderConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; function bodyResponse(status: number, headers?: Record): Response { // ReadableStream body so cancel() is observable. @@ -290,24 +291,31 @@ describe("native Chat completions and the replay refusal", () => { }, } as unknown as OcxConfig; - const response = await handleChatCompletions( - new Request("http://localhost/v1/chat/completions", { - method: "POST", - headers: { "content-type": "application/json" }, - body: JSON.stringify({ - model: "replay-refusal-fixture/model", - messages: [{ role: "user", content: "ping" }], + // Taken after the inherited test home is in effect so native Chat can record its send. + const releaseSpendHome = acquireOwnedSpendHome(); + try { + const response = await handleChatCompletions( + new Request("http://localhost/v1/chat/completions", { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + model: "replay-refusal-fixture/model", + messages: [{ role: "user", content: "ping" }], + }), }), - }), - config, - { model: "", provider: "" }, - ); + config, + { model: "", provider: "" }, + ); - expect(sends).toBe(1); - expect(response.status).toBe(429); - expect(response.headers.get("Retry-After")).toBeNull(); - expect(await response.json()).toMatchObject({ - error: { code: "upstream_reset_replay_refused" }, - }); + expect(sends).toBe(1); + expect(response.status).toBe(429); + expect(response.headers.get("Retry-After")).toBeNull(); + expect(await response.json()).toMatchObject({ + error: { code: "upstream_reset_replay_refused" }, + }); + } finally { + // Released after the response body is consumed so no stream retains the ledger owner. + releaseSpendHome(); + } }); }); diff --git a/tests/responses/chat-completions-endpoint.test.ts b/tests/responses/chat-completions-endpoint.test.ts index d23a857b8b0..b87b3177779 100644 --- a/tests/responses/chat-completions-endpoint.test.ts +++ b/tests/responses/chat-completions-endpoint.test.ts @@ -4,6 +4,7 @@ import { tmpdir } from "node:os"; import { join } from "node:path"; import { loadConfig, saveConfig } from "../../src/config"; import { startServer } from "../../src/server"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { ownedServiceHomeInspection } from "../helpers/owned-service-home-inspection"; import type { OcxConfig, OcxProviderConfig } from "../../src/types"; import { installIsolatedCodexHome, type IsolatedCodexHome } from "../helpers/isolated-codex-home"; @@ -60,6 +61,11 @@ let previousHome: string | undefined; let isolatedCodexHome: IsolatedCodexHome | null = null; const originalFetch = globalThis.fetch; +// A case that calls a handler directly never takes the writer lease startServer takes, so its +// dispatch is refused. Never file-wide: most cases here start a real server that takes it too. +let releaseSpendHome: (() => void) | undefined; +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; + beforeEach(() => { previousHome = process.env.OPENCODEX_HOME; isolatedCodexHome = installIsolatedCodexHome("ocx-chat-completions-"); @@ -69,6 +75,8 @@ beforeEach(() => { }); afterEach(() => { + releaseSpendHome?.(); + releaseSpendHome = undefined; resetProviderRequestPacingForTest(); if (previousHome === undefined) delete process.env.OPENCODEX_HOME; else process.env.OPENCODEX_HOME = previousHome; @@ -367,6 +375,7 @@ async function driveChatFallbackServiceTier( }, }, } as OcxConfig; + takeSpendHome(); const response = await handleChatCompletions( new Request("http://localhost/v1/chat/completions", { method: "POST", @@ -973,8 +982,10 @@ test("chat-native consumes pacing before the response-header timeout starts", as }), }); + takeSpendHome(); const first = await handleChatCompletions(request(), config, {} as Parameters[2]); expect(first.status).toBe(200); + takeSpendHome(); const secondPending = handleChatCompletions(request(), config, {} as Parameters[2]); await Bun.sleep(5); expect(starts).toBe(1); @@ -1004,6 +1015,7 @@ test("chat-native stays outside the Responses empty-completion retry guard", asy } as Partial & { fetch: typeof globalThis.fetch }); config.emptyCompletionRetry = true; + takeSpendHome(); const response = await handleChatCompletions( new Request("http://localhost/v1/chat/completions", { method: "POST", @@ -1632,6 +1644,7 @@ test("chat-native client cancellation cancels the upstream stream and logs 499", body: JSON.stringify({ model: "mock/test-model", stream: true, messages: [{ role: "user", content: "hi" }] }), }); const logCtx = {} as Parameters[2]; + takeSpendHome(); const response = await handleChatCompletions( request, mockConfig("https://provider.example/v1"), @@ -1683,6 +1696,7 @@ test("chat-native request abort releases its active-turn lease and logs 499", as body: JSON.stringify({ model: "mock/test-model", stream: true, messages: [{ role: "user", content: "hi" }] }), signal: clientAbort.signal, }); + takeSpendHome(); const response = await handleChatCompletions( request, mockConfig("https://provider.example/v1"), @@ -1722,6 +1736,7 @@ test("chat-native cancelled non-streaming SSE returns 499 instead of partial suc readStarted(); }, }), { headers: { "content-type": "text/event-stream" } })) as typeof fetch; + takeSpendHome(); const result = handleChatCompletions(new Request("http://localhost/v1/chat/completions", { method: "POST", signal: clientAbort.signal, headers: { "content-type": "application/json" }, @@ -1755,6 +1770,7 @@ test("chat-native SSE enforces configured stall timeout despite non-progress fra cancel() { cancels += 1; clearInterval(timer); }, }), { headers: { "content-type": "text/event-stream" } })) as typeof fetch; try { + takeSpendHome(); const response = await handleChatCompletions(new Request("http://localhost/v1/chat/completions", { method: "POST", signal: clientAbort.signal, headers: { "content-type": "application/json" }, @@ -1854,6 +1870,7 @@ test("chat-native valid terminal retains precedence over a late non-streaming ab }, cancel() { clientAbort.abort("late cancellation after terminal"); }, }), { headers: { "content-type": "text/event-stream" } })) as typeof fetch; + takeSpendHome(); const response = await handleChatCompletions(new Request("http://localhost/v1/chat/completions", { method: "POST", signal: clientAbort.signal, headers: { "content-type": "application/json" }, body: JSON.stringify({ model: "mock/test-model", stream: false, messages: [{ role: "user", content: "hi" }] }), @@ -1872,6 +1889,7 @@ test("chat-native non-streaming SSE reports a typed stall failure instead of par }, cancel() { cancels += 1; }, }), { headers: { "content-type": "text/event-stream" } })) as typeof fetch; + takeSpendHome(); const response = await handleChatCompletions(new Request("http://localhost/v1/chat/completions", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ model: "mock/test-model", stream: false, messages: [{ role: "user", content: "hi" }] }), @@ -1918,6 +1936,7 @@ test("chat-native non-streaming SSE collects CRLF multiline and split UTF-8 fram controller.close(); }, }), { headers: { "content-type": "text/event-stream" } })) as typeof fetch; + takeSpendHome(); const response = await handleChatCompletions(new Request("http://localhost/v1/chat/completions", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ model: "mock/test-model", stream: false, messages: [{ role: "user", content: "hi" }] }), @@ -1942,6 +1961,7 @@ test("chat-native direct streaming without an admission lease does not record a headers: { "content-type": "application/json" }, body: JSON.stringify({ model: "mock/test-model", stream: true, messages: [{ role: "user", content: "hi" }] }), }); + takeSpendHome(); const response = await handleChatCompletions( request, mockConfig("https://provider.example/v1"), diff --git a/tests/responses/chat-conversation-affinity.test.ts b/tests/responses/chat-conversation-affinity.test.ts index 97c599b3088..3254c709042 100644 --- a/tests/responses/chat-conversation-affinity.test.ts +++ b/tests/responses/chat-conversation-affinity.test.ts @@ -6,6 +6,7 @@ import { handleChatCompletions } from "../../src/server/chat-completions"; import type { OcxConfig } from "../../src/types"; import { fakeChatGptJwt } from "../helpers/fake-chatgpt-jwt"; import { installIsolatedCodexHome, type IsolatedCodexHome } from "../helpers/isolated-codex-home"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; // #3433 transport contract only: these client-assigned fixture IDs are not a capture of Hermes. @@ -14,14 +15,20 @@ const identityHeaders = ["session_id", "session-id", "thread-id", "x-codex-paren let isolated: IsolatedCodexHome; let home: string; let previousHome: string | undefined; +let releaseSpendHome: (() => void) | undefined; beforeEach(() => { isolated = installIsolatedCodexHome("ocx-chat-identity-"); previousHome = process.env.OPENCODEX_HOME; home = mkdtempSync(join(tmpdir(), "ocx-chat-identity-config-")); process.env.OPENCODEX_HOME = home; + // Taken after this case installs its home so direct Chat dispatch owns that journal. + releaseSpendHome = acquireOwnedSpendHome(); }); afterEach(() => { + // Released before this case restores and removes its home so no live database is unlinked. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; isolated.restore(); if (previousHome === undefined) delete process.env.OPENCODEX_HOME; diff --git a/tests/responses/chat-json-sse-fallback.test.ts b/tests/responses/chat-json-sse-fallback.test.ts index e3fc1bb8711..bc357fa5403 100644 --- a/tests/responses/chat-json-sse-fallback.test.ts +++ b/tests/responses/chat-json-sse-fallback.test.ts @@ -6,9 +6,21 @@ import { responsesJsonToChatCompletion, collectChatCompletion, responsesSseToCha import { jsonCompletionSse } from "../../src/server/chat-native-sse"; import { getRequestLogEntries } from "../../src/server/request-log"; import { readUsageEntries } from "../../src/usage/log"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; let upstream: ReturnType | undefined; -afterEach(async () => { await upstream?.stop(true); upstream = undefined; }); +let releaseSpendHome: (() => void) | undefined; +const takeSpendHome = (): void => { + // Taken only for direct Chat dispatches so mixed pure-converter cases do not open the journal. + releaseSpendHome ??= acquireOwnedSpendHome(); +}; +afterEach(async () => { + // Released first so a failed assertion cannot leave the inherited sandbox lease live. + releaseSpendHome?.(); + releaseSpendHome = undefined; + await upstream?.stop(true); + upstream = undefined; +}); interface Chunk { choices: Array<{ index: number; delta: { @@ -34,6 +46,7 @@ async function streamFixture(output: unknown[], status = "completed", cancel = f adapter: "openai-responses", baseUrl: `http://127.0.0.1:${upstream.port}/v1`, authMode: "key", apiKey: "fixture-key", allowPrivateNetwork: true, models: ["model"], } } }; + takeSpendHome(); const response = await handleChatCompletions(new Request("http://localhost/v1/chat/completions", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ model: "fixture/model", stream: !delivery.jsonFinish, messages: [{ role: "user", content: "fixture" }], @@ -327,6 +340,7 @@ describe("service_tier echo relay", () => { body: JSON.stringify({ model: "fixture/model", stream, messages: [{ role: "user", content: "ping" }] }), }), config, { model: "", provider: "" }, { requestId: `tier-relay-${stream}`, start: Date.now() }); + takeSpendHome(); const jsonResponse = await post(false); expect(jsonResponse.status).toBe(200); expect(await jsonResponse.json()).toMatchObject({ service_tier: "priority", choices: [{ finish_reason: "stop" }] }); diff --git a/tests/responses/chat-refusal.test.ts b/tests/responses/chat-refusal.test.ts index 27f6ff86efd..9e2a81eff74 100644 --- a/tests/responses/chat-refusal.test.ts +++ b/tests/responses/chat-refusal.test.ts @@ -9,6 +9,7 @@ import { jsonCompletionSse, nativeChatSse } from "../../src/server/chat-native-s import type { OcxConfig } from "../../src/types"; import { createTestTranslatorBudget } from "../helpers/translator-budget"; import { installIsolatedCodexHome, type IsolatedCodexHome } from "../helpers/isolated-codex-home"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { resetProviderRequestPacingForTest } from "../../src/providers/request-pacing"; type Rec = Record; @@ -400,13 +401,19 @@ describe("refusal handler delivery matrix", () => { const originalFetch = globalThis.fetch; let isolatedHome: IsolatedCodexHome | undefined; let previousOcxHome: string | undefined; + let releaseSpendHome: (() => void) | undefined; beforeEach(() => { previousOcxHome = process.env.OPENCODEX_HOME; isolatedHome = installIsolatedCodexHome("ocx-refusal-fixture-"); process.env.OPENCODEX_HOME = isolatedHome.path; + // Taken after this matrix installs its home so direct Chat dispatch owns that journal. + releaseSpendHome = acquireOwnedSpendHome(); globalThis.fetch = (async () => { throw new Error("unstubbed external transport"); }) as typeof fetch; }); afterEach(() => { + // Released before the matrix restores its home so no live database survives teardown. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; resetProviderRequestPacingForTest(); if (previousOcxHome === undefined) delete process.env.OPENCODEX_HOME; diff --git a/tests/responses/empty-completion-core.test.ts b/tests/responses/empty-completion-core.test.ts index 6ec5541f123..6a645c8da54 100644 --- a/tests/responses/empty-completion-core.test.ts +++ b/tests/responses/empty-completion-core.test.ts @@ -8,6 +8,7 @@ import { } from "../../src/providers/request-pacing"; import type { RequestLogContext } from "../../src/server/request-log"; import type { AdapterEvent, OcxConfig, OcxParsedRequest, OcxProviderConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; const actualResolver = await import("../../src/server/adapter-resolve"); const actualResolveAdapter = actualResolver.resolveAdapter; @@ -20,6 +21,10 @@ let builtBodies: string[] = []; let customRunTurn: ProviderAdapter["runTurn"] | undefined; let passthroughFetchCalls = 0; let bodyObservationReleaseCalls = 0; +let releaseSpendHome: (() => void) | undefined; + +// Direct dispatch needs the writer lease that startServer normally owns for this home. +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; function attemptAt(index: number): AdapterEvent[] { return attemptEvents[index] ?? [{ type: "error", message: `missing fixture attempt ${index}` }]; @@ -165,6 +170,9 @@ beforeEach(() => { }); afterEach(() => { + // Release the preload-home lease before later teardown can replace or remove that home. + releaseSpendHome?.(); + releaseSpendHome = undefined; resetProviderRequestPacingForTest(); delete process.env.OCX_EMPTY_COMPLETION_RETRY; }); @@ -176,6 +184,7 @@ describe("empty-completion core integration", () => { // and that transport already falls back to HTTP SSE for exactly these bodies (#2473), with // an 18.2 MB HTTP 200 observed in #2426. Unset must mean "send it", not "guess a ceiling". const logCtx: RequestLogContext = { model: "", provider: "" }; + takeSpendHome(); const response = await handleResponses( request(false, "x".repeat(20 * 1024 * 1024)), config("test-passthrough"), @@ -220,6 +229,7 @@ describe("empty-completion core integration", () => { }); test("a normal-sized passthrough body still reaches upstream", async () => { + takeSpendHome(); const response = await handleResponses( request(false), config("test-passthrough", { maxUpstreamBodyBytes: 4_096 }), @@ -232,6 +242,7 @@ describe("empty-completion core integration", () => { }); test("an explicit zero limit lets an oversized turn reach upstream", async () => { + takeSpendHome(); const response = await handleResponses( request(false, "x".repeat(512)), config("test-passthrough", { maxUpstreamBodyBytes: 0 }), @@ -266,6 +277,7 @@ describe("empty-completion core integration", () => { emit({ type: "done" }); }; + takeSpendHome(); const response = await handleResponses(request(true), paced, { model: "", provider: "" }); expect(response.status).toBe(200); const reader = response.body!.getReader(); @@ -297,6 +309,7 @@ describe("empty-completion core integration", () => { ]; const logCtx: RequestLogContext = { model: "", provider: "" }; + takeSpendHome(); const response = await handleResponses(request(stream), config("test-run-turn"), logCtx); const body = await response.text(); @@ -319,6 +332,7 @@ describe("empty-completion core integration", () => { ]; const logCtx: RequestLogContext = { model: "", provider: "" }; + takeSpendHome(); const response = await handleResponses(request(stream), config("test-http"), logCtx); const body = await response.text(); @@ -352,6 +366,7 @@ describe("empty-completion core integration", () => { const paced = config("test-http"); paced.providers.fixture!.requestPacing = { enabled: true, minIntervalMs: 100 }; + takeSpendHome(); const response = await handleResponses(request(false), paced, { model: "", provider: "" }); expect(response.status).toBe(200); expect(httpCalls).toBe(2); @@ -369,6 +384,7 @@ describe("empty-completion core integration", () => { const tierGated = config("test-http"); tierGated.providers.fixture!.supportsServiceTier = false; + takeSpendHome(); const response = await handleResponses( request(false, "please answer", { service_tier: "priority" }), tierGated, @@ -388,6 +404,7 @@ describe("empty-completion core integration", () => { const disabled = config("test-run-turn"); delete disabled.emptyCompletionRetry; + takeSpendHome(); const response = await handleResponses(request(false), disabled, { model: "", provider: "" }); await response.text(); @@ -410,6 +427,7 @@ describe("empty-completion core integration", () => { emit({ type: "done" }); }; + takeSpendHome(); const response = await handleResponses( request(true), config("test-run-turn", { stallTimeoutSec: 0.05 }), @@ -424,6 +442,7 @@ describe("empty-completion core integration", () => { test("combo and routed-compaction turns are excluded from the retry", async () => { attemptEvents = [[{ type: "done" }], [{ type: "text_delta", text: "must not run" }, { type: "done" }]]; + takeSpendHome(); const combo = await handleResponses( request(false), config("test-run-turn"), @@ -472,6 +491,7 @@ describe("empty-completion core integration", () => { }), }); + takeSpendHome(); const response = await handleResponses(req, guarded, { model: "", provider: "" }); const body = await response.text(); diff --git a/tests/responses/fresh-connection-optout.test.ts b/tests/responses/fresh-connection-optout.test.ts index 944afbd222a..0cde659563e 100644 --- a/tests/responses/fresh-connection-optout.test.ts +++ b/tests/responses/fresh-connection-optout.test.ts @@ -9,6 +9,7 @@ import { handleResponses } from "../../src/server/responses"; import type { RequestLogContext } from "../../src/server/request-log"; import type { OcxConfig, OcxProviderConfig } from "../../src/types"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; describe("wantsFreshConnection", () => { test("returns false when env is unset or empty", () => { @@ -277,6 +278,8 @@ describe("the OAuth dispatch boundary", () => { process.env.OPENCODEX_HOME = home; process.env.CODEX_HOME = home; process.env.OCX_FRESH_CONNECTION_HOSTS = freshHost; + // Taken after this case installs its home so the direct dispatch owns that journal. + const releaseSpendHome = acquireOwnedSpendHome(); const sends: Array<{ url: string; init?: RequestInit }> = []; try { @@ -330,6 +333,8 @@ describe("the OAuth dispatch boundary", () => { expect(headers.get("x-grok-req-id")).toBeTruthy(); } } finally { + // Released before restoring or removing the home so Windows can delete its lease files. + releaseSpendHome(); globalThis.fetch = nativeFetch; if (previousHosts === undefined) delete process.env.OCX_FRESH_CONNECTION_HOSTS; else process.env.OCX_FRESH_CONNECTION_HOSTS = previousHosts; diff --git a/tests/responses/openai-responses-passthrough.test.ts b/tests/responses/openai-responses-passthrough.test.ts index 42ace1b77a1..f9c2029f38a 100644 --- a/tests/responses/openai-responses-passthrough.test.ts +++ b/tests/responses/openai-responses-passthrough.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, spyOn, test } from "bun:test"; +import { afterEach, describe, expect, spyOn, test } from "bun:test"; import { Buffer } from "node:buffer"; import { createOpenAIChatAdapter } from "../../src/adapters/openai-chat"; import { createResponsesPassthroughAdapter as createResponsesPassthroughAdapterProduction } from "../../src/adapters/openai-responses"; @@ -22,9 +22,17 @@ import { import { createTranslatorBudget } from "../../src/lib/translator-budget"; import type { AdapterEvent, OcxConfig } from "../../src/types"; import { withTestTranslatorBudget } from "../helpers/translator-budget"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; +import { buildKeyAuthUrl } from "../helpers/passthrough-key-url"; import { restoreRoutedNamespaceCalls } from "../../src/responses/namespace-tool-compat"; import { restoreRoutedCustomCalls } from "../../src/responses/custom-tool-compat"; +// A case that calls handleResponses directly never takes the writer lease startServer takes, so +// its dispatch is refused. Dropped in teardown so a throwing case cannot leave the lease behind. +let releaseSpendHome: (() => void) | undefined; +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; +afterEach(() => { releaseSpendHome?.(); releaseSpendHome = undefined; }); + const createResponsesPassthroughAdapter = (...args: Parameters) => withTestTranslatorBudget(createResponsesPassthroughAdapterProduction(...args)); @@ -559,6 +567,7 @@ test("noncanonical Responses preserves provider-owned safety-buffering hints", a dropCodexSafetyBuffering: true, providers: { fixture: providerConfig }, } as OcxConfig; + takeSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -692,23 +701,6 @@ test("passthrough serialized-body observation releases after the request settles budget.dispose(); }); -function buildKeyAuthUrl(baseUrl: string, responsesPath?: string): string { - const adapter = createResponsesPassthroughAdapter({ - adapter: "openai-responses", - baseUrl, - authMode: "key" as const, - apiKey: "sk-test", - ...(responsesPath === undefined ? {} : { responsesPath }), - }); - return adapter.buildRequest({ - modelId: "test-model", - context: { messages: [] }, - stream: true, - options: {}, - _rawBody: { model: "test-model", input: "ping" }, - }, { headers: new Headers() }).url; -} - describe("OpenAI Responses key-auth URL construction", () => { test("BUG-R289 preserves legacy /v1/responses URL when responsesPath is absent", () => { for (const [baseUrl, expectedUrl] of [ @@ -4283,6 +4275,7 @@ describe("routed namespace and custom-tool identity", () => { }); try { + takeSpendHome(); const jsonResponse = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -4303,6 +4296,7 @@ describe("routed namespace and custom-tool identity", () => { arguments: "{}", }); + takeSpendHome(); const sseResponse = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -4367,6 +4361,7 @@ describe("routed namespace and custom-tool identity", () => { }) as typeof fetch; try { + takeSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -4713,11 +4708,15 @@ describe("raw usage passthrough on the forward path (#41980 parity, #37138 adjac stream, input: [{ role: "user", content: [{ type: "input_text", text: "hi" }] }], }); - const call = (stream: boolean) => handleResponses(new Request("http://localhost/v1/responses", { - method: "POST", - headers: { "content-type": "application/json" }, - body: requestBody(stream), - }), config, { model: "", provider: "" }); + // Inside the arrow: taken beside it, at collection time, the first teardown drops it for good. + const call = (stream: boolean) => { + takeSpendHome(); + return handleResponses(new Request("http://localhost/v1/responses", { + method: "POST", + headers: { "content-type": "application/json" }, + body: requestBody(stream), + }), config, { model: "", provider: "" }); + }; test("streamed response.completed with usage extras reaches the client byte-identical", async () => { const savedFetch = globalThis.fetch; @@ -4794,6 +4793,7 @@ test("canonical Responses hint suppression is opt-in at the request boundary", a const config = { port: 0, dropCodexSafetyBuffering, providers: { openai: { ...provider, codexAccountMode: "direct", upstreamWebsocket: false, } } } as OcxConfig; + takeSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json", authorization: "Bearer fixture-forward-token" }, body: JSON.stringify({ model: "openai/gpt-5.6-sol", input: "ping", stream: true }), diff --git a/tests/responses/responses-account-label.test.ts b/tests/responses/responses-account-label.test.ts index 08dacdc59f3..bfccb8afb10 100644 --- a/tests/responses/responses-account-label.test.ts +++ b/tests/responses/responses-account-label.test.ts @@ -15,10 +15,15 @@ import type { RequestLogContext } from "../../src/server/request-log"; import { handleResponses } from "../../src/server/responses"; import type { OcxConfig } from "../../src/types"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { CodexWsMetadata } from "../../src/server/responses/codex-ws-metadata"; import { applyAccountQuotaFromUpstreamHeaders, getAccountQuotaHistory } from "../../src/codex/quota"; const originalFetch = globalThis.fetch; +let releaseSpendHome: (() => void) | undefined; + +// Taken only by callbacks that physically dispatch, after withPoolHome installs their home. +const takeSpendHome = (): void => { releaseSpendHome = acquireOwnedSpendHome(); }; function poolConfig(accountIds: string[]): OcxConfig { return { @@ -80,6 +85,9 @@ async function withPoolHome(run: (home: string) => Promise): Promise { try { return await run(home); } finally { + // Released before the helper removes or restores the home so its lease cannot outlive it. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; clearCodexUpstreamHealth(); clearThreadAccountMap(); @@ -133,6 +141,7 @@ describe("Responses account usage attribution", () => { const originalWebSocket = globalThis.WebSocket; try { await withPoolHome(async home => { + takeSpendHome(); writeFileSync(join(home, "auth.json"), JSON.stringify({ tokens: { access_token: "main-access-token", account_id: "main-account" }, })); @@ -198,6 +207,7 @@ describe("Responses account usage attribution", () => { const finalQuotaAllowed = new Promise(resolve => { releaseFinalQuota = resolve; }); try { await withPoolHome(async () => { + takeSpendHome(); savePoolCredential("pool-ws-replaced"); class MetadataSocket { listeners = new Map void>>(); @@ -255,6 +265,7 @@ describe("Responses account usage attribution", () => { test("main-pool and legacy added accounts carry their effective labels", async () => { await withPoolHome(async home => { + takeSpendHome(); writeFileSync(join(home, "auth.json"), JSON.stringify({ tokens: { access_token: "main-access-token", account_id: "main-account" }, })); @@ -280,6 +291,7 @@ describe("Responses account usage attribution", () => { test("a pre-stream quota retry updates attribution to the serving alternate account", async () => { await withPoolHome(async () => { + takeSpendHome(); const config = poolConfig(["pool-a", "pool-b"]); for (const id of ["pool-a", "pool-b"]) { savePoolCredential(id); @@ -310,6 +322,7 @@ describe("Responses account usage attribution", () => { test("a quota message wrapped in HTTP 502 cools the account and retries an alternate", async () => { await withPoolHome(async () => { + takeSpendHome(); const config = poolConfig(["pool-a", "pool-b"]); for (const id of ["pool-a", "pool-b"]) { savePoolCredential(id); @@ -349,6 +362,7 @@ describe("Responses account usage attribution", () => { // refused nothing -- and the cooldown outlives the request that invented it. test("a refused reset replay is not quota evidence and invites no client retry", async () => { await withPoolHome(async () => { + takeSpendHome(); const config = poolConfig(["pool-a"]); savePoolCredential("pool-a"); updateAccountQuota("pool-a", 10); @@ -372,6 +386,7 @@ describe("Responses account usage attribution", () => { test("a wrapped quota failure cools a sole account when no alternate exists", async () => { await withPoolHome(async () => { + takeSpendHome(); const config = poolConfig(["pool-a"]); savePoolCredential("pool-a"); updateAccountQuota("pool-a", 10); diff --git a/tests/responses/responses-compact-handoff-admission.test.ts b/tests/responses/responses-compact-handoff-admission.test.ts index 5fcb2aa67e3..3ebe8c78706 100644 --- a/tests/responses/responses-compact-handoff-admission.test.ts +++ b/tests/responses/responses-compact-handoff-admission.test.ts @@ -8,6 +8,7 @@ import { clearCodexUpstreamHealth } from "../../src/codex/routing"; import { clearUpstreamHostHealth } from "../../src/codex/upstream-host-health"; import { handleResponsesCompact } from "../../src/server/responses"; import type { OcxConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; const originalFetch = globalThis.fetch; @@ -44,7 +45,7 @@ describe("compact handoff route admission namespacing", () => { } as OcxConfig; } - function withPoolEnv(run: (config: OcxConfig) => Promise): Promise { + async function withPoolEnv(run: (config: OcxConfig) => Promise): Promise { const testDir = mkdtempSync(join(tmpdir(), "ocx-compact-handoff-admission-")); const previousOpencodexHome = process.env.OPENCODEX_HOME; const previousCodexHome = process.env.CODEX_HOME; @@ -60,7 +61,13 @@ describe("compact handoff route admission namespacing", () => { chatgptAccountId: "pool_acc", }); updateAccountQuota("pool-a", 10); - return run(poolConfig()).finally(() => { + // Taken after this helper installs its home so direct compact dispatch owns that journal. + const releaseSpendHome = acquireOwnedSpendHome(); + try { + return await run(poolConfig()); + } finally { + // Released before this helper restores and removes its home so no live database is unlinked. + releaseSpendHome(); globalThis.fetch = originalFetch; clearCodexUpstreamHealth(); clearUpstreamHostHealth(); @@ -70,7 +77,7 @@ describe("compact handoff route admission namespacing", () => { else process.env.OPENCODEX_HOME = previousOpencodexHome; if (previousCodexHome === undefined) delete process.env.CODEX_HOME; else process.env.CODEX_HOME = previousCodexHome; - }); + } } function compactionRequest( @@ -155,8 +162,12 @@ describe("compact handoff route admission namespacing", () => { // The owner stores the deepseek route under (its principal, this lane). const stored = await compact("deepseek/deepseek-v4-flash", owner); - expect(stored.status).toBe(200); - expect(calls).toEqual([{ model: "deepseek-v4-flash", nativeCompact: false }]); + try { + expect(stored.status).toBe(200); + expect(calls).toEqual([{ model: "deepseek-v4-flash", nativeCompact: false }]); + } finally { + await stored.body?.cancel(); + } // A different admitted principal re-sending the same lane header must not // claim it: every attempt stays on the requested model's native compact. @@ -171,16 +182,24 @@ describe("compact handoff route admission namespacing", () => { ] as const) { calls.length = 0; const res = await compact("openai-apikey/gpt-5.6-sol", intruder); - expect(res.status).toBe(502); - expect(calls.length).toBeGreaterThan(0); - expect(calls.every(call => call.model === "gpt-5.6-sol" && call.nativeCompact)).toBe(true); + try { + expect(res.status).toBe(502); + expect(calls.length).toBeGreaterThan(0); + expect(calls.every(call => call.model === "gpt-5.6-sol" && call.nativeCompact)).toBe(true); + } finally { + await res.body?.cancel(); + } } // The owner's own quota-blocked retry still finds the route and hands off. calls.length = 0; const handoff = await compact("openai-apikey/gpt-5.6-sol", owner); - expect(handoff.status).toBe(200); - expect(calls.at(-1)).toEqual({ model: "deepseek-v4-flash", nativeCompact: false }); + try { + expect(handoff.status).toBe(200); + expect(calls.at(-1)).toEqual({ model: "deepseek-v4-flash", nativeCompact: false }); + } finally { + await handoff.body?.cancel(); + } }); // Five request sequences ride the transient-502 retry ladder; the default // 5s budget is not enough on a contended host. diff --git a/tests/responses/responses-compaction-routing.test.ts b/tests/responses/responses-compaction-routing.test.ts index 3250e696c6a..45e174abedd 100644 --- a/tests/responses/responses-compaction-routing.test.ts +++ b/tests/responses/responses-compaction-routing.test.ts @@ -7,7 +7,7 @@ import { sessionLaneIdFromRequest } from "../../src/server/request-log-conversat * contract; every other gateway has to be driven as a plain summarizer, or Codex * fatals on a compaction turn that came back as an ordinary message. */ -import { afterEach, describe, expect, jest, spyOn, test } from "bun:test"; +import { afterEach, beforeEach, describe, expect, jest, spyOn, test } from "bun:test"; import { mkdtempSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; @@ -42,111 +42,24 @@ import type { OcxConfig, OcxProviderConfig } from "../../src/types"; import { clearComboRecallForTests, recallComboForLane, rememberComboForLane } from "../../src/server/responses/combo-session-recall"; import { captureConfigGeneration } from "../../src/lib/state-store-sweeper"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { baseCompactionBody, compactionRequest, completedPayload, jsonResponse, keyProviderConfig, nativePoolConfig, sseResponse, twoAccountPoolConfig } from "../helpers/compaction-routing-fixtures"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; const originalFetch = globalThis.fetch; +// A case that calls a handler directly never runs startServer, so it never takes the +// spend-journal writer lease and its dispatch is refused before it reaches its own contract. +// Taken per dispatching block rather than for the whole file: five cases install a home of their +// own inside the case body, and a lease binds the directory in effect when it was taken. +let releaseSpendHome: (() => void) | undefined; +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; +const dropSpendHome = (): void => { releaseSpendHome?.(); releaseSpendHome = undefined; }; + afterEach(() => { + dropSpendHome(); globalThis.fetch = originalFetch; }); -function keyProviderConfig(overrides: Partial = {}): OcxConfig { - return { - defaultProvider: "gw", - providers: { - gw: { - adapter: "openai-responses", - baseUrl: "https://gateway.example/v1", - authMode: "key", - apiKey: "test-key", - ...overrides, - }, - }, - } as unknown as OcxConfig; -} - -function nativePoolConfig(): OcxConfig { - return { - defaultProvider: "openai", - activeCodexAccountId: "pool-a", - providers: { - openai: { - adapter: "openai-responses", - baseUrl: "https://chatgpt.com/backend-api/codex", - authMode: "forward", - codexAccountMode: "pool", - }, - }, - codexAccounts: [{ - id: "pool-a", - email: "pool@example.test", - isMain: false, - chatgptAccountId: "pool_acc", - }], - } as OcxConfig; -} - -/** Two-account pool: the alternate-attempt tests need somewhere for the retry to go. */ -function twoAccountPoolConfig(): OcxConfig { - const config = nativePoolConfig(); - config.codexAccounts = [ - { id: "pool-a", email: "a@example.test", isMain: false, chatgptAccountId: "pool_acc_a" }, - { id: "pool-b", email: "b@example.test", isMain: false, chatgptAccountId: "pool_acc_b" }, - ] as OcxConfig["codexAccounts"]; - return config; -} - -function compactionRequest( - body: Record, - signal?: AbortSignal, - extraHeaders: Record = {}, -): Request { - return new Request("http://localhost/v1/responses", { - method: "POST", - headers: { "content-type": "application/json", ...extraHeaders }, - body: JSON.stringify(body), - signal, - }); -} - -function baseCompactionBody(extra: Record = {}): Record { - return { - model: "gw/some-model", - stream: false, - input: [ - { type: "message", role: "user", content: [{ type: "input_text", text: "earlier turn" }] }, - { type: "compaction_trigger" }, - ], - tools: [{ type: "function", name: "shell" }], - tool_choice: "auto", - parallel_tool_calls: true, - ...extra, - }; -} - -function jsonResponse(payload: unknown): Response { - return new Response(JSON.stringify(payload), { - status: 200, - headers: { "content-type": "application/json" }, - }); -} - -function completedPayload(text: string): Record { - return { - id: "resp_1", - status: "completed", - output: [{ type: "message", role: "assistant", content: [{ type: "output_text", text }] }], - usage: { input_tokens: 10, output_tokens: 5, total_tokens: 15 }, - }; -} - -function sseResponse(events: Array>): Response { - const body = events.map(e => `event: ${String(e.type)}\ndata: ${JSON.stringify(e)}\n\n`).join(""); - return new Response(body, { - status: 200, - headers: { "content-type": "text/event-stream" }, - }); -} - describe("supportsNativeResponsesCompactEndpoint (#422)", () => { const canonicalForward = { adapter: "openai-responses", @@ -183,6 +96,7 @@ describe("supportsNativeResponsesCompactEndpoint (#422)", () => { }); describe("Codex auth-context error parity (#2392)", () => { + beforeEach(takeSpendHome); const cases: Array<{ label: string; createError: () => Error; @@ -344,6 +258,7 @@ describe("Codex auth-context error parity (#2392)", () => { }); describe("native compact usage reporting", () => { + beforeEach(takeSpendHome); test("the buffered upstream body fills the request log usage and stays intact for the client", async () => { const config = { defaultProvider: "openai-apikey", @@ -374,6 +289,9 @@ describe("native compact usage reporting", () => { const previousOpencodexHome = process.env.OPENCODEX_HOME; const previousCodexHome = process.env.CODEX_HOME; process.env.OPENCODEX_HOME = testDir; + // This case serves from its own directory, so the block lease cannot cover it. + dropSpendHome(); + takeSpendHome(); process.env.CODEX_HOME = testDir; try { const mainConfig = nativePoolConfig(); @@ -402,6 +320,8 @@ describe("native compact usage reporting", () => { } finally { globalThis.fetch = originalFetch; clearAccountQuota(); + // Released before the directory holding it is removed. + dropSpendHome(); removeTreeWithRetry(testDir); if (previousOpencodexHome === undefined) delete process.env.OPENCODEX_HOME; else process.env.OPENCODEX_HOME = previousOpencodexHome; @@ -412,6 +332,7 @@ describe("native compact usage reporting", () => { }); describe("native Codex pool compaction", () => { + beforeEach(takeSpendHome); test("ignores a retired Spark reset without cooling later compact requests", async () => { const testDir = mkdtempSync(join(tmpdir(), "ocx-compact-scope-")); const previousOpencodexHome = process.env.OPENCODEX_HOME; @@ -421,6 +342,9 @@ describe("native Codex pool compaction", () => { let sparkPhase = true; try { process.env.OPENCODEX_HOME = testDir; + // This case serves from its own directory, so the block lease cannot cover it. + dropSpendHome(); + takeSpendHome(); process.env.CODEX_HOME = testDir; clearCodexUpstreamHealth(); saveCodexAccountCredential("pool-a", { @@ -471,6 +395,8 @@ describe("native Codex pool compaction", () => { } finally { globalThis.fetch = originalFetch; clearCodexUpstreamHealth(); + // Released before the directory holding it is removed. + dropSpendHome(); removeTreeWithRetry(testDir); if (previousOpencodexHome === undefined) delete process.env.OPENCODEX_HOME; else process.env.OPENCODEX_HOME = previousOpencodexHome; @@ -494,6 +420,9 @@ describe("native Codex pool compaction", () => { const bodyReleased = new Promise(resolve => { releaseBody = resolve; }); try { process.env.OPENCODEX_HOME = testDir; + // This case serves from its own directory, so the block lease cannot cover it. + dropSpendHome(); + takeSpendHome(); process.env.CODEX_HOME = testDir; Date.now = () => now; clearCodexUpstreamHealth(); @@ -541,6 +470,8 @@ describe("native Codex pool compaction", () => { Date.now = originalNow; globalThis.fetch = originalFetch; clearCodexUpstreamHealth(); + // Released before the directory holding it is removed. + dropSpendHome(); removeTreeWithRetry(testDir); if (previousOpencodexHome === undefined) delete process.env.OPENCODEX_HOME; else process.env.OPENCODEX_HOME = previousOpencodexHome; @@ -562,6 +493,9 @@ describe("native Codex pool compaction", () => { const fetchStarted = new Promise(resolve => { markFetchStarted = resolve; }); try { process.env.OPENCODEX_HOME = testDir; + // This case serves from its own directory, so the block lease cannot cover it. + dropSpendHome(); + takeSpendHome(); process.env.CODEX_HOME = testDir; Date.now = () => now; clearCodexUpstreamHealth(); @@ -606,6 +540,8 @@ describe("native Codex pool compaction", () => { Date.now = originalNow; globalThis.fetch = originalFetch; clearCodexUpstreamHealth(); + // Released before the directory holding it is removed. + dropSpendHome(); removeTreeWithRetry(testDir); if (previousOpencodexHome === undefined) delete process.env.OPENCODEX_HOME; else process.env.OPENCODEX_HOME = previousOpencodexHome; @@ -616,6 +552,7 @@ describe("native Codex pool compaction", () => { }); describe("routed compaction for key-mode openai-responses (#422)", () => { + beforeEach(takeSpendHome); test("rewrites the wire: no trigger, no tools, summarizer prompt present", async () => { const bodies: Array> = []; globalThis.fetch = (async (_url: unknown, init?: RequestInit) => { @@ -736,6 +673,7 @@ describe("routed compaction for key-mode openai-responses (#422)", () => { }); describe("bare native compaction model without canonical openai (#2901)", () => { + beforeEach(takeSpendHome); /** A GitHub-Copilot-style operator: one third-party provider, no `openai` row at all. */ function copilotOnlyConfig(): OcxConfig { return { @@ -842,6 +780,7 @@ describe("bare native compaction model without canonical openai (#2901)", () => }); describe("compaction terminal handling (#422)", () => { + beforeEach(takeSpendHome); test("an upstream failure does not become an empty compaction", async () => { globalThis.fetch = (async () => jsonResponse({ id: "resp_1", @@ -924,11 +863,15 @@ describe("compaction terminal handling (#422)", () => { * fired, three means it recursed. */ describe("compact alternate-account attempt (#913)", () => { + beforeEach(takeSpendHome); function withPoolEnv(name: string, run: (config: OcxConfig) => Promise): Promise { const testDir = mkdtempSync(join(tmpdir(), name)); const previousOpencodexHome = process.env.OPENCODEX_HOME; const previousCodexHome = process.env.CODEX_HOME; process.env.OPENCODEX_HOME = testDir; + // This case serves from its own directory, so the block lease cannot cover it. + dropSpendHome(); + takeSpendHome(); process.env.CODEX_HOME = testDir; clearCodexUpstreamHealth(); clearUpstreamHostHealth(); @@ -947,6 +890,8 @@ describe("compact alternate-account attempt (#913)", () => { clearCodexUpstreamHealth(); clearUpstreamHostHealth(); clearAccountQuota(); + // Released before the directory holding it is removed. + dropSpendHome(); removeTreeWithRetry(testDir); if (previousOpencodexHome === undefined) delete process.env.OPENCODEX_HOME; else process.env.OPENCODEX_HOME = previousOpencodexHome; @@ -1821,6 +1766,7 @@ describe("compact alternate-account attempt (#913)", () => { }); describe("compaction combo recall after combo switch (#3891)", () => { + beforeEach(takeSpendHome); afterEach(() => clearComboRecallForTests()); function comboTestConfig(): OcxConfig { @@ -2270,6 +2216,7 @@ test("a no-eligible policy compact request persists the evaluation trace", async * already degrade an unpaired output to "[tool output for unknown call]" on their own. */ describe("computer screenshot output translation boundary", () => { + beforeEach(takeSpendHome); const screenshot = { type: "computer_call_output", call_id: "call_screen", output: { type: "computer_screenshot", image_url: "https://example.com/screen.png" }, @@ -2368,6 +2315,7 @@ describe("computer screenshot output translation boundary", () => { }); describe("external task-input envelopes (#3735)", () => { + beforeEach(takeSpendHome); // Synthetic charset/length fixture: short plaintext in this slot is deliberately // normalized to input_text before parsing, so it cannot exercise opaque rejection. const opaqueOutput = `g${"A".repeat(127)}`; @@ -2479,6 +2427,7 @@ describe("external task-input envelopes (#3735)", () => { }); describe("established-history external task input (#3807)", () => { + beforeEach(takeSpendHome); // Synthetic complete envelope from the #3735 contract; #3807's history rendering // is not a captured outbound request. Keep the real tool pair distinct from delivery. const deliveryText = " Follow up on the earlier tool result.\n"; @@ -2613,6 +2562,7 @@ describe("established-history external task input (#3807)", () => { }); describe("unpaired tool result boundary (#3259)", () => { + beforeEach(takeSpendHome); function unpairedBody(item: Record): Record { return { model: "gw/some-model", @@ -2730,6 +2680,7 @@ describe("unpaired tool result boundary (#3259)", () => { }); describe("unusable-call_id task-input seed (#3807)", () => { + beforeEach(takeSpendHome); const seed = (extra: Record) => ({ type: "function_call_output", id: "fc_seed", name: "create_thread", namespace: "codex", output: "continue", ...extra, diff --git a/tests/responses/responses-console-go-upload-retry.test.ts b/tests/responses/responses-console-go-upload-retry.test.ts index 68fc1972ebc..75805f3c64e 100644 --- a/tests/responses/responses-console-go-upload-retry.test.ts +++ b/tests/responses/responses-console-go-upload-retry.test.ts @@ -6,6 +6,7 @@ import { markResponseNonReplayable } from "../../src/lib/upstream-retry"; import { handleResponses } from "../../src/server/responses/core"; import type { RequestLogContext } from "../../src/server/request-log"; import type { OcxConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; const originalFetch = globalThis.fetch; @@ -32,13 +33,19 @@ const EFFORT_REFUSAL = JSON.stringify({ }); let testDir = ""; +let releaseSpendHome: (() => void) | undefined; beforeEach(() => { testDir = mkdtempSync(join(tmpdir(), "ocx-console-go-upload-retry-")); process.env.OPENCODEX_HOME = testDir; + // Take the writer lease after this case installs its home so direct handler dispatch can open the spend journal. + releaseSpendHome = acquireOwnedSpendHome(); }); afterEach(() => { + // Release before restoring or removing the home to prevent Windows removal failures and POSIX unlinked databases. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; if (originalOpenCodexHome === undefined) delete process.env.OPENCODEX_HOME; else process.env.OPENCODEX_HOME = originalOpenCodexHome; diff --git a/tests/responses/responses-custom-tool-repair-dispatch.test.ts b/tests/responses/responses-custom-tool-repair-dispatch.test.ts new file mode 100644 index 00000000000..fd8d34349f4 --- /dev/null +++ b/tests/responses/responses-custom-tool-repair-dispatch.test.ts @@ -0,0 +1,979 @@ +/** + * The routed custom-tool repair contract as handleResponses actually serves it. + * + * Split out of responses-custom-tool-repair.test.ts, which keeps the cases that exercise the + * compat functions directly. These are the cases that dispatch, and a dispatching case needs the + * spend-journal writer lease that startServer would have taken; the file it came from is at its + * file-size cap and had no room to take it. + */ +import { afterEach, describe, expect, test } from "bun:test"; +import { handleResponses } from "../../src/server/responses"; +import type { OcxConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; +import { CANONICAL_PATCH, DECORATED_PATCH, dataPayload, frame } from "../helpers/custom-tool-repair-fixtures"; + +// Taken at each dispatch rather than per case, and dropped in teardown so a case that throws +// mid-assertion cannot leave the lease behind for the next one to trip over. +let releaseSpendHome: (() => void) | undefined; +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; +afterEach(() => { releaseSpendHome?.(); releaseSpendHome = undefined; }); + +describe("routed Responses custom-tool repair through handleResponses", () => { + test("handleResponses sends an upstream-safe exec function and restores client SSE", async () => { + const savedFetch = globalThis.fetch; + let outboundBody: Record | undefined; + const upstreamItem = { + type: "function_call", + id: "fc_exec", + call_id: "call_exec", + name: "exec", + arguments: "{\"input\":\"const apps = await sky.list_apps();\"}", + status: "completed", + }; + const upstream = [ + frame("response.output_item.added", { output_index: 0, item: { ...upstreamItem, arguments: "", status: "in_progress" } }), + frame("response.function_call_arguments.done", { output_index: 0, item_id: "fc_exec", arguments: upstreamItem.arguments }), + frame("response.output_item.done", { output_index: 0, item: upstreamItem }), + frame("response.completed", { response: { id: "resp_1", status: "completed", output: [upstreamItem] } }), + "data: [DONE]", + ].join("\n\n") + "\n\n"; + globalThis.fetch = (async (_input, init) => { + outboundBody = JSON.parse(String(init?.body)) as Record; + return new Response(upstream, { headers: { "content-type": "text/event-stream" } }); + }) as typeof fetch; + const config = { + port: 0, + defaultProvider: "fixture", + providers: { + fixture: { + adapter: "openai-responses", + baseUrl: "https://fixture.test/v1", + authMode: "key", + apiKey: "fixture-key", + }, + }, + } as OcxConfig; + + try { + takeSpendHome(); + const response = await handleResponses(new Request("http://localhost/v1/responses", { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + model: "fixture/deepseek-v4-flash", + stream: true, + input: [{ role: "user", content: [{ type: "input_text", text: "list apps" }] }], + tools: [{ type: "custom", name: "exec", description: "Run JavaScript", format: { type: "grammar", syntax: "lark" } }], + }), + }), config, { model: "", provider: "" }); + const clientSse = await response.text(); + const outboundTools = outboundBody?.tools as Array> | undefined; + + expect(outboundTools?.[0]).toMatchObject({ type: "function", name: "exec" }); + expect(clientSse).toContain('"type":"custom_tool_call"'); + expect(clientSse).toContain('"type":"response.custom_tool_call_input.done"'); + expect(clientSse).toContain('"input":"const apps = await sky.list_apps();"'); + expect(clientSse).not.toContain("response.function_call_arguments.done"); + expect(clientSse).not.toContain('"type":"function_call"'); + expect(clientSse).toContain("data: [DONE]"); + } finally { + globalThis.fetch = savedFetch; + } + }); + + test("handleResponses lowers and restores apply_patch when the destination denies custom tools", async () => { + const savedFetch = globalThis.fetch; + let outboundBody: Record | undefined; + const upstreamItem = { + type: "function_call", + id: "fc_patch_next", + call_id: "call_patch_next", + name: "apply_patch", + arguments: JSON.stringify({ input: "*** Begin Patch\n*** End Patch" }), + status: "completed", + }; + const upstream = [ + frame("response.output_item.added", { + output_index: 0, + item: { ...upstreamItem, arguments: "", status: "in_progress" }, + }), + frame("response.function_call_arguments.done", { + output_index: 0, + item_id: upstreamItem.id, + arguments: upstreamItem.arguments, + }), + frame("response.output_item.done", { output_index: 0, item: upstreamItem }), + frame("response.completed", { + response: { id: "resp_patch", status: "completed", output: [upstreamItem] }, + }), + "data: [DONE]", + ].join("\n\n") + "\n\n"; + globalThis.fetch = (async (_input, init) => { + outboundBody = JSON.parse(String(init?.body)) as Record; + return new Response(upstream, { headers: { "content-type": "text/event-stream" } }); + }) as typeof fetch; + const config = { + port: 0, + defaultProvider: "fixture", + providers: { + fixture: { + adapter: "openai-responses", + baseUrl: "https://fixture.test/v1", + authMode: "key", + apiKey: "fixture-key", + supportsResponsesCustomTools: false, + }, + }, + } as OcxConfig; + + try { + takeSpendHome(); + const response = await handleResponses(new Request("http://localhost/v1/responses", { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + model: "fixture/grok-4.6", + stream: true, + input: [ + { + type: "custom_tool_call", + id: "ctc_patch_prior", + call_id: "call_patch_prior", + name: "apply_patch", + input: "noop", + }, + { type: "custom_tool_call_output", call_id: "call_patch_prior", output: "done" }, + ], + tools: [{ + type: "custom", + name: "apply_patch", + description: "Apply a patch", + format: { type: "grammar", syntax: "lark" }, + }], + }), + }), config, { model: "", provider: "" }); + const clientSse = await response.text(); + const outboundTools = outboundBody?.tools as Array> | undefined; + const outboundInput = outboundBody?.input as Array> | undefined; + + expect(outboundTools?.[0]).toMatchObject({ type: "function", name: "apply_patch" }); + expect(outboundInput?.[0]).toMatchObject({ + type: "function_call", + call_id: "call_patch_prior", + name: "apply_patch", + arguments: JSON.stringify({ input: "noop" }), + }); + expect(outboundInput?.[1]).toMatchObject({ + type: "function_call_output", + call_id: "call_patch_prior", + output: "done", + }); + expect(clientSse).toContain('"type":"custom_tool_call"'); + expect(clientSse).toContain('"id":"ctc_patch_next"'); + expect(clientSse).toContain('"call_id":"call_patch_next"'); + expect(clientSse).toContain('"name":"apply_patch"'); + expect(clientSse).toContain('"type":"response.custom_tool_call_input.done"'); + expect(clientSse).toContain("data: [DONE]"); + expect(clientSse).not.toContain('"type":"function_call"'); + expect(clientSse).not.toContain("response.function_call_arguments.done"); + } finally { + globalThis.fetch = savedFetch; + } + }); + + test("handleResponses lowers apply_patch for a noncanonical forward destination that denies custom tools", async () => { + const savedFetch = globalThis.fetch; + let outboundBody: Record | undefined; + let outboundAuthorization: string | null = null; + let outboundUrl = ""; + const upstreamItem = { + type: "function_call", + id: "fc_patch_next", + call_id: "call_patch_next", + name: "apply_patch", + arguments: JSON.stringify({ input: "*** Begin Patch\n*** End Patch" }), + status: "completed", + }; + const upstream = [ + frame("response.output_item.added", { + output_index: 0, + item: { ...upstreamItem, arguments: "", status: "in_progress" }, + }), + frame("response.function_call_arguments.done", { + output_index: 0, + item_id: upstreamItem.id, + arguments: upstreamItem.arguments, + }), + frame("response.output_item.done", { output_index: 0, item: upstreamItem }), + frame("response.completed", { + response: { id: "resp_patch", status: "completed", output: [upstreamItem] }, + }), + "data: [DONE]", + ].join("\n\n") + "\n\n"; + globalThis.fetch = (async (input, init) => { + outboundUrl = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url; + outboundBody = JSON.parse(String(init?.body)) as Record; + outboundAuthorization = new Headers(init?.headers).get("authorization"); + return new Response(upstream, { headers: { "content-type": "text/event-stream" } }); + }) as typeof fetch; + const config = { + port: 0, + defaultProvider: "fixture", + providers: { + fixture: { + adapter: "openai-responses", + baseUrl: "https://provider.example/v1", + authMode: "forward", + headers: { authorization: "Bearer provider-static" }, + supportsResponsesCustomTools: false, + }, + }, + } as OcxConfig; + + try { + takeSpendHome(); + const response = await handleResponses(new Request("http://localhost/v1/responses", { + method: "POST", + headers: { "content-type": "application/json", authorization: "Bearer caller-secret" }, + body: JSON.stringify({ + model: "fixture/grok-4.6", + stream: true, + input: [ + { + type: "custom_tool_call", + id: "ctc_patch_prior", + call_id: "call_patch_prior", + name: "apply_patch", + input: "noop", + }, + { type: "custom_tool_call_output", call_id: "call_patch_prior", output: "done" }, + ], + tools: [{ + type: "custom", + name: "apply_patch", + description: "Apply a patch", + format: { type: "grammar", syntax: "lark" }, + }], + }), + }), config, { model: "", provider: "" }); + const clientSse = await response.text(); + const outboundTools = outboundBody?.tools as Array> | undefined; + const outboundInput = outboundBody?.input as Array> | undefined; + + expect(outboundUrl).toBe("https://provider.example/v1/responses"); + expect(outboundAuthorization).toBe("Bearer provider-static"); + expect(outboundTools?.[0]).toMatchObject({ type: "function", name: "apply_patch" }); + expect(outboundInput?.[0]).toMatchObject({ + type: "function_call", + call_id: "call_patch_prior", + name: "apply_patch", + arguments: JSON.stringify({ input: "noop" }), + }); + expect(outboundInput?.[1]).toMatchObject({ + type: "function_call_output", + call_id: "call_patch_prior", + output: "done", + }); + expect(clientSse).toContain('"type":"custom_tool_call"'); + expect(clientSse).toContain('"id":"ctc_patch_next"'); + expect(clientSse).toContain('"call_id":"call_patch_next"'); + expect(clientSse).toContain('"name":"apply_patch"'); + expect(clientSse).toContain('"type":"response.custom_tool_call_input.done"'); + expect(clientSse).toContain("data: [DONE]"); + expect(clientSse).not.toContain('"type":"function_call"'); + expect(clientSse).not.toContain("response.function_call_arguments.done"); + } finally { + globalThis.fetch = savedFetch; + } + }); + + test("handleResponses continuation rewrites custom_tool_call_output and keeps call_id ordered", async () => { + const savedFetch = globalThis.fetch; + const outboundBodies: Array> = []; + const firstUpstreamItem = { + type: "function_call", + id: "fc_exec", + call_id: "call_exec", + name: "exec", + arguments: "{\"input\":\"const apps = await sky.list_apps();\"}", + status: "completed", + }; + const secondUpstreamMessage = { + type: "message", + id: "msg_2", + role: "assistant", + content: [{ type: "output_text", text: "27 apps" }], + status: "completed", + }; + let turn = 0; + globalThis.fetch = (async (_input, init) => { + outboundBodies.push(JSON.parse(String(init?.body)) as Record); + turn += 1; + if (turn === 1) { + const upstream = [ + frame("response.output_item.added", { output_index: 0, item: { ...firstUpstreamItem, arguments: "", status: "in_progress" } }), + frame("response.function_call_arguments.done", { output_index: 0, item_id: "fc_exec", arguments: firstUpstreamItem.arguments }), + frame("response.output_item.done", { output_index: 0, item: firstUpstreamItem }), + frame("response.completed", { response: { id: "resp_1", status: "completed", output: [firstUpstreamItem] } }), + "data: [DONE]", + ].join("\n\n") + "\n\n"; + return new Response(upstream, { headers: { "content-type": "text/event-stream" } }); + } + const upstream = [ + frame("response.output_item.added", { output_index: 0, item: { ...secondUpstreamMessage, content: [], status: "in_progress" } }), + frame("response.output_item.done", { output_index: 0, item: secondUpstreamMessage }), + frame("response.completed", { response: { id: "resp_2", status: "completed", output: [secondUpstreamMessage] } }), + "data: [DONE]", + ].join("\n\n") + "\n\n"; + return new Response(upstream, { headers: { "content-type": "text/event-stream" } }); + }) as typeof fetch; + const config = { + port: 0, + defaultProvider: "fixture", + providers: { + fixture: { + adapter: "openai-responses", + baseUrl: "https://fixture.test/v1", + authMode: "key", + apiKey: "fixture-key", + }, + }, + } as OcxConfig; + const tools = [{ type: "custom", name: "exec", description: "Run JavaScript", format: { type: "grammar", syntax: "lark" } }]; + + try { + takeSpendHome(); + const first = await handleResponses(new Request("http://localhost/v1/responses", { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + model: "fixture/deepseek-v4-flash", + stream: true, + input: [{ role: "user", content: [{ type: "input_text", text: "list apps" }] }], + tools, + }), + }), config, { model: "", provider: "" }); + const firstSse = await first.text(); + expect(firstSse).toContain('"type":"custom_tool_call"'); + expect(firstSse).toContain('"call_id":"call_exec"'); + expect(firstSse).not.toContain('"type":"function_call"'); + + takeSpendHome(); + const second = await handleResponses(new Request("http://localhost/v1/responses", { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + model: "fixture/deepseek-v4-flash", + stream: true, + input: [ + { role: "user", content: [{ type: "input_text", text: "list apps" }] }, + { + type: "custom_tool_call", + id: "ctc_exec", + call_id: "call_exec", + name: "exec", + input: "const apps = await sky.list_apps();", + }, + { type: "custom_tool_call_output", call_id: "call_exec", output: "27 apps" }, + { type: "custom_tool_call_output", call_id: "call_other", output: "wrong pairing must stay distinct" }, + ], + tools, + }), + }), config, { model: "", provider: "" }); + const secondSse = await second.text(); + const continuationInput = outboundBodies[1]?.input as Array>; + expect(outboundBodies).toHaveLength(2); + expect(continuationInput).toEqual(expect.arrayContaining([ + expect.objectContaining({ + type: "function_call", + call_id: "call_exec", + name: "exec", + arguments: JSON.stringify({ input: "const apps = await sky.list_apps();" }), + }), + expect.objectContaining({ + type: "function_call_output", + call_id: "call_exec", + output: "27 apps", + }), + ])); + const execOutput = continuationInput.find(item => item.type === "function_call_output" && item.call_id === "call_exec"); + const otherOutput = continuationInput.find(item => item.call_id === "call_other"); + expect(execOutput).toMatchObject({ type: "function_call_output", output: "27 apps" }); + expect(otherOutput).toMatchObject({ type: "custom_tool_call_output", call_id: "call_other" }); + expect(continuationInput.filter(item => item.type === "function_call_output")).toHaveLength(1); + expect(secondSse).toContain('"text":"27 apps"'); + expect(secondSse).toContain('"id":"resp_2"'); + expect(secondSse).not.toContain('"type":"function_call"'); + expect(secondSse.indexOf("resp_2")).toBeLessThan(secondSse.indexOf("data: [DONE]")); + } finally { + globalThis.fetch = savedFetch; + } + }); + + test("handleResponses restores routed custom calls in non-streaming JSON", async () => { + const savedFetch = globalThis.fetch; + const upstreamItem = { + type: "function_call", + id: "fc_exec", + call_id: "call_exec", + name: "exec", + arguments: "{\"input\":\"const apps = await sky.list_apps();\"}", + status: "completed", + }; + globalThis.fetch = (async () => new Response(JSON.stringify({ + id: "resp_json", + status: "completed", + output: [upstreamItem], + }), { headers: { "content-type": "application/json" } })) as typeof fetch; + const config = { + port: 0, + defaultProvider: "fixture", + providers: { + fixture: { + adapter: "openai-responses", + baseUrl: "https://fixture.test/v1", + authMode: "key", + apiKey: "fixture-key", + }, + }, + } as OcxConfig; + + try { + takeSpendHome(); + const response = await handleResponses(new Request("http://localhost/v1/responses", { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + model: "fixture/deepseek-v4-flash", + stream: false, + input: [{ role: "user", content: [{ type: "input_text", text: "list apps" }] }], + tools: [{ type: "custom", name: "exec", description: "Run JavaScript", format: { type: "grammar", syntax: "lark" } }], + }), + }), config, { model: "", provider: "" }); + const body = await response.json() as { output: Array> }; + + expect(body.output[0]).toMatchObject({ + type: "custom_tool_call", + id: "ctc_exec", + name: "exec", + input: "const apps = await sky.list_apps();", + }); + expect(body.output[0]).not.toHaveProperty("arguments"); + } finally { + globalThis.fetch = savedFetch; + } + }); + + test("handleResponses does not restore routed custom calls excluded by request policy", async () => { + const savedFetch = globalThis.fetch; + const upstreamItem = { + type: "function_call", + id: "fc_exec", + call_id: "call_exec", + name: "exec", + arguments: "{\"input\":\"ignored policy\"}", + status: "completed", + }; + const config = { + port: 0, + defaultProvider: "fixture", + providers: { + fixture: { + adapter: "openai-responses", + baseUrl: "https://fixture.test/v1", + authMode: "key", + apiKey: "fixture-key", + }, + }, + } as OcxConfig; + const execTool = { + type: "custom", + name: "exec", + description: "Run JavaScript", + format: { type: "grammar", syntax: "lark" }, + }; + const ordinaryTool = { + type: "function", + name: "ordinary", + description: "Ordinary function", + parameters: { type: "object" }, + }; + const cases: Array<{ + name: string; + stream: boolean; + tools: Array>; + toolChoice?: unknown; + metadata?: unknown; + /** The upstream call names a tool this request never declared at all (#1700). */ + undeclared?: boolean; + }> = [ + { + name: "streaming none", + stream: true, + tools: [execTool], + toolChoice: "none", + }, + { + name: "streaming allowlist", + stream: true, + tools: [execTool, ordinaryTool], + toolChoice: { + type: "allowed_tools", + mode: "required", + tools: [{ type: "function", name: "ordinary" }], + }, + }, + { + name: "named ordinary function", + stream: false, + tools: [execTool, ordinaryTool], + toolChoice: { type: "function", name: "ordinary" }, + }, + { + name: "custom-looking metadata without a declared tool", + stream: false, + tools: [ordinaryTool], + metadata: { nested: { type: "custom", name: "exec" } }, + undeclared: true, + }, + ]; + + globalThis.fetch = (async (_input, init) => { + const outboundBody = JSON.parse(String(init?.body)) as { stream?: boolean }; + if (outboundBody.stream === true) { + const upstream = [ + frame("response.output_item.added", { + output_index: 0, + item: { ...upstreamItem, arguments: "", status: "in_progress" }, + }), + frame("response.function_call_arguments.done", { + output_index: 0, + item_id: "fc_exec", + arguments: upstreamItem.arguments, + }), + frame("response.output_item.done", { output_index: 0, item: upstreamItem }), + frame("response.completed", { + response: { id: "resp_policy", status: "completed", output: [upstreamItem] }, + }), + "data: [DONE]", + ].join("\n\n") + "\n\n"; + return new Response(upstream, { headers: { "content-type": "text/event-stream" } }); + } + return new Response(JSON.stringify({ + id: "resp_policy", + status: "completed", + output: [upstreamItem], + }), { headers: { "content-type": "application/json" } }); + }) as typeof fetch; + + try { + for (const policyCase of cases) { + takeSpendHome(); + const response = await handleResponses(new Request("http://localhost/v1/responses", { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + model: "fixture/deepseek-v4-flash", + stream: policyCase.stream, + input: [{ role: "user", content: [{ type: "input_text", text: policyCase.name }] }], + tools: policyCase.tools, + ...(policyCase.toolChoice !== undefined ? { tool_choice: policyCase.toolChoice } : {}), + ...(policyCase.metadata !== undefined ? { metadata: policyCase.metadata } : {}), + }), + }), config, { model: "", provider: "" }); + + if (policyCase.stream) { + const clientSse = await response.text(); + expect(clientSse).toContain('"type":"function_call"'); + expect(clientSse).toContain('"id":"fc_exec"'); + expect(clientSse).toContain("response.function_call_arguments.done"); + expect(clientSse).not.toContain("custom_tool_call"); + expect(clientSse).not.toContain("ctc_exec"); + } else if (policyCase.undeclared) { + // #1700: this request's catalog holds only `ordinary` — a metadata blob that merely + // looks like a tool declaration declares nothing — so a call to `exec` is refused + // instead of relayed. The restore contract still holds either way: it never became + // a custom_tool_call. + expect(response.status).toBe(502); + const body = await response.json() as { error: { message: string } }; + expect(body.error.message).toContain('undeclared client tool "exec"'); + } else { + const body = await response.json() as { output: Array> }; + expect(body.output[0]).toEqual(upstreamItem); + } + } + } finally { + globalThis.fetch = savedFetch; + } + }); + + test("handleResponses preserves native apply_patch calls that were never converted", async () => { + const savedFetch = globalThis.fetch; + const upstreamItem = { + type: "function_call", + id: "fc_patch", + call_id: "call_patch", + name: "apply_patch", + arguments: "{\"patch\":\"*** Begin Patch\"}", + status: "completed", + }; + globalThis.fetch = (async () => new Response(JSON.stringify({ + id: "resp_patch", + status: "completed", + output: [upstreamItem], + }), { headers: { "content-type": "application/json" } })) as typeof fetch; + const config = { + port: 0, + defaultProvider: "fixture", + providers: { + fixture: { + adapter: "openai-responses", + baseUrl: "https://fixture.test/v1", + authMode: "key", + apiKey: "fixture-key", + }, + }, + } as OcxConfig; + + try { + takeSpendHome(); + const response = await handleResponses(new Request("http://localhost/v1/responses", { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + model: "fixture/deepseek-v4-flash", + stream: false, + input: [{ role: "user", content: [{ type: "input_text", text: "patch" }] }], + tools: [{ + type: "custom", + name: "apply_patch", + description: "Apply a patch", + format: { type: "grammar", syntax: "lark" }, + }], + }), + }), config, { model: "", provider: "" }); + const body = await response.json() as { output: Array> }; + + expect(body.output[0]).toEqual(upstreamItem); + } finally { + globalThis.fetch = savedFetch; + } + }); + + test("handleResponses preserves disallowed native apply_patch input in JSON and SSE", async () => { + const savedFetch = globalThis.fetch; + const config = { + port: 0, + defaultProvider: "fixture", + providers: { + fixture: { + adapter: "openai-responses", + baseUrl: "https://fixture.test/v1", + authMode: "key", + apiKey: "fixture-key", + }, + }, + } as OcxConfig; + const upstreamItem = { + type: "custom_tool_call", + id: "ctc_patch", + call_id: "call_patch", + name: "apply_patch", + input: DECORATED_PATCH, + status: "completed", + }; + + globalThis.fetch = (async (_input, init) => { + const outbound = JSON.parse(String(init?.body)) as { stream?: boolean }; + if (outbound.stream === true) { + const upstream = [ + frame("response.output_item.added", { + output_index: 0, + item: { ...upstreamItem, input: "", status: "in_progress" }, + }), + frame("response.custom_tool_call_input.done", { + output_index: 0, + item_id: "ctc_patch", + input: DECORATED_PATCH, + }), + frame("response.output_item.done", { output_index: 0, item: upstreamItem }), + frame("response.completed", { + response: { id: "resp_patch_stream", status: "completed", output: [upstreamItem] }, + }), + "data: [DONE]", + ].join("\n\n") + "\n\n"; + return new Response(upstream, { headers: { "content-type": "text/event-stream" } }); + } + return Response.json({ id: "resp_patch_json", status: "completed", output: [upstreamItem] }); + }) as typeof fetch; + + try { + for (const stream of [false, true]) { + takeSpendHome(); + const response = await handleResponses(new Request("http://localhost/v1/responses", { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + model: "fixture/deepseek-v4-flash", + stream, + input: [{ role: "user", content: [{ type: "input_text", text: "patch" }] }], + tools: [ + { + type: "custom", + name: "apply_patch", + description: "Apply a patch", + format: { type: "grammar", syntax: "lark" }, + }, + { + type: "function", + name: "ordinary", + description: "Ordinary function", + parameters: { type: "object" }, + }, + ], + tool_choice: stream + ? { + type: "allowed_tools", + mode: "required", + tools: [{ type: "function", name: "ordinary" }], + } + : { type: "function", name: "ordinary" }, + }), + }), config, { model: "", provider: "" }); + + if (!stream) { + const body = await response.json() as { output: Array> }; + expect(body.output[0]).toEqual(upstreamItem); + continue; + } + + const blocks = (await response.text()).split("\n\n").filter(block => block.includes("data: {")); + const payloads = blocks.map(dataPayload); + const inputDone = payloads.find(payload => payload.type === "response.custom_tool_call_input.done"); + expect(inputDone).toMatchObject({ input: DECORATED_PATCH }); + const itemDone = payloads.find(payload => payload.type === "response.output_item.done") as { + item?: Record; + } | undefined; + expect(itemDone?.item).toMatchObject({ type: "custom_tool_call", input: DECORATED_PATCH }); + const completed = payloads.find(payload => payload.type === "response.completed") as { + response?: { output?: Array> }; + } | undefined; + expect(completed?.response?.output?.[0]).toMatchObject({ input: DECORATED_PATCH }); + } + } finally { + globalThis.fetch = savedFetch; + } + }); + + test("handleResponses repairs authorized native apply_patch calls in JSON and SSE", async () => { + const savedFetch = globalThis.fetch; + const config = { + port: 0, + defaultProvider: "fixture", + providers: { + fixture: { + adapter: "openai-responses", + baseUrl: "https://fixture.test/v1", + authMode: "key", + apiKey: "fixture-key", + }, + }, + } as OcxConfig; + const upstreamItem = { + type: "custom_tool_call", + id: "ctc_patch", + call_id: "call_patch", + name: "apply_patch", + input: DECORATED_PATCH, + status: "completed", + }; + + globalThis.fetch = (async (_input, init) => { + const outbound = JSON.parse(String(init?.body)) as { stream?: boolean }; + if (outbound.stream === true) { + const upstream = [ + frame("response.output_item.added", { + output_index: 0, + item: { ...upstreamItem, input: "", status: "in_progress" }, + }), + frame("response.custom_tool_call_input.done", { + output_index: 0, + item_id: "ctc_patch", + input: DECORATED_PATCH, + }), + frame("response.output_item.done", { output_index: 0, item: upstreamItem }), + frame("response.completed", { + response: { id: "resp_patch_stream", status: "completed", output: [upstreamItem] }, + }), + "data: [DONE]", + ].join("\n\n") + "\n\n"; + return new Response(upstream, { headers: { "content-type": "text/event-stream" } }); + } + return Response.json({ id: "resp_patch_json", status: "completed", output: [upstreamItem] }); + }) as typeof fetch; + + try { + for (const stream of [false, true]) { + takeSpendHome(); + const response = await handleResponses(new Request("http://localhost/v1/responses", { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + model: "fixture/deepseek-v4-flash", + stream, + input: [{ role: "user", content: [{ type: "input_text", text: "patch" }] }], + tools: [{ + type: "custom", + name: "apply_patch", + description: "Apply a patch", + format: { type: "grammar", syntax: "lark" }, + }], + }), + }), config, { model: "", provider: "" }); + + if (!stream) { + const body = await response.json() as { output: Array> }; + expect(body.output[0]).toMatchObject({ + type: "custom_tool_call", + name: "apply_patch", + input: CANONICAL_PATCH, + }); + continue; + } + + const blocks = (await response.text()).split("\n\n").filter(block => block.includes("data: {")); + const payloads = blocks.map(dataPayload); + const inputDone = payloads.find(payload => payload.type === "response.custom_tool_call_input.done"); + expect(inputDone).toMatchObject({ input: CANONICAL_PATCH }); + const itemDone = payloads.find(payload => payload.type === "response.output_item.done") as { + item?: Record; + } | undefined; + expect(itemDone?.item).toMatchObject({ type: "custom_tool_call", input: CANONICAL_PATCH }); + const completed = payloads.find(payload => payload.type === "response.completed") as { + response?: { output?: Array> }; + } | undefined; + expect(completed?.response?.output?.[0]).toMatchObject({ input: CANONICAL_PATCH }); + } + } finally { + globalThis.fetch = savedFetch; + } + }); + + test("handleResponses does not restore a custom image tool replaced by hosted preference", async () => { + const savedFetch = globalThis.fetch; + let outboundBody: Record | undefined; + const upstreamItem = { + type: "function_call", + id: "fc_image", + call_id: "call_image", + name: "image_gen.generate", + arguments: "{}", + status: "completed", + }; + globalThis.fetch = (async (_input, init) => { + outboundBody = JSON.parse(String(init?.body)) as Record; + return new Response(JSON.stringify({ + id: "resp_image", + status: "completed", + output: [upstreamItem], + }), { headers: { "content-type": "application/json" } }); + }) as typeof fetch; + const config = { + port: 0, + defaultProvider: "fixture", + providers: { + fixture: { + adapter: "openai-responses", + baseUrl: "https://fixture.test/v1", + authMode: "key", + apiKey: "fixture-key", + modelPreferHostedTools: { "deepseek-v4-flash": ["image_generation"] }, + }, + }, + } as OcxConfig; + + try { + takeSpendHome(); + const response = await handleResponses(new Request("http://localhost/v1/responses", { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + model: "fixture/deepseek-v4-flash", + stream: false, + input: [{ role: "user", content: [{ type: "input_text", text: "draw" }] }], + tools: [{ + type: "custom", + name: "image_gen.generate", + description: "Generate an image", + format: { type: "grammar", syntax: "lark" }, + }], + }), + }), config, { model: "", provider: "" }); + const body = await response.json() as { output: Array> }; + const outboundTools = outboundBody?.tools as Array> | undefined; + + expect(outboundTools).toEqual([{ type: "image_generation" }]); + expect(body.output[0]).toEqual(upstreamItem); + } finally { + globalThis.fetch = savedFetch; + } + }); + + test("handleResponses leaves custom tools native for forward-auth passthrough", async () => { + const savedFetch = globalThis.fetch; + let outboundBody: Record | undefined; + let outboundAuthorization: string | null = null; + let outboundUrl = ""; + const upstreamItem = { + type: "function_call", + id: "fc_exec", + call_id: "call_exec", + name: "exec", + arguments: "{\"input\":\"native\"}", + status: "completed", + }; + globalThis.fetch = (async (input, init) => { + outboundUrl = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url; + outboundBody = JSON.parse(String(init?.body)) as Record; + outboundAuthorization = new Headers(init?.headers).get("authorization"); + return new Response(JSON.stringify({ id: "resp_forward", status: "completed", output: [upstreamItem] }), { + headers: { "content-type": "application/json" }, + }); + }) as typeof fetch; + const config = { + port: 0, + defaultProvider: "fixture", + providers: { + fixture: { + adapter: "openai-responses", + baseUrl: "https://chatgpt.com/backend-api/codex", + authMode: "forward", + }, + }, + } as OcxConfig; + + try { + takeSpendHome(); + const response = await handleResponses(new Request("http://localhost/v1/responses", { + method: "POST", + headers: { "content-type": "application/json", authorization: "Bearer caller-token" }, + body: JSON.stringify({ + model: "fixture/native-model", + stream: false, + input: "run", + tools: [{ type: "custom", name: "exec", description: "Run JavaScript", format: { type: "grammar", syntax: "lark" } }], + }), + }), config, { model: "", provider: "" }); + const clientBody = await response.json() as { output: Array> }; + const outboundTools = outboundBody?.tools as Array> | undefined; + + expect(outboundUrl).toBe("https://chatgpt.com/backend-api/codex/responses"); + expect(outboundAuthorization).toBe("Bearer caller-token"); + expect(outboundTools?.[0]).toMatchObject({ type: "custom", name: "exec" }); + expect(clientBody.output[0]).toMatchObject({ type: "function_call", name: "exec" }); + expect(clientBody.output[0]).not.toHaveProperty("input"); + } finally { + globalThis.fetch = savedFetch; + } + }); +}); diff --git a/tests/responses/responses-custom-tool-repair.test.ts b/tests/responses/responses-custom-tool-repair.test.ts index 98336d02416..3011f7c307c 100644 --- a/tests/responses/responses-custom-tool-repair.test.ts +++ b/tests/responses/responses-custom-tool-repair.test.ts @@ -6,23 +6,8 @@ import { } from "../../src/responses/custom-tool-compat"; import { compileCodeModeHelperInput } from "../../src/responses/code-mode-helper-compat"; import { createRoutedCustomToolRestoreBlockRewrite } from "../../src/server/responses-custom-tool-repair"; -import { handleResponses } from "../../src/server/responses"; -import type { OcxConfig } from "../../src/types"; import { createTestTranslatorBudget } from "../helpers/translator-budget"; - -function dataPayload(block: string): Record { - const line = block.split(/\r?\n/).find(entry => entry.startsWith("data:")); - if (!line) throw new Error("missing SSE data line"); - return JSON.parse(line.slice(5).trim()) as Record; -} - -function frame(event: string, payload: Record): string { - return `event: ${event}\ndata: ${JSON.stringify({ type: event, ...payload })}`; -} - -const DECORATED_PATCH = "*** Begin Patch ***\n*** Update File: README.md\n@@\n-old\n+new\n*** End Patch ***"; -const CANONICAL_PATCH = "*** Begin Patch\n*** Update File: README.md\n@@\n-old\n+new\n*** End Patch"; -const WRAPPED_DECORATED_PATCH = JSON.stringify({ input: DECORATED_PATCH }); +import { CANONICAL_PATCH, DECORATED_PATCH, WRAPPED_DECORATED_PATCH, dataPayload, frame } from "../helpers/custom-tool-repair-fixtures"; describe("routed Responses custom-tool compatibility", () => { test("restores legacy structured shell aliases as executable unified-exec input", () => { @@ -1195,949 +1180,4 @@ describe("routed Responses custom-tool compatibility", () => { rewrite.dispose?.(); }); - test("handleResponses sends an upstream-safe exec function and restores client SSE", async () => { - const savedFetch = globalThis.fetch; - let outboundBody: Record | undefined; - const upstreamItem = { - type: "function_call", - id: "fc_exec", - call_id: "call_exec", - name: "exec", - arguments: "{\"input\":\"const apps = await sky.list_apps();\"}", - status: "completed", - }; - const upstream = [ - frame("response.output_item.added", { output_index: 0, item: { ...upstreamItem, arguments: "", status: "in_progress" } }), - frame("response.function_call_arguments.done", { output_index: 0, item_id: "fc_exec", arguments: upstreamItem.arguments }), - frame("response.output_item.done", { output_index: 0, item: upstreamItem }), - frame("response.completed", { response: { id: "resp_1", status: "completed", output: [upstreamItem] } }), - "data: [DONE]", - ].join("\n\n") + "\n\n"; - globalThis.fetch = (async (_input, init) => { - outboundBody = JSON.parse(String(init?.body)) as Record; - return new Response(upstream, { headers: { "content-type": "text/event-stream" } }); - }) as typeof fetch; - const config = { - port: 0, - defaultProvider: "fixture", - providers: { - fixture: { - adapter: "openai-responses", - baseUrl: "https://fixture.test/v1", - authMode: "key", - apiKey: "fixture-key", - }, - }, - } as OcxConfig; - - try { - const response = await handleResponses(new Request("http://localhost/v1/responses", { - method: "POST", - headers: { "content-type": "application/json" }, - body: JSON.stringify({ - model: "fixture/deepseek-v4-flash", - stream: true, - input: [{ role: "user", content: [{ type: "input_text", text: "list apps" }] }], - tools: [{ type: "custom", name: "exec", description: "Run JavaScript", format: { type: "grammar", syntax: "lark" } }], - }), - }), config, { model: "", provider: "" }); - const clientSse = await response.text(); - const outboundTools = outboundBody?.tools as Array> | undefined; - - expect(outboundTools?.[0]).toMatchObject({ type: "function", name: "exec" }); - expect(clientSse).toContain('"type":"custom_tool_call"'); - expect(clientSse).toContain('"type":"response.custom_tool_call_input.done"'); - expect(clientSse).toContain('"input":"const apps = await sky.list_apps();"'); - expect(clientSse).not.toContain("response.function_call_arguments.done"); - expect(clientSse).not.toContain('"type":"function_call"'); - expect(clientSse).toContain("data: [DONE]"); - } finally { - globalThis.fetch = savedFetch; - } - }); - - test("handleResponses lowers and restores apply_patch when the destination denies custom tools", async () => { - const savedFetch = globalThis.fetch; - let outboundBody: Record | undefined; - const upstreamItem = { - type: "function_call", - id: "fc_patch_next", - call_id: "call_patch_next", - name: "apply_patch", - arguments: JSON.stringify({ input: "*** Begin Patch\n*** End Patch" }), - status: "completed", - }; - const upstream = [ - frame("response.output_item.added", { - output_index: 0, - item: { ...upstreamItem, arguments: "", status: "in_progress" }, - }), - frame("response.function_call_arguments.done", { - output_index: 0, - item_id: upstreamItem.id, - arguments: upstreamItem.arguments, - }), - frame("response.output_item.done", { output_index: 0, item: upstreamItem }), - frame("response.completed", { - response: { id: "resp_patch", status: "completed", output: [upstreamItem] }, - }), - "data: [DONE]", - ].join("\n\n") + "\n\n"; - globalThis.fetch = (async (_input, init) => { - outboundBody = JSON.parse(String(init?.body)) as Record; - return new Response(upstream, { headers: { "content-type": "text/event-stream" } }); - }) as typeof fetch; - const config = { - port: 0, - defaultProvider: "fixture", - providers: { - fixture: { - adapter: "openai-responses", - baseUrl: "https://fixture.test/v1", - authMode: "key", - apiKey: "fixture-key", - supportsResponsesCustomTools: false, - }, - }, - } as OcxConfig; - - try { - const response = await handleResponses(new Request("http://localhost/v1/responses", { - method: "POST", - headers: { "content-type": "application/json" }, - body: JSON.stringify({ - model: "fixture/grok-4.6", - stream: true, - input: [ - { - type: "custom_tool_call", - id: "ctc_patch_prior", - call_id: "call_patch_prior", - name: "apply_patch", - input: "noop", - }, - { type: "custom_tool_call_output", call_id: "call_patch_prior", output: "done" }, - ], - tools: [{ - type: "custom", - name: "apply_patch", - description: "Apply a patch", - format: { type: "grammar", syntax: "lark" }, - }], - }), - }), config, { model: "", provider: "" }); - const clientSse = await response.text(); - const outboundTools = outboundBody?.tools as Array> | undefined; - const outboundInput = outboundBody?.input as Array> | undefined; - - expect(outboundTools?.[0]).toMatchObject({ type: "function", name: "apply_patch" }); - expect(outboundInput?.[0]).toMatchObject({ - type: "function_call", - call_id: "call_patch_prior", - name: "apply_patch", - arguments: JSON.stringify({ input: "noop" }), - }); - expect(outboundInput?.[1]).toMatchObject({ - type: "function_call_output", - call_id: "call_patch_prior", - output: "done", - }); - expect(clientSse).toContain('"type":"custom_tool_call"'); - expect(clientSse).toContain('"id":"ctc_patch_next"'); - expect(clientSse).toContain('"call_id":"call_patch_next"'); - expect(clientSse).toContain('"name":"apply_patch"'); - expect(clientSse).toContain('"type":"response.custom_tool_call_input.done"'); - expect(clientSse).toContain("data: [DONE]"); - expect(clientSse).not.toContain('"type":"function_call"'); - expect(clientSse).not.toContain("response.function_call_arguments.done"); - } finally { - globalThis.fetch = savedFetch; - } - }); - - test("handleResponses lowers apply_patch for a noncanonical forward destination that denies custom tools", async () => { - const savedFetch = globalThis.fetch; - let outboundBody: Record | undefined; - let outboundAuthorization: string | null = null; - let outboundUrl = ""; - const upstreamItem = { - type: "function_call", - id: "fc_patch_next", - call_id: "call_patch_next", - name: "apply_patch", - arguments: JSON.stringify({ input: "*** Begin Patch\n*** End Patch" }), - status: "completed", - }; - const upstream = [ - frame("response.output_item.added", { - output_index: 0, - item: { ...upstreamItem, arguments: "", status: "in_progress" }, - }), - frame("response.function_call_arguments.done", { - output_index: 0, - item_id: upstreamItem.id, - arguments: upstreamItem.arguments, - }), - frame("response.output_item.done", { output_index: 0, item: upstreamItem }), - frame("response.completed", { - response: { id: "resp_patch", status: "completed", output: [upstreamItem] }, - }), - "data: [DONE]", - ].join("\n\n") + "\n\n"; - globalThis.fetch = (async (input, init) => { - outboundUrl = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url; - outboundBody = JSON.parse(String(init?.body)) as Record; - outboundAuthorization = new Headers(init?.headers).get("authorization"); - return new Response(upstream, { headers: { "content-type": "text/event-stream" } }); - }) as typeof fetch; - const config = { - port: 0, - defaultProvider: "fixture", - providers: { - fixture: { - adapter: "openai-responses", - baseUrl: "https://provider.example/v1", - authMode: "forward", - headers: { authorization: "Bearer provider-static" }, - supportsResponsesCustomTools: false, - }, - }, - } as OcxConfig; - - try { - const response = await handleResponses(new Request("http://localhost/v1/responses", { - method: "POST", - headers: { "content-type": "application/json", authorization: "Bearer caller-secret" }, - body: JSON.stringify({ - model: "fixture/grok-4.6", - stream: true, - input: [ - { - type: "custom_tool_call", - id: "ctc_patch_prior", - call_id: "call_patch_prior", - name: "apply_patch", - input: "noop", - }, - { type: "custom_tool_call_output", call_id: "call_patch_prior", output: "done" }, - ], - tools: [{ - type: "custom", - name: "apply_patch", - description: "Apply a patch", - format: { type: "grammar", syntax: "lark" }, - }], - }), - }), config, { model: "", provider: "" }); - const clientSse = await response.text(); - const outboundTools = outboundBody?.tools as Array> | undefined; - const outboundInput = outboundBody?.input as Array> | undefined; - - expect(outboundUrl).toBe("https://provider.example/v1/responses"); - expect(outboundAuthorization).toBe("Bearer provider-static"); - expect(outboundTools?.[0]).toMatchObject({ type: "function", name: "apply_patch" }); - expect(outboundInput?.[0]).toMatchObject({ - type: "function_call", - call_id: "call_patch_prior", - name: "apply_patch", - arguments: JSON.stringify({ input: "noop" }), - }); - expect(outboundInput?.[1]).toMatchObject({ - type: "function_call_output", - call_id: "call_patch_prior", - output: "done", - }); - expect(clientSse).toContain('"type":"custom_tool_call"'); - expect(clientSse).toContain('"id":"ctc_patch_next"'); - expect(clientSse).toContain('"call_id":"call_patch_next"'); - expect(clientSse).toContain('"name":"apply_patch"'); - expect(clientSse).toContain('"type":"response.custom_tool_call_input.done"'); - expect(clientSse).toContain("data: [DONE]"); - expect(clientSse).not.toContain('"type":"function_call"'); - expect(clientSse).not.toContain("response.function_call_arguments.done"); - } finally { - globalThis.fetch = savedFetch; - } - }); - - test("handleResponses continuation rewrites custom_tool_call_output and keeps call_id ordered", async () => { - const savedFetch = globalThis.fetch; - const outboundBodies: Array> = []; - const firstUpstreamItem = { - type: "function_call", - id: "fc_exec", - call_id: "call_exec", - name: "exec", - arguments: "{\"input\":\"const apps = await sky.list_apps();\"}", - status: "completed", - }; - const secondUpstreamMessage = { - type: "message", - id: "msg_2", - role: "assistant", - content: [{ type: "output_text", text: "27 apps" }], - status: "completed", - }; - let turn = 0; - globalThis.fetch = (async (_input, init) => { - outboundBodies.push(JSON.parse(String(init?.body)) as Record); - turn += 1; - if (turn === 1) { - const upstream = [ - frame("response.output_item.added", { output_index: 0, item: { ...firstUpstreamItem, arguments: "", status: "in_progress" } }), - frame("response.function_call_arguments.done", { output_index: 0, item_id: "fc_exec", arguments: firstUpstreamItem.arguments }), - frame("response.output_item.done", { output_index: 0, item: firstUpstreamItem }), - frame("response.completed", { response: { id: "resp_1", status: "completed", output: [firstUpstreamItem] } }), - "data: [DONE]", - ].join("\n\n") + "\n\n"; - return new Response(upstream, { headers: { "content-type": "text/event-stream" } }); - } - const upstream = [ - frame("response.output_item.added", { output_index: 0, item: { ...secondUpstreamMessage, content: [], status: "in_progress" } }), - frame("response.output_item.done", { output_index: 0, item: secondUpstreamMessage }), - frame("response.completed", { response: { id: "resp_2", status: "completed", output: [secondUpstreamMessage] } }), - "data: [DONE]", - ].join("\n\n") + "\n\n"; - return new Response(upstream, { headers: { "content-type": "text/event-stream" } }); - }) as typeof fetch; - const config = { - port: 0, - defaultProvider: "fixture", - providers: { - fixture: { - adapter: "openai-responses", - baseUrl: "https://fixture.test/v1", - authMode: "key", - apiKey: "fixture-key", - }, - }, - } as OcxConfig; - const tools = [{ type: "custom", name: "exec", description: "Run JavaScript", format: { type: "grammar", syntax: "lark" } }]; - - try { - const first = await handleResponses(new Request("http://localhost/v1/responses", { - method: "POST", - headers: { "content-type": "application/json" }, - body: JSON.stringify({ - model: "fixture/deepseek-v4-flash", - stream: true, - input: [{ role: "user", content: [{ type: "input_text", text: "list apps" }] }], - tools, - }), - }), config, { model: "", provider: "" }); - const firstSse = await first.text(); - expect(firstSse).toContain('"type":"custom_tool_call"'); - expect(firstSse).toContain('"call_id":"call_exec"'); - expect(firstSse).not.toContain('"type":"function_call"'); - - const second = await handleResponses(new Request("http://localhost/v1/responses", { - method: "POST", - headers: { "content-type": "application/json" }, - body: JSON.stringify({ - model: "fixture/deepseek-v4-flash", - stream: true, - input: [ - { role: "user", content: [{ type: "input_text", text: "list apps" }] }, - { - type: "custom_tool_call", - id: "ctc_exec", - call_id: "call_exec", - name: "exec", - input: "const apps = await sky.list_apps();", - }, - { type: "custom_tool_call_output", call_id: "call_exec", output: "27 apps" }, - { type: "custom_tool_call_output", call_id: "call_other", output: "wrong pairing must stay distinct" }, - ], - tools, - }), - }), config, { model: "", provider: "" }); - const secondSse = await second.text(); - const continuationInput = outboundBodies[1]?.input as Array>; - expect(outboundBodies).toHaveLength(2); - expect(continuationInput).toEqual(expect.arrayContaining([ - expect.objectContaining({ - type: "function_call", - call_id: "call_exec", - name: "exec", - arguments: JSON.stringify({ input: "const apps = await sky.list_apps();" }), - }), - expect.objectContaining({ - type: "function_call_output", - call_id: "call_exec", - output: "27 apps", - }), - ])); - const execOutput = continuationInput.find(item => item.type === "function_call_output" && item.call_id === "call_exec"); - const otherOutput = continuationInput.find(item => item.call_id === "call_other"); - expect(execOutput).toMatchObject({ type: "function_call_output", output: "27 apps" }); - expect(otherOutput).toMatchObject({ type: "custom_tool_call_output", call_id: "call_other" }); - expect(continuationInput.filter(item => item.type === "function_call_output")).toHaveLength(1); - expect(secondSse).toContain('"text":"27 apps"'); - expect(secondSse).toContain('"id":"resp_2"'); - expect(secondSse).not.toContain('"type":"function_call"'); - expect(secondSse.indexOf("resp_2")).toBeLessThan(secondSse.indexOf("data: [DONE]")); - } finally { - globalThis.fetch = savedFetch; - } - }); - - test("handleResponses restores routed custom calls in non-streaming JSON", async () => { - const savedFetch = globalThis.fetch; - const upstreamItem = { - type: "function_call", - id: "fc_exec", - call_id: "call_exec", - name: "exec", - arguments: "{\"input\":\"const apps = await sky.list_apps();\"}", - status: "completed", - }; - globalThis.fetch = (async () => new Response(JSON.stringify({ - id: "resp_json", - status: "completed", - output: [upstreamItem], - }), { headers: { "content-type": "application/json" } })) as typeof fetch; - const config = { - port: 0, - defaultProvider: "fixture", - providers: { - fixture: { - adapter: "openai-responses", - baseUrl: "https://fixture.test/v1", - authMode: "key", - apiKey: "fixture-key", - }, - }, - } as OcxConfig; - - try { - const response = await handleResponses(new Request("http://localhost/v1/responses", { - method: "POST", - headers: { "content-type": "application/json" }, - body: JSON.stringify({ - model: "fixture/deepseek-v4-flash", - stream: false, - input: [{ role: "user", content: [{ type: "input_text", text: "list apps" }] }], - tools: [{ type: "custom", name: "exec", description: "Run JavaScript", format: { type: "grammar", syntax: "lark" } }], - }), - }), config, { model: "", provider: "" }); - const body = await response.json() as { output: Array> }; - - expect(body.output[0]).toMatchObject({ - type: "custom_tool_call", - id: "ctc_exec", - name: "exec", - input: "const apps = await sky.list_apps();", - }); - expect(body.output[0]).not.toHaveProperty("arguments"); - } finally { - globalThis.fetch = savedFetch; - } - }); - - test("handleResponses does not restore routed custom calls excluded by request policy", async () => { - const savedFetch = globalThis.fetch; - const upstreamItem = { - type: "function_call", - id: "fc_exec", - call_id: "call_exec", - name: "exec", - arguments: "{\"input\":\"ignored policy\"}", - status: "completed", - }; - const config = { - port: 0, - defaultProvider: "fixture", - providers: { - fixture: { - adapter: "openai-responses", - baseUrl: "https://fixture.test/v1", - authMode: "key", - apiKey: "fixture-key", - }, - }, - } as OcxConfig; - const execTool = { - type: "custom", - name: "exec", - description: "Run JavaScript", - format: { type: "grammar", syntax: "lark" }, - }; - const ordinaryTool = { - type: "function", - name: "ordinary", - description: "Ordinary function", - parameters: { type: "object" }, - }; - const cases: Array<{ - name: string; - stream: boolean; - tools: Array>; - toolChoice?: unknown; - metadata?: unknown; - /** The upstream call names a tool this request never declared at all (#1700). */ - undeclared?: boolean; - }> = [ - { - name: "streaming none", - stream: true, - tools: [execTool], - toolChoice: "none", - }, - { - name: "streaming allowlist", - stream: true, - tools: [execTool, ordinaryTool], - toolChoice: { - type: "allowed_tools", - mode: "required", - tools: [{ type: "function", name: "ordinary" }], - }, - }, - { - name: "named ordinary function", - stream: false, - tools: [execTool, ordinaryTool], - toolChoice: { type: "function", name: "ordinary" }, - }, - { - name: "custom-looking metadata without a declared tool", - stream: false, - tools: [ordinaryTool], - metadata: { nested: { type: "custom", name: "exec" } }, - undeclared: true, - }, - ]; - - globalThis.fetch = (async (_input, init) => { - const outboundBody = JSON.parse(String(init?.body)) as { stream?: boolean }; - if (outboundBody.stream === true) { - const upstream = [ - frame("response.output_item.added", { - output_index: 0, - item: { ...upstreamItem, arguments: "", status: "in_progress" }, - }), - frame("response.function_call_arguments.done", { - output_index: 0, - item_id: "fc_exec", - arguments: upstreamItem.arguments, - }), - frame("response.output_item.done", { output_index: 0, item: upstreamItem }), - frame("response.completed", { - response: { id: "resp_policy", status: "completed", output: [upstreamItem] }, - }), - "data: [DONE]", - ].join("\n\n") + "\n\n"; - return new Response(upstream, { headers: { "content-type": "text/event-stream" } }); - } - return new Response(JSON.stringify({ - id: "resp_policy", - status: "completed", - output: [upstreamItem], - }), { headers: { "content-type": "application/json" } }); - }) as typeof fetch; - - try { - for (const policyCase of cases) { - const response = await handleResponses(new Request("http://localhost/v1/responses", { - method: "POST", - headers: { "content-type": "application/json" }, - body: JSON.stringify({ - model: "fixture/deepseek-v4-flash", - stream: policyCase.stream, - input: [{ role: "user", content: [{ type: "input_text", text: policyCase.name }] }], - tools: policyCase.tools, - ...(policyCase.toolChoice !== undefined ? { tool_choice: policyCase.toolChoice } : {}), - ...(policyCase.metadata !== undefined ? { metadata: policyCase.metadata } : {}), - }), - }), config, { model: "", provider: "" }); - - if (policyCase.stream) { - const clientSse = await response.text(); - expect(clientSse).toContain('"type":"function_call"'); - expect(clientSse).toContain('"id":"fc_exec"'); - expect(clientSse).toContain("response.function_call_arguments.done"); - expect(clientSse).not.toContain("custom_tool_call"); - expect(clientSse).not.toContain("ctc_exec"); - } else if (policyCase.undeclared) { - // #1700: this request's catalog holds only `ordinary` — a metadata blob that merely - // looks like a tool declaration declares nothing — so a call to `exec` is refused - // instead of relayed. The restore contract still holds either way: it never became - // a custom_tool_call. - expect(response.status).toBe(502); - const body = await response.json() as { error: { message: string } }; - expect(body.error.message).toContain('undeclared client tool "exec"'); - } else { - const body = await response.json() as { output: Array> }; - expect(body.output[0]).toEqual(upstreamItem); - } - } - } finally { - globalThis.fetch = savedFetch; - } - }); - - test("handleResponses preserves native apply_patch calls that were never converted", async () => { - const savedFetch = globalThis.fetch; - const upstreamItem = { - type: "function_call", - id: "fc_patch", - call_id: "call_patch", - name: "apply_patch", - arguments: "{\"patch\":\"*** Begin Patch\"}", - status: "completed", - }; - globalThis.fetch = (async () => new Response(JSON.stringify({ - id: "resp_patch", - status: "completed", - output: [upstreamItem], - }), { headers: { "content-type": "application/json" } })) as typeof fetch; - const config = { - port: 0, - defaultProvider: "fixture", - providers: { - fixture: { - adapter: "openai-responses", - baseUrl: "https://fixture.test/v1", - authMode: "key", - apiKey: "fixture-key", - }, - }, - } as OcxConfig; - - try { - const response = await handleResponses(new Request("http://localhost/v1/responses", { - method: "POST", - headers: { "content-type": "application/json" }, - body: JSON.stringify({ - model: "fixture/deepseek-v4-flash", - stream: false, - input: [{ role: "user", content: [{ type: "input_text", text: "patch" }] }], - tools: [{ - type: "custom", - name: "apply_patch", - description: "Apply a patch", - format: { type: "grammar", syntax: "lark" }, - }], - }), - }), config, { model: "", provider: "" }); - const body = await response.json() as { output: Array> }; - - expect(body.output[0]).toEqual(upstreamItem); - } finally { - globalThis.fetch = savedFetch; - } - }); - - test("handleResponses preserves disallowed native apply_patch input in JSON and SSE", async () => { - const savedFetch = globalThis.fetch; - const config = { - port: 0, - defaultProvider: "fixture", - providers: { - fixture: { - adapter: "openai-responses", - baseUrl: "https://fixture.test/v1", - authMode: "key", - apiKey: "fixture-key", - }, - }, - } as OcxConfig; - const upstreamItem = { - type: "custom_tool_call", - id: "ctc_patch", - call_id: "call_patch", - name: "apply_patch", - input: DECORATED_PATCH, - status: "completed", - }; - - globalThis.fetch = (async (_input, init) => { - const outbound = JSON.parse(String(init?.body)) as { stream?: boolean }; - if (outbound.stream === true) { - const upstream = [ - frame("response.output_item.added", { - output_index: 0, - item: { ...upstreamItem, input: "", status: "in_progress" }, - }), - frame("response.custom_tool_call_input.done", { - output_index: 0, - item_id: "ctc_patch", - input: DECORATED_PATCH, - }), - frame("response.output_item.done", { output_index: 0, item: upstreamItem }), - frame("response.completed", { - response: { id: "resp_patch_stream", status: "completed", output: [upstreamItem] }, - }), - "data: [DONE]", - ].join("\n\n") + "\n\n"; - return new Response(upstream, { headers: { "content-type": "text/event-stream" } }); - } - return Response.json({ id: "resp_patch_json", status: "completed", output: [upstreamItem] }); - }) as typeof fetch; - - try { - for (const stream of [false, true]) { - const response = await handleResponses(new Request("http://localhost/v1/responses", { - method: "POST", - headers: { "content-type": "application/json" }, - body: JSON.stringify({ - model: "fixture/deepseek-v4-flash", - stream, - input: [{ role: "user", content: [{ type: "input_text", text: "patch" }] }], - tools: [ - { - type: "custom", - name: "apply_patch", - description: "Apply a patch", - format: { type: "grammar", syntax: "lark" }, - }, - { - type: "function", - name: "ordinary", - description: "Ordinary function", - parameters: { type: "object" }, - }, - ], - tool_choice: stream - ? { - type: "allowed_tools", - mode: "required", - tools: [{ type: "function", name: "ordinary" }], - } - : { type: "function", name: "ordinary" }, - }), - }), config, { model: "", provider: "" }); - - if (!stream) { - const body = await response.json() as { output: Array> }; - expect(body.output[0]).toEqual(upstreamItem); - continue; - } - - const blocks = (await response.text()).split("\n\n").filter(block => block.includes("data: {")); - const payloads = blocks.map(dataPayload); - const inputDone = payloads.find(payload => payload.type === "response.custom_tool_call_input.done"); - expect(inputDone).toMatchObject({ input: DECORATED_PATCH }); - const itemDone = payloads.find(payload => payload.type === "response.output_item.done") as { - item?: Record; - } | undefined; - expect(itemDone?.item).toMatchObject({ type: "custom_tool_call", input: DECORATED_PATCH }); - const completed = payloads.find(payload => payload.type === "response.completed") as { - response?: { output?: Array> }; - } | undefined; - expect(completed?.response?.output?.[0]).toMatchObject({ input: DECORATED_PATCH }); - } - } finally { - globalThis.fetch = savedFetch; - } - }); - - test("handleResponses repairs authorized native apply_patch calls in JSON and SSE", async () => { - const savedFetch = globalThis.fetch; - const config = { - port: 0, - defaultProvider: "fixture", - providers: { - fixture: { - adapter: "openai-responses", - baseUrl: "https://fixture.test/v1", - authMode: "key", - apiKey: "fixture-key", - }, - }, - } as OcxConfig; - const upstreamItem = { - type: "custom_tool_call", - id: "ctc_patch", - call_id: "call_patch", - name: "apply_patch", - input: DECORATED_PATCH, - status: "completed", - }; - - globalThis.fetch = (async (_input, init) => { - const outbound = JSON.parse(String(init?.body)) as { stream?: boolean }; - if (outbound.stream === true) { - const upstream = [ - frame("response.output_item.added", { - output_index: 0, - item: { ...upstreamItem, input: "", status: "in_progress" }, - }), - frame("response.custom_tool_call_input.done", { - output_index: 0, - item_id: "ctc_patch", - input: DECORATED_PATCH, - }), - frame("response.output_item.done", { output_index: 0, item: upstreamItem }), - frame("response.completed", { - response: { id: "resp_patch_stream", status: "completed", output: [upstreamItem] }, - }), - "data: [DONE]", - ].join("\n\n") + "\n\n"; - return new Response(upstream, { headers: { "content-type": "text/event-stream" } }); - } - return Response.json({ id: "resp_patch_json", status: "completed", output: [upstreamItem] }); - }) as typeof fetch; - - try { - for (const stream of [false, true]) { - const response = await handleResponses(new Request("http://localhost/v1/responses", { - method: "POST", - headers: { "content-type": "application/json" }, - body: JSON.stringify({ - model: "fixture/deepseek-v4-flash", - stream, - input: [{ role: "user", content: [{ type: "input_text", text: "patch" }] }], - tools: [{ - type: "custom", - name: "apply_patch", - description: "Apply a patch", - format: { type: "grammar", syntax: "lark" }, - }], - }), - }), config, { model: "", provider: "" }); - - if (!stream) { - const body = await response.json() as { output: Array> }; - expect(body.output[0]).toMatchObject({ - type: "custom_tool_call", - name: "apply_patch", - input: CANONICAL_PATCH, - }); - continue; - } - - const blocks = (await response.text()).split("\n\n").filter(block => block.includes("data: {")); - const payloads = blocks.map(dataPayload); - const inputDone = payloads.find(payload => payload.type === "response.custom_tool_call_input.done"); - expect(inputDone).toMatchObject({ input: CANONICAL_PATCH }); - const itemDone = payloads.find(payload => payload.type === "response.output_item.done") as { - item?: Record; - } | undefined; - expect(itemDone?.item).toMatchObject({ type: "custom_tool_call", input: CANONICAL_PATCH }); - const completed = payloads.find(payload => payload.type === "response.completed") as { - response?: { output?: Array> }; - } | undefined; - expect(completed?.response?.output?.[0]).toMatchObject({ input: CANONICAL_PATCH }); - } - } finally { - globalThis.fetch = savedFetch; - } - }); - - test("handleResponses does not restore a custom image tool replaced by hosted preference", async () => { - const savedFetch = globalThis.fetch; - let outboundBody: Record | undefined; - const upstreamItem = { - type: "function_call", - id: "fc_image", - call_id: "call_image", - name: "image_gen.generate", - arguments: "{}", - status: "completed", - }; - globalThis.fetch = (async (_input, init) => { - outboundBody = JSON.parse(String(init?.body)) as Record; - return new Response(JSON.stringify({ - id: "resp_image", - status: "completed", - output: [upstreamItem], - }), { headers: { "content-type": "application/json" } }); - }) as typeof fetch; - const config = { - port: 0, - defaultProvider: "fixture", - providers: { - fixture: { - adapter: "openai-responses", - baseUrl: "https://fixture.test/v1", - authMode: "key", - apiKey: "fixture-key", - modelPreferHostedTools: { "deepseek-v4-flash": ["image_generation"] }, - }, - }, - } as OcxConfig; - - try { - const response = await handleResponses(new Request("http://localhost/v1/responses", { - method: "POST", - headers: { "content-type": "application/json" }, - body: JSON.stringify({ - model: "fixture/deepseek-v4-flash", - stream: false, - input: [{ role: "user", content: [{ type: "input_text", text: "draw" }] }], - tools: [{ - type: "custom", - name: "image_gen.generate", - description: "Generate an image", - format: { type: "grammar", syntax: "lark" }, - }], - }), - }), config, { model: "", provider: "" }); - const body = await response.json() as { output: Array> }; - const outboundTools = outboundBody?.tools as Array> | undefined; - - expect(outboundTools).toEqual([{ type: "image_generation" }]); - expect(body.output[0]).toEqual(upstreamItem); - } finally { - globalThis.fetch = savedFetch; - } - }); - - test("handleResponses leaves custom tools native for forward-auth passthrough", async () => { - const savedFetch = globalThis.fetch; - let outboundBody: Record | undefined; - let outboundAuthorization: string | null = null; - let outboundUrl = ""; - const upstreamItem = { - type: "function_call", - id: "fc_exec", - call_id: "call_exec", - name: "exec", - arguments: "{\"input\":\"native\"}", - status: "completed", - }; - globalThis.fetch = (async (input, init) => { - outboundUrl = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url; - outboundBody = JSON.parse(String(init?.body)) as Record; - outboundAuthorization = new Headers(init?.headers).get("authorization"); - return new Response(JSON.stringify({ id: "resp_forward", status: "completed", output: [upstreamItem] }), { - headers: { "content-type": "application/json" }, - }); - }) as typeof fetch; - const config = { - port: 0, - defaultProvider: "fixture", - providers: { - fixture: { - adapter: "openai-responses", - baseUrl: "https://chatgpt.com/backend-api/codex", - authMode: "forward", - }, - }, - } as OcxConfig; - - try { - const response = await handleResponses(new Request("http://localhost/v1/responses", { - method: "POST", - headers: { "content-type": "application/json", authorization: "Bearer caller-token" }, - body: JSON.stringify({ - model: "fixture/native-model", - stream: false, - input: "run", - tools: [{ type: "custom", name: "exec", description: "Run JavaScript", format: { type: "grammar", syntax: "lark" } }], - }), - }), config, { model: "", provider: "" }); - const clientBody = await response.json() as { output: Array> }; - const outboundTools = outboundBody?.tools as Array> | undefined; - - expect(outboundUrl).toBe("https://chatgpt.com/backend-api/codex/responses"); - expect(outboundAuthorization).toBe("Bearer caller-token"); - expect(outboundTools?.[0]).toMatchObject({ type: "custom", name: "exec" }); - expect(clientBody.output[0]).toMatchObject({ type: "function_call", name: "exec" }); - expect(clientBody.output[0]).not.toHaveProperty("input"); - } finally { - globalThis.fetch = savedFetch; - } - }); }); diff --git a/tests/responses/responses-forward-incomplete-quota.test.ts b/tests/responses/responses-forward-incomplete-quota.test.ts index 0d93e3d5e44..ee79fd9c182 100644 --- a/tests/responses/responses-forward-incomplete-quota.test.ts +++ b/tests/responses/responses-forward-incomplete-quota.test.ts @@ -26,6 +26,7 @@ import { isEagerRelaySseResponse } from "../../src/server/relay"; import { sendResponseToWebSocket, type WsData } from "../../src/server/ws-bridge"; import { installIsolatedCodexHome } from "../helpers/isolated-codex-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { INTERNAL_DEADLINE_MS, SERVER_BUDGET_MS } from "../helpers/test-budget"; const provider: OcxProviderConfig = { @@ -116,6 +117,8 @@ async function exerciseSpawnReporter(path: ReporterPath): Promise { const home = mkdtempSync(join(tmpdir(), "ocx-incomplete-quota-")); const codexHome = installIsolatedCodexHome("ocx-incomplete-quota-codex-"); process.env.OPENCODEX_HOME = home; + // Taken after this reporter installs its home so every direct dispatch owns its journal. + const releaseSpendHome = acquireOwnedSpendHome(); const accountId = "incomplete-quota-endpoint"; const model = "gpt-test"; const config: OcxConfig = { @@ -303,6 +306,8 @@ async function exerciseSpawnReporter(path: ReporterPath): Promise { expect(wsDispatches).toBe(path === "guarded-ws" ? 2 : 0); expect(httpDispatches).toBe(path === "guarded-ws" ? 0 : 2); } finally { + // Released before restoring or removing the home so the lease files are not left open. + releaseSpendHome(); client?.close(); await endpoint.stop(true); await upstream.stop(true); diff --git a/tests/responses/responses-function-tool-repair.test.ts b/tests/responses/responses-function-tool-repair.test.ts index 2f9343cd3d2..599e9cd9fa9 100644 --- a/tests/responses/responses-function-tool-repair.test.ts +++ b/tests/responses/responses-function-tool-repair.test.ts @@ -1,6 +1,6 @@ import { handleResponses } from "../../src/server/responses"; import type { OcxConfig } from "../../src/types"; -import { describe, expect, test } from "bun:test"; +import { afterEach, describe, expect, test } from "bun:test"; import { collectFunctionCallRepairSchemas, repairFunctionCalls, @@ -10,6 +10,18 @@ import { createResponsesFunctionToolRepairBlockRewrite } from "../../src/server/ import { createTranslatorBudget, TranslatorBudgetExceededError } from "../../src/lib/translator-budget"; import { sseDataPayload } from "../../src/server/sse-payload-rewrite"; import { currentTurnWireToolCatalogBody } from "../../src/server/responses-undeclared-tool-guard"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; + +let releaseSpendHome: (() => void) | undefined; + +// Direct physical dispatch needs the writer lease to prevent spend-ledger ownership failures. +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; + +afterEach(() => { + // Release first so a failed dispatch cannot leak ownership into the next case. + releaseSpendHome?.(); + releaseSpendHome = undefined; +}); const parameters = { type: "object", properties: { cell_id: { type: "string" }, yield_time_ms: { type: "integer" }, @@ -391,6 +403,7 @@ test("native Responses JSON/SSE and replay share the original function schema re method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ model: "fixture/grok-probe", stream, input: [{ role: "user", content: "synthetic" }], tools, ...extra }), }); + takeSpendHome(); const response = await handleResponses(request(), config, { model: "", provider: "" }); expect(response.status).toBe(200); const raw = await response.text(); diff --git a/tests/responses/responses-image-gen-repair.test.ts b/tests/responses/responses-image-gen-repair.test.ts index f5f358081ea..dfafde3725d 100644 --- a/tests/responses/responses-image-gen-repair.test.ts +++ b/tests/responses/responses-image-gen-repair.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, test } from "bun:test"; +import { afterEach, describe, expect, test } from "bun:test"; import { imageGenToolCallAliases, relaySseWithImageGenCallRestore as relaySseWithImageGenCallRestoreProduction, @@ -8,6 +8,18 @@ import { handleResponses } from "../../src/server/responses"; import type { OcxConfig } from "../../src/types"; import { finalizeTranslatorBudgetResponse } from "../../src/lib/translator-budget"; import { createTestTranslatorBudget } from "../helpers/translator-budget"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; + +let releaseSpendHome: (() => void) | undefined; + +// Direct physical dispatch needs the writer lease to prevent spend-ledger ownership failures. +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; + +afterEach(() => { + // Release first so a failed dispatch cannot leak ownership into the next case. + releaseSpendHome?.(); + releaseSpendHome = undefined; +}); function relaySseWithImageGenCallRestore( body: ReadableStream, @@ -185,6 +197,7 @@ describe("Responses image-gen call restoration", () => { } as OcxConfig; try { + takeSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -245,6 +258,7 @@ describe("Responses image-gen call restoration", () => { } as OcxConfig; try { + takeSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -317,6 +331,7 @@ describe("Responses image-gen call restoration", () => { } as OcxConfig; try { + takeSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, diff --git a/tests/responses/responses-inbound-store-default.test.ts b/tests/responses/responses-inbound-store-default.test.ts index 23bcc6aee10..7f370de68c2 100644 --- a/tests/responses/responses-inbound-store-default.test.ts +++ b/tests/responses/responses-inbound-store-default.test.ts @@ -18,6 +18,7 @@ import { afterEach, describe, expect, test } from "bun:test"; import { CODEX_FORWARD_BASE_URL } from "../../src/providers/openai-tiers"; import { handleResponses } from "../../src/server/responses"; import type { OcxConfig, OcxProviderConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; function providerConfig(overrides: Partial = {}): OcxConfig { return { @@ -36,7 +37,13 @@ function providerConfig(overrides: Partial = {}): OcxConfig { describe("/v1/responses defaults store:false only for the canonical forward Codex backend", () => { const originalFetch = globalThis.fetch; - afterEach(() => { globalThis.fetch = originalFetch; }); + let releaseSpendHome: (() => void) | undefined; + afterEach(() => { + // Release first so a failed dispatch cannot leak writer ownership into the next case. + releaseSpendHome?.(); + releaseSpendHome = undefined; + globalThis.fetch = originalFetch; + }); function captureUpstream(): { urls: string[]; bodies: string[] } { const urls: string[] = []; @@ -61,7 +68,9 @@ describe("/v1/responses defaults store:false only for the canonical forward Code store: unknown, ): Promise<{ url: string; body: Record | null }> { const { urls, bodies } = captureUpstream(); - await handleResponses( + // Direct dispatch needs the writer lease to prevent spend-ledger ownership failures. + releaseSpendHome = acquireOwnedSpendHome(); + const turn = await handleResponses( new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -75,6 +84,10 @@ describe("/v1/responses defaults store:false only for the canonical forward Code config, { model: "", provider: "" }, ); + // Every row here asks for a stream and then reads only the captured upstream REQUEST, so + // the turn's own body was left live. Draining it lets the parser, the completion callbacks + // and the lifetime cleanup finish before the teardown below hands back the writer lease. + await turn.text(); let parsed: Record | null = null; try { parsed = bodies[0] ? (JSON.parse(bodies[0]) as Record) : null; } catch { parsed = null; } return { url: urls[0] ?? "", body: parsed }; diff --git a/tests/responses/responses-muse-tool-name-alias.test.ts b/tests/responses/responses-muse-tool-name-alias.test.ts index 655165d3944..30f76330d48 100644 --- a/tests/responses/responses-muse-tool-name-alias.test.ts +++ b/tests/responses/responses-muse-tool-name-alias.test.ts @@ -1,5 +1,5 @@ import { createHash } from "node:crypto"; -import { describe, expect, test } from "bun:test"; +import { afterEach, describe, expect, test } from "bun:test"; import { createResponsesPassthroughAdapter as createResponsesPassthroughAdapterProduction } from "../../src/adapters/openai-responses"; import { buildMuseToolNameAliasPlan, @@ -11,8 +11,20 @@ import { import { expandPreviousResponseInput } from "../../src/responses/state"; import { handleResponses } from "../../src/server/responses"; import type { OcxConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { withTestTranslatorBudget } from "../helpers/translator-budget"; +let releaseSpendHome: (() => void) | undefined; + +// Direct physical dispatch needs the writer lease to prevent spend-ledger ownership failures. +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; + +afterEach(() => { + // Release first so a failed dispatch cannot leak ownership into the next case. + releaseSpendHome?.(); + releaseSpendHome = undefined; +}); + const createResponsesPassthroughAdapter = (...args: Parameters) => withTestTranslatorBudget(createResponsesPassthroughAdapterProduction(...args)); @@ -270,6 +282,7 @@ describe("muse tool-name inbound restore through handleResponses", () => { }), { headers: { "content-type": "application/json" } }); }) as typeof fetch; try { + takeSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -304,6 +317,7 @@ describe("muse tool-name inbound restore through handleResponses", () => { return new Response(upstream, { headers: { "content-type": "text/event-stream" } }); }) as typeof fetch; try { + takeSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -338,6 +352,7 @@ describe("muse tool-name inbound restore through handleResponses", () => { return new Response(upstream, { headers: { "content-type": "text/event-stream" } }); }) as typeof fetch; try { + takeSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -389,6 +404,7 @@ describe("muse tool-name inbound restore through handleResponses", () => { return new Response(upstream, { headers: { "content-type": "text/event-stream" } }); }) as typeof fetch; try { + takeSpendHome(); const turn1 = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, diff --git a/tests/responses/responses-native-main-refresh.test.ts b/tests/responses/responses-native-main-refresh.test.ts index f70bc07f1ee..3a318cc0830 100644 --- a/tests/responses/responses-native-main-refresh.test.ts +++ b/tests/responses/responses-native-main-refresh.test.ts @@ -14,12 +14,14 @@ import { tryAdmitTurn } from "../../src/server/lifecycle"; import { handleResponses, handleResponsesCompact } from "../../src/server/responses"; import type { RequestLogContext } from "../../src/server/request-log"; import type { OcxConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; const originalFetch = globalThis.fetch; let home = ""; let previousOcxHome: string | undefined; let previousCodexHome: string | undefined; +let releaseSpendHome: (() => void) | undefined; const OTHER_ACCOUNT_ID = "other"; function config(options: { secondAccount?: boolean } = {}): OcxConfig { @@ -57,6 +59,8 @@ beforeEach(() => { previousCodexHome = process.env.CODEX_HOME; process.env.OPENCODEX_HOME = home; process.env.CODEX_HOME = home; + // Take the writer lease after this case installs its home so direct handler dispatch can open the spend journal. + releaseSpendHome = acquireOwnedSpendHome(); clearAccountNeedsReauth(MAIN_CODEX_ACCOUNT_ID); clearAccountNeedsReauth(OTHER_ACCOUNT_ID); clearCodexUpstreamHealth(); @@ -71,6 +75,9 @@ beforeEach(() => { }); afterEach(() => { + // Release before restoring or removing the home to prevent Windows removal failures and POSIX unlinked databases. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; clearAccountNeedsReauth(MAIN_CODEX_ACCOUNT_ID); clearAccountNeedsReauth(OTHER_ACCOUNT_ID); diff --git a/tests/responses/responses-opaque-blob-recovery.test.ts b/tests/responses/responses-opaque-blob-recovery.test.ts index a47a155f387..48290dad1ba 100644 --- a/tests/responses/responses-opaque-blob-recovery.test.ts +++ b/tests/responses/responses-opaque-blob-recovery.test.ts @@ -14,6 +14,7 @@ import { } from "../../src/server/responses/core"; import type { RequestLogContext } from "../../src/server/request-log"; import type { OcxConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; import { markBodyNonPersistable, rememberResponseState, previousResponseProviderState } from "../../src/responses/state"; @@ -66,15 +67,21 @@ const CALLER_MISMATCH_BLOB_ERROR = JSON.stringify({ }); let testDir = ""; +let releaseSpendHome: (() => void) | undefined; beforeEach(() => { testDir = mkdtempSync(join(tmpdir(), "ocx-opaque-blob-recovery-")); process.env.OPENCODEX_HOME = testDir; + // Take the writer lease after this case installs its home so direct handler dispatch can open the spend journal. + releaseSpendHome = acquireOwnedSpendHome(); clearReasoningReplayCacheForTests(); resetThoughtSignatureReplayForTests(); }); afterEach(() => { + // Release before restoring or removing the home to prevent Windows removal failures and POSIX unlinked databases. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; clearReasoningReplayCacheForTests(); resetThoughtSignatureReplayForTests(); diff --git a/tests/responses/responses-pool-401-refresh.test.ts b/tests/responses/responses-pool-401-refresh.test.ts index b1043cc2dd4..2fc4409c130 100644 --- a/tests/responses/responses-pool-401-refresh.test.ts +++ b/tests/responses/responses-pool-401-refresh.test.ts @@ -33,6 +33,7 @@ import { encryptedInput, recoverySse, } from "../helpers/agent-task-recovery"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; /** @@ -51,6 +52,7 @@ const originalFetch = globalThis.fetch; let home = ""; let previousOcxHome: string | undefined; let previousCodexHome: string | undefined; +let releaseSpendHome: (() => void) | undefined; function config(options: { secondAccount?: boolean } = {}): OcxConfig { return { @@ -306,6 +308,8 @@ beforeEach(() => { previousCodexHome = process.env.CODEX_HOME; process.env.OPENCODEX_HOME = home; process.env.CODEX_HOME = home; + // Direct handler dispatches need the writer lease that startServer normally holds. + releaseSpendHome = acquireOwnedSpendHome(); clearAccountNeedsReauth(ACCOUNT_ID); clearAccountNeedsReauth(OTHER_ACCOUNT_ID); clearCodexUpstreamHealth(); @@ -316,6 +320,9 @@ beforeEach(() => { }); afterEach(() => { + // Release before home teardown to prevent Windows removal failures and a live unlinked database. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; clearCompactHandoffRoutesForTests(); clearAccountNeedsReauth(ACCOUNT_ID); diff --git a/tests/responses/responses-preview-main-read-fence.test.ts b/tests/responses/responses-preview-main-read-fence.test.ts index b0156293459..d7380c778d2 100644 --- a/tests/responses/responses-preview-main-read-fence.test.ts +++ b/tests/responses/responses-preview-main-read-fence.test.ts @@ -40,6 +40,7 @@ import { encryptedInput, recoverySse, } from "../helpers/agent-task-recovery"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; /** @@ -184,15 +185,22 @@ async function postSpawn( const requestHeaders = new Headers(headers); requestHeaders.set("content-type", "application/json"); requestHeaders.set("x-openai-subagent", "collab_spawn"); - const response = await handleResponses(new Request("http://localhost/v1/responses", { - method: "POST", - headers: requestHeaders, - body: JSON.stringify({ model, input, stream: false }), - }), config, logCtx, options); - // handleResponses owns its translator budget through the returned body lifecycle. Draining the - // body also lets completed Responses schedule their state write before afterEach cancels it. - await response.arrayBuffer(); - return response; + // Acquire on this case's installed home so direct dispatch can open the shared spend journal. + const releaseSpendHome = acquireOwnedSpendHome(); + try { + const response = await handleResponses(new Request("http://localhost/v1/responses", { + method: "POST", + headers: requestHeaders, + body: JSON.stringify({ model, input, stream: false }), + }), config, logCtx, options); + // handleResponses owns its translator budget through the returned body lifecycle. Draining the + // body also lets completed Responses schedule their state write before afterEach cancels it. + await response.arrayBuffer(); + return response; + } finally { + // Release before afterEach removes this home to prevent Windows removal failures. + releaseSpendHome(); + } } beforeEach(() => { diff --git a/tests/responses/responses-reasoning-effort-downgrade.test.ts b/tests/responses/responses-reasoning-effort-downgrade.test.ts index ee18288fce7..e609d2f6e80 100644 --- a/tests/responses/responses-reasoning-effort-downgrade.test.ts +++ b/tests/responses/responses-reasoning-effort-downgrade.test.ts @@ -6,6 +6,7 @@ import { handleResponses } from "../../src/server/responses/core"; import { resetReasoningMetadataCachesForTests } from "../../src/providers/reasoning-metadata"; import type { RequestLogContext } from "../../src/server/request-log"; import type { OcxConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; /** * Rejected-rung learning on the request path: a rung the catalog advertises can still be refused @@ -27,6 +28,7 @@ const REFUSAL = JSON.stringify({ const UNRELATED = JSON.stringify({ error: { type: "invalid_request_error", message: "Invalid upload request." } }); let testDir = ""; +let releaseSpendHome: (() => void) | undefined; function writeSnapshot(values: string[]): void { writeFileSync(join(testDir, "reasoning-metadata-cache.json"), JSON.stringify({ @@ -101,10 +103,15 @@ function success(): Response { beforeEach(() => { testDir = mkdtempSync(join(tmpdir(), "ocx-reasoning-downgrade-")); process.env.OPENCODEX_HOME = testDir; + // Direct handler dispatches need the writer lease that startServer normally holds. + releaseSpendHome = acquireOwnedSpendHome(); resetReasoningMetadataCachesForTests(); }); afterEach(() => { + // Release before home teardown to prevent Windows removal failures and a live unlinked database. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; resetReasoningMetadataCachesForTests(); if (originalOpenCodexHome === undefined) delete process.env.OPENCODEX_HOME; diff --git a/tests/responses/responses-reasoning-summary-passthrough.test.ts b/tests/responses/responses-reasoning-summary-passthrough.test.ts index ab6e099bcc7..dfebadfd066 100644 --- a/tests/responses/responses-reasoning-summary-passthrough.test.ts +++ b/tests/responses/responses-reasoning-summary-passthrough.test.ts @@ -3,6 +3,9 @@ import { providerConfigSeed } from "../../src/providers/derive"; import { getProviderRegistryEntry } from "../../src/providers/registry"; import { handleResponses } from "../../src/server/responses/core"; import type { OcxConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; + +let releaseSpendHome: (() => void) | undefined; /** * The passthrough relay for DeepSeek's native /responses endpoint emits @@ -59,6 +62,8 @@ async function runHandleResponses(body: Record, upstreamBody: u { status: 200, headers: { "content-type": contentType } }, )) as typeof fetch; const config = { providers: { deepseek: deepseekSeed() } } as unknown as OcxConfig; + // Direct dispatch needs the writer lease that prevents spend-ledger ownership failures. + releaseSpendHome = acquireOwnedSpendHome(); return handleResponses( new Request("http://localhost/v1/responses", { method: "POST", @@ -73,7 +78,12 @@ async function runHandleResponses(body: Record, upstreamBody: u describe("passthrough reasoning summary rewrite honors hideThinkingSummary", () => { const originalFetch = globalThis.fetch; - afterEach(() => { globalThis.fetch = originalFetch; }); + afterEach(() => { + // Release the lease before later teardown can replace the preload sandbox home. + releaseSpendHome?.(); + releaseSpendHome = undefined; + globalThis.fetch = originalFetch; + }); test("SSE: hidden thinking stays on the content channel", async () => { // No reasoning.summary in the request -> parseRequest sets hideThinkingSummary. diff --git a/tests/responses/responses-self-named-namespace-scrub.test.ts b/tests/responses/responses-self-named-namespace-scrub.test.ts index df187d48d1e..410ed394bac 100644 --- a/tests/responses/responses-self-named-namespace-scrub.test.ts +++ b/tests/responses/responses-self-named-namespace-scrub.test.ts @@ -10,9 +10,18 @@ import { afterEach, expect, test } from "bun:test"; import { handleResponses } from "../../src/server/responses"; import { scrubSelfNamedToolCallNamespace } from "../../src/server/responses-self-named-namespace-scrub"; import type { OcxConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; const originalFetch = globalThis.fetch; -afterEach(() => { globalThis.fetch = originalFetch; }); +let releaseSpendHome: (() => void) | undefined; +// Direct dispatch needs the writer lease that prevents spend-ledger ownership failures. +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; +afterEach(() => { + // Release the lease before later teardown can replace the preload sandbox home. + releaseSpendHome?.(); + releaseSpendHome = undefined; + globalThis.fetch = originalFetch; +}); function forwardConfig(): OcxConfig { return { @@ -79,6 +88,7 @@ test("a self-named namespace on a passthrough custom_tool_call is scrubbed befor status: 200, headers: { "content-type": "text/event-stream" }, })) as typeof fetch; + takeSpendHome(); const res = await handleResponses(request(), forwardConfig(), { model: "", provider: "" }); expect(res.status).toBe(200); const text = await res.text(); @@ -116,6 +126,7 @@ test("a self-named namespace declared by the current turn is preserved", async ( ], }; + takeSpendHome(); const res = await handleResponses(request(body), forwardConfig(), { model: "", provider: "" }); expect(res.status).toBe(200); const text = await res.text(); @@ -143,6 +154,7 @@ test("the reserved functions namespace does not create a same-name collision", a ], }; + takeSpendHome(); const res = await handleResponses(request(body), forwardConfig(), { model: "", provider: "" }); expect(res.status).toBe(200); const text = await res.text(); @@ -155,6 +167,7 @@ test("a self-named namespace on a passthrough bare function_call is scrubbed", a status: 200, headers: { "content-type": "text/event-stream" }, })) as typeof fetch; + takeSpendHome(); const res = await handleResponses(request(), forwardConfig(), { model: "", provider: "" }); expect(res.status).toBe(200); const text = await res.text(); @@ -178,6 +191,7 @@ test("a Chat-shaped function declaration still authorizes the bare function scru status: 200, headers: { "content-type": "text/event-stream" }, })) as typeof fetch; + takeSpendHome(); const res = await handleResponses(request(chatShaped), forwardConfig(), { model: "", provider: "" }); expect(res.status).toBe(200); const text = await res.text(); @@ -214,6 +228,7 @@ test("tool_choice for a namespaced custom tool cannot authorize a colliding bare ], }; + takeSpendHome(); const res = await handleResponses(request(body), forwardConfig(), { model: "", provider: "" }); expect(res.status).toBe(200); const text = await res.text(); @@ -248,6 +263,7 @@ test("mixed custom and function collisions are scoped to the response item type" ], }; + takeSpendHome(); const res = await handleResponses(request(body), forwardConfig(), { model: "", provider: "" }); expect(res.status).toBe(200); const text = await res.text(); @@ -271,6 +287,7 @@ test("a genuine MCP namespace on a passthrough call is left alone", async () => status: 200, headers: { "content-type": "text/event-stream" }, })) as typeof fetch; + takeSpendHome(); const res = await handleResponses(request(), forwardConfig(), { model: "", provider: "" }); const text = await res.text(); expect(text).toContain('"namespace":"mcp__docs"'); @@ -287,6 +304,7 @@ test("the bounded JSON (stream:false) passthrough path scrubs the same shape (#3 headers: { "content-type": "application/json", authorization: "Bearer test", "chatgpt-account-id": "acct" }, body: JSON.stringify({ ...requestBody, stream: false }), }); + takeSpendHome(); const res = await handleResponses(req, forwardConfig(), { model: "", provider: "" }); expect(res.status).toBe(200); const body = await res.json() as { output: Array> }; diff --git a/tests/responses/responses-send-budget-counts.test.ts b/tests/responses/responses-send-budget-counts.test.ts index 7585db3728e..b97e6f57832 100644 --- a/tests/responses/responses-send-budget-counts.test.ts +++ b/tests/responses/responses-send-budget-counts.test.ts @@ -14,6 +14,7 @@ import { mkdtempSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { saveCredential } from "../../src/oauth/store"; import { createRequestExecutionBudget } from "../../src/lib/request-execution-budget"; @@ -31,6 +32,16 @@ import { createRequestExecutionBudget } from "../../src/lib/request-execution-bu */ const originalFetch = globalThis.fetch; +// Every dispatching row below calls the handler directly, so it takes the spend-journal writer +// lease that startServer would have taken for it. Per row rather than per file: two rows install +// their own OPENCODEX_HOME, and a lease is bound to the directory in effect when it was taken. +// The teardown drop is a backstop for a row that throws mid-assertion, because a lease left +// behind makes the NEXT row's different home read as an ownership conflict rather than as this +// row's failure. +let releaseSpendHome: (() => void) | undefined; +const takeSpendHome = (): void => { releaseSpendHome = acquireOwnedSpendHome(); }; +const dropSpendHome = (): void => { releaseSpendHome?.(); releaseSpendHome = undefined; }; + beforeEach(() => { clearComboSelectionState(); clearComboTargetCooldowns(); @@ -38,6 +49,7 @@ beforeEach(() => { }); afterEach(() => { + dropSpendHome(); globalThis.fetch = originalFetch; setCachedCatalogForTests(null); clearComboSelectionState(); @@ -105,6 +117,9 @@ describe("upstream sends per logical request", () => { const previousJwtFlag = process.env.OPENCODEX_DEVIN_SEND_USER_JWT; const home = mkdtempSync(join(tmpdir(), "devin-send-count-")); process.env.OPENCODEX_HOME = home; + // Taken on the home this row just installed, and dropped in its finally before that home + // is removed: an open lease inside a directory being deleted fails the removal on Windows. + takeSpendHome(); delete process.env.OPENCODEX_DEVIN_SEND_USER_JWT; const apiKey = "devin-count-test"; // Devin is an OAuth-kind provider: the key the adapter ends up using is injected onto the @@ -149,6 +164,7 @@ describe("upstream sends per logical request", () => { totalSends: totalSends(logCtx), }, `status ${response.status}: ${body.slice(0, 200)}`).toEqual({ chatCalls: 1, totalSends: 1 }); } finally { + dropSpendHome(); if (previousHome === undefined) delete process.env.OPENCODEX_HOME; else process.env.OPENCODEX_HOME = previousHome; if (previousJwtFlag === undefined) delete process.env.OPENCODEX_DEVIN_SEND_USER_JWT; @@ -168,6 +184,7 @@ describe("upstream sends per logical request", () => { const previousJwtFlag = process.env.OPENCODEX_DEVIN_SEND_USER_JWT; const home = mkdtempSync(join(tmpdir(), "devin-send-denied-")); process.env.OPENCODEX_HOME = home; + takeSpendHome(); delete process.env.OPENCODEX_DEVIN_SEND_USER_JWT; const apiKey = "devin-denied-test"; await saveCredential("devin", { @@ -235,6 +252,7 @@ describe("upstream sends per logical request", () => { refused: true, }); } finally { + dropSpendHome(); if (previousHome === undefined) delete process.env.OPENCODEX_HOME; else process.env.OPENCODEX_HOME = previousHome; if (previousJwtFlag === undefined) delete process.env.OPENCODEX_DEVIN_SEND_USER_JWT; @@ -248,6 +266,7 @@ describe("upstream sends per logical request", () => { const upstream = alwaysFailing(502, "upstream busy"); const logCtx: RequestLogContext = { model: "", provider: "" }; + takeSpendHome(); const response = await handleResponses( responsesRequest("t0/model-t0"), { defaultProvider: "t0", providers: { t0: transientChatProvider("t0") } } as unknown as OcxConfig, @@ -267,6 +286,7 @@ describe("upstream sends per logical request", () => { const upstream = alwaysFailing(502, "upstream busy"); const logCtx: RequestLogContext = { model: "", provider: "" }; + takeSpendHome(); const response = await handleResponses(responsesRequest("combo/fan"), comboOverTargets(1), logCtx); expect(response.status).toBe(502); @@ -281,6 +301,7 @@ describe("upstream sends per logical request", () => { const upstream = alwaysFailing(502, "upstream busy"); const logCtx: RequestLogContext = { model: "", provider: "" }; + takeSpendHome(); const response = await handleResponses(responsesRequest("combo/fan"), comboOverTargets(3), logCtx); expect(response.status).toBe(502); @@ -311,6 +332,7 @@ describe("upstream sends per logical request", () => { const upstream = alwaysFailing(502, "upstream busy"); const logCtx: RequestLogContext = { model: "", provider: "" }; + takeSpendHome(); const response = await handleResponses(responsesRequest("combo/fan"), comboOverTargets(13), logCtx); expect(response.status).toBe(502); @@ -348,6 +370,7 @@ describe("ambiguous reset safety across Responses recovery", () => { throw Object.assign(new Error("The socket connection was closed unexpectedly."), { code: "ECONNRESET" }); }) as typeof fetch; const logCtx: RequestLogContext = { model: "", provider: "" }; + takeSpendHome(); const response = await handleResponses( responsesRequest(combo ? "combo/fan" : "t0/model-t0"), config, logCtx, ); @@ -372,6 +395,7 @@ describe("ambiguous reset safety across Responses recovery", () => { throw Object.assign(new Error("connection reset by peer"), { code: "ECONNRESET" }); }) as typeof fetch; const logCtx: RequestLogContext = { model: "", provider: "" }; + takeSpendHome(); const response = await handleResponses(responsesRequest("combo/fan"), comboOverTargets(2), logCtx); expect(response.status).toBe(429); expect((await response.json()).error.code).toBe("upstream_reset_replay_refused"); @@ -387,6 +411,7 @@ describe("ambiguous reset safety across Responses recovery", () => { sends += 1; throw Object.assign(new Error("reset"), { code: "ECONNRESET" }); }) as typeof fetch; + takeSpendHome(); const response = await handleResponses(responsesRequest("combo/fan"), config, { model: "", provider: "" }); expect(response.status).toBe(429); expect((await response.json()).error.code).toBe("upstream_reset_replay_refused"); @@ -407,6 +432,7 @@ describe("ambiguous reset safety after outer recovery", () => { throw Object.assign(new Error("connection reset by peer"), { code: "ECONNRESET" }); }) as typeof fetch; const logCtx: RequestLogContext = { model: "", provider: "" }; + takeSpendHome(); const response = await handleResponses(responsesRequest("combo/fan"), config, logCtx); expect(response.status).toBe(429); expect((await response.json()).error.code).toBe("upstream_reset_replay_refused"); @@ -435,6 +461,7 @@ describe("ambiguous reset safety after outer recovery", () => { throw Object.assign(new Error("connection reset by peer"), { code: "ECONNRESET" }); }) as typeof fetch; const logCtx: RequestLogContext = { model: "", provider: "" }; + takeSpendHome(); const response = await handleResponses(responsesRequest("t0/model-t0"), config, logCtx); expect(response.status).toBe(429); diff --git a/tests/responses/responses-shadow-intercept.test.ts b/tests/responses/responses-shadow-intercept.test.ts index feafd404dfc..d5cbdd680c4 100644 --- a/tests/responses/responses-shadow-intercept.test.ts +++ b/tests/responses/responses-shadow-intercept.test.ts @@ -14,10 +14,17 @@ import type { RequestLogContext } from "../../src/server/request-log"; import type { OcxConfig } from "../../src/types"; import { catalogConvergenceFactory } from "../helpers/catalog-convergence"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; const originalFetch = globalThis.fetch; +let releaseSpendHome: (() => void) | undefined; +// Taken only by rows that reach upstream through the direct handler helper. +const takeSpendHome = (): void => { releaseSpendHome = acquireOwnedSpendHome(); }; afterEach(() => { + // Released first so a failed dispatch cannot leak the writer lease into the next row. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; }); @@ -137,6 +144,7 @@ async function post( describe("shadow call intercept request path (issue #311)", () => { test("rewrites a gpt-5.6-luna helper call without overriding configured effort (#2706)", async () => { + takeSpendHome(); const bodies: Array> = []; globalThis.fetch = (async (_url: unknown, init?: RequestInit) => { bodies.push(JSON.parse(String(init?.body ?? "{}")) as Record); @@ -157,6 +165,7 @@ describe("shadow call intercept request path (issue #311)", () => { }); test("a self-target is a no-op instead of an intercept loop (#2706)", async () => { + takeSpendHome(); const bodies: Array> = []; const logCtx: RequestLogContext = { model: "", provider: "" }; globalThis.fetch = (async (_url: unknown, init?: RequestInit) => { @@ -183,6 +192,7 @@ describe("shadow call intercept request path (issue #311)", () => { }); test("rewrites a gpt-5.6-luna turn request too (#1684)", async () => { + takeSpendHome(); const bodies: Array> = []; const logCtx: RequestLogContext = { model: "", provider: "" }; globalThis.fetch = (async (_url: unknown, init?: RequestInit) => { @@ -206,6 +216,7 @@ describe("shadow call intercept request path (issue #311)", () => { // Recording the operator-configured prefix instead of the caller's raw string removes the // class, rather than adding one more pattern to a deny-list. test("the recorded marker is the configured prefix, never the caller's raw model string", async () => { + takeSpendHome(); const logCtx: RequestLogContext = { model: "", provider: "" }; globalThis.fetch = (async () => new Response(JSON.stringify({ choices: [{ message: { role: "assistant", content: "ok" }, finish_reason: "stop" }], @@ -222,6 +233,7 @@ describe("shadow call intercept request path (issue #311)", () => { }); test("a configured non-default prefix is recorded as itself", async () => { + takeSpendHome(); const logCtx: RequestLogContext = { model: "", provider: "" }; globalThis.fetch = (async () => new Response(JSON.stringify({ choices: [{ message: { role: "assistant", content: "ok" }, finish_reason: "stop" }], @@ -296,6 +308,7 @@ function chatOk(text: string): Response { describe("a combo shadow-call target enters the failover loop (#4129)", () => { test("a helper call rewritten to a combo hops past a 429 to the second target", async () => { + takeSpendHome(); const urls: string[] = []; const logCtx: RequestLogContext = { model: "", provider: "" }; globalThis.fetch = (async (url: unknown) => { @@ -327,6 +340,7 @@ describe("a combo shadow-call target enters the failover loop (#4129)", () => { }); test("a combo whose first target intersects the source still routes as a combo", async () => { + takeSpendHome(); const urls: string[] = []; const logCtx: RequestLogContext = { model: "", provider: "" }; globalThis.fetch = (async (url: unknown) => { @@ -360,6 +374,7 @@ describe("a combo shadow-call target enters the failover loop (#4129)", () => { }); test("a non-combo replacement still takes the ordinary late intercept", async () => { + takeSpendHome(); const urls: string[] = []; const logCtx: RequestLogContext = { model: "", provider: "" }; globalThis.fetch = (async (url: unknown) => { diff --git a/tests/responses/responses-show-thinking-summary.test.ts b/tests/responses/responses-show-thinking-summary.test.ts index a749518b63e..2fe5e8d5f07 100644 --- a/tests/responses/responses-show-thinking-summary.test.ts +++ b/tests/responses/responses-show-thinking-summary.test.ts @@ -6,6 +6,11 @@ import { providerConfigSeed } from "../../src/providers/derive"; import { getProviderRegistryEntry } from "../../src/providers/registry"; import { handleResponses } from "../../src/server/responses/core"; import type { OcxConfig, OcxProviderConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; + +let releaseInheritedSpendHome: (() => void) | undefined; +// Taken per inherited-home dispatch so mixed custom-home rows bind to their own directory. +const takeInheritedSpendHome = (): void => { releaseInheritedSpendHome = acquireOwnedSpendHome(); }; // Provider-opted visible thinking (showThinkingSummary): a provider that serves // genuine user-facing reasoning surfaces it on the summary channel even when the @@ -57,9 +62,15 @@ async function runHandleResponses(body: Record, seed: OcxProvid describe("showThinkingSummary provider option", () => { const originalFetch = globalThis.fetch; - afterEach(() => { globalThis.fetch = originalFetch; }); + afterEach(() => { + // Released first so a failed row cannot leak ownership into the next sandbox case. + releaseInheritedSpendHome?.(); + releaseInheritedSpendHome = undefined; + globalThis.fetch = originalFetch; + }); test("provider opt-in never relabels raw content as a summary", async () => { + takeInheritedSpendHome(); const response = await runHandleResponses( { model: "deepseek-v4-flash", input: "ping", stream: true }, shownSeed(), @@ -70,6 +81,7 @@ describe("showThinkingSummary provider option", () => { }); test("explicit client summary none keeps thinking hidden", async () => { + takeInheritedSpendHome(); const response = await runHandleResponses( { model: "deepseek-v4-flash", input: "ping", stream: true, reasoning: { summary: "none" } }, shownSeed(), @@ -80,6 +92,7 @@ describe("showThinkingSummary provider option", () => { }); test("without the provider option, omitted summary stays hidden", async () => { + takeInheritedSpendHome(); const seed = { ...providerConfigSeed(getProviderRegistryEntry("deepseek")!), apiKey: "sk-test" } as OcxProviderConfig; const response = await runHandleResponses( { model: "deepseek-v4-flash", input: "ping", stream: true }, @@ -101,6 +114,8 @@ describe("showThinkingSummary provider option", () => { const home = mkdtempSync(join(tmpdir(), "ocx-show-thinking-")); const prevHome = process.env.OPENCODEX_HOME; process.env.OPENCODEX_HOME = home; + // Taken after this row installs its home so the direct dispatch owns that journal. + const releaseSpendHome = acquireOwnedSpendHome(); writeFileSync(join(home, "auth.json"), JSON.stringify({ "google-antigravity": { activeAccountId: "active", @@ -165,6 +180,8 @@ describe("showThinkingSummary provider option", () => { if (stream) expect(text).toContain("response.completed"); expect(text).toContain("OK"); } finally { + // Released before restoring or removing the home so its lease files can be deleted. + releaseSpendHome(); if (prevHome === undefined) delete process.env.OPENCODEX_HOME; else process.env.OPENCODEX_HOME = prevHome; rmSync(home, { recursive: true, force: true }); diff --git a/tests/responses/responses-snapshot-repair-server.test.ts b/tests/responses/responses-snapshot-repair-server.test.ts index 26aeabb8e98..3b4f1230b0f 100644 --- a/tests/responses/responses-snapshot-repair-server.test.ts +++ b/tests/responses/responses-snapshot-repair-server.test.ts @@ -13,6 +13,11 @@ import { import type { OcxConfig } from "../../src/types"; import { installIsolatedCodexHome, type IsolatedCodexHome } from "../helpers/isolated-codex-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; + +// Case-local, never file-wide: the other rows start a real server that takes the same lease. +let releaseSpendHome: (() => void) | undefined; +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; setDefaultTimeout(30_000); @@ -118,6 +123,8 @@ beforeEach(() => { }); afterEach(async () => { + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; await isolated.restore(); removeTreeWithRetry(TEST_DIR); @@ -252,6 +259,9 @@ describe("responsesSnapshotRepair through /v1/responses", () => { }, } as OcxConfig; + // This row calls the handler directly instead of going through the server the other rows + // start, so it takes the writer lease itself. Dropped in the file's own teardown. + takeSpendHome(); const response = await handleResponses( new Request("http://localhost/v1/responses", { method: "POST", @@ -508,6 +518,8 @@ describe("responsesSnapshotRepair through /v1/responses", () => { test("sparse JSON completion inference precedes function repair in client output and replay", async () => { const expected = '{"cell_id":"4","yield_time_ms":120000}'; + // Dispatches directly rather than through a server, so it takes the lease itself. + takeSpendHome(); const item = { type: "function_call", id: "fc_sparse_wait", call_id: "call_sparse_wait", name: "wait", arguments: '{"cell_id":4,"yield_time_ms":120000.0}' }; let responseId = `resp_sparse_${crypto.randomUUID()}`; let capturedInput: Array> = []; diff --git a/tests/responses/responses-stateless-dangling-call-repair.test.ts b/tests/responses/responses-stateless-dangling-call-repair.test.ts index 13b30573d9b..8e8c52ba15c 100644 --- a/tests/responses/responses-stateless-dangling-call-repair.test.ts +++ b/tests/responses/responses-stateless-dangling-call-repair.test.ts @@ -13,8 +13,10 @@ import { providerConfigSeed } from "../../src/providers/derive"; import { getProviderRegistryEntry } from "../../src/providers/registry"; import { handleResponses } from "../../src/server/responses/core"; import type { OcxConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; const MODEL = "deepseek-v4-flash"; +let releaseSpendHome: (() => void) | undefined; function deepseekProvider(): ReturnType & { apiKey: string } { return { ...providerConfigSeed(getProviderRegistryEntry("deepseek")!), apiKey: "sk-test" }; @@ -22,7 +24,12 @@ function deepseekProvider(): ReturnType & { apiKey: s describe("stateless Responses wire repairs orphaned tool calls", () => { const originalFetch = globalThis.fetch; - afterEach(() => { globalThis.fetch = originalFetch; }); + afterEach(() => { + // Release the lease before later teardown can replace the preload sandbox home. + releaseSpendHome?.(); + releaseSpendHome = undefined; + globalThis.fetch = originalFetch; + }); async function drive(input: unknown[]): Promise<{ url: string; body: Record }> { const requests: Array<{ url: string; body: Record }> = []; @@ -34,6 +41,8 @@ describe("stateless Responses wire repairs orphaned tool calls", () => { return Response.json({ id: "resp_deepseek", object: "response", status: "completed", output: [] }); }) as typeof fetch; const config = { providers: { deepseek: deepseekProvider() } } as unknown as OcxConfig; + // Direct dispatch needs the writer lease that prevents spend-ledger ownership failures. + releaseSpendHome = acquireOwnedSpendHome(); await handleResponses( new Request("http://localhost/v1/responses", { method: "POST", diff --git a/tests/responses/responses-tool-search-repair.test.ts b/tests/responses/responses-tool-search-repair.test.ts index d415fff16eb..392aa00a5ec 100644 --- a/tests/responses/responses-tool-search-repair.test.ts +++ b/tests/responses/responses-tool-search-repair.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, test } from "bun:test"; +import { afterEach, describe, expect, test } from "bun:test"; import { isTranslatorBudgetExceededError } from "../../src/lib/translator-budget"; import { restoreRoutedToolSearchCallsInJson, @@ -7,8 +7,16 @@ import { import { createRoutedToolSearchRestoreBlockRewrite } from "../../src/server/responses-tool-search-repair"; import { handleResponses } from "../../src/server/responses"; import type { OcxConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { createTestTranslatorBudget } from "../helpers/translator-budget"; +let releaseSpendHome: (() => void) | undefined; +afterEach(() => { + // Release the lease before later teardown can replace the preload sandbox home. + releaseSpendHome?.(); + releaseSpendHome = undefined; +}); + function frame(event: string, payload: Record): string { return `event: ${event}\ndata: ${JSON.stringify({ type: event, ...payload })}`; } @@ -349,6 +357,8 @@ describe("routed Responses tool-search compatibility", () => { }) as typeof fetch; try { + // Direct dispatch needs the writer lease that prevents spend-ledger ownership failures. + releaseSpendHome = acquireOwnedSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -395,6 +405,7 @@ describe("routed Responses tool-search compatibility", () => { }) as typeof fetch; try { + releaseSpendHome = acquireOwnedSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -433,6 +444,7 @@ describe("routed Responses tool-search compatibility", () => { }) as typeof fetch; try { + releaseSpendHome = acquireOwnedSpendHome(); await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -495,6 +507,7 @@ describe("routed Responses tool-search compatibility", () => { }), { headers: { "content-type": "application/json" } })) as typeof fetch; try { + releaseSpendHome = acquireOwnedSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, diff --git a/tests/responses/responses-undeclared-tool-guard.test.ts b/tests/responses/responses-undeclared-tool-guard.test.ts index d0e4000bde1..99a50b2b1a7 100644 --- a/tests/responses/responses-undeclared-tool-guard.test.ts +++ b/tests/responses/responses-undeclared-tool-guard.test.ts @@ -4,7 +4,7 @@ * with the target file untouched. The bridged paths already fail closed on the same condition * (`declaredToolNames`, src/bridge/sse.ts); these pin the passthrough's equivalent. */ -import { describe, expect, test } from "bun:test"; +import { afterEach, describe, expect, test } from "bun:test"; import { collectDeclaredNamelessClientCallTypes, collectDeclaredBareWireToolNames, @@ -25,6 +25,15 @@ import { handleResponses } from "../../src/server/responses"; import { expandPreviousResponseInput } from "../../src/responses/state"; import type { OcxConfig } from "../../src/types"; import { createTestTranslatorBudget } from "../helpers/translator-budget"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; +import { readAll, streamFromText } from "../helpers/sse-stream"; + +// A case that calls handleResponses directly never runs startServer, so it never takes the +// spend-journal writer lease and its dispatch is refused before it reaches its own contract. +// Dropped in teardown so a case that throws mid-assertion cannot leave the lease behind. +let releaseSpendHome: (() => void) | undefined; +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; +afterEach(() => { releaseSpendHome?.(); releaseSpendHome = undefined; }); /** One SSE event block without its blank-line delimiter. */ function frame(type: string, payload: Record): string { @@ -36,33 +45,6 @@ function sse(type: string, payload: Record): string { return `${frame(type, payload)}\n\n`; } -function streamFromText(text: string): ReadableStream { - const chunk = new TextEncoder().encode(text); - let sent = false; - return new ReadableStream({ - pull(controller) { - if (sent) { - controller.close(); - return; - } - sent = true; - controller.enqueue(chunk); - }, - }); -} - -async function readAll(stream: ReadableStream): Promise { - const reader = stream.getReader(); - const decoder = new TextDecoder(); - let text = ""; - for (;;) { - const { done, value } = await reader.read(); - if (done) break; - text += decoder.decode(value, { stream: true }); - } - return text; -} - async function relay( upstream: string, declared: Iterable, @@ -810,6 +792,7 @@ describe("the reported turn, end to end through handleResponses", () => { const savedFetch = globalThis.fetch; globalThis.fetch = (async () => upstream()) as typeof fetch; try { + takeSpendHome(); return await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -949,6 +932,7 @@ describe("a refused turn does not become continuation state", () => { { headers: { "content-type": "application/json" } }, )) as typeof fetch; try { + takeSpendHome(); return await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -1056,6 +1040,7 @@ describe("a refused turn does not become continuation state", () => { })) as typeof fetch; let response: Response; try { + takeSpendHome(); response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -1119,6 +1104,7 @@ describe("a refused turn does not become continuation state", () => { })) as typeof fetch; let response: Response; try { + takeSpendHome(); response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -1208,6 +1194,7 @@ describe("real relay and continuation caller normalization (#4176 / #4181)", () }), }); + takeSpendHome(); const turn1Res = await handleResponses(turn1Req, config, { model: "", provider: "" }); expect(turn1Res.status).toBe(200); const clientStreamText = await turn1Res.text(); @@ -1240,6 +1227,7 @@ describe("real relay and continuation caller normalization (#4176 / #4181)", () }), }); + takeSpendHome(); const turn2Res = await handleResponses(turn2Req, config, { model: "", provider: "" }); expect(turn2Res.status).toBe(200); await turn2Res.json(); @@ -1278,6 +1266,7 @@ describe("real relay and continuation caller normalization (#4176 / #4181)", () })) as typeof fetch; try { + takeSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -1315,6 +1304,7 @@ describe("real relay and continuation caller normalization (#4176 / #4181)", () })) as typeof fetch; try { + takeSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -1389,6 +1379,7 @@ describe("empty and absent tool catalogs", () => { const savedFetch = globalThis.fetch; globalThis.fetch = (async () => upstream()) as typeof fetch; try { + takeSpendHome(); return await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -2324,6 +2315,7 @@ describe("xAI hosted-call authorization through handleResponses", () => { }); }) as typeof fetch; try { + takeSpendHome(); return await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, diff --git a/tests/responses/ws-native-steering.test.ts b/tests/responses/ws-native-steering.test.ts index e2e99831093..dfa89bed85d 100644 --- a/tests/responses/ws-native-steering.test.ts +++ b/tests/responses/ws-native-steering.test.ts @@ -10,6 +10,15 @@ import { getRequestLogEntries, clearRequestLogsForTests } from "../../src/server import { runOptionalShutdownHooks } from "../../src/lib/optional-shutdown-hooks"; import { MAX_ACTIVE_TURNS, tryAdmitTurn } from "../../src/server/lifecycle"; import { configSchema } from "../../src/config/schema/config-schema"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; + +// The websocket handler dispatches through the real request path, so it reaches the shared spend +// journal and needs the writer lease startServer would have taken. Without it the turn is refused +// and the symptom is this file's own waitFor timing out, which names nothing. +let releaseSpendHome: (() => void) | undefined; +// Every synthetic client this file opens, so teardown can close them before the lease is given +// back rather than leaving a handler mid-turn against a journal nobody owns. +const clients: Array> = []; type Frame = Record; const realSocket = globalThis.WebSocket; @@ -48,12 +57,14 @@ const waitFor = async (condition: () => boolean) => { throw new Error("fixture condition timed out"); }; function downstream(fields: Frame = {}, settings = config(), credential = "test") { + releaseSpendHome ??= acquireOwnedSpendHome(); const handler = createWebsocketHandler({ config: settings, deps: {} } as ServeOptionsContext); const sent: Frame[] = []; const ws = { readyState: 1, data: { headers: new Headers({ authorization: `Bearer ${credential}`, "thread-id": `fixture-${credential}`, session_id: `fixture-${credential}` }) } as WsData, send: (text: string) => { sent.push(JSON.parse(text)); return 1; }, close() { handler.close(ws); }, } as unknown as ServerWebSocket; const send = (frame: Frame) => handler.message(ws, JSON.stringify(frame)); + clients.push(ws); send({ type: "response.create", model: "gpt-5.5", input: "initial", ...fields }); return { ws, sent, send, handler }; } @@ -78,13 +89,40 @@ beforeEach(() => { globalThis.fetch = (async () => { fallbackCalls++; throw new Error("unexpected network/fallback in native steering fixture"); }) as typeof fetch; clearRequestLogsForTests(); }); -afterEach(() => { - for (const socket of Socket.all) socket.close(); - Socket.all = []; - runOptionalShutdownHooks(); - globalThis.WebSocket = realSocket; - globalThis.fetch = realFetch; - for (const key of proxyKeys) { delete process.env[key]; if (savedProxy[key] !== undefined) process.env[key] = savedProxy[key]; } +afterEach(async () => { + // handler.close only STARTS the pump cancellation. Waiting for the socket to drop its stream + // cancel and its native control is what proves the turn finished accounting; releasing the + // lease before that leaves a reader settling against a journal nobody owns. + // + // The rest runs even when that wait gives up, and the failure still propagates. A wait that + // expired is NOT evidence the turn settled: it means this fixture could not prove it, and the + // case should say so while still handing back the lease and the globals it replaced. + let failure: unknown; + const note = (error: unknown): void => { failure ??= error; }; + try { + // Every client gets its close and its wait even after an earlier one gave up. Stopping at + // the first failure left the rest open for the next case to inherit. + for (const client of clients.splice(0)) { + // Separate guards: close() runs the production handler, so a throw there would otherwise + // skip this client's completion wait as well as its own failure. + try { client.close(); } catch (error) { note(error); } + try { + await waitFor(() => client.data.cancel === undefined && client.data.nativeControl === undefined); + } catch (error) { note(error); } + } + for (const socket of Socket.all) { + try { socket.close(); } catch (error) { note(error); } + } + Socket.all = []; + try { runOptionalShutdownHooks(); } catch (error) { note(error); } + // The release itself can throw, and it used to take the global restore down with it. + try { releaseSpendHome?.(); } catch (error) { note(error); } finally { releaseSpendHome = undefined; } + } finally { + globalThis.WebSocket = realSocket; + globalThis.fetch = realFetch; + for (const key of proxyKeys) { delete process.env[key]; if (savedProxy[key] !== undefined) process.env[key] = savedProxy[key]; } + } + if (failure !== undefined) throw failure; }); test("configuration is explicit opt-in and malformed values fail closed", () => { diff --git a/tests/responses/ws-upstream.test.ts b/tests/responses/ws-upstream.test.ts index 62a00888dc3..8ea36d1349b 100644 --- a/tests/responses/ws-upstream.test.ts +++ b/tests/responses/ws-upstream.test.ts @@ -30,9 +30,10 @@ import { } from "../../src/server/responses/ws-upstream"; import type { OcxProviderConfig } from "../../src/types"; import type { OcxConfig } from "../../src/types"; +import { BOUNDED_WS_RUNTIME, codexWsUpstreamFetch, shouldUseCodexWsUpstream, streamingInit } from "../helpers/ws-upstream-fixtures"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; const CODEX_URL = "https://chatgpt.com/backend-api/codex/responses"; -const BOUNDED_WS_RUNTIME = "1.4.0"; // #864 keeps win32 rewrite traffic out of the tee()+JS-pull chain, so // `isWin32EagerRewrite(platform, needsClientRewrite)` sends it through the eager @@ -45,26 +46,6 @@ const BOUNDED_WS_RUNTIME = "1.4.0"; // constant that only held before the backfill landed. const EAGER_RELAY_FORCED_BY_PLATFORM = isWin32EagerRewrite(process.platform, true); -function shouldUseCodexWsUpstream(url: string, init?: RequestInit, upstreamWebsocket = false): boolean { - return rawShouldUseCodexWsUpstream(url, init, BOUNDED_WS_RUNTIME, upstreamWebsocket); -} - -function codexWsUpstreamFetch( - url: string, - init: RequestInit, - fallback: typeof fetch, -): Promise { - return rawCodexWsUpstreamFetch(url, init, fallback, BOUNDED_WS_RUNTIME); -} - -function streamingInit(body: Record = {}): RequestInit { - return { - method: "POST", - headers: { "content-type": "application/json", authorization: "Bearer test" }, - body: JSON.stringify({ model: "gpt-5.5", stream: true, ...body }), - }; -} - describe("shouldUseCodexWsUpstream", () => { test("uses HTTP SSE on runtimes without a bounded response sink", async () => { expect(bunSupportsBoundedCodexWsRelay("1.3.14")).toBe(false); @@ -234,7 +215,14 @@ beforeEach(() => { for (const key of PROXY_ENV_KEYS) delete process.env[key]; }); +// A case that calls handleResponses directly never takes the writer lease startServer takes, +// so its dispatch is refused. Dropped in teardown so a throwing case cannot leave it behind. +let releaseSpendHome: (() => void) | undefined; +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; + afterEach(() => { + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.WebSocket = RealWebSocket; globalThis.fetch = RealFetch; FakeWebSocket.instances = []; @@ -467,6 +455,7 @@ describe("handleResponses Codex WS relay selection", () => { const config = { ...forwardConfig(), plaintextV2AgentMessages: true } as OcxConfig; const request = plaintextV2CollaborationRequest(); + takeSpendHome(); const response = await handleResponses(request, config, { model: "", provider: "" }, { codexWsRuntimeIdentity: BOUNDED_WS_RUNTIME, }); @@ -532,6 +521,7 @@ describe("handleResponses Codex WS relay selection", () => { }); const config = { ...forwardConfig(), plaintextV2AgentMessages: true } as OcxConfig; + takeSpendHome(); const response = await handleResponses( plaintextV2CollaborationRequest(), config, @@ -558,6 +548,7 @@ describe("handleResponses Codex WS relay selection", () => { }); }); + takeSpendHome(); const response = await handleResponses(request(), forwardConfig(), { model: "", provider: "" }, { codexWsRuntimeIdentity: BOUNDED_WS_RUNTIME, }); @@ -580,6 +571,7 @@ describe("handleResponses Codex WS relay selection", () => { { status: 200, headers: { "content-type": "text/event-stream" } }, )) as typeof fetch; + takeSpendHome(); const response = await handleResponses(request(), forwardConfig(), { model: "", provider: "" }, { codexWsRuntimeIdentity: BOUNDED_WS_RUNTIME, }); @@ -601,6 +593,7 @@ describe("handleResponses Codex WS relay selection", () => { }); const logCtx = { model: "", provider: "" }; + takeSpendHome(); const response = await handleResponses(request(), forwardConfig(), logCtx, { codexWsRuntimeIdentity: BOUNDED_WS_RUNTIME, }); @@ -620,6 +613,7 @@ describe("handleResponses Codex WS relay selection", () => { }); const logCtx = { model: "", provider: "" }; + takeSpendHome(); const response = await handleResponses(request(), forwardConfig(), logCtx, { codexWsRuntimeIdentity: BOUNDED_WS_RUNTIME, }); @@ -644,6 +638,7 @@ describe("handleResponses Codex WS relay selection", () => { { status: 200, headers: { "content-type": "text/event-stream" } }, )) as typeof fetch; + takeSpendHome(); const response = await handleResponses(request(), forwardConfig(), { model: "", provider: "" }); expect(FakeWebSocket.instances).toHaveLength(0); @@ -681,6 +676,7 @@ describe("handleResponses Codex WS relay selection", () => { { status: 200, headers: { "content-type": "text/event-stream" } }, )) as typeof fetch; + takeSpendHome(); const response = await handleResponses(request(), forwardConfig(), { model: "", provider: "" }); const text = await response.text(); @@ -729,6 +725,7 @@ describe("codexWsUpstreamFetch", () => { ws.emit("message", { data: JSON.stringify({ type: "response.completed", response: { id: "r1", status: "completed", output: [] } }) }); }; globalThis.WebSocket = CapturingSocket as unknown as typeof WebSocket; + takeSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { authorization: "Bearer fixture", "content-type": "application/json", "x-openai-internal-codex-responses-lite": "true" }, diff --git a/tests/routing/combo-management-api.test.ts b/tests/routing/combo-management-api.test.ts index ba6bd7e2d03..7bdd2fb69e1 100644 --- a/tests/routing/combo-management-api.test.ts +++ b/tests/routing/combo-management-api.test.ts @@ -41,6 +41,7 @@ import type { OcxConfig } from "../../src/types"; import { syncCatalogModels } from "../../src/codex/catalog"; import { injectClaudeAgentDefs } from "../../src/claude/agents-inject"; import { catalogConvergenceFactory } from "../helpers/catalog-convergence"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; const VALID_COMBO = { targets: [{ provider: "a", model: "m1" }] }; @@ -1250,6 +1251,8 @@ describe("supported disabled-provider activation", () => { return Response.json({ error: { message: "default provider must not be reached" } }, { status: 500 }); }, }); + // Taken after withTempHome installs this case's home so physical dispatch owns its ledger. + const releaseSpendHome = acquireOwnedSpendHome(); try { const config = baseConfig({ defaultProvider: "c", @@ -1283,9 +1286,13 @@ describe("supported disabled-provider activation", () => { headers: { "content-type": "application/json" }, body: JSON.stringify({ model: "combo/free", input: "hello", stream: false }), }), config, { model: "", provider: "" }); - expect(routed.status).toBe(200); - expect(bHits).toBe(1); - expect(cHits).toBe(0); + try { + expect(routed.status).toBe(200); + expect(bHits).toBe(1); + expect(cHits).toBe(0); + } finally { + await routed.body?.cancel(); + } expect((await comboApi(config, "PATCH", "/api/providers?name=b", { disabled: true }))?.status).toBe(200); const diagnostics = readConfigDiagnostics(); @@ -1305,6 +1312,8 @@ describe("supported disabled-provider activation", () => { expect(bHits).toBe(1); expect(cHits).toBe(0); } finally { + // Released before withTempHome removes the directory, preventing a live database there. + releaseSpendHome(); await upstreamB.stop(true); await upstreamC.stop(true); } @@ -1335,6 +1344,8 @@ describe("combo response-path strategy accounting", () => { let bHits = 0; const upstreamA = Bun.serve({ hostname: "127.0.0.1", port: 0, fetch() { aHits += 1; return completion("a"); } }); const upstreamB = Bun.serve({ hostname: "127.0.0.1", port: 0, fetch() { bHits += 1; return completion("b"); } }); + // Taken after the inherited test home is in effect so both physical dispatches can record. + const releaseSpendHome = acquireOwnedSpendHome(); try { const config = baseConfig({ providers: { @@ -1343,10 +1354,22 @@ describe("combo response-path strategy accounting", () => { }, combos: { free: { strategy: "least-used", targets: [{ provider: "a", model: "m1" }, { provider: "b", model: "m2" }] } }, }); - expect((await handleResponses(responseRequest(), config, { model: "", provider: "" })).status).toBe(200); - expect((await handleResponses(responseRequest(), config, { model: "", provider: "" })).status).toBe(200); + const first = await handleResponses(responseRequest(), config, { model: "", provider: "" }); + try { + expect(first.status).toBe(200); + } finally { + await first.body?.cancel(); + } + const second = await handleResponses(responseRequest(), config, { model: "", provider: "" }); + try { + expect(second.status).toBe(200); + } finally { + await second.body?.cancel(); + } expect({ aHits, bHits }).toEqual({ aHits: 1, bHits: 1 }); } finally { + // Released after both bodies are cancelled so no stream retains the ledger owner. + releaseSpendHome(); await upstreamA.stop(true); await upstreamB.stop(true); } @@ -1361,6 +1384,8 @@ describe("combo response-path strategy accounting", () => { fetch() { aHits += 1; return Response.json({ error: { message: "busy" } }, { status: 429, headers: { "retry-after": "60" } }); }, }); const upstreamB = Bun.serve({ hostname: "127.0.0.1", port: 0, fetch() { bHits += 1; return completion("b"); } }); + // Taken after the inherited test home is in effect so failover dispatch can record its sends. + const releaseSpendHome = acquireOwnedSpendHome(); try { const config = baseConfig({ providers: { @@ -1370,10 +1395,16 @@ describe("combo response-path strategy accounting", () => { combos: { free: { strategy: "reset-window", targets: [{ provider: "a", model: "m1" }, { provider: "b", model: "m2" }] } }, }); const response = await handleResponses(responseRequest(), config, { model: "", provider: "" }); - expect(response.status).toBe(200); - expect({ aHits, bHits }).toEqual({ aHits: 1, bHits: 1 }); - expect(isComboTargetInCooldown("free", { provider: "a", model: "m1" })).toBe(true); + try { + expect(response.status).toBe(200); + expect({ aHits, bHits }).toEqual({ aHits: 1, bHits: 1 }); + expect(isComboTargetInCooldown("free", { provider: "a", model: "m1" })).toBe(true); + } finally { + await response.body?.cancel(); + } } finally { + // Released after the response body is cancelled so no stream retains the ledger owner. + releaseSpendHome(); await upstreamA.stop(true); await upstreamB.stop(true); } diff --git a/tests/routing/fastwire-characterization-wire.test.ts b/tests/routing/fastwire-characterization-wire.test.ts index 7d3c01d0dc1..5f4d3f6380e 100644 --- a/tests/routing/fastwire-characterization-wire.test.ts +++ b/tests/routing/fastwire-characterization-wire.test.ts @@ -6,10 +6,17 @@ import * as adapterResolveModule from "../../src/server/adapter-resolve"; import type { RequestLogContext } from "../../src/server/request-log"; import { handleResponses } from "../../src/server/responses/core"; import type { OcxConfig, OcxProviderConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; const originalFetch = globalThis.fetch; +let releaseSpendHome: (() => void) | undefined; +// Direct dispatch needs the writer lease that prevents spend-ledger ownership failures. +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; afterEach(() => { + // Release the lease before later teardown can replace the preload sandbox home. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; }); @@ -45,7 +52,8 @@ async function driveResponses(args: { ...(args.callerTier === undefined ? {} : { service_tier: args.callerTier }), }; - await handleResponses( + takeSpendHome(); + const turn = await handleResponses( new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -56,6 +64,9 @@ async function driveResponses(args: { {}, ); + // The turn's body is a live stream. Releasing it here means no reader is still attached when + // the lease is dropped, which is what turns a finished case into a pending one. + await turn.body?.cancel(); expect(bodies).toHaveLength(1); return { outboundBody: bodies[0]!, logCtx }; } @@ -355,7 +366,9 @@ describe("FastWire characterization: rawBody observation point", () => { }), }); - await handleResponses(request, config, { model: "", provider: "" }, {}); + takeSpendHome(); + const turn = await handleResponses(request, config, { model: "", provider: "" }, {}); + await turn.body?.cancel(); expect(outboundBody?.service_tier).toBe("priority"); expect(adapterRawBody?.service_tier).toBe("flex"); } finally { diff --git a/tests/routing/fastwire-observability.test.ts b/tests/routing/fastwire-observability.test.ts index 0ced61dd44e..587f98242fd 100644 --- a/tests/routing/fastwire-observability.test.ts +++ b/tests/routing/fastwire-observability.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, test } from "bun:test"; +import { afterEach, describe, expect, test } from "bun:test"; import type { AdapterRequest } from "../../src/adapters/base"; import { createOpenAIChatAdapter } from "../../src/adapters/openai-chat"; import { createResponsesPassthroughAdapter } from "../../src/adapters/openai-responses"; @@ -26,6 +26,14 @@ import { estimateComboCost, serviceTierContextFromOutcome } from "../../src/usag import type { ExpectedPriceOverlay } from "../../src/usage/expected-prices"; import { normalizeUsageEntryForTest } from "../../src/usage/log"; import { createTestTranslatorBudget, withTestTranslatorBudget } from "../helpers/translator-budget"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; + +let releaseSpendHome: (() => void) | undefined; +afterEach(() => { + // Release the lease before later teardown can replace the preload sandbox home. + releaseSpendHome?.(); + releaseSpendHome = undefined; +}); const SERVICE_WIRE = { kind: "service-tier" as const, @@ -491,6 +499,8 @@ describe("FastWire logging and persistence", () => { }) as typeof fetch; const logCtx: RequestLogContext = { model: "", provider: "" }; try { + // Direct dispatch needs the writer lease that prevents spend-ledger ownership failures. + releaseSpendHome = acquireOwnedSpendHome(); const response = await handleResponses( new Request("http://localhost/v1/responses", { method: "POST", diff --git a/tests/routing/probe-lease-dispatch-wiring.test.ts b/tests/routing/probe-lease-dispatch-wiring.test.ts index 00c4a6b942e..e1d372ddb39 100644 --- a/tests/routing/probe-lease-dispatch-wiring.test.ts +++ b/tests/routing/probe-lease-dispatch-wiring.test.ts @@ -30,6 +30,7 @@ import { saveCodexAccountCredential } from "../../src/codex/account-store"; import { clearAccountQuota, updateAccountQuota } from "../../src/codex/auth-api"; import { handleResponses } from "../../src/server/responses"; import type { OcxConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; /** @@ -104,6 +105,8 @@ describe("recovery limiter wiring is reachable from production (#4701)", () => { }, } as OcxConfig; + // Acquire on the installed test home so this physical dispatch can open the spend journal. + const releaseSpendHome = acquireOwnedSpendHome(); try { const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", @@ -115,6 +118,8 @@ describe("recovery limiter wiring is reachable from production (#4701)", () => { expect(response.status).toBe(200); expect(sharedPoolBackpressure().state().initialSends).toBe(1); } finally { + // Release before afterEach removes the home to prevent Windows removal failures. + releaseSpendHome(); globalThis.fetch = originalFetch; } }); diff --git a/tests/routing/routing-policy-surface-parity.test.ts b/tests/routing/routing-policy-surface-parity.test.ts index d73c5ff483f..5bdd93161a7 100644 --- a/tests/routing/routing-policy-surface-parity.test.ts +++ b/tests/routing/routing-policy-surface-parity.test.ts @@ -11,6 +11,7 @@ import type { AdapterEvent, OcxConfig, OcxProviderConfig } from "../../src/types import { clearRequestLogsForTests, type RequestLogContext } from "../../src/server/request-log"; import { readUsageEntries } from "../../src/usage/log"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; const MODEL = "policy/daily"; const EXPECTED_RICH_EVIDENCE = { @@ -125,8 +126,15 @@ mock.module("../../src/server/adapter-resolve", () => ({ const { handleResponses, handleResponsesCompact } = await import("../../src/server/responses"); const { handleChatCompletions } = await import("../../src/server/chat-completions"); const { handleClaudeMessages } = await import("../../src/server/claude-messages"); +let releaseSpendHome: (() => void) | undefined; + +// Taken only by handler rows whose fixture adapter produces a dispatched response. +const takeSpendHome = (): void => { releaseSpendHome = acquireOwnedSpendHome(); }; afterEach(() => { + // Released first so a failed handler row cannot leak ownership into the next case. + releaseSpendHome?.(); + releaseSpendHome = undefined; adapterFactory = undefined; }); @@ -224,6 +232,7 @@ describe("routing policy request evidence parity (via dev handlers)", () => { } }); test("rich evidence (tools + image) produces identical route decision across all three surfaces", async () => { + takeSpendHome(); adapterFactory = minimalSuccessAdapter; const config = testConfig(); @@ -345,6 +354,7 @@ describe("routing policy request evidence parity (via dev handlers)", () => { }); test("plain text with no tools produces no hard requirements on every surface", async () => { + takeSpendHome(); adapterFactory = minimalSuccessAdapter; const config = testConfig(); diff --git a/tests/routing/subagent-fallback-handle-responses.test.ts b/tests/routing/subagent-fallback-handle-responses.test.ts index fb236802e1d..cc7eca13c0a 100644 --- a/tests/routing/subagent-fallback-handle-responses.test.ts +++ b/tests/routing/subagent-fallback-handle-responses.test.ts @@ -9,6 +9,7 @@ import { mkdtempSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { saveCodexAccountCredential } from "../../src/codex/account-store"; +import { setRelayPlatformForTests } from "../../src/server/responses/passthrough-delivery"; import { clearAccountQuota, updateAccountQuota, @@ -43,6 +44,7 @@ import { encryptedInput as recoverableEncryptedInput, recoverySse, } from "../helpers/agent-task-recovery"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; setDefaultTimeout(30_000); @@ -52,6 +54,7 @@ const originalNow = Date.now; let testDir: string; let previousOpencodexHome: string | undefined; let previousCodexHome: string | undefined; +let releaseSpendHome: (() => void) | undefined; beforeEach(() => { testDir = mkdtempSync(join(tmpdir(), "ocx-subagent-hr-")); @@ -59,6 +62,8 @@ beforeEach(() => { previousCodexHome = process.env.CODEX_HOME; process.env.OPENCODEX_HOME = testDir; process.env.CODEX_HOME = testDir; + // Direct handler dispatches need the writer lease that startServer normally holds. + releaseSpendHome = acquireOwnedSpendHome(); clearThreadAccountMap(); clearCodexUpstreamHealth(); clearAccountQuota(); @@ -71,6 +76,9 @@ beforeEach(() => { }); afterEach(() => { + // Release before home teardown to prevent Windows removal failures and a live unlinked database. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; Date.now = originalNow; clearThreadAccountMap(); @@ -2150,9 +2158,16 @@ describe("native passthrough terminal finalization", () => { const terminals: ResponsesTerminalStatus[] = []; mockSseUpstream(sseBody); - const platformDescriptor = Object.getOwnPropertyDescriptor(process, "platform"); - // Force win32 so eager-relay decision path is reachable via streamMode override. - Object.defineProperty(process, "platform", { value: "win32", configurable: true }); + // darwin, not win32, because this pair is about streamMode choosing the path. On win32 a + // turn that needs a client rewrite takes the eager relay unconditionally (#864), so the + // legacy half could never be legacy there and the marker assertion below would be a lie. + // darwin is the platform where the configured mode actually decides. + // + // The claim is also narrowed to the relay decision itself: overwriting process.platform + // globally redirects filesystem, ACL and state-directory identity too, and the spend-ledger + // owner lowercases its home on win32, which on a case-sensitive filesystem is a different + // directory. That made the send unreservable and the turn delivered no terminal at all. + setRelayPlatformForTests("darwin"); try { const response = await postSpawn( cfg, @@ -2161,6 +2176,12 @@ describe("native passthrough terminal finalization", () => { onNativePassthroughTerminal: (status) => terminals.push(status), }, ); + // Asserted before the callback is inspected, so a turn that never delivered says so + // instead of presenting as a missing callback. + expect(response.status).toBe(200); + expect(response.headers.get("content-type")).toContain("text/event-stream"); + // The relay path this case exists to exercise, proven rather than assumed. + expect(isEagerRelaySseResponse(response)).toBe(streamMode === "eager-relay"); const responseText = await response.text(); // Allow inspection consumer microtasks to settle. await Bun.sleep(20); @@ -2170,7 +2191,7 @@ describe("native passthrough terminal finalization", () => { responseText, }; } finally { - if (platformDescriptor) Object.defineProperty(process, "platform", platformDescriptor); + setRelayPlatformForTests(undefined); } } diff --git a/tests/server/agent-task-recovery-cache.test.ts b/tests/server/agent-task-recovery-cache.test.ts index 35b5ba70501..1b5c5567fef 100644 --- a/tests/server/agent-task-recovery-cache.test.ts +++ b/tests/server/agent-task-recovery-cache.test.ts @@ -17,9 +17,20 @@ import { recoverySse, routedConfig, } from "../helpers/agent-task-recovery"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; const realDateNow = Date.now; +// Direct handler dispatch never takes the writer lease that startServer would take, so it is refused. +let releaseSpendHome: (() => void) | undefined; +beforeEach(() => { + releaseSpendHome = acquireOwnedSpendHome(); +}); +afterEach(() => { + releaseSpendHome?.(); + releaseSpendHome = undefined; +}); + describe("agent task recovery cache", () => { beforeEach(() => resetAgentTaskRecoveryCache()); diff --git a/tests/server/agent-task-recovery-combo.test.ts b/tests/server/agent-task-recovery-combo.test.ts index 8823270ff26..7df943326bc 100644 --- a/tests/server/agent-task-recovery-combo.test.ts +++ b/tests/server/agent-task-recovery-combo.test.ts @@ -25,8 +25,15 @@ import { recoverySse, routedConfig, } from "../helpers/agent-task-recovery"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +// Direct handler dispatch never takes the writer lease that startServer would take, so it is +// refused. Taken inside the block below rather than here, because that block installs its own +// OPENCODEX_HOME after this hook would have run, and a lease binds the directory in effect when +// it was taken. +let releaseSpendHome: (() => void) | undefined; + function providerCompletion(): Response { return Response.json({ id: "chatcmpl_combo_recovery", @@ -58,6 +65,7 @@ describe("combo path encrypted agent task recovery", () => { beforeEach(() => { home = mkdtempSync(join(tmpdir(), "ocx-agent-task-combo-")); process.env["OPENCODEX_HOME"] = home; + releaseSpendHome = acquireOwnedSpendHome(); clearResponseStateMemoryForTests(); resetAgentTaskRecoveryState(); clearCachedProviderQuotas(); @@ -70,6 +78,9 @@ describe("combo path encrypted agent task recovery", () => { clearCachedProviderQuotas(); clearComboTargetCooldowns(); clearResponseStateForTests(); + // Released after the state flush and before the directory holding it is removed. + releaseSpendHome?.(); + releaseSpendHome = undefined; removeTreeWithRetry(home); if (priorHome === undefined) delete process.env["OPENCODEX_HOME"]; else process.env["OPENCODEX_HOME"] = priorHome; diff --git a/tests/server/agent-task-recovery-fallback.test.ts b/tests/server/agent-task-recovery-fallback.test.ts index 19495add896..1bb983c13ec 100644 --- a/tests/server/agent-task-recovery-fallback.test.ts +++ b/tests/server/agent-task-recovery-fallback.test.ts @@ -13,6 +13,17 @@ import { recoverySse, routedConfig, } from "../helpers/agent-task-recovery"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; + +// Direct handler dispatch never takes the writer lease that startServer would take, so it is refused. +let releaseSpendHome: (() => void) | undefined; +beforeEach(() => { + releaseSpendHome = acquireOwnedSpendHome(); +}); +afterEach(() => { + releaseSpendHome?.(); + releaseSpendHome = undefined; +}); describe("agent task recovery fallback routing", () => { beforeEach(() => { diff --git a/tests/server/agent-task-recovery-security.test.ts b/tests/server/agent-task-recovery-security.test.ts index c7a5ede55db..e478a160c89 100644 --- a/tests/server/agent-task-recovery-security.test.ts +++ b/tests/server/agent-task-recovery-security.test.ts @@ -19,9 +19,20 @@ import { routedConfig, ROUTING_ENVELOPE, } from "../helpers/agent-task-recovery"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; const realDateNow = Date.now; +// Direct handler dispatch never takes the writer lease that startServer would take, so it is refused. +let releaseSpendHome: (() => void) | undefined; +beforeEach(() => { + releaseSpendHome = acquireOwnedSpendHome(); +}); +afterEach(() => { + releaseSpendHome?.(); + releaseSpendHome = undefined; +}); + describe("agent task recovery security", () => { beforeEach(() => resetAgentTaskRecoveryState()); diff --git a/tests/server/agent-task-recovery.test.ts b/tests/server/agent-task-recovery.test.ts index faf117f1a76..ffbeb296279 100644 --- a/tests/server/agent-task-recovery.test.ts +++ b/tests/server/agent-task-recovery.test.ts @@ -26,6 +26,17 @@ import { ROUTING_ENVELOPE, SECOND_FERNET_TASK, } from "../helpers/agent-task-recovery"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; + +// Direct handler dispatch never takes the writer lease that startServer would take, so it is refused. +let releaseSpendHome: (() => void) | undefined; +beforeEach(() => { + releaseSpendHome = acquireOwnedSpendHome(); +}); +afterEach(() => { + releaseSpendHome?.(); + releaseSpendHome = undefined; +}); describe("agent task recovery (opt-in, default off)", () => { beforeEach(() => { diff --git a/tests/server/cancel-body-on-abort.test.ts b/tests/server/cancel-body-on-abort.test.ts index 075fb80c084..24f1df143c1 100644 --- a/tests/server/cancel-body-on-abort.test.ts +++ b/tests/server/cancel-body-on-abort.test.ts @@ -1,8 +1,16 @@ -import { describe, expect, test } from "bun:test"; +import { afterEach, describe, expect, test } from "bun:test"; import { cancelBodyOnAbort } from "../../src/lib/abort"; import { handleLive, readBodyCapped } from "../../src/server/live"; import { handleResponses } from "../../src/server/responses"; import type { OcxConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; + +let releaseSpendHome: (() => void) | undefined; +afterEach(() => { + // Release the lease before later teardown can replace the preload sandbox home. + releaseSpendHome?.(); + releaseSpendHome = undefined; +}); function bodyWithCancelSpy(): { body: ReadableStream; cancelled: () => boolean } { let cancelled = false; @@ -197,6 +205,8 @@ describe("readBodyCapped settles the stream when a read throws", () => { } as OcxConfig; try { + // Direct dispatch needs the writer lease that prevents spend-ledger ownership failures. + releaseSpendHome = acquireOwnedSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -258,6 +268,7 @@ describe("readBodyCapped settles the stream when a read throws", () => { } as OcxConfig; try { + releaseSpendHome = acquireOwnedSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, diff --git a/tests/server/context-history-ownership.test.ts b/tests/server/context-history-ownership.test.ts index 3a1df4253f1..04c10475847 100644 --- a/tests/server/context-history-ownership.test.ts +++ b/tests/server/context-history-ownership.test.ts @@ -16,6 +16,7 @@ import { resetContextRelayActivationForTests } from "../../src/codex/context-com const principal = "principal-a"; const keyAdmission: DataPlaneAdmission = { kind: "configured", keyId: "k1", source: "dedicated", contextPrincipalId: principal }; import type { OcxConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; const destination = "https://chatgpt.com/backend-api/codex"; @@ -25,6 +26,7 @@ let previousCodexHome: string | undefined; let home = ""; let sent: Array<{ url: string; headers: Headers }> = []; let failFirstAccount: string | undefined; +let releaseSpendHome: (() => void) | undefined; function install(id: string, owner: string, token = `${id}-token`): void { saveCodexAccountCredential(id, { accessToken: token, refreshToken: `${id}-refresh`, @@ -75,6 +77,8 @@ beforeEach(() => { previousHome = process.env.OPENCODEX_HOME; previousCodexHome = process.env.CODEX_HOME; home = mkdtempSync(join(tmpdir(), "ocx-context-owner-")); process.env.OPENCODEX_HOME = home; process.env.CODEX_HOME = home; + // Direct handler dispatches need the writer lease that startServer normally holds. + releaseSpendHome = acquireOwnedSpendHome(); setContextFeature(true); clearContextSessionOwnersForTests(); clearAccountQuota(); clearThreadAccountMap(); clearCodexUpstreamHealth(); for (const id of ["pool-a", "pool-b", "__main__"]) clearAccountNeedsReauth(id); @@ -98,6 +102,9 @@ beforeEach(() => { }); afterEach(() => { + // Release before home teardown to prevent Windows removal failures and a live unlinked database. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; clearContextSessionOwnersForTests(); clearAccountQuota(); clearThreadAccountMap(); clearCodexUpstreamHealth(); removeTreeWithRetry(home); diff --git a/tests/server/plaintext-v2-agent-messages-server.test.ts b/tests/server/plaintext-v2-agent-messages-server.test.ts index 4de9f24bfc1..46829c129fd 100644 --- a/tests/server/plaintext-v2-agent-messages-server.test.ts +++ b/tests/server/plaintext-v2-agent-messages-server.test.ts @@ -15,10 +15,19 @@ import { import { clearResponseStateForTests, expandPreviousResponseInput } from "../../src/responses/state"; import { handleResponses } from "../../src/server/responses"; import type { OcxConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; const originalFetch = globalThis.fetch; +let releaseInheritedSpendHome: (() => void) | undefined; +// Taken per inherited-home dispatch because the pool retry row installs a different home. The +// ??= keeps a second call inside one case idempotent rather than replacing the release callback +// it would need; no row here calls it twice today, so this is defence, not a fixed regression. +const takeInheritedSpendHome = (): void => { releaseInheritedSpendHome ??= acquireOwnedSpendHome(); }; beforeEach(() => { clearResponseStateForTests(); }); afterEach(() => { + // Released first so a failed row cannot leak its writer lease into the next case. + releaseInheritedSpendHome?.(); + releaseInheritedSpendHome = undefined; globalThis.fetch = originalFetch; clearResponseStateForTests(); }); @@ -89,12 +98,16 @@ async function withPoolHome(run: () => Promise): Promise { const previousCodexHome = process.env.CODEX_HOME; process.env.OPENCODEX_HOME = home; process.env.CODEX_HOME = home; + // Taken after the pool case installs its home so its direct dispatch owns that journal. + const releaseSpendHome = acquireOwnedSpendHome(); clearCodexUpstreamHealth(); clearThreadAccountMap(); clearAccountQuota(); try { return await run(); } finally { + // Released before removal or env restoration so the lease cannot outlive this home. + releaseSpendHome(); clearCodexUpstreamHealth(); clearThreadAccountMap(); clearAccountQuota(); @@ -137,6 +150,7 @@ function overLimitResponsePayload(id = "resp-plaintext-v2-overflow") { describe("plaintext v2 agent messages at the Responses server boundary", () => { test.each(["json", "legacy-tee", "eager-relay"] as const)("null namespace restores before %s delivery and continuation storage", async mode => { + takeInheritedSpendHome(); const id = `resp-null-namespace-${mode}`; const item = { ...completedResponsePayload(id).output[0]!, namespace: null }; const payload = { id, status: "completed", output: [item] }; @@ -156,6 +170,7 @@ describe("plaintext v2 agent messages at the Responses server boundary", () => { }); test("rewrites the canonical request and restores every SSE response snapshot", async () => { + takeInheritedSpendHome(); const sentBodies: string[] = []; globalThis.fetch = (async (_input: RequestInfo | URL, init?: RequestInit) => { sentBodies.push(typeof init?.body === "string" ? init.body : ""); @@ -207,6 +222,7 @@ describe("plaintext v2 agent messages at the Responses server boundary", () => { }); test("restores the namespace in bounded JSON responses", async () => { + takeInheritedSpendHome(); globalThis.fetch = (async () => new Response(JSON.stringify(completedResponsePayload()), { status: 200, headers: { "content-type": "application/json" }, @@ -225,6 +241,7 @@ describe("plaintext v2 agent messages at the Responses server boundary", () => { }); test("rejects an unclassified successful response while restoration is required", async () => { + takeInheritedSpendHome(); globalThis.fetch = (async () => new Response( JSON.stringify(completedResponsePayload()), { status: 200 }, @@ -244,6 +261,7 @@ describe("plaintext v2 agent messages at the Responses server boundary", () => { }); test("restores aliases after SSE snapshot repair copies request tools and tool choice", async () => { + takeInheritedSpendHome(); globalThis.fetch = (async () => { const response = completedResponsePayload("resp-snapshot-sse"); return new Response( @@ -279,6 +297,7 @@ describe("plaintext v2 agent messages at the Responses server boundary", () => { }); test("restores aliases after bounded JSON snapshot repair", async () => { + takeInheritedSpendHome(); globalThis.fetch = (async () => new Response( JSON.stringify(completedResponsePayload("resp-snapshot-json")), { status: 200, headers: { "content-type": "application/json" } }, @@ -304,6 +323,7 @@ describe("plaintext v2 agent messages at the Responses server boundary", () => { }); test("keeps the marker and reserved namespace when the option is disabled", async () => { + takeInheritedSpendHome(); const sentBodies: string[] = []; globalThis.fetch = (async (_input: RequestInfo | URL, init?: RequestInit) => { sentBodies.push(typeof init?.body === "string" ? init.body : ""); @@ -324,6 +344,7 @@ describe("plaintext v2 agent messages at the Responses server boundary", () => { }); test("keeps the whole request unchanged when tool-search history conflicts with the alias", async () => { + takeInheritedSpendHome(); const sentBodies: string[] = []; globalThis.fetch = (async (_input: RequestInfo | URL, init?: RequestInit) => { sentBodies.push(typeof init?.body === "string" ? init.body : ""); @@ -425,6 +446,7 @@ describe("plaintext v2 agent messages at the Responses server boundary", () => { }); test("fails closed for over-limit streamed responses in both relay modes", async () => { + takeInheritedSpendHome(); for (const streamMode of ["legacy-tee", "eager-relay"] as const) { globalThis.fetch = (async () => new Response( `event: response.completed\ndata: ${JSON.stringify({ @@ -451,6 +473,7 @@ describe("plaintext v2 agent messages at the Responses server boundary", () => { }); test("rejects over-limit bounded JSON before HTTP or WebSocket reframing", async () => { + takeInheritedSpendHome(); const fixtureId = "plaintext-v2-bounded-json-fixture"; const fixtureModel = "fixture-model"; const mutableRegistry = PROVIDER_REGISTRY as unknown as Array>; @@ -503,6 +526,7 @@ describe("plaintext v2 agent messages at the Responses server boundary", () => { }); test("rejects an over-limit JSON response and does not retain it for continuation", async () => { + takeInheritedSpendHome(); const sentBodies: string[] = []; let requestIndex = 0; globalThis.fetch = (async (_input: RequestInfo | URL, init?: RequestInit) => { @@ -547,6 +571,7 @@ describe("plaintext v2 agent messages at the Responses server boundary", () => { }); test.each([undefined, "websocket"] as const)("stores the client namespace across an option change on %s", async inboundTransport => { + takeInheritedSpendHome(); const sentBodies: string[] = []; let requestIndex = 0; globalThis.fetch = (async (_input: RequestInfo | URL, init?: RequestInit) => { @@ -605,6 +630,7 @@ test("plaintext startup warning requires explicit opt-in and names retention", ( for (const streamMode of ["legacy-tee", "eager-relay"] as const) { for (const refusal of ["malformed", "unknown-alias", "conflicting-binding"] as const) { test(`${streamMode} ${refusal} is refused without caching or retry`, async () => { + takeInheritedSpendHome(); let sends = 0; const sent: string[] = []; globalThis.fetch = (async (_url: RequestInfo | URL, init?: RequestInit) => { @@ -635,6 +661,7 @@ for (const streamMode of ["legacy-tee", "eager-relay"] as const) { } test("malformed bounded JSON is a single-attempt 502", async () => { + takeInheritedSpendHome(); let sends = 0; globalThis.fetch = (async () => { sends += 1; return new Response("{malformed", { headers: { "content-type": "application/json" } }); }) as typeof fetch; const response = await handleResponses(collaborationRequest(), config(true), { model: "", provider: "" }); @@ -644,6 +671,7 @@ test("malformed bounded JSON is a single-attempt 502", async () => { }); test("cross-coordinate namespace conflict cannot publish continuation", async () => { + takeInheritedSpendHome(); let sends = 0; globalThis.fetch = (async () => { sends += 1; @@ -663,6 +691,7 @@ test("cross-coordinate namespace conflict cannot publish continuation", async () test("concurrent native requests do not share plaintext alias metadata", async () => { + takeInheritedSpendHome(); const pending: Array<{ enabled: boolean; resolve: (value: Response) => void }> = []; let bothReady!: () => void; const ready = new Promise(resolve => { bothReady = resolve; }); diff --git a/tests/server/response-model-identity.test.ts b/tests/server/response-model-identity.test.ts index 11d021563d8..319018c231d 100644 --- a/tests/server/response-model-identity.test.ts +++ b/tests/server/response-model-identity.test.ts @@ -2,10 +2,15 @@ import { afterEach, describe, expect, test } from "bun:test"; import { handleResponses } from "../../src/server/responses/core"; import type { RequestLogContext } from "../../src/server/request-log"; import type { OcxConfig, OcxProviderConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; const originalFetch = globalThis.fetch; +let releaseSpendHome: (() => void) | undefined; afterEach(() => { + // Release the lease before later teardown can replace the preload sandbox home. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; }); @@ -85,6 +90,8 @@ async function post(args: { }) as typeof fetch; const logCtx = { model: "", provider: "" } as RequestLogContext; + // Direct dispatch needs the writer lease that prevents spend-ledger ownership failures. + releaseSpendHome = acquireOwnedSpendHome(); const response = await handleResponses( new Request("http://localhost/v1/responses", { method: "POST", diff --git a/tests/server/server-agent-task-recovery-replay.test.ts b/tests/server/server-agent-task-recovery-replay.test.ts index caaad660aad..9c660b2e292 100644 --- a/tests/server/server-agent-task-recovery-replay.test.ts +++ b/tests/server/server-agent-task-recovery-replay.test.ts @@ -1,4 +1,4 @@ -import { afterEach, expect, spyOn, test } from "bun:test"; +import { afterEach, beforeEach, expect, spyOn, test } from "bun:test"; import { createKiroAdapter } from "../../src/adapters/kiro"; import { ADAPTER_REGISTRY } from "../../src/adapters/registry"; import { parseRequest } from "../../src/responses/parser"; @@ -7,8 +7,19 @@ import { conversationIdFromResponsesRequest } from "../../src/server/request-log import type { OcxParsedRequest } from "../../src/types"; import { recoverEncryptedAgentTask, resetAgentTaskRecoveryState, restoreCachedEncryptedAgentTasks } from "../../src/server/responses/agent-task-recovery"; import { codexHeaders, encryptedInput, fakeChatGptJwt, FERNET_TASK, SECOND_FERNET_TASK, originalFetch, recoverySse, routedConfig } from "../helpers/agent-task-recovery"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; afterEach(() => { globalThis.fetch = originalFetch; resetAgentTaskRecoveryState(); }); +// Direct handler dispatch never takes the writer lease that startServer would take, so it is refused. +let releaseSpendHome: (() => void) | undefined; +beforeEach(() => { + releaseSpendHome = acquireOwnedSpendHome(); +}); +afterEach(() => { + releaseSpendHome?.(); + releaseSpendHome = undefined; +}); + test("replay reuses admitted recovery after a tool result without another network call", async () => { let calls = 0; globalThis.fetch = (async () => { calls++; return new Response(recoverySse("Read nonce.txt exactly.")); }) as typeof fetch; diff --git a/tests/server/server-auth.test.ts b/tests/server/server-auth.test.ts index ad8d5b48bf1..aec00ee0be2 100644 --- a/tests/server/server-auth.test.ts +++ b/tests/server/server-auth.test.ts @@ -36,6 +36,8 @@ import { startServer, } from "../../src/server"; import { clearRequestLogsForTests, getRequestLogEntries } from "../../src/server/request-log"; +import { setRelayPlatformForTests } from "../../src/server/responses/passthrough-delivery"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { readUsageEntries } from "../../src/usage/log"; import { handleManagementAPI } from "../../src/server/management-api"; import { handleResponses, handleResponsesCompact } from "../../src/server/responses"; @@ -753,6 +755,7 @@ describe("server local API auth", () => { }; let acceptedCount = 0; + const releaseSpendHome = acquireOwnedSpendHome(); try { const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", @@ -767,8 +770,10 @@ describe("server local API auth", () => { expect(response.status).toBe(429); expect(acceptedCount).toBe(1); expect(upstreamModels).toEqual(["first-model", "second-model"]); + await response.text(); } finally { await upstream.stop(true); + releaseSpendHome(); } }); @@ -3479,8 +3484,11 @@ describe("server local API auth", () => { }); test("Activation E: both stream modes retry only before response relay construction", async () => { - const platformDescriptor = Object.getOwnPropertyDescriptor(process, "platform"); - Object.defineProperty(process, "platform", { value: "win32", configurable: true }); + // The relay decision only, not the whole process. A global platform override also changes + // state-directory identity, which is lowercased on win32 and so names a different directory + // on a case-sensitive filesystem: the server's own writer lease stopped matching and the + // retry was refused before it could reach the second account. + setRelayPlatformForTests("win32"); try { for (const streamMode of ["legacy-tee", "eager-relay"] as const) { const positive = await startPoolRetryHarness(accountId => accountId === "acct-pool-a" @@ -3512,7 +3520,7 @@ describe("server local API auth", () => { } } } finally { - if (platformDescriptor) Object.defineProperty(process, "platform", platformDescriptor); + setRelayPlatformForTests(undefined); } }, { timeout: SERVER_BUDGET_MS }); diff --git a/tests/server/server-combo-failover-e2e.test.ts b/tests/server/server-combo-failover-e2e.test.ts index afbfc5ecacd..483772891de 100644 --- a/tests/server/server-combo-failover-e2e.test.ts +++ b/tests/server/server-combo-failover-e2e.test.ts @@ -38,6 +38,8 @@ import { startServer } from "../../src/server"; import { fakeChatGptJwt } from "../helpers/fake-chatgpt-jwt"; import { catalogConvergenceFactory } from "../helpers/catalog-convergence"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { chatErrorStream, chatStream, chatSuccess, chatTruncatedZeroOutputStream, responsesSuccess } from "../helpers/combo-failover-upstream"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { heldResponse } from "../helpers/held-response"; import { clearResponseStateForTests, @@ -142,6 +144,17 @@ let originalFetch: typeof fetch; let originalNow: () => number; const servers: Array> = []; +// A case that calls a handler directly never takes the writer lease startServer takes, so its +// dispatch is refused. Taken at the dispatch helpers rather than file-wide: the cases that do +// start a real server already own it, and this only ever adds a reference on the same home. +let releaseSpendHome: (() => void) | undefined; +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; +// Every turn these helpers hand back. A row that asserts only on a status leaves a +// transformed body unread, and cancelling those before the listeners stop is what keeps a +// reader from settling against the journal after its lease is gone. +const pendingTurns: Response[] = []; +function trackTurn(response: Response): Response { pendingTurns.push(response); return response; } + beforeEach(() => { originalFetch = globalThis.fetch; originalNow = Date.now; @@ -168,11 +181,25 @@ beforeEach(() => { afterEach(async () => { let responseStatePending = true; + let cancelFailure: unknown; try { + // Rows that assert only on a status leave a transformed body unread. Cancelling those first + // means no reader is still attached when the listeners stop and the lease is given back. A + // cancel that throws fails the case rather than being swallowed, but not before every other + // turn and the listeners below have had their chance to close. + for (const turn of pendingTurns.splice(0)) { + if (turn.bodyUsed || !turn.body || turn.body.locked) continue; + try { await turn.body.cancel(); } + catch (error) { cancelFailure ??= error; } + } for (const server of servers.splice(0)) await server.stop(true); await flushResponseState(); responseStatePending = responseStatePersistPendingForTests(); } finally { + // After the listeners are stopped and the response state is flushed, both of which can + // still account against the journal, and before the home below is removed. + releaseSpendHome?.(); + releaseSpendHome = undefined; clearResponseStateForTests(); clearCursorThreadContinuityForTests(); globalThis.fetch = originalFetch; @@ -191,6 +218,7 @@ afterEach(async () => { clearCodexUpstreamHealth(); clearRequestLogsForTests(); } + if (cancelFailure !== undefined) throw cancelFailure; expect(responseStatePending).toBe(false); }); @@ -204,60 +232,6 @@ function baseUrl(server: ReturnType): string { return `${server.url.toString().replace(/\/$/, "")}/v1`; } -function chatSuccess(text: string, model = "model"): Response { - return Response.json({ - id: `chatcmpl-${model}`, - object: "chat.completion", - model, - choices: [{ index: 0, message: { role: "assistant", content: text }, finish_reason: "stop" }], - usage: { prompt_tokens: 2, completion_tokens: 1, total_tokens: 3 }, - }); -} - -function chatStream(text: string): Response { - const frames = [ - `data: ${JSON.stringify({ choices: [{ index: 0, delta: { content: text }, finish_reason: null }] })}\n\n`, - `data: ${JSON.stringify({ choices: [{ index: 0, delta: {}, finish_reason: "stop" }], usage: { prompt_tokens: 2, completion_tokens: 1, total_tokens: 3 } })}\n\n`, - "data: [DONE]\n\n", - ].join(""); - return new Response(frames, { headers: { "content-type": "text/event-stream" } }); -} - -function chatTruncatedZeroOutputStream(): Response { - const frames = [ - `data: ${JSON.stringify({ choices: [{ index: 0, delta: {}, finish_reason: null }] })}\n\n`, - ].join(""); - return new Response(frames, { headers: { "content-type": "text/event-stream" } }); -} - -function chatErrorStream(message: string, prefix?: string): Response { - const frames = [ - ...(prefix - ? [`data: ${JSON.stringify({ choices: [{ index: 0, delta: { content: prefix }, finish_reason: null }] })}\n\n`] - : []), - `data: ${JSON.stringify({ error: { type: "server_error", code: "upstream_server_error", message } })}\n\n`, - "data: [DONE]\n\n", - ].join(""); - return new Response(frames, { headers: { "content-type": "text/event-stream" } }); -} - -function responsesSuccess(text: string, model = "responses-model"): Record { - return { - id: `resp-${model}`, - object: "response", - status: "completed", - model, - output: [{ - id: "msg_backup", - type: "message", - role: "assistant", - status: "completed", - content: [{ type: "output_text", text, annotations: [] }], - }], - usage: { input_tokens: 2, output_tokens: 1, total_tokens: 3 }, - }; -} - function comboConfig( providers: OcxConfig["providers"], targets = Object.keys(providers).map((name, index) => ({ provider: name, model: `m${index + 1}` })), @@ -277,11 +251,12 @@ async function post( options: HandleOptions = {}, headers: Record = {}, ): Promise { - return handleResponses(new Request("http://localhost/v1/responses", { + takeSpendHome(); + return trackTurn(await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json", ...headers }, body: JSON.stringify({ model: "combo/free", input: "hello", stream: false, ...raw }), - }), config, { model: "", provider: "" }, options); + }), config, { model: "", provider: "" }, options)); } let loggedRequestSequence = 0; @@ -294,18 +269,19 @@ async function postLogged( ): Promise { const logCtx: RequestLogContext = { model: "", provider: "" }; const start = Date.now(); + takeSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json", ...headers }, body: JSON.stringify({ model: "combo/free", input: "hello", stream: false, ...raw }), }), config, logCtx, options); loggedRequestSequence += 1; - return responseWithDeferredRequestLog( + return trackTurn(responseWithDeferredRequestLog( response, `combo-test-${loggedRequestSequence}`, start, logCtx, - ); + )); } async function postModelLogged( @@ -317,18 +293,19 @@ async function postModelLogged( ): Promise { const logCtx: RequestLogContext = { model: "", provider: "" }; const start = Date.now(); + takeSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json", ...headers }, body: JSON.stringify({ model, input: "hello", stream: false, ...raw }), }), config, logCtx, options); loggedRequestSequence += 1; - return responseWithDeferredRequestLog( + return trackTurn(responseWithDeferredRequestLog( response, `direct-test-${loggedRequestSequence}`, start, logCtx, - ); + )); } async function latestAttemptReceipts(config: OcxConfig) { @@ -2063,6 +2040,7 @@ describe("server combo failover 030 activation matrix", () => { "chatgpt-account-id": authKind === "mismatched-account" ? "other-account" : authKind === "org-only-jwt" ? "org-foreign" : "acct-scoped-sidecar", }; + takeSpendHome(); const response = authKind === "chat-valid" ? await (await import("../../src/server/chat-completions")).handleChatCompletions(new Request("http://localhost/v1/chat/completions", { method: "POST", headers: { "content-type": "application/json", ...headers }, @@ -3383,7 +3361,8 @@ describe("server combo failover 030 activation matrix", () => { let cancels = 0; const parent: RequestLogContext = { model: "", provider: "" }; const snapshots: RequestLogContext[] = []; - const response = await handleResponses(new Request("http://localhost/v1/responses", { + takeSpendHome(); + const response = trackTurn(await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json", session_id: "hop-recall" }, body: JSON.stringify({ model: "combo/free", input: "hello", stream: true }), }), config, parent, { @@ -3394,7 +3373,7 @@ describe("server combo failover 030 activation matrix", () => { finalized.resolve(); }, onNativePassthroughCancel: () => { cancels += 1; }, - }); + })); expect(response.status).toBe(200); await response.text(); await within(finalized.promise); @@ -3426,6 +3405,7 @@ describe("server combo failover 030 activation matrix", () => { const finalized = deferred(); const observed: Array<{ status: number; log: RequestLogContext }> = []; try { + takeSpendHome(); const response = await within(handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ model: "combo/free", input: "hello", stream: true }), @@ -3688,11 +3668,12 @@ describe("cursor conversation continuity across store:false chains", () => { } async function postCursor(config: OcxConfig, raw: Record): Promise { - return handleResponses(new Request("http://localhost/v1/responses", { + takeSpendHome(); + return trackTurn(await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ stream: false, store: false, ...raw }), - }), config, { model: "", provider: "" }, {}); + }), config, { model: "", provider: "" }, {})); } function cursorConfig(): OcxConfig { @@ -3784,7 +3765,8 @@ describe("cursor conversation continuity across store:false chains", () => { const seen: string[] = []; customCursorTransportFactory = fakeCursorTransportFactory(seen); const config = cursorConfig(); - const postThreadTurn = (input: unknown) => handleResponses(new Request("http://localhost/v1/responses", { + takeSpendHome(); + const postThreadTurn = async (input: unknown) => trackTurn(await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json", @@ -3797,7 +3779,7 @@ describe("cursor conversation continuity across store:false chains", () => { store: false, prompt_cache_key: "shared-cache-key", }), - }), config, { model: "", provider: "" }, {}); + }), config, { model: "", provider: "" }, {})); expect((await postThreadTurn("start")).status).toBe(200); expect((await postThreadTurn([ @@ -3814,7 +3796,8 @@ describe("cursor conversation continuity across store:false chains", () => { const seen: string[] = []; customCursorTransportFactory = fakeCursorTransportFactory(seen); const config = cursorConfig(); - const postDesktopTurn = (input: unknown) => handleResponses(new Request("http://localhost/v1/responses", { + takeSpendHome(); + const postDesktopTurn = async (input: unknown) => trackTurn(await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json", @@ -3827,7 +3810,7 @@ describe("cursor conversation continuity across store:false chains", () => { stream: false, store: false, }), - }), config, { model: "", provider: "" }, {}); + }), config, { model: "", provider: "" }, {})); expect((await postDesktopTurn("start")).status).toBe(200); expect((await postDesktopTurn([ @@ -3844,7 +3827,8 @@ describe("cursor conversation continuity across store:false chains", () => { const seen: string[] = []; customCursorTransportFactory = fakeCursorTransportFactory(seen); const config = cursorConfig(); - const postThreadTurn = (input: unknown) => handleResponses(new Request("http://localhost/v1/responses", { + takeSpendHome(); + const postThreadTurn = async (input: unknown) => trackTurn(await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json", @@ -3857,7 +3841,7 @@ describe("cursor conversation continuity across store:false chains", () => { store: false, prompt_cache_key: "shared-cache-key", }), - }), config, { model: "", provider: "" }, {}); + }), config, { model: "", provider: "" }, {})); expect((await postThreadTurn("hello")).status).toBe(200); expect((await postThreadTurn([ @@ -3883,13 +3867,14 @@ describe("combo compact failover", () => { async function postCompactLogged(config: OcxConfig): Promise { const logCtx: RequestLogContext = { model: "", provider: "" }; const start = Date.now(); + takeSpendHome(); const response = await handleResponsesCompact(compactRequest({ model: "combo/free", stream: false, input: [{ type: "message", role: "user", content: [{ type: "input_text", text: "earlier turn" }] }], }), config, logCtx); loggedRequestSequence += 1; - return responseWithDeferredRequestLog(response, `combo-compact-${loggedRequestSequence}`, start, logCtx); + return trackTurn(responseWithDeferredRequestLog(response, `combo-compact-${loggedRequestSequence}`, start, logCtx)); } function canonicalPoolConfig( diff --git a/tests/server/server-combo-reasoning-replay-eligibility.test.ts b/tests/server/server-combo-reasoning-replay-eligibility.test.ts index 5f39d0a9251..38451a7f950 100644 --- a/tests/server/server-combo-reasoning-replay-eligibility.test.ts +++ b/tests/server/server-combo-reasoning-replay-eligibility.test.ts @@ -15,6 +15,7 @@ import { clearComboRecallForTests } from "../../src/server/responses/combo-sessi import { TARGET_INCOMPATIBLE_MESSAGE } from "../../src/server/responses/core-errors"; import type { OcxConfig, OcxProviderConfig } from "../../src/types"; import { installIsolatedCodexHome, type IsolatedCodexHome } from "../helpers/isolated-codex-home"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; type HandleOptions = NonNullable[3]>; @@ -23,6 +24,10 @@ let testDir = ""; let previousHome: string | undefined; let isolatedCodexHome: IsolatedCodexHome | null = null; const servers: Array> = []; +let releaseSpendHome: (() => void) | undefined; + +// Acquire only for rows that physically dispatch, after their temporary home is installed. +const takeSpendHome = (): void => { releaseSpendHome = acquireOwnedSpendHome(); }; beforeEach(() => { previousHome = process.env.OPENCODEX_HOME; @@ -38,6 +43,9 @@ beforeEach(() => { }); afterEach(async () => { + // Release before home teardown to prevent Windows removal failures and a live unlinked database. + releaseSpendHome?.(); + releaseSpendHome = undefined; let responseStatePending = true; try { for (const server of servers.splice(0)) await server.stop(true); @@ -172,6 +180,7 @@ describe("combo mandatory reasoning replay failover", () => { }); test("upstream_server_error failover to strict Responses preserves existing reasoning_text", async () => { + takeSpendHome(); const failed = serve(() => Response.json({ error: { type: "server_error", code: "upstream_server_error", message: "busy" }, }, { status: 500 })); @@ -208,6 +217,7 @@ describe("combo mandatory reasoning replay failover", () => { }); test("a foreign opaque-only replay skips the strict target without forwarding or fabrication", async () => { + takeSpendHome(); let firstTargetFails = false; const first = serve(() => firstTargetFails ? Response.json({ error: { type: "server_error", code: "upstream_server_error", message: "busy" } }, { status: 500 }) @@ -257,6 +267,7 @@ describe("combo mandatory reasoning replay failover", () => { }); test("an exhausted combo reports target_incompatible when mandatory plaintext is unavailable", async () => { + takeSpendHome(); let firstTargetFails = false; const first = serve(() => firstTargetFails ? Response.json({ error: { type: "server_error", code: "upstream_server_error", message: "busy" } }, { status: 500 }) diff --git a/tests/server/server-combo-zero-output-failover.test.ts b/tests/server/server-combo-zero-output-failover.test.ts index 88adaf522db..a5a7a9fa292 100644 --- a/tests/server/server-combo-zero-output-failover.test.ts +++ b/tests/server/server-combo-zero-output-failover.test.ts @@ -5,6 +5,7 @@ import { join } from "node:path"; import { ManagementRequest as Request } from "../helpers/management-auth"; import { comboProviderFactory } from "../helpers/combo-provider"; import { installIsolatedCodexHome, type IsolatedCodexHome } from "../helpers/isolated-codex-home"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; import { removeTreeWithRetry } from "../helpers/remove-tree"; import { clearComboSelectionState, clearComboTargetCooldowns } from "../../src/combos"; import { clearComboRecallForTests } from "../../src/server/responses/combo-session-recall"; @@ -43,12 +44,15 @@ let previousHome: string | undefined; let isolatedCodexHome: IsolatedCodexHome | null = null; const servers: Array> = []; const provider = comboProviderFactory(() => undefined); +let releaseSpendHome: (() => void) | undefined; beforeEach(() => { previousHome = process.env.OPENCODEX_HOME; isolatedCodexHome = installIsolatedCodexHome("ocx-combo-zero-output-codex-"); testDir = mkdtempSync(join(tmpdir(), "ocx-combo-zero-output-")); process.env.OPENCODEX_HOME = testDir; + // Direct handler dispatches need the writer lease that startServer normally holds. + releaseSpendHome = acquireOwnedSpendHome(); clearComboSelectionState(); clearComboRecallForTests(); clearComboTargetCooldowns(); @@ -59,6 +63,9 @@ beforeEach(() => { }); afterEach(async () => { + // Release before home teardown to prevent Windows removal failures and a live unlinked database. + releaseSpendHome?.(); + releaseSpendHome = undefined; let responseStatePending = true; try { for (const server of servers.splice(0)) await server.stop(true); diff --git a/tests/server/server-management-auth.test.ts b/tests/server/server-management-auth.test.ts index d5dae240414..a0554993819 100644 --- a/tests/server/server-management-auth.test.ts +++ b/tests/server/server-management-auth.test.ts @@ -1794,13 +1794,17 @@ describe("management and data-plane credential separation", () => { saveConfig(remoteConfig()); process.env.USERNAME ??= "tester"; setPlatformForTests("win32"); - // Env-token init never needs file ACL. Time out management-token paths so a - // broken file-backed ACL cannot be what made management available; allow - // other file hardens so startServer → saveConfig works on real win32 - // (config-mutation directory harden soft-fails home timeouts). + // Env-token init never needs file ACL. Time out the management TOKEN FILE so a broken + // file-backed ACL cannot be what made management available; the assertion that the state's + // source is "environment" is what proves which path answered. + // + // The state directory itself is no longer timed out. It was never load-bearing for this + // claim, and it is hardened with required: true by the spend-journal owner during + // startServer, which correctly refuses rather than soft-failing: an unverified ACL on the + // directory holding a secret is not something to proceed past. setIcaclsRunnerForTests(args => { const target = args[0] ?? ""; - if (target === testHome || target.endsWith("admin-api-token")) { + if (target.endsWith("admin-api-token")) { return { success: false, exitCode: null, timedOut: true, stdout: "" }; } return { success: true, exitCode: 0, timedOut: false, stdout: "" }; diff --git a/tests/server/spend-ledger-lifecycle.test.ts b/tests/server/spend-ledger-lifecycle.test.ts new file mode 100644 index 00000000000..17154d46b8f --- /dev/null +++ b/tests/server/spend-ledger-lifecycle.test.ts @@ -0,0 +1,101 @@ +/** + * The failed-start rollback owns two things at once: stopping whatever came up, and giving the + * state directory back. Doing the second before the first has finished is what single-writer + * ownership exists to prevent, and it cannot be observed from a passing startup. + */ +import { afterEach, beforeEach, expect, test } from "bun:test"; +import { mkdtempSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { acquireSpendLedgerServerLifecycle } from "../../src/server/index/spend-ledger-lifecycle"; +import { spendLedgerOwnerSnapshot } from "../../src/lib/spend-ledger-owner"; +import { resetSharedSpendLedgerForTest } from "../../src/lib/spend-reservation-ledger"; +import { removeTreeWithRetry } from "../helpers/remove-tree"; + +let root = ""; +let home = ""; +let previousHome: string | undefined; +const stopOrder: string[] = []; + +beforeEach(() => { + root = mkdtempSync(join(tmpdir(), "ocx-spend-lifecycle-")); + home = join(root, "state"); + previousHome = process.env.OPENCODEX_HOME; + process.env.OPENCODEX_HOME = home; + stopOrder.length = 0; + resetSharedSpendLedgerForTest(); +}); + +afterEach(() => { + resetSharedSpendLedgerForTest(); + if (previousHome === undefined) delete process.env.OPENCODEX_HOME; + else process.env.OPENCODEX_HOME = previousHome; + removeTreeWithRetry(root); +}); + +/** A listener whose stop stays pending until the case says otherwise, like a real drain. */ +function controlledListener(name: string, mode: "resolve" | "reject" = "resolve") { + let settle: () => void = () => {}; + const stopped = new Promise((resolve, reject) => { + settle = () => { if (mode === "reject") reject(new Error(`${name} stop failed`)); else resolve(); }; + }); + stopped.catch(() => { /* the rollback owns this rejection; the case must not be unhandled */ }); + return { + settle, + server: { + stop(_closeActiveConnections?: boolean): Promise { + stopOrder.push(name); + return stopped; + }, + }, + }; +} + +/** Let the rollback's allSettled continuation run without inventing a duration. */ +async function drainContinuations(): Promise { + for (let turn = 0; turn < 8; turn += 1) await Promise.resolve(); +} + +test("a failed start keeps the lease until every listener has actually stopped", async () => { + const lifecycle = acquireSpendLedgerServerLifecycle(home); + const first = controlledListener("first"); + const second = controlledListener("second"); + lifecycle.track(first.server); + lifecycle.track(second.server); + expect(spendLedgerOwnerSnapshot().ownership).toBe("held"); + + lifecycle.releaseAfterFailedStart(); + // Newest first, and both asked before anything is awaited. + expect(stopOrder).toEqual(["second", "first"]); + await drainContinuations(); + // Still held: neither stop has settled, so a listener could still be serving. + expect(spendLedgerOwnerSnapshot().ownership).toBe("held"); + + first.settle(); + await drainContinuations(); + expect(spendLedgerOwnerSnapshot().ownership).toBe("held"); + + second.settle(); + await drainContinuations(); + expect(spendLedgerOwnerSnapshot().ownership).toBe("unheld"); +}); + +test("a listener whose stop rejects still stops the rest and still returns the directory", async () => { + const lifecycle = acquireSpendLedgerServerLifecycle(home); + const failing = controlledListener("failing", "reject"); + const healthy = controlledListener("healthy"); + lifecycle.track(healthy.server); + lifecycle.track(failing.server); + + lifecycle.releaseAfterFailedStart(); + expect(stopOrder).toEqual(["failing", "healthy"]); + + failing.settle(); + await drainContinuations(); + // One refusal does not strand the directory, and it does not skip the other listener either. + expect(spendLedgerOwnerSnapshot().ownership).toBe("held"); + + healthy.settle(); + await drainContinuations(); + expect(spendLedgerOwnerSnapshot().ownership).toBe("unheld"); +}); diff --git a/tests/server/spend-ledger-owner-startup.test.ts b/tests/server/spend-ledger-owner-startup.test.ts new file mode 100644 index 00000000000..f8649f7e2f3 --- /dev/null +++ b/tests/server/spend-ledger-owner-startup.test.ts @@ -0,0 +1,106 @@ +/** startServer owns and releases the shared spend journal lease (#5123). */ +import { afterEach, beforeEach, expect, test } from "bun:test"; +import { existsSync, mkdtempSync, readFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { saveConfig } from "../../src/config"; +import { flushConfigDirHardeningForTests } from "../../src/config/paths"; +import { flushNativeMainStartupReleases } from "../../src/codex/native-profile-startup"; +import { + SPEND_LEDGER_JOURNAL_FILENAME, + SPEND_LEDGER_SALT_FILENAME, + resetSharedSpendLedgerForTest, +} from "../../src/lib/spend-reservation-ledger"; +import { acquireSpendLedgerOwner, spendLedgerOwnerSnapshot } from "../../src/lib/spend-ledger-owner"; +import { startServer } from "../../src/server"; +import type { OcxConfig } from "../../src/types"; +import { installIsolatedCodexHome, type IsolatedCodexHome } from "../helpers/isolated-codex-home"; +import { removeTreeWithRetry } from "../helpers/remove-tree"; + +let home = ""; +let previousHome: string | undefined; +let codexHome: IsolatedCodexHome | null = null; + +function config(): OcxConfig { + return { + port: 0, + hostname: "127.0.0.1", + defaultProvider: "kimi", + providers: { kimi: { adapter: "openai-chat", baseUrl: "https://kimi.test/v1", models: ["k3"] } }, + }; +} + +beforeEach(() => { + home = mkdtempSync(join(tmpdir(), "ocx-spend-owner-startup-")); + previousHome = process.env.OPENCODEX_HOME; + process.env.OPENCODEX_HOME = home; + codexHome = installIsolatedCodexHome("ocx-spend-owner-codex-"); + resetSharedSpendLedgerForTest(); + saveConfig(config()); +}); + +afterEach(async () => { + await flushNativeMainStartupReleases(); + await flushConfigDirHardeningForTests(); + resetSharedSpendLedgerForTest(); + if (previousHome === undefined) delete process.env.OPENCODEX_HOME; + else process.env.OPENCODEX_HOME = previousHome; + codexHome?.restore(); + codexHome = null; + removeTreeWithRetry(home); +}); + +test("startServer acquires before serving and final stop releases", async () => { + const server = startServer(0); + expect(spendLedgerOwnerSnapshot().ownership).toBe("held"); + try { + const adminToken = readFileSync(join(home, "admin-api-token"), "utf8").trim(); + const liveness = await fetch(new URL("/healthz", server.url)); + expect(await liveness.json()).not.toHaveProperty("spendLedger"); + const health = await fetch(new URL("/api/system/health", server.url), { + headers: { "x-opencodex-api-key": adminToken }, + }); + expect(await health.json()).toMatchObject({ + spendLedger: { + ownership: "held", + initialized: false, + configured: false, + degraded: false, + persistFailures: 0, + corruptRecords: 0, + }, + }); + expect(existsSync(join(home, SPEND_LEDGER_JOURNAL_FILENAME))).toBe(false); + expect(existsSync(join(home, SPEND_LEDGER_SALT_FILENAME))).toBe(false); + } finally { + await server.stop(true); + } + expect(spendLedgerOwnerSnapshot().ownership).toBe("unheld"); +}); + +/** Bounded wait: the rollback returns the directory on a continuation, not in the throw's turn. */ +async function waitForOwnership(expected: "held" | "unheld"): Promise { + for (let turn = 0; turn < 200; turn += 1) { + if (spendLedgerOwnerSnapshot().ownership === expected) return; + await Bun.sleep(5); + } + expect(spendLedgerOwnerSnapshot().ownership).toBe(expected); +} + +test("a partial start that bound public before an auxiliary failure releases ownership", async () => { + const blocker = Bun.serve({ port: 0, hostname: "127.0.0.1", fetch: () => new Response("blocked") }); + try { + const candidate = config(); + candidate.unauthenticatedLoopbackListener = { enabled: true, port: blocker.port }; + saveConfig(candidate); + expect(() => startServer(0)).toThrow(); + // The rollback stops the listener it already bound BEFORE it gives the directory back, so + // ownership returns once that stop settles rather than in the same turn as the throw. + // Asserting it synchronously passed only while the rollback discarded the stop promise. + await waitForOwnership("unheld"); + const next = acquireSpendLedgerOwner(); + next.release(); + } finally { + await blocker.stop(true); + } +}); diff --git a/tests/server/terminal-guard-server.test.ts b/tests/server/terminal-guard-server.test.ts index e95a380ef45..22bac135c2e 100644 --- a/tests/server/terminal-guard-server.test.ts +++ b/tests/server/terminal-guard-server.test.ts @@ -7,6 +7,11 @@ import { clearKeyCooldowns } from "../../src/providers/key-failover"; import { handleResponses } from "../../src/server/responses"; import type { OcxConfig } from "../../src/types"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; + +let releaseInheritedSpendHome: (() => void) | undefined; +// Taken per inherited-home dispatch because one row below installs a different home. +const takeInheritedSpendHome = (): void => { releaseInheritedSpendHome = acquireOwnedSpendHome(); }; const config = { port: 0, @@ -98,10 +103,14 @@ describe("server terminal guard integration", () => { }); afterEach(() => { + // Released first so a failed row cannot carry its writer lease into the next case. + releaseInheritedSpendHome?.(); + releaseInheritedSpendHome = undefined; globalThis.fetch = originalFetch; }); test("re-asks Claude once inside the same Responses turn and forwards the tool call", async () => { + takeInheritedSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -124,6 +133,7 @@ describe("server terminal guard integration", () => { }); test("terminal-guard continuation 429 replays on the same key before surfacing", async () => { + takeInheritedSpendHome(); const retryConfig = { ...config, providers: { @@ -175,6 +185,8 @@ describe("server terminal guard integration", () => { const previousHome = process.env.OPENCODEX_HOME; const home = mkdtempSync(join(tmpdir(), "ocx-terminal-guard-failover-")); process.env.OPENCODEX_HOME = home; + // Taken after this case installs its home so the direct dispatch owns that journal. + const releaseSpendHome = acquireOwnedSpendHome(); clearKeyCooldowns("claude-se"); const budgetConfig = { ...config, @@ -221,6 +233,8 @@ describe("server terminal guard integration", () => { // A per-iteration budget would replay on the second key too (5+ sends). expect(sends).toBe(4); } finally { + // Released before restoring or removing the home so its lease files can be deleted. + releaseSpendHome(); clearKeyCooldowns("claude-se"); if (previousHome === undefined) delete process.env.OPENCODEX_HOME; else process.env.OPENCODEX_HOME = previousHome; @@ -229,6 +243,7 @@ describe("server terminal guard integration", () => { }); test("terminal-guard continuation shares the request-wide 429 budget with the main loop", async () => { + takeInheritedSpendHome(); const budgetConfig = { ...config, providers: { @@ -279,6 +294,7 @@ describe("server terminal guard integration", () => { }); test("terminal-guard continuation preserves structured cyber_policy semantics", async () => { + takeInheritedSpendHome(); const secret = `OpenAI flagged this request for potential high-risk cybersecurity activity. Authorization: ${["Bear", "er"].join("")} continuationsecret123456`; let sends = 0; globalThis.fetch = (async () => { @@ -316,6 +332,7 @@ describe("server terminal guard integration", () => { }); test("terminal-guard continuation abort during the 429 wait yields 499 without replaying", async () => { + takeInheritedSpendHome(); const abortConfig = { ...config, providers: { @@ -364,6 +381,7 @@ describe("server terminal guard integration", () => { }); test("a stalled continuation body reports 504 even when cancelling it aborts the client signal", async () => { + takeInheritedSpendHome(); // Cancelling the stalled source can disconnect the client in the same tick. The // classifier has to read the thrown error first, or this timeout is reported as a // client cancellation and the caller loses the upstream stall signal. @@ -397,6 +415,7 @@ describe("server terminal guard integration", () => { }); test("a stalled initial body fails with a 504 upstream error instead of a proxy error", async () => { + takeInheritedSpendHome(); // The initial stream has no continuation classifier: without one the bridge catch // reports this upstream timeout as a 500 proxy_error. const stallConfig = { ...config, stallTimeoutSec: 1 } as unknown as OcxConfig; @@ -424,6 +443,7 @@ describe("server terminal guard integration", () => { }); test("terminal-guard 429 wait longer than the stall budget still succeeds (heartbeats)", async () => { + takeInheritedSpendHome(); const stallConfig = { ...config, stallTimeoutSec: 1, @@ -471,6 +491,7 @@ describe("server terminal guard integration", () => { }, 5_000); test("openai-chat provider without terminalContinuationGuard does not re-ask", async () => { + takeInheritedSpendHome(); const chatConfig = openAiChatConfig(); let sends = 0; globalThis.fetch = (async () => { @@ -497,6 +518,7 @@ describe("server terminal guard integration", () => { }); test("openai-chat provider with terminalContinuationGuard false does not re-ask", async () => { + takeInheritedSpendHome(); const chatConfig = openAiChatConfig(false); let sends = 0; globalThis.fetch = (async () => { @@ -522,6 +544,7 @@ describe("server terminal guard integration", () => { }); test("openai-chat provider with terminalContinuationGuard re-asks once and forwards the tool call", async () => { + takeInheritedSpendHome(); const chatConfig = openAiChatConfig(true); let sends = 0; const bodies: Record[] = []; @@ -553,6 +576,7 @@ describe("server terminal guard integration", () => { }); test("combo attempts do not run an opted-in openai-chat terminal guard", async () => { + takeInheritedSpendHome(); const comboConfig = { ...openAiChatConfig(true), combos: { @@ -586,6 +610,7 @@ describe("server terminal guard integration", () => { }); test("routed compaction does not run an opted-in openai-chat terminal guard", async () => { + takeInheritedSpendHome(); const chatConfig = openAiChatConfig(true); let sends = 0; globalThis.fetch = (async () => { diff --git a/tests/server/v2-agent-message-failfast.test.ts b/tests/server/v2-agent-message-failfast.test.ts index 0e0dc66a24b..18aba6211bf 100644 --- a/tests/server/v2-agent-message-failfast.test.ts +++ b/tests/server/v2-agent-message-failfast.test.ts @@ -7,8 +7,12 @@ import { } from "../../src/server/responses"; import type { OcxConfig } from "../../src/types"; import { fakeChatGptJwt } from "../helpers/fake-chatgpt-jwt"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; const originalFetch = globalThis.fetch; +let releaseSpendHome: (() => void) | undefined; +// Direct dispatch needs the writer lease that prevents spend-ledger ownership failures. +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; /** * Structurally faithful Fernet fixture: version + timestamp + IV + one AES-CBC @@ -40,6 +44,9 @@ const ROUTING_ENVELOPE = [ const MESSAGE_ROUTING_ENVELOPE = ROUTING_ENVELOPE.replace("NEW_TASK", "MESSAGE"); afterEach(() => { + // Release the lease before later teardown can replace the preload sandbox home. + releaseSpendHome?.(); + releaseSpendHome = undefined; globalThis.fetch = originalFetch; }); @@ -128,6 +135,16 @@ async function post( }), config, { model: "", provider: "" }); } +async function dispatchPost( + config: OcxConfig, + model: string, + input: unknown[], + headers: HeadersInit = {}, +): Promise { + takeSpendHome(); + return post(config, model, input, headers); +} + describe("V2 routed agent-message ciphertext guard", () => { test("blocks a pure Fernet-only agent task", () => { expect(hasUnreadableEncryptedAgentTask(agentMessage([ @@ -233,7 +250,7 @@ describe("V2 routed agent-message ciphertext guard", () => { }); }) as typeof fetch; - const response = await post( + const response = await dispatchPost( mixedComboConfig(), "combo/mixed", agentMessage([ @@ -313,7 +330,7 @@ describe("V2 routed agent-message ciphertext guard", () => { }); }) as typeof fetch; - const response = await post( + const response = await dispatchPost( config, "combo/mixed", agentMessage([ @@ -500,7 +517,7 @@ describe("V2 routed agent-message ciphertext guard", () => { { type: "input_text", text: ROUTING_ENVELOPE }, { type: "encrypted_content", encrypted_content: FERNET_TASK }, ]); - const response = await post(nativeConfig(), "gpt-5.5", input, { + const response = await dispatchPost(nativeConfig(), "gpt-5.5", input, { authorization: "Bearer caller-codex-token", }); @@ -585,7 +602,7 @@ describe("routed Responses agent-message ciphertext repair", () => { test("repairs a mixed child result replayed behind a later user turn", async () => { const outbound = captureOutbound("relay-model"); - const response = await post(routedResponsesConfig(), "relay/child-model", [mixedChildResult(), userTurn]); + const response = await dispatchPost(routedResponsesConfig(), "relay/child-model", [mixedChildResult(), userTurn]); expect(response.status).toBe(200); expect(outbound()).toHaveLength(1); @@ -604,7 +621,7 @@ describe("routed Responses agent-message ciphertext repair", () => { expect(hasUnreadableEncryptedAgentTask(input)).toBe(false); const outbound = captureOutbound("relay-model"); - const response = await post(routedResponsesConfig(), "relay/child-model", input); + const response = await dispatchPost(routedResponsesConfig(), "relay/child-model", input); expect(response.status).toBe(200); expect(outbound()[0]).not.toContain(FERNET_TASK); @@ -618,7 +635,7 @@ describe("routed Responses agent-message ciphertext repair", () => { expect(hasUnreadableEncryptedAgentTask(input)).toBe(false); const outbound = captureOutbound("relay-model"); - const response = await post(routedResponsesConfig(), "relay/child-model", input); + const response = await dispatchPost(routedResponsesConfig(), "relay/child-model", input); expect(response.status).toBe(200); expect(outbound()[0]).not.toContain(FERNET_TASK); @@ -638,7 +655,7 @@ describe("routed Responses agent-message ciphertext repair", () => { test("leaves a fully readable child result exactly as the adapter already lowered it", async () => { const outbound = captureOutbound("relay-model"); - const response = await post(routedResponsesConfig(), "relay/child-model", [{ + const response = await dispatchPost(routedResponsesConfig(), "relay/child-model", [{ type: "agent_message", author: "/root/child", recipient: "/root", @@ -666,7 +683,7 @@ describe("routed Responses agent-message ciphertext repair", () => { }); }) as typeof fetch; - const response = await post(routedConfig(), "xai/grok-4.5", [mixedChildResult(), userTurn]); + const response = await dispatchPost(routedConfig(), "xai/grok-4.5", [mixedChildResult(), userTurn]); expect(response.status).toBe(200); expect(forwardedBody).toContain("the child finished the migration"); @@ -688,7 +705,7 @@ describe("routed Responses agent-message ciphertext repair", () => { }); }) as typeof fetch; - const response = await post(nativeConfig(), "gpt-5.5", [mixedChildResult(), userTurn], { + const response = await dispatchPost(nativeConfig(), "gpt-5.5", [mixedChildResult(), userTurn], { authorization: "Bearer caller-codex-token", }); @@ -710,7 +727,7 @@ describe("routed Responses agent-message ciphertext repair", () => { } as OcxConfig; const outbound = captureOutbound("relay-model"); - const response = await post(config, "relayfwd/child-model", [mixedChildResult(), userTurn]); + const response = await dispatchPost(config, "relayfwd/child-model", [mixedChildResult(), userTurn]); expect(response.status).toBe(200); expect(outbound()[0]).not.toContain(FERNET_TASK); @@ -736,7 +753,7 @@ describe("routed Responses agent-message ciphertext repair", () => { } as OcxConfig; const outbound = captureOutbound("relay-model"); - const response = await post(config, "combo/routed", [mixedChildResult(), userTurn]); + const response = await dispatchPost(config, "combo/routed", [mixedChildResult(), userTurn]); expect(response.status).toBe(200); expect(outbound()).toHaveLength(1); @@ -755,7 +772,7 @@ describe("routed Responses agent-message ciphertext repair", () => { expect(structurallyValidFernetTokens(`${first}${second}`)).toEqual([FERNET_TASK]); const outbound = captureOutbound("relay-model"); - const response = await post(routedResponsesConfig(), "relay/child-model", [{ + const response = await dispatchPost(routedResponsesConfig(), "relay/child-model", [{ type: "agent_message", author: "/root/child", recipient: "/root", @@ -776,7 +793,7 @@ describe("routed Responses agent-message ciphertext repair", () => { test("repairs a token embedded inside a text part and keeps the prose around it", async () => { const outbound = captureOutbound("relay-model"); - const response = await post(routedResponsesConfig(), "relay/child-model", [{ + const response = await dispatchPost(routedResponsesConfig(), "relay/child-model", [{ type: "agent_message", author: "/root/child", recipient: "/root", @@ -801,7 +818,7 @@ describe("routed Responses agent-message ciphertext repair", () => { for (const [name, text] of Object.entries(readable)) { const outbound = captureOutbound("relay-model"); - const response = await post(routedResponsesConfig(), "relay/child-model", [{ + const response = await dispatchPost(routedResponsesConfig(), "relay/child-model", [{ type: "agent_message", author: "/root/child", recipient: "/root", @@ -819,7 +836,7 @@ describe("routed Responses agent-message ciphertext repair", () => { // two ordinary encoded fragments do not become a marker merely by being adjacent. const outbound = captureOutbound("relay-model"); - const response = await post(routedResponsesConfig(), "relay/child-model", [{ + const response = await dispatchPost(routedResponsesConfig(), "relay/child-model", [{ type: "agent_message", author: "/root/child", recipient: "/root", @@ -847,7 +864,7 @@ describe("routed Responses agent-message ciphertext repair", () => { expect(structurallyValidFernetTokens(blob)).toEqual([]); const outbound = captureOutbound("relay-model"); - const response = await post(routedResponsesConfig(), "relay/child-model", [{ + const response = await dispatchPost(routedResponsesConfig(), "relay/child-model", [{ type: "agent_message", author: "/root/child", recipient: "/root", diff --git a/tests/service/service-tier-capability.test.ts b/tests/service/service-tier-capability.test.ts index febdfc7a6e0..6ab92047eb6 100644 --- a/tests/service/service-tier-capability.test.ts +++ b/tests/service/service-tier-capability.test.ts @@ -26,6 +26,11 @@ import { import { candidateCapabilityEvidence } from "../../src/routing/capability"; import { resolveProductionBehaviorValues } from "../../src/routing/compatibility/behavior"; import type { OcxConfig, OcxProviderConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; + +let releaseSpendHome: (() => void) | undefined; +// Direct dispatch needs the writer lease that prevents spend-ledger ownership failures. +const takeSpendHome = (): void => { releaseSpendHome ??= acquireOwnedSpendHome(); }; describe("registry capability reaches saved configs without overriding them", () => { test("the registry holds the defaults; the seed stays free of them so explicit config stays distinguishable", () => { @@ -389,7 +394,12 @@ describe("routing evidence uses the final model adapter", () => { describe("the gate fires on the live handleResponses path", () => { const originalFetch = globalThis.fetch; - afterEach(() => { globalThis.fetch = originalFetch; }); + afterEach(() => { + // Release the lease before later teardown can replace the preload sandbox home. + releaseSpendHome?.(); + releaseSpendHome = undefined; + globalThis.fetch = originalFetch; + }); function captureBody(): { bodies: Record[] } { const bodies: Record[] = []; @@ -409,7 +419,8 @@ describe("the gate fires on the live handleResponses path", () => { ): Promise> { const { bodies } = captureBody(); const config = { providers: { [providerName]: provider }, ...(fastMode === undefined ? {} : { fastMode }) } as unknown as OcxConfig; - await handleResponses( + takeSpendHome(); + const turn = await handleResponses( new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -419,6 +430,9 @@ describe("the gate fires on the live handleResponses path", () => { { model: "", provider: "" }, {}, ); + // The turn's body is a live stream. Releasing it here means no reader is still attached + // when the lease is dropped, which is what turns a finished case into a pending one. + await turn.body?.cancel(); return bodies[0] ?? {}; } @@ -458,7 +472,8 @@ describe("the gate fires on the live handleResponses path", () => { test("DeepSeek clears a stripped caller tier from request logging", async () => { const { bodies } = captureBody(); const logCtx: RequestLogContext = { model: "", provider: "" }; - await handleResponses( + takeSpendHome(); + const turn = await handleResponses( new Request("http://localhost/v1/responses", { method: "POST", headers: { "content-type": "application/json" }, @@ -473,6 +488,7 @@ describe("the gate fires on the live handleResponses path", () => { logCtx, {}, ); + await turn.body?.cancel(); const upstreamBody = bodies[0]; expect(upstreamBody).toBeDefined(); diff --git a/tests/usage/request-log.test.ts b/tests/usage/request-log.test.ts index f27426480ad..f4842c27809 100644 --- a/tests/usage/request-log.test.ts +++ b/tests/usage/request-log.test.ts @@ -41,25 +41,14 @@ import { mkdtempSync} from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { removeTreeWithRetry } from "../helpers/remove-tree"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; +import { log } from "../helpers/request-log-entry"; import { decodeRequestLogCursor, selectRequestLogPoll } from "../../src/server/request-log-cursor"; async function* replayAdapterEvents(events: AdapterEvent[]): AsyncGenerator { for (const event of events) yield event; } -function log(overrides: Partial): RequestLogEntry { - return { - requestId: "ocx-test", - timestamp: 1, - model: "gpt-test", - provider: "openai", - status: 200, - durationMs: 10, - usageStatus: "unreported", - ...overrides, - }; -} - describe("request log metadata", () => { test("Claude evidence is normalized before direct ring ingress and cannot be mutated afterwards", () => { const previousHome = process.env.OPENCODEX_HOME; @@ -240,6 +229,9 @@ describe("request log metadata", () => { }, } as OcxConfig; + // This row calls the handler directly, so it takes the spend-journal writer lease that + // startServer would have taken. Released in the finally, before the fetch stub is restored. + const releaseSpendHome = acquireOwnedSpendHome(); try { const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", @@ -256,7 +248,11 @@ describe("request log metadata", () => { adapter: "openai-responses", sendCount: 1, })]); + // Read before the lease is released: the row asserts on metadata only, so without this it + // finishes with the turn's body still attached and the lease dropped underneath it. + await response.text(); } finally { + releaseSpendHome(); globalThis.fetch = originalFetch; } }); diff --git a/tests/web-search/web-search-passthrough-bridge.test.ts b/tests/web-search/web-search-passthrough-bridge.test.ts index 92d8a2e9ed3..05d06f4332a 100644 --- a/tests/web-search/web-search-passthrough-bridge.test.ts +++ b/tests/web-search/web-search-passthrough-bridge.test.ts @@ -32,6 +32,7 @@ import { waitForProviderRequestSlot, } from "../../src/providers/request-pacing"; import type { OcxConfig, OcxParsedRequest, OcxProviderConfig, ProviderWebSearchBridgeBackend, ProviderWebSearchBridgeConfig } from "../../src/types"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; /** One SSE event block without its blank-line delimiter. */ function frame(type: string, payload: Record): string { @@ -1420,6 +1421,8 @@ describe("the reported turn, end to end through handleResponses", () => { hooks.onProviderResponse?.(leg); return new Response(text, { headers: { "content-type": "text/event-stream" } }); }) as unknown as typeof fetch; + // Direct dispatch needs the writer lease that startServer normally owns for this home. + const releaseSpendHome = acquireOwnedSpendHome(); try { const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", @@ -1428,6 +1431,8 @@ describe("the reported turn, end to end through handleResponses", () => { }), ocxConfig, { model: "", provider: "" }); return { body: await response.text(), outbound, destinations, searches, searchUrls, searchHeaders }; } finally { + // Release before later teardown can replace or remove the preload sandbox home. + releaseSpendHome(); globalThis.fetch = savedFetch; } } diff --git a/tests/web-search/web-search.test.ts b/tests/web-search/web-search.test.ts index 0041ff26462..ebc3ecd405e 100644 --- a/tests/web-search/web-search.test.ts +++ b/tests/web-search/web-search.test.ts @@ -15,6 +15,7 @@ import type { OcxMessage, OcxParsedRequest } from "../../src/types"; import { fakeChatGptJwt } from "../helpers/fake-chatgpt-jwt"; import { createTestTranslatorBudget } from "../helpers/translator-budget"; import { withUpstreamHttpVersion } from "../../src/lib/upstream-http-version"; +import { acquireOwnedSpendHome } from "../helpers/owned-spend-home"; /** * Wrap a fetch so it applies the provider's HTTP-version pin the way `providerFetch` does in @@ -566,7 +567,13 @@ describe("web-search sidecar planning", () => { }); const originalFetch = globalThis.fetch; -afterEach(() => { globalThis.fetch = originalFetch; }); +let releaseSpendHome: (() => void) | undefined; +afterEach(() => { + // Release the preload-home lease before later teardown can replace or remove that home. + releaseSpendHome?.(); + releaseSpendHome = undefined; + globalThis.fetch = originalFetch; +}); test("issue #2885 — Zhipu-shaped web-search routing preserves the provider HTTP version pin", async () => { let routedProtocol: string | undefined; @@ -606,6 +613,8 @@ test("issue #2885 — Zhipu-shaped web-search routing preserves the provider HTT throw new Error("the routed web-search leg must use the provider fetch"); }) as typeof fetch; + // Direct dispatch needs the writer lease that startServer normally owns for this home. + releaseSpendHome = acquireOwnedSpendHome(); const response = await handleResponses(new Request("http://localhost/v1/responses", { method: "POST", headers: { diff --git a/tests/windows/windows-deploy-close-regressions.test.ts b/tests/windows/windows-deploy-close-regressions.test.ts index 5d4504fea67..b65925b29be 100644 --- a/tests/windows/windows-deploy-close-regressions.test.ts +++ b/tests/windows/windows-deploy-close-regressions.test.ts @@ -90,7 +90,14 @@ describe("server bind canonicalizes explicit localhost but preserves wildcards ( // loopback-only, so a bare substring ban would forbid the fix rather than the defect. // Pin the assertion to the public serve call instead: it must take bindHost and nothing // else. - expect(src).toContain("server = Bun.serve({ ...serveOptions, port: listenPort, hostname: bindHost });"); + // Wrapper-aware, because the public listener is now handed to a lifecycle registrar as it is + // created. Both halves of the original claim are kept: the serve call's argument object is + // pinned exactly, so the public bind still takes bindHost and nothing else, and `server` is + // still what that call is assigned to, through at most one registrar call. + expect(src).toContain("Bun.serve({ ...serveOptions, port: listenPort, hostname: bindHost })"); + expect(src).toMatch( + /\bserver = (?:[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*\()?Bun\.serve\(\{ \.\.\.serveOptions, port: listenPort, hostname: bindHost \}\)/, + ); expect(src).not.toMatch(/port: listenPort,\s*\n\s*hostname: "127\.0\.0\.1"/); expect(src).not.toContain("port: listenPort, hostname: \"127.0.0.1\""); }); From 838af40f1b2fe32596b207ff85afcda40636f4d9 Mon Sep 17 00:00:00 2001 From: JUN Date: Sun, 20 Sep 2026 00:00:40 +0900 Subject: [PATCH 48/97] feat(registry): derive selector decode hints from a classified registry (#5177) * feat(registry): derive selector decode hints from a classified registry An encoded selector decodes against the native model ids a provider is known to accept. That set was a hand-written list of eight registry maps, so an id declared only in an unlisted map could not be decoded, and every new model-keyed field had to be remembered by whoever added it. src/providers/registry/model-ids.ts now classifies every field of ProviderRegistryEntry by what its KEYS mean, and knownModelIdsForProvider asks the registry instead of listing maps itself. Fifteen direct maps contribute keys, keyAuthServiceTier contributes its nested modelSupportsServiceTier keys, and the remaining seventy-five fields are classified as carrying no identity. Classifying the non-model fields is the point: the satisfies clause makes a new registry field a type error until somebody decides what its keys mean, rather than letting it default to invisible. Two checks, deliberately different. The satisfies clause proves the classification is exhaustive over the interface when this compiles; a parity case proves the fields the shipped entries actually carry are all classified. A new interface field fails the first, a shipped entry carrying something unclassified fails the second. Hints stay identity evidence. They publish no catalog row, grant no availability or entitlement, and confer no transport authority: registry transport identity is still checked before hints are read, an ambiguous selector is still rejected rather than guessed, and virtualModels contributes its selectable keys only, never the wire target a client may not name. Coverage: each formerly omitted direct map and the nested map independently seed a decode, with negatives for unknown pass-through, ambiguous rejection, transport mismatch and no catalog row from a hint alone; the parity suite adds per-map collection, non-model records contributing nothing, stable first-seen-wins ordering, and the shipped meta-muse entry recovering its ids from maps alone. The classifier is imported directly rather than through the registry facade, which is at its file-size cap. No layout inventory changes, since no test file was added. routedProviderConfig and the static policy paths are untouched. Local checks: NOT RUN. * test(registry): cover all fifteen classified maps at the public route level The route-level table proved the seven maps the old hand-written list omitted. The other eight rested on helper parity alone, which is a weaker claim: after this change every one of them is reached through the same classification, so they belong in the same public table. It now covers all fifteen direct maps plus the nested key-auth map. Also asserts the helper's documented contract rather than assuming it: the returned array is frozen and rejects a push, and the registry entry is byte-identical afterwards. That matters because the registry is process-wide shared state, and a decode path that sorted an entry's maps in place would be editing it for every later caller. A shipped-entry route case was written and then dropped rather than kept. The Muse ids contain no slash, so encoding them is the identity function and the route would pass them through whether or not any hint existed. It proved nothing about decoding, and the fifteen synthetic slash-bearing rows already prove that at the public level. The shipped-entry evidence stays where it is honest: the parity suite asserts the helper recovers those ids from the classified maps, which is meaningful because the helper never reads the models list even though this entry also declares them there. No production change, no new fixture mechanism, no cap or layout movement. Local checks: NOT RUN. * fix(registry): read classified registry fields through typed keys The decode-hint loop asserted the entry to Record to index it by field name. ProviderRegistryEntry is an interface, so it carries no implicit index signature and tsc rejected the conversion as insufficiently overlapping (TS2352 at model-ids.ts:152), which failed Typecheck and the test that spawns a real tsc over the production graph. Iterating the classification's own keys as keyof ProviderRegistryEntry keeps the read typed: the record-keys branch indexes the entry by that key and guards the value as a non-null object, and the nested role reads keyAuthServiceTier by name because that field is its only owner. Same fields, same order, same keys; no assertion through unknown and no behavior change. local checks: NOT RUN --- src/providers/registry/model-ids.ts | 167 ++++++++++++++++++ src/router.ts | 21 +-- structure/catalog.md | 8 + structure/providers-and-adapters.md | 1 + tests/codex-integration/slug-codec.test.ts | 125 +++++++++++++ .../provider-registry-parity.test.ts | 120 +++++++++++++ 6 files changed, 429 insertions(+), 13 deletions(-) create mode 100644 src/providers/registry/model-ids.ts diff --git a/src/providers/registry/model-ids.ts b/src/providers/registry/model-ids.ts new file mode 100644 index 00000000000..d074176e811 --- /dev/null +++ b/src/providers/registry/model-ids.ts @@ -0,0 +1,167 @@ +import type { ProviderRegistryEntry } from "./types"; + +/** + * What a registry field's KEYS mean for selector decoding. + * + * An encoded selector is decoded against the native model ids a provider is known to accept. + * That set used to be a hand-written list of eight registry maps, so an id declared only in an + * unlisted map could not be decoded, and every new model-keyed field had to be remembered. + * + * Every field of ProviderRegistryEntry is classified below, including the ones that carry no + * model identity at all. That is deliberate: the "satisfies" check makes a new registry field a + * TYPE error until somebody decides what its keys mean, rather than letting it default to + * invisible. The two checks are different and both matter - the satisfies clause proves the + * classification is exhaustive when this compiles, and the parity test proves the fields the + * shipped registry actually carries are the ones classified here. + * + * These are decode hints and nothing more. A hint does not publish a catalog row, grant + * availability or entitlement, and it does not confer transport authority: the caller still + * checks registry transport identity before asking for them, and an ambiguous selector is still + * rejected rather than guessed. + */ +type RegistryFieldModelIdRole = + | { readonly kind: "none" } + | { readonly kind: "record-keys" } + | { readonly kind: "nested-record-keys"; readonly key: "modelSupportsServiceTier" }; + +const NONE = { kind: "none" } as const; +const RECORD_KEYS = { kind: "record-keys" } as const; +/** + * Key-auth declares its own service-tier support under a nested map. + * + * Reading its keys is identity evidence only. It does not activate the key-auth service tier, + * which stays the business of the service-tier resolver. + */ +const KEY_AUTH_SERVICE_TIER = { kind: "nested-record-keys", key: "modelSupportsServiceTier" } as const; + +/** + * Not a configuration surface. Exported so the parity suite can compare this classification + * against the fields the shipped registry entries actually carry at runtime. + */ +export const REGISTRY_FIELD_MODEL_ID_ROLES = { + id: NONE, + label: NONE, + adapter: NONE, + baseUrl: NONE, + apiKeyTransport: NONE, + alias: NONE, + authKind: NONE, + codexAccountMode: NONE, + allowKeyAuthOverride: NONE, + allowPrivateNetworkByDefault: NONE, + keyOptional: NONE, + apiKeyValidation: NONE, + freeTier: NONE, + allowBaseUrlOverride: NONE, + preserveCustomDestination: NONE, + baseUrlChoices: NONE, + staticHeaders: NONE, + modelSuffixBracketStrip: NONE, + featured: NONE, + sponsor: NONE, + dashboardPreset: NONE, + note: NONE, + dashboardUrl: NONE, + defaultModel: NONE, + models: NONE, + liveModels: NONE, + modelWireDefaults: RECORD_KEYS, + fastWire: NONE, + modelResponsesUpstreamStreaming: RECORD_KEYS, + modelResponsesTerminalRepair: RECORD_KEYS, + responsesItemIdRepair: NONE, + responsesPath: NONE, + chatCompletionsPath: NONE, + destinationAliases: NONE, + statelessResponses: NONE, + requiresAdjacentResponsesToolResults: NONE, + requiresPairedResponsesToolResults: NONE, + annotateEmptyToolOutputs: NONE, + supportsServiceTier: NONE, + supportsOpenAiWebSearchToolFields: NONE, + supportsResponsesCustomTools: NONE, + modelSupportsServiceTier: RECORD_KEYS, + keyAuthServiceTier: KEY_AUTH_SERVICE_TIER, + fastTierDescription: NONE, + modelServiceTierCapabilityBaseUrlGuard: NONE, + preserveResponsesReasoningContent: NONE, + modelSupportsReasoningSummaries: RECORD_KEYS, + modelSupportsVerbosity: RECORD_KEYS, + supportsVerbosity: NONE, + modelDiscovery: NONE, + contextWindow: NONE, + modelContextWindows: RECORD_KEYS, + modelDisplayNames: RECORD_KEYS, + modelInputModalities: RECORD_KEYS, + defaultMaxOutputTokens: NONE, + modelMaxOutputTokens: RECORD_KEYS, + reasoningEfforts: NONE, + modelReasoningEfforts: RECORD_KEYS, + modelDefaultReasoningEfforts: RECORD_KEYS, + reasoningEffortMap: NONE, + modelReasoningEffortMap: RECORD_KEYS, + directReasoningEffortModels: NONE, + reasoningWireFormat: NONE, + noVisionModels: NONE, + noReasoningModels: NONE, + noTemperatureModels: NONE, + noTopPModels: NONE, + noPenaltyModels: NONE, + noJsonSchemaModels: NONE, + parallelToolCalls: NONE, + promptCacheKey: NONE, + chatServiceTier: NONE, + openaiChatEofTolerance: NONE, + autoToolChoiceOnlyModels: NONE, + preserveReasoningContentModels: NONE, + requiresReasoningPlaceholderModels: NONE, + showThinkingSummary: NONE, + reasoningSplitModels: NONE, + reasoningDetailsModels: NONE, + thinkingToggleModels: NONE, + thinkingBudgetModels: NONE, + escapeBuiltinToolNames: NONE, + oauthId: NONE, + virtualModels: RECORD_KEYS, + modelMaxInputTokens: RECORD_KEYS, + jawcodeBundle: NONE, + extraMetadataAliases: NONE, + metadataModelIdNormalize: NONE, + googleMode: NONE, + project: NONE, + location: NONE, +} satisfies Record; + +/** + * The native model ids this registry entry names, in registry-field order, first seen wins. + * + * Only KEYS are collected. virtualModels is a map whose keys are the selected identities and + * whose values name a transport target, so its wireModelId values are deliberately not read: + * a wire target is not something a client may select by name. + */ +export function registryModelIdKeys(entry: ProviderRegistryEntry): readonly string[] { + const ids: string[] = []; + const seen = new Set(); + const add = (key: string): void => { + if (key.length === 0 || seen.has(key)) return; + seen.add(key); + ids.push(key); + }; + for (const field of Object.keys(REGISTRY_FIELD_MODEL_ID_ROLES) as (keyof ProviderRegistryEntry)[]) { + const role = REGISTRY_FIELD_MODEL_ID_ROLES[field]; + if (role.kind === "none") continue; + if (role.kind === "record-keys") { + const map = entry[field]; + if (typeof map !== "object" || map === null) continue; + for (const key of Object.keys(map)) add(key); + continue; + } + // The nested role belongs to keyAuthServiceTier alone, so its owner is read by name. + // ProviderRegistryEntry is an interface and carries no implicit index signature, so a + // by-name read is what keeps this loop typed instead of asserted through unknown. + const nested = entry.keyAuthServiceTier?.[role.key]; + if (typeof nested !== "object" || nested === null) continue; + for (const key of Object.keys(nested)) add(key); + } + return Object.freeze(ids); +} diff --git a/src/router.ts b/src/router.ts index 3e28a911869..26a60d4913d 100644 --- a/src/router.ts +++ b/src/router.ts @@ -19,6 +19,9 @@ import { providerCodexAccountMode, registryModelServiceTierCapabilityApplies, } from "./providers/registry"; +// Imported from the module directly rather than through the registry facade, which is at its +// file-size cap. +import { registryModelIdKeys } from "./providers/registry/model-ids"; import { applyDirectReasoningEffortContracts, hasLegacyClinePassReasoningEfforts } from "./providers/derive"; import { cloneFastWire } from "./providers/fastwire"; import { @@ -117,19 +120,11 @@ export function knownModelIdsForProvider( : undefined; for (const id of registry?.models ?? []) ids.add(id); // Registry model-keyed hint maps double as known native ids (e.g. NVIDIA carries no - // static models list but names `moonshotai/kimi-k2.6` in its effort/window maps). - for (const map of [ - registry?.modelContextWindows, - registry?.modelInputModalities, - registry?.modelReasoningEfforts, - registry?.modelDefaultReasoningEfforts, - registry?.modelReasoningEffortMap, - registry?.modelMaxOutputTokens, - registry?.modelSupportsServiceTier, - registry?.modelSupportsVerbosity, - ]) { - for (const id of Object.keys(map ?? {})) ids.add(id); - } + // static models list but names `moonshotai/kimi-k2.6` in its effort/window maps). Which + // maps count is classified by the registry itself rather than listed here, so an id declared + // only in a map this function forgot is no longer undecodable, and a new model-keyed field + // fails typecheck until its keys are given a meaning. + for (const id of registry ? registryModelIdKeys(registry) : []) ids.add(id); for (const cached of getStaleCached(provName) ?? []) ids.add(cached.id); for (const model of config?.customModels ?? []) { if (model.provider === provName && model.modelId) ids.add(model.modelId); diff --git a/structure/catalog.md b/structure/catalog.md index dfa424ea1b5..0f8b8449974 100644 --- a/structure/catalog.md +++ b/structure/catalog.md @@ -86,6 +86,14 @@ keeps a combo's advertised intersection aligned with the final custom row withou provider-native row or inventing capabilities for other models. Public custom-row materialization and routed-slug deduplication remain the final catalog owner's responsibility. Codex's native `ultra` mode is preserved and is not a literal API wire promise. + +Selector decode hints are identity evidence and nothing else. `knownModelIdsForProvider` unions +the configured models, the registry's static list, the native ids the registry's classified +model-keyed maps name (`src/providers/registry/model-ids.ts`), the last-known-good discovery +cache and custom model ids, so an id declared only in a policy map still round-trips through an +encoded selector. A hint publishes no catalog row, grants no availability or entitlement and +confers no transport authority: the registry transport identity is checked before hints are +read, and an ambiguous selector is still rejected rather than guessed. When account selectors are enabled, the sync path may also observe exact, visible, API-supported OpenAI-family ids from Codex's user-owned catalog/cache. Only rows with native catalog provenance are trusted; unknown ids are carried through startup cache invalidation as hidden observations and diff --git a/structure/providers-and-adapters.md b/structure/providers-and-adapters.md index 91ec48f0130..b9049bf3ae2 100644 --- a/structure/providers-and-adapters.md +++ b/structure/providers-and-adapters.md @@ -7,6 +7,7 @@ the [bounded ingestion contract](transports/inventory.md#bounded-response-ingest | Path | Responsibility | | --- | --- | | `src/providers/registry.ts` | Compatibility facade; canonical provider presets for CLI, dashboard, OAuth, key providers, and metadata live in `src/providers/registry/entries-core.ts` and `entries-extended.ts`, with model seeds in `model-seeds.ts`. | +| `src/providers/registry/model-ids.ts` | Classifies every `ProviderRegistryEntry` field by what its KEYS mean for selector decoding, and derives the native model ids an entry names. The classification is exhaustive by construction: a new registry field fails typecheck until its keys are given a meaning, which is what stops an identity-bearing map from being silently left out of decoding. Imported directly rather than through the facade, which is at its file-size cap. | | `src/providers/derive.ts` | Enrichment from provider presets into user config. | | `src/oauth/` | OAuth providers, token storage, refresh, and auth-token resolution. The login callback listener binds a per-provider FIXED loopback port, so consecutive logins reuse the same number; every response it sends ends its connection (`Connection: close`, including non-callback paths such as a stray `/favicon.ico` 404). Stopping the listener does not close an established socket, so without that a pooled client would deliver the next login's callback to the retired flow, which rejects the unknown state as a CSRF mismatch while the live flow waits. Kiro add-account identity prefers same-session `whoami` over a leftover SQLite state profile, and never persists the Builder ID service profile ARN as `accountId`. | | `src/combos/request.ts` | Clones each selected combo target request and applies the existing target capability ladder: adaptive unknown targets and explicit empty ladders receive no unsupported reasoning/thinking controls, while known ladders retain per-target resolution. | diff --git a/tests/codex-integration/slug-codec.test.ts b/tests/codex-integration/slug-codec.test.ts index 5248b75020c..a7e1550411c 100644 --- a/tests/codex-integration/slug-codec.test.ts +++ b/tests/codex-integration/slug-codec.test.ts @@ -19,6 +19,8 @@ import { knownModelIdsForProvider, routeModel } from "../../src/router"; import { buildCatalogEntries, resetCatalogRuntimeStateForTests } from "../../src/codex/catalog"; import { clearModelCache, setCached } from "../../src/codex/model-cache"; import { getModelMetadata } from "../../src/generated/model-metadata"; +import { PROVIDER_REGISTRY } from "../../src/providers/registry"; +import { registryModelIdKeys } from "../../src/providers/registry/model-ids"; import type { RawEntry } from "../../src/codex/catalog"; import type { OcxConfig } from "../../src/types"; @@ -119,6 +121,44 @@ describe("slug-codec primitives", () => { }); describe("routeModel decode (proxy layer)", () => { + const fixtureId = "slug-codec-registry-fixture"; + const fixtureBaseUrl = "https://slug-codec-registry.fixture.example/v1"; + const mutableRegistry = PROVIDER_REGISTRY as unknown as Array>; + + function withSyntheticRegistryEntry( + fields: Record, + assertion: (config: OcxConfig) => void, + ): void { + // A disposable row prevents decode tests from changing any shipped provider metadata. + mutableRegistry.push({ + id: fixtureId, + label: "Slug codec registry fixture", + adapter: "openai-chat", + baseUrl: fixtureBaseUrl, + authKind: "key", + preserveCustomDestination: true, + ...fields, + }); + const config: OcxConfig = { + port: 10100, + defaultProvider: fixtureId, + providers: { + [fixtureId]: { + adapter: "openai-chat", + baseUrl: fixtureBaseUrl, + authMode: "key", + apiKey: "k", + }, + }, + }; + try { + assertion(config); + } finally { + const index = mutableRegistry.findIndex(entry => entry.id === fixtureId); + if (index >= 0) mutableRegistry.splice(index, 1); + } + } + test("encoded zenmux slug decodes to the native id via the registry seed (cold cache)", () => { const route = routeModel(zenmuxConfig(), "zenmux/moonshotai-kimi-k3-free"); expect(route.providerName).toBe("zenmux"); @@ -149,6 +189,91 @@ describe("routeModel decode (proxy layer)", () => { expect(routeModel(config, "nvidia/moonshotai/kimi-k2.6").modelId).toBe("moonshotai/kimi-k2.6"); }); + test("every classified direct registry map independently seeds selector decoding", () => { + // All fifteen, not only the ones the old hand-written list omitted. The eight it did carry + // are now reached through the same classification as the rest, so they belong in the public + // route-level table too rather than resting on helper-level parity alone. + const cases = [ + ["modelWireDefaults", "openai-chat"], + ["modelResponsesUpstreamStreaming", false], + ["modelResponsesTerminalRepair", { graceMs: 25 }], + ["modelSupportsServiceTier", true], + ["modelSupportsReasoningSummaries", false], + ["modelSupportsVerbosity", true], + ["modelContextWindows", 100_000], + ["modelDisplayNames", "Synthetic display name"], + ["modelInputModalities", ["text"]], + ["modelMaxOutputTokens", 8_000], + ["modelReasoningEfforts", ["low"]], + ["modelDefaultReasoningEfforts", "low"], + ["modelReasoningEffortMap", { low: "low" }], + ["virtualModels", { wireModelId: "wire-target", reasoningMode: "pro" }], + ["modelMaxInputTokens", 100_000], + ] as const; + const nativeIds = new Map(); + const fields = Object.fromEntries(cases.map(([field, value], index) => { + const nativeId = `vendor/${field}-${index}`; + nativeIds.set(field, nativeId); + return [field, { [nativeId]: value }]; + })); + + withSyntheticRegistryEntry(fields, config => { + for (const [field] of cases) { + const nativeId = nativeIds.get(field)!; + const route = routeModel(config, `${fixtureId}/${encodeRoutedModelId(nativeId)}`); + expect(route.modelId, field).toBe(nativeId); + } + }); + }); + + test("the nested key-auth service-tier map seeds selector decoding", () => { + const nativeId = "vendor/nested-service-tier-model"; + withSyntheticRegistryEntry({ + keyAuthServiceTier: { modelSupportsServiceTier: { [nativeId]: true } }, + }, config => { + expect(routeModel(config, `${fixtureId}/${encodeRoutedModelId(nativeId)}`).modelId).toBe(nativeId); + }); + }); + + test("the collected ids are frozen and the registry entry is left untouched", () => { + // The helper documents a frozen result and promises not to mutate registry data. A caller + // that could push into the returned array, or a helper that sorted the entry's own maps in + // place, would be editing shared process-wide registry state from a decode path. + const metaMuse = PROVIDER_REGISTRY.find(entry => entry.id === "meta-muse")!; + const before = JSON.stringify(metaMuse); + const ids = registryModelIdKeys(metaMuse); + expect(Object.isFrozen(ids)).toBe(true); + expect(() => (ids as string[]).push("vendor/injected")).toThrow(); + expect(JSON.stringify(metaMuse)).toBe(before); + }); + + test("decode hints preserve unknown pass-through and ambiguous-selector rejection", () => { + withSyntheticRegistryEntry({ + modelWireDefaults: { "a/b-c": "openai-chat" }, + modelDisplayNames: { "a-b/c": "Ambiguous sibling" }, + }, config => { + expect(routeModel(config, `${fixtureId}/unknown-model`).modelId).toBe("unknown-model"); + expect(() => routeModel(config, `${fixtureId}/a-b-c`)).toThrow(/ambiguous/); + }); + }); + + test("a provider with a mismatched transport inherits no registry decode hints", () => { + const nativeId = "vendor/transport-guarded-model"; + withSyntheticRegistryEntry({ modelDisplayNames: { [nativeId]: "Transport guarded" } }, config => { + config.providers[fixtureId]!.baseUrl = "https://unrelated.example/v1"; + expect(routeModel(config, `${fixtureId}/${encodeRoutedModelId(nativeId)}`).modelId) + .toBe(encodeRoutedModelId(nativeId)); + }); + }); + + test("a registry decode hint alone does not publish a catalog row", () => { + const nativeId = "vendor/decode-hint-only"; + withSyntheticRegistryEntry({ modelDisplayNames: { [nativeId]: "Decode hint only" } }, () => { + const entries = buildCatalogEntries(nativeTemplate(), [], []); + expect(entries.some(entry => entry.slug === `${fixtureId}/${encodeRoutedModelId(nativeId)}`)).toBe(false); + }); + }); + test("defaultModel encoded fallback routes to the native id", () => { const config: OcxConfig = { port: 10100, diff --git a/tests/providers/provider-registry-parity.test.ts b/tests/providers/provider-registry-parity.test.ts index fe67c9ac99d..91d311ac3ca 100644 --- a/tests/providers/provider-registry-parity.test.ts +++ b/tests/providers/provider-registry-parity.test.ts @@ -16,6 +16,12 @@ import { providerConfigSeed, } from "../../src/providers/derive"; import { PROVIDER_REGISTRY, registryEntryForProviderDestination } from "../../src/providers/registry"; +import { + REGISTRY_FIELD_MODEL_ID_ROLES, + registryModelIdKeys, +} from "../../src/providers/registry/model-ids"; +import type { ProviderRegistryEntry } from "../../src/providers/registry/types"; +import { META_MUSE_MODELS } from "../../src/providers/registry/model-seeds"; import { FREE_PROVIDER_DIRECTORY } from "../../src/providers/free-directory"; import { applyProviderConfigHints } from "../../src/codex/catalog"; import { routeModel } from "../../src/router"; @@ -58,6 +64,120 @@ describe("provider registry parity", () => { expect(new Set(ids).size).toBe(ids.length); }); + test("every field carried by the shipped registry has a model-id role classification", () => { + // This is the runtime half. The module's satisfies clause is the compile-time half, so + // together they catch both a new interface field and a shipped entry carrying an unclassified field. + const classifiedFields = new Set(Object.keys(REGISTRY_FIELD_MODEL_ID_ROLES)); + for (const entry of PROVIDER_REGISTRY) { + for (const field of Object.keys(entry)) { + expect(classifiedFields.has(field), `${entry.id}.${field}`).toBe(true); + } + } + }); + + test("every direct model-id map is collected independently", () => { + const cases = [ + ["modelWireDefaults", "openai-chat"], + ["modelResponsesUpstreamStreaming", false], + ["modelResponsesTerminalRepair", { graceMs: 25 }], + ["modelSupportsServiceTier", true], + ["modelSupportsReasoningSummaries", false], + ["modelSupportsVerbosity", true], + ["modelContextWindows", 100_000], + ["modelDisplayNames", "Synthetic display name"], + ["modelInputModalities", ["text"]], + ["modelMaxOutputTokens", 8_000], + ["modelReasoningEfforts", ["low"]], + ["modelDefaultReasoningEfforts", "low"], + ["modelReasoningEffortMap", { low: "low" }], + ["virtualModels", { wireModelId: "wire-target", reasoningMode: "pro" }], + ["modelMaxInputTokens", 90_000], + ] as const; + + for (const [field, value] of cases) { + const modelId = `vendor/${field}`; + const entry = { + id: `fixture-${field}`, + label: `Fixture ${field}`, + adapter: "openai-chat", + baseUrl: "https://registry-model-id.fixture.example/v1", + authKind: "key", + [field]: { [modelId]: value }, + } as ProviderRegistryEntry; + expect(registryModelIdKeys(entry), field).toEqual([modelId]); + } + }); + + test("non-model records contribute no selector identities", () => { + const entry = { + id: "fixture-non-model-records", + label: "Fixture non-model records", + adapter: "openai-chat", + baseUrl: "https://registry-model-id.fixture.example/v1", + authKind: "key", + staticHeaders: { "x-model/header": "value" }, + reasoningEffortMap: { "effort/label": "high" }, + responsesItemIdRepair: { + message: ["message/value"], + reasoning: ["reasoning/value"], + repairMissingTerminalIds: true, + }, + } as ProviderRegistryEntry; + expect(registryModelIdKeys(entry)).toEqual([]); + }); + + test("virtual models contribute selectable keys but never wire target values", () => { + const entry = { + id: "fixture-virtual-model", + label: "Fixture virtual model", + adapter: "openai-chat", + baseUrl: "https://registry-model-id.fixture.example/v1", + authKind: "key", + virtualModels: { + "client/selectable": { wireModelId: "wire/target", reasoningMode: "pro" }, + }, + } as ProviderRegistryEntry; + expect(registryModelIdKeys(entry)).toEqual(["client/selectable"]); + expect(registryModelIdKeys(entry)).not.toContain("wire/target"); + }); + + test("deduplication keeps registry-field order and the first occurrence", () => { + const entry = { + id: "fixture-stable-deduplication", + label: "Fixture stable deduplication", + adapter: "openai-chat", + baseUrl: "https://registry-model-id.fixture.example/v1", + authKind: "key", + modelWireDefaults: { + "first/model": "openai-chat", + "shared/model": "openai-chat", + }, + modelResponsesUpstreamStreaming: { + "shared/model": false, + "second/model": false, + }, + modelContextWindows: { + "third/model": 100_000, + "shared/model": 100_000, + }, + } as ProviderRegistryEntry; + expect(registryModelIdKeys(entry)).toEqual([ + "first/model", + "shared/model", + "second/model", + "third/model", + ]); + }); + + test("a shipped entry's ids are recovered from its classified maps, not its models list", () => { + const metaMuse = PROVIDER_REGISTRY.find(entry => entry.id === "meta-muse")!; + // meta-muse declares these ids in BOTH its models list and its context-window, modality and + // effort maps. The helper never reads models, so recovering them here is evidence the maps + // were read. Compared against the seed the entry is built from rather than a copied literal, + // so adding a Muse model does not fail this case for the wrong reason. + expect(registryModelIdKeys(metaMuse)).toEqual([...META_MUSE_MODELS]); + }); + test("key-login export is derived from the registry", () => { expect(KEY_LOGIN_PROVIDERS).toEqual(deriveKeyLoginMap()); expect(Object.keys(KEY_LOGIN_PROVIDERS)).toEqual(EXPECTED_KEY_PROVIDER_IDS); From 96a6de86b71cf8a8f78959e0bf626dac642510a7 Mon Sep 17 00:00:00 2001 From: JUN Date: Sun, 20 Sep 2026 00:26:52 +0900 Subject: [PATCH 49/97] Reject lossy Google tool schemas on opt-in (#5167) * feat(providers): opt-in rejection of lossy Google tool schemas Add persisted provider-scoped googleToolSchemaPolicy with an opt-in reject-lossy value. Under the policy, any initial compilation with schema loss throws a content-free policy error before the request can reach a physical send, and a structured 400 repair that would erase declaration constraints is withheld: the original upstream 400 returns through the existing error path with no changed repair send, no attempt accounting change, and a content-free repair diagnostic. The field is validated at the schema boundary, admitted to the management provider editor as editor-safe state, creatable through ocx provider add, and documented in English and all seven locales. Omission remains the compatible report-only behavior; direct mode keeps its existing no-repair path. Closes #5112 * docs(structure): list the complete bounded repair diagnostic shape * feat(providers): refuse indeterminate compilation under reject-lossy Cascade follow-up to the parent's uncertainty reporting: strict policy now refuses when bounded comparison is exhausted (uncertainComparisons > 0) as well as on proven loss, and the policy error names the indeterminate cause. An exhausted comparison can hide a changed constraint, so unknown is never admitted as lossless. Compatible mode is unchanged. Adapter-boundary tests assert refusal with zero sends for every endpoint mode. Closes #5112 * test(providers): expect the preserved original 400 in the Vertex repair test n The withheld-repair contract returns the original upstream 400 through the pre-existing normalization, which preserves ordinary upstream detail text. The previous assertion wrongly demanded the client response exclude the canary; the canary exclusion binds the new google-tool-schema-repair diagnostic record, which remains asserted. Hosted CI run 35443168272 shard test 1/4 caught the wrong assertion (red); this is the fix. Part of #5112 * test(server): name the Google schema-policy config test for the server domain The layout membership oracle requires the regex seed and the explicit table to agree: google-tool-schema-policy-config.test.ts seeded to adapters/google while sitting in tests/server. Rename to the server convention (management-google-tool-schema-policy.test.ts) so the seed resolves correctly, and update both inventories. The oracle is unchanged. Part of #5112 * docs(providers): document indeterminate refusal and the uncertainty field Review fold: strict policy refuses initial loss OR an indeterminate bounded comparison (uncertainComparisons > 0), and the initial and repair diagnostics carry the bounded uncertainty count. All eight guides, all eight provider-configuration pages, and the structure contract now say so consistently. Part of #5112 * test(providers): assert the preserved original 400 body in both paths Review fold: the Cloud Code Assist and direct-mode strict tests now assert the returned body is exactly the original upstream error payload, not merely status 400 and a single send, and the guide texts state that repair withholding applies only under reject-lossy while omitted or compatible policies replay the repaired request (all eight locales). Part of #5112 * docs(providers): strict initial refusal emits no loss record Source-confirmed: under reject-lossy the compiler throws before the diagnostic call, so the initial loss record appears only on the omitted/compatible path; the policy error carries the same bounded facts, and the repair path keeps its separate record. Clarified in all eight guides. Part of #5112 * docs(providers): drop the unbounded policy-error claim Review fold: the policy error carries phase, endpoint class, category counts, and the indeterminate flag, not the full report shape. The clause claiming otherwise is removed from all eight guides; the strict no-loss-record statement stays. Part of #5112 --- .../src/content/docs/fr/guides/providers.md | 18 +- .../fr/reference/configuration/providers.md | 1 + .../src/content/docs/guides/providers.md | 16 +- .../src/content/docs/ja/guides/providers.md | 13 +- .../ja/reference/configuration/providers.md | 1 + .../src/content/docs/ko/guides/providers.md | 15 +- .../ko/reference/configuration/providers.md | 1 + .../docs/reference/configuration/providers.md | 1 + .../src/content/docs/ru/guides/providers.md | 17 +- .../ru/reference/configuration/providers.md | 1 + .../src/content/docs/tr/guides/providers.md | 15 +- .../tr/reference/configuration/providers.md | 1 + .../content/docs/zh-cn/guides/providers.md | 13 +- .../reference/configuration/providers.md | 1 + .../content/docs/zh-tw/guides/providers.md | 12 +- .../reference/configuration/providers.md | 1 + scripts/test-layout/layout.json | 1 + src/adapters/google-http.ts | 59 +++- src/adapters/google-tool-schema.ts | 2 + src/adapters/google-wire-compiler.ts | 54 +++- src/adapters/google.ts | 13 +- src/cli/provider.ts | 14 +- src/config/schema/leaf-validators.ts | 1 + src/server/auth-cors.ts | 1 + src/types/provider.ts | 2 + structure/config.md | 8 + structure/gui-and-management-api.md | 5 + structure/ops/docs-and-release.md | 4 + structure/providers-and-adapters.md | 2 +- structure/providers/google.md | 12 + structure/runtime.md | 4 + structure/transports/inventory.md | 2 +- .../google-tool-schema-contract.test.ts | 259 +++++++++++++++++- tests/cli/cli-provider.test.ts | 45 +++ tests/fixtures/test-layout-expected.json | 1 + ...nagement-google-tool-schema-policy.test.ts | 104 +++++++ 36 files changed, 663 insertions(+), 57 deletions(-) create mode 100644 tests/server/management-google-tool-schema-policy.test.ts diff --git a/docs-site/src/content/docs/fr/guides/providers.md b/docs-site/src/content/docs/fr/guides/providers.md index e5a52f40c34..3ee9500bbf8 100644 --- a/docs-site/src/content/docs/fr/guides/providers.md +++ b/docs-site/src/content/docs/fr/guides/providers.md @@ -135,13 +135,19 @@ Les vérifications de quota Google Antigravity utilisent des points de terminais Les déclarations d’outils Google sont compilées selon la classe du point de terminaison sélectionné. Lorsque le débogage du fournisseur est activé — avec `ocx debug provider on`, le bouton Logs du -tableau de bord ou `OCX_DEBUG=1` — la perte de schéma lors de la conversion de compatibilité émet un enregistrement +tableau de bord ou `OCX_DEBUG=1` — la perte de schéma lors de la conversion de compatibilité sur le +chemin où la politique est absente ou vaut `compatible` émet un enregistrement `[ocx:google:google-tool-schema-loss]` (à suivre avec `ocx debug provider logs -f`) ne contenant que -la version du rapport, la classe du point de terminaison, un indicateur `lossy`, des catégories de -perte fixes avec des compteurs bornés et un indicateur de troncature. Les noms d’outils et de -propriétés, les chemins, les valeurs et le texte du schéma ne sont jamais inclus. Ce diagnostic -observe la conversion compatible existante sans rejeter la requête. Les schémas de sortie natifs -n’entrent pas dans ce diagnostic. Consultez la +la version du rapport, la classe du point de terminaison, un indicateur `lossy`, un compteur borné de +comparaisons indéterminées, des catégories de perte fixes avec des compteurs bornés et un indicateur de troncature. Les noms d’outils et de +propriétés, les chemins, les valeurs et le texte du schéma ne sont jamais inclus. Avec une politique +absente ou `compatible`, ce diagnostic observe la conversion sans la refuser. Sous `reject-lossy`, +une compilation initialement avec perte ou dont la comparaison bornée est indéterminée est refusée +avant l’envoi ; aucun enregistrement de perte distinct n’est émis pour la requête refusée. Sous `reject-lossy`, une +réparation Vertex ou Cloud Code Assist qui supprimerait des contraintes émet un enregistrement +`google-tool-schema-repair` également sans contenu et renvoie le 400 d’origine sans nouvel envoi ; +avec une politique absente ou `compatible`, la requête réparée est rejouée comme auparavant. AI Studio direct ne tente jamais cette réparation. Les schémas +de sortie natifs restent hors de ces deux chemins. Consultez la [référence des commandes de débogage](/fr/reference/cli/agents/). diff --git a/docs-site/src/content/docs/fr/reference/configuration/providers.md b/docs-site/src/content/docs/fr/reference/configuration/providers.md index c4efe840231..a96d502b6c4 100644 --- a/docs-site/src/content/docs/fr/reference/configuration/providers.md +++ b/docs-site/src/content/docs/fr/reference/configuration/providers.md @@ -148,6 +148,7 @@ sauvegarde dont le contenu diffère, puis réécrit en identifiants sans préfix | `escapeBuiltinToolNames?` | `boolean` | Échapper aux noms d'outils intégrés pour les passerelles compatibles Anthropic et les restaurer lors des appels renvoyés. | | `anthropicEofTolerance?` | `boolean` | Laissez une passerelle compatible Anthropic compléter un flux qui se termine avant `message_stop`, uniquement lorsque du texte visible ou une entrée complète d'outil d'objet JSON a été reçue. Désactivé par défaut. | | `googleMode?` | `"ai-studio" \| "vertex" \| "cloud-code-assist"` | Mode Google transport/auth. Par défaut `ai-studio`. | +| `googleToolSchemaPolicy?` | `"compatible" \| "reject-lossy"` | Google uniquement. Une valeur absente ou `compatible` conserve le schéma compatible et la réparation 400 existante hors mode direct. `reject-lossy` refuse une perte initiale ou une comparaison bornée indéterminée avant l’envoi et bloque une réparation Vertex ou Cloud Code Assist qui ouvrirait des contraintes. AI Studio direct n’effectue jamais cette réparation. | | `project?` | `string` | ID du projet Vertex ou Antigravity Cloud Code Assist. | | `location?` | `string` | Région Vertex ; la valeur de repli de l'environnement est `GOOGLE_CLOUD_LOCATION`. | | `mcpServers?` | `Record` | Cursor uniquement : serveurs MCP sur entrée-sortie standard ou HTTP diffusé en continu. | diff --git a/docs-site/src/content/docs/guides/providers.md b/docs-site/src/content/docs/guides/providers.md index 1701da603f9..b3d584b80fa 100644 --- a/docs-site/src/content/docs/guides/providers.md +++ b/docs-site/src/content/docs/guides/providers.md @@ -213,11 +213,17 @@ Google Antigravity account and provider quota probes use fixed Google accounting Google tool declarations are compiled against the selected endpoint class. When provider debug is on — `ocx debug provider on`, the dashboard Logs toggle, or `OCX_DEBUG=1` — schema loss during compatibility -conversion emits a `[ocx:google:google-tool-schema-loss]` record (tail with `ocx debug provider logs -f`) -carrying only the report version, endpoint class, a `lossy` indicator, fixed loss categories with -bounded counts, and a truncation flag. Tool and property names, paths, values, and schema text are -never included. This diagnostic observes the existing compatible conversion and does not reject -the request. Native output schemas are outside this diagnostic. See the +conversion on the omitted or `compatible` policy path emits a `[ocx:google:google-tool-schema-loss]` +record (tail with `ocx debug provider logs -f`) +carrying only the report version, endpoint class, a `lossy` indicator, a bounded uncertainty count, +fixed loss categories with bounded counts, and a truncation flag. Tool and property names, paths, values, and schema text are +never included. With an omitted or `compatible` policy, this diagnostic observes the existing +conversion without rejecting it. Under `reject-lossy`, an initially lossy or comparison-indeterminate +compilation is refused before dispatch; no separate loss record is emitted for the refused request. Under +`reject-lossy`, a Vertex or Cloud Code Assist repair that would erase constraints emits a similarly +content-free `google-tool-schema-repair` record and returns the original 400 without a changed send; +with an omitted or `compatible` policy, the repaired request is replayed as before. Direct AI +Studio never performs this repair. Native output schemas are outside both policy paths. See the [debug command reference](/reference/cli/agents/). diff --git a/docs-site/src/content/docs/ja/guides/providers.md b/docs-site/src/content/docs/ja/guides/providers.md index 4d00948cf16..755066be1da 100644 --- a/docs-site/src/content/docs/ja/guides/providers.md +++ b/docs-site/src/content/docs/ja/guides/providers.md @@ -124,12 +124,17 @@ Google Antigravity のアカウント・プロバイダーのクォータ確認 Google のツール宣言は、選択されたエンドポイントクラスに合わせてコンパイルされます。 `ocx debug provider on`、ダッシュボードの Logs トグル、または `OCX_DEBUG=1` でプロバイダー -デバッグを有効にすると、互換性変換でのスキーマ損失は +デバッグを有効にすると、ポリシーの省略時または `compatible` の互換性変換でのスキーマ損失は `[ocx:google:google-tool-schema-loss]` レコードを出力します(`ocx debug provider logs -f` で 追跡できます)。レコードに含まれるのは、レポートのバージョン、エンドポイントクラス、 -`lossy` インジケーター、上限付き件数を伴う固定の損失カテゴリ、切り詰めフラグだけです。 -ツール名、プロパティ名、パス、値、スキーマ本文は含まれません。この診断は既存の互換変換を -観測するだけで、要求を拒否しません。ネイティブ出力スキーマは診断対象外です。 +`lossy` インジケーター、判定不能な比較の上限付き件数、上限付き件数を伴う固定の損失カテゴリ、切り詰めフラグだけです。 +ツール名、プロパティ名、パス、値、スキーマ本文は含まれません。ポリシーの省略時または +`compatible` では変換を拒否せず観測します。`reject-lossy` では、初期コンパイルに損失がある場合、 +または上限付き比較が判定不能な場合、送信前に拒否します。拒否されたリクエストに別の損失レコードは +出力されません。`reject-lossy` では、制約を消す Vertex または Cloud Code Assist の修復は同様に内容を含まない +`google-tool-schema-repair` を出力し、変更送信を行わず元の 400 を返します。ポリシーの省略時または +`compatible` では、修復済みリクエストを従来どおり再送します。直接 AI Studio は +この修復を行いません。ネイティブ出力スキーマは両方のポリシー経路の対象外です。 [デバッグコマンドのリファレンス](/ja/reference/cli/agents/)も参照してください。 diff --git a/docs-site/src/content/docs/ja/reference/configuration/providers.md b/docs-site/src/content/docs/ja/reference/configuration/providers.md index a80f27ff51d..a9fdaf8c813 100644 --- a/docs-site/src/content/docs/ja/reference/configuration/providers.md +++ b/docs-site/src/content/docs/ja/reference/configuration/providers.md @@ -140,6 +140,7 @@ account を削除しても mapping は保持され、同じ id を再追加す | `escapeBuiltinToolNames?` | `boolean` | Anthropic 互換ゲートウェイの組み込みツール名をエスケープし、返された呼び出しで復元します。 | | `anthropicEofTolerance?` | `boolean` | `message_stop` 前にストリームが終了しても、可視テキストまたは完全な JSON オブジェクトのツール入力が受信済みの場合に限り完了を許可します(Anthropic 互換ゲートウェイ向け)。デフォルトはオフ。 | | `googleMode?` | `"ai-studio" \| "vertex" \| "cloud-code-assist"` | Google トランスポート/認証モード。デフォルトは`ai-studio`です。 | +| `googleToolSchemaPolicy?` | `"compatible" \| "reject-lossy"` | Google 専用です。省略時または `compatible` は互換スキーマと既存の非直接 400 修復を維持します。`reject-lossy` は初期損失または判定不能な上限付き比較を送信前に拒否し、制約を開く Vertex/Cloud Code Assist 修復を保留します。直接 AI Studio はこの修復を行いません。 | | `project?` | `string` | Vertex または Antigravity Cloud Code Assist プロジェクト ID。 | | `location?` | `string` |頂点の位置。環境フォールバックは `GOOGLE_CLOUD_LOCATION` です。 | | `mcpServers?` | `Record` |カーソルのみ: 標準入出力またはストリーミング可能な HTTP MCP サーバー。 | diff --git a/docs-site/src/content/docs/ko/guides/providers.md b/docs-site/src/content/docs/ko/guides/providers.md index aaaecb8fcc9..710c28d9f8f 100644 --- a/docs-site/src/content/docs/ko/guides/providers.md +++ b/docs-site/src/content/docs/ko/guides/providers.md @@ -121,12 +121,17 @@ Google Antigravity 계정·제공자 할당량 확인은 모델 목록 폴백을 ### Google 도구 스키마 손실 진단 Google 도구 선언은 선택된 엔드포인트 클래스에 맞춰 컴파일됩니다. `ocx debug provider on`, -대시보드 Logs 토글 또는 `OCX_DEBUG=1`로 프로바이더 디버그를 켜면 호환성 변환 중 스키마 손실이 -발생하면 `[ocx:google:google-tool-schema-loss]` 레코드를 기록합니다 +대시보드 Logs 토글 또는 `OCX_DEBUG=1`로 프로바이더 디버그를 켜면 정책을 생략하거나 +`compatible`인 호환성 변환 중 스키마 손실이 발생할 때 `[ocx:google:google-tool-schema-loss]` 레코드를 기록합니다 (`ocx debug provider logs -f`로 tail할 수 있습니다). 이 레코드에는 보고서 버전, 엔드포인트 -클래스, `lossy` 표시, 상한이 있는 개수를 포함한 고정 손실 범주, 잘림 여부만 들어갑니다. -도구명과 속성명, 경로, 값, 스키마 본문은 포함하지 않습니다. 이 진단은 기존 호환 변환을 -관찰할 뿐 요청을 거부하지 않습니다. 네이티브 출력 스키마는 이 진단의 대상이 아닙니다. +클래스, `lossy` 표시, 판정 불가능한 비교의 상한 개수, 상한이 있는 개수를 포함한 고정 손실 범주, 잘림 여부만 들어갑니다. +도구명과 속성명, 경로, 값, 스키마 본문은 포함하지 않습니다. 정책을 생략하거나 +`compatible`이면 변환을 거부하지 않고 관찰합니다. `reject-lossy`에서는 초기 컴파일에 손실이 있거나 +상한 비교를 판정할 수 없으면 전송 전에 거부합니다. 거부된 요청에는 별도의 손실 레코드를 기록하지 +않습니다. `reject-lossy`에서는 제약을 지우는 Vertex 또는 Cloud Code Assist 복구가 동일하게 내용이 없는 +`google-tool-schema-repair`를 기록하고 변경 전송 없이 원래 400을 반환합니다. 정책을 생략하거나 +`compatible`이면 복구된 요청을 이전과 같이 다시 전송합니다. 직접 AI Studio는 +이 복구를 수행하지 않습니다. 네이티브 출력 스키마는 두 정책 경로 모두의 대상이 아닙니다. [디버그 명령어 참고 문서](/ko/reference/cli/agents/)도 확인하세요. diff --git a/docs-site/src/content/docs/ko/reference/configuration/providers.md b/docs-site/src/content/docs/ko/reference/configuration/providers.md index 505c56b5557..55e1f4457d4 100644 --- a/docs-site/src/content/docs/ko/reference/configuration/providers.md +++ b/docs-site/src/content/docs/ko/reference/configuration/providers.md @@ -140,6 +140,7 @@ managed map을 활성화하면 privacy-safe selector를 만들고, 이후 계정 | `escapeBuiltinToolNames?` | `boolean` | Anthropic 호환 게이트웨이를 위해 내장 도구 이름을 이스케이프하고, 반환된 호출에서는 다시 복원합니다. | | `anthropicEofTolerance?` | `boolean` | `message_stop` 전에 스트림이 끝나도 표시 텍스트 또는 완전한 JSON 객체 툴 입력을 받은 경우에만 완료를 허용합니다(Anthropic 호환 게이트웨이용). 기본값은 꺼짐. | | `googleMode?` | `"ai-studio" \| "vertex" \| "cloud-code-assist"` | Google 전송/인증 모드입니다. 기본값은 `ai-studio`입니다. | +| `googleToolSchemaPolicy?` | `"compatible" \| "reject-lossy"` | Google 전용입니다. 생략하거나 `compatible`이면 호환 스키마와 기존 비직접 400 복구를 유지합니다. `reject-lossy`는 초기 손실 또는 판정 불가능한 상한 비교를 전송 전에 거부하고 제약을 개방하는 Vertex 또는 Cloud Code Assist 복구를 보류합니다. 직접 AI Studio는 이 복구를 수행하지 않습니다. | | `project?` | `string` | Vertex 또는 Antigravity Cloud Code Assist 프로젝트 id입니다. | | `location?` | `string` | Vertex 위치입니다. 환경 변수 폴백은 `GOOGLE_CLOUD_LOCATION`입니다. | | `mcpServers?` | `Record` | Cursor 전용입니다. stdio 또는 Streamable HTTP MCP 서버입니다. | diff --git a/docs-site/src/content/docs/reference/configuration/providers.md b/docs-site/src/content/docs/reference/configuration/providers.md index a8b6f0c7333..ada6821e078 100644 --- a/docs-site/src/content/docs/reference/configuration/providers.md +++ b/docs-site/src/content/docs/reference/configuration/providers.md @@ -218,6 +218,7 @@ Providers can expose a built-in shorthand, such as `agy` for `google-antigravity | `escapeBuiltinToolNames?` | `boolean` | Escape built-in tool names for Anthropic-compatible gateways and restore them in returned calls. | | `anthropicEofTolerance?` | `boolean` | Let an Anthropic-compatible gateway complete a stream that ends before `message_stop`, only when visible text or a complete JSON-object tool input was received. Off by default. | | `googleMode?` | `"ai-studio" \| "vertex" \| "cloud-code-assist"` | Google transport/auth mode. Default `ai-studio`. | +| `googleToolSchemaPolicy?` | `"compatible" \| "reject-lossy"` | Google only. Omitted/`compatible` preserves the compatible tool schema and existing non-direct 400 repair. `reject-lossy` rejects initial schema loss or an indeterminate bounded comparison before dispatch and withholds a Vertex or Cloud Code Assist repair that would open constraints. Direct AI Studio never performs that repair. | | `directGeminiWireRenames?` | `boolean` | Google only. Applies only to direct AI Studio requests. Omitted or `true` keeps the `-tiered` wire rename for Gemini Flash ids (`gemini-3.7-flash` -> `gemini-3.7-flash-tiered`); `false` sends the requested bare ids to the wire unchanged. Vertex preserves the requested model ID, and Cloud Code Assist routing is unchanged. Set `false` when the configured upstream still serves the bare ids. | | `project?` | `string` | Vertex or Antigravity Cloud Code Assist project id. | | — | — | Antigravity account quota probes (`retrieveUserQuota` and `retrieveUserQuotaSummary`) always go to Google's own Cloud Code host through the pinned outbound transport, regardless of a configured `baseUrl`; the account bearer is never sent to an operator-configured endpoint and a redirect aborts the probe. Only the model-list fallback still honors `baseUrl`. | diff --git a/docs-site/src/content/docs/ru/guides/providers.md b/docs-site/src/content/docs/ru/guides/providers.md index edc995c1d8c..a850eb8dcb7 100644 --- a/docs-site/src/content/docs/ru/guides/providers.md +++ b/docs-site/src/content/docs/ru/guides/providers.md @@ -133,12 +133,19 @@ ocx logout Объявления инструментов Google компилируются для выбранного класса конечной точки. Когда отладка провайдера включена командой `ocx debug provider on`, переключателем Logs в дашборде или переменной -`OCX_DEBUG=1`, потеря схемы при преобразовании совместимости записывает событие +`OCX_DEBUG=1`, потеря схемы при преобразовании совместимости на пути с отсутствующей политикой или +`compatible` записывает событие `[ocx:google:google-tool-schema-loss]` (следите за ним через `ocx debug provider logs -f`). Оно -содержит только версию отчёта, класс конечной точки, индикатор `lossy`, фиксированные категории -потерь с ограниченными счётчиками и признак усечения. Имена инструментов и свойств, пути, значения -и текст схемы не включаются. Диагностика только наблюдает существующее совместимое преобразование -и не отклоняет запрос. Нативные схемы вывода в неё не входят. См. +содержит только версию отчёта, класс конечной точки, индикатор `lossy`, ограниченный счётчик +неопределённых сравнений, фиксированные категории потерь с ограниченными счётчиками и признак усечения. Имена инструментов и свойств, пути, значения +и текст схемы не включаются. При отсутствии политики или `compatible` преобразование только +наблюдается. При `reject-lossy` начальная компиляция с потерей или неопределённым результатом +ограниченного сравнения отклоняется до отправки; отдельное событие потери для отклонённого запроса +не записывается. При `reject-lossy` +восстановление Vertex или Cloud Code Assist, снимающее ограничения, пишет столь же безопасное событие +`google-tool-schema-repair` и возвращает исходный 400 без изменённой отправки; при отсутствии политики +или при `compatible` исправленный запрос повторяется как прежде. Прямой AI Studio +такое восстановление не выполняет. Нативные схемы вывода исключены из обоих путей. См. [справочник команд отладки](/ru/reference/cli/agents/). diff --git a/docs-site/src/content/docs/ru/reference/configuration/providers.md b/docs-site/src/content/docs/ru/reference/configuration/providers.md index 05a21c86ac7..21227ef1abd 100644 --- a/docs-site/src/content/docs/ru/reference/configuration/providers.md +++ b/docs-site/src/content/docs/ru/reference/configuration/providers.md @@ -153,6 +153,7 @@ cross-route credential fallback не существует. Строки API GPT- | `escapeBuiltinToolNames?` | `boolean` | Экранировать built-in tool name'ы для Anthropic-compatible gateway'ев и восстанавливать их в возвращаемых call'ах. | | `anthropicEofTolerance?` | `boolean` | Позволяет Anthropic-совместимому шлюзу завершить поток до `message_stop`, только если получен видимый текст или полный JSON-объект аргументов инструмента. По умолчанию выключено. | | `googleMode?` | `"ai-studio" \| "vertex" \| "cloud-code-assist"` | Режим транспорта/аутентификации Google. По умолчанию `ai-studio`. | +| `googleToolSchemaPolicy?` | `"compatible" \| "reject-lossy"` | Только Google. Отсутствие поля или `compatible` сохраняет совместимую схему и существующее недиректное восстановление после 400. `reject-lossy` отклоняет начальную потерю или неопределённый результат ограниченного сравнения до отправки и блокирует восстановление Vertex или Cloud Code Assist, которое сняло бы ограничения. Прямой AI Studio такое восстановление не выполняет. | | `project?` | `string` | Идентификатор проекта Vertex или Antigravity Cloud Code Assist. | | `location?` | `string` | Локация Vertex; fallback через окружение — `GOOGLE_CLOUD_LOCATION`. | | `mcpServers?` | `Record` | Только Cursor: MCP-серверы в режимах stdio или Streamable HTTP. | diff --git a/docs-site/src/content/docs/tr/guides/providers.md b/docs-site/src/content/docs/tr/guides/providers.md index 81380857c91..4686180f086 100644 --- a/docs-site/src/content/docs/tr/guides/providers.md +++ b/docs-site/src/content/docs/tr/guides/providers.md @@ -148,11 +148,18 @@ Google Antigravity hesap ve sağlayıcı kota sorguları, model listesine geri d Google araç bildirimleri seçilen uç nokta sınıfına göre derlenir. Sağlayıcı hata ayıklaması `ocx debug provider on`, kontrol panelindeki Logs anahtarı veya `OCX_DEBUG=1` ile açıldığında, -uyumluluk dönüşümü sırasında şema kaybı bir `[ocx:google:google-tool-schema-loss]` kaydı yayınlar +politika yokken veya `compatible` iken uyumluluk dönüşümü sırasında oluşan şema kaybı bir +`[ocx:google:google-tool-schema-loss]` kaydı yayınlar (`ocx debug provider logs -f` ile takip edin). Kayıt yalnızca rapor sürümünü, uç nokta sınıfını, -bir `lossy` göstergesini, sınırlı sayımlara sahip sabit kayıp kategorilerini ve kesilme işaretini -taşır. Araç ve özellik adları, yollar, değerler ve şema metni hiçbir zaman dahil edilmez. Bu -tanılama mevcut uyumlu dönüşümü gözlemler ve isteği reddetmez. Yerel çıktı şemaları bu tanılamanın +bir `lossy` göstergesini, sınırlı bir belirsiz karşılaştırma sayısını, sınırlı sayımlara sahip sabit kayıp kategorilerini ve kesilme işaretini +taşır. Araç ve özellik adları, yollar, değerler ve şema metni hiçbir zaman dahil edilmez. Politika +yoksa veya `compatible` ise dönüşüm reddedilmeden gözlemlenir. `reject-lossy` altında, ilk derleme +kayıplıysa veya sınırlı karşılaştırmanın sonucu belirsizse gönderimden önce reddedilir; reddedilen +istek için ayrı bir kayıp kaydı yayınlanmaz. +`reject-lossy` altında, kısıtları kaldıracak bir Vertex veya Cloud Code Assist onarımı +aynı şekilde içeriksiz bir `google-tool-schema-repair` kaydı üretir ve değiştirilmiş gönderim yapmadan +özgün 400 yanıtını döndürür; politika yoksa veya `compatible` ise onarılan istek daha önce olduğu gibi +yeniden gönderilir. Doğrudan AI Studio bu onarımı yapmaz. Yerel çıktı şemaları iki politika yolunun da dışındadır. [Hata ayıklama komutu başvurusuna](/tr/reference/cli/agents/) bakın. diff --git a/docs-site/src/content/docs/tr/reference/configuration/providers.md b/docs-site/src/content/docs/tr/reference/configuration/providers.md index 110c69be3c6..57f5d867189 100644 --- a/docs-site/src/content/docs/tr/reference/configuration/providers.md +++ b/docs-site/src/content/docs/tr/reference/configuration/providers.md @@ -154,6 +154,7 @@ alanlı seçilmiş kimlikleri yalın kimliklere yeniden yazar. | `escapeBuiltinToolNames?` | `boolean` | Anthropic uyumlu ağ geçitleri için yerleşik araç adlarından kaçış yapın ve döndürülen çağrılarda bunları geri yükleyin. | | `anthropicEofTolerance?` | `boolean` | Yalnızca görünür metin veya eksiksiz bir JSON nesnesi araç girdisi alındığında, Anthropic uyumlu bir ağ geçidinin `message_stop` öncesinde biten bir akışı tamamlamasına izin verin. Varsayılan olarak kapalıdır. | | `googleMode?` | `"ai-studio" \| "vertex" \| "cloud-code-assist"` | Google aktarım/kimlik doğrulama modu. Varsayılan `ai-studio`. | +| `googleToolSchemaPolicy?` | `"compatible" \| "reject-lossy"` | Yalnızca Google. Alanın atlanması veya `compatible`, uyumlu şemayı ve mevcut doğrudan olmayan 400 onarımını korur. `reject-lossy`, ilk kaybı veya sonucu belirsiz sınırlı bir karşılaştırmayı gönderimden önce reddeder ve kısıtları açacak Vertex ya da Cloud Code Assist onarımını engeller. Doğrudan AI Studio bu onarımı yapmaz. | | `project?` | `string` | Vertex veya Antigravity Cloud Code Assist proje kimliği. | | `location?` | `string` | Vertex konumu; ortam geri dönüşü `GOOGLE_CLOUD_LOCATION`'dır. | | `mcpServers?` | `Record` | Yalnızca Cursor: stdio veya Akışlanabilir HTTP MCP sunucuları. | diff --git a/docs-site/src/content/docs/zh-cn/guides/providers.md b/docs-site/src/content/docs/zh-cn/guides/providers.md index 9f652287309..ea7bce13ce0 100644 --- a/docs-site/src/content/docs/zh-cn/guides/providers.md +++ b/docs-site/src/content/docs/zh-cn/guides/providers.md @@ -115,11 +115,16 @@ Google Antigravity 账户和提供方的配额查询(包括模型列表回退 ### Google 工具架构损失诊断 Google 工具声明会按所选端点类别进行编译。通过 `ocx debug provider on`、仪表盘 Logs 开关或 -`OCX_DEBUG=1` 启用提供方调试后,兼容性转换中的架构损失会输出一条 +`OCX_DEBUG=1` 启用提供方调试后,在省略策略或使用 `compatible` 的路径上,兼容性转换中的架构损失会输出一条 `[ocx:google:google-tool-schema-loss]` 记录(可用 `ocx debug provider logs -f` 持续查看), -其中仅包含报告版本、端点类别、`lossy` 指示器、带有上限计数的固定损失类别和截断标志, -绝不包含工具名、属性名、路径、值或架构文本。此诊断只观察现有的兼容转换,不会拒绝请求。 -原生输出架构不属于此诊断范围。请参阅[调试命令参考](/zh-cn/reference/cli/agents/)。 +其中仅包含报告版本、端点类别、`lossy` 指示器、有上限的不确定比较计数、带有上限计数的固定损失类别和截断标志, +绝不包含工具名、属性名、路径、值或架构文本。省略策略或使用 `compatible` 时只观察转换。 +在 `reject-lossy` 下,如果初始编译有损或有界比较结果不确定,则会在发送前拒绝;被拒绝的 +请求不会另行输出损失记录。在 `reject-lossy` 下,会移除约束的 +Vertex 或 Cloud Code Assist 修复会输出同样不含内容的 `google-tool-schema-repair` 记录,并在不发送 +修改请求的情况下返回原始 400;省略策略或使用 `compatible` 时,会像以前一样重放修复后的请求。 +直连 AI Studio 不执行该修复。原生输出架构不属于这两条策略路径。 +请参阅[调试命令参考](/zh-cn/reference/cli/agents/)。 Nous refresh 发生终止性失败后,请运行 `ocx login nous` 重新认证。 diff --git a/docs-site/src/content/docs/zh-cn/reference/configuration/providers.md b/docs-site/src/content/docs/zh-cn/reference/configuration/providers.md index 653f0a54d78..e0e61490a1d 100644 --- a/docs-site/src/content/docs/zh-cn/reference/configuration/providers.md +++ b/docs-site/src/content/docs/zh-cn/reference/configuration/providers.md @@ -140,6 +140,7 @@ selector,而不是分配一个新名称。 | `escapeBuiltinToolNames?` | `boolean` | 为 Anthropic 兼容网关转义内置工具名,并在返回的调用中恢复。 | | `anthropicEofTolerance?` | `boolean` | 允许 Anthropic 兼容网关在 `message_stop` 前结束流,仅当已收到可见文本或完整的 JSON 对象工具输入时。默认关闭。 | | `googleMode?` | `"ai-studio" \| "vertex" \| "cloud-code-assist"` | Google 传输/身份验证模式。默认 `ai-studio`。 | +| `googleToolSchemaPolicy?` | `"compatible" \| "reject-lossy"` | 仅限 Google。省略或设为 `compatible` 时保留兼容架构和现有的非直连 400 修复。`reject-lossy` 会在发送前拒绝初始损失或结果不确定的有界比较,并阻止会放宽约束的 Vertex 或 Cloud Code Assist 修复。直连 AI Studio 从不执行该修复。 | | `project?` | `string` | Vertex 或 Antigravity Cloud Code Assist 项目 id。 | | `location?` | `string` | Vertex 位置;环境变量回退为 `GOOGLE_CLOUD_LOCATION`。 | | `mcpServers?` | `Record` | 仅 Cursor:stdio 或 Streamable HTTP MCP 服务器。 | diff --git a/docs-site/src/content/docs/zh-tw/guides/providers.md b/docs-site/src/content/docs/zh-tw/guides/providers.md index 16f6b356510..f3374f1a4e3 100644 --- a/docs-site/src/content/docs/zh-tw/guides/providers.md +++ b/docs-site/src/content/docs/zh-tw/guides/providers.md @@ -120,11 +120,15 @@ Google Antigravity 帳戶與供應商的配額查詢(包括模型清單備援 ### Google 工具結構描述損失診斷 Google 工具宣告會依所選端點類別進行編譯。透過 `ocx debug provider on`、儀表板 Logs 開關或 -`OCX_DEBUG=1` 啟用供應商偵錯後,相容性轉換中的結構描述損失會輸出一筆 +`OCX_DEBUG=1` 啟用供應商偵錯後,在省略政策或使用 `compatible` 的路徑上,相容性轉換中的結構描述損失會輸出一筆 `[ocx:google:google-tool-schema-loss]` 記錄(可用 `ocx debug provider logs -f` 持續查看), -其中只包含報告版本、端點類別、`lossy` 指標、帶有上限計數的固定損失類別與截斷旗標, -絕不包含工具名稱、屬性名稱、路徑、值或結構描述文字。此診斷只觀察既有的相容轉換, -不會拒絕請求。原生輸出結構描述不屬於此診斷範圍。請參閱 +其中只包含報告版本、端點類別、`lossy` 指標、有上限的不確定比較計數、帶有上限計數的固定損失類別與截斷旗標, +絕不包含工具名稱、屬性名稱、路徑、值或結構描述文字。省略政策或使用 `compatible` 時只觀察 +轉換。在 `reject-lossy` 下,若初始編譯有損或有界比較結果不確定,會在傳送前拒絕;被拒絕的 +請求不會另外輸出損失記錄。在 `reject-lossy` 下,會移除限制的 +Vertex 或 Cloud Code Assist 修復會輸出同樣不含內容的 `google-tool-schema-repair` 記錄,並在不傳送 +修改請求的情況下回傳原始 400;省略政策或使用 `compatible` 時,會像以前一樣重播修復後的請求。 +直接 AI Studio 不執行此修復。原生輸出結構描述不屬於這兩條政策路徑。請參閱 [偵錯命令參考](/zh-tw/reference/cli/agents/)。 diff --git a/docs-site/src/content/docs/zh-tw/reference/configuration/providers.md b/docs-site/src/content/docs/zh-tw/reference/configuration/providers.md index 80b8e415291..395ec06ec77 100644 --- a/docs-site/src/content/docs/zh-tw/reference/configuration/providers.md +++ b/docs-site/src/content/docs/zh-tw/reference/configuration/providers.md @@ -110,6 +110,7 @@ ocx models provider openrouter on | `noVisionModels?` | `string[]` | 透過視覺 sidecar 發送的純文字模型;比對容忍 Ollama `:size` 標籤。 | | `escapeBuiltinToolNames?` | `boolean` | 為 Anthropic 相容閘道轉義內建工具名稱,並在回傳的呼叫中還原它們。 | | `googleMode?` | `"ai-studio" \| "vertex" \| "cloud-code-assist"` | Google 傳輸/認證模式。預設 `ai-studio`。 | +| `googleToolSchemaPolicy?` | `"compatible" \| "reject-lossy"` | 僅限 Google。省略或設為 `compatible` 時保留相容結構描述與既有的非直接 400 修復。`reject-lossy` 會在傳送前拒絕初始損失或結果不確定的有界比較,並阻止會放寬限制的 Vertex 或 Cloud Code Assist 修復。直接 AI Studio 不會執行該修復。 | | `project?` | `string` | Vertex 或 Antigravity Cloud Code Assist 專案 id。 | | `location?` | `string` | Vertex 位置;環境後備為 `GOOGLE_CLOUD_LOCATION`。 | | `mcpServers?` | `Record` | 僅 Cursor:stdio 或 Streamable HTTP MCP 伺服器。 | diff --git a/scripts/test-layout/layout.json b/scripts/test-layout/layout.json index 32615632839..e69c654a9c8 100644 --- a/scripts/test-layout/layout.json +++ b/scripts/test-layout/layout.json @@ -1549,6 +1549,7 @@ "responses-code-mode-patch-compile.test.ts": "responses", "gui-codex-usage-score-parity.test.ts": "gui", "web-search-sidecar-429.test.ts": "web-search", + "management-google-tool-schema-policy.test.ts": "server", "codex-shim-destroyed-probe.test.ts": "codex-integration" }, "migrated": [ diff --git a/src/adapters/google-http.ts b/src/adapters/google-http.ts index de21ea93fb5..bbebb36cb61 100644 --- a/src/adapters/google-http.ts +++ b/src/adapters/google-http.ts @@ -2,8 +2,10 @@ import type { AdapterFetchContext, AdapterRequest } from "./base"; import { createAdapterPhysicalSend } from "./physical-send"; import type { SendClass } from "../lib/request-execution-budget"; import type { AttemptRecoveryKind } from "../usage/log"; +import { debugProviderDiagnosticLazy } from "../lib/debug"; import { isQuotaExhaustedBody, retryableGoogleStatus, safeGoogleHttpErrorMessage } from "./google-errors"; -import { repairGoogleInvalidRequestBody } from "./google-wire-compiler"; +import { repairGoogleInvalidRequestBodyWithReport } from "./google-wire-compiler"; +import type { GoogleToolSchemaPolicy, GoogleToolSchemaProfile } from "./google-tool-schema"; import { normalizeUpstreamHttpErrorResponse, readDisplaySafeErrorPayloadText } from "./upstream-http-error"; import { abortError, @@ -22,6 +24,8 @@ const GOOGLE_RETRY_MAX_MS = 2_000; export interface GoogleRetryOptions { /** Repair-and-replay structurally invalid 400 bodies (Vertex/Antigravity behavior). */ repairInvalid400?: boolean; + toolSchemaProfile?: GoogleToolSchemaProfile; + toolSchemaPolicy?: GoogleToolSchemaPolicy; } async function normalizeFinalGoogleError(label: string, res: Response, signal?: AbortSignal): Promise { @@ -45,6 +49,8 @@ export async function fetchGoogleWithRetry( opts: GoogleRetryOptions = {}, ): Promise { const repairInvalid400 = opts.repairInvalid400 ?? true; + const toolSchemaProfile = opts.toolSchemaProfile ?? { endpointClass: "vertex" }; + const toolSchemaPolicy = opts.toolSchemaPolicy ?? "compatible"; const timeoutMs = ctx.timeoutMs ?? 200_000; const send = createAdapterPhysicalSend(ctx); let lastError: unknown; @@ -77,10 +83,22 @@ export async function fetchGoogleWithRetry( } catch (error) { if (ctx.abortSignal?.aborted) throw error; } - const repairedBody = repairGoogleInvalidRequestBody(activeRequest.body, payloadText); - if (repairedBody !== undefined) { + const repair = repairGoogleInvalidRequestBodyWithReport(activeRequest.body, payloadText, toolSchemaProfile); + if (repair !== undefined) { + if (repair.toolSchemaLoss) { + const changedSendAllowed = toolSchemaPolicy !== "reject-lossy"; + debugProviderDiagnosticLazy("google", "google-tool-schema-repair", () => ({ + ...repair.toolSchemaLoss, + phase: "repair", + declarationCount: repair.toolSchemaDeclarationCount ?? 0, + changedSendAllowed, + })); + if (!changedSendAllowed) { + return ctx.returnRawErrors ? res : normalizeFinalGoogleError(label, res, ctx.abortSignal); + } + } compatibilityReplayUsed = true; - activeRequest = { ...activeRequest, body: repairedBody }; + activeRequest = { ...activeRequest, body: repair.body }; pendingResponse = res; sendClass = "repair"; attempt--; // The changed-request replay is separate from transient retry accounting. @@ -145,16 +163,37 @@ export async function fetchGoogleWithRetry( * demand" spikes, plus plain rate-limit 429s, both of which previously failed immediately * because the default server fetch path only retries connection resets. */ -export function fetchDirectGeminiWithRetry(request: AdapterRequest, ctx: AdapterFetchContext = {}): Promise { - return fetchGoogleWithRetry("Gemini", request, { ...ctx, returnRawErrors: true }, { repairInvalid400: false }); +export function fetchDirectGeminiWithRetry( + request: AdapterRequest, + ctx: AdapterFetchContext = {}, + schemaPolicy: Pick = {}, +): Promise { + return fetchGoogleWithRetry("Gemini", request, { ...ctx, returnRawErrors: true }, { + ...schemaPolicy, + repairInvalid400: false, + }); } /** Vertex AI retry wrapper. */ -export function fetchVertexWithRetry(request: AdapterRequest, ctx: AdapterFetchContext = {}): Promise { - return fetchGoogleWithRetry("Vertex AI", request, ctx); +export function fetchVertexWithRetry( + request: AdapterRequest, + ctx: AdapterFetchContext = {}, + schemaPolicy: Pick = {}, +): Promise { + return fetchGoogleWithRetry("Vertex AI", request, ctx, { + toolSchemaProfile: { endpointClass: "vertex" }, + ...schemaPolicy, + }); } /** Antigravity (Cloud Code Assist) retry wrapper. */ -export function fetchAntigravityWithRetry(request: AdapterRequest, ctx: AdapterFetchContext = {}): Promise { - return fetchGoogleWithRetry("Antigravity", request, ctx); +export function fetchAntigravityWithRetry( + request: AdapterRequest, + ctx: AdapterFetchContext = {}, + schemaPolicy: Pick = {}, +): Promise { + return fetchGoogleWithRetry("Antigravity", request, ctx, { + toolSchemaProfile: { endpointClass: "cloud-code-assist" }, + ...schemaPolicy, + }); } diff --git a/src/adapters/google-tool-schema.ts b/src/adapters/google-tool-schema.ts index 944314a2732..a28290fe602 100644 --- a/src/adapters/google-tool-schema.ts +++ b/src/adapters/google-tool-schema.ts @@ -56,6 +56,7 @@ const MERGED_SCHEMA_KEYS = [ type SanitizeResult = Schema | typeof BUDGET_EXHAUSTED; export type GoogleToolSchemaEndpointClass = "ai-studio" | "vertex" | "cloud-code-assist"; +export type GoogleToolSchemaPolicy = "compatible" | "reject-lossy"; export interface GoogleToolSchemaProfile { endpointClass: GoogleToolSchemaEndpointClass; @@ -80,6 +81,7 @@ export type GoogleToolSchemaLossCategory = | "dereference-limit-widened" | "depth-limit-widened" | "node-budget-widened" + | "repair-opened-schema" | "unsupported-constraint-dropped" | "invalid-schema-widened"; diff --git a/src/adapters/google-wire-compiler.ts b/src/adapters/google-wire-compiler.ts index 38540597119..00c00334ca4 100644 --- a/src/adapters/google-wire-compiler.ts +++ b/src/adapters/google-wire-compiler.ts @@ -1,9 +1,12 @@ import { createHash } from "node:crypto"; import { + addGoogleToolSchemaLoss, createGoogleToolSchemaLossReport, + GOOGLE_TOOL_SCHEMA_LOSS_COUNT_LIMIT, mergeGoogleToolSchemaLossReport, sanitizeGeminiToolParametersWithReport, type GoogleToolSchemaLossReport, + type GoogleToolSchemaPolicy, type GoogleToolSchemaProfile, } from "./google-tool-schema"; @@ -12,6 +15,24 @@ type JsonObject = Record; const GOOGLE_TOOL_NAME = /^[A-Za-z_][A-Za-z0-9_-]{0,63}$/; const GOOGLE_THINKING_LEVELS = new Set(["minimal", "low", "medium", "high"]); +export class GoogleToolSchemaPolicyError extends Error { + readonly phase = "initial" as const; + readonly endpointClass: GoogleToolSchemaProfile["endpointClass"]; + readonly categories: GoogleToolSchemaLossReport["categories"]; + /** True when refusal is due to exhausted bounded comparison rather than proven loss. */ + readonly indeterminate: boolean; + + constructor(report: GoogleToolSchemaLossReport) { + const categories = { ...report.categories }; + const indeterminate = report.uncertainComparisons > 0; + super(`google tool schema policy rejected ${report.lossy ? "lossy" : "indeterminate"} initial compilation (${report.endpointClass}; categories=${JSON.stringify(categories)}${indeterminate ? `; uncertainComparisons=${report.uncertainComparisons}` : ""})`); + this.name = "GoogleToolSchemaPolicyError"; + this.endpointClass = report.endpointClass; + this.categories = categories; + this.indeterminate = indeterminate; + } +} + function isObject(value: unknown): value is JsonObject { return !!value && typeof value === "object" && !Array.isArray(value); } @@ -196,6 +217,7 @@ function compileToolConfig(value: unknown, toWireName: (name: string) => string) export function compileGoogleWireBody( input: unknown, profile: GoogleToolSchemaProfile = { endpointClass: "ai-studio" }, + policy: GoogleToolSchemaPolicy = "compatible", ): { body: JsonObject; restoreToolName: (name: string) => string; @@ -210,6 +232,11 @@ export function compileGoogleWireBody( if (isObject(source.systemInstruction)) body.systemInstruction = source.systemInstruction; const tools = compileTools(source.tools, names.toWire, profile, toolSchemaLossReport); if (tools) body.tools = tools; + // Strict mode refuses proven loss and bounded-comparison indeterminacy alike: an exhausted + // comparison can hide a changed constraint, so unknown is not admitted as lossless. + if (policy === "reject-lossy" && (toolSchemaLossReport.lossy || toolSchemaLossReport.uncertainComparisons > 0)) { + throw new GoogleToolSchemaPolicyError(toolSchemaLossReport); + } const generationConfig = compileGenerationConfig(source.generationConfig); if (generationConfig) body.generationConfig = generationConfig; const toolConfig = compileToolConfig(source.toolConfig, names.toWire); @@ -241,8 +268,18 @@ export function isGoogleThinkingConfigErrorText(errorPayload: string): boolean { return /thinking[_ ]?(?:config|level)/i.test(errorPayload); } +export interface GoogleInvalidRequestRepair { + body: string; + toolSchemaLoss?: GoogleToolSchemaLossReport; + toolSchemaDeclarationCount?: number; +} + /** Build a changed request for one known-safe replay of an INVALID_ARGUMENT response. */ -export function repairGoogleInvalidRequestBody(body: string, errorPayload: string): string | undefined { +export function repairGoogleInvalidRequestBodyWithReport( + body: string, + errorPayload: string, + profile: GoogleToolSchemaProfile = { endpointClass: "ai-studio" }, +): GoogleInvalidRequestRepair | undefined { const schemaError = isGoogleToolSchemaErrorText(errorPayload); const thinkingError = isGoogleThinkingConfigErrorText(errorPayload); if (!schemaError && !thinkingError) return undefined; @@ -255,6 +292,8 @@ export function repairGoogleInvalidRequestBody(body: string, errorPayload: strin if (!isObject(parsed)) return undefined; const root = isObject(parsed.request) ? parsed.request : parsed; let changed = false; + let toolSchemaLoss: GoogleToolSchemaLossReport | undefined; + let toolSchemaDeclarationCount: number | undefined; if (thinkingError && isObject(root.generationConfig) && "thinkingConfig" in root.generationConfig) { delete root.generationConfig.thinkingConfig; @@ -270,6 +309,9 @@ export function repairGoogleInvalidRequestBody(body: string, errorPayload: strin const index = indexed === undefined ? -1 : Number.parseInt(indexed, 10); const rejected = declarations[index]; const targets = rejected ? [rejected] : declarations; + toolSchemaLoss = createGoogleToolSchemaLossReport(profile); + addGoogleToolSchemaLoss(toolSchemaLoss, "repair-opened-schema", targets.length); + toolSchemaDeclarationCount = Math.min(targets.length, GOOGLE_TOOL_SCHEMA_LOSS_COUNT_LIMIT); for (const declaration of targets) { declaration.parameters = { type: "object", properties: {} }; delete declaration.parametersJsonSchema; @@ -277,5 +319,13 @@ export function repairGoogleInvalidRequestBody(body: string, errorPayload: strin changed = true; } } - return changed ? JSON.stringify(parsed) : undefined; + return changed ? { + body: JSON.stringify(parsed), + ...(toolSchemaLoss ? { toolSchemaLoss, toolSchemaDeclarationCount } : {}), + } : undefined; +} + +/** Compatibility facade for callers that need only the changed body. */ +export function repairGoogleInvalidRequestBody(body: string, errorPayload: string): string | undefined { + return repairGoogleInvalidRequestBodyWithReport(body, errorPayload)?.body; } diff --git a/src/adapters/google.ts b/src/adapters/google.ts index 6d3e39eed75..1e8631ae645 100644 --- a/src/adapters/google.ts +++ b/src/adapters/google.ts @@ -739,6 +739,7 @@ function invalidGoogleShapeEvent( } export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapter { + const toolSchemaPolicy = provider.googleToolSchemaPolicy ?? "compatible"; const toolSchemaProfile = { endpointClass: provider.googleMode ?? "ai-studio", } satisfies GoogleToolSchemaProfile; @@ -808,7 +809,11 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte ...(provider.googleMode === "vertex" || provider.googleMode === "cloud-code-assist" ? { fetchResponse: (request: AdapterRequest, ctx?: AdapterFetchContext): Promise => - (provider.googleMode === "cloud-code-assist" ? fetchAntigravityWithRetry : fetchVertexWithRetry)(request, ctx), + (provider.googleMode === "cloud-code-assist" ? fetchAntigravityWithRetry : fetchVertexWithRetry)( + request, + ctx, + { toolSchemaProfile, toolSchemaPolicy }, + ), formatErrorBody: (status: number, _headers: Headers, payloadText: string): string => (provider.googleMode === "cloud-code-assist" ? safeAntigravityHttpErrorMessage : safeVertexHttpErrorMessage)(status, payloadText), } @@ -979,7 +984,7 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte const fcc = (existing.functionCallingConfig ?? {}) as Record; draftRequest.toolConfig = { ...existing, functionCallingConfig: { ...fcc, mode: "VALIDATED" } }; } - const compiled = compileGoogleWireBody(draftRequest, toolSchemaProfile); + const compiled = compileGoogleWireBody(draftRequest, toolSchemaProfile, toolSchemaPolicy); reportToolSchemaLoss(compiled.toolSchemaLossReport); const request = compiled.body; restoreGoogleToolName = compiled.restoreToolName; @@ -1030,7 +1035,7 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte } if (provider.googleMode === "vertex") { - const compiled = compileGoogleWireBody(body, toolSchemaProfile); + const compiled = compileGoogleWireBody(body, toolSchemaProfile, toolSchemaPolicy); reportToolSchemaLoss(compiled.toolSchemaLossReport); restoreGoogleToolName = compiled.restoreToolName; const vertexProject = provider.project || process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT || "api-key"; @@ -1077,7 +1082,7 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte if (!apiKey) throw new Error("google (AI Studio) requires a non-empty API key"); headers["x-goog-api-key"] = apiKey; - const compiled = compileGoogleWireBody(body, toolSchemaProfile); + const compiled = compileGoogleWireBody(body, toolSchemaProfile, toolSchemaPolicy); reportToolSchemaLoss(compiled.toolSchemaLossReport); restoreGoogleToolName = compiled.restoreToolName; return { url, method: "POST", headers, body: JSON.stringify(compiled.body) }; diff --git a/src/cli/provider.ts b/src/cli/provider.ts index 958989a94fc..83ea1027a75 100644 --- a/src/cli/provider.ts +++ b/src/cli/provider.ts @@ -139,7 +139,7 @@ function handleList(args: string[]): void { // provider add // --------------------------------------------------------------------------- -const ADD_USAGE = "Usage: ocx provider add [--adapter ] [--base-url ] [--api-key ] [--api-key-transport ] [--default-model ] [--model --text-only] [--allow-private-network] [--set-default] [--force] [--json] [--sync]"; +const ADD_USAGE = "Usage: ocx provider add [--adapter ] [--base-url ] [--api-key ] [--api-key-transport ] [--default-model ] [--model --text-only] [--google-tool-schema-policy ] [--allow-private-network] [--set-default] [--force] [--json] [--sync]"; async function handleAdd(args: string[]): Promise { const name = args[0]; @@ -164,6 +164,7 @@ async function handleAdd(args: string[]): Promise { const adapter = consumeFlagValue(restArgs, "--adapter"); const baseUrl = consumeFlagValue(restArgs, "--base-url"); const defaultModel = consumeFlagValue(restArgs, "--default-model"); + const googleToolSchemaPolicy = consumeFlagValue(restArgs, "--google-tool-schema-policy"); const textOnly = consumeFlag(restArgs, "--text-only"); const capabilityModel = consumeFlagValue(restArgs, "--model"); rejectUnknownArgs(restArgs, ADD_USAGE); @@ -228,6 +229,17 @@ async function handleAdd(args: string[]): Promise { } provConfig.apiKeyTransport = apiKeyTransport; } + if (googleToolSchemaPolicy !== undefined) { + if (googleToolSchemaPolicy !== "compatible" && googleToolSchemaPolicy !== "reject-lossy") { + console.error('Error: --google-tool-schema-policy must be "compatible" or "reject-lossy".'); + process.exit(1); + } + if (provConfig.adapter !== "google") { + console.error("Error: --google-tool-schema-policy requires the google adapter."); + process.exit(1); + } + provConfig.googleToolSchemaPolicy = googleToolSchemaPolicy; + } const existingProvider = config.providers[name]; if (existingProvider?.modelCapabilities !== undefined && provConfig.modelCapabilities === undefined) { diff --git a/src/config/schema/leaf-validators.ts b/src/config/schema/leaf-validators.ts index 6dc1b35aa0d..3f5988f5424 100644 --- a/src/config/schema/leaf-validators.ts +++ b/src/config/schema/leaf-validators.ts @@ -268,6 +268,7 @@ export const providerConfigSchema = z.object({ // canonical ChatGPT backend WS selection is independent of this flag. upstreamWebsocket: z.boolean().optional(), directGeminiWireRenames: z.boolean().optional(), + googleToolSchemaPolicy: z.enum(["compatible", "reject-lossy"]).optional(), noStructuredOutputModels: z.array(z.string().min(1)) .transform(normalizeNonBlankStringArray) .optional(), diff --git a/src/server/auth-cors.ts b/src/server/auth-cors.ts index 554f9e298b4..d415e030b12 100644 --- a/src/server/auth-cors.ts +++ b/src/server/auth-cors.ts @@ -948,6 +948,7 @@ const PROVIDER_CONFIG_FIELD_POLICY = { upstreamHttpVersion: "editor", upstreamWebsocket: "editor", directGeminiWireRenames: "editor", + googleToolSchemaPolicy: "editor", disabled: "editor", codexAccountMode: "editor", apiKey: "redacted", diff --git a/src/types/provider.ts b/src/types/provider.ts index 808ad536731..459c7359f25 100644 --- a/src/types/provider.ts +++ b/src/types/provider.ts @@ -901,6 +901,8 @@ export interface OcxProviderConfig { * "cloud-code-assist" = Google Antigravity (Cloud Code Assist) OAuth + CCA envelope. */ googleMode?: "ai-studio" | "vertex" | "cloud-code-assist"; + /** Google tool-schema compatibility policy. Omitted preserves compatible report-only behavior. */ + googleToolSchemaPolicy?: "compatible" | "reject-lossy"; /** Vertex AI GCP project id (or GOOGLE_CLOUD_PROJECT / GCLOUD_PROJECT env). */ project?: string; /** Vertex AI location, e.g. "us-central1" or "global" (or GOOGLE_CLOUD_LOCATION env). */ diff --git a/structure/config.md b/structure/config.md index dd7198ceb1d..05ed7e7ceb6 100644 --- a/structure/config.md +++ b/structure/config.md @@ -28,6 +28,11 @@ deduplication and credential storage separately from Codex config injection. ## Config surface +Google providers may persist `googleToolSchemaPolicy` as `compatible` or `reject-lossy`. +`ocx provider add --google-tool-schema-policy` is one authoring path and is accepted only when the +effective adapter is `google`. Omission remains absent in `config.json`; the adapter resolves it to +`compatible` in memory. + ### OpenCodex home and live process state `initializePersistedConfigIfMissing` in `src/config.ts` is the create-only path consumed by @@ -317,6 +322,9 @@ and re-exports them as a compatibility facade; it must not grow a second copy. V ordering, and cross-field rules are part of the write/load contract because management requests and hand-edited `config.json` must accept and reject the same provider shapes. +The Google tool-schema policy uses a closed enum at this boundary. Unknown values fail config load, +management admission, and command-line creation rather than silently degrading to compatible mode. + > Decision record: [ADR-0020](decisions/ADR-0020-provider-validation-ownership.md) ## Provider relative send paths diff --git a/structure/gui-and-management-api.md b/structure/gui-and-management-api.md index 47ef706b615..e6226c58894 100644 --- a/structure/gui-and-management-api.md +++ b/structure/gui-and-management-api.md @@ -115,6 +115,11 @@ be treated as implemented: ## API ownership +The provider editor admits `googleToolSchemaPolicy` as an editor-safe, non-secret field. Its value +is validated as `compatible` or `reject-lossy` before live adoption and persistence; an invalid +value changes neither state. Omission remains absent and is resolved by the Google adapter rather +than materialized by the management API. + `src/server/index.ts` authenticates and routes `/api/*`, then delegates to `src/server/management-api.ts`, which composes the route modules under `src/server/management/`. Codex account routes live in `src/codex/auth-api/routes.ts` because they own the credential store, not diff --git a/structure/ops/docs-and-release.md b/structure/ops/docs-and-release.md index cf6de0f2317..967b81ecf09 100644 --- a/structure/ops/docs-and-release.md +++ b/structure/ops/docs-and-release.md @@ -31,6 +31,10 @@ lists its required source/registry paths and preview/apply flags. ## Public docs +The provider configuration reference and provider guide own the public Google tool-schema policy: +the persisted values/default, initial refusal, non-direct repair withholding, direct no-repair +behavior, and content-free diagnostics. English and all translated copies change together. + The public documentation site lives in `docs-site/` and is built with Astro + Starlight. English is served at the site root, with Korean under `/ko`, Simplified Chinese under `/zh-cn`, Traditional Chinese under `/zh-tw`, Russian under `/ru`, and Japanese under `/ja`. `docs-site/astro.config.mjs` is the locale source of truth. diff --git a/structure/providers-and-adapters.md b/structure/providers-and-adapters.md index b9049bf3ae2..6589563b616 100644 --- a/structure/providers-and-adapters.md +++ b/structure/providers-and-adapters.md @@ -15,7 +15,7 @@ the [bounded ingestion contract](transports/inventory.md#bounded-response-ingest | `src/responses/muse-tool-name-alias.ts` | Host-gated Meta Muse 64-char tool-name alias/restore used by the Responses passthrough. | | `src/adapters/openai-chat.ts`, `src/adapters/openai-chat/` | OpenAI-compatible Chat Completions bridge, split into leaves (`wire.ts`, `messages.ts`, `response-events.ts`, `passthrough.ts`, `tool-call-validation.ts`, `tool-schema.ts`, `errors.ts`). Its client delivery shapes in `src/chat/outbound.ts` and `src/server/chat-native-sse.ts` relay the upstream `service_tier` echo on non-stream, folded-stream, and synthesized-SSE bodies, never inventing the key when the upstream omits it. | | `src/adapters/anthropic.ts` | Anthropic Messages bridge. A `refusal` or `content_filter` stop reason yields an explicit `incomplete` event with `retryable: false` rather than `done` with that stopReason (#4312); `max_tokens` remains `done`. | -| `src/adapters/google.ts` | Gemini bridge. The final wire compiler owns [endpoint-scoped, content-free tool-schema loss reporting](providers/google.md#google-tool-schema-loss-reporting); reporting does not change routing or request bytes. | +| `src/adapters/google.ts` | Gemini bridge. The final wire compiler owns [endpoint-scoped tool-schema loss policy](providers/google.md#google-tool-schema-loss-reporting): compatible mode changes no request bytes, strict initial loss creates no physical send, and strict non-direct repair creates no changed repair send. | | `src/adapters/azure.ts` | Azure OpenAI bridge. | | `src/adapters/cursor.ts`, `src/adapters/cursor/` | Cursor protobuf transport: discovery, request builder, event decoding, MCP, thread continuity, native-exec policy. | | `src/adapters/devin.ts`, `src/adapters/devin/cloud-direct/` | Devin runTurn transport over Cognition Connect-RPC. `GetChatMessage` uses the Responses provider executor and shared physical-send budget; catalog and JWT support RPCs remain outside inference-send accounting. | diff --git a/structure/providers/google.md b/structure/providers/google.md index a583a8a9289..5582a356d9f 100644 --- a/structure/providers/google.md +++ b/structure/providers/google.md @@ -102,6 +102,18 @@ and 1,024 visited nodes; reporting stops with those limits and does not inspect debug is enabled. `generationConfig.responseMimeType` and `generationConfig.responseJsonSchema` are output-schema fields and never enter tool-schema sanitation or loss accounting. +`googleToolSchemaPolicy` is provider-scoped. Omission and `compatible` retain the report-only body +and existing repair replay. `reject-lossy` refuses an initially lossy or comparison-indeterminate +compilation before `buildRequest` returns, so no physical send exists. Vertex and Cloud Code Assist carry the same +resolved policy into their 400 compatibility repair: indexed repair reports one opened declaration, +unindexed repair reports every declaration it would open, and strict policy returns the original +400 without a changed repair send. The `google-tool-schema-repair` diagnostic inherits the complete +bounded report shape — version, endpoint class, `lossy`, `uncertainComparisons`, truncation flag, +and saturating fixed category counts — and adds only the `repair` phase, the declaration count, and whether the changed +send was allowed. +AI Studio direct mode continues to disable 400 repair entirely. Output schemas remain outside both +initial and repair policy. + ## Google wire-shape projection `src/adapters/google-wire-shape.ts` describes a compiled Google request without carrying any of diff --git a/structure/runtime.md b/structure/runtime.md index d5053cc74c0..84eb843b35c 100644 --- a/structure/runtime.md +++ b/structure/runtime.md @@ -108,6 +108,10 @@ does not perform OAuth, and runtime credential resolution rereads the owned sour | `src/codex/shim.ts` | Codex autostart shim: replaces the `codex` binary with a wrapper that auto-starts the proxy on demand. It skips startup for management subcommands even when value-taking global flags precede the subcommand, and transactionally restores complete, stable external launcher replacements without a watcher or PATH rediscovery. | | `src/service.ts` | OS service manager (macOS launchd, Linux systemd, Windows schtasks): always-on proxy with crash restart. Facade over the `src/service/` leaves — `src/service/launchd.ts`, `src/service/systemd.ts`, `src/service/windows-ops.ts`, `src/service/windows-scheduler.ts`, `src/service/windows-taskxml.ts`, `src/service/state.ts`, `src/service/guards.ts`, `src/service/health.ts`, `src/service/repair.ts`, `src/service/orchestration.ts`, `src/service/diagnostics.ts`, `src/service/cli.ts`. | +`src/cli/provider.ts` accepts the Google-only `--google-tool-schema-policy` creation flag and rejects +an unknown value or non-Google effective adapter before persistence. The persisted field and default +are owned by the [config contract](config.md#config-surface). + The `src/` root stays thin: process entry (`src/cli.ts`, `src/index.ts`), shared config/types, router, bridge, service manager, reasoning-effort definitions, and the stall-timeout budget live there. Feature code is grouped by responsibility: diff --git a/structure/transports/inventory.md b/structure/transports/inventory.md index 9dbe612b559..f4eee217b0c 100644 --- a/structure/transports/inventory.md +++ b/structure/transports/inventory.md @@ -29,7 +29,7 @@ surface is listed here so a maintainer can find the owner without grepping: | Azure OpenAI Responses | `src/adapters/azure.ts` | Deployment-shaped URLs on top of the Responses contract. | | Responses custom-tool preview | `src/bridge/sse.ts`, `src/server/responses-custom-tool-repair.ts`, `src/responses/progressive-freeform-input.ts` | Direct adapter events and routed function restoration share one progressive wrapper decoder. Fence-shaped `exec`/`apply_patch` prefixes stay held until authoritative completion normalization, while each caller retains its own patch-envelope and byte-budget policy. | | Meta Muse Responses tool names | `src/responses/muse-tool-name-alias.ts`, `src/adapters/openai-responses.ts` | `api.meta.ai` only: function names over 64 characters or containing characters outside `[a-zA-Z0-9_-]` become collision-safe wire aliases and are restored before the client sees them. | -| Google / Vertex / Antigravity | `src/adapters/google.ts`, `src/adapters/google-http.ts`, `src/adapters/google-wire-compiler.ts`, `src/adapters/google-tool-schema.ts`, `src/adapters/google-truncation.ts`, `src/adapters/google-errors.ts`, `src/adapters/google-antigravity-wire.ts`, `src/adapters/google-antigravity-replay.ts`, `src/adapters/google-wire-shape.ts` | Vertex and Antigravity install a Google-family `fetchResponse` and so own their retry policy, while AI Studio Gemini leaves it undefined and uses the default server fetch path. The Google-family wrapper reuses the shared abort/deadline helpers (`src/lib/upstream-retry.ts`), wire-body repair, and upstream error normalization. The final compiler also produces the [content-free tool-schema loss report](../providers/google.md#google-tool-schema-loss-reporting). `google-wire-shape.ts` sits outside that path entirely: it only reads the compiled body, and only when provider debug is on. | +| Google / Vertex / Antigravity | `src/adapters/google.ts`, `src/adapters/google-http.ts`, `src/adapters/google-wire-compiler.ts`, `src/adapters/google-tool-schema.ts`, `src/adapters/google-truncation.ts`, `src/adapters/google-errors.ts`, `src/adapters/google-antigravity-wire.ts`, `src/adapters/google-antigravity-replay.ts`, `src/adapters/google-wire-shape.ts` | Vertex and Antigravity install a Google-family `fetchResponse` and so own their retry policy, while AI Studio Gemini leaves it undefined and uses the default server fetch path. The Google-family wrapper reuses shared abort/deadline helpers, upstream error normalization, and policy-aware wire-body repair: strict initial schema loss sends nothing, while strict repair withholding returns the original 400 without a changed send. The final compiler produces the [content-free tool-schema loss contract](../providers/google.md#google-tool-schema-loss-reporting). `google-wire-shape.ts` remains diagnostic-only. | | Mimo Free | `src/adapters/mimo-free.ts` | Client identity and JWT handling are transport-local; the per-install client id lives in the opencodex state root. | | Anthropic image ingress | `src/adapters/anthropic-image-guard.ts`, `src/adapters/anthropic-image-normalize.ts`, `src/adapters/anthropic-image-codec.ts` | Oversized or unsupported images are normalized or rejected before reaching upstream. An image's ladder position is pinned to its own identity (content hash + media type) rather than recomputed from recency each request (#4532); appending a newer image therefore cannot demote and re-encode older images and bust Anthropic's prompt prefix cache. Unseen images still take the age-tier pyramid's first position, the total byte budget still binds, and a 413 `tierBias` retry still applies. Recorded positions only move down the ladder, so the store is monotonic. | | Adapter execution support | `src/adapters/run-turn-queue.ts`, `src/adapters/tool-catalog-nudge.ts`, `src/adapters/identity.ts`, `src/adapters/image.ts`, `src/adapters/upstream-http-error.ts` | Shared machinery: turn ordering, tool-catalog nudging, client fingerprinting, image conversion, upstream error normalization. | diff --git a/tests/adapters/google/google-tool-schema-contract.test.ts b/tests/adapters/google/google-tool-schema-contract.test.ts index 8959b8d4b39..a8f4256683c 100644 --- a/tests/adapters/google/google-tool-schema-contract.test.ts +++ b/tests/adapters/google/google-tool-schema-contract.test.ts @@ -1,11 +1,17 @@ import { afterEach, describe, expect, test } from "bun:test"; import { createGoogleAdapter as createGoogleAdapterProduction } from "../../../src/adapters/google"; +import type { AdapterRequest } from "../../../src/adapters/base"; +import { + fetchAntigravityWithRetry, + fetchDirectGeminiWithRetry, + fetchVertexWithRetry, +} from "../../../src/adapters/google-http"; import { GOOGLE_TOOL_SCHEMA_LOSS_COUNT_LIMIT, sanitizeGeminiToolParametersWithReport, type GoogleToolSchemaEndpointClass, } from "../../../src/adapters/google-tool-schema"; -import { compileGoogleWireBody } from "../../../src/adapters/google-wire-compiler"; +import { compileGoogleWireBody, GoogleToolSchemaPolicyError } from "../../../src/adapters/google-wire-compiler"; import { getDebugLogEntries, resetDebugLogBufferForTests } from "../../../src/lib/debug-log-buffer"; import { resetDebugSettingsForTests, setDebugSettings } from "../../../src/lib/debug-settings"; import type { OcxParsedRequest, OcxProviderConfig } from "../../../src/types"; @@ -146,6 +152,50 @@ function compiledRequest(body: string, endpointClass: GoogleToolSchemaEndpointCl : parsed; } +function repairRequest(enveloped = false): AdapterRequest { + const request = { + contents: [{ role: "user", parts: [{ text: "REPAIR_PROMPT_CANARY_5112" }] }], + tools: [{ functionDeclarations: [ + { + name: "REPAIR_TOOL_ONE_CANARY_5112", + parameters: { + type: "object", + properties: { REPAIR_PROPERTY_ONE_CANARY_5112: { type: "string", enum: ["REPAIR_VALUE_ONE_CANARY_5112"] } }, + }, + }, + { + name: "REPAIR_TOOL_TWO_CANARY_5112", + parameters: { + type: "object", + properties: { REPAIR_PROPERTY_TWO_CANARY_5112: { type: "integer", minimum: 1 } }, + }, + }, + ] }], + }; + return { + url: "https://google.example.test/generate", + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify(enveloped ? { request } : request), + }; +} + +function responseSequence(responses: Response[]): { calls: string[]; executor: typeof fetch } { + const calls: string[] = []; + let index = 0; + const executor = (async (_input: RequestInfo | URL, init?: RequestInit) => { + calls.push(typeof init?.body === "string" ? init.body : ""); + return responses[index++] ?? responses[responses.length - 1]!; + }) as typeof fetch; + return { calls, executor }; +} + +function googleError(message: string): Response { + return new Response(JSON.stringify({ + error: { code: 400, status: "INVALID_ARGUMENT", message }, + }), { status: 400, headers: { "content-type": "application/json" } }); +} + afterEach(() => { resetDebugSettingsForTests(); resetDebugLogBufferForTests(); @@ -665,6 +715,213 @@ describe("Google tool-schema loss report", () => { }); }); + test.each(ENDPOINT_CASES)("reject-lossy refuses initial $endpointClass loss before any send", async ({ endpointClass, provider }) => { + const adapter = createGoogleAdapter({ ...provider, googleToolSchemaPolicy: "reject-lossy" }); + let sends = 0; + const executor = (async () => { + sends++; + return new Response("unexpected send"); + }) as typeof fetch; + let caught: unknown; + try { + const built = await adapter.buildRequest(endpointRequest(true)); + await adapter.fetchResponse?.(built, { executor }); + } catch (error) { + caught = error; + } + expect(caught).toBeInstanceOf(GoogleToolSchemaPolicyError); + const policyError = caught as GoogleToolSchemaPolicyError; + expect(policyError.phase).toBe("initial"); + expect(policyError.endpointClass).toBe(endpointClass); + expect(policyError.categories).toEqual({ "enum-value-filtered": 1 }); + expect(sends).toBe(0); + for (const canary of [ + "ENDPOINT_TOOL_CANARY_5112", + "ENDPOINT_PROPERTY_CANARY_5112", + "ENDPOINT_VALUE_CANARY_5112", + "OUTPUT_SCHEMA_CANARY_5112", + ]) { + expect(policyError.message).not.toContain(canary); + } + }); + test.each(ENDPOINT_CASES)("reject-lossy refuses indeterminate $endpointClass compilation before any send", async ({ endpointClass, provider }) => { + const adapter = createGoogleAdapter({ ...provider, googleToolSchemaPolicy: "reject-lossy" }); + let sends = 0; + const executor = (async () => { + sends++; + return new Response("unexpected send"); + }) as typeof fetch; + let caught: unknown; + try { + const built = await adapter.buildRequest(endpointRequestUncertain()); + await adapter.fetchResponse?.(built, { executor }); + } catch (error) { + caught = error; + } + expect(caught).toBeInstanceOf(GoogleToolSchemaPolicyError); + const policyError = caught as GoogleToolSchemaPolicyError; + expect(policyError.phase).toBe("initial"); + expect(policyError.endpointClass).toBe(endpointClass); + expect(policyError.indeterminate).toBe(true); + expect(policyError.categories).toEqual({}); + expect(policyError.message).toContain("indeterminate"); + expect(sends).toBe(0); + }); + + test.each(ENDPOINT_CASES)("reject-lossy accepts lossless $endpointClass tools and native output schemas", async ({ endpointClass, provider }) => { + const built = await createGoogleAdapter({ ...provider, googleToolSchemaPolicy: "reject-lossy" }) + .buildRequest(endpointRequest(false)); + const request = compiledRequest(built.body, endpointClass); + const generationConfig = request.generationConfig as Record; + expect(generationConfig.responseMimeType).toBe("application/json"); + expect(generationConfig.responseJsonSchema).toEqual({ + type: "object", + properties: { OUTPUT_SCHEMA_CANARY_5112: { type: "integer", minimum: 1 } }, + }); + }); + + test.each(ENDPOINT_CASES)("omitted and compatible policy keep $endpointClass request bytes identical", async ({ endpointClass, provider }) => { + const omitted = await createGoogleAdapter(provider).buildRequest(endpointRequest(true)); + const compatible = await createGoogleAdapter({ ...provider, googleToolSchemaPolicy: "compatible" }) + .buildRequest(endpointRequest(true)); + expect(stableWireBody(compatible.body, endpointClass)).toBe(stableWireBody(omitted.body, endpointClass)); + }); + + test("reject-lossy withholds indexed Vertex repair and reports only content-free facts", async () => { + const rawError = "tools.1.custom.input_schema: JSON schema is invalid REPAIR_ERROR_CANARY_5112"; + const fixture = responseSequence([googleError(rawError), new Response("unexpected repair")]); + const realError = console.error; + console.error = () => {}; + try { + setDebugSettings({ debug: true }); + const response = await fetchVertexWithRetry(repairRequest(), { + executor: fixture.executor, + timeoutMs: 5_000, + }, { toolSchemaPolicy: "reject-lossy" }); + expect(response.status).toBe(400); + const responseText = await response.text(); + expect(responseText).toContain("Vertex AI invalid request"); + // The withheld repair returns the ORIGINAL upstream 400 through the pre-existing + // normalization (safeGoogleHttpErrorMessage classification + credential/path redaction), + // which preserves ordinary upstream detail text. The canary exclusion applies to the NEW + // diagnostic record below, not to the preserved original response. + expect(responseText).toBe("Vertex AI invalid request: " + rawError); + expect(fixture.calls).toHaveLength(1); + const lines = getDebugLogEntries().map(entry => entry.line) + .filter(line => line.includes("google-tool-schema-repair")); + expect(lines).toHaveLength(1); + expect(lines[0]).toContain('"endpointClass":"vertex"'); + expect(lines[0]).toContain('"repair-opened-schema":1'); + expect(lines[0]).toContain('"declarationCount":1'); + expect(lines[0]).toContain('"changedSendAllowed":false'); + for (const canary of ["REPAIR_", "input_schema", "JSON schema", "CANARY_5112"]) { + expect(lines[0]).not.toContain(canary); + } + } finally { + console.error = realError; + } + }); + + test("reject-lossy withholds unindexed Cloud Code Assist repair for every declaration", async () => { + const rawError = "function declarations contain an invalid schema REPAIR_ERROR_CANARY_5112"; + const fixture = responseSequence([ + googleError(rawError), + new Response("unexpected repair"), + ]); + const realError = console.error; + console.error = () => {}; + try { + setDebugSettings({ debug: true }); + const response = await fetchAntigravityWithRetry(repairRequest(true), { + executor: fixture.executor, + timeoutMs: 5_000, + returnRawErrors: true, + }, { toolSchemaPolicy: "reject-lossy" }); + expect(response.status).toBe(400); + // The returned body is the original upstream 400 payload, not a replacement. + expect(await response.json()).toEqual({ + error: { code: 400, status: "INVALID_ARGUMENT", message: rawError }, + }); + expect(fixture.calls).toHaveLength(1); + const line = getDebugLogEntries().map(entry => entry.line) + .find(entry => entry.includes("google-tool-schema-repair")); + expect(line).toContain('"endpointClass":"cloud-code-assist"'); + expect(line).toContain('"repair-opened-schema":2'); + expect(line).toContain('"declarationCount":2'); + expect(line).toContain('"changedSendAllowed":false'); + expect(line).not.toContain("REPAIR_ERROR_CANARY_5112"); + } finally { + console.error = realError; + } + }); + + test.each([ + ["indexed", "tools.1.custom.input_schema: JSON schema is invalid", 1], + ["unindexed", "function declarations contain an invalid schema", 2], + ] as const)("compatible mode preserves the %s changed repair send", async (_name, message, count) => { + const fixture = responseSequence([googleError(message), new Response("ok", { status: 200 })]); + const realError = console.error; + console.error = () => {}; + try { + setDebugSettings({ debug: true }); + const response = await fetchVertexWithRetry(repairRequest(), { + executor: fixture.executor, + timeoutMs: 5_000, + }, { toolSchemaPolicy: "compatible" }); + expect(response.status).toBe(200); + expect(fixture.calls).toHaveLength(2); + const repaired = JSON.parse(fixture.calls[1]!) as { tools: Array<{ functionDeclarations: Array<{ parameters: unknown }> }> }; + const declarations = repaired.tools[0]!.functionDeclarations; + expect(declarations.filter(item => JSON.stringify(item.parameters) === '{"type":"object","properties":{}}')) + .toHaveLength(count); + const line = getDebugLogEntries().map(entry => entry.line) + .find(entry => entry.includes("google-tool-schema-repair")); + expect(line).toContain(`"repair-opened-schema":${count}`); + expect(line).toContain('"changedSendAllowed":true'); + } finally { + console.error = realError; + } + }); + + test("direct mode never repairs or emits a repair diagnostic under reject-lossy", async () => { + const rawError = "tools.0.custom.input_schema: JSON schema is invalid"; + const fixture = responseSequence([ + googleError(rawError), + new Response("unexpected repair"), + ]); + setDebugSettings({ debug: true }); + const response = await fetchDirectGeminiWithRetry(repairRequest(), { + executor: fixture.executor, + timeoutMs: 5_000, + }, { toolSchemaPolicy: "reject-lossy", toolSchemaProfile: { endpointClass: "ai-studio" } }); + expect(response.status).toBe(400); + expect(await response.json()).toEqual({ + error: { code: 400, status: "INVALID_ARGUMENT", message: rawError }, + }); + expect(fixture.calls).toHaveLength(1); + expect(getDebugLogEntries().some(entry => entry.line.includes("google-tool-schema-repair"))).toBe(false); + }); + + test("thinking-only repair is policy-independent and carries no tool-schema report", async () => { + const request = repairRequest(); + request.body = JSON.stringify({ + contents: [{ role: "user", parts: [{ text: "hi" }] }], + generationConfig: { thinkingConfig: { thinkingLevel: "high" }, maxOutputTokens: 100 }, + }); + const fixture = responseSequence([ + googleError("thinking_config.thinking_level is unsupported"), + new Response("ok", { status: 200 }), + ]); + setDebugSettings({ debug: true }); + const response = await fetchVertexWithRetry(request, { + executor: fixture.executor, + timeoutMs: 5_000, + }, { toolSchemaPolicy: "reject-lossy" }); + expect(response.status).toBe(200); + expect(fixture.calls).toHaveLength(2); + expect(getDebugLogEntries().some(entry => entry.line.includes("google-tool-schema-repair"))).toBe(false); + }); + test.each(ENDPOINT_CASES)("derives and consumes the $endpointClass profile at the adapter boundary", async ({ endpointClass, provider }) => { const adapter = createGoogleAdapter(provider); const realError = console.error; diff --git a/tests/cli/cli-provider.test.ts b/tests/cli/cli-provider.test.ts index 5c8b72860b4..7c9d75affad 100644 --- a/tests/cli/cli-provider.test.ts +++ b/tests/cli/cli-provider.test.ts @@ -335,6 +335,51 @@ describe("ocx provider", () => { } }); + test.each(["compatible", "reject-lossy"] as const)("provider add persists Google tool-schema policy %s", policy => { + const { dir } = freshConfig(); + try { + const result = runCli([ + "provider", "add", "google-policy", + "--adapter", "google", + "--base-url", "https://generativelanguage.googleapis.com", + "--api-key", "test-key", + "--google-tool-schema-policy", policy, + ], { OPENCODEX_HOME: dir }); + expect(result.status).toBe(0); + expect(readConfig(dir).providers["google-policy"].googleToolSchemaPolicy).toBe(policy); + } finally { + removeTreeWithRetry(dir); + } + }); + + test("provider add rejects invalid or non-Google tool-schema policy without changing config", () => { + const { dir, configPath } = freshConfig(); + try { + const before = readFileSync(configPath, "utf8"); + const invalid = runCli([ + "provider", "add", "google-policy", + "--adapter", "google", + "--base-url", "https://generativelanguage.googleapis.com", + "--google-tool-schema-policy", "silent-loss", + ], { OPENCODEX_HOME: dir }); + expect(invalid.status).toBe(1); + expect(invalid.stderr).toContain('must be "compatible" or "reject-lossy"'); + expect(readFileSync(configPath, "utf8")).toBe(before); + + const wrongAdapter = runCli([ + "provider", "add", "chat-policy", + "--adapter", "openai-chat", + "--base-url", "https://example.test/v1", + "--google-tool-schema-policy", "reject-lossy", + ], { OPENCODEX_HOME: dir }); + expect(wrongAdapter.status).toBe(1); + expect(wrongAdapter.stderr).toContain("requires the google adapter"); + expect(readFileSync(configPath, "utf8")).toBe(before); + } finally { + removeTreeWithRetry(dir); + } + }); + test("provider add rejects duplicate without --force", () => { const { dir } = freshConfig(); try { diff --git a/tests/fixtures/test-layout-expected.json b/tests/fixtures/test-layout-expected.json index 242d3b21983..4b3c59d7b42 100644 --- a/tests/fixtures/test-layout-expected.json +++ b/tests/fixtures/test-layout-expected.json @@ -750,6 +750,7 @@ "main-quota-window-observation.test.ts": "codex-integration", "management-api-logs-metrics.test.ts": "server", "management-client-config-route.test.ts": "server", + "management-google-tool-schema-policy.test.ts": "server", "management-integration-journal-delete.test.ts": "server", "management-integration-routes.test.ts": "server", "management-origin-tls.test.ts": "server", diff --git a/tests/server/management-google-tool-schema-policy.test.ts b/tests/server/management-google-tool-schema-policy.test.ts new file mode 100644 index 00000000000..31f3ba41965 --- /dev/null +++ b/tests/server/management-google-tool-schema-policy.test.ts @@ -0,0 +1,104 @@ +import { expect, spyOn, test } from "bun:test"; +import { mkdtempSync, readFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; + +import { loadConfig, saveConfig } from "../../src/config"; +import { validateConfigCandidate } from "../../src/config/diagnostics"; +import * as destinationPolicy from "../../src/lib/destination-policy"; +import { providerEditorConfigDTO } from "../../src/server/auth-cors"; +import { handleManagementAPI } from "../../src/server/management-api"; +import type { OcxConfig } from "../../src/types"; +import { catalogConvergenceFactory } from "../helpers/catalog-convergence"; +import { ManagementRequest as Request } from "../helpers/management-auth"; +import { removeTreeWithRetry } from "../helpers/remove-tree"; + +function config(policy?: "compatible" | "reject-lossy"): OcxConfig { + return { + port: 0, + defaultProvider: "google", + providers: { + google: { + adapter: "google", + baseUrl: "https://generativelanguage.googleapis.com", + apiKey: "test-key", + googleMode: "ai-studio", + ...(policy ? { googleToolSchemaPolicy: policy } : {}), + }, + }, + }; +} + +test("Google tool-schema policy validates, persists, and stays absent when omitted", () => { + const testDir = mkdtempSync(join(tmpdir(), "ocx-google-tool-schema-policy-")); + const previousHome = process.env.OPENCODEX_HOME; + process.env.OPENCODEX_HOME = testDir; + try { + for (const policy of ["compatible", "reject-lossy"] as const) { + saveConfig(config(policy)); + const loaded = loadConfig(); + expect(loaded.providers.google?.googleToolSchemaPolicy).toBe(policy); + saveConfig(loaded); + expect(loadConfig().providers.google?.googleToolSchemaPolicy).toBe(policy); + } + + saveConfig(config()); + const omitted = loadConfig(); + expect(omitted.providers.google?.googleToolSchemaPolicy).toBeUndefined(); + saveConfig(omitted); + expect(loadConfig().providers.google?.googleToolSchemaPolicy).toBeUndefined(); + + const invalid = config() as unknown as Record; + (invalid.providers as Record>).google!.googleToolSchemaPolicy = "silent-loss"; + const validation = validateConfigCandidate(invalid); + expect(validation.ok).toBe(false); + if (!validation.ok) expect(validation.error).toContain("googleToolSchemaPolicy"); + } finally { + if (previousHome === undefined) delete process.env.OPENCODEX_HOME; + else process.env.OPENCODEX_HOME = previousHome; + removeTreeWithRetry(testDir); + } +}); + +test("provider editor round-trips valid policy and rejects an unknown value without mutation", async () => { + const testDir = mkdtempSync(join(tmpdir(), "ocx-google-tool-schema-editor-")); + const previousHome = process.env.OPENCODEX_HOME; + process.env.OPENCODEX_HOME = testDir; + const live = config("compatible"); + saveConfig(live); + const resolved = spyOn(destinationPolicy, "providerDestinationResolvedError").mockResolvedValue(null); + const request = async (body: unknown) => { + const url = new URL("http://localhost/api/providers"); + return (await handleManagementAPI(new Request(url, { + method: "PUT", + headers: { "content-type": "application/json" }, + body: JSON.stringify(body), + }), url, live, { createManagementConvergeCodex: catalogConvergenceFactory() }))!; + }; + try { + const baseline = providerEditorConfigDTO(loadConfig()); + expect(baseline.providers.google?.googleToolSchemaPolicy).toBe("compatible"); + const next = structuredClone(baseline); + next.providers.google!.googleToolSchemaPolicy = "reject-lossy"; + const accepted = await request({ baseline, next }); + expect(accepted.status, await accepted.text()).toBe(200); + expect(live.providers.google?.googleToolSchemaPolicy).toBe("reject-lossy"); + expect(loadConfig().providers.google?.googleToolSchemaPolicy).toBe("reject-lossy"); + + const stable = providerEditorConfigDTO(loadConfig()); + const invalid = structuredClone(stable) as unknown as { + providers: Record>; + }; + invalid.providers.google!.googleToolSchemaPolicy = "silent-loss"; + const beforeBytes = readFileSync(join(testDir, "config.json"), "utf8"); + const rejected = await request({ baseline: stable, next: invalid }); + expect(rejected.status).toBe(400); + expect(live.providers.google?.googleToolSchemaPolicy).toBe("reject-lossy"); + expect(readFileSync(join(testDir, "config.json"), "utf8")).toBe(beforeBytes); + } finally { + resolved.mockRestore(); + if (previousHome === undefined) delete process.env.OPENCODEX_HOME; + else process.env.OPENCODEX_HOME = previousHome; + removeTreeWithRetry(testDir); + } +}); From 00ac9b6a6c0707b8e315b88f334c396162909b17 Mon Sep 17 00:00:00 2001 From: JUN Date: Sun, 20 Sep 2026 00:45:44 +0900 Subject: [PATCH 50/97] docs: record thirteen verified contract issue outcomes (#5187) * docs: record thirteen verified contract issue outcomes * docs: keep open-work records neutral and date checkpoints --- .../260919_contract_resolution/000_plan.md | 6 ++-- .../260919_contract_resolution/001_status.md | 18 +++++++--- .../020_integration.md | 2 ++ .../260919_contract_resolution/031_pr_5157.md | 10 +++++- .../034_strict_schema_policy.md | 24 +++++++++++++ .../035_static_policy_resolver.md | 24 +++++++++++++ .../037_acceptance_ledger.md | 14 +++++--- .../038_metrics_review.md | 35 +++++++++++++++++++ .../039_decode_hint_review.md | 29 +++++++++++++++ .../040_preview_review.md | 7 ++++ 10 files changed, 156 insertions(+), 13 deletions(-) create mode 100644 devlog/_plan/260919_contract_resolution/038_metrics_review.md create mode 100644 devlog/_plan/260919_contract_resolution/039_decode_hint_review.md create mode 100644 devlog/_plan/260919_contract_resolution/040_preview_review.md diff --git a/devlog/_plan/260919_contract_resolution/000_plan.md b/devlog/_plan/260919_contract_resolution/000_plan.md index 7f8ac58ac9d..f0d238bf18f 100644 --- a/devlog/_plan/260919_contract_resolution/000_plan.md +++ b/devlog/_plan/260919_contract_resolution/000_plan.md @@ -18,8 +18,8 @@ Evidence lives in this unit; previous implementation specifications remain in `d | Lane | Sole issue ownership | File domains and sequence | | --- | --- | --- | -| Runtime | #5109 #5110 #5111 #5113 #5115 #5122 #5123 #5124 | Raw transport contract, custom input consistency, send accounting, journal ownership and continuation policy. Stack null-body/coding only if a real shared helper dependency exists; upload can stay independent. Keep stream and state changes separate. | -| Policy and operator | #5112 #5114 #5116 #5117 #5118 #5119 #5120 #5121 | Schema reports before reject-lossy policy, static merge parity before consolidation, identity hints separate from availability, authority-map/tooling, optional metrics and pure preview, documentation alignment. Stack by these dependencies; independent docs can land separately. | +| Runtime | #5109 #5110 #5111 #5113 #5115 #5118 #5122 #5123 #5124 | Raw transport contract, custom input consistency, send accounting, journal ownership and continuation policy. Stack null-body/coding only if a real shared helper dependency exists; upload can stay independent. Keep stream and state changes separate. | +| Policy and operator | #5112 #5114 #5116 #5117 #5119 #5120 #5121 | Schema reports before reject-lossy policy, static merge parity before consolidation, identity hints separate from availability, authority-map/tooling, optional metrics and pure preview, documentation alignment. Stack by these dependencies; independent docs can land separately. | | Coordinator | Review, CI, base/merge judgment and issue closure | Workers never merge or close issues. Cross-lane shared test-layout/structure changes are serialized at integration, with no cap increases or dropped regressions. | The user chose two different main-task models and a specific subagent model. Runtime/model selection provenance stays in task records rather than public repository artifacts. Workers may use unlimited useful subagent rounds; concurrent workers have disjoint writes and never perform branch-level git operations in parallel on one checkout. @@ -49,3 +49,5 @@ The roadmap is locked, the two isolated implementation owners are active, and th Ownership amendment: #5115 moved to the runtime owner after the policy owner confirmed no implementation writer or commit existed. Independent preparation can proceed on current dev because its known-model hint region is unchanged by #5174; final landing remains after #5171 and #5174, with a fresh integration base, reviewed delta and exact-head hosted CI. The two-owner limit, acceptance criteria and execution restrictions are unchanged. Independent preparation audit accepted the #5115 ownership amendment: `knownModelIdsForProvider` is byte-identical across #5174, the registry entry type is unchanged by that layer, and the new helper has no static-policy dependency. Expected later overlap is import ordering and line movement; integration must retain both independent changes and obtain new-head hosted proof. + +Second ownership amendment: #5118 transferred to the existing runtime owner after confirmation that no implementation writer, branch or commit existed. Server and dashboard delivery remain required, with the prior private pre-build audit incorporated before implementation. Metrics-to-preview shared-route integration is serialized; preparation can proceed in disjoint files. Dashboard evidence must satisfy the actual file-based screenshot gate using hosted artifacts under the no-local-build restriction. No third implementation owner was created. diff --git a/devlog/_plan/260919_contract_resolution/001_status.md b/devlog/_plan/260919_contract_resolution/001_status.md index 3b18bd361f4..0b92cf7613c 100644 --- a/devlog/_plan/260919_contract_resolution/001_status.md +++ b/devlog/_plan/260919_contract_resolution/001_status.md @@ -1,13 +1,13 @@ # Campaign status -Status: ACTIVE. Ten of the sixteen original issues are resolved and closed. Remaining: #5112, #5114, #5115, #5117, #5118, #5123. Supplementary sideband recovery #5161 and send-assertion follow-up #5170 are merged. Runtime ownership #5157, strict-policy child #5167 (report parent #5162 merged), and static-policy resolver/consumer stack #5171/#5174 are under exact-head hosted verification and static review. Latest integration recorded here: #5162 at `8a030721b3ffc909ca7d8b05ca0b7c873c1493a1`. +Status: ACTIVE. Thirteen of the sixteen original issues are resolved and closed. Remaining: #5114, #5117, #5118. Supplementary sideband recovery #5161 and send-assertion follow-up #5170 are merged. Runtime ownership #5157 is merged. Strict-policy child #5167 is merged. Static-policy resolver/consumer stack #5171/#5174 and metrics #5183 remain under review and hosted verification; preview #5185 is a draft. Integration snapshot at 2026-09-19T15:27:51Z: #5167 at `96a6de86b71cf8a8f78959e0bf626dac642510a7`. ## Owners | Lane | State | Issues | | --- | --- | --- | -| Runtime | Active in an isolated worktree | #5109 #5110 #5111 #5113 #5115 #5122 #5123 #5124 | -| Policy and operator | Active in an isolated worktree | #5112 #5114 #5116 #5117 #5118 #5119 #5120 #5121 | +| Runtime | Active in an isolated worktree | #5109 #5110 #5111 #5113 #5115 #5118 #5122 #5123 #5124 | +| Policy and operator | Active in an isolated worktree | #5112 #5114 #5116 #5117 #5119 #5120 #5121 | Private orchestration records retain the actual task handles, model-selection evidence and wake cursors. The current coordinator heartbeat is ACTIVE at a 20-minute interval. It follows the two existing implementation owners; it must not duplicate them. The coordinator owns integration and issue closure. @@ -20,8 +20,8 @@ Private orchestration records retain the actual task handles, model-selection ev ## Issue outcomes -Closed: #5109, #5110, #5111, #5113, #5116, #5119, #5120, #5121, #5122, #5124. -Open: #5112, #5114, #5115, #5117, #5118, #5123. +Closed: #5109, #5110, #5111, #5112, #5113, #5115, #5116, #5119, #5120, #5121, #5122, #5123, #5124. +Open: #5114, #5117, #5118. The entries below are chronological historical checkpoints. Their earlier open/closed states do not override the current summary or acceptance ledger. @@ -126,3 +126,11 @@ Report parent #5162 merged at `8a030721b3ffc909ca7d8b05ca0b7c873c1493a1` after c Runtime owner pushed `9e789c1613b22109dd0398e9619be8902bff9662` for #5157: management ACL failure injection is restricted to the token file, the stream retry fixture uses its narrow relay-platform seam, and the direct combo fixture holds a writer lease and drains its response. Assertions and production ownership rules are unchanged in this delta. Independent review and fresh hosted CI are required. Policy owner is implementing #5117 in its isolated checkout while repairing #5174; #5115 and #5118 remain required scope. Ownership amendment: #5115 moved to the runtime owner after the policy owner confirmed no implementation writer or commit existed. Independent preparation can proceed on current dev because its known-model hint region is unchanged by #5174; final landing remains after #5171 and #5174, with a fresh integration base, reviewed delta and exact-head hosted CI. The two-owner limit, acceptance criteria and execution restrictions are unchanged. + +#5157 integrated and #5123 closed after final acceptance verification. Current progress is11/16, with five remaining original issues. See031_pr_5157.md for exact-head CI and merge evidence. + +Second ownership amendment: #5118 transferred to the existing runtime owner after confirmation that no implementation writer, branch or commit existed. Server and dashboard delivery remain required, with the prior private pre-build audit incorporated before implementation. Metrics-to-preview shared-route integration is serialized; preparation can proceed in disjoint files. Dashboard evidence must satisfy the actual file-based screenshot gate using hosted artifacts under the no-local-build restriction. No third implementation owner was created. + +#5177 is integrated and #5115 closed after complete acceptance verification. Current progress is12/16; remaining issues are #5112/#5114/#5117/#5118. The independent decode-hint change landed before policy migration after a recorded source-based sequencing amendment. + +The current-task heartbeat was updated and read back ACTIVE with the existing twenty-minute cadence. It now reflects twelve closed issues, runtime ownership of #5118, policy ownership of #5112/#5114/#5117, and the remaining publication/visual verification duties. Other task monitors were not modified. diff --git a/devlog/_plan/260919_contract_resolution/020_integration.md b/devlog/_plan/260919_contract_resolution/020_integration.md index 2909611e5b0..d005e4e438b 100644 --- a/devlog/_plan/260919_contract_resolution/020_integration.md +++ b/devlog/_plan/260919_contract_resolution/020_integration.md @@ -74,3 +74,5 @@ Background receipt update: #5009 advanced from a relocated-test conflict to clea Background receipts now record clean replay for #3901 at `d0da0264e8092f65575b6eb69aa9bc2ee067e9d8` and #3983 at `c25e79ea0d076859aa43f09fd97802e3e7cd79ee` after the whitespace correction. #4989 publication matched remote head `7a8cb1ad286355c5aaefcdd84b16752daad8e849`. The separate consolidation command reports #3389 closed as superseded by #4989, not merged. #3025 still reports a Logs.tsx conflict at a later replay step. These are external lane receipts rather than campaign completion evidence. Final background batch in this notification: #4056 reports clean replay at `5eb0d1e311a1c2d5986bcd701711cd007f2090b8`; #4225 still has a compatibility-facade conflict. An older pinned-base check detected concurrent remote changes for #5157 and #5136, and verified an externally updated #5016. The historical pinned-base mismatch is not current mergeability evidence and triggers no automatic overwrite/rebase by this coordinator. Both campaign implementation owners remain active, repairing the separately observed exact-head CI failures. + +Cumulative integration verification: push run [35446842226](https://github.com/lidge-jun/opencodex/actions/runs/35446842226) completed successfully at `8a030721b3ffc909ca7d8b05ca0b7c873c1493a1`, including aggregate ci and all applicable jobs. This independently verifies the earlier runtime union through #5170/#5162. The later docs-only #5175 is separate; future runtime integrations still require fresh cumulative proof. Superseded earlier runs are not retried merely because their canceled legs made an aggregate red. diff --git a/devlog/_plan/260919_contract_resolution/031_pr_5157.md b/devlog/_plan/260919_contract_resolution/031_pr_5157.md index 64884c8a1c0..660153430b7 100644 --- a/devlog/_plan/260919_contract_resolution/031_pr_5157.md +++ b/devlog/_plan/260919_contract_resolution/031_pr_5157.md @@ -1,6 +1,6 @@ # PR 5157: spend-ledger writer ownership -Issue #5123 is open. [PR #5157](https://github.com/lidge-jun/opencodex/pull/5157) targets `dev`; its current head is `647dc675019a995b97c73c7b7ce02fe4cebaf5f4`. It has not been integrated and is not approved for merge until exact-head hosted verification and remaining public reviews pass. +Issue #5123 is closed after verified integration. [PR #5157](https://github.com/lidge-jun/opencodex/pull/5157) targets `dev`; its current head is `a67cd9b3be6965f3b7435aa0702b6b9b5bf68fc3`. It merged into dev as `40670044146adc714f06d8b2e29f9114f8393df5`; the entries below preserve pre-integration checkpoints. The proposed control requires a single writer for each state directory. Implementation and regression changes have received independent static reviews, including storage, startup/shutdown, fixture lifetime, and current integration compatibility. Detailed security review and historical repair reasoning are retained in ignored task scratch pending a final published outcome. @@ -9,3 +9,11 @@ The preceding head `271139883a552f1aac9ce3f847eb94e3327e5efc` failed Linux shard Local suites, individual tests, typecheck, builds, installation and runtime execution were NOT RUN. Static syntax screens performed during earlier review are not compiler or runtime proof. No issue closure or completion claim is made. A subsequent three-file fixture correction addresses platform-specific hosted failures. Independent delta review and current-head hosted CI are running; previous-head successes do not establish the new head. Public status remains open and unmerged. + +Acceptance mapping exposed a mode-activation gap in the process tests. The new test-only delta adds all four holder/contender combinations with actual contender policy configuration, and a transition from observation to enforcement. Independent review and new-head hosted CI are pending; no production behavior change or completion is claimed. + +Independent review of the mode-activation correction at `a67cd9b3be6965f3b7435aa0702b6b9b5bf68fc3` passed. The real-process matrix and configuration transition now exercise the stated modes; existing failure, restart, cleanup and privacy checks remain. Hosted CI at this head is still required. + +Verified integration at 2026-09-19T14:35:24Z: reviewed head `a67cd9b3be6965f3b7435aa0702b6b9b5bf68fc3` passed all applicable hosted checks and aggregate [35448104919](https://github.com/lidge-jun/opencodex/actions/runs/35448104919). Logs show actual four-mode process contention, observation-to-enforcement transition, independent directories, crash recovery and startup rollback. Independent technical/security and nine-file integration-union reviews passed; no unresolved public reviews or maintainer objections remained. Merge `40670044146adc714f06d8b2e29f9114f8393df5` was verified in origin/dev before #5123 closed at 2026-09-19T14:36:03Z. The resulting cumulative dev run remains separately monitored. + +Cumulative dev verification completed successfully at merge head `40670044146adc714f06d8b2e29f9114f8393df5` in [push run35449204833](https://github.com/lidge-jun/opencodex/actions/runs/35449204833). All applicable jobs and aggregate passed, confirming the integrated ownership change with the current runtime union. diff --git a/devlog/_plan/260919_contract_resolution/034_strict_schema_policy.md b/devlog/_plan/260919_contract_resolution/034_strict_schema_policy.md index f3eeccfed11..a2561f82aee 100644 --- a/devlog/_plan/260919_contract_resolution/034_strict_schema_policy.md +++ b/devlog/_plan/260919_contract_resolution/034_strict_schema_policy.md @@ -23,3 +23,27 @@ Secondchildhostedfailure: test2job105898238282 layoutseed resolvesgoogle-tool-sc Child745f6b6 test-onlycorrectionindependentPASS: originalVertex400literalexpected, newdiagnosticprivacyretained, renamedmanagement-configtestbody100%unchangedandseed/explicit/expectedagree. Parsedregistrydiffhasnoothermappingchanges. Latestchild60516397 requiresinterdiffconfirmation beforeusingearlierevidence. Latestchild60516397 onlyrestoresregistryformatting over745f6b6; parsedfullJSONsemanticsequalforbothlayoutfiles. Previousscopedtest/code reviewsremainvalid; currentheadCIrequired. + +Prepared post-parent cascade at `16ed5bee42eb53110983e2788f607c390bf43ac0` has clean merge-tree against current dev. Range-diff matches the first four strict-policy commits exactly; test rename/repair history is consolidated. Final inventory/union re-review was assigned before treating the cascade as equivalent. The previous head CI is not new-head proof; fresh hosted CI remains required. + +Independent cascade review PASS at `16ed5bee42eb53110983e2788f607c390bf43ac0`: base ancestry verified, first four stable patch IDs preserved, complete child patch equivalent excluding the two test-layout inventories, renamed test byte-identical, and inventories changed only the intended test name. Production strict-uncertainty behavior, docs and regression assertions remain intact. The new head is published and hosted CI is in progress. + +Current public review additionally requests consistent documentation of both strict refusal conditions (proven loss or indeterminate comparison), and exact repair-diagnostic shape. Source/documentation validation was assigned before accepting the requested edits. The request for local verification commands does not override the task restriction: applicable hosted suite, type and privacy proof must be recorded instead. The current PR remains unmerged. + +Independent documentation validation confirmed a bounded seventeen-file correction: all eight guide/configuration pairs must describe rejection on proven loss or indeterminate comparison; the eight guides must include the bounded uncertainty count in their report shape; the Google structure repair-shape list must include the same field already emitted by source. No runtime change was requested. + +Documentation correction `fc12e8f7b009cc31b6bebf7b6633c91de35d972b` is prepared; seventeen-file locale/shape interdiff review assigned. Earlier runtime reviews remain relevant only where source is unchanged; new-head hosted proof is still required. + +The seventeen-file uncertainty documentation correction passed independent review. New head `50af16087ca08751af7c1b1e49fd85337a1b99f2` additionally clarifies that compatibility repair replay remains enabled by default and adds exact original-400-body assertions in two existing regression cases. This narrow delta is under re-review; production source is unchanged. + +Final nine-file delta at `50af16087ca08751af7c1b1e49fd85337a1b99f2` passed independent review: each translated guide distinguishes strict repair withholding from unchanged default replay, and both additional response assertions retain the original 400 payload and one-send behavior while diagnostic canaries stay excluded. Production source is unchanged. No known static blocker remains; current-head hosted jobs are still running. + +Final integration-union review passed for candidate tree `07141dc1ab9e6dbe313208a1bf5a00f3e0979968` with dev `4067004414`: five shared structure/layout files preserve both ownership and strict-policy contracts; source/tests on each side remain intact. New public wording feedback identified one separate diagnostic-boundary clarification: strict initial compilation throws before initial loss-record emission, while strict repair has its own record. Main verified the source order and requested a precise eight-guide correction, without changing runtime behavior. + +The latest guide-only review accepted the strict initial diagnostic boundary but rejected a newly added statement that the policy error carries the full same facts as the report. The error and report have different bounded shapes. The owner was asked only to remove that added clause across eight translations, retaining all already-correct behavior descriptions and avoiding a runtime expansion. + +Commit `eb5d51b7c0` removes only the newly introduced overclaim about policy-error/report equivalence from all eight guides. Main inspected the bounded deletion; independent language consistency re-review is pending. No runtime or regression behavior changes in this delta. + +Independent review accepted final eight-guide clause removal at `eb5d51b7c022637ac086639a695864bcf1f7a136`. No other claim or behavior changed. Current-head hosted verification remains required before integration. + +Verified integration: #5167 merged as `96a6de86b71cf8a8f78959e0bf626dac642510a7` at2026-09-19T15:26:53Z. Exact headeb5d51b7 passed every applicable job and aggregate [35450471540](https://github.com/lidge-jun/opencodex/actions/runs/35450471540), including type/privacy checks. Logs explicitly show endpoint loss/uncertainty refusals, lossless/native-output acceptance, indexed/unindexed withholding, direct no-repair and CLI/management persistence. All known reviews resolved; current union retains ownership and decode hints. Both parent8a030721 and child merge ancestries were verified before #5112 was closed. No local execution. diff --git a/devlog/_plan/260919_contract_resolution/035_static_policy_resolver.md b/devlog/_plan/260919_contract_resolution/035_static_policy_resolver.md index 3a08cfb1b16..6d6a5c04872 100644 --- a/devlog/_plan/260919_contract_resolution/035_static_policy_resolver.md +++ b/devlog/_plan/260919_contract_resolution/035_static_policy_resolver.md @@ -21,3 +21,27 @@ Second independent review passed router/server source tracing at `7b25d449d98280 Final parent preflight at `2fdd21004eb256890ae9d7a54baab6c00653c65d`: applicable hosted CI and aggregate35446324533 passed, but thirteen public review threads remain unresolved. Merge is held. Findings concern legacy policy parity, limit projection and provenance/documentation; independent source adjudication is split between legacy compatibility and the other projection findings. Owner must reconcile any valid findings in the parent and cascade its child, with fresh exact-head evidence. A green run and earlier subset reviews do not override concrete unresolved findings. Independent source adjudication of thirteen parent threads accepted eleven and rejected two. Accepted work includes raw-input legacy parity, shared family-limit resolution, cross-field input bounds, selected-destination validation/provenance, captured-auth capability overlays, output-default fallback and two documentation scope corrections. Existing callers already repair three legacy cases, so these must not be misreported as observed runtime failures. The explicit captured-auth boundary and existing supported custom-header policy support rejecting two proposed changes. Owner received precise source evidence and minimum regression cases; no blanket header-name heuristic or weakened shared-policy objective was accepted. Corrections must be reviewed at the new parent head and cascaded to the child. + +Parent correction `b21937d152fba9b7eccb8d4c8ff454a0595fa5e6` is published. It addresses the accepted parity, limit and provenance findings with focused oracle cases and extracts pure merge helpers. Two independent re-reviews cover the same adjudicated split; rejected changes remain excluded. New-head CI and child cascade are required before integration. + +The repaired parent still has two concrete review blockers: the legacy reasoning-ladder repair must require a matched registry entry so intentional custom destinations are preserved; service-tier provenance must follow the captured-auth overlay and provider fallback, including unlisted models. Other accepted fixes passed their assigned reviews. Owner received minimal regressions and was asked to batch both corrections before cascading the consumer layer. + +Follow-up parent `df578b6719500344091fcf60a94c3879af72b908` adds the matched-entry legacy guard and corrects service-tier provenance fallback, with focused parity cases and documentation clarification. Independent re-review is limited to the two remaining findings; earlier accepted changes are unchanged. New-head hosted verification is running. + +Both narrow re-reviews at `df578b6719500344091fcf60a94c3879af72b908` passed. Custom unmatched destinations retain their explicit reasoning ladder/provenance; canonical legacy repair remains. Service-tier provenance now follows merged model defaults and captured-auth provider fallback, retaining operator false and covering an unlisted key-auth model. No known static parent blocker remains; current-head hosted proof and consumer cascade remain required. + +Consumer child `20ea64ff9475204443391ffa16980be2f914a579` incorporates the corrected parent but still fails the four observed consumer classes in hosted run35450781362: a narrowed route type omits staticPolicy, resolved URL refusal parity, virtual-model identity behavior, and clearing explicit modality back to inference. Range-diff shows the consumer production patch was unchanged; parent repairs cannot substitute for consumer-specific fixes. Completed job logs and exact anchors were delivered to its owner for a coherent repair while preserving existing assertions. + +Owner confirmed the earlier consumer repair had not actually been executed after its delegated attempt did not proceed. Coordinator requested verified worker acceptance and an actual immutable diff before any renewed repair claim; the parent-only cascade does not count as consumer correction. Existing implementation and regression scope remain unchanged. + +Independent execution-driven source diagnosis split the child failures into two consumer fixes (route type propagation and final wire-model identity selection) and two parent parity fixes exposed by consumption (absent base-URL error semantics and legacy colon-family map lookup). Exact capability lookup remains exact-only. Original test expectations were confirmed meaningful and must remain. Parent integration is held again until these cross-layer findings are corrected; prior isolated static PASS did not establish complete consumer equivalence. + +Prepared consumer correction `1a2ed3eb896d4ee54d7e8b0eefa3d104c28ec684` requires further review: it fixes the retry type and a missing-URL guard, but temporarily restores the old catalog modality authority and does not visibly change the reported final-wire identity selection. Coordinator explicitly retained the shared-authority objective and requested completing those contracts after the parent fallback fix, not treating a compatible bypass as the requested consolidation. Original transport identity assertions remain required. + +Independent consumer review confirmed the type correction, but the virtual-model identity repair was still absent at1a2ed. Owner was explicitly directed to resolve from the final routed model rather than namespaced logging identity, and to consume the shared modality result once the parent lookup parity is fixed. Parent correction6892fd25 adds absent-URL and colon-family cases and is under narrow re-review. + +Parent6892 narrow review found one cross-source provenance mismatch: a registry exact model key wins the merged value over an operator family key, while separate source lookups can incorrectly report operator provenance. Owner was asked to derive value and provenance from the same winning merged lookup and add a cross-source regression. Absent-URL behavior and exact-only capability precedence otherwise passed. Parent remains held until the source/value agreement is proved. + +Parent `844cea4e0f11b5fa78fb5b1352a6949f4ab19035` adds merged winning-key provenance; the consumer stack is published on it at `304648706a360a737cad4d6473b9d164869e4c45`. Narrow parent re-review and exact-head hosted checks are pending. Running checks are not recorded as passing execution evidence. + +Independent review accepted winning-key provenance at `844cea4e0f11b5fa78fb5b1352a6949f4ab19035`, including cross-source exact/family precedence and explicit false. Source and provenance now share the same key-selection order. Current parent/child hosted proof remains in progress. diff --git a/devlog/_plan/260919_contract_resolution/037_acceptance_ledger.md b/devlog/_plan/260919_contract_resolution/037_acceptance_ledger.md index 61fde8b1965..733804705fe 100644 --- a/devlog/_plan/260919_contract_resolution/037_acceptance_ledger.md +++ b/devlog/_plan/260919_contract_resolution/037_acceptance_ledger.md @@ -1,16 +1,16 @@ # Sixteen-issue acceptance ledger -This checkpoint does not declare the campaign complete. On 2026-09-19, a fresh GitHub query confirmed ten closed issues and six open issues. Every recorded closed-issue merge below was checked as an ancestor of `origin/dev` at `8a030721b3ffc909ca7d8b05ca0b7c873c1493a1`. Acceptance/review and exact-head hosted receipts are in the linked per-PR records; this checkpoint does not re-run or replace those checks. +This checkpoint does not declare the campaign complete. Current disposition: thirteen closed issues and three open issues. The initial 2026-09-19 checkpoint confirmed ten closed issues and six open issues; the later verified #5123 closure is recorded below. The initial ten-issue checkpoint checked its recorded merges against `8a030721b3ffc909ca7d8b05ca0b7c873c1493a1`. The three later merges for #5123, #5115 and #5112 were separately verified after landing; all thirteen closed-issue merges have now been checked against `96a6de86b71cf8a8f78959e0bf626dac642510a7`. Acceptance/review and exact-head hosted receipts are in the linked per-PR records; this checkpoint does not re-run or replace those checks. | Issue | Current disposition | Evidence / remaining requirement | | --- | --- | --- | | #5109 | Closed; landed through #5125 | [`4e7d7132d8`](021_pr_5125.md); closure at 2026-09-19T08:08:28Z. | | #5110 | Closed; landed through #5127 | [`9824aa55bb`](023_pr_5127.md); closure at 2026-09-19T09:23:33Z. | | #5111 | Closed; landed through #5126 | [`af4f744c75`](022_pr_5126.md); closure at 2026-09-19T10:01:05Z. | -| #5112 | Open; incomplete | Report parent #5162 landed; strict-policy child #5167 requires new-base review, hosted verification and landing. [Record](033_schema_report_review.md). | +| #5112 | Closed; parent #5162 and child #5167 landed | [`96a6de86b7`](034_strict_schema_policy.md); current closure verified after both ancestries. | | #5113 | Closed; landed through #5129 | [`bb2fa5ab25`](024_pr_5129.md); closure at 2026-09-19T10:04:15Z. | | #5114 | Open; incomplete | Resolver #5171 passed hosted CI but has unresolved review findings; consumer #5174 has hosted failures under repair. Both layers must land. [Record](035_static_policy_resolver.md). | -| #5115 | Open; incomplete | Runtime owner now owns registry identity-map classification and selector/availability regressions; final landing follows #5174. [Record](000_plan.md). | +| #5115 | Closed; landed through #5177 | [`838af40f1b`](039_decode_hint_review.md); closure at 2026-09-19T15:01:16Z. | | #5116 | Closed; landed through #5155 | [`6d42723387`](030_pr_5155.md); closure at 2026-09-19T11:07:05Z. | | #5117 | Open; incomplete | Opt-in metadata-only exporter is being implemented; full privacy/auth/counting/lifecycle acceptance remains unverified. [Record](000_plan.md). | | #5118 | Open; incomplete | Server-owned read-only preview, fingerprint validation and dialog integration still required. [Record](000_plan.md). | @@ -18,9 +18,13 @@ This checkpoint does not declare the campaign complete. On 2026-09-19, a fresh G | #5120 | Closed; landed through #5134 | [`1b54f2940b`](026_pr_5134.md); closure at 2026-09-19T09:02:10Z. | | #5121 | Closed; landed through #5138 | [`5ce51cb554`](027_pr_5138.md); closure at 2026-09-19T10:08:29Z. | | #5122 | Closed; landed through #5152 | [`26d3a862d6`](028_pr_5152.md); closure at 2026-09-19T11:06:36Z. | -| #5123 | Open; incomplete | Writer ownership #5157 at 9e789c1613 passed latest fixture-delta review; fresh hosted proof and landing remain required. [Record](031_pr_5157.md). | +| #5123 | Closed; landed through #5157 | [`4067004414`](031_pr_5157.md); closure at 2026-09-19T14:36:03Z. | | #5124 | Closed; landed through #5130 | [`acd43bf442`](025_pr_5130.md); closure at 2026-09-19T10:06:43Z. | -Supplementary requirements: sideband diagnostic/cleanup #5161 and send-assertion follow-up #5170 landed and their goalplan tasks are complete. The broader sideband root-cause issue is not claimed resolved. Public devlog publication, final cumulative dev verification, all remaining acceptance checks, final PABCD closure and heartbeat shutdown remain outstanding. No local test, typecheck, build, installation or proxy execution has been performed. +Supplementary requirements: sideband diagnostic/cleanup #5161 and send-assertion follow-up #5170 landed and their goalplan tasks are complete. The broader sideband root-cause issue is not claimed resolved. The initial public devlog checkpoint is merged; later evidence publication, final cumulative dev verification, all remaining acceptance checks, final PABCD closure and heartbeat shutdown remain outstanding. No local test, typecheck, build, installation or proxy execution has been performed. Publication review checkpoint: independent re-review accepted the corrected English owner/status summary, neutral pre-integration ownership record, and this ledger. The complete historical working records were preserved in ignored scratch; no implementation evidence was discarded. This is documentation readiness for the reviewed files, not permission to declare or publish the campaign as complete. + +Public checkpoint #5175 landed as `57b1df792ef7e66e17b0110727eefdd5387e164d` at 2026-09-19T14:13:30Z after reviewed head `128a47ea9db9b93ffc80fc2d42a2f4cddcc8f8c0` passed all applicable hosted checks and public review. Runtime checks were change-inapplicable, not executed. The original coordinator checkout staging was retained. Future implementation outcomes still require ledger updates and independent completion proof. + +At the #5123 checkpoint, the total was eleven closed and five open; this earlier checkpoint remains historical evidence. diff --git a/devlog/_plan/260919_contract_resolution/038_metrics_review.md b/devlog/_plan/260919_contract_resolution/038_metrics_review.md new file mode 100644 index 00000000000..358b76358f6 --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/038_metrics_review.md @@ -0,0 +1,35 @@ +# Metrics export acceptance review + +Issue #5117 remains open. Prepared implementation `7578198be2289966fa637e36c996faf9368c1cec` adds an opt-in bounded exporter, configuration, management routing, documentation and focused tests. Runtime aggregation and configuration/privacy/documentation reviews were assigned independently. No local execution was performed. + +Runtime review found two required corrections. Buffered HTTP 200 responses with a failed or incomplete terminal body lose terminal status at the non-stream finalizer and can be classified as completed; parsed terminal metadata must reach the metrics recorder without overriding cancellation or read errors. The new focused cases call recorder/logging helpers or inspect source strings, so they do not prove real HTTP or WebSocket finalization. Add transport-level flows and authenticated scrape assertions for exact logical/physical counts, terminal outcomes and missing timing/cancellation cases. + +Static review accepted bounded labels, the WebSocket duplicate-finalization guard, attempt send-count inputs, terminal-stream EOF handling, disabled-mode inactivity and fresh-owner reset semantics. These accepted parts do not offset the missing acceptance evidence. The implementation owner received the source anchors and must return a corrected immutable head for review and hosted CI. + +The separate config/auth/privacy/docs review passed at the prepared head. It covered default-off strict validation and malformed-load behavior, restart activation, shared transport injection, management authentication before disabled404, fixed labels/finite values, English and seven translated documentation sets, and lifecycle/units documentation. Runtime aggregation and transport-level proof gaps above remain blocking; the scoped PASS is not full implementation acceptance. + +Correction `fbbe437614` passed independent runtime re-review: bounded terminal metadata is propagated only at clean EOF; cancellation and read-error precedence remain. New real-server HTTP and WebSocket scrape regressions cover exact logical/send counts, failed/incomplete buffered responses, retry/recovery, EOF/cancellation, missing versus zero TTFT and disabled behavior. Combined with the earlier config/auth/privacy/docs review, no known static blocker remains. Hosted verification and integration with the current writer-ownership layer still need proof. + +Published as [PR #5183](https://github.com/lidge-jun/opencodex/pull/5183), dev base, head `298ec5f1ce45fdd412eee3d14b6665a199e6eaeb`, after rebasing onto the landed ownership change. The terminal-metadata correction has an identical patch ID; only base-dependent union handling in the initial feature layer changed. Independent rebase/fixture compatibility review and new-head hosted CI are required. The PR is attached to the coordinator task and covers the complete #5117 endpoint scope. + +Initial #5183 hosted run35450374594 failed four new real-flow cases. The first buffered-read-error fixture reports an uncaught injected error; following cases encounter a state-home ownership conflict. Owner received completed-job logs for diagnosis of the first failure and cleanup consequences, without weakening ownership or removing transport assertions. This observed execution failure takes precedence over the earlier source-only PASS. + +A second completed hosted job (Linux shard3, job105916394852) identified one source-oracle mismatch: the WebSocket idle-timeout test expected the previous one-argument handler construction. Owner received the exact anchor to update alongside real-flow repairs while retaining explicit timeout and activation assertions. No test removal or policy relaxation was requested. + +Independent rebase review found no additional integration loss: source/test blobs match the reviewed feature, overlap docs/inventories preserve both metrics and ownership, and production shutdown still releases ownership in final cleanup. The observed read-error fixture and subsequent home-conflict cascade remain owner-assigned repairs; their existence is not evidence to relax production ownership. The separate source-oracle mismatch also remains tracked until corrected. + +Fixture/source-oracle corrections committed at `6158748a4cd2cf5ed70420e2aef56069994910e7`; independent review is scoped to error activation, real transport assertions, complete teardown and retained WebSocket idle-policy coverage. No passing execution claim until new-head hosted CI. + +Independent review accepted `6158748a4cd2cf5ed70420e2aef56069994910e7`: real read-error activation occurs after the first delivered chunk, error precedence remains observable, server teardown is awaited with a failure-visible cleanup safety net, and WebSocket source assertions preserve idle policy and terminal/fallback checks. Current-head hosted jobs are running without observed failures at this checkpoint; no runtime success is claimed yet. + +New-head hosted execution at6158748 removed the subsequent state-home conflicts but still failed two actual transport cases: the buffered error rejects the fetch before body consumption, and cancellation is scraped before the expected aborted count is visible. Owner and independent source reviewer are investigating deterministic transport/error handling and finalization observation, preserving exact counts and avoiding fixed sleeps or skipped assertions. Static fixture approval did not establish execution success. + +Further source tracing corrected the fixture-only assumption: a pre-response handler rejection bypasses final request logging, so the metric is absent. Owner was asked to use the existing once-only finalization guard before rethrowing, preserving client-visible transport behavior and missing timing semantics. The separate cancellation count failure is a propagation race; a bounded upstream-cancel signal can establish the actual completion boundary without sleeps or relaxed counts. Both require new source/test review and hosted proof. + +Production/error-boundary correction `bf462d6070977746a2c5eb377220ca0d80494aaa` is published on #5183. Independent re-review is focused on once-only pre-response failure finalization, unchanged client transport errors, timing/send facts and deterministic cancellation observation. Fresh hosted verification is required. + +Review of the new exception finalizer found a concrete pre-response cancellation case: a client abort during a buffered read reaches the same catch but must classify as aborted, not a non-abort read failure. Owner was asked to choose the existing cancellation status/reason from the actual request signal, preserve once-only finalization and rethrow, and add a live pending-body abort regression while retaining the non-abort failure test. + +Hosted run35451702720 atbf462 again falsified assumptions in the error/cancellation fixtures: the client fetch resolved rather than rejecting in the observed handler-error case, and the expected upstream cancel callback was not observed before the bounded deadline. Owner and reviewer were told to derive a deterministic real-server harness boundary from source and existing conventions, preserve the actual metrics assertions, and avoid changing assertions speculatively or raising timeouts. + +Head `8b589b3114b82027e164f38e08dc580803c89c43` adds cancellation-aware status/reason to the pre-response finalizer and a real pending-body abort case. That correction is under narrow review. The earlier read-error and cancellation fixture execution failures are separate and remain unresolved until a deterministic harness and new hosted proof establish them. diff --git a/devlog/_plan/260919_contract_resolution/039_decode_hint_review.md b/devlog/_plan/260919_contract_resolution/039_decode_hint_review.md new file mode 100644 index 00000000000..f458fd530a9 --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/039_decode_hint_review.md @@ -0,0 +1,29 @@ +# Registry decode-hint review + +Issue #5115 is owned by the runtime lane following the explicit ownership handoff. Prepared head `b56511bc6d21a20928d8cfe66e97fbbe8a860ba9` is based on `8a030721b3ffc909ca7d8b05ca0b7c873c1493a1`. It adds a registry-owned exhaustive field classification and replaces only the router's manual identity-map list, with existing-file regression additions and structure documentation. + +Independent source review passed: direct and nested model-key maps contribute only their intended identity keys; non-model records and virtual wire-target values remain excluded; existing configured, cached and custom identity sources remain; the transport guard precedes registry hints; no catalog availability or entitlement is inferred. Separate test/documentation review and exact-head hosted execution remain required. + +The layer can be prepared independently because #5174 leaves the known-model hint function unchanged. Final integration remains after #5171 and #5174, with a current integration base, reviewed union and fresh hosted proof. No local execution and no completed-issue claim. + +Test review found missing public-boundary coverage: all maps are enumerated through the helper, but the actual route-decoding table covers only the seven newly omitted direct maps. Owner was asked to extend that same bounded table to all classified direct maps, add the shipped map-only provider decode case and verify the declared frozen-result contract. Existing transport, ambiguity, unknown pass-through and no-availability negatives were accepted. No implementation defect or cap violation was claimed. + +Correction `3918a95040` extends public routing coverage to all fifteen direct maps and checks frozen output. A new shipped-entry example used a transport-mismatched custom configuration and slash-free IDs, so its route equality could pass without activating registry hints. Main review requested a canonical configuration and an explicit map-only known-ID assertion, with accurate naming; the synthetic slash-ID matrix remains the proof of decoding. No production source change was requested. + +The independent test review passed the overall corrected coverage. It also corrected the preceding transport inference: this provider uses the non-key registry-owned matching path, so the custom fixture does not demonstrate transport exclusion. The actual issue is the slash-free selector assertion not proving decode activation. Existing synthetic public cases and shipped helper provenance are sufficient; the shipped example needs accurate wording, not a new production transport change or expanded acceptance contract. + +Final narrow test correction `8502bf99aa` removes only the newly added vacuous slash-free route example and its unused import. All fifteen synthetic public decode cases, the nested case, negatives and frozen-result checks remain; shipped-entry collection parity remains in the separate provider test. Source and test reviews are accepted for publication with exact-head hosted verification; final integration order is unchanged. + +Published as [PR #5177](https://github.com/lidge-jun/opencodex/pull/5177), base dev, exact head `8502bf99aaae6785eac4fe86d818fc454f79872d`. Template and reviewed test scope checked; attached to the coordinator task. Exact-head hosted CI and future integration with the earlier policy layers remain required before #5115 closure. + +Initial #5177 hosted run35448915385 failed the gates job on TS2352 at model-ids.ts:152 (registry entry cast to an indexed record), and a production-graph type-contract test exited nonzero. Completed job logs were retrieved directly before the overall run finished. Owner received the exact diagnostic and is correcting typed iteration/casting without changing classification semantics or removing the contract test. New-head hosted proof is required. + +The prepared type correction iterates keys of the exhaustive classification with the registry key type, reads direct maps through that key and reads the sole nested owner explicitly. Main source review found the current classification semantics preserved without the invalid index-signature cast. A syntax search returning no error-node matches is not a compiler pass; the corrected head still needs hosted type and suite proof. + +Type correction published at `a654ee8e4469f2c431b378a4ec42c68765e74a90` on #5177. Main reviewed the one-file typed-iteration delta; an independent narrow check and fresh hosted compiler/suite proof are pending. Existing public decoding and immutable-output regression coverage is unchanged. + +Independent one-file review of `a654ee8e4469f2c431b378a4ec42c68765e74a90` passed: role iteration order, selected-field access, sole nested owner, exclusion, deduplication and frozen output remain unchanged. Hosted compiler and suite verification is still pending; no local execution occurred. + +At corrected head `a654ee8e4469f2c431b378a4ec42c68765e74a90`, hosted run35449601489 gates and Linux shard4 passed. The shard log explicitly shows the previously failing production-graph translator-budget type contract passing. The original two failures are cleared; remaining applicable jobs and final integration still require completion. + +Verified integration: #5177 merged as `838af40f1b2fe32596b207ff85afcda40636f4d9` at 2026-09-19T15:00:41Z. Exact-head run35449601489 passed all applicable checks and aggregate; public decode cases were observed in macOS logs. Independent source/test/type correction and integration review passed, no public threads or maintainer objections remained, and all six files were preserved in the clean union with no overlapping dev changes. The former policy-first order was explicitly revised after both independent source review and the policy owner confirmed no semantic dependency. Later policy integration must preserve the helper/import and obtain fresh union proof. Issue #5115 closed at 2026-09-19T15:01:16Z after actual dev ancestry verification. diff --git a/devlog/_plan/260919_contract_resolution/040_preview_review.md b/devlog/_plan/260919_contract_resolution/040_preview_review.md new file mode 100644 index 00000000000..c65794e4e09 --- /dev/null +++ b/devlog/_plan/260919_contract_resolution/040_preview_review.md @@ -0,0 +1,7 @@ +# Integration preview delivery status + +Issue #5118 remains open. [PR #5185](https://github.com/lidge-jun/opencodex/pull/5185) is a draft server-layer implementation. The preview API, confirmation-bound mutation, regression coverage, documentation and dashboard delivery must all be completed and verified before issue closure. + +The owner is continuing implementation under independent review. Detailed working review records are retained in ignored scratch. Draft publication and an individual review result are not completion evidence. + +No local tests, typecheck, build, installation or proxy runtime execution were performed. Applicable exact-head hosted CI and actual dashboard visual evidence remain required; a built preview artifact alone is not a screenshot. From efb55e71e547ac83563e1d45dd60fb0b646e6cf7 Mon Sep 17 00:00:00 2001 From: JUN Date: Sun, 20 Sep 2026 01:10:55 +0900 Subject: [PATCH 51/97] Resolve static model policy once for catalog and routing (#5171) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(providers): add resolved static model policy with parity fixtures Introduce src/providers/resolved-model-policy.ts: one immutable, recursively frozen resolution of static provider/model policy with explicit field-level precedence and provenance, consumed by nothing yet. Observed/discovered limits stay out of the frozen result and are applied through the separate call-local clampObservedModelLimits projection. Parity fixtures pin byte/behavior equivalence with the current merge outcomes for registry defaults, explicit overrides, custom rows, unknown models, discovered hints, hard pins, aliases, and explicit false values. Consumer migration lands in the stacked child. Part of #5114 * fix(providers): close three static-policy parity gaps Review fold on the resolver layer: - Explicit modelCapabilities inputModalities now outranks the registry modelInputModalities map, with operator-capability provenance, matching the catalog projection's current precedence. - authMode no longer unconditionally prefers registry OAuth: the resolver accepts a caller-captured effective-auth authority (credential-free), falling back to the current registry/operator chain when absent. - The model identity contract is now explicit: resolution keys on the final wire identity after alias and virtual-model rewriting, with selected identity retained as diagnostic provenance. New parity fixtures cover capability precedence, captured key override and fallback, alias/virtual identities, and repeat-resolution equality. Part of #5114 * test(providers): derive the auth-mode oracle from the existing authority The captured-auth fixtures now compute the expected effective mode with the existing routedProviderConfig authority for a usable literal key and an unresolved key reference, then assert the resolver matches it. A future migration capturing the wrong mode fails these fixtures; no credential value enters the resolver input or result. Part of #5114 * test(providers): prove clamp non-mutation instead of banning a substring Hosted CI caught a false positive: the frozen policy legitimately retains the registry map's registry-only 90000 entry, so a global substring ban can never pass (run 35445279670 shard 4). Replace it with a pre-clamp deep snapshot equality check across both clamp calls, exact model cap assertions, explicit retention of the registry-only entry, and absence of observed fields on the model projection. Part of #5114 * fix(providers): reproduce legacy repair behaviors in static policy Fold the adjudicated review findings into the resolver: direct-effort stale-list repair, static-catalog liveModels authority, the ClinePass reasoning ladder, Anthropic family context, the maxInput<=contextWindow invariant, override-URL rejection semantics, captured key-auth service-tier overlay, defaultMaxOutputTokens fallback, and operator / registry baseUrl provenance now match the current route and catalog authority, each with a parity fixture against the existing oracle. The MiMo auth repair and header heuristics proposals were rejected by review adjudication and are not implemented (effective auth stays caller-captured; validation boundaries unchanged). The pure merge helpers moved to resolved-model-policy-merge.ts for module discipline. Part of #5114 * fix(providers): guard legacy repair to matched entries and fix tier provenance Review fold: the legacy ClinePass ladder repair now requires a matched registry entry, so an intentional custom-destination ladder survives with operator provenance; and model supportsServiceTier provenance now follows the same merged model-default authority that produced the value, falling back to provider provenance, with a regression for an unlisted key-auth model. Part of #5114 * fix(providers): guard absent override URLs and restore colon-family lookup Review fold: baseUrl normalization now mirrors the pre-migration router (absent/non-string values become the empty candidate, so the existing Invalid baseUrl guard fires instead of a TypeError, and template-only rows keep the registry fallback), with an oracle fixture comparing the complete error against routedProviderConfig. Legacy model maps resolve exact match, then colon-family base, then case-fold; explicit capability declarations stay exact-only. Regressions cover the custom ClinePass ladder preservation and unlisted key-auth tier provenance. Part of #5114 * fix(providers): keep map value and provenance on the same winning key Review fold: legacy map lookups searched operator and registry maps separately, so a registry exact key could win the value while provenance reported an operator family match. legacyModelSource now selects the winning key in one exact then colon-family then case-fold walk over the merged map and assigns provenance from that key's owner. Cross-source regression included. Part of #5114 * docs(structure): scope observed-limit fill to the call-local projection Review fold: "unknown remains unknown" was overly broad — the call-local projection returns the observed value when the static one is absent. Only a both-absent pair is unknown, and the frozen static policy itself never changes. Part of #5114 --- scripts/test-layout/layout.json | 1 + src/providers/resolved-model-policy-merge.ts | 167 ++++ src/providers/resolved-model-policy.ts | 399 +++++++++ structure/catalog.md | 17 + structure/config.md | 26 + structure/providers-and-adapters.md | 1 + tests/fixtures/test-layout-expected.json | 1 + tests/providers/resolved-model-policy.test.ts | 799 ++++++++++++++++++ 8 files changed, 1411 insertions(+) create mode 100644 src/providers/resolved-model-policy-merge.ts create mode 100644 src/providers/resolved-model-policy.ts create mode 100644 tests/providers/resolved-model-policy.test.ts diff --git a/scripts/test-layout/layout.json b/scripts/test-layout/layout.json index e69c654a9c8..ac1a90a8c17 100644 --- a/scripts/test-layout/layout.json +++ b/scripts/test-layout/layout.json @@ -1162,6 +1162,7 @@ "relay-eager.test.ts": "server", "release-helper.test.ts": "ci-workflows", "release-notes.test.ts": "ci-workflows", + "resolved-model-policy.test.ts": "providers", "release-version-line.test.ts": "ci-workflows", "remote-catalog.test.ts": "clients", "remote-workspace-activation.test.ts": "clients", diff --git a/src/providers/resolved-model-policy-merge.ts b/src/providers/resolved-model-policy-merge.ts new file mode 100644 index 00000000000..b767d903c36 --- /dev/null +++ b/src/providers/resolved-model-policy-merge.ts @@ -0,0 +1,167 @@ +import type { OcxProviderConfig } from "../types"; +import { MODEL_ADAPTER_OVERRIDE_ALLOWED } from "../types"; +import type { InboundWire, ModelWireDefault, ProviderRegistryEntry } from "./registry/types"; + +export type StaticPolicySource = + | "operator" | "operator-capability" | "captured-auth" + | "registry" | "hard-pin" | "provider-default" | "unknown"; + +export function detachedClone(value: T): T { + if (Array.isArray(value)) return value.map(item => detachedClone(item)) as T; + if (value && typeof value === "object") { + return Object.fromEntries(Object.entries(value as Record) + .map(([key, nested]) => [key, detachedClone(nested)])) as T; + } + return value; +} + +export function recursivelyFreeze(value: T): T { + if (!value || typeof value !== "object" || Object.isFrozen(value)) return value; + for (const nested of Object.values(value as Record)) recursivelyFreeze(nested); + return Object.freeze(value); +} + +export function scalar(operator: T | undefined, registry: T | undefined): [T | undefined, StaticPolicySource] { + if (operator !== undefined) return [detachedClone(operator), "operator"]; + if (registry !== undefined) return [detachedClone(registry), "registry"]; + return [undefined, "unknown"]; +} + +export function mapFill( + registry: Readonly> | undefined, + operator: Readonly> | undefined, +): [Record | undefined, StaticPolicySource] { + if (!registry && !operator) return [undefined, "unknown"]; + return [detachedClone({ ...(registry ?? {}), ...(operator ?? {}) }), operator ? "operator" : "registry"]; +} + +export function nestedMapFill( + registry: Readonly>> | undefined, + operator: Readonly>> | undefined, +): [Record> | undefined, StaticPolicySource] { + if (!registry && !operator) return [undefined, "unknown"]; + const merged: Record> = {}; + for (const [key, value] of Object.entries(registry ?? {})) merged[key] = { ...value }; + for (const [key, value] of Object.entries(operator ?? {})) { + merged[key] = { ...(merged[key] ?? {}), ...value }; + } + return [merged, operator ? "operator" : "registry"]; +} + +export function positiveCapMap( + registry: Readonly> | undefined, + operator: Readonly> | undefined, +): [Record | undefined, StaticPolicySource] { + if (!registry && !operator) return [undefined, "unknown"]; + const merged = { ...(registry ?? {}) }; + for (const [key, value] of Object.entries(operator ?? {})) { + merged[key] = typeof merged[key] === "number" ? Math.min(merged[key]!, value) : value; + } + return [merged, operator ? "operator" : "registry"]; +} + +export function stableUnion( + registry: readonly string[] | undefined, + operator: readonly string[] | undefined, +): [string[] | undefined, StaticPolicySource] { + if (!registry && !operator) return [undefined, "unknown"]; + return [[...new Set([...(registry ?? []), ...(operator ?? [])])], operator ? "operator" : "registry"]; +} + +export function staticHeaders( + registry: Readonly> | undefined, + operator: Readonly> | undefined, +): [Record | undefined, StaticPolicySource] { + if (!registry && !operator) return [undefined, "unknown"]; + if (!registry) return [{ ...(operator ?? {}) }, "operator"]; + if (!operator) return [{ ...registry }, "registry"]; + const claimed = new Set(Object.keys(operator).map(name => name.toLowerCase())); + const merged: Record = { ...operator }; + for (const [name, value] of Object.entries(registry)) { + if (!claimed.has(name.toLowerCase())) merged[name] = value; + } + return [merged, "operator"]; +} + +export function resolvedBaseUrl( + entry: Readonly | undefined, + provider: Readonly, +): [string, StaticPolicySource] { + if (!entry) return [provider.baseUrl, "operator"]; + const configured = typeof provider.baseUrl === "string" ? provider.baseUrl.trim() : ""; + const configuredIsResolved = configured.length > 0 && !/\{[^}]*\}/.test(configured); + if (entry.allowBaseUrlOverride && !configuredIsResolved) { + throw new Error(`Invalid baseUrl for provider "${entry.id}": expected a nonblank URL without unresolved placeholders`); + } + return (/\{[^}]*\}/.test(entry.baseUrl) || entry.allowBaseUrlOverride) && configuredIsResolved + ? [configured, "operator"] + : [entry.baseUrl, "registry"]; +} + +export function sameStringArray(left: readonly string[] | undefined, right: readonly string[]): boolean { + return left?.length === right.length && left.every((value, index) => value === right[index]); +} + +/** Legacy config-map lookup: exact id, colon family, then case-folded exact id. */ +export function legacyModelValue(record: Readonly> | undefined, modelId: string): T | undefined { + if (!record) return undefined; + if (Object.hasOwn(record, modelId)) return record[modelId]; + const colon = modelId.indexOf(":"); + if (colon > 0 && Object.hasOwn(record, modelId.slice(0, colon))) return record[modelId.slice(0, colon)]; + const folded = modelId.toLowerCase(); + return Object.entries(record).find(([key]) => key.toLowerCase() === folded)?.[1]; +} + +/** Provenance from the same merged-key walk as legacyModelValue. */ +export function legacyModelSource( + operator: Readonly> | undefined, + registry: Readonly> | undefined, + modelId: string, +): StaticPolicySource { + const merged = { ...(registry ?? {}), ...(operator ?? {}) }; + let winningKey: string | undefined; + if (Object.hasOwn(merged, modelId)) winningKey = modelId; + const colon = modelId.indexOf(":"); + if (winningKey === undefined && colon > 0 && Object.hasOwn(merged, modelId.slice(0, colon))) { + winningKey = modelId.slice(0, colon); + } + if (winningKey === undefined) { + const folded = modelId.toLowerCase(); + winningKey = Object.keys(merged).find(key => key.toLowerCase() === folded); + } + if (winningKey === undefined) return "unknown"; + return Object.hasOwn(operator ?? {}, winningKey) ? "operator" : "registry"; +} + +export function anthropicFamilyContextWindow( + record: Readonly> | undefined, + id: string, +): number | undefined { + if (!record || !id.toLowerCase().startsWith("claude-")) return undefined; + let candidate = id; + while (true) { + const cut = candidate.lastIndexOf("-"); + if (cut <= 0 || !/^\d+$/.test(candidate.slice(cut + 1))) return undefined; + candidate = candidate.slice(0, cut); + const value = record[candidate] + ?? Object.entries(record).find(([key]) => key.toLowerCase() === candidate.toLowerCase())?.[1]; + if (typeof value === "number" && value > 0) return value; + } +} + +export function wireDefault( + declared: ModelWireDefault | undefined, + provider: Readonly, + entry: Readonly | undefined, + inbound: InboundWire, + effectiveAuthMode: OcxProviderConfig["authMode"] | undefined, +): string | undefined { + if (declared === undefined || !MODEL_ADAPTER_OVERRIDE_ALLOWED.has(provider.adapter)) return undefined; + if (typeof declared !== "string") { + if (!declared.inbound.includes(inbound)) return undefined; + const authMode = effectiveAuthMode ?? provider.authMode ?? entry?.authKind; + if (declared.authModes && authMode && !declared.authModes.includes(authMode)) return undefined; + } + const wire = typeof declared === "string" ? declared : declared.wire; + return MODEL_ADAPTER_OVERRIDE_ALLOWED.has(wire) ? wire : undefined; +} diff --git a/src/providers/resolved-model-policy.ts b/src/providers/resolved-model-policy.ts new file mode 100644 index 00000000000..e8d385c9b74 --- /dev/null +++ b/src/providers/resolved-model-policy.ts @@ -0,0 +1,399 @@ +import type { ModelCapabilities, OcxProviderConfig } from "../types"; +import { MODEL_ADAPTER_OVERRIDE_ALLOWED, pinnedWireAdapter } from "../types"; +import { isCanonicalOpenAiForwardProvider } from "./openai-tiers"; +import { resolveProviderAuthTransport } from "./fastwire"; +import { registryEntrySupportsLiveModelDiscovery } from "./static-model-discovery"; +import type { InboundWire, ProviderRegistryEntry, ResponsesTerminalRepairPolicy } from "./registry/types"; +import { + anthropicFamilyContextWindow, + detachedClone, + legacyModelValue, + legacyModelSource, + mapFill, + nestedMapFill, + positiveCapMap, + recursivelyFreeze, + resolvedBaseUrl, + sameStringArray, + scalar, + stableUnion, + staticHeaders, + wireDefault, + type StaticPolicySource, +} from "./resolved-model-policy-merge"; +export type { StaticPolicySource } from "./resolved-model-policy-merge"; +export type StaticProviderPolicyField = + | "adapter" | "baseUrl" | "apiKeyTransport" | "headers" | "authMode" | "codexAccountMode" + | "responsesPath" | "chatCompletionsPath" | "keyOptional" | "freeTier" | "modelSuffixBracketStrip" + | "defaultModel" | "models" | "liveModels" | "contextWindow" | "modelContextWindows" + | "modelDisplayNames" | "modelInputModalities" | "modelMaxInputTokens" | "defaultMaxOutputTokens" + | "modelMaxOutputTokens" | "reasoningEfforts" | "modelReasoningEfforts" + | "modelDefaultReasoningEfforts" | "reasoningEffortMap" | "modelReasoningEffortMap" + | "reasoningWireFormat" | "noVisionModels" | "noReasoningModels" | "noTemperatureModels" + | "noTopPModels" | "noPenaltyModels" | "noJsonSchemaModels" | "parallelToolCalls" + | "promptCacheKey" | "chatServiceTier" | "openaiChatEofTolerance" | "statelessResponses" + | "requiresAdjacentResponsesToolResults" | "requiresPairedResponsesToolResults" | "annotateEmptyToolOutputs" + | "fastWire" | "supportsServiceTier" | "modelSupportsServiceTier" | "supportsOpenAiWebSearchToolFields" + | "supportsResponsesCustomTools" | "preserveResponsesReasoningContent" | "modelSupportsReasoningSummaries" + | "supportsVerbosity" | "modelSupportsVerbosity" | "responsesItemIdRepair" | "autoToolChoiceOnlyModels" + | "preserveReasoningContentModels" | "requiresReasoningPlaceholderModels" | "reasoningSplitModels" + | "reasoningDetailsModels" | "thinkingToggleModels" | "thinkingBudgetModels" | "showThinkingSummary" + | "escapeBuiltinToolNames" | "googleMode" | "project" | "location" | "modelCapabilities" + | "modelAutoCompactTokenLimits" | "modelSuppressSyntheticMax" | "modelReasoningSummaryDelivery" + | "codexToolMode" | "modelAdapters"; +type StaticProviderPolicyShape = Pick; +export type ResolvedProviderStaticPolicy = Readonly> & Readonly<{ + adapter: string; + baseUrl: string; +}>; +export interface ResolvedPerModelStaticPolicy { + readonly adapter: string; + readonly contextWindow?: number; + readonly inputModalities?: readonly string[]; + readonly maxInputTokens?: number; + readonly maxOutputTokens?: number; + readonly reasoningEfforts?: readonly string[]; + readonly defaultReasoningEffort?: string; + readonly supportsReasoningSummaries?: boolean; + readonly supportsVerbosity?: boolean; + readonly supportsServiceTier?: boolean; + readonly fastTierDescription?: string; + readonly directReasoningEffort?: boolean; + readonly responsesUpstreamStreaming?: boolean; + readonly responsesTerminalRepair?: Readonly; +} +export interface ResolvedModelPolicy { + readonly version: 1; + readonly providerName: string; + readonly modelId: string; + readonly transportMatchedRegistry: boolean; + readonly effectiveAlias?: string | null; + readonly provider: ResolvedProviderStaticPolicy; + readonly model: Readonly; + readonly provenance: Readonly<{ + alias: StaticPolicySource; + provider: Readonly>>; + model: Readonly>>; + }>; +} +export interface ResolveModelPolicyInput { + readonly providerName: string; + /** Final wire identity after resolveModelAlias and resolveOpenAiVirtualModel; public selection stays diagnostic-only. */ + readonly modelId: string; + readonly provider: Readonly; + readonly registryEntry?: Readonly; + readonly transportMatchedRegistry: boolean; + readonly inboundWire?: InboundWire; + /** Exact post-rewrite model capability declaration captured by the caller. */ + readonly modelCapabilities?: Readonly; + /** Credential-free live admission result: key only after a usable override, otherwise the registry mode. */ + readonly effectiveAuth?: Readonly<{ authMode: NonNullable }>; + /** Capture-time collision-aware alias decision. Omit to use provider then registry fallback. */ + readonly effectiveAlias?: string | null; + readonly effectiveAliasSource?: Exclude; +} +export interface ObservedModelLimits { + readonly contextWindow?: number; + readonly maxInputTokens?: number; + readonly maxOutputTokens?: number; +} +/** Call-local projection: observed values stay outside ResolvedModelPolicy and may only narrow caps. */ +export function clampObservedModelLimits( + policy: Readonly>, + observed: Readonly, +): Readonly { + const clamp = (staticCap: number | undefined, observedValue: number | undefined): number | undefined => { + if (observedValue === undefined) return staticCap; + return staticCap === undefined ? observedValue : Math.min(staticCap, observedValue); + }; + const contextWindow = clamp(policy.contextWindow, observed.contextWindow); + const clampedMaxInputTokens = clamp(policy.maxInputTokens, observed.maxInputTokens); + const maxInputTokens = clampedMaxInputTokens !== undefined && contextWindow !== undefined + ? Math.min(clampedMaxInputTokens, contextWindow) + : clampedMaxInputTokens; + const maxOutputTokens = clamp(policy.maxOutputTokens, observed.maxOutputTokens); + return Object.freeze({ + ...(contextWindow !== undefined ? { contextWindow } : {}), + ...(maxInputTokens !== undefined ? { maxInputTokens } : {}), + ...(maxOutputTokens !== undefined ? { maxOutputTokens } : {}), + }); +} +export function resolveModelPolicy(input: ResolveModelPolicyInput): ResolvedModelPolicy { + const entry = input.transportMatchedRegistry ? input.registryEntry : undefined; + const provider = input.provider; + const providerPolicy: Partial = {}; + const providerProvenance: Partial> = {}; + const [baseUrl, baseUrlSource] = resolvedBaseUrl(entry, provider); + const put = (key: K, value: StaticProviderPolicyShape[K] | undefined, source: StaticPolicySource): void => { + if (value !== undefined) providerPolicy[key] = detachedClone(value) as never; + providerProvenance[key] = source; + }; + const putScalar = (key: K, registryValue: StaticProviderPolicyShape[K] | undefined): void => { + const [value, source] = scalar(provider[key], registryValue); + put(key, value, source); + }; + const putUnion = (key: StaticProviderPolicyField, registryValue: readonly string[] | undefined): void => { + const [value, source] = stableUnion(registryValue, provider[key] as string[] | undefined); + put(key, value as never, source); + }; + const putMergedMap = ( + key: K, + registryValue: Readonly> | undefined, + operatorValue: Readonly> | undefined, + ): void => { + const [value, source] = mapFill(registryValue, operatorValue); + put(key, value as StaticProviderPolicyShape[K], source); + }; + put("adapter", entry?.adapter ?? provider.adapter, entry ? "registry" : "operator"); + put("baseUrl", baseUrl, baseUrlSource); + putScalar("apiKeyTransport", entry?.apiKeyTransport); + const [headers, headersSource] = staticHeaders(entry?.staticHeaders, provider.headers); + put("headers", headers, headersSource); + const resolvedAuthMode = input.effectiveAuth?.authMode + ?? (entry?.authKind === "forward" || entry?.authKind === "oauth" + ? entry.authKind + : provider.authMode === "forward" ? undefined : provider.authMode ?? entry?.authKind); + put("authMode", resolvedAuthMode, input.effectiveAuth + ? "captured-auth" + : entry?.authKind === "forward" || entry?.authKind === "oauth" ? "registry" + : provider.authMode !== undefined ? "operator" : entry ? "registry" : "unknown"); + putScalar("codexAccountMode", entry?.codexAccountMode); + const keyAuthDefaults = entry?.allowKeyAuthOverride === true + && resolvedAuthMode === "key" + && ["authorization_bearer", "x_api_key"].includes(resolveProviderAuthTransport( + provider.adapter, + resolvedAuthMode, + provider.apiKeyTransport, + )) + ? entry.keyAuthServiceTier + : undefined; + for (const key of [ + "responsesPath", "chatCompletionsPath", "keyOptional", "freeTier", "modelSuffixBracketStrip", + "defaultModel", "models", "liveModels", "contextWindow", "defaultMaxOutputTokens", + "reasoningWireFormat", "parallelToolCalls", "promptCacheKey", + "openaiChatEofTolerance", "statelessResponses", + "requiresAdjacentResponsesToolResults", "requiresPairedResponsesToolResults", + "annotateEmptyToolOutputs", "fastWire", "supportsServiceTier", + "supportsOpenAiWebSearchToolFields", "supportsResponsesCustomTools", + "preserveResponsesReasoningContent", "supportsVerbosity", "responsesItemIdRepair", + "showThinkingSummary", "escapeBuiltinToolNames", "googleMode", "project", "location", + ] as const) putScalar(key, entry?.[key] as StaticProviderPolicyShape[typeof key] | undefined); + const legacyClinePassLadder = entry !== undefined && input.providerName === "cline-pass" + && provider.reasoningWireFormat === "gateway-object" + && sameStringArray(provider.reasoningEfforts, ["low"]); + put("reasoningEfforts", legacyClinePassLadder ? entry?.reasoningEfforts : provider.reasoningEfforts ?? entry?.reasoningEfforts, + legacyClinePassLadder || provider.reasoningEfforts === undefined ? entry?.reasoningEfforts ? "registry" : "unknown" : "operator"); + put("chatServiceTier", provider.chatServiceTier ?? keyAuthDefaults?.chatServiceTier ?? entry?.chatServiceTier, + provider.chatServiceTier !== undefined ? "operator" : keyAuthDefaults?.chatServiceTier !== undefined ? "registry" : entry?.chatServiceTier !== undefined ? "registry" : "unknown"); + put("supportsServiceTier", provider.supportsServiceTier ?? keyAuthDefaults?.supportsServiceTier ?? entry?.supportsServiceTier, + provider.supportsServiceTier !== undefined ? "operator" : keyAuthDefaults?.supportsServiceTier !== undefined ? "registry" : entry?.supportsServiceTier !== undefined ? "registry" : "unknown"); + if (entry && !registryEntrySupportsLiveModelDiscovery(entry)) put("liveModels", false, "registry"); + putMergedMap("modelDisplayNames", entry?.modelDisplayNames, provider.modelDisplayNames); + putMergedMap("modelInputModalities", entry?.modelInputModalities, provider.modelInputModalities); + putMergedMap("modelMaxOutputTokens", entry?.modelMaxOutputTokens, provider.modelMaxOutputTokens); + putMergedMap("modelReasoningEfforts", entry?.modelReasoningEfforts, provider.modelReasoningEfforts); + putMergedMap("modelDefaultReasoningEfforts", entry?.modelDefaultReasoningEfforts, provider.modelDefaultReasoningEfforts); + const registryServiceTier = !entry?.modelServiceTierCapabilityBaseUrlGuard + || entry.modelServiceTierCapabilityBaseUrlGuard(provider.baseUrl) + ? entry?.modelSupportsServiceTier + : undefined; + const registryServiceTierDefaults = registryServiceTier || keyAuthDefaults?.modelSupportsServiceTier + ? { ...(registryServiceTier ?? {}), ...(keyAuthDefaults?.modelSupportsServiceTier ?? {}) } + : undefined; + putMergedMap("modelSupportsServiceTier", registryServiceTierDefaults, provider.modelSupportsServiceTier); + putMergedMap("modelSupportsReasoningSummaries", entry?.modelSupportsReasoningSummaries, provider.modelSupportsReasoningSummaries); + putMergedMap("modelSupportsVerbosity", entry?.modelSupportsVerbosity, provider.modelSupportsVerbosity); + for (const key of [ + "modelCapabilities", "modelAutoCompactTokenLimits", "modelSuppressSyntheticMax", + "modelReasoningSummaryDelivery", "codexToolMode", "modelAdapters", + ] as const) putScalar(key, undefined); + for (const key of ["modelContextWindows", "modelMaxInputTokens"] as const) { + const [value, source] = input.providerName === "openai-apikey" + ? positiveCapMap(entry?.[key], provider[key]) + : mapFill(entry?.[key], provider[key]); + put(key, value, source); + } + const [effortMap, effortMapSource] = mapFill(entry?.reasoningEffortMap, provider.reasoningEffortMap); + put("reasoningEffortMap", effortMap, effortMapSource); + const [modelEffortMap, modelEffortMapSource] = nestedMapFill(entry?.modelReasoningEffortMap, provider.modelReasoningEffortMap); + put("modelReasoningEffortMap", modelEffortMap, modelEffortMapSource); + for (const key of [ + "noVisionModels", "noReasoningModels", "noTemperatureModels", "noTopPModels", + "noPenaltyModels", "noJsonSchemaModels", "autoToolChoiceOnlyModels", + "preserveReasoningContentModels", "requiresReasoningPlaceholderModels", + "reasoningSplitModels", "reasoningDetailsModels", "thinkingToggleModels", "thinkingBudgetModels", + ] as const) putUnion(key, entry?.[key]); + for (const directModel of entry?.directReasoningEffortModels ?? []) { + const staleBudget = [directModel, ...(entry?.thinkingBudgetModels ?? [])]; + const routedStaleBudget = [...(entry?.thinkingBudgetModels ?? []), directModel]; + if (sameStringArray(provider.thinkingBudgetModels, staleBudget) + || sameStringArray(provider.thinkingBudgetModels, routedStaleBudget)) { + providerPolicy.thinkingBudgetModels = [...(entry?.thinkingBudgetModels ?? [])]; + providerProvenance.thinkingBudgetModels = "registry"; + } + const explicitEfforts = Object.entries(provider.modelReasoningEfforts ?? {}) + .filter(([key]) => key.toLowerCase() === directModel.toLowerCase()); + if (explicitEfforts.length > 0) { + for (const key of Object.keys(providerPolicy.modelReasoningEfforts ?? {})) { + if (key.toLowerCase() === directModel.toLowerCase()) delete providerPolicy.modelReasoningEfforts![key]; + } + for (const [key, value] of explicitEfforts) (providerPolicy.modelReasoningEfforts ??= {})[key] = [...value]; + } else if (entry?.modelReasoningEfforts?.[directModel] !== undefined) { + (providerPolicy.modelReasoningEfforts ??= {})[directModel] = [...entry.modelReasoningEfforts[directModel]!]; + } + const explicitDefault = Object.entries(provider.modelDefaultReasoningEfforts ?? {}) + .filter(([key]) => key.toLowerCase() === directModel.toLowerCase()); + if (explicitDefault.length > 0) { + for (const key of Object.keys(providerPolicy.modelDefaultReasoningEfforts ?? {})) { + if (key.toLowerCase() === directModel.toLowerCase()) delete providerPolicy.modelDefaultReasoningEfforts![key]; + } + for (const [key, value] of explicitDefault) (providerPolicy.modelDefaultReasoningEfforts ??= {})[key] = value; + } else if (entry?.modelDefaultReasoningEfforts?.[directModel] !== undefined) { + (providerPolicy.modelDefaultReasoningEfforts ??= {})[directModel] = entry.modelDefaultReasoningEfforts[directModel]!; + } + const explicitMap = Object.entries(provider.modelReasoningEffortMap ?? {}) + .filter(([key]) => key.toLowerCase() === directModel.toLowerCase()); + for (const key of Object.keys(providerPolicy.modelReasoningEffortMap ?? {})) { + if (key.toLowerCase() === directModel.toLowerCase()) delete providerPolicy.modelReasoningEffortMap![key]; + } + if (explicitMap.length > 0) { + for (const [key, value] of explicitMap) (providerPolicy.modelReasoningEffortMap ??= {})[key] = { ...value }; + } else { + (providerPolicy.modelReasoningEffortMap ??= {})[directModel] = {}; + } + } + const modelValue = (record: Readonly> | undefined): T | undefined => + legacyModelValue(record, input.modelId); + const modelSource = (operator: Readonly> | undefined, registry: Readonly> | undefined): StaticPolicySource => + legacyModelSource(operator, registry, input.modelId); + const modelOrProviderSource = ( + operatorMap: Readonly> | undefined, registryMap: Readonly> | undefined, + operatorDefault: T | undefined, registryDefault: T | undefined, + ): StaticPolicySource => { + const exact = modelSource(operatorMap, registryMap); + return exact !== "unknown" ? exact : operatorDefault !== undefined ? "operator" : registryDefault !== undefined ? "registry" : "unknown"; + }; + const configuredAdapter = provider.modelAdapters?.[input.modelId]; + const pin = pinnedWireAdapter(input.providerName, input.modelId); + const normalizedModelId = input.modelId.trim().toLowerCase(); + const registryWire = wireDefault(entry?.modelWireDefaults?.[normalizedModelId], provider, entry, + input.inboundWire ?? "responses", resolvedAuthMode); + const explicitWire = configuredAdapter && MODEL_ADAPTER_OVERRIDE_ALLOWED.has(configuredAdapter) + ? configuredAdapter + : undefined; + const providerAdapter = providerPolicy.adapter ?? provider.adapter; + const effectiveProviderForWire = resolvedAuthMode === provider.authMode + ? provider + : { ...provider, authMode: resolvedAuthMode }; + const canonicalForward = isCanonicalOpenAiForwardProvider(effectiveProviderForWire); + const adapter = pin + ?? (!canonicalForward ? explicitWire ?? registryWire : undefined) + ?? providerAdapter; + const adapterSource: StaticPolicySource = pin + ? "hard-pin" + : explicitWire && !canonicalForward + ? "operator" + : registryWire && !canonicalForward + ? "registry" + : "provider-default"; + const declaredModalities = input.modelCapabilities?.inputModalities; + const capabilityModalities = Array.isArray(declaredModalities) && declaredModalities.length > 0 + ? [...declaredModalities] + : undefined; + const exactContextWindow = modelValue(providerPolicy.modelContextWindows); + const familyContextWindow = providerPolicy.adapter === "anthropic" + ? anthropicFamilyContextWindow(providerPolicy.modelContextWindows, input.modelId) + : undefined; + const modelContextWindow = exactContextWindow ?? familyContextWindow ?? providerPolicy.contextWindow; + const exactMaxInputTokens = modelValue(providerPolicy.modelMaxInputTokens); + const modelMaxInputTokens = exactMaxInputTokens !== undefined && modelContextWindow !== undefined + ? Math.min(exactMaxInputTokens, modelContextWindow) + : exactMaxInputTokens; + const exactMaxOutputTokens = modelValue(providerPolicy.modelMaxOutputTokens); + const modelMaxOutputTokens = exactMaxOutputTokens ?? providerPolicy.defaultMaxOutputTokens; + const modelReasoningEfforts = modelValue(providerPolicy.modelReasoningEfforts) ?? providerPolicy.reasoningEfforts; + const modelSupportsReasoningSummaries = modelValue(providerPolicy.modelSupportsReasoningSummaries) + ?? (modelValue(providerPolicy.modelReasoningSummaryDelivery) !== undefined ? true : undefined); + const modelSupportsVerbosity = modelValue(providerPolicy.modelSupportsVerbosity) ?? providerPolicy.supportsVerbosity; + const modelSupportsServiceTier = modelValue(providerPolicy.modelSupportsServiceTier) ?? providerPolicy.supportsServiceTier; + const model: ResolvedPerModelStaticPolicy = { + adapter, + ...(modelContextWindow !== undefined ? { contextWindow: modelContextWindow } : {}), + ...(capabilityModalities ?? modelValue(providerPolicy.modelInputModalities) !== undefined + ? { inputModalities: capabilityModalities ?? modelValue(providerPolicy.modelInputModalities) } + : {}), + ...(modelMaxInputTokens !== undefined ? { maxInputTokens: modelMaxInputTokens } : {}), + ...(modelMaxOutputTokens !== undefined ? { maxOutputTokens: modelMaxOutputTokens } : {}), + ...(modelReasoningEfforts !== undefined ? { reasoningEfforts: modelReasoningEfforts } : {}), + ...(modelValue(providerPolicy.modelDefaultReasoningEfforts) !== undefined ? { defaultReasoningEffort: modelValue(providerPolicy.modelDefaultReasoningEfforts) } : {}), + ...(modelSupportsReasoningSummaries !== undefined ? { supportsReasoningSummaries: modelSupportsReasoningSummaries } : {}), + ...(modelSupportsVerbosity !== undefined ? { supportsVerbosity: modelSupportsVerbosity } : {}), + ...(modelSupportsServiceTier !== undefined ? { supportsServiceTier: modelSupportsServiceTier } : {}), + ...(modelSupportsServiceTier === true && entry?.fastTierDescription !== undefined + ? { fastTierDescription: entry.fastTierDescription } + : {}), + ...(entry?.directReasoningEffortModels?.includes(input.modelId) ? { directReasoningEffort: true } : {}), + ...(entry?.modelResponsesUpstreamStreaming?.[normalizedModelId] !== undefined + ? { responsesUpstreamStreaming: entry.modelResponsesUpstreamStreaming[normalizedModelId] } + : {}), + ...(entry?.modelResponsesTerminalRepair?.[normalizedModelId] !== undefined + ? { responsesTerminalRepair: entry.modelResponsesTerminalRepair[normalizedModelId] } + : {}), + }; + const modelProvenance: Partial> = { + adapter: adapterSource, + }; + modelProvenance.contextWindow = modelOrProviderSource(provider.modelContextWindows, entry?.modelContextWindows, provider.contextWindow, entry?.contextWindow); + if (modelProvenance.contextWindow === "unknown" && familyContextWindow !== undefined) { + modelProvenance.contextWindow = anthropicFamilyContextWindow(provider.modelContextWindows, input.modelId) !== undefined + ? "operator" + : "registry"; + } + modelProvenance.inputModalities = capabilityModalities + ? "operator-capability" + : modelSource(provider.modelInputModalities, entry?.modelInputModalities); + modelProvenance.maxInputTokens = modelSource(provider.modelMaxInputTokens, entry?.modelMaxInputTokens); + modelProvenance.maxOutputTokens = modelOrProviderSource( + provider.modelMaxOutputTokens, + entry?.modelMaxOutputTokens, + provider.defaultMaxOutputTokens, + entry?.defaultMaxOutputTokens, + ); + modelProvenance.reasoningEfforts = modelOrProviderSource(provider.modelReasoningEfforts, entry?.modelReasoningEfforts, provider.reasoningEfforts, entry?.reasoningEfforts); + modelProvenance.defaultReasoningEffort = modelSource( + provider.modelDefaultReasoningEfforts, + entry?.modelDefaultReasoningEfforts, + ); + modelProvenance.supportsReasoningSummaries = modelSource(provider.modelSupportsReasoningSummaries, entry?.modelSupportsReasoningSummaries); + if (modelProvenance.supportsReasoningSummaries === "unknown" && modelValue(provider.modelReasoningSummaryDelivery) !== undefined) { + modelProvenance.supportsReasoningSummaries = "operator"; + } + modelProvenance.supportsVerbosity = modelOrProviderSource(provider.modelSupportsVerbosity, entry?.modelSupportsVerbosity, provider.supportsVerbosity, entry?.supportsVerbosity); + const exactServiceTierSource = modelSource(provider.modelSupportsServiceTier, registryServiceTierDefaults); + modelProvenance.supportsServiceTier = exactServiceTierSource !== "unknown" ? exactServiceTierSource + : providerProvenance.supportsServiceTier ?? "unknown"; + modelProvenance.responsesUpstreamStreaming = model.responsesUpstreamStreaming === undefined ? "unknown" : "registry"; + modelProvenance.responsesTerminalRepair = model.responsesTerminalRepair === undefined ? "unknown" : "registry"; + modelProvenance.fastTierDescription = model.fastTierDescription === undefined ? "unknown" : "registry"; + modelProvenance.directReasoningEffort = model.directReasoningEffort === undefined ? "unknown" : "registry"; + const alias = input.effectiveAlias !== undefined + ? input.effectiveAlias + : provider.alias !== undefined + ? provider.alias + : entry?.alias; + const aliasSource: StaticPolicySource = input.effectiveAlias !== undefined + ? input.effectiveAliasSource ?? "operator" + : provider.alias !== undefined + ? "operator" + : entry?.alias !== undefined ? "registry" : "unknown"; + return recursivelyFreeze(detachedClone({ + version: 1 as const, + providerName: input.providerName, + modelId: input.modelId, + transportMatchedRegistry: entry !== undefined, + ...(alias !== undefined ? { effectiveAlias: alias } : {}), + provider: providerPolicy as ResolvedProviderStaticPolicy, + model, + provenance: { alias: aliasSource, provider: providerProvenance, model: modelProvenance }, + })); +} diff --git a/structure/catalog.md b/structure/catalog.md index 0f8b8449974..73d05b1662a 100644 --- a/structure/catalog.md +++ b/structure/catalog.md @@ -22,6 +22,23 @@ validation-pending. Import alone supplies no entitlement evidence for the model ## Shared catalog +Static policy and observed catalog evidence are separate authorities. +`src/providers/resolved-model-policy.ts` resolves and freezes only registry/operator static facts, +hard wire pins, aliases, and explicit false/empty declarations. Discovery responses, generated +metadata, cache freshness, availability, credentials, account state, quota and health never enter +that result. A catalog consumer may pass observed context, max-input, or max-output values to the +resolver's call-local limit projection; the lower observed/static value wins, and an observed value +may fill an absent static one only inside that call-local projection — the frozen static policy is +unchanged and never widened — max input never exceeds the resolved context window, and the +projection mutates neither input. P1a establishes this provider-owned contract +without changing catalog assembly; consumer migration is a separate layer. +Policy is keyed by the final upstream wire model. Public alias and virtual-model identities remain +diagnostic/catalog provenance and must be resolved before policy capture. Exact nonempty explicit +input-modality declarations outrank the registry/config modality map; an empty declaration +falls through to that map. +Anthropic numeric point releases inherit the nearest configured family context window before the +provider-wide fallback. Exact model output limits precede the provider default output limit. + `src/codex/catalog.ts` builds a shared Codex-shaped catalog for CLI, TUI, App, and SDK. It: - preserves native OpenAI entries from the live catalog or static fallback, and emits diff --git a/structure/config.md b/structure/config.md index 05ed7e7ceb6..7972ed9a21b 100644 --- a/structure/config.md +++ b/structure/config.md @@ -314,6 +314,32 @@ Both fields must stay positive finite integers at disk-config and management val Registry entries may seed them through `providerConfigSeed`, key-login derivation, OAuth reconcile, and `routeModel`, but user config overrides registry defaults per field/key. +`src/providers/resolved-model-policy.ts` is the detached static-policy authority for this merge +contract. It preserves each field's existing rule rather than assigning one global priority: +operator scalars and explicit booleans fill over registry defaults, per-model maps fill per key, +restriction lists form a stable union, and hard wire pins precede valid operator overrides and +registry wire defaults. Only the canonical `openai-apikey` provider merges +`modelContextWindows` and `modelMaxInputTokens` by taking the lower positive value; other +providers use ordinary operator-per-key fill. Its output is recursively +frozen and carries field/model provenance. It never persists resolved policy and excludes API keys, +account selection, quota, health, cooldowns, discovered availability, and request-owned evidence. +Observed context/input/output values are combined only in a call-local projection that can narrow a +captured static cap but cannot write observations into the static result. +The resolver's model id is the post-alias, post-virtual-rewrite wire identity. An exact nonempty +`modelCapabilities[model].inputModalities` declaration outranks the legacy per-model modality map; +an empty declaration is non-authoritative and falls through. OAuth/key override admission remains a +live caller decision: the resolver accepts only its credential-free effective auth mode and records +that provenance, never the key, reference, or usability evidence that produced it. +Canonical static catalogs force live discovery off, narrowly recognized generated reasoning shapes +are repaired before freezing only for a matched registry transport, and same-named custom +destinations keep their operator-owned values. Key-auth service-tier defaults apply only to a +captured key authority; exact-model provenance comes from the merged key/registry map, then falls +back to the resolved provider capability provenance. A model max-input value is bounded by its +resolved context window. +Legacy model maps resolve exact id, then the base before a colon suffix, then case-folded exact id; +the separately captured explicit capability row remains exact-only. Per-model provenance is assigned +from the key that wins that same merged lookup, not from an independent source search. + ## Provider validation ownership `src/config/provider-validation.ts` owns the pure provider payload checks shared by persisted config, diff --git a/structure/providers-and-adapters.md b/structure/providers-and-adapters.md index 6589563b616..be4787bd18b 100644 --- a/structure/providers-and-adapters.md +++ b/structure/providers-and-adapters.md @@ -9,6 +9,7 @@ the [bounded ingestion contract](transports/inventory.md#bounded-response-ingest | `src/providers/registry.ts` | Compatibility facade; canonical provider presets for CLI, dashboard, OAuth, key providers, and metadata live in `src/providers/registry/entries-core.ts` and `entries-extended.ts`, with model seeds in `model-seeds.ts`. | | `src/providers/registry/model-ids.ts` | Classifies every `ProviderRegistryEntry` field by what its KEYS mean for selector decoding, and derives the native model ids an entry names. The classification is exhaustive by construction: a new registry field fails typecheck until its keys are given a meaning, which is what stops an identity-bearing map from being silently left out of decoding. Imported directly rather than through the facade, which is at its file-size cap. | | `src/providers/derive.ts` | Enrichment from provider presets into user config. | +| `src/providers/resolved-model-policy.ts`, `src/providers/resolved-model-policy-merge.ts` | Static provider/model policy resolution for the final upstream wire model, plus its pure clone/merge/URL/family helpers. The resolver detaches and freezes registry defaults, operator overrides, exact explicit input-modality declarations, hard wire pins, aliases, and explicit false/empty values with field-level provenance. Callers supply transport match, the exact capability row, and a credential-free effective auth decision; credential bytes, usability evidence, account/quota/health state, and observed limits remain outside the result. | | `src/oauth/` | OAuth providers, token storage, refresh, and auth-token resolution. The login callback listener binds a per-provider FIXED loopback port, so consecutive logins reuse the same number; every response it sends ends its connection (`Connection: close`, including non-callback paths such as a stray `/favicon.ico` 404). Stopping the listener does not close an established socket, so without that a pooled client would deliver the next login's callback to the retired flow, which rejects the unknown state as a CSRF mismatch while the live flow waits. Kiro add-account identity prefers same-session `whoami` over a leftover SQLite state profile, and never persists the Builder ID service profile ARN as `accountId`. | | `src/combos/request.ts` | Clones each selected combo target request and applies the existing target capability ladder: adaptive unknown targets and explicit empty ladders receive no unsupported reasoning/thinking controls, while known ladders retain per-target resolution. | | `src/adapters/openai-responses.ts` | Native OpenAI/ChatGPT Responses passthrough. | diff --git a/tests/fixtures/test-layout-expected.json b/tests/fixtures/test-layout-expected.json index 4b3c59d7b42..d677aea796a 100644 --- a/tests/fixtures/test-layout-expected.json +++ b/tests/fixtures/test-layout-expected.json @@ -988,6 +988,7 @@ "relay-eager.test.ts": "server", "release-helper.test.ts": "ci-workflows", "release-notes.test.ts": "ci-workflows", + "resolved-model-policy.test.ts": "providers", "release-version-line.test.ts": "ci-workflows", "remote-catalog.test.ts": "clients", "remote-workspace-activation.test.ts": "clients", diff --git a/tests/providers/resolved-model-policy.test.ts b/tests/providers/resolved-model-policy.test.ts new file mode 100644 index 00000000000..99ecc9411bc --- /dev/null +++ b/tests/providers/resolved-model-policy.test.ts @@ -0,0 +1,799 @@ +import { describe, expect, test } from "bun:test"; +import type { OcxProviderConfig } from "../../src/types"; +import { captureWireAdapterHardPins } from "../../src/types"; +import type { ProviderRegistryEntry } from "../../src/providers/registry/types"; +import { PROVIDER_REGISTRY } from "../../src/providers/registry"; +import { effectiveProviderAliasDecision, resolveModelAlias } from "../../src/providers/default-aliases"; +import { resolveOpenAiVirtualModel } from "../../src/providers/openai-virtual-models"; +import { routedProviderConfig } from "../../src/router"; +import { resolveWireProtocolOverride } from "../../src/server/adapter-resolve"; +import { applyProviderConfigHints } from "../../src/codex/catalog/model-hints"; +import { captureFastPolicyAuthority } from "../../src/providers/service-tier"; +import { + clampObservedModelLimits, + resolveModelPolicy, +} from "../../src/providers/resolved-model-policy"; + +const MODEL = "vendor/model-a"; + +function registry(overrides: Partial = {}): ProviderRegistryEntry { + return { + id: "fixture-provider", + label: "Fixture provider", + adapter: "openai-chat", + baseUrl: "https://registry.invalid/v1", + authKind: "key", + contextWindow: 120_000, + modelContextWindows: { [MODEL]: 100_000, "registry-only": 90_000 }, + modelInputModalities: { [MODEL]: ["text", "image"] }, + modelMaxInputTokens: { [MODEL]: 80_000 }, + modelMaxOutputTokens: { [MODEL]: 16_000 }, + modelReasoningEfforts: { [MODEL]: ["low", "high"] }, + modelDefaultReasoningEfforts: { [MODEL]: "high" }, + modelSupportsReasoningSummaries: { [MODEL]: true }, + modelSupportsVerbosity: { [MODEL]: true }, + modelSupportsServiceTier: { [MODEL]: true }, + staticHeaders: { "X-Registry": "registry", "User-Agent": "registry-agent" }, + parallelToolCalls: true, + showThinkingSummary: true, + alias: "registry-alias", + ...overrides, + }; +} + +function provider(overrides: Partial = {}): OcxProviderConfig { + return { + adapter: "openai-chat", + baseUrl: "https://registry.invalid/v1", + authMode: "key", + ...overrides, + }; +} + +function resolve( + configured: OcxProviderConfig, + entry: ProviderRegistryEntry | undefined = registry(), + transportMatchedRegistry = true, +) { + return resolveModelPolicy({ + providerName: "fixture-provider", + modelId: MODEL, + provider: configured, + registryEntry: entry, + transportMatchedRegistry, + }); +} + +describe("resolved static model policy parity", () => { + test("representative registry maps stay byte-equivalent to the current route merge", () => { + const entry = PROVIDER_REGISTRY.find(candidate => { + if (candidate.allowBaseUrlOverride || /\{[^}]*\}/.test(candidate.baseUrl)) return false; + const shared = Object.keys(candidate.modelContextWindows ?? {}).find(modelId => ( + candidate.modelMaxOutputTokens?.[modelId] !== undefined + && candidate.modelReasoningEfforts?.[modelId] !== undefined + )); + return shared !== undefined; + }); + expect(entry).toBeDefined(); + const modelId = Object.keys(entry!.modelContextWindows!).find(candidate => ( + entry!.modelMaxOutputTokens?.[candidate] !== undefined + && entry!.modelReasoningEfforts?.[candidate] !== undefined + ))!; + const configured = provider({ + adapter: entry!.adapter, + baseUrl: entry!.baseUrl, + authMode: entry!.authKind, + }); + const current = routedProviderConfig(entry!.id, configured); + const policy = resolveModelPolicy({ + providerName: entry!.id, + modelId, + provider: configured, + registryEntry: entry, + transportMatchedRegistry: true, + }); + expect(JSON.stringify({ + context: policy.provider.modelContextWindows, + output: policy.provider.modelMaxOutputTokens, + efforts: policy.provider.modelReasoningEfforts, + })).toBe(JSON.stringify({ + context: current.modelContextWindows, + output: current.modelMaxOutputTokens, + efforts: current.modelReasoningEfforts, + })); + }); + + test("registry defaults match the current registry-first route projection", () => { + const policy = resolve(provider()); + expect({ + adapter: policy.provider.adapter, + baseUrl: policy.provider.baseUrl, + contextWindow: policy.model.contextWindow, + inputModalities: policy.model.inputModalities, + maxInputTokens: policy.model.maxInputTokens, + maxOutputTokens: policy.model.maxOutputTokens, + reasoningEfforts: policy.model.reasoningEfforts, + defaultReasoningEffort: policy.model.defaultReasoningEffort, + summaries: policy.model.supportsReasoningSummaries, + verbosity: policy.model.supportsVerbosity, + serviceTier: policy.model.supportsServiceTier, + alias: policy.effectiveAlias, + }).toEqual({ + adapter: "openai-chat", + baseUrl: "https://registry.invalid/v1", + contextWindow: 100_000, + inputModalities: ["text", "image"], + maxInputTokens: 80_000, + maxOutputTokens: 16_000, + reasoningEfforts: ["low", "high"], + defaultReasoningEffort: "high", + summaries: true, + verbosity: true, + serviceTier: true, + alias: "registry-alias", + }); + expect(policy.provenance.model.contextWindow).toBe("registry"); + expect(policy.provenance.alias).toBe("registry"); + }); + + test("operator values win per model while registry-only siblings survive", () => { + const configured = provider({ + modelContextWindows: { [MODEL]: 70_000, "operator-only": 60_000 }, + modelInputModalities: { [MODEL]: ["text"] }, + modelMaxInputTokens: { [MODEL]: 50_000 }, + modelMaxOutputTokens: { [MODEL]: 8_000 }, + modelReasoningEfforts: { [MODEL]: [] }, + modelDefaultReasoningEfforts: { [MODEL]: "low" }, + modelSupportsReasoningSummaries: { [MODEL]: false }, + modelSupportsVerbosity: { [MODEL]: false }, + modelSupportsServiceTier: { [MODEL]: false }, + headers: { "user-agent": "operator-agent", "X-Operator": "operator" }, + parallelToolCalls: false, + showThinkingSummary: false, + alias: "operator-alias", + }); + const policy = resolve(configured); + expect(policy.provider.modelContextWindows).toEqual({ + [MODEL]: 70_000, + "registry-only": 90_000, + "operator-only": 60_000, + }); + expect(policy.provider.headers).toEqual({ + "user-agent": "operator-agent", + "X-Operator": "operator", + "X-Registry": "registry", + }); + expect(policy.model).toMatchObject({ + contextWindow: 70_000, + inputModalities: ["text"], + maxInputTokens: 50_000, + maxOutputTokens: 8_000, + reasoningEfforts: [], + defaultReasoningEffort: "low", + supportsReasoningSummaries: false, + supportsVerbosity: false, + supportsServiceTier: false, + }); + expect(policy.provider.parallelToolCalls).toBe(false); + expect(policy.provider.showThinkingSummary).toBe(false); + expect(policy.effectiveAlias).toBe("operator-alias"); + expect(policy.provenance.model.supportsReasoningSummaries).toBe("operator"); + }); + + test("nonempty explicit capability modalities outrank the registry map", () => { + const configured = provider({ modelCapabilities: { [MODEL]: { inputModalities: ["audio"] } } }); + const policy = resolveModelPolicy({ + providerName: "fixture-provider", + modelId: MODEL, + provider: configured, + registryEntry: registry(), + transportMatchedRegistry: true, + modelCapabilities: configured.modelCapabilities![MODEL], + }); + const current = applyProviderConfigHints("fixture-provider", configured, { provider: "fixture-provider", id: MODEL }); + expect(policy.model.inputModalities).toEqual(["audio"]); + expect(policy.model.inputModalities).toEqual(current.inputModalities); + expect(policy.provenance.model.inputModalities).toBe("operator-capability"); + }); + + test("empty explicit capability modalities fall through to the registry map", () => { + const policy = resolveModelPolicy({ + providerName: "fixture-provider", + modelId: MODEL, + provider: provider(), + registryEntry: registry(), + transportMatchedRegistry: true, + modelCapabilities: { inputModalities: [] }, + }); + expect(policy.model.inputModalities).toEqual(["text", "image"]); + expect(policy.provenance.model.inputModalities).toBe("registry"); + }); + + test("absent explicit capabilities preserve the current registry-map winner", () => { + const policy = resolve(provider()); + expect(policy.model.inputModalities).toEqual(["text", "image"]); + expect(policy.provenance.model.inputModalities).toBe("registry"); + }); + + test("cleared exact capability restores colon-family legacy modalities", () => { + const modelId = "ModelA:variant"; + const configured = provider({ + modelInputModalities: { ModelA: ["audio"] }, + modelCapabilities: { [modelId]: { inputModalities: ["text", "image"] } }, + }); + const withExactCapability = resolveModelPolicy({ + providerName: "custom", + modelId, + provider: configured, + transportMatchedRegistry: false, + modelCapabilities: configured.modelCapabilities![modelId], + }); + expect(withExactCapability.model.inputModalities).toEqual(["text", "image"]); + delete configured.modelCapabilities![modelId]; + const cleared = resolveModelPolicy({ + providerName: "custom", + modelId, + provider: configured, + transportMatchedRegistry: false, + }); + expect(cleared.model.inputModalities).toEqual(["audio"]); + expect(cleared.provenance.model.inputModalities).toBe("operator"); + }); + + test("colon-family legacy modalities resolve without an exact capability declaration", () => { + const policy = resolveModelPolicy({ + providerName: "custom", + modelId: "ModelA:variant", + provider: provider({ modelInputModalities: { ModelA: ["audio"] } }), + transportMatchedRegistry: false, + }); + expect(policy.model.inputModalities).toEqual(["audio"]); + expect(policy.provenance.model.inputModalities).toBe("operator"); + }); + + test("registry exact key beats operator family with matching provenance", () => { + const modelId = "ModelA:variant"; + const entry = registry({ modelInputModalities: { [modelId]: ["text", "image"] } }); + const configured = provider({ modelInputModalities: { ModelA: ["audio"] } }); + const policy = resolveModelPolicy({ + providerName: entry.id, + modelId, + provider: configured, + registryEntry: entry, + transportMatchedRegistry: true, + }); + expect(policy.model.inputModalities).toEqual(["text", "image"]); + expect(policy.provenance.model.inputModalities).toBe("registry"); + }); + + test("captured effective auth admits a usable key override without credential material", () => { + const entry = PROVIDER_REGISTRY.find(candidate => ( + candidate.authKind === "oauth" && candidate.allowKeyAuthOverride === true + ))!; + const configured = provider({ + adapter: entry.adapter, + baseUrl: entry.baseUrl, + authMode: "key", + apiKey: "usable-private-key", + }); + const authority = routedProviderConfig(entry.id, configured); + expect(authority.authMode).toBe("key"); + const policy = resolveModelPolicy({ + providerName: entry.id, + modelId: entry.defaultModel ?? MODEL, + provider: configured, + registryEntry: entry, + transportMatchedRegistry: true, + effectiveAuth: { authMode: authority.authMode! }, + }); + expect(policy.provider.authMode).toBe(authority.authMode); + expect(policy.provenance.provider.authMode).toBe("captured-auth"); + expect(JSON.stringify(policy)).not.toContain("usable-private-key"); + }); + + test("captured unresolved key authority falls back to registry OAuth", () => { + const entry = PROVIDER_REGISTRY.find(candidate => ( + candidate.authKind === "oauth" && candidate.allowKeyAuthOverride === true + ))!; + const envName = "OCX_TEST_RESOLVED_POLICY_MISSING_KEY"; + const previous = process.env[envName]; + delete process.env[envName]; + try { + const reference = `\${${envName}}`; + const configured = provider({ + adapter: entry.adapter, + baseUrl: entry.baseUrl, + authMode: "key", + apiKey: reference, + }); + const authority = routedProviderConfig(entry.id, configured); + expect(authority.authMode).toBe("oauth"); + const policy = resolveModelPolicy({ + providerName: entry.id, + modelId: entry.defaultModel ?? MODEL, + provider: configured, + registryEntry: entry, + transportMatchedRegistry: true, + effectiveAuth: { authMode: authority.authMode! }, + }); + expect(policy.provider.authMode).toBe(authority.authMode); + expect(policy.provenance.provider.authMode).toBe("captured-auth"); + expect(JSON.stringify(policy)).not.toContain(reference); + } finally { + if (previous === undefined) delete process.env[envName]; + else process.env[envName] = previous; + } + }); + + test("a custom transport receives no registry policy", () => { + const configured = provider({ + baseUrl: "https://custom.invalid/v1", + contextWindow: 42_000, + apiKey: "private-fixture-value", + modelSupportsVerbosity: { [MODEL]: false }, + }); + const policy = resolve(configured, registry(), false); + expect(policy.transportMatchedRegistry).toBe(false); + expect(policy.provider.baseUrl).toBe("https://custom.invalid/v1"); + expect(policy.provider.contextWindow).toBe(42_000); + expect(policy.model.contextWindow).toBe(42_000); + expect(policy.model.supportsVerbosity).toBe(false); + expect(JSON.stringify(policy)).not.toContain("private-fixture-value"); + expect(policy.provenance.model.contextWindow).toBe("operator"); + }); + + test("unknown capabilities stay absent rather than becoming false or empty", () => { + const policy = resolveModelPolicy({ + providerName: "custom", + modelId: "unknown-model", + provider: provider({ baseUrl: "https://custom.invalid/v1" }), + transportMatchedRegistry: false, + }); + expect(policy.model).toEqual({ adapter: "openai-chat" }); + expect(policy.model.contextWindow).toBeUndefined(); + expect(policy.model.reasoningEfforts).toBeUndefined(); + expect(policy.model.supportsReasoningSummaries).toBeUndefined(); + expect(policy.provenance.model.contextWindow).toBe("unknown"); + }); + + test("discovered limits remain call-local and are clamped by frozen static caps", () => { + const configured = provider({ + modelContextWindows: { [MODEL]: 70_000 }, + modelMaxInputTokens: { [MODEL]: 50_000 }, + modelMaxOutputTokens: { [MODEL]: 8_000 }, + }); + const policy = resolve(configured); + const widened = clampObservedModelLimits(policy.model, { + contextWindow: 90_000, + maxInputTokens: 60_000, + maxOutputTokens: 12_000, + }); + const narrowed = clampObservedModelLimits(policy.model, { + contextWindow: 40_000, + maxInputTokens: 30_000, + maxOutputTokens: 4_000, + }); + expect(widened).toEqual({ contextWindow: 70_000, maxInputTokens: 50_000, maxOutputTokens: 8_000 }); + expect(narrowed).toEqual({ contextWindow: 40_000, maxInputTokens: 30_000, maxOutputTokens: 4_000 }); + const current = applyProviderConfigHints("fixture-provider", configured, { + provider: "fixture-provider", + id: MODEL, + contextWindow: 90_000, + maxInputTokens: 60_000, + maxOutputTokens: 12_000, + }); + expect(widened).toEqual({ + contextWindow: current.contextWindow, + maxInputTokens: current.maxInputTokens, + maxOutputTokens: current.maxOutputTokens, + }); + expect(policy.model).toMatchObject({ contextWindow: 70_000, maxInputTokens: 50_000, maxOutputTokens: 8_000 }); + // The frozen policy legitimately retains the registry map's "registry-only": 90_000 entry, + // so a blanket substring ban cannot prove the observed clamp stayed out. Prove non-mutation + // instead: deep-frozen snapshot equality across both clamp calls, exact model caps, the + // registry-only entry retained, and no observed fields on the model projection. + const beforeSnapshot = JSON.stringify(policy); + clampObservedModelLimits(policy.model, { contextWindow: 90_000, maxInputTokens: 60_000, maxOutputTokens: 12_000 }); + clampObservedModelLimits(policy.model, { contextWindow: 40_000, maxInputTokens: 30_000, maxOutputTokens: 4_000 }); + expect(JSON.stringify(policy)).toBe(beforeSnapshot); + expect(policy.provider.modelContextWindows?.["registry-only"]).toBe(90_000); + expect(policy.model).not.toHaveProperty("observedContextWindow"); + }); + + test("hard pins outrank explicit model adapters and registry wire defaults", () => { + const modelId = Object.keys(captureWireAdapterHardPins("opencode-go"))[0]!; + const entry = registry({ + id: "opencode-go", + modelWireDefaults: { [modelId]: "openai-responses" }, + }); + const policy = resolveModelPolicy({ + providerName: "opencode-go", + modelId, + provider: provider({ modelAdapters: { [modelId]: "openai-chat" } }), + registryEntry: entry, + transportMatchedRegistry: true, + }); + expect(policy.model.adapter).toBe("anthropic"); + expect(policy.provenance.model.adapter).toBe("hard-pin"); + expect(policy.model.adapter).toBe(resolveWireProtocolOverride( + "opencode-go", + modelId, + provider({ modelAdapters: { [modelId]: "openai-chat" } }), + ).adapter); + }); + + test("explicit wire override beats a registry default and an explicit provider adapter opts out", () => { + const entry = registry({ modelWireDefaults: { [MODEL]: "openai-responses" } }); + const explicit = resolve(provider({ modelAdapters: { [MODEL]: "openai-responses" } }), entry); + const optOut = resolve(provider({ modelAdapters: { [MODEL]: "openai-chat" } }), entry); + expect(explicit.model.adapter).toBe("openai-responses"); + expect(explicit.provenance.model.adapter).toBe("operator"); + expect(optOut.model.adapter).toBe("openai-chat"); + expect(optOut.provenance.model.adapter).toBe("operator"); + }); + + test("captured alias decisions preserve explicit null and registry provenance", () => { + const disabled = resolveModelPolicy({ + providerName: "fixture-provider", + modelId: MODEL, + provider: provider(), + registryEntry: registry(), + transportMatchedRegistry: true, + effectiveAlias: null, + effectiveAliasSource: "operator", + }); + const capturedRegistry = resolveModelPolicy({ + providerName: "fixture-provider", + modelId: MODEL, + provider: provider(), + registryEntry: registry(), + transportMatchedRegistry: true, + effectiveAlias: "registry-alias", + effectiveAliasSource: "registry", + }); + expect(disabled.effectiveAlias).toBeNull(); + expect(disabled.provenance.alias).toBe("operator"); + expect(capturedRegistry.effectiveAlias).toBe("registry-alias"); + expect(capturedRegistry.provenance.alias).toBe("registry"); + }); + + test("captured registry alias matches the current collision-aware decision", () => { + const entry = PROVIDER_REGISTRY.find(candidate => candidate.alias !== undefined)!; + const configured = provider({ adapter: entry.adapter, baseUrl: entry.baseUrl, authMode: entry.authKind }); + const config = { providers: { [entry.id]: configured } }; + const current = effectiveProviderAliasDecision(entry.id, configured, config); + const policy = resolveModelPolicy({ + providerName: entry.id, + modelId: entry.defaultModel ?? "fixture-model", + provider: configured, + registryEntry: entry, + transportMatchedRegistry: true, + effectiveAlias: current, + effectiveAliasSource: "registry", + }); + expect(policy.effectiveAlias).toBe(current); + expect(policy.provenance.alias).toBe("registry"); + }); + + test("model alias policy resolves against the post-alias native identity", () => { + const configured = provider({ modelAliases: { [MODEL]: "short-selector" } }); + const resolved = resolveModelAlias({ defaultModelAliases: false }, configured, [MODEL], "short-selector"); + expect(resolved).toBe(MODEL); + const policy = resolveModelPolicy({ + providerName: "fixture-provider", + modelId: resolved!, + provider: configured, + registryEntry: registry(), + transportMatchedRegistry: true, + }); + expect(policy.modelId).toBe(MODEL); + expect(policy.model.contextWindow).toBe(100_000); + }); + + test("virtual model policy resolves against the post-rewrite wire identity", () => { + const entry = PROVIDER_REGISTRY.find(candidate => candidate.virtualModels !== undefined)!; + const selectedModelId = Object.keys(entry.virtualModels!)[0]!; + const resolution = resolveOpenAiVirtualModel(entry.id, selectedModelId)!; + const configured = provider({ adapter: entry.adapter, baseUrl: entry.baseUrl, authMode: entry.authKind }); + const policy = resolveModelPolicy({ + providerName: entry.id, + modelId: resolution.wireModelId, + provider: configured, + registryEntry: entry, + transportMatchedRegistry: true, + }); + expect(policy.modelId).toBe(resolution.wireModelId); + expect(policy.modelId).not.toBe(resolution.selectedModelId); + }); + + test("repeat resolution is deeply equal, frozen, and detached", () => { + const configured = provider({ modelInputModalities: { [MODEL]: ["text"] } }); + const entry = registry(); + const input = { + providerName: "fixture-provider", + modelId: MODEL, + provider: configured, + registryEntry: entry, + transportMatchedRegistry: true, + } as const; + const first = resolveModelPolicy(input); + const second = resolveModelPolicy(input); + expect(first).toEqual(second); + expect(first).not.toBe(second); + expect(first.provider).not.toBe(second.provider); + expect(first.model).not.toBe(second.model); + expect(first.model.inputModalities).not.toBe(second.model.inputModalities); + expect(Object.isFrozen(first)).toBe(true); + expect(Object.isFrozen(second)).toBe(true); + }); + + test("stale direct-effort budget classification matches current route repair", () => { + const entry = PROVIDER_REGISTRY.find(candidate => candidate.id === "alibaba-token-plan")!; + const directModel = entry.directReasoningEffortModels![0]!; + const configured = provider({ + adapter: entry.adapter, + baseUrl: entry.baseUrl, + authMode: entry.authKind, + thinkingBudgetModels: [directModel, ...(entry.thinkingBudgetModels ?? [])], + }); + const current = routedProviderConfig(entry.id, configured); + const policy = resolveModelPolicy({ + providerName: entry.id, modelId: directModel, provider: configured, + registryEntry: entry, transportMatchedRegistry: true, + }); + expect(policy.provider.thinkingBudgetModels).toEqual(current.thinkingBudgetModels); + expect(policy.provider.modelReasoningEfforts?.[directModel]).toEqual(current.modelReasoningEfforts?.[directModel]); + expect(policy.provider.modelDefaultReasoningEfforts?.[directModel]).toEqual(current.modelDefaultReasoningEfforts?.[directModel]); + expect(policy.provider.modelReasoningEffortMap?.[directModel]).toEqual(current.modelReasoningEffortMap?.[directModel]); + }); + + test.each(["cline-pass", "mimo-free"])("%s stale live discovery matches static route authority", id => { + const entry = PROVIDER_REGISTRY.find(candidate => candidate.id === id)!; + const configured = provider({ adapter: entry.adapter, baseUrl: entry.baseUrl, authMode: entry.authKind, liveModels: true }); + const current = routedProviderConfig(id, configured); + const policy = resolveModelPolicy({ + providerName: id, modelId: entry.defaultModel ?? MODEL, provider: configured, + registryEntry: entry, transportMatchedRegistry: true, + effectiveAuth: { authMode: current.authMode! }, + }); + expect(policy.provider.liveModels).toBe(current.liveModels); + expect(policy.provider.liveModels).toBe(false); + }); + + test("historical ClinePass ladder matches current route repair", () => { + const entry = PROVIDER_REGISTRY.find(candidate => candidate.id === "cline-pass")!; + const configured = provider({ + adapter: entry.adapter, baseUrl: entry.baseUrl, authMode: entry.authKind, + reasoningWireFormat: "gateway-object", reasoningEfforts: ["low"], + }); + const current = routedProviderConfig(entry.id, configured); + const policy = resolveModelPolicy({ + providerName: entry.id, modelId: entry.defaultModel!, provider: configured, + registryEntry: entry, transportMatchedRegistry: true, + }); + expect(policy.provider.reasoningEfforts).toEqual(current.reasoningEfforts); + }); + + test("custom ClinePass destination keeps an intentional low-only gateway ladder", () => { + const entry = PROVIDER_REGISTRY.find(candidate => candidate.id === "cline-pass")!; + const configured = provider({ + adapter: entry.adapter, + baseUrl: "https://custom-cline-pass.invalid/v1", + authMode: entry.authKind, + reasoningWireFormat: "gateway-object", + reasoningEfforts: ["low"], + }); + const current = routedProviderConfig(entry.id, configured); + const policy = resolveModelPolicy({ + providerName: entry.id, + modelId: entry.defaultModel!, + provider: configured, + registryEntry: entry, + transportMatchedRegistry: false, + }); + expect(policy.provider.reasoningEfforts).toEqual(current.reasoningEfforts); + expect(policy.provider.reasoningEfforts).toEqual(["low"]); + expect(policy.provenance.provider.reasoningEfforts).toBe("operator"); + }); + + test("Anthropic numeric-family context matches current catalog fallback", () => { + const entry = PROVIDER_REGISTRY.find(candidate => ( + candidate.adapter === "anthropic" && Object.keys(candidate.modelContextWindows ?? {}).length > 0 + ))!; + const family = Object.keys(entry.modelContextWindows!)[0]!; + const pointRelease = `${family}-20260919`; + const configured = provider({ + adapter: entry.adapter, baseUrl: entry.baseUrl, authMode: entry.authKind, + modelContextWindows: { ...entry.modelContextWindows }, + }); + const current = applyProviderConfigHints(entry.id, configured, { provider: entry.id, id: pointRelease }); + const policy = resolveModelPolicy({ + providerName: entry.id, modelId: pointRelease, provider: configured, + registryEntry: entry, transportMatchedRegistry: true, + }); + expect(policy.model.contextWindow).toBe(current.contextWindow); + }); + + test("resolved max input never exceeds the resolved context", () => { + const configured = provider({ modelContextWindows: { [MODEL]: 70_000 }, modelMaxInputTokens: { [MODEL]: 90_000 } }); + const policy = resolveModelPolicy({ + providerName: "custom", modelId: MODEL, + provider: configured, + transportMatchedRegistry: false, + }); + const current = applyProviderConfigHints("custom", configured, { provider: "custom", id: MODEL }); + expect(policy.model.maxInputTokens).toBe(current.maxInputTokens); + expect(policy.model).toMatchObject({ contextWindow: 70_000, maxInputTokens: 70_000 }); + expect(clampObservedModelLimits(policy.model, { maxInputTokens: 80_000 })) + .toMatchObject({ contextWindow: 70_000, maxInputTokens: 70_000 }); + }); + + test("override URL rejection and template fallback match current routing", () => { + const entry = PROVIDER_REGISTRY.find(candidate => candidate.allowBaseUrlOverride === true)!; + const configured = provider({ adapter: entry.adapter, baseUrl: "{unresolved}", authMode: entry.authKind }); + expect(() => routedProviderConfig(entry.id, configured)).toThrow(/Invalid baseUrl/); + expect(() => resolveModelPolicy({ + providerName: entry.id, modelId: entry.defaultModel ?? MODEL, provider: configured, + registryEntry: entry, transportMatchedRegistry: true, + })).toThrow(/Invalid baseUrl/); + const template = registry({ baseUrl: "https://{region}.invalid/v1", allowBaseUrlOverride: false }); + const fallback = resolveModelPolicy({ + providerName: template.id, modelId: MODEL, + provider: provider({ baseUrl: "{unresolved}" }), registryEntry: template, transportMatchedRegistry: true, + }); + expect(fallback.provider.baseUrl).toBe(template.baseUrl); + expect(fallback.provenance.provider.baseUrl).toBe("registry"); + }); + + test("absent override URL matches current Invalid baseUrl oracle while templates fall back", () => { + const entry = PROVIDER_REGISTRY.find(candidate => candidate.allowBaseUrlOverride === true)!; + const absent = { adapter: entry.adapter, authMode: entry.authKind } as OcxProviderConfig; + expect(() => routedProviderConfig(entry.id, absent)) + .toThrow(`Invalid baseUrl for provider "${entry.id}": expected a nonblank URL without unresolved placeholders`); + expect(() => resolveModelPolicy({ + providerName: entry.id, + modelId: entry.defaultModel ?? MODEL, + provider: absent, + registryEntry: entry, + transportMatchedRegistry: true, + })).toThrow(`Invalid baseUrl for provider "${entry.id}": expected a nonblank URL without unresolved placeholders`); + const template = registry({ baseUrl: "https://{region}.invalid/v1", allowBaseUrlOverride: false }); + const templateAbsent = { adapter: template.adapter, authMode: template.authKind } as OcxProviderConfig; + const fallback = resolveModelPolicy({ + providerName: template.id, + modelId: MODEL, + provider: templateAbsent, + registryEntry: template, + transportMatchedRegistry: true, + }); + expect(fallback.provider.baseUrl).toBe(template.baseUrl); + expect(fallback.provenance.provider.baseUrl).toBe("registry"); + }); + + test("captured key-auth service-tier overlay matches current authority and preserves false", () => { + const entry = PROVIDER_REGISTRY.find(candidate => candidate.keyAuthServiceTier !== undefined)!; + const modelId = Object.keys(entry.keyAuthServiceTier?.modelSupportsServiceTier ?? entry.modelSupportsServiceTier ?? {})[0] ?? MODEL; + const keyConfigured = provider({ adapter: entry.adapter, baseUrl: entry.baseUrl, authMode: "key" }); + const keyAuthority = captureFastPolicyAuthority(entry.id, keyConfigured, true); + const keyPolicy = resolveModelPolicy({ + providerName: entry.id, modelId, provider: keyConfigured, + registryEntry: entry, transportMatchedRegistry: true, effectiveAuth: { authMode: "key" }, + }); + const oauthPolicy = resolveModelPolicy({ + providerName: entry.id, modelId, + provider: provider({ adapter: entry.adapter, baseUrl: entry.baseUrl, authMode: "oauth" }), + registryEntry: entry, transportMatchedRegistry: true, effectiveAuth: { authMode: "oauth" }, + }); + expect(keyPolicy.provider.supportsServiceTier).toBe(keyAuthority.capability.provider); + expect(keyPolicy.provider.supportsServiceTier).not.toBe(oauthPolicy.provider.supportsServiceTier); + const configured = provider({ + adapter: entry.adapter, baseUrl: entry.baseUrl, authMode: "key", + supportsServiceTier: false, chatServiceTier: false, + modelSupportsServiceTier: { [modelId]: false }, + }); + const authority = captureFastPolicyAuthority(entry.id, configured, true); + const policy = resolveModelPolicy({ + providerName: entry.id, modelId, provider: configured, + registryEntry: entry, transportMatchedRegistry: true, effectiveAuth: { authMode: "key" }, + }); + expect(policy.provider.supportsServiceTier).toBe(authority.capability.provider); + expect(policy.provider.chatServiceTier).toBe(authority.capability.chatServiceTier); + expect(policy.model.supportsServiceTier).toBe(authority.capability.models[modelId]); + expect(policy.model.supportsServiceTier).toBe(false); + }); + + test("unlisted key-auth model inherits provider service tier with registry provenance", () => { + const entry = PROVIDER_REGISTRY.find(candidate => candidate.id === "xai")!; + const modelId = "grok-4.20-multi-agent-0309"; + expect(entry.modelSupportsServiceTier?.[modelId]).toBeUndefined(); + const configured = provider({ adapter: entry.adapter, baseUrl: entry.baseUrl, authMode: "key" }); + const authority = captureFastPolicyAuthority(entry.id, configured, true); + const policy = resolveModelPolicy({ + providerName: entry.id, + modelId, + provider: configured, + registryEntry: entry, + transportMatchedRegistry: true, + effectiveAuth: { authMode: "key" }, + }); + expect(policy.model.supportsServiceTier).toBe(authority.capability.provider); + expect(policy.model.supportsServiceTier).toBe(true); + expect(policy.provenance.model.supportsServiceTier).toBe("registry"); + }); + + test("provider default output fallback and provenance match current route", () => { + const entry = PROVIDER_REGISTRY.find(candidate => candidate.defaultMaxOutputTokens !== undefined)!; + const configured = provider({ adapter: entry.adapter, baseUrl: entry.baseUrl, authMode: entry.authKind }); + const current = routedProviderConfig(entry.id, configured); + const policy = resolveModelPolicy({ + providerName: entry.id, modelId: entry.defaultModel ?? MODEL, provider: configured, + registryEntry: entry, transportMatchedRegistry: true, + }); + expect(policy.model.maxOutputTokens).toBe(current.defaultMaxOutputTokens); + expect(policy.provenance.model.maxOutputTokens).toBe("registry"); + }); + + test("lower-cap merge is scoped to the canonical API-key provider", () => { + const apiEntry = PROVIDER_REGISTRY.find(candidate => candidate.id === "openai-apikey")!; + const apiModel = Object.keys(apiEntry.modelMaxInputTokens ?? {})[0]!; + const apiConfigured = provider({ + adapter: apiEntry.adapter, baseUrl: apiEntry.baseUrl, authMode: apiEntry.authKind, + modelContextWindows: { [apiModel]: apiEntry.modelContextWindows![apiModel]! + 1_000 }, + modelMaxInputTokens: { [apiModel]: apiEntry.modelMaxInputTokens![apiModel]! + 1_000 }, + }); + const apiCurrent = routedProviderConfig(apiEntry.id, apiConfigured); + const api = resolveModelPolicy({ + providerName: apiEntry.id, modelId: apiModel, provider: apiConfigured, + registryEntry: apiEntry, transportMatchedRegistry: true, + }); + expect(api.model.contextWindow).toBe(apiCurrent.modelContextWindows?.[apiModel]); + expect(api.model.maxInputTokens).toBe(apiCurrent.modelMaxInputTokens?.[apiModel]); + const entry = PROVIDER_REGISTRY.find(candidate => ( + candidate.id !== "openai-apikey" && Object.keys(candidate.modelContextWindows ?? {}).length > 0 + ))!; + const modelId = Object.keys(entry.modelContextWindows!)[0]!; + const configured = provider({ + adapter: entry.adapter, baseUrl: entry.baseUrl, authMode: entry.authKind, + modelContextWindows: { [modelId]: entry.modelContextWindows![modelId]! + 1_000 }, + }); + const ordinaryCurrent = routedProviderConfig(entry.id, configured); + const ordinary = resolveModelPolicy({ + providerName: entry.id, modelId, provider: configured, + registryEntry: entry, transportMatchedRegistry: true, + }); + expect(ordinary.model.contextWindow).toBe(ordinaryCurrent.modelContextWindows?.[modelId]); + }); + + test("selected base URL carries operator provenance", () => { + const entry = PROVIDER_REGISTRY.find(candidate => candidate.allowBaseUrlOverride === true)!; + const configured = provider({ + adapter: entry.adapter, baseUrl: "https://operator.invalid/v1", authMode: entry.authKind, + }); + const current = routedProviderConfig(entry.id, configured); + const policy = resolveModelPolicy({ + providerName: entry.id, modelId: MODEL, provider: configured, + registryEntry: entry, transportMatchedRegistry: true, + }); + expect(policy.provider.baseUrl).toBe(current.baseUrl); + expect(policy.provenance.provider.baseUrl).toBe("operator"); + }); + + test("result is detached, recursively frozen, and excludes mutable request evidence", () => { + const configured = provider({ + apiKey: "secret-value", + _apiKeyAttempt: { entryId: "account-like-private-id" }, + modelInputModalities: { [MODEL]: ["text"] }, + }); + const entry = registry(); + const policy = resolve(configured, entry); + configured.modelInputModalities![MODEL]!.push("audio"); + entry.modelContextWindows![MODEL] = 1; + expect(policy.model.inputModalities).toEqual(["text"]); + expect(policy.model.contextWindow).toBe(100_000); + expect(Object.isFrozen(policy)).toBe(true); + expect(Object.isFrozen(policy.provider)).toBe(true); + expect(Object.isFrozen(policy.model.inputModalities)).toBe(true); + expect(JSON.stringify(policy)).not.toContain("secret-value"); + expect(JSON.stringify(policy)).not.toContain("account-like-private-id"); + }); +}); From 4823bbb5fe1eb478be9ae614fdd10f9c0842c332 Mon Sep 17 00:00:00 2001 From: Epinephrine Date: Sun, 20 Sep 2026 02:26:19 +0900 Subject: [PATCH 52/97] fix(ci): preserve punctuation-bearing emails when defusing mentions (#5172) Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com> --- .github/scripts/issue-translation.cjs | 10 ++++++++++ .github/scripts/issue-translation.test.cjs | 14 ++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/.github/scripts/issue-translation.cjs b/.github/scripts/issue-translation.cjs index 242e63bba2e..41638a9d993 100644 --- a/.github/scripts/issue-translation.cjs +++ b/.github/scripts/issue-translation.cjs @@ -805,12 +805,22 @@ function sanitizeTranslationBody(raw, maxChars = 60000) { .split(MARKER).join("") .split(END_MARKER).join("") .replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/g, "") + // Mask the @ inside email addresses first: punctuation-bearing local + // parts (x!@example.com, a=b@example.com, a/b@example.com) must not be + // read as mention boundaries. Requiring a dotted domain keeps + // "end!@octocat"-style mentions defused. \u0001 cannot appear in the + // input (control chars were stripped above), so it is a safe sentinel. + .replace( + /[A-Za-z0-9.!#$%&'*+\/=?^_`{|}~-]+@[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+/g, + (email) => email.replace("@", "\u0001"), + ) // Defuse pings at Markdown/punctuation boundaries — a colon is a boundary // too — but not emails, npm: scopes, or other mid-token at-signs. .replace( /(^|[^A-Za-z0-9._%+-])(? { assert.ok(out.includes("npm:@scope")); }); + it("preserves punctuation-bearing email local parts while defusing mentions", () => { + const out = sanitizeTranslationBody( + "mail x!@example.com, a=b@example.com, or a/b@example.com; end!@octocat key=@value path/@handle user.name@example.com user+tag@example.com", + ); + assert.ok(out.includes("x!@example.com")); + assert.ok(out.includes("a=b@example.com")); + assert.ok(out.includes("a/b@example.com")); + assert.ok(out.includes("user.name@example.com")); + assert.ok(out.includes("user+tag@example.com")); + assert.match(out, /end!@\u200boctocat/); + assert.match(out, /key=@\u200bvalue/); + assert.match(out, /path\/@\u200bhandle/); + }); + it("ignores forged body-embedded legacy state", () => { const forged = appendTranslationBlock(SOURCE, "English") + `\nGd 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%0A5_~FND*U6dB5G=fHLa$J6@&x@>&hiU*CIqTz7HI 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%0AV}Ygp)NY&gM|Qx(1adCKa>Rw-dyzG>`A{mc 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ξC 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 literal 0 HcmV?d00001 diff --git a/.github/pr-assets/5197-apply-narrow.png b/.github/pr-assets/5197-apply-narrow.png new file mode 100644 index 0000000000000000000000000000000000000000..4538af09a0d69969eb4a63a0e4057d32d5991ae8 GIT binary patch literal 174199 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

    m7x{|`{Pg@npMbZtVaKHzrEDc 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�z9JxeqtT2XRfW@fZVF0cVv@S_k5k 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 MB`w8D1*^CJ1DpxnDgXcg literal 0 HcmV?d00001 diff --git a/.github/pr-assets/5197-capture-receipt.json b/.github/pr-assets/5197-capture-receipt.json new file mode 100644 index 00000000000..89b06a80b15 --- /dev/null +++ b/.github/pr-assets/5197-capture-receipt.json @@ -0,0 +1,180 @@ +{ + "status": "HISTORICAL/CORRECTED-GUI-TREE", + "proofType": "fixture-rendered GUI proof from a hosted PR merge-ref build associated with the source head and GUI-tree-equivalent to the reviewed GUI; not a live backend or a literal PR-head build", + "sourceArtifact": { + "name": "PR #5197 hosted merge-ref GUI build associated with source head 07bf0a4dbe", + "artifactId": 10595174777, + "artifactName": "dashboard-preview-6c9576edb372200efec9d6ad4fea7b1e0dc35fb4", + "workflowRun": 35481230775, + "workflowAttempt": 1, + "workflowConclusion": "success", + "entrypoint": "index.html", + "javascript": "assets/index-CKL6ayU1.js", + "stylesheet": "assets/index-BTuCbqQd.css", + "buildCommit": "6c9576edb372200efec9d6ad4fea7b1e0dc35fb4", + "prHead": "07bf0a4dbe369f204c2216f5e8c07c87f52d649c", + "guiTree": "06c1f0c620cbfca2a557813f7ec54b7c11cbb540" + }, + "commands": { + "fixtureServer": "cd && python3 fixture_server.py", + "asideReplTemplate": "/usr/bin/perl -e 'alarm shift; exec @ARGV' 120 aside repl \"\"", + "desktopWindow": "Aside window {1446,762} -> CSS viewport 1280x720", + "narrowWindow": "Aside window {646,842} -> CSS viewport 480x800", + "ko390Window": "Aside native page zoom 125 percent plus window {654,900} -> observed CSS viewport 390x686" + }, + "reproduction": { + "baseUrl": "http://127.0.0.1:18799/", + "harnessScript": "fixture_server.py (scratch-only capture harness; not tracked)", + "driver": "Aside CLI repl opened the base URL in the real browser, selected fixture modes through POST /__fixture/mode, drove the dashboard controls, read back assertions, and captured each frame at the recorded CSS viewport and DPR." + }, + "fixtureRoutes": [ + "GET / and static assets", + "GET /healthz", + "GET /api/startup-health", + "GET /api/client-integrations", + "GET /api/client-integrations/opencode", + "GET /api/client-integrations/journal?client=opencode", + "POST /api/client-integrations/preview", + "PUT /api/client-integrations/opencode", + "POST /api/client-integrations/restore/preview", + "POST /api/client-integrations/restore", + "GET /api/client-integrations/aside/profiles", + "GET /api/client-integrations/aside/profiles/7", + "GET /api/client-integrations/aside/profiles/7/journal", + "POST /api/client-integrations/aside/profiles/7/preview", + "PUT /api/client-integrations/aside/profiles/7", + "POST /__fixture/mode", + "GET /__fixture/state" + ], + "requestSequences": { + "apply": [ + "POST /__fixture/mode {mode:apply}", + "GET /api/client-integrations/opencode", + "GET /api/client-integrations/journal?client=opencode", + "POST /api/client-integrations/preview {clientId:opencode,operation:apply}" + ], + "foreignOverwrite": [ + "POST /__fixture/mode {mode:overwrite}", + "GET /api/client-integrations/opencode -> conflict, reason foreign-edit", + "GET /api/client-integrations/journal?client=opencode", + "POST /api/client-integrations/preview {clientId:opencode,operation:overwrite}" + ], + "restoreDrift": [ + "POST /__fixture/mode {mode:restore}", + "GET /api/client-integrations/opencode", + "GET /api/client-integrations/journal?client=opencode -> op-restore-001", + "POST /api/client-integrations/restore/preview {opId:op-restore-001,confirmDrift:false}" + ], + "stale409Reconfirmation": [ + "POST /__fixture/mode {mode:stale}", + "GET state and journal", + "POST /api/client-integrations/preview -> initial p1:dddd... plan", + "PUT /api/client-integrations/opencode with initial binding -> 409 integration_preview_stale plus p1:eeee... fresh plan", + "GET state and journal reconciliation", + "capture before reconfirming" + ], + "koRestoreDrift390": ["select Korean in dashboard", "run restoreDrift", "capture at observed innerWidth 390"], + "koStaleReconfirm390": ["keep Korean selected", "run stale409Reconfirmation", "capture before reconfirming at innerWidth 390"], + "koProfileDisableNoop390": [ + "POST /__fixture/mode {mode:profile-noop}", + "GET /api/client-integrations/aside/profiles -> profile 7 enabled=true,state=absent", + "POST /api/client-integrations/aside/profiles/7/preview {operation:disable} -> willChange=false,changes=[],profileId=7", + "assert document no-op copy and sync-preference disclosure", + "assert primary Disable button enabled", + "assert consequence body contains neither Korean backup nor rollback text", + "capture", + "PUT /api/client-integrations/aside/profiles/7 {enabled:false,operation:disable,planFingerprint:p1:ffffffffffffffffffffffffffffffff}", + "GET /__fixture/state verifies recorded binding" + ], + "keyboardFocus": [ + "open apply dialog", + "press Tab twice to focus primary Apply", + "capture visible focus ring", + "assert dialog count 1 before Escape", + "press Escape and assert dialog count 0" + ] + }, + "captureBinding": { + "prHead": "07bf0a4dbe369f204c2216f5e8c07c87f52d649c", + "hostedBuildCommit": "6c9576edb372200efec9d6ad4fea7b1e0dc35fb4", + "sourceGuiTree": "06c1f0c620cbfca2a557813f7ec54b7c11cbb540", + "hostedBuildGuiTree": "06c1f0c620cbfca2a557813f7ec54b7c11cbb540", + "guiTreeEqual": true + }, + "interactionObservations": { + "keyboardFocusVisible": true, + "dialogCountBeforeEscape": 1, + "dialogCountAfterEscape": 0 + }, + "profileNoopVerification": { + "previewDto": { + "version": 1, + "clientId": "aside", + "operation": "disable", + "state": "absent", + "foreignEdit": "none", + "changes": [], + "fingerprint": "p1:ffffffffffffffffffffffffffffffff", + "canApply": true, + "willChange": false, + "profileId": 7 + }, + "assertions": { + "documentScopedNoopCopyVisible": true, + "syncPreferenceDisclosureVisible": true, + "primaryButtonEnabled": true, + "backupPromiseAbsent": true, + "rollbackPromiseAbsent": true + }, + "recordedBinding": { + "enabled": false, + "operation": "disable", + "planFingerprint": "p1:ffffffffffffffffffffffffffffffff" + } + }, + "viewports": [ + { + "name": "desktop", + "cssWidth": 1280, + "cssHeight": 720, + "devicePixelRatio": 2, + "pngWidth": 2560, + "pngHeight": 1440, + "files": ["apply-desktop.png","overwrite-foreign-desktop.png","restore-drift-desktop.png","stale-reconfirm-desktop.png","keyboard-focus.png"] + }, + { + "name": "narrow", + "cssWidth": 480, + "cssHeight": 800, + "devicePixelRatio": 2, + "pngWidth": 960, + "pngHeight": 1600, + "files": ["apply-narrow.png","overwrite-foreign-narrow.png","restore-drift-narrow.png","stale-reconfirm-narrow.png"] + }, + { + "name": "ko-390", + "cssWidth": 390, + "cssHeight": 686, + "devicePixelRatio": 2.5, + "browserZoomPercent": 125, + "pngWidth": 976, + "pngHeight": 1716, + "dimensionNote": "Observed CSS viewport and DPR imply a nominal 975x1715 raster; the actual PNG is 976x1716, one physical pixel per axis larger. The capture did not independently isolate the cause of that rounding difference.", + "files": ["ko-restore-drift-390.png","ko-stale-reconfirm-390.png","ko-profile-disable-noop-390.png"] + } + ], + "pngSha256": { + "apply-desktop.png": "4427b60e8885c68e2478c319e4ef428d959b4cc13ee5141a64a92777550ab420", + "apply-narrow.png": "0e2dfd18e76c26755c7b347e149de29dab2b4a40d2074e2ad293d93ced2e34e3", + "keyboard-focus.png": "29714ff85f13b35cc72fffc1a36b6d07ee820be1f9824c9f56a317f15c38feb1", + "ko-profile-disable-noop-390.png": "09baf33f610dccff7d26b77717682f046da821cb2ff8276325be829882f20648", + "ko-restore-drift-390.png": "7c51f352c24defd7cc0c669e53fd254ae314f79faf6cc48a65b9dd2589fe46de", + "ko-stale-reconfirm-390.png": "9dc051b7e97a19fd3dff66958fde432d35f94473ddc403424af13fcdc5ec5254", + "overwrite-foreign-desktop.png": "0e6d14543dfe4ff5847aa3d66d26c499f32235c02a6d741f32a528b1af12f986", + "overwrite-foreign-narrow.png": "8c9af82bc4cfe79e6400c10fb553378524c3f49074145a0cf845db52c3691b63", + "restore-drift-desktop.png": "42127e71f1f13a4902b31e59861de518dc339028a3b3cdbe130f259f0a78f5fb", + "restore-drift-narrow.png": "e7482dfe56b92350641b8a3b13ab3da79e7c8130db74a5cb5208a79e0ee9b2f9", + "stale-reconfirm-desktop.png": "307444c11e8369593b1a023fbeb2ee1ad63bf8deaa7c8bc6dfb9aa7728e6c6c1", + "stale-reconfirm-narrow.png": "8938274b183b888eaf8159bd6083ced670ac2070ef1a5cbdd6424475f4cc1b77" + } +} diff --git a/.github/pr-assets/5197-keyboard-focus.png b/.github/pr-assets/5197-keyboard-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..98c77eba848de3fa279fc6e77212f4c6e8401704 GIT binary patch literal 291707 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

    lFO-h!7Sp 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%0DK`SAMaGKPGszNqb%WhTPcJF= z*!bYb!II`H&HUEgzqLzVjir8B@PZd(-k`eP8F?gLI*AnG%FJ0O0Fl?nN)oTaERw-4`(Gz9_U1>?H6l{h7yc6;0iN@Q>t>y6W7c(1`q zfYse|teD}sHp&EDXn&Ci1-b&PmC4b^-&TqO$PjfdNvomE%h%IX(#?fR%qvF`m#-33 zvy~*HFqEIg?k}wc>^KdJwey^Ev`*emIeyE;`UPbRkdzKp##qq8*ypj(kUqN~0{VZz z|8P-9qL`j$-eSCg-)azG9F5)B*eF-@p~BhH53wTs{>t!arpeWw@eQJ%j})G=qOQy9 zFmGDmOEn92eD#`SF8QW6$O>gHUhdq`$S7I?kWan>m(S`r=ljQQb_`X66s|9!ZF_rr z2mn;~hMQZBE*=WErYy=ALjAIB?sU7b=ywMnVfHEynyInz>fz1(UecR$=gt>lA-kPJ z4L6Fpe)HASWsG!g^=E6W!^Enps@l9y8zUlEudvF<-nsnMFCqjms0?_YRFvX%Ad1O- ziuJI0D<{_qNG7(FL5981o391#zlV=d}8yF;pS^)p~7YEj#AHoC=UGx6>$mq4cB!PUAYJaS^L*8w zfZLV+S>>GTP6m)1B6mqsQ+<1joxx3NQ%Sam_iLpU_<8YLA48RNb zT)LK;-D@XivhuMU%1)gZA=99D-hsOh_aL*B_p>L?Gv~GWF<2>(M^5`%Hk^qhJ7klV zB`-tbrQ(jl3mh`%m)yF&Ifnr4D6l=ih7h?g0QhC{lMA&r=$9Wz&cHQuhq-+`nwf|V ziXKf+6l$&Y?#Sx5Lr(^;ImWZc%$%91N=K)VjXWz*7L_r(wqK;j73L#w1FsUK*ZyY{ zY9H|NLB=pU-OH=Izd9fypDc7P#Y~i*_4@^#3dG6{>xPg~w+P;=KjUiJdR!!5s*K>YtV>2`aM87ZZ$pKJ=@8h$lC+r8=(|yYvXN# zRup!_Ixm3jkqQ!fI-YMc4GCt|x$y3`y+~cZ6Z$SkOt@jAPAjl81{p= zpuE3>>)m7i@M!!S$z~Z_H6y!T7y!-sbOVmKEcWR+Fao3vuG^prYXvrac{OTS|CESU zrM#AI=eYOByZM0RrVkVr)uNke)tA}{MWexZFNUi1{dg})MuxkG$U_)Q^Axz4>`ne6 zccyw1x52%V+QF@npO$!r=$9`IBS~1cgzpA!g(!!a<|D@X9nsbUsTOS(1b+;XAg==F z#|engvXuOim8f_ys;ArC;fF>vVqeL?ME~`?0i+%fqOL^%5sFh3qn{53q}E9<7W9OX zx;NoDB(Q_tA^G2Es;c%FpA3&l#>T{uT^RmKSRTdRKTbM5ba?A zqMWmHZ7iyaGaEpsfIvcIBH;9|WMKYT`lXVuT3Gn2KTSxVH@2dNrV9cS!P41PmC?#uxM;TioP zqfMj1N&`e-{zhlkYB&rcvThr8yGrHt7+-`0qj2$emdXy;BO-Prdxe7S&%d4ps-!(>(94gdK+WF7_4@`_q|j)tE0{5Z50e zJbJJO#VcCpvOBUlEmhI+Su=I+ulB{rV6q*bo(^oNS*mU3Dqs~edUSTcZAm~-6AE@o zqOv|`#oqb*idT2LQE`J#W;9BS_^?jn8}EAZ-?2dI$baH9?yGlszf^5W^W5NeN#7T+ z`!z-K^gJj%xE0jYwFW6+-cJN_^B~;2`HqZPMVpc(pOJHGQBKVp=!deA&1vx?Jp`-G zjelKt((+{C`4}2zlGt=bp2|ty0o`2g*5aquemOhYd-x6w+uO=*MmK4SN!*jl-4$=2 zyO)HDt;#>$GHj$XscDIheiNSo>61L`a(7&G4l#c6q{>UD!QmF%X!Zv;K^m=!-p5@v zTIeZGL4~g~Mj*r$8-q;2(WqCqSP-H3qGFJlfsyfHBa+bF1f_LGn(NCDW1b{ozJ(U-hZ9@V}1^?tLbp6KH`vUpG8x~ zza#vOi5FHO$DikXA}Hh7Z-0Miw_&Xu-2UxusUz?vuS5%>9H5t=m8W0gL#)#lAUJn@ zX(9ON9o#Nog7P{8hti_7O6AVOI`D)ZAFw8;(cvcSM+NYZv9*+0lrQ%t;pL!!5Yr?2 zr2rSsuS95A()P`7{GPIGCd_K{47z>Azds`I%TR_G555Nw313^hAH$l(XuzFla@MCx zdp|Ua*g>$?2yg4);9zQM3Wn|0;pW&p7#8)Jnv++*h6Dz}YV&mu!O#DuhUiioHiSn< z;l$2nQS(?bi3srx`hDXh@nuzwc+EQdHlm3?Hyi$-QVD0M+uz_gF*Poi7_ch}3T~t} zBu1q zhuZ~C%N05t^eDay&}BxGId(uCUCvjGr}ePl>-{BZ5;#rv-{v4I2B0*VX!}^`8Hb`* zOqJ4A$Swp=yEZU9>ti>CW}eF}XPM32=?W%@0-DeO^q=+65BUQ2Pt6yGC+kElvDSX( z08;*2+74Z^uAXkTdvMa8gH?r9M2(yNI=M+40a+vMt7h$$=w1YdAl7>C(|evhS-crbB;>7q)j_ z9+WannOQ6|g-2)+V*Jg2Za#d4izIJ-tWf1;U1B_%m&|EC@23{gz=iUER*ow<;E(^7 zBZcR-S^mBz>)I?4OKB>aF>c8uny)S9XzarZInlc@L2O-S6ICTcX<8 z!6iamALTL&$tBFu?BbRB{o3R&*l<9NOG%gk1kzOY%I{ARGpFhW?pA6`fwM)r9Nz5@ zM+-G1f*$yI$Sdqp_3AZ)fqPbK%s_GCF4k$prD{5=Sr`_zu8jJ1dH1%J)}wv&0A$^c z@o2uIk97IaDz_r|@Xer=0^pL6{MJ9K`)3c~OIDsZHzb^Wj>1<>UlGtEQBF6oyoo1d zIz}pzo17uI-4_l|lh6OrlERP8lzU?DcdXW_UL(sd=Eghzf$aJnBw*s#taL5|aOUCM z@Der0+^YJC9UmXPrhUL@0cbT}_~L{uBaJpOjM(S?p}eDi%3!mfAtJW?s*slnk)?UU zlM)=s4!5FjJocEwM0itM=IbpHD>qr#r5#k1>^^!Jpta{gBT9SRycpLi|RINFKiKR(Ab`&u6fH@9H3L=sp2R8eu-8whbbT#U1$3cIrqO#Hq zl%ab+6SW1`&pr`xpXvd8oXh;@$Jef#2Fg6SjI>UmKs;RiLY|l!!w-sL#$8I*7B8xM z@0N$Jwa+_E{8D!v_6h+JfQc@wOD5t6;Wfe zk`NX32b31Evit3R0k>t_hfRKg-LivWgl3z*A#&?=Fy^rE0yDTx?nHcHA3v0-P03?* z{a$@s{F^PIk{Lhjj1AK8a+=i*O`OL9&qz@B7Tre$I)n8duC#0(LCWo?9}*<)hvkGq zkhizDUm2e%hk{Uv+%9(QKv3)R)3xw<6t#dn`IJsrD|QEoTjA&Q^oWa3sx%1MuSKrZ z3?fUZ*~@E?)9Gvxz*~lJ^{L>cOPFU`i$a~`3_tEnK>R+f4{`g5qzm_KVaH>RY9X)( zs{?Y)5>i`NcO)DIDo>f3l2WvF27`>5U|3kjcVc1!MNI`J&6hFKx}`;FD_YYin<@>z z92h?9$ZcF*3Am|Qub;K|?9LXu%<+spkF^(zfB*LTJ?!yQL!&@Ya=4%#nHVcJDXH%$ z1lgFCT#TVhs!LLAEK2<4b+auy6SP_8U%Y2-xiK7;1Md#V?VfDas&QbiUY*-%wxRvg zsK(bp^>aOY9dP+cBOyzh&ISm~QVaedqcyJj5l4FOp&k8<0=u5U6VK(8E|6eO6ZO1Y zLFv0>+j$A}lGPuoGpP~BI?Uq1GjXib3#s3P6sjy|(={mhsP7sMN_$%ubLv4J*EF~t z2m(QFx%vL$`YNUH*TU)2FPXGZ$q3N%mdg-Cofb6cc*&F^77}>)E2{48y_*#*5l;A% z(N*a2ViKcin(jLY%3QE%O}id$!fMF)JKW?7iZvpK8I1=T-38CP3s?Kl(KO11+C&FB zPxo6sd@-4kB?8sEc%1!Q*@!)|FGjAQ#q_<|t*D!J*G9h1`DA$*s>jfb10H<`Xj;9T zgAj5!9^Jg<}};sF6WU*)-Rv@ zS~%t@VNd17>{h9u$Fo~r^Zpt{kX5f$ML7E#@qg0ZfhnhVQM{|f6}NkSdaP?HIuQ$V zl9QEEC0*-3lio}04g)2j=b~LN(5TL7E_p)q$^fLxerKeZZiub72<(K_!#W?6SOG?J zQue^R9d?KEPKqY&BIBUs9H#;_I&T_#9j1^RXFFWMvN@gxBC4txn;ZrzS~Mf?0VMUd zJGGPdh>S0+>5ZX<{Q2knq#ueLr18C0Ga2>1KUuJb^^>6vu<#DM*rf)9g|bU_jIC_- z?Fy@+T-n~PJ@&9mg$7}FP=Gf$m8P|HU=t_m7i4DskB@%BFnctvA7o{FL<~Sa1qi7w z#-C%IGkN>0pPx<-j}uM+UpI#Am};{)IP8r%p$(zRXgb892&w~*Cg)Q9@q@&w3_CYI z`hXq3IPxA+0RC?CeSC3gz3h@L&t90D!Q`SrP5iDE+oUTYwh=;? zUfQi*0>{N5Fm8P8d_+l^k67WIR!>J2w&fGlCqDI>bipqvnr%E!H`Z+BY&oU)0J@LA zD+4ZZCHw*U3Pju&Y479NH;+(>xLEz!S*D0J%2wZ*4ntC7v*bq(TqPHLE|`7VnFrmC zR9CBlOZ@^8g_~H!*9x+NTgJN*pii#}yaq%;6W^15s@|bM<0~i;8*MQ*aQrCLj(NqR+9Rfb+cjxwM z!By7BJw=xc3^2MhXp2Km(asgx<%ade>Yy{zZGWkFk|qpFTQivqLAh#WpE0aL+BMx^HOIbH`0u-0W_n5Z;0apfeEGS;)tw6v{~q$iYy&W1X)j?xh=_>h zXb!I&%W@7^P-o1+iX>=ma&_^6PUk% z2}2_Tt3Tv-GxAnJL19d(5(;Ac_PF(feC4_7>U#*;%cz(bKVJN^S1^TYda=~e{I>DE zB5I#hRH|dbzRF{|)n5!g6S_rR(dQY;Sfxf^k&R-`yArLu|7$wah9nz?%Y;D%rm3pC zs9cRxVq-VV4`~0ft#I2CWlFO&D?d;EUF$r(9%N}@RogCeD4fZ7Qh)Bf2Wq5b1Vc$3 zlpY7W<|>OA!lmfQ!Sl7ZMNTcCUfZ?#OahC`<8sk;od3HT8*s)SWO&`}b#=Y*{3R#A z2_nN~L02e4H<@39_fL6FRpiNc0*)IsS_X81ixtW$87UiN!nl)qdqB153a)?MqA@S5UHpoyyk?f}DY2wW>UlGs#L&~k z=|~^xwRAa~n2;cwdJ`}~40{V3OD)hX5_DUCPU$f@T&(rwFxBFxo(6dopOkcL=;Mj% z0#Ro6kIMt+d63UnsqYoO=(h+?6}z_y66-22ve?Z%5W5w82ZXVStp3zRYjnDqoeu)t zD11uZ2jIQebM-E=q=*3skdYI_=EQ;JcT zW{V5zo|oY@xY`0BdaJOp3flU<*LJem-?aoS>*{puO?BB-XZ`;sQjRBsMkRAY2=%^ICG-S_LMNWuTjZK5L*Cg|}62 z1UPq*wgQu~v2Smu?CV2Wu*Na<_9pbv)6#@$zGr70wR19o6q@0K?1n|T1fTrV$@k3;oGc+}o%ia~yIhFL_Q=$zFNvRLL4)su1o zHpJFQ>5V0G+zh+Cw*r?8X1NSmXto3|GXu*8=@gW09EvRbgpGqk70&ah%x_3%BrqXB zxQ2VXp2^&#l_MUmaUEfTHo~k)O-FYNcKUdB6_xlZUW^wRMV{Af6XC5gV`Mt7dDPP^ z@cDp1miq-8hAi}C7p|85--Xt#k4}uMAg9O^h#f0l_e^mi;91Aqs|#-bF#^R&NcZj< z=#b86n5_vm8uw2yX>rwBOn*Eo#{Sp?;wPW_DA9osk*(Y8CX6iB{`cl|<@rf%V>1~G zhlCTHtDxm_@^WsTc45Jz6Lh=@JiOBL)_Li4gXjlPl6rx>0}#mww6f!lKuvc&S|m_V z@`LLgjOZLLlO{G67PL-)My6*lni;S~0-?`bPoX~2aKG(~R$BJ32MIMi(KTP@$^Ojhc`p@faeIut z;e5$M7)tWp04IS!);;2W#{U(n(E&a5Tcr?}MHeuaU^D`Q>j6Z$HJSSa#5gTfm>_px zC&n>895;ewcrYYyrMd?%+;vh9?eHC7`?79jg&rL)vKM-#Khhx8yZ~YYm~-W33|lMw zHu!iSFCblZ(?BGsp7#^1z!~V$nk4wDI)fh(bl1=xvG_jedOfj(;XQ++z(X;gs{lTOr7lLJ=E~&B63=_^JfFaR(*TqY;0q&*5OL!L z4HVE6_d01NT$}k=JGJ5b9v`%s?@$!g>(A6K3UwNtN0S8_L9295u!^=Z3EeVcbnp(} zB%)i^eItCs76~E9->m<5J?r8b_ycIt944wO{NWG&t;$}5SzJj|t*Nu_1LO<)?*SMZc+3ySKqwM$*&PEG3}PNz2&m@}nly8Pv@qrdbKoGV z%c=f63Ctp#`L$sF3ls@{&p-iN1^vg@eAdFk!YeJF$jHccN2`7+c~MDmH(gkAi=Nj@ zb)`BkYk|G5-49P%pIba`zsfX_x)0SojlO$+(6VmE@kji9(3# zInp71@t7@+|7ZMjd|m|E3{6ZLhZ))k9wumJJpj)dxTT?#--7p&cPG_8N*WkM?Rbq? zg{fYg3VTeNHy@G8F|4}JwpKjunJB;A1!QMN(TRGt*@*6;QXbK>e*MrM{LUP=$%By3 zi{#?&E7CCIRJP8&TDY^hS&3`%mLHu0v4db^cGfO!4qVtu=vWm7$K5_zL%bpzGSlY4 z@62DQoR{T6ozCd`0xw*S`3%R-NjG6_4-YTh*ACi4II+r3OgxHj-Vyj4l8}((MEJ$a z19p7Qngl+Ec{#mtx->Y2wYivMg*oYkK&N64H76Q2LX-%^1@zt}-qDEdSnz#Z?#f6> zkB#;3B7fwvS=PpkIkgIaQf}bp`o*mbjM(4c2EmOah2EyI(mR}7*B zgu^yEzI)osqZv+Qav_s!zM8jGC){pbzq$kc2BDi(e|71=`Sx5?#sy&MfCsJ=e~YXV z`$Xob_ZTP)BNz%v##M1oK>SNNL`Lwu3+K)>(gDspXTuOc^XWz5H(CX@xidhr2hD3C z^<@E&dqzC~7jst^DR@VFd`aqgf$0p16b>)))of5#V#UKA>FsOAw+suv4Ce?7H+3R8 zoaPa~7y*|M?H@dL8Lt=uA+HA#=f!?#{=aR|F1BtqGeyqElkfTMns3&_o~@RPW;Yu$ z{xpNDfxIVK&0 zOa^`cv5^uP)oYaGd)>nsSZX8b0z^8y!1=}uA!@bI?9QF*)@jUi#lXN*g5^;EFYte8 z>+9S^)Yu$ZH@KN~?jC7B_y?g1uY>MGctpq*&cWPH`n$D&W56-C1pV%H$siPhGhkBD zy51T*bl__JPRv;$85t{hdodYK#APU9dpWHpdgA&NxHD}~ zW`eQ8$Fth*M+DIDx&R2ri2wgxTu2%&48?-{PKkj?%HUK-FywRqP@1VTK z1t9H#N?-waIx(@$^?ruLmyqS%!gi!c)OPy} zT=t}{n`>YhrshE-;?jT3Xz}#e3X8G1F@oN=?J$ZoaF~E^Gx2-P^M63@W?w6_;g_9H zJO`%UeY?EfjFqFJrt;*ld40@D!sp-v@!daB*GU6pVcY70)*hmFNGq^6^c@59C7TrJ zIeP);-QefPdk(*R?elv7+Er!flE>i!^zguIoLsn3#iCSyfe>8ri10 zc>@?o`~W!(6_SYO->+o&(+dM17*nMB`_=19eiwB`H#PCY^r*pXQxDP#g@#gs$fz^N zb=o&^?r(HeRCH8TLpMIaSW1B_uPJE6tj_YxHDZYsldsIeM2DP=#%XW#+}g)uJ}Jkk z9WK^GM>lrB8`;NDvS%_h?QbuqpR6%-g-8*;#ED9c$WH-$2&d|8j3tuD1u9229H=Axa` z$$YnQ;}=}~5w{|yvE~<35JLklztQwlwy31BQ$gKDQGg;V`9ghQar+gnqU!^GVM&3XW7`ctM+>Z~sxxQVT zax)qZjl&1}0p;c~`wSG0ZG=Trf#Py2BNX!=qsSN)ZD91$vP=1o-HUK)YKZ$UJqU2-@8%yjiOa~_~qxlj7nC^bYl4&AX`8tVXh5S{2VN) zGrVw|)f2K?7n2B}vH>k#5O`VAbVgrYP4Sv$gz&BT&PdwxL*-mK&!-nx6-+NBMC8VL z+EyZ^6m*H@VZ)_L?^zhVMoYkFO42-b*2_1PP>Ekf-*obRX!m8dBt+ zhhqg~&nct4?Bq+4I9!QVLB89!<3-80c-9K6*dYsN?8ssg67Ms%L%y+pY~g9l&!_!w za(0T@`+?lmQE<@Q(t<)}7ns9Af9V?Rnubned2%NJBTprr-~l{XpnT#1b_1zLs+UtY z(@^>uLuJ8f!p}n|lS{j*y0I{RTQS+~x92;p0m+C1XElA5KPlO4`!bqCX(C#+vv?%k zm+_gq=FVznEoooGQF28UW+&ILIY|$eKI9C&^9pJESb)$G#fsyDQz{Hr4k!lzsbo+? zM<-D1Z9g1B*Em>)8t56+Mz0`XHxjy3R8-`(vc9LZy5O@I#iW$3Q}vM{8wXUb;>0lK zpnqr2?E{2=Fn>WwL4hHzR|brJ?2}5J^?AR3eN0wWlf3&7@b3U_J_#`AV~~(6f#Dp9 z00v;KvFr#y9P|1Hix&q^$+yjoVA&=#NUPofgzzTxsb8lFS(Hf2K& zEAp?ll(z*O1Z#!E#0a+8*TL`K@+e#;!pgtGB1UMqL+j3$gZ*}Ei7;f!J#p>R=1wkr zLj|M?^YAgc`lHWIPF%=vA6VOp2Q7T5*%`aU2L2$DViFLH^++%Ns>hWLfBB@}_>3QJ z7SKsYLL!|j_E;1wwLMO|JA={D$I)`c%IbhIZ;-k15cnug<{I;=a&uJ*RY4zv_cku} zW#(NNgWUJf=YS{_#ZV2drWBIHR0*!e2x;hW!JUiU&v39%VdYSQn=X=ribu?^WV;D` zUP!FH<+%kI5&iM$5c$cVi1#(b=nNfdQPQ%q1>m_dFc`IyQB%VqvcHHRWC)FQn+1(z zLeGKsjmC~c8elBsTiMP7GPAyzCt0yZWw~0U$;+w`o_duFIV%ct50|VOhn2>jg8&*f z<=~SzfF(ggc`=Op?G88do$hucKO+SCwA;($JEtgSC^` zqhV#Cx+rLisoWSJ5Ygy>r4zTu&9<&_bLocsUK?~28xyPUodrTeSts=w9#K#GGHU^T52san1&&S5U{MRC3v_=A~ zu_pS8e*X+py?kvSN{f({a;16APZ!sC##sLcZju|AG#sX^awJXMe_Nn-OZKfnOFltQ zCS@?;)nQ?K8e&7xJlADWR3;lT+Cv(Yseb$_N3Il-m{HKb1Kl~Z^!-)Y&UimsT@B{eC+}f@Wp{79Bn<4Ix(+*~O|O}0 zzFWh+=rZ4P}tm`eOj`7gLYWbg?(=2xT8 zJECVYXd3D_U*l`b@)5kT05o-!g#FzQOh>WswNjEWUAlzb+ntMKg=Xoh1&bM`^xvtz z_p;hi0eT9n;-y$()&WEOTL#BUt6aks@0rRPYGhvsA}@b3V7k%N(`0=P_I+6f!%*$N ztQ=Pj7SNT^-q~#r`A>J*>LbbQOM7;l24onC*Km*qqHOSCIedC!7UO$>>Py=$gU3x< zFs(Ob_T`Ze&x7Wb>VNbBa^aI_g8fp)Q@4VqC|{sAVL`wnV_{+8yZV-V;#Z>4s%cWx zpMz3ohl(&plb_P-|5(!#T)DXax>7%JHX;6XeQk~gNHSBf`$0(Bh+NmmNAKZkhyqAzhFEQl)HtDLEIDPiPlDPj&(PL`9!g^IdUAn%O+~~O-)cR1^`?t2Q zRMsjQKtcdA9SpI8YYkAFBqSwisHwR=uRE@=Fp33<+u7Om_xImuYifq7BM<;!W*Y(+ zva@X}Dni*Kv-a@tP*jW&WI^zOg@yeVrjPO9f`l+ch#D1c$^T&?tLMD3RKVH+GnZ1KaZxFZMFaTS3^>vcC>+J_w8CI{WI7jW;F{{@TMAkWsW?Ki?QE0WW z)b>vQ{-!8WF+a_IJ{Umb!La0aWK;KdqvBWud*BSEgApt2OjGWdPeUT_9fuSD=%tFQ zSL63p%7i6anM6N6*1`;u%JQ6J7~e&&ivmv5d;Q*o_8U1Z?Paue^SE){-+XmuceDorPPLLZs6h)74f zKRo7p68zk}yu$O}MMeAoqL-_8iMcxfhU)s5DY6A`2{BPta;jaTSdjjBplp7@#w1Tl z7%0Uk+^t!bgsH_Y5;U#LDLeeBG1ZkIisU6LrHu4>W-KaOyuF{2{htE}9D~g5(>}=q z#;k2;JP8J3HcWX2#ea}zx>P=4|BCf}6jy`MIbgS?oWoJKno`XA+S9J+_XV+GNYcg> za|Yc4KOuttXqmq(etZ>ghHRUWqvvC&tE30+WZT9HxM7*tAy` zDmq+LApE)WNHWK%vIE_I#bJQPa)jC)ncJ7%!u(dh@AsKS#Esh8&|HIJbh&$UQClqk zJ{1K$glxDWWr-MH%eJ8cl*vqSzDvZp7~dm+<=_Q+wRu~SZgrHoG3B2dV|`o{sz1J& zgT&2K`pxlgM|?CkEEf2>#Trq^pr*@35j_=KD)grmI^gD^|3UAFNE>7spAAmy9Y1K0 z29YXn8ocg?95bxHTL7+Pgf?J}+!9PC@A{fC1fm5~XkW@p?^8=LF_<_Vk8LEj2uj?D zzZ)N-NP}Any8=swruBBa#v(Cax!Hq&f))xr^S1pqgK#g^pF>Miu{@prL#O3~q8LI1I+*BJx)>(N4#XEVfCvHBKzvQ4Rl{3R7|c@9`#z$uzN^hLpyz z$<$R1P+{RY*xN(itfy1mqSE|srg9xlVoWGU)9MqR34&7D_(6@t$Mz=~hMFg40)~`< za3&{-@^=usCRDx(3~BK}T`Z!+XHChf$>spo12&PrPt$n+t&cH9b>%+rBz81PANx4}zO+AhXJJL%NrNSmP13RCpDD>Y&<$1ac;kuGJ4VkfY5@#l#!zYfl#9MWl} ziss+r@^vANhx(c~6=o{T8ZI5XP&P0YfFnqqhf#JhRUVny1Kv2LtqN0m1 z^uRFT>+!8EXwD8+Ggd9BV^|&9oqB!z)3Ax7f^vN@T>CZT_`QFor@yjtAX>@szjr-h zjI{vtj27|yO~m4pRZualuH7oXrJI@SLaQj$~Bek{vb z{v1_WOpBZ4=+n?OTTPJJwkI>?5M{)ZpC^p%ui=s!Oy zAj4+P6q2DB>{%>tr#>Nn-XC>CHxeAlZ@=U?FsGNBBB@RC<79?W+pxVS zV#({gmUh>_e_hbI2E*WyEg|cor4u7aM+KtABql}w{nXh8@|J{U_)w_obm$zPG%lD% zIg5JT+9MQul*y;r%L3~{Gc7qunepF&5=0eRH8ktN;#G7siq(6cm$ycZWH9-w%oL4G z7uYz$CmZq!{wOMu6y^!z`D>)5W7hlp!%iEUVCRsYgTNz%Nt+Z6H*{k#G5^-d2=*u>7W3hTu;T?8eQnM4T!eDXew5S7lv(QEN)C~%pvT{% zmrYDt)CbChzER&b3;$I(C$8k0on}qH`*sPV+v1{Fd6dmrk{Elo*RNGOsrHA-V=I{{ zHU)9q3{thL#J_kLF>@&y8K0uTV)yCvjOzARi|sNUH-TXlpe1*gK}LB-;^)cxtp*t{ zMu!Yr#7Vtql}N+eR$BqMP%_K-hy z3To*_!n4*+LlL>+#Zwrp^&kB6t@$uG#U-Ejk=Tr%MUejc6-0q2MX^{tH1JX810y57 z^2Jg|Hbr$m3wjW`4xf{sevxdz962*Hvyf0L&?YJ>6e(M9adB1E)FdS&K%G;mj{)cz zL_}JkwjrLJoSYU~>xw231m~WX9Bb3xrY@#@QXN!u_UVc6C7CfP7=?rnI#6L_d1P}V zp~q2-Ft*+%F+YH2qV8@xIPdov36r+T0f~8Tw)P2|zh)Y0nCQRy?#?&M)comV&Z;?% zn$)Ckf)Qq{-z{Ix7|yQ&$OwLE{W0%YXm=9SAyJP2ewXZah*&B_;peSY9TkFTiosht|L@ zc<#@f_~Mj)In^>jxvkOMW(!AbaM6Shd^UXu!nXZz6)|wc!2M>&jj zddjvTB?y=GAp>3$PgQ2^k0sDTAqY<;d5wZwSW$B16e53bMd~7r|GRi)ALo0bCe0~m z5EqKgOk(bj-qmn|SpZgh3g~xZKFO2>e>9K_3fm2lg!gPw#o<)dbjN5)eEZsb9rzf| z^qMVx!byHuc_+W~%7N;SnnaewMVh;OzJ1^V#ec7LzB~~mgZj$KZ1Olwfcm#mpb|xy zlDBhxp2!8&ZbJj15LI8x%k%~J=?wRyW3CkTV0{*6a*` z-!S9En2A0vp+djifN->LGVE=n@oGbs6YeaE_%K{%dXOfHsX@_yX+aoS9r6%0IB9e6 z1D3#-t*fgG{476FV&muI;^O3ajAdnH0*>7``!IJ~JXZ9M2^&BclNPa%rcQvoF$v>+ zbXwR_3>>2^vgS5bOVGqsEj1BtJH?Gevka9fGJArK=c&@zF)SmVP~Zk9MzT-EII{q^O87 zm9op!xOmRJ&WrqW8`mc}s>ZptmC(3qT`B9!`-b9WKHOK9xoYN8->dOw$(%=Xm!F1o zSAPwBq?nOwH%pmUqWpIY`ZnL4yk^CeUo#Z_x>siO+byp9hdnz@dq$pLZRCBuX7KC^ zerdy=!=v9|uP=jH_lkuXC79Bp>(xuqHn@?5VZ@3H@^DpG{X~xr+6TI&{^g4W;EE4d zQ$WMdntjbhDa4WgYBIQX7rdIR6ms=;bv3^=C1#2o3RwivF9zYiay|gLIw$GQk$L#A zF_%kfxT`Prc5LIr_9;zoVW+tvK*}ZSH_b(njw_edibuy=_d4{$jbkUdl5%6`5$KgLZX3!7H%xM=!PVw zSDS*2S~qWPyx`RN->*@4iWKJF+RncOl4B)Z)4vdsgOr`MpY?UB%IiuE?`-#XWO`?L z<*F?6xSyCD$;PpIVk=6yVTVq&xS*;2JP}O4!KU_9wO1Vp#g<@aoqVLvf2z>Oiw+{` z2$L_&t7e3&#K^$>A4TnzHCXKK^D()4idX;J0eqF-5tenwu%5(;WMj;IIu~RDwx#YFXf9SUWBKFPy6*3+0+k~vhLFal0ekl^LNYQXZ4tWxUWk_a( ze3eRpUq5vJNJ6#Lx5OM)WEI~anNOxGyY!Q4S224tU-aHN!GH?dp7_I0-*kmB5|@L? zS+OZn8p3xe%VQ8?i(_fgt1K+`{}=4;Zqm>1F6K_Z0*P0SnKkdu-v zNghj#a+Vb{((?Sfl~l*S``rJ2m0-V7&%%AH-$)xO`+-w`yI3_kAg3dljKPGBN@|^+@6KV0f332?nsQBRN7suhWpSD4o4zrD+fvMjCP>?C}Iq&$ZU)jO}K1ST^yD#`;-V}3; zPDt|XQutFA)@qqmF~AfXYvBdLC9Z>GqChKGf6Fzh4TKTuiKWIGe3({ zY3RzBfdjtwsCXPnr?X^$jdgG&d+9j?w{9k3j&S%dOopR=L-PM;$Ncvjv+KR$4zJ3E zX5(d*enkjbk!qnp(+C~Y0T&=Zlatt@IPL40Lw0v8{VLXX$Yr zU#Au2Abe~Y;FGRs?Odtnqe!^B+m&y_{wQv>K}N{CngcjrJsyy61?K-h?9Y6{jokoO zrE5Zr*U^O55(8ngIEvlCI8m!2*RbeW>U5s+nz@Q18DzT|=0@R@J6&6L4vJ`IezTO1 zar*iin%TdQ4hEBfMsrh}V#H_q={^FJ7?x!pf8y&LM z0Aei#Z(2WISsXoeLU64bph*(m20L2FLLAMZE(QCa0ALvhnh_}jUH`%XaD%YHhDMYa z-}C<_Fz41w(P}bdwY2Rgci|JQP$ICx^4pi*$; zRC0*6&kWc7?0Ad8GQnYtm(M*t^^6d)JRf%q*RkZ^xxl<_4QM(C;4pJPxFlmwSHejJvobS9y!{~TXYp? zdYiq5ft4OAx+z|r)>j84uV`?0e;Sqk^b@Al zDQ1aDjEs%W!I9&1E)6$|_mf9{)Q3StVp#^4UnG64TppIpJREi+kGPTITkIZPRJi&U zp>4ZBgw-S+`x#T^T3M-dr~SKZ!Iod>$ZN1|+7h^os3@D^8g1$l{_Lp2m|FimJrK!& z;#pf*82Zr*3~qY>8c$xAL!D~tS%A@*FIKnp@j95R0y4gYCo|jAk8;CAHvGPj729)s zn9+T?e(Jec@m?--@<`;5O4t?IR0uQe(1h(p$i`)B5evc28hx#VvN{MzA(5zqPBbfW zs4hxaM#q*3uMnC4=T~@9Cuy~C3;=7Bit=d_74HkE<&R(vLDKZRwu!JXa;c*)r7%a|W1O<$$iVp{T0s`6T}? zzmdh17l1)Kf!V-nw_;|ZbOY68u=fYVoB+FL2hdNNet@}qJyot>;6=)1_jPj`)TEaH z-{wimDFDRq+d05`{|LYgfkBM`Pc%3|HS z3NOe0L~#_nLohcr7*CIw?@tE6CE9fz0x3lE){-ZOrd%5P&aHT)n;`%p>gjk93j)c= z#UbxeiB8=qkn9W&4}SzAJ+MW~8xC)lygiC@(zkqo=|0u=75{J=H;$(D+)oSeH%hgt z`Kpb3Sd69P*Q3X~t$HByRwmh>RM&eFYaD-*j3q4x1SG&cyZb%B{OJLR&*s00h60r- z|DP4#g!qK>ogC*)pgl6|2%(US0dAU)>%DPr7wp!?@?^hwol29g0GyJXyzF~P;om@I zMpkqVwroUn^ubu3Rf~_eZQX`i-kkThvaN6&8g#CEr=P<>q}T{_V-pi9iNvMWdbYp_ zat1hqe1U7^`PTK%jQK?nUK6nlUv3o!T4Y-h)G=KKWTO@#b=fGnD zV6U7mxwrnIUc+u;x3vwA_Ytf~`)T!rSW689TIztUpdJ{okmdbU~ zH&d%YU&pq*zffU(_vZxAz0_m&XB+Syfe?40Sp5jx%Yepf*O&z05rHe5o16P?5B)Qc zb%9C0G@ocDx14+aoap=BSMeNv{0w*_`@rGY=zZt5@duy@ujz6NYFfi%2|0d1AfF!3 z%Lm(oQGo8#F|S?NUGq8!Dc1XZRC4#m9mwXe{ydqKU&E5uW4CTN$Y-){bm0M(N^(ld zBQST|iN@)9o#a6mU>G!?lx<}r#qwVQFWgx<=m2O@0-4=3-$N%3=ILiTNe73os=x#; z&JBhYwvU_xMZE{$YXaj@n!q?Pt4RXY8+fcLfC+L<|FGz=R|>E#Z~lei!pDhZc;Ya- zfkvv#Uly%{q1cnDfGp0f+W;uz;UD}5YH+JeOf{(i*&1egPOKDmuVr6gSlRtrlf9H! z`Au(cIO^cDy-i&DWNr_HK<;>dO(iBBeed=%{QX+n9X0^xeRU_w^!49WL!=8Zhze3K zn{S7CWBKlmlZVppy91nfT=q4@?}r8lgGy$;zo&Vk+xRvBBPpu)qeA9Qa(2t>CraVn zlgIOM;k@9cV6s@v@d8iBp^xgW0}vRP8jnT9?+<1wC>$gS{!BkX6Y^5@jU@0lKO+99 zT?s&We(_d7pcw>tY3Yyj^Qy%@Eo(6+9{07iwSVgO$^vib5k-Iq-hoe$9-39@zqJ6t zMN0VU}aJmO{qmKt~m$zk|*QJJiAI@GDwt(W5CBel?TObaN zf=Z~@TJ-efuC0g&0Kwu42=!-jJL0na&co9W5*eIa?(FRJxmVa5%|RG}J8)QweoH(! zY&r#Wtr>krKjF{q}{MzfypHKVqgdD{TEdUVW~Ytl)QxzfJeRUlTb+^N64@Z5zcUt<`Mdw5%MOfqc|@W zi=s?|>B?}ZcW%iaM_fkSWmiPOvTytZ+iX8ppKD3Kw!8aMYEW7yzHD#vg4#SaaXvZS zyzRlloRu80UGRT5aOzAd5)P?)b2D(-JxS;xC`?aOLQH*co0Xf%6#X*2Cghi2#RTrp z*^1T5eI5fbd~U9{z{*3MBTL|uEzbhjo13t($vQ_fM1LYqYoIL-m`u>)XYmw?#Rdw-=`42-Z?qy{%XEke?= z3=czSHHG@U|Ez{S-rOEtqu>HN-qTsk*9txx0^p?_73joV5OA^r%9HazvTx1Z?GaGE zs3s18XI!dVne59%&v<(ri1Eivs>S!=0f>ws?Zcx+ zw!nW`4g2%mSolG{Q|VV)Vd59!?5r(Ta$JR`ZBp>)l=VEB22^>9oU{%()S6#HB!e%? zF>iQ<1p~@x>ZvK_S?%O~{EJrnO|c?ekTx;bt->m4;Srn&VTDuwCo@GP@VuA_CH0_v z{aS|mnf-Z^x?bIS{A$4$hkn3H^Z*n2oZV#KqwR&i7}}uJQDgbZly@mH}$}R`B5(Bu=~#U%^Ttz>bVl4mFN3Jf(jY7>eq? z8jSZx@ssUjexC<64vzcKSA?Q_1B`~_b{Eo@(*Qp@CCRs$YP^)enwL~k`&LoWclWz= zzc!rA(BF(rm>qRD3AAHbA#2;XC-25Jj79BU!xY;aNL!bc!%@+7B#OVJ;}V+aZ%s}# z@HI1&hM%HqQ!rUc>s6p93uCqWH79HTm7wL->xXXhK^@*+OE6n0Dg18%wlg5>6Vq3oy1#t zVh_K3O22{3_GHBO@!~D^Y8G>YHS8nA=icK`mOwoCS<%3v%|!8%@RaQ#;Z&)1L9JEu zPJa4?Ac)8yy}SaCx~&E43;FlD<93uueMR2VmX*)VM{`vPzJ8ZpARGMCVmg#w+~Me` zO?{NEt*rM=5y&5zm3*6oE}W;CTy^PW96da4#7RXp&=Zx#jnz7?4B#mwbcQF5g4gOv z3TVqis*22JAco*B)fl7WMmFI}AO4D0kBx%q>NQeP1#n~Eosq_tRuc9OTGq^%o2xWS zyZyV+c*xsWvaztfcSb>is`F+7 zo-rfSS6DqMEIv-u%Ag5*e}9an$M#2C(pJ-5AA&k6XJFLgl7>O^iyTJ zmEbY}GT{%EG6!xou#>}r`Aoa-%ET+GZZ zUxkV?fM7CB%wn;qYO@!>pIe;1o8%2er~gYhb}2SDT>?fl0=Ctd#dt-6mlV`dtA|&) zINI`$DR?3#UnyC&4ihd{_#N&o!XO~cz58(yvOKJ%r#?)GrcrX8X`#^7uKJsk4)^}U zfwb1S7w(|(XUe=XS_UxINun zUjW?;M5qrx@XVQ@e6KP+VOAnTG1Q}kUEKjAp80V)XJVI*fnku}LuGAU6LN`taj4ty zClm;XO%a;rb|ZmlBj%-VgYI-E;k=GMt%r?=hvR*D1XbCyG-<5#EBC>2wAqdC1dgnY zL%#gi`PzNYyg1EBW{$Z@Tp3tFim=cIQ29+mymk3+iB0qJbHWkp^X?5#%EI$2(3@_b)6o z@;O7P*W>0e((-}jQ6-&Ji0w50%_kMxVLZ5{n>1;=wyCu5Y~nP4t$Lk&%jO16(hZO>BF9TF=H?wSts->d~XuQ_?J- z2V7y{@Q!Vq(6}!W->1UG5OZe>7G~Ibc+^WTfD7yrNX8;wE!H_cv8h=IR1-294cY>L z1321Gl=>$!) zVYQ1bWkK0KQ{)v*yVrcVWx&oFyezz_Fb~CABL~5of~F}Wb+$oTt}Ri_=x7gSs1#5| zNl5|NcebZ<2Qf;<7Vn4Hz4%m(O8NTqBJpYrZ?~gzDc}<@H~)zj5IWLps)a(WwwVVY zznh947Zo28&&e6%818Nc80D+Qp1#YY<(Kbh*ZY9#40xF7-cFa|xqwObAX}DU@N%Z1 zjELpG!Ds7nIJ8V;0PVRLQttTV%_?RGz`1axBL?tfJiH@j$)l`w{jH(&g2Hbgp7CBS ze2ci)1tBg6+b>#%KFuek~%K!9$}1O{q= z&U#^-Z?=lj_d^rUI=x5Zsj_gVei0wK{XGM0oUGy&+A-i93wBgaY0N*)R_;6RejSqa zpUsYu3gf^GSwH$K61T>h?JUaT%r1kh?=bQ8jf^Y(edM z0nOv8kPUuJx=Eikf6CHxbL(0o>pRjb8tZL{BY58``6iomAiJewIOtlbz6Eu z0-NV$!EP3K=vUyfzLRsD{NY{TL+>+q&F6S{-(wjxPX|ax(3?qkQkz)5sti|6>lK4p zcAs8{{-k^a=)~g`$1-I)3pDNU z0iYj1D%cEK{n%%R9PE`(0F9&T3d;1yD)sWax376_0PZi7#hXV!@e5y_difGS$*dTH z64O!R8hY6xH5C;YfWXHjFw863wr=w6VmOtIs=;nmM5^>|1vuv?l>xDT4v8kCwMi5t zrrxxAC?heI;6hpk$fv+9E8BK+;R#ZICvHTwqI%aX0bl`URVOcy`|JQr@913KPzl-x zr8W77GZlddyugfi_h)qMk@7JOz)>(>eFu`rZTyGGwfRNzpG=#G8)xS9Um$jJEEc`JtG(fe5V0mtM)IY;7DZc>6FpvVC%dHfm` zHMl>2avsf&_@Hw0u>~G}H2l=%nK#%0>Z?&4&!aC9UuT9xw!dpAl+TRb9x{Y(C_L|U z*_|c&YIKAq-W3x7m$;O|c>W{(NYI^aR&I{+vx$q#56hsBnK6-0$snsPmq%_D4DN0&puV`lyKW}T39}tDe}<< zys3I;D{mT(H)KJWB0oYqV!3`7=EQh_;%E@3;}NLZQT`;$y|}mlAo4)o#I|3{PJr*U zCwYIt?3)R=t$+|5v*-y})hDbY1SA+;dOr%1aVi{^`YMGM`G#a8Cc#a<}>I`M!( z&0+|cCNqvt&CGn%O=L^RxzA<&G&ci*#0m3s8Kkq|ZJdCaE2HWMBpjBBh{(vE9cXV! zz0Z#-ngEgoP=(Rr0ri&@;E~AsX**Ey->g77(DD57`P@>Z6Q~VgUbq3$0w{1`0ildO zAe!gI@@1>L@%*%zzC0Z$uRZOj58^aixgexX%+R_9|7+j|2T8#AN-GS87Xac^fIGIj z{AX6UY`m@3s1Y-->kYhcYm7@H-{8V?IHdp90;-Ex;%C6Y?=o*wla@9IDt9u>(|t5q z3q8)mcDX;?PK>aK;2t*fd~e1eBAH9AIob4!fR249bs|z% zRC+C{$E?z->wHI?qwLkOd5-Y~_@iA9BZas*Av6lEoui<6rcOf0V1>3w}mnpKg+ zNBkkui*%vfeG=vQgGE8NF|GiLNPEXXL3{lr#OO-xMgs?XR40)&8M99>EefhywFS}$ zX_@H`VS)P3ONMr9vtK*ZY4)lUxL``<_pD}-6BceuWih@KH1PFSY`8o)Yp6-=~2vy$;1t@SuD@PnB{fZE6bNc@#AgeFTor zM^JTpzElgY0iYCzCUyZ97yi`|U;)yNL==M-4oI&w8aO!v&!3~!J-W8c+klFa_wR5T z*rzp*cp@4?0zrHq{d&nM?DwOP6<=FME_TIp3vy~Mm>)|yFxB1rdqVur%$Vnu2qTd$ z^ZX~pD23PUjVN>oX#?3JU6Cx`6^zcl*OsJDa}cSMA1|(_hQLFd!}SZ7LD3Bi zaI)~FvTNe^yksZTFGG_NIQb(noMPCkZcWpb3nQBJ^aF@tWPt8C$ScZAH#pCF>g?iWzWN~Nft_+ ztysXo4GhRx?whlMUtGUPrQ=9MeUcWs+U2#6bp?n8`SeTsmWO+BB`|&E8sJJnMY_-3 z9qnyB_@H~R{XS@2aFVR}#rdY*f&%tI!;wz`IM*FV%0+6(tC(?}wF6Y(G+|TGWc?#a{I|8h7 zN;AS|Zs0_I3DN-0;0O3b9I!8f*k3N7sYAH4VOD^Hr&X4{NEhoq|Hy={i5UAMqgDc@ zGBp;qOi`K=iGo;{IAA@CcD8;-+&x;he&yS78s(%2W^9y=4{40FP`+5TsCRD?W zQ`)1#qWX`EJay6L?=M@)A;frN??i+8!7&E@8Fg1z0V8-QFeEW7$UN^6!%^#|sHan? zD2=zRpad^lZpG!=;IAX10_yAQsUq>1b!rip=RiE#o%x=Vl2fFn4hFQ00A$4uP&gF~ zXNs9>f_$RU{Y+LS0yG;|UB@h98FU~}&SRBku^(T&kg!Up-kU1B1(iN4E2{?Aa=$;% z306lXNuRv%LDXvCz@(WcoQL?p5ITVqn%~1I^y=c>`eafP?@?pr0+{TTK1}G2%UM)h z87Ek?2iteT^-4= zhgg$H*QD4^pmMgK5y$W4mV~!rFt~B^JzJ1$dp+F1hn}SxU(<+DugXwPK?o`S!+=#m zk-5bkFzLyTx7IBew*E?!AMU3`Cg%}0UOax$3~lUcpy>0~?WWR_lEnG#Rz?>RYyWrK zD4SKb%K}c&QQ6;MSOf(HQ=!Vr%9a54f|wKTDKcSm{Ams;J}cgP<$X2dh%qXqB9!HF z#FR}bl5(kgb%rz;57EI9m8b!Qt#M0iLpz zNQ9%GQ?G^yB|@Jibff*6#F{LkF7v?6Z(1(p1iqMo-Qrv>r>aI{Loc&gX6 z8@;+i*6n&EYqu+T_=qEkw5!u(Zoq6m*Nr12OGKek`g@|o9-18zf77}SL9@RmvA25v zN|f(}#4scFXN!e#lYm=Fn}wcs1~#(pxG4kKSdazbGyF{R?hoFjgfnXQ{ZJ^l447Dz zQ<_j~j7fObe?Oo2_i)3ZCE%8<_a$uDEIFXvFM^}?aZB*A@6K}Q-@}B--SHDItPH5{ z-)y~Mnkg9$NxUc7VBy9SPQ#(*+HRfAJ+6MSaxZ50&U7bBQa~PZn^s#i35`-tIHU8* zo1uIJtESpGU}Nvshd0s~1qDQM(2XzmP*Q^0Cw~&ihOx7x4I&y?INET$*)K1>c`*vw z@ap>dEnr5}dYenMA@^e?swol74H{rb1>V^%H4-q7ex3m&7+{vAix|p7`2I>HNX!}$ zX>Y$7!ji39^O2<87U1c=eib4OKwE{T{0Yis#2V`A)4;$%9Qk@^WCZW;_ZlKvkY8l^ zxbPuG_i|!faRhKjKs2viEGjH~T4o@^RE{*?hCwVA>xTd>{24j61)|x?98AG-l8Usi>$F z+!LyDV+BKcf-yp-4ko_iz*gG9hcaka%OP9zQKJz9@$hb02GY~lNkeM#xB?6!)S)vS z4HY*~JwX1umg7mD-n$#&%p!E;A0-2B>=?O(0Th$O)cE8>HOtoaN=9WJ?G& zOmyyLo{L)mKfR3&qYeXVv4tN)3FKGEBTzeQ!M*v(!dFa85CsKd0an^nFjR<_ZnKv= zC}IepF58PA6MQdD5H|^+N95|XasTqozl$M=Yvsd?2`wSlq@OYOb1q9X>pj2sr1*ox z+7zR)FOp~E4Aamht_jr|@^F&Ez$<)7JtGY>Pdx2LsF8}iuEf*7(%n6fM3(o6Lq^xS zAWM5?-mW@L2?r6|)%z|^)b${f3#F#|B4#QTp-^o`hoE(8ROFY;?L27Uc_SIZCLiL4 z8s`}I#E1~Z7tb$)Y-n4X0AI2VhbVM+SDHeWoKxFiZ*1%x{{>j|jG)x-pEhOu$jX?M!+)CHov-+bdk}JI*u$VEqwBn6 z@;;ZJf(>P*`ziG$h}%1mhzp)mDyd4kE3GjT7RIW+F%xjrY#by1HgXl^u;_*>0 zA$q;@Xk>Le@g+xvo1sPG7AKMssguMh4$5aq9A_V?lmvr55Cvb8=Yw99gPIBVk~)Hb zhC&N!ffc_Dvax&ZM_(#Pufu0OI{RQ#6F_}P#HKG1hIDX7J{0@JMhAJv!xUAH;ycC;jW#j|7jsyRYU|HBs~Ugf!GHd^Ta%T{9WOm>!=~+P%lXw> zbms39i#*Drp(=ypgf9`8Zb~WR5f>C3UxvhKVIYaB3^&mlUgL~IEHsrS4uiJ$rffhqYW)4?6 zyNM5GZDC>WhYf@OeM=%~M0zS|%h%E{R?Ue>bSKy5svTJEzM!rIpXq@0r_fF}&oX@3 z#TOT63SVdSaUv=#u^@yc^#cVrWj(1^tXEn?B%Vkb7h=I<)Hb-Um4GNXcb@r zV01!)x99_xgPx6)WmE(;uAJ}3n9Hb7WKhpfLnR-o73tUYNW;91xJjaoAfG-=TEdf1 zQ$RqYwiFL@@x5JQa&C|t?ebY z-c|;a-BdI!JBe<5LVh{02+1FKEtRs!PsWCa3yPG}JjPndtKe~$;9=8GF@4A9XN#!K zx)C|-@HIw?&ObnoT^ReDf*fLX%IfpU{HWB>tO<{-P^no_tgX@=B~~W>TMOW{F_2!B zQAOJiLUKVaS3E^kwML`9w`b5|Ol5%_Hd29FpZ{K!sf4*vZFBQdy$FOEnH`uKl*<6z z!EglJDCqqD2C1jyNWk`O)_2yg7C-w_YiHulvwlj_ShNHqlCE=y`#-`55F2m--Zn>eQU&rJq94%z3go zDB0XS5G3n}VHaw5)yMK7nBD4GpJvS! zZT!=8tE~yx8D&O+g1|y!HL$p-C}>lYmr8A(v3JB42*p4Q-e-O03X0j_(Mur;xB=Yb z7#fkWgo*=1r#^80eec9c$gzc6s80`a1XrUx>R6Z6|7HpBbnJM|oj{*Pt zwh;T!(js7Reb^yaL1PoG^)N1BlpA47t>_xD!h#VdI8({ty|BDJM~X03Kp_+6&e}FC z?UB-^h9ieY{JL8LSs5Nh5c$m&c0Yfb)h$2aErv5QZM)_-yHaYfes+2q z5gC~Ye@ecE31%69kxHN1&W%@--bdK{?<*2XBVOe(h$|uz7z*OEG{_?5sD+=xaY$9; z$%Dadzfx8>K}=gI5w%@~$U#P+0l*bPD*1YTSM8OpqLSP5dTQ_`GURCSY*SFA(jFAu z)cm63KYhix6n+2NLJOsnlP4d}o`|GZSv&{u4)p|B5Y_bbm?UTW`DgqlyA=}5f~y$m z=|$bV<@JMt?m32zOWp%Zs?^u$4Ze}FmEWJTv&lba+rf{vV-9G3zqp9P!Wer^NB8gU z^Dp$TlgkwHHykboexuBF+pfM!|AhTsHbR%Zs3&OO=r|r_UM%pNTQO0*X4Fu&2Y10c z@r@wS^$3^57WT=X>9z#oJl7 zM^Tx`&}(Fq;*b;M^~FMktO3BeaR}HxdIyumDb9in79(Hyn?mvCxD4<$rKUh>eC0!A zGGnFyv4h4NA*mqS(d^)f?!3G_g;ie5iRtMz%v58O4xZy0pct7lj%2r60X^-F#L;RL z_`mg!f59={xN!ACuYkBDwF)LCFdCkd+Jpdkp9*g(J6BVhN%Tf)&Cq(wsT$LbLQ!gI$53i%3z1n9I;tc8_l%!@pWN>`lpzAaGm0f* zM}Fe$Ke+wiIk{KXJNP$6kS3w`>~|~T_FE^Y{ev?l(HP>56yC!SQG~bT%!R(_HfhQn z@Chy(g?$f019?$H)^9+z&m2`vmToRW-sn`>iSSl!l7moQ59DV%)$oq@XC~;1Sh|Y~azakBji?FoOaX@qjznL2ttDIb^rmvh(@MR4^cVCP> z@EF{F$2h6Lwpy=C`DEuq|Eohhrs6|XcTs(m2=r6U?LYYkA{m<4s$Xzrwk0;w&cKbw z=b71EKQsi7k>KAYJQ?ktq10TrQp>QOqpiuQ(M6Lz-0K?`z7Hcnm zVihxa{re0eFqxK&Fc84C5&yfPHHDneHD>6F%!wgPR`+G1yZolB1JE=vr%5RKgj`e; z=JKIVa&})s5#)*{_qca$#L89Si^GjySgv$aS`skqKQ}m}G7-PP5#>P=7o$+qcZd7j=B`^!TA zH7x1@1J$b8BZpTUfb1g#kD~r`j&qOxRQOGO9hU<|{lD)b2vahVmINZDrlQ=xNr^^m zByuP+-3J|MLUX{}7E&vXi!+OZcG4ScwzaDcLxhg)(*t`u+Iqr;Chf)!f*wJew57xw zO;JZ_T4S-RXhsXdEPmvFi9tN_L(w2~_QSR4)4Pu!7d!A1KmFQ4`@u2L9c>yK#q8T& zqEb6C!Z4h?or|$`Rv2u8GEAh(ci6GkDY`WNQk;x0AVrXS!vTSb6YwyQ6MyrK9Xld% zyPIde`*Yq)k^g+mZzx}hP3%$rIoYR=8RP5qgTWnDc-$dA8h0=NaC2fO}b0<^fddNSzRzDop2nm>WhlwQFdq$ z<4gGV0(k$oZD zzkTMAZo3K-p1FxRC-r;a8@dyOz~kn_g}+b?%|%jdi26D;JxSDa3ubW;K1#$FB^!+` zd!(-Lhw6tBnbLj?T*T%$CYw z&oxHb^zl6|RY|MN=IQ-GP*t zpZk=57^tC5*pvpsgdpNZOPlUnbelkWb20M&vlgw6yx(gRm@K{R!GLO`3p#oKbnL$n$CQelqO`K|ov$Yc{r;N*1@} zqku9rn3^7V zW63@su=g2jF6x(*oC%#w=VO{nIM=gOu#!%OK9PxvDLtJtQjQw{hwimD^w!kp?HOp| z>$dpZKXtx<0&mTU5KK|5t-y_zGI_AQ*zLc+T7G$X1^Q~9VDy8y%h|3~xdOf*DUn$w z$0>ki;zoC7y2b#`?^}2bQm?b2M{I(?wSUK^6uTS2gcTw7cd1gecx$#O7=>zPZ{4Lu!9JL zacQ6y#ajJCDkmH`%mpz4pSIRbi*td5&<)_mu`0;6gD@R)SMtbr3i;a?1j z#{p@S1X_vM{I@Ujgc`qK)0G2?bXsKCW)i9*bjRp0PQUt#&%vE4bYu4;x7UhHPSecl z>sIyigP|wYna(reHK$cEWq)W58Oal9&{055$1r10Bn^e9UOJYI&$IHq)~rMSzuh|& z4CY(`Vya0;2wMLAuT~(TIt0xJ3Jj6xsQOav(v~ngb%w0m!B#XwXVr^B8KuP+Ut>uYz4Vvs7JL7^+y&EtPwz=tYN!H}cn?u=_)RV4Bb$u#^XKq4| z(5}%hA2;yyGwe4%lQ)2l@DAwnlh=T`H5Wj!_Yw5(vNhX;TmPOUl&p8iTvQGS3_pZm zB$dVX%q`;rpE0$@;SLc_TKJYGM<8J;5<6?b+m z@b8uD(}Ecgpqy=ughIJ^xOPRn;Nai@sWiZXmiE5j{1{dIasH*qjHY_%yxIXlU!%D# ztZl=AnuV_-|HZ`PZI7T6v#vY0)A*j}r~f{|7F-1S>W zC|ZwT+=U$IDGPp)c*4wGp1S2mo-<$6);DEG=A{EhmXyJu9tV*+XSEhzd8M#BWS-Xh#Q zEk-djprrzOji!YA$yqR628_f_@8oOJ)2MUUDABBZ2Oqg;GCl2nANM>=-{;{PY=G8o zpnP@Ov#F`Fu(@pLK_j|ca7?hHiSB=rATAic_cm2kkJ1xbS5+gT*iC4*K{fGO_<=w z>E2Yw8C|Cc)wG=2+s$5Mwm$5x2pOv=e^q2*WXlpxgedl@yv*%IY7&e2m+I7^9^O5T z*aKPowx?FLwWf{^uz!>TOApXjrB4w6JC?MKO{w{BFy_dxEdWm9mg=bJjALgE8tuQe zfYZ~26meyaDuP+vWwf^oet%?TWSH*9^Arr>57@WC6o~fjAS4_$2K}-lL7*nXnDKr5 z&fFa4;01&_m_)TcW1-5 ztG6%Z4Asgs{ChFD416ahGwK|fTJFH|ylen%T4@g@fWA!vJ>mnP$mqPB#{d((rvV?I z-Qye%c#V{sLP}OEjC;uAwLjLWk_OmZ+jd2`2`lhlJa2pwD%+f1&lLj{Kh_dZ?2LeR zve#@Dv*`MiwjDu7QFpa8p^0c`fSZpXtg2p``%ZCAYil4TT)%faS-L*sB@7(1B3 zeFkJ%ZQXWucPBF%0F?gI;-#i25TlFW+O@UAfqmBil<(+#$9~}P9s*U<6EPkMf71+=v4Q+y-+5>UWutI|;x?1pr zxJ{QRr7VBb`x808^d5GPhRN+m4kl`==SEY=g&Y!!n-^#kD z#(1UrXbd`RQUt`rRzzKU%1JGUAC^@zry9t&9C0oDI@SWiDI8l_JBq5NDRP3W6f0M6 zUVg*aeEtg@T~bVyU|35I{2p+0fk_(|*QS5vVnB`uDvIMTu`>jHA7Xe9@w=i}2#g=R zh90P8ptg$f^Jlsg$>L}xW)`?k$SD}~+Aty^vp?;}frd3U8VD|OA%(xF)|VeHYrq)+ z=5iYX8(UA7UBE(}L7UgiERdV*bw`cD?RG~KEl<0h4b>dhnHkwjhqHWn5_u9h+61CJ zH~IqKxqgkOV+UM8+qa+&4F=V;7{TOU0?DZ^cA%302iGd?&F;FM+EC$D1!%9MpAN zOxs_-M6BY#>Ki{l1ok;r*Fzoa{hH^2h`k}w7OCY65u zRhCX^oU?20J54fPnTHV@tx#FGaqLZ%zvGM7#k}Q_ZKC@)$-0;*PlCQR@9wQ#s^4g- z?!^pX+03ot%ACs2*4_fp;V%THfSw5uWLQgmrol+D1wy|{NXYGe

    N0-y0Cl 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

    C8t%@aN_EicNBo5%P`xmc7On`HXEv?7E^H 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⋘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 E1DziDe7GP0aZ=QPr+em@pI85vv#w zp925oWE&uG{@A`XEERrGwE>Ps^d;;PKRmoU3$U?qq!=3+b*Q`8R?J~TF0o3K5|r|I zDzK#tjx@8_6|Tn-{1}>-m|}9;>#$R&Hk=9slJns*ir?YFngQi}ehkXd`3;i&A!f<` z0=QrC?dG(|bheHBonu5NtQ??u9zq1}V9hu`V@0q#riDP53>f)pCB?TeN(2r6Hb;k(6-foUBv(_vC-_dg!q1OhzO{*e&T z0&b~Zxq7?owbAwa0ODnU#2o0;t=4m;^=TANcl&pyvo8}a6ciLxR8+Kf$E5*+kqP+r zOr2TJea5A!&XST6@k0nyl)T2b>`AM_#&18#)s7(n&&>2%KaehiHnTMNI*SvrMiy|S zs4u9sfI+qY_<$|WQl{5Wee%E+%>#msoR}OeE4YYfhy*#b6}G_-Oe7w%5jFoT3~zxn zwLvE2>!4`&pbv-(Q&L0ONQ;lep1-qzJl5dGt2BA9OMpKyF)>L=%s%RmF2pWG;DoqB zE^sYtCLpMsGMjAj-%Q4nBV;F+KW&ADQyg_o8x{b$edqnbH%x70UtRRZ z^&}uLfH60EGJl7i4&&sc+n9Y=V5pqlG+MCZnPmEOJT302 z61%@t7V|!e&A#nq9Eq*UTdk7$2|w+G*K&R8E3T{=&L{t1@Ut{W%D&L>D|J)AY3(UE z_f7iEZ`9Bh0%{lOfQ{i_z&(HZ`_>9r+E_x%R^hEeZ+#8496e{?GAILwerFpqz<<>G*kZF&~Edt{QyP6X%1T%}&6M zon7Rt^5mE5LOR0|6s520ZnEYrp1D2 z!IaY8^2{2@FDb!!`e_SW?3Qd60mqumhvJk;>kN)8WBg_B8#4`%kv(&!QeM*K9hY3> zHTH3XOd(8t>S*8b#+Q&SiPn`EIiiYRTX>vLsm(Ld3WRSR*J4#!oc}j~60Lk$aPn$>$-$fTKW@(52B7g7i_NTxh~DE zjk4#hh+@&>Nc2j>!SPz0bj_sS_{EOUVJH#k#-ReYcd&U@19swgUh)tRyM$N0EZUU0 zTT;$4_0<35pwDBK!rMMx+*$NDU`k3h?AiJzD^7Y+A8@?%aq{mgIhWnW2aoJ6n>^ws zZ{h&QmEaj1xRGdo4T(9#y`-=px~D@nvkM%sf45&E=nx2B2!hvc1iiPS&WvWget~1S zItKW<2~magW;&iXOb6H|2_{yi;r7o}T@u5lS1mke1K~WPx0XoxAdritc<#Vou6sy6 zv^|m%UGWGBbmFUEGt=mPI*l;aVxs(-{}nUo$z=cXm7^;!=U*)^8_j}|orJaVf3~xf zH>bRY_DSh1pcW#vnOeVa#?g*UJ2Uh!OC{REk~n+KF7 ztr?ve9t2x(zs&dOAMf=`*Wi2DrrO&3K@YY1>4MMhneQr#r#ezoQ6&&miGij3k=^|< z7Vrt}ASzuOhrS{}>QS9bt`Q<=f_yWEv9+ zWZG%)6eZP}D(;LFzKz%ik#5Meh(C?E*Zu20Gy35#7#vSYiV6uQMri@!$#bKIk>I{| zE5pweL$5kJm&w<)nFKreXKKAKyZu7h>28*8?E2&#L80Zjs^)U}eek-L-xfbyPjXr^ z8Jdd2{PT#6=IICNT)Qu0ObtO(7l1UD

    @dRZX`eGb1cID+KC_Ji)TlBxBK{&kHfs z_T{v*Xp1&vF?-Nz7goxTAB?Ine2~6CPh$rwSFGw8Ft3S0P?nvi|kD~cIo>c z3m)Ox>cN5gD494cjY)7JNxM$2L=1#HU-qTh3R!-AQPXdD7K-=~SZGQ=SLx8nJSCUP z#GwqYb6LnBX1G)+4u-q<^hz>;PL{T}e2G{voykiWfvw^AR$@JS*+Fp1Wuvn5a39z4 z^?X`65=|xeuzm7Tk~bsyGV*o$%G9bKekVC~W*^c}+uYUtfc$6PG9&`JDDaj@hC8pF zprD6+B0eb8Sw<0}C3Ad7=J}@_8#t`(pzs?)^=9ko6HDrk~LRyP0v;$5PEU+@}M%DZZ=-b9j$^{yO(a8`Ao0{ zzZ@;MQtmw4)f|)j5lA!+>WDQWJig{hrMWbGm;2v1B!BC-o6ZDRAr(@X*1sTwwGm4d zjOg6Ax@Tgk5m6$15>J3A74bBO#J4FR_%?(ag2&fFWAYt^F&t59=RlaYJSBLXhJ;p@ zIGbxaNep&Quz~USKrm2p2$!(&)q)R105X>xVmQh+pO(V9*5YWu^aj5@pB_LL0I#dd zFpKD@axC2sCK=X$}Q;A2a96_Q=X0wf(cI0NsWZ4&)$dD83i<{@})C4Al( z>e*z^k=KXpy9Co%3s~)KYJB2We-^vDdG|M`V?D|d9QBiDgDPVj5e0w_$cMK+q!MET zMwTrgZ2HsSz?$f(4$M~JEa_Wi|1s_Uf0eL_&t=gC%)DsPJh`H3Ui}~_{|D{P(7P6O?UfHXyi*R^lx>;+Idv%>#dl-pApzKs6bY4(!P$G6XMnP zGZ}52VzbSOAt(^m(;~I|G6wdgl-*WcLCFKZUi@3)jSIaUSM@lVZ!C2P3*1RkgWo&a zU^<_>8e@5MRmzi?$3iCK=69KPE;tmBgC9Y)+qpsw#z zykJ7IRwD=yLF50?t8|4J*hKrF3ntp$3Yu92Bo5yT#eX^?Vbk{e7omme|Go4POVYkb z5&PQ$FRiSZPwc&?ek!i_9t~b>J(Eb~DtgIqFqQ}Pv8u% zi+9U8N`TTpx&qr@;P)2)#0ProxcniYq;AnaF5bFQ8I#|Fw<#@}^vD+*)};RFG){>csiF!c(QD?dd%5bW5HSkN+|10VZj?(Rif%J#pf?#OOrzx>_y20+x7@-g7+ zvG%M^_{XlVF_mt;sl0m&LW&6z<_y!o#b@*#otfrnxuk2j5ZMS1uJR!Ck(Vr z!#@-#uR-z9(&^vxSBuNcy<3z6EhN4~+x*~vZcg8M_=+XqzuwfhB8+hq$LvhPRNr!m zEzEQ#Q+tEiy&2=*Z>73;Gd_PKiWmBW!Tqu_ZPL`u>WBZ)gqe($KUI#%p}WXXf(+Lr z{u=B`U;ffu|HJDC@znM?`X|g&AT0oy(DxQJxs9HRTU<>$-!F?LF6z`(MM(<0OuT&L`e$m`Z zUQWY#YQ02R`^1(|G`{vgXYh_KnuqdL$P4TCUIx_JG(`{uIzcdV$~FG+uQ$4H;O!lx zB|azO)i8-zM@G>`4&WTxC&5@E9Ii^O`&j5)AQynVQ%WJIndZ|b`%j+D7`YN*J}won{~D{t%Ew9NXOg_B zj=lE-snonL`XyoI2T$F>M{YleZJPiU#6w~`5ktoK*bOK5b)^36MBU}Jz!BIT{nAMVEP*M1dtc#Tx~Fsq@s zlcww;Z$I|X=j6V@Fo88wLqyVGP&7<$cMHt5k`u{vv=|B?N?nnBnZeMjz){&n;#`uWkv)6&5 zr|hx><@v-}xjBf8>;OIw{2W44viGWYPsO4;=G_Lv8;{5f{Y7_R`tUz2eY+_y_*zvZvQDOG%O8%pvRF6H3numpmS{+GCg%sK zKBR?7%k0L3F?dyl$SK8_STW2}Wc$jSKUH?)seF}e);~3GayJ`UpIo*f)!q09V)8;P zBaV{wh@d5ORP;vaXdjNW>N4+F$KR2qpAxnwzMh>kfv0~{?R&k|Dztqrev|KiP|Vtc z=I^q6f8pWN;Z4uU$vNVp-zEDT7?MEif19|TryDI0lg+6c`B-Bb#tfz|xd8EV4!yvu zm=dEm^iCr~G4v-9PLFphOE*}nfVkX6IacjUI7U=_&&zm180cToVUlqFDun)(cvhl+ zh;l4}5Ku?(XP)>=&S=^7O=^n4lf{4QT+Fqfxegh7cX>i;j2z+>>z}JBmi^J6 z4q-1f^ZNYwDOd7Qc8J;YPc=7??M;qw%PhnNOAJ^aZ5dSUv+H*_UQY+--Zg{kKtQN& zE$p{N5C&RvGdY>3@YphZAUHn?AC(UE=XGyc2#*m(+(9hX_Ep&XS)`U6jMFD#JLKwu z*@5mHP*lW%x?o|Q7;U!Bp(?AXOb@z&b{MZ!VVDCQH$G4ZdGupnr`3%dR-gXSNB%0U zP`C4t#u!|tYChQ9^`0+R{=s-xe!8RRVj2h@LS9Fd5G5L#@aSrU>9FkJ!1;i~p%y7Y ffC55_zq=Aao|$!2x~dYBLS*% literal 0 HcmV?d00001 diff --git a/.github/pr-assets/5197-ko-profile-disable-noop-390.png b/.github/pr-assets/5197-ko-profile-disable-noop-390.png new file mode 100644 index 0000000000000000000000000000000000000000..fa5d1bfcb021ea49710c94bf40db73dd708f089c GIT binary patch literal 183998 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 _ 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

    hkbP;mRolQs6_jnnX6k@#Yx3{wLNG6 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%0DwqB1Q8dRShJsYkFHw z|C|LS`~Ja`ozF(UN2V?F&@FE6aeqSR)N`&|n?I&dmuHCPnr9?#US#6EH0_4FB~@0C zra3ISms{gH^Wz_se}K0G^j8w50KgiyE{T0W><9sgT=j0kn>SMbChVu~jok-45P*F_ zfUAdP2j@jFNahbvoF_)K=B{*iE?A@sZN#a0;=1!!61XSmgO0H8dWC&)i%}ZkYv+F( z9-!>I-C1)t@o`wZ$wv-CgHZwAWMO+{bY?pbkNc~xvG*QY)a%+Xb}Id>X%BgNTjKRZ z?4)d2&#YrG*+?iYH4eBZDqSm z;Wm}edWkHPAb6?*&24n1+pmEK5MP1w&zJ+yAg2y&p6l0Zf6Ojay_2drWSP#$ze3R? zZH(n|fq&Pn+|w>FC~&5MF;jjLoSuHLv2#px}*)GbiO8C?jqXvk}vd$ z5+|Zwi28iOLG*}F7=1#QYN9AprRdRp?t5O6HSz(vuJUIOTa9&ZSmM zw>l|D(5%^G^{OimKmMMW$f|o9xk=x;kyp5C%O;l45~s#R(1kVbS&oxga-Hv085-@Q z?h?VMQWFhD_L>!RTEl$clVK%KM#tZ_``z|lVrA*zX*YOjxLHDe*xHI3Pz04C2^^CLlAlNvG#AN|=6_78rn36>wKv%*fyPg;FSRCWTz@|Pbxfh%u z;9-4#cb5j&R?R5Xdt$o>oBn&`^(09%Nwg9fdMrI@(x=p7tiL79rwQ>j;cr`>4vqwB z2gEJ^q5dB37evg%wuI5-EyYxY{_VLUJ0w@ye=f@BFh)U8t%I^FB(|+8?S;yUwOK90AfcN?rG@iRZ z(Azcky_DJa9iP>p5TN9nj6S)M;_QEMR46da?dxzZYJTx##Cv7o)HE z55}G$-%-s%GQ8uxw)WK6G7sC(4*gA4*TMs<^fV&N5fw<$ycWRjKkplvuA3Hj^;X?g zk~P7>WNp6m{A%TCg!$6ZhPd>5ITof|9e=dIpZMjiU)5G6g?e8_EB(<)f79X6CbdNy zuW29QtGiL{S*W`Wv2kUEEIw?1BDphlTxu?K-j2I zoA^~+ssE#}--a={NW|Z%G{;_cVf5o!bUz~f8alExGqrC1){rd^JyBwx|5@bF%TOf^ z1}0;>6%U;lzMfrflTx+(Weml~9f9M8{nMon+utrrd2cNGJ%7a9(X&9>PQ%uvd}2{S ztx#(}X`g2;A15E)gZ5NkDs)=dXiU~+dRP86;nN@ew4Y`pD)VWrqzF$P6>&sth*mH) z?TBkhML^9o8rMXWjyn-Vz#`jbO<>u|)czl&*p*@jDe{!Ar=3kO3*-CK)?Ol+c5IUQ zQQZ8gCYui|--Gc%0wmDW|4flL$O#Xv_Fj$C7hftgV(@H{PEF!aTuSDRq-jSVVizK# z#>EJ(yEVr>Q}ccM1p@;naaNJaJ|=?f8zy$wLZA$9^aDc3)*g~T`mM(33%A4Af*l_c zAg$r;9`1)b{wKcdq};}(rTu9osH+ocFWp9~Hf=f0rXLC}1R~*1Nd2>KT1_9-5ND3` z#K{wY$Of6Z07%H70dimzNO72?%|r=q6ez7C@C*zV!&2vR(ofdRG_MQ;40w3mQW9-! zJ~K$@_>fRN<@0S4tanZcG5;1`3N5jnheiY^S@Zd)m} zaDJ*ZVb#TSq`S~75#|{*XVixT8=y*y;#1LL6yc|&2!{8Vv{8CqON%!+tt0|&(5n^J zz3KzqpAWH3HsM{i+gVLnt)DQb9VFJESj#BHKLfcPGj=UyjRDs$_&!am!;I6Vi=u)) z`k_EG@1$U447~oGNZc_87tOhpdyf)k^=~r)>o_LSP0*{PVmDr>&vik3v?ng~0ld)d zsBt{WY;*GvI#GmrO}~TZ#}_Ld#~qh0PlO2YJ(Q1Mpb)$5Yl@w_MOWv?f)q~1y|Om8 zT7$-j4yo79i8Z`zxlPq1iXlEISj@q-YP^dGyka|T$5s629+^jI3j#i!qppM4Q^he@ z6QQpZ?BT>vl#tn!kVZTW#PMh-d$;xUN6!AIaM zRui4Wor~6_?pFhGS!(NalXAS3&LGv$@J*aD`Chutu&z5*=*a@{rMAe{0UFgaOZ8bms8e((;$taR;Uzf; z`WtJ_WX#(A&B0i`Wx-JQvG}JXE~}@&P0X(on^S349@owD#R26JCBaJP>Vr~TB}Yb2 z_Fc>^(u2)_2nGzxTOk>mnuVetv{t5bw zz{Af3xd!!TM4?;u^_01)e_xo0|LnM~m_V><+NMVC9yi(8`0K_?n%PYyQ78G=Oz;=> zSSIVo21YfX9IaF_d@@WublVp6vOQ}hH$@SXl`Gb|beEtme!6brQ0Cnu4B7S922ZMrLN#dUu!7E z1VnYFP~sJxSV~<^a+FJ=2N>6i-#$qmz0Y~X=7KG1dLJ)JP?o8>>8}As0=#!{+IL%5 znppi>jlTRuYF7y;!yBWBFX=0-;mwr39ib*fZt~G3nF!T*(W*OZ2x4oW~T zDbpUiT}GsaTgoC6`BK1*dAF;8hm~IyXAApu;{bXX^gsU&&>#KRy|p?o zqye>M_B4+6=hR^tsYVPdTm39T6BX-UxTL;w5oTB6Y9R{8q=# zJCo5O+Nh<8be%^IF*LsvKIQBcP~Q9W%KP>Z8w-}6`W%t+ApQH5Sx&k?Hme#A5gf)j zE!>FJDv!%m*)oZxIB3*Q<~R`<7!W!N@sSpj5_E|s;jF*I0!ZC zi0_VO9d39I^!53ygr%D20yGDd8iJMVaX<6iMQ)%Q*x(Fp=IKvmSzq!8i@->M8u%L? zlZ(o3dVs?-ME=m{S#cyBBpdgQj6>ksE%>S%@Waz4zIe2MhD;bBT+JWplFVEFBd*8L z1Sex+Fk#~|t^-R7sB*MipHg!fe{)kXb9r?{?r%F!SonMx9m-c`0Nu6y;Xl=*HUP3% zFvOtK54=x#x?LrYUpH3u@grpRo~TJ^eNb|XN@7ilVX^lL1zzqrfR#XKVMs7PuY-P3 zx^{&)t|s|8j;NGCJ z*m;yoPHb!}!q^3rdB6q-Lu|BCXkRMVuVjjx0_sUuS631PVfqI@R??Es-)6u^c_d3Y)k}!4yI1(=1l?{CAs0F3fl!r4E z2C#cQ(yt+=CK;TJcS@ZnXICE}h6V_aHMX`vQO-K&#YRL@jPO1QuSPq29d2*Eax$CW zew$6y1xo%2Bs9YD>2JVLDvtJ24bo}rVqKjS1gls#>%MEP9d|*vo>AP5!l_qEAz(u= zucHqW zT^zMKdU#S>8 z)_>LePV5W-vn-r4BtmxX=v?yv-v+jHurKe(mu3aC1d`vyYVjcvc+IDGi)x^o>@U=j z-f-$IrcP^>=Q&k=KcXReOr{??d=Hk=Knw=a; z08!Qe7+Rs52v_K;8fn~d&`{8dy(=4UE7NxDmEqO0X5yZLudgpClS8xn61)6b!=QE$ zZ1V-|$%{|cWeV5e{uM27&ZVE%-aEgsvFIbLC%u}{kgPDM>~Afp9{Ve1VIA> zsE6M`%nUI9JfrMc680QB<5!WlPe8sp(HrPHG zvW%{{1KxjWc)ZX68p&Qh{dS1z>ZprwyHssXJ`1A0W{6)=Y*UkaXw7Csd&^Z;1H*4!v)B zmBMTGSj&)no=Mmpp?en_)ftdcvFmE>dE|W?4h@T7pt4!{Sx@r#LyZ_%^rJtaH-0!v zu*zu4ss0tTe=6(8$HXAF(GnAb7)P>4hA3OU9o~)sccrNp=C{&S(crtk@KiQgy=eJ- z&vKL!*Kea@0iP3@5=4GmI&(+NGg)A9*$;(x6=(tNG=lfj_^8SHz2j$3;u_fR{auaWJ^U3HaPXb{WMTPD zV9C}}IlT!P3b)3$VE_Rf6+YA1yJLLb8I=sl?N?Bo09!13=(B+4WwJZQBHY|Npk{La zU@I%z4qoqC`(kH|R0*H3sF>mGmVKBYy+jZTf!7J!A)E?_?DyFFbVf#;{$ z{1jmBo{RpOzeYgGG2;;+!2AuvY3j4zB_6GN<{H&~bnt1`srYFmGkde_KUHq_4|3B; zPfy?6NyeuUart#@d;ZX?Xy^YBQRl!@S|whMGN3r9dlLMU34*~*3{Cz9T$ntc+X_P1 zB*?Pr2DgFe76y+L1jU#s2rqR|?No#BImr>2oCY$`@mq#2Nyyzdl2pVbhzJzus{bD9v2!^7o|N*mV0pN<3K<_q#j^3#iC?pOTW{Q=^^>jv}N< z#&2%P84)*=g~{qkCn!9)@P*JbRM2K!k%>ePFN0;MMr;^7Rlx!StdX%(KofzfK3B01 z2GR?lRW<*34e2QW<9Gqw4s1{yw*~6Tg`h3i?5OIlDaPN9I9@N4F1WxnXEcy=E@!BNUibaY3umo(m9N324FLYz@_?+{7)vPF7P+$E7Je1Ln{-C$L>c^ zS6rS!@}pHDMotz$GU(B#r+?c?OMBDBxk+DRCrycn67$*K|I| z-!BhcK)mlQuUXlwqs#kd1CKO_Y_lW*^!o+qcNVc-tV|_FH1Y=aO2hkPxwS+U@Lh6 zo2RXnV=MX3#mn6ijeIaAe=X$nl@FZYS@?&e*1Ef6DVYtt!46=RKwkisqdXepeK%$$ zB^Ohd%qeM{ew4B-_vh-`i=1qVFT0DfeKIJl;XHv}Fw^9!!tp}sKFAs4lSPyBe$M!) zB6(=w^XZU4f`aJEPj@gQDJA6wz_i3htzU@X(3`FJ-V>MN)`=>@To>Y7MH#W+VsN-! z)$z5+LJyg19yB{4QM434iTV6R+9M9Y*i!|f5r~fOcqudtJg0p8a1)(Ft8hTiEPz{i ze=LUAkk2h*Tm}`UmFxY&*m+qhfq90R2*2RWMD99*rPLa`iBHfMMs&2CCjZPuMhIK?XXP;rF_%RD-$nxX$Cm@O`6qBtI0v`8;=xE#E4}QAw42s(sLM z1Y36I{tC&8^IXl&CQb&hY7v)n3`_E8pIL`GC)n&~qLtfdJ-C(L?%C}xGj_57Ht!hA zsY95NlXDBCeVzBNfCc5GcHYA_JpfZgI=^`mRFla=g5 z=)1vd0v^a{UU5IH00Onxt*2|@F5__1FxPaU#(YYdxK~+_f`;)EBse2VD(bZWD=hY? zgI( zG+Q%&keb<3Sy@@APy;yv%CKFdk5cZQKobj56^5EOVu!%gLiz2Gud4`YB{y}Kqv>Lm zg?-$$D_(d#B?0r9p12HZOzzRUb?*rBcN1q>KG+0HlL|Lm@%8z?V2rK%>{Y47~l zq(CizR%nc1o7OaX$~%i1-09(;z^pGcR2_5Ig*=R-`oGtGMYv@hD-aw?8jraf`4?yY zPBkW(0Al1rE!9;YB^e00F-IOvv(!<({aMkqol4m^z4%{`Z9-(|-KTd<<>MqaeXEmu~kP&a3VWH|&%{EBL!jiK*gr{zYm>!Wbr6pn2MYQ8H)Rr>s&erVTxD#Nx;Ju65KQC8x&!doL7&(oJ-t0ry=*ijUB+ zjaEXI`2QZpbUf;ky`yrR9W^HA5caN3avIvZfhR_cKk(QFzy+`%n$|zyala8a?{7=F_P4v2^`*;0-bAp(Zwgj36;^XIY<2?0z)g3o6)jc_KHRO{Z|a63l+kQ4_N zu_%lGdg$TXO`BMjmHHMZL<9w$9G(f=%sl6(betE6v4pu2w!AZMm*b3?w6L6`j2I3X z;}BQm_u{NWoAGs||NG3yRaKAjegO;Me_ud@-;o93f`}L|;h+raC=u1p6~)Oi6JhW% zs^ELplK|xCg#G9Ln*F41&Y8K6;V=QfY^V27mgMzH1bw^gT#e)2@9D(pzSO5(V1p;Z z$nOea8jE)0-(Q)jye2Bj%HDr|7ey%-s=i043R~O3v^a)^J$XCa^brJcbg!;lErnBg zOntV>ge`L6j5u2ekg9xZ{yx~M`TAET_!D=rvov1(De2TD<2C$hH*r_r>sR`7Fsfxe zt#oM%hRa)PJ7;;LW}OnDB|Y?e@;2|^<{JNOQsmsy+{yCq`f>?$5Kk>FGX$L#WqZn7 zt}f1&s4Z4P;Pw?$RVM3xtQAeRd9D;Y94C*(QKwb`s?jC?OI$Kh&s_&y7w5V99S9nj zb-kg8Cgoq)sEN7Vwyv}a-tANX6WHQ+8LS)ZhsRGyUpPcu{ezd77h&)&eKhLT}w-ZlxpM*^<%YAt{2ttM*drCu%-(CpcTnlrxz6>H`2@gs( z>!VJ3c}G3RJijY0vVXeK_9#2x^I|{p8N%3k--X_5x$VPk2jjK;2H=o$ZuuOu+ zV40~8vy;%~85D<02CV$M#joSz-#^rL z4rlGlXE^HuXr%nxg2O;I%&YI1>j`!5KZ6;<0Upy;kfCAxg+#rN5akdVFDsxy0_V=_ z?)=0r&pv9pNXoxXW`7J~?c}sv$d$~#w4;6^wOT#J_Bcx^b>$6Y9p3@Ypd$i5L_7Gb z4B{NXss7u&+za6+o4q6v(62CW%Mc9s)t}1gXA}0nT)-1G7nnV#2n1_bs;O`98<6(? z?OSdOfoNyzbHf0Z(bOOR-!;j!CH zev(m7s#xc8(+*;s%|l4)QVH8S_%00$4CtBqr@MSNPv$XcAiC7Ab}MKj!o2X5ov9`= zK`H-M4Hl=N(Hx}n0nS&iS_5z3N=h&(9Uw5?Y#vG{_@@aNtb`3nCi><65|%`pS*#Yf zCt|qln~v`qe0c_T8Z4Y(tBLN{jIaTvR$`dRV1MnH!Z#8#j8D%qN$H|6=LLI}m_<7Z z_VpfI&0#y8axJPK^%_yt>sy7QlfLy$xy={(UHgj$rsdc3qZM-C*JzJHOBgxUsv{2cMI&M zD?w+w_B#SUV9{JyLY}5fKqBUq^&>%IBM)KpiCDa;Me;sdUyn zXefJ~{7ufwoYw`mRjBxq`wZf|>RtN=)ga|dYa4umw9X)KH?}Auv&t`GvK!%E16_1& zvImymBXwY>H7+w0TzK|9hFTQGczGoEN$@Nh|1~0KesfL?%rK%F;LxxCOf~y^G&}*f zC?1{quZG!ys5t@KnUz_*1}Z98?r){DJ4(tM@BL{y+nzXXa~YO6W3i97<7lHk46&3er3QOluBJDn&!ipY$~QqL%xfdEIpKGn8v!{H54ad_KG<1o64SohDVfu8 z43?qP*IV(`C!9q0x*}9|x z6+#v)nZdYDUt@;4r@A)pAmJ|&Fl1X-`LtV^tI*(!HJ~vZK@=?gW*FF&SD~1lxFo!$ zjry(~&8&bL8PgYYoE>L__bH`EP!iY)*^rsg>C+3ssoTg@!c_loQ^!VNX1J zb>j=T6c|LbDzp0I-!Glh&RGtFvK7Ne&T=7ti^l8@du``r=O#iDiRpZgSI1Dt_q_1& zJIGzv8H{h~N$oaZ`*`^MTa@^&^EI{gXDeNs^^+eK;w)4yyYmL;z%2g|g3kGhwN33W zWiC#b-Vv!|Zrh-WA@Q!xC+oq?-uvrA$>{a%D@IVp>w<)7k!xP9UK}XN z&vvF>*S#^PdzW5r{B5k@#q(SSSJd%+WiM74<7hsVgz#ZvtqN(RO7iB8Z3t_+eObN$ zmYEZ;|MF)l9mB~o4Ghaxn*Ep74s`t1uipax1p&6D$@@sL&Pf{DSpeH>Q0KA&4_CKD zcY$_PFN=jEvV%q%Il6gNRa01TrKFWUMQEOOqR)L)>=?wYR$+{L+l{X(S`4sT!cXRZ5le=F(A4o$= z%D}t2McoNd3ES69HW#p#@TrB|p9@k7#r>>L&s@sZy4#S^mu+k>fHnH+Y@6_vjL3cIAJ)8$WrXYFPo%2V2h{5@ zdY0QEksp$U_ozva*9<_4CYEPmDi{|hK#I=I&0P^6;jM%-MqM0`(-Z<;74Lgk5*2gX z!=Mk2j(~uGhU5dk7aLQTOZ79 z3;CuIJJNh{G@KaCT>{*ZM5PVD0EONcVxQ_s=HTDBz%TE{pv$8!zF*`G1>9G|W7)S( z8sYrEM#mv&h;KzrzwhY;Yi|Yjbfp8m*loW*jsK}Zyc_A=H=box^h8ZAZiiHY)HMl+ zg6()NYu!_`%>9}BRjCSLho36{0b$X3Xq&ERMbLf{qpA1e?`}g~=3iwVQn0HHh|3UU z#b$q;Rh&jyzr8hH_UOmg%=aRLa?O--=dRbC3auMgaEdWqsoy<6gB%P*>Yoj(sc>Ut z>SicYqqsXmu~Wp`gOI&0-o#)7CM1YOIl1`f9kblqN=?vX(5mrZS8uOhr1)SYL38ni9%~GQ+aazRl!HkzMol&vL>%~zrJ4kqSW7(FA z6=NxK)6ntW|EaM|84!&MZOBnfVo`Sb)Tv1Wo%jM=IVFM2=vqxJEm9v~2P7-I;Kw52 z@cK1iyHk;Lwzp7}EN~4DxKPm|Ex))pi4pHhXoVF7?cjH=Fn0!o0H(P;!suA<9{o2{ z(Al);@d9M)c#P_gztMMF)A8}t_0Hf&k@1}h)XMYc|5CKX(`=({5Hq#uab$q@DLZdz zWLC9|W6-Y3T2CDYM^JQzY2`pE;87aI-ew{*58=FQ_XQASqGG_^{BK9Z{3IF<#jWsR zh*ME_dwLQBu)x>o4L9?hJgMdIw2k3!)bC{OpDOs6k_8$bo*ngPv10T0z-e7POLyPe zAtIi3ow7CQ9hdhPl_kAkGko=D55eI~cZFDpB)s@p3i7w=M$dG0dd-;cD<(dNsy}(0Lh$cg7!^H>IW@-$n zo)fR*{MSUbdXJqH-T=viPrTXH){nw2_+Fhl@cl^*A_K2Em{Uo0zx$EweQL71C#6hC85S z)H)B>%S&-+2@w%Mwf7ZgW~=XV2!{-i}=EhO2FopFb9awM=D)5M=YpX z32%%m%yV<^U^1`pi1apkzpy1y;73A2k{5hmr+<$&B>j9sWJIk#X@igO>7H39x^^%6^e4xLK*qKCzejlPQ?1FS z6GWDWkoq4j>Uf9`fG;|p=HOAJ9W<3JJx4NarxFkPF~cYdMLrCZzt1iJuv zLkW9WEyx0JTMT->O>#pm{D{!{4r>JpKUJ0=SDpV&Qw_O2@zRwSd{3Ch93?xUKF9nAFB=sgZX_ z(n~c@S2M?yaX)x8S&B{0T@N=ksPofF_+r%T04@VkGWWrtdurCqT|5Vk4pas?<#j+zWZ8I*^`4Y`D7)zClj@nlr@}_ins|cY z)UM#@j8E8^ggdaBZa?5m4x?& z_Tf%Ik6d1GM+Dx&w-*uniJH;|!8=DV5k?$})hmN@cLMe4;V6bakKaWS%1JE1^hiQi zf%3HkGTQM{gD3B^H8$YI^eM*>8Y|b0nzQ--JuFZZ677p~*};0q#Bz19RSv|8P)=mW za3Hp8gA*{|tKmQj{-K(}btkKTu6D1r4_oIalue;=zVLwl;&jL8i?%Y+ZxU`phabPx zX1$kNjlCQaUyzUAl6jzDb&r;j;wJ<$>l!LlLN?M*lQ|uZer&)g042MNtG_SYl_9GD zkM%_E`eN1LgjyglyYU=0EI|}c5Gru$T$p}Is4r|KPUOvY-&HmEQs#i0_f156L1 z@fLQrj*gBnGKFZ8J8*ZJFPj@y+-L~8;rLUtE9-y0f=)!-^Oke!N}M|S|IY=WVq>gQ zK+1PI>^bIcEal*mtyIfK7#8OfR$>|w6nb-}``Zr`;jAzgS=6|FT!Bw{PhRW^nPg|g zWtv#(mNDX10@uW*rnNx73kZHeX6HHMW`+CBK+by8Bgd}6>tNM$Ujqm?E)aqvanOE)@$(RD`fJTz$~+sY+ket2eYZ z*zeR=Cxsc@doGl&3h6-O5BZ~?am9W1-&As4wlBfqcZo^FGLXpJ&@m-$Kgs1`rlrVF zg^V6GlOrWe#2LBfyA@A*O+DC~!p*4$DHtuaK@1JC9QqWI!DGt%k#m82p4rWQ%H#Z= zLo}k~o^UQE7b(fqeO~-*p5E+r&`uAY3QkvEaz@k=7v&Wd6|mL$nf-mWlQm&K9%wcl z!Ivsv{l%&uYqAZrN3weX(BSfu5}HHMgkDNM7h2^wSna;FA4rpW7%%Sk=lBNsGF!rr ziiQTqF?M;XJonq}a2URC0h^t|GcVQ|Ml)Lj16d!X5=C&Be0no~#A5Ve9u*TZ57)b5 zCOSRpYRC^T%4FK9MRFNuK{rHlM=L1}&0XKBCyhU3H(rw0nU_jSuy$vs|ILFJECDbazR2r*wmKcY}n064H&7gmi-<@J`Ni&iDQE0))NS zT6@ef?r}#F0SdJ`L7XKV$6u=q^H(MpS-!q?iIrVCyzI7F1 zuit8mTM@6E&d73`B>eWObUgj{54Hjx(utqj+vFba7=pp_e=Y~@g=wndYV&Nv{pT|53j>T6a66hgsI9gv69nY<4A5h#SQ84Qkm%{%<7 zAbmxx9&wb)s4EG*h#Uym5o9a&L+|&lGw#m?3`E_5CpPo~zvqpvv$JZC_a#jo&+5s~ zR%9afi~ML&O3vglXfUK1TrdwP@%JwW6e0}hgP69C%DFOmQ4fFsmT{He9L@~2Qtz0K zb6E*Go}Nt?gJ~xUU?2#e&v^a!oE5jVDtX<- zSTeQ0zdx>#=B@L?H08G*Ucq4EaU;cJDe#gDA*C65m3U$p^S(x zK7XmS7|-vOc!Hxq#YGL!l(2&ofq7V)>ia!{UiG;K-l^|k|989FecHkVk#THQXA(xv= zP85Q+7nY2^BNm4R3Qp#*2gJm35$KO35YzXN^VMv!`|;y*;r0c}l%F;z=q|&bLYl7j zG!I8>K=*Bo$7M#+ay$JL&T+)g7I}FBM|Q*XwCZ4@aS8&Ps&ZjGD71E*S%n)-0F<98 zd3l%3%*Y`J&c{R6xD=3R=1wx)S#!Wx}A$Xn{#wH_^!4E({^}l-HAb5sk$2RV>&o_7m z(5Hz1K8hxBgI4Gj&@6RQdcE8baw>8i-jfhu6pD4vgY<*{Pke(LH(85))l6J z&jx1MTVS6jiJ}xNo)4N_5EC31k)pxFBbTG^IJn6 zz!Aug;5?XItX(TMFKmY277cU+%mZ*Ef*CdFLI)ne81tHj0($}OCcS(LjA&TEzbMwj z4#O7f#tpscxY;_RN6P}>V2gzPg4ndSv1@m_ zbJcAU#i&sR{C-J@w$axy{S`tV! zKiLf2I$7Z={8{*N3O-5Gk2Jrnpox#lRmh7x2U1~QLLk5yua5OxL@3_jwAsc&^UFaF zp?`+YY0E6)q6Mrff{mL-6ALiv&isSga?SVwLwYiqWP_WhK45EhrZR(D4zPjmP5{Ak zET1DZm_n1q;|C%Vo_ph#B>`K=q4dj1N{oPur##K-F6RJgDBNS2LIK$c2B?%z;Im&C z^JSjC=6gEJYh1>9kucU@8g3$GWO&Rprd=f@5LlX}!<(y?_;-7nP}88zoE{VmG%a^~Ik7`;ZeePplJGaY z1VIiXm@pVMnuTxJza}r|-J5^^R9UIMLa39$?}BxTBA-GRJoQQfsI~|aO39{HI-2jR zock<)dYl8E3C+r_&3W+DQp!AB{Tb&8-9YfQtadpya^|DR041y_x-JjZeht8Pu+b<2 z0Mntoj~#RL;qL;uPfrkln;_u-7e^Dt+Ce!>P%GDMAmk6II&-V|i91Xp8o%U%KJZ0w8>>+BY^`SsobX=zf@Npl&qX#@o z;M=4cO4AsP{yv_+>1J}zfI0M>f04j~=x&|L&Em8&Zu1l17)v-^11`>`Vu9Uvr+{?s zdUL3zI!l4p)6;Uor&Xmb;`cB%ERVg`X0uyXeWY)@R0-|-1cb-0fCLX>En5Z7-nb5f zZUqGgg5TrqLk^N!?i)>pf&pBYO`TeOR7=ecw!(+)_YL__mz^)e@Ri$xricRr67j^{ zU%xGfdkt*VY{~kp?rj>qsPm%Tz4tOp&+BZNvgME0=_)P$dVy#F)_T}hoj<};;ekB-P!IA!UF1(W zo)=eo8{l{mjg{L;L}tZ?3gPDiJ=$0m6$$AzX`fU<|>HkQe#am-u0Eo(++JF~X| zzdSZam@CFsB0^r28GuhiBH{}349467qgJJ0ojE|?MF@EWxGj*fGi$WPH2{a*BLL1| z-H_AlTn@)0D^+>dq5eTP^A#pv!M6WuYHAARpVN)$VMzk{uKrgdfH7Ix(QG6KR!P*8H6Z=rlLi>jz)m-a*86XZ4KzGz)3K!UpV>VYgEnz0 z09<7mactJA6`D?W>%2OaV+N%B0ixMgq9njCuE9BSy*IA%kqpYXH-r`d5zMNEuiZ2_ zXB^kMZUHbvD%euMWd$-#JrIi%I?$|z_I&`qcTu232s{`OCbG^YfY~wZW}T5i5pryd+W)Aj^{?qF!t0bgHjwn_{Nf*54HLj3vj=eHDk zFmmgq(#1=JgknU7fCe@G8M~~D+(HkYHv{alLX(AnAVB0J5y9JCMpcOkz;!Ug{T@Q> z(e}6upmo57i*^B!Cpoeu1NZlEz^6UVzeIq$Cic2=3wV z=4Jt&d=kX~V4G6)zc~RYseXqE9aT35_Yc?C6zdSz` zN}~g4>h~Od>y|&r?1Q>?el603=uA7pMuJ|(&AuK$)&tH0hG_W|UZXCsyg?`8b_Uzn zi}L#VbC9ZMyHLk6mCE=2Cksgb)a^GtS>|ZK6gs68@N^BLuJMulssmWB^2jlR;qoo@3eZY{^$Fu(o<1iQ<8VB2hOyM9 zW@U?8$lG{jubnTfax^I{2A&NXmft@`6VQX%_r|t^w=Zl6=Z!YV%e)7%+s!##K36zX ziY=cgLy^rWVqErFRV{zyzojp82?|5>KiLQH_W99bHGF?Nr4zWUSi>qOWEcbwf9B}l zzZY!oc3P}iahKtAAt?IJ7}26oKsf}SVz>S8rPiKGxips{;mGxdeXhVv4BVkVpeEWe zEH`P5gXaz`AoR}i*1_}5D;V+vfm7ZO!*e%JNCu3yheFfiYiWJ+4SF5(Q<`$a>}Sr* z(P1c2qhIE0YVD|`P#?x*Q52T7#__QnBk&(L$^Jv$!C+~TRl%ZV8DAc!_z|5=tVSg) zjPmTTbZHgQA3l#_I)=v3Xt(uX{huE$CfCG1#+*bmpJoeby&n|JgS0$pkcGQSR2YM!@qz^}vo-*-|QftOjb#n2)+N)lmU z`CeIE6f*=OGLBZ7H35&@E>jV;o1w7L9@4SDc|pVjVM9%HY`4?1t@oviyo;mlFiWPQ z>L$W2?5&~zbUWU0{wRfX^CJ1>P;jMlRA0ji{|{O-k`_SdDuzy4rPF{Bn@qbP<+%JS zG-$qqPaSn!XiIFuf@lMmJ`OELeGIBUSK|4@4YiOJ8f<-t(5%lGytYkLjj2f(Iy}C( zZu}1W*#5ET7^R@k60*`plv<$;KBno@-0-Tm ztHEAujd7MpKjBU|S}F$yU-XBksdZL9z-wZA}7AkXxwcDwI)8pHk{7q)G%D7}{_)#pKy_u46Ocf~D zb|f@0;+nVl*o}KXc7DX12hzw$ylKv;bv9*bd>56yw+2-Mm4-8La8KuGowxiD|G|x) zZb;tT?88V|Eq{?-IYZ%BWW~0jHyh<`wJyFFX=iXKE3LWi%xd!kDY<9|GtF$nsp12t zg1RyGjeF#}qk$4;{n#Nmthqre>R-KAt`GN$O)L7+nW-;7^}89$_c1I96`d0`(`o-O zn8xmnws%;Dq8mTuNX*CCR2t|FYfM&}|F$;#=!U&Snt!@Gg7h&qB)zsY!tJAs3fyR6 zeH4NjHoPix2W4pc#2Cvw1GZgt+lDi~E|sl~K3>)uY}Gk@o!N9oiWhe+!OR%~A!+s+ z$0gC9>@`TEgkfXhx6a7wil}UC^zIF(v6(TF19zs45e+S=sTmtJk%;`s%sa}Pmt0np zIw>A`b+foLQ@h!6ZQnyMS;`f9Ely>Ko7+oOM*qXVzrx7@fR!^vwZu%B?Ih=wkxT-4AEYeoxwZUwdC#ExcOjBHoGX2&5lQ>`P86 zsd|27u-?XV4qnyP4367-iF?a1-DrNHbb&GHP!g|8x`>R-X)_hmmC=dHp}f|3QsJpx zK$d8PFspYuN5N+w8>!rc*X~rk*;bg9>s1YFz-dRNJ_tNSbM?gNzK98+kO}~Aox7Gr~;}sW5OvRWom4vabu=UOtND#nR|ntQ=ahrh;}Cq3`c6VP{}{tyWKxA2YsXREx49T|6`dmJi9S5+ zApOo_Nm$R-%QTiucd3RGhlRX5J4Eg@`$vosUSq>%=oOaVah3`nmzU zB-N{TO-Q81>6vRC`;`pQ$QU)z`xKJzqz+B$jd!vm3R(!lGMLlJt&Y-RU|Q0a=(1Kl z9k3PVNB8zh&D6Jl%Iy!8X+wla6KQ+#?J!?`92d-1Iw-?HAKEo~m+OyGBh`A7(HKW{ zji7ss5GY1jM|pyvDQ*Np8oTb^rFZb$66>Tq5%x&h)*u+wT@EFUyEUC7R!b zHI+waVr&2LS~%pIMQxRQNU;9gMrypByo{8aEnnR5mS>Je=cjO$1@_kc-xQ2&|n__K6;^B*$hw3X?%ifY@!X5 z9P08Ibc+e&|++U-3)qa?d7?So%z7RpPR?Nc%CeqDppQSJ@TMy%j;Scsjj} zc(<**)}K~iR$Y4s4<%5wnrVqYxmQ!sj5zQlqMPm~5;WBUhGDy&1a{2HCR%4ULa9eY z^Dpq!M)3sf9tAfW@=&ce2~fpaTEn3YC}SwxM#84cmN**-PO>G~I9fGvq-%M$M|eY! zv2^HZYdq*L9{Gk6aTa^$i$yz!8=WEVJkV*=7{03ZwX=m<&m&+QE4@eXEt zNm-@kV(X?t5(hF%m>n(3a9+kEv+EuZ^a^~XJo|c^RL9YdBRoNc6r;S$AV^lW`g5`StT$28XD%NB?D~qSM zjnKyv8pWwi#tbs`l?E=gU(+TVeTTj$j=pVRx=kWFQj)}vycWXK`{Pg!z5Cw2=C4&k z>wUw8Rz~UjUb%|IzdY?5xjRd_GM4v@-b>5bNtu!K1|6sVy#(?yX@Y0nl%j`rJSU8k7CRe67{hE()%!LQlfs+9W&kJ{#3Kiq!Are_^Jdq zm4*%k3*X;J!>Ie~l916HLCCN`))<^+v)Y{b@zUJwREDgTS=1X|hRdmhwPIHrsN!3$ zOrl3(os{kebJy^TVLw{rE+aU6Z0a%nTEy4dndCh*)hS@h6VH4s^1GG6ofr8YHXq7G z)!_+0RNG}qiT!uX$pvi|6Za@n*R^_#C1-Zpl(MVKy;i8Qel$8kj>_lwWz%UaYn z4-Sk?w4TSw8L>l720~g<)uvIH#5EdGf>3Gq6?Gk_qRfL5GBMufaRi;wy%T71=1&5* zR#L(!i8$*uy`KGQ(p;;V_u~CU?^HgS$7!Ctz4dpX4+&Ex)0VaNpz0o9k(wvC?hs&R zz6Z|HgyUN50`>WX5&R(jO%B7K4C?5;{jEAm2@S&6$L5bGSG{^<*s0N;a9Q{%%aIu= zm+wQ2GO+#tx9(p9yIb$j@ ztM8LW`v_c){f+wgt9>fKd_ z!;eKv`HqZ>0;z|gwt}a~azdCiF}b+k$Wt>yvvWMkg*jzm%{SVRg?c+YW1EWai}EIB zsw_GGin7+F?I$>3T+#?DJ0p{e$*5Rsjk2R-Qs>7WK2~f@Oy4o7aVB6_*C&i)e*NM4 z;Wp~d+d#OMC&V^(H>tr^ZPZ+M!csYtn0hj|?83rhH$Ux%f|>tK3ld}UYMgHeR(e7F zY;3H6jf-mI!l9vrlNrYGf>&qZuaU>h_1dl*kKYWx`>o%=6NcVP_V0T}BgcFomKKIn z!CG(ImMc+!m|2brsE3SCe)!ihD|d5<;SV)Az#vR^WI%;p#ge?Szn4x$l&L!^#u*`- z(l|U)=5S+bh0}gG_GW0ClDMYUjqA9W--QFBa=t9jZ1`_^50%7FewRxQ8|H@>VehYsu&=S+gDq=v`3lIs-7YHrj_-f>%Ph>S6| zYrPFeXzRQ_6Hc@TWjG+%#JYG0hni&O1q!C%Onb~BtD)6sn~YRV&*d1{xXGPgwpWLTkgL(d`73`OVN zb#`=9^d9uICnZGA)t@wlH5B8$nwEO55T%lWp9}OSEhZufVM7f1_4FS!sB<=QYt&bN zqP7%_5&{C(P*&@>pz3AAiU~|2`)(scITg0H`QD}3d_V|_s~!pR=vLn@-P#}02H(u> zxD{h#NyAfwRDow&!+Hd}FG3>&=}g8o#F z!_LHh;V$T|Pj}Da>g!H+wXqLw1}9OD2cIu@?guB#$%A=k<@iu@_g|DpRz*I1xSYqE zO`dx2bxg;Hy%%!AlFrDt1F<^rx?<}wj#6cXl*JX%6Qer3(R8}|)seCZ3aMW<`PJb2 zv@T{UsaSe%a!HmxKyc~RHDwI_#2sD_D3RA*d(kqt&fp)?jjhJ}EP&fbRfU_T<-m>P zsw7pDBUV>4lFS~WgETJV0liQgRUY%JrBzM_+sqTckud(uf@RF&j?>CBZy(Qaod2F| zGKayj1$!e$XZ_PoK#j}x0<@}an!1mPW^d08f%Gzi`Y#-jV(o)k=ZAz&X}4pYSs9-8 z{Oc4iC<1?}(VzG!sYugnCbA}!84Rq6}A`-tdL3t-){yEc?_eyslZTa`DN&VhhUt5oh zLmM43JlHYYlmw=8#6d5>;i0*3xd-+Wl!pF~jp30dz6ip`(YB1S6bCHAp6Kb1L=Euo z|Az&Plz-)-aLvwf>D|ZcEmNdR*IH-ZJoq3Y)1780C1|HbZ?~6$r|Gpf>&R|BPaA=N zj$Hk(P_L@aKtISgZoO@^q?IvGz{7D4(&MaQz*x=gnD1Mv9Jhy%;rG-F0&+(kJI44e z;=3JJh933ao(~G+vNWcrq5;LG&T88ulgNxeDG7u`J|i^B_LvXR?qz*ddpFE$-^|_Q z?TxJi(ez%mms^}i%36t&Jo>?UPYR{iyWZVRS&)tS#lgyfPC28Om0;Xl>7O&-I3s5b zZ5{DYg>PEapp60YyE{4id+QJR_yTQTemCrQJ}EXjtFkSu4Bzb_b0(|Vpc@#S=(*Kk zVW0n+v~i4-gk(Ai#ymsx>Zg{z&Xy1P`ot_oY*RJFxG~u-4d;jce=%gRdcPJIB1LNTx&Y8JiX5m8##oVX1I$nU)&S@7iR!ldd+5sI4NT z>l|X&dmE!9u^l(er1X`1WD>?mJv7nU{{%wf}bHV(aR>r2UCT`Mp^zraJ30mCb^9Ggpc$>Sr1FwEg0| z$nfbunI&yRNaSV*{S;SDT_e2lwvHl^(aNfX2E`C5^ArsSlFz9e@;4-8X&b`nDq&N-m+GM$8O?r^?tV*?SVM;2EfYO$ z``ig?T-^;?#2h1Os8sk1QXKcpOrNawupYp#3ijlL6jzvzYmcO?I) zrFj)gs<0lPs- z;Yi=v>-@h_agbkM@S#^=?l-1Tbt=6-x7=<2MuS+%+Ed!N9m9`+JB>1PagjXu7Dbw` ze>nm*bA`jadJNw=#N5uVYNIZ@_(wvP1T1GS;n{Jkt#t==YS4I-uy#F>_h>satA zBc-PD80c?TCMB-z617tM|$n@!Z&Js3?C^HUf8SO>tv~rEuT#KLSnuuoXlt zgwrw3{111s#V|+JlO|(+=tC7_b0t&pXGCrFX#I|_?7SP zM!kolQqV%4#)0K6IsNWo^72Obs%bOawVger12f!zMWk}}66Hq=_4whrteXF9-=5ey zUJe}oP_*|NAo^C{2s^(n^Iy%VT+1k=m18%tyN~itQbzO8qMeoEMosd+7z2umPSl|P zlWQhr2HBA+L`h{E99WW0uP2bkY%FKLi`Vl?PfnxK3#RdiUjYrqSI*S zxY+v066L$&{JP-({u)X!2bIsQQz}7n?ToY=cI1dV(+<`>mNfQ%;o)Htf_8ahFKb75 z6B1kK!wLKO`S=bH68s-A>o5Zf;=mX;Za0Qh_L|lt#QeG=G<}~$i}%afQ-vBeB`{VB zWzwpCbt-^~MmuyT<>e-ipPB43h&vMVcCj=wPoWUFV&UH>4qXnxb3~^CqL16;~i#qGLTGPYqk|?pE zROTpU{3Z$o_;ZGLy6uPc_$!cL9%tq*@Z5YerwS#MCDa3M zBV53@(@3}361A08NCqrW)Bq|C^ux#|#ii5k6MQm>l?MI$GD7VoV4ungn1uoi3{eCi z%0&bwn#%G=w#VIxo*c75pRh8CY;0i-^TQOyjOlmwV3=dda>OP zOllBZrp7bsX%zC~DBwB)WdtbrC`@D61@724I$WNB`V1_B=@E9228YCeZw)Gz7Do+6 z2*q$z#^VCZ+^7*uq`4z6aZ}yVD%M&S=>l>FJ&Sdk&a}chXwR zJEI*n+6{O(svncg5Ewc>@V@W&D~&$ydsOZNeiT|ERPg_vfaLNRJ{qvI!1Z{W%OyWc z1H+*Vi2sMUcL}>nuS#SZU#gk)VH*uT4$*OTI&R9ndT`Q$4fk_(I=_89(hHqP5w)ziT&dxHttKK z^$t%icvx5itc19!S3^_`8aQgT<(e{+1upwfJSi($4Q-DW(rtIvDEb|!&M!ZEff5PW zA8i3u2B4(WsFlco6&Q#fQ7TSgd(RwV@NJM~00>P|oUxA=>!9a8cDdWw&DZ?7`Wg$| zED8kN{sMXy5H+(Hbt#sfzp?q$>wkO~j*L&C)@&Ky@_W|*`R0|x1G1d1?gNvl-d+K2 zYOBKBz;Qx!g^0|sPkwa&htfr zgC$UgT5LDo?T`lo)?EYp?_qK9?A~0>+V%~S-Jh>{{k{SoUUfi3Q3{-AfWONemnshx z)y_lXhga^aMkt-ePd^{zUu>@t*}oW5>^`kF1VGQnbK9sdRT&XK_W&kO*X=PN6hHi) zI{UwKlmhmvW(5ITfbfpGsQ*9rtuN08 z!gQ&OPJMo`R|mlOzf6US+-HAj0B|B-;1Me%omHF+`vGO65vcp<t!a2Isa^F+xj+D# zhf6l$1Y9qh_0Ncnqd80UDu7M|BESI!Ga{@f+%6wDm4NN$XZalM+A(0r4c38Xed9jY zzka+gblp3jvl=Vx&3Jl5H|+EKJyS9Y#1D)HWr}-DT2W~K^2NkFj&3Fm_=?QFe1O#{ z(X5<}={0uNRLK_(mQG_zs-udmLX9BzI&a zjWr3z-Va7Sr`5-k6>cq#Pmu~)H?SaCpP>qa8W%qZu}raRO;yJ_@U))7j_jCj0gp<; zU>=l8RksDqzg_@|7%XkM%*S5y%PG~7P!DGStLPG&jv?U+1_+Tv0WV|lv9||A>HrP^ zSWaUso`J9)5Kz^S$E??kge*}vna^Vf$l8N))8LX%OV|JG1ulooD@$M}jYckt;@S*s zFBvsTQ^=*3BO5>z^Z?_lI?tiIEv5D4aX0ax2~T08>vm^EuCGssyUT;JRL~7f}~dbaLUK5vC|L zQ^a-5!OfdL*Z5-#*Wi6bqQ9VGLBpegH*O4wzu~5RKpeofzInMzFFq&d@}7K146u7_ zZ;uuRvGhfDzQ*1k6j1L4UmN$Ml|3HaUH_OivjIw86B7y}STARwD0@w`7xkA32}6uR zT5ES82A*a7;uz$DDT=xLz!^~)5HUXeLiZ;Zw4VL~*bm4G)>`tP7-j&0uy&Cd*rHpO zE0cnHDgP1{!x8wihdkh+$m?8GIyLQ$_8@HV5esv$9m0#GhUc#_wUl&RL&#-h^N9V? zsl1nWOad*{MP~22Jz2p01YGG?XJ=~F`E_Xx&tn%hN;P`Fy@C9R+-i<)v z23X%$;6H*&gN%fv-{#lpd6|^N2bl0d|D1EdO8#3WM{0lnCeSHt6SFNMiPz_gRGP_U zvQz3NxE*|h_B{iJc7>z|6Z!tvBk@{Pjj%yQn7>FX+%Pamg*-l;`vL~0J3dfYrPZ?- z7fVOPWmyvq7i?%F=_-QkSnrd_#S;sUjFb`tvYb+djEE6*cROIW zNL*zN;wQn^w1CFrYZKrlb@|>hSzA~$?|sX;pE_LwwK^h)$9!ySdivfq@NbY#Jy4<| zmZSV`v6&0;7X%U%6*4inYc4|=j760KktaaE#Jz{Lyai!Mqn(ur4wu%@}`918NdX@X{c1p@}6be=10XVqfvZ>{Q=TJkH+vxR>Ev8wg)_aiokl_dj;Ju zO>_a9P8kO;U+AMF;D&@fwxO~a)G-?o;F!1d4wUPE%$W`iyx5Y+zPrB{`?${xl13mi zhr@)yX`~8Wr2r9)xK;r8-Oc-xld{AF2oVc_!9~vR4B`8GJdLef&2J=*u&_;nC76&? zZAW?#k4`0@84u>*M_#!taa^AXFC3&qhFIVo$~+bcbmkDCr8AtJ)M-`oX4*^C1hK2* ztZT9l7>hHEFHPlh$;#b7?BRELp=#IYDld3~>HusCXqFLV>!|Z*?Xe0#V=nV4l(3X=}>je-)L7cFuyq6pS=O; z(r$weP>hI@p2v$0SYo+=ALuJ~X=M{hf?4r9RDtUMbhfp+Cj-uYt>x;=HUGyu z5*O6OsHmVd|E(_)^2y+XpxTNmA_=q}*uu7em$nYrs44}b1ECP8uVR821*I&`tSX1Y zFTckl$*BB(C<0#E*C$FWpd1rl@ccb%0a}&h0jxoCrZpg61cFc`*7NVUZv;Kgm{}K^ zv=k0gSHR~Q@Sfjj)gbuO4KC=i2a0a@^xH~0LA)9>eIY7fHCE59u$KrF$Kn}1%M@6i z(E^?}MnU54-nGy{sOO*)0HkhgHa|d-$3o8x2oDbq-rr8_>+^(p^$)F3#K1=WxZ~$$5fA(~)TAZ(U&h-br^wX>0>*y4$G&y z{+eK9&N8z(n#knPP+b!*o5%t+Rb>w7xNw~Wic|(ydrSe1{F?3G6YV3a54J0Kum^uU zA-2iykW5b%+2W#1I1BHP{Q*q7X1Qc4TUb!35M*TKP>6YJj2=Bhm}qmOdmn&ef&%p1 zv4Eahd7c}T5?b~Z$U%l}i7O21$ueoe#Uvy^gakI$G(P3M?~i=y(Pfw2s8|SpKVbPP z_ld;-O>unZ`e>;?ki~dH;z`W?qHq=O%NSFILm@a;r6N#*VKmQysw>*fxW_r!_rs9o zs7fY?SEt^}B*KQV=ytHO{@P1woY#OZ57Cx5Xs6++gK4+i^nEIw z3#zv_^p`%)D7uLdTLH_HWwWm_5=5)QMdziCZ?WkVCk7t7(FxeMaGfO3(U3y8H&*8> z=Z5bwC6X$Jt-oM=wOaa?{AuU3B7QthAe7Vy7Rk}bx*N6Q`|S$kzo*HmVURz(FolQ| zbfMh>e19dOy7D*sKdP)Nj;E`)uloJD#$_I>ECt-s$R3{(HD0YMO_NZXZ1Hk2EhoVK z%UBziNLPD{40ZNxcXUS!7}l0W1B+O>cLQlf19&-y1jJSu*z^f=ne4z4?Nd(i-jb}z znPHto3Xr4JZFGHG3K-TCA`4#Uu)#Y1&qd z<7?L@z?rflsZOJJW&UbJ`3|TkMENsgHRju$#C+EM+1Tn|^~6}t!WpbapK8K+nYi({ zO@Iz_soRUZf(DFZkuj*X2-cFjG_43&y(TB&qGo{k_VEUO? zU0^&#B)WGwC$oZuZ%r0Zz>Bvx!2-e+3>tA$=f%Fu-Jcy- zFpwSi4ZfUCC7C3f984L0mUbRxDv^na=<(r_(mE=B90Oyh8ER)CxeD{9R7rG7MA--^ zC`mQG7Z;F93|-G}s5H^PRzpg*fysTk5*GvGV(%J%d-#dD6tMl@uxS-ZzV+cs(XE5S zz`HZ$J8z`!B&vU(L;U5!`?~?rv?dvlje+o{T#=7u5>Kz3e0sloh3J%5JG2>83Af|< zdRtGIMVou9KX6|SRD}rS_jMt`#{#seAAoZqk)1q_#IA4Xu7_CpsrWlaAJmsx7@;RH#?5abZQy7IMuvxbwDSpIMyYjfDOckR zvIYEm;KpR-iVh{Es~wbnpgJf9-|iU|{)5XI9-wo+SG)Y{ucx;Py1iEp5CLj>-@#17%?OpSYq zg26_RNM#0xp51?yyJ|e}$%6t{B@`a@+3P@=-6|v)Nji;!&nPyV_g&U(k0HsqigKCa zomOoB+o`JGxDrw0u!g%MO5)B^P;u+f0Z(bHFmn{GcZj0&%2%_l34MJ?Iz#ly=71>Dc2X-21!25|iH?Gy7T5)a zghbbiGJYFDB|f-N0|qbcjoy=V?{cky6EJWNQfhZLDO)3zQ)ogdIQ!VA1XZ(1-LqAQs7;ams zD-!h%HbMg#4Xy1X8WyuBf9MJI3NJtQI zegH7SdXotZed36Ckg$O12oUOJfhOFA#}<1G9zG|-YRqKR(=G!Dd9N>Eb<60IDHQcm z)NoQIg0dUQf$HoU4!>mgcPjn-b~m_pM67}lV@$W^)~8T`sDfnMvW`# z28`U1pvSRtCcn!|Ff=$Jh=7UTJjtM}kY0;5r3>s$NDwNqW~CXN?>I$H@h!L9o(#ax z=A{4L>?5D$2=ZusasO;Wle96bK{LT_kr9{98YRAP&8Y)XRE0e*ASo;Dt=plVEPgtq zQ4`~v$>X+vxoZefz-ht1c?tAYiEc&@L@*NTQP9RSwpBVGw@MUD;!*y_36!v?ITJ%L zucVeMcDmjkxrvEA;LoZF)pzrPI$o;g+S}9fWsC)XFHg|x83@m0Q8j((s<^)ca|AJe zO?Gpn0E!r@WsE_*UmU9pgA83LggAG%C0_%9xA9a13kr|j`ZDaLJdNz(!2#R*YF=*k zNQ>{Ur7W2N3dSxmUqq*t^9Lb}jALuA2AvA4dPl=W390~(G`_S%nj~~6ku~l)zFKEo z*!ARAx)hhLy?z-MHg|QmRDG0}>_c*mV61sd?mpKf63Sh``xypU3BNbKUC7WJrIA*Z zn)Sx87`wTGJ~0tXAkbiTM2Xl2V)QLC{@G@GA{ecnOr^{0p7gabMJ{CwLn!x@ia)jh zB)&0SIZqID=d6JE4%9H!`nB0+`Ho^QJ^qggpgXxakUHwZQx$l5YBy-Q07wrQmgxQP zeMaJZMdB8MSf(ZHfoCDYBL!yjw7jgJ;!&zJqO|Z z%h8~~t58G*8+>j))o(PqMVc`-a3741DmexGy{U{uCrhd*0S-O$%FOu{hLXD855$<; zrlv&1I3vUiaL?Fy`%@+BpL*SY7Yn=pjX&nAV4utrO7!;mrk>k;1+Fr0jSgwhwj|8v zA;^G5f)sDTtb?olh_%&I_y~&yBsw^2kJkr$I!s^XGjOCnIY;UYk|>)4JL6%BX^f+} zaz0XT5x0F5>mijaPF!QQFmlJ^d&By-2e0|&&8OqV3Do`b}q|2%Wr9P$!H;0>&o`b4%RWy07D+BBOyHkGd}^rgVVN5G%l-5Da4$zY|0yyPwKY4E7u4`ZhnctQSzyo^3VY0uX?!Y}J%!$IIG4Dhb zBJ3n2T>T*ZYwRSpCzvj^dU^u;1LRYjA{{XzbqG2jda#YSWMvl)ouPBYFb8wA!h^`4PY5R=YLzQw%E)s<^wC5 zmF9ylA9ul;0eCd1lEeg2$hk|`bZ!6+El#37c)Y`}WClpTuJ`x=!|3J|@+aTmX-qbN z--)tZZ4E&CU~az#J(})Hwl7NI*^bDgAfe#A zghAR4P!zl!|Juh5kdoqPphqVY@FUQtFnR3v-LnO<)1MV8PtcQ}0e%;JG4j~uag@s+ zup`Al?KoeEV*UW6R~+pAKOyzsnPo0O)A4 z475g5bHYn{1kOJ%jcU{wH7Qj6`fw+0Hgmp9{V(e6CqNr1VHbQC^SVVbEs@!wipHWZ zUcw-XVbT8w^D)=}PV20HqZ^cf&o186-q6t~S=;I=+5DH_SaC;y)MTkh3RKC~EOY-2 z`fG)E10TTbAwTF975(`AT?QlSzQdr{zI%)kjD#5+8j7I%@;u9CltNhj^>?A!uY73i ziDrVHC#v0T$aK1x7*Jl)0szogPG|lNMtBK)fXs7qbAJlh*d31MG94Ul@e6FZ4hqWQ zwD=D8iJ}4j_`_v|71TgG0er*Ci+;|2Rx+qF^qIzXuX@YQ$CMym8syDnY`C%}of(t_ zMS2DnYtdzIbSh^{tbX{o9rS&?2g9SMvs~e~LGS)pu!?$(mYH&)hOfiohI^I2gLfUI zOYfJ&@7S@8zqcKs3?_ZG2h5*q@SZSuN|e$gKQ_8`s*UqHq5}LMgJpyR{w;%64d9s& zr?jfU)3Opv;HKCDk62rawH6yUfNg@U;ukhhyd`64!G)SD|B;l~Y`<1_n!{HQOhv#x zZ4DgMSfacF49XSp!>H!t`Tii9>UEm0ZqI^u^a9z?VY{C-3Sxp~pbU+z$p>*E6nG7h z8jO+Agn`R!_;m{U_UT;rkJjoXfET0PodEkBambllf(?G zLSVNR1`ij8d5GU&-x^^@!n9N;NRWeQ!c1}_oO1ypsLf{p#NQk(U~{)qP=Lms%Wc2r z3imtq669S!h<^zpd<39m7j+`qqer>h=?c6+ZbGrzF;oPh8hj;K-ogN`7kR=wKp)_@eX z>~kkDw&CaLSQ>Nz^`iBoS9q4$^TTdplg0O-T-a(c5=wtvaUbB{PfC;&^HbI2SA^Ze zV-%({PoY#?8#$OcVcTAq^_r>>9Sa?MeW&@uM8N9hz8SU)iHIF|XVtv#?@J;S#Q1yj z8}&352=1nG_*BR)Nm8p=ZQy3Y9w?H3vv0@Qf$r|AGt zqSwi8lbHgo`4-gA{y=n3_$7=f*3dZ@SMH!*VSxFbt>*Ais#1dJrR{1?@+t@f!w#Zp zvk4Fp0*dKw<>(TAP-+O#?XPdU!29B0J{Lma^5X1gFEQ2?P&&F3a(@0%C1A=DLeYp9 zt+~LMeTtUtj;KaoGBnhgaOg=IX!+oYcq#!hv)`J17DwhYgOxry+c4BktYOj!7m|@I z2utg$mtIHDe0rD03M+=i0?Cv0#>;V3Ql3sZr9)bt-8O^b3HVf}Phxk#&PZ%dzj(kyvK-_TTJ{^gIN^7%vV4cEaU*(X^{)yzUKDi+(23GkGqD_A z7)m`kuXOY6JwB5YR_gHo{~bB=?5=2udh{hGr=4PJdPkr=-SJ(l-!$O_?xuktfeW;G z&j$r8Nx+2$`t_IHV1EODVw^DRCmkAj=p!J=bmW7zJ{F7%sc5txI6nSE0~n1m*J$^n z9>n8zPQ9X=k@PG1KVx^8=u`F))CK8Jn};o*h;pckl^AzKK_{X3|NX!v1c@gbC7P0g zjaTU4;=FV9)uImyE7X6bh*6^$q>39?lSmbl#PyjgS{<7w|Ceb7JmXWNw96d-+(lbI zVy)NqY_wVYm*+x}FYC_bQGFT}A5s(f^36VymISZfnIq&)Ad^676bBk>L?EQ}#U?W>@e3Yr&4_& zltXNn>CvuL9pb|P(9V#Eep!vly8e?guqb-ZtK);NnE_%L?kmL}-amR~$?-N7x zEh+Xy!AZ$)dA=XC){+On-=_=%UiCnu+UCpiHP;$V$RaUTMI{0V|_He zyJAD)555slkf`k>*_P!QKkK4WA4++FX)a<_RjQBczi)o)qmhw2TPDt%0*Uy^1KXU1 znQg*H4m)Qqs;pZ`OM9g^vym4qs+oWw<9-^dyZj;(PuLiKG{5 z)!$}yiYRtVt`Oy4q%|j;e0w9N#IJ%9M=($~e&z^A2@U2inYC?qnjzO@Kb7C; zBNP4WPKWop)Gdo3p>5pS!=Eahu|*|%`UjJM3D==5fJWA3iEO79nO$j z6bK_`n`x5sSQappDm+>|t*BDs*tvjfkpCG*cIph<9_4bFg?6^jQu25Z7?B0BQ&!C&=M_-3mfbhG(u8~nC!8)WNG7bf!~Z@Gh76MkP$ zhtf#H-ozk9kCGZ3`gILo?fb@!iu}19!BE`Te%m}&*FT>%}HjE}D8?k?$ zAd9V@4@BsjPX-^6oiQHd8-1xRds;!|H~ppiPBU|aAm_X2xDI#uuSWG-AqL8V2)0{E zJOx61!WuoMT8?&Pp>K7F<(pNt>EGCf%_CRzTJ&Zeso!z%b9B+aGF75-ljwWKMEjKm zS6KNAlWoAWx20AoJlip4+^e?X1UfIx^Ouvd0`w-Kj!qSDNQ8Bh0q`m$9}NZd^8>dNbeozwvx z4&!a0*p)+hsYJ}BUkRp1e$(I9_T;nr7=7<-oLl@1jfW1`?fR;*mUt=>s7s=zEk00R z0gFS*+xMcQ#n~XJd|yt){t1n^(;~DM@|!9lF|@c19Ue!&AB?@~#3GPQESjz6)~}7) zV78sGOIe%| zP}jRc-7uf}*3Nd6wr%-6FY-UA+kIanOiRomYlv#vUTWCxANG@0t`|LM2%DbgIlo@y zT=GKUoEl2dI+xU)phq9iX?khi{&+BI==+kYx+-P)&xkOyHs2z-$y}IBGa2K|qPw5L zk;g%i{d!&7IK8x!F!C$9U;KhOvWN%heqr2=}9*v zyFmuz=2*T~B=Cb~s|NuIyKC92aztGYvg9TlNOV|$x0h%>5ma4GnF^t+y%o=T8T7zB z^;S5#lG2k_0*jugPaATX*7B4~DQgn=S>?0ie#zI7#zg6RDz)k%1?c6EBb^_phG1oR z>5Z!)H_en8%L}gg>krD$1#GiYd+qs%&M6VZR_Q2aeT)4bLvSFe=|C*`HjtQxRu}cx z_v{PJ<%jOmxAXJoIBdi16ayG`EP&j_$2f&sEA5gBM0vzrQ&Ll#P6hE z9y#k_JPzh6oRfz>MUTHRCN+vl=s0cNzRjFxUzS$We>R9}mT~>ubm1#g176*=l-H5f ziIbW=6y;unGgZ?S&n?MazL^6v6I#h?=atXC$lf?uSZ6;Ic7U{Jc`f}r-<}S7R~YHU z64%2F0ANRYCWGg=^|pVewWWf8c%HR9Du)14UrJ#+pAKNr119${B}PR@XaU~6_oKFOW)p7f8hD;-A}JNe3yn-w$DrT zD^RQK1=SAMUYd>ZnAx*T66f15ZDw(RD;<--SW?>q-8sUJaYAQ~QM3JHZV_>Ybl#uO z?Q42p>m}AaV60o@XpdYd%fD;>4TmA%;WK-`Lnm{S`&5UKh5BL9fA5jGHYbYTPtBgUkD~*uP_}Gl}>IZ`-?aXYK^J(Uxm!ex}!U;dVXVSMP`yp$K*)o-0tV z;`(T+>8uq&gXJueB2Cy>n^2-lKtqFT$qPHo*j|~D{}4hH=NsIg!VnwAe9e&m2OV(m z8e-U3bpekxFz}Wv4WhQ8BLxtIzRqj~jnY#=JM=-NURPoP5UQzFf!Zr{zb~$XwQ#&& ziT`&Wbfxej%i z**?=1N;SqJ)hkM#_h<357sR2ur1;8%mQ4KfYf8Lp&Z}mJnv;{Q4D4S<{JMXcR69Z)N=L^pkwH_tNRsN#j{~_5UZe;mHU@W&4|n~Y>DN~dPb=pq zT(bT1VM*~B77oHDg4UBK;DIt4_q@*h7ov)Nidn7ir%W1C4Qb~qo6>tHt=~h?mML>z z=>#eu#G$VO& z)E{0We89FX3lkw^BX>zi801Kw!;_h>Et*BWJ?MsgY&!J9{$p3-Yi5EFB}d9gn?M)` z33-$07MX>a?>c?0cO+OSG!m>XlHEF{F0y~C-13#$v1}5Hr|A^UPszogII#95Jx7nU z7^9zjp0z_+LWDpe)`I#eshPvLQj$P$?j3KtJK*|(HSClv+Kwvfd&F#Og*0IvO!7nZ z-_+wwz~}||ZMqY%!8*Pfk2jLFGgN+WJcTeNz(J- zchii?JGEd)brjjt`4)K1l9D08XMcRZlYC>pI{j{`ehj0ey}#bh#{<*A_ysq+PtGAi z?~i+ulg@H`ob7@bLrXoR;&Dd#OYlBSZ9RJ0p`)!)m@yY2>T2X+^l>#3b9)~@JA3hZ z(BqH6Lq4n(GWTw02G{qjI}!Uaw|VZZ+bNLyV4kZ_Ohh~pPHxqBNI-bXN56&^$mAr+ zrBsPEYL*mg%v7lGH`+blsc-E|C>~L!(zDym5^grH<8?^1XQTPUe8*^nUj42;+AK0d zT*8o<`m;Sdd5{pk*wmj@_R{SU(}S2*z_tV=Ly|U;h#6OX}z2xbAM17n6Xw9g=~yqZvX+RW7+4KY4$afyk2FU*;)6DtvJUqB9 zAFV>Jx{L4Eo+6oJtV|@ z1@*2GOSQL*eG3>(m~>~q$_XuPtNh+qrZ3ZM8?x@x5XfWaU#D~I-)k+}#&7$x#rKM# zHH2l5zF7KR3e0eR4#X?J<)x>09D4{Eq^*T}CrUqH0`p-VK(ih=X3R(y-sKjC101SA zvg+7;3Eqt?t#5EVfMKk~eYhWd$sLR=4*4U@z%=CCCtj~+J<#F%c=Y5DGOAP)d42a{ z$OMi6Km!)!e8yAsZOt3xN+T<9?=h27OTKsgYhbW*0lAl>@y`u+5f^cTR0;U8@DZ3! zf~7Xd6Z$?e*Uo2Gzl;1*ju5Ud&#h31zm&*#F2^Q8@uaf|nHXgRQK8UtyJCKobiM4gk0uG(UkK3N0+|r5@%XAg0vjYe&&D>v3w7aZ z>K(;n!14tgMmx$imsZZeq2F!CVZSB3Cz;2@_u_O3@#w+oonFk>&w#Wns}qvescJjk zryb+(IGXKzLldAA*lSQdqOe_mU-`%|Ax+B0XCok-PkZu`2wSx(g24Q>2#027pi@)4 z#YG$mt}G!^^3;6vc$<9*c^R-8dZr=+OWu{YaD6$hUzNTr7h($)iY#)AO9eM+cQf6XQA19 z0b*-#vCv*69N#YP4PvFq~{C}GdB)^>R4pb{9|$w#%|9+xx)0&@ax;n zNkn86^f$hOwol~#faJghioy^quWxC>He;;3yir$}gP2xjfJb7D675UyfpJXrBrT>C4RhHhpqMyX7> zo5FtU$#;5eD$RSr$&2?Z#!F_3RkTv69|Y)AmyRc4y$qxcv|VTV*$^!7s?XvMs;!8u zWQSlD=jWXJ@$z-G=>=tqUAS)yxILL%C0L0PT~ELO=>RziZx}CD2S7?eDbtHDx2B2;O_Up$_49l0eet zF&6)&tqCzZ;PD3&BI0L;(0P1*lxD2FP8IupT0Co?zsdcOc`4{yyYbioYf@Ast(c^F zhts`$z}FzloXfJ<5OcX3JsK;}otLX!mHtm+ia18!MKs$&4Y$ggf;U6g{e3%(C>u+}5#l4N;jSkj|@tk_2klg};fmKKbOLHF^ z+Is2a1n9>?qX#*+K35F|xi8YiPQL1GjQylacQ!k?@!?7~A#vtxYeM?=fdv?4NvPegUPENe6by_Ts;!D&&6<6_198|+`D!EQ5QXW==612Cul1swz z!G9xL$71Ga6BRot#}XVNWo3W(^pYkK(RIsE{e|h1!~C0>4|rvN88rBc)t{qrA*yHQ zJWOEz`ccT9B1N(i3j!XQqkAH0Bn``-g(ytJaMSNOu$$e%!Zb(u>XU#qL^(w1);hHo zPFFCUhLLc<1)qC{LlG>-XS%CQ%0nY)GX@8F2B#r+r>E~sV1yrB6mUhPR8zqOQ~brM z((vE`wQRwEv4G+5QtMdPAL_hMwW=flkvZNL!#Bq{q9i0NcbL~7zLb9lKBUk35(!pc z?uff@#AGQ(0CgR=4-U~v<;h~#CpPpx+;g@C)%Dj0*seVouU)#1HisRN74Lb?)k0BE zsJyKjcW)#nM;Vm~1tR9~UYH>!?3M9wP2Nx7h(^3Ovi&@DT{}DdWPUAl1wH| zVAuCjD+i^#j^H@7sAEm)3%RE%y^}K$I%T?V?WybUWNGdlvSP2d{W1F`{ydtSOwnbT zlfQhEUT=C}>%h-RX0=?8s=BkfVep-70s-UM%1F3uFL4Zo)vTd)x=Bz(OV`(y5DoRL z%!L~jQ&j|}!<5|T_aD>OFVnaT(C}z3AQFs}RXtrk3N{BeDo+h(4RO~R5giO?6r`?sC;2Hrb&A}m^3R`DM9&m`LwoNmD*ve z?Ohlg5LlMzlcZOmv$F-yd5ra4XOPWs#01Tj2@ubvPP86p4 zaMo~YW|xX*KNz?@Ngpvnk%D>#WUahHH67MN_xaTme=26kmC}vFe37J{~FM;m` z*8%239mDa~xKALdS$ZUD@B$d*z;+69+9wqblc-yoRY6wudwJUGe-2aK(czKVR;+F1b*maqg6m{rYw<%EuSA`SzT#=&h|DWgo2d^!n9QpR7~0rGE=q zH#=_%e*vyX$?bMw%yzjkGZ&8!@k(mvRfwP)8XlfwqfXQ?^r441xo@#7C2pA7KdOUF z^`1AZ=uvHu&0I8q4hy>js00Jrni^qyNFav@ z+0Xh(Uu@=*-nAIOz`@y`Ea4$Hgz}MIO7Zk9&R92({fsLJgj1o~1iaCp%H}qY*IQ9f zJ_#N^HqFme0#;6d>I#U5bYd)E?raZ~t}Q~fBUv-o-EDbwaSGZkkoGOTq|vQ?+KnqE zbqzX~ zL$73y8Zg$WX-thfgtr68?>ME_4SBXZJx zS%8cV=_J-B->~l#;2(i_v}*Sxo>BKb$y0BI2CZf0-a@CwtYq*?1hpu@Z@9$Y;EC=SdwTgY)rYeg3!x7>uA{9Kk9sYRBkUpC34~z-#zcjK>>{93#s5|cPXAHADh3)1!k(cUrVBrC zdTy3O_V;Qifrpk{3#5r!-?h}S zjF106?tQG~hbRadgU{Sz7$x*M{F1{SFlf#OT>EwHhqgCP3wXNJzufvvUt52eL6YKky}{4< zWon-5iqSv5GKkZ-4^L_=C~bn*-oe(3&A^IukKt_{+5RTte#)Fv=0=WkI-cdA{5Ge%d2SV_UmMK&gW$#GnMzyAFE4 zmMAJ>;)^pVtoLlyL-RFrRO0)DRg=cX2!UMl0Z#KTg9T4NS?F0E>ZY5;Z*n1KEIdt_moewGT^6l33aZGPBi346=-|Wk_wGRMDm{BE@G{j7*&#ER15SW+A1>Kr@4^obYoeN=PSFWXnNv`U|bFLy*(@_0O zZ}}YuYEf#g4d{Uhz+J0hI;(rW?`yl{PWmzWJdQS+Ul^!dy=adawirg%9v$|VPnIAw zeGO$NS}Qd^K7t~vbwfxHRdDFkV@mYJRlm^l*tWMbZPC2Og%6gdC*01W@`8x`epFs- zi7rQGOlUW9G1d0}cwfWT)>Yw0lw{My+AtjOI&v=8?{&o9!HY+C!Y7-YAFF*tQyrP( zX*4%1;j^9XVERzr_s-0SYNml+XkOBg(x*(gJa{Qt;YhZuT-*4)Z8DP*Cu8~h1scX$ z!8N;}cY8$oy_vO$N7U`Bg9(lRyM#s~n$@kiEGU^KhLLg8h`J8j-MhOpF5)yyhcjus zH28cocx=YkZH78$T;D7az>P~tC(g^S0$fJh&hr&i&~w?&E9+ifP}3uc2*3PAyq#|| zp!o1zNKrCp&l#{xAvO0BGQVsB`ASPBp&!#|S3t!g#qYG$nttbgE~Jy@NT`bq!%Rd$ z6_%!bk1MJq13KZq&|`bf3aL-U6jj^I7r;jc1V{-8BmtxauA#^4cEo_cxc>C#gbNh#Pd%7zy* zB-%dR%q97_gYcau!5PW-siY~>j5?i7wk>geTjwEKMMFaqz5YKLEF9dO67xTf`$mO* z?ypmdS)dR&S*Gq2x8j)36!Seew;xY8Yln88TelP@O~_Elp?xv9NfoxMQ?Wk;4+D2t zq#YU%7qOly-K{J7y7~kn{HB||o1uLt@Dliu-F*Gw8A9w~AY?BE`)?kN<;Q|Z=z1mc zy2^T1VRGVjGBuPr+KF0dj}uBt9B)uDW>qvoNRLs)xVRpqR6jmk8+vB~?C&Mh>{seP zx3?N4Z{K~MB<}vONZ&9j9456rsKN*_U)AQn?)kf_n=V3>+HW9@k^49*YI^nV;I9=p*dL$~2YYve;gQ z+jpO|yf$x$!ge}{qvqII?d88mffUl@7O*&xRs9EHW~R(-_6)#9@#ojoPyH*{5kS##m9w+DTy(PIfs5S4X zXKVg$P42>6knVh@+TNi4RVws9Jyp!Q=@3590J{2Gc~f;f3=G3+;G`$tg}p~MMDV*F zk4C&Qc^WnijfBTd*ibhuWow!#C9~S$$;cg>jUw$YAC~jsAl3E24vlA_qw~?P+Wspg zoyB0*252mZxbt6a>(fQ^7=2xhacAYX7*O&jJUf*DDQ(a*dna}Ls#dV~coVQJ{o#b| zh98$1I>l3~=dfHu{$0v|=zUJL*7By=)Nlqs*&`os-^y%lZS9coSq-I?lH6zpss{u! zDB*aAfRV<|bp7kK_qX9U1W5}!Uk_-mWb9c~lYpkL9fRR--hwpWBzF#|C@$^QEbJx# z+}vEBD@^EJaZ)YLb*IeM{ z0|r_E6E-NH?-RMZ{#}y(E4$Qozh&$a_2h!d3ki8=CKQ8S70>`tIH7v=b(M(f4)bWt zAi2~UX{@eRa9x(26Fh*Txa?MBbB=5W`Ah1PPd zr1`3RR%;(ZKGk~#x$b7lQ3{HSzlG~8;PoOP3p1xq>qFbH&qET1bAN9oKw{$ymrIDX zY?I>Fzcf}3SxW|EvrlNKU#^ucAKMh6*Hv#dVZr|0h8$*%lwb#mWlKz z<)o_}an@#&|LYnH`W+@dwMJSm-nfOl88lfrsbP7|KWrULj4FvYvVS`1{82%aV2|Nf zFikoyb6$a{Ip32&W540yVF;$Q|4H9a^X4!uDNMQ1i`o!O9Cn*a=02-#fyz7gLGp*M z0w5Pa8rT+ytUzRPmkuOlf4l)(3Pgz);F}V3i)J~t2R&kMC$%0}dC2Kc}La|Q!cJOkpaW6Lt)P|s6#xIm`gU7VW#}K zGW-@yclp`NUu{#A&d6p$*k1=--QgR{f6M@ic zNEicJ@6DGm)M;sHMWY#)8u!q9sYF4Bl<&#@f3T#$>2useQ`p- z`SY>8Khh@{qut0E!(bq?3lVQvWNU@Zrh|X}{zb3Cv5x`ampG)-)Q`yaC6ttctQL4H z{zfUkEYyDh-D|$my5ge22PTugqd9A48v+ouCBhXCR!&hfux7NV*tW<4A2e#T5Zv&x zD#Mq=rPH2;y}vb5vA*Ullv|!^qc~K%zXEeYiLnBO0*i=UN9g+en!gyZ=8I#x>!6v)sppEb>o4YU zedXDvT6oxgfr_n^4HD@DDv|Q7>HK>Q0<7XuKDX~$AowPV-zFo)|Ghv@Pp`vm;^pv> zhU#b^aH#L(AA=0T+2c9LICY(lQ$*hIqobmM$I(4rUOG-rD!Xscg$%?9ei1|BN>=&Y z4K20X9>Qa55Kx%$%$%+deZ1>+;ihEwB|7mD;CIr`9Or7y01beN4Nz({`}KeX2UkF~&G-yUw5`5> z8{_($J=Ijv7t2q55C)^~vRnjb0UL?hOZ0AgC+Cv}@(|9&-_p<8K@|v=a(Cq?e#e-r zJ9VR#TMS~2#!e-t;|_eZalx{QmGoS#`zrg_R?V3IbNm2Hi995;E(wEd2Kr5L@14KU zN~o*j>w-I!N{{MqTq%=<7$#+lp-f@Zv>*P@oV-wP4#bdCAkYSTd2Nm$L+_V}Ui2M>hfW&T1r)Sco45Xx3d2}U|8{CVy#WZt!DbLx9wqLM^^e7?^t&C0Sr8c0 z=80!GDbzOa|2_HojbovB95mDFlQ333B>H#$&Y=OZd|!R^vvRKGGxmSquIA@!_aACA zenD4m$!hYO0TKF3xa3Nheb2%T@|4`EL8K2;jR4DyI{2yL72H{q)8W_dh@PXkE z;g{%v=R})l|L-RpJ*c|NFL{Vt}4uX;2fM@q?c2A#%I0U0eM>sWBEZilnUmk*lXXs!J_c9 z%12li{4CO%%NHh*lbpiv54h<+IQ@A`{Ez^K2q9BYU zm7sEGf-rPf`jim}B?Ce9Fa6d_NMD6nsca^QXa4i0tNR zfeDs#m7wv0s>!IqZE05cU4C-wsv-Cqz)`v}Jpxw=SWC*dBFusUi!0<91r;3%*T{Q) zuupLyCUwWtYQtk&96&*pC|*QoRL?hmo7|R=7}Zim;LW|+ESxt#77!6p#~nkZ)uH(Q z+pQAzzra$c$=gxe4JLiCuV1zWVEX&}FEqF#EB^qEWK!;pvm^7R5nRCGIL6JdE}_+s zM+adeWAP$iqA{)HSnORh*|ZzQl)r$@6svdB+YUMy=+6C{AN!#m0*sfRY6&m?voAr* zpr04bq8kef%WG#{@jp*xc=J@cA965bLzr+84NmN*O5q-n76rZm{MQZ?S%4rJXs{Ptr3EFgX$!2MwV~9zL9eZxefIVu1qh_P-Y#Q(b=}623I`8TPeAZ^Fm|#Z=3474 zfd2Co%GVA$aQM7~i&&tedU9jGc{S+Zi19gtG)&#Qh0&zYjc?fttXi;H4o)lhCSP?R z-VnF8Zawx|Mj5Vpx!ObEAV$D^AxVd^oI$?jIf>e&o+Snne=68)pW#xYq#<<>i0Xlc zcJrhMM!H)XvvJTOMUeABqSytJ)W8s5i-H=_gIMM}(Lf%Wge`&EI_~B1{shQl6z~Lpj~;?K;;c*Zo5P5(AAC^f^}f31o6@0Nel_nr zfXk@|P>P;+zT5svj%xBTG>*$M9~9hA4^UOJAI8VXW2GlrXR6EO23iZ* zP7D<9hEkaZg}4)m;;i?USH8~e36uuOzK{o=8{Sg2p=AFV)G^t z?zpN!MaKs7>1a|{Lgz$Kh~1Z$m;NUvfsJ8^g0*8c_{Vk<-e{Z<81D1ks(>;G7#pC) zmw5e2{7e{1hv^BAjp3!8=8MdVvDofN8GAW~WVz4geXt~~7*vxg88vHNdl_o6MM$K| zUTz6dWZj?dTYr?6AKwVO`ehu-U!W5QJAdFY;m!t;^%NYF0@m{{w9GlqMdM#gc&T6z^P5k=k1Umem{U5g22!SsT)?EU?D|K0Bg+#*K5OC&YCcU~AVy#Aw*Cx!j5TNDCHe1!mDUJQ@PLeY6-ci8unBM8r>X%mM+z{g&eD+#8` z&d3lTT5#Qtr>-Mo-yYFYpnCE_4stDZKcM>m1&YYO%g2q}YDuW&(&KN7!)t(DfX$k# z^06Eu?V<4g7B433j0~MC%oruYlf=P_1KN-PJRyEyse}8TKZY>`)2gXreuY^EDwJ19 zI7i*I&0uL-^t4;eX1}4my$u*t!Z7m!7_B7@`jMv|@w^mo+|J@EoIu*J3shqG%G*D` zw0mQ6=GGyC4pt?$04$7Y@@5`Zv(d!^$7#7_GJ!vu`GA zUjOzeRn+rvVo@H2gTLtGucshZN>Y5OaLymK=) z2xKdRF914DGvFgnN{q9hm2>5ZgXGOtqDG+B4Cuv)J$q8Di^+xMJRA?NM0N#V+wO_Z zTJDU@)x}yp0KaFMOxQcNxZu40s$GYC}(Bn2}dFd~)E4rKqwulm|Ig!76mih4`|<00AaX#1IJ z0!xHmB*N3b3yLi|-cTHw7Nm%~hkkOWYNcxOzV-#;NTERuY4vrKA|DHRHdF$$<3)RZNf!F0 zwhLu}7~Iz|6Lm-q8I?bz-0SNlVu8sH1qB6`jR)YH#RqgIU_KZuq6CnxrSvsoR1Y*^ zV;p%F;AQ-}Xbp{0$dCz8ISpB^$jp%=xs4z={iL4~jt*mR8dP&Wj60mufh zNFVLSH-A5WR8C+QjC=%_XI-&GD~^Ru8y?w*DMOi_n?)1AbHwNqPw@sb9UYAuXsCa$ z0R4H+;QgBZ`rG_h8M$|R)TqD!==sQ@11K>NL|c$xfcpz-Gl%)=L5Hmx&{#aSZ@;1R zY;DityWLvS!^OFz8xnfiM@(^#mfZk=5&%0f26;DJ{TjvJ94Q4?=l5jZ$Cj~&BCg79 ze|e9EDg)S=bGA|Ea2aaZkr4A}Fvuym*j<5NjIW^Y2C}gXOn4C98G%(fbOAg@4H&|x zNz*{^0KWvIP5vBAxTxCv{S3&4S&AE9l{anTjU(ighphuu$rbZ$B%Csj8x?Te*N&-Y za+MQaLEbc2uk9hC6Cm@DB+7@w2p~L6>YiJ?QXo&X0#xQtitdhhhB?NP_seZR!$X{AY6uw#3FeP{_A>(b z)6xgT5w_}=Z%;3tF9%=>;OGS2dw7#bom*>jT&M>Sd_V_4uhJES3FWT_^-J@;&yR7q z8T0G~m9yz3z0brwjyZXQ361Y?8`i2P;^o}$C#~6?3w%PfQ3`ijwe3Qa$wCvGrYPkD zh2Uy07<|d00#{CU{1wpIT3a|fn595tbi?=aJVUV$1UG<@JDeJsj7A=qD6bpeP$Z*9 zzqu48O9FH7{DUm}Avo}{V})Dq-Y_XQkVHWulNE$lF^l$W4m`KDXJJo$6md}qe1CiM zMV{M@(EtEb_(>c(g&Sja6tsD4QM2!qzr|ULah7Bx9c%8mW+Wv!JQx70g zdeJ-ofQN#>`LdFgZtnOz81a4w1hOIVU{HUrLvVHapQYJX@#trLW@1M5FYg>9gnhoNpo+hCxb{uQ@a55l2L7BRCeah{ z&5&onCLPH2T!yxUQ?GzALAHy=(Cid8ei*MPvf^6M3LDSyJ?;Kc>x_)@7mki(LEBHdjHygM zGu$RkZ8I-zI|H4j{1}JVp%$_>Z35h*C%K7)y)DbcH%|*Npr!UAT#Y>nUnvF;vq>Tjc*w810@u5lXPRg=26sMN}Esj`xT`QnUc;hBdiiSfkd{D|G??%s=}ca&w6Vp(q|s&LpA-N5ld(VdWa z9z)(X&Y@#aZ8cq>tz1wIHm~SwDhYY^Q!fCh%AbM$>~7*}{|BwT)zcis$nh_e7%p4H zT)&X)1+0cmldPsnTOHd2Q-Le&05B=;cimm^(ERYNe!AiG(J-!WM|F|GyLV&ep4&6p z>?)YMlDPGh0#1vPKX6qM3G8}H7Sp~1A+ndSb>TrU?W5^ZGl@zDx)E@xJRQ@Z6ZKxo zvTxI~n*D@HM!zpy@4zCv>d~#R1E#X~%d^2nX*iL7&i!_svJz-RU2 z&E+F*wKM_3C^o^zFCVU-Ew@Tmy6qD}IVIxqQ**%SWH^K1j)F8$?^%@J8*Gl|(n95Z zK_lsgPfi}kS@%*_QI{d0^%V&~-YzZopB=>YVheh{NI@Jsj-t1S7KS-peb&aRbecyv z#qst&$gQ$&9D+JSp02n0dL5r0tDS;%ktrs#;Xp^BX?>AVF0L~HIL2>+pEwvnfq%SW zjf0e}zz=p$lg-5pxmox171u77v*_=i?UPv^rE#u`8N+?AN(LQJAyijj9_|So^q&c8 z!PI*BnoOr?84t-=)qVc@V4WPCVpDga`+2}%1YD%Qx}4+YJ!tD5Ot1IYUw&RRQ)R6u zimeHr-K*Tv06514(Lai17F2C%>gb33dPO2LGul_X%gf;yE|#MmTa#YbHwVV5e*8^sASJ+ypTJYHQirikl|j|LZ{+ z;u6PUqV|;QDEIrL$?nJ{8+U0|0i=GWJI*M{;5duo`FcT`cRdXg03;c~V84x!c~X*-{C)>Zbi@jNJ+z#nCjN zqHT9icb+=w?t%kE3V+$n~4mL)fCXq|L5g3t= zS_^&Fo5?}Z==f_4x|Bdt)Tv#lAJ(?EuyNi4f-37$1Jpj7j5CzcTpe-2p+@5u#zQOp zK^*Z>tj-J@aXzF8&CUNXGB+rVGC>GH;aBfbnUcsQb8#}Jb$v z1T}Cjb>8MvyY{-Qf4R-BH&tn^WqE5aJtl!$j~@=@Lv9~L@?^0b*;l0 z9gfH}J{RVtl?^a_fvA+T$zmh_*-KEI08D4U(3IsA-6p$6#xrn5nXh%u?x3pv(#z}W zv6JOc%#C+Z`dVw?e6^85+i8xIWFOFlAroQ`CNc%uC0AGT9uz@}>g(pj9L*Fkp3V%3 zVcHIe=!IjgYv%n&egaQ$G!)H<{07XFj89-BI6^R9O6A}QEC!Fin_2seU14Nt@}&8i z`9Jur6fs|u-aw44MPY_@E+BN!;p3;{eEoe+SdE|Du30Wni4<$3qxDukxkiSWKbk3- zN;E^~xb0-HMv9 z(T#4}2bD|9@4{wZ+bsYLH6~t&k!aT+&jHE|x#98|`sY62@!k@rc4FmuCYYwI6d!8q z28PbJ82N*D7rbfrLHz{HI+e(q$33xhzSG4Qo8K)v!{44AJ&1|jGiJI8ASgm!GFyVe z3Iy=z!Eg&IMp7fUdV-@}l9qEvHa&2y#FT)5V|F$I17;iTGy@`O>-wQQ(#PrT_nfJp) zS1@r{1fc;!{eZ!1TEh)>7Sv=Jm$3qR{KKh^aH@HUmTXpsViliO zz?$A2L@)cq_f&xq+X2yv9@?g*j*u0|Q9x`z{F1gcf)mF^oYY+~%LC+bOy5Ox?{N z4X41cE>xTuZE4=R*rdM6>+&ls{nPVvkib}t7mOF<1SSgEi;D8g43^CBL1%u;kCO0) z$bhwTYb|lYhFiha9r!ZfK7x%}|K|pf6Hgj1c!J#S^bU&zp7-ct`mW6dywiCzocGVb z9P!}pX!9Eq{EvPHDno{KU5^rh!GlI|3+SINBQj3s=jXj-vXNN!c$Ss&95?tc%mOsp zK}__c8Bf(J+yBS6Z;=JtfKwhrHv>TxLnk?`F(NJ&=qRt<-0p!f>n#usWZTp~jAsXQ zYK;6g=EQQ_eXMpo0cQY37k!|@+=p6ov7kQ{KQ8=;WU&q<%4hXFRbvejP zz5MkPU>wUvbB>Tmmib>SAQ2plHk5ohyf;TXvlJuGPELlAi;Wx6FrZb6R8JsGP?^#z zm&c@VwtyW_oP;>WmyV-=`uBWToe*aV+McKkIVS9P?k)#buNq)syAjjesnsja`reU* zp=^jI*FX+kX_9ZEk>=HGqd}R$lL44kTP*|m=j!UXn;uv@T|Xa={j?e=Ln1XK-67%V zFuwb}%C^QI9gh^;6d-R6EY-|=Tk>x2c1Zy?kn19)xuZbi_SJ`dkB8n6nknAr$ zKid4lf{VFyP6X4DmrHG@(B^qxo{hU}703F_doH!1LT~ou=oaQJjHxD1v8CKd0*`9A z1dBo71)Bi2?!dc4vJNivJVclEBo>+MvSQSR#zx?B!-SdIEn&uW1v1TBCFD7mP-;j_?aq?XX1-}JfP(oe?o_AMdXD+j{{tB6CR zJX0A$95)~({gCkJAm9S%Y%}`^X1TVr)m%4cryJyGwp)rV8=yFg&@Jn!b$N8}3lX#G z+?wJCXeIsb-OHHi96*4a2|LHcY(shT2Sbo4Y}*6F6?g>mUa8e3GyLw-3e!hfaFz>a zN)lmU@Dr>nW!t24!kTp}fFcNdDu9%MhUy%64Z{JL@z_lieuN6izn&K;&JS8myf3SW zq;LSrD1xH`xB-GzFTkS94xZRlj;SG1wOt{c5fm-lsD9_b9}4(BZDGP3bzsU*_W6Ao zrH(wy)2{bG9TXZHuoz5&&0hgE+DCrNK$lbeGsIhaFuE`T&c~8vGK-qa@2P!)JAuMh z!;86T`m6m3k!X|XGR;5JxZp&fzo1h)ef9^J=$V*MLd0vvhW4+umE0rJr6Lly2D^!gpH)j^@<~8K(`$;s-Jb!z=wMXej*KF#JeOI0 zzvWnDer4E}7ovu2?p#tcCvhm_fNjz7tvFm^yN#|aZ*Ld}+cgU@Y0 z58W%k5Wsiluseze--Fc*vuv1J%%;m+nzaWy^9e6=1ciBBY>a&Uvt=z#r0xa#X0!rZ zJqUL$OTc=R9USywVtzR=T`^f~JX^6YRmvv?qX6iy!3`XdNx#%o2Hy-w_8QpcC*8E( zaa>wx#P-tC2;!Z8hSq+MS{C zXt-1x`re+FKJ5B{;I{gsgX^7U70&BbcorCN#OROTw_6ndvH1T`_tsxkcWbz}2uMo^ zNF&|SARyf#B@NQuNOwqgccXN7H`3kR-QD<3_CEWE_xuNEjK?vap}<<}%Zz)@`*U5_ zV+X7I7YgBqK@zj^?bK7^19PaL4kxcQLlR-@Dspd^{U1cX;eKZq3)AbE+^+$U*LtdJSiNU4``C~%RHQDVm zaewfK^gKuT1$qQGj{~cRqcSjd6D(nmFF@t)g;}RwZdjsrhJXm`H5tGROnYU(O#`c) zI`FiUN#}{9he3F#+8xb0CntdV#L`T!(M(xSCuhXmL54WAKKlH`63ze)VPlVP3^I6K z9l$R#GO`YMT?|GNxzCu-vlwPm0deAuAsOGK8Au3-bh@~!$jIOYhPrxxr9jY-bP)?b zxxr4c>e+YoBDOCO?-$1^`U{j=9(p7bGNGNoX7Qy@zz=@kJe|lelRBBEFnXc(YSarO z^;}mh^teR`rJF=ULU&YCm(`qwjaT%2rU$uHs!E&3FHoTYDUzr5Hn+`2y_#Y9DR9Tn z1bxEs`S0=Ys)FHsz+=y5LQ6nz=-sg}L{V*bolv>kAw=jlFeX$?+3EN53J)L*g5&!o zA(H|R`egeB&9^G+goAHC40LGOWcVWSN>kAE?_73U zS~f`)gCjHldPBmbo-c|=w&O*Spj|n1`1obs@&YYTH(4TbBG|(S?XCo=!NBb{p;jt{ zZ3Dc9Mx)a{uqFWfVVUy=h1gmOwIY~~YZ>5z_#i_EhRqQ)=Qk+JMK>tl!&*|v*-B-9 zCetSQZN_i=i*h%6_Utp6|5F2MH!GIh;!aOygKAV)U5a+kKOJ9BT?*RsSZ3jD9Au28 zvugvph-<@p71C~`F*%KaL#)fmQHIb?8m}0PCs!ZaW4)_35^9CwH=v36;m*d@e{63j z+;V8kU3tT8*Su!e5>LnPROfTJ#}l2NQ-)-XZZU&p%(-s0fiW25#mp)BAE&`)zNfr=qg-A5%J#b;*XGBbtAII zVh3?2A{JR(O5_)zT23x$NKwQb zgzT2h%xpgetrr$jP>W}0W?=t4!4DgD1o*B%Ka|P!0&7CNqE$ASkH37a3S3py4m&yH zJ;SlH?#)L=naF1!9ptIXDy?eA928tYGt+AYPb-*T`Z}Xg)ItS2vM*I3FL!lzn(`lN zfyc@(8as$F+}ezBVl)@>4cpmyun0U17p3MCKK(Fm<{Kdm3xiX|%ju%IsgV-6t;TXE zz^4HNf3gQb!p`Rd^{I30vow5p_AQ-YqDonf1!H0D538jeavB3ae3zg$&M7(7tMLu3 z8HbYyY3IDUVeM-89+9nCiQ@yfpQ+?h1cXGrD8R%wOOXEpG_p`~C>7aOs?D?cYb}(l zL)z^!uX3%^qSRS@6GsMVR&WX9WVgEe@F_m%!F=6w39E{qeQRpj4elMo|H{^J#275R zXCrUhSrQ{{K~kMD{h(-hWPLjrlBkk)8}e9Pd4s%4Mbbi{NYsPScrKlTT2omI(J!B2 zzX%R@$zvDFo(GcLD#!=#mF@cSv>M7_UF#g`3by{0gDbN+5VFdYhF^Yzvs?OnUt6lk zSn4`A%gg5NlOm{l7_904`R~^h`hdOuJbIo;`HICOq}y%W!2qidX}LkH?2+{<%sv6^ zv%A>*OTWUP`v`p6w_QkEu)`2(&3gL<=gMTeQ56bhX@7;skv`R+EezR(<3>((Qi?kV zT6VnP<3rb#*wUHZi}vssIY@6$eH^s5^?;+$clb`Wr`imfczWrMz-EmXs(WZnAEv}@`vd5B|9a?Jd_Y_xc1ckw}i znjr72^&%J_QiU7NPL2=dQRN#Z5J>A z%wR!nVPW63D#VlY<`s?+QQ>AO0d~; zn3z;aXI~dhdXQR7bv)y5E!9GD&b1O{-lR<@HOjQ8D5XCq<9KFj@lWg;myv`C9IY%Y zbD;+Kig#L@+B-M8&COTA7I74O``X1;xPG`+H1pd+VvgQbaX~2R%RGF5Lxl zsikL-=cc4@snEJzJkK_O+dtIGu2hB_)8MGN~iL?Q_UP3MwH>;g7@%z{Ld#6q5~*Kg;2#Se{B<3=|L1r&Xs7DqWC8Z@^t-nwE^=B zazn+!r|93vKK1Dce*zzh6i>}GR$#LH^TUXEpov{rNH>jyxZ@{yL{o5!&WeLD*wMQ9 z5FD#TjiK~H*ajG$SgXv|$$kE6D_+(gEmM~YRN#xS)sc0nxZ+K9B8mzk)YUZfG<cua-F1?oP8L<{Js%<3kcW3}7Q()3Q9-hD>o%azDn3?Ia>rn&i*)Dl`38vHq$?kCO5X8C-J@QKjsMhYyjX>FWHBhG0o@KLgxmHHvV|FsWj zId%#~Q2#0JVo@BP4vy2>hg~+p!R&`A8If8P6>UJ6dU)f)Xn5#VAKBNBvdt$21F6Wond&4lAooyR{dO;&Ok!Q77zYD%FqZ$%E*woFPAk$>Kk zFr88f{heBkBmAX3^aF}EYDdN!tS5PE@6ez<@A3z1)c!)AEpfswPaap2OM*pN5zli=Uyu zlwlm_&^ws;K2d?Vw42k(W+-i&Jpt-FldBbq5sF<|#X+Xds?uttitd7C;P_GQl(9;o zBLUh>5JeYjdGx=5a=btF(8Lpq+1IsZaB8c%w7@f+%M>;IEAqDF+PgT?#fq~BHipGt zpTGMiD^5f2SfsQ#X<%&R_Jwbj)GB?&2)9On;;M5{6?EEfI2t&|RvDDwUNMu)rST=% zeSB7JN-9}dnBwnw0w(tVLgy6-nhp!seyo3a+Wy(k5)<0fSLnH#?4rI(9yr$^#`+MZ zMipSa$7%^xg`2pdZg#zf_C64URm%j^!%Toa(pUkRUzZrXL733WTauvb)$~LNJ%za{ z&Zd{{aER=PNRlox?k0FRI!sA@NTm~OVgi3LsR=*b`ES|D#@4Ww{zRJHAtGd`@v2+! zxPulenuxgTLrAr;_I_)%tqXXORsL2eIohk?U$JhF<oXiq4?OL%| z^}5Mg+X~%N#G@iL@nz%Bge%XCrJ4u@EGRPlgcPV^Q7)fPHB5k z*GCFc5-tC`pR!1NaLScK6Ut0-KS*1oTJRmY&Feb2`(0#|f#}9Om3Pf&-*04exbSe_1KDz(#-jYOw_jCw&ohIX(}GQ+dbmlNViu zOdO8xJ{T>@nxOwu2LQ(3%1$+vn7zb?ybkQ&0w}UVL7aAN%Upx zI7o<@;XS+0oT$@!;XHMB;7VKLN@(;aRgnNmVud8{X3SiNgxz(V>3CO|`Kiu0*q}ay zXOjS9OW4TwyFVTDHo}ut%%OC!HlwOk*%RyhX2Q3R^*}<d#xusrrM&V zu!K9-(oGGM&h%D{c~PwE>0pKp4fwR|na?ukju1f=fZNu6<2DooyPlUBzx0fQHuz>Z zp@zYa03Sl+%3@I?-eA1>_{~(>-@&&Ug7oy;ccgX=YL4;!`r$C}rd+0FZ8hF`M4a<| z->C~#YASMlqVOpGeJ$b^O_#qEu6m2@^Lr8J z0m;Fmy()K|$?(2QSP1gO%HQeQ9#cZp;ZFD;!l9iaCAL&+jzr`Dy$-@ICl*uql)i%# z`Uf7=*r&hj_!ya$B>nelLg9#}MDkEbrp@YMLuK zJ4m_Y;+dnXZwSZ0QuCnGrp0hW-8$W?H)Q+2#1qHLOa+g{p>AU&R&X^ZtljVrXzhDJ#8z zE-k@9*Ko^s#O9i8;kCCyaedCvLAl(Uq1?s&IFQ{3w`To^Jy`NX(fkU=e;MF4Du7fy zE8axfZ4ggDTc^7Ywoi~YLAky!v$JPq#kVa%jz?GKXtlowz3vW6u8btB(n;7^u_E-% z?~Y~K9184^K=~tUc3$SE{>1zQ+BOX((wQzePK+=b?}{OvlXrKL!)n<(6=Olh9t}w! z18vbnHpjJTzX@GF$|xb}S3&T(GbWK#c1ah^@{r)f67dKqe{u~=S=Niy+|&ez3?B;4 z!L(mwRAXUCI1&Hh)Fsyq3mWM+ z*zsyu|1%bi8RLsL7cJr^OAAbo!lxy%bU+~`|0O38x%aj!QfyDm`X)}eP0CJ9^qy-W z=&oY}TSeB23(?p>2k}pNq^5f0=9TMckd@>@azG4sYOY)gCJ+1?u2nFRN6xIi$Wuq6 zdUma-Y4};@rz+S}i?X#Gf);7Ii8X~hj-T)KOin9S?>L7TP81h0^V5~us2-pwF~*{k z+hyylL|OtDJn%hpObLFIAvQ~DZc@k1PvC0rR*}10(#%Jg;}qWM1kS(SGKuMj()^Ut zbLJ=>$&R75MhzvYFi|y2q;@y>F~MrmYQsj3hwq5C(z+7**PHPG7_o6``svbdV3Bkl zzax@Pn1m74M8fho5lr~16q*15W8IWw5Eq8}5@j%5sEuy%(cyTqZu4bCWl6j{pwQ-v zVUqN}az|6Kt+nVB0W+Tw(@!h(M5P70oCHw1NRTpD83hNAGcL>Zr;*Nrp?@N6MR6Zn zuL&f9a#6rBqUlxuWmj8>jUbH@xn|tgW<9O4k%M>~wu8g>eQf9*W(OJVFbBWwV9*R< zEtbMOB0ja=C1Hd}N23Yz+^30%?uKVhB|Vb1^d{?wD+g34xxbK5btN=;k2m1QMm{b# z;?au=+7K~9SJ1HGBlY)?t;bcXI_p96Ws`;0)hz=VO1H*WK5`~Y!nfNep7 z7V%c=g`J2huw)l!u#8Z1UuPkE8fOxpnz9h=t6IQ@ih$8L8UY)VBAmmp1fi|=DU$pn za^{Uw{kZv3xn)diqQp&Bmpc|c{kzA9uWt^DN*D&lLe6h4a$jjHAlnS-6{1=f#dcX2 z;$?*JxchYThd8`FzrH0n&w}E$6OY!Qt-|*owFh4B#29#&`QHCW^C7BJz6r~J1eUz< zjgIF>&|&{21bVHu+aurbwt=bJNCxle=4O@Asb-itMR>*>h~FRua7hfXdI14+EH=7) zd|sf*2J8y{n;qap04f87*|Hx1KESbw1^r^>GPz%0MB@hHfLEwWkx~hnWWod)xX*sI zBo_iY>{Qexkaz}cL`Xs3V__b2BtaOch!_Zzk`S~83_QoDH4K|Tz@{mdD1`|T18s;4 z0EK{=-4xVqwjX#YEg3um(9oE#H2TkH^$}8*wHEyd0^3(WzriLJSUC56^ani%kZXe~ z9bR|edT|?F1NyrOZ5dj?F%h(t1$EH@IS0(?kZl6Nt+7VEQ_rO~5q6Q9VtdgiP7-72@fRD~p#y{|?8N6KC-w1hKp!_|#IX;kIQE6p; zWfaTt54+eM6h*AG-IX>{Gk*Ow`Uv5?KHZ=g($AXNUl_$yRIq}iUy(?}T~o7lw zu^hnYgD4yxMls+`_8y<7nD<{qm*7$OqtYTljdQC&#KiyZgwYBNLs+nJB1X>Y)2mUc7P_ zmRC)&Y~&XSK;(x2=~9bnT=)3W;vyK@e}OsAR3P)+!SrCBO!}A|==o00U+x8}@i9&c zW%)n{eP991Tgy4~^)>6)6@@p&7eKV@wKE1r8R+rFQ+;3wWOBbbEqJnhWCvekGt5IJLx{Sd+{NV^DJyC&tLPFi!k_kbUot-== zx7Pd7!qy+Dg;Fzt&;j)3h@(1FX3GHDSq-3PBB|G29vop_vr5HAfE~rzj`@$I0YS=9UVMVhHryS%ly3*;?Y7jvtT`BNRo<_ z9n^NLmCONwj|V`<7HK?}9~HB%WC`4JLm`9bWplPc+Z1$?-_{@{*Z}X80}x;d;?4FZ z=c*j(H5!YQOM%MFUsI5StJcc%R{FqJquN-m3Fg&35EABQb;CPscQ~Pp@8t=|zF$34 zNAYfmLjOhp|0)@f!$fMPb@!O@#RlzFJD^~`j>qA4cW+yImI~+1vi_E&!|#DtsL!329sofzNn+ zwpMFN|Ho~0((A|ls;47W>05j@r?XFDS4Y!Dn#(T1&e@9k+&Cu-y}fzKLlJ(_WM(tK zK!SkF;p!-fIT(8)Z!}YfE}hXfccC!%TXH&=r?Sug&h!yIpJW6ETso(s+5dW`s zVxBMR>>SewK>&Ob@4R<*cE+I5MD#HAaRohTfGow+;(c{0uU+#1nlF}bpp{KS%P|Ba z3;4*#r+b78K;=Drz{3MrW0^0q3(3bNu$<(Xy}Bu=hy%+$;MeORR&6=?0HX5%Q%#?K zW(@XQurhHtAH{fK#ktYt@>o?$D}|x~kS|LuerN zH_MITP`LTtwf%d+<#hPZ_Hg#f;m(00jXEOjD9DYwbU3+#+Ze2YhL(zEiDDEKsrfn{ z40ck~mva8PpfvGr**^lde>K`S5FU`x#yluh`Z`c!fWws6`wu;e>+9=R0^S{(7PNX` z#ss1I!g_&N5rx4VOsN*YAdW!@OllwSxZWUE^u`S;t5x5@N&B9qQD{H=g=y7WLnKE5 zQGn@K<_nMv;w7ekM;^O>6G6ceyf)EM3L2C*cjqKyGh;}^qlor3j;ETLwIEMLK9kQI zEIBL}7>F#=E zz(6{iaamfi6}bS%*srp?`;WG#>GLdiXX9NlZbpr4pR`EdodRxRjK_r$#EOxfWC6!! zU~LIgwb58}xZr3^KWe@H2oNKePUM?>t!~2K`p?Zgc?kpjb~wBA zMmu3xN1wnI35{He@585r!B{%I-;~(w9?g;O$dG={TSkG6UbbfWIYCP#6pLtT2zxT` zmmd~&f4z;~zvY^cdT+pddQbVMIqc2J8Q(3}d+41kaa;^(UwZD(N1F$52$%$-8~`!C3l`dC1Jua#(-F-3e|J%n4nRNBLh(~umISQ#;xQaN>{~#2 znsKS430z^R!mlxhQM2y=4p|C(4udtPN;jSwE`b=!OK84w`<1OeFZ6hR)M|179HBdK z*x|N2%S^tFVg~XWqvr=C3~D75df)KChRYqQozsb$qRd)v(A2U64rn0HJdy_l1`4T2 zN{hZJd;n3`AUY8#{u=BzNH|{;U#klOWB{E4VsT-;W&x1by?&ecWTfKJc72gV3(l2| z9d8pTZL+}=V>OxRUS0KES!y_gv`7P%hkLomh={+P-Q3)OLN9Ce#Sv7Lpm^OMdID9` z0VmYbT*W3j(wWPf&1Zm2eF9psV6c@(B?xk&yTr><^V3VNXn_3&p2u*~XY+X+hON`>ol{L>tf6X0TgPdzbt_bJ$0n z0{qLA?6m3odY42Vy>~XapWGg=jwQ2wfOHJVHW6vv03!t4oz)2%sR3;Xde^68S$dUQ z{bEB<{{fN*w?UZ({n+BsuC0~h?;do2vdonX5VW{uf7SI)zg@Ej9ykEPLe#nedlZm0 zniP+k&swNlCR?F9jKfN!R4At5i?Y`O6jc{B7&OTrCo+jY!+cJD83OCSL=0PrzD_dB zj`*y}6uxk)+soUZV1Ooo(4kK4NuaF-67Ox`6!==Lexj_mmj`<%5-yu@FS%^{U{{`JBz!09Eu&!(Xir-` z`2Pok%V{5<8r+ewA#j{!aqCru2tiG(S>tk@{_jN{NL0Z_R1k6fBmGs4pyLE`vjGuA zE-eUMS6Alr#aWP6zFl2B!eoox= z(-}tNv;D6lK}SgpClAA`Isvu>BfCwE^j%n7q%`j;kJH+ua;b&(G_tK*>;0W0Bbe0He7G{;I~MI%-g$ zJTT)TC01FTt^h^H7|UE02n5_bJj7)$btVB8bFAl}Oa=dew+|@UUsRI+fn@ua*a7Q( zrNTJvboj{g zLb27&53qoaCli0Fgu8{n-45H4D-9B7p~ugFH?u&5S3GmJTMfUw~f( z7NZ+rC;%K&^{@bXqRUl1tf+pIE@Wqb&NG3k;&ySr?_^RY@lJe~q>3>c|`gOSgd zZ~lnbK0ZFcP8ArJ)Sqt*Fpu$9M}BK_9R>4KOrZ*#;&6s-!2#tOSB$W|-Rq6Q;_Fh4 zg}(Iejm5Ebvqh8Fj9d!88l>>7yf9GH9(k2}&@GTDlQ;P<~*d_y8 z0N^mzdwIT@S7#--;_Lg0fo$|3Xe*}iTCD)kPpMcXi|C}Qi}wKe_ukjVItyG@Q}le1 z2P3dC#=+({*3DZhM4d>DJZ z4X6MgZrpEoG##*Q0a#E+Gn}?QBC(_KMhU?8i%U=XWU&reaS@!HaJgNozry>r15pYX zAZg%W41i`_c1yRHPUxB-3}%CYt;AbqSOXXwWMG@C@amsc4On1&F8iMiMK(a?gpab6 zIl)(i%8r6^7JQ~Qf6t7O`^Wclxc9Gj;xnBB$$e?Pxhb%XUjVfRqqelFMTE5qPIcl6 zAMl2HXfJMV!Y|W0$x z1lDH3m^2GzR&Au>F(~Zi2@%2;=nO5l4#tT`g>gksPtT3^$H@b;%B?rxOaTPW6dJIm zdNH!p69C&X-UYn43E=+#tcKZ34aR9BNV)DDocWx_B?<4d^jbE6s|3wfCnASL4#%6N zBxX7KdT^^@|8PZRjF!slsL7;GK|2p@CPt382GS1aDsq7DjO)u|*$Oi6>jFUaMjcMaeSy5#SF~Ff zW{)+nJ_HKxgI5g!+SvU{rSPDuH6>UwUuzyTNq*4f*8|5)fcBI9rBW_+`*TVYwbu=7 zN?RXKnt<*XWXV?or7KvQ=)vX60gFjAg=9PcBqIpBK(fF`JUlmm5rTvAB=ILzP{0vv z+b(rmuH`C}D1A#LxvbOa0#%&jk~SXS0liTDKGrd%wrn;qusfZsI|Yh;tK~)mrX;{2 zWq@nVV;vukpF3dh8|#8W&J;VCG68EEDm_o0rP*x3<&un<;lQ7Fo5LAx*8CQV(Z9u~ zZmvCVRv`JJbG|;7r7yQMwJa`LbL>l_aUPNq1(8Mu?vQwNzSWBs`b!+RH%f}DZ!U%M z$=5;%rQ-n+Qzcsb!Iux~h+22ZQFDoHSY$1hrr{C>uFDY2ewhF4jR%j_F~JG%}CDqNqP<} zk?+-K^d)?lzXghtQyO)XP`9ZKwmdHP+cIt&AKGqe%AVI?c;`TNwQ}o4Tz*=Xa{76w zQS%0dr|Oam87aDGjy!R{l)?ryK2aG_<#~n#;=>QmpBMdiGWOJGs~OjQRc9H*z9<6O zS!*Zg1lReZExX*Oa@b!sLzxv+Hvrs{mv`x(aLPEf}7bS5++ zf*u@lfx#JwDp3PdeBLNy`9da`{(pA?oeJX$sns6O#l=ZKANKQduz)X2!O!j3@6yhL z>MO*A3T$d0mR9da9Jjh`dbg9}Qc(n8_qi$Sx%`mw%-cN+yPS?T2}1rU5YXaj-nET# zD-RQV)cVS$`jPh~NGAVn-}rTkkhOBrG{_$q*mZxr(e2x4JS_d*$aTIpNmvY?910o| zG&_;OuIlK+WdQHf`uXG2UI4Glc!=iS;v6_TocDO<{pZUNUcW4_hH?uGa1Dof(GfSX z7jG%>Si~auJHEl1j0h53M3%X27hO05`6SpMv>2-SPz7L#NFmUdd?R-dBM^BnrA7wqO?;1^8QdU!RoMfAfueo3%#%|I(L5dI-n<c5VR-MsE{kI1>h zH;D+BOsDq`C2h=y535{^GUX}2XE&7B?D$dSqPtMw1fS!Xx%#ES0{J%dnKgF#H@fli zky2i&LV+eas$^LDC>FeW$%d+#qeM^kRCqFwAf9L-jQ^rBoZ4i6!fSfzxqx{C9 zgNx@(fY;XuHciYv8~P)zB$C&$NJX}dwv=VM7+`F6Ka08An)u=9(>i5vuvdSd+RRS4Jl1<@S1Ai{4JCuxWR~0Z+M88s~ASk<<3@ zpYqY+SWEr&Npyt@t79YNG<#LI#&g_zbosRR76?SYaVewL!jqAb&Q#P@To0P)VJ0nq zqWOW@%|{ombz$cd-iesBL)}Z>#LH>$ zz&|;5Oabc@vn7#Hjw{j!#04(CNiaaL28ip)5=oueqCcVWWiN!{X4S^c3g}9HYr;aX zpD`_~z0t~jz|acWoBAg+tf2w>s1R)2D2}5s$@nw&E9;cQF{GV+SlQtz4}GwZe*G<8 znm?YEZ;~;+Q{mKdgM1sJ2A!Y;3*2<=1aXa;V!E?gEN9m&_!j_EtI1HnkP)Tc} zCvP0pAo-!vN{f(w{ME?AYcml#hsIBz{88jFC5Y;URf=Ng#SBw*3>oT7M;Bt^4ebTE zJJNCUoeb9Vr;g*7iL>>z*;B7kpbWn8{@F=4z_VK}w0Hj#6YfN~b`E)k%HH})5MVz%ERRJDSt?*WGNx?JptcTbpqmDgMkj?d$7}NuO#d2o*CVaN8 z&qcvkF(fkbv2|HI(6fvrpYPUAk5j^%b2@vf*{_rf%q*{v<{?OY?cTM}*T*<5yS+F6 zU>hywW@a%zyPA+k?m*J=rF9wSIAXduF>G>t#ZoWNi$qmK=kQ=42&WzCKCV6_<8z7A zZFEkGos|(go50t8;T?O0O_gN@8e6+jJ+6kh6CYFMT6EoIEtQz$JyX>0avPI38_A~E zKR@eF=)z=lpg#p0~UQ0iBI*D^)5a*3;HBM5gZ+5ThVnw8G}lTHp$ahP}DO#tzpdZN9QA7 z@Uf|ugZ9hpR4i4Ne)k_miKP$0a$5P@6gOryq#C^g_kY-2(?56gzj08HQ}WMwOAN~k z#IZp#F0Y;n>*OpJuuQV3mfsmJcc3C&of=@B7U>b{*=_Zx1}@wS*YgXjv8ED(v<}n zbhLXRb|g*2sQU;9;a4h21oJ5q>jP)E*Ud#k;~k3EJSmfX?Vmq{*HGHq4JrPJoX+cX zc?{es{ifJ5bme^4&~>4P||@#INt#0u_7Vf$GE zcW-9X+hbTFvbEtkP|PZ?Z+b7lNIiw zP5*jBJvnceXK$JtZ|+j4U&(wIgTW%L7guUd1id-?`$H!4@?*H;_8Yze;xPyv5=`Tr-T10iWAILuKI0}apwh$Z3Hm3 zdvMbjaQm<1!tgh$qUIPW=55Ss_OYgpkb;T~ACB?3B^DFg%G}0DZt7GGakj@LnjAC+ zLVsExsKVmNQ8Jg={na1FR&)C+RUApkGBCjltyGqupCQSRTCE&qeAJk-m~Z(bn^_cj zsh}{S>o*hr?-by{) zgoXPD(|1{koVxFD!`2(d${L?87He{cpmV+zC#iU^7MWFw4B|iWGy4_IidM9^4YFcW zTHAe89DQfpJuk_IrWi47bN%)-{mMirTkP{mF%enm;)X3E?_%hR!kKxk3yrw1Kz^Zv zovf_ZRGleidA4XQz2B$8L{?&DWUR@;MH@6qt5KIP-#9Jqk<`%y0!15i>jhcuCKSAs zZcdhZ>JVdOwDJzgQ!=qcyP;=b^hv-;dNaE;qfj`PP+*IDsyErf=&AbqQc!clK7rq} z?YBz;miJTM!`vZ3qy;A4n{@8-ar1SW{R;N2#}Az`@<-QCOe+YAF^RrkXPh#|j}gf> zI7CuQ=Fv4r-(Kx}FKM8@$fePwjxLv z5KGy2?>P1?=|wHfilODjZnO&@2;atXunoa-U~)@Ii%;9S{%4VXGZ^;5xg&;=U7y!x zpMt-Ksr9qU??h&gC!fM$Sfi#;GfC_ax1_Qrqv=JuVG>$xa+UJ|e?LTqWb%j;hftoU zmpr!1y(HJFIw%)$u$nG?HIl5>(C9+o2r1D%yx0W)x{Gv*bcSx?s{two2N9`q;-Bua ztguD(KN=oPO&2rLUwTP16@Os0qj12d`uHOKkcE(unKO5B&T30ESF?zqwxmZFYC<&A z+~K8yZy4plemhYk*C}?8tnOnyb%o`f9z>J1Qc`wq>FAj)cCs!lPva8dTcOjj7xf^v zI8>Qd0_7^cIeE~iR;HycL-iZ^wlljES(-&C>CoH>?A*`A2nBWwzCLN8QrRt!Fb|Ip zkGdD}Te=B{A$45#y$#WPT_?;H6w*d4>PcS_M~H4Fp+z0cGf{N zj4n3$67Ixao0QC2e1;-l3cm-}q$1CXZRIA3H1{Fo-Sbp^V^Uw6GAm%5s!<)S2DLiU z-ulglqHcl*n);q(c^FZ(58<1lMKzE9))Xd&GY$cq$V^x(=P2F8qC4V)**o zNRJ9dF4N+5FV^<3itgVA{J$@ilv%0ufBjRxy^G~q8x2QKk~1uS%*L$Xq{86%jB9kW zv>4VGxnI4%pU-=X&g}_m<7j!OdiTSre3kPb(}xFSQqacqyh-#*)SP9*cGN#64HH!h z$4tIm@~Ut|51&tJamZQxiGyIcN{#B^{T8c+-J+v8R?8)5L8Ca@NJ*@&Yy-Dh8WdhZ z(tN10iGckWFr0v9Hwk6)?eN%mJx)K~a8{?^xJtnlU)icm+Un{ZsVR{lM4amP#T$5~ zk)h)tB{2qBvkwBCzAF*yn7QP6nZJcaND&A94SI>bpjaNMu@as-!Kd!S!pzz?nP@B> z{O%6OS}f?b(7L;7j7Ei#8MMQ2P`J8aqh1P|#VQM=(yu$$iqKt6jg4`jJ?LHxuY6=D zXVz{}rlyY~Wl|paXgZDNP=kEWIenj3B_g6IT(WLjqjowRS+(h6TADoaV?~Te&#D;8 z$BXIxLQVJxBa=JQjs4up$z0uZEp0H00H;@FxAm;(-^29T{jW<7)a{fdC}7f?LWWZ& z`PbD?unOkfNH7{d3SbU97{%7oJ1yMxbzLH=z;H6->K(SXCy!cQAyV6B(zNZ-8!$6u zxA?crh?a0gA084p7qw3bOaBnS9X=R{21Tg5$+cRG;BUzxTtxY3UoJ_19CxJ2knueZ zL?wTI_Lj^#Ge33P*fyo1F$eAd%}=>6<}FT-$w`Z9s~ryZ%7&kh!`%xn6hrv&_oG-y zW?XUb=or^!qR7X~W-&lz`1TL#QrMK?g%JaC-T0V=G&EKO_hVj)PXpcX?~ZeJlmFcX z^p=^0%UNc-(e|?l%CWw$+my%QNK5lCYs;#I94;X%iIu*h>}Sr62u>C-!r!a8jS~^H zxCou5ulXpf+CpD=@N)*WJ)RkP1Sy4nw}>~b=qprW4Ila7NaZ))6d=T8&g zOliO9Z`|Nk1%F5%nu4cqX-Sqg+#7*KKlx^2Xm%3F_^a_K{_R-{$;ttTaBNuH>ei`< zFr6mJb(I{uY1lN`HB~I{Qht+R8;XES3Yr1c{^4m#aw@!K9sZnVs(7W>sf*!;&#bHR zGVah1E%;JHwTCg-D3lsHQCDsxRyv>Uvm`Fx*r%bmMt6R=@IRYf?~A9d3U?X<*4}lA zrUvJ@$i?*gimBpGq+zSd709I7*^>!1I8EX<^U>n}+^#29Kb%T%PQa*T-uw|^#=&KD zHAYRX7&tu?aM%bjzkgNFblFgvlfV0?LZBtY78z#M7#G_k^lrp8y_7&pZnDf7_6G~8 z7%Ua!wgdt!H=QkU&KWWMgH&>Z3tM!4&8iJs9umB{f1q6py7@BkqfqaZ2D_B$EHjbF zYOq7Rw4}o!A4Z+!rBoL0<}P&w)rMVtAa3n~aE#WG1F5Bni+(1LYUMcpcwNb5%oIk- zz7VUA^pgL_`H!WM_l-jKNhk4oFZA{dEgvQ1Z4~#qEaZ`0A+6{f(^9*UT={h6s9WEJ z)+UI%KPTr#2og7KkwsvYQ+F|w`PzL1r|fiJ%iM;X_g8=34)xU030}h8*a}R#`w|d% zjwrQ;-Cg@mjdC21{T$+jd#_|KlR(y>#v#G#Q8C}5-?(rBg&(Un?Mf2rHd8??0mC>w zb=4@4?f;}ZYw^T|?-ZkF86v_U`F>Q}h0OZTKr-~t#>KtKf@A7{-M>rDRYM?}dn*El#0@+OCL9%6pd zcz8SPorcI$R09SYv-HUnC6Pyh6sP-jd z&TL)#U*2}iqp>g{z=^{qDU$j(rLXF6S}(B5orYsrZ-lhl{_}5Sz9H{) zacqec-4}ibEm~6>o{7dcMWGX0>cu&3Lf=j}%~rP2I<1>d!kKOjF_(@venxH@UFw2+ z0asae^adZ7e7Gr?NY2iJoD!xFagvGhx{-YCctj%#(=*eLIuYt@NEQAbnlk(y+6Z4f zt-l=MI%(KVe>`pTyxgG!JSZL^A?OQ?ZEgJ~_O*k9goFfs286h{>XrKY0AmDQe8&lK z3X3`G0jj+8Y%vd6>s_yK$@3RaQ&S040hhOviZ{?{AUHw!>%#z5t5wr=E#cGJ4&lGM z-nylq2-P*Y|)e=_6!H@#3A zxc0gVHLYfsmC3LVVNmEP&=CD@NxYxbG-^~!OAb29QFPSu)bhlRWw*PTwYqx;}*Vl@oId&ghj^6wUWzFVVRIp;b=Xh#~UZ!Te$B}${aNIKlg%%C&=H3sE_ zfFWES0sn?)T2>p#NO4g3KAm=4&@aAcSr))Oma=oTU{>0)lWgYka;c6^^t(7S@40}c zwB0kpsaq9fvb-RSczP34WvxlW;3(7896Ce7z`y_)5GJhzoQ~dDJ%2^w5p*Wx__+lb zw>?)vu6OizzvGu73zhGN@_601AOuyNW`fZ$6tYa}Fa8%Hm?9 zIy22N5&nQs!_C0Jz{FGukk0jWok9zN0k{=+l{a$`Dv)zfHXdCP?MnHdcM+7`*X1JI zwp>>qHNn@2p{Tr@gHeH-gBOnG?^sS%t8v&mLq#OX;TQf;WOVU4iPy6g+&XjDz_LNa zL)`EWp5&BcmE#s7-1kR#UL1j&X0DauJS9`^+PK* z#>dA2QZs1GMC3cy&eYD+4&Fw)Zo6f>OMdCbGl=K7OuyCe2NgjyWC%nP#9@{gE&5WF zaW9)lK#Omspr9adLdD0!0~fYvNX1a*(6s&&-+8nJ8#|}n7fb4%=b6*b!Lye2MTsU* zL7qcVK@%p5#j&r%Tx%Y=jWDUQN`sUekfH z;Nr~fKKFFJ;930Uo(fC)3j}H&PpOl9Ceq?;9%yap$ zwC%-37?#NSSNan$t>8WHm!Y2UA|jg%Tqsqb23Gvp3*^3A&_{5^@a71#h)1CZZ}My5 zi2U9nKyu}XLBgMK)-D*1u@RAKX)AJy+O|DgSml84Ku0=4EDj^afwx3fEnl`tt*EH* zCQwUCLYd%buWj#aA8B70+Q1t?)^efR1V8Q=V#eQ=5*pr;9x}67hLMv~VwH{P_ZMv) zZKGICIWwi7(3-BpHQ=K)5c@_tK%{hOcnAA5DV2!7YX^hzuf+#};CBx1W<>Tiye%|8 z?AEGV>Am9<5PS6AUQhl47A5jkHs&{I0t=AEVf~{e3w>Ox_wT`nu7Wt0DS)oi|BH`> zg@uhR2Yy+fwQcqBC4!91Ai>~yY=|c%(y#S;_QsGW%Wd|-{nfx^CGPJCNAx=_aN8Th zR8YHL#^WhQ=7)_Rcw_UBO0czJad8*$mNv9VNJuu>q(r};+b`N*^8M+kW0BqW1i|mt zFokI`I~x9^pua$^WMOr+&3awnKkwxTxfsPx$xmaOrtfIAy za|h{$=IhG{6i2H3_PLwuO@xU=nV^cDA&!%?cIA($!TDa?|)@kLE) zzR$LTu=`NjA*90ECs9kYnznSyi@uT4kPZdDW-{?I)@JO{#hm=GL}^|szn9XMW;JZX zz`GmC@tr9E_uWc<9}Cn96kaNL9<=Pb%sn>@$3Co%=v3R3;-4s8U^o8|Gk{voxOI9 ztX_7k6bRhTei6R@DQ?DSTXkNvu<1NpNA|q?MR4`W?QWailM3@oUl+kmId~cFyR%8a z#kZWgmmR$E4+sF$?o0+bOw9iM%OOSZ3C`lJ-|?ilb6WzG_^g&EH&3eFgg9f<^A-iKcTaBs=yg#E{DgLZL$aXb z?@EotZMz3|%wKOCM&qU#Keyg(M7SU6-7x^K$6nr-bBQv{-@#B4w*@lpg#&TEyWJ?g zBn0PydECb)GM*2UG925nFE5cZ*p-iMZU3IFo@YJXcez&Q8*KBa-z9dWShZpk^8C9W zZ95OM>W0w>UFt0JxTe8ye+K^ge)3wN`vF?pFL%AXpoQ6j^*wyy9}%*1Uk>53u^SdX zzG6l578$*_X?Flv;!5OvaJfGe5COw0`Lqu9w)CEbm5cY}Z+ol3W~NO!ligmi~=cXvp4H~+=$^S!R$d-|Tj-k(@|tr=sEIp&hX zgj`X_x3E9FrP3n7P_^Myg;_m)xfD{oJ_;!G)B>4DSc;^T9y-c zTa3XJqiof&Ti(IKoV=dFBOB1(0LS@^B0)F1su#}fvjXoS+i60_@4J4D7G;X9vjN7S za?6H=eZ6ZQE_OA1&}0CK!va-n%e$%SXd#V&5E>Ttcw3nf_Do4d#k_hoH{zvEv85E@ z7RxnHvgMHj1!9nav%dqN72}7es@uCB{mUYa=8d<o+ciK%bwl}Na4trja&@5~G3c~_WkEB!F#U$Cv<;~tVyHX}WU!!{2 zRqk2Y+;nrwbFD#nXaagVkgicJZG*1+)B%$VTjslB$n>E_j#m}>`W&!`Hm-f%`w=Od zw{^9hz1M5P&2T=Pcf6d^cz$^_Td#8hT_R~1s!r&Q@KtVs?SsmUyQ+NtT`2{8T-=*p z2?1Zom9zL-@&_zJQeQ5v0CR`WQ2K9C&LcRC0r>;8YRphTb-{WR@67U@CyjV?(dmuB zTU-u->k2+}2o}T(tsMN0@cfmmhW%di+wuT7YfQN*SfLzNU@|WxqMc($TzKibyLfOW zJM>R{ab)GO>mt=#+LV>-uHT*gQL&2wM>5}RT)4GC#K_i%dw{x5jupmq3h3M7j)`WQ z!5tC)1cAqck=Pjw|2be|26-8az6dK$n54L#hUmYyxR(&T8$;B;`Ez>uWd%io4X}i6 zF3Y?&nmG(dq26;KXTeuR z(sp|B$W!vqfT$ATI%sr2k2{O80Zkn3vV_F+nU=r_w+|APFY?j`qSub?h#k{Ne#6AjJwJF*el|E9x9i!m~?Vtf%~};%CYbl!}L?I ziY9d$98=6y1NF+zV!g|vp55MEU^!7=_zA|;sBPyzhC32k)`|5b{|^heppX=C5PLfN zgD41i44@B2e*#m_VN8tCb5|y(rCD)f;pQS=kUuNCtBa7wMKO1+uG(@XQVV5^y@n=h z78aGLY1J3eqXQkc&-Lj%!~6cQcEI0<0b?<@Le&_3G1{uQwUwCvt62Y#zWD*Y-J9T5 zaRSO+>93o>`-k5?=s#cTzgZ+l(4?BBhC2%VwCKF(C4tlR1smZ)VstBo9ycK9S?zDT z>vkFyG1F1TRcdR?<+O?dFEVjvdh6X(8OM@0U^7zsZ_JEU;^w$a<`7+i;921+ek}@p z3IlEK>~+y(fiUKydc=s`k*?>rpypFH%C_EQ++Qa!jly|+f_%9_sN$~-7ARiddy?JV7=8dh6Cw)JLA2o^RV z^ED%{Ze>eYbTI=KnuvmhOChkPc?OD+w;ZwH7(e@uU=&?omAOE7UQh|%O4U93`jF1P z=Fu^Pfw^Flc5&j={sIlptrhcm1Pr%(9O8LH-v60jSAvU>`zusDt3%LB=ybN`h(8sI z>ahx`q5CC3S|p2gOs?!*$m&xUqgNEUjFiU#ssAo;^sXS4vzjem1I`^41&8l$EFy3| zK11ar^Z^#MvjT}Npk%*>S@oZyfH@Be3{;e+Q~!ngTX$@y z?}cuowmbLR2o@=-`R_{zAVh}#W2l2oX}jGs*m7}zm>9h#-AQ}TBy10Niv!A;z11U) z-u|$9#<1=c<$5=Pt;ezZiaVg!D#*%G^DCZ%c;Wctv0K6cHoHin(Jq2}9AYj!P2pIF zobb(&b1Pjjc_xKUlMC~F*7Hrovu2A2xAy1(S-Krc9~|W(hMgh*)$a(gbI6?A(I5e~ z;L4y_wBJg2+j34W!a}*MChtGi$O;%`HgSbrR%Sd7;s|6pr0-sX(1eyM(~(?@ooCj2 z1&!bQcDl9&8uf38-bHr4;NxyNYP1`v!^q40c@PHFuLTkuWK~wR{tc0NdR%g5)c-A< z3srpqavc8qgUV0b5xhrSTBJQeWBY=2w_A)Jry*Aww(biH>ofd{ZurbFu=2p0CXND{ z?UL91A#nM&tL!7jAF|1j*tC77mFwV$A9p0g@Otc%QRsfWX2)wed~tkWNaPb3VuVoi zBaQTA9Muy}E^&{RXGQO?m@8E6wO4abu-G?DS zx-tmCX8*S14_e@W5Z-*Zg)7XH_%X=0&UjlvVq?}AjLqvH9T!x zxleyQ9MHR}aA`-jM5-iQ+y;wI(@i4BFe9846SV5JNk&}wb-nCquWWU;TO?}7m37@` z7x zvxTFk^I=o|eJ!)w^xHvG;RIL>yzj4V5@(vW*iRmNGfr~(H%U;Hcp}=tP8KP!t4hE{ z?6&;~OjSS;^0*_Ll`3U>v!#ZTCE8Y3@tmz(G$bdv z0<{nSOHlK{OxlC>0KST4at)`nLE6|TNZb)aiO5*99OxVq6CJhQgtUH3SUY|?Iu2Fh zf4rC=sW1+|`RKgls6v*=OM;{4LPAJoN-ad&Gwq=baT z2+#ieb1E+$nR(Heu1kad3(D246kD%VA6Vao5$S91Zu4ZM-a%LP9^l^g`frKRU{@23dqkuR3h9%n!3m>?*< zy>?~v-7bsu!@}7v<_d=(Ad!w;dU$1a4wgH00Wc(5g zgDggY@3a#%!z6jW>roMt`jFT0p6)I8BjfWKBY+i@wWb~A>8vZ6Sr5ijQtdK^^?TyxQjX~cj_*NfW7{u z9U8~LY`m6`*#o9r1)xb-w=>?4GtRB|OL8N@?bD3jw*$Dl_aJ>T|2YmwvZZzF2rDee z1wPLwsL$UrzR?Hnqm)21Y#rKq-y0F%Yr-L3Ky{vfkPZPx-na4G9%3H8BrEcS1%Jeh zHz_%F5!37-tQ!G3d?BIvzc?Wtmw^^Hepu#b6;PVxZ};A zVKg+1L`2&ikThkEr#~K;22uKnIA6zPJp3F_${$Nn+x5wQ1Yz~Yg4r|y@W|dtOfv9n zL$})*sDAI(KK%hpt;5v|c%B(a^aPyN2t&#kv~@a-In>dO@b|DVcO74&s|G=;6eIXJ zA=o7ejj+8LqY&u7bkhde+Pa-iVB2&Gc4xhG1k{|!YyG=5RM=J!v#ubvhoNR|Kmwb@ z_+p69^WhIIkulG3s{a(Af_aF;W)+IJk{w<4^XBa!C zY5VlZKd5g{h#`)d`fKq@?tasF<;z>=X=rE|0psGfzH5>l+*fjS@s<9e1l4ObHDOTbXev2hNQWFU+>v1 zHwXHi2r~neCk!exOssFtm02(a%cWWIX(15YSK1X&e(ik)D{%4}a|}`L{N;$fWEGWz z`Y#5mU>>f4vjzh>nu43`*WwI&A8P&8yycp)qTAy~_j^F651$};0#T1?!3^Hk#cI1> zWDPDUoL3|0DRD3P9g1t~X~yOh2|E8f3d^ENeg`lwg4}k*ZMyPg!bNTr%b7iL(uL+- z-db9F?d&12j~$6^Anjhg^Pv(j3MW%01eig=FNd!Qc!@495{oe9x-rNGb4CYm77b3l z5EF-AFsQ5_cszQ1%x01v#aJ(q7k@G!9_viMe@8);;9-hubEKI+26oElx*w-&FHYqy zNzeZ%NDyh)Zq7IXdP28qkof5YwqPxeSYAi4e_56{5ZNDr5sx{?Q$UU>tks@S7BVv1kmB7R_|vHL63DgJj*b;ga5m&Sgbr>;uq^(;(&cpkVAAo+v9a; zsjtFgbMHFho^H{N({d8u3z* z$=uFRdW(g67hfJnTJf?mKK?@JAD3Z4ZdV$5-l&xsT{t3(6@`$Fx=)yS^M=s6d% zynQ)HG?4HNDk}n~!3wEvdxggqj)#fa@Z!2cVf-Nb^O5r53v>HC8V(@7p(zdhB_%}a zKh=b-NU2(kOW#ROvuaGcl3v0$v_+<|ow(+UT*hkeH(U6ABxl@g^akN=pPm7%gOXMN z*#G2BUoNoEkcSu{%QcD!W2t_2RtAPz({eLq;^Ls#NW?Ju-hV)KLwjKR5vc`6{IS3v zfu0LW)Oa&g05d&~SeC`by4oeo_jwE4_9+N#F-LG;FWR5pf*hRR!L_9ji=knMG|33I zK4YV32KTbzs9}FKfL#Yf@Ye^+{6H81fanGmqD6)$doSSL%EK0C>y8*B$bM3U6#|~b zRSi28-z6L-CDYrTcHw{w@wr+W)dRDS>ZE$mefgYd64r%3{qmP-yMFj@XjS+d34rzm zWeEnhL**v4-nKqpKNpd1?Y{$6vjzj3Q7cOfp`65fg-7c@Sxp~Z>DeY zqW}=DSNK&CyB#@$62GE`eiUH9^zS$juB44YzqlGbMG!TDi+9+3VEzf%X;lgEo%F5i zSY>sDk@ z&em}Rk4_^b7}p2%pIF$gUm&>EIVW>f!@;wlGcVRQTdu4%7%)bc*CWaLBum@}9Y)JRy(>_mX(xd3O*QiCM*tJ^u|=H#WTvcs z3%@|zrS1h*YWr{x!WSAzfMfL z$oYH@61;)FxXLu$`%ufl0t10EE#;6A+>2&V*{(wVrGi^9VmmM8~ zjq)oHwH({j|BX+4i^92xdcyB02D< z@XC^E5rlI1+Wy!EiAqk>@e;kCx}i5SA_X=*9@+{bgJb%;PYNkCQ!t*xljI_`S>6{l zNj1~KX@;Dcmgz=r;+7_DjPZ~qyUY#9E1W0K6g1tIi#syCH7i5N=JQP%KnRZ#%7KrdHpSsTHXr>okv`0gO*=KYV1u6;6w z`$N6EVN%)5l4GJom4oI z#T$|&A4g^G5+vtg?rlZ8`rZ+(T`i7)ZRKzY{{*GYtON6^e*1ii4!h>D3 z#6vjmkz!guz?HJzKd&=Bt@|P}xC|N*k@?K$;Jb6yHJ7#A?OB%AQ}*E>AhLs!g%+Ft z1$nt@5nHU3-F3UYYI`Jc;1v&F1dTZ><22jS;aG%M)g}bNOR;Se0ThK|On=^eJ+aI9 zvW0ij^as7TA@ZL6D!xM^Tyj06fSiiC34on3#+wsgXQgck5yZF4#((KG;lD13m(1R%gdAy(^$zuZqjxxsT`-cXQ*F5|U;pRm;|{u`kPS(m z5Yrw;vK9+T;dpcH>se||S~dLCe7-}zIOMcnlV9T8r?#8eAGR1ZGkLJs%vEAyaE}Ry zh(KW#%x%m4&~}N6wD}js~w_Vr$>ygx5aO5cl9;CBFo9k zQwnx~?%+q$`ZLFiYgeMjJTF9HICECRgii6le_Xxer;-4bqf3c{K#ifjBuDzrq8cC5 z1YMX17EGA?UB#H-g7Mm@I>JRXnB^6ka08rXzH(PgK?S_clw`da=tkNl>?HjgjW(J$ zw2y-!EGaB)mex;I2Ya{nH$63#@9XCGms%lA4IDPS6a2K)-+sUoXfIML1~p^{jB=TB z`J&IUUxviKkU47KISWg2qwB;ry6c$He}N+LeHJ(;fGm2Y_n160+V}DV22lnHs<+fRtLo{jeU=N9l$7A|gG7b_oupWu1S>a`z^kQw zFsE16g098sTjFGAcU*0I{r{9ZkH!`_7`^&Jl1jlE!?$6#lNKr~E4L$mc7(4>U`j6r zMaky2v+wQ;t>a<)^i+AzDz2xT-shbES4cfWIFi=qH~R`oYv51wA(}+C(!ra{fo-Kz z7E{UHQ_rs6>)sV~$CV@8_t`To>geD_UcbCZzqBiK?RYqa6ndTQiU4?`LkJED<<~#l z7aaLr4+G&Xt=_y&S8~z^AfaixYu?LRzPief!TD+nnTx&HKe1>Zr|0Oa1@T|;T3o&1 z^dQ2?s0htK(H+XH03Yigx&AG{CrybbeP}>--F&BEvD7T!?bpzaKAYQ} zevf{nrqu_Wrd_!~3`sb1;&N^ZT@4n=KB(F%HP7(9G8d!ju)JboIemR%?UvKi)4o0_ za93Bzg_mmo1gZnoipwwl!b7eo37-C&`X!h4w09kS3(HSehzxb04Nmg3ZN6=bTDdzC zLqd+zNKIQJ-vU)z9-+gBr&CBQ4M$(36_s`OS+&s& zjIsOcxeKC^K~n)0aKWe-q5yR^&HYa)0^7*ita`i=Ik-N=Sye`Y-Bg}uy^~2>r8^2B;<(YBw?xK_9jKvGLTdg3t6~5H3_2S%7p`8Bv{gA z8;2jCY-^A7pGSij{t`+HOSZHXF-4P0w$eiCEktL_5$x>S(+>Xz5yx8|Hg0ZiKE4Be z_aro7L!Z|^lkrlsqw{+57{p<(j;5KVwu}uqd#WqlX42M2H*MYT7r$I~m>jt||OEq#vE@FZH_kbNk!=EJk0d>72w*rI6%q~_by?nae| z_mB5Gwu6I%K@U3-5Ca4^Wh=)h$12B_zB}~uD<>zp5BMo9JyK;6!Dbnrw%q9)Ym79) zbskF4avBz*cdrfh)vnLwH{`WF4rZ{V1CslyLpo>TxlYtWyTpl{&NjK@z*xM<3AvOc zwgGw$6yOKFR)?s82tVYu-|nZaiDIKVj}wvW{c1+s^9x^3whG z-Y_f-&t0X|g1&-$EIUTNp==nGG0Q$)S2OBf1`IGh?*I}SU|5Kj1N|4ymQ%SGn^p%7pfSrlstJDeNI+ zq3^O5Q06sc`9?~X8_HRmyipzZ(ev@qeyeSPpPfBe{VEei?m!ngmJ|P@7~HPX$+U&+ex0p*_iT>cXQyu(tcdyaBH+6F? z1D2D0M)&+YVd4soNgx#RdeZRW7*{hEu1Uq|~!%g{w$rf1>5b@ND)$r za&I&iWK>}|>PWE5?}|zvnfGvMt3Nmc`jzKnVA;yeknJ*OR zOMQoZy7 zbtMpI3gR$AlKi9sG3pbD8y!Kg#&`53B7b-o1={&l728zu9%2Y>ySRe2rC_{@xql!S z2AsQ_#_G)AAcXgg@_($8W{`p&;9qq{AZY(JN`BHqX>T<|=cmv%`repx>}pxKW0 zlgOuZ=HE?|S18kKv+xPqI+siD?KTDp>r(X4V5OVa72=DK6A@bVdQM}n@l2bJ9Lpr4 z7QX<_%d%?^|Mend?e*4>4nScdLo9Ug#41+*r0Z?Cj0llXsdlYvoHoQe`urr1Xk*)xJOLLxQQd|tS8rXKMRKte zsIqL%1*eKsU|HSmL%@;h(N9C5x`7ktXw^_#=GRWImcQ42w|qaTaf(IRl6Km?>#5rK zEkr`#=i`{-xqx4wT*@a8Va{&i@rwn!jXCKs7Io&o!>qCm*4mfsebe3gSUqx%IHi`g z@3O4*UA}Z384zXc`t$bhhH;h#(fnSGckrq1-pt}i?j=v$QoPOP;7!CX)6$6!G%I*6 zdo=F7siF8nD*$hJ|Dekm&^UIk$K&Q8{OqeMF6643%_8F#G*ebY;`;G#@)13vu^Zs+!vhqUO4_oLSm--TY#MXp{b^bf?IFu6i@PjS?R1`TE zPk~$o;~paFYUaJ>4(_2wG(MJ=qGBTD1!>WmBPxl)?3Sk%yw_sn^sZCX8UbAjU5}*} z4(g^&QE_<3IbTin0)N!>T6-{#o=km??6=m9>e!pvjphB>2_?s)^wERek}KZ1QfE0^ zy=-nGK(8R2VDX4%xa}(Gw8E!y&UZnLHehRdT+|)UFQTP1(MX;{rD7q!q_gufQC6TN8$glfa?6~6K(yKn`qDZf}D$m zT#rlByY0ogff7+Y>&ls*h~|5Id82*OMC`QIwWe+e{xixqhNTzxnznF@f%mh!nb*R+ zmdW7~QQ_Ga%!?%Q63x&X4h<>$o(zL>1!S*NcWgJjxE?gAep%Zkv*V)k`b$SXlxejj ztHVs>tSW7Xwgzrp6UaPnPM`?(JjARTsI?*+<;4&Z*vE46y>)MzfTQ}&Sm&(cJt-9v zTBc%l7aE-|;ih;du_uA2Y#YOU+qCf~{D*e}WSn}gyNaZImDPUoHIoRPlZW-lh4nQ4 z)X$G__g!`4tO)K~+$ksqxpg7rTl_VAxg)X-(DKPhkc=cywNNuGWljrrCJ!U;G0Q6t zx%dVmOqy10K13X+v|Tq9?6^i1VfNl&m#;_Jm||P1GCAA$;Sp%GDXokOjU?#pL7u}pACx-`;KIO=iKgrN-9f&0|;7GVh z?H`Swz6@PTd>rYmlxmh!76EAnP%B_byBsI)tzsdSKi=XxIE11_|&<5b?{5Dc3Mq+LJ1@dv5kBJ+`VY{_pRnKdnTjw?xu?-3<+e zY24pZzB~oUjo_myNG;F7=K;i5hCp6I{_pcTXf$*c9E@jg76G-qyR}+d?nSEsBpLzV zW3jYSa9p?6mKz)io=WP0dc%KrrbGYl8(%RO!;W3oW#q}HEjc@*+f7AJ@cUm)SHdWo*dfoH>EgAaX+6y-zq5mc|vnN+*57TQa zvwa+zoP5Ir%Mb&J@$xQ_N3YMYNU@c%eK~sYVrVtm5251}wo|9ie& ze9;!+e&NwQX-06L$PUnJ2vn=gmjI?*XxnXUNojI(ChB&y&|S4S3$N^2+~qL?nZdKb`0=9EtIp z=cZmcy9FhR=M`t$Lgkux|c8t{XDMuG&G$ZCHV43#bvk3)qC`_9c}-u zKH9jFP$tB8HOcAq#f2icc5B}HTI-e5+u~Anz2h~rlK!sc|8~Em#4B?IpC71b#gV_< zbV!b@)l!3W#^Z#X0a1o?<>$m#_u5W_f65>%`*o!S*1f9Vrvlv@sdKdlfA)ztV2mw3 zU)2{M)t#4WmpFkl@o#~8e?cfAfD0oe%_}b40@C4|?KO4Ea;TZ7K01L$$Aud061M|t z_J4aIiT#}fi8P5EiQ<%l`aT3CGeQcRR;$~L5(m6LhQDc%57gXrS0vVL3>d8 zZv~Tl_KCQ^R%w?ATR%?-dRuLD%Q=}u=UFtW%S1irl$F_bXLP~aV8LwxW$zX1*4riX zd~00o@>k9}g%{jd7XQ{l`F*v;VF8Ym@mc!uO$O|0zzwP^bqC?m2WueXJ)pcGb^gk!YE}L9P}ory zs@I92QBF?e(uw`XR^@Vvq~UowZ~1&q2dHvit81L_wWPFrUnPp!@hZ5^yA}Z{5$I+9(~rldE-9(! z!}lxO0*{3vB8cU$eH#IDZbmxj-^K~@KO;bOSH%Gr8(2iVB2L(8rbyuac-dKj{`ZM~dc5kecl z=U~mP>9?G_V!&P${&|r8G>rH5tpMPu&HU1;{@V3}LIx)yEF1+H8BoY)oP7SfOyn{o z$^n@~xV)@vC=j)^+&(G+>4({SG6M64w&Rg^rnr=1G6F#g*WWgD`M`eASmh-VhtVnHxM zDSwg+n+Wu2|J_qtcV9nZcycaKKI6*{T?^CWe@i@>ieN)o<*k$EM902zkV#qL$ z#{6tbitb=17fDQqGl44BZq{n4Js5cYcz?a2Uug_9QE$M^YfS;P==i;wk~2nN{C*N7 z&3@$NI_lpxl72hCjlx)h6s~BG8J%2#XhVGfe!T^rg(rk(&;13O7Iyu|&B5o5V` z#y{1IDOT#sY{h%3eiGSa80q+muXbFCMF6@u{Z+>3A{Tib0SSP{ z87Ha3pQ7cO9-~%^PTOZ2Ha-GAZd6kLC2y*VCDc_nHqRo{^mTjm{jrozRyR|1y z%#0ui^~3Qm(t!Tf3=y(QzhT?Th&dDuXHNM%K98G|mr=K{usH8EGbNdYOx@=jm^GsR zd%pSxio$yL2&15n51g)Ce4(8tBYEaSzYU@^khhSq)0;m_`)PABF)0>SMUUYQaq5}? zs!ol4iBUUU;C+dDah=v8i+(Lpri1T7!6DG&g2G}YukN&9;278N_T-gcPczKO#u|FAWPwqlM_(&O2Hv={<|kKbag zG^IFuGjdZe$5%V27r7PgCKQA3A=DV49VR`M>|LPoVNLQIUh;`Qvf9k2nK1f=8luF+ z*$V50A}l(qIr?aPZNg^;LT&0l4PLzfXK`@0SsNYgL!3#mSGK=~SvXFzL0>Jv&aV#B zQK>E}x}Y)5`->K)H?!!z`nD{rWO$+`6Ww1LMVo`|QxKb-hRAyuWbG5QoS9QB0g1lp zIp`S}Xr#A<4+zUPRuVo24xXx@bLCeP2L{=2})jtO*|GKL?HWOr3#}bz`@TL7!=%e(=3<%~6N-%-Zw;CgUerC?$Zo17yp(F49bF zg_89?joRjOZ>#-o5!~f1k03E?&Ql!NNn_(sx`s((zr0^uKwIQmNd3U+&c{jEoL!Uk zbIk>zM%T`^BQq<`ANCUfg()4#5nS4F81;Vf;O5kjyaEx(y5${7W0tt$`|qn zDVfw?%tdrU4AsM`$>YKoYEYSPWqltdr9P4_$mzO>Gf9$D8Z9@uy3DQStImg$ql?eN z9@9E?vv))V%X{zG%x)J@ZmE_#aG{32b&|>LvwOVRy+Pce5T!G6QF!|04?WdIc1m?P zxyWLx%)ZqcbVO#9;1XT{d4q<}Pg70(L_=(irX5m_uD_Cq^tTuc^HG@NER#p` zqjY?iB@`v{tq_-g@F(YhJhWepjtJqxI?D*er(mdEg(sWlg1?k%riMS39bFANtnr!Ii0RcWfMvh;C1$9GV%%?m+tiPSd*eMzt zQ&KvF32kiuwQ4K?T9SP8ePg3mnJUHpw4`)bC2B$goi$|K)&b@L>3kAet@TPB#f7^9 z=7K|xZ3NLcG}f@>Rd*gU14UR5%U{_wnZns~tR&F|B+-(v`4uZD1Z;v8s9t|K^&#}L zi0=Hk@a3yWv&yi%P}m7^wu;xd>{Ts>{TZR1Sn+)PoAGl~n!(hKLL#xnshatCdc+{? z{!ppc9~s;^gRkUE$70BsF9aZcd!QgO-st4rt?hR3w4beNr8M}%nx4_G?iz(YeaBkI z!b*L&O3p>FjIscuPK%YO-}rQmTVhNZ4Dsi2cIy{aCs~XYK>?)5P=l+PnE^tl+&5Sp z*0+n3gt%Lu54L&w!Kyf8lTD7OmftY0= zJ)q>x#Ea~1V^d;@lkgBOAj$HiRY~wr(_pcO<`*(sD}T#Ar!iN)4f6H_fp7Ip4^=-I z;nd4@^?odO@0hR}Dfh(Rbg^;tH%ZO4!U=GDNSx?vH_wTHGt98!v>H5%FTiB8Z3;vjGV(5|_ zrj77OZNNcdH6<1}sq9V@Qo=c!q!V>p{a9pquNJKn&qUA-ag$bf;9&Nw|(e z(RsnO1Qk-le)iePS;L98eDq#sFRCNM5m(^&$Z*& z7}bAf5OR{Gio^C}vshJ)2q{ioxJZ(R{T;<^@U|6p-fVwG_$ci`HbQs#K6t>^SbDEtnDYCI)|Bz8A<7RyMnu^>?N+qge%qJV2D^Us+ zl-RER5IjQZG%=$lf2pj>mM0dwkFI)5n$3M1DrIa8Imk@^F1-vFjZZxhvA}|lvM}ie zi8!4P`T!IE4Pr+?vfmF9EO--BFdBj-o77W`?@RAHt?ZE}Z1LURK~-VOSb56a5B4%| z+h8Y2x%+jk89z}$Rn-#nZzgjc1TR$==1dGvirniKSbG$xO+CF`Ywxcx%(cK$%AkIB zqCEDq7VY|m5gCZ&2y=-L_d)wpuyW;f!Wv6%GipI`IencrH$tA&cvj|cZw1R~A|5+G zpTDp_2K*8AbZNypls-oBK(V`k#V>+6dLp)&Nl)Rv$f{FviGS*@IXHAM3 z+QW~@Pr91rCO>L*js~m-_j7lwWsj_LMWi=dNBIwJDVoS7+O3uU`j_HR@59j+8y$=M zsrDoY`_N5>f^VuqayW|aflWpnr+{f2)bzexaml8K9O}ZlY&i5+q4s&0^(peu;XXnV z^m6533fqz1l%B8#6sydqn?GTqQX8a7{JsKKll*w(zo~FVKMm`CZB&JkCa*grDmq*a z7nHtYi}Dq?c4BzFXtG?TG%MWn3*9z#9D)MZjhev%4?pDb3x&n(W*Hm?mcRAaB2lqW ze-7J^VPn%><~FG%)pmA}((WFVyv|394UTkfq3d%2TD2QOicvp{MENBqkY+79_!cu` z7P!U^@hPgI337zLev#T|Gco9yTq|&rtXa^An~@poNW_{~Gx|udb3Cev9yQZ$d&v6v zgPVFe-&J`!@?Ij}&?u7@A#SWhUXec!;*hwzda9NXZ~tggVtl4$Q!(?=p~s974p8}y zY0Oiq%n}fpfJ|gUZ5&Q??0okthg3Y&vdMgyp%N0>c|@f&5+g&PX39RcOgkDfu%Y(+ z4_CP#azqq+mb^{n^UGu*PxB8m{rzgv`&$K`pF5{($2yZ%bvPmL5>;3|BR__flvod? zL1%0Y6XlR*1#vhL@fTQxMpOMhaOtcNH7?K?k>xmnx0&D;{abYz$wvE#ANN`-9?vvH znlkYb{O%~SgiP(^z!6J-uZfyuef~(@XufhKU73>B_tQ8O%!B0{$5Lgj4ku|L4S<0T zupmhG>{i)#0G@6{}e=84YKNuy~R^E;T))f9d^BkLT{Lf>ZD0UW^_gss?V+>N*uXWzF$fk;pyU5@g zPUtIeB~qx6h@gh{D`Pa+qZ*9F4FV#FJcY8(mNZY_R;B4{EK164$h~MNuh}s&B}tyQ zO%NErt+R7QHl$PoKN%*e(MUy|>d4tInt0Q=5s>9f$)1+v#XzFmwhYO9ULddKD?+E) zwAbEd_f{%}G7Z7IX2R)v(!qd%SzA-5_k&$x8}dHtRLx)2$iugiiKM7BPs>_mKsCnu z^Nli|P#Hv#3Wl&@l3x0AEAd+b*ENLE%%M6JL9|OgEnp~xA8+D;RlD(W77-XJ1|`j^V8Ej z%dQJby`f%NA898RmnrVmY{iSPAlUG# zlY2QqUm<-wa#V$^CZE9UQe9K6bMXkg`Oa->=3*1MTDv9WAfH?sI^ljtDQ-`Ny4#(; zKGlu)br8mEJrTKpsDQ5`w(u|vTT$(ug;6!*kkaiI2)EDFDG0eTh|tBP`B+~B81IgB>{%yDT1 z>+jmCtpzR^xpbjW#RZ+KRwkG1Qk8M>(|SMBC9p$f8?Am0W`*{fM#q!K_jrU5seX~h z(SRU(zr0WFT~yzzC%wo~Rq)j=;@ay2@rYJh%4&RlqT)IINEaI^1|=QnpY9>3fsO;y z1=x$|6X$X9;pQRgj0^qi{*J10a}*RrlFover~2bbvD80BvqcZ87m+Il-9zV5hU3_@ zpew5uBj2oZMNRn`U9rj3b3Agxm&UPwh>cfa4*HIx;?TNzgLq^#UUiG&UxI#{-T$Mc zUgZ;|^bh?e`Gz`Pn#z?#7oJLm-Hdz+DCYhM*a^pr>Ciw02>9#BB6|vDsDdL6L zr*pmYk^S19^hMCp0uU*CxjU}v=CG}1Hd7}$5{Fh)pbS|26`zm^hP?YMQy`I0x`=78 z?^I883L%Cvw}*uyqNFs`wiG&T5t8*B>vH6G3%&yivE9&BW_$0>vU)?t`;eBtXdNXf zE2v4dq`2AP0}*r26FHv;wEIx+Q|=abb7f?XkJsrA_!P;)Z!!$XgXcM9HgT_=#AW%U z9#SwHAW#mXWHph}psX8~W$)JInH;76Kntw^OSwH8DNXA_ zbX>ZKh?F)Os>p3^Tzcgdc{RS)ktY)p3h#;D^`(2yI^Bv-Gy&kbj8l@LVo1cy}vF< z67exSWGfWSJY0&a>}Mt7-(cx~wd1skCH8GVpe4|at|E21vgt!4;`u>3Knd%eTb=Od zN~3W6)#bx?&@#LkGaYiRt!y*!MkWUkT`_L7xwI2MAAgVUnE2Jqof@U+2 zILR~jAz$eagc3Z6BzB8ADioWVAe2Oe`1>BvP5T;Jx-9Rv=r2OPe&40&xo+oO*4KPs zTJ|*391Zv9m@Xgzqb?F)(8Y6x_EZ9wMhDv`p?LSo$xq&99(J_CQ_TyfCaM!bkllz& z_MlcP6;U%}4(`J{(ELqis|Nxd!J8#Pf=5Q4LIL4$h zz5|=6QcP4q21Z#ZMe=QCHo0Oo6^3HMwY4NRyql!eF$8L2yI!$;)> zA4WTXM}tH%!AC$i5<3<@87zzV1C%Cf{#RXiy4{zkakAfQLWtm_kQR;>&re7+NwPCO zOU<;I9O6V{Q5Tw!cV-7@D`=Hc2wP8FCqTQ*KkfoBbZK8$seSqgtsR^d=OCFXbCIe? zSv06#ot&Kngk}xc%PVL$k9^{SoD#Lgk#St|XpLk{Sg@6|3riZRrbXL;kV_2!CcA1? z1SiqwBCo8>6exSnR`{9f+ScN9xTsy3Wb#m=_<6u(cB8NG5MAJ}for77 zu_iY-rjF{Fg9{cM7ZTEjD!NS@cGPu(=T_$8`XE5s zrUhCxS;mUeFFh+^ZInAA87-}xeRg_iAs@BOloF`(`fCkQ;{EOZ%A3F2`AF_q#@!`MoCsg=k-Q7*Mwk1|6by*+L z$RJ@_)Nr{1%aS>oHS_H8bL3OzJ;e>twg-6q5mv>!dCUs5?Ki0Xp3I&69;j9o7DWCM zPT79vQ#OlGG<;G4?#hpmQo+Va(!0vmyxsf|_f@4{Y|D>i^;U!QA{?wJ$JpG~t&(w2tp(U_k@rlz8)?IvI<~qF>!Vp_$6OrTxFxcP64=X(y&Qa|1_9(7H1g z*)m}nVWP|N`WmyST~SUV27DB{?D`Dbd9==PBfLtJ5fu>{-c#A-V|~M+9cJc)l=!>l z-8SE8{k}%D1*^(WIolr%5B%DS*iebpn^Rq zxgH4prg_kb|Gsv(aVfSy&x3@QrYqpOEZOk`Bm-%V*HR()_uT#idoz^Pc7q%d2E4&J z3jtA6D13Tkz*k9qgk>FP63CHr*Z;QpgWxLz8iYX2N--~YN*>{7KqJB>q>}sfsivF)1vHt)3Y>V{*;Qu%bfT^*<9AK3>Wj@*a z?<^dFk)bVrBZB{$P)lG7|3^6#hK=;UbjbYw^9uZ*61e~GbMpV`O8}M~V&L2%?MVs< znbY1fp8!h$%CGQxt3vB!oE(q^LciVXA#d$pu=q8q8=&K3533oUdGX14LYj-NBCU}Dn%<@oKjml*t(hF9MW90jMf^7?>f#IL+awLk z%E}b}^U&X>g01|16(0UzFKNrRW-bp;;6(>o+r%rk@Gb5}T>ZP6cQ~e6ep`AY#!~`@lTh+)Npvb& zvqQ}>W|(26XMofwl=jGxK&K6ZWN+>PM5${AZ=S`Bm~);{^nVYJ>C#bNH-UicK;g$& z8Z*Fm1qo|yAQl1=EX&~vC#+VRlc$Hbn}zZk(!(t_XWKv`W~F7AL< zfdLH&76wwTezHebRJ10WIyk4{Q-E;9TZE}_3J!irA5(De8}!!Mt47;Pc{hLFddD7I zy14m){wJXt6(C&T;pdM=5-7;zv`Nr>_O)Zrz#MuJasiS!zfGO@D3=2Ak-f2jFS5gw<>pjrYx0jVQu~O}|j<_d34xE{2VVi`RzI{yz}3Rot5s%_2n zN=TToQUs*>CgYwwL4F#5&jzNqLF(dsp3{b-+6j7gX?`Q5hu1*6&F!(mAw!+X`L@41-+2ZH-8`?uCA*z4FeWP5DvK}hiKJWLsxj&v3kimM}m?4Xs z0nTG~W3J`d7KiWVaYT>>$FO(d9vQqYd26Ak$R_Q-v6Q>i5B<6D=^|awBIQ27ZTcf- zf3`&>X2Du;h5Pj$j+;+DZa+kK+jt$zKZaL-^p_jYCPtl}3O5G_=BFytXz5C)At2RX@h9OAdUj5$BEFyM21izo=tx|*)rb7ySe}F1r+$GucLbbk?$_z zb}c&RzGnW0jbNx|c=QV`W;=|3%>iEnL3GqhKEutF?U;ya17~2$_}@4Lha)0u+Kq0f zbP@pV>tc&dvF#C$Nru9!e0bubGj%QMuxytm92~KEToaC@#9|Z8*H9H*Swe?@+H;mWy8%RGZWLT_i0fyw^eDZGj#aUAC`-JBq zvRBi5CkbdoR1Eq&yB*(9YB<;&&=!$pUEupC;veQhuDks`kK1R+*l8QXy7)?Bd%Vi1 z(18)jPb@eLu7If(kPk|#mn-~Sb#FM9Funm;yrftRLNVWeg{$4lOZ2FJx>j;ydKlZI zi7@EpX5Vc5vRDU9+GJAEB_!DYUU&L;mHqQTR;Ad_{al44+xZw9c!9flTS!~10K_XI zjI+L|F1Lm`e3v8;vmN|l*D43qfoVE0uLv#khQy zfTfkrX6ZLqaZW21p#kvgaW@&D3Mkq^QFE&?@$+Zf*bYISui|3{zV1A6kcLR?%@VNy z27c8lEs@SD4={$L{w&vX=M~%v)5H(jOt~Qb@Y=-cKzL}Api!N9|vyI}I zT_7s?-oK+w`$o*YnlNXxi6+2*kyOLg8{Nwz(jG=11ZwB}<*~fJtLDQo=Wc5HP9J8H zG|!>}3-PG+5fGRiOwi_^3kCqUg~%FwJSC>oqLdiHhQ<>>FBnT5jtk9frr7t1D8@LB z47xS?pwi{>Q^Ox(n1&e(|NTmHgK|VohmI=%xxDMbPUaCVFvAqnBc(~zNfF6rlSZUq zdc^mtD@o0r_2Juz7#i;>Cuv#==X2zVbphR146E4BvNAH~32IA>ywnl23A9%A{BirK zC1Srv@fL@a5fC{z|9S-y1&bJ}E7*)IW(UOboP; zifaHW*!aw%rdL`291_pe`a?3m_PdY^S@9x=oN%3b(fnUSV_h*4bfe;MB z*}OVpYY6F_Fj>_#qg(4@*_(z}^XE9GwY0+D_)?1n{jM&J|NmRWXUbAoNIVU59q zhI+_vcMw!E{F%ck@*^@i-)BEs`Irw^>zsKBk<@vD6#PtYPt<}3O}_6hL$TX*Vi6F# zWj^^{@Vto)3)<4YK0eboIw8MDc;cP(haS8tAn+r~3&|P63X}n%di5)bt}UowRgCA7 zJhY09`C%KMnSiO6-}?gRzA@-ruJcuFQhzf<-Mnw^_$24Brpp|WFVCrQ!(CX8fJ&`s z_MDM%NBB7gHRv0i*%sHFJg{&p1$7cwu~aar1apHyO7oj^)b!U+Tr)2 zuwxQ&N9m|Fcni|OXj%B&0P0inJM;j--Gzb|3{L-#V)s+{f60=Y-xTNSKuHFhQLdDOqt6tG-}K-+&*`M)1iO zbHYNlb$69+faEjjPS3ERs_{r(IO@b&Sj@VIYrk&zG(vF4>%5lGMc5KGB8B=>oRh!f z6%%18X)CZDk-(&gPu(sUE2>64c8>3yx5)52uCO(Zk$+=}8`qR)VMoUwid2SeF zrKOS#GHU)x(dq2H8;;C4*q|HOvKz@`eJi1vFX|S-r&&C8(8WmV7r1ren8^ExMaT4d z3eQ{>?)Z`?6Wa3#6eMwa6jK+BLF`%jGxvX4CID+H{CnPPWm;uYnaEemN@PV}a}`kM1=%$>ZO}>)-R0hIp8kNlT2^Sd1wV-W8+^vj#lmwiJEM!twjheg>fG zyl}e#`}6Aiftyu$hT2w(<#*d=PbL;#*Aw0cS@+?c`?^IMf$;R^4L3lIzRoMc&Ysjg z%;UUi8#%*d)T!0|)axI%6^#b<&`~NRLD}TY{=QZ*mtfEwKjU8@o!`I$R#!IAX z%05~v7fepa7vKc8;HI`3y(SqEF@z$pnK!?h4l{!DDssw~E1?dA%QfbQQHBqC+}_j8 zTe$ekpfxNBeg#*>NadeUCe60$Cz9!#+b@q-cqTqtof%s5ZyV@-6C#ABK))J?WHkQn zK=(N-{t{O~bzQOy_MDu&B*4LKC@>qO1jVq_W(E96-bAieZw!B?9#j{Rj9#w~ap5p| z83_Na;R<4E08&I&KTmdkIa1BETs-tz=1u? zC|7X-Ah7)vm3nQU{{*P(4;TxphmUY(%%KzarmS3)hhuI4@Ie6l0Fak$);~Whpq&aS z7(P!Tk-RhD`E4y<#EJgH;J#x6?4i|g{NwPFYdS+UARX=p>zsO#vKG(DHceQV`E=+< z#7wm?rwjB=fsB&B#_vq7ipC0dFPVS?V}Oct^WV0epe|JnWFN-M-WO;85tq{Hx0o1h zPS)inWZm@0;@E)#rc!LfLTUV`oUn5(E_`Jd#k8#sK)PEop z_IC4z?@(H74n>u0MW(3jX4v~`JKi{LvujNhxr`o2|KPyNZ&>*(@N~A?AaUEnP~Ve{ zP1|3CU%K5I8Mk-I_Xb@*0SOl2U2;{>`DEeQlB1*XAXL>IBnYzXowJ|7jYk1g&*(>N zKd9SwO4h+KS02ZtU>#Mkn+%^!O<|5s#NqEV!1jK zKtU(leM!em{%DVIvx~Wdt^_1jKaQaFbE1rOY$Xp=USq52a3rJ2yqCZgHOogCIY}OQ z`q|LH-qi%t0e9bOJwtdNmoFo3rf54i2AtgmYYN+a1VKdJ#=9K{h?8Q&7|PSLC-}7a zorJIl@(2{{{T$04^R1Zzh`hWaMLkQt3ZGhu07?RPw??JllD2=+h89qwIf?xN7>sD4 zXX|)DBr zhJ7PFJ&CCr<|6F5CBttt_4!vs7~Zh-K&p*5DgW5q9w~T$0#M?iY*Wb)1r%d7;XF#C2K({btq1(NSpxD*q$`g~)vW=msZ7U^F&bJi1KJDlCD) zi#=Al#s>TT6LePGtLa1?v)*FzIjix7;gRffV$oYT%&@6Y@2KXx;^p#UAZw=pqD{Ih z#78u{_8oyv{i5`EYa@pAQUz{Chzl!a31|!Ky?zkjxY6mqXp>u#APG+i)5Ry%^f%6J zeCfSinsuSQ3Svxx`2^w~EaDh=7Y5>91no~n@* z7kU%WVhBH3;*vM;4ID#6JhfYNs?9fXg7VY4F7X{w@4K55ud;FQg1M-xzLTKOYUX+6 zoeI5i;>uq7g)>1UvY0@Vj+potn)^3Bo60rlQzVy>!$VM2S^G2jcg)srKE*-5r%cuj z-f)7MS@E9~c;NJeOJFZh*%`jm$ame`(ms;o!m}XqQd7gZ#bJU^oqkujGHjO7|2tG9 zf~!9TK%#U3LLw&H{ms*U4MS22|3U`YamqZ!Th7hAQ7J&Ird%K-_02gNVvj2QdrP00 z6=gAd(O75D7vJ(>HDgJqwlz9=SqZzAt=|`Nw_mlbO0#fI_AUu6i4Adr$GuZS4$uCy zBzF*|V)>?iPSE8(8>uTse6h5q_`8YN5XcY2vL}N2J7Y3&6dAJ&&MeBScJEzjxuHK@ ze}+~@K~A_2P#0(`2uu8Rf3G;3yr!}7%;DD!TL?JDn-lEdDms!)m%Rw|@g(FDe9S;u znOQ_+aJxUhIXgeDs=Lr_YR>%)#Ef@3kBjnTg|nKxi}PRX1pQ08{O?}Cz7~kGyPoV= zv#Gpw#Jkup_Y!w=fO-az!fA9mujD9UOlKp9Q652F@$=_Cl4+oe`_H8>%I%Z5SOe!yR)w)go-5g*dqAyT|r_OY>b9YTIdWs;ARqxPpFbIFm_PX7i_5$1*Us zE~k-8djSplwFVO6v}N48{g_rBLCH-xlsQLcCkxgmZJz)93$JCsyyaI83O^l-`Io14 z9O*G2lF7vpUN+Ai@WYdVzHCBW_9YLmv$_<%`H2hN++Z~C5q zcTVlV=xy`Q!E_kNULqeJpimEJt+-!XeSnW&C38&vcpD;ublI3_DeNlYE>&MN|2?B0 zi(cLzvz(n-{*Bdyzs5YO<5^N#`|+om0)XwOC=rXh#9q6IZ8@Qy_F?e^o^>YbZuRgq z&(q>;S_Q|@2zff~Rx74~0zT!s0MrTYKHQRs0}G67_^DgF;9|KGRD>21RHzrm9D zKRs&sf1K~g^_@~A02#pS>>+4WR8&CLT@0NkP;?AMq8$tY9Bi#1B^8y+jW#qgpxOZl z-{tFr05%XnI0d5trS+$yY4wgqhwm(Z-t?<)E$&ve>J`8`1V#fWhd{tk)DFSig6CFm zugG}~gu*-J@Q`j5C<}LoPEKt9TmXh>tn~OnAX-oJ!ph$MEg9x1m~q%b!xv~sy#mf@ z{)8r<8}k+8b(5V&@NK^?`Ppbv0#Q;eBX8v&aSGan2ArJozJ!lUY8g4)h4=4K=sS;&Y>-!6|TJQ-w} zw|k_07Dyi`M6V(w{#dE?%=Hw^F`$_iYX7{XoZtA~ruE-2_W_Ai?W~b2k%@dS8dM8{ zRrnyVM}bI}x~*N7%FAe^&#Z)1msko}cnWz=J`l|t1MZB-zG7=kEmA*XWW z->(x&1z_BVzn?~izBa2*%Zq*X`?*+J_0F`_QjWq~U4ua_QhLqX+DfDdV0@OiB9riM z3Ic+~)kTt9^`-u)g64XJZNui2Yn+j6)*NL&4*8F5&PEA69zZ&D$j{*D#1MMh9Z)Y zdAslPXNd64x8Xjk3GsY|2otQ(GM3ui2>PHv^Xas5cF@ z4EhSeQQertE_(gei3<}ojem82E?3ZIZxE8e=V?ggrv(I#sGL<7I)@7sL4w!Gs9@(I zYaF%`;5M$uler?2LpH{NASh#%ajR0<#?U#gLZe_7w1o2Fl;NWI`1s$mnub5vTj9v` zi86+o(pH^`eCg210DOMmRW&e{sU9w5goPJ82|kVAj~5l4 zU29&-tI|$O!-+g(Y*#KY)x7l_K-Zv?IX&FoEdnD^q1#V1V3-s}0~TF*mJnae7M%N9 zn6#&gl_OxNg8Ow{nP@9OFuZKBnJG&>(7<-Vs-4yv-d8xq*<_*7+@^x%hPE&zi>I1o zBxKuu?hTOIKm>uabY$5l)s{`_UZ0kaHg{fBP%Pe&hit@5*~_8GZa*qCff=JSDE zFzp9xjM>Z&0#j3$50=oshwk%N*SdoOO$28EzKfwvN% zwR^$OjW$Z=L~_=APoA4Bn@~7A#qA0pW2s?|B;rnieO${V(9#l^r&^#3ef?ugd3VcO z96rdu09CZtw4upGxo>;*9yy-`$Y5MnH}Db*Kg@0sfUC?ZoE$ww1uNb3;Ba)tw87qY zZNRpv8&z5h^NffPeFz~b3^M@?5!I7K1fSIOgJb4==JJH`Tc;?KtkBV|mwi-66yLj; zQ~UBt^F@?ruD zj9{B{2s_3p0V{`@#l*tsdnwFzEsY=_Yj?lT{H_=0;LG1n>|1pP8@+*%nS1fL=rhTD z(WW2J?B`)v^_%5ViGVA~?0|K8f5U)ywBC^y8-u=CQAyb(LCvl2;qgH~!2m(pa1i2L zBdo&F{UAeFG)JXkmf)>HmBnn% zav}1=FLHczIZI6@y2UVGo)3IFG7YZhzfN_`@*X%&{qv( zmu?pyzO82Uf6QE$6sNeulV+;y4r=|V+5?Hh6-fQSE&85U#x8kt zIsDL)lH0*w#`#hxSggf3xtibcaJ`M+;ij$+PHr8T~6!J+AJdu*HCcJhKMMl zrkf0VK0MOK=O}3_RI!hL^YDYK+d0oyYKys#D zm$1u)$z=v}s3|h));UT(smDcb@Nr90;aL^Ks2ncJr(#>&5>T54Y2~!^=3*U%N5Ma` zRN}k+y*)z@?I;JOeJ9q^pl z{I5-9%>>U|XlZhHdB8+I#1PN1OWQ)ZKr@QEmU#_qI!hswZVX7z_ND$o7zB5oHzDMr z-N)c;4E+N&(&9z2O*rLR*tsk@34S;DglS|LvWL!zvkhOvQWbx3HW15dhg5#(>>NfeXwF6q1?WqG z{tt24F4Ct1i-RGA+7_Cr9Vq&JK*wneXCPIDQZn@#Yb~Hw#EOW``Vas428@F*A zif~97Cz(Gx(S=5P=gh=PZ6ee)YsN7F`TtiilfNtZ*YwcV5R(TgQ41xH) zG7S!+aaF)lHW7cD7Er@xIPeUf?DBsk?YgxfBdAFFw6C&2Jba?QMH*i{%9mZ!Sw-l3 zws(*(_`P1Lyv((desVMT5h|D9lgX2`VXYmV8!*~jwwzyKwi`a*z^x<$Dtf95YV;=8VS@*+oD_^V1;GGOBN*T%u zVI$lqOEgaMHJWcO%o5l7XE@Q}9L;SOJ2mhQVG}a9W30;xgUEo>XB-^!I*xbhl#TfH zMKuRhjHd%p2YSut`dAhqXG8uI=+kgez714$M0!w6{PyBh%br;V~oHxDOhZlJD~EwnQHhfoVfyz4*6 z6Xjd2htC38wg2i-uPUr2A!v!83J#IT#kdH!u;PN|mepv@)I~#s{Q_r`7J}V%XN@~H zDz5=M{_JA*S}@EH>VPdpNdY`OqDWXghStGAupGYqN1CgmY49ZC7WAiqC!=2&AXJ#K zEbTT|r?E~g!~gCDu&oyoM1uT~O!lnRnasy5GqoFjKY7L>|4!hr7xc|!yx16(u{)B& z5t}Wt3F#WL8b=CTJOffMTdr1`bVX$PV85tJb<&T&$M+2x^piI9DU0h)TooAFZ(;_C#~B%%K`+Wf)#06VS8T?# z-ON6U2VEtFj11h;Rh2O)^wG~oO-9E4sRSDvA^z+)p+kf_vp%1Pe=ZU>_Htd4cvGmO z6zRCBIHm-QGS`@yp}7sJ5TLPS(doI7L}2Dt7^ba5`0cF?Nm~%UUvYk}&|=%)KkW~c zpANLu@^EOj&bC~WFy#Nh%Vhf11st2gj?%2!loth<$5sXkK1fd&)<_{1q85xr`9)d7 z-Sgwy=O@L;Bn^*$O#F?7Mi;xA#?Dwu218mWtQ5vM6^BrXxu4idmZlfOxO(DakjA{x zYXNVpv`pO4f3zXpiAT#@#L4*GsEX#0oCYzlw~buxRnu@{e0X=))jk=qp5VK z9a7^XwH})6mRvou(va*>g7nf#OO5y~{mgfqrP-tgV1=7~p1?vr9z6y5(R%Vpx2bm4 zWu*K^5^wu&5pifQ^58c6n7H#orSo68fV!V>e=|CUcEB@hRP@q5a#yUn8o%)@mwN#Z5vKvFc6BFm0Ib`W~9hpmuZw=;z{Z%lh;)i^u zmT=^LRU7qWj$YP$i%v_97ZgFc#-y-;O+F-Ug(F4SK)A(>%FN0dO|$(n(?>TmThU?N z7*4W<3K={(PqYPOIGlZsBvGgtSt+xyY6xJfdB>8J~L@|bbdF^I1q zLn7=-FdkAmA-5I31wC*gQ=kcYcZC@v0a4rIZUYN6=S|cGj!6zMPYF4aFNn~<$#5Iq ztJg&WA4DsgY7Y@TfKdRai*r#yEZsjUA@o@$gzY6(S{x8+nK+{9x2f^EVwSYTMlYs$ zu|ExFSH+#N*BdHjXbH*i_CJry4@Xt}5u1oz#&y8-sH1Z#+{N6klr^$CW!T;>YgAqQ zli2{ZDKS4SPX{8UBP~kteUSD7nc_|M{;WK*)A(U3?kT}va4Fs}QBdocE}zVYb4lkL zVNLe6&$j7DJVGre#Mf14Yr``&Zg2fHsD56JYCoC3$Wz@(yv+4IJB>ziU@n=E$THH+ zr)=_tvMhs~(BAl?pX2+D1I5$t@Cdti_b^AorU1EDaf~z+V(9WBYr%&4uJ|DbjsdqJ zkHR;JgrJw}U($aD0tj0C4o}qC*YlX8DiGV3JsrMB1hu@YO9aE;oKc1!&yiu%)2Au7 zcp(q{bRLjF!;E;5U2yGhm5V@0zMlNUa_RQ^XFN(gM~Cu;dQ+v}~smE;CLlm}G zTQ&E`vO>(FSvf$lpkLhVl!DI#&}X{purvTkBRnf>g#8DJfhexp_Z7e9sUfTq#ui#- z#5R}Nh-8Jj=6-F3$lnPDa*g;Vp#&5jyQzzzvb;83E-QbzN^o{jGWc>j!w*^dxR`Oc zevya!Og)eOB1yB~Fp3>D%{XYaTOMew#X_@U+5>|I+Sz$bxj6=8WJN*P=?r?XBQ~as zP+39Y!hG{k94_J-C~~dhE911(@&(#91?6mqqI2BHm?WT47?Q#Yc#0lbE`L{96#J|^ zf;oxK-omh>k6#g;21_d?|6;J}y258tQ-0~48~n4zPc3?ufj1uuo!~5DNni2o5dPOH zd^Z9;t{zdP88LL~)7=p>$2(iDc-C5*PJ;?i7i|6GSv@rSkOOA((H(F0PCQvUXT3(n zF~W|_ij0NPg<5=NrKJ_=3I9h2_mL6sfI_SY>TEDXB1%9FlNGM3u_FaDh%l5CqR&AK zm4r_7*<2+FM4?NKg*fkbwS56gJ*YQ&@9a29*-jl@Nhc>)r`2g6A~X7^-e=&&2*-Y5 zQZd4X3*yoY^Dwa5Zk`MtR?5bZDgBFOdp|P36fLSvI=)Jr6;n2Jwtf%wZ(;CIF=#($ zRW$nD$OJgo-x2#_gTvZb4tW3_W;P9`aA$l&WT)}BM z9T7O2p4o0__$Gpws8pfIAwxTaG4Et2t3yk>v@>|9HQzi+=G+^8h%?{>qQ|zMR!faW zLMG9Twri(?`>fCO$>E!iVYa!7!vpVxDg@g_jpbNFLBbYuLQmXWkxR4jRPa(*mSjab zg)YKhu2`R%uS-<$rh|O`Sz*0cO|{9Vsj=ED!)4*pnk7MA%Ie7Zm|I>^1DSSH54WbV zZTu+(iLx>ze`@lXC zN0v%zqIQ1H!I+GoNswG1!M!Ke`>6Z;P=()!{Ns?-r5<9)wV~lykTfLK`oYpQDK5^Z z_~EF<$?RwEAt9F!GG||WwTjMu4gDv~-=?EW`_Xzb9{;)L2pVmyXR@R0+TqQl5p3L_q#B9E|y&^1o{b}9_ z8-G?+==TpM<9tB{Vyl%%Ai*w~kg*TF4GzC^4^Vop?6Hk|!h zpvIZ-C!>0>ShWkP$Q1XHK6G0J*~-?8xrCTK^A_?2jczL-hQi(#we*AQ0qFL9c%m@n ztZZTRp-#<;q;}I(1(`Wz<oUV*mU-aT^I$?(hoZ3Uso#i+v8bN^yBs?BjqL?L4P4y zR4`}%QK+b({8D&uuO#B^Oj)4OvwZ8ZZz611q7>JPN0|ugrW{ZeICvPk;Z*ZwJ^xMT2R6cL*!ZG=1BCt zkstBY9y#InH`|VBD=Xq!-YWL`RQ}rEg@+?Vosut#h(|DOi0n0sR0R7!ny?DYa!&u@ zV)Jbqc~tDm7^(IyKb$92SxR*Vs_*RIgWFU7%%I!Yk}UM&FIZ?;l}qFP;9wu~X#iia z%rZqcd^w%ChnR3i^T~yRgtco!tC`L4^l+JiuVWr_0hur|t=skuQcd`>fDdC6g0sI) z{#MKj1GL`~yK$+l;m;8(lNv4@AC}r$u@cNULB*hHH7uJiE0gPFKJ=F2=-mDp%@Fpe z;%bv(%w(aPzFd436Q$DlEAz|&#s$L4gm^Q6PP<>6G|v0$mtjxQ9uUj~>0{M%9)Q~! z#osgi;PFSOFBDjWTGuQK_Lg4&J$MH#`b9|~h~2KTWTU2tmCuR(w~8$!C~Ld&vfBUO zs=R2aXx!N4jD(G@W;F z7`d;2^lG?|2%--YfrASgv;I)-L=kacpdy(a@J~y8kwE;n<9f3^4zvm?1+_YikGQ#j z{-SArmSUYVaf|g#7F~7xt%#RgN^iwlEeh4+5;_o<2b&Sb|?EztZMDM zSo-)FBAa}m4j&cS+q-l)^lIj0KZwp~o>B8D)c8P!12G~p;>+Jni{72g+Dg!Gu!^-r z+^mLNbr#8kL{s;@t$_6sArLN_Hf}PGWx#!sk){5zwsFBd zQ<1Hli5=H78w(3w`r}kR-5Jl1+)$FyCgCCvhs;iSWbKuuwtm zTWUQ&wHCakdOD~$!onI*VbGvEJ}Ch|8~gjxaOj(u-)R(K=l%Sp`K%%L4-FQ6;a;Wb zro-%1ocCloDP=@QXCnkA&@qD*GKM_MY$~O?zqfNOyPJcMhp6CDn|+XZPUhe-nY(~Y z!KBJnHgS;#)I!n1SQQ-!gb1lY;!MnsJpx-P8Fbbu9bgAJt)oVkJgMo(tukIH)BT@; z1K&9Csk88}4ge4JIf7mET%7M0eMagETN7&o;lQP&&)Tx)){f=M>#IE}`yv!fS#<(x84op?04@k55|z=%>etTm=CzXJOCeBYLZ_4YlEuKdpY zV;!Jj69&he6x1?@+cHMASgR7}m~siMM0)XN+dx)z^=5K9YGZlr%1I0D`kMtQkn@P* zP-}uVdSB0mJD@kGtWTRWV>u5Qc?!kbbf@>s)njR9-O5ZU+G8^3N37iRL2=jBEuG1b zEDCN&yXM2+3FBTnd{Hb~aGS-HvG?S#jWmUy*Dsb=A-xM$FvrEv0-;n2?GdFdCt{{vLJM&0lw>lebc_P+ zcYflBTm6ZczFuJ&VF?LmSBVdN1rg)t6NvG@aq+;7@rVrBsT!0{1=yio?LR;o%(W77 z4kywXJ(*nQp^^tsC||E$xEbQV^rg>FbcZ&)C}V4v&!CC3A}Di^J_Cyc`l1#`mr@FE zMO>eQ)&qO3UswPt0XcP&+U@|e!Gre$Tefp)X zyk_|0TyS#8h^>OLHKJwZ9Na`8LHwO6dhmQBMVfRU&jn~Zm2Q>^vxG&4pDrvD2{V?a zARCv>PRP?&9{&B9iBRW9f{K!yCyjROB;RP0KtT-=5G#d=5G*@}vw+!P4oUUrhD=J* z49H=J9Qr`CaNMyiVf2SVl$aMD`WD9q^p(X3otu#0H10>YuS^BXBa#?bG=^4-ql#&m zz9*1$nZ}fljHkY6!oS6smo;u-a-Fh6H+cYwtIc#G;tvIHH|5seut1*kj)33prTz+h zxUzc#;l^-GLx4Al>~m`=VQQX&iOE!3L37S6aW@s!wz*7la^T5 zrl}87f4O??^$|`$!&k}O(}7V#DrLLHw4!Wmv}U(HIfi-236NBH*8)A}3cK%gPV}A# zwV5VDSsZaw0Gk(^?K8pmymM*|*rp@tL2BPXu9lat%k!JA&HWVKHR8*&w)*pb#+T(& zgK^I-ZV@YM-ya{u;N*ES7$oM$PftgXr?t;LVSl$H>og4=QB-_Dir{Rn!C9oCVvS;I zBM0&WDJj%-H}V&XS^y_Twg7?L8DrI~0(}zY3H<F#QXxL!+J zMf{fCb1}ZZ(~RAgJ3zjB(W(ZyWsVQ~z7uDiXr0-Ih5VE!-li)G^G>pN8r&VJpj`0g zlzcBIp@dVONW3HTx4ExkJ!(^N>6k@NN-f{&e6WTYX`0X(k}kY*PpcY)SrR2H%BB{T z38@*)IZ%|--CVr{zpQ_|JH|aj>53UfM}SJjihMc)aSRX(xt@kI%0 zbcAvq`~g%ofVQUUh2P_3es3u9#>~T`xxT*s=PNMH9_*_C0hY+8ckEjP04Yv44DTV8N|bCcTDxh*_Ur2_s4WvYapd+SGBPq5!P$@@1}~kkk4Q?W zB)~1yAdi)WZ|peMxje_q);8+D7V;;IfQqZ+z8E6)+Nak)zZq!Bu|~dUz&`0v{3`Ah zt_Z;&blHO|Y#@)AXABmbR!rS*=KCyYRk!%6MQ0?`qIQE+iS&3e7>;~XuP^~b%8ibV zrGA@dCRTa-uofvia&{v|Ll^BkiMW0MLP%{Dv8utO%EtG41f3+ax)r{E99(MbrD`QA zWl6FV-%L5rH(2c$wuWxk2hC44NYH&zk+9J&F6T?T-wOIh(m%_Ao%>f;KQf52%#y29 z>UH;>92P`k-7~WU0shi~i}^?PKw6>>!GMo|=DqiC&Q_Ny zUAWAKHcGlks^U2(BG7mlf^a3w4zhYIca4ynVe671Oy_68-kI!y~}A4}saP2qMfywy9n=3ez%!&=gD5 z5Eu^O|AW1^3XAHE+QtV_K@m|>NfALBBt%JR>5@)CB!(fRV?dBbM3E4Xke05Yh7OVL znqfphni-m*`9J*L>pl4&e@EZ-ao~2YnZ5Uu>sjkw_gd?fwG1ntX}ud@wLZh1pPeiS zzP%bq@v4M0mZnXgSM{{tdFGNw=D*nJi_evS={Tz&mH8d*JbFicQe;y14sbkb)#y_+ zowJx8GLeh=$aZ74XWkCI22=LsGCjackx_V%vE+;T`_g*scMxp3^v%SE-)FjEw}T&x z*)xS}y?k@yiWbM0Ln~W>tZLFb$(m>Z9alFuA;rh+|4L`{IhUV!{DLVv+<5s;f=zUW zW;CY#gVsZ(`SW=HAPNc!0e32qkeV4}0aLT|*{bQ#*=5WAu zFP1jI6;=CsgYWz>m=T)w1HLP;Z9}4A7;B~ycs1ZkjPTnv&f9^$e@<_>|Do&dy?plw z9P;}|n9JC{J=)0ec9*7D)-U|0~KmdG(FYM=66iR=GEvtvvqb^i&I!VL~0%x~o|OR;gLY z!20Hj&pqgEo~D_w+}ch%tq4sG z)%J6-j!La6NFK}03e**&*mf(_?c^+~2CC#<5g$FR3FULzVUgXT&~ff60v=bWD~}(w zYEXi-iY+E3n=aM(XlBATDLKkuQuI7soQVkXzUdZD%%FQ8BjFJsEBF(}yMZ zkpB>0vMHu_!@Ujo>9RO_p#v_ zddPd`dzyds5`4D)N;lYr-TYecFeXPpf2J#Z-pWj5@ES#xw&UCHh!#_mx$0(n(ROb= z@7%{4X)Bz)W>BqtsDh{}7b#TCU>QE~w`l|sN#1a!QDXmB*O53ViyN3LS@;R@4$9Km{$Fua6kn@yjkOdk| z`~6jMk&U+2bV9Sd4GXW4Oo&DNE{$2C?QX)VL7Bx~gChEkwrK+k4yIx<%8Aqi0>r&m&#^paY?lxVr%89FAm&akS& zgYPfM0zfrS(XYNSErB~+z9QnqBS|6{^NGH7`|!#CVgc)ajA{5MF1lqVh@$pY7S<~M zT$f;|V%D3Gyn7o0xivVHqR3?|1wVdeCx+RQ-8}sChw@|GQ_5_hIOubDfK$?Xj{hb? z&#uX9dp-ljXu!mwM~sKF)h~?H!oGK$qv>qz0yJJAYYJ9teWfP1sI_X*J?Y;CR7=do3OY_LdHy?H(V@a)@qQjj zodA&_1hVpH=wwdMxhl7PqV@Z}+goe9bnzm>n~nb4^C3aW67*f9@jR~G%uz&|i^hl% z48~M#E79D)TvDTI_;kUyN5tGPU)6oKQ^4)3ec?eaW-|Yc_!e5CaWDGY4V1uomx&#U zQtE6^Cy6<6^@{`q!ksjC-BDg4UWJOa*tju>=n1Euy#;I9@?d)5vx0KRncBI~HTe$2 zKcE3ap-_P7R~$UvK3HiA5hAaOFB)qcYExlh`0io%n&y!Y_5zyP&Ta-Jnhr4a6>>o? z=u{erEkPhH4@mJUC?f}CKG{-;NIge@0n)(QG5$C%-yZKIA!=-FT;DRZRMArGV56~> zG-h?pJvgq}{6Mz@!91he4-AvDv*ZJ0D|fE9D-7jF2pIxx#(@%IsHh$Msol$Kjx-_r zt)Lg}v3J!b=>Uh6M=)DES7L8iEq?QL*)7wrar9nufF*guvoTwvYoRNKs&?Po?wuez z1j24t8;DlS1oZjXxvUf-uBWe>#FfI_0#|yn-z>i;W0EYwZ;UYe9&99;$~Smz%cNLp zHwQx?Ls4_*xf>^6ypH$ml59rVWepU)wp|D)ZF7j|AP`N5+IS1!^VvfE(mj$xpn!RJ zcvM$c3qac=QJk{J^{J7GR;#EhokhE1`gd!{sKtB_ik!4ZTH8$sAT1eL-8m|Wl&M(B zm-1IVXEeU=-?BYhkJyYx%X=D7@7V}k1)%g8t6UPZowoMEbb|6{l9T-5ySh8M-8maj zjphr$>*4M79JJnE+!Gwa^qIL}VG>YML-92iCThUUiYv+~ECwRSA9%h9}h zdgwUls39d|@yi+w@1tUnF80l~kyrjrYrU&BC9O7hHul8l_jTK~3e5 z*VWS{O-~}yu0_Wp91xz;#73{gN>CUQRPlsn@WC|LU>zH?7YkAh5D4VGUp#Fx8!mR< z#u|Kj@ZgFFxZJrD2nGv69Nt0-E?4FLUI&*e51k3Yh2U;2kV^006N6(1^5Vr+M{xOn zxBXu+B)0w0UBkm)&c&jp#CF5Yii+NtJg2;HkC=|^5&?0+cN=THcXR0~_wH77fFOj@ z#_Hzg0531wO%t&HIwB~%+nYgx7AGeSz7n%WRO{o+HR^n^vkCKHFD51GgTt#625Qm&x4!}qR>YQ z-aG%g!MU)M8M^8_42u5C)eD=(lCDA*Wn=8i#Ziw2?PCT>; zDp80VHq{4#hJv%l}|8vui`GcAL|(V&*kyE{xe z0^5|PQU)m#`gON}8)kEhiKi}OZ80sLtQsX}}rtzJ(h338P zO)@ev-CJg+rn)A^2B)K&henLiIU5zuUbDFq*L5f-5|iHMdH?i@^UTWQiN9_ZosG_= z=^Mbo#ogClxm1c52Q6iCBx*QJTrnU?7t!;x#jWwI4d1H(G4)<;uc{)QBZv z6p>C@eb{f-p5_kJK4&=7s*}vKJUq?7Viu;RsY%;wXV_vhODtXm+`SW~n_qFV$K&kW za6(P5u4~s-*U`wxigOq^wlpe(EsG8a_ne=jj_a$}ivCtjY>X0p>;&TtCs=VnHa237 zGEeb)t2!sNyL*B9@I4S7o@B$6dSxRGcerJg4Wgo#Q;R_@vchs8q~UXI*W~AH2Gfq{ ztc7}}D{UySOs~=>df0I0V?Whghn)f(za;XR8&PuE>isa>z~PSXWJN&XBzea_r1KPp zrze`TN=bP%GNWrTEd`|ccBsaJ%!u`r9T1{bJ&%geFEvvOa6#2>Z{+I~N3Sary9D2Z z@$wjp|F!Re!C-cit16G4Y=MoJF78dvWI(5klw>feiYm^#V%!A~xK1aVz6P{z%BwK* zd9{>qPY@3x7ib=~{(*>$+zJC?68=U>!Glej{0v8jJ%*$L@W|OZ8Bz5r29vqYnA_Kj zqez$Ry7|l+zBLVv{2KmzlgkJRg20Z+Kw`3|MIZn-k8eA|b@*;3X`17_lc)arXQazQ zs5;4k;Fq&iS)$vCyv2*=?hQjG2M5ZG%&2D(aF~?BBD`MMkd(>XTCMJou#j~U=exhA zdphbi-w~mbSOud=$0j=CO`Eb+t|YQ};;|b=dFqn&LEd|ZE)zJhl=~8{9<%a^e4cna zboJiu*r3#`(oE@3H6NfI25A-eKhYJHN%lK_?_zkiSIIZ?epR-F;m4=BKVP}WvazChP!a689c-k7vO|ildbTyS4Pa_N~_qv_kV2ZISXQavZY^nb~{8)Qkd!KmN#4R7a+;+Vh zF~s>MO}0w9>W4$+38LDZabwiyAvu$Lz&JPe-1L>Hyzc7a^SUxMEheNB*9OiPGXa(Y z2-p0M!9RuKvCA7xA4ZT)m1{UI*=5~;Ut4)!f;JNi%vE(`KKrCgX7I%y(7gk z^PTV3J=^51A-XQ}*IxFsO1@z{v2;CJgq@AglH}Nb?Qc`xj?k9#OMV);lc_huH(nX8 zK4XNEJJRENcXsR!XXcQ#?J?4c&hgwcr|U)edmXn`B1REme4f+Vs}6P)1dXhg|Dg74I|%wt=#+(}L}qQs-d zTycF-ldA+)sA0WS!KyIqR@D#NWh>#|f6VaK=zZ$%Qqua{WK2@tnX;ypL(=gByhfaA zTk|0#=wWU*O}m$Br|rs({;B6lnIm^If7&ge0}EI>6ctE+!eKUPU=_jGc^W2A=1I_p z9{O%<<2pRt_THyg*8f)Fg>n1qlQ)wIgr?x457Ngla6T1mQCQsCDVdbYxML=<-+Mn)=$q-S|o^#9OL38*i)si(6v#7NM zhp0?}|MB}Lw0qd@V?QITPCDAqce2)FyZEccd{ObJ?ZXY)LX$P|d`fb@+BI$qsr=Q3 zJ5DZNK)%Fi>r`2^ku7yH@?jB^f{m^@T$TI%+147h;S@(2X~wlJJGA^TXVX2GZ72lZ z)sd)d&f{^tN+t2o0F^zlHc4cCK^PQm>Fy{+lCHBrCCn3l=7{5J^=@Ne_OICHA~lwV zMZ3AudN#n|S0)Vnk<*YQzZagv9%Wl|C(Ntbr^MS)*^Nn_!Pz_;vD#gA@YeNbF=Sa* z?Yxw;3Ibgc4BHoDii0Ju9dfq~4RVLCx@R0`S+d$oM$GoGL(??GLDsl$BbQ z=x~Df>W=Uf9Np?Ut6YbvVer9s)?5_L<5H-wO$&TqiZGt5lNfx3Ej}b8$nSt=)Fmq8 z-`3_V0~522q^L|a4Lx(bB)sJ%si-r$t`;LHvQfk7Y2s%1+h5yr`2J&4wY|p8yJDvQ ziv?^_rBk}$*gt(Ze`EUYCwY&XuY)or0xqOG3$JM!4s3ykwJLTeQo8R=H7gn{ndsZHNoc;J(-`41T<ijqb)CM%pK1L?PKn2-{EpZ*;}KCIZRjaz|Nm1)$_^z$2F8#$rPtnyMlR~ z3a@MgCb9A1FwQr{Ac_pR>9CLS%>96=S*)0NxP?PM`vaFBU%BIdV#$f`E1LcE8M{a1 zhdd`z!d%=XAnK!2>=%pZ!JBDw%VnHu;ogk^1RGA;DTyg~NqgLhS{4cl?$AWFTo0v3Ta?@B&m9e zSW1(W5kRvUs+jwxdM8(;8apQ!)Sd`@Ldzqa1Q8EYw!4#OJ!Z}3a8W*rN_`LE`YXhq zv*I>*_%oZP0P{ThQMs`T)xFNW(<6JgI)l^BJ@nmJm$$}Tk}?&N@WNpsB(DS{@Ro>k z*t)h+Gohs4;gFGTWYcf#4ThxtkhAF@8LQb`MXHH)qw+TF#krUpCDxV36OStYe))US z&%^F?LaVVvqq>yh-zgZ-qDGdGKvR3h_uGFaD5t{MMu3ReGk7W}zCr$HpHc01NGfAa zXXumoIFl%Gl-dD-7D1`S-+9u)ySq&>f_e9yJlAKdG&28iNID9q$g%x4DQLiGtrC}8 zO)WYZ_X=$z*cm0AyiH!6@vvK=t#y5J;+Bu6;OAM}#+jVRlLIpHK(T)~F?)Bsb=>va zpPD5>Uf9BmI{IOp80ToJrEy$rW%IX-LvjE`aforVQsjS@K^Hz9_#_Z z9fmCW$l+oOel)SSP9fO-<-Jb9S?(TeM%nLsrletjN z!>am~1q-Q;0H)jV!c&1n!}TZXq&E1oHTY~F&v>{uk4Y-o=0*)nu$A}ONR zu%K_VGgk3sV~%pb2Wm1WK7lYkv#2?Cv#5}iHeP=K2}Sbx7p1p0{G6`tnbGv_f<1h0 zXk&BW@JSHHbk7W_7%nEMld~C+zh{S_d93b`CTY4)C>Dcl%G5E*LvHptd!#qN9l+f# zipJpAYac%q(IDF-NN6I1nia$zZrw7E2i@wl3%kCWjx+R$s8F-`9q&3CWe6=Lir+bWq z*@rZIw{w(<9L+BV#HAC(W#;Fjg9Mz+qb?ABQp~J1Fp(JD(&Art=U49_V2G`GMc48H zl;DN^rj29%4vnBFqfnHxY0iY^vY(Q@ z!xsn7!kg1NZpU!y2Oy}OEKN^fjI)k^>Jcl$mU-1Rx(~c7kSRx<*<4|snNveOg_qE*a?jp-7kpN z&K*1tPVktO-pAm1B@IW9aD~oVrcivN25I_}FH^WezlyUVc|5M8bwIRZ-P%9{NvLZkxoP-|=~)IE;LG3daK4B11r0p>fA%|K7D2iQU1)4VOgs z&r@Qe$_paY#w6^%_Nl$Y;(h=1T=_^+VZlLXMTh>PyHl!;zww9JlG`r_uJfnIowJKC zOTB!Nn~Tpp%@0gaXm|u7O=JqbI}~zJ0e31Lp{m&>7 zc9`(#M+K$ecd#&EnA&})y?!d;ksK1R*C^&+n;g~jYlP=F7X$OYE%anTnS^?_&ZEYE ze!b(<6Lj^qSj%ay*`eGX^H6RzVK*a>ooAVyntLz}y@kiN)!8Zc_mC3*vqh*M-P+3o z4ac68PoXhV*X;1M-x3eK6)VfQh}4D{m9Q7t4B7i5M8&m49|Z~+nT;MH=SNz$*MZ$~ zYV?S)d0ym|cqXetjF{_E6&20iv{IjhkH>1-fbS~*qy_%0nvbpeo8~dghmpF%wj8y3wy@w7-9a<@>(`Q#;_onw1b)=eD;T2U>Tpx4MO(wJWBq?k;FJ4XcihTatQg&&#J83x6As6fL(; z7A2U5CzP;y;A@(Ei%4r^@?sn#p{s~|6i3>`tI=Wikb%Q`nW3v#A}I8C+R=OS_=i>Z zP%Nl6K%FVSR+)Z|Jw-QYA*-t~j0J)f>g)bLXI!F^-Np)ig2%EJl%e({Y(_fkqdgwV zmYyr=$`_)iRdo*N`W61l;(x|m?y4l4d{ZVHl0?`ZFY{=CmsL$3*sA7`B7LV~^07sw z<9*tWNxU2sRj-SE-QgK=-;2VWW}}mN9R<5a4kqVU1)&(0LpCB*S)Pt3-&E5mGpyW< zs2J0`$VY2jcRy?7t|d`rb%ALO`r*-X@A2c0xgv3pnm-a9!&g~Pw5t;VroWn?ue4c-e(h>TIiQ;+Uv z@*4f}tz*iViJFK-Q@G8_BkkN@CN0W}$>ED$$YAF#vI+G`#f8-Qc&EaQ)hXAH#Y#DE zv$4(qS_ulhk9rRf8$@Nn(?rBxnFsfI_kr5fhYsxh0so&SRr3HCRk=7c0E&R3u`Wrj zlOejnh!a{S7L{iA-Hac0^Ww9|x~+C$C9QU5`w%)ei6@;|FTTXJM#HNLJUy}2w587)GHRe8}GWKAh*FuiGf zuEG;<`g}!m(rAiEIqT4oS4#YK!`AJESg;AUsjAY#H$2`jbfcD5VTFUae`*SqjiEIA zG(Yxxj323)RF>sA8;9lj@2+Va#~s=9-}9|itvcyB@0mTvrRdJW^N6ZXO3eCE@O7Vy zf8AvIC?;&vX{B`4NeQqtZl?$DuRnxQ2RyO<9vl<%xp?gEyNbV;n!&;5#df+QzZ<-? zFaSP!SYYh!p->iEEV)av*;f`Dk@~uL%(Q~ zF0338lNK7lghi5RH23;I%(yrim=7$BNKJMK^XG~gg04W1$Wj@?Xhn|8N^;ZN@-@&H zWOJNk*)A2TvD%pMfhzrfqKg#8@-_&79L^J9ozy7gOVn42&_DywW818rv9K zsy~fUv|Nsk13mtRef#5X4JUe87bNf4ytn=a3RHdK($$R&jgl-lt{BU+WA(AjZZfAS zIrQ_VWOxA3x6;Y@*Sh%kKGc$K&v{)!nKT~^*&j-Zn7AKoE$`3_CD59>uivFn=#DV9 zF4xZU5?&%-PJgl#WLW!(H0CqPkBrfJOtK`DjZtjlAhg3Lej`>uW1MWGR0UCQ)RgSl zo=zNqw9jFYqpQ}Y$m$^VX5|sTUEF|iz{7Hxrpz3ybLMfzh7vB88%QU_F)qd3m6ijo zG3!uW(o3Qr&71$!&2-#bm+@W^0V`qrn~m$qw2KK!!=V*?#Xn)}pFR)Wu4G(WJ>gM0 z9blA5{im8!!FAng0GCpW-<+Ke*;9BtmN<898n$=)g%|LGHH!jYp5fV%{<ecZ}|S`@cGiLMR569sHW(-Sd96sPq$c8 z-EUm4Q+VLX%F4>t){t3gNl8f&cT=USWI7W){S=h6wA`c+ID~dLrUiY^rft$wpSiRl zK6mf0{Vx`P1z^zTY;(;dz{JM`04)6u>@(lxn1IuT?yrwcRho|13W0mM-gftVkuSgn z0(tcm5uBRmy_mAqcp7@I7JqQibhJe0dj|5d|Hl$wFEwjCZoW8?@`VG87u2|*CM$I- zsbl}!NrY7ggEtq2>eyI&l7U-Rr>g&B88}Y#%x0&jU0^y*&46;y*yOVC>)@ao z`T{z~b=>*3(l9E=1=6y2rvl32x1cXeHnV%wpz5Okp^p3jkJlx}^N5U?$@zmE{^ku{ z!wBU{|MSzjMqZstzFcT10L>HbYsa4i9OnhR16`IKaMU-3H7Whc654Aya|IND&43G} z2Ab1~OE>+Qi>0--yptqYj37T9H7?+AF08*_O&1BAy`wS%w~Obfb2lWEDeSd(j`yLn zw@*MkNAn40^E90j3DVTKg6ZLFJ{^(Y-@#xojJzF^+)I?4VMo)gKT1S4UVU3&3%EG#Tsw+}W%5 zeE#~=yYSQj7lbxqlk7zI(UXrO2Q=n>!??!K!E~t@bMh5VnO)r(DL@Gbu+7o-O6moB zGU0cI<3u*Im`suh4K?86)B`3bSU<0x&4LhUya4BGCm77M?p-Hi;hz$>^y!;t>Hf#7 zm%ItF*?UnABFKY=*B+5F=99$M;eozzxWuMm z%yuY~cl%+oOIm+_zs5slbk7XnFw@b|%`v_!5!x{Bv{j(?C`PyT4QLmPWbd52ou7JN zbJQK}73w8`JjlMgFaFYe(sud|A=o1a%jp4WM|sWX`=w2{zKf{dSH|v!M=|=B*sZ0u z|88w<^;d0QVg)3o6C84L1Ht>~{B&9BV)Np>)EWmm(0zR20R&d1mgkNdcxLOPY_cj0e1E*`->-m_E9D)r&OKWRu zzkVq+ev*#+0F}yK0&BeB^~o^e5uj6eYN>p4T^=}k$_SR!WM@nI`QBswL^fj+HYtXP z=H0)ogn-=e;Nzmdt+jEtuewKi9Kki5Q`1qd_K{)dLP+~55Gm6rRFB`U=qTE+htCUM zHh`(wE=M7-0Cc$6Y9~8SPma5ZK2N_)!}gBWCUYT!jt4VezVIp$|&Wj?TwOan&*0kMn6u$9*o!l z45Ni7i0`Qr{NAGm*5ubIYpGroJ}oo*eavVW5yzymxGYBzcj)?1Mf>lBTwL|;yVIlH zWnCSov->-c_tqkxCy3>+!J$;^bB~;okyTDF0+C9kELiOZP`?QQRiN7AYdUO892bN+ zI6Q+ul()T0X8Gj?c&o3fsl9DC_?RP5M>HGvqrf$DHU=b@r1jMJHF^*g-lzxjeQh(h zIK3FS|IUjNRMHu{(i~Igwo1;^NnlYGdI$b{S~t4!=Z$itn(VC^^MEt=uZqlRqVAmj zVU}$me-gm7tV;PzYCk_$_1W75b%uZ(FCoam0v|bQy%?x6gr29kK5^mX4hZD<>F1}{ z<*=a&n6XEUNQQ1?HS=}HYx8Ub<+adDKj^Wt>!~zA01Q19t4N5b#g#_ap=JVa<6mz!ceGf`^O$ROtHIH~jP7+pG5=;5VYyynV0 zU$1*7&PkpgVzDjYea>lFaCrm^}ByeTQ1OyN~PER95OZ z$;BKzg780W-*5`)veq`E6`~o8K4+hP!?P_JU+Nx@Om0~QsA9)IT6@P zvJ$_+evpI64Z9#_vBB^*&+*GIiXU8lA%v)O7-M3Ux51(nw9v9#X~IClj2hO zx}K?&Ng5YOJWYx)IQ4*SF8Y+CzcfHEZyYKO{ZZXHB-?Pi;An~TOEa{~QE`Vi2GFEl znES+_9y!pUKW3q6d6qWWF7KhaY{gKcf7U^V>p{`X$wL1uf-EMq9IbYGguQmDUAg`2 z%9rT>j^T&xQLeGFDyYk0heU4GW?LEh! zdo7fEJ6N>k*gbjQ*l9?@YwqOPGz0C;v#^fIs$T1|!kHf(jzCUY)a{c$Ly>CBI%*57 z`w}SdH0{ecmH2=4{H_f}C_ngJg0{^Zvg@D3x*x%O z5_IJOM0~T@NwY3~x!(IZO~tc31q|dp zWMAKKPvQ!t0Pl0(GPd}J(Hz{J-p`2}A8h^`fw3z&u*_-}8#0BQf2oXxmDaY7dbLx< zl-VcUGnb8hxd?wkcKXvxHoR_cT|_%x+bM&0ME3FKbY>^C3383cK&JD*=X^w|p+~!G z17+@sPVl=`?+~ig{xcnFc;rf8vTyxuQN;X4Y~AHB4cl?SG}a71ihII2Lev}Msab5B zA6iql=o*F^zW%zMP_uk^1@9**B`TV%NDnlg>kib0M_U(MCCP^SByHYwNys%fYC5&Q z)!%sli59~0T7HC#0Jr7Lnz>=>v*DA3j{nrlV2!(b73VfqeMWh~clnG?T9%FrXoUI~ zUu$b&=iro@FLlO(K$B{G2bf)@HeHu53gywFOJx!h9l5xzr?0QCEG+PoA-p%S{(}up zn#fTe#^peP00cON{)+E0m`LxQKZS+X6}Derh%?D7m7shY#fXTABw_jvIH1kFXO3JJ zjjxZ#D}P#EOGzXdCCFNOL0D7WgxD|twSU>}-Zmof#YT2l&pY8KeKWFs6~h|0nsZ?{ z(U;$KDPwqn;zJbH<-Rg+FeC2D_YqThr`*>$5bgO=1_d-S14~I)CVA5lhGtXxsFbkw z*c{wbot3gHHHZw)uKu-4RWTtk#xE>Pkx6RA`OhCg>(P3Dulceoo~OJ@M4*Azc(g=Z zmxOfJzfRm2YaGEM>S(+4##lAzVeZ0Y3xhk&w|#uy62_`$hVbUhHgC=4BXe83nzORz z?|cu(6u-goTH@~z)_~r&#L*MsvdG(i>Ad5rd*ZdksQmY!`N5q_24(J2&EpoP_>axI zoWTDehNd5`_7L>UpOUD(dCA9QEA(Nj%9zm`e){qugWliVHbBed zS4$vVr+#gGs|Rc2SdRofZyC8~xf?4i^61rn&;OZ2zmk%8E5A;F3J5g_H$}kXMNQ5+ zuyO$bR5?nc>b~3t8<0;B3tJS{6uJE0mI1;SaW0qg$5P}!2539wJV&g=e*yul6)sJY zfYe`?YZ`oDW%wkkI^j-zxx;}Ko9tb1FHONXH3AyA+}nRf~#m<8H!spl1#KCDd5TpEZFAl75> znX|}KPkqOlUv@UGZw@HJ>ZMdaK^$Y@%i@CS9<-vOV)7)gBY_evq)3{@e6bZKWqa>( z-5f6w2-J`;ARhz8EovcW9cWR&ie2se_3PKbz^8!bHyp=+_Lxu&l%XwPo)#57a*`Ss zy0lOKb$?~@KYT5jURbLR#1_PsTXV@{&JrJd1wS#75LRI{vC0JQXYC#9W*7^$^% z5=AL6lpqs&{8+&Gkqv2S0B6w2%VIl#9r^&eXZw^Gr#n!CAyphEOOB&*g!riNi)Enu zH66}JHGH}d09-Tp`O)&_B)F5X`{?Kx04`#niS!KFPk;$GcpvRpUk+eG^n?3;t+D@$ z1-NQFaV|V93Wk*e_GR(EVseD?FwjGW#efC!Gp2XeZ#UY>J2p47*7Df=;#mLUlS0*P zf(6IfrsCtvt@q;2t6CxjyA!liGoovnov85ORO(_^sz8Y=XuTQe^WYCp$XDcjf@Y;^ zqADU|@zHU|0n1<9|8z=T#99>eM|Hfa;xABC{SW7eppC^AZ~y_H>9b->o6n6pSHWWa ziMm7;1Z@UtBPshuL_`)g*Hc7dk6O@w1lbR}d3-MJ_2d#lKf zGZ4t>&iaedb&AL8`2`G{y&9~rkPR>-O0SPWtk|_qyK9bAZKIpb0T+_H@bVLmh28&n z+rdIbQxfql5-I(cC_}*6{v@!NnnA?Yv6gUwN8v!RjC-c_%eLd=dd~Thz~W+_%Na3& zU0eLoftzl==nAMOn3|pSY=`2Daw;-wg(bn7dGYLEt95@L0pY0obyaFjyuHm{X<93 zjLxl@%jK~1Pbo)>vUb$T$R-HHxm?qD?>VfN1dMA@@15++nKfiivmMpgNVEK_cfjL~ zp8xa5>{$A#!u|#@=6)UTdT8}J_*Nl%&^@!X>sWNnB`bd&Y@16P6%3SJ^q=dX@od~f zI**W_E?;WHVjcQQbAV(fhDoZrs`v^R#~ML8Z!XvckRxD43`K!OKz=DyId3LLAfqr` zw-Mq2=QC!2(9gA*&=VgY4`#H8|mXV&mA)NA-AE*clO6)ubzfmO%L`qr%%qJ{B)B9v~G!IA@ z?VW=&!h&y&_4Pi0Bngb5R0-dN<)zDCQwJh{gRWvD6upb3_4M=xhSr-*OhH_Tm*i7mfrQ@CmR8 zdw6|)eF3@mWkc!J%fR@czUa=4Bg4YZQb_k99ioj zx5Y0tn;WAyXOsiMuHVYBE#x+W8(oa2^O`l}2Y-29vKZm@Z+t9{o97CrveBOrH%dK9 z(fH3Gt~Hie=(w=$t7UyBLv*I6P+9*OfOL}XV+JJ{t%c42fXm5Yubqt4Q!Ew!mY{go zu(H;9PR8qVj@z3l{?x;pKS z5H8%m?I)o+D-8XZ64ok+n3!0EmOT@{H+Ly=g;sWS7@@blB`PC?pMO)jShE1+%$sDr zzj{GcRmJv&%Gr|Uoaz$ZJ95K17mXfRqqhw&70u$ig(KNA>F)=azkcccN^oT3)!|2t zj(737rQEozSkh8!P1@cwTniZD^qDTBobld((JvE1>h$^#9OkDA;Vu7$w~PRq;}ND?O7qEDQT>lOO|>I9z$tEmeVRZ=eq)5a z+Yq-}?)p);14;cu6>AVOXxLn$zfFqZla1TD2QB58ckOuuhev_ zJmBo znasss>aXuc>7TssHolgU!4n@{(wN{K_-5jv2ch*Jv$EeM&1=aW=0sN@?`v;db5seV zrWO=TxbQZuW7e8hQ#8Z7%&2aeDjnWuke_iW(x}9bN^KhxtMp0m*&`R4cF6@Ry6xi{ zgo*;;?B>r%Qv5CL^$4qz?C%$Ggl|$0;fCGDjm`0?Cx_i*qSq-Y&&dZGumvs0U^r-bDE0>Yg&GBpwd6dESGFc%}?!WA^E z;vCL}vlq+%)v(ppqIl3iKpu#^ocP2{?7gz{Nkqz?zx3bgbZ((e(%>3Zg`u(s_-mGw}UcN}5R83kKb6C11DYYoid*Pq?Hp$Rr zFe{LUbaP{)!={QKYiMa~z&q{(gjUCK|I0m-*Of!*MGNvs^vLlay|zmATZMm~Jip^# z$qrk;_Y7D<6Q&pY#rf`mS~J!^qD*)Hky-@oOo}7OzNzYUdoa~-R7~m}@!p%HO*Q`d z=A6`y~y&Y4Kri(2|?E(|i)qJNm`wI5$iDVjaGY-Yko_u#I8oMFk4 z#UuolcZJC`k=jUYU7P<;#>_*nZ3-^X+LTuzX!&woVSQFAU$`vS;P^75lm!PJq}n3F}m>glk?5>OsYfg5(_uz{R8=HBI4eTa{nH+cD%Va zIM(OammLFNeXLx-=@9h>E`=-~{?$yYrfJJv_r*|b;ATu&(VZL3PXFfpc@_cjB zAP+D<>7@Nixk*`^ySO12!`?KT600^x0QpwbErG%?N)&J87i42z*u{LGnV#NGbs7tA zIRE+efd0GN!dEZC_kF?tHlZJBq+!hQ06vTto*JSQGVhl#RVYqA7azJEhR zRuG}v>tJDlr$JFjfB-{=XzzgWyE*$K*T>dqOvYK?(T^Ciya2Z2oyyU5+zy>NmaVu(A|!ZGN2bR=5+%n``oWav2+G)Ed6Ze5YR-jK54* zEdX;NvThJs6uW0r`1y!l4XX9GBCR|VW*L2_$}p0t%yM*a?bML$f3bkxnI>o_ z<4MeDe7k@4$mo63SAQp8XOX1zH6MSva#k=6t3_qg4m**~Qh2}pu-cbGTgb@&|F!m= z@o;@X{~|>~L=YqdQKJ(ziL93BL?=2?qOHzqQKLjn^woQ!x5ctrBGE-JvAXD1^d6qG z{QmzJ&+F%%kGuEYbI+NXGxMGA%z-1Epu5<3r|0c~hZSe2a3Er#ChFrP*9s9Ez>R6Azx_C55v-U6A~qljFeW4wh}n`Y`J>A@`f#R-A;qT<#nMvz_0 zd+cwl@H@j?RX(#|*!2L9X>fe+OZQ5fZnHH$ww6U~OC3-k9|8o2W!l(jxC~9-Gsz`i zz!gyKE0EYfu1z$dUTW z)~#NN$%|+zyIbPY|84WRYM*I4c{9yx%Qa*f65zhw2;3Ta|Ajaq;xNU=s8wfzb^rFl zmBYIE9ht?4|CIKno^%~sRI02Cd7KQwWjbn4+IHV;gHBB+UfNphUnP)aKZ|XPVRLI~ ziJx1_aDkF9D?>_=$6@k_*OG++4m%cpm@3kzwmSS<{F{t z0Qec}WyoSF+N;21r&?%HY^m&;*X+fadfV>2I1z6Fi$uZ<8_eNNcOh7|Q&Y25X48OjJ20f$xu$5DxDIQxs;_iz zN02vfOio1p2p%%TY}AocL3HOyi&4BWyy=j+wvmS7@0Ii!S&8)de_i@*&jwFE`hVqe zLlA6JcHfTBoCQ6?_I-0&Lc&z5A_>jrw)@rAJQq62*5U?ey*>Es=oi3_u;1cOUV&U| zb~{<0V-V-7YEB*126(Yd^1lnv#bWO1YIvwahp!vu_v^ez;uMWat}VWBA_t_4m>xMZx4 z?6dK**WiF)l_7Xc0fN{69lK*wZU3iz3}T+ZCK)bpbzXCb=_Oj;nkQ?q@xqA|iy`p{ zk|$X&Eo$#hm;8saGYq}phiR-{g7GOjtm?tN*aQ>EcgFWl>^V9;hRR=z@_yy-t*}h< z%STFarPW%$S_(4Tmb|22f~g3!G+Pm$`S@zsDN>XF?8RdFVD5o@W z*i_w&LmPTJ;yXtn^}g3bI5usEQ+JoFD(X}eWTHBLQ}2uljuQhS4A(fTM>%i270h7K zm1)4K^zx_vVHDLL#~Ug^qOryxJZ}inwPI%~vfPc$4&q$-Nq`P@mP6lZF)G)Eqq%~m z)K+PX7qQFWtL$a0`{cDsvMwE7ySKgac(r`CLu?%ZZ;kG~jFa|>(+nU<{+pJ%S8Sos z2n6KKxWKr0d?l$O=A^$YyFDhXnih$YWiCQr#owVl&H0r``7MyDOnGzX`6ONsxFgW&waLF#le zgq_PJiq2^Vpouueb76!&!2?Q*W{-L;C;g85^*x9rQ4JU9z(gWOh=dy!G%jL zQngkM#?BR|FDFK4CYknAbwZF`_vFi#X#d-j+KaYC7vpUfV$N*Ba(a4{9-9QPHS#{)Y6Ah=@=q*3XEa>!Z2J5R*6`F}?gzjk^>N07 zz-kJX(u@=I$i4b=)W+&Q%d#VxU)QZrcp+_4iz+4onQ=9Sp!f;&cBraa|LO#=w}u9Y zRzH@m)oBIN635`Uz>?gXC!qfV1+pV}L@m`1zy)#~98xvWwde~*<=)X94*&R? zI981kgQsK1$H%}2(!T{dQ)tk`$a0f4>V3|=jqSB^K>bn{6(74}?+KeDYJh3Uy%3Iq zV6_Ic1?}sjTL&aFY(nMxx7g}J!2u-bf?+`Rg7dvf=FnLSktoN*a?_a+t0@$$)a|~$ z`suvrS@v3rYxy40m@YTJ$*&7tS5Ei&gj##$@U*0V3fp5jIXSt6tJv+^a)FOl-Kg?a zZkq=KT7#*EVH1-R&wuma5piG2i(2aS4WF|m9~yPhX@Krr-&;IC`+E-h#iX(;25w?7 znEEE~6HHBLy&@M;(q_$TSH^y3H1&C<=?v|gOHog%vs5C9W$RpUGF@&vwvpmJ&v{$R zxzySkv?fbb435LO$WG&Aiw!H2dERLvV?ny${8WJIY%K!Jyz$?@ZiDgz z;eT2QYWf?C@THO8)%1VieDCy1J_K^H`~l z1VG_{5Xw%GxcHWABQ-UZhL(pvgc?F?cKKmab=}6(?+^698G@{#=+U1T|0|$U9WZK6 z>YI+=t$j^71?Mi4DJ+3aH7Q}O6O^Oaa04jz&oN&tJG?gsf_Cv~W~sexknzk8 z5e#YQ6Q)$DJ$nD@{4~MmC?RmLmZIFb5b^Je=)e57FY>K>gI8h0-THr@#cH$_U$hvq zs(AMv^~s>YBe&T~=^jjFk@P%e2aI?fgQ0$PF9Y)v%r=E!Ghp4F&B&dco%{tQGD{(cc$+BSl1^C6Hu6#Br%4zzwS5T?YKE=z~!})yQrhnB6T!za)3VeG^T# zc1t1s**UPuPBB9-J)^?|L(YT?b(dV3TJhDEF1E&FbCqk!QPmo+KiTtgqe1%*@+4=g;%6&F{g%qo9jdz2xzFWv`X`0y;DqAVt$tQ?_RQ zN#B9zxl3;Wn{?IYrTTS7t^1$qdRaYG|BOPCuF0jwAT~hjo)QSi*}~|K>dwm29s}Y? zIGvNzAc)c}Ib zJQCj1dxMETy4gkI8al%DHXmFt_>Ae$(B^rYBuphny)uZD1!lsu)d^86?nVIoDtHqN? zNeNpZEz#X;BDM`)E-&6(dUD1rb-!EGI0jbI3kwVHyd<%+`dj)rsEZdCQ6eK3xxn|n zFxe05V&SU#s_4zI7A~IRX4+Z(Z}YpG!tH{Z2c4oOA#(gh zwBp9XY7we1rT^!oVK0tB12v*yLhBSkZYIZ1$f^geV(UErn-}WyLs%SYsjb(q<`0Ip za$spkGrs-BoS|22~VHUyIcU;tv?h>Q+F`4(gAcAe!|)3oBjE=+-pc_;B(`=tZ>#cxb$;n@rWG%j+EgF z^;Clkd93iOOIfrBn`6p z#v9v=Nf%xKxAQ1jy5;cA(X^u zM?zOB%mMMTzYIh%Mz~&oKs`5{bFgJXR1nGjF)k!be*@fMbaW_1$littO&GpAswin| z{q5xwC+_BS(U2s=F2 zExj7v2n46KZF3Q{1JGCnzNS-SgMj;SM^8?cR=1#@YCOvT81rO_E5pF>nqoMd+Rh2E zb5}k_eqMTHANFUJ_dqsUaJLx~nLNPmezGXC0>QEg{B+CZR(A_>8E#IrzO6aT6UDBF zuV3YU^I-RHZ2v7G(BQ_Gc;LGI5ufF;Rc$vCK01bpe0tR7)^x=@>_$j3C*>m%#@y%% z8+n0SELEbsKh?ydl4yzee_+}UafN(m^LL9UwzS;BEIoNG%LjxUkNjlOWZfUf+Xoo= zdnuK!>;at%muSFI5#hhfEoT!D*rZTKrYmMlMIca1lPr*iy9z{SdEjniyER2Hi=9w1 z2dk~0m%b?5NNJrYuRC79UMIv{^<6g#|Yg z8qEO0A7aW@Hp6vlaM*5qag&C7+%&31oo4f@5zg}yRoZRElmPYYdVO!--&t4s+FvY< z2LBomR4FB+D?#!+0@I@SL8Obj+krY!DlOwJM6QPbttj$cPrmAF9Qo;b*ld>UEng-z z*6f5+Z=KcB@`B+tIo;1Po5tP%kli{l2+xwf$!Y;2c z3*_7`LbU;bQPX98IoHIX5bu@hZG8~u$<~}MV8CeRtWIUb1g+JgEIp;hH$D;dRQ0;7 z=NV^yCp1db;kHxzYZ>l31<@T7Fd6QbPXbeBC1biV{^gZOXn+`apWmG<`(ZnVPV{gW zdI9fIW>t~#kgLnVkD{%6eV@)_1wT%jZk&Nt7$V(8C*+N#-qbH=&aCqN8sU~%XRw|( z1nOXge3``DQFU?)7`a}8IqL=i0^L5XREY;K#GMm$K2CZ)^#s2AU7ZYmJ@3PU!StX$ zNK6@=iq48b?FIj6$Rsc@;JR`Pvhib~H>!{9Wx%$ePMQ6hR+7YnD%4l$1Cq>IgLP&n zSOi!pWr>8skHlpCe6pjbbmQ7S_V=pWScsDfTW#eg^+6DS(@NQJN~0+vufSl5al&j= z{jUnTd`XH)|7!^`s$+s0#6(}&CbS$w99H?`sgu{;A6e>JR=3QG^Gs%9SUp z!lc~>7=0a9G7hEPg?V-Po4>P~(nB8$D7}aiTnj4S2~-vr(`?)$wUYb6QI zo7tc&{CVt}_)+l-2B?z8H!d!1%;F=<2jD3S5nJ~Z+)?zM=oSrDE1?wJ))J($eja!P zO7WVl(Ol5xbv;(8Ym{!==`pqn2HLL1-cBW93n~8?V_eVp`RrgRwJfqSx zH}b;m-aed9b`GI*t!T%4c#GhrlLL?wecFat9D8VrnDEo`TdGC!h z8B3GqKusyV333-+ID=rA2Rhq0DdqZ+|0`ktCb{~6ApUN2ZSp}mpDoZdNPNvz2x*Fr zo1{1`mq^mOmN)x{M%n~KMBieB9nnpX#K5zVJupm#5t6k2NaCmCYA3E8W{s=)_j(F# zLzpc+e|?K$>onbvdml)y#HL47#sJiS*_LAg8agu1A9*PBDXiBYsgMo5Hc;j+JDhD> zC#nvpL>v#Y+{t##CD+_n=t;0j_NCI{4jp=$#vyyJpwFvofDdj3Y zSS~%Rqs2|O(HekJb<&>E#ug0_*^VZz9a5HLY2yLGphp&qCC0nK5I?HKB!{?~09OV9 zXmQPBR?)G;ebwPs#;PuK4)nG(vYKfxbYfoQ5G-8i)^$dV-OP%VAXh(6N!YZrJ|sQ$AtE*;d}rm)E&(LHDMiYpNI>c z=$bAA=vjumpSM&Fxq(WDuh1lByfemHjvi`qPr`J=L+U6KyoBY`(^7#I9V8p?t_%ls zi7{1x+0w!7(bo}l{1BI8)Zc7zfHs-ttCZ_RdyScCm&^uK_(fiCu+Uq?jsk~?u=?Kt z@^8+Al)F@p3e!WI&1{lQHT{fFe|=w@jKcZbV;_O zNG+24MfT}S;_0lKnw_nSyPv@0+{cTjGzz@#zB(Rx>lytyuEu&49r{?;<%zGEYJR(Z zqp>VrdTf+==6(IV_F`jIKTjY5eSY@vFpH^lGj_XR3!7CL^cz);(z3SSWsCwxpa3wC z!R$8Q7qA1Ad%xs7%6?fTv>$z{sZ#nxHcZkX(lxwYj56N&_>-1KDIn)=uTDJk`NtCo z03c(H2!`2>V#c0WzBT*A%w^=0Tb5K^bUOhtunNwzSfSo=kKzlW=y#4L znrcZp(s2E##3EH*oc!R{g_ClDT85FZ>8rd%gCge28qXhnDxgi@hNE({0|*wQdGpe# zO8HtNf?zl}$c4zEpH^R>wsbhWRone6KIXUdmeNplgXt$*Kq&E@rw?3_`;07KCifZV zS?osDQ17C(2GTt~uO8FR4`oyHqwGnr1iy^yL^nHH6n@jd(ATWZsh2+U zLaI2Xoh%)_*ogwP?C{C&d>sE`VwG1uF2?26ez5w22?B?rB(UiBhWcBcfI)0c?f_G+=rp4C#DtL)5nzvb^5vrD>A+c`(xf zvE6d-0RG7*!IW*+ofr;`temykmpFKP2uvoXl~GR>_ZI1~BnY^ToNsbLRyaNr-Gs#8 zXjHibm+R(L0>u=YsQ#P^j9+zaFp9er9Wf>o_neBy|0rGnU*_Zy#~c{ zSlaVkSu5YLkT0*FiWaLWc6_w%;W+BXOIZG zV=~f#qZXbAQjMiY3u_@wxY)5sP^N`5t$bi4U4UljW2Wwumtn@SHPO32Unf*bUgb!U zh`I8~Zk4KZ(&}L_y%F=c$t@5OG8e^h7cHz1g0>=JH!-ct9*<+wXx~Z#6BrwhcrPF3 z*SE&Z)vJ4-zAwBoD8(ZRUkp7CeG~oc_uDx0@iTDV9FB+j%552{tvfa1L`t7Inr!2E zokNz=wiBr`GJ^=^SM>*P$Svgpv%LFO#P>>T-d@VH5zc$`{ndM^kV0M_9@dXhFT)~g zt+`*qUSbKQN6(j^lqK~|Cp4Un5h}b2qYb5$+z@LLiA&-D%VBu908y9^i5}!wX3X2$ zXKY~V9f^8E8G}O@*VITjWFjlNk^;h#e{`7|gU4pU)}{4|CL|d_%y8k|TZo>!Nv}b1M;C4+{;g)_ zIg8y0bYrQ&y=JvOSkLlmyuwj8^>P6+Tsw>u7+x_Y9lM7r1NC#b2mus10)2oF#3=jj zoMX+JKeiGnp5W(*s?Mnj%BTWodw1_a(erFq+X`^wvOx>!nyP7%9DDy;W0=7~Da3BC zpz?1KOti$#_fB|LyFS+3n)Lil)Wi21kBOaD=X5Qbl)P$7v0ah9?>}OzAfbS#S0+7+ zm_ow{_HF|S3pZTecJ1}htMJzrl0_q4d~;;?k^L>-5*;|~?-5F#hJD`9J{#rt8-@Rh zhb+rD+=VPMHi)qn9DmXHm)-)mFCNxq*UP)7Suj$Zd`cs{D+56!Q?9_Tv1pz=(V!OM zV0Di%8|-}w79_!ZElr|o$*IXA>EVq1_C#1K|#D&f=q8N;S&7w zyoJ)7%co51FINTxnVI^oOly5c5rYwP1TsH!T7FhG-xYZ`s&-bDba2R_B|3u^A+_`X z8^hdx&$F)ccL6g)&^LG6!=`xXHI=dvV%2OzGq%2$_pmJntayuB1w{5p_Gb^SC(P~UznZ2B z)b)mSw0myrt)_ifHd~x${`-t(h^bCslEff!8=cGR%yE&87H6U$$UHx1Bi<_kf84-E c`d4ujZ#%eZzlu}`|G|-!eEq6K!pQ%B0MVtkLjV8( literal 0 HcmV?d00001 diff --git a/.github/pr-assets/5197-ko-stale-reconfirm-390.png b/.github/pr-assets/5197-ko-stale-reconfirm-390.png new file mode 100644 index 0000000000000000000000000000000000000000..4960694a7aceb079cdc3c39a4da7fe8295c83aa0 GIT binary patch literal 192015 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 z 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

    gCB9+`Y4A~QE*2eKT($c{z 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ï{t-oKim+WcG#a+xgEij`>RLFD|O#XPS?ySr`5LMmOV##hOr}7 zwvmC@RGcqL@~}{bVvOj6!ACB}H%Lc4PCp(Zbd!_@tBasszh96}`@?!<_Jj-#x6oL^ z^|wuQQ($kf#~LeNopL1-(c(s^A0hJv8YWAVW?^Wczx-l*b3K39LK`6psWF%PgQp+J zNaE&>`Ncofj5Bl|odtodEA|eL0A<-7MLaH|N_*h~kUPLO6i+N`reYsvCW_J~8Y$ep z?zqSOpGl90%hvd~ZjnGI9h_{a5&_f9a3He*R_Q1kBuG1U7Aehyj*o9Dn)$4IkO1BF z)_R7#$Uz^6(LOBoqz!xfoMS0-2&a2BibSW3_n0T z?pfDl6Idjx9joal|IhlXOtx$|la;jPFUPd4(5aSN7_7Z_Dk-cJ;t~`TbXOv%PjoQ& ztEnL3+pEJIn#Al*u{x{iUp-8>#yQ$bPC-R6Bm2f=$C+6qx-fI>;KVv=9v-!% z1?GR|ues&-9xfI)g?07;N_Z&9wGY)KuV`OIk*9Y#&p6=GIGWc`*Yy>$mtAo5cqE)2 zkpKUuCm7d7xuNUYBEhYJ-kw!VQy2K6qI6Bh^1E&S7Zq7Ty#H*%Zh_5@`Et`OHtE4R zDIwF;-uc~)!aa715prbMMI%{qN)nKB{BpzJ6=VG86iZH-nb{Fnj(nX-kNz86vANX$ zT@7nVysic}CnS!V9^8b=*#C`NREqPmq&H%hKx!ZanIFI4e{YBgzIA^=ouoPznMNWY zJxu7oi=p2^P#qrgA>cwKn1LVkzBR4|nQi26AFll^Rg~BB0?(r`eciiaKmGBVcenp{ zH0{m=b(6@QfUq4HMgXPnM;q7w%y4qu+?Xihoz^gpw*OfLZx$1N$%&PAuD$?UEO-i$ zx&9k7EoLTBN}70pJs7v8Dwf2mZD?<&kYP+YqL@gEkTf0_I9#Qamei}a5pF*a_W6_^ zr!y?SkTEf=?e?0uVkI_&|2-AO{l}$2ku(3hPZO|UdWI|nt1yAFk6>g>I$)0*hHlVa zUPb@p>4zPE>M)W()ATE-N#Pxe)|Cfln;_XML2SCrBwt z82d`VbsvUuAKZ7#(C$lBViC1+-977#VS1wTr4#uGPT(IKoU%=aGO#rZSNC; zz$t0pS*r}T+{4?yQU2fGYS|f((BPdT^Dk0}V#MRb*WJ1*+ZnoTCdSCX>IgrvLYyK} z&6;pK70@LRe+H?1CZJst4-kI7RR|MKj)oEor?*!R-}|BOgh8=-dZlYW5lN2GX;5m`~i!E+rN4d}*{{|PU7m7kYp38LF<=gySEL>d&AxuNgkM!0<5|7p^2evCIcvGA zNm{$Mz&E?@OtL1OrDD60T9;-mSx*m-jREaE{}Q?7`DL$JkZ=%JJ8z}+o9kAshK0jv z^@^GUTb}*q@QIq^9$SNxyyIEQ5}S6ru&bPhH5xC&*veO5h}xHovc<6cv^1abpyX|4 zwBFgGv#6E~!Se zq6MM>)8T0n^y&@IeYNd4Ma7@$D%0T$&y-!tV2HGqG#L2*@;1lit-eY-eKcmAk;KEQ zv50RyoP4zq-%n1@6co7l+WE0Zk*P|{VJ}JR4LYh0Z+8S&7{VZ#2ztPkF1yB!+kAX+ z#IHGNTQ-#KMjj9Rw`?;c2c$b+n%uPN@&=Dp8FwU(j`s;4;OJLq5jU~Tr2m>Z{;L&= zw-jggnw_mleOhA7;wo1_rOJYr86|Lw5IH!Z$Fb$HFI{mLm#>-wVaTc2Q-+DonuXv$ zLG>SXP)ybEr~6#~~!Uu_Eq`~Sz*Sw&UZeqG<7yIVjI1nF)NQIwLB?gphnq*Fjz z>24IHyBnlSgojePyBprc_{RV2JMussZrOX^*R|H1^EYV-n5%65y_Al1iSXi(#z|g8 zRsQm{=7f~=dX+H}ek%%bJgZ9$Qa#P~%V>un24W8*^ zgI@X0)_j>Buklm5elXiu9+qyO#+&a2|{9K__-HrOY#|76Q5C!F!SXBrw_6p;-EaI5Pm5J z(F>v?T4yOe?c%jn9_C#qk6^d10~-XOPi|)3YfXvR^4bK81H@#0s+Zz9=(a&*ko}Lv zc!5jNOl^XYYzpr-Kz5q}?^?AzHNOon>8?)ZV3}#<1FKHm=Sch~Z(2~OXi$8&TXAo@ zB?-PetGnMM*_#=Zj;gm;81I|&Zc5F83<0GQnnuV`qk0uhCDt6);SQXAFK#%c7b4_A z>xBe{g-|TckIJX~{UqO}UdX#Ds8qXcO>hX)r@0>l-Bed(%_45g!}xv(*;DxW{*uSJ z1rolwET?hzochX)fCKPw1~49#pUFV7Ln&85JSBu3Hvh0@9f}v=GWsqXo(6y7p&40b zfpMpSn9Ef*?3tZQT?Z0}hZU9y363x~eU-^$G3!|iI7`%+^}^A7K7V8;7+6__s-h~( zS_s8vJwJ{^>_nIM$Ew=}RTn-jPdjd^s+|Mqs_)!6YQ?(#Z@r)* z=PA*FO2O)dMRpB?EbJr{tX9Jh!I@|?Rl(tLail949?$T(XfEJ2Vt_eMzzlJBWuVg2 z+_{+1d^MY}tjcJkikuiv=;JD8Ro%nKl#ou=VfGwN7l1_?9v23sQOumE*UgL|vP8&C zf?p;Ll~#C%>ks=+K`Ym%@RDPgZvT~=?E>ukF1u;i8KPFGL>R_sR7I)SH$;Q=261N> zZ{izmAVA*ztWhJF2Dw3x8_WN1?RO4W2cJWL)bX#+c2~gFiWdqc6A@(YzhT9jSbQ1* zdq`4X5SRbA?fdtB-790U>i>W0I5h?LzR#?4AQqLN^W1ajJ=x^TwZW5}=?e<%WIJ3S zuwZzXK?`}eB#56vTm<%GQ2=xWoJ=%)BBi3fUy+^$_&h{n2Bf&S9}?~Bx|7D^wy&E1 z+XcWUXm#4Ad1NvJ47K1*C~d6PgdaA#8PBKNe~l1TTj&JB-e``z&E#aQ-x)kC1YZ#O z(wp=~!#2t2*GTaFn8Y`m6SV!>&tzizsoeK` z?7yx*xb)R8oG$yAf2CUTIcbU#{;7p`g-ZUU?H=f<6kiFfUVQ?VMB%EoLi0fd57WEc z;f=8m6{4lWpY62|!pQ%FhZ*^T{-A)%#vh1UE?p5%sOfohBJy=*56^^GQwuBD;~ z+4A-JRXez9p8w@+2kq#cgBut=;4zv%#en%@W)8fBI)a}hO$_giR#^#|WhpzRLm>x` ztUgO3-)xyl{sC>PxBul-Wj?qI{IHyqZMA}L0Q8)3tcWd!MWvf#PdMP`esI)NQ@RMN zO-L<|-d^vrISwDZmT0KxtH zjNBm&2w{%9<8o%m75V`P)jgcrpO}_I(vvTU|Vrgjgf2bH#0sA$w4(I?Lu0+@d>wx4!Y!zq#M z(gpEuBrFQ=Um&tK+0sKD2if<;_0jLJUwaR^Z9*m$!_Q)hD9o4GPZ(*=`ns(+Y?wm+ zLe>l%PaHH5>SB5+0iJ06?2g%at%ez;hYWF?}#8|+Uy z8cS6H&JnhSFdm3x~ia1=*^WGl%nV`n=dpF0;X(Tt!{b5|Tacu9tZT7@7 z)y$VcP=m9v6-)D~cYpCIX#e*N_pkg9f$%>!tr9%y8EO?0TxJ=4;l4|Momw1@bbHh}dp7CA5^)<$D|;Zn;se7t!}g#FH+^vn6fLWcmeJV+49GUXX2 z*Vx71-y;<89TfEXm;DLH*YzER4yt5pAOXE;uq|p zRks!+HUSfPa|Q;7BHhM-8&ZR>>~MRg*G%;KsZmZ;jztb#dO~0yf&9(g13yCS#(cKP z?^r!0=1IMM#|qTw_4o5s;izOe|Ey|N6LFoRatNaM^WIcCF4J-e0_KR2X8kWu=dP4# z^n2^1S}(mu!COahG(_I12XAJ9k-8kuk+uK6ts@BXxpNjc|8D25x$~4I+~zrBiWPi5 z>HE^X7(Dq%*=8!DWOQ!N9M}_Yh4p~z?3F+iYxxz0QGb*kH^Xrsw6?=VZ-#RJd zDQanLWPB8Dq}ziuHODHGQ&P+%aPV$(L0gaMSmJ6NB#cQn^7tItC$kef}lb4GmRJ;XDRpR zFAC&>6P{`~{PwP?+qdGHu)L3f^{8}Zbh&}nds@}=dL!mBt>CWl?d7gmoZCMyTdHdw zETLBiOI1eS9Pp(M`6vns>6g605x2Hg+`TavCkd-8bUwPtwf=#KM5_i5eK`4%`K5tx#tM^7-tg~et#RJwK7E15x zX5^>6I0RQ6iQwT?n7q4<6p$JVg39jHF&kItw@J(KjD#EAjffFR;KoD+ad`PbhZ=(o z)Jduo|7#Tbv;oWUY{)Ecidm41wY!5sN42ObrllXqmBi{0|JP-iBxhc3aLwU3jKJnt zhC1QW|6aT?|I(+q`cP+++>|2a)y>Y|#(MX2`*?2srWdzpaj#;YMGDEgmi$+!#deG5 zjv~9^Gi+&b@_gK<=8plVs9k#jhUW6N|0WtPvz~T?Gj8|>5Igd83k9hV4rZ-Jt5^b5 z{$C6qvxBJoV~c&t^nlkw^H#-w6_m;CJ{nW}jcjPWBaG$ws8Kj=FOI@+!<)N>xFp2M z5|Np&hm6zg#oMxz@lAgx;yjHrl~FQwka?dPkW+YCI-^P%RXGPv5J+`wimH(XQAW z;4>W>vW5e#Cl7`IqP8fen{90 zm(gr$SgADMOAJtcy%@C&?5=;9^Z2EKjnjXRvab*;dVDJ#`>=b&@}|a&houRYgG2!h zP(=a>X$UX7U7evq@gwo<1Kq9&GdhD8=359bx6GE9V`80> zf28HUN&)xj{`HEb>FV1g5jP?($-daaclT`v+nOOt5rh=pMYa&_qLl#H1F&-hAHG7! zkV_g*6lA5lCtAKhD0P6;a z)@@tM!ElX29yYzY3XjWh7?;{mqW}$be(0s}U6ypF^d}qKY42*L;QSBpxP~Afl&9WF zE(IUfo=C^ArbuzIcyqUJd3Sp{J}GIrgL+imMuY@8;32$fB{?|y}_4TQ|b+Rc4M%=x;=zIB~F&*#C(~>Z>c}59+VvSdV0i{=rkXTD)rv38O z$vnHQ#0rReMH6^*GJ>k%@5Hts*nbOQ0eDZTL|vmrv`#KCH=5&~Vml1hSMLt1v=iM; zx+KaDOZ^&+t{;Uz^m_aXeRK%24q!$0WO<}Lb*?sHR2=qw&UYw)5vxzw$r2K||DV*o zq#!u^?KFeyKbEWEPl#|hRTt&U~NwYPdqI-l!|oXUy9L0ej1d$ZCPLA;Wq9AO|~89TpAb zVxGbQ!-neq3zI;zqPST&8NC&p!Ih^JlZq8i@JTZylQ2T%E)#2k?9Pa3VhH$nppW^y3(rt6%AatYU*L$Nd&0B-S4Hv zF7UcY^tCr4fEepf734Ky*(YUIIwO9bP*~+$!lO(I|)ra{uf6}PGMTUrjX?zi0eDI~BlkqfVlCj(=VK`vS{_<%<_nHS{UrFUCFM)FheZ9a`1oJ<5Q;hukOCl zb>i;kNHHXQ-8Q@5Z8U(x>NpQK2T{$0e6^xr-)R@!)ab}hcybXdtEbty(!xD}M1Og6 z1r7uV-70%HyVC?1XTKyKE7H+2^#*{*b6ft)ql@DY=C9*9h7p8}mHy+;0pqpD>EBQ0 z4$x!t{r%W8sYrVN3z*(E;3QFKOXSHPkCIkyMEr4`km3G!4VDsnSHArXCM0bL zt=`qo7@Kih<6R9TaIL~r(fKD3ZIfpMfmU#0%C0ts*btCiBnDvB%7kU4?0(3-xSJ%K zCdHF*^CN?X)>MfAEIHGd5&mJZ*eko$L9aCTi*?AIMvo*jseXy-hh|U3Bcn@$Z0aqj zj?tc8r((L>|14D@H#7 z_f$!;{(Ra%5?IE#2G=L9|F;VO8}oO?zJ)XpK*5hh`ato#Cp!p#9(QA^FsZGyb>5zSg zUq57|PZ=c99|<|uxE#_WY4XcmArx7_%zJybh~0(5|7+{2YOU~&AXtN)HkTx*@>4k2 z2W{!W4)=P%?je?`k<6s6uD<{bbq7!!CQjN<|qO3K@|!zr46kLN)cj|{nGpf z3F)b(RcmaU!)nh%4iWpMH(yM<62dvzJt3!@59asqYko@_=g;#8039dYL3VM2`YF%z zXr^GY+~r~XV+q#}pDUJ$N^epBBi1=5{D+w2oEsTYNSB4n=2s;rG&CrjlD^S zrIyK7f@;G~G=^89_cg1nX^}s)5p^O~4|G3%^XTWhgc8BMb6Gx{;QfmRI>KF2nM1mw zsyz_=Z+wZrxN&#fykPhn$FSEtU9I>6Zimk3wAZXdp{>8a6B-?GBUbB3^fY(N9;7fw z)F5GzKyAc>2JcWwvxiL7mUX~I1ShpN7&Bs7F7Z>Ujmt{H?x)A!okwtWmuP(+mnQ09 zx}8|b&JL#XV?fn~HCr;@W(u@v|9Ja|By2cs%x3tWDPeMVQ={8sv)hYJwj&30B4*>* z)P5!8eAS{3927Ck-KW|Apxz|?AgAC^gzxq+g5{^WH_mOnOxz$puDTLL$by8x%en(G zaug95e>^yBe=-aRz97dj2+vi?r>CU55i2i~;WU6%Y3vk5L!ceugs=o!OtNF{_RX+u&QNhPpf^}po$ETg& z{<}fn1eQj?6`Fnno)s27Y7BN;u@=X|3U{VeRH+0S<|-@gbYd{KgnX}1S!fo@-a?pp z+OBOFgEm1dnsApDxRB@%+gpq{GYC}&N1M;S1hoF`GxI0Djp@7Ae^Q*t&6qEloW|cQ zZs5TT{4V!SRu|?aXLB40J&$8T={tf$^3#bQV3i!6h5H26QxuitC2kz%^X{=xjtB}- zUk9JOCRhk4RdTY;_kG?+6*y~+5WN_F)r%|McqI8Ix2GrEx9!ln?PIHQ(1_*?zuhCY zb+D9?@me|q@<5orM$sU?<3nid{N6fvaZihz35F@6`MVQMY=BwEKnu<0=KVyvYI!C6zGu z3j3V?b^8?dbpPvJr^*#smXo8~%+FvmB?qrmwIx__6167?mzh>E{=QfB4-9_u&eV3` zuFBEgMY?g0_uS94{_EQRXxR6Q#UBa|ZVEhXn7fQ$g~@HJc`0uO8vjS++6zjdR+XQBpzVr}BPC#~BzmR}R1g`WRh$JY32C-hM1xqBGT57R>f`&^BSduc_zW`bpyS z@b4!HMK19BrhoyCVri;EWAs@JlY|xoq&|URYJu+_#?plETN7CFoAkvP{SNbqeC(xF z`QByw;#ex`>G9>o2ik2);DS#?q{~S+jk4~ zzykTS;R*|`v$c6-5WyOyq%?sd6*6vufxRSN>zAc9?j@DeIxnM? z9Fpv|VZ+}qA#9NKLY|pVNaYS=^8llR$`?QoLfd)%1A%CpPX!BqP@+o5iHr zH6g}5QMUj|^GgNis01uK=js{sG9GY+(r|W3oi+8?ll}KNnGhv+^pX8L24PCSrcUjWr zNd_onFj?^qiKa871yJ_ne}C4y!%{RDOxVZc`Sz3;vC~!Qj=rmynLVyc^eN}~ANu)j z^Ynr2EMZ?9ca0Y%(4t{sNz;7T%HucX^7cj7w#Vg^X$EA=ru^Qe4(_+_JyyCqa+3zG zUfOpOn9@FxF*Rdo!-=XEx?(WMfs0N^j(D9AqA6yNx2i33q2}>MPtF57QKOlE zs6pS)H{IPpfl&C~xngL=t%6B&@gIyWEut`tPQtzf3Q2cIvI5uQ=fAdD>i}f=Y%wAs zj^qRc{ONfQ)^CBeB@Koz?;D*=^VzVR2Nf8e_TbxnPGL}_dAED7~@{AHj0$vPzH;9-EcD!PM7@+0GotrCL{8Dv=;=S%hY09Zet|agJ&RpE z6jM^K`^IxZh;L8-(`#nc#kk~PHH3|Jz2o}Nnfvt9pr9E=Bg(;t`;GE%M1_ z>1sIeT1vh)|8gE1(C~Q6v2Y;rY3B;Y&*SEg(^3aG{HDM*Xg^Gz6MVtAkoTG`_A$k6 zUpm+P>y^Lt)q3j_mzdr^{sqkum0sX=qNCb8-XM*5tZjC8y*xp8 z)q??=kuOr^uRDr!@Z6rSaAn3#nR0Zsg_+4p>&}xbEs+hV6IU>@8~=0~wipCddNiA! z=(4CghnCqWkMmavNQlOF9%OTz$CInEzr4BJZAQi<12y88O;c&%lRzxgM(X~w{t1n# z<337@6?Ec3c*=UYoSC3Hk5{zaGagMx6>4eX2jz_8Rl15*v-^Hz@i84Hi|p4&Q#o3r z>@r_g>tPmU0I?M5xqhqUM7(HKZGx(p(dkn z&x(x+{g-EsCy>j(gsAQLFF2f@N2mK;Erd+<&vSzo$u5=nlI_<4r`DzoajsS2ztewx z525h;z~mf1esizd(+?@!u;_W~19D#LrD6jMA?TNKL`ucIv``6U+e4sbHRe7-#)5e5 zvl^;1gnHNG&3q*ZZ=ey+>nf4fX4J(;|KSBuu>XECJ;Ld^!)i1+ut5;UP&$PT7CswG zMYTCYN#RLx)9*orJoRf8_ar)*@mViDPW|UzYjf7YgmlAxRWK~d+en;C!F3AZQY0?G zIrlDy{PW|7E>V)jqGd3t>Q;~#`N`qcB+A5IDV8XRNBy~V!1ew%w5FIvJx9}TIzg@1 z7AHiCAYfU?9{$6ppW+LW9Iv*y80y#*qoEG?1zT=ZKPr0u}FL zXV~B5(st1~I_0WXlGz}fS%X^sZPdKG#qJ?8ingGFXD^*w1{pk>XhR;8ggli??QfvA zO5}zJ>dRVxc}}~Ta;YdbAOY0kP+?x;rV59AJN2mfXqRM>m=jN+^+l^QM@lR3Po8#h zdUz6CPx}A(NyY@ZVk^uCTnj+-JI{S885UiNpts^n}0@yP7lvL?R~BQmdX* zk~DSS*eI_jHt<|!twzY=C1TcA|KVii_&ziy`Qm@O0ATr(r1G7SaD>0Y5A5QCemuCh zKEbYL?y>H4sSA!)70!?S_&isHx16$8B4>)irdMEX{Jvj?%rF20(=;oyxHw+fUXn)L zk6~1Is%Xn&AsL*mw7`KVcM>qP+=B zX0>G|kj*w7{>Lm*W=eVPUDPNUw$V@GhwMfB`m9aqJJi#IC)}#vv%KFD zbpLTkSBdF>rt_NP(Fcf8++kI2o36cXYBBt@%mhZ_m#%zLwm?C}NrXi?QS^@`Mv#`L z;8F?QwG$=c?aN-*l@OG8n6Z^l38u|ePlb!Y$4pxzfmxfp@hBb~Mx^=ltwy@AtqoSE*4MSccO(v!T zzvU{!Uz2SRCkhB=Bw;+QwQ@mGJ6(j0${t_i_~NfLPT?SJ+pJ5s{VT)>4_TY$qKuxp zWMjb(I*h%<^2*ZuHM5f(`VFwnB{vDwgfzXj90PVYZtg#tSH~+9TG+ll^6weYfrl8$ z#}s-~wnltjMesv1veG&v+TF2HDVZs7l>rSYMJQRYk3d0eaz!tb+A z93Kw-N5x#X)Xm@I0_6S=<&B4!WqkS5&3V7TJso}K&ly0x9<`!#8(DAP;)7xf41t$k zaZ;fQzDbCz1z~2oa0xaakX2t=DZ6 zA=8a%KWqR`LqxJD(Ihz0E@^B2ch0XIs z+;HDf_w1@`Q`L<&7g>DCb^gL?rl2-Bx_)x!i7@XP5_B4KT27qal~Uqu_O`=>M8*=7 zYW=sK>o$u!mY6|d4m_p(It8oI{8ENz#Vj@mD;hJ8(^_d?D+xYO#&q|B2}TmztI$2Ev^LWrMJdSL8%#;`<5W zWtapG@*Mpj;o@n^R?}DX?BOpZT`xoC5n>aDIFY9S>tAJ%bA&}08L2G(8tSLggV0178XoIC>02refRBhbcQiS_^7P&_C>C7?0RRjX0CDkbdx>ggu-vbV z04j%Ci!P)G$x^qM4wZ8ByM-OshQHv_g1u^2YR4guGMrM>6?|yOr=2-A5OMu>=jWrz z3npe;Az`ICgzoPJP0N`YT%%VioM@s=cg-$GUSySKA2bP(v(F+btKJ3NGu4X-PtAs_r4zALL7{p7|No0Z`%?w#p03GRO9o(Cu)2zFOPQPEyhBt0gKa z2UL@BEor=2*j>2LBWYJU{~9U0+X(gk$s=tKL%z|_{_YH~F*;I0)cK3)GmWxrl9C+R zZ%T>R%L}@qpKi2auHQrHPwr7G8op@@OXAZfQQ9(XH+D0)eC8fmqcSqu`qfT+NthW6 z=J4@awXs$D35#3s8UUN>c(VLQB5G&M?7;&cgip`+CsK@G&bMNsMZ`p57dkkS-bSEG zzZKYg+XHO|x0*L`Bxt0#`%ughzn?1V=5#q;_yNycoO*O9MJU3cI?Mf=#mreBq;G-p zfQLlsTse0uVmn9ee!-9dz|p%T=@kRd*=pLrn#|nUB``w!QRoX5jH_+!V_1{LK>9?@ z6B*9cMsdIAc;vPJa&*7_hDh8gW>MeQ$FrGJ8DmRN7D|n}G^#8~Lw#+T z+lYd~^@>pnv1AAL0DaX^+`NN)=mNW5ecmF4rZyM|hp%tp`myFXLg(ycV>Vh?sBPSo!nCg@4s{>Zp!th%YhHko}e^8C~KZxzq*7X@{rmQ^8bj^V$o z5DLEvIK;x(1pdvjWimJ6dy;njRlc=4#6Q?lOr3;P+5HV`{O#ggy*9HMJi~+W`e6?w zQH>V#Cnw)3GL3=G{;#f!7LE_UiOARcH^r(TAparlwP`j2y0 z_%__heroh7XmUTID9mQX9eQhLk}B#V2qcS!xtMg@;RLzF&CmlO;g0Ruu~jGlgjpjQ z61S96XAIzoqm_62I-YxY^dEu&+%ZJlf=QnO*an}B9?c_p5e%|m9m0(J5A2X&?cKI? zO{UK+1+rS9W^JU|u@l0lw=m#hQPu?ihJ)mng+bv2$*C3dJwS%J>hth<^ zK5j&V?am8|e-^mx!uCKohJ5U=5UOVFN&AyDhBn(Rd=rvR^AZC`Fbd zM(yP(74_3(;Eqpbc7|+@6^1Bk_#Z3>-X2BeV+2&yP1Suww-&(2y{kE@(Szm+(BjnV z-=;7pl=Cxfo|mug)#eF*9CRApuP%lKK0s223i+SWphN=tWewdrlmzUY$igvaf|4=p zUhoJw8ZS&*Gdz=4&&_WSj980q!7r*0nM-*af!D#0UR^e6>mz0J0|MZmwtv4mq;*^^ zX>0R=_9F+EM`#0zch#}6Y85db(!du&Pq1`4Re{e_kVY?IF79Hn}3&IHSdo z|G7`_p*li7hc~dRy;bUT}t!0 zuGxJ>gXwulg;MUAP6%87t0~%jXlKY?c5MqNgoR%r)8(%tEI=}g;^g9F^y>v^G>=@U zT5!O@1Y z-$md%t20k-AzFe^5d z=;x^IwGmp_=U}^Ell0AFb+P{|Eh@R5Z-32S1*+k(8nZ(xhmmCN?NQz1kZ}k6Vl3Gh zTa@Ps0w~s<;p5siu_Z=vM#L7#CMQy+#JBokD(ndaQp*S*Sh1p_j6ODv6p2?g-I$I%M*w4k{r6R~pbRvvrO;?yxVJ7PhO$U*bkp$hkAcY)kCS z)ZQsw=x72VZj0-qPisVmjptRV_^fAO+sOW}h`Nw>4g=%iyL>y;{=v5XIL?@je_OV1 z7OX)C_7x>k8zPEo&;Et}#i$~7^3|}qsRZAT1_3%{KYyAx5jgYqLt^$hT_k_+qMaqJdB-!+LsSPZ5t3~Yz+)bJ7TaFI{jaZf)@$E zbghr_EQIXFby{&x`q)CiDpCPM1yBf=2a=#wCPF6W*>?HPKt?>b#VDmH4W>L|bFS64 zNJ=e#n9(l3%5AvRTjuwxU+;!UaIz3kruxKrdz2uCkqOrJV#(M8XxMpV;Z?QuKSx6L z^vAV`mxv4_2cCO3mumrb8V1sV&6$>yoB?$zt1X@Z0dDYc0C$Ik(NAFw66TDUk$rCS z;g+&$m461tHAfLSBo8MdG0-xnR+Jx-^OQX~c4OOhgEMWi*=v?>76az4rVVbGN*qqM zNRv_e-##9k(rC4CU}Skvw*tV3y@R-7{Wu}g6P6vqkUW`@C5Uzi0^tj@sK*i)WvYIpn)jM~UEvv=FQdE$@TY5tfEa?doaFplgzCYi zIViAl7XqEaB@frVB(^9d;#o#~wgn+EL}UXqg3ZBkuLB6|{!;-C6g%l)5V}mS#b@SZ z__QNz9%X0bzFYE#0fUsZovTQ|g6_1n1Yavp|{^CmbfaDVpsMV`=|AHa_%O@gvCISU;3GLte6-FFK$}bc{*Y56FjSnQkR3Pd6rIl-X8#6VR<_nb|N2C3pyfa~4UrmKCNIGR-@NyYo+$ zs-OHifhNQ&=(GYY9GGyFxvFM#i$(15MJ=V6Enh&dJ*gRpUNvD*_govN z6pL5-nsocqYP9s9cI)_0M`Hh!8g>4zU_(1;UOxDgK#=X@RXANy`pb?# z*Pd^EqIC4G=m~0}H1+-@3Yxt4d9V;X%$C*+?LMM1Au#1X?$zqXxPS*R=$D{ZW zcpjQIwHc$&DVBN7-rRq9!NryfzN^(io%npcIE?r!Q=+A8G%=m@@b+24fjM` zp;Qr|(E<6&&EgMd()ypOYw-&Itr=yvADvU&JiOJJvcB6CqYQ)_>^J^kO3^;r$g>w1<>1TUmQQ6>S=;WD&L{Sp5M zdPKUz<@`65SH&O4wZDd6z|V+7Z~V&TkXK{$lO|U0K|{!_`E*qZkLz%eUn?E!2dXWD zzkzv{=>Y$KUODO)hz%!EGBAKMxP?{bvf9>6F1@`_z%}OU#{We%d>N`~U<_12^Glo$SfD zt2_b$76EpakBX2iy;jIiOl>%^KX!P68vRVIiGu5mBcDw##xYxzeSR2~4R>E; z{f9xVL}9m0i6tYY#ENaoHz?NsY@I_V=mq&%5nG29CU}beR2}6pdvvDKza$KP#%_XM zz}2oa(`BhTeTbli=Xi|s%hN-=NiggB(>62BKlOv*Stx}nH0r|QE7B|0C`S_Hs!^W1 zUSe8p<$gb+a>8{4@74wA1nu82M?XTM0dAyMD`7S2BCMoO^2)BDLgL;pVM}e=`^c_s zFM||BcN2y)>=UecK1`-$g_w01Uw~*twaPy+MQTyMqn0|q*N?^e6eE5c8m-EyELr`OsJ`Qw zH6|am5_^-zux*pTlr~h-mfGip5HJKjN%qhzbUl92nQEq<;i912pSvF^QHpN5uX zd3FV#fGe2>ilPHZA$2%<;j)Zny z`Va^s(M)FQwq5spHEo5kacPquMD=e^v%0>NLPiI12O>eCNuSe4^jcf#5+Mw`I+P-2 zRua*jED*wpnYc`K zw5oQ;42tRj9Ww;M5^%m~jKDq*f&s&|y7itZarg3V;kcL^YsGA@j<;%V zi>VseSS-j0e6LZq6an)Ri&otcBzJ_<5idw|&j2&KKwbFp$qn|ZQjP6AY*he1iz4}m ze$r-chl0~MH#t)NhJ|4T?%(Z55#qF=<5v{EcfDFc6O8tsnH@4CK3Ldr=)f8kyW#y+m#}=OO6XaLAXy9e_6y(orFYj zrhheqO%|j6JvVqJFjg;4srEXF^`1x<7(|MFJovLWFSavT{uD(17$&#WTScnc*pcr1 zSTp;VB^NiN-=!e`sPx+J3&yV{Kp>eR(c%=u7v|?lXps-O8nhBnJA7}ZLqJ-!^==Ue z5Cu(-Z6s50$KiUa@~%Dyt~$e`%Y89s9NwU0iN9a`<*jvmyOn~hKPpMwH6%st7Wh0K ztQ2m$I;t7ZGqxJF7zlb<$)&}5Q%xi+&{-5t{<-av@}i8tomN7_KI}9bRA_6|^W6_LDH^8>)KhHhFu8CGozJ zgy9f(X>oDDgdSITj59~Zj}s~XDj%3TZK8zC>eOC74|=f(hcvx_<1{ADDIqr5iHP2! ze;x82MS1vi#94pl?8}#-p;VEfBsR8*2cTtgjAn3L#xQD`o{H6vDk-N4yPzFpZV{UZ z)TU`nylt&h&|dG^h-YjU6U@r|B7r32tpK{xDhk4}g3 zzxgdgxDT&@om%>YLz$%4M9?of5>5aLc3Wx=E<775FR$CA7l#f(`k_y|IFX;o4k-tB zP(bx(NC;Dnb_>@-4;^#amU4u)sgWK=dOhG5{HzB&nksBaH;b||$Y)Xd0ee$F2U@{q;6NAC)!pDfPLvmVIBe7B&~f2jI4 zFnczo+uS-h@mGshA%$SJ5gWa_yvg>MVD@w7#(e@*gg`6YR`XXUeeboMZK%@7cvJ!y zTB&jTpRIjO9r#n^9E8`&W1q@UPo$al2Hj+=V}~Z!>2&|NP)Ca^E}S#VSCbmY#O(FZ z13AaPehvIIXMzfnO3e4MUq9^%j(Mik@b&R%J4JlY=oX#F)2c8|{9&A7r z!_jQ)i*%Yv8n971IGGuL3og5w8))1@+2DHdHcOOxGzZuaz-qsq&bw%)F;=tm;G#Iw|P9$N) zoy^T4>r(!SdJRe33xA%BY`o#AJ=y0vmqmJlB3PX0B$?1$F6HQnJ<{~Q)I}0=BXp9y z`jTKrjpm`~BHfs?LZLP*BFcKx9(cNkz7e*#l(`ghi6^3lH*>K&>*c-5Kul+ea#gO< zs8XzoDN7Fr{pM(OME0ZQlVXf%MTbuk5&D8PXz3||T4^#bpKe)l20SLoZf*6CCK+#I zlr<5>!DQqRc--1rT3YIIaAszT&CNLX>i+4MMn8!lsEyUmteL3k=s;NOkj7-_ZP0f0 z^v&(gEh$kLey^=+@ARoEBDq#F<8O_50$D{GBU(}VII7Z=#eJTL;*kthB+D-yfnO}~ zBqQgwZxutMaIUyr*nD-pQLvcty5&W4NBFvBGrHYp&(3OU&Yaog*>sik%MpauC2vg- zhA`f7@$vEfd)HCsvNtE1Wz}n8PQG(NazUP`)J!Vz;(^G}RJ8|kY30mWd6_FZAV8kd zewSkxAX5$@_50Poz0zi$S2#XMmaH?1k~6sTR<^o6Kj{Obhu^Y`5Z*df3LEuveO0qs zk}DII<}4{EKE_y2vP6{LmilK}cwfbuHSj|L*Ovc|(SncPFR7kfgz-BmJTMP_I|U3& ziL7f%o4mcwm43+ZuN<(y^Z$6q$kXnlZ_s4*0@?JCyr;$6VNQqF$@c+f zy4m1=M+tuJ@q8r$_NK3$aLNel+!|UJSGG;E%_2s47Y1<*QP7@|^LJykNt-2dAG}Yx zs8))vUe?Dd7Mt)r9 zMMm-YEk6*UN;PDezA?&p;P@^n*hdFF;J|4l!bKb7^`-ujfJ^0VK84MxAH|A+F~(!a z)EbBtdHuZAYMSAwmN=&(dtwj3OzKG6yc!wB-v4Od%=~0ur}vYWFuadY%E_MH5imm4 zW7dINhV3X@AmT&@|JVar>mFW>K~b(JPZUXr^9JCO#|p?@?i*1 zEq%2yd5P4nY7in$$9wn}-AHUE=yR)Z5ybob?DDcqEXxr06#dmP8EULhqe!Yyc@5xi zno8I_lu5|-wqTiDnfNSe{p7NJOo3pg$_F)v_oo$t_*dpu&REM{L0&tO^Rc}Ie`7}N zN3UD09-{E_Ma$;Nl}rM+q9;JTnQl7%`D<=_+DQb0838hJKW>u^5^=yib#NMw+FE_1 zCTiSgdD*7MW&a6*LyV!uft5abYC`kwM}ckMUPE|+hC-u8CG&02UhHkJL0Gjf?U!@$ z))ah26ghwW@SYYRM}4&n`{Gzt6(PaJ8<_&Xx5(Zf`Pi94xl)hhMIbeb;j@A#KVR-x zkZ_6qeiEdi@Qqdj4Q(gczml|y(Q*a;e!urj)!(IdQpAjYTiNx?g>s})Lj~Jaf-@wG zUj96*NZydBsfh=`Mu{h4-2S<*YS1W@s1Uv>LQhuv%@PZ3hr%b|5AO~Cujiy9j!5D- z2pky739*=}V*wt?M~_Cj!;Iw>Y|R|_@yqs=rq7)IkF&Gzsw&#rKHc5j-QC?G5~84V z3DVu&At;S>gM@(6-61XA2kGvvZ+Y*1|AB7|#&F0v?0wGOYp*reoX_){(LC~`u>iHT z+gEE>f!tTqMN7pzSt<7ue>v?tD|WAKE@Z4;_t$hk0Xn!w%e&ThYO63A%5P~S*@J>b zeN3~oGIFOCz|AMArNly6foG$H4py-5O_A!#LSLV*KSSh3Q0ZPq0XH!68<$5St3h1M zt|yJ9BHU0DIP$w{fju@sTT~T0TS0L9E8xPu3w|=IE-R*^ob^?(hpS=Jpd?p%9h9HM zqmjp@${C!`gXH2G7Ag>B8VD~cD#{#D^o7M=H^fyy{$-$rfuY9Q($E^-Ws#}w-_h`K z6*QRSa->Q0iUNLA^!#45K8>J>jDifjY}26%R>Cs>T9Nr3l5u}~XmXWPZ<3>W_9JSq zVzF!$E-W03C@fZa(+%5igHmCcnEcAW?SkW%m1cWVW8Yb=r_i&X#c@koApn}$kg`(4 zi8az2-i3@l$vIQXXsYereK-$=@XvY!W3R&@#Z2EL>ZeE{dG5Mh1zP!fQ9MMlf6gpI ze-27n6sH8r+%JGzNwq+_2a}p$CQtB1IKI5>D!r6>wUp5SJRrfFnMC$&8oiOzdCgx~ zIP}y&?b?z~=Q6t9=ueLW9*SX4csHpu7F|m&*655KM&GwKn4gm(ak^OLxXa#(#5k*8 z<=!hzG=`JU+#l-*|J0>67%o@@H*CmVi4WldThL5Tp=6&ws34wn=$-i+)COvgsNh}X z-^Q;X2u$`iB%UlrxV$wiBlds85y2&)TQaeCvi+H{SH1!cBNBIm)s$}&cKOK3Co{4*P%V`)|XjS|vc2*D~{{sI&~r$oKh@!6Ha zfBrl!SkG->x3TN?cQU8xC)!_L_5#PH`LnK5D+jYC^TnLS-XqQ3W7WK};EDf<6!nFn z=M|)X*R6+bp|lL!hF%oKK8(d$wxlvmm%y+T zT36-+MpEk3?0 zGfpe!51@|*uo0xw4+L^=oSP)n%tvLxvN(eIjx10auc=8Ij0ZIbB!!AfOERko6( zIh4_@3PqC=jgPb@YNyLh?`bN?iolA6WQx|WWF5xrF6f-t<+P7v>R+Mc81kXW(&b`{XC|OKRXp+N0J_L>;6`#qa+{*T!UdT5QrZ3NkHc9cnIkKp4yq zq8vt`Nik&_^S<%CNoU$n-bAwB3UHuZO@~p`t2Ax;Z&hFe zdJPJm}ZZ;jxMgFpZ!`h`Qtk5 z!_J1{m-XhSdQWa{cuHBBTf~3aN&O&8^&A}9`Fb}}GV>~FH&}^#pdR}E{d+YTF*fo5 zF~2h%ckq0gt`Jh|h?9|in=`(D%*zu?i{>9=VB>epe0q5*X)xEfC0j=jOv+G3n*3vCz)1i3E6W=q8;nUVf=BV} zwJbz~3RvnFikOr@7Ll)i=S*@?7Zv>(1r_z``g&~RWIP*taJP0Epu9tXW`~?e7jKqa z%+nau>wziZ{%$8{U0q0AXlQV-v_=Ne_Y?xnbPj+rEsc$E00>fLFV5+}+1-r6)A56b zp8pCY8V|iK@M7=#0vV5iT@WA*ybfm7?1%qC z14sveCOex5+IMtwbF;Ts?#vV@MVg#8?m?FW6nu_~wyUQHOh*QWZ_>#A_CngPURCs- z|Ff6^Jzo3>sB9^g4l9m|^g}(Brb@peXH}W20r;~iH(M;7fo}QzG!CZZL>03qAQ=SY zZ86vRYT(zxDIRvZ*p4;nDHNA*JKY>I3pr2#ISonwM^CUlfPqJ4U}Wra5)%`P#4ao@ z&NRM6(T8rEv^aGsEGhBw^xpoR9MeH@9eevoOyK+UczX~MBFRKbZ;A(U4IvvzEN@jD zZ4?yxCxKZEBrSnq?e?k;6|^cSet)rjv{=t-)K&VR3Aa1nV*$k5`PaqO6BD46i*!`@ zEiU7?UAP)dU{GAP?J>=rkd^I(9FwiWlG&-4WmTCea2)zPq ze_U=Z6(*)fqa8U}XwEi3Yll&O@LoFsBHNDVdmCV3U%#RM2n8pu-@iSox676{KA812 z4N1|_#RYdh1~zs%@+!W^wDC%)929rS2^ouR!EHL)-7I~SRfN3)Z6vC>Odgn0RmdoQ z0lk^5F-Qx zKLmCvz5{^y3mMP_rgUbGL%j%y=YztI#pau8;~-yXXc~BcqCtU4kNmr_;d1=wW$G_g zpKW^2-t6dcQ~IU>gFAREtK)}(;vZ~aZFmO0&&x~K*sFB6&(I?&zeU_N707X+@$|5Z zt8nlxc^b^@-#-NV0lv2#4ZKuF9Eo_k5-l_LUU%4q26Sdt7U^`!3vIvCX(x2)5ztBQ zpV?uW@)p5F=!3jsbHXJ`rm7=?7q)XdE{fyY_Sof(kW!XX04;PyjDRm}A; zU@T8V{=BcVwop<+YC)KG2Za})pT+n{Zc1jH6?6lP`pRqpSHF|1)pN>p$_c(oN^&PL ze#sH@epD(1`UH6E*)n9V_^k1PU?BpVG(G-(@YupAToNix4gSPgn$OEIIZ=k0nOPSW$libX+ZQv? z+YjKJ0CU2wn!*5CFH&v&3?w>bSuojc9@XJLfJnpe#q12YGJ)CHmt`V$=5z+;FFa-_zvO~} zIBeS8rK+ml1dtG+YE%}0^Y7`)UuTVri^GBUknxoPgYAb=NB=W24EEu|zozf~qE0Ve zAwWDM+b0kO5x}QvB6C4?we9r6Cm})6d6mD201QD;)-5t&C{)U-No?QC=YyUe)>D9B zo%(WW(PLMN4hqrtd^5`PTXOlkJ^W?1Q{2``?8_p;+ek3Eq1Xqv6oZ+)S1b_1;JjHO z5QQ8yq5O|*#n%TCjJZqKX=wnO2#_>2fEn`3ay))j&I(o>x;g`^Ifu;k_;4XSmSk@Q z-hT?@g}SO{r9Y5kZ31>Vke1>wLw(^bf++mrOR%fyW1|OvOP24?c+erzv_C8+OI!g8 z5vHHwczkzvmtC*Ev)g0MZver9H^o*SXwrJ)^5>R{2*c*372?QVi4{WqUoHUI`T=kY zzDWi^*ACaVYE0O@%UNyfl6#sn3gEY!Jsjrjpu-XJO|uUGt2@^#zKNnxk zPJ_%)5|d$YB#kriUEig?0+%4q7sNOt&YLRaelb8ITES6qBsTlys6XEZi}EF7~JVE*GFbK3*KJV`r583un2pVdSOS)f40tn z`a#;R=LtiE)ZdgV^JKmT_TCJLZ0Hu?&~t`B@e)3!@TwVG>x0z(wyE(%H#KEkG`<|0Heu6FQw>LZx7(RZkLSj%|$ z_-Z3PVHZ0K;alLW#>-AF9=s4L-jA;k>kI&G1myFbB(a2&I=97vMlB~G8#*o?FnqA@ z0vDgJmmF|$a6mUCf57GdXcUK~`ZnvjvR>C<3Umb-BF{S4|+p_B%xd1uS7- zG~_0?gOr?{H8Aacn}~k}6GM;%jCO^}lAw6$5EU${P9gF~kngf!H31ttCowT`z2)Kl z_NR>;+32WVZ6M*z&XQo+u#gE1cQEFNMl0r@)>ATOv`7B-_V#6lXK&AHY-Av0)ufI4 z+kZvMfW2(22mA$mL~JfQvy>(4$Hy4-@Pgt#_lH%I=v8Lk>&M?~Yx$a}>DeaC;{P;Y zL(?(nT6ZD-1U+R1aQ?9?jmZJIbp!YX#KmG!rt66yJTwYWuNh@9@sVuS+Ov|*<6g&2 z;35=w>gtxRc31drVj_I~=eo6-Ng<{%w$Al8>~L3eoI03G5UF)Wem*q;Ae&I+07TxG zNbDX#+vQU1#;R1X%mM&pw^|#JOS?D1qt-SX&-*_dA2rw6=m7Dd`-%unB8c=bNcfOm zos6dQhv4cpnf_}A`lszda3arorkTG6$++^RSXA9n75SGy)V2avjPX%$Mm`g)!hQLk z0kcQNKJFjlMs}Q;WC4;OnnS@{EAi|+;c8hcVr`h#NG6Yy;(B1$+3R)@uD= z$0klXQOk31{)J+{8pfGTw>psA1-5=%Is}oFc$+#4NS9OJQ5G|l{~7=|0I@p8MBmR9 zX5L=qJUtx&FF&;R{%~eXf+kD!EeIp|y)=(!0~nr^+@^4X$5u1uNkeC?M0CXL0hBDHPJbTc~JWwfwSEncSYFjudP!<^F;@ZPrI{?>* z)W;x^&ykV9k5JGO(c)g?;jq??iLxU3^>bGHzT8iwy&(<&0xTjMAH~8YH%l;y!GQ+m zZ3QkwAfbl0U*+tug*TiczICIMO>Zo*mcg`1@9g<}NIVa7 zeX@r6wi$@2fO8T7b3(H~G33e|C`WR;%imSrZ+wxQb(jd$r6603+{D8ZUg&1u;+XL^ zO<}!(k4F|Y#Y``op4LW0^dVQ=R;Mq>0RUi`gOMj<5H$alOJ32rYO@aFgX0nN3R4u7A}Ro$Se)xKON5+9BozI2tfN?s(B4afl8Ko~7bqVpCI7`2__%Jw23S zo}C|pfzDanWtQ#POC>abc$N}) zl6%tmJb2%ocl=>!)p`7ivG*ncb;G-`r2s1D+2nbw*VOYV6JPRsSKb(_))3F9_ z=Yy~T2Nf)H(p-FGulj-$=7xs8rNLM!KQG_y{Ox;zWrRht&{*R5!Eu@gmd^2< zz_Br`YM%~jrKYYe(ey!MQhk2Bymh{%+Qr>RZxQj{9NYrD4*m9#bVdka4v^LevO(V) zY)G5WRbgt8J{AFdAQBo{1&DS*t08%YUf1?R!EN zkoiG|I2gIw_JFmx?c@Ps&BqnixB1DJM@tR)`T2E!J;=}lw3~&O>R_?Dls*Kb}(2(9~P=Gm{WC(Yj&!r!(@t51x)-aX*=(XKaSH}3$ zx3sTP=06?RIZ58D)M@l*-t{6n3E>ye0CCupIxI|=BoolmIQ99$zI zUm|sJ5{a57wc?1PgXfGABY*6F%&z})o1P_q(+`B^cPNKz;xGPHBt0eN$Y!K(AbY-z;<4jFBn=VtkAE6d3|q= z$uId-l9+zf42`a25k)JJm1sOcX#U{?&bL$vIrS@aIw%-@#S61=(mskJi7x^a zkKMzy8mS<#nS9gx&Mw^E-z&+d6z0juFEbbVe=i!3296-|E9`VZRTwo&d^Xd`9c(<>NQ=9k;cSzqoBH7CQ7( zPP-r9yI^@JxQ3XRm}`b6I!5}4V8dr3l5_4t-zMii)ugX=qSG%x8S`^hpj+-H799A~ zuaA#BUKd+S0Ms0JBq|l3V;Y!J1~!zU&$qI@eTc!N`;uv}oz|;uiXP7lr|2BI)ldX< z{r;c>9s90@MrAsGpX}*6p~DKo=S91}rW>7W@L9Ma;$Ms5y{DJe5G~(kIdI|Bn!jP$ z1I3x%kzH@Y^w*B8wFI_6twT|b3i01*exB&Qf3Wm^>LeYb)YUm-uR!z!MPxJZMbLbosBzTHEV=0sX!$PP zK%ctZ^<;W>Nq;G_G}!oyo1wBj4?oV+nblTB`DNeCfK_ zQP_%y!^{)BIEZvPpH_}<^#t+m7TAX3Yl?Cutu;oW7rRw)j8@Fcx&vzx81;JgmoT8PmF$(!;%(u7q-BIlN zjgG*)dDtkJ0_?SM#Jul*d$xc~+Q|&>XTu2NGfV__9A0@85U|xCF>3{#|@qu%AX{{PE$q zWzw+>%z~ztWu!t@6N~&dfQ3_IHA&O9A|`Qse2nQ9V8OKvu3yXp5R<=u?3D;4d=rL) z^OxT})ChfAfK}nW&k+a~OifKA`2=ipOBfG9>tc`r0Oplp6#G~R1c{vZ22GY$Ras+V z7?m*8(kVJF8X)B7qVZYhwJ(iNYzuzN0m;+mw02#N=gadGNzmcT(F-P9Z!gmI(Sv$4 zgy045R@fE!csfbDO?rtcRsOeB0o*Zmw~$?C)*cedZd1@F;%B&ylwV+f@{2c(5hn2Q z?qcc%j_7MK7KSJIHY38*a?lG;_^{%^^z?5X?zY)K0G!qV071`I8lZCC5>SaRP`3iu zJ;GGrD%3%Sp#8r->qOE(hQcnqnWUiVB0C;RaWf*eKwfu2l^0K1BVmqmY&#c%*Id;f z`w&C~dqVTrZUW1MhK1{Nb_Ur1@Wq~aO8>9U7|l=t(A3p`4$5+wONH6i?(dfc4_7K^ptsc59j&w9ky*V{}s z6lfyA7JjA0{cKK&tj*(eq6m6Y@nw0OrZ5>4+GR zTko$2?Xj(@wTqLE#bDCI zf8i*sEVJlsBM5*2-}dT!toGPOQ~|)!iZyRUYEPgP)J@^!V-TVVf$0M0MJuEpLGK*w z0AakuQ_i>C#_%y?aRR)xVVMf|UAp_cic!oGBTGscwQUIrb(q8G%j_g-cT-cOe))Vk z2ExgOrVGr*xlU9#gQtn>B86V$kx;ru8IQ()srG8%Q!dTjb zjY_TCVUA+Y{E4lykpgskAhL@gq|9oH4YS`kRnGyqu5;ExaH_I&a5KQj=05^?(}SI_yBswsGQIzhs3Ez=<* zYRM~hp%6>)G%C0j`0jd+`$rC~knT4(X&+qO&z2Z&4C}Ym&5Hvh0B!9s=S))E7cTe}q!wzZRW{OcJ=nhg6Cd88;2bM(xnmIX@NsZpkhO#MesrG?9&fG=*2iC- zmoV$GOu6nQ+MF%CkzRvuKQDQ)eT4|Gp(5VGi#}BWGGri+uLh_a*bQvKOeVMym3ke9 zW}#$6YwP#$yA*&)0viORNY87+!^O%2;O+ndK{4C;YDxEJ zYSs*%oRya}Dm|LCdoWOdMi|jR2HoCqzE^SxOrL%I{V31HG5&Y-0vvHl#Yd@j>|*hw zE2192GDXuS<|?mnfb=z_rN#O!aU$~=ph~_3f^2xb-I~3xc^vYN$Kgy1VJn=VxcBYu z-menK-Sm>I&w1K&m1AD_OqmXCN<`uq!}M=Z?PH5$ALC;VeDoo*B?o04z&2ScR90~k zULQbaOvC#CJQ$0OP6aK{3)F>K3dv<}Z;6XllQ}AhAG$JJw?UaD7bm~q%5wzF&$&b< zhvFo`4?r)Tu?hD&kPGZNuZ$Eh#Zxu)>>}V00droMjg9T`VrRFMiPOPB(#Yr(9)P(C z50^;=?Qp~ZRICdL?*0($s6dZ^O$U(az%~h&$0-PknUWX3j{nxF-vQY!)oOAsBnvnO zD=7LPN=Zi?GIY3Mynj~MjKC=%0DwdTMj~j~QxmTZs&~&%JCxOTSNjWZX7gU>i16nS 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�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%0A>p)EDbpz3-vnFzeyOjo?_8<6)%_*@ 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

    ! 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

    hV!Vcgf&xP|?Bg2jNg1+?-!z(p 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%0A79$2X=I-a35FGg0R;Shiefo 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%0Ao=s7F0~Ue7kn-qM`B#@o)4edt2Fwds1d~0W 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%0A}sS!ie`zNJs-) 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

    *g$Tk_3Vl{tV&*yJ-0A~PjWNs3*zLCjE~IHa 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 bB*eRa>@CbSU3?CHgQu>nqg10{^Wy&jOu0_p literal 0 HcmV?d00001 diff --git a/.github/pr-assets/5197-stale-reconfirm-desktop.png b/.github/pr-assets/5197-stale-reconfirm-desktop.png new file mode 100644 index 0000000000000000000000000000000000000000..7f830bda54e8269138a8be3e26ff841e5a8992dc GIT binary patch literal 305752 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 z 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

    $}>sqejXK%#h!*OA+kS}Ws# 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 = { "integrations.dialog.overwrite.undo": "Vorher wird ein Snapshot gespeichert, deshalb steht dieser Schritt unten in der Rollback-Liste und kann zurückgenommen werden.", "integrations.dialog.overwrite.confirm": "Ersetzen", "integrations.action.overwrite": "Ersetzen", + "integrations.preview.loading": "Der genaue Änderungsplan wird geladen…", + "integrations.preview.failed": "Der Änderungsplan konnte nicht geladen werden. Es wurde nichts geändert.", + "integrations.preview.stale": "Die Integration wurde während der Bestätigung geändert. Prüfe den aktualisierten Plan und bestätige erneut.", + "integrations.dialog.apply.title": "Diese Integration anwenden?", + "integrations.dialog.apply.changes": "opencodex fügt der Client-Konfiguration seine verwalteten Anbieter-Einstellungen hinzu.", + "integrations.dialog.apply.breakage": "Der Client verwendet die Modelle, die diese opencodex-Instanz derzeit bereitstellt.", + "integrations.dialog.apply.undo": "Zuerst wird eine Sicherung gespeichert; die Änderung kann im Rollback-Center rückgängig gemacht werden.", + "integrations.dialog.apply.confirm": "Anwenden", + "integrations.dialog.disable.title": "Diese Integration deaktivieren?", + "integrations.dialog.disable.changes": "Nur Einstellungen im Besitz von opencodex werden entfernt.", + "integrations.dialog.disable.breakage": "Der Client verwendet keine über diese opencodex-Instanz gerouteten Modelle mehr.", + "integrations.dialog.disable.undo": "Zuerst wird eine Sicherung gespeichert; die Änderung kann im Rollback-Center rückgängig gemacht werden.", + "integrations.dialog.disable.confirm": "Deaktivieren", + "integrations.plan.heading": "Server-Änderungsplan", + "integrations.plan.operation": "Vorgang: {operation}", + "integrations.plan.operation.apply": "Anwenden", + "integrations.plan.operation.overwrite": "Ersetzen", + "integrations.plan.operation.disable": "Deaktivieren", + "integrations.plan.operation.restore": "Wiederherstellen", + "integrations.plan.change.add": "Hinzufügen", + "integrations.plan.change.replace": "Ersetzen", + "integrations.plan.change.remove": "Entfernen", + "integrations.plan.change.snapshot": "Sicherung speichern", + "integrations.plan.change.ownership": "Besitznachweis aktualisieren", + "integrations.plan.change.journal": "Rollback-Eintrag aufzeichnen", + "integrations.plan.foreign.none": "Keine externen Änderungen erkannt.", + "integrations.plan.foreign.unowned": "Ein nicht von opencodex verwalteter Einstellungsblock wird ersetzt.", + "integrations.plan.foreign.foreignEdit": "Änderungen im von opencodex verwalteten Block werden ersetzt.", + "integrations.plan.foreign.drift": "Die Datei wurde seit diesem Rollback-Punkt geändert.", + "integrations.plan.noop.applied": "Am verwalteten Client-Dokument sind keine Änderungen nötig; die Integrationseinstellungen sind bereits vorhanden.", + "integrations.plan.noop.disabled": "Am verwalteten Client-Dokument sind keine Änderungen nötig; die Integrationseinstellungen sind bereits entfernt.", + "integrations.plan.noop.profilePreference": "Die Synchronisierungseinstellung des Profils wird beim Bestätigen trotzdem gespeichert.", + "integrations.plan.refused": "Der Server kann diesen Plan nicht sicher anwenden.", + "integrations.plan.refusal.notInstalled": "Der Client ist nicht installiert. Installiere ihn, aktualisiere diese Seite und zeige die Änderung erneut an.", + "integrations.plan.refusal.conflict": "Die verwalteten Einstellungen stehen im Konflikt mit der aktuellen Datei. Prüfe die Datei oder verwende Ersetzen, wenn diese Aktion verfügbar ist.", + "integrations.plan.refusal.unsafe": "Die Client-Konfiguration kann nicht sicher geändert werden. Repariere oder ersetze die Datei und versuche es erneut.", + "integrations.plan.refusal.nonLoopback": "Dieser Client benötigt eine Loopback-Proxyadresse. Verwende localhost, einen Tunnel oder eine lokale Weiterleitung.", + "integrations.plan.refusal.driftRequiresConfirm": "Die Datei wurde nach diesem Rollback-Punkt geändert. Prüfe vor der Wiederherstellung den Drift-Plan.", + "integrations.plan.refusal.snapshotExpired": "Die Sicherung für diesen Rollback-Punkt ist abgelaufen und kann nicht mehr wiederhergestellt werden.", + "integrations.plan.refusal.writeFailed": "Der Server konnte keinen sicheren Schreibvorgang vorbereiten. Aktualisiere den Integrationsstatus und versuche es erneut.", + "integrations.mutation.pending": "Die bestätigte Änderung wird angewendet…", + "integrations.bulk.breakage": "Jeder Client verwendet keine über diese opencodex-Instanz gerouteten Modelle mehr.", + "integrations.bulk.undo": "Jeder Client behält seine eigene Sicherung und seinen Rollback-Eintrag.", + "integrations.bulk.confirm": "Alle deaktivieren", "integrations.semantics.opencode": "Gilt nur für direkte Starts von der Festplatte; die Umgebungsinjektion von ocx opencode hat Vorrang.", "integrations.semantics.pi": "Gilt für neue Sitzungen.", "integrations.semantics.omp": "Starten Sie OMP neu, um den Katalog zu laden.", diff --git a/gui/src/i18n/en.ts b/gui/src/i18n/en.ts index e2ec5ba7032..4146debb96d 100644 --- a/gui/src/i18n/en.ts +++ b/gui/src/i18n/en.ts @@ -1920,6 +1920,50 @@ export const en = { "integrations.dialog.overwrite.undo": "A snapshot is saved first, so this appears in the rollback list below and can be undone.", "integrations.dialog.overwrite.confirm": "Replace", "integrations.action.overwrite": "Replace", + "integrations.preview.loading": "Loading the exact change plan…", + "integrations.preview.failed": "The change plan could not be loaded. Nothing was changed.", + "integrations.preview.stale": "The integration changed while you were confirming. Review the updated plan and confirm again.", + "integrations.dialog.apply.title": "Apply this integration?", + "integrations.dialog.apply.changes": "opencodex will add its managed provider settings to the client configuration.", + "integrations.dialog.apply.breakage": "The client will use the models currently exposed by this opencodex instance.", + "integrations.dialog.apply.undo": "A backup is saved first, and the change can be undone from the rollback center.", + "integrations.dialog.apply.confirm": "Apply", + "integrations.dialog.disable.title": "Disable this integration?", + "integrations.dialog.disable.changes": "Only settings owned by opencodex will be removed.", + "integrations.dialog.disable.breakage": "The client will stop using models routed through this opencodex instance.", + "integrations.dialog.disable.undo": "A backup is saved first, and the change can be undone from the rollback center.", + "integrations.dialog.disable.confirm": "Disable", + "integrations.plan.heading": "Server change plan", + "integrations.plan.operation": "Operation: {operation}", + "integrations.plan.operation.apply": "Apply", + "integrations.plan.operation.overwrite": "Replace", + "integrations.plan.operation.disable": "Disable", + "integrations.plan.operation.restore": "Restore", + "integrations.plan.change.add": "Add", + "integrations.plan.change.replace": "Replace", + "integrations.plan.change.remove": "Remove", + "integrations.plan.change.snapshot": "Save backup", + "integrations.plan.change.ownership": "Update ownership record", + "integrations.plan.change.journal": "Record rollback entry", + "integrations.plan.foreign.none": "No outside edits were detected.", + "integrations.plan.foreign.unowned": "A settings block not owned by opencodex will be replaced.", + "integrations.plan.foreign.foreignEdit": "Edits inside the opencodex-managed block will be replaced.", + "integrations.plan.foreign.drift": "The file has changed since this rollback point.", + "integrations.plan.noop.applied": "No changes to the managed client document are needed; its integration settings are already present.", + "integrations.plan.noop.disabled": "No changes to the managed client document are needed; its integration settings are already absent.", + "integrations.plan.noop.profilePreference": "The profile sync preference will still be saved when you confirm.", + "integrations.plan.refused": "The server cannot safely apply this plan.", + "integrations.plan.refusal.notInstalled": "The client is not installed. Install it, refresh this page, and preview the change again.", + "integrations.plan.refusal.conflict": "The managed settings conflict with the current file. Review the file or use Replace when that action is available.", + "integrations.plan.refusal.unsafe": "The client configuration cannot be changed safely. Repair or replace the file before trying again.", + "integrations.plan.refusal.nonLoopback": "This client requires a loopback proxy address. Use localhost access, a tunnel, or a local forwarder before trying again.", + "integrations.plan.refusal.driftRequiresConfirm": "The file changed after this rollback point. Review the drift-aware plan before restoring.", + "integrations.plan.refusal.snapshotExpired": "The backup for this rollback point has expired, so it can no longer be restored.", + "integrations.plan.refusal.writeFailed": "The server could not prepare a safe write. Refresh the integration state before trying again.", + "integrations.mutation.pending": "Applying the confirmed change…", + "integrations.bulk.breakage": "Each client will stop using models routed through this opencodex instance.", + "integrations.bulk.undo": "Each client keeps its own backup and rollback entry.", + "integrations.bulk.confirm": "Disable all", "integrations.semantics.opencode": "Direct disk launches only; ocx opencode environment injection takes precedence.", "integrations.semantics.pi": "Applies to new sessions.", "integrations.semantics.omp": "Restart OMP to load the catalog.", diff --git a/gui/src/i18n/fr.ts b/gui/src/i18n/fr.ts index 32118e4f428..1153c7329b2 100644 --- a/gui/src/i18n/fr.ts +++ b/gui/src/i18n/fr.ts @@ -1852,6 +1852,50 @@ export const fr: Record = { "integrations.dialog.overwrite.undo": "Un instantané est enregistré au préalable : cette opération apparaît dans la liste de restauration ci-dessous et peut être annulée.", "integrations.dialog.overwrite.confirm": "Remplacer", "integrations.action.overwrite": "Remplacer", + "integrations.preview.loading": "Chargement du plan de modification exact…", + "integrations.preview.failed": "Le plan de modification n’a pas pu être chargé. Rien n’a été modifié.", + "integrations.preview.stale": "L’intégration a changé pendant la confirmation. Vérifiez le plan mis à jour et confirmez à nouveau.", + "integrations.dialog.apply.title": "Appliquer cette intégration ?", + "integrations.dialog.apply.changes": "opencodex ajoutera ses paramètres de fournisseur gérés à la configuration du client.", + "integrations.dialog.apply.breakage": "Le client utilisera les modèles actuellement exposés par cette instance opencodex.", + "integrations.dialog.apply.undo": "Une sauvegarde est d’abord créée et la modification peut être annulée depuis le centre de restauration.", + "integrations.dialog.apply.confirm": "Appliquer", + "integrations.dialog.disable.title": "Désactiver cette intégration ?", + "integrations.dialog.disable.changes": "Seuls les paramètres appartenant à opencodex seront supprimés.", + "integrations.dialog.disable.breakage": "Le client cessera d’utiliser les modèles routés par cette instance opencodex.", + "integrations.dialog.disable.undo": "Une sauvegarde est d’abord créée et la modification peut être annulée depuis le centre de restauration.", + "integrations.dialog.disable.confirm": "Désactiver", + "integrations.plan.heading": "Plan de modification du serveur", + "integrations.plan.operation": "Opération : {operation}", + "integrations.plan.operation.apply": "Appliquer", + "integrations.plan.operation.overwrite": "Remplacer", + "integrations.plan.operation.disable": "Désactiver", + "integrations.plan.operation.restore": "Restaurer", + "integrations.plan.change.add": "Ajouter", + "integrations.plan.change.replace": "Remplacer", + "integrations.plan.change.remove": "Supprimer", + "integrations.plan.change.snapshot": "Enregistrer une sauvegarde", + "integrations.plan.change.ownership": "Mettre à jour l’enregistrement de propriété", + "integrations.plan.change.journal": "Enregistrer l’entrée de restauration", + "integrations.plan.foreign.none": "Aucune modification externe détectée.", + "integrations.plan.foreign.unowned": "Un bloc de paramètres n’appartenant pas à opencodex sera remplacé.", + "integrations.plan.foreign.foreignEdit": "Les modifications dans le bloc géré par opencodex seront remplacées.", + "integrations.plan.foreign.drift": "Le fichier a changé depuis ce point de restauration.", + "integrations.plan.noop.applied": "Aucune modification du document client géré n’est nécessaire ; ses paramètres d’intégration sont déjà présents.", + "integrations.plan.noop.disabled": "Aucune modification du document client géré n’est nécessaire ; ses paramètres d’intégration sont déjà absents.", + "integrations.plan.noop.profilePreference": "La préférence de synchronisation du profil sera tout de même enregistrée après confirmation.", + "integrations.plan.refused": "Le serveur ne peut pas appliquer ce plan en toute sécurité.", + "integrations.plan.refusal.notInstalled": "Le client n’est pas installé. Installez-le, actualisez cette page et prévisualisez à nouveau la modification.", + "integrations.plan.refusal.conflict": "Les paramètres gérés sont en conflit avec le fichier actuel. Vérifiez le fichier ou utilisez Remplacer si cette action est disponible.", + "integrations.plan.refusal.unsafe": "La configuration du client ne peut pas être modifiée en toute sécurité. Réparez ou remplacez le fichier avant de réessayer.", + "integrations.plan.refusal.nonLoopback": "Ce client exige une adresse proxy en boucle locale. Utilisez localhost, un tunnel ou un transfert local avant de réessayer.", + "integrations.plan.refusal.driftRequiresConfirm": "Le fichier a changé après ce point de restauration. Vérifiez le plan tenant compte des changements avant de restaurer.", + "integrations.plan.refusal.snapshotExpired": "La sauvegarde de ce point de restauration a expiré et ne peut plus être restaurée.", + "integrations.plan.refusal.writeFailed": "Le serveur n’a pas pu préparer une écriture sûre. Actualisez l’état de l’intégration avant de réessayer.", + "integrations.mutation.pending": "Application de la modification confirmée…", + "integrations.bulk.breakage": "Chaque client cessera d’utiliser les modèles routés par cette instance opencodex.", + "integrations.bulk.undo": "Chaque client conserve sa propre sauvegarde et son entrée de restauration.", + "integrations.bulk.confirm": "Tout désactiver", "integrations.semantics.opencode": "Uniquement pour les lancements directs depuis le disque ; l’injection d’environnement par ocx opencode est prioritaire.", "integrations.semantics.pi": "S’applique aux nouvelles sessions.", "integrations.semantics.omp": "Redémarrez OMP pour charger le catalogue.", diff --git a/gui/src/i18n/ja.ts b/gui/src/i18n/ja.ts index db10ef9e6f9..64a68f59419 100644 --- a/gui/src/i18n/ja.ts +++ b/gui/src/i18n/ja.ts @@ -1776,6 +1776,50 @@ export const ja: Record = { "integrations.dialog.overwrite.undo": "先にスナップショットを保存するので、下のロールバック一覧に残り、元に戻せます。", "integrations.dialog.overwrite.confirm": "置き換える", "integrations.action.overwrite": "置き換える", + "integrations.preview.loading": "正確な変更プランを読み込んでいます…", + "integrations.preview.failed": "変更プランを読み込めませんでした。変更は行われていません。", + "integrations.preview.stale": "確認中に統合の状態が変わりました。更新されたプランを確認して、もう一度確定してください。", + "integrations.dialog.apply.title": "この統合を適用しますか?", + "integrations.dialog.apply.changes": "opencodex が管理するプロバイダー設定をクライアント設定に追加します。", + "integrations.dialog.apply.breakage": "クライアントは、この opencodex インスタンスが現在公開しているモデルを使用します。", + "integrations.dialog.apply.undo": "先にバックアップが保存され、ロールバックセンターから元に戻せます。", + "integrations.dialog.apply.confirm": "適用", + "integrations.dialog.disable.title": "この統合を無効にしますか?", + "integrations.dialog.disable.changes": "opencodex が所有する設定だけを削除します。", + "integrations.dialog.disable.breakage": "クライアントは、この opencodex インスタンス経由のモデルを使用しなくなります。", + "integrations.dialog.disable.undo": "先にバックアップが保存され、ロールバックセンターから元に戻せます。", + "integrations.dialog.disable.confirm": "無効にする", + "integrations.plan.heading": "サーバー変更プラン", + "integrations.plan.operation": "操作: {operation}", + "integrations.plan.operation.apply": "適用", + "integrations.plan.operation.overwrite": "置き換え", + "integrations.plan.operation.disable": "無効化", + "integrations.plan.operation.restore": "復元", + "integrations.plan.change.add": "追加", + "integrations.plan.change.replace": "置き換え", + "integrations.plan.change.remove": "削除", + "integrations.plan.change.snapshot": "バックアップを保存", + "integrations.plan.change.ownership": "所有権記録を更新", + "integrations.plan.change.journal": "ロールバック履歴を記録", + "integrations.plan.foreign.none": "外部の編集は検出されませんでした。", + "integrations.plan.foreign.unowned": "opencodex が所有していない設定ブロックを置き換えます。", + "integrations.plan.foreign.foreignEdit": "opencodex 管理ブロック内の編集を置き換えます。", + "integrations.plan.foreign.drift": "このロールバック地点以降にファイルが変更されています。", + "integrations.plan.noop.applied": "管理対象のクライアント文書を変更する必要はありません。統合設定はすでに存在します。", + "integrations.plan.noop.disabled": "管理対象のクライアント文書を変更する必要はありません。統合設定はすでに存在しません。", + "integrations.plan.noop.profilePreference": "確認すると、プロファイルの同期設定は引き続き保存されます。", + "integrations.plan.refused": "サーバーはこのプランを安全に適用できません。", + "integrations.plan.refusal.notInstalled": "クライアントがインストールされていません。インストール後にページを更新し、変更をもう一度確認してください。", + "integrations.plan.refusal.conflict": "管理対象の設定が現在のファイルと競合しています。ファイルを確認するか、利用可能な場合は置き換えを使用してください。", + "integrations.plan.refusal.unsafe": "クライアント設定を安全に変更できません。ファイルを修復または置き換えてから再試行してください。", + "integrations.plan.refusal.nonLoopback": "このクライアントにはループバックのプロキシアドレスが必要です。localhost、トンネル、またはローカル転送を使用してください。", + "integrations.plan.refusal.driftRequiresConfirm": "このロールバック地点以降にファイルが変更されました。変更を考慮したプランを確認してから復元してください。", + "integrations.plan.refusal.snapshotExpired": "このロールバック地点のバックアップは期限切れのため、復元できません。", + "integrations.plan.refusal.writeFailed": "サーバーは安全な書き込みを準備できませんでした。統合状態を更新してから再試行してください。", + "integrations.mutation.pending": "確認済みの変更を適用しています…", + "integrations.bulk.breakage": "各クライアントは、この opencodex インスタンス経由のモデルを使用しなくなります。", + "integrations.bulk.undo": "各クライアントに個別のバックアップとロールバック履歴が残ります。", + "integrations.bulk.confirm": "すべて無効にする", "integrations.semantics.opencode": "ディスクから直接起動した場合にのみ適用されます。ocx opencode の環境注入が優先されます。", "integrations.semantics.pi": "新しいセッションから適用されます。", "integrations.semantics.omp": "カタログを読み込むには OMP を再起動してください。", diff --git a/gui/src/i18n/ko.ts b/gui/src/i18n/ko.ts index 2c54e07072f..d5a4a9392c5 100644 --- a/gui/src/i18n/ko.ts +++ b/gui/src/i18n/ko.ts @@ -1368,6 +1368,50 @@ export const ko: Record = { "integrations.dialog.overwrite.undo": "먼저 스냅숏을 저장하므로 아래 되돌리기 목록에 남고 다시 되돌릴 수 있습니다.", "integrations.dialog.overwrite.confirm": "덮어쓰기", "integrations.action.overwrite": "덮어쓰기", + "integrations.preview.loading": "정확한 변경 계획을 불러오는 중…", + "integrations.preview.failed": "변경 계획을 불러오지 못했습니다. 아무것도 변경하지 않았습니다.", + "integrations.preview.stale": "확인하는 동안 통합 상태가 바뀌었습니다. 갱신된 계획을 검토하고 다시 확인하세요.", + "integrations.dialog.apply.title": "이 통합을 적용할까요?", + "integrations.dialog.apply.changes": "opencodex가 관리하는 공급자 설정을 클라이언트 구성에 추가합니다.", + "integrations.dialog.apply.breakage": "클라이언트는 현재 이 opencodex 인스턴스가 제공하는 모델을 사용합니다.", + "integrations.dialog.apply.undo": "먼저 백업을 저장하며 롤백 센터에서 변경을 되돌릴 수 있습니다.", + "integrations.dialog.apply.confirm": "적용", + "integrations.dialog.disable.title": "이 통합을 비활성화할까요?", + "integrations.dialog.disable.changes": "opencodex가 소유한 설정만 제거합니다.", + "integrations.dialog.disable.breakage": "클라이언트는 이 opencodex 인스턴스를 통해 라우팅되는 모델을 더 이상 사용하지 않습니다.", + "integrations.dialog.disable.undo": "먼저 백업을 저장하며 롤백 센터에서 변경을 되돌릴 수 있습니다.", + "integrations.dialog.disable.confirm": "비활성화", + "integrations.plan.heading": "서버 변경 계획", + "integrations.plan.operation": "작업: {operation}", + "integrations.plan.operation.apply": "적용", + "integrations.plan.operation.overwrite": "교체", + "integrations.plan.operation.disable": "비활성화", + "integrations.plan.operation.restore": "복원", + "integrations.plan.change.add": "추가", + "integrations.plan.change.replace": "교체", + "integrations.plan.change.remove": "제거", + "integrations.plan.change.snapshot": "백업 저장", + "integrations.plan.change.ownership": "소유권 기록 갱신", + "integrations.plan.change.journal": "롤백 항목 기록", + "integrations.plan.foreign.none": "외부 편집이 감지되지 않았습니다.", + "integrations.plan.foreign.unowned": "opencodex가 소유하지 않은 설정 블록을 교체합니다.", + "integrations.plan.foreign.foreignEdit": "opencodex 관리 블록 안의 편집 내용을 교체합니다.", + "integrations.plan.foreign.drift": "이 롤백 시점 이후 파일이 변경되었습니다.", + "integrations.plan.noop.applied": "관리되는 클라이언트 문서는 변경할 필요가 없습니다. 통합 설정이 이미 있습니다.", + "integrations.plan.noop.disabled": "관리되는 클라이언트 문서는 변경할 필요가 없습니다. 통합 설정이 이미 없습니다.", + "integrations.plan.noop.profilePreference": "확인하면 프로필 동기화 설정은 계속 저장됩니다.", + "integrations.plan.refused": "서버가 이 계획을 안전하게 적용할 수 없습니다.", + "integrations.plan.refusal.notInstalled": "클라이언트가 설치되어 있지 않습니다. 설치한 뒤 페이지를 새로 고치고 변경 사항을 다시 미리 확인하세요.", + "integrations.plan.refusal.conflict": "관리 설정이 현재 파일과 충돌합니다. 파일을 검토하거나 사용할 수 있다면 교체 작업을 선택하세요.", + "integrations.plan.refusal.unsafe": "클라이언트 구성을 안전하게 변경할 수 없습니다. 파일을 복구하거나 교체한 뒤 다시 시도하세요.", + "integrations.plan.refusal.nonLoopback": "이 클라이언트에는 루프백 프록시 주소가 필요합니다. localhost, 터널 또는 로컬 포워더를 사용한 뒤 다시 시도하세요.", + "integrations.plan.refusal.driftRequiresConfirm": "이 롤백 시점 이후 파일이 변경되었습니다. 변경 상태를 반영한 계획을 검토한 뒤 복원하세요.", + "integrations.plan.refusal.snapshotExpired": "이 롤백 시점의 백업이 만료되어 더 이상 복원할 수 없습니다.", + "integrations.plan.refusal.writeFailed": "서버가 안전한 쓰기 작업을 준비하지 못했습니다. 통합 상태를 새로 고친 뒤 다시 시도하세요.", + "integrations.mutation.pending": "확인한 변경 사항을 적용하는 중…", + "integrations.bulk.breakage": "각 클라이언트는 이 opencodex 인스턴스를 통해 라우팅되는 모델을 더 이상 사용하지 않습니다.", + "integrations.bulk.undo": "각 클라이언트는 자체 백업과 롤백 항목을 유지합니다.", + "integrations.bulk.confirm": "모두 비활성화", "integrations.semantics.opencode": "디스크에서 직접 실행할 때만 적용됩니다. ocx opencode의 환경 주입이 우선합니다.", "integrations.semantics.pi": "새 세션부터 적용됩니다.", "integrations.semantics.omp": "카탈로그를 불러오려면 OMP를 재시작하세요.", diff --git a/gui/src/i18n/ru.ts b/gui/src/i18n/ru.ts index 2d281e0ac0e..631637977eb 100644 --- a/gui/src/i18n/ru.ts +++ b/gui/src/i18n/ru.ts @@ -1847,6 +1847,50 @@ export const ru: Record = { "integrations.dialog.overwrite.undo": "Снимок сохраняется заранее, поэтому операция попадёт в список откатов ниже и её можно отменить.", "integrations.dialog.overwrite.confirm": "Заменить", "integrations.action.overwrite": "Заменить", + "integrations.preview.loading": "Загрузка точного плана изменений…", + "integrations.preview.failed": "Не удалось загрузить план изменений. Ничего не изменено.", + "integrations.preview.stale": "Интеграция изменилась во время подтверждения. Проверьте обновлённый план и подтвердите снова.", + "integrations.dialog.apply.title": "Применить эту интеграцию?", + "integrations.dialog.apply.changes": "opencodex добавит управляемые настройки провайдера в конфигурацию клиента.", + "integrations.dialog.apply.breakage": "Клиент будет использовать модели, доступные через этот экземпляр opencodex.", + "integrations.dialog.apply.undo": "Сначала сохраняется резервная копия; изменение можно отменить в центре отката.", + "integrations.dialog.apply.confirm": "Применить", + "integrations.dialog.disable.title": "Отключить эту интеграцию?", + "integrations.dialog.disable.changes": "Будут удалены только настройки, принадлежащие opencodex.", + "integrations.dialog.disable.breakage": "Клиент перестанет использовать модели, направляемые через этот экземпляр opencodex.", + "integrations.dialog.disable.undo": "Сначала сохраняется резервная копия; изменение можно отменить в центре отката.", + "integrations.dialog.disable.confirm": "Отключить", + "integrations.plan.heading": "План изменений сервера", + "integrations.plan.operation": "Операция: {operation}", + "integrations.plan.operation.apply": "Применить", + "integrations.plan.operation.overwrite": "Заменить", + "integrations.plan.operation.disable": "Отключить", + "integrations.plan.operation.restore": "Восстановить", + "integrations.plan.change.add": "Добавить", + "integrations.plan.change.replace": "Заменить", + "integrations.plan.change.remove": "Удалить", + "integrations.plan.change.snapshot": "Сохранить резервную копию", + "integrations.plan.change.ownership": "Обновить запись владения", + "integrations.plan.change.journal": "Записать точку отката", + "integrations.plan.foreign.none": "Внешние изменения не обнаружены.", + "integrations.plan.foreign.unowned": "Блок настроек, не принадлежащий opencodex, будет заменён.", + "integrations.plan.foreign.foreignEdit": "Изменения внутри блока opencodex будут заменены.", + "integrations.plan.foreign.drift": "Файл изменился после этой точки отката.", + "integrations.plan.noop.applied": "Управляемый документ клиента изменять не нужно: настройки интеграции уже присутствуют.", + "integrations.plan.noop.disabled": "Управляемый документ клиента изменять не нужно: настройки интеграции уже отсутствуют.", + "integrations.plan.noop.profilePreference": "После подтверждения настройка синхронизации профиля всё равно будет сохранена.", + "integrations.plan.refused": "Сервер не может безопасно применить этот план.", + "integrations.plan.refusal.notInstalled": "Клиент не установлен. Установите его, обновите страницу и снова просмотрите изменение.", + "integrations.plan.refusal.conflict": "Управляемые настройки конфликтуют с текущим файлом. Проверьте файл или используйте замену, если она доступна.", + "integrations.plan.refusal.unsafe": "Конфигурацию клиента нельзя безопасно изменить. Исправьте или замените файл перед повторной попыткой.", + "integrations.plan.refusal.nonLoopback": "Этому клиенту нужен адрес прокси в loopback. Используйте localhost, туннель или локальную переадресацию.", + "integrations.plan.refusal.driftRequiresConfirm": "Файл изменился после этой точки отката. Проверьте план с учётом изменений перед восстановлением.", + "integrations.plan.refusal.snapshotExpired": "Резервная копия для этой точки отката истекла и больше не может быть восстановлена.", + "integrations.plan.refusal.writeFailed": "Сервер не смог подготовить безопасную запись. Обновите состояние интеграции перед повторной попыткой.", + "integrations.mutation.pending": "Применение подтверждённого изменения…", + "integrations.bulk.breakage": "Каждый клиент перестанет использовать модели, направляемые через этот экземпляр opencodex.", + "integrations.bulk.undo": "У каждого клиента останется собственная резервная копия и запись отката.", + "integrations.bulk.confirm": "Отключить все", "integrations.semantics.opencode": "Действует только при прямом запуске с диска; внедрение окружения через ocx opencode имеет приоритет.", "integrations.semantics.pi": "Применяется к новым сеансам.", "integrations.semantics.omp": "Перезапустите OMP, чтобы загрузить каталог.", diff --git a/gui/src/i18n/tr.ts b/gui/src/i18n/tr.ts index d4a599fa65b..1646ccb8251 100644 --- a/gui/src/i18n/tr.ts +++ b/gui/src/i18n/tr.ts @@ -1866,6 +1866,50 @@ export const tr: Record = { "integrations.dialog.overwrite.undo": "Önce bir anlık görüntü kaydedilir; bu işlem aşağıdaki geri alma listesinde görünür ve geri alınabilir.", "integrations.dialog.overwrite.confirm": "Değiştir", "integrations.action.overwrite": "Değiştir", + "integrations.preview.loading": "Kesin değişiklik planı yükleniyor…", + "integrations.preview.failed": "Değişiklik planı yüklenemedi. Hiçbir şey değiştirilmedi.", + "integrations.preview.stale": "Onay sırasında entegrasyon değişti. Güncellenen planı inceleyip yeniden onaylayın.", + "integrations.dialog.apply.title": "Bu entegrasyon uygulansın mı?", + "integrations.dialog.apply.changes": "opencodex, yönettiği sağlayıcı ayarlarını istemci yapılandırmasına ekleyecek.", + "integrations.dialog.apply.breakage": "İstemci, bu opencodex örneğinin sunduğu modelleri kullanacak.", + "integrations.dialog.apply.undo": "Önce yedek kaydedilir; değişiklik geri alma merkezinden geri alınabilir.", + "integrations.dialog.apply.confirm": "Uygula", + "integrations.dialog.disable.title": "Bu entegrasyon devre dışı bırakılsın mı?", + "integrations.dialog.disable.changes": "Yalnızca opencodex’e ait ayarlar kaldırılacak.", + "integrations.dialog.disable.breakage": "İstemci, bu opencodex örneği üzerinden yönlendirilen modelleri kullanmayı bırakacak.", + "integrations.dialog.disable.undo": "Önce yedek kaydedilir; değişiklik geri alma merkezinden geri alınabilir.", + "integrations.dialog.disable.confirm": "Devre dışı bırak", + "integrations.plan.heading": "Sunucu değişiklik planı", + "integrations.plan.operation": "İşlem: {operation}", + "integrations.plan.operation.apply": "Uygula", + "integrations.plan.operation.overwrite": "Değiştir", + "integrations.plan.operation.disable": "Devre dışı bırak", + "integrations.plan.operation.restore": "Geri yükle", + "integrations.plan.change.add": "Ekle", + "integrations.plan.change.replace": "Değiştir", + "integrations.plan.change.remove": "Kaldır", + "integrations.plan.change.snapshot": "Yedek kaydet", + "integrations.plan.change.ownership": "Sahiplik kaydını güncelle", + "integrations.plan.change.journal": "Geri alma kaydı oluştur", + "integrations.plan.foreign.none": "Dış düzenleme algılanmadı.", + "integrations.plan.foreign.unowned": "opencodex’e ait olmayan bir ayar bloğu değiştirilecek.", + "integrations.plan.foreign.foreignEdit": "opencodex yönetimli blok içindeki düzenlemeler değiştirilecek.", + "integrations.plan.foreign.drift": "Dosya bu geri alma noktasından sonra değişti.", + "integrations.plan.noop.applied": "Yönetilen istemci belgesinde değişiklik gerekmiyor; entegrasyon ayarları zaten mevcut.", + "integrations.plan.noop.disabled": "Yönetilen istemci belgesinde değişiklik gerekmiyor; entegrasyon ayarları zaten yok.", + "integrations.plan.noop.profilePreference": "Onayladığınızda profil eşitleme tercihi yine de kaydedilir.", + "integrations.plan.refused": "Sunucu bu planı güvenle uygulayamıyor.", + "integrations.plan.refusal.notInstalled": "İstemci yüklü değil. İstemciyi yükleyin, sayfayı yenileyin ve değişikliği yeniden önizleyin.", + "integrations.plan.refusal.conflict": "Yönetilen ayarlar mevcut dosyayla çakışıyor. Dosyayı inceleyin veya varsa Değiştir işlemini kullanın.", + "integrations.plan.refusal.unsafe": "İstemci yapılandırması güvenle değiştirilemiyor. Yeniden denemeden önce dosyayı onarın veya değiştirin.", + "integrations.plan.refusal.nonLoopback": "Bu istemci bir geri döngü proxy adresi gerektiriyor. localhost, tünel veya yerel yönlendirme kullanın.", + "integrations.plan.refusal.driftRequiresConfirm": "Dosya bu geri alma noktasından sonra değişti. Geri yüklemeden önce değişikliği dikkate alan planı inceleyin.", + "integrations.plan.refusal.snapshotExpired": "Bu geri alma noktasının yedeği sona erdiği için artık geri yüklenemez.", + "integrations.plan.refusal.writeFailed": "Sunucu güvenli bir yazma işlemi hazırlayamadı. Yeniden denemeden önce entegrasyon durumunu yenileyin.", + "integrations.mutation.pending": "Onaylanan değişiklik uygulanıyor…", + "integrations.bulk.breakage": "Her istemci, bu opencodex örneği üzerinden yönlendirilen modelleri kullanmayı bırakacak.", + "integrations.bulk.undo": "Her istemci kendi yedeğini ve geri alma kaydını tutar.", + "integrations.bulk.confirm": "Tümünü devre dışı bırak", "integrations.semantics.opencode": "Doğrudan disk başlatmaları.", "integrations.semantics.pi": "Yeni oturumlara uygulanır.", "integrations.semantics.hermes": "Yeni oturumlara uygulanır.", diff --git a/gui/src/i18n/vi.ts b/gui/src/i18n/vi.ts index de781fc3bad..3d726cc35e7 100644 --- a/gui/src/i18n/vi.ts +++ b/gui/src/i18n/vi.ts @@ -1869,6 +1869,50 @@ export const vi: Record = { "integrations.dialog.overwrite.undo": "Một bản sao lưu sẽ được lưu trước tiên, do đó thao tác này sẽ xuất hiện trong danh sách hoàn tác bên dưới và có thể được khôi phục.", "integrations.dialog.overwrite.confirm": "Thay thế", "integrations.action.overwrite": "Thay thế", + "integrations.preview.loading": "Đang tải kế hoạch thay đổi chính xác…", + "integrations.preview.failed": "Không thể tải kế hoạch thay đổi. Không có gì bị thay đổi.", + "integrations.preview.stale": "Tích hợp đã thay đổi trong lúc xác nhận. Hãy xem kế hoạch mới và xác nhận lại.", + "integrations.dialog.apply.title": "Áp dụng tích hợp này?", + "integrations.dialog.apply.changes": "opencodex sẽ thêm các cài đặt nhà cung cấp do nó quản lý vào cấu hình máy khách.", + "integrations.dialog.apply.breakage": "Máy khách sẽ dùng các mô hình hiện được phiên bản opencodex này cung cấp.", + "integrations.dialog.apply.undo": "Bản sao lưu được lưu trước và có thể hoàn tác thay đổi trong trung tâm khôi phục.", + "integrations.dialog.apply.confirm": "Áp dụng", + "integrations.dialog.disable.title": "Tắt tích hợp này?", + "integrations.dialog.disable.changes": "Chỉ các cài đặt thuộc opencodex sẽ bị xóa.", + "integrations.dialog.disable.breakage": "Máy khách sẽ ngừng dùng các mô hình được định tuyến qua phiên bản opencodex này.", + "integrations.dialog.disable.undo": "Bản sao lưu được lưu trước và có thể hoàn tác thay đổi trong trung tâm khôi phục.", + "integrations.dialog.disable.confirm": "Tắt", + "integrations.plan.heading": "Kế hoạch thay đổi từ máy chủ", + "integrations.plan.operation": "Thao tác: {operation}", + "integrations.plan.operation.apply": "Áp dụng", + "integrations.plan.operation.overwrite": "Thay thế", + "integrations.plan.operation.disable": "Tắt", + "integrations.plan.operation.restore": "Khôi phục", + "integrations.plan.change.add": "Thêm", + "integrations.plan.change.replace": "Thay thế", + "integrations.plan.change.remove": "Xóa", + "integrations.plan.change.snapshot": "Lưu bản sao", + "integrations.plan.change.ownership": "Cập nhật bản ghi quyền sở hữu", + "integrations.plan.change.journal": "Ghi mục khôi phục", + "integrations.plan.foreign.none": "Không phát hiện chỉnh sửa bên ngoài.", + "integrations.plan.foreign.unowned": "Một khối cài đặt không thuộc opencodex sẽ bị thay thế.", + "integrations.plan.foreign.foreignEdit": "Các chỉnh sửa trong khối do opencodex quản lý sẽ bị thay thế.", + "integrations.plan.foreign.drift": "Tệp đã thay đổi kể từ điểm khôi phục này.", + "integrations.plan.noop.applied": "Không cần thay đổi tài liệu máy khách được quản lý; cài đặt tích hợp đã có sẵn.", + "integrations.plan.noop.disabled": "Không cần thay đổi tài liệu máy khách được quản lý; cài đặt tích hợp đã không còn.", + "integrations.plan.noop.profilePreference": "Tùy chọn đồng bộ hồ sơ vẫn sẽ được lưu khi bạn xác nhận.", + "integrations.plan.refused": "Máy chủ không thể áp dụng kế hoạch này một cách an toàn.", + "integrations.plan.refusal.notInstalled": "Máy khách chưa được cài đặt. Hãy cài đặt, làm mới trang và xem trước thay đổi lần nữa.", + "integrations.plan.refusal.conflict": "Cài đặt được quản lý xung đột với tệp hiện tại. Hãy xem lại tệp hoặc dùng Thay thế khi có thể.", + "integrations.plan.refusal.unsafe": "Không thể thay đổi cấu hình máy khách một cách an toàn. Hãy sửa hoặc thay tệp trước khi thử lại.", + "integrations.plan.refusal.nonLoopback": "Máy khách này cần địa chỉ proxy loopback. Hãy dùng localhost, đường hầm hoặc chuyển tiếp cục bộ.", + "integrations.plan.refusal.driftRequiresConfirm": "Tệp đã thay đổi sau điểm khôi phục này. Hãy xem kế hoạch có tính đến thay đổi trước khi khôi phục.", + "integrations.plan.refusal.snapshotExpired": "Bản sao lưu cho điểm khôi phục này đã hết hạn nên không thể khôi phục nữa.", + "integrations.plan.refusal.writeFailed": "Máy chủ không thể chuẩn bị thao tác ghi an toàn. Hãy làm mới trạng thái tích hợp trước khi thử lại.", + "integrations.mutation.pending": "Đang áp dụng thay đổi đã xác nhận…", + "integrations.bulk.breakage": "Mỗi máy khách sẽ ngừng dùng các mô hình được định tuyến qua phiên bản opencodex này.", + "integrations.bulk.undo": "Mỗi máy khách giữ bản sao lưu và mục khôi phục riêng.", + "integrations.bulk.confirm": "Tắt tất cả", "integrations.semantics.opencode": "Chỉ khởi chạy trực tiếp trên đĩa; việc inject môi trường ocx opencode sẽ được ưu tiên.", "integrations.semantics.pi": "Áp dụng cho các session mới.", "integrations.semantics.omp": "Khởi động lại OMP để tải catalog.", diff --git a/gui/src/i18n/zh-TW.ts b/gui/src/i18n/zh-TW.ts index 4c952631604..cb4513ba7ef 100644 --- a/gui/src/i18n/zh-TW.ts +++ b/gui/src/i18n/zh-TW.ts @@ -2506,6 +2506,50 @@ export const zhTW: Record = { "integrations.dialog.overwrite.undo": "會先儲存快照,因此這次操作會出現在下方的還原清單中,可以復原。", "integrations.dialog.overwrite.confirm": "替換", "integrations.action.overwrite": "替換", + "integrations.preview.loading": "正在載入精確的變更計畫…", + "integrations.preview.failed": "無法載入變更計畫。未進行任何變更。", + "integrations.preview.stale": "確認期間整合狀態已變更。請檢視更新後的計畫並再次確認。", + "integrations.dialog.apply.title": "套用此整合?", + "integrations.dialog.apply.changes": "opencodex 會將其管理的供應商設定加入用戶端設定。", + "integrations.dialog.apply.breakage": "用戶端將使用此 opencodex 執行個體目前提供的模型。", + "integrations.dialog.apply.undo": "系統會先儲存備份,可在回復中心復原此變更。", + "integrations.dialog.apply.confirm": "套用", + "integrations.dialog.disable.title": "停用此整合?", + "integrations.dialog.disable.changes": "只會移除 opencodex 擁有的設定。", + "integrations.dialog.disable.breakage": "用戶端將停止使用透過此 opencodex 執行個體路由的模型。", + "integrations.dialog.disable.undo": "系統會先儲存備份,可在回復中心復原此變更。", + "integrations.dialog.disable.confirm": "停用", + "integrations.plan.heading": "伺服器變更計畫", + "integrations.plan.operation": "操作:{operation}", + "integrations.plan.operation.apply": "套用", + "integrations.plan.operation.overwrite": "替換", + "integrations.plan.operation.disable": "停用", + "integrations.plan.operation.restore": "還原", + "integrations.plan.change.add": "新增", + "integrations.plan.change.replace": "替換", + "integrations.plan.change.remove": "移除", + "integrations.plan.change.snapshot": "儲存備份", + "integrations.plan.change.ownership": "更新擁有權記錄", + "integrations.plan.change.journal": "記錄回復項目", + "integrations.plan.foreign.none": "未偵測到外部編輯。", + "integrations.plan.foreign.unowned": "將替換不屬於 opencodex 的設定區塊。", + "integrations.plan.foreign.foreignEdit": "將替換 opencodex 管理區塊內的編輯。", + "integrations.plan.foreign.drift": "檔案在此回復點之後已變更。", + "integrations.plan.noop.applied": "不需要變更受管理的用戶端文件;整合設定已存在。", + "integrations.plan.noop.disabled": "不需要變更受管理的用戶端文件;整合設定已不存在。", + "integrations.plan.noop.profilePreference": "確認後仍會儲存設定檔同步偏好。", + "integrations.plan.refused": "伺服器無法安全地套用此計畫。", + "integrations.plan.refusal.notInstalled": "用戶端尚未安裝。請先安裝、重新整理此頁面,再次預覽變更。", + "integrations.plan.refusal.conflict": "受管理的設定與目前檔案衝突。請檢查檔案,或在可用時使用「替換」。", + "integrations.plan.refusal.unsafe": "無法安全地變更用戶端設定。請修復或替換檔案後再試一次。", + "integrations.plan.refusal.nonLoopback": "此用戶端需要迴路代理位址。請使用 localhost、通道或本機轉送後再試一次。", + "integrations.plan.refusal.driftRequiresConfirm": "檔案在此回復點後已變更。請先檢視包含變更的計畫再還原。", + "integrations.plan.refusal.snapshotExpired": "此回復點的備份已過期,無法再還原。", + "integrations.plan.refusal.writeFailed": "伺服器無法準備安全寫入。請重新整理整合狀態後再試一次。", + "integrations.mutation.pending": "正在套用已確認的變更…", + "integrations.bulk.breakage": "每個用戶端都將停止使用透過此 opencodex 執行個體路由的模型。", + "integrations.bulk.undo": "每個用戶端都會保留各自的備份和回復項目。", + "integrations.bulk.confirm": "全部停用", "integrations.semantics.opencode": "僅適用於直接從磁碟啟動;ocx opencode 的環境注入優先。", "integrations.semantics.pi": "適用於新工作階段。", "integrations.semantics.omp": "重新啟動 OMP 以載入模型目錄。", diff --git a/gui/src/i18n/zh.ts b/gui/src/i18n/zh.ts index 2ed40cb237f..aa5049f34ce 100644 --- a/gui/src/i18n/zh.ts +++ b/gui/src/i18n/zh.ts @@ -1349,6 +1349,50 @@ export const zh: Record = { "integrations.dialog.overwrite.undo": "会先保存快照,因此这次操作会出现在下方的回滚列表中,可以撤销。", "integrations.dialog.overwrite.confirm": "替换", "integrations.action.overwrite": "替换", + "integrations.preview.loading": "正在加载准确的更改计划…", + "integrations.preview.failed": "无法加载更改计划。未进行任何更改。", + "integrations.preview.stale": "确认期间集成状态已变化。请查看更新后的计划并再次确认。", + "integrations.dialog.apply.title": "应用此集成?", + "integrations.dialog.apply.changes": "opencodex 会将其管理的提供商设置添加到客户端配置。", + "integrations.dialog.apply.breakage": "客户端将使用此 opencodex 实例当前提供的模型。", + "integrations.dialog.apply.undo": "系统会先保存备份,可在回滚中心撤销此更改。", + "integrations.dialog.apply.confirm": "应用", + "integrations.dialog.disable.title": "禁用此集成?", + "integrations.dialog.disable.changes": "仅移除 opencodex 拥有的设置。", + "integrations.dialog.disable.breakage": "客户端将停止使用通过此 opencodex 实例路由的模型。", + "integrations.dialog.disable.undo": "系统会先保存备份,可在回滚中心撤销此更改。", + "integrations.dialog.disable.confirm": "禁用", + "integrations.plan.heading": "服务器更改计划", + "integrations.plan.operation": "操作:{operation}", + "integrations.plan.operation.apply": "应用", + "integrations.plan.operation.overwrite": "替换", + "integrations.plan.operation.disable": "禁用", + "integrations.plan.operation.restore": "恢复", + "integrations.plan.change.add": "添加", + "integrations.plan.change.replace": "替换", + "integrations.plan.change.remove": "移除", + "integrations.plan.change.snapshot": "保存备份", + "integrations.plan.change.ownership": "更新所有权记录", + "integrations.plan.change.journal": "记录回滚条目", + "integrations.plan.foreign.none": "未检测到外部编辑。", + "integrations.plan.foreign.unowned": "将替换不属于 opencodex 的设置块。", + "integrations.plan.foreign.foreignEdit": "将替换 opencodex 管理块内的编辑。", + "integrations.plan.foreign.drift": "文件在此回滚点之后发生了变化。", + "integrations.plan.noop.applied": "无需更改托管的客户端文档;集成设置已存在。", + "integrations.plan.noop.disabled": "无需更改托管的客户端文档;集成设置已不存在。", + "integrations.plan.noop.profilePreference": "确认后仍会保存配置文件同步偏好。", + "integrations.plan.refused": "服务器无法安全地应用此计划。", + "integrations.plan.refusal.notInstalled": "客户端尚未安装。请先安装,刷新此页面,然后重新预览更改。", + "integrations.plan.refusal.conflict": "托管设置与当前文件冲突。请检查文件,或在可用时使用“替换”。", + "integrations.plan.refusal.unsafe": "无法安全地更改客户端配置。请修复或替换文件后重试。", + "integrations.plan.refusal.nonLoopback": "此客户端需要环回代理地址。请使用 localhost、隧道或本地转发后重试。", + "integrations.plan.refusal.driftRequiresConfirm": "文件在此回滚点后发生了变化。请先查看包含变化的计划再恢复。", + "integrations.plan.refusal.snapshotExpired": "此回滚点的备份已过期,无法再恢复。", + "integrations.plan.refusal.writeFailed": "服务器无法准备安全写入。请刷新集成状态后重试。", + "integrations.mutation.pending": "正在应用已确认的更改…", + "integrations.bulk.breakage": "每个客户端都将停止使用通过此 opencodex 实例路由的模型。", + "integrations.bulk.undo": "每个客户端都会保留各自的备份和回滚条目。", + "integrations.bulk.confirm": "全部禁用", "integrations.semantics.opencode": "仅适用于直接从磁盘启动;ocx opencode 的环境注入优先。", "integrations.semantics.pi": "对新会话生效。", "integrations.semantics.omp": "重启 OMP 以加载模型目录。", diff --git a/gui/src/pages/integrations/AsideProfilesPage.tsx b/gui/src/pages/integrations/AsideProfilesPage.tsx index 8d1434dacf4..c7981995379 100644 --- a/gui/src/pages/integrations/AsideProfilesPage.tsx +++ b/gui/src/pages/integrations/AsideProfilesPage.tsx @@ -1,4 +1,4 @@ -import { useCallback, useRef, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import { useT } from "../../i18n/shared"; import { useDataSurface } from "../../data-surface"; import { DataSurfaceSkeleton } from "../../components/data-surface"; @@ -7,11 +7,30 @@ import { markFor } from "../../components/integration-marks"; import { Notice, Switch } from "../../ui"; import IntegrationStateBadge from "./IntegrationStateBadge"; import FileIntegrationPage from "./FileIntegrationPage"; +import ConsequenceDialog, { type ConsequenceCopy } from "./ConsequenceDialog"; import { describeRefusal, describeAsideProfileOutcome } from "./refusal-copy"; import type { AsideProfileOutcome } from "./aside-profile-contract"; -import { IntegrationApiError, toggleIntegration } from "./integration-api"; +import { + bindingFor, + IntegrationApiError, + isIntegrationPreviewUnavailable, + previewIntegrationMutation, + toggleIntegration, + type IntegrationMutationPlan, +} from "./integration-api"; import { loadAsideProfiles, syncAsideProfiles, type AsideProfileStatus } from "./aside-profile-api"; +const PROFILE_APPLY_COPY: ConsequenceCopy = { + titleKey: "integrations.dialog.apply.title", changesKey: "integrations.dialog.apply.changes", + breakageKey: "integrations.dialog.apply.breakage", undoKey: "integrations.dialog.apply.undo", + confirmKey: "integrations.dialog.apply.confirm", +}; +const PROFILE_DISABLE_COPY: ConsequenceCopy = { + titleKey: "integrations.dialog.disable.title", changesKey: "integrations.dialog.disable.changes", + breakageKey: "integrations.dialog.disable.breakage", undoKey: "integrations.dialog.disable.undo", + confirmKey: "integrations.dialog.disable.confirm", +}; + export default function AsideProfilesPage({ apiBase, active = true }: { apiBase: string; active?: boolean }) { const t = useT(); const [selected, setSelected] = useState(null); @@ -19,6 +38,19 @@ export default function AsideProfilesPage({ apiBase, active = true }: { apiBase: const pendingRef = useRef(false); const [failure, setFailure] = useState(null); const [profileFailures, setProfileFailures] = useState>(new Map()); + const [planned, setPlanned] = useState<{ + profile: AsideProfileStatus; + enabled: boolean; + plan: IntegrationMutationPlan | null; + loading: boolean; + failure: string | null; + } | null>(null); + const previewAbortRef = useRef(null); + const previewGenerationRef = useRef(0); + useEffect(() => () => { + previewGenerationRef.current += 1; + previewAbortRef.current?.abort(); + }, []); const fetchProfiles = useCallback((signal: AbortSignal) => loadAsideProfiles(apiBase, signal), [apiBase]); const resource = useDataSurface(`aside-profiles:${apiBase}`, [apiBase], fetchProfiles, { enabled: active, @@ -28,7 +60,7 @@ export default function AsideProfilesPage({ apiBase, active = true }: { apiBase: const data = resource.state.data; const profiles = data?.profiles ?? []; const loadError = resource.state.showError || Boolean(data?.error); - const busy = pending !== null || resource.state.refreshing; + const busy = pending !== null || resource.state.refreshing || planned !== null; const label = (profile: AsideProfileStatus) => profile.name || t("integrations.aside.profile", { id: profile.profileId }); const reconcileOutcomes = (outcomes: AsideProfileOutcome[]) => setProfileFailures(previous => { @@ -48,17 +80,23 @@ export default function AsideProfilesPage({ apiBase, active = true }: { apiBase: } else setFailure(describeRefusal(t, error)); }; - const mutate = async (enabled: boolean, profileId?: number) => { + const mutate = async (enabled: boolean, profileId?: number, plan?: IntegrationMutationPlan) => { if (pendingRef.current) return; pendingRef.current = true; setPending(profileId ?? "all"); setFailure(null); try { - const result = await toggleIntegration(apiBase, "aside", enabled, undefined, undefined, profileId); + const result = await toggleIntegration(apiBase, "aside", { + enabled, profileId, ...(plan ? { binding: bindingFor(plan) } : {}), + }); reconcileOutcomes(result.results ?? (profileId === undefined ? profiles.map(row => row.profileId) : [profileId]) .map(id => ({ profileId: id, ok: true }))); } - catch (error) { failed(error, profileId); } + catch (error) { + if (plan && error instanceof IntegrationApiError && error.stalePlan) throw error; + failed(error, profileId); + if (plan) throw new Error(describeRefusal(t, error), { cause: error }); + } finally { // Even a refused writer may have durably saved desired sync preferences. resource.refresh(); @@ -66,6 +104,36 @@ export default function AsideProfilesPage({ apiBase, active = true }: { apiBase: setPending(null); } }; + const requestProfileMutation = async (profile: AsideProfileStatus, enabled: boolean) => { + if (pendingRef.current || planned) return; + const controller = new AbortController(); + const generation = previewGenerationRef.current + 1; + previewGenerationRef.current = generation; + previewAbortRef.current?.abort(); + previewAbortRef.current = controller; + setPlanned({ profile, enabled, plan: null, loading: true, failure: null }); + try { + const plan = await previewIntegrationMutation(apiBase, "aside", enabled ? "apply" : "disable", controller.signal, profile.profileId); + if (controller.signal.aborted || generation !== previewGenerationRef.current) return; + previewAbortRef.current = null; + setPlanned({ profile, enabled, plan, loading: false, failure: null }); + } catch (error) { + if (controller.signal.aborted || generation !== previewGenerationRef.current) return; + previewAbortRef.current = null; + if (isIntegrationPreviewUnavailable(error)) { + setPlanned(null); + resource.refresh(); + return; + } + setPlanned({ profile, enabled, plan: null, loading: false, failure: t("integrations.preview.failed") }); + } + }; + const closePlanned = () => { + previewGenerationRef.current += 1; + previewAbortRef.current?.abort(); + previewAbortRef.current = null; + setPlanned(null); + }; const sync = async () => { if (pendingRef.current) return; pendingRef.current = true; @@ -150,10 +218,10 @@ export default function AsideProfilesPage({ apiBase, active = true }: { apiBase:

    {needsUpdate && } - void mutate(!profile.enabled, profile.profileId)} + void requestProfileMutation(profile, !profile.enabled)} disabled={busy || loadError || locked} label={t("integrations.aside.toggle", { name })} />
    @@ -161,6 +229,20 @@ export default function AsideProfilesPage({ apiBase, active = true }: { apiBase: })} )} + {planned && ( + { + if (!plan) return; + await mutate(planned.enabled, planned.profile.profileId, plan); + setPlanned(null); + }} + /> + )} ); } diff --git a/gui/src/pages/integrations/ConsequenceDialog.tsx b/gui/src/pages/integrations/ConsequenceDialog.tsx index 94ec1ac4f3f..9ddaf95d871 100644 --- a/gui/src/pages/integrations/ConsequenceDialog.tsx +++ b/gui/src/pages/integrations/ConsequenceDialog.tsx @@ -1,6 +1,8 @@ import { useCallback, useEffect, useRef, useState, type ReactNode } from "react"; import { useT, type TKey } from "../../i18n/shared"; import { Notice } from "../../ui"; +import IntegrationPlanDetails, { type LabeledIntegrationPlan } from "./IntegrationPlanDetails"; +import { IntegrationApiError, type IntegrationMutationPlan } from "./integration-api"; export interface ConsequenceCopy { titleKey: TKey; @@ -21,49 +23,93 @@ function CopySlot({ copyKey, vars }: { copyKey: TKey; vars?: Record{before}{path}{after.join(path)}

    ; } +function planHasRollback(plan: IntegrationMutationPlan): boolean { + return plan.changes.some(change => change.kind === "snapshot" || change.kind === "journal"); +} + export default function ConsequenceDialog({ copy, + plan = null, + plans, + hasUnboundAction = false, + planStale = false, + planLoading = false, + planFailure = null, onConfirm, onClose, }: { copy: ConsequenceCopy; - onConfirm: () => Promise | void; + plan?: IntegrationMutationPlan | null; + plans?: readonly LabeledIntegrationPlan[]; + hasUnboundAction?: boolean; + planStale?: boolean; + planLoading?: boolean; + planFailure?: string | null; + onConfirm: (plan?: IntegrationMutationPlan) => Promise | void; onClose: () => void; }) { const t = useT(); const dialogRef = useRef(null); + const triggerRef = useRef(null); const [pending, setPending] = useState(false); const [failure, setFailure] = useState(null); + const [staleOverride, setStaleOverride] = useState<{ + sourceFingerprint: string | null; + plan: IntegrationMutationPlan; + } | null>(null); const titleId = "integration-consequence-dialog-title"; + const planRequired = plan !== null || planLoading || planFailure !== null || plans !== undefined; + const activePlan = staleOverride?.sourceFingerprint === (plan?.fingerprint ?? null) + ? staleOverride.plan + : plan; + const stale = staleOverride?.sourceFingerprint === (plan?.fingerprint ?? null); + const noActionableBulkTarget = plans !== undefined + && !hasUnboundAction + && !plans.some(item => item.plan.canApply); + const showUndo = !planRequired + || (activePlan ? planHasRollback(activePlan) : plans?.some(item => planHasRollback(item.plan)) === true); + const dismiss = useCallback(() => { + if (!pending) onClose(); + }, [onClose, pending]); useEffect(() => { const dialog = dialogRef.current; + const active = document.activeElement; + triggerRef.current = active?.tagName === "BUTTON" ? active as HTMLElement : null; if (dialog && !dialog.open) dialog.showModal(); - return () => { if (dialog?.open) dialog.close(); }; + return () => { + if (dialog?.open) dialog.close(); + if (triggerRef.current?.isConnected) triggerRef.current.focus?.(); + }; }, []); const handleCancel = useCallback((event: React.SyntheticEvent) => { event.preventDefault(); - if (!pending) onClose(); - }, [onClose, pending]); + dismiss(); + }, [dismiss]); const confirm = useCallback(async () => { if (pending) return; setPending(true); setFailure(null); try { - await onConfirm(); + await onConfirm(activePlan ?? undefined); } catch (error) { + if (error instanceof IntegrationApiError && error.stalePlan) { + setStaleOverride({ sourceFingerprint: plan?.fingerprint ?? null, plan: error.stalePlan }); + return; + } setFailure(error instanceof Error ? error.message : t("integrations.error.generic")); + } finally { setPending(false); } - }, [onConfirm, pending, t]); + }, [activePlan, onConfirm, pending, plan?.fingerprint, t]); const slots: ReactNode[] = [ , , - , ]; + if (showUndo) slots.push(); if (copy.sideEffectKey) { slots.push(); } @@ -73,6 +119,7 @@ export default function ConsequenceDialog({ ref={dialogRef} className="modal-overlay" aria-labelledby={titleId} + aria-busy={pending} onCancel={handleCancel} >
    {slots}
    +
    + {planLoading &&

    {t("integrations.preview.loading")}

    } + {pending &&

    {t("integrations.mutation.pending")}

    } + {(stale || planStale) && {t("integrations.preview.stale")}} + {planFailure && {planFailure}} +
    + {failure && {failure}}
    -
    diff --git a/gui/src/pages/integrations/FileIntegrationPage.tsx b/gui/src/pages/integrations/FileIntegrationPage.tsx index b1f8ec37374..3ee7db1b967 100644 --- a/gui/src/pages/integrations/FileIntegrationPage.tsx +++ b/gui/src/pages/integrations/FileIntegrationPage.tsx @@ -1,4 +1,4 @@ -import { useCallback, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import { useDataSurface } from "../../data-surface"; import { DataSurfaceSkeleton } from "../../components/data-surface"; import { useT, type TKey } from "../../i18n/shared"; @@ -14,12 +14,18 @@ import { describeRefusal } from "./refusal-copy"; import { loadIntegrationJournal, loadIntegrationState, + previewIntegrationMutation, toggleIntegration, + bindingFor, + IntegrationApiError, deleteJournalEntry, + isIntegrationPreviewUnavailable, isMissingJournalEntry, type FileIntegrationClientId, type IntegrationJournalRow, type IntegrationStatus, + type IntegrationMutationPlan, + type IntegrationPlanOperation, } from "./integration-api"; export type { FileIntegrationClientId }; @@ -45,6 +51,22 @@ function overwriteCopy(reason: string | undefined, path: string): ConsequenceCop }; } +const APPLY_COPY: ConsequenceCopy = { + titleKey: "integrations.dialog.apply.title", + changesKey: "integrations.dialog.apply.changes", + breakageKey: "integrations.dialog.apply.breakage", + undoKey: "integrations.dialog.apply.undo", + confirmKey: "integrations.dialog.apply.confirm", +}; + +const DISABLE_COPY: ConsequenceCopy = { + titleKey: "integrations.dialog.disable.title", + changesKey: "integrations.dialog.disable.changes", + breakageKey: "integrations.dialog.disable.breakage", + undoKey: "integrations.dialog.disable.undo", + confirmKey: "integrations.dialog.disable.confirm", +}; + const SEMANTICS_KEY: Record = { opencode: "integrations.semantics.opencode", pi: "integrations.semantics.pi", @@ -101,8 +123,19 @@ export default function FileIntegrationPage({ const [restoring, setRestoring] = useState(null); /* The row awaiting delete confirmation. */ const [deleting, setDeleting] = useState(null); - /* Open only while the user is confirming an overwrite. */ - const [overwriting, setOverwriting] = useState(false); + const [plannedMutation, setPlannedMutation] = useState<{ + operation: Exclude; + plan: IntegrationMutationPlan | null; + loading: boolean; + failure: string | null; + } | null>(null); + const previewAbortRef = useRef(null); + const previewGenerationRef = useRef(0); + + useEffect(() => () => { + previewGenerationRef.current += 1; + previewAbortRef.current?.abort(); + }, []); const fetchState = useCallback( (signal: AbortSignal) => loadIntegrationState(apiBase, client, signal, profileId), @@ -144,14 +177,54 @@ export default function FileIntegrationPage({ void historyResource.refresh(); }; - const mutate = async (enabled: boolean) => { + const requestMutation = async (operation: Exclude) => { + if (!status || pending || plannedMutation) return; + const controller = new AbortController(); + const generation = previewGenerationRef.current + 1; + previewGenerationRef.current = generation; + previewAbortRef.current?.abort(); + previewAbortRef.current = controller; + setPlannedMutation({ operation, plan: null, loading: true, failure: null }); + try { + const plan = await previewIntegrationMutation(apiBase, client, operation, controller.signal, profileId); + if (controller.signal.aborted || generation !== previewGenerationRef.current) return; + previewAbortRef.current = null; + setPlannedMutation({ operation, plan, loading: false, failure: null }); + } catch (error) { + if (controller.signal.aborted || generation !== previewGenerationRef.current) return; + previewAbortRef.current = null; + if (isIntegrationPreviewUnavailable(error)) { + setPlannedMutation(null); + refresh(); + return; + } + setPlannedMutation({ operation, plan: null, loading: false, failure: t("integrations.preview.failed") }); + } + }; + + const closePlannedMutation = () => { + previewGenerationRef.current += 1; + previewAbortRef.current?.abort(); + previewAbortRef.current = null; + setPlannedMutation(null); + }; + + const mutate = async (plan: IntegrationMutationPlan) => { if (!status || pending) return; setPending(true); setFailure(null); try { - await toggleIntegration(apiBase, client, enabled, undefined, undefined, profileId); + await toggleIntegration(apiBase, client, { + enabled: plan.operation !== "disable", + overwriteConflict: plan.operation === "overwrite", + profileId, + binding: bindingFor(plan), + }); + setPlannedMutation(null); } catch (error) { - setFailure(describeRefusal(t, error)); + refresh(); + if (error instanceof IntegrationApiError && error.stalePlan) throw error; + throw new Error(describeRefusal(t, error), { cause: error }); } finally { refresh(); setPending(false); @@ -167,19 +240,6 @@ export default function FileIntegrationPage({ * Errors are NOT swallowed here -- they propagate so ConsequenceDialog can * render them inside the dialog, where the user still has the cancel button. */ - const overwrite = async () => { - if (!status) return; - setFailure(null); - try { - await toggleIntegration(apiBase, client, true, undefined, true, profileId); - refresh(); - } catch (error) { - setFailure(describeRefusal(t, error)); - refresh(); - throw error; - } - }; - /* * The switch means exactly what its label says. * @@ -189,7 +249,7 @@ export default function FileIntegrationPage({ * to remove the block; updating a stale block is a separate action with its * own button below. */ - const toggle = () => void mutate(!(status && (profileId !== undefined ? status.enabled : (status.state === "current" || status.state === "stale")))); + const toggle = () => void requestMutation(enabled ? "disable" : "apply"); if (!status) { return ( @@ -241,7 +301,7 @@ export default function FileIntegrationPage({ @@ -617,7 +779,7 @@ export default function IntegrationsOverview({ onOpen={() => navigateHash(row.hash)} onToggle={row.toggle ? () => requestToggle(row, !(row.toggleOn ?? row.applied)) : null} onOverwrite={row.status !== null && row.status.state === "conflict" && row.installed - ? () => setPendingOverwrite(row) + ? () => void requestFilePlan(row, "overwrite") : null} /> ))} @@ -723,25 +885,41 @@ export default function IntegrationsOverview({ }} /> )} - {pendingOverwrite && pendingOverwrite.status && ( + {plannedCard && plannedCard.row.status && ( setPendingOverwrite(null)} - onConfirm={async () => { - await overwriteCard(pendingOverwrite); - setPendingOverwrite(null); + vars: { path: plannedCard.row.status.configPath }, + } : plannedCard.operation === "disable" ? FILE_DISABLE_COPY : FILE_APPLY_COPY} + plan={plannedCard.plan} + planLoading={plannedCard.loading} + planFailure={plannedCard.failure} + onClose={closePlannedCard} + onConfirm={async plan => { + if (!plan) return; + await toggleCard(plannedCard.row, plan.operation !== "disable", plan); + setPlannedCard(null); }} /> )} + {bulkPlans && ( + item.plan === null)} + planStale={bulkPlans.stale} + planLoading={bulkPlans.loading} + planFailure={bulkPlans.failure} + onClose={closeBulkPlans} + onConfirm={async () => { await disableAll(bulkPlans); }} + /> + )} ); } diff --git a/gui/src/pages/integrations/RestoreDialog.tsx b/gui/src/pages/integrations/RestoreDialog.tsx index 93352bf3c55..fea64673d7a 100644 --- a/gui/src/pages/integrations/RestoreDialog.tsx +++ b/gui/src/pages/integrations/RestoreDialog.tsx @@ -1,8 +1,22 @@ import { useCallback, useEffect, useRef, useState } from "react"; import { useT } from "../../i18n/shared"; import { Notice } from "../../ui"; -import { describeRefusal, refusalOf } from "./refusal-copy"; -import { restoreIntegration, type IntegrationJournalRow } from "./integration-api"; +import { describeRefusal } from "./refusal-copy"; +import IntegrationPlanDetails from "./IntegrationPlanDetails"; +import { + bindingFor, + IntegrationApiError, + isIntegrationPreviewUnavailable, + previewIntegrationRestore, + restoreIntegration, + type IntegrationJournalRow, + type IntegrationMutationPlan, +} from "./integration-api"; + +interface BoundRestorePlan { + plan: IntegrationMutationPlan; + confirmDrift: boolean; +} /** * Restore confirmation, including the drift second step. @@ -38,9 +52,36 @@ export default function RestoreDialog({ const restoreFocusRef = useRef(null); const restoreFallbackRef = useRef(null); const restoredRef = useRef(false); - const [drift, setDrift] = useState(false); + const onCloseRef = useRef(onClose); + const onRestoredRef = useRef(onRestored); + const onReconcileRef = useRef(onReconcile); + const tRef = useRef(t); + const previewAbortRef = useRef(null); + const previewGenerationRef = useRef(0); + const [boundPlan, setBoundPlan] = useState(null); + const [previewPending, setPreviewPending] = useState(true); + const [stale, setStale] = useState(false); const [pending, setPending] = useState(false); - const [failure, setFailure] = useState(null); + const [previewFailure, setPreviewFailure] = useState(null); + const [mutationFailure, setMutationFailure] = useState(null); + const scopedProfileId = row.clientId === "aside" ? profileId ?? row.profileId : undefined; + const plan = boundPlan?.plan ?? null; + const drift = plan?.foreignEdit === "drift"; + + useEffect(() => { + onCloseRef.current = onClose; + onRestoredRef.current = onRestored; + onReconcileRef.current = onReconcile; + tRef.current = t; + }, [onClose, onReconcile, onRestored, t]); + + const dismiss = useCallback(() => { + if (pending) return; + previewGenerationRef.current += 1; + previewAbortRef.current?.abort(); + previewAbortRef.current = null; + onCloseRef.current(); + }, [pending]); useEffect(() => { const dialog = dialogRef.current; @@ -86,33 +127,116 @@ export default function RestoreDialog({ }; }, []); + const loadPreview = useCallback(async () => { + const controller = new AbortController(); + const generation = previewGenerationRef.current + 1; + previewGenerationRef.current = generation; + previewAbortRef.current?.abort(); + previewAbortRef.current = controller; + setPreviewPending(true); + setPreviewFailure(null); + setMutationFailure(null); + setBoundPlan(null); + setStale(false); + try { + let confirmDrift = false; + let next = await previewIntegrationRestore(apiBase, row.opId, confirmDrift, controller.signal, scopedProfileId); + if (next.refusalReason === "drift_requires_confirm") { + confirmDrift = true; + next = await previewIntegrationRestore(apiBase, row.opId, confirmDrift, controller.signal, scopedProfileId); + } + if (controller.signal.aborted || generation !== previewGenerationRef.current) return; + setBoundPlan({ plan: next, confirmDrift }); + } catch (error) { + if (controller.signal.aborted || generation !== previewGenerationRef.current) return; + if (isIntegrationPreviewUnavailable(error)) { + onReconcileRef.current?.(); + onCloseRef.current(); + return; + } + setPreviewFailure(tRef.current("integrations.preview.failed")); + } finally { + if (!controller.signal.aborted && generation === previewGenerationRef.current) { + previewAbortRef.current = null; + setPreviewPending(false); + } + } + }, [apiBase, row.opId, scopedProfileId]); + + useEffect(() => { + const timeout = window.setTimeout(() => { void loadPreview(); }, 0); + return () => { + window.clearTimeout(timeout); + previewGenerationRef.current += 1; + previewAbortRef.current?.abort(); + previewAbortRef.current = null; + }; + }, [loadPreview]); + const handleCancel = useCallback((event: React.SyntheticEvent) => { event.preventDefault(); - if (!pending) onClose(); - }, [onClose, pending]); + dismiss(); + }, [dismiss]); const submit = async () => { - if (pending) return; + if (pending || previewPending || !boundPlan || !boundPlan.plan.canApply) return; + const attemptedConfirmDrift = boundPlan.confirmDrift; setPending(true); - setFailure(null); + setMutationFailure(null); try { - await restoreIntegration(apiBase, row.opId, drift, undefined, row.clientId === "aside" ? profileId ?? row.profileId : undefined); + await restoreIntegration(apiBase, { + opId: row.opId, + confirmDrift: attemptedConfirmDrift, + profileId: scopedProfileId, + binding: bindingFor(boundPlan.plan), + }); restoredRef.current = true; - onRestored(); - onClose(); + onRestoredRef.current(); + onCloseRef.current(); } catch (error) { // Aside may have saved target intent before the writer refused. Reconcile // without closing the dialog or announcing a successful restore. - if (row.clientId === "aside") onReconcile?.(); - if (refusalOf(error)?.reason === "drift_requires_confirm") { - // Not a failure: the user has not been asked yet. Ask now. - setDrift(true); + if (row.clientId === "aside") onReconcileRef.current?.(); + if (error instanceof IntegrationApiError && error.stalePlan) { + let fresh = error.stalePlan; + let freshConfirmDrift = attemptedConfirmDrift; setPending(false); + try { + if (fresh.refusalReason === "drift_requires_confirm") { + const controller = new AbortController(); + const generation = previewGenerationRef.current + 1; + previewGenerationRef.current = generation; + previewAbortRef.current?.abort(); + previewAbortRef.current = controller; + setPreviewPending(true); + freshConfirmDrift = true; + try { + fresh = await previewIntegrationRestore(apiBase, row.opId, freshConfirmDrift, controller.signal, scopedProfileId); + } finally { + if (!controller.signal.aborted && generation === previewGenerationRef.current) { + previewAbortRef.current = null; + setPreviewPending(false); + } + } + if (controller.signal.aborted || generation !== previewGenerationRef.current) return; + } + } catch (previewError) { + if (previewError instanceof Error && previewError.name === "AbortError") return; + if (isIntegrationPreviewUnavailable(previewError)) { + onReconcileRef.current?.(); + onCloseRef.current(); + return; + } + setPreviewFailure(tRef.current("integrations.preview.failed")); + return; + } + setBoundPlan({ plan: fresh, confirmDrift: freshConfirmDrift }); + setStale(true); return; } // Shared formatter so a residual write — compensation itself failed, the // file may be intermediate — is disclosed here too, not only its path. - setFailure(describeRefusal(t, error)); + setMutationFailure(describeRefusal(t, error)); setPending(false); } }; @@ -122,6 +246,7 @@ export default function RestoreDialog({ ref={dialogRef} className="modal-overlay" aria-labelledby="integration-restore-title" + aria-busy={pending} onCancel={handleCancel} > -