@iislee/opencodex 2.11.0 → 2.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS_INSTALL.md +109 -0
- package/README.md +117 -22
- package/bin/ocx.mjs +245 -88
- package/bin/package-main.mjs +1 -1
- package/gui/dist/assets/index-Be1sDpWw.css +1 -0
- package/gui/dist/assets/index-D4OKgUV4.js +114 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/alibaba-color.svg +1 -1
- package/gui/dist/provider-icons/antigravity-color.svg +1 -1
- package/gui/dist/provider-icons/claude-color.svg +1 -1
- package/gui/dist/provider-icons/cline-color.svg +16 -0
- package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/commandcode-color.svg +1 -0
- package/gui/dist/provider-icons/copilot-color.svg +1 -1
- package/gui/dist/provider-icons/cursor-color.svg +1 -1
- package/gui/dist/provider-icons/deepseek-color.svg +1 -1
- package/gui/dist/provider-icons/firepass-color.svg +1 -1
- package/gui/dist/provider-icons/fireworks-color.svg +1 -1
- package/gui/dist/provider-icons/gemini-color.svg +1 -1
- package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
- package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
- package/gui/dist/provider-icons/grok.svg +1 -1
- package/gui/dist/provider-icons/groq-color.svg +1 -1
- package/gui/dist/provider-icons/huggingface-color.svg +1 -1
- package/gui/dist/provider-icons/kimi-color.svg +1 -1
- package/gui/dist/provider-icons/kiro-color.svg +2 -2
- package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
- package/gui/dist/provider-icons/mistral-color.svg +1 -1
- package/gui/dist/provider-icons/moonshot-color.svg +1 -1
- package/gui/dist/provider-icons/nvidia-color.svg +1 -1
- package/gui/dist/provider-icons/ollama-color.svg +1 -1
- package/gui/dist/provider-icons/openai.svg +1 -1
- package/gui/dist/provider-icons/opencode.svg +2 -1
- package/gui/dist/provider-icons/openrouter-color.svg +1 -1
- package/gui/dist/provider-icons/pi.svg +2 -2
- package/gui/dist/provider-icons/qianfan-color.svg +1 -1
- package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
- package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/vllm-color.svg +1 -1
- package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
- package/package.json +21 -10
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +475 -62
- package/src/adapters/base.ts +82 -7
- package/src/adapters/client-fingerprint.ts +18 -12
- package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
- package/src/adapters/command-code.ts +637 -0
- package/src/adapters/cursor/call-id.ts +44 -0
- package/src/adapters/cursor/catalog.ts +541 -0
- package/src/adapters/cursor/checkpoint-store.ts +308 -0
- package/src/adapters/cursor/cursor-errors.ts +144 -6
- package/src/adapters/cursor/discovery.ts +122 -14
- package/src/adapters/cursor/effort-map.ts +106 -4
- package/src/adapters/cursor/envelope-echo.ts +290 -0
- package/src/adapters/cursor/framing.ts +39 -0
- package/src/adapters/cursor/h2-pool.ts +123 -0
- package/src/adapters/cursor/http1-bidi.ts +361 -0
- package/src/adapters/cursor/images.ts +704 -0
- package/src/adapters/cursor/live-models.ts +180 -59
- package/src/adapters/cursor/live-transport.ts +623 -170
- package/src/adapters/cursor/message-mapper.ts +4 -1
- package/src/adapters/cursor/native-exec-common.ts +23 -2
- package/src/adapters/cursor/native-exec-desktop.ts +23 -0
- package/src/adapters/cursor/native-exec-fs.ts +10 -7
- package/src/adapters/cursor/native-exec-network.ts +1 -1
- package/src/adapters/cursor/native-exec-shell.ts +5 -3
- package/src/adapters/cursor/native-exec.ts +121 -14
- package/src/adapters/cursor/protobuf-events.ts +829 -11
- package/src/adapters/cursor/protobuf-request.ts +447 -75
- package/src/adapters/cursor/request-builder.ts +271 -35
- package/src/adapters/cursor/tool-definitions.ts +252 -12
- package/src/adapters/cursor/tool-result-normalize.ts +115 -0
- package/src/adapters/cursor/transport.ts +22 -0
- package/src/adapters/cursor/types.ts +48 -1
- package/src/adapters/cursor.ts +336 -39
- package/src/adapters/exec-tool-result-normalize.ts +99 -0
- package/src/adapters/google-antigravity-replay.ts +713 -41
- package/src/adapters/google-antigravity-wire.ts +48 -10
- package/src/adapters/google-errors.ts +44 -12
- package/src/adapters/google-http.ts +38 -10
- package/src/adapters/google-tool-schema.ts +80 -15
- package/src/adapters/google-truncation.ts +11 -0
- package/src/adapters/google.ts +742 -86
- package/src/adapters/identity.ts +39 -6
- package/src/adapters/image.ts +1 -1
- package/src/adapters/kiro-constants.ts +27 -0
- package/src/adapters/kiro-errors.ts +11 -0
- package/src/adapters/kiro-events.ts +19 -1
- package/src/adapters/kiro-thinking.ts +18 -2
- package/src/adapters/kiro-tools.ts +65 -17
- package/src/adapters/kiro.ts +270 -73
- package/src/adapters/mimo-free.ts +17 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1377 -344
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +1164 -64
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/run-turn-queue.ts +36 -1
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +105 -21
- package/src/adapters/xai-tool-schema.ts +436 -0
- package/src/adapters/xai-web-search.ts +186 -0
- package/src/bridge.ts +512 -92
- package/src/chat/inbound.ts +57 -20
- package/src/chat/outbound.ts +97 -33
- package/src/claude/agents-inject.ts +40 -10
- package/src/claude/context-windows.ts +37 -14
- package/src/claude/desktop-3p.ts +243 -9
- package/src/claude/gateway-cache.ts +41 -4
- package/src/claude/inbound.ts +72 -3
- package/src/claude/model-info.ts +38 -15
- package/src/claude/outbound.ts +88 -21
- package/src/cli/access.ts +46 -3
- package/src/cli/account-api.ts +150 -19
- package/src/cli/account-auth.ts +33 -6
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +648 -28
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +97 -19
- package/src/cli/agent.ts +53 -2
- package/src/cli/alias.ts +66 -0
- package/src/cli/capabilities-command.ts +94 -0
- package/src/cli/capabilities.ts +496 -0
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +60 -15
- package/src/cli/claude.ts +129 -35
- package/src/cli/codex-log-guard-doctor.ts +103 -0
- package/src/cli/codex-shim-autorestore.ts +2 -0
- package/src/cli/codex-shim-readiness.ts +76 -0
- package/src/cli/combo.ts +8 -0
- package/src/cli/config-command.ts +74 -10
- package/src/cli/dispatch.ts +821 -0
- package/src/cli/doctor.ts +440 -56
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +46 -20
- package/src/cli/help.ts +34 -274
- package/src/cli/index.ts +417 -528
- package/src/cli/init.ts +5 -17
- package/src/cli/inspect.ts +230 -0
- package/src/cli/integrations.ts +120 -2
- package/src/cli/lab.ts +607 -0
- package/src/cli/launcher-context.ts +77 -0
- package/src/cli/minimax.ts +497 -0
- package/src/cli/models-runtime.ts +130 -2
- package/src/cli/models.ts +118 -16
- package/src/cli/observe.ts +123 -11
- package/src/cli/opencode.ts +4 -2
- package/src/cli/provider-runtime.ts +34 -3
- package/src/cli/provider.ts +25 -3
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +476 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +57 -10
- package/src/cli/star-prompt.ts +71 -15
- package/src/cli/status.ts +51 -4
- package/src/cli/storage.ts +234 -0
- package/src/cli/system-command.ts +16 -0
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +153 -6
- package/src/cli/usage-report.ts +184 -0
- package/src/cli/v2.ts +137 -18
- package/src/cli/version-skew.ts +46 -0
- package/src/cli.ts +1 -1
- package/src/clients/config-export.ts +1442 -23
- package/src/clients/effective-status.ts +30 -2
- package/src/clients/probes/cline.ts +81 -0
- package/src/codex/account-label.ts +35 -1
- package/src/codex/account-lifecycle.ts +130 -13
- package/src/codex/account-namespaces.ts +49 -3
- package/src/codex/account-pause.ts +2 -1
- package/src/codex/account-priority.ts +84 -0
- package/src/codex/account-store.ts +29 -2
- package/src/codex/account-usability.ts +25 -2
- package/src/codex/admission.ts +256 -0
- package/src/codex/affinity-debug.ts +162 -0
- package/src/codex/app-server-processes.ts +570 -107
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +893 -246
- package/src/codex/auth-collision.ts +5 -3
- package/src/codex/auth-context.ts +348 -32
- package/src/codex/autostart-health.ts +24 -1
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +86 -10
- package/src/codex/catalog/bundled.ts +331 -33
- package/src/codex/catalog/effort.ts +138 -32
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +555 -45
- package/src/codex/catalog/native-models.ts +75 -0
- package/src/codex/catalog/parsing.ts +269 -30
- package/src/codex/catalog/provider-fetch.ts +1626 -144
- package/src/codex/catalog/sync.ts +1576 -187
- package/src/codex/catalog-admission.ts +199 -0
- package/src/codex/catalog-refresh-status.ts +105 -0
- package/src/codex/catalog-write-serialization.ts +242 -0
- package/src/codex/catalog.ts +6 -3
- package/src/codex/codex-write-lock.ts +386 -0
- package/src/codex/convergence-types.ts +614 -0
- package/src/codex/convergence.ts +676 -0
- package/src/codex/coordinator-doctor.ts +332 -0
- package/src/codex/custom-model-catalog-migration.ts +176 -0
- package/src/codex/desired-state.ts +230 -0
- package/src/codex/desktop-app-restart.ts +355 -0
- package/src/codex/features.ts +636 -39
- package/src/codex/generation.ts +202 -0
- package/src/codex/history-job.ts +436 -0
- package/src/codex/history-lock.ts +242 -0
- package/src/codex/history-manifest.ts +112 -0
- package/src/codex/history-migration-guardian.ts +30 -24
- package/src/codex/history-provider.ts +1016 -235
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +223 -0
- package/src/codex/inject-coordination.ts +373 -0
- package/src/codex/inject.ts +1114 -152
- package/src/codex/injected-marker.ts +37 -3
- package/src/codex/integration-record.ts +266 -0
- package/src/codex/internal/catalog-writer.ts +203 -0
- package/src/codex/internal/history-writer.ts +81 -0
- package/src/codex/journal.ts +66 -4
- package/src/codex/log-guard/inspect.ts +524 -0
- package/src/codex/log-guard/lock.ts +150 -0
- package/src/codex/log-guard/maintenance.ts +403 -0
- package/src/codex/log-guard/path-safety.ts +88 -0
- package/src/codex/log-guard/policy.ts +44 -0
- package/src/codex/log-guard/processes.ts +205 -0
- package/src/codex/log-guard/protection.ts +489 -0
- package/src/codex/log-guard/sqlite-errors.ts +9 -0
- package/src/codex/main-account-cache.ts +24 -0
- package/src/codex/main-account.ts +29 -1
- package/src/codex/management-convergence.ts +167 -0
- package/src/codex/model-cache.ts +56 -10
- package/src/codex/model-entitlements.ts +360 -0
- package/src/codex/native-main-admission.ts +47 -0
- package/src/codex/native-main-auth-temp.ts +187 -0
- package/src/codex/native-main-claim.ts +178 -0
- package/src/codex/native-main-lock-file.ts +162 -0
- package/src/codex/native-main-owner.ts +329 -0
- package/src/codex/native-profile-api.ts +247 -0
- package/src/codex/native-profile-manager.ts +1531 -0
- package/src/codex/native-profile-processes.ts +121 -0
- package/src/codex/native-profile-recovery.ts +99 -0
- package/src/codex/native-profile-stage-store.ts +387 -0
- package/src/codex/native-profile-startup.ts +622 -0
- package/src/codex/native-profile-store.ts +855 -0
- package/src/codex/native-profile-types.ts +120 -0
- package/src/codex/native-residue.ts +675 -0
- package/src/codex/paths.ts +80 -1
- package/src/codex/plan-from-token.ts +140 -0
- package/src/codex/plan.ts +40 -0
- package/src/codex/plugins-doctor.ts +1 -1
- package/src/codex/pool-rotation.ts +74 -4
- package/src/codex/project-config-warnings.ts +20 -6
- package/src/codex/prompt-journal.ts +352 -0
- package/src/codex/prompt-layers.ts +1313 -0
- package/src/codex/prompt-lock.ts +143 -0
- package/src/codex/prompt-text-probe.ts +238 -0
- package/src/codex/quota-rejection.ts +298 -0
- package/src/codex/quota.ts +264 -21
- package/src/codex/refresh.ts +11 -2
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +514 -94
- package/src/codex/runtime.ts +159 -38
- package/src/codex/shim.ts +1065 -31
- package/src/codex/subagent-model-fallback.ts +437 -43
- package/src/codex/sync.ts +191 -2
- package/src/codex/transition-state.ts +720 -0
- package/src/codex/upstream-host-health.ts +368 -0
- package/src/codex/user-identity.ts +557 -0
- package/src/codex/warmup.ts +187 -81
- package/src/codex/write-coordination.ts +114 -0
- package/src/combos/failover.ts +47 -0
- package/src/combos/index.ts +4 -0
- package/src/combos/request.ts +32 -0
- package/src/combos/types.ts +91 -9
- package/src/compatibility/index.ts +26 -0
- package/src/compatibility/manifest.ts +253 -0
- package/src/compatibility/openai-responses.ts +121 -0
- package/src/config/atomic-write.ts +219 -0
- package/src/config/paths.ts +40 -0
- package/src/config/process-state.ts +309 -0
- package/src/config/provider-name.ts +24 -0
- package/src/config/provider-validation.ts +177 -0
- package/src/config/rebase-provenance.ts +68 -0
- package/src/config.ts +1713 -709
- package/src/generated/compatibility-version.json +3324 -0
- package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
- package/src/grok/inject.ts +16 -5
- package/src/grok/inspect.ts +45 -0
- package/src/grok/sync.ts +2 -2
- package/src/images/loop.ts +157 -33
- package/src/images/plan.ts +24 -13
- package/src/integrations/config-io.ts +269 -0
- package/src/integrations/journal.ts +315 -0
- package/src/integrations/merge.ts +135 -0
- package/src/integrations/mutation-flight.ts +71 -0
- package/src/integrations/native/ownership-preflight.ts +202 -0
- package/src/integrations/omp-yaml-source.ts +358 -0
- package/src/integrations/owned-refresh.ts +74 -0
- package/src/integrations/ownership-policy.ts +160 -0
- package/src/integrations/ownership.ts +155 -0
- package/src/integrations/registry.ts +166 -0
- package/src/integrations/serialize.ts +314 -0
- package/src/integrations/state.ts +433 -0
- package/src/integrations/store.ts +103 -0
- package/src/integrations/writer-lock.ts +98 -0
- package/src/integrations/writer.ts +715 -0
- package/src/lab/artifacts/sanitize.ts +586 -0
- package/src/lab/artifacts/secure-fs.ts +475 -0
- package/src/lab/artifacts/store.ts +310 -0
- package/src/lab/automation/budgets.ts +78 -0
- package/src/lab/automation/config-persistence.ts +256 -0
- package/src/lab/automation/constants.ts +39 -0
- package/src/lab/automation/cooldown.ts +103 -0
- package/src/lab/automation/dispatch.ts +211 -0
- package/src/lab/automation/index.ts +13 -0
- package/src/lab/automation/orchestrator.ts +499 -0
- package/src/lab/automation/persistence.ts +512 -0
- package/src/lab/automation/planner.ts +371 -0
- package/src/lab/automation/policy.ts +136 -0
- package/src/lab/automation/queue.ts +191 -0
- package/src/lab/automation/recovery.ts +24 -0
- package/src/lab/automation/route-context.ts +21 -0
- package/src/lab/automation/run-key.ts +44 -0
- package/src/lab/automation/runs-query.ts +34 -0
- package/src/lab/automation/types.ts +160 -0
- package/src/lab/conformance/assertion.ts +325 -0
- package/src/lab/conformance/digest.ts +22 -0
- package/src/lab/conformance/executor.ts +741 -0
- package/src/lab/conformance/fixture-provider.ts +27 -0
- package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
- package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
- package/src/lab/conformance/harness-budget.ts +47 -0
- package/src/lab/conformance/index.ts +5 -0
- package/src/lab/conformance/jcs.ts +64 -0
- package/src/lab/conformance/json-pointer.ts +39 -0
- package/src/lab/conformance/manifest.ts +180 -0
- package/src/lab/conformance/mcp-stub.ts +179 -0
- package/src/lab/conformance/negative-controls.ts +164 -0
- package/src/lab/conformance/observation.ts +355 -0
- package/src/lab/conformance/runner.ts +68 -0
- package/src/lab/conformance/sse-normalize.ts +59 -0
- package/src/lab/conformance/suite-manifest.ts +78 -0
- package/src/lab/conformance/types.ts +214 -0
- package/src/lab/constants.ts +126 -0
- package/src/lab/digest.ts +64 -0
- package/src/lab/events/errors.ts +9 -0
- package/src/lab/events/limits.ts +117 -0
- package/src/lab/events/types.ts +229 -0
- package/src/lab/events/validate.ts +781 -0
- package/src/lab/fabric/constants.ts +40 -0
- package/src/lab/fabric/executor.ts +492 -0
- package/src/lab/fabric/index.ts +80 -0
- package/src/lab/fabric/manifest.ts +222 -0
- package/src/lab/fabric/observe.ts +489 -0
- package/src/lab/fabric/patch.ts +79 -0
- package/src/lab/fabric/producer-child.ts +139 -0
- package/src/lab/fabric/producer-isolate.ts +276 -0
- package/src/lab/fabric/producer-protocol.ts +61 -0
- package/src/lab/fabric/scratch.ts +439 -0
- package/src/lab/fabric/subject.ts +106 -0
- package/src/lab/fabric/types.ts +134 -0
- package/src/lab/fabric/verifier.ts +98 -0
- package/src/lab/index.ts +54 -0
- package/src/lab/ledger/artifact-refs.ts +127 -0
- package/src/lab/ledger/invalidation.ts +136 -0
- package/src/lab/ledger/purge.ts +310 -0
- package/src/lab/ledger/store.ts +532 -0
- package/src/lab/live/credential-lease.ts +53 -0
- package/src/lab/live/destination.ts +155 -0
- package/src/lab/live/executor.ts +336 -0
- package/src/lab/live/inert-tools.ts +56 -0
- package/src/lab/live/manifest.ts +85 -0
- package/src/lab/live/mcp-loopback.ts +57 -0
- package/src/lab/live/runner.ts +19 -0
- package/src/lab/live/sandbox.ts +61 -0
- package/src/lab/live/suite-manifest.ts +41 -0
- package/src/lab/live/transport.ts +118 -0
- package/src/lab/live/types.ts +197 -0
- package/src/lab/observe/from-conformance.ts +301 -0
- package/src/lab/observe/from-live.ts +117 -0
- package/src/lab/paths.ts +153 -0
- package/src/lab/projection/rebuild.ts +495 -0
- package/src/lab/projection/schema.ts +135 -0
- package/src/lab/projection/verdicts.ts +474 -0
- package/src/lab/projection/verification.ts +412 -0
- package/src/lab/public/bundle.ts +217 -0
- package/src/lab/public/community-authority.ts +175 -0
- package/src/lab/public/community-files.ts +29 -0
- package/src/lab/public/community.ts +479 -0
- package/src/lab/public/file-safety.ts +155 -0
- package/src/lab/public/ids.ts +26 -0
- package/src/lab/public/index.ts +16 -0
- package/src/lab/public/mutation-lock.ts +424 -0
- package/src/lab/public/operator.ts +353 -0
- package/src/lab/public/origin-purge.ts +79 -0
- package/src/lab/public/origin.ts +203 -0
- package/src/lab/public/privacy.ts +143 -0
- package/src/lab/public/private-file.ts +261 -0
- package/src/lab/public/project.ts +124 -0
- package/src/lab/public/purge-test-fault.ts +21 -0
- package/src/lab/public/purge.ts +223 -0
- package/src/lab/public/registry.ts +44 -0
- package/src/lab/public/revocation.ts +252 -0
- package/src/lab/public/signature.ts +243 -0
- package/src/lab/public/storage.ts +105 -0
- package/src/lab/public/strict-json.ts +206 -0
- package/src/lab/public/time.ts +26 -0
- package/src/lab/public/types.ts +172 -0
- package/src/lab/public/validate.ts +391 -0
- package/src/lab/query/catalog.ts +101 -0
- package/src/lab/query/connection.ts +107 -0
- package/src/lab/query/constants.ts +4 -0
- package/src/lab/query/cursor.ts +132 -0
- package/src/lab/query/dto-map.ts +277 -0
- package/src/lab/query/errors.ts +22 -0
- package/src/lab/query/freshness.ts +53 -0
- package/src/lab/query/index.ts +45 -0
- package/src/lab/query/latest-observation.ts +59 -0
- package/src/lab/query/passive-production.ts +159 -0
- package/src/lab/query/queries.ts +444 -0
- package/src/lab/query/types.ts +266 -0
- package/src/lab/subject/behavior-fingerprint.ts +77 -0
- package/src/lab/subject/installation-salt.ts +112 -0
- package/src/lab/subject/protocol-subject.ts +80 -0
- package/src/lab/subject/route-subject.ts +74 -0
- package/src/lib/admin-secrets.ts +24 -0
- package/src/lib/app-owned-memory-stores.ts +22 -0
- package/src/lib/bounded-body.ts +167 -11
- package/src/lib/bun-runtime.ts +125 -12
- package/src/lib/bun-stream-caps.ts +13 -9
- package/src/lib/codex-restart-contract.ts +120 -0
- package/src/lib/config-ownership.ts +26 -2
- package/src/lib/destination-policy.ts +65 -1
- package/src/lib/errors.ts +80 -5
- package/src/lib/fabric-task-execution-authority.ts +7 -0
- package/src/lib/fabric-task-host.ts +29 -0
- package/src/lib/lab-activation.ts +223 -0
- package/src/lib/lab-live-execution-authority.ts +13 -0
- package/src/lib/lab-live-host.ts +30 -0
- package/src/lib/lab-live-pinned-sender.ts +56 -0
- package/src/lib/lab-live-route-production.ts +130 -0
- package/src/lib/lab-passive-linker-registration.ts +26 -0
- package/src/lib/local-management-attestation.ts +51 -0
- package/src/lib/local-management-capability.ts +100 -0
- package/src/lib/local-provider-reload-contract.ts +100 -0
- package/src/lib/optional-shutdown-hooks.ts +57 -0
- package/src/lib/package-tree-integrity.ts +101 -0
- package/src/lib/pinned-http.ts +145 -26
- package/src/lib/process-control.ts +6 -2
- package/src/lib/provider-outbound.ts +49 -9
- package/src/lib/redact.ts +419 -3
- package/src/lib/self-launch-argv.ts +15 -0
- package/src/lib/server-resource-ownership.ts +71 -0
- package/src/lib/service-secrets.ts +15 -0
- package/src/lib/shadow-call.ts +35 -4
- package/src/lib/sse-decoder.ts +41 -0
- package/src/lib/state-store-registrations.ts +10 -2
- package/src/lib/system-restart-contract.ts +73 -0
- package/src/lib/token-estimate.ts +19 -2
- package/src/lib/tool-argument-integers.ts +253 -0
- package/src/lib/translator-budget.ts +44 -0
- package/src/lib/upstream-http-version.ts +57 -0
- package/src/lib/upstream-reachability.ts +95 -0
- package/src/lib/upstream-retry.ts +156 -3
- package/src/lib/windows-atomic-replace.ts +155 -0
- package/src/lib/windows-elevation.ts +70 -2
- package/src/lib/windows-secret-acl.ts +409 -69
- package/src/lib/windows-service-wrappers.ts +72 -0
- package/src/lib/windows-text.ts +106 -0
- package/src/lib/windows-user-principal.ts +341 -0
- package/src/lib/winsw.ts +33 -5
- package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
- package/src/oauth/account-import/index.ts +15 -0
- package/src/oauth/account-import/parser.ts +83 -0
- package/src/oauth/account-import/registry.ts +18 -0
- package/src/oauth/account-import/service.ts +75 -0
- package/src/oauth/account-import/types.ts +91 -0
- package/src/oauth/anthropic.ts +12 -1
- package/src/oauth/callback-server.ts +30 -4
- package/src/oauth/chatgpt.ts +12 -1
- package/src/oauth/cline.ts +203 -0
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +46 -5
- package/src/oauth/generic-account-failover.ts +231 -0
- package/src/oauth/google-antigravity.ts +35 -3
- package/src/oauth/health.ts +20 -12
- package/src/oauth/index.ts +462 -71
- package/src/oauth/key-providers.ts +25 -0
- package/src/oauth/kimi.ts +25 -3
- package/src/oauth/kiro.ts +95 -6
- package/src/oauth/local-token-detect.ts +13 -2
- package/src/oauth/log.ts +3 -1
- package/src/oauth/login-cli.ts +88 -28
- package/src/oauth/nous.ts +798 -0
- package/src/oauth/open-browser-choice.ts +26 -0
- package/src/oauth/store.ts +133 -26
- package/src/oauth/token-guardian.ts +9 -3
- package/src/oauth/types.ts +15 -0
- package/src/pi/models.ts +2 -2
- package/src/providers/alibaba-region-migration.ts +1 -1
- package/src/providers/antigravity-models.ts +521 -31
- package/src/providers/auto-compact-budget.ts +65 -0
- package/src/providers/base-url-choices.ts +10 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +176 -0
- package/src/providers/context-cap.ts +26 -8
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/default-aliases.ts +65 -0
- package/src/providers/derive.ts +281 -6
- package/src/providers/fastwire.ts +507 -0
- package/src/providers/free-directory.ts +10 -7
- package/src/providers/google-vertex-location.ts +14 -0
- package/src/providers/key-failover.ts +71 -3
- package/src/providers/label.ts +35 -2
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +115 -22
- package/src/providers/model-presets.ts +119 -0
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/new-model-policy.ts +146 -0
- package/src/providers/openai-sidecar.ts +72 -4
- package/src/providers/openai-tier-startup.ts +31 -2
- package/src/providers/openai-tiers.ts +119 -4
- package/src/providers/openai-virtual-models.ts +1 -0
- package/src/providers/opencode-zen-rate-limit.ts +102 -0
- package/src/providers/provider-id-rewrite.ts +30 -0
- package/src/providers/quota.ts +1379 -40
- package/src/providers/registry.ts +1545 -112
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +94 -6
- package/src/providers/static-model-discovery.ts +86 -0
- package/src/providers/xai-responses-opt-in.ts +15 -0
- package/src/providers/xai-transport.ts +32 -4
- package/src/reasoning-effort.ts +68 -3
- package/src/responses/apply-patch-envelope.ts +63 -0
- package/src/responses/code-mode-helper-compat.ts +50 -0
- package/src/responses/compaction.ts +26 -1
- package/src/responses/custom-tool-compat.ts +384 -0
- package/src/responses/hosted-tool-policy.ts +9 -0
- package/src/responses/namespace-tool-compat.ts +435 -0
- package/src/responses/parser.ts +225 -38
- package/src/responses/provider-continuation.ts +98 -0
- package/src/responses/provider-opaque-metadata.ts +73 -0
- package/src/responses/reasoning-envelope.ts +9 -1
- package/src/responses/reasoning-replay-cache.ts +504 -0
- package/src/responses/schema.ts +12 -2
- package/src/responses/spill-store.ts +75 -10
- package/src/responses/state.ts +659 -31
- package/src/responses/thought-signature-replay.ts +364 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/responses/turn-termination.ts +107 -0
- package/src/router.ts +405 -31
- package/src/routing/analytics.ts +379 -0
- package/src/routing/capability.ts +244 -0
- package/src/routing/compatibility/assemble.ts +73 -0
- package/src/routing/compatibility/behavior.ts +278 -0
- package/src/routing/compatibility/catalog.ts +99 -0
- package/src/routing/compatibility/endpoint.ts +52 -0
- package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
- package/src/routing/compatibility/policy.ts +181 -0
- package/src/routing/compatibility/provider-slot.ts +56 -0
- package/src/routing/compatibility/reader.ts +110 -0
- package/src/routing/compatibility/subject.ts +191 -0
- package/src/routing/compatibility/types.ts +64 -0
- package/src/routing/compatibility/version.ts +104 -0
- package/src/routing/cost.ts +77 -0
- package/src/routing/evaluator.ts +495 -0
- package/src/routing/health.ts +412 -0
- package/src/routing/history/cursor.ts +43 -0
- package/src/routing/history/indexer.ts +605 -0
- package/src/routing/history/schema.ts +72 -0
- package/src/routing/profile-namespace.ts +15 -0
- package/src/routing/profile.ts +547 -0
- package/src/routing/quota.ts +155 -0
- package/src/routing/request-evidence.ts +45 -0
- package/src/routing/trace.ts +776 -0
- package/src/server/adapter-resolve.ts +2 -29
- package/src/server/auth-cors.ts +289 -48
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +154 -72
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +445 -0
- package/src/server/claude-messages.ts +160 -44
- package/src/server/direct-local-http.ts +347 -0
- package/src/server/effort-policy.ts +18 -0
- package/src/server/github-copilot-responses-repair.ts +338 -0
- package/src/server/gui-static.ts +39 -10
- package/src/server/images.ts +94 -12
- package/src/server/index.ts +1021 -190
- package/src/server/lifecycle.ts +336 -14
- package/src/server/live.ts +136 -17
- package/src/server/local-management-read-client.ts +90 -0
- package/src/server/local-provider-reload-client.ts +137 -0
- package/src/server/management/agent-settings-routes.ts +433 -116
- package/src/server/management/api-key-usage.ts +31 -5
- package/src/server/management/body.ts +6 -0
- package/src/server/management/codex-prompt-routes.ts +570 -0
- package/src/server/management/combo-routes.ts +64 -25
- package/src/server/management/config-routes.ts +511 -51
- package/src/server/management/context.ts +89 -2
- package/src/server/management/integration-routes.ts +498 -0
- package/src/server/management/lab-automation-routes.ts +206 -0
- package/src/server/management/lab-routes.ts +563 -0
- package/src/server/management/logs-usage-routes.ts +127 -52
- package/src/server/management/model-routes.ts +461 -133
- package/src/server/management/model-rows.ts +167 -0
- package/src/server/management/native-integration-routes.ts +770 -0
- package/src/server/management/oauth-account-routes.ts +90 -8
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +836 -159
- package/src/server/management/request-history-routes.ts +191 -0
- package/src/server/management/route-registry.ts +332 -0
- package/src/server/management/routing-analytics-routes.ts +74 -0
- package/src/server/management/routing-profile-routes.ts +380 -0
- package/src/server/management/shared.ts +27 -11
- package/src/server/management/sidebar-routes.ts +47 -31
- package/src/server/management/storage-log-guard-routes.ts +186 -0
- package/src/server/management/sync-response.ts +69 -0
- package/src/server/management/system-restart.ts +289 -33
- package/src/server/management/system-routes.ts +77 -0
- package/src/server/management/usage-summary-cache.ts +9 -1
- package/src/server/management/vision-sidecar-options.ts +167 -0
- package/src/server/management/web-search-sidecar-options.ts +120 -0
- package/src/server/management-api.ts +126 -23
- package/src/server/management-auth.ts +220 -5
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/port-reclaim.ts +1 -1
- package/src/server/ports.ts +41 -1
- package/src/server/proxy-liveness.ts +161 -10
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +221 -54
- package/src/server/relay.ts +479 -87
- package/src/server/request-decompress.ts +113 -6
- package/src/server/request-log-conversation.ts +51 -0
- package/src/server/request-log.ts +298 -31
- package/src/server/responses/agent-task-recovery-cache.ts +143 -0
- package/src/server/responses/agent-task-recovery.ts +465 -0
- package/src/server/responses/codex-auth-error.ts +55 -0
- package/src/server/responses/collaboration.ts +239 -36
- package/src/server/responses/combo-stream-preflight.ts +178 -0
- package/src/server/responses/compact.ts +444 -72
- package/src/server/responses/core.ts +3579 -436
- package/src/server/responses/empty-completion-guard.ts +333 -0
- package/src/server/responses/encrypted-payload.ts +62 -39
- package/src/server/responses/fetch-helpers.ts +89 -99
- package/src/server/responses/input-admission.ts +187 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/passthrough-error.ts +33 -9
- package/src/server/responses/policy-fallback.ts +178 -0
- package/src/server/responses/responses-field-backfill.ts +343 -0
- package/src/server/responses/terminal-guard.ts +26 -5
- package/src/server/responses/upstream-error.ts +5 -0
- package/src/server/responses/ws-upstream.ts +381 -0
- package/src/server/responses-custom-tool-repair.ts +363 -0
- package/src/server/responses-item-id-repair.ts +54 -6
- package/src/server/responses-json-events.ts +90 -0
- package/src/server/responses-model-rewrite.ts +29 -0
- package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
- package/src/server/responses-snapshot-repair.ts +621 -0
- package/src/server/responses-terminal-repair.ts +363 -0
- package/src/server/responses-tool-search-repair.ts +267 -0
- package/src/server/responses-undeclared-tool-guard.ts +376 -0
- package/src/server/responses.ts +18 -2
- package/src/server/search.ts +78 -13
- package/src/server/sse-frame-buffer.ts +319 -0
- package/src/server/sse-payload-rewrite.ts +110 -22
- package/src/server/startup-action-control.ts +8 -1
- package/src/server/startup-health-cache.ts +19 -1
- package/src/server/system-env.ts +80 -9
- package/src/server/ws-bridge.ts +53 -40
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +1153 -94
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/storage/cleanup.ts +2 -2
- package/src/storage/policy-job.ts +14 -4
- package/src/storage/policy.ts +88 -23
- package/src/storage/scanner.ts +1 -1
- package/src/storage/worker-lifecycle.ts +14 -14
- package/src/tray/windows-tray.ps1 +83 -9
- package/src/tray/windows.ts +43 -16
- package/src/types/accounts.ts +37 -0
- package/src/types/config.ts +911 -0
- package/src/types/provider.ts +614 -0
- package/src/types/request.ts +397 -0
- package/src/types/tools.ts +236 -0
- package/src/types/wire.ts +80 -0
- package/src/types.ts +107 -1237
- package/src/update/index.ts +37 -23
- package/src/update/job.ts +445 -68
- package/src/update/notify.ts +12 -6
- package/src/update/npm-cache-preflight.d.mts +47 -0
- package/src/update/npm-cache-preflight.mjs +201 -0
- package/src/update/transactional-install.d.mts +22 -0
- package/src/update/transactional-install.mjs +266 -0
- package/src/usage/cost.ts +0 -0
- package/src/usage/expected-prices.ts +287 -16
- package/src/usage/log.ts +666 -50
- package/src/usage/summary.ts +388 -17
- package/src/usage/user-cost-overlay-reconciler.ts +313 -0
- package/src/usage/user-cost-overlays.ts +314 -0
- package/src/vision/anthropic-describe.ts +10 -6
- package/src/vision/backends.ts +97 -0
- package/src/vision/describe.ts +27 -16
- package/src/vision/eligibility.ts +250 -0
- package/src/vision/index.ts +238 -24
- package/src/vision/reasoning.ts +55 -0
- package/src/vision/routed-describe.ts +175 -0
- package/src/vision/timeout-bounds.ts +9 -0
- package/src/web-search/anthropic-executor.ts +13 -7
- package/src/web-search/backends.ts +108 -0
- package/src/web-search/exa-executor.ts +119 -0
- package/src/web-search/executor.ts +21 -6
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +150 -15
- package/src/web-search/loop.ts +284 -54
- package/src/web-search/parse.ts +125 -30
- package/src/web-search/sources.ts +60 -0
- package/src/web-search/xai-executor.ts +219 -0
- package/gui/dist/assets/index-DTpMHS4F.js +0 -67
- package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
- package/gui/dist/provider-icons/antigravity.svg +0 -1
- package/gui/dist/provider-icons/claude.svg +0 -1
- package/gui/dist/provider-icons/copilot.svg +0 -1
- package/gui/dist/provider-icons/cursor.svg +0 -2
- package/gui/dist/provider-icons/gemini.svg +0 -1
- package/gui/dist/provider-icons/grok-color.svg +0 -1
- package/gui/dist/provider-icons/kiro.svg +0 -14
- package/src/cli/internal-dispatch.ts +0 -20
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import type { CompatibilityVerdict, EvidenceLayer } from "../constants";
|
|
2
|
+
|
|
3
|
+
export const PUBLIC_EVIDENCE_BUNDLE_SCHEMA_VERSION = "public_evidence_bundle_v1" as const;
|
|
4
|
+
export const PUBLIC_EXPORT_POLICY_VERSION = "public_export_policy_v1" as const;
|
|
5
|
+
export const PUBLIC_EVIDENCE_REVOCATION_SCHEMA_VERSION = "public_evidence_revocation_v1" as const;
|
|
6
|
+
export const PUBLIC_ROUTE_REGISTRY_SCHEMA_VERSION = "public_route_registry_v1" as const;
|
|
7
|
+
|
|
8
|
+
export const PUBLIC_ADAPTER_FAMILIES = [
|
|
9
|
+
"openai-responses",
|
|
10
|
+
"openai-chat",
|
|
11
|
+
"anthropic-messages",
|
|
12
|
+
] as const;
|
|
13
|
+
export type PublicAdapterFamily = (typeof PUBLIC_ADAPTER_FAMILIES)[number];
|
|
14
|
+
|
|
15
|
+
export interface PublicRouteRegistryEntryV1 {
|
|
16
|
+
providerId: string;
|
|
17
|
+
modelId: string;
|
|
18
|
+
adapterFamilies: PublicAdapterFamily[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface PublicRouteRegistryManifestV1 {
|
|
22
|
+
schemaVersion: typeof PUBLIC_ROUTE_REGISTRY_SCHEMA_VERSION;
|
|
23
|
+
registryVersion: string;
|
|
24
|
+
sourceCommit: string;
|
|
25
|
+
entries: PublicRouteRegistryEntryV1[];
|
|
26
|
+
manifestDigest: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface PublicProtocolSubjectV1 {
|
|
30
|
+
subjectKind: "protocol";
|
|
31
|
+
compatibilityVersion: string;
|
|
32
|
+
adapterFamily: PublicAdapterFamily;
|
|
33
|
+
inboundProtocol: string;
|
|
34
|
+
upstreamProtocol: string;
|
|
35
|
+
surface: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface PublicRouteSubjectV1 {
|
|
39
|
+
subjectKind: "route";
|
|
40
|
+
providerId: string;
|
|
41
|
+
modelId: string;
|
|
42
|
+
adapterFamily: PublicAdapterFamily;
|
|
43
|
+
compatibilityVersion: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface PublicTaskSubjectV1 {
|
|
47
|
+
subjectKind: "task";
|
|
48
|
+
route: PublicRouteSubjectV1;
|
|
49
|
+
taskClassId: string;
|
|
50
|
+
taskClassVersion: string;
|
|
51
|
+
taskFixtureDigest: string;
|
|
52
|
+
verifierManifestDigest: string;
|
|
53
|
+
fabricCompatibilityVersion: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export type PublicEvidenceSubjectV1 =
|
|
57
|
+
| PublicProtocolSubjectV1
|
|
58
|
+
| PublicRouteSubjectV1
|
|
59
|
+
| PublicTaskSubjectV1;
|
|
60
|
+
|
|
61
|
+
export interface PublicAssertionSummaryV1 {
|
|
62
|
+
id: string;
|
|
63
|
+
required: boolean;
|
|
64
|
+
passed: boolean;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface PublicIncidentRefV1 {
|
|
68
|
+
corpusId: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface PublicEvidenceRecordV1 {
|
|
72
|
+
recordId: string;
|
|
73
|
+
subjectId: string;
|
|
74
|
+
evidenceLayer: EvidenceLayer;
|
|
75
|
+
suiteId: string;
|
|
76
|
+
suiteVersion: string;
|
|
77
|
+
scenarioId: string;
|
|
78
|
+
scenarioVersion: string;
|
|
79
|
+
verdict: CompatibilityVerdict;
|
|
80
|
+
observedDayUtc: string;
|
|
81
|
+
subject: PublicEvidenceSubjectV1;
|
|
82
|
+
assertions: PublicAssertionSummaryV1[];
|
|
83
|
+
incidentRefs?: PublicIncidentRefV1[];
|
|
84
|
+
artifactRefs?: string[];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface PublicArtifactV1 {
|
|
88
|
+
artifactId: string;
|
|
89
|
+
artifactClass: string;
|
|
90
|
+
mediaType: string;
|
|
91
|
+
byteCount: number;
|
|
92
|
+
contentBase64: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface PublicPublisherV1 {
|
|
96
|
+
algorithm: "ed25519";
|
|
97
|
+
keyId: string;
|
|
98
|
+
publicKey: string;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface PublicBundleSignatureV1 {
|
|
102
|
+
algorithm: "ed25519";
|
|
103
|
+
signedDigest: string;
|
|
104
|
+
signature: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface PublicEvidenceBundleUnsignedV1 {
|
|
108
|
+
schemaVersion: typeof PUBLIC_EVIDENCE_BUNDLE_SCHEMA_VERSION;
|
|
109
|
+
exportPolicyVersion: typeof PUBLIC_EXPORT_POLICY_VERSION;
|
|
110
|
+
bundleId: string;
|
|
111
|
+
createdDayUtc: string;
|
|
112
|
+
publisher: PublicPublisherV1;
|
|
113
|
+
records: PublicEvidenceRecordV1[];
|
|
114
|
+
artifacts: PublicArtifactV1[];
|
|
115
|
+
bundleDigest: string;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface PublicEvidenceBundleV1 extends PublicEvidenceBundleUnsignedV1 {
|
|
119
|
+
signature: PublicBundleSignatureV1;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface PublicEvidencePreviewBundleV1 {
|
|
123
|
+
schemaVersion: typeof PUBLIC_EVIDENCE_BUNDLE_SCHEMA_VERSION;
|
|
124
|
+
exportPolicyVersion: typeof PUBLIC_EXPORT_POLICY_VERSION;
|
|
125
|
+
createdDayUtc: string;
|
|
126
|
+
records: PublicEvidenceRecordV1[];
|
|
127
|
+
artifacts: PublicArtifactV1[];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export type PublicRevocationReasonV1 =
|
|
131
|
+
| "publisher_retracted"
|
|
132
|
+
| "privacy_retraction"
|
|
133
|
+
| "evidence_invalidated"
|
|
134
|
+
| "superseded";
|
|
135
|
+
|
|
136
|
+
export interface PublicRevocationTargetV1 {
|
|
137
|
+
kind: "bundle" | "record";
|
|
138
|
+
id: string;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface PublicEvidenceRevocationV1 {
|
|
142
|
+
schemaVersion: typeof PUBLIC_EVIDENCE_REVOCATION_SCHEMA_VERSION;
|
|
143
|
+
revocationId: string;
|
|
144
|
+
issuedDayUtc: string;
|
|
145
|
+
publisher: PublicPublisherV1;
|
|
146
|
+
targets: PublicRevocationTargetV1[];
|
|
147
|
+
reason: PublicRevocationReasonV1;
|
|
148
|
+
signature: PublicBundleSignatureV1;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export type PublicRevocationVerificationResult =
|
|
152
|
+
| { status: "cryptographically_valid"; revocation: PublicEvidenceRevocationV1 }
|
|
153
|
+
| { status: "schema_rejected" | "digest_invalid" | "signature_invalid" | "publisher_mismatch" | "unknown_target"; detail?: string };
|
|
154
|
+
|
|
155
|
+
export interface CommunityEvidenceSummaryV1 {
|
|
156
|
+
trustClass: "community_untrusted_v1";
|
|
157
|
+
status: "cryptographically_valid";
|
|
158
|
+
bundleId: string;
|
|
159
|
+
publisherKeyId: string;
|
|
160
|
+
activeRecordCount: number;
|
|
161
|
+
revokedRecordCount: number;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export type PublicProjectionNotExportableReason =
|
|
165
|
+
| "private_route_identity"
|
|
166
|
+
| "unsupported_subject"
|
|
167
|
+
| "unsafe_public_field"
|
|
168
|
+
| "unsupported_adapter_family";
|
|
169
|
+
|
|
170
|
+
export type PublicEvidenceProjectionResult =
|
|
171
|
+
| { status: "exportable"; record: PublicEvidenceRecordV1 }
|
|
172
|
+
| { status: "not_exportable"; reason: PublicProjectionNotExportableReason; detailCode?: string };
|
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
import { EVIDENCE_LAYERS, VERDICTS, type EvidenceLayer } from "../constants";
|
|
2
|
+
import { isSha256Hex } from "../digest";
|
|
3
|
+
import { publicEvidenceId } from "./ids";
|
|
4
|
+
import { findPublicRouteRegistryEntry } from "./registry";
|
|
5
|
+
import {
|
|
6
|
+
PUBLIC_ADAPTER_FAMILIES,
|
|
7
|
+
PUBLIC_ROUTE_REGISTRY_SCHEMA_VERSION,
|
|
8
|
+
type PublicAdapterFamily,
|
|
9
|
+
type PublicAssertionSummaryV1,
|
|
10
|
+
type PublicEvidenceRecordV1,
|
|
11
|
+
type PublicEvidenceSubjectV1,
|
|
12
|
+
type PublicIncidentRefV1,
|
|
13
|
+
type PublicProtocolSubjectV1,
|
|
14
|
+
type PublicRouteRegistryEntryV1,
|
|
15
|
+
type PublicRouteRegistryManifestV1,
|
|
16
|
+
type PublicRouteSubjectV1,
|
|
17
|
+
type PublicTaskSubjectV1,
|
|
18
|
+
} from "./types";
|
|
19
|
+
|
|
20
|
+
const MAX_PUBLIC_STRING_BYTES = 4 * 1024;
|
|
21
|
+
const MAX_PUBLIC_ASSERTIONS = 64;
|
|
22
|
+
const MAX_PUBLIC_INCIDENT_REFS = 32;
|
|
23
|
+
const MAX_PUBLIC_ARTIFACT_REFS = 16;
|
|
24
|
+
const PUBLIC_IDENTIFIER = /^[A-Za-z0-9][A-Za-z0-9._:+-]{0,255}$/;
|
|
25
|
+
const UTC_DAY = /^\d{4}-\d{2}-\d{2}$/;
|
|
26
|
+
const SOURCE_COMMIT = /^[0-9a-f]{40}$/;
|
|
27
|
+
|
|
28
|
+
const PUBLIC_INCIDENT_CORPUS_IDS = new Set(
|
|
29
|
+
Array.from({ length: 21 }, (_, index) => `IC-${String(index + 1).padStart(3, "0")}`),
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
export class PublicEvidenceValidationError extends Error {
|
|
33
|
+
override readonly name = "PublicEvidenceValidationError";
|
|
34
|
+
|
|
35
|
+
constructor(readonly code: string, message: string) {
|
|
36
|
+
super(message);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
41
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function assertObject(value: unknown, field: string): Record<string, unknown> {
|
|
45
|
+
if (!isPlainObject(value)) {
|
|
46
|
+
throw new PublicEvidenceValidationError("invalid_type", `${field} must be an object`);
|
|
47
|
+
}
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function assertKnownKeys(
|
|
52
|
+
raw: Record<string, unknown>,
|
|
53
|
+
field: string,
|
|
54
|
+
allowed: readonly string[],
|
|
55
|
+
): void {
|
|
56
|
+
const allow = new Set(allowed);
|
|
57
|
+
for (const key of Object.keys(raw)) {
|
|
58
|
+
if (!allow.has(key)) {
|
|
59
|
+
throw new PublicEvidenceValidationError("unknown_field", `${field}.${key} is not public schema`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function assertString(value: unknown, field: string, max = MAX_PUBLIC_STRING_BYTES): string {
|
|
65
|
+
if (typeof value !== "string") {
|
|
66
|
+
throw new PublicEvidenceValidationError("invalid_type", `${field} must be a string`);
|
|
67
|
+
}
|
|
68
|
+
if (value.includes("\0")) {
|
|
69
|
+
throw new PublicEvidenceValidationError("unsafe_public_field", `${field} contains NUL`);
|
|
70
|
+
}
|
|
71
|
+
if (new TextEncoder().encode(value).byteLength > max) {
|
|
72
|
+
throw new PublicEvidenceValidationError("field_too_large", `${field} exceeds ${max} bytes`);
|
|
73
|
+
}
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function assertPublicIdentifier(value: unknown, field: string): string {
|
|
78
|
+
const result = assertString(value, field, 256);
|
|
79
|
+
if (!PUBLIC_IDENTIFIER.test(result)) {
|
|
80
|
+
throw new PublicEvidenceValidationError("unsafe_public_field", `${field} is not a closed public identifier`);
|
|
81
|
+
}
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function assertBoolean(value: unknown, field: string): boolean {
|
|
86
|
+
if (value !== true && value !== false) {
|
|
87
|
+
throw new PublicEvidenceValidationError("invalid_type", `${field} must be boolean`);
|
|
88
|
+
}
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function assertSha256(value: unknown, field: string): string {
|
|
93
|
+
const result = assertString(value, field, 64);
|
|
94
|
+
if (!isSha256Hex(result)) {
|
|
95
|
+
throw new PublicEvidenceValidationError("invalid_digest", `${field} must be lowercase sha256 hex`);
|
|
96
|
+
}
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function assertClosed<T extends string>(
|
|
101
|
+
value: unknown,
|
|
102
|
+
field: string,
|
|
103
|
+
allowed: readonly T[],
|
|
104
|
+
): T {
|
|
105
|
+
if (typeof value !== "string" || !(allowed as readonly string[]).includes(value)) {
|
|
106
|
+
throw new PublicEvidenceValidationError("closed_set", `${field} is not in the public closed set`);
|
|
107
|
+
}
|
|
108
|
+
return value as T;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function assertUtcDay(value: unknown, field: string): string {
|
|
112
|
+
const result = assertString(value, field, 10);
|
|
113
|
+
if (!UTC_DAY.test(result)) {
|
|
114
|
+
throw new PublicEvidenceValidationError("invalid_day", `${field} must be YYYY-MM-DD`);
|
|
115
|
+
}
|
|
116
|
+
const parsed = new Date(`${result}T00:00:00.000Z`);
|
|
117
|
+
if (Number.isNaN(parsed.getTime()) || parsed.toISOString().slice(0, 10) !== result) {
|
|
118
|
+
throw new PublicEvidenceValidationError("invalid_day", `${field} must be a real UTC day`);
|
|
119
|
+
}
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function validateAdapterFamily(value: unknown, field: string): PublicAdapterFamily {
|
|
124
|
+
return assertClosed(value, field, PUBLIC_ADAPTER_FAMILIES);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function validateProtocolSubject(rawValue: unknown): PublicProtocolSubjectV1 {
|
|
128
|
+
const raw = assertObject(rawValue, "subject");
|
|
129
|
+
assertKnownKeys(raw, "subject", [
|
|
130
|
+
"subjectKind",
|
|
131
|
+
"compatibilityVersion",
|
|
132
|
+
"adapterFamily",
|
|
133
|
+
"inboundProtocol",
|
|
134
|
+
"upstreamProtocol",
|
|
135
|
+
"surface",
|
|
136
|
+
]);
|
|
137
|
+
if (raw.subjectKind !== "protocol") {
|
|
138
|
+
throw new PublicEvidenceValidationError("layer_subject_mismatch", "protocol layer requires protocol subject");
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
subjectKind: "protocol",
|
|
142
|
+
compatibilityVersion: assertPublicIdentifier(raw.compatibilityVersion, "subject.compatibilityVersion"),
|
|
143
|
+
adapterFamily: validateAdapterFamily(raw.adapterFamily, "subject.adapterFamily"),
|
|
144
|
+
inboundProtocol: assertPublicIdentifier(raw.inboundProtocol, "subject.inboundProtocol"),
|
|
145
|
+
upstreamProtocol: assertPublicIdentifier(raw.upstreamProtocol, "subject.upstreamProtocol"),
|
|
146
|
+
surface: assertPublicIdentifier(raw.surface, "subject.surface"),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function validateRouteSubject(rawValue: unknown): PublicRouteSubjectV1 {
|
|
151
|
+
const raw = assertObject(rawValue, "subject");
|
|
152
|
+
assertKnownKeys(raw, "subject", [
|
|
153
|
+
"subjectKind",
|
|
154
|
+
"providerId",
|
|
155
|
+
"modelId",
|
|
156
|
+
"adapterFamily",
|
|
157
|
+
"compatibilityVersion",
|
|
158
|
+
]);
|
|
159
|
+
if (raw.subjectKind !== "route") {
|
|
160
|
+
throw new PublicEvidenceValidationError("layer_subject_mismatch", "route layer requires route subject");
|
|
161
|
+
}
|
|
162
|
+
const providerId = assertPublicIdentifier(raw.providerId, "subject.providerId");
|
|
163
|
+
const modelId = assertPublicIdentifier(raw.modelId, "subject.modelId");
|
|
164
|
+
const adapterFamily = validateAdapterFamily(raw.adapterFamily, "subject.adapterFamily");
|
|
165
|
+
const entry = findPublicRouteRegistryEntry(providerId, modelId);
|
|
166
|
+
if (!entry || !entry.adapterFamilies.includes(adapterFamily)) {
|
|
167
|
+
throw new PublicEvidenceValidationError("public_registry_rejected", "route is not in the reviewed public registry");
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
subjectKind: "route",
|
|
171
|
+
providerId,
|
|
172
|
+
modelId,
|
|
173
|
+
adapterFamily,
|
|
174
|
+
compatibilityVersion: assertPublicIdentifier(raw.compatibilityVersion, "subject.compatibilityVersion"),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function validateTaskSubject(rawValue: unknown): PublicTaskSubjectV1 {
|
|
179
|
+
const raw = assertObject(rawValue, "subject");
|
|
180
|
+
assertKnownKeys(raw, "subject", [
|
|
181
|
+
"subjectKind",
|
|
182
|
+
"route",
|
|
183
|
+
"taskClassId",
|
|
184
|
+
"taskClassVersion",
|
|
185
|
+
"taskFixtureDigest",
|
|
186
|
+
"verifierManifestDigest",
|
|
187
|
+
"fabricCompatibilityVersion",
|
|
188
|
+
]);
|
|
189
|
+
if (raw.subjectKind !== "task") {
|
|
190
|
+
throw new PublicEvidenceValidationError("layer_subject_mismatch", "task layer requires task subject");
|
|
191
|
+
}
|
|
192
|
+
return {
|
|
193
|
+
subjectKind: "task",
|
|
194
|
+
route: validateRouteSubject(raw.route),
|
|
195
|
+
taskClassId: assertPublicIdentifier(raw.taskClassId, "subject.taskClassId"),
|
|
196
|
+
taskClassVersion: assertPublicIdentifier(raw.taskClassVersion, "subject.taskClassVersion"),
|
|
197
|
+
taskFixtureDigest: assertSha256(raw.taskFixtureDigest, "subject.taskFixtureDigest"),
|
|
198
|
+
verifierManifestDigest: assertSha256(raw.verifierManifestDigest, "subject.verifierManifestDigest"),
|
|
199
|
+
fabricCompatibilityVersion: assertPublicIdentifier(
|
|
200
|
+
raw.fabricCompatibilityVersion,
|
|
201
|
+
"subject.fabricCompatibilityVersion",
|
|
202
|
+
),
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function validateSubject(raw: unknown, layer: EvidenceLayer): PublicEvidenceSubjectV1 {
|
|
207
|
+
if (layer === "protocol_conformance") return validateProtocolSubject(raw);
|
|
208
|
+
if (layer === "live_route_compatibility") return validateRouteSubject(raw);
|
|
209
|
+
if (layer === "task_effectiveness") return validateTaskSubject(raw);
|
|
210
|
+
const _exhaustive: never = layer;
|
|
211
|
+
throw new PublicEvidenceValidationError("unsupported_layer", String(_exhaustive));
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function validateAssertion(rawValue: unknown, index: number): PublicAssertionSummaryV1 {
|
|
215
|
+
const raw = assertObject(rawValue, `assertions[${index}]`);
|
|
216
|
+
assertKnownKeys(raw, `assertions[${index}]`, ["id", "required", "passed"]);
|
|
217
|
+
return {
|
|
218
|
+
id: assertPublicIdentifier(raw.id, `assertions[${index}].id`),
|
|
219
|
+
required: assertBoolean(raw.required, `assertions[${index}].required`),
|
|
220
|
+
passed: assertBoolean(raw.passed, `assertions[${index}].passed`),
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export function isPublicIncidentRef(value: unknown): value is string {
|
|
225
|
+
return typeof value === "string" && PUBLIC_INCIDENT_CORPUS_IDS.has(value);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function validateIncidentRef(rawValue: unknown, index: number): PublicIncidentRefV1 {
|
|
229
|
+
const raw = assertObject(rawValue, `incidentRefs[${index}]`);
|
|
230
|
+
assertKnownKeys(raw, `incidentRefs[${index}]`, ["corpusId"]);
|
|
231
|
+
const corpusId = assertString(raw.corpusId, `incidentRefs[${index}].corpusId`, 6);
|
|
232
|
+
if (!isPublicIncidentRef(corpusId)) {
|
|
233
|
+
throw new PublicEvidenceValidationError("incident_ref_rejected", `${corpusId} is not in the reviewed corpus`);
|
|
234
|
+
}
|
|
235
|
+
return { corpusId };
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function validateUniqueIds(rawValue: unknown, field: string, max: number): string[] {
|
|
239
|
+
if (!Array.isArray(rawValue)) {
|
|
240
|
+
throw new PublicEvidenceValidationError("invalid_type", `${field} must be an array`);
|
|
241
|
+
}
|
|
242
|
+
if (rawValue.length > max) {
|
|
243
|
+
throw new PublicEvidenceValidationError("array_too_large", `${field} exceeds ${max}`);
|
|
244
|
+
}
|
|
245
|
+
const values = rawValue.map((value, index) => assertSha256(value, `${field}[${index}]`));
|
|
246
|
+
if (new Set(values).size !== values.length) {
|
|
247
|
+
throw new PublicEvidenceValidationError("duplicate_id", `${field} contains duplicates`);
|
|
248
|
+
}
|
|
249
|
+
return values;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export function validatePublicEvidenceRecord(rawValue: unknown): PublicEvidenceRecordV1 {
|
|
253
|
+
const raw = assertObject(rawValue, "record");
|
|
254
|
+
assertKnownKeys(raw, "record", [
|
|
255
|
+
"recordId",
|
|
256
|
+
"subjectId",
|
|
257
|
+
"evidenceLayer",
|
|
258
|
+
"suiteId",
|
|
259
|
+
"suiteVersion",
|
|
260
|
+
"scenarioId",
|
|
261
|
+
"scenarioVersion",
|
|
262
|
+
"verdict",
|
|
263
|
+
"observedDayUtc",
|
|
264
|
+
"subject",
|
|
265
|
+
"assertions",
|
|
266
|
+
"incidentRefs",
|
|
267
|
+
"artifactRefs",
|
|
268
|
+
]);
|
|
269
|
+
|
|
270
|
+
const evidenceLayer = assertClosed(raw.evidenceLayer, "record.evidenceLayer", EVIDENCE_LAYERS);
|
|
271
|
+
const subject = validateSubject(raw.subject, evidenceLayer);
|
|
272
|
+
const subjectId = assertSha256(raw.subjectId, "record.subjectId");
|
|
273
|
+
const expectedSubjectId = publicEvidenceId("subject", subject);
|
|
274
|
+
if (subjectId !== expectedSubjectId) {
|
|
275
|
+
throw new PublicEvidenceValidationError("subject_id_mismatch", "record.subjectId does not match public subject");
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (!Array.isArray(raw.assertions)) {
|
|
279
|
+
throw new PublicEvidenceValidationError("invalid_type", "record.assertions must be an array");
|
|
280
|
+
}
|
|
281
|
+
if (raw.assertions.length > MAX_PUBLIC_ASSERTIONS) {
|
|
282
|
+
throw new PublicEvidenceValidationError("array_too_large", `record.assertions exceeds ${MAX_PUBLIC_ASSERTIONS}`);
|
|
283
|
+
}
|
|
284
|
+
const assertions = raw.assertions.map(validateAssertion);
|
|
285
|
+
|
|
286
|
+
let incidentRefs: PublicIncidentRefV1[] | undefined;
|
|
287
|
+
if (raw.incidentRefs !== undefined) {
|
|
288
|
+
if (!Array.isArray(raw.incidentRefs)) {
|
|
289
|
+
throw new PublicEvidenceValidationError("invalid_type", "record.incidentRefs must be an array");
|
|
290
|
+
}
|
|
291
|
+
if (raw.incidentRefs.length > MAX_PUBLIC_INCIDENT_REFS) {
|
|
292
|
+
throw new PublicEvidenceValidationError(
|
|
293
|
+
"array_too_large",
|
|
294
|
+
`record.incidentRefs exceeds ${MAX_PUBLIC_INCIDENT_REFS}`,
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
incidentRefs = raw.incidentRefs.map(validateIncidentRef);
|
|
298
|
+
const ids = incidentRefs.map((ref) => ref.corpusId);
|
|
299
|
+
if (new Set(ids).size !== ids.length) {
|
|
300
|
+
throw new PublicEvidenceValidationError("duplicate_id", "record.incidentRefs contains duplicates");
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const artifactRefs = raw.artifactRefs === undefined
|
|
305
|
+
? undefined
|
|
306
|
+
: validateUniqueIds(raw.artifactRefs, "record.artifactRefs", MAX_PUBLIC_ARTIFACT_REFS);
|
|
307
|
+
|
|
308
|
+
const withoutRecordId: Omit<PublicEvidenceRecordV1, "recordId"> = {
|
|
309
|
+
subjectId,
|
|
310
|
+
evidenceLayer,
|
|
311
|
+
suiteId: assertPublicIdentifier(raw.suiteId, "record.suiteId"),
|
|
312
|
+
suiteVersion: assertPublicIdentifier(raw.suiteVersion, "record.suiteVersion"),
|
|
313
|
+
scenarioId: assertPublicIdentifier(raw.scenarioId, "record.scenarioId"),
|
|
314
|
+
scenarioVersion: assertPublicIdentifier(raw.scenarioVersion, "record.scenarioVersion"),
|
|
315
|
+
verdict: assertClosed(raw.verdict, "record.verdict", VERDICTS),
|
|
316
|
+
observedDayUtc: assertUtcDay(raw.observedDayUtc, "record.observedDayUtc"),
|
|
317
|
+
subject,
|
|
318
|
+
assertions,
|
|
319
|
+
...(incidentRefs !== undefined ? { incidentRefs } : {}),
|
|
320
|
+
...(artifactRefs !== undefined ? { artifactRefs } : {}),
|
|
321
|
+
};
|
|
322
|
+
const recordId = assertSha256(raw.recordId, "record.recordId");
|
|
323
|
+
const expectedRecordId = publicEvidenceId("record", withoutRecordId);
|
|
324
|
+
if (recordId !== expectedRecordId) {
|
|
325
|
+
throw new PublicEvidenceValidationError("record_id_mismatch", "record.recordId does not match public record");
|
|
326
|
+
}
|
|
327
|
+
return { recordId, ...withoutRecordId };
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function validateRegistryEntry(rawValue: unknown, index: number): PublicRouteRegistryEntryV1 {
|
|
331
|
+
const raw = assertObject(rawValue, `entries[${index}]`);
|
|
332
|
+
assertKnownKeys(raw, `entries[${index}]`, ["providerId", "modelId", "adapterFamilies"]);
|
|
333
|
+
if (!Array.isArray(raw.adapterFamilies) || raw.adapterFamilies.length === 0) {
|
|
334
|
+
throw new PublicEvidenceValidationError("invalid_registry", `entries[${index}].adapterFamilies must be non-empty`);
|
|
335
|
+
}
|
|
336
|
+
const adapterFamilies = raw.adapterFamilies.map((value, adapterIndex) =>
|
|
337
|
+
validateAdapterFamily(value, `entries[${index}].adapterFamilies[${adapterIndex}]`)
|
|
338
|
+
);
|
|
339
|
+
if (new Set(adapterFamilies).size !== adapterFamilies.length) {
|
|
340
|
+
throw new PublicEvidenceValidationError("duplicate_id", `entries[${index}].adapterFamilies contains duplicates`);
|
|
341
|
+
}
|
|
342
|
+
return {
|
|
343
|
+
providerId: assertPublicIdentifier(raw.providerId, `entries[${index}].providerId`),
|
|
344
|
+
modelId: assertPublicIdentifier(raw.modelId, `entries[${index}].modelId`),
|
|
345
|
+
adapterFamilies,
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
export function validatePublicRouteRegistryManifest(rawValue: unknown): PublicRouteRegistryManifestV1 {
|
|
350
|
+
const raw = assertObject(rawValue, "publicRouteRegistry");
|
|
351
|
+
assertKnownKeys(raw, "publicRouteRegistry", [
|
|
352
|
+
"schemaVersion",
|
|
353
|
+
"registryVersion",
|
|
354
|
+
"sourceCommit",
|
|
355
|
+
"entries",
|
|
356
|
+
"manifestDigest",
|
|
357
|
+
]);
|
|
358
|
+
if (raw.schemaVersion !== PUBLIC_ROUTE_REGISTRY_SCHEMA_VERSION) {
|
|
359
|
+
throw new PublicEvidenceValidationError("unsupported_version", "unsupported public route registry schema");
|
|
360
|
+
}
|
|
361
|
+
const registryVersion = assertPublicIdentifier(raw.registryVersion, "publicRouteRegistry.registryVersion");
|
|
362
|
+
const sourceCommit = assertString(raw.sourceCommit, "publicRouteRegistry.sourceCommit", 40);
|
|
363
|
+
if (!SOURCE_COMMIT.test(sourceCommit)) {
|
|
364
|
+
throw new PublicEvidenceValidationError("invalid_registry", "publicRouteRegistry.sourceCommit must be a commit SHA");
|
|
365
|
+
}
|
|
366
|
+
if (!Array.isArray(raw.entries) || raw.entries.length === 0 || raw.entries.length > 512) {
|
|
367
|
+
throw new PublicEvidenceValidationError("invalid_registry", "publicRouteRegistry.entries must contain 1..512 entries");
|
|
368
|
+
}
|
|
369
|
+
const entries = raw.entries.map(validateRegistryEntry);
|
|
370
|
+
const identities = entries.map((entry) => `${entry.providerId}\0${entry.modelId}`);
|
|
371
|
+
if (new Set(identities).size !== identities.length) {
|
|
372
|
+
throw new PublicEvidenceValidationError("duplicate_id", "publicRouteRegistry.entries contains duplicates");
|
|
373
|
+
}
|
|
374
|
+
const manifestDigest = assertSha256(raw.manifestDigest, "publicRouteRegistry.manifestDigest");
|
|
375
|
+
const expectedDigest = publicEvidenceId("route_registry", {
|
|
376
|
+
schemaVersion: PUBLIC_ROUTE_REGISTRY_SCHEMA_VERSION,
|
|
377
|
+
registryVersion,
|
|
378
|
+
sourceCommit,
|
|
379
|
+
entries,
|
|
380
|
+
});
|
|
381
|
+
if (manifestDigest !== expectedDigest) {
|
|
382
|
+
throw new PublicEvidenceValidationError("digest_invalid", "publicRouteRegistry.manifestDigest mismatch");
|
|
383
|
+
}
|
|
384
|
+
return {
|
|
385
|
+
schemaVersion: PUBLIC_ROUTE_REGISTRY_SCHEMA_VERSION,
|
|
386
|
+
registryVersion,
|
|
387
|
+
sourceCommit,
|
|
388
|
+
entries,
|
|
389
|
+
manifestDigest,
|
|
390
|
+
};
|
|
391
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import {
|
|
2
|
+
discoverLiveScenarios,
|
|
3
|
+
expandLiveScenario,
|
|
4
|
+
loadLiveCaseAuthority,
|
|
5
|
+
} from "../live/manifest";
|
|
6
|
+
import {
|
|
7
|
+
liveSuiteManifestDigestForCase,
|
|
8
|
+
} from "../live/suite-manifest";
|
|
9
|
+
import {
|
|
10
|
+
discoverScenarios,
|
|
11
|
+
expandScenario,
|
|
12
|
+
loadCaseAuthority,
|
|
13
|
+
} from "../conformance/manifest";
|
|
14
|
+
import {
|
|
15
|
+
suiteManifestDigestForCase,
|
|
16
|
+
} from "../conformance/suite-manifest";
|
|
17
|
+
import {
|
|
18
|
+
discoverFabricScenarios,
|
|
19
|
+
expandFabricScenario,
|
|
20
|
+
fabricSuiteManifestDigest,
|
|
21
|
+
loadFabricCaseAuthority,
|
|
22
|
+
} from "../fabric/manifest";
|
|
23
|
+
import { scenarioManifestDigest } from "../digest";
|
|
24
|
+
import type { CaseRecord, EvidenceLayer, VerificationRole } from "../conformance/types";
|
|
25
|
+
import type { CatalogFilters, CatalogScenarioDto } from "./types";
|
|
26
|
+
|
|
27
|
+
type CatalogAuthority = {
|
|
28
|
+
manifestDefaults: {
|
|
29
|
+
version: string;
|
|
30
|
+
suiteVersion: string;
|
|
31
|
+
evidenceLayer: EvidenceLayer;
|
|
32
|
+
verificationRole: VerificationRole;
|
|
33
|
+
freshness: { maxAgeMs: number | null };
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
function mapCaseToCatalogScenario<TAuthority extends CatalogAuthority>(
|
|
38
|
+
caseRecord: CaseRecord,
|
|
39
|
+
authority: TAuthority,
|
|
40
|
+
suiteDigestFn: (caseRecord: CaseRecord, authority: TAuthority) => string,
|
|
41
|
+
expandFn: (caseRecord: CaseRecord, authority: TAuthority) => Record<string, unknown>,
|
|
42
|
+
): CatalogScenarioDto {
|
|
43
|
+
const expanded = expandFn(caseRecord, authority);
|
|
44
|
+
return {
|
|
45
|
+
scenarioId: caseRecord.id,
|
|
46
|
+
scenarioVersion: authority.manifestDefaults.version,
|
|
47
|
+
evidenceLayer: authority.manifestDefaults.evidenceLayer,
|
|
48
|
+
suiteId: caseRecord.suite,
|
|
49
|
+
suiteVersion: authority.manifestDefaults.suiteVersion,
|
|
50
|
+
capability: caseRecord.capability,
|
|
51
|
+
verificationRole: caseRecord.verificationRole ?? authority.manifestDefaults.verificationRole,
|
|
52
|
+
requirements: {
|
|
53
|
+
inboundProtocols: [...caseRecord.requirements.inboundProtocols],
|
|
54
|
+
upstreamProtocols: [...caseRecord.requirements.upstreamProtocols],
|
|
55
|
+
surfaces: [...caseRecord.requirements.surfaces],
|
|
56
|
+
},
|
|
57
|
+
freshness: { ...authority.manifestDefaults.freshness },
|
|
58
|
+
scenarioManifestDigest: scenarioManifestDigest(expanded),
|
|
59
|
+
suiteManifestDigest: suiteDigestFn(caseRecord, authority),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function queryLabCatalog(filters: CatalogFilters = {}): CatalogScenarioDto[] {
|
|
64
|
+
const items: CatalogScenarioDto[] = [];
|
|
65
|
+
if (!filters.layer || filters.layer === "protocol_conformance") {
|
|
66
|
+
const authority = loadCaseAuthority();
|
|
67
|
+
const suites = filters.suiteId ? [filters.suiteId] : undefined;
|
|
68
|
+
const scenarios = discoverScenarios(authority, suites ?? undefined);
|
|
69
|
+
for (const caseRecord of scenarios) {
|
|
70
|
+
items.push(mapCaseToCatalogScenario(caseRecord, authority, suiteManifestDigestForCase, expandScenario));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (!filters.layer || filters.layer === "live_route_compatibility") {
|
|
74
|
+
const authority = loadLiveCaseAuthority();
|
|
75
|
+
const suites = filters.suiteId ? [filters.suiteId] : undefined;
|
|
76
|
+
const scenarios = discoverLiveScenarios(authority, suites ?? undefined);
|
|
77
|
+
for (const caseRecord of scenarios) {
|
|
78
|
+
items.push(mapCaseToCatalogScenario(caseRecord, authority, liveSuiteManifestDigestForCase, expandLiveScenario));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (!filters.layer || filters.layer === "task_effectiveness") {
|
|
82
|
+
const authority = loadFabricCaseAuthority();
|
|
83
|
+
const suites = filters.suiteId ? [filters.suiteId] : undefined;
|
|
84
|
+
const scenarios = discoverFabricScenarios(authority, suites ?? undefined);
|
|
85
|
+
for (const caseRecord of scenarios) {
|
|
86
|
+
items.push(mapCaseToCatalogScenario(
|
|
87
|
+
caseRecord,
|
|
88
|
+
authority,
|
|
89
|
+
(row, auth) => fabricSuiteManifestDigest(row.suite, auth),
|
|
90
|
+
expandFabricScenario,
|
|
91
|
+
));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return items.sort((a, b) => {
|
|
95
|
+
const layerCmp = a.evidenceLayer.localeCompare(b.evidenceLayer);
|
|
96
|
+
if (layerCmp !== 0) return layerCmp;
|
|
97
|
+
const suiteCmp = a.suiteId.localeCompare(b.suiteId);
|
|
98
|
+
if (suiteCmp !== 0) return suiteCmp;
|
|
99
|
+
return a.scenarioId.localeCompare(b.scenarioId);
|
|
100
|
+
});
|
|
101
|
+
}
|