From 1e89dc9deea6f43fd3091ac1a5bc4bf501ff43f7 Mon Sep 17 00:00:00 2001 From: JUN <243035832+lidge-jun@users.noreply.github.com> Date: Thu, 29 Oct 2026 03:02:37 +0900 Subject: [PATCH] test: partition Windows apply coverage and refresh shard weights --- scripts/ci/test-durations.windows.tsv | 726 ++++++++++-------- .../test-layout/layout-codex-collision.json | 3 + structure/codex-cli-update.md | 13 +- ...x-cli-update-windows-apply-install.test.ts | 113 +++ ...-cli-update-windows-apply-outcomes.test.ts | 112 +++ ...ex-cli-update-windows-apply-shared.test.ts | 139 ++++ .../codex-cli-update-windows-apply.test.ts | 448 +---------- tests/fixtures/test-layout-expected.json | 2 +- .../codex-cli-windows-apply-fixture.ts | 114 +++ 9 files changed, 901 insertions(+), 769 deletions(-) create mode 100644 tests/codex-integration/codex-cli-update-windows-apply-install.test.ts create mode 100644 tests/codex-integration/codex-cli-update-windows-apply-outcomes.test.ts create mode 100644 tests/codex-integration/codex-cli-update-windows-apply-shared.test.ts create mode 100644 tests/helpers/codex-cli-windows-apply-fixture.ts diff --git a/scripts/ci/test-durations.windows.tsv b/scripts/ci/test-durations.windows.tsv index a7af543944f..75e6467cc47 100644 --- a/scripts/ci/test-durations.windows.tsv +++ b/scripts/ci/test-durations.windows.tsv @@ -1,10 +1,10 @@ # Per-file Bun test durations in milliseconds, read from hosted CI job logs. # Consumed by scripts/ci/run-bun-test-batches.sh to balance shards; a file without a row weighs the median. # Regenerate with scripts/ci/test-durations.ts (usage in its header); do not edit by hand. -# Source: run 38250055508 (dev dc45bb2ca9, lane=all), windows 1/9-9/9 +# Source: run 38250055508 Windows baseline; run 40727740334 Windows 3/9 batches 1-16 and 5/9 batches 1-55 (unfinished batches/attribution excluded); four apply partitions estimated at 2x local Windows wall time, Bun 1.4.4 (63.68/92.58/147.45/122.77s); refresh estimates from next complete hosted Windows run 7665 tests/adapters/abort-race.test.ts -3710 tests/adapters/adapter-buffered-tool-conformance.test.ts -2560 tests/adapters/adapter-error-inline.test.ts +2527 tests/adapters/adapter-buffered-tool-conformance.test.ts +189 tests/adapters/adapter-error-inline.test.ts 6010 tests/adapters/adapter-inner-send-budget-wiring.test.ts 4077 tests/adapters/adapter-inner-send-budget.test.ts 2297 tests/adapters/adapter-input-media-guard.test.ts @@ -12,9 +12,9 @@ 2536 tests/adapters/adapter-tool-conformance.test.ts 127 tests/adapters/adapter-usage.test.ts 15352 tests/adapters/anthropic/anthropic-429-policy.test.ts -94 tests/adapters/anthropic/anthropic-account-metadata.test.ts -6105 tests/adapters/anthropic/anthropic-account-pause-outbound.test.ts -18837 tests/adapters/anthropic/anthropic-account-pause.test.ts +96 tests/adapters/anthropic/anthropic-account-metadata.test.ts +1635 tests/adapters/anthropic/anthropic-account-pause-outbound.test.ts +34616 tests/adapters/anthropic/anthropic-account-pause.test.ts 33903 tests/adapters/anthropic/anthropic-account-pool.test.ts 31891 tests/adapters/anthropic/anthropic-account-threshold.test.ts 128 tests/adapters/anthropic/anthropic-agentrouter-language-framing.test.ts @@ -25,12 +25,12 @@ 2667 tests/adapters/anthropic/anthropic-compatible-stream.test.ts 2805 tests/adapters/anthropic/anthropic-cooldown-recovery.test.ts 143 tests/adapters/anthropic/anthropic-empty-content.test.ts -192 tests/adapters/anthropic/anthropic-eof-tolerance.test.ts -2314 tests/adapters/anthropic/anthropic-error-body.test.ts -189 tests/adapters/anthropic/anthropic-error-stop-reason.test.ts -4020 tests/adapters/anthropic/anthropic-fast-opt-in.test.ts +158 tests/adapters/anthropic/anthropic-eof-tolerance.test.ts +3156 tests/adapters/anthropic/anthropic-error-body.test.ts +98 tests/adapters/anthropic/anthropic-error-stop-reason.test.ts +4266 tests/adapters/anthropic/anthropic-fast-opt-in.test.ts 175 tests/adapters/anthropic/anthropic-fast-speed.test.ts -145 tests/adapters/anthropic/anthropic-haiku-5-5-contract.test.ts +96 tests/adapters/anthropic/anthropic-haiku-5-5-contract.test.ts 144 tests/adapters/anthropic/anthropic-hardening.test.ts 219 tests/adapters/anthropic/anthropic-image-guard.test.ts 3641 tests/adapters/anthropic/anthropic-image-normalize.test.ts @@ -43,47 +43,51 @@ 174 tests/adapters/anthropic/anthropic-message-stop-termination.test.ts 129 tests/adapters/anthropic/anthropic-messages-passthrough-oauth.test.ts 142 tests/adapters/anthropic/anthropic-messages-passthrough.test.ts -28681 tests/adapters/anthropic/anthropic-model-routes.test.ts -12323 tests/adapters/anthropic/anthropic-model-weekly-admission.test.ts +51479 tests/adapters/anthropic/anthropic-model-routes.test.ts +15779 tests/adapters/anthropic/anthropic-model-weekly-admission.test.ts 159 tests/adapters/anthropic/anthropic-opaque-strip.test.ts 191 tests/adapters/anthropic/anthropic-output-maxima.test.ts -143 tests/adapters/anthropic/anthropic-parallel-tool-disable.test.ts +80 tests/adapters/anthropic/anthropic-parallel-tool-disable.test.ts 288 tests/adapters/anthropic/anthropic-pool-toggle-copy.test.ts +7889 tests/adapters/anthropic/anthropic-pool-usage-limit.test.ts 19193 tests/adapters/anthropic/anthropic-quota-dispatch.test.ts 8049 tests/adapters/anthropic/anthropic-ratelimit-headers.test.ts -207 tests/adapters/anthropic/anthropic-reasoning.test.ts +208 tests/adapters/anthropic/anthropic-reasoning.test.ts +78 tests/adapters/anthropic/anthropic-replay.test.ts 1821 tests/adapters/anthropic/anthropic-reset-grants.test.ts 12330 tests/adapters/anthropic/anthropic-revoked-token-boundaries.test.ts -5885 tests/adapters/anthropic/anthropic-revoked-token-continuation.test.ts +5856 tests/adapters/anthropic/anthropic-revoked-token-continuation.test.ts 11924 tests/adapters/anthropic/anthropic-revoked-token-sidecars.test.ts 48338 tests/adapters/anthropic/anthropic-revoked-token.test.ts 855 tests/adapters/anthropic/anthropic-sidecar-account-failover.test.ts -160 tests/adapters/anthropic/anthropic-sonnet-5-5-contract.test.ts +112 tests/adapters/anthropic/anthropic-sonnet-5-5-contract.test.ts 130 tests/adapters/anthropic/anthropic-stream-hardening.test.ts 111 tests/adapters/anthropic/anthropic-tail-guard.test.ts 204 tests/adapters/anthropic/anthropic-thinking-signature.test.ts 128 tests/adapters/anthropic/anthropic-thinking-usage.test.ts 117 tests/adapters/anthropic/anthropic-tool-call-id.test.ts -176 tests/adapters/anthropic/anthropic-tool-declaration-constraints.test.ts +334 tests/adapters/anthropic/anthropic-tool-declaration-constraints.test.ts 196 tests/adapters/anthropic/anthropic-tool-schema.test.ts 10713 tests/adapters/anthropic/anthropic2-fast-parity.test.ts 173 tests/adapters/bridge-legacy-shell-normalization.test.ts 3786 tests/adapters/bridge-lifecycle.test.ts -779 tests/adapters/bridge-nonstreaming-terminal.test.ts +464 tests/adapters/bridge-nonstreaming-terminal.test.ts 369 tests/adapters/bridge-raw-reasoning-hidden.test.ts 343 tests/adapters/bridge-reasoning-replay-batch.test.ts 206 tests/adapters/bridge-stall.test.ts -127 tests/adapters/bridge-terminal-singleness.test.ts +93 tests/adapters/bridge-terminal-singleness.test.ts 479 tests/adapters/bridge.test.ts 190 tests/adapters/buffered-response-shape-guards.test.ts -309 tests/adapters/coding-agent-tool-result-images.test.ts +79 tests/adapters/coding-agent-tool-result-images.test.ts 3031 tests/adapters/empty-tool-output-annotation.test.ts 237 tests/adapters/exec-tool-result-normalize.test.ts +315 tests/adapters/fix-tool-number-preservation.test.ts 156 tests/adapters/google/antigravity-baseurl-override.test.ts 445 tests/adapters/google/antigravity-discovered-families.test.ts 143 tests/adapters/google/antigravity-refusal.test.ts 418 tests/adapters/google/antigravity-static-catalog.test.ts -950 tests/adapters/google/gcp-adc.test.ts +1092 tests/adapters/google/gcp-adc.test.ts +13105 tests/adapters/google/gcp-credential-boundary.test.ts 176 tests/adapters/google/gemini-37-flash-migration.test.ts 191 tests/adapters/google/gemini-web-search.test.ts 223 tests/adapters/google/google-adapter.test.ts @@ -96,22 +100,23 @@ 332 tests/adapters/google/google-errors.test.ts 161 tests/adapters/google/google-hardening.test.ts 781 tests/adapters/google/google-models-listing.test.ts -130 tests/adapters/google/google-output-clamp.test.ts +80 tests/adapters/google/google-output-clamp.test.ts 143 tests/adapters/google/google-provider-metadata-roundtrip.test.ts -508 tests/adapters/google/google-signature-history-roundtrip.test.ts +317 tests/adapters/google/google-signature-history-roundtrip.test.ts +111 tests/adapters/google/google-stream-fragmentation.test.ts 112 tests/adapters/google/google-strict-tool-validated-mode.test.ts 111 tests/adapters/google/google-structured-output.test.ts 138 tests/adapters/google/google-tool-result-adjacency.test.ts -156 tests/adapters/google/google-tool-schema-contract.test.ts +158 tests/adapters/google/google-tool-schema-contract.test.ts 191 tests/adapters/google/google-tool-schema.test.ts 3304 tests/adapters/google/google-vertex-http.test.ts 126 tests/adapters/google/google-vertex-stream.test.ts 97 tests/adapters/google/google-vertex-thought-signature.test.ts 127 tests/adapters/google/google-wire-compiler.test.ts 113 tests/adapters/google/google-wire-shape.test.ts -174 tests/adapters/google/vertex-catalog.test.ts +175 tests/adapters/google/vertex-catalog.test.ts 518 tests/adapters/identity-neutralize.test.ts -931 tests/adapters/identity-subagent.test.ts +809 tests/adapters/identity-subagent.test.ts 13111 tests/adapters/key-failover.test.ts 206 tests/adapters/openai/inline-think-boundaries.test.ts 10329 tests/adapters/openai/openai-api-virtual-models.test.ts @@ -120,10 +125,11 @@ 159 tests/adapters/openai/openai-chat-developer-position.test.ts 174 tests/adapters/openai/openai-chat-eof.test.ts 158 tests/adapters/openai/openai-chat-glm-summary.test.ts -336 tests/adapters/openai/openai-chat-hardening.test.ts +555 tests/adapters/openai/openai-chat-hardening.test.ts 5481 tests/adapters/openai/openai-chat-image-normalization.test.ts -140 tests/adapters/openai/openai-chat-inline-think-tags.test.ts +125 tests/adapters/openai/openai-chat-inline-think-tags.test.ts 142 tests/adapters/openai/openai-chat-invalid-tool-call-diagnostics.test.ts +128 tests/adapters/openai/openai-chat-mistral-content.test.ts 223 tests/adapters/openai/openai-chat-model-suffix.test.ts 1627 tests/adapters/openai/openai-chat-native-policy.test.ts 191 tests/adapters/openai/openai-chat-parallel-stream.test.ts @@ -134,11 +140,11 @@ 144 tests/adapters/openai/openai-chat-serialized-tool-call-content.test.ts 285 tests/adapters/openai/openai-chat-serialized-tool-call-hold-bound.test.ts 269 tests/adapters/openai/openai-chat-serialized-tool-call-scaling.test.ts -190 tests/adapters/openai/openai-chat-serialized-tool-call-think.test.ts +95 tests/adapters/openai/openai-chat-serialized-tool-call-think.test.ts 286 tests/adapters/openai/openai-chat-system-order.test.ts 143 tests/adapters/openai/openai-chat-tool-call-id-remint.test.ts 157 tests/adapters/openai/openai-chat-tool-result-images.test.ts -111 tests/adapters/openai/openai-chat-url.test.ts +80 tests/adapters/openai/openai-chat-url.test.ts 143 tests/adapters/openai/openai-chat-video-part.test.ts 192 tests/adapters/openai/openai-empty-assistant-history.test.ts 6501 tests/adapters/openai/openai-provider-option-e2e.test.ts @@ -147,9 +153,10 @@ 318 tests/adapters/openai/openai-provider-option-tooling.test.ts 125 tests/adapters/openai/openai-provider-option.test.ts 311 tests/adapters/physical-send.test.ts -218 tests/adapters/reasoning-replay-identity.test.ts +271 tests/adapters/qoder-spawn-readmission.test.ts +281 tests/adapters/reasoning-replay-identity.test.ts 2406 tests/adapters/reasoning-replay-robustness.test.ts -448 tests/adapters/routed-agent-messages.test.ts +483 tests/adapters/routed-agent-messages.test.ts 156 tests/adapters/run-turn-queue.test.ts 1702 tests/adapters/terminal-continuation-owner-rotation.test.ts 98 tests/adapters/tool-argument-integers.test.ts @@ -159,6 +166,10 @@ 359 tests/adapters/translator-budget-lifetime.test.ts 3584 tests/adapters/translator-budget.test.ts 127 tests/adapters/upstream-http-error.test.ts +1571 tests/advisor/advisor-adaptive.test.ts +697 tests/advisor/advisor-core-boundary.test.ts +302 tests/advisor/advisor-internal-authority.test.ts +191 tests/advisor/advisor-state.test.ts 127 tests/ci-workflows/assert-mergeable-review.test.ts 368 tests/ci-workflows/brand-favicons.test.ts 364 tests/ci-workflows/build-desktop-icon-set.test.ts @@ -167,53 +178,54 @@ 790 tests/ci-workflows/bun-runtime.test.ts 144 tests/ci-workflows/ci-bun-crash-classifier.test.ts 127 tests/ci-workflows/ci-concurrency-groups.test.ts -143 tests/ci-workflows/ci-crash-disposition.test.ts +78 tests/ci-workflows/ci-crash-disposition.test.ts 3042 tests/ci-workflows/ci-gui-typecheck-gate.test.ts 111 tests/ci-workflows/ci-privacy-gate.test.ts -567 tests/ci-workflows/ci-review-lanes.test.ts +302 tests/ci-workflows/ci-review-lanes.test.ts 1411 tests/ci-workflows/ci-scope-gaps.test.ts 171 tests/ci-workflows/ci-scope-reduction.test.ts 159 tests/ci-workflows/ci-shard-balance.test.ts 94 tests/ci-workflows/ci-structure-gate.test.ts -1226 tests/ci-workflows/ci-workflows.test.ts -159 tests/ci-workflows/cleanup-orphaned-workflows.test.ts -142 tests/ci-workflows/closed-pr-branch-cleanup.test.ts +248 tests/ci-workflows/ci-test-lane.test.ts +1029 tests/ci-workflows/ci-workflows.test.ts +79 tests/ci-workflows/cleanup-orphaned-workflows.test.ts +82 tests/ci-workflows/closed-pr-branch-cleanup.test.ts 7676 tests/ci-workflows/cold-spawn-warmup.test.ts 435 tests/ci-workflows/compatibility-version.test.ts 147 tests/ci-workflows/docs-429-failover-claims.test.ts 144 tests/ci-workflows/docs-bun-source-requirement.test.ts 161 tests/ci-workflows/docs-developer-role-policy.test.ts 343 tests/ci-workflows/docs-gjc-reasoning-export.test.ts -127 tests/ci-workflows/docs-gui-screenshot-policy.test.ts -380 tests/ci-workflows/docs-link-targets.test.ts +95 tests/ci-workflows/docs-gui-screenshot-policy.test.ts +413 tests/ci-workflows/docs-link-targets.test.ts 159 tests/ci-workflows/docs-provider-billing-claims.test.ts 186 tests/ci-workflows/docs-provider-discovery-limits.test.ts 163 tests/ci-workflows/docs-provider-preset-counts.test.ts 272 tests/ci-workflows/docs-readme-memory-inventory.test.ts -144 tests/ci-workflows/docs-readme-translation-parity.test.ts +114 tests/ci-workflows/docs-readme-translation-parity.test.ts 162 tests/ci-workflows/docs-remote-hub-claims.test.ts 304 tests/ci-workflows/dsh-path-contract.test.ts 647 tests/ci-workflows/dsh-rc6-compat-script.test.ts -1103 tests/ci-workflows/dsh-writer-lock.test.ts +696 tests/ci-workflows/dsh-writer-lock.test.ts 300 tests/ci-workflows/exhaustive-deps-suppression.test.ts -410 tests/ci-workflows/file-size-ratchet.test.ts +556 tests/ci-workflows/file-size-ratchet.test.ts 332 tests/ci-workflows/fixture-dir-uniqueness.test.ts 142 tests/ci-workflows/fixture-teardown-helper.test.ts 175 tests/ci-workflows/install-scripts.test.ts -177 tests/ci-workflows/installed-gate-drivers.test.ts +275 tests/ci-workflows/installed-gate-drivers.test.ts 155 tests/ci-workflows/keyring-smoke.test.ts 137 tests/ci-workflows/linux-desktop-packaged-ci.test.ts 95 tests/ci-workflows/linux-desktop-packaged-e2e.test.ts -162 tests/ci-workflows/macos-serial-lanes.test.ts +232 tests/ci-workflows/macos-serial-lanes.test.ts 3855 tests/ci-workflows/package-tree-fenced-restart.test.ts 4263 tests/ci-workflows/package-tree-integrity.test.ts 334 tests/ci-workflows/package-tree-restart-ownership.test.ts 356 tests/ci-workflows/package-tree-retarget.test.ts 158 tests/ci-workflows/pr-readiness-reattest.test.ts -122 tests/ci-workflows/privacy-scan-asset-names.test.ts -154 tests/ci-workflows/privacy-scan-meta-key.test.ts +74 tests/ci-workflows/privacy-scan-asset-names.test.ts +96 tests/ci-workflows/privacy-scan-meta-key.test.ts 202 tests/ci-workflows/privacy-scan-ssh-endpoint.test.ts -442 tests/ci-workflows/release-desktop-scripts.test.ts +236 tests/ci-workflows/release-desktop-scripts.test.ts 40759 tests/ci-workflows/release-helper.test.ts 361 tests/ci-workflows/release-notes.test.ts 144 tests/ci-workflows/release-outcome-report.test.ts @@ -229,17 +241,18 @@ 428 tests/ci-workflows/skill-ocx-workflows.test.ts 155 tests/ci-workflows/skill-ocx.test.ts 2809 tests/ci-workflows/structure-ssot.test.ts +3329 tests/ci-workflows/test-home-guard-unpreloaded.test.ts 59749 tests/ci-workflows/test-home-guard.test.ts 222 tests/ci-workflows/test-runner-bun.test.ts -22500 tests/ci-workflows/test-runner.test.ts +31432 tests/ci-workflows/test-runner.test.ts 128 tests/ci-workflows/test-sandbox-cleanup.test.ts 145 tests/ci-workflows/test-temp-quarantine.test.ts 129 tests/ci-workflows/version-line.test.ts 192 tests/ci-workflows/warmup-registration.test.ts 322 tests/ci-workflows/zz-ci-api-usage-isolation.test.ts -111 tests/ci-workflows/zz-ci-storage-policy-isolation.test.ts +94 tests/ci-workflows/zz-ci-storage-policy-isolation.test.ts 207 tests/ci-workflows/zz-pr-coderabbit-readiness-revalidation.test.ts -46703 tests/claude-integration/anthropic2-native-routing.test.ts +72575 tests/claude-integration/anthropic2-native-routing.test.ts 13495 tests/claude-integration/claude-529-mapping.test.ts 269 tests/claude-integration/claude-agent-startup-sync.test.ts 205 tests/claude-integration/claude-agents-inject-client.test.ts @@ -250,13 +263,14 @@ 123 tests/claude-integration/claude-authmode-migration.test.ts 2106 tests/claude-integration/claude-cli-picker-surface.test.ts 850 tests/claude-integration/claude-cli-picker.test.ts -224 tests/claude-integration/claude-cli.test.ts +190 tests/claude-integration/claude-cli.test.ts +17682 tests/claude-integration/claude-client-refusal-status.test.ts 728 tests/claude-integration/claude-code-thought-signature-scope.test.ts -288 tests/claude-integration/claude-compatibility.test.ts +128 tests/claude-integration/claude-compatibility.test.ts 1538 tests/claude-integration/claude-config-home-isolation.test.ts -269 tests/claude-integration/claude-context-accounting.test.ts +412 tests/claude-integration/claude-context-accounting.test.ts 145 tests/claude-integration/claude-context-windows.test.ts -251 tests/claude-integration/claude-desktop-1m.test.ts +206 tests/claude-integration/claude-desktop-1m.test.ts 33007 tests/claude-integration/claude-desktop-cli.test.ts 4768 tests/claude-integration/claude-desktop-config-path.test.ts 5743 tests/claude-integration/claude-desktop-discovery.test.ts @@ -266,46 +280,48 @@ 172 tests/claude-integration/claude-desktop-native-context.test.ts 5799 tests/claude-integration/claude-desktop-picker-profile.test.ts 25728 tests/claude-integration/claude-desktop-picker-routes.test.ts -3490 tests/claude-integration/claude-desktop-picker.test.ts +6417 tests/claude-integration/claude-desktop-picker.test.ts 127 tests/claude-integration/claude-desktop-policy.test.ts -38272 tests/claude-integration/claude-desktop-remote-hub.test.ts +38392 tests/claude-integration/claude-desktop-remote-hub.test.ts 437 tests/claude-integration/claude-desktop-system-proxy.test.ts 2854 tests/claude-integration/claude-devin-output-order.test.ts 348 tests/claude-integration/claude-dotenv-provenance-transport.test.ts -2826 tests/claude-integration/claude-estimate-projection.test.ts +3333 tests/claude-integration/claude-estimate-projection.test.ts 21085 tests/claude-integration/claude-first-party-agent-sync.test.ts -41676 tests/claude-integration/claude-first-party-union.test.ts -175 tests/claude-integration/claude-gateway-cache.test.ts -1938 tests/claude-integration/claude-inbound-cache-stabilize.test.ts +50038 tests/claude-integration/claude-first-party-union.test.ts +160 tests/claude-integration/claude-gateway-cache.test.ts +3298 tests/claude-integration/claude-inbound-cache-stabilize.test.ts 123 tests/claude-integration/claude-inbound-debug.test.ts -157 tests/claude-integration/claude-inbound-token-footer.test.ts +158 tests/claude-integration/claude-inbound-token-footer.test.ts 175 tests/claude-integration/claude-inbound-tool-reference.test.ts -223 tests/claude-integration/claude-inbound.test.ts +206 tests/claude-integration/claude-inbound.test.ts +5506 tests/claude-integration/claude-intercept-acl-barrier.test.ts 159 tests/claude-integration/claude-intercept-cleanup.test.ts 389 tests/claude-integration/claude-intercept-client-class.test.ts 23891 tests/claude-integration/claude-intercept-local-ca-files.test.ts 428 tests/claude-integration/claude-intercept-local-ca-windows.test.ts 18234 tests/claude-integration/claude-intercept-local-ca.test.ts -1286 tests/claude-integration/claude-intercept-model-bindings.test.ts -4732 tests/claude-integration/claude-intercept-no-proxy.test.ts +1536 tests/claude-integration/claude-intercept-model-bindings.test.ts +4414 tests/claude-integration/claude-intercept-no-proxy.test.ts 14616 tests/claude-integration/claude-intercept-on-demand.test.ts 7586 tests/claude-integration/claude-intercept-proxy-auth.test.ts 314 tests/claude-integration/claude-intercept-proxy.test.ts 1295 tests/claude-integration/claude-intercept-settings.test.ts -142 tests/claude-integration/claude-long-context-eligibility.test.ts +176 tests/claude-integration/claude-long-context-eligibility.test.ts 99359 tests/claude-integration/claude-management-api.test.ts 43995 tests/claude-integration/claude-messages-endpoint.test.ts -4221 tests/claude-integration/claude-messages-thread.test.ts +4651 tests/claude-integration/claude-messages-thread.test.ts 747 tests/claude-integration/claude-model-info.test.ts 15392 tests/claude-integration/claude-models-discovery.test.ts 6467 tests/claude-integration/claude-native-affinity.test.ts +5141 tests/claude-integration/claude-native-fast-1m-ingress.test.ts 67983 tests/claude-integration/claude-native-passthrough.test.ts 347 tests/claude-integration/claude-native-rate-limit-headers.test.ts 746 tests/claude-integration/claude-native-reasoning-continuity.test.ts 984 tests/claude-integration/claude-native-reasoning-provenance.test.ts -16457 tests/claude-integration/claude-outbound.test.ts +30628 tests/claude-integration/claude-outbound.test.ts 208 tests/claude-integration/claude-output-schema-strict.test.ts -352 tests/claude-integration/claude-picker-bootstrap.test.ts +381 tests/claude-integration/claude-picker-bootstrap.test.ts 11408 tests/claude-integration/claude-picker-ca-store.test.ts 6570 tests/claude-integration/claude-picker-ca.test.ts 1184 tests/claude-integration/claude-picker-listener.test.ts @@ -314,18 +330,20 @@ 27450 tests/claude-integration/claude-picker-runtime.test.ts 26190 tests/claude-integration/claude-picker-startup.test.ts 188 tests/claude-integration/claude-picker-trust.test.ts -1006 tests/claude-integration/claude-picker-upload.test.ts +4132 tests/claude-integration/claude-picker-upload.test.ts 11622 tests/claude-integration/claude-prompt-too-long.test.ts 143 tests/claude-integration/claude-shell-hook.test.ts 265 tests/claude-integration/claude-sidecar-override.test.ts -143 tests/claude-integration/claude-source-envelope.test.ts +175 tests/claude-integration/claude-source-envelope.test.ts 405 tests/claude-integration/claude-subagent-model-force.test.ts 302 tests/claude-integration/claude-system-env-auto.test.ts -1047 tests/claude-integration/messages-native-decline-trace.test.ts +793 tests/claude-integration/claude-translated-cache-ttl.test.ts +1142 tests/claude-integration/messages-native-decline-trace.test.ts +14356 tests/claude-integration/messages-native-key-selection.test.ts 54261 tests/claude-integration/messages-native-oauth.test.ts 3996 tests/claude-integration/messages-native-opaque-state.test.ts -8920 tests/claude-integration/messages-native-scope.test.ts -29289 tests/claude-integration/messages-native.test.ts +14016 tests/claude-integration/messages-native-scope.test.ts +45606 tests/claude-integration/messages-native.test.ts 37964 tests/claude-integration/messages-request-id-endpoint.test.ts 175 tests/claude-integration/messages-request-id-headers.test.ts 48631 tests/claude-integration/messages-revoked-token.test.ts @@ -333,19 +351,19 @@ 127 tests/cli/agent-driven.test.ts 174 tests/cli/agent-subagent-force.test.ts 179 tests/cli/claude-config-first-party.test.ts -24387 tests/cli/cli-access-audio-live.test.ts +24288 tests/cli/cli-access-audio-live.test.ts 599 tests/cli/cli-access-audio.test.ts 192 tests/cli/cli-access-data-plane.test.ts 190 tests/cli/cli-access-key-guard.test.ts 991 tests/cli/cli-access-rename.test.ts 448 tests/cli/cli-account-alias-target.test.ts -190 tests/cli/cli-account-cancel-flow.test.ts +434 tests/cli/cli-account-cancel-flow.test.ts 236 tests/cli/cli-account-key-quota.test.ts 159 tests/cli/cli-account-kiro-device.test.ts -1457 tests/cli/cli-account-login-options.test.ts +953 tests/cli/cli-account-login-options.test.ts 128 tests/cli/cli-account-orca-import.test.ts 405 tests/cli/cli-account-pin-drain.test.ts -7188 tests/cli/cli-account-policy.test.ts +3189 tests/cli/cli-account-policy.test.ts 176 tests/cli/cli-account-pool-verbs.test.ts 111 tests/cli/cli-account-threshold.test.ts 459 tests/cli/cli-account-verify-status.test.ts @@ -355,7 +373,7 @@ 207 tests/cli/cli-alias-json.test.ts 172 tests/cli/cli-anthropic-account-threshold.test.ts 174 tests/cli/cli-anthropic2-account.test.ts -484 tests/cli/cli-api-protocols.test.ts +286 tests/cli/cli-api-protocols.test.ts 287 tests/cli/cli-aside-sync.test.ts 94 tests/cli/cli-capabilities-arguments.test.ts 213 tests/cli/cli-capabilities.test.ts @@ -368,7 +386,7 @@ 253 tests/cli/cli-capability-operation-workflows.test.ts 253 tests/cli/cli-capability-provider-workflows.test.ts 127 tests/cli/cli-catalog-command-result.test.ts -200 tests/cli/cli-catalog-prewarm.test.ts +94 tests/cli/cli-catalog-prewarm.test.ts 2250 tests/cli/cli-claude-desktop-profile.test.ts 126 tests/cli/cli-client-start-fence.test.ts 177 tests/cli/cli-client-start-owner-e2e.test.ts @@ -378,35 +396,37 @@ 190 tests/cli/cli-codex-log-guard.test.ts 1507 tests/cli/cli-combo-parity.test.ts 192 tests/cli/cli-combo-partial-update.test.ts -468 tests/cli/cli-combo-stats.test.ts -363 tests/cli/cli-companion-timeline.test.ts +2476 tests/cli/cli-combo-session-pin.test.ts +238 tests/cli/cli-combo-stats.test.ts +349 tests/cli/cli-companion-timeline.test.ts 266 tests/cli/cli-companion-usage.test.ts 221 tests/cli/cli-companion.test.ts -6600 tests/cli/cli-config-bom.test.ts +1936 tests/cli/cli-config-bom.test.ts 11880 tests/cli/cli-config-command.test.ts 6581 tests/cli/cli-config-default-show.test.ts 4918 tests/cli/cli-config-show-client.test.ts 15137 tests/cli/cli-connect-readiness.test.ts 4679 tests/cli/cli-dispatch.test.ts 160 tests/cli/cli-dto-fidelity.test.ts -713 tests/cli/cli-effort-slug.test.ts +1295 tests/cli/cli-effort-slug.test.ts 3330 tests/cli/cli-effort.test.ts 450 tests/cli/cli-ensure-client-state.test.ts 327 tests/cli/cli-ensure-readiness.test.ts 4019 tests/cli/cli-export-command.test.ts +301 tests/cli/cli-export-model-names.test.ts 143 tests/cli/cli-head.test.ts 3500 tests/cli/cli-headless-parity.test.ts 7346 tests/cli/cli-help-navigation.test.ts -23892 tests/cli/cli-help-paths.test.ts +24294 tests/cli/cli-help-paths.test.ts 11408 tests/cli/cli-help-recovery.test.ts 24483 tests/cli/cli-help.test.ts -2301 tests/cli/cli-init-port.test.ts +1466 tests/cli/cli-init-port.test.ts 734 tests/cli/cli-injection-follow.test.ts 112 tests/cli/cli-integer-options.test.ts 222 tests/cli/cli-integration-cursor.test.ts 206 tests/cli/cli-integration-droid.test.ts 2062 tests/cli/cli-integration-journal.test.ts -3286 tests/cli/cli-integration-preview.test.ts +3683 tests/cli/cli-integration-preview.test.ts 384 tests/cli/cli-json-contract.test.ts 444 tests/cli/cli-json-input.test.ts 385 tests/cli/cli-kiro-auto-selection.test.ts @@ -430,10 +450,11 @@ 30228 tests/cli/cli-models.test.ts 477 tests/cli/cli-native-profile.test.ts 159 tests/cli/cli-observe-logs.test.ts -148 tests/cli/cli-observe-snapshot.test.ts +238 tests/cli/cli-observe-snapshot.test.ts 192 tests/cli/cli-path-diagnostics.test.ts -1221 tests/cli/cli-provider-batch.test.ts +1076 tests/cli/cli-provider-batch.test.ts 619 tests/cli/cli-provider-lifecycle-runtime.test.ts +5151 tests/cli/cli-provider-list-active.test.ts 174 tests/cli/cli-provider-result.test.ts 302 tests/cli/cli-provider-settings.test.ts 9108 tests/cli/cli-provider-sync-result.test.ts @@ -445,7 +466,7 @@ 6964 tests/cli/cli-resolve-subprocess.test.ts 159 tests/cli/cli-resolve.test.ts 143 tests/cli/cli-restart-handoff.test.ts -7643 tests/cli/cli-restart-health.test.ts +6178 tests/cli/cli-restart-health.test.ts 10401 tests/cli/cli-restore-back.test.ts 170 tests/cli/cli-route-policy-not-found.test.ts 3271 tests/cli/cli-route-policy-write.test.ts @@ -458,14 +479,15 @@ 410 tests/cli/cli-status-oauth-health.test.ts 1931 tests/cli/cli-status-startup-health.test.ts 129 tests/cli/cli-stop-json.test.ts -527 tests/cli/cli-storage-inspect.test.ts +464 tests/cli/cli-stop-refusal-transport.test.ts +184 tests/cli/cli-storage-inspect.test.ts 2233 tests/cli/cli-storage-policy-fields.test.ts 286 tests/cli/cli-system-health.test.ts 128 tests/cli/cli-system-settings-parity.test.ts 476 tests/cli/cli-transport-honesty.test.ts 7971 tests/cli/cli-update-badge.test.ts 916 tests/cli/cli-update-restart-admission.test.ts -128 tests/cli/cli-update-restart-child.test.ts +80 tests/cli/cli-update-restart-child.test.ts 300 tests/cli/cli-update-restart-desktop-service.test.ts 420 tests/cli/cli-update-restart-home.test.ts 206 tests/cli/cli-update-restart-service-record.test.ts @@ -474,39 +496,41 @@ 254 tests/cli/cli-update-restart.test.ts 436 tests/cli/cli-usage-hub.test.ts 222 tests/cli/cli-usage-model-search.test.ts -186 tests/cli/cli-usage-report.test.ts -253 tests/cli/cli-usage-scope.test.ts +452 tests/cli/cli-usage-report.test.ts +427 tests/cli/cli-usage-scope.test.ts 13314 tests/cli/cli-v2-runtime.test.ts 26018 tests/cli/cli-version-skew.test.ts 1413 tests/cli/ensure-desired-integrations-race.test.ts 5631 tests/cli/hub-disable.test.ts -1637 tests/cli/hub-gated-local-clients.test.ts +1981 tests/cli/hub-gated-local-clients.test.ts 236 tests/cli/hub-invite.test.ts 354 tests/cli/interactive-confirm.test.ts +1473 tests/cli/local-credentials.test.ts 142 tests/cli/model-selection-guidance.test.ts 431 tests/cli/ocx-launcher-desktop-handoff.test.ts 65949 tests/cli/ocx-launcher-runtime.test.ts -177 tests/cli/ocx-launcher-source.test.ts +249 tests/cli/ocx-launcher-source.test.ts 125 tests/cli/ocx-run.test.ts -8797 tests/cli/restore-completes-shared-teardown.test.ts +6603 tests/cli/restore-completes-shared-teardown.test.ts 4101 tests/cli/route-explainability.test.ts 52182 tests/cli/sibling-home-client-sync.test.ts -244 tests/cli/star-deferral.test.ts +95 tests/cli/star-deferral.test.ts 119 tests/cli/start-args.test.ts 149 tests/cli/start-ownership-publication.test.ts 143 tests/cli/system-restart-client-package-tree.test.ts 190 tests/cli/system-restart-client.test.ts 8766 tests/cli/uninstall.test.ts +3902 tests/clients/agent-clients.test.ts 200 tests/clients/aside-profile-identity.test.ts 1230 tests/clients/aside-profile-paths.test.ts -15270 tests/clients/aside-profile-sync-owner.test.ts +6359 tests/clients/aside-profile-sync-owner.test.ts 2221 tests/clients/aside-profiles-catalog-refresh.test.ts 12191 tests/clients/aside-profiles.test.ts 129 tests/clients/client-catalog-compatibility.test.ts 46676 tests/clients/client-connect.test.ts -159 tests/clients/client-export-effective-metadata.test.ts -554 tests/clients/client-export-live-wire.test.ts -174 tests/clients/client-export-modality-enum.test.ts +254 tests/clients/client-export-effective-metadata.test.ts +685 tests/clients/client-export-live-wire.test.ts +448 tests/clients/client-export-modality-enum.test.ts 190 tests/clients/client-export-reasoning-controls.test.ts 159 tests/clients/client-export-reasoning-metadata.test.ts 286 tests/clients/client-fingerprint.test.ts @@ -514,31 +538,34 @@ 815 tests/clients/client-hub-state.test.ts 142 tests/clients/client-hub-usage.test.ts 4879 tests/clients/client-lifecycle-lock.test.ts -9909 tests/clients/client-link-connect.test.ts +17501 tests/clients/client-link-connect.test.ts 1185 tests/clients/client-link-relay.test.ts -13912 tests/clients/client-link-runtime.test.ts +19272 tests/clients/client-link-runtime.test.ts 1156 tests/clients/client-link-state.test.ts -127 tests/clients/client-link-status.test.ts +93 tests/clients/client-link-status.test.ts 2919 tests/clients/client-link-teardown.test.ts -7267 tests/clients/client-link-tunnel.test.ts -6412 tests/clients/client-machine-listener.test.ts +10401 tests/clients/client-link-tunnel.test.ts +6802 tests/clients/client-machine-listener.test.ts 158 tests/clients/client-runtime.test.ts 127 tests/clients/cline-client.test.ts 6074 tests/clients/cline-writer.test.ts 2296 tests/clients/command-code-client-contract.test.ts 161 tests/clients/command-code-client.test.ts -614 tests/clients/desktop-3p-guard.test.ts +778 tests/clients/desktop-3p-guard.test.ts 4256 tests/clients/desktop-3p-removal.test.ts 4232 tests/clients/desktop-3p.test.ts 156 tests/clients/desktop-app-restart-posix.test.ts 760 tests/clients/desktop-app-restart.test.ts 1937 tests/clients/desktop-app-server-shim-launcher.test.ts 385 tests/clients/desktop-app-server-shim.test.ts +10158 tests/clients/desktop-bundle-trust-async.test.ts 175 tests/clients/desktop-chatgpt-config.test.ts 143 tests/clients/desktop-cli-command-surface.test.ts 128 tests/clients/desktop-cli-contracts.test.ts -175 tests/clients/desktop-exit-ownership.test.ts -112 tests/clients/desktop-host-visibility.test.ts +111 tests/clients/desktop-compatibility-certificate-service.test.ts +474 tests/clients/desktop-compatibility-runtime.test.ts +81 tests/clients/desktop-exit-ownership.test.ts +245 tests/clients/desktop-host-visibility.test.ts 129 tests/clients/desktop-install-identity.test.ts 523 tests/clients/desktop-profile.test.ts 144 tests/clients/desktop-proxy-direct-transport.test.ts @@ -546,22 +573,23 @@ 175 tests/clients/desktop-restart-handoff.test.ts 152 tests/clients/desktop-runtime-identity.test.ts 114 tests/clients/desktop-start-at-login-default.test.ts -161 tests/clients/desktop-startup-surface.test.ts +81 tests/clients/desktop-startup-surface.test.ts 8909 tests/clients/desktop-supervised-restart.test.ts -159 tests/clients/desktop-tray-availability.test.ts +95 tests/clients/desktop-tray-availability.test.ts 174 tests/clients/desktop-update-surface.test.ts 95 tests/clients/desktop-widget-entry.test.ts 3056 tests/clients/droid-client.test.ts -3922 tests/clients/droid-managed-reasoning-defaults.test.ts +4428 tests/clients/droid-managed-reasoning-defaults.test.ts 2489 tests/clients/droid-normalized-reasoning-defaults.test.ts -8328 tests/clients/integrations-current-store.test.ts -9892 tests/clients/integrations-dsh-profile-patch.test.ts +188 tests/clients/gentle-shell-path.test.ts +9427 tests/clients/integrations-current-store.test.ts +9964 tests/clients/integrations-dsh-profile-patch.test.ts 6258 tests/clients/integrations-hermes-affinity.test.ts 3381 tests/clients/integrations-journal.test.ts 1158 tests/clients/integrations-merge.test.ts 159 tests/clients/integrations-serialize.test.ts -1042 tests/clients/integrations-state.test.ts -949 tests/clients/integrations-superseded-store.test.ts +873 tests/clients/integrations-state.test.ts +1081 tests/clients/integrations-superseded-store.test.ts 1319 tests/clients/integrations-writer-frozen-config.test.ts 2062 tests/clients/integrations-writer-guard.test.ts 10174 tests/clients/integrations-writer.test.ts @@ -569,8 +597,10 @@ 94 tests/clients/lazycodex-detection.test.ts 95 tests/clients/link-admission-wait.test.ts 97 tests/clients/link-boundary.test.ts -542 tests/clients/link-compensation.test.ts -143 tests/clients/link-fingerprint.test.ts +111 tests/clients/link-codex-settings-digest.test.ts +552 tests/clients/link-compensation.test.ts +95 tests/clients/link-fingerprint.test.ts +523 tests/clients/link-home-settings.test.ts 1397 tests/clients/link-ports.test.ts 921 tests/clients/link-relay-bound-transport.test.ts 207 tests/clients/link-routes.test.ts @@ -580,43 +610,44 @@ 689 tests/clients/link-ssh-runner.test.ts 458 tests/clients/link-status-projection.test.ts 479 tests/clients/link-store.test.ts -5319 tests/clients/link-supervisor.test.ts +4962 tests/clients/link-supervisor.test.ts 142 tests/clients/link-tunnel-state.test.ts -1794 tests/clients/mutation-plan.test.ts +2096 tests/clients/mutation-plan.test.ts 176 tests/clients/omo-client.test.ts 872 tests/clients/omo-role-models.test.ts 253 tests/clients/omp-path-contract.test.ts -191 tests/clients/omp-yaml-source-inline-comments.test.ts -4066 tests/clients/opencode-kilo-refresh.test.ts +143 tests/clients/omp-yaml-source-inline-comments.test.ts +4954 tests/clients/opencode-kilo-refresh.test.ts 188 tests/clients/pi-path-contract.test.ts -176 tests/clients/prime-client.test.ts +159 tests/clients/prime-client.test.ts 1300 tests/clients/raycast-client.test.ts -128 tests/clients/raycast-detect.test.ts +109 tests/clients/raycast-detect.test.ts 6932 tests/clients/remote-catalog.test.ts 158 tests/clients/remote-control-prototype.test.ts 220 tests/clients/remote-workspace-activation.test.ts 190 tests/clients/remote-workspace-agent-wire.test.ts 396 tests/clients/remote-workspace-app-server.integration.test.ts -316 tests/clients/remote-workspace-claude.integration.test.ts -222 tests/clients/remote-workspace-cli-runtimes.test.ts +156 tests/clients/remote-workspace-claude.integration.test.ts +1112 tests/clients/remote-workspace-cli-runtimes.test.ts 173 tests/clients/remote-workspace-cli.test.ts -349 tests/clients/remote-workspace-codex-runtime.test.ts +520 tests/clients/remote-workspace-codex-runtime.test.ts 364 tests/clients/remote-workspace-command-runner.test.ts -126 tests/clients/remote-workspace-device.test.ts +111 tests/clients/remote-workspace-device.test.ts 191 tests/clients/remote-workspace-hub.test.ts -328 tests/clients/remote-workspace-linux-confinement.test.ts +79 tests/clients/remote-workspace-linux-confinement.test.ts 606 tests/clients/remote-workspace-management.test.ts 144 tests/clients/remote-workspace-platform.test.ts 127 tests/clients/remote-workspace-protocol.test.ts 158 tests/clients/remote-workspace-rpc-framing.test.ts 1055 tests/clients/remote-workspace-secret-store.test.ts 8484 tests/clients/remote-workspace-server.test.ts -158 tests/clients/remote-workspace-session-binding.test.ts +96 tests/clients/remote-workspace-session-binding.test.ts 130 tests/clients/remote-workspace-sessions.test.ts 156 tests/clients/remote-workspace-tool-bridge.test.ts 401 tests/clients/remote-workspace.test.ts 16041 tests/clients/sync-client-integrations-unattended.test.ts 8408 tests/clients/sync-client-integrations.test.ts +1509 tests/clients/t3code-client-lifecycle.test.ts 5905 tests/codex-integration/active-registry-admission.test.ts 15323 tests/codex-integration/active-turn-disconnect.test.ts 539 tests/codex-integration/anthropic2-catalog.test.ts @@ -625,9 +656,10 @@ 904 tests/codex-integration/catalog-async-lifetime.test.ts 3984 tests/codex-integration/catalog-auto-refresh-client-fanout.test.ts 7420 tests/codex-integration/catalog-auto-refresh-scheduler.test.ts -19901 tests/codex-integration/catalog-auto-review-row.test.ts +255 tests/codex-integration/catalog-auto-review-override.test.ts +11487 tests/codex-integration/catalog-auto-review-row.test.ts 301 tests/codex-integration/catalog-cursor-search.test.ts -191 tests/codex-integration/catalog-custom-ordering.test.ts +514 tests/codex-integration/catalog-custom-ordering.test.ts 289 tests/codex-integration/catalog-duplicate-slug-dedup.test.ts 124 tests/codex-integration/catalog-free-pricing-status.test.ts 42654 tests/codex-integration/catalog-full-picker-order.test.ts @@ -636,16 +668,16 @@ 112 tests/codex-integration/catalog-hub-context-window.test.ts 331 tests/codex-integration/catalog-input-modality-enum.test.ts 348 tests/codex-integration/catalog-llamacpp-capabilities.test.ts -4962 tests/codex-integration/catalog-modelalias-unique-sync.test.ts +2315 tests/codex-integration/catalog-modelalias-unique-sync.test.ts 680 tests/codex-integration/catalog-oauth-observation.test.ts 1003 tests/codex-integration/catalog-opencode-go-context-window.test.ts 156 tests/codex-integration/catalog-opengateway-hints.test.ts 4863 tests/codex-integration/catalog-remote-pull.test.ts -172 tests/codex-integration/catalog-retain-models.test.ts -411 tests/codex-integration/catalog-routed-comp-hash.test.ts +238 tests/codex-integration/catalog-retain-models.test.ts +349 tests/codex-integration/catalog-routed-comp-hash.test.ts 161 tests/codex-integration/catalog-seed-window-fill.test.ts -142 tests/codex-integration/catalog-slug-uniqueness-boundary.test.ts -335 tests/codex-integration/catalog-verbosity-default.test.ts +175 tests/codex-integration/catalog-slug-uniqueness-boundary.test.ts +286 tests/codex-integration/catalog-verbosity-default.test.ts 386 tests/codex-integration/catalog-vision-sidecar-modalities.test.ts 446 tests/codex-integration/catalog-zero-credit-picker.test.ts 23354 tests/codex-integration/client-injection-guard.test.ts @@ -656,33 +688,34 @@ 126 tests/codex-integration/codex-account-namespaces.test.ts 9834 tests/codex-integration/codex-account-selection-atomicity.test.ts 1069 tests/codex-integration/codex-account-selection-preferences.test.ts +985 tests/codex-integration/codex-account-store-quota-isolation.test.ts 1182 tests/codex-integration/codex-account-store-refresh-classification.test.ts 5135 tests/codex-integration/codex-account-store.test.ts 1853 tests/codex-integration/codex-account-threshold-api.test.ts 1980 tests/codex-integration/codex-account-threshold-auth.test.ts 1745 tests/codex-integration/codex-account-threshold-routing.test.ts 1918 tests/codex-integration/codex-account-unusable-reason.test.ts -816 tests/codex-integration/codex-admission-primitives.test.ts +821 tests/codex-integration/codex-admission-primitives.test.ts 1186 tests/codex-integration/codex-admission.test.ts 338 tests/codex-integration/codex-affinity-debug.test.ts 126 tests/codex-integration/codex-app-server-path-spaces.test.ts 13079 tests/codex-integration/codex-app-server-processes.test.ts 219 tests/codex-integration/codex-app-server-restart-service.test.ts -14551 tests/codex-integration/codex-auth-api.test.ts +21413 tests/codex-integration/codex-auth-api.test.ts 396 tests/codex-integration/codex-auth-cancel-ownership.test.ts 2183 tests/codex-integration/codex-auth-collision.test.ts 3464 tests/codex-integration/codex-auth-context.test.ts 6065 tests/codex-integration/codex-auth-release.test.ts 1199 tests/codex-integration/codex-catalog-admission.test.ts -147 tests/codex-integration/codex-catalog-exclusions.test.ts +191 tests/codex-integration/codex-catalog-exclusions.test.ts 712 tests/codex-integration/codex-catalog-golden.test.ts -6538 tests/codex-integration/codex-catalog-heal-integration.test.ts +17936 tests/codex-integration/codex-catalog-heal-integration.test.ts 444 tests/codex-integration/codex-catalog-identity-neutral.test.ts 12216 tests/codex-integration/codex-catalog-intent.test.ts 423 tests/codex-integration/codex-catalog-ladders.test.ts 966 tests/codex-integration/codex-catalog-model-picker-order.test.ts 128 tests/codex-integration/codex-catalog-refresh-status.test.ts -10754 tests/codex-integration/codex-catalog-restore.test.ts +4882 tests/codex-integration/codex-catalog-restore.test.ts 144 tests/codex-integration/codex-catalog-routed-removal.test.ts 284 tests/codex-integration/codex-catalog-self-heal.test.ts 70037 tests/codex-integration/codex-catalog-sync-hardening.test.ts @@ -690,16 +723,22 @@ 1000 tests/codex-integration/codex-catalog-write-serialization.test.ts 7239 tests/codex-integration/codex-catalog-writer.test.ts 8476 tests/codex-integration/codex-catalog.test.ts -143 tests/codex-integration/codex-cli-install-provenance.test.ts +159 tests/codex-integration/codex-cli-install-provenance.test.ts 192 tests/codex-integration/codex-cli-installation-identity.test.ts 143 tests/codex-integration/codex-cli-installation-targets.test.ts 143 tests/codex-integration/codex-cli-update-launcher-policy.test.ts +127 tests/codex-integration/codex-cli-update-paths.test.ts +185160 tests/codex-integration/codex-cli-update-windows-apply-install.test.ts +294900 tests/codex-integration/codex-cli-update-windows-apply-outcomes.test.ts +245540 tests/codex-integration/codex-cli-update-windows-apply-shared.test.ts +127360 tests/codex-integration/codex-cli-update-windows-apply.test.ts 3633 tests/codex-integration/codex-cli-update-zero-effect.test.ts 978 tests/codex-integration/codex-cli-windows-installation-files.test.ts +23101 tests/codex-integration/codex-cli-windows-plan.test.ts 83015 tests/codex-integration/codex-composed-acceptance.test.ts 36774 tests/codex-integration/codex-config-drift-heal.test.ts 4709 tests/codex-integration/codex-config-generation.test.ts -15047 tests/codex-integration/codex-config-preservation.test.ts +11743 tests/codex-integration/codex-config-preservation.test.ts 25935 tests/codex-integration/codex-config-write-lock.test.ts 301 tests/codex-integration/codex-context-owner.test.ts 40794 tests/codex-integration/codex-convergence-account-selectors.test.ts @@ -708,11 +747,11 @@ 1048 tests/codex-integration/codex-coordinator-doctor.test.ts 667 tests/codex-integration/codex-credits-after-limit-main.test.ts 3374 tests/codex-integration/codex-credits-after-limit.test.ts -3204 tests/codex-integration/codex-credits-probes.test.ts +1967 tests/codex-integration/codex-credits-probes.test.ts 1352 tests/codex-integration/codex-credits-settings.test.ts 320 tests/codex-integration/codex-credits.test.ts 3065 tests/codex-integration/codex-desired-state.test.ts -705 tests/codex-integration/codex-entitlement-identity-read-fence.test.ts +645 tests/codex-integration/codex-entitlement-identity-read-fence.test.ts 5141 tests/codex-integration/codex-envkey-admission-substitution.test.ts 364 tests/codex-integration/codex-exec-invocation.test.ts 1448 tests/codex-integration/codex-failure-window.test.ts @@ -728,10 +767,10 @@ 143 tests/codex-integration/codex-history-worker-boundary.test.ts 3871 tests/codex-integration/codex-history-worker.test.ts 1506 tests/codex-integration/codex-history-writer.test.ts -26350 tests/codex-integration/codex-home-owner-lifecycle.test.ts +22479 tests/codex-integration/codex-home-owner-lifecycle.test.ts 6832 tests/codex-integration/codex-home-owner.test.ts 147 tests/codex-integration/codex-home-wsl-local-state.test.ts -222 tests/codex-integration/codex-home-wsl.test.ts +348 tests/codex-integration/codex-home-wsl.test.ts 13128 tests/codex-integration/codex-idle-window.test.ts 380 tests/codex-integration/codex-inject-history-wording.test.ts 332916 tests/codex-integration/codex-inject-integration.test.ts @@ -744,7 +783,8 @@ 965 tests/codex-integration/codex-integration-record.test.ts 8918 tests/codex-integration/codex-journal-recovery.test.ts 72818 tests/codex-integration/codex-journal.test.ts -95 tests/codex-integration/codex-legacy-config-keys.test.ts +9637 tests/codex-integration/codex-launcher-diagnostics.test.ts +143 tests/codex-integration/codex-legacy-config-keys.test.ts 1360 tests/codex-integration/codex-lineage-placement.test.ts 11720 tests/codex-integration/codex-linked-account-pause.test.ts 2155 tests/codex-integration/codex-log-guard-coderabbit.test.ts @@ -759,7 +799,7 @@ 128 tests/codex-integration/codex-log-guard-processes.test.ts 3366 tests/codex-integration/codex-log-guard-protection.test.ts 1265 tests/codex-integration/codex-log-guard-status-zero-write.test.ts -2568 tests/codex-integration/codex-main-account-refresh.test.ts +4505 tests/codex-integration/codex-main-account-refresh.test.ts 8720 tests/codex-integration/codex-main-grant-refusal.test.ts 5134 tests/codex-integration/codex-main-rotation.test.ts 601 tests/codex-integration/codex-main-token-invalidated.test.ts @@ -774,11 +814,11 @@ 3514 tests/codex-integration/codex-models-cache-invalidate.test.ts 6095 tests/codex-integration/codex-native-availability-nux.test.ts 6354 tests/codex-integration/codex-native-residue.test.ts -1183 tests/codex-integration/codex-pin-drain-projection.test.ts +1957 tests/codex-integration/codex-pin-drain-projection.test.ts 3215 tests/codex-integration/codex-plan.test.ts 6984 tests/codex-integration/codex-plugins-doctor.test.ts 2695 tests/codex-integration/codex-pool-credit-policy.test.ts -824 tests/codex-integration/codex-pool-plan-exclusion.test.ts +729 tests/codex-integration/codex-pool-plan-exclusion.test.ts 110 tests/codex-integration/codex-pool-refresh-backoff.test.ts 6617 tests/codex-integration/codex-pool-request-owned-main.test.ts 43781 tests/codex-integration/codex-pool-rotation.test.ts @@ -796,12 +836,13 @@ 1918 tests/codex-integration/codex-prompt-text-probe.test.ts 6017 tests/codex-integration/codex-prompt-writes.test.ts 6412 tests/codex-integration/codex-provider-table-retention.test.ts -2080 tests/codex-integration/codex-quota-auto-refresh-generation.test.ts +1474 tests/codex-integration/codex-quota-auto-refresh-generation.test.ts 841 tests/codex-integration/codex-quota-auto-refresh-main-admission.test.ts 10130 tests/codex-integration/codex-quota-auto-refresh.test.ts -174 tests/codex-integration/codex-quota-capacity.test.ts +96 tests/codex-integration/codex-quota-capacity.test.ts 316 tests/codex-integration/codex-quota-history.test.ts 446 tests/codex-integration/codex-quota-parser-parity.test.ts +779 tests/codex-integration/codex-quota-persistence.test.ts 3376 tests/codex-integration/codex-quota-prime.test.ts 1897 tests/codex-integration/codex-quota-query-backoff.test.ts 403 tests/codex-integration/codex-quota-rejection.test.ts @@ -809,8 +850,8 @@ 7282 tests/codex-integration/codex-reset-credit-auto-redeem.test.ts 9942 tests/codex-integration/codex-reset-credit-operation-ledger.test.ts 578 tests/codex-integration/codex-reset-credit-recovery.test.ts -127 tests/codex-integration/codex-restart-contract-parity.test.ts -443 tests/codex-integration/codex-restart-route.test.ts +205 tests/codex-integration/codex-restart-contract-parity.test.ts +2300 tests/codex-integration/codex-restart-route.test.ts 29610 tests/codex-integration/codex-restore-app-rewrite.test.ts 39279 tests/codex-integration/codex-retained-root-serialization.test.ts 650 tests/codex-integration/codex-routing-cache-affinity-detour.test.ts @@ -824,13 +865,13 @@ 125 tests/codex-integration/codex-shim-ensure-failure.test.ts 185 tests/codex-integration/codex-shim-fnm.test.ts 162 tests/codex-integration/codex-shim-migration.test.ts -161 tests/codex-integration/codex-shim-overlay-candidates.test.ts +145 tests/codex-integration/codex-shim-overlay-candidates.test.ts 190 tests/codex-integration/codex-shim-overlay-readiness.test.ts 182 tests/codex-integration/codex-shim-overlay-transaction.test.ts 79 tests/codex-integration/codex-shim-overlay.test.ts 5044 tests/codex-integration/codex-shim-path-readiness.test.ts 7716 tests/codex-integration/codex-shim-readiness.test.ts -158 tests/codex-integration/codex-shim-runtime-preflight.test.ts +221 tests/codex-integration/codex-shim-runtime-preflight.test.ts 128 tests/codex-integration/codex-shim-standalone.test.ts 16501 tests/codex-integration/codex-shim.test.ts 4323 tests/codex-integration/codex-sidecar-credit-policy.test.ts @@ -845,16 +886,17 @@ 3644 tests/codex-integration/codex-transition-state-adoption.test.ts 1302 tests/codex-integration/codex-transition-state-first-use-regression.test.ts 8470 tests/codex-integration/codex-transition-state-race.test.ts -9081 tests/codex-integration/codex-transition-state.test.ts +1823 tests/codex-integration/codex-transition-state.test.ts 1715 tests/codex-integration/codex-user-identity.test.ts 14053 tests/codex-integration/codex-v2-gate.test.ts 682 tests/codex-integration/codex-warmup.test.ts 19820 tests/codex-integration/codex-web-search-switch.test.ts 95 tests/codex-integration/codex-websocket-registry.test.ts -17682 tests/codex-integration/codex-write-lock.test.ts -130 tests/codex-integration/combo-authoritative-reset.test.ts +7550 tests/codex-integration/codex-write-lock.test.ts +80 tests/codex-integration/combo-authoritative-reset.test.ts 340 tests/codex-integration/combo-codex-exhaustion-cooldown.test.ts -301 tests/codex-integration/combo-last-resort.test.ts +4917 tests/codex-integration/combo-description-catalog.test.ts +112 tests/codex-integration/combo-last-resort.test.ts 112 tests/codex-integration/combo-permanent-failure-cooldown.test.ts 110 tests/codex-integration/combo-reset-window-model-scope.test.ts 570 tests/codex-integration/combos.test.ts @@ -864,7 +906,7 @@ 140 tests/codex-integration/custom-model-catalog-migration.test.ts 2156 tests/codex-integration/discovered-native-models.test.ts 5124 tests/codex-integration/doctor.test.ts -1026 tests/codex-integration/effort-policy.test.ts +1175 tests/codex-integration/effort-policy.test.ts 297 tests/codex-integration/fast-row-listing.test.ts 793 tests/codex-integration/fast-row.test.ts 396 tests/codex-integration/gather-routed-models-single-flight.test.ts @@ -876,18 +918,19 @@ 12027 tests/codex-integration/history-paginated-transition-destinations.test.ts 175 tests/codex-integration/injection-link-websocket.test.ts 3010 tests/codex-integration/injection-model-api.test.ts -348 tests/codex-integration/injection-model-suggest-routes.test.ts +316 tests/codex-integration/injection-model-suggest-routes.test.ts 192 tests/codex-integration/injection-routing-drift.test.ts 13888 tests/codex-integration/injection-routing-heal-apply.test.ts 739 tests/codex-integration/injection-routing-healer.test.ts 17176 tests/codex-integration/issue-452-empty-503.test.ts -38712 tests/codex-integration/issue-702-expired-replay-state.test.ts +57244 tests/codex-integration/issue-702-expired-replay-state.test.ts 1549 tests/codex-integration/issue-914-transport-attribution.test.ts 4176 tests/codex-integration/low-quota-protection.test.ts 1530 tests/codex-integration/main-account-credit-renewal.test.ts 144 tests/codex-integration/main-account-external-usage.test.ts -54184 tests/codex-integration/main-account-hard-lock-auth.test.ts +32570 tests/codex-integration/main-account-hard-lock-auth.test.ts 1190 tests/codex-integration/main-account-hard-lock-default.test.ts +7330 tests/codex-integration/main-account-hard-lock-fallback-off.test.ts 250 tests/codex-integration/main-account-hard-lock-policy.test.ts 1269 tests/codex-integration/main-account-hard-lock-recovery.test.ts 206 tests/codex-integration/main-account-hard-lock-retirement.test.ts @@ -899,11 +942,12 @@ 5818 tests/codex-integration/main-quota-provenance.test.ts 2554 tests/codex-integration/main-quota-window-observation.test.ts 410 tests/codex-integration/messaging-local-cli.test.ts -238 tests/codex-integration/messaging-local-discovery.test.ts +112 tests/codex-integration/messaging-local-discovery.test.ts 206 tests/codex-integration/messaging-local-envelope.test.ts -587 tests/codex-integration/messaging-local-lifecycle.test.ts +603 tests/codex-integration/messaging-local-lifecycle.test.ts 160 tests/codex-integration/messaging-local-send.test.ts 334 tests/codex-integration/messaging-local-socket.test.ts +126 tests/codex-integration/messaging-remote-interop.test.ts 141 tests/codex-integration/model-cache-generation-tombstone.test.ts 309 tests/codex-integration/model-cache.test.ts 236 tests/codex-integration/model-display-names-management-api.test.ts @@ -917,29 +961,30 @@ 937 tests/codex-integration/native-claude-code-toggle.test.ts 9624 tests/codex-integration/native-claude-desktop-toggle.test.ts 35950 tests/codex-integration/native-codex-toggle.test.ts -2227 tests/codex-integration/native-grok-toggle.test.ts +2284 tests/codex-integration/native-grok-toggle.test.ts 394 tests/codex-integration/native-main-auth-temp.test.ts 112 tests/codex-integration/native-main-claim-cache.test.ts 624 tests/codex-integration/native-main-claim.test.ts -35806 tests/codex-integration/native-main-owner-lifetime.test.ts +36752 tests/codex-integration/native-main-owner-lifetime.test.ts 953 tests/codex-integration/native-model-toggle.test.ts 159 tests/codex-integration/native-profile-api.test.ts 31558 tests/codex-integration/native-profile-crash-boundaries.test.ts 8342 tests/codex-integration/native-profile-drain-server.test.ts 14922 tests/codex-integration/native-profile-manager.test.ts -669 tests/codex-integration/native-profile-processes.test.ts +459 tests/codex-integration/native-profile-processes.test.ts 146 tests/codex-integration/native-profile-recovery.test.ts 3675 tests/codex-integration/native-profile-route-security.test.ts -1360 tests/codex-integration/native-profile-stage-lifecycle.test.ts +1475 tests/codex-integration/native-profile-stage-lifecycle.test.ts 1428 tests/codex-integration/native-profile-startup-release.test.ts 64051 tests/codex-integration/native-profile-startup.test.ts 1014 tests/codex-integration/native-profile-store.test.ts +413 tests/codex-integration/native-source-priority.test.ts 6118 tests/codex-integration/orca-import.test.ts 652 tests/codex-integration/parallel-tool-calls-optin.test.ts 190 tests/codex-integration/project-config-warning-snapshot.test.ts 238 tests/codex-integration/project-config-warnings.test.ts -523 tests/codex-integration/reasoning-effort.test.ts -446 tests/codex-integration/reasoning-metadata.test.ts +477 tests/codex-integration/reasoning-effort.test.ts +222 tests/codex-integration/reasoning-metadata.test.ts 900 tests/codex-integration/reserve-auth-context.test.ts 175 tests/codex-integration/reserve-availability.test.ts 20920 tests/codex-integration/reserve-catalog-lifecycle.test.ts @@ -947,7 +992,7 @@ 2408 tests/codex-integration/reserve-dispatch.test.ts 395 tests/codex-integration/reserve-helper-boundary.test.ts 478 tests/codex-integration/reserve-passive-revocation.test.ts -2585 tests/codex-integration/reserve-quota-scope.test.ts +3113 tests/codex-integration/reserve-quota-scope.test.ts 174 tests/codex-integration/selected-models.test.ts 749 tests/codex-integration/slug-codec.test.ts 8039 tests/codex-integration/token-guardian.test.ts @@ -959,26 +1004,27 @@ 254 tests/config/client-config-export.test.ts 570 tests/config/client-config-new-clients.test.ts 190 tests/config/compaction-recovery-settings.test.ts -459 tests/config/config-account-thresholds.test.ts -5145 tests/config/config-anthropic-instance-pool.test.ts +429 tests/config/config-account-thresholds.test.ts +7096 tests/config/config-anthropic-instance-pool.test.ts 426 tests/config/config-blocked-model-redirects.test.ts 461 tests/config/config-catalog-auto-refresh.test.ts 129 tests/config/config-commandcode-claude-pin.test.ts +111 tests/config/config-hosted-search-projection.test.ts 4355 tests/config/config-load-degrade.test.ts 7987 tests/config/config-mutation-lock.test.ts 804 tests/config/config-non-object-backup.test.ts -1297 tests/config/config-ownership-uninstall.test.ts +714 tests/config/config-ownership-uninstall.test.ts 127 tests/config/config-rebase-provenance-writers.test.ts -175 tests/config/config-save-boundary.test.ts +126 tests/config/config-save-boundary.test.ts 763 tests/config/config-skills-catalog-refresh.test.ts 887 tests/config/config-spend-ceilings.test.ts 447 tests/config/config-spend-pool-collision.test.ts 19125 tests/config/config-user-edits.test.ts 108 tests/config/expand-user-path.test.ts -13849 tests/config/hub-disable-live-save.test.ts +12959 tests/config/hub-disable-live-save.test.ts 17473 tests/config/model-pinned-effort-config.test.ts 173 tests/config/owner-registry-acl.test.ts -193 tests/config/protocol-settings.test.ts +161 tests/config/protocol-settings.test.ts 15051 tests/config/serving-runtimes.test.ts 5904 tests/config/settings-desktop-switch-apply.test.ts 1473 tests/config/settings-fast-rows.test.ts @@ -1008,7 +1054,7 @@ 109 tests/gui/gui-pair-capability.test.ts 1511 tests/gui/gui-pair-client.test.ts 21411 tests/gui/gui-pair-delivery.test.ts -7717 tests/gui/gui-pair-http.test.ts +7146 tests/gui/gui-pair-http.test.ts 347 tests/gui/gui-static.test.ts 317 tests/gui/gui-tray-vibrancy-surface.test.ts 476 tests/gui/html-lang-boot-script.test.ts @@ -1024,9 +1070,9 @@ 2 tests/gui/platform-dialog-guard.test.ts 176 tests/gui/provider-payload.test.ts 196 tests/gui/provider-subscription-cli.test.ts -120 tests/gui/provider-workspace-auth.test.ts +95 tests/gui/provider-workspace-auth.test.ts 254 tests/gui/provider-workspace-data.test.ts -142 tests/gui/provider-workspace-rail.test.ts +254 tests/gui/provider-workspace-rail.test.ts 298 tests/gui/provider-workspace-state.test.ts 280 tests/gui/quota-bars-rows.test.ts 142 tests/gui/qwen-cloud-endpoints.test.ts @@ -1044,13 +1090,14 @@ 174 tests/images/download-connect-deadline-default.test.ts 143 tests/images/gemini-inline.test.ts 521 tests/images/loop-reasoning-replay.test.ts -3658 tests/images/loop.test.ts +205 tests/images/loop-terminal-refusal.test.ts +3928 tests/images/loop.test.ts 320 tests/images/pinned-https-get.test.ts 159 tests/images/plan.test.ts 96 tests/images/synthetic-tool.test.ts 234 tests/images/xai-client.test.ts -427 tests/images/z-fulfill.test.ts -648 tests/images/z-handler-activation.test.ts +189 tests/images/z-fulfill.test.ts +696 tests/images/z-handler-activation.test.ts 838 tests/lab/core-lab-boundary.test.ts 428 tests/lab/core-link-boundary.test.ts 15613 tests/lab/lab-activation.test.ts @@ -1060,7 +1107,7 @@ 967 tests/lab/lab-automation-management-http.test.ts 126 tests/lab/lab-automation-persisted-cap-regression.test.ts 4764 tests/lab/lab-automation-review-regressions.test.ts -4163 tests/lab/lab-automation.test.ts +2504 tests/lab/lab-automation.test.ts 1951 tests/lab/lab-community-evidence.test.ts 1855 tests/lab/lab-community-filename-contract.test.ts 239 tests/lab/lab-community-mutation-lock.test.ts @@ -1079,16 +1126,16 @@ 1710 tests/lab/lab-live-probe.test.ts 238 tests/lab/lab-live-receipt-integrity.test.ts 606 tests/lab/lab-live-review-regressions.test.ts -1617 tests/lab/lab-live-sandbox.test.ts +633 tests/lab/lab-live-sandbox.test.ts 240 tests/lab/lab-passive-production-evidence.test.ts 350 tests/lab/lab-passive-production-surfaces.test.ts 127 tests/lab/lab-paths-security.test.ts -507 tests/lab/lab-post-merge-hardening.test.ts +396 tests/lab/lab-post-merge-hardening.test.ts 550 tests/lab/lab-post-merge-projection.test.ts 369 tests/lab/lab-private-file-consumer-recovery.test.ts 124 tests/lab/lab-private-file-durability.test.ts 206 tests/lab/lab-public-api-json.test.ts -141 tests/lab/lab-public-artifact-policy.test.ts +608 tests/lab/lab-public-artifact-policy.test.ts 2451 tests/lab/lab-public-coderabbit-regressions.test.ts 509 tests/lab/lab-public-core-contract.test.ts 1417 tests/lab/lab-public-deep-review-regressions.test.ts @@ -1104,51 +1151,52 @@ 1492 tests/lab/lab-public-security-regressions.test.ts 1921 tests/lab/lab-public-surfaces.test.ts 491 tests/lab/lab-public-wire-contract.test.ts -190 tests/lab/lab-read-filter-validation.test.ts +365 tests/lab/lab-read-filter-validation.test.ts 48084 tests/lab/lab-read-surfaces.test.ts 871 tests/lib/abort-idle-deadline.test.ts 237 tests/lib/acl-error-classification.test.ts 445 tests/lib/ambiguous-resend-composition.test.ts 129 tests/lib/ambiguous-resend-gate.test.ts 378 tests/lib/bun-runtime-preflight.test.ts -143 tests/lib/bun-stream-caps.test.ts +96 tests/lib/bun-stream-caps.test.ts 173 tests/lib/clearable-deadline.test.ts 716 tests/lib/credential-redirect-guard.test.ts 144 tests/lib/debug.test.ts 189 tests/lib/execution-budget-permits.test.ts -160 tests/lib/failure-attribution.test.ts +125 tests/lib/failure-attribution.test.ts 126 tests/lib/failure-stage-model.test.ts 382 tests/lib/local-chat-completion.test.ts -113 tests/lib/local-destinations.test.ts +90 tests/lib/local-destinations.test.ts 176 tests/lib/local-upstream.test.ts +3308 tests/lib/opaque-proxy-tunnel-protocol.test.ts 2678 tests/lib/optional-shutdown-hooks.test.ts -380 tests/lib/pinned-http-content-coding.test.ts +351 tests/lib/pinned-http-content-coding.test.ts 407 tests/lib/pinned-http.test.ts -223 tests/lib/plugin-loader.test.ts +113 tests/lib/plugin-loader.test.ts 128 tests/lib/plugin-upstream-hooks.test.ts 157 tests/lib/privacy-mask-account.test.ts 402 tests/lib/process-control-graceful.test.ts 109 tests/lib/process-control.test.ts -273 tests/lib/provider-egress.test.ts +79 tests/lib/provider-egress.test.ts 141 tests/lib/reasoning-replay-scope-source.test.ts 1290 tests/lib/redact.test.ts 160 tests/lib/remove-tree-helper.test.ts 298 tests/lib/self-launch-argv.test.ts 1628 tests/lib/socks5-fetch.test.ts 204 tests/lib/socks5-upload-lifecycle.test.ts -2014 tests/lib/spend-ceiling-enforcement.test.ts +2188 tests/lib/spend-ceiling-enforcement.test.ts 314 tests/lib/spend-contract-c.test.ts 94 tests/lib/spend-corruption-compat.test.ts 112 tests/lib/spend-experimental-history.test.ts 2729 tests/lib/spend-ledger-file-journal.test.ts 7428 tests/lib/spend-ledger-owner.test.ts -1519 tests/lib/spend-pool-continuity.test.ts +2128 tests/lib/spend-pool-continuity.test.ts 128 tests/lib/spend-reservation-ledger.test.ts 1440 tests/lib/spend-seed-overflow.test.ts 174 tests/lib/spend-unbound-expiry.test.ts 158 tests/lib/spend-zero-config-compat.test.ts 142 tests/lib/stall-subprocess-exit.test.ts -310 tests/lib/stall-timeout.test.ts +111 tests/lib/stall-timeout.test.ts 478 tests/lib/standalone.test.ts 144 tests/lib/strict-semver.test.ts 142 tests/lib/synced-state-location.test.ts @@ -1165,13 +1213,13 @@ 8646 tests/oauth/adapter-event-oauth-failover.test.ts 10976 tests/oauth/anthropic2-discovery-ownership.test.ts 4240 tests/oauth/chatgpt-device-auth.test.ts -157 tests/oauth/chatgpt-oauth.test.ts +277 tests/oauth/chatgpt-oauth.test.ts 188 tests/oauth/chatgpt-token-boundaries.test.ts 238 tests/oauth/chatgpt-token-expiry.test.ts 20253 tests/oauth/generic-oauth-failover.test.ts 4220 tests/oauth/generic-oauth-refusal-composition.test.ts 2597 tests/oauth/key-login-live-update.test.ts -205 tests/oauth/key-login-preserves-model-costs.test.ts +234 tests/oauth/key-login-preserves-model-costs.test.ts 110 tests/oauth/local-token-detect.test.ts 6423 tests/oauth/oauth-account-attribution.test.ts 348 tests/oauth/oauth-account-id-collision.test.ts @@ -1182,9 +1230,10 @@ 11232 tests/oauth/oauth-anthropic-instance-health.test.ts 11569 tests/oauth/oauth-anthropic-instance-multiprocess.test.ts 15296 tests/oauth/oauth-anthropic-instance-refresh.test.ts -23356 tests/oauth/oauth-anthropic-instance-registration.test.ts +28028 tests/oauth/oauth-anthropic-instance-registration.test.ts 386 tests/oauth/oauth-callback-binds.test.ts 143 tests/oauth/oauth-callback-server.test.ts +12962 tests/oauth/oauth-code-login.test.ts 158 tests/oauth/oauth-device-code-contract.test.ts 4276 tests/oauth/oauth-health.test.ts 7108 tests/oauth/oauth-kiro-refresh-attention.test.ts @@ -1212,6 +1261,7 @@ 143 tests/providers/alibaba-region-startup.test.ts 984 tests/providers/alibaba-token-plan-responses-optin.test.ts 1524 tests/providers/alibaba-token-plan-wire-defaults.test.ts +2174 tests/providers/api-key-auto-pause-distribution.test.ts 887 tests/providers/api-key-catalog-authority.test.ts 108 tests/providers/api-key-selection-capture.test.ts 633 tests/providers/aside-client.test.ts @@ -1219,7 +1269,7 @@ 428 tests/providers/azure-adapter.test.ts 322 tests/providers/azure-model-router-tool-schema.test.ts 1151 tests/providers/azure-vendor-metadata.test.ts -353 tests/providers/baseten-provider.test.ts +223 tests/providers/baseten-provider.test.ts 179 tests/providers/chutes-provider.test.ts 270 tests/providers/claude-cli-adapter.test.ts 300 tests/providers/cline-pass-deepseek-v4-tool-replay.test.ts @@ -1237,6 +1287,7 @@ 837 tests/providers/command-code-efforts.test.ts 158 tests/providers/command-code-error-finish.test.ts 204 tests/providers/command-code-fakeip-discovery.test.ts +7279 tests/providers/command-code-plan-denial.test.ts 4647 tests/providers/command-code-project-context.test.ts 1808 tests/providers/command-code-provider.test.ts 684 tests/providers/command-code-quota.test.ts @@ -1263,13 +1314,13 @@ 125 tests/providers/cursor/cursor-discovery.test.ts 369 tests/providers/cursor/cursor-display-names.test.ts 6168 tests/providers/cursor/cursor-effort-rows.test.ts -97 tests/providers/cursor/cursor-effort-suffix.test.ts +159 tests/providers/cursor/cursor-effort-suffix.test.ts 135 tests/providers/cursor/cursor-effort-table.test.ts 205 tests/providers/cursor/cursor-envelope-echo-retry.test.ts -189 tests/providers/cursor/cursor-eof-terminal.test.ts -145 tests/providers/cursor/cursor-errors.test.ts -128 tests/providers/cursor/cursor-exec-empty-result.test.ts -199 tests/providers/cursor/cursor-fast-listing.test.ts +255 tests/providers/cursor/cursor-eof-terminal.test.ts +146 tests/providers/cursor/cursor-errors.test.ts +91 tests/providers/cursor/cursor-exec-empty-result.test.ts +175 tests/providers/cursor/cursor-fast-listing.test.ts 143 tests/providers/cursor/cursor-fast-tier.test.ts 394 tests/providers/cursor/cursor-foreground-shell.test.ts 223 tests/providers/cursor/cursor-framing.test.ts @@ -1285,18 +1336,18 @@ 159 tests/providers/cursor/cursor-local-installer.test.ts 4440 tests/providers/cursor/cursor-local-models-schema.test.ts 237 tests/providers/cursor/cursor-mcp-manager.test.ts -967 tests/providers/cursor/cursor-mcp-stdio.test.ts +1095 tests/providers/cursor/cursor-mcp-stdio.test.ts 175 tests/providers/cursor/cursor-message-mapper.test.ts 96 tests/providers/cursor/cursor-native-exec-common.test.ts 254 tests/providers/cursor/cursor-native-exec-policy.test.ts 342 tests/providers/cursor/cursor-native-exec-shell.test.ts 174 tests/providers/cursor/cursor-native-exec.test.ts 143 tests/providers/cursor/cursor-oauth-shell.test.ts -777 tests/providers/cursor/cursor-oauth.test.ts +635 tests/providers/cursor/cursor-oauth.test.ts 129 tests/providers/cursor/cursor-pool.test.ts 157 tests/providers/cursor/cursor-protobuf-events.test.ts 252 tests/providers/cursor/cursor-repetition-breaker.test.ts -287 tests/providers/cursor/cursor-request-builder.test.ts +301 tests/providers/cursor/cursor-request-builder.test.ts 158 tests/providers/cursor/cursor-request-compat.test.ts 375 tests/providers/cursor/cursor-roster-account-scope.test.ts 123 tests/providers/cursor/cursor-silent-redirect.test.ts @@ -1316,7 +1367,7 @@ 1832 tests/providers/cursor/cursor-transport-retry.test.ts 159 tests/providers/cursor/cursor-ultra-mode.test.ts 139 tests/providers/cursor/cursor-umbrella-rows.test.ts -112 tests/providers/cursor/cursor-uncallable-quarantine.test.ts +96 tests/providers/cursor/cursor-uncallable-quarantine.test.ts 350 tests/providers/cursor/cursor-vision-wire-harness.test.ts 774 tests/providers/cyber-policy-error-fidelity.test.ts 281 tests/providers/deepinfra-provider.test.ts @@ -1326,7 +1377,7 @@ 159 tests/providers/deepseek-reasoning-replay-gaps.test.ts 191 tests/providers/deepseek-reasoning-replay.test.ts 2069 tests/providers/deepseek-responses-item-id-repair.test.ts -2335 tests/providers/devin-adapter-reset-wait.test.ts +2769 tests/providers/devin-adapter-reset-wait.test.ts 1031 tests/providers/devin-adapter.test.ts 773 tests/providers/devin-anthropic-signature-fallback.test.ts 393 tests/providers/devin-chat-wire-fixes.test.ts @@ -1339,7 +1390,7 @@ 1870 tests/providers/devin-login.test.ts 726 tests/providers/devin-output-budget.test.ts 1203 tests/providers/devin-prompt-cache.test.ts -1317 tests/providers/devin-provider-merge-migration.test.ts +1617 tests/providers/devin-provider-merge-migration.test.ts 1048 tests/providers/devin-quota.test.ts 175 tests/providers/devin-reasoning-continuation.test.ts 96 tests/providers/devin-stated-reset-hardening.test.ts @@ -1349,16 +1400,16 @@ 177 tests/providers/digitalocean-scaleway-provider.test.ts 220 tests/providers/exa-web-search.test.ts 141 tests/providers/fast-row-ingress.test.ts -221 tests/providers/featherless-provider.test.ts +381 tests/providers/featherless-provider.test.ts 465 tests/providers/flash-route-image-modalities.test.ts 3919 tests/providers/forward-admission-separation.test.ts 8998 tests/providers/github-copilot/github-copilot-account-origin.test.ts 37772 tests/providers/github-copilot/github-copilot-auto-runtime.test.ts 161 tests/providers/github-copilot/github-copilot-auto.test.ts 379 tests/providers/github-copilot/github-copilot-catalog-hints.test.ts -158 tests/providers/github-copilot/github-copilot-context-tier.test.ts +207 tests/providers/github-copilot/github-copilot-context-tier.test.ts 16134 tests/providers/github-copilot/github-copilot-oauth.test.ts -94 tests/providers/github-copilot/github-copilot-sse-rewrite.test.ts +112 tests/providers/github-copilot/github-copilot-sse-rewrite.test.ts 935 tests/providers/github-copilot/github-copilot-stream-contract.test.ts 6467 tests/providers/github-copilot/github-copilot-wire-defaults.test.ts 125 tests/providers/haiku-5-5-catalog.test.ts @@ -1373,10 +1424,11 @@ 7409 tests/providers/kiro/kiro-account-state-disk.test.ts 1935 tests/providers/kiro/kiro-account-state-imports.test.ts 1364 tests/providers/kiro/kiro-adapter.test.ts -2773 tests/providers/kiro/kiro-auth-context-continuation.test.ts +3300 tests/providers/kiro/kiro-auth-context-continuation.test.ts 1636 tests/providers/kiro/kiro-auto-selection.test.ts 936 tests/providers/kiro/kiro-builder-id-profile.test.ts -96 tests/providers/kiro/kiro-calibration.test.ts +95 tests/providers/kiro/kiro-calibration.test.ts +334 tests/providers/kiro/kiro-completion-with-real-tools.test.ts 1364 tests/providers/kiro/kiro-device-builder.test.ts 7898 tests/providers/kiro/kiro-device-social.test.ts 478 tests/providers/kiro/kiro-fallback-error-body.test.ts @@ -1388,7 +1440,7 @@ 2777 tests/providers/kiro/kiro-model-preference.test.ts 8380 tests/providers/kiro/kiro-oauth.test.ts 23971 tests/providers/kiro/kiro-org-user-identity.test.ts -6161 tests/providers/kiro/kiro-pool-load-settings.test.ts +7499 tests/providers/kiro/kiro-pool-load-settings.test.ts 4098 tests/providers/kiro/kiro-pool-rank.test.ts 4567 tests/providers/kiro/kiro-quota-metrics.test.ts 142 tests/providers/kiro/kiro-reasoning-roundtrip.test.ts @@ -1398,7 +1450,7 @@ 671 tests/providers/kiro/kiro-retry.test.ts 3873 tests/providers/kiro/kiro-review-regressions.test.ts 299 tests/providers/kiro/kiro-single-final.test.ts -633 tests/providers/kiro/kiro-stream.test.ts +801 tests/providers/kiro/kiro-stream.test.ts 807 tests/providers/kiro/kiro-transport-parity.test.ts 152 tests/providers/kiro/kiro-usage-quota.test.ts 620 tests/providers/kiro/kiro-usage-restart.test.ts @@ -1414,11 +1466,11 @@ 386 tests/providers/mimo-token-plan-capacity.test.ts 174 tests/providers/mimo-token-plan-provider.test.ts 626 tests/providers/mimo-v26-catalog.test.ts -5556 tests/providers/minimax-clients.test.ts +1082 tests/providers/minimax-clients.test.ts 1461 tests/providers/minimax-combo-image-input.test.ts 631 tests/providers/minimax-quota.test.ts -237 tests/providers/minimax-reasoning-split.test.ts -192 tests/providers/model-presets.test.ts +301 tests/providers/minimax-reasoning-split.test.ts +110 tests/providers/model-presets.test.ts 1757 tests/providers/model-rename-migration.test.ts 358 tests/providers/model-roster-seed-repair.test.ts 95 tests/providers/moonshot-endpoints.test.ts @@ -1431,25 +1483,25 @@ 468 tests/providers/muse-tool-name-alias.test.ts 5603 tests/providers/new-model-policy-runtime.test.ts 112 tests/providers/new-model-policy.test.ts -159 tests/providers/nous-oauth-live.test.ts +389 tests/providers/nous-oauth-live.test.ts 13336 tests/providers/nous-oauth.test.ts 222 tests/providers/novita-provider.test.ts 173 tests/providers/nscale-vultr-provider.test.ts 348 tests/providers/nvidia-nim-hardening.test.ts -606 tests/providers/ollama/ollama-native-parser.test.ts -144 tests/providers/ollama/ollama-native-reasoning-wire.test.ts -1 tests/providers/ollama/ollama-native-structured-output.test.ts +474 tests/providers/ollama/ollama-native-parser.test.ts +188 tests/providers/ollama/ollama-native-reasoning-wire.test.ts +81 tests/providers/ollama/ollama-native-structured-output.test.ts 505 tests/providers/ollama/ollama-native-tool-continuations.test.ts 827 tests/providers/ollama/ollama-native-v4.test.ts 442 tests/providers/ollama/ollama-native.test.ts 522 tests/providers/ollama/ollama-show-enrichment-v7.test.ts -363 tests/providers/ollama/ollama-show-enrichment.test.ts +253 tests/providers/ollama/ollama-show-enrichment.test.ts 361 tests/providers/ollama/ollama-show-ignore-abort.test.ts -996 tests/providers/opencode-cli.test.ts +859 tests/providers/opencode-cli.test.ts 126 tests/providers/opencode-go-deepseek.test.ts 448 tests/providers/opencode-go-grok46-responses.test.ts 3139 tests/providers/opencode-go-luna-wire.test.ts -299 tests/providers/opencode-go-muse-context.test.ts +433 tests/providers/opencode-go-muse-context.test.ts 520 tests/providers/opencode-go-muse-vision.test.ts 427 tests/providers/opencode-go-quota.test.ts 11091 tests/providers/opencode-go-session-header.test.ts @@ -1457,12 +1509,13 @@ 95 tests/providers/opencode-muse-terminal-repair.test.ts 128 tests/providers/opencode-zen-deepseek-reasoning.test.ts 106 tests/providers/opencode-zen-rate-limit.test.ts -110 tests/providers/opengateway-key-validation.test.ts +111 tests/providers/opengateway-key-validation.test.ts 159 tests/providers/opengateway-provider.test.ts 619 tests/providers/openrouter-provider-routing.test.ts 174 tests/providers/openrouter-quota-reset-cooldown-4024.test.ts 555 tests/providers/opper-provider.test.ts 599 tests/providers/orcarouter-provider.test.ts +2189 tests/providers/provider-account-quota-failure-reasons.test.ts 3058 tests/providers/provider-account-quota-persistence.test.ts 10596 tests/providers/provider-account-quota.test.ts 381 tests/providers/provider-anthropic-instance-quota.test.ts @@ -1478,21 +1531,21 @@ 14169 tests/providers/provider-connection-test.test.ts 1937 tests/providers/provider-cost-overlay-config.test.ts 412 tests/providers/provider-discovery-log-suppression.test.ts -176 tests/providers/provider-egress-outbound.test.ts -205 tests/providers/provider-id-rewrite.test.ts +111 tests/providers/provider-egress-outbound.test.ts +110 tests/providers/provider-id-rewrite.test.ts 4317 tests/providers/provider-key-store.test.ts 529 tests/providers/provider-live-models.test.ts 426 tests/providers/provider-model-aliases.test.ts -877 tests/providers/provider-model-discovery-contract.test.ts +586 tests/providers/provider-model-discovery-contract.test.ts 155 tests/providers/provider-outbound-private-network.test.ts 4611 tests/providers/provider-outbound.test.ts 700 tests/providers/provider-quota-label-sanitize.test.ts 776 tests/providers/provider-quota-observed-marker.test.ts -407 tests/providers/provider-quota-ollama-cloud.test.ts +1235 tests/providers/provider-quota-ollama-cloud.test.ts 14681 tests/providers/provider-quota.test.ts 729 tests/providers/provider-registry-parity.test.ts 230 tests/providers/provider-runtime-fetch.test.ts -270 tests/providers/provider-static-model-discovery.test.ts +206 tests/providers/provider-static-model-discovery.test.ts 127 tests/providers/provider-tls-profile.test.ts 613 tests/providers/qoder-adapter.test.ts 111 tests/providers/qoder-live-models.test.ts @@ -1500,6 +1553,7 @@ 158 tests/providers/qoder-scaffold-guard.test.ts 93 tests/providers/qwen38-preserve-reasoning.test.ts 1227 tests/providers/rate-limit-retry.test.ts +164 tests/providers/registry-transport-alias.test.ts 285 tests/providers/resolved-model-policy.test.ts 316 tests/providers/sambanova-nebius-provider.test.ts 222 tests/providers/sponsor-presets.test.ts @@ -1509,39 +1563,39 @@ 159 tests/providers/umans-provider.test.ts 7974 tests/providers/upstream-transient-retry.test.ts 161 tests/providers/vercel-gateway-provider-routing.test.ts -127 tests/providers/vision-classification-seed-repair.test.ts +235 tests/providers/vision-classification-seed-repair.test.ts 143 tests/providers/volcengine-ark-assistant-content.test.ts 142 tests/providers/xai/grok-47-build-fast-metadata.test.ts 80069 tests/providers/xai/grok-47-fast-model-wire.test.ts 366 tests/providers/xai/grok-47-fast-model.test.ts 524 tests/providers/xai/grok-attribution.test.ts 5470 tests/providers/xai/grok-config-inject.test.ts -173 tests/providers/xai/grok-config-write-lock.test.ts +284 tests/providers/xai/grok-config-write-lock.test.ts 35562 tests/providers/xai/grok-coupon-claim.test.ts 2120 tests/providers/xai/grok-coupon-reconcile.test.ts 980 tests/providers/xai/grok-effort-inject.test.ts -162 tests/providers/xai/grok-lifecycle.test.ts +237 tests/providers/xai/grok-lifecycle.test.ts 13266 tests/providers/xai/grok-management-api.test.ts 7999 tests/providers/xai/grok-models-effort-list.test.ts -11820 tests/providers/xai/grok-orphan-adoption.test.ts +7019 tests/providers/xai/grok-orphan-adoption.test.ts 194 tests/providers/xai/grok-reset-coupon-cli.test.ts -935 tests/providers/xai/grok-reset-coupons.test.ts +1128 tests/providers/xai/grok-reset-coupons.test.ts 652 tests/providers/xai/grok-selection.test.ts 712 tests/providers/xai/grok-session-identity.test.ts 587 tests/providers/xai/grok-status.test.ts 840 tests/providers/xai/grok-sync.test.ts -285 tests/providers/xai/grok-writer-boundary.test.ts +253 tests/providers/xai/grok-writer-boundary.test.ts 144 tests/providers/xai/xai-empty-catalog-tool-choice.test.ts 174 tests/providers/xai/xai-no-stop.test.ts 145 tests/providers/xai/xai-oauth-retry.test.ts 2666 tests/providers/xai/xai-refresh-lock.test.ts 156 tests/providers/xai/xai-responses-adjacency.test.ts 209 tests/providers/xai/xai-tool-schema.test.ts -347 tests/providers/xai/xai-transport.test.ts +350 tests/providers/xai/xai-transport.test.ts 173 tests/providers/xai/xai-web-search-compat.test.ts 175 tests/providers/xai/xai-web-search.test.ts -386 tests/providers/zai-reasoning-replay.test.ts -191 tests/providers/zcode-client.test.ts +468 tests/providers/zai-reasoning-replay.test.ts +286 tests/providers/zcode-client.test.ts 930 tests/providers/zed-hosted-provider.test.ts 454 tests/providers/zed-retained-budget.test.ts 245 tests/providers/zhipu-bigmodel-provider.test.ts @@ -1552,14 +1606,15 @@ 3092 tests/responses/chat-completions-deferred-tools.test.ts 74323 tests/responses/chat-completions-endpoint.test.ts 3344 tests/responses/chat-completions-pool-mode.test.ts -5652 tests/responses/chat-conversation-affinity.test.ts +10497 tests/responses/chat-conversation-affinity.test.ts 920 tests/responses/chat-inbound-developer-position.test.ts 253 tests/responses/chat-inbound-reasoning-none.test.ts 397 tests/responses/chat-inbound-reasoning-replay.test.ts +1190 tests/responses/chat-incomplete-length-reason.test.ts 157 tests/responses/chat-inline-document-bytes.test.ts 3122 tests/responses/chat-json-sse-fallback.test.ts 1953 tests/responses/chat-legacy-functions-combo.test.ts -1687 tests/responses/chat-media-translation.test.ts +2860 tests/responses/chat-media-translation.test.ts 7625 tests/responses/chat-native-combo.test.ts 330 tests/responses/chat-native-decline-reason.test.ts 9570 tests/responses/chat-native-developer-role.test.ts @@ -1569,23 +1624,25 @@ 376 tests/responses/chat-native-sse-stall.test.ts 248 tests/responses/chat-refusal-scope.test.ts 2333 tests/responses/chat-refusal.test.ts -2967 tests/responses/chat-responses-control-integration.test.ts +2997 tests/responses/chat-responses-control-integration.test.ts 159 tests/responses/chat-responses-control-scope.test.ts -4473 tests/responses/chat-sse-framing-guard.test.ts +4440 tests/responses/chat-sse-framing-guard.test.ts 139 tests/responses/chat-tool-choice-allowed-tools.test.ts 96 tests/responses/citation-markers.test.ts 141 tests/responses/codex-ws-pool-contention.test.ts +10345 tests/responses/compact-key-selection.test.ts 178 tests/responses/compaction-event-ownership.test.ts 173 tests/responses/compaction-progress.test.ts 378 tests/responses/continuation-dedup.test.ts -413 tests/responses/custom-tool-compat.test.ts +283 tests/responses/custom-tool-compat.test.ts 8181 tests/responses/droid-reasoning-defaults.test.ts 1919 tests/responses/empty-completion-core.test.ts 114 tests/responses/empty-completion-guard.test.ts -143 tests/responses/empty-completion-hardening.test.ts -246 tests/responses/eventstream-decoder.test.ts +1358 tests/responses/empty-completion-hardening.test.ts +96 tests/responses/eventstream-decoder.test.ts +30288 tests/responses/explicit-empty-tool-catalog.test.ts 477 tests/responses/external-task-input-repair.test.ts -879 tests/responses/fresh-connection-optout.test.ts +777 tests/responses/fresh-connection-optout.test.ts 7798 tests/responses/jev-initial-effort-wire.test.ts 130 tests/responses/legacy-shell-compat.test.ts 317 tests/responses/messages-native-bridge-policy.test.ts @@ -1595,11 +1652,12 @@ 583 tests/responses/opaque-blob-wrapped-rejection.test.ts 1789 tests/responses/openai-responses-passthrough.test.ts 192 tests/responses/openai-responses-summary-none.test.ts +193 tests/responses/opengateway-completion-receipts.test.ts 152 tests/responses/parser-content-audio.test.ts 428 tests/responses/passthrough-abort.test.ts 39738 tests/responses/passthrough-deferred-tools.test.ts 182 tests/responses/passthrough-grok-upstream-envelope-echo.test.ts -253 tests/responses/passthrough-headers.test.ts +889 tests/responses/passthrough-headers.test.ts 127 tests/responses/passthrough-override.test.ts 191 tests/responses/plaintext-v2-agent-messages.test.ts 143 tests/responses/protocol-baseline.test.ts @@ -1607,29 +1665,31 @@ 275 tests/responses/protocol-direct-encoders-chat.test.ts 97 tests/responses/protocol-direct-encoders-local-upstream.test.ts 175 tests/responses/protocol-direct-encoders-messages.test.ts -142 tests/responses/protocol-direct-encoders-stall-disabled.test.ts +109 tests/responses/protocol-direct-encoders-stall-disabled.test.ts 157 tests/responses/protocol-dto.test.ts 404 tests/responses/protocol-envelope.test.ts 127 tests/responses/protocol-features.test.ts -126 tests/responses/protocol-guard.test.ts +95 tests/responses/protocol-guard.test.ts 1061 tests/responses/protocol-ingress-guard.test.ts 111 tests/responses/protocol-opaque-state.test.ts -125 tests/responses/protocol-path.test.ts +80 tests/responses/protocol-path.test.ts 190 tests/responses/protocol-plan-snapshot.test.ts 128 tests/responses/protocol-plan.test.ts 608 tests/responses/protocol-shadow-plan.test.ts -175 tests/responses/protocol-trace.test.ts +94 tests/responses/protocol-trace.test.ts 152 tests/responses/provider-egress-fetch.test.ts -238 tests/responses/reasoning-effort-summary-default.test.ts +1188 tests/responses/reasoning-archive-http.test.ts +641 tests/responses/reasoning-effort-summary-default.test.ts 253 tests/responses/reasoning-envelope.test.ts 333 tests/responses/reserve-dispatch-ws.test.ts 144 tests/responses/responses-4546-incident-regression.test.ts -258 tests/responses/responses-account-change-scrub.test.ts +222 tests/responses/responses-account-change-scrub.test.ts 6641 tests/responses/responses-account-label.test.ts 5223 tests/responses/responses-alternate-main-cancellation.test.ts +744 tests/responses/responses-anthropic-billing-send-budget.test.ts 1907 tests/responses/responses-anthropic-fast-downgrade.test.ts 4253 tests/responses/responses-azure-opaque-blob-recovery.test.ts -476 tests/responses/responses-bare-echo-helper-fence.test.ts +285 tests/responses/responses-bare-echo-helper-fence.test.ts 3369 tests/responses/responses-canonical-nonstream.test.ts 174 tests/responses/responses-canonical-only-top-level-fields.test.ts 663 tests/responses/responses-chat-tool-call-content.test.ts @@ -1639,6 +1699,7 @@ 176 tests/responses/responses-code-mode-patch-compile.test.ts 159 tests/responses/responses-code-mode-shell-compile.test.ts 2414 tests/responses/responses-combo-exhausted-error.test.ts +2237 tests/responses/responses-combo-fallback-off.test.ts 8207 tests/responses/responses-compact-handoff-admission.test.ts 6723 tests/responses/responses-compaction-override.test.ts 176 tests/responses/responses-compaction-policy-identity.test.ts @@ -1655,7 +1716,7 @@ 1840 tests/responses/responses-custom-tool-repair-dispatch.test.ts 205 tests/responses/responses-custom-tool-repair.test.ts 172 tests/responses/responses-custom-tool-stream-consistency.test.ts -130 tests/responses/responses-default-namespace-emit-normalize.test.ts +117 tests/responses/responses-default-namespace-emit-normalize.test.ts 16198 tests/responses/responses-devin-401-replay.test.ts 127 tests/responses/responses-dispatch-receipt.test.ts 191 tests/responses/responses-fetch-helpers-boundary.test.ts @@ -1667,7 +1728,7 @@ 1633 tests/responses/responses-forward-incomplete-quota.test.ts 156 tests/responses/responses-forward-output-cap.test.ts 286 tests/responses/responses-forward-posit-continuation.test.ts -328 tests/responses/responses-forward-prompt-envelope.test.ts +484 tests/responses/responses-forward-prompt-envelope.test.ts 253 tests/responses/responses-freeform-wrapper-keys.test.ts 667 tests/responses/responses-function-tool-repair.test.ts 18050 tests/responses/responses-grok-devin-preflight.test.ts @@ -1686,12 +1747,13 @@ 1325 tests/responses/responses-image-gen-repair.test.ts 1554 tests/responses/responses-inbound-store-default.test.ts 143 tests/responses/responses-item-id-repair.test.ts -316 tests/responses/responses-json-events.test.ts +95 tests/responses/responses-json-events.test.ts 314 tests/responses/responses-legacy-dotted-tool-name-repair.test.ts 5858 tests/responses/responses-main-quota-observation.test.ts 2377 tests/responses/responses-memory-models.test.ts 1110 tests/responses/responses-muse-tool-choice.test.ts 1334 tests/responses/responses-muse-tool-name-alias.test.ts +10171 tests/responses/responses-native-key-cooldown.test.ts 6461 tests/responses/responses-native-main-refresh.test.ts 16948 tests/responses/responses-opaque-blob-recovery.test.ts 143 tests/responses/responses-parser-agent-message.test.ts @@ -1699,23 +1761,24 @@ 209 tests/responses/responses-parser.test.ts 174 tests/responses/responses-passthrough-transient-policy.test.ts 35267 tests/responses/responses-pool-401-refresh.test.ts -210 tests/responses/responses-pool-refresh-attribution.test.ts -4599 tests/responses/responses-preview-main-read-fence.test.ts +256 tests/responses/responses-pool-refresh-attribution.test.ts +5825 tests/responses/responses-preview-main-read-fence.test.ts 902 tests/responses/responses-reasoning-effort-downgrade.test.ts 1171 tests/responses/responses-reasoning-summary-passthrough.test.ts 160 tests/responses/responses-reset-replay.test.ts 394 tests/responses/responses-routed-web-search-fields.test.ts -6074 tests/responses/responses-run-turn-web-search.test.ts +717 tests/responses/responses-run-turn-key-pacing.test.ts +11927 tests/responses/responses-run-turn-web-search.test.ts 3192 tests/responses/responses-self-named-namespace-scrub.test.ts 10179 tests/responses/responses-send-budget-counts.test.ts 4639 tests/responses/responses-send-budget-errors.test.ts 1312 tests/responses/responses-shadow-intercept.test.ts -3933 tests/responses/responses-show-thinking-summary.test.ts +4597 tests/responses/responses-show-thinking-summary.test.ts 1283 tests/responses/responses-skills-snapshot.test.ts 8250 tests/responses/responses-snapshot-repair-server.test.ts 565 tests/responses/responses-snapshot-repair.test.ts 128 tests/responses/responses-sparse-terminal-tool-scope.test.ts -8548 tests/responses/responses-spend-anchor.test.ts +16787 tests/responses/responses-spend-anchor.test.ts 159 tests/responses/responses-spend-capacity-guard.test.ts 921 tests/responses/responses-spend-contract-c.test.ts 635 tests/responses/responses-spend-ledger-wiring.test.ts @@ -1723,9 +1786,9 @@ 1441 tests/responses/responses-spill-admission-headroom.test.ts 513 tests/responses/responses-spill-inspection.test.ts 445 tests/responses/responses-spill-orphan-sweep.test.ts -396 tests/responses/responses-spill-shutdown-clock.test.ts +349 tests/responses/responses-spill-shutdown-clock.test.ts 197 tests/responses/responses-state-snapshot-select.test.ts -222 tests/responses/responses-state-snapshot-stubs.test.ts +110 tests/responses/responses-state-snapshot-stubs.test.ts 507 tests/responses/responses-state-store-false.test.ts 1496 tests/responses/responses-state-write-amplification.test.ts 11606 tests/responses/responses-state.test.ts @@ -1749,7 +1812,8 @@ 159 tests/responses/sse-payload-rewrite.test.ts 238 tests/responses/sse-rewrite-line-endings.test.ts 127 tests/responses/sse-unspaced-data-fields.test.ts -518 tests/responses/thought-signature-credential-scope.test.ts +176 tests/responses/thought-signature-credential-scope.test.ts +1080 tests/responses/turn-membership-ingress.test.ts 161 tests/responses/visualization-directives.test.ts 3522 tests/responses/ws-ambiguous-resend.test.ts 205 tests/responses/ws-endpoint.test.ts @@ -1769,11 +1833,12 @@ 143 tests/routing/cl01-openai-chat-review-regressions.test.ts 175 tests/routing/cl01-review-regressions.test.ts 822 tests/routing/codex-agent-role-models.test.ts -95 tests/routing/codex-role-auto-assign.test.ts +129 tests/routing/codex-role-auto-assign.test.ts 138 tests/routing/codex-role-sizing.test.ts 242 tests/routing/combo-child-headers.test.ts 17455 tests/routing/combo-management-api.test.ts 221 tests/routing/combo-stream-preflight.test.ts +236 tests/routing/combo-terminal-refusal.test.ts 15346 tests/routing/compatibility-provider-equivalence.test.ts 134 tests/routing/destination-policy-resolved.test.ts 190 tests/routing/fastwire-characterization-routing.test.ts @@ -1785,7 +1850,8 @@ 3939 tests/routing/jev-decision-model-config.test.ts 3062 tests/routing/jev-decision-provider-combo.test.ts 494 tests/routing/jev-decision.test.ts -1131 tests/routing/jev-model-backend.test.ts +1141 tests/routing/jev-model-backend.test.ts +2461 tests/routing/jev-quota-publication.test.ts 131 tests/routing/jev-service-exchange.test.ts 109 tests/routing/jev-typesafe-golden.test.ts 554 tests/routing/policy-execution.test.ts @@ -1793,22 +1859,22 @@ 292 tests/routing/probe-lease.test.ts 412 tests/routing/resolved-model-policy-consumers.test.ts 286 tests/routing/router-blocked-cross-provider.test.ts -248 tests/routing/router-combo-failover-classification.test.ts +123 tests/routing/router-combo-failover-classification.test.ts 417 tests/routing/router-discarded-baseurl-warning.test.ts 175 tests/routing/router-template-baseurl.test.ts 467 tests/routing/router.test.ts -12480 tests/routing/routing-analytics.test.ts +4634 tests/routing/routing-analytics.test.ts 159 tests/routing/routing-capability-catalog.test.ts 1665 tests/routing/routing-capability-model-matching.test.ts 127 tests/routing/routing-compatibility-auth-identity.test.ts 31008 tests/routing/routing-compatibility-boundaries.test.ts -366 tests/routing/routing-compatibility-model-matching.test.ts +130 tests/routing/routing-compatibility-model-matching.test.ts 15852 tests/routing/routing-compatibility.test.ts -172 tests/routing/routing-identity-domains.test.ts +95 tests/routing/routing-identity-domains.test.ts 1157 tests/routing/routing-policy-dispatch-scope.test.ts 397 tests/routing/routing-policy-fallback.test.ts 113 tests/routing/routing-policy-pool-quota.test.ts -16023 tests/routing/routing-policy-surface-parity.test.ts +15763 tests/routing/routing-policy-surface-parity.test.ts 30646 tests/routing/routing-profile-management-editor.test.ts 2559 tests/routing/routing-profile.test.ts 509 tests/routing/subagent-context-staleness.test.ts @@ -1818,11 +1884,11 @@ 567 tests/routing/subagent-model-fallback-api.test.ts 26150 tests/routing/subagent-model-fallback.test.ts 3900 tests/routing/subagent-roster-migration.test.ts -2188 tests/routing/subagent-roster-retention.test.ts +2055 tests/routing/subagent-roster-retention.test.ts 1870 tests/server/account-import.test.ts 52368 tests/server/account-pool-management-api.test.ts 302 tests/server/adapter-resolve.test.ts -1887 tests/server/agent-task-recovery-cache.test.ts +1831 tests/server/agent-task-recovery-cache.test.ts 3191 tests/server/agent-task-recovery-combo.test.ts 856 tests/server/agent-task-recovery-fallback.test.ts 1439 tests/server/agent-task-recovery-security.test.ts @@ -1837,7 +1903,7 @@ 17204 tests/server/api-debug.test.ts 31173 tests/server/api-key-attribution.test.ts 810 tests/server/api-key-model-scope.test.ts -1825 tests/server/api-key-scope-alpha-search.test.ts +1937 tests/server/api-key-scope-alpha-search.test.ts 722 tests/server/api-key-scope-audio.test.ts 625 tests/server/api-key-scope-images.test.ts 238 tests/server/api-key-scope-live.test.ts @@ -1855,8 +1921,9 @@ 15591 tests/server/claude-intercept-integration.test.ts 1937 tests/server/codex-agent-role-routes.test.ts 827 tests/server/codex-role-auto-assign-routes.test.ts -129 tests/server/combo-requested-effort.test.ts -620 tests/server/companion-settings.test.ts +1920 tests/server/codex-role-history-recovery.test.ts +96 tests/server/combo-requested-effort.test.ts +268 tests/server/companion-settings.test.ts 8310 tests/server/config.test.ts 213 tests/server/consume-for-inspection-cancel.test.ts 7443 tests/server/context-history-ownership.test.ts @@ -1877,7 +1944,7 @@ 3553 tests/server/inference-send-budget.test.ts 141 tests/server/input-admission.test.ts 271 tests/server/jev-decision-scope.test.ts -3778 tests/server/link-enrollment.test.ts +4047 tests/server/link-enrollment.test.ts 2581 tests/server/link-join-route.test.ts 6598 tests/server/link-listener-admission.test.ts 634 tests/server/link-listener-lifecycle.test.ts @@ -1887,16 +1954,17 @@ 95 tests/server/live-native-calls.test.ts 443 tests/server/local-account-switch-capability.test.ts 2233 tests/server/local-account-switch-ingress.test.ts -3030 tests/server/local-aside-sync-capability.test.ts +7306 tests/server/local-aside-sync-capability.test.ts 240 tests/server/local-management-attestation.test.ts 208 tests/server/local-management-capability.test.ts 2963 tests/server/local-management-direct-transport.test.ts 359 tests/server/local-provider-reload-client.test.ts 2065 tests/server/local-read-response-proof.test.ts +681 tests/server/login-shell-path.test.ts 206 tests/server/logs-timezone.test.ts -421 tests/server/loopback-companion-client-targets.test.ts +176 tests/server/loopback-companion-client-targets.test.ts 190 tests/server/loopback-listener-admission.test.ts -73964 tests/server/loopback-listener-integration.test.ts +87254 tests/server/loopback-listener-integration.test.ts 1805 tests/server/management-anthropic-reset-grants.test.ts 460 tests/server/management-api-logs-metrics.test.ts 583 tests/server/management-api-logs-timing-basis.test.ts @@ -1910,17 +1978,18 @@ 465 tests/server/management-model-roster-gather-race.test.ts 206 tests/server/management-model-roster.test.ts 236 tests/server/management-origin-tls.test.ts -5073 tests/server/management-provider-atomicity.test.ts +4953 tests/server/management-provider-atomicity.test.ts 29922 tests/server/management-provider-compat-carry.test.ts +492 tests/server/management-provider-context-inference.test.ts 6540 tests/server/management-provider-hide-raw-reasoning.test.ts 2203 tests/server/management-provider-pinsless-validation.test.ts 3396 tests/server/management-provider-proto-override.test.ts 7459 tests/server/management-provider-reasoning-lists.test.ts -1207 tests/server/management-provider-request-pacing.test.ts -111 tests/server/management-provider-reset-replay.test.ts +1291 tests/server/management-provider-request-pacing.test.ts +95 tests/server/management-provider-reset-replay.test.ts 1202 tests/server/management-provider-synthetic-max.test.ts 1982 tests/server/management-provider-upstream-websocket.test.ts -105607 tests/server/management-provider-validation.test.ts +191841 tests/server/management-provider-validation.test.ts 2301 tests/server/management-provider-verbosity.test.ts 449 tests/server/management-route-registry.test.ts 14131 tests/server/management-sidecar-anthropic-instance.test.ts @@ -1945,10 +2014,11 @@ 1206 tests/server/provider-send-path-import.test.ts 209 tests/server/proxy-env-macos.test.ts 380 tests/server/proxy-env.test.ts +762 tests/server/proxy-liveness-owner-evidence.test.ts 145 tests/server/proxy-liveness-package-tree-fence.test.ts 332 tests/server/proxy-liveness.test.ts 918 tests/server/relay-eager.test.ts -11141 tests/server/replay-refusal-parity.test.ts +17663 tests/server/replay-refusal-parity.test.ts 1743 tests/server/reserve-claude-policy.test.ts 12235 tests/server/reserve-ingress.test.ts 794 tests/server/response-log-inspection.test.ts @@ -1959,6 +2029,7 @@ 314 tests/server/route-decision-trace.test.ts 4273 tests/server/server-403-permission-e2e.test.ts 1616 tests/server/server-agent-task-recovery-replay.test.ts +18492 tests/server/server-antigravity-model-roster-routing.test.ts 349 tests/server/server-antigravity-verify-replay-scope.test.ts 21282 tests/server/server-antigravity-web-search-validation.test.ts 1013 tests/server/server-auth-localhost-bind.test.ts @@ -1968,39 +2039,41 @@ 1948 tests/server/server-cli-key-probe-admission.test.ts 117 tests/server/server-clickjacking-headers.test.ts 1131 tests/server/server-combo-cooldown-fallback.test.ts -1469 tests/server/server-combo-cooldown-recording.test.ts -61563 tests/server/server-combo-failover-e2e.test.ts -116 tests/server/server-combo-held-response.test.ts +2629 tests/server/server-combo-cooldown-recording.test.ts +87540 tests/server/server-combo-failover-e2e.test.ts +95 tests/server/server-combo-held-response.test.ts 13621 tests/server/server-combo-plan-model-refusal.test.ts 4923 tests/server/server-combo-reasoning-replay-eligibility.test.ts 3193 tests/server/server-combo-zero-output-failover.test.ts +26419 tests/server/server-generic-oauth-affinity.test.ts 100094 tests/server/server-google-antigravity-oauth-401-replay.test.ts 14209 tests/server/server-google-antigravity-oauth-429-budget.test.ts 97 tests/server/server-gui-bundle-freshness.test.ts 190 tests/server/server-images-bodyless-content-length.test.ts 4132 tests/server/server-images-pool-admission.test.ts -47342 tests/server/server-images.test.ts +116516 tests/server/server-images.test.ts 444 tests/server/server-jev-combo-e2e.test.ts 221 tests/server/server-jev-model-decision-e2e.test.ts 51941 tests/server/server-key-failover-e2e.test.ts 24660 tests/server/server-kiro-completion-e2e.test.ts -1978 tests/server/server-kiro-device-login.test.ts +2142 tests/server/server-kiro-device-login.test.ts 7822 tests/server/server-kiro-oauth-401-replay.test.ts 41320 tests/server/server-kiro-refusal-e2e.test.ts 3677 tests/server/server-live-existing-call.test.ts 413 tests/server/server-live-frame-log.test.ts 8565 tests/server/server-live-realtime-fixtures.test.ts 36487 tests/server/server-live.test.ts -109 tests/server/server-loopback-host-gate.test.ts +272 tests/server/server-loopback-host-gate.test.ts 37140 tests/server/server-management-auth.test.ts -2837 tests/server/server-management-log-admission.test.ts -8175 tests/server/server-new-model-policy-arrival.test.ts +4775 tests/server/server-management-log-admission.test.ts +14904 tests/server/server-new-model-policy-arrival.test.ts 3688 tests/server/server-opencode-go-goal-streaming.test.ts 9373 tests/server/server-rate-limit-retry-e2e.test.ts 4063 tests/server/server-request-body-size.test.ts 18704 tests/server/server-search.test.ts 6158 tests/server/server-startup-reconcile-resilience.test.ts 5463 tests/server/server-stop-config-hardening.test.ts +2825 tests/server/server-terminal-refusal-wiring.test.ts 2637 tests/server/server-xai-chat-reasoning-streaming.test.ts 4998 tests/server/server-xai-header-parity.test.ts 12122 tests/server/server-xai-oauth-401-replay.test.ts @@ -2009,9 +2082,9 @@ 2909 tests/server/session-lane-recall-harness.test.ts 508 tests/server/sidebar-routes.test.ts 210 tests/server/sidebar-star-state.test.ts -127 tests/server/spend-instrumentation-log.test.ts +192 tests/server/spend-instrumentation-log.test.ts 1255 tests/server/spend-ledger-lifecycle.test.ts -3984 tests/server/spend-ledger-owner-startup.test.ts +4967 tests/server/spend-ledger-owner-startup.test.ts 191 tests/server/startup-action-control-elevation.test.ts 247 tests/server/startup-action-control.test.ts 33636 tests/server/startup-health-packaged-probe.test.ts @@ -2025,10 +2098,10 @@ 5949 tests/server/terminal-guard-server.test.ts 208 tests/server/terminal-guard.test.ts 574 tests/server/update-async-routes.test.ts -156 tests/server/upstream-connect-error.test.ts +267 tests/server/upstream-connect-error.test.ts 127 tests/server/upstream-http-version.test.ts 8946 tests/server/v1-hub-state.test.ts -2523 tests/server/v2-agent-message-failfast.test.ts +3236 tests/server/v2-agent-message-failfast.test.ts 160 tests/service/autostart-health.test.ts 12949 tests/service/container-bootstrap.test.ts 302 tests/service/crash-guard.test.ts @@ -2042,7 +2115,7 @@ 476 tests/service/live-service-manager-guard.test.ts 128 tests/service/managing-cli.test.ts 186 tests/service/ownership-mutation-lease-diagnostics.test.ts -1112 tests/service/process-state.test.ts +1302 tests/service/process-state.test.ts 1637 tests/service/service-auth-qualified-localhost.test.ts 492 tests/service/service-child-ownership.test.ts 386 tests/service/service-claim.test.ts @@ -2050,28 +2123,29 @@ 395 tests/service/service-desktop-startup-health.test.ts 162 tests/service/service-desktop-startup-linux.test.ts 1475 tests/service/service-desktop-startup.test.ts -140 tests/service/service-handled-signal-exit.test.ts +96 tests/service/service-handled-signal-exit.test.ts 343 tests/service/service-health-sentinel-launch.test.ts 160 tests/service/service-health-sentinel-policy.test.ts 11109 tests/service/service-health-sentinel-process.test.ts 1268 tests/service/service-health-sentinel-runner.test.ts +4091 tests/service/service-log.test.ts 301 tests/service/service-multishell-path.test.ts 177 tests/service/service-ownership-compatibility.test.ts 823 tests/service/service-ownership-handover.test.ts -6468 tests/service/service-ownership-state.test.ts +5072 tests/service/service-ownership-state.test.ts 142 tests/service/service-probe-docker.test.ts -761 tests/service/service-runtime-preflight.test.ts -4665 tests/service/service-secrets.test.ts +897 tests/service/service-runtime-preflight.test.ts +9825 tests/service/service-secrets.test.ts 421 tests/service/service-sqlite-home.test.ts 127 tests/service/service-start-environment.test.ts -174 tests/service/service-stop-verification.test.ts +207 tests/service/service-stop-verification.test.ts 2354 tests/service/service-tier-capability.test.ts 433 tests/service/service-wsl-home-ownership.test.ts 3149 tests/service/service.test.ts 285 tests/service/shutdown-drain.test.ts 143 tests/service/shutdown-launcher.test.ts 156 tests/service/stale-state-purge.test.ts -324 tests/service/standalone-service.test.ts +81 tests/service/standalone-service.test.ts 12835 tests/service/stop-deferred-teardown.test.ts 145 tests/service/systemd-install-cleanup-hardening.test.ts 508 tests/service/winsw.test.ts @@ -2083,7 +2157,7 @@ 5376 tests/storage/api-storage-policy.test.ts 2934 tests/storage/api-storage.test.ts 31100 tests/storage/storage-cleanup.test.ts -31040 tests/storage/storage-mutation-race.test.ts +26814 tests/storage/storage-mutation-race.test.ts 2572 tests/storage/storage-policy-config-race.test.ts 6050 tests/storage/storage-policy-job-responsive.test.ts 256472 tests/storage/storage-policy.test.ts @@ -2092,7 +2166,7 @@ 2014 tests/storage/storage-scanner.test.ts 5111 tests/storage/storage-worker-lifecycle.test.ts 128 tests/storage/storage-worker-os-join-settle.test.ts -25046 tests/storage/storage-worker-teardown-isolate.test.ts +25280 tests/storage/storage-worker-teardown-isolate.test.ts 1657 tests/test-layout-tooling.test.ts 432 tests/test-layout.test.ts 159 tests/update/pnpm-command-isolation.test.ts @@ -2100,18 +2174,21 @@ 563 tests/update/update-bun-ownership-lease.test.ts 111 tests/update/update-desktop-badge.test.ts 127 tests/update/update-desktop-owner.test.ts +320 tests/update/update-guarded-ops.test.ts 11455 tests/update/update-job.test.ts 127 tests/update/update-mise-launcher-target.test.ts 165 tests/update/update-mise-node-runtime.test.ts 732 tests/update/update-mise.test.ts -583 tests/update/update-notify.test.ts +648 tests/update/update-notify.test.ts 493 tests/update/update-npm-cache-preflight.test.ts 110 tests/update/update-npm-invocation.test.ts +9357 tests/update/update-npm-timeout.test.ts 302 tests/update/update-pnpm.test.ts 617 tests/update/update-refresh.test.ts 58556 tests/update/update-restart-lease.test.ts 2811 tests/update/update-stop-classification.test.ts -392 tests/update/update-stop-first.test.ts +312 tests/update/update-stop-first.test.ts +11533 tests/update/update-teardown-handover.test.ts 1761 tests/update/update-transactional-leftovers.test.ts 350 tests/update/update-transactional.test.ts 338 tests/update/update-tray-handoff.test.ts @@ -2138,7 +2215,7 @@ 11246 tests/usage/request-history-index.test.ts 220 tests/usage/request-log-attempt-identity.test.ts 161 tests/usage/request-log-conversation.test.ts -461 tests/usage/request-log-estimate-cap.test.ts +303 tests/usage/request-log-estimate-cap.test.ts 381 tests/usage/request-log-generation-window.test.ts 206 tests/usage/request-log-jev.test.ts 112 tests/usage/request-log-model-filter.test.ts @@ -2150,7 +2227,7 @@ 318 tests/usage/request-pacing.test.ts 25796 tests/usage/upstream-failure-diagnostics.test.ts 416 tests/usage/usage-aggregate-cache.test.ts -99 tests/usage/usage-anthropic-fast-pricing.test.ts +109 tests/usage/usage-anthropic-fast-pricing.test.ts 126 tests/usage/usage-antigravity-55.test.ts 142 tests/usage/usage-attempt-delivery.test.ts 126 tests/usage/usage-cost.test.ts @@ -2174,13 +2251,14 @@ 94 tests/usage/usage-time-range.test.ts 129 tests/usage/usage-timeline.test.ts 1125 tests/usage/user-cost-overlay-coderabbit-regressions.test.ts -6190 tests/usage/user-cost-overlay-live-reconcile.test.ts +5333 tests/usage/user-cost-overlay-live-reconcile.test.ts 953 tests/usage/user-cost-overlay-provider-delete.test.ts 313 tests/videos/fulfill-video.test.ts 110 tests/videos/plan-video.test.ts 142 tests/videos/xai-video-client.test.ts +22612 tests/vision/mistral-vision-sidecar.test.ts 443 tests/vision/sidecar-abort.test.ts -224 tests/vision/sidecar-auth.test.ts +207 tests/vision/sidecar-auth.test.ts 289 tests/vision/sidecar-candidates.test.ts 2508 tests/vision/sidecar-settings-vision-controls.test.ts 1790 tests/vision/sidecar-settings-vision-filter.test.ts diff --git a/scripts/test-layout/layout-codex-collision.json b/scripts/test-layout/layout-codex-collision.json index 4f028bf7120..9de4af05843 100644 --- a/scripts/test-layout/layout-codex-collision.json +++ b/scripts/test-layout/layout-codex-collision.json @@ -1,5 +1,8 @@ { "codex-cli-windows-child.test.ts": "codex-integration", + "codex-cli-update-windows-apply-install.test.ts": "codex-integration", + "codex-cli-update-windows-apply-outcomes.test.ts": "codex-integration", + "codex-cli-update-windows-apply-shared.test.ts": "codex-integration", "codex-cli-update-windows-layout.test.ts": "codex-integration", "codex-cli-windows-plan.test.ts": "codex-integration", "codex-launcher-diagnostics.test.ts": "codex-integration", diff --git a/structure/codex-cli-update.md b/structure/codex-cli-update.md index 24abbc7df38..acac60cd64f 100644 --- a/structure/codex-cli-update.md +++ b/structure/codex-cli-update.md @@ -217,11 +217,14 @@ not npm's exit code. Version uses the pinned Node with the verified JS entrypoin then repeats selection/content observation; it does not attest arbitrary future CMD lookup. Cleanup errors remain separate from the result. The existing job execution layer retries result persistence without repeating installation. No automatic rollback or stale-lock recovery exists. -`tests/codex-integration/codex-cli-update-windows-apply.test.ts` covers real offline npm in private -shared fixtures, unrelated package/shim preservation, terminal close failure, partial mutations, -absence, selection, unknown retention, async pins and persistence retry. One JS launcher executes -a compiled CLR x64 backing fixture that verifies Job membership and returns the version. This is -executable-fixture evidence, not a run of the vendor Codex product. +`tests/codex-integration/codex-cli-update-windows-apply.test.ts` covers authority and toolchain pins. +Its siblings `tests/codex-integration/codex-cli-update-windows-apply-install.test.ts`, +`tests/codex-integration/codex-cli-update-windows-apply-outcomes.test.ts` and +`tests/codex-integration/codex-cli-update-windows-apply-shared.test.ts` cover real offline npm, +partial mutations, retention, persistence retry, unrelated package/shim preservation and terminal +close failure. `tests/helpers/codex-cli-windows-apply-fixture.ts` keeps cleanup ownership per file. +One JS launcher executes a compiled CLR x64 backing fixture that verifies Job membership and +returns the version. This is executable-fixture evidence, not a run of the vendor Codex product. ## Explicit POSIX apply diff --git a/tests/codex-integration/codex-cli-update-windows-apply-install.test.ts b/tests/codex-integration/codex-cli-update-windows-apply-install.test.ts new file mode 100644 index 00000000000..472e33cebe3 --- /dev/null +++ b/tests/codex-integration/codex-cli-update-windows-apply-install.test.ts @@ -0,0 +1,113 @@ +import { windowsTempAncestryPreload } from "../helpers/windows-temp-ancestry"; +import { expect } from "bun:test"; +import { copyFileSync, mkdirSync, readFileSync, existsSync } from "node:fs"; +import { join, dirname } from "node:path"; +import { applyCodexCliUpdate } from "../../src/codex/cli-update-apply"; +import { startWindowsCliChild } from "../../src/codex/windows-cli-child"; +import { createCodexCliUpdateFence, cancelCodexCliUpdateFence, createWorkerCommitWindow, codexCliUpdateIsCancelled, allocateCodexCliUpdateGateOwner } from "../../src/codex/cli-update-selection-gate"; +import { createWindowsApplyFixtures, native, WINDOWS_APPLY_BUDGET_MS, fixtureCleanupProven, type WorkerFixtureReply, mainRoot, backingRoot, write } from "../helpers/codex-cli-windows-apply-fixture"; + +const { liveFixtureRoots, fixture, approved } = createWindowsApplyFixtures(); + +native("a fresh Worker runs real offline Windows FFI install and closes only after native settlement", async () => { + let root: string | undefined, closed = false, errored = false, worker: Worker | undefined; + const requestId = crypto.randomUUID(), messages: WorkerFixtureReply[] = []; + try { + const f = await fixture(undefined, created => { root = created; liveFixtureRoots.add(created); }); + const id = await approved(f); + worker = new Worker(new URL("../helpers/windows-apply-worker.ts", import.meta.url), + { type: "module", preload: windowsTempAncestryPreload(f.root) }); + const joined = new Promise((resolve, reject) => { + worker!.addEventListener("message", event => { messages.push(event.data); }); + worker!.addEventListener("error", () => { errored = true; reject(new Error("offline Worker failed")); }, { once: true }); + worker!.addEventListener("close", () => { closed = true; resolve(); }, { once: true }); + }); + const gate = new SharedArrayBuffer(8), fence = createCodexCliUpdateFence(); + worker.postMessage({ requestId, planId: id, inspectionDeps: f.deps.inspectionDeps, target: f.target, gate, fence }); + await joined; + expect(messages.filter(m => m.type === "native-start")).toHaveLength(1); + expect(messages.filter(m => m.type === "fixture-error")).toHaveLength(0); + const results = messages.filter(m => m.type === "result"); + expect(results).toHaveLength(1); + expect(results[0]!.result).toMatchObject({ outcome: "applied", reason: "verified_target", leaseRetained: false, cleanupErrors: [] }); + expect(fixtureCleanupProven(messages, requestId, closed, errored)).toBe(true); + expect(Atomics.load(new Int32Array(gate), 0)).toBe(0); + expect(existsSync(join(f.prefix, ".ocx-codex-cli-apply.lock"))).toBe(false); + } finally { + // A still-live native Worker keeps its exact fixture; never terminate to fake settlement. + if (root && fixtureCleanupProven(messages, requestId, closed, errored)) liveFixtureRoots.delete(root); + } +}, WINDOWS_APPLY_BUDGET_MS); + +native("Windows cancellation won inside final synchronous scan cannot create an installer", async () => { + const f = await fixture(undefined, root => liveFixtureRoots.add(root)), id = await approved(f); + const fence = createCodexCliUpdateFence(), gate = new SharedArrayBuffer(8); + const gateOwner = allocateCodexCliUpdateGateOwner(gate); + let scans = 0, starts = 0; + const result = await applyCodexCliUpdate(id, { ...f.deps, + isCancelled: codexCliUpdateIsCancelled(fence), + commitWindow: createWorkerCommitWindow({ gate, fence, owner: gateOwner }), + scanProcesses: () => { + scans++; + if (Atomics.load(new Int32Array(gate), 0) === gateOwner) expect(cancelCodexCliUpdateFence(fence)).toBe(true); + return { kind: "observed", processes: [] }; + }, + startWindowsChild: invocation => { starts++; return startWindowsCliChild(invocation); }, + }); + if (!result.leaseRetained) liveFixtureRoots.delete(f.root); + expect(scans).toBeGreaterThan(0); + expect(result).toMatchObject({ outcome: "refused", reason: "cancelled", leaseRetained: false }); + expect(starts).toBe(0); + expect(Atomics.load(new Int32Array(gate), 0)).toBe(0); +}, WINDOWS_APPLY_BUDGET_MS); + +native("Windows apply runs real offline npm under owned Job, then verifies full target and version", async () => { + const f = await fixture(), id = await approved(f); + const result = await applyCodexCliUpdate(id, f.deps); + expect(result, JSON.stringify(result)).toMatchObject({ outcome: "applied", reason: "verified_target", + installerExitCode: 0, installedVersion: "1.1.0", leaseRetained: false, cleanupErrors: [] }); + expect(existsSync(join(f.prefix, ".ocx-codex-cli-apply.lock"))).toBe(false); +}, WINDOWS_APPLY_BUDGET_MS); + +native("Windows terminal no-op is not_applied even with nonzero installer exit", async () => { + const f = await fixture(), id = await approved(f); + const result = await applyCodexCliUpdate(id, { ...f.deps, install: async () => ({ terminal: true, exitCode: 17 }) }); + expect(result, JSON.stringify(result)).toMatchObject({ outcome: "not_applied", leaseRetained: false, cleanupErrors: [] }); +}, WINDOWS_APPLY_BUDGET_MS); + +native("Windows pack children and installer descendant share transaction ownership", async () => { + const f = await fixture(), realNode = join(f.deps.inspectionDeps.env.PATH, "node.exe"); + const realNpm = join(f.deps.inspectionDeps.env.PATH, "node_modules/npm/bin/npm-cli.js"); + const tools = join(f.root, "toolchain"), npmCli = join(tools, "node_modules/npm/bin/npm-cli.js"), trace = join(f.root, "trace.jsonl"); + mkdirSync(dirname(npmCli), { recursive: true }); copyFileSync(realNode, join(tools, "node.exe")); + write(join(tools, "node_modules/npm/package.json"), JSON.stringify({ name: "npm", version: "11.16.0", bin: { npm: "bin/npm-cli.js" } })); + const sources = Object.fromEntries([f.target.set.main, f.target.set.backing].map((a, i) => { + const path = join(f.root, `${i}.tgz`); write(path, i ? f.target.backing : f.target.main); return [`${a.name}@${a.version}`, path]; + })); + write(npmCli, [ + 'const fs=require("node:fs"), path=require("node:path"), cp=require("node:child_process");', + 'const args=process.argv.slice(2);', + `fs.appendFileSync(${JSON.stringify(trace)},JSON.stringify(args[0])+"\\n");`, + `const sources=${JSON.stringify(sources)};`, + 'if(args[0]==="pack") { const source=sources[args[1]]; if(!source)process.exit(91);', + 'const name=path.basename(source); fs.copyFileSync(source,path.join(args[args.indexOf("--pack-destination")+1],name));', + 'console.log(JSON.stringify([{filename:name}])); } else if(args[0]==="install") {', + `const r=cp.spawnSync(${JSON.stringify(realNode)},[${JSON.stringify(realNpm)},...args],{env:process.env,stdio:"inherit"});process.exit(r.status??92);`, + '} else process.exit(93);', + ].join("\n")); + f.deps.inspectionDeps.env.PATH = tools; + const id = await approved(f); + const result = await applyCodexCliUpdate(id, { ...f.deps, fetchArtifact: undefined }); + expect(result, JSON.stringify(result)).toMatchObject({ outcome: "applied", leaseRetained: false, cleanupErrors: [] }); + expect(readFileSync(trace, "utf8").trim().split("\n").map(line => JSON.parse(line))).toEqual(["pack", "pack", "install"]); +}, WINDOWS_APPLY_BUDGET_MS); + +native("Windows complete readback outranks a nonzero installer exit", async () => { + const f = await fixture(), id = await approved(f); + const result = await applyCodexCliUpdate(id, { ...f.deps, install: async () => { + for (const [path, bytes] of Object.entries(f.target.mainFiles)) write(join(f.prefix, mainRoot, path), bytes); + for (const [path, bytes] of Object.entries(f.target.backingFiles)) write(join(f.prefix, backingRoot, path), bytes); + return { terminal: true, exitCode: 17 }; + } }); + expect(result, JSON.stringify(result)).toMatchObject({ outcome: "applied", installerExitCode: 17, cleanupErrors: [] }); +}, WINDOWS_APPLY_BUDGET_MS); diff --git a/tests/codex-integration/codex-cli-update-windows-apply-outcomes.test.ts b/tests/codex-integration/codex-cli-update-windows-apply-outcomes.test.ts new file mode 100644 index 00000000000..ab0244addb5 --- /dev/null +++ b/tests/codex-integration/codex-cli-update-windows-apply-outcomes.test.ts @@ -0,0 +1,112 @@ +import { windowsTempAncestryPreload } from "../helpers/windows-temp-ancestry"; +import { expect } from "bun:test"; +import { mkdirSync, readFileSync, writeFileSync, existsSync, renameSync } from "node:fs"; +import { join, dirname } from "node:path"; +import { applyCodexCliUpdate } from "../../src/codex/cli-update-apply"; +import { createCodexCliUpdatePlan } from "../../src/codex/cli-update-plan"; +import { inspectCodexCliInstall } from "../../src/codex/cli-install-provenance"; +import { holdWindowsCodexCliPlanToolchain, withWindowsCodexCliPlanToolchain } from "../../src/codex/cli-windows-plan-provenance"; +import { repoPath, repoRoot } from "../helpers/repo-root"; +import { spawnTestChild } from "../helpers/spawn-test-child"; +import { runCodexCliUpdateJobWork } from "../../src/codex/cli-update-job-execution"; +import { createWindowsApplyFixtures, native, WINDOWS_APPLY_BUDGET_MS, WINDOWS_APPLY_CHILD_BUDGET_MS, mainRoot, backingRoot, nativePath, write } from "../helpers/codex-cli-windows-apply-fixture"; + +const { fixture, approved } = createWindowsApplyFixtures(); + +native("Windows cancellation and unknown session observation cannot start an installer", async () => { + const f = await fixture(), id = await approved(f); let installs = 0; + const install = async () => { installs++; return { terminal: true, exitCode: 0 }; }; + const abort = new AbortController(); abort.abort(); + expect((await applyCodexCliUpdate(id, { ...f.deps, install, signal: abort.signal })).reason).toBe("cancelled"); + expect((await applyCodexCliUpdate(id, { ...f.deps, install, + scanProcesses: () => ({ kind: "unavailable" }) })).reason).toBe("blocked_process_state_unknown"); + let scans = 0; + expect((await applyCodexCliUpdate(id, { ...f.deps, install, + scanProcesses: () => ++scans < 3 ? { kind: "observed", processes: [] } : { kind: "unavailable" } })).reason) + .toBe("blocked_process_state_unknown"); + expect(scans).toBe(3); + expect(installs).toBe(0); +}, WINDOWS_APPLY_BUDGET_MS); + +native.each(["auxiliary", "shim", "hidden-lock", "extra-file", "new-empty-backing", "selection"] as const)("Windows partial %s refuses not_applied", async kind => { + const f = await fixture(); + if (kind === "new-empty-backing") { + const nested = join(f.prefix, mainRoot, "bin", "node_modules", "@openai", "codex-win32-x64"); + mkdirSync(dirname(nested), { recursive: true }); renameSync(join(f.prefix, backingRoot), nested); + } + const id = await approved(f); + const result = await applyCodexCliUpdate(id, { ...f.deps, install: async () => { + if (kind === "auxiliary") write(join(f.prefix, mainRoot, "README.md"), "changed"); + if (kind === "shim") write(join(f.prefix, "codex.ps1"), "changed"); + if (kind === "hidden-lock") write(join(f.prefix, "node_modules/.package-lock.json"), "{}"); + if (kind === "extra-file") write(join(f.prefix, backingRoot, "unexpected.txt"), "extra"); + if (kind === "new-empty-backing") mkdirSync(join(f.prefix, backingRoot)); + if (kind === "selection") f.deps.inspectionDeps.env.CODEX_CLI_PATH = join(f.prefix, "other.cmd"); + return { terminal: true, exitCode: 1 }; + } }); + expect(result, JSON.stringify(result)).toMatchObject({ outcome: "ambiguous", leaseRetained: false }); +}, WINDOWS_APPLY_BUDGET_MS); + +native("Windows uncertain installer retains lease and staging until owning process exits", async () => { + const f = await fixture(), id = await approved(f); + const entry = join(f.root, "uncertain.test.ts"), receipt = join(f.root, "result.json"); + const literals = JSON.stringify({ id, inspectionDeps: f.deps.inspectionDeps, target: f.deps.resolveTarget(), + main: f.target.main.toString("base64"), backing: f.target.backing.toString("base64"), receipt, prefix: f.prefix }); + writeFileSync(entry, [ + 'import { test, expect } from "bun:test";', + 'import { existsSync, writeFileSync } from "node:fs";', + `import { applyCodexCliUpdate } from ${JSON.stringify(repoPath("src/codex/cli-update-apply.ts"))};`, + `const f = ${literals};`, + 'test("retained transaction", async () => {', + 'const result = await applyCodexCliUpdate(f.id, { platform:"win32", inspectionDeps:f.inspectionDeps,', + 'resolveTarget:()=>f.target, scanProcesses:()=>({kind:"observed",processes:[]}),', + 'fetchArtifact:async a=>Buffer.from(a.installName==="@openai/codex"?f.main:f.backing,"base64"),', + 'install:async()=>({terminal:false,exitCode:null}) });', + 'const stage=existsSync(f.prefix+"/.ocx-codex-cli-apply.lock/stage");', + 'writeFileSync(f.receipt,JSON.stringify({result,stage}));', + 'expect(result.outcome).toBe("ambiguous"); expect(result.leaseRetained).toBe(true); expect(stage).toBe(true);', + `},${WINDOWS_APPLY_CHILD_BUDGET_MS});`, + ].join("\n")); + const child = await spawnTestChild([process.execPath, "test", "--preload", windowsTempAncestryPreload(f.root), + "--no-env-file", "--no-install", "--timeout", String(WINDOWS_APPLY_CHILD_BUDGET_MS), entry], + { cwd: repoRoot(), env: process.env, deadlineMs: WINDOWS_APPLY_CHILD_BUDGET_MS + 5000 }); + expect(child.reaped).toBe(true); expect(child.pipesClosed).toBe(true); expect(child.exitCode, child.stderr).toBe(0); + expect(JSON.parse(readFileSync(receipt, "utf8"))).toMatchObject({ stage: true, + result: { outcome: "ambiguous", reason: "installer_state_unknown", leaseRetained: true } }); + // The child has exited: only now can the fixture's retained kernel handles be gone. +}, WINDOWS_APPLY_BUDGET_MS); + +native("Windows completion persistence retry does not repeat the installer", async () => { + const f = await fixture(), id = await approved(f); let installs = 0, finishes = 0; + await runCodexCliUpdateJobWork(() => applyCodexCliUpdate(id, { ...f.deps, + install: async () => { installs++; return { terminal: true, exitCode: 0 }; } }), { + begin: async () => 1, + finish: async (_revision, result) => { + expect(result.outcome).toBe("not_applied"); + if (++finishes < 3) throw Object.assign(new Error("fixture busy"), { code: "EBUSY" }); + return null; + }, read: async () => null, release: async () => {}, + }); + expect(installs).toBe(1); expect(finishes).toBe(3); +}, WINDOWS_APPLY_BUDGET_MS); + +native("Windows toolchain pins survive an awaited callback; bounded shared prefix is eligible", async () => { + const f = await fixture(); + const tools = join(f.root, "toolchain"), npmCli = join(tools, "node_modules/npm/bin/npm-cli.js"); + write(join(tools, "node.exe"), f.old.backingFiles[nativePath]); + write(join(tools, "node_modules/npm/package.json"), JSON.stringify({ name: "npm", version: "11.0.0", bin: { npm: "bin/npm-cli.js" } })); + write(npmCli, "// never executed\n"); f.deps.inspectionDeps.env.PATH = tools; + const report = await inspectCodexCliInstall({ ...f.deps.inspectionDeps, observeInstallContent: true }); + expect(report.managed).toBe(true); + expect(await withWindowsCodexCliPlanToolchain(report, async () => { + await Bun.sleep(10); + // This write must still be denied after await; returning a promise while + // releasing native pins early would make this assertion fail. + expect(() => writeFileSync(npmCli, "replacement")).toThrow(); return 42; + })).toBe(42); + writeFileSync(npmCli, "// changed after release\n"); + const refreshed = await inspectCodexCliInstall({ ...f.deps.inspectionDeps, observeInstallContent: true }); + const pin = await holdWindowsCodexCliPlanToolchain(refreshed); expect(pin).not.toBeNull(); expect(await pin!.release()).toBe(true); + mkdirSync(join(f.prefix, "node_modules", "unrelated")); + expect((await createCodexCliUpdatePlan(f.deps)).applicable).toBe(true); +}, WINDOWS_APPLY_BUDGET_MS); diff --git a/tests/codex-integration/codex-cli-update-windows-apply-shared.test.ts b/tests/codex-integration/codex-cli-update-windows-apply-shared.test.ts new file mode 100644 index 00000000000..26496f34e5e --- /dev/null +++ b/tests/codex-integration/codex-cli-update-windows-apply-shared.test.ts @@ -0,0 +1,139 @@ +import { createCodexCliTestRoot } from "../helpers/codex-cli-fixture-root"; +import { windowsTempAncestryPreload } from "../helpers/windows-temp-ancestry"; +import { expect } from "bun:test"; +import { mkdirSync, readFileSync, writeFileSync, existsSync, symlinkSync, unlinkSync, linkSync } from "node:fs"; +import { join } from "node:path"; +import { applyCodexCliUpdate } from "../../src/codex/cli-update-apply"; +import { createCodexCliUpdatePlan } from "../../src/codex/cli-update-plan"; +import { repoPath, repoRoot } from "../helpers/repo-root"; +import { spawnTestChild } from "../helpers/spawn-test-child"; +import { startWindowsCliChild, type WindowsCliChild } from "../../src/codex/windows-cli-child"; +import { windowsInstallNamespaceSupported } from "../../src/codex/cli-update-windows-observation"; +import { createWindowsApplyFixtures, native, WINDOWS_APPLY_BUDGET_MS, WINDOWS_APPLY_CHILD_BUDGET_MS, mainRoot, backingRoot, write } from "../helpers/codex-cli-windows-apply-fixture"; + +const { roots, fixture, approved } = createWindowsApplyFixtures(); + +native("Windows shared prefix preserves unrelated package and shims while executing x64 backing", async () => { + // Use the existing Windows compiler, with no package install or downloaded binary. + // This is a CLR x64 executable fixture with actual Win32 Job observation, not vendor Codex. + const build = createCodexCliTestRoot("ocx-win-apply-"); roots.push(build); + const source = join(build, "Backing.cs"), exe = join(build, "backing.exe"), trace = join(build, "native.json"); + write(source, [ + 'using System; using System.IO; using System.Runtime.InteropServices;', + 'class Backing {', + '[DllImport("kernel32.dll")] static extern IntPtr GetCurrentProcess();', + '[DllImport("kernel32.dll")] static extern bool IsProcessInJob(IntPtr p, IntPtr j, out bool inside);', + 'static int Main(string[] args) { bool inside;', + 'if(IntPtr.Size!=8 || args.Length!=1 || args[0]!="--version" || !IsProcessInJob(GetCurrentProcess(),IntPtr.Zero,out inside) || !inside)return 93;', + 'var self=System.Diagnostics.Process.GetCurrentProcess();', + `File.WriteAllText(@"${trace.replaceAll('"', '""')}", "{\\"inJob\\":true,\\"x64\\":true,\\"pid\\":"+self.Id+",\\"startUtc\\":\\""+self.StartTime.ToUniversalTime().ToString("o")+"\\"}");`, + 'Console.WriteLine("codex-cli 1.1.0"); return 0; } }', + ].join("\n")); + const compiler = join(process.env.SystemRoot ?? "C:/Windows", "Microsoft.NET/Framework64/v4.0.30319/csc.exe"); + expect(existsSync(compiler), "x64 fixture compiler must be available; do not substitute a synthetic PE").toBe(true); + const compiled = await spawnTestChild([compiler, "/nologo", "/platform:x64", "/target:exe", `/out:${exe}`, source], + { cwd: build, env: process.env, deadlineMs: 10000 }); + expect(compiled.reaped && compiled.pipesClosed).toBe(true); expect(compiled.exitCode, compiled.stdout + compiled.stderr).toBe(0); + const f = await fixture(readFileSync(exe)); + const unrelated = { "node_modules/unrelated/package.json": '{"name":"unrelated","version":"2.0.0","bin":"index.js"}', + "node_modules/unrelated/index.js": '#!/usr/bin/env node\nconsole.log("unrelated");\n', + "unrelated": "unrelated bare shim\n", "unrelated.cmd": "unrelated cmd shim\n", "unrelated.ps1": "unrelated powershell shim\n" }; + for (const [path, bytes] of Object.entries(unrelated)) write(join(f.prefix, path), bytes); + const children: WindowsCliChild[] = []; + const id = await approved(f), result = await applyCodexCliUpdate(id, { ...f.deps, startWindowsChild: invocation => { + const child = startWindowsCliChild(invocation); children.push(child); return child; + } }); + expect(result, JSON.stringify(result)).toMatchObject({ outcome: "applied", reason: "verified_target", installerExitCode: 0, + installedVersion: "1.1.0", leaseRetained: false, cleanupErrors: [], verificationPid: null }); + const backing = JSON.parse(readFileSync(trace, "utf8")); + expect(backing).toMatchObject({ inJob: true, x64: true }); expect(backing.pid).toBeGreaterThan(0); + expect(Number.isNaN(Date.parse(backing.startUtc))).toBe(false); + expect(children).toHaveLength(2); + for (const child of children) { + expect(child.observe()).toMatchObject({ terminal: true, unknown: false }); + expect((await child.wait()).cleanupComplete).toBe(true); expect(child.native.handles.size).toBe(0); + } + // Preserve actual descendant identity in the supervisor's bounded test log. + console.log("owned x64 fixture", JSON.stringify({ backing, jobs: children.map(c => ({ pid: c.pid, start: c.creationTime })) })); + for (const [path, bytes] of Object.entries(unrelated)) expect(readFileSync(join(f.prefix, path), "utf8")).toBe(bytes); + expect(existsSync(join(f.prefix, ".ocx-codex-cli-apply.lock"))).toBe(false); +}, WINDOWS_APPLY_BUDGET_MS); + +native.each(["package", "shim", "new-entry"] as const)("Windows shared prefix unexpected %s mutation is ambiguous", async kind => { + const f = await fixture(); + write(join(f.prefix, "node_modules/unrelated/package.json"), '{"name":"unrelated","version":"2.0.0"}'); + write(join(f.prefix, "unrelated.cmd"), "original"); + const id = await approved(f); + const result = await applyCodexCliUpdate(id, { ...f.deps, install: async () => { + for (const [path, bytes] of Object.entries(f.target.mainFiles)) write(join(f.prefix, mainRoot, path), bytes); + for (const [path, bytes] of Object.entries(f.target.backingFiles)) write(join(f.prefix, backingRoot, path), bytes); + write(join(f.prefix, kind === "package" ? "node_modules/unrelated/package.json" : kind === "shim" ? "unrelated.cmd" : "unexpected"), "changed"); + return { terminal: true, exitCode: 0 }; + } }); + expect(result).toMatchObject({ outcome: "ambiguous", leaseRetained: false }); +}, WINDOWS_APPLY_BUDGET_MS); + +native("Windows shared namespace still refuses linked unrelated entries", async () => { + const f = await fixture(), outside = join(f.root, "outside"), alias = join(f.prefix, "node_modules/unrelated"); + mkdirSync(outside); write(join(outside, "value"), "must not be followed or changed"); + symlinkSync(outside, alias, "junction"); + expect(windowsInstallNamespaceSupported(f.prefix)).toBe(false); + expect((await createCodexCliUpdatePlan(f.deps)).refusal).toBe("windows_apply_disabled"); + unlinkSync(alias); + linkSync(join(outside, "value"), join(f.prefix, "unrelated.cmd")); + expect(windowsInstallNamespaceSupported(f.prefix)).toBe(false); + expect(readFileSync(join(outside, "value"), "utf8")).toBe("must not be followed or changed"); +}, WINDOWS_APPLY_BUDGET_MS); + +native.each(["installer", "version"] as const)("Windows %s terminal EOF with native CloseHandle failure retains owner and reports cleanup", async policy => { + const f = await fixture(), id = await approved(f); + const entry = join(f.root, "cleanup.test.ts"), receipt = join(f.root, "cleanup.json"); + const literals = JSON.stringify({ id, inspectionDeps: f.deps.inspectionDeps, target: f.deps.resolveTarget(), + main: f.target.main.toString("base64"), backing: f.target.backing.toString("base64"), receipt, prefix: f.prefix, policy, + mainFiles: f.target.mainFiles, backingFiles: Object.fromEntries(Object.entries(f.target.backingFiles).map(([p, b]) => [p, Buffer.from(b).toString("base64")])) }); + write(entry, [ + 'import { test, expect } from "bun:test";', + 'import { existsSync, writeFileSync, readFileSync } from "node:fs";', + 'import { join } from "node:path";', + `import { applyCodexCliUpdate } from ${JSON.stringify(repoPath("src/codex/cli-update-apply.ts"))};`, + `import { WindowsChildNative } from ${JSON.stringify(repoPath("src/codex/windows-cli-child-native.ts"))};`, + `import { startWindowsCliChildWithNative } from ${JSON.stringify(repoPath("src/codex/windows-cli-child.ts"))};`, + `import { normalizeCodexCliJobResult } from ${JSON.stringify(repoPath("src/codex/cli-update-job-execution.ts"))};`, + `import { projectCodexCliUpdateJobLifecycle } from ${JSON.stringify(repoPath("src/codex/cli-update-job.ts"))};`, + `const f=${literals};`, + 'test("terminal cleanup ownership",async()=>{ let child, realClose; const native=new WindowsChildNative();', + 'try { const result=await applyCodexCliUpdate(f.id,{platform:"win32",inspectionDeps:f.inspectionDeps,', + 'resolveTarget:()=>f.target,scanProcesses:()=>({kind:"observed",processes:[]}),', + 'fetchArtifact:async a=>Buffer.from(a.installName==="@openai/codex"?f.main:f.backing,"base64"),', + 'install:f.policy==="version"?async()=>{ for(const [p,b] of Object.entries(f.mainFiles))writeFileSync(join(f.prefix,"node_modules/@openai/codex",p),b);', + 'for(const [p,b] of Object.entries(f.backingFiles))writeFileSync(join(f.prefix,"node_modules/@openai/codex-win32-x64",p),Buffer.from(b,"base64"));return {terminal:true,exitCode:0}; }:undefined,', + 'startWindowsChild: invocation=>{ child=startWindowsCliChildWithNative(invocation,native);realClose=native.k.CloseHandle;', + 'native.k.CloseHandle=h=>h===child.process?0:realClose(h);return child; }});', + 'expect(child.observe().terminal).toBe(true);expect(child.pipe.eof).toBe(true);', + 'expect((await child.wait()).cleanupComplete).toBe(false);expect(native.handles.has(child.process)).toBe(true);', + 'expect(result).toMatchObject({outcome:"ambiguous",reason:"child_cleanup_unverified",leaseRetained:true,cleanupErrors:["child_cleanup_failed"]});', + 'expect(JSON.parse(readFileSync(join(f.prefix,"node_modules/@openai/codex/package.json"),"utf8")).version).toBe("1.1.0");', + 'expect(normalizeCodexCliJobResult(result)).toEqual(result);', + 'expect(projectCodexCliUpdateJobLifecycle({...result,status:"finished",active:false})).toMatchObject({childState:"terminal",leaseState:"retained"});', + 'const stage=existsSync(join(f.prefix,".ocx-codex-cli-apply.lock/stage"));expect(stage).toBe(true);', + 'writeFileSync(f.receipt,JSON.stringify({result,stage,terminal:child.observe().terminal,handles:native.handles.size}));', + '} finally { if(realClose)native.k.CloseHandle=realClose; for(const h of [...native.handles])native.close(h);expect(native.dispose()).toBe(true); }', + `},${WINDOWS_APPLY_CHILD_BUDGET_MS});`, + ].join("\n")); + const result = await spawnTestChild([process.execPath, "test", "--preload", windowsTempAncestryPreload(f.root), + "--no-env-file", "--no-install", "--timeout", String(WINDOWS_APPLY_CHILD_BUDGET_MS), entry], + { cwd: repoRoot(), env: process.env, deadlineMs: WINDOWS_APPLY_CHILD_BUDGET_MS + 5000 }); + expect(result.reaped && result.pipesClosed).toBe(true); expect(result.exitCode, result.stderr).toBe(0); + expect(JSON.parse(readFileSync(receipt, "utf8"))).toMatchObject({ terminal: true, handles: 1, stage: true }); + // Retained authority is intentionally not released by production. This isolated + // owner has exited, so only now may afterEach remove its private fixture prefix. +}, WINDOWS_APPLY_BUDGET_MS); + +native("Windows shared prefix terminal no-op preserves full observed original", async () => { + const f = await fixture(); + write(join(f.prefix, "node_modules/unrelated/package.json"), '{"name":"unrelated","version":"2.0.0"}'); + write(join(f.prefix, "unrelated.cmd"), "original"); + const id = await approved(f); + const result = await applyCodexCliUpdate(id, { ...f.deps, install: async () => ({ terminal: true, exitCode: 0 }) }); + expect(result).toMatchObject({ outcome: "not_applied", reason: "original_install_unchanged", leaseRetained: false, cleanupErrors: [] }); +}, WINDOWS_APPLY_BUDGET_MS); diff --git a/tests/codex-integration/codex-cli-update-windows-apply.test.ts b/tests/codex-integration/codex-cli-update-windows-apply.test.ts index 3facc2252c4..8b3eaf46dd9 100644 --- a/tests/codex-integration/codex-cli-update-windows-apply.test.ts +++ b/tests/codex-integration/codex-cli-update-windows-apply.test.ts @@ -1,68 +1,26 @@ -import { createCodexCliTestRoot } from "../helpers/codex-cli-fixture-root"; -import { SPAWN_BUDGET_MS } from "../helpers/test-budget"; -import { trustWindowsTempFixtureAncestry, windowsTempAncestryPreload } from "../helpers/windows-temp-ancestry"; -import { afterEach, expect, test } from "bun:test"; -import { cpSync, realpathSync, copyFileSync, mkdirSync, readFileSync, writeFileSync, existsSync, renameSync, symlinkSync, unlinkSync, linkSync } from "node:fs"; -import { join, dirname, parse } from "node:path"; +import { expect, test } from "bun:test"; +import { readFileSync, writeFileSync, existsSync, renameSync } from "node:fs"; +import { join } from "node:path"; import { applyCodexCliUpdate } from "../../src/codex/cli-update-apply"; import { createCodexCliUpdatePlan } from "../../src/codex/cli-update-plan"; import { inspectCodexCliInstall } from "../../src/codex/cli-install-provenance"; -import { holdWindowsCodexCliPlanToolchain, withWindowsCodexCliPlanToolchain } from "../../src/codex/cli-windows-plan-provenance"; +import { holdWindowsCodexCliPlanToolchain } from "../../src/codex/cli-windows-plan-provenance"; import { openWindowsCliApplyAuthority, type WindowsApplyAcquisition } from "../../src/codex/cli-update-job-store-windows"; -import { hardenSecretDirAsync } from "../../src/lib/windows-secret-acl"; import { trackBackgroundWork } from "../../src/lib/background-work"; -import { removeTreeAfterBackgroundWork } from "../helpers/remove-tree"; -import { fixtureArtifact, fixtureTar } from "../helpers/codex-cli-apply-artifact"; -import { fixturePath, repoPath, repoRoot } from "../helpers/repo-root"; +import { repoPath } from "../helpers/repo-root"; import { spawnTestChild } from "../helpers/spawn-test-child"; -import { runCodexCliUpdateJobWork } from "../../src/codex/cli-update-job-execution"; import { startWindowsCliChild, type WindowsCliChild } from "../../src/codex/windows-cli-child"; -import { windowsInstallNamespaceSupported } from "../../src/codex/cli-update-windows-observation"; -import { createCodexCliUpdateFence, cancelCodexCliUpdateFence, createWorkerCommitWindow, - codexCliUpdateIsCancelled, allocateCodexCliUpdateGateOwner, codexCliUpdateSelectionGate, resetCodexCliSelectionGatesForTests } from "../../src/codex/cli-update-selection-gate"; +import { createCodexCliUpdateFence, createWorkerCommitWindow, allocateCodexCliUpdateGateOwner, codexCliUpdateSelectionGate, resetCodexCliSelectionGatesForTests } from "../../src/codex/cli-update-selection-gate"; import { installCodexShim } from "../../src/codex/shim"; import { clearPersistedCodexRuntime } from "../../src/codex/runtime"; import { restartCodexDesktopApp } from "../../src/codex/desktop-app-restart"; import { recoverWindowsCodexCliInstallations } from "../../src/codex/cli-update-windows-apply"; import { windowsNpmExecutionArgs } from "../../src/codex/windows-npm-execution"; import { CodexRemoteWorkspaceRuntimeFactory, RemoteWorkspaceCoordinator } from "../../src/remote-control"; +import { createWindowsApplyFixtures, native, WINDOWS_APPLY_BUDGET_MS, fixtureCleanupProven, type WorkerFixtureReply, write } from "../helpers/codex-cli-windows-apply-fixture"; + +const { liveFixtureRoots, fixture, approved } = createWindowsApplyFixtures(); -const native = process.platform === "win32" && process.arch === "x64" ? test : test.skip; -// Full native npm-tree ACL/identity renewal and real children are the proof. -// Bound this class for a shared Windows host; keep every admission/readback assertion. -const WINDOWS_APPLY_BUDGET_MS = 4 * SPAWN_BUDGET_MS; -const WINDOWS_APPLY_CHILD_BUDGET_MS = 2 * SPAWN_BUDGET_MS; -const roots: string[] = []; -const liveFixtureRoots = new Set(); -type WorkerFixtureReply = { type: string; requestId?: string; cleanupConfirmed?: boolean; result?: import("../../src/codex/cli-update-apply").CodexCliApplyResult }; -function fixtureCleanupProven(messages: readonly unknown[], requestId: string, closed: boolean, errored: boolean): boolean { - if (!closed || errored) return false; - const replies: WorkerFixtureReply[] = []; - for (const value of messages) { - if (!value || typeof value !== "object" || Array.isArray(value)) return false; - const message = value as WorkerFixtureReply; - // Assertions can fail independently: teardown authority rejects ALL foreign, - // malformed or error traffic, including traffic mixed with a valid result. - if (message.requestId !== requestId || !["native-start", "result"].includes(message.type)) return false; - if (message.type === "native-start" && (value as { committed?: unknown }).committed !== true) return false; - if (message.type === "result" && (!message.result || typeof message.result !== "object" - || Array.isArray(message.result) || message.cleanupConfirmed !== true)) return false; - if (message.type === "result") { - const result = message.result!; - const version = (value: unknown) => value === null || typeof value === "string"; - if (!["applied", "not_applied", "refused", "ambiguous"].includes(result.outcome) - || typeof result.reason !== "string" || !/^[a-f0-9]{32}$/.test(result.planId) - || !version(result.installedVersion) || !version(result.targetVersion) - || !(result.installerExitCode === null || Number.isInteger(result.installerExitCode)) - || !(result.verificationPid === null || (Number.isInteger(result.verificationPid) && result.verificationPid > 0))) return false; - } - replies.push(message); - } - const results = replies.filter(message => message.type === "result"); - return results.length === 1 - && results[0]!.cleanupConfirmed === true && results[0]!.result?.leaseRetained === false - && Array.isArray(results[0]!.result?.cleanupErrors) && results[0]!.result!.cleanupErrors.length === 0; -} test("Worker close alone never authorizes removing a native fixture", () => { const result: import("../../src/codex/cli-update-apply").CodexCliApplyResult = { outcome: "applied", reason: "verified_target", planId: "a".repeat(32), installedVersion: "1.0.0", targetVersion: "1.1.0", @@ -82,68 +40,6 @@ test("Worker close alone never authorizes removing a native fixture", () => { expect(fixtureCleanupProven([safe], "owned", false, false)).toBe(false); expect(fixtureCleanupProven([safe], "owned", true, false)).toBe(true); }); -afterEach(async () => { - for (const root of roots.splice(0)) { - if (liveFixtureRoots.has(root)) { roots.push(root); continue; } - await removeTreeAfterBackgroundWork(root); - } -}); -const mainRoot = "node_modules/@openai/codex", backingRoot = "node_modules/@openai/codex-win32-x64"; -const nativePath = "vendor/x86_64-pc-windows-msvc/bin/codex.exe"; -const write = (path: string, bytes: string | Buffer) => { mkdirSync(dirname(path), { recursive: true }); writeFileSync(path, bytes); }; -function artifacts(version: string, executable?: Buffer) { - const pe = Buffer.alloc(512); pe.write("MZ"); pe.writeUInt32LE(64, 60); pe.write("PE\0\0", 64); - pe.writeUInt16LE(0x8664, 68); pe.writeUInt16LE(1, 70); pe.writeUInt16LE(240, 84); pe.writeUInt16LE(2, 86); pe.writeUInt16LE(0x20b, 88); - // Synthetic PE only. The real Node verification child executes this fixture's JS; - // this is an npm/readback test, not a claim that a real Codex native binary ran. - const mainFiles = { "package.json": JSON.stringify({ name: "@openai/codex", version, - bin: { codex: "bin/codex.js" }, optionalDependencies: { "@openai/codex-win32-x64": version } }), - "bin/codex.js": executable ? '#!/usr/bin/env node\n' + - 'const cp=require("node:child_process"), path=require("node:path");\n' + - 'const exe=path.join(__dirname,"../../codex-win32-x64/vendor/x86_64-pc-windows-msvc/bin/codex.exe");\n' + - 'const child=cp.spawn(exe,process.argv.slice(2),{stdio:"inherit",windowsHide:true});\n' + - 'child.on("error",()=>{process.exitCode=91});child.on("exit",code=>{process.exitCode=code??92});\n' - : `#!/usr/bin/env node\nconsole.log("codex-cli ${version}");\n`, "README.md": "auxiliary\n" }; - const backingFiles = { "package.json": JSON.stringify({ name: "@openai/codex-win32-x64", version, os: ["win32"], cpu: ["x64"] }), - [nativePath]: executable ?? pe, "vendor/auxiliary.txt": "auxiliary\n" }; - const main = fixtureTar(mainFiles), backing = fixtureTar(backingFiles); - return { mainFiles, backingFiles, main, backing, set: { platform: "win32" as const, arch: "x64", - main: fixtureArtifact(main, version), backing: fixtureArtifact(backing, version, "@openai/codex-win32-x64", "@openai/codex-win32-x64") } }; -} -async function fixture(executable?: Buffer, onCreated?: (root: string) => void) { - // This host's observed writable AppData ancestry refused; this is not a ban on - // every profile. Evaluate actual ancestry ACL/owner/reparse evidence instead. - // Create only this test-owned directory below the repository's volume anchor; - // never repair or suppress metadata on the host's existing ancestor directories. - const root = createCodexCliTestRoot("ocx-win-apply-"); - onCreated?.(root); roots.push(root); - await hardenSecretDirAsync(root, { required: true }); - trustWindowsTempFixtureAncestry(root); - const prefix = join(root, "prefix"); mkdirSync(prefix); - await hardenSecretDirAsync(prefix, { required: true }); - const old = artifacts("1.0.0"), target = artifacts("1.1.0", executable); - for (const [relative, bytes] of Object.entries(old.mainFiles)) write(join(prefix, mainRoot, relative), bytes); - for (const [relative, bytes] of Object.entries(old.backingFiles)) write(join(prefix, backingRoot, relative), bytes); - const shims = JSON.parse(readFileSync(fixturePath("codex-windows-npm-shims.json"), "utf8")); - for (const [name, bytes] of Object.entries(shims.files)) write(join(prefix, name), String(bytes)); - const sourceNode = realpathSync(Bun.which("node.exe")!); - const nodeDir = join(root, "nodejs"); mkdirSync(nodeDir); - copyFileSync(sourceNode, join(nodeDir, "node.exe")); - cpSync(join(dirname(sourceNode), "node_modules", "npm"), join(nodeDir, "node_modules", "npm"), { recursive: true }); - const inspectionDeps = { env: { CODEX_CLI_PATH: join(prefix, "codex.cmd"), PATH: nodeDir, PATHEXT: ".EXE;.CMD" }, - configDir: join(root, "absent-home"), arch: "x64" as const, selectionAttested: true }; - const deps = { platform: "win32" as const, inspectionDeps, - resolveTarget: () => ({ kind: "resolved" as const, version: "1.1.0", integrity: target.set.main.integrity, artifacts: target.set }), - scanProcesses: () => ({ kind: "observed" as const, processes: [] }), - fetchArtifact: async (artifact: typeof target.set.main) => artifact.installName === "@openai/codex" ? target.main : target.backing }; - return { root, prefix, old, target, deps }; -} -async function approved(f: Awaited>) { - const plan = await createCodexCliUpdatePlan(f.deps); - expect(plan, JSON.stringify(plan)).toMatchObject({ applicable: true, refusal: null }); - expect(plan.planId).toMatch(/^[a-f0-9]{32}$/); return plan.planId!; -} - native("Windows apply holds distinct prefix lease and private staging, then releases exact owners", async () => { // Register before fixture setup/acquisition can yield. A failed assertion or // unknown native release leaves both the exact root and preload producer held. @@ -323,329 +219,3 @@ native("Windows npm execution refuses ancestor CommonJS and ESM modules outside expect(existsSync(marker)).toBe(false); } }, WINDOWS_APPLY_BUDGET_MS); - -native("a fresh Worker runs real offline Windows FFI install and closes only after native settlement", async () => { - let root: string | undefined, closed = false, errored = false, worker: Worker | undefined; - const requestId = crypto.randomUUID(), messages: WorkerFixtureReply[] = []; - try { - const f = await fixture(undefined, created => { root = created; liveFixtureRoots.add(created); }); - const id = await approved(f); - worker = new Worker(new URL("../helpers/windows-apply-worker.ts", import.meta.url), - { type: "module", preload: windowsTempAncestryPreload(f.root) }); - const joined = new Promise((resolve, reject) => { - worker!.addEventListener("message", event => { messages.push(event.data); }); - worker!.addEventListener("error", () => { errored = true; reject(new Error("offline Worker failed")); }, { once: true }); - worker!.addEventListener("close", () => { closed = true; resolve(); }, { once: true }); - }); - const gate = new SharedArrayBuffer(8), fence = createCodexCliUpdateFence(); - worker.postMessage({ requestId, planId: id, inspectionDeps: f.deps.inspectionDeps, target: f.target, gate, fence }); - await joined; - expect(messages.filter(m => m.type === "native-start")).toHaveLength(1); - expect(messages.filter(m => m.type === "fixture-error")).toHaveLength(0); - const results = messages.filter(m => m.type === "result"); - expect(results).toHaveLength(1); - expect(results[0]!.result).toMatchObject({ outcome: "applied", reason: "verified_target", leaseRetained: false, cleanupErrors: [] }); - expect(fixtureCleanupProven(messages, requestId, closed, errored)).toBe(true); - expect(Atomics.load(new Int32Array(gate), 0)).toBe(0); - expect(existsSync(join(f.prefix, ".ocx-codex-cli-apply.lock"))).toBe(false); - } finally { - // A still-live native Worker keeps its exact fixture; never terminate to fake settlement. - if (root && fixtureCleanupProven(messages, requestId, closed, errored)) liveFixtureRoots.delete(root); - } -}, WINDOWS_APPLY_BUDGET_MS); - -native("Windows cancellation won inside final synchronous scan cannot create an installer", async () => { - const f = await fixture(undefined, root => liveFixtureRoots.add(root)), id = await approved(f); - const fence = createCodexCliUpdateFence(), gate = new SharedArrayBuffer(8); - const gateOwner = allocateCodexCliUpdateGateOwner(gate); - let scans = 0, starts = 0; - const result = await applyCodexCliUpdate(id, { ...f.deps, - isCancelled: codexCliUpdateIsCancelled(fence), - commitWindow: createWorkerCommitWindow({ gate, fence, owner: gateOwner }), - scanProcesses: () => { - scans++; - if (Atomics.load(new Int32Array(gate), 0) === gateOwner) expect(cancelCodexCliUpdateFence(fence)).toBe(true); - return { kind: "observed", processes: [] }; - }, - startWindowsChild: invocation => { starts++; return startWindowsCliChild(invocation); }, - }); - if (!result.leaseRetained) liveFixtureRoots.delete(f.root); - expect(scans).toBeGreaterThan(0); - expect(result).toMatchObject({ outcome: "refused", reason: "cancelled", leaseRetained: false }); - expect(starts).toBe(0); - expect(Atomics.load(new Int32Array(gate), 0)).toBe(0); -}, WINDOWS_APPLY_BUDGET_MS); - -native("Windows apply runs real offline npm under owned Job, then verifies full target and version", async () => { - const f = await fixture(), id = await approved(f); - const result = await applyCodexCliUpdate(id, f.deps); - expect(result, JSON.stringify(result)).toMatchObject({ outcome: "applied", reason: "verified_target", - installerExitCode: 0, installedVersion: "1.1.0", leaseRetained: false, cleanupErrors: [] }); - expect(existsSync(join(f.prefix, ".ocx-codex-cli-apply.lock"))).toBe(false); -}, WINDOWS_APPLY_BUDGET_MS); - -native("Windows terminal no-op is not_applied even with nonzero installer exit", async () => { - const f = await fixture(), id = await approved(f); - const result = await applyCodexCliUpdate(id, { ...f.deps, install: async () => ({ terminal: true, exitCode: 17 }) }); - expect(result, JSON.stringify(result)).toMatchObject({ outcome: "not_applied", leaseRetained: false, cleanupErrors: [] }); -}, WINDOWS_APPLY_BUDGET_MS); - -native("Windows pack children and installer descendant share transaction ownership", async () => { - const f = await fixture(), realNode = join(f.deps.inspectionDeps.env.PATH, "node.exe"); - const realNpm = join(f.deps.inspectionDeps.env.PATH, "node_modules/npm/bin/npm-cli.js"); - const tools = join(f.root, "toolchain"), npmCli = join(tools, "node_modules/npm/bin/npm-cli.js"), trace = join(f.root, "trace.jsonl"); - mkdirSync(dirname(npmCli), { recursive: true }); copyFileSync(realNode, join(tools, "node.exe")); - write(join(tools, "node_modules/npm/package.json"), JSON.stringify({ name: "npm", version: "11.16.0", bin: { npm: "bin/npm-cli.js" } })); - const sources = Object.fromEntries([f.target.set.main, f.target.set.backing].map((a, i) => { - const path = join(f.root, `${i}.tgz`); write(path, i ? f.target.backing : f.target.main); return [`${a.name}@${a.version}`, path]; - })); - write(npmCli, [ - 'const fs=require("node:fs"), path=require("node:path"), cp=require("node:child_process");', - 'const args=process.argv.slice(2);', - `fs.appendFileSync(${JSON.stringify(trace)},JSON.stringify(args[0])+"\\n");`, - `const sources=${JSON.stringify(sources)};`, - 'if(args[0]==="pack") { const source=sources[args[1]]; if(!source)process.exit(91);', - 'const name=path.basename(source); fs.copyFileSync(source,path.join(args[args.indexOf("--pack-destination")+1],name));', - 'console.log(JSON.stringify([{filename:name}])); } else if(args[0]==="install") {', - `const r=cp.spawnSync(${JSON.stringify(realNode)},[${JSON.stringify(realNpm)},...args],{env:process.env,stdio:"inherit"});process.exit(r.status??92);`, - '} else process.exit(93);', - ].join("\n")); - f.deps.inspectionDeps.env.PATH = tools; - const id = await approved(f); - const result = await applyCodexCliUpdate(id, { ...f.deps, fetchArtifact: undefined }); - expect(result, JSON.stringify(result)).toMatchObject({ outcome: "applied", leaseRetained: false, cleanupErrors: [] }); - expect(readFileSync(trace, "utf8").trim().split("\n").map(line => JSON.parse(line))).toEqual(["pack", "pack", "install"]); -}, WINDOWS_APPLY_BUDGET_MS); - -native("Windows complete readback outranks a nonzero installer exit", async () => { - const f = await fixture(), id = await approved(f); - const result = await applyCodexCliUpdate(id, { ...f.deps, install: async () => { - for (const [path, bytes] of Object.entries(f.target.mainFiles)) write(join(f.prefix, mainRoot, path), bytes); - for (const [path, bytes] of Object.entries(f.target.backingFiles)) write(join(f.prefix, backingRoot, path), bytes); - return { terminal: true, exitCode: 17 }; - } }); - expect(result, JSON.stringify(result)).toMatchObject({ outcome: "applied", installerExitCode: 17, cleanupErrors: [] }); -}, WINDOWS_APPLY_BUDGET_MS); - -native("Windows cancellation and unknown session observation cannot start an installer", async () => { - const f = await fixture(), id = await approved(f); let installs = 0; - const install = async () => { installs++; return { terminal: true, exitCode: 0 }; }; - const abort = new AbortController(); abort.abort(); - expect((await applyCodexCliUpdate(id, { ...f.deps, install, signal: abort.signal })).reason).toBe("cancelled"); - expect((await applyCodexCliUpdate(id, { ...f.deps, install, - scanProcesses: () => ({ kind: "unavailable" }) })).reason).toBe("blocked_process_state_unknown"); - let scans = 0; - expect((await applyCodexCliUpdate(id, { ...f.deps, install, - scanProcesses: () => ++scans < 3 ? { kind: "observed", processes: [] } : { kind: "unavailable" } })).reason) - .toBe("blocked_process_state_unknown"); - expect(scans).toBe(3); - expect(installs).toBe(0); -}, WINDOWS_APPLY_BUDGET_MS); - -native.each(["auxiliary", "shim", "hidden-lock", "extra-file", "new-empty-backing", "selection"] as const)("Windows partial %s refuses not_applied", async kind => { - const f = await fixture(); - if (kind === "new-empty-backing") { - const nested = join(f.prefix, mainRoot, "bin", "node_modules", "@openai", "codex-win32-x64"); - mkdirSync(dirname(nested), { recursive: true }); renameSync(join(f.prefix, backingRoot), nested); - } - const id = await approved(f); - const result = await applyCodexCliUpdate(id, { ...f.deps, install: async () => { - if (kind === "auxiliary") write(join(f.prefix, mainRoot, "README.md"), "changed"); - if (kind === "shim") write(join(f.prefix, "codex.ps1"), "changed"); - if (kind === "hidden-lock") write(join(f.prefix, "node_modules/.package-lock.json"), "{}"); - if (kind === "extra-file") write(join(f.prefix, backingRoot, "unexpected.txt"), "extra"); - if (kind === "new-empty-backing") mkdirSync(join(f.prefix, backingRoot)); - if (kind === "selection") f.deps.inspectionDeps.env.CODEX_CLI_PATH = join(f.prefix, "other.cmd"); - return { terminal: true, exitCode: 1 }; - } }); - expect(result, JSON.stringify(result)).toMatchObject({ outcome: "ambiguous", leaseRetained: false }); -}, WINDOWS_APPLY_BUDGET_MS); - -native("Windows uncertain installer retains lease and staging until owning process exits", async () => { - const f = await fixture(), id = await approved(f); - const entry = join(f.root, "uncertain.test.ts"), receipt = join(f.root, "result.json"); - const literals = JSON.stringify({ id, inspectionDeps: f.deps.inspectionDeps, target: f.deps.resolveTarget(), - main: f.target.main.toString("base64"), backing: f.target.backing.toString("base64"), receipt, prefix: f.prefix }); - writeFileSync(entry, [ - 'import { test, expect } from "bun:test";', - 'import { existsSync, writeFileSync } from "node:fs";', - `import { applyCodexCliUpdate } from ${JSON.stringify(repoPath("src/codex/cli-update-apply.ts"))};`, - `const f = ${literals};`, - 'test("retained transaction", async () => {', - 'const result = await applyCodexCliUpdate(f.id, { platform:"win32", inspectionDeps:f.inspectionDeps,', - 'resolveTarget:()=>f.target, scanProcesses:()=>({kind:"observed",processes:[]}),', - 'fetchArtifact:async a=>Buffer.from(a.installName==="@openai/codex"?f.main:f.backing,"base64"),', - 'install:async()=>({terminal:false,exitCode:null}) });', - 'const stage=existsSync(f.prefix+"/.ocx-codex-cli-apply.lock/stage");', - 'writeFileSync(f.receipt,JSON.stringify({result,stage}));', - 'expect(result.outcome).toBe("ambiguous"); expect(result.leaseRetained).toBe(true); expect(stage).toBe(true);', - `},${WINDOWS_APPLY_CHILD_BUDGET_MS});`, - ].join("\n")); - const child = await spawnTestChild([process.execPath, "test", "--preload", windowsTempAncestryPreload(f.root), - "--no-env-file", "--no-install", "--timeout", String(WINDOWS_APPLY_CHILD_BUDGET_MS), entry], - { cwd: repoRoot(), env: process.env, deadlineMs: WINDOWS_APPLY_CHILD_BUDGET_MS + 5000 }); - expect(child.reaped).toBe(true); expect(child.pipesClosed).toBe(true); expect(child.exitCode, child.stderr).toBe(0); - expect(JSON.parse(readFileSync(receipt, "utf8"))).toMatchObject({ stage: true, - result: { outcome: "ambiguous", reason: "installer_state_unknown", leaseRetained: true } }); - // The child has exited: only now can the fixture's retained kernel handles be gone. -}, WINDOWS_APPLY_BUDGET_MS); - -native("Windows completion persistence retry does not repeat the installer", async () => { - const f = await fixture(), id = await approved(f); let installs = 0, finishes = 0; - await runCodexCliUpdateJobWork(() => applyCodexCliUpdate(id, { ...f.deps, - install: async () => { installs++; return { terminal: true, exitCode: 0 }; } }), { - begin: async () => 1, - finish: async (_revision, result) => { - expect(result.outcome).toBe("not_applied"); - if (++finishes < 3) throw Object.assign(new Error("fixture busy"), { code: "EBUSY" }); - return null; - }, read: async () => null, release: async () => {}, - }); - expect(installs).toBe(1); expect(finishes).toBe(3); -}, WINDOWS_APPLY_BUDGET_MS); - -native("Windows toolchain pins survive an awaited callback; bounded shared prefix is eligible", async () => { - const f = await fixture(); - const tools = join(f.root, "toolchain"), npmCli = join(tools, "node_modules/npm/bin/npm-cli.js"); - write(join(tools, "node.exe"), f.old.backingFiles[nativePath]); - write(join(tools, "node_modules/npm/package.json"), JSON.stringify({ name: "npm", version: "11.0.0", bin: { npm: "bin/npm-cli.js" } })); - write(npmCli, "// never executed\n"); f.deps.inspectionDeps.env.PATH = tools; - const report = await inspectCodexCliInstall({ ...f.deps.inspectionDeps, observeInstallContent: true }); - expect(report.managed).toBe(true); - expect(await withWindowsCodexCliPlanToolchain(report, async () => { - await Bun.sleep(10); - // This write must still be denied after await; returning a promise while - // releasing native pins early would make this assertion fail. - expect(() => writeFileSync(npmCli, "replacement")).toThrow(); return 42; - })).toBe(42); - writeFileSync(npmCli, "// changed after release\n"); - const refreshed = await inspectCodexCliInstall({ ...f.deps.inspectionDeps, observeInstallContent: true }); - const pin = await holdWindowsCodexCliPlanToolchain(refreshed); expect(pin).not.toBeNull(); expect(await pin!.release()).toBe(true); - mkdirSync(join(f.prefix, "node_modules", "unrelated")); - expect((await createCodexCliUpdatePlan(f.deps)).applicable).toBe(true); -}, WINDOWS_APPLY_BUDGET_MS); - -native("Windows shared prefix preserves unrelated package and shims while executing x64 backing", async () => { - // Use the existing Windows compiler, with no package install or downloaded binary. - // This is a CLR x64 executable fixture with actual Win32 Job observation, not vendor Codex. - const build = createCodexCliTestRoot("ocx-win-apply-"); roots.push(build); - const source = join(build, "Backing.cs"), exe = join(build, "backing.exe"), trace = join(build, "native.json"); - write(source, [ - 'using System; using System.IO; using System.Runtime.InteropServices;', - 'class Backing {', - '[DllImport("kernel32.dll")] static extern IntPtr GetCurrentProcess();', - '[DllImport("kernel32.dll")] static extern bool IsProcessInJob(IntPtr p, IntPtr j, out bool inside);', - 'static int Main(string[] args) { bool inside;', - 'if(IntPtr.Size!=8 || args.Length!=1 || args[0]!="--version" || !IsProcessInJob(GetCurrentProcess(),IntPtr.Zero,out inside) || !inside)return 93;', - 'var self=System.Diagnostics.Process.GetCurrentProcess();', - `File.WriteAllText(@"${trace.replaceAll('"', '""')}", "{\\"inJob\\":true,\\"x64\\":true,\\"pid\\":"+self.Id+",\\"startUtc\\":\\""+self.StartTime.ToUniversalTime().ToString("o")+"\\"}");`, - 'Console.WriteLine("codex-cli 1.1.0"); return 0; } }', - ].join("\n")); - const compiler = join(process.env.SystemRoot ?? "C:/Windows", "Microsoft.NET/Framework64/v4.0.30319/csc.exe"); - expect(existsSync(compiler), "x64 fixture compiler must be available; do not substitute a synthetic PE").toBe(true); - const compiled = await spawnTestChild([compiler, "/nologo", "/platform:x64", "/target:exe", `/out:${exe}`, source], - { cwd: build, env: process.env, deadlineMs: 10000 }); - expect(compiled.reaped && compiled.pipesClosed).toBe(true); expect(compiled.exitCode, compiled.stdout + compiled.stderr).toBe(0); - const f = await fixture(readFileSync(exe)); - const unrelated = { "node_modules/unrelated/package.json": '{"name":"unrelated","version":"2.0.0","bin":"index.js"}', - "node_modules/unrelated/index.js": '#!/usr/bin/env node\nconsole.log("unrelated");\n', - "unrelated": "unrelated bare shim\n", "unrelated.cmd": "unrelated cmd shim\n", "unrelated.ps1": "unrelated powershell shim\n" }; - for (const [path, bytes] of Object.entries(unrelated)) write(join(f.prefix, path), bytes); - const children: WindowsCliChild[] = []; - const id = await approved(f), result = await applyCodexCliUpdate(id, { ...f.deps, startWindowsChild: invocation => { - const child = startWindowsCliChild(invocation); children.push(child); return child; - } }); - expect(result, JSON.stringify(result)).toMatchObject({ outcome: "applied", reason: "verified_target", installerExitCode: 0, - installedVersion: "1.1.0", leaseRetained: false, cleanupErrors: [], verificationPid: null }); - const backing = JSON.parse(readFileSync(trace, "utf8")); - expect(backing).toMatchObject({ inJob: true, x64: true }); expect(backing.pid).toBeGreaterThan(0); - expect(Number.isNaN(Date.parse(backing.startUtc))).toBe(false); - expect(children).toHaveLength(2); - for (const child of children) { - expect(child.observe()).toMatchObject({ terminal: true, unknown: false }); - expect((await child.wait()).cleanupComplete).toBe(true); expect(child.native.handles.size).toBe(0); - } - // Preserve actual descendant identity in the supervisor's bounded test log. - console.log("owned x64 fixture", JSON.stringify({ backing, jobs: children.map(c => ({ pid: c.pid, start: c.creationTime })) })); - for (const [path, bytes] of Object.entries(unrelated)) expect(readFileSync(join(f.prefix, path), "utf8")).toBe(bytes); - expect(existsSync(join(f.prefix, ".ocx-codex-cli-apply.lock"))).toBe(false); -}, WINDOWS_APPLY_BUDGET_MS); - -native.each(["package", "shim", "new-entry"] as const)("Windows shared prefix unexpected %s mutation is ambiguous", async kind => { - const f = await fixture(); - write(join(f.prefix, "node_modules/unrelated/package.json"), '{"name":"unrelated","version":"2.0.0"}'); - write(join(f.prefix, "unrelated.cmd"), "original"); - const id = await approved(f); - const result = await applyCodexCliUpdate(id, { ...f.deps, install: async () => { - for (const [path, bytes] of Object.entries(f.target.mainFiles)) write(join(f.prefix, mainRoot, path), bytes); - for (const [path, bytes] of Object.entries(f.target.backingFiles)) write(join(f.prefix, backingRoot, path), bytes); - write(join(f.prefix, kind === "package" ? "node_modules/unrelated/package.json" : kind === "shim" ? "unrelated.cmd" : "unexpected"), "changed"); - return { terminal: true, exitCode: 0 }; - } }); - expect(result).toMatchObject({ outcome: "ambiguous", leaseRetained: false }); -}, WINDOWS_APPLY_BUDGET_MS); - -native("Windows shared namespace still refuses linked unrelated entries", async () => { - const f = await fixture(), outside = join(f.root, "outside"), alias = join(f.prefix, "node_modules/unrelated"); - mkdirSync(outside); write(join(outside, "value"), "must not be followed or changed"); - symlinkSync(outside, alias, "junction"); - expect(windowsInstallNamespaceSupported(f.prefix)).toBe(false); - expect((await createCodexCliUpdatePlan(f.deps)).refusal).toBe("windows_apply_disabled"); - unlinkSync(alias); - linkSync(join(outside, "value"), join(f.prefix, "unrelated.cmd")); - expect(windowsInstallNamespaceSupported(f.prefix)).toBe(false); - expect(readFileSync(join(outside, "value"), "utf8")).toBe("must not be followed or changed"); -}, WINDOWS_APPLY_BUDGET_MS); - -native.each(["installer", "version"] as const)("Windows %s terminal EOF with native CloseHandle failure retains owner and reports cleanup", async policy => { - const f = await fixture(), id = await approved(f); - const entry = join(f.root, "cleanup.test.ts"), receipt = join(f.root, "cleanup.json"); - const literals = JSON.stringify({ id, inspectionDeps: f.deps.inspectionDeps, target: f.deps.resolveTarget(), - main: f.target.main.toString("base64"), backing: f.target.backing.toString("base64"), receipt, prefix: f.prefix, policy, - mainFiles: f.target.mainFiles, backingFiles: Object.fromEntries(Object.entries(f.target.backingFiles).map(([p, b]) => [p, Buffer.from(b).toString("base64")])) }); - write(entry, [ - 'import { test, expect } from "bun:test";', - 'import { existsSync, writeFileSync, readFileSync } from "node:fs";', - 'import { join } from "node:path";', - `import { applyCodexCliUpdate } from ${JSON.stringify(repoPath("src/codex/cli-update-apply.ts"))};`, - `import { WindowsChildNative } from ${JSON.stringify(repoPath("src/codex/windows-cli-child-native.ts"))};`, - `import { startWindowsCliChildWithNative } from ${JSON.stringify(repoPath("src/codex/windows-cli-child.ts"))};`, - `import { normalizeCodexCliJobResult } from ${JSON.stringify(repoPath("src/codex/cli-update-job-execution.ts"))};`, - `import { projectCodexCliUpdateJobLifecycle } from ${JSON.stringify(repoPath("src/codex/cli-update-job.ts"))};`, - `const f=${literals};`, - 'test("terminal cleanup ownership",async()=>{ let child, realClose; const native=new WindowsChildNative();', - 'try { const result=await applyCodexCliUpdate(f.id,{platform:"win32",inspectionDeps:f.inspectionDeps,', - 'resolveTarget:()=>f.target,scanProcesses:()=>({kind:"observed",processes:[]}),', - 'fetchArtifact:async a=>Buffer.from(a.installName==="@openai/codex"?f.main:f.backing,"base64"),', - 'install:f.policy==="version"?async()=>{ for(const [p,b] of Object.entries(f.mainFiles))writeFileSync(join(f.prefix,"node_modules/@openai/codex",p),b);', - 'for(const [p,b] of Object.entries(f.backingFiles))writeFileSync(join(f.prefix,"node_modules/@openai/codex-win32-x64",p),Buffer.from(b,"base64"));return {terminal:true,exitCode:0}; }:undefined,', - 'startWindowsChild: invocation=>{ child=startWindowsCliChildWithNative(invocation,native);realClose=native.k.CloseHandle;', - 'native.k.CloseHandle=h=>h===child.process?0:realClose(h);return child; }});', - 'expect(child.observe().terminal).toBe(true);expect(child.pipe.eof).toBe(true);', - 'expect((await child.wait()).cleanupComplete).toBe(false);expect(native.handles.has(child.process)).toBe(true);', - 'expect(result).toMatchObject({outcome:"ambiguous",reason:"child_cleanup_unverified",leaseRetained:true,cleanupErrors:["child_cleanup_failed"]});', - 'expect(JSON.parse(readFileSync(join(f.prefix,"node_modules/@openai/codex/package.json"),"utf8")).version).toBe("1.1.0");', - 'expect(normalizeCodexCliJobResult(result)).toEqual(result);', - 'expect(projectCodexCliUpdateJobLifecycle({...result,status:"finished",active:false})).toMatchObject({childState:"terminal",leaseState:"retained"});', - 'const stage=existsSync(join(f.prefix,".ocx-codex-cli-apply.lock/stage"));expect(stage).toBe(true);', - 'writeFileSync(f.receipt,JSON.stringify({result,stage,terminal:child.observe().terminal,handles:native.handles.size}));', - '} finally { if(realClose)native.k.CloseHandle=realClose; for(const h of [...native.handles])native.close(h);expect(native.dispose()).toBe(true); }', - `},${WINDOWS_APPLY_CHILD_BUDGET_MS});`, - ].join("\n")); - const result = await spawnTestChild([process.execPath, "test", "--preload", windowsTempAncestryPreload(f.root), - "--no-env-file", "--no-install", "--timeout", String(WINDOWS_APPLY_CHILD_BUDGET_MS), entry], - { cwd: repoRoot(), env: process.env, deadlineMs: WINDOWS_APPLY_CHILD_BUDGET_MS + 5000 }); - expect(result.reaped && result.pipesClosed).toBe(true); expect(result.exitCode, result.stderr).toBe(0); - expect(JSON.parse(readFileSync(receipt, "utf8"))).toMatchObject({ terminal: true, handles: 1, stage: true }); - // Retained authority is intentionally not released by production. This isolated - // owner has exited, so only now may afterEach remove its private fixture prefix. -}, WINDOWS_APPLY_BUDGET_MS); - -native("Windows shared prefix terminal no-op preserves full observed original", async () => { - const f = await fixture(); - write(join(f.prefix, "node_modules/unrelated/package.json"), '{"name":"unrelated","version":"2.0.0"}'); - write(join(f.prefix, "unrelated.cmd"), "original"); - const id = await approved(f); - const result = await applyCodexCliUpdate(id, { ...f.deps, install: async () => ({ terminal: true, exitCode: 0 }) }); - expect(result).toMatchObject({ outcome: "not_applied", reason: "original_install_unchanged", leaseRetained: false, cleanupErrors: [] }); -}, WINDOWS_APPLY_BUDGET_MS); diff --git a/tests/fixtures/test-layout-expected.json b/tests/fixtures/test-layout-expected.json index e503df551af..6946a347fa8 100644 --- a/tests/fixtures/test-layout-expected.json +++ b/tests/fixtures/test-layout-expected.json @@ -44,7 +44,7 @@ "server-combo-stream-required-tool.test.ts": "server", "combo-required-tool-stream-preflight.test.ts": "routing", "responses-anthropic-compaction-prefix.test.ts": "responses", "service-proxy-env.test.ts": "service", - "codex-cli-update-windows-apply.test.ts": "codex-integration", + "codex-cli-update-windows-apply.test.ts": "codex-integration", "codex-cli-update-windows-apply-install.test.ts": "codex-integration", "codex-cli-update-windows-apply-outcomes.test.ts": "codex-integration", "codex-cli-update-windows-apply-shared.test.ts": "codex-integration", "codex-cli-update-windows-recovery.test.ts": "codex-integration", "codex-cli-update-windows-pending.test.ts": "codex-integration", "codex-cli-update-windows-layout.test.ts": "codex-integration", diff --git a/tests/helpers/codex-cli-windows-apply-fixture.ts b/tests/helpers/codex-cli-windows-apply-fixture.ts new file mode 100644 index 00000000000..7100392e886 --- /dev/null +++ b/tests/helpers/codex-cli-windows-apply-fixture.ts @@ -0,0 +1,114 @@ +import { createCodexCliTestRoot } from "./codex-cli-fixture-root"; +import { SPAWN_BUDGET_MS } from "./test-budget"; +import { trustWindowsTempFixtureAncestry } from "./windows-temp-ancestry"; +import { afterEach, expect, test } from "bun:test"; +import { cpSync, realpathSync, copyFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"; +import { join, dirname } from "node:path"; +import { createCodexCliUpdatePlan } from "../../src/codex/cli-update-plan"; +import { hardenSecretDirAsync } from "../../src/lib/windows-secret-acl"; +import { removeTreeAfterBackgroundWork } from "./remove-tree"; +import { fixtureArtifact, fixtureTar } from "./codex-cli-apply-artifact"; +import { fixturePath } from "./repo-root"; + +export const native = process.platform === "win32" && process.arch === "x64" ? test : test.skip; +// Full native npm-tree ACL/identity renewal and real children are the proof. +// Bound this class for a shared Windows host; keep every admission/readback assertion. +export const WINDOWS_APPLY_BUDGET_MS = 4 * SPAWN_BUDGET_MS; +export const WINDOWS_APPLY_CHILD_BUDGET_MS = 2 * SPAWN_BUDGET_MS; +export type WorkerFixtureReply = { type: string; requestId?: string; cleanupConfirmed?: boolean; result?: import("../../src/codex/cli-update-apply").CodexCliApplyResult }; +export function fixtureCleanupProven(messages: readonly unknown[], requestId: string, closed: boolean, errored: boolean): boolean { + if (!closed || errored) return false; + const replies: WorkerFixtureReply[] = []; + for (const value of messages) { + if (!value || typeof value !== "object" || Array.isArray(value)) return false; + const message = value as WorkerFixtureReply; + // Assertions can fail independently: teardown authority rejects ALL foreign, + // malformed or error traffic, including traffic mixed with a valid result. + if (message.requestId !== requestId || !["native-start", "result"].includes(message.type)) return false; + if (message.type === "native-start" && (value as { committed?: unknown }).committed !== true) return false; + if (message.type === "result" && (!message.result || typeof message.result !== "object" + || Array.isArray(message.result) || message.cleanupConfirmed !== true)) return false; + if (message.type === "result") { + const result = message.result!; + const version = (value: unknown) => value === null || typeof value === "string"; + if (!["applied", "not_applied", "refused", "ambiguous"].includes(result.outcome) + || typeof result.reason !== "string" || !/^[a-f0-9]{32}$/.test(result.planId) + || !version(result.installedVersion) || !version(result.targetVersion) + || !(result.installerExitCode === null || Number.isInteger(result.installerExitCode)) + || !(result.verificationPid === null || (Number.isInteger(result.verificationPid) && result.verificationPid > 0))) return false; + } + replies.push(message); + } + const results = replies.filter(message => message.type === "result"); + return results.length === 1 + && results[0]!.cleanupConfirmed === true && results[0]!.result?.leaseRetained === false + && Array.isArray(results[0]!.result?.cleanupErrors) && results[0]!.result!.cleanupErrors.length === 0; +} +export const mainRoot = "node_modules/@openai/codex", backingRoot = "node_modules/@openai/codex-win32-x64"; +export const nativePath = "vendor/x86_64-pc-windows-msvc/bin/codex.exe"; +export const write = (path: string, bytes: string | Buffer) => { mkdirSync(dirname(path), { recursive: true }); writeFileSync(path, bytes); }; +function artifacts(version: string, executable?: Buffer) { + const pe = Buffer.alloc(512); pe.write("MZ"); pe.writeUInt32LE(64, 60); pe.write("PE\0\0", 64); + pe.writeUInt16LE(0x8664, 68); pe.writeUInt16LE(1, 70); pe.writeUInt16LE(240, 84); pe.writeUInt16LE(2, 86); pe.writeUInt16LE(0x20b, 88); + // Synthetic PE only. The real Node verification child executes this fixture's JS; + // this is an npm/readback test, not a claim that a real Codex native binary ran. + const mainFiles = { "package.json": JSON.stringify({ name: "@openai/codex", version, + bin: { codex: "bin/codex.js" }, optionalDependencies: { "@openai/codex-win32-x64": version } }), + "bin/codex.js": executable ? '#!/usr/bin/env node\n' + + 'const cp=require("node:child_process"), path=require("node:path");\n' + + 'const exe=path.join(__dirname,"../../codex-win32-x64/vendor/x86_64-pc-windows-msvc/bin/codex.exe");\n' + + 'const child=cp.spawn(exe,process.argv.slice(2),{stdio:"inherit",windowsHide:true});\n' + + 'child.on("error",()=>{process.exitCode=91});child.on("exit",code=>{process.exitCode=code??92});\n' + : `#!/usr/bin/env node\nconsole.log("codex-cli ${version}");\n`, "README.md": "auxiliary\n" }; + const backingFiles = { "package.json": JSON.stringify({ name: "@openai/codex-win32-x64", version, os: ["win32"], cpu: ["x64"] }), + [nativePath]: executable ?? pe, "vendor/auxiliary.txt": "auxiliary\n" }; + const main = fixtureTar(mainFiles), backing = fixtureTar(backingFiles); + return { mainFiles, backingFiles, main, backing, set: { platform: "win32" as const, arch: "x64", + main: fixtureArtifact(main, version), backing: fixtureArtifact(backing, version, "@openai/codex-win32-x64", "@openai/codex-win32-x64") } }; +} +// Each importing test file owns its fixture roots and cleanup hook, including without --isolate. +export function createWindowsApplyFixtures() { + const roots: string[] = []; + const liveFixtureRoots = new Set(); + afterEach(async () => { + for (const root of roots.splice(0)) { + if (liveFixtureRoots.has(root)) { roots.push(root); continue; } + await removeTreeAfterBackgroundWork(root); + } + }); + async function fixture(executable?: Buffer, onCreated?: (root: string) => void) { + // This host's observed writable AppData ancestry refused; this is not a ban on + // every profile. Evaluate actual ancestry ACL/owner/reparse evidence instead. + // Create only this test-owned directory below the repository's volume anchor; + // never repair or suppress metadata on the host's existing ancestor directories. + const root = createCodexCliTestRoot("ocx-win-apply-"); + onCreated?.(root); roots.push(root); + await hardenSecretDirAsync(root, { required: true }); + trustWindowsTempFixtureAncestry(root); + const prefix = join(root, "prefix"); mkdirSync(prefix); + await hardenSecretDirAsync(prefix, { required: true }); + const old = artifacts("1.0.0"), target = artifacts("1.1.0", executable); + for (const [relative, bytes] of Object.entries(old.mainFiles)) write(join(prefix, mainRoot, relative), bytes); + for (const [relative, bytes] of Object.entries(old.backingFiles)) write(join(prefix, backingRoot, relative), bytes); + const shims = JSON.parse(readFileSync(fixturePath("codex-windows-npm-shims.json"), "utf8")); + for (const [name, bytes] of Object.entries(shims.files)) write(join(prefix, name), String(bytes)); + const sourceNode = realpathSync(Bun.which("node.exe")!); + const nodeDir = join(root, "nodejs"); mkdirSync(nodeDir); + copyFileSync(sourceNode, join(nodeDir, "node.exe")); + cpSync(join(dirname(sourceNode), "node_modules", "npm"), join(nodeDir, "node_modules", "npm"), { recursive: true }); + const inspectionDeps = { env: { CODEX_CLI_PATH: join(prefix, "codex.cmd"), PATH: nodeDir, PATHEXT: ".EXE;.CMD" }, + configDir: join(root, "absent-home"), arch: "x64" as const, selectionAttested: true }; + const deps = { platform: "win32" as const, inspectionDeps, + resolveTarget: () => ({ kind: "resolved" as const, version: "1.1.0", integrity: target.set.main.integrity, artifacts: target.set }), + scanProcesses: () => ({ kind: "observed" as const, processes: [] }), + fetchArtifact: async (artifact: typeof target.set.main) => artifact.installName === "@openai/codex" ? target.main : target.backing }; + return { root, prefix, old, target, deps }; + } + async function approved(f: Awaited>) { + const plan = await createCodexCliUpdatePlan(f.deps); + expect(plan, JSON.stringify(plan)).toMatchObject({ applicable: true, refusal: null }); + expect(plan.planId).toMatch(/^[a-f0-9]{32}$/); return plan.planId!; + } + + return { roots, liveFixtureRoots, fixture, approved }; +}