@apifuse/provider-sdk 2.2.0-beta.7 → 2.2.0-beta.70
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/AUTHORING.md +943 -51
- package/CHANGELOG.md +273 -1
- package/LICENSE +21 -0
- package/README.md +117 -29
- package/SUBMISSION.md +3 -2
- package/bin/apifuse-check.ts +293 -13
- package/bin/apifuse-dev.ts +42 -19
- package/bin/apifuse-migrate-deployment.ts +200 -0
- package/bin/apifuse-migrate-operation-declaration.ts +55 -0
- package/bin/apifuse-migrate-shape.ts +202 -0
- package/bin/apifuse-pack-check.ts +19 -6
- package/bin/apifuse-pack-smoke.ts +57 -2
- package/bin/apifuse-pack-types.ts +736 -38
- package/bin/apifuse-perf.ts +59 -23
- package/bin/apifuse-record.ts +923 -94
- package/bin/apifuse-submit-check.ts +2313 -281
- package/bin/apifuse-test.ts +3 -1
- package/bin/submit-check-delimited-text.ts +50 -0
- package/dist/auth-turn/index.d.ts +3 -3
- package/dist/auth-turn/index.js +1 -1
- package/dist/auth.d.ts +14 -0
- package/dist/auth.js +67 -0
- package/dist/ceremonies/index.d.ts +16 -0
- package/dist/ceremonies/index.js +141 -36
- package/dist/cli/commands.d.ts +1 -1
- package/dist/cli/commands.js +30 -0
- package/dist/cli/create.d.ts +1 -1
- package/dist/cli/create.js +8 -2
- package/dist/cli/deployment-intent.d.ts +178 -0
- package/dist/cli/deployment-intent.js +277 -0
- package/dist/cli/local-connection.d.ts +111 -0
- package/dist/cli/local-connection.js +151 -0
- package/dist/cli/migrate-deployment-intent.d.ts +132 -0
- package/dist/cli/migrate-deployment-intent.js +1552 -0
- package/dist/cli/migrate-operation-declaration.d.ts +70 -0
- package/dist/cli/migrate-operation-declaration.js +2206 -0
- package/dist/cli/migrate-operation-shape.d.ts +44 -0
- package/dist/cli/migrate-operation-shape.js +113 -0
- package/dist/cli/migrate-provider-shape.d.ts +56 -0
- package/dist/cli/migrate-provider-shape.js +580 -0
- package/dist/cli/resolver-runtime.d.ts +21 -0
- package/dist/cli/resolver-runtime.js +31 -0
- package/dist/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl +141 -23
- package/dist/cli/templates/provider/Dockerfile.tpl +1 -1
- package/dist/cli/templates/provider/README.md.tpl +41 -19
- package/dist/cli/templates/provider/index.ts.tpl +6 -3
- package/dist/cli/templates/provider/operations/ping.ts.tpl +4 -1
- package/dist/cli/templates/provider/provider.json.tpl +6 -0
- package/dist/config/loader.d.ts +202 -16
- package/dist/config/loader.js +491 -141
- package/dist/contract-serialization.js +4 -8
- package/dist/contract-types.d.ts +12 -5
- package/dist/contract.js +24 -10
- package/dist/declaration-validation.d.ts +34 -0
- package/dist/declaration-validation.js +305 -0
- package/dist/define.d.ts +71 -29
- package/dist/define.js +807 -69
- package/dist/dev.d.ts +5 -0
- package/dist/dev.js +8 -1
- package/dist/engine.d.ts +129 -0
- package/dist/engine.js +209 -0
- package/dist/error-observability.d.ts +7 -0
- package/dist/error-observability.js +61 -0
- package/dist/error-resolution.d.ts +18 -0
- package/dist/error-resolution.js +243 -0
- package/dist/errors.d.ts +74 -0
- package/dist/errors.js +99 -0
- package/dist/fixture-sanitization.d.ts +28 -0
- package/dist/fixture-sanitization.js +371 -0
- package/dist/handle-meta.d.ts +90 -0
- package/dist/handle-meta.js +73 -0
- package/dist/handle.d.ts +226 -0
- package/dist/handle.js +345 -0
- package/dist/health-scenario.d.ts +1901 -0
- package/dist/health-scenario.js +653 -0
- package/dist/i18n/catalog.js +21 -1
- package/dist/i18n/error-messages.d.ts +86 -0
- package/dist/i18n/error-messages.js +192 -0
- package/dist/i18n/index.d.ts +1 -0
- package/dist/i18n/index.js +1 -0
- package/dist/i18n/keys.d.ts +12 -0
- package/dist/i18n/keys.js +76 -5
- package/dist/i18n/operation-locale-namespace.d.ts +2 -0
- package/dist/i18n/operation-locale-namespace.js +7 -0
- package/dist/index.d.ts +40 -15
- package/dist/index.js +29 -11
- package/dist/lint.d.ts +43 -11
- package/dist/lint.js +2512 -177
- package/dist/native-address.d.ts +43 -0
- package/dist/native-address.js +281 -0
- package/dist/native-egress-policy.d.ts +31 -0
- package/dist/native-egress-policy.js +288 -0
- package/dist/observability.d.ts +5 -2
- package/dist/observability.js +48 -1
- package/dist/provider.d.ts +18 -8
- package/dist/provider.js +11 -6
- package/dist/runtime/auth-flow.d.ts +6 -1
- package/dist/runtime/auth-flow.js +8 -0
- package/dist/runtime/bounded-expiring-map.d.ts +21 -0
- package/dist/runtime/bounded-expiring-map.js +64 -0
- package/dist/runtime/browser-telemetry-binding.d.ts +5 -0
- package/dist/runtime/browser-telemetry-binding.js +83 -0
- package/dist/runtime/browser-telemetry.d.ts +76 -0
- package/dist/runtime/browser-telemetry.js +165 -0
- package/dist/runtime/browser.d.ts +4 -0
- package/dist/runtime/browser.js +688 -83
- package/dist/runtime/cache-telemetry.d.ts +71 -0
- package/dist/runtime/cache-telemetry.js +177 -0
- package/dist/runtime/cache.d.ts +3 -0
- package/dist/runtime/cache.js +245 -23
- package/dist/runtime/capability-response.d.ts +3 -0
- package/dist/runtime/capability-response.js +56 -0
- package/dist/runtime/capability-telemetry.d.ts +46 -0
- package/dist/runtime/capability-telemetry.js +68 -0
- package/dist/runtime/chrome149-header-order.d.ts +58 -0
- package/dist/runtime/chrome149-header-order.js +289 -0
- package/dist/runtime/diagnostic-env-values.d.ts +5 -0
- package/dist/runtime/diagnostic-env-values.js +57 -0
- package/dist/runtime/diagnostic-env.d.ts +14 -0
- package/dist/runtime/diagnostic-env.js +44 -0
- package/dist/runtime/diagnostic-redactor.d.ts +54 -0
- package/dist/runtime/diagnostic-redactor.js +571 -0
- package/dist/runtime/egress-lease.d.ts +65 -0
- package/dist/runtime/egress-lease.js +236 -0
- package/dist/runtime/engine-mode.d.ts +74 -0
- package/dist/runtime/engine-mode.js +152 -0
- package/dist/runtime/env.js +14 -1
- package/dist/runtime/executor.d.ts +3 -2
- package/dist/runtime/executor.js +23 -26
- package/dist/runtime/handle-wordlist.d.ts +43 -0
- package/dist/runtime/handle-wordlist.js +256 -0
- package/dist/runtime/handle.d.ts +71 -0
- package/dist/runtime/handle.js +908 -0
- package/dist/runtime/http-telemetry-binding.d.ts +10 -0
- package/dist/runtime/http-telemetry-binding.js +152 -0
- package/dist/runtime/http-telemetry-guard.d.ts +16 -0
- package/dist/runtime/http-telemetry-guard.js +202 -0
- package/dist/runtime/http-telemetry.d.ts +104 -0
- package/dist/runtime/http-telemetry.js +190 -0
- package/dist/runtime/http.d.ts +34 -0
- package/dist/runtime/http.js +680 -121
- package/dist/runtime/insights.js +2 -2
- package/dist/runtime/instrumentation.d.ts +2 -2
- package/dist/runtime/instrumentation.js +462 -19
- package/dist/runtime/native-network-errors.d.ts +33 -0
- package/dist/runtime/native-network-errors.js +69 -0
- package/dist/runtime/native-network.d.ts +105 -0
- package/dist/runtime/native-network.js +1433 -0
- package/dist/runtime/native-telemetry.d.ts +142 -0
- package/dist/runtime/native-telemetry.js +231 -0
- package/dist/runtime/ocr-telemetry.d.ts +82 -0
- package/dist/runtime/ocr-telemetry.js +192 -0
- package/dist/runtime/ocr.d.ts +29 -0
- package/dist/runtime/ocr.js +468 -0
- package/dist/runtime/otlp.d.ts +71 -2
- package/dist/runtime/otlp.js +398 -16
- package/dist/runtime/provider.d.ts +7 -0
- package/dist/runtime/provider.js +14 -0
- package/dist/runtime/proxy-errors.js +6 -2
- package/dist/runtime/proxy-nodemaven.d.ts +56 -0
- package/dist/runtime/proxy-nodemaven.js +147 -0
- package/dist/runtime/proxy-retry-policy.d.ts +4 -1
- package/dist/runtime/proxy-retry-policy.js +11 -2
- package/dist/runtime/proxy-telemetry.d.ts +133 -3
- package/dist/runtime/proxy-telemetry.js +218 -70
- package/dist/runtime/redirect-hop-headers.d.ts +19 -0
- package/dist/runtime/redirect-hop-headers.js +58 -0
- package/dist/runtime/redirects.d.ts +61 -0
- package/dist/runtime/redirects.js +149 -0
- package/dist/runtime/redis.d.ts +1 -1
- package/dist/runtime/redis.js +4 -2
- package/dist/runtime/request-options.d.ts +75 -1
- package/dist/runtime/request-options.js +588 -0
- package/dist/runtime/request-telemetry.d.ts +70 -0
- package/dist/runtime/request-telemetry.js +229 -0
- package/dist/runtime/resolver-config.d.ts +13 -0
- package/dist/runtime/resolver-config.js +14 -0
- package/dist/runtime/resolver-public.d.ts +3 -0
- package/dist/runtime/resolver-public.js +1 -0
- package/dist/runtime/resolver-runtime-options.d.ts +14 -0
- package/dist/runtime/resolver-runtime-options.js +33 -0
- package/dist/runtime/resolver-shared.d.ts +24 -0
- package/dist/runtime/resolver-shared.js +69 -0
- package/dist/runtime/resolver-span-attributes.d.ts +34 -0
- package/dist/runtime/resolver-span-attributes.js +93 -0
- package/dist/runtime/resolver-telemetry.d.ts +135 -0
- package/dist/runtime/resolver-telemetry.js +204 -0
- package/dist/runtime/resolver-usage.d.ts +32 -0
- package/dist/runtime/resolver-usage.js +54 -0
- package/dist/runtime/resolver-vendors/bindings.d.ts +53 -0
- package/dist/runtime/resolver-vendors/bindings.js +45 -0
- package/dist/runtime/resolver-vendors/browser.d.ts +24 -0
- package/dist/runtime/resolver-vendors/browser.js +423 -0
- package/dist/runtime/resolver-vendors/capsolver.d.ts +22 -0
- package/dist/runtime/resolver-vendors/capsolver.js +544 -0
- package/dist/runtime/resolver-vendors/hosts.d.ts +23 -0
- package/dist/runtime/resolver-vendors/hosts.js +68 -0
- package/dist/runtime/resolver-vendors/hypersolutions.d.ts +27 -0
- package/dist/runtime/resolver-vendors/hypersolutions.js +369 -0
- package/dist/runtime/resolver-vendors/twocaptcha.d.ts +24 -0
- package/dist/runtime/resolver-vendors/twocaptcha.js +425 -0
- package/dist/runtime/resolver-vendors/types.d.ts +125 -0
- package/dist/runtime/resolver-vendors/types.js +106 -0
- package/dist/runtime/resolver.d.ts +79 -0
- package/dist/runtime/resolver.js +1094 -0
- package/dist/runtime/state-telemetry.d.ts +79 -0
- package/dist/runtime/state-telemetry.js +194 -0
- package/dist/runtime/state.d.ts +10 -1
- package/dist/runtime/state.js +322 -82
- package/dist/runtime/stealth-akamai-sbsd.d.ts +54 -0
- package/dist/runtime/stealth-akamai-sbsd.js +142 -0
- package/dist/runtime/stealth-cookies.d.ts +24 -0
- package/dist/runtime/stealth-cookies.js +131 -0
- package/dist/runtime/stealth-owned-headers.d.ts +39 -0
- package/dist/runtime/stealth-owned-headers.js +57 -0
- package/dist/runtime/stealth-telemetry.d.ts +92 -0
- package/dist/runtime/stealth-telemetry.js +179 -0
- package/dist/runtime/stealth.d.ts +45 -6
- package/dist/runtime/stealth.js +1775 -320
- package/dist/runtime/stt-telemetry.d.ts +77 -0
- package/dist/runtime/stt-telemetry.js +176 -0
- package/dist/runtime/stt.js +18 -19
- package/dist/runtime/timeout.d.ts +5 -0
- package/dist/runtime/timeout.js +12 -0
- package/dist/runtime/trace-config.d.ts +12 -0
- package/dist/runtime/trace-config.js +62 -0
- package/dist/runtime/trace.d.ts +17 -0
- package/dist/runtime/trace.js +176 -25
- package/dist/runtime-boundary-lint.d.ts +137 -0
- package/dist/runtime-boundary-lint.js +590 -0
- package/dist/schema.d.ts +20 -0
- package/dist/schema.js +72 -2
- package/dist/serve.d.ts +1 -1
- package/dist/serve.js +1 -1
- package/dist/server/error-observability.d.ts +1 -0
- package/dist/server/error-observability.js +1 -0
- package/dist/server/error-stack-frames.d.ts +35 -0
- package/dist/server/error-stack-frames.js +219 -0
- package/dist/server/index.d.ts +21 -2
- package/dist/server/index.js +11 -2
- package/dist/server/runtime-diagnostics.d.ts +165 -0
- package/dist/server/runtime-diagnostics.js +360 -0
- package/dist/server/sdk-version.d.ts +3 -0
- package/dist/server/sdk-version.js +19 -0
- package/dist/server/self-test-input-tokens.d.ts +2 -1
- package/dist/server/self-test-input-tokens.js +18 -14
- package/dist/server/self-test-redaction.js +8 -33
- package/dist/server/self-test.d.ts +18 -3
- package/dist/server/self-test.js +139 -76
- package/dist/server/sensitive-values.d.ts +26 -0
- package/dist/server/sensitive-values.js +137 -0
- package/dist/server/serve-implementation.d.ts +285 -0
- package/dist/server/serve-implementation.js +3172 -0
- package/dist/server/serve.d.ts +1 -75
- package/dist/server/serve.js +1 -1170
- package/dist/server/state-backend-report.d.ts +70 -0
- package/dist/server/state-backend-report.js +113 -0
- package/dist/server/trace-output.d.ts +7 -0
- package/dist/server/trace-output.js +111 -0
- package/dist/server/types.d.ts +37 -5
- package/dist/server/types.js +34 -1
- package/dist/stateful/errors.d.ts +19 -0
- package/dist/stateful/errors.js +24 -0
- package/dist/stateful/http-provider-event-emitter.d.ts +40 -0
- package/dist/stateful/http-provider-event-emitter.js +237 -0
- package/dist/stateful/http-session-owner-registry.d.ts +44 -0
- package/dist/stateful/http-session-owner-registry.js +210 -0
- package/dist/stateful/index.d.ts +18 -0
- package/dist/stateful/index.js +18 -0
- package/dist/stateful/provider-event-delivery-failures.d.ts +32 -0
- package/dist/stateful/provider-event-delivery-failures.js +43 -0
- package/dist/stateful/provider-event-pipeline-metrics.d.ts +46 -0
- package/dist/stateful/provider-event-pipeline-metrics.js +48 -0
- package/dist/stateful/provider-event-pipeline.d.ts +50 -0
- package/dist/stateful/provider-event-pipeline.js +1 -0
- package/dist/stateful/provider-events.d.ts +101 -0
- package/dist/stateful/provider-events.js +289 -0
- package/dist/stateful/session-key.d.ts +15 -0
- package/dist/stateful/session-key.js +86 -0
- package/dist/stateful/stateful-provider-adapter-context.d.ts +5 -0
- package/dist/stateful/stateful-provider-adapter-context.js +42 -0
- package/dist/stateful/stateful-provider-adapter-metrics.d.ts +15 -0
- package/dist/stateful/stateful-provider-adapter-metrics.js +21 -0
- package/dist/stateful/stateful-provider-adapter.d.ts +98 -0
- package/dist/stateful/stateful-provider-adapter.js +287 -0
- package/dist/stateful/stateful-provider-observability.d.ts +62 -0
- package/dist/stateful/stateful-provider-observability.js +161 -0
- package/dist/stateful/stateful-provider-owner-forwarder.d.ts +41 -0
- package/dist/stateful/stateful-provider-owner-forwarder.js +237 -0
- package/dist/stateful/stateful-provider-runtime-context.d.ts +35 -0
- package/dist/stateful/stateful-provider-runtime-context.js +61 -0
- package/dist/stateful/stateful-provider-runtime-executor.d.ts +34 -0
- package/dist/stateful/stateful-provider-runtime-executor.js +52 -0
- package/dist/stateful/stateful-provider-session-routing.d.ts +67 -0
- package/dist/stateful/stateful-provider-session-routing.js +345 -0
- package/dist/stateful/stateful-provider-session-runtime.d.ts +98 -0
- package/dist/stateful/stateful-provider-session-runtime.js +245 -0
- package/dist/stateful-signing.d.ts +18 -0
- package/dist/stateful-signing.js +27 -0
- package/dist/stealth/profiles.d.ts +15 -4
- package/dist/stealth/profiles.js +169 -211
- package/dist/stream-evidence.d.ts +74 -0
- package/dist/stream-evidence.js +785 -0
- package/dist/stream.js +7 -1
- package/dist/testing/index.d.ts +2 -1
- package/dist/testing/index.js +2 -1
- package/dist/testing/run.d.ts +32 -2
- package/dist/testing/run.js +509 -25
- package/dist/trace-sanitization.d.ts +6 -0
- package/dist/trace-sanitization.js +68 -0
- package/dist/types.d.ts +899 -210
- package/dist/types.js +1 -0
- package/dist/typescript-module.d.ts +39 -0
- package/dist/typescript-module.js +72 -0
- package/package.json +52 -6
- package/src/auth-turn/index.ts +1 -1
- package/src/auth.ts +118 -0
- package/src/ceremonies/index.ts +189 -46
- package/src/cli/commands.ts +37 -0
- package/src/cli/create.ts +8 -2
- package/src/cli/deployment-intent.ts +364 -0
- package/src/cli/local-connection.ts +221 -0
- package/src/cli/migrate-deployment-intent.ts +1908 -0
- package/src/cli/migrate-operation-declaration.ts +3026 -0
- package/src/cli/migrate-operation-shape.ts +184 -0
- package/src/cli/migrate-provider-shape.ts +778 -0
- package/src/cli/resolver-runtime.ts +72 -0
- package/src/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl +141 -23
- package/src/cli/templates/provider/Dockerfile.tpl +1 -1
- package/src/cli/templates/provider/README.md.tpl +41 -19
- package/src/cli/templates/provider/index.ts.tpl +6 -3
- package/src/cli/templates/provider/operations/ping.ts.tpl +4 -1
- package/src/cli/templates/provider/provider.json.tpl +6 -0
- package/src/config/loader.ts +774 -181
- package/src/contract-serialization.ts +5 -7
- package/src/contract-types.ts +12 -5
- package/src/contract.ts +24 -10
- package/src/declaration-validation.ts +376 -0
- package/src/define.ts +1105 -131
- package/src/dev.ts +13 -1
- package/src/engine.ts +390 -0
- package/src/error-observability.ts +64 -0
- package/src/error-resolution.ts +269 -0
- package/src/errors.ts +157 -0
- package/src/fixture-sanitization.ts +422 -0
- package/src/handle-meta.ts +143 -0
- package/src/handle.ts +694 -0
- package/src/health-scenario.ts +960 -0
- package/src/i18n/catalog.ts +23 -1
- package/src/i18n/error-messages.ts +255 -0
- package/src/i18n/index.ts +1 -0
- package/src/i18n/keys.ts +80 -6
- package/src/i18n/operation-locale-namespace.ts +10 -0
- package/src/index.ts +390 -23
- package/src/lint.ts +2975 -234
- package/src/native-address.ts +340 -0
- package/src/native-egress-policy.ts +358 -0
- package/src/observability.ts +51 -1
- package/src/provider.ts +207 -27
- package/src/runtime/auth-flow.ts +15 -0
- package/src/runtime/bounded-expiring-map.ts +67 -0
- package/src/runtime/browser-telemetry-binding.ts +92 -0
- package/src/runtime/browser-telemetry.ts +289 -0
- package/src/runtime/browser.ts +882 -99
- package/src/runtime/cache-telemetry.ts +247 -0
- package/src/runtime/cache.ts +258 -22
- package/src/runtime/capability-response.ts +53 -0
- package/src/runtime/capability-telemetry.ts +101 -0
- package/src/runtime/chrome149-header-order.ts +330 -0
- package/src/runtime/diagnostic-env-values.ts +56 -0
- package/src/runtime/diagnostic-env.ts +65 -0
- package/src/runtime/diagnostic-redactor.ts +668 -0
- package/src/runtime/egress-lease.ts +341 -0
- package/src/runtime/engine-mode.ts +233 -0
- package/src/runtime/env.ts +15 -1
- package/src/runtime/executor.ts +39 -32
- package/src/runtime/handle-wordlist.ts +266 -0
- package/src/runtime/handle.ts +1180 -0
- package/src/runtime/http-telemetry-binding.ts +162 -0
- package/src/runtime/http-telemetry-guard.ts +208 -0
- package/src/runtime/http-telemetry.ts +292 -0
- package/src/runtime/http.ts +896 -150
- package/src/runtime/insights.ts +2 -2
- package/src/runtime/instrumentation.ts +628 -28
- package/src/runtime/native-network-errors.ts +99 -0
- package/src/runtime/native-network.ts +1853 -0
- package/src/runtime/native-telemetry.ts +366 -0
- package/src/runtime/ocr-telemetry.ts +308 -0
- package/src/runtime/ocr.ts +564 -0
- package/src/runtime/otlp.ts +468 -21
- package/src/runtime/provider.ts +15 -0
- package/src/runtime/proxy-errors.ts +12 -4
- package/src/runtime/proxy-nodemaven.ts +222 -0
- package/src/runtime/proxy-retry-policy.ts +12 -1
- package/src/runtime/proxy-telemetry.ts +358 -103
- package/src/runtime/redirect-hop-headers.ts +71 -0
- package/src/runtime/redirects.ts +215 -0
- package/src/runtime/redis.ts +7 -2
- package/src/runtime/request-options.ts +728 -1
- package/src/runtime/request-telemetry.ts +375 -0
- package/src/runtime/resolver-config.ts +18 -0
- package/src/runtime/resolver-public.ts +44 -0
- package/src/runtime/resolver-runtime-options.ts +50 -0
- package/src/runtime/resolver-shared.ts +113 -0
- package/src/runtime/resolver-span-attributes.ts +139 -0
- package/src/runtime/resolver-telemetry.ts +362 -0
- package/src/runtime/resolver-usage.ts +99 -0
- package/src/runtime/resolver-vendors/bindings.ts +61 -0
- package/src/runtime/resolver-vendors/browser.ts +591 -0
- package/src/runtime/resolver-vendors/capsolver.ts +727 -0
- package/src/runtime/resolver-vendors/hosts.ts +81 -0
- package/src/runtime/resolver-vendors/hypersolutions.ts +480 -0
- package/src/runtime/resolver-vendors/twocaptcha.ts +555 -0
- package/src/runtime/resolver-vendors/types.ts +261 -0
- package/src/runtime/resolver.ts +1543 -0
- package/src/runtime/state-telemetry.ts +298 -0
- package/src/runtime/state.ts +435 -89
- package/src/runtime/stealth-akamai-sbsd.ts +207 -0
- package/src/runtime/stealth-cookies.ts +155 -0
- package/src/runtime/stealth-owned-headers.ts +67 -0
- package/src/runtime/stealth-telemetry.ts +309 -0
- package/src/runtime/stealth.ts +2275 -372
- package/src/runtime/stt-telemetry.ts +282 -0
- package/src/runtime/stt.ts +96 -91
- package/src/runtime/timeout.ts +18 -0
- package/src/runtime/trace-config.ts +78 -0
- package/src/runtime/trace.ts +257 -35
- package/src/runtime-boundary-lint.ts +707 -0
- package/src/schema.ts +80 -2
- package/src/serve.ts +6 -1
- package/src/server/error-observability.ts +1 -0
- package/src/server/error-stack-frames.ts +214 -0
- package/src/server/index.ts +184 -2
- package/src/server/runtime-diagnostics.ts +522 -0
- package/src/server/sdk-version.ts +22 -0
- package/src/server/self-test-input-tokens.ts +29 -14
- package/src/server/self-test-redaction.ts +10 -40
- package/src/server/self-test.ts +205 -89
- package/src/server/sensitive-values.ts +211 -0
- package/src/server/serve-implementation.ts +4596 -0
- package/src/server/serve.ts +1 -1685
- package/src/server/state-backend-report.ts +185 -0
- package/src/server/trace-output.ts +189 -0
- package/src/server/types.ts +34 -1
- package/src/stateful/README.md +146 -0
- package/src/stateful/errors.ts +35 -0
- package/src/stateful/http-provider-event-emitter.ts +314 -0
- package/src/stateful/http-session-owner-registry.ts +306 -0
- package/src/stateful/index.ts +18 -0
- package/src/stateful/provider-event-delivery-failures.ts +80 -0
- package/src/stateful/provider-event-pipeline-metrics.ts +95 -0
- package/src/stateful/provider-event-pipeline.ts +61 -0
- package/src/stateful/provider-events.ts +462 -0
- package/src/stateful/session-key.ts +111 -0
- package/src/stateful/stateful-provider-adapter-context.ts +59 -0
- package/src/stateful/stateful-provider-adapter-metrics.ts +48 -0
- package/src/stateful/stateful-provider-adapter.ts +562 -0
- package/src/stateful/stateful-provider-observability.ts +261 -0
- package/src/stateful/stateful-provider-owner-forwarder.ts +310 -0
- package/src/stateful/stateful-provider-runtime-context.ts +96 -0
- package/src/stateful/stateful-provider-runtime-executor.ts +96 -0
- package/src/stateful/stateful-provider-session-routing.ts +546 -0
- package/src/stateful/stateful-provider-session-runtime.ts +403 -0
- package/src/stateful-signing.ts +46 -0
- package/src/stealth/profiles.ts +212 -231
- package/src/stream-evidence.ts +988 -0
- package/src/stream.ts +8 -1
- package/src/testing/index.ts +10 -1
- package/src/testing/run.ts +685 -19
- package/src/trace-sanitization.ts +110 -0
- package/src/types.ts +1014 -273
- package/src/typescript-module.ts +100 -0
- package/dist/choice-token.d.ts +0 -24
- package/dist/choice-token.js +0 -74
- package/dist/runtime/choice.d.ts +0 -15
- package/dist/runtime/choice.js +0 -413
- package/src/choice-token.ts +0 -165
- package/src/runtime/choice.ts +0 -686
package/dist/server/self-test.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
-
import { readFileSync } from "node:fs";
|
|
3
2
|
import { TURN_KINDS } from "../auth-turn/index.js";
|
|
3
|
+
import { SDK_VERSION } from "./sdk-version.js";
|
|
4
4
|
import { Hono } from "hono";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { resolveHealthCheckInputDateTokens } from "./self-test-input-tokens.js";
|
|
@@ -58,23 +58,6 @@ export const SELF_TEST_AUTH_FLOW_REJECTED_SKIP_REASON = "auth_flow_rejected";
|
|
|
58
58
|
*/
|
|
59
59
|
const AUTH_REJECTION_HTTP_STATUSES = new Set([401, 403]);
|
|
60
60
|
const INTERACTIVE_TURN_KIND_SET = new Set(TURN_KINDS.filter((descriptor) => descriptor.rendering !== "terminal" && descriptor.kind !== "retry").map((descriptor) => descriptor.kind));
|
|
61
|
-
function resolveSdkVersion() {
|
|
62
|
-
try {
|
|
63
|
-
const packageJsonUrl = new URL("../../package.json", import.meta.url);
|
|
64
|
-
const parsed = JSON.parse(readFileSync(packageJsonUrl, "utf8"));
|
|
65
|
-
if (parsed &&
|
|
66
|
-
typeof parsed === "object" &&
|
|
67
|
-
"version" in parsed &&
|
|
68
|
-
typeof parsed.version === "string") {
|
|
69
|
-
return parsed.version;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
catch {
|
|
73
|
-
// fall through to unknown
|
|
74
|
-
}
|
|
75
|
-
return "unknown";
|
|
76
|
-
}
|
|
77
|
-
const SDK_VERSION = resolveSdkVersion();
|
|
78
61
|
function healthCheckSuite(operation) {
|
|
79
62
|
return operation.healthCheck;
|
|
80
63
|
}
|
|
@@ -115,25 +98,15 @@ export function computeSelfTestPlanDigest(provider) {
|
|
|
115
98
|
}
|
|
116
99
|
/**
|
|
117
100
|
* Fail-closed read-only classification: an operation may self-test only when
|
|
118
|
-
* its
|
|
119
|
-
* toolRouter.riskClass "read") and nothing marks it side-effecting. Unclassified
|
|
120
|
-
* operations are refused so the endpoint cannot become a mutation oracle.
|
|
101
|
+
* its authored safety source of truth classifies it as read-only.
|
|
121
102
|
*/
|
|
122
103
|
export function isSelfTestReadOnlyOperation(operation) {
|
|
123
|
-
|
|
124
|
-
if (annotations?.readOnly === false)
|
|
125
|
-
return false;
|
|
126
|
-
if (annotations?.destructive === true)
|
|
127
|
-
return false;
|
|
128
|
-
const riskClass = operation.toolRouter?.riskClass;
|
|
129
|
-
if (riskClass !== undefined && riskClass !== "read")
|
|
130
|
-
return false;
|
|
131
|
-
return annotations?.readOnly === true || riskClass === "read";
|
|
104
|
+
return operation.riskClass === "read";
|
|
132
105
|
}
|
|
133
106
|
/** Binds the self-test executor to a tenant app's /v1 pipeline in-process. */
|
|
134
107
|
export function createSelfTestInvoke(app) {
|
|
135
|
-
return async ({ operationId, input, connection, requestId }) => {
|
|
136
|
-
const
|
|
108
|
+
return async ({ operationId, input, connection, requestId, signal }) => {
|
|
109
|
+
const responsePromise = Promise.resolve(app.request(`/v1/${encodeURIComponent(operationId)}`, {
|
|
137
110
|
method: "POST",
|
|
138
111
|
headers: { "content-type": "application/json" },
|
|
139
112
|
body: JSON.stringify({
|
|
@@ -141,7 +114,14 @@ export function createSelfTestInvoke(app) {
|
|
|
141
114
|
input: input ?? {},
|
|
142
115
|
...(connection ? { connection } : {}),
|
|
143
116
|
}),
|
|
144
|
-
|
|
117
|
+
...(signal ? { signal } : {}),
|
|
118
|
+
}));
|
|
119
|
+
const response = await responsePromise;
|
|
120
|
+
if (signal?.aborted) {
|
|
121
|
+
await cancelSelfTestResponse(response);
|
|
122
|
+
signal.throwIfAborted();
|
|
123
|
+
}
|
|
124
|
+
// An abort after body consumption starts may let response.text() finish.
|
|
145
125
|
const text = await response.text();
|
|
146
126
|
let body = text;
|
|
147
127
|
try {
|
|
@@ -161,20 +141,52 @@ export function createSelfTestInvoke(app) {
|
|
|
161
141
|
return { status: response.status, data: body };
|
|
162
142
|
};
|
|
163
143
|
}
|
|
144
|
+
async function cancelSelfTestResponse(response) {
|
|
145
|
+
await response.body?.cancel().catch(() => undefined);
|
|
146
|
+
}
|
|
147
|
+
function selfTestAbortReason(reason, sensitiveValues) {
|
|
148
|
+
const text = reason instanceof Error
|
|
149
|
+
? reason.message || reason.name
|
|
150
|
+
: reason === undefined
|
|
151
|
+
? "aborted"
|
|
152
|
+
: String(reason);
|
|
153
|
+
return redactSelfTestText(text, sensitiveValues);
|
|
154
|
+
}
|
|
155
|
+
function logSelfTestCancellation(provider, options, requestId, selected, signal, sensitiveValues) {
|
|
156
|
+
const event = {
|
|
157
|
+
level: "info",
|
|
158
|
+
event: "self_test_run_cancelled",
|
|
159
|
+
providerId: provider.id,
|
|
160
|
+
requestId,
|
|
161
|
+
operationId: selected.operationId,
|
|
162
|
+
caseName: selected.healthCase.name,
|
|
163
|
+
reason: selfTestAbortReason(signal.reason, sensitiveValues),
|
|
164
|
+
};
|
|
165
|
+
if (options.logger) {
|
|
166
|
+
options.logger(event);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
console.log(JSON.stringify(event));
|
|
170
|
+
}
|
|
164
171
|
/** Binds the self-test auth-flow driver to a tenant app's /auth pipeline in-process. */
|
|
165
172
|
export function createSelfTestAuthFlowInvoke(app) {
|
|
166
|
-
return async ({ route, requestId, flowId, connectionId, externalRef, input, context }) => {
|
|
173
|
+
return async ({ route, requestId, flowId, connectionId, externalRef, input, context, engine, signal, }) => {
|
|
167
174
|
const response = await app.request(`/auth/${route}`, {
|
|
168
175
|
method: "POST",
|
|
169
176
|
headers: { "content-type": "application/json" },
|
|
170
177
|
body: JSON.stringify({
|
|
171
178
|
requestId,
|
|
172
179
|
flowId,
|
|
180
|
+
// Engine ceremony leases are scoped to a tenant; the self-test has no
|
|
181
|
+
// customer tenant, so it presents a fixed one that never collides.
|
|
182
|
+
tenantId: "self-test",
|
|
173
183
|
...(connectionId ? { connectionId } : {}),
|
|
174
184
|
...(externalRef ? { externalRef } : {}),
|
|
175
185
|
...(input ? { input } : {}),
|
|
176
186
|
...(context ? { context } : {}),
|
|
187
|
+
...(engine ? { engine } : {}),
|
|
177
188
|
}),
|
|
189
|
+
...(signal ? { signal } : {}),
|
|
178
190
|
});
|
|
179
191
|
const text = await response.text();
|
|
180
192
|
let body = text;
|
|
@@ -193,19 +205,32 @@ class SelfTestCaseTimeoutError extends Error {
|
|
|
193
205
|
this.name = "SelfTestCaseTimeoutError";
|
|
194
206
|
}
|
|
195
207
|
}
|
|
196
|
-
async function withCaseTimeout(run, timeoutMs) {
|
|
208
|
+
async function withCaseTimeout(run, timeoutMs, controller) {
|
|
197
209
|
let timer;
|
|
210
|
+
let onAbort;
|
|
198
211
|
try {
|
|
199
212
|
return await Promise.race([
|
|
200
213
|
run(),
|
|
201
214
|
new Promise((_, reject) => {
|
|
202
|
-
timer = setTimeout(() =>
|
|
215
|
+
timer = setTimeout(() => {
|
|
216
|
+
const error = new SelfTestCaseTimeoutError(timeoutMs);
|
|
217
|
+
controller.abort(error);
|
|
218
|
+
reject(error);
|
|
219
|
+
}, timeoutMs);
|
|
220
|
+
}),
|
|
221
|
+
new Promise((_, reject) => {
|
|
222
|
+
onAbort = () => reject(controller.signal.reason);
|
|
223
|
+
controller.signal.addEventListener("abort", onAbort, { once: true });
|
|
224
|
+
if (controller.signal.aborted)
|
|
225
|
+
onAbort();
|
|
203
226
|
}),
|
|
204
227
|
]);
|
|
205
228
|
}
|
|
206
229
|
finally {
|
|
207
230
|
if (timer !== undefined)
|
|
208
231
|
clearTimeout(timer);
|
|
232
|
+
if (onAbort)
|
|
233
|
+
controller.signal.removeEventListener("abort", onAbort);
|
|
209
234
|
}
|
|
210
235
|
}
|
|
211
236
|
function objectProperty(value, key) {
|
|
@@ -291,6 +316,7 @@ function parseAuthFlowResponse(result) {
|
|
|
291
316
|
};
|
|
292
317
|
}
|
|
293
318
|
const contextPatch = objectProperty(result.body, "contextPatch");
|
|
319
|
+
const egressLease = objectProperty(objectProperty(result.body, "engine"), "egressLease");
|
|
294
320
|
return {
|
|
295
321
|
ok: true,
|
|
296
322
|
turn: {
|
|
@@ -301,6 +327,7 @@ function parseAuthFlowResponse(result) {
|
|
|
301
327
|
...(contextPatch && typeof contextPatch === "object" && !Array.isArray(contextPatch)
|
|
302
328
|
? { contextPatch: contextPatch }
|
|
303
329
|
: {}),
|
|
330
|
+
...(typeof egressLease === "string" && egressLease ? { engine: { egressLease } } : {}),
|
|
304
331
|
};
|
|
305
332
|
}
|
|
306
333
|
function applyAuthFlowContextPatch(base, patch) {
|
|
@@ -389,6 +416,7 @@ async function materializeFlowCredential(execution, inputs, options = {}) {
|
|
|
389
416
|
flowId,
|
|
390
417
|
...(options.connectionId ? { connectionId: options.connectionId } : {}),
|
|
391
418
|
...(options.externalRef ? { externalRef: options.externalRef } : {}),
|
|
419
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
392
420
|
}));
|
|
393
421
|
if (!started.ok) {
|
|
394
422
|
return { kind: "flow_error", code: started.code, message: started.message };
|
|
@@ -460,6 +488,10 @@ async function materializeFlowCredential(execution, inputs, options = {}) {
|
|
|
460
488
|
...(options.externalRef ? { externalRef: options.externalRef } : {}),
|
|
461
489
|
input: submitInputs,
|
|
462
490
|
...(Object.keys(flowContext).length > 0 ? { context: flowContext } : {}),
|
|
491
|
+
// The ceremony egress lease is engine state, not flow context: carry it the
|
|
492
|
+
// way the gateway does so the continue turn stays on the start turn's egress.
|
|
493
|
+
...(started.engine ? { engine: started.engine } : {}),
|
|
494
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
463
495
|
}));
|
|
464
496
|
if (!continued.ok) {
|
|
465
497
|
// Providers built with defineCredentialsAuth cannot return a retry
|
|
@@ -613,6 +645,7 @@ async function resolveSelfTestConnection(execution, operationId, suite, options
|
|
|
613
645
|
...(options.isAbandoned !== undefined ? { isAbandoned: options.isAbandoned } : {}),
|
|
614
646
|
connectionId,
|
|
615
647
|
externalRef: `${execution.provider.id}-${operationId}-self-test`,
|
|
648
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
616
649
|
});
|
|
617
650
|
if (!("credential" in materialized)) {
|
|
618
651
|
// Only the multi-turn SKIP is negative-cached. Flow ERRORS
|
|
@@ -632,10 +665,9 @@ async function resolveSelfTestConnection(execution, operationId, suite, options
|
|
|
632
665
|
}
|
|
633
666
|
return materialized;
|
|
634
667
|
}
|
|
635
|
-
//
|
|
636
|
-
//
|
|
637
|
-
//
|
|
638
|
-
// reuse a login whose latency just failed the case, hiding the failure.
|
|
668
|
+
// Abort is cooperative: a flow may still complete after the case deadline
|
|
669
|
+
// if provider code ignores the signal. Never cache that late credential or
|
|
670
|
+
// let the next probe hide the timed-out login.
|
|
639
671
|
if (options.isAbandoned?.() === true) {
|
|
640
672
|
return {
|
|
641
673
|
kind: "flow_error",
|
|
@@ -659,7 +691,7 @@ async function resolveSelfTestConnection(execution, operationId, suite, options
|
|
|
659
691
|
function isAuthFailureCaseResult(result) {
|
|
660
692
|
return result.status === "failed" && (result.httpStatus === 401 || result.httpStatus === 403);
|
|
661
693
|
}
|
|
662
|
-
async function executeSelfTestCase(execution, operationId, suite, healthCase) {
|
|
694
|
+
async function executeSelfTestCase(execution, operationId, suite, healthCase, caseController) {
|
|
663
695
|
const { provider, invoke } = execution;
|
|
664
696
|
// execution.sensitiveValues may grow while the case runs (flow-issued
|
|
665
697
|
// secrets); redact always reads the live array.
|
|
@@ -671,6 +703,7 @@ async function executeSelfTestCase(execution, operationId, suite, healthCase) {
|
|
|
671
703
|
// a 30s case must never take ~4×30s across its stages.
|
|
672
704
|
const caseDeadlineAtMs = performance.now() + timeoutMs;
|
|
673
705
|
const remainingCaseTimeoutMs = () => Math.max(1, Math.ceil(caseDeadlineAtMs - performance.now()));
|
|
706
|
+
const runWithCaseTimeout = (run, remainingMs) => withCaseTimeout(run, remainingMs, caseController);
|
|
674
707
|
const beginCase = () => {
|
|
675
708
|
const startedAt = new Date().toISOString();
|
|
676
709
|
const startedAtMs = performance.now();
|
|
@@ -695,14 +728,15 @@ async function executeSelfTestCase(execution, operationId, suite, healthCase) {
|
|
|
695
728
|
});
|
|
696
729
|
}
|
|
697
730
|
const resolveConnection = async (forceLogin) => {
|
|
698
|
-
// The
|
|
699
|
-
//
|
|
700
|
-
//
|
|
731
|
+
// The deadline aborts the in-process flow request. Keep the abandonment
|
|
732
|
+
// guard as a backstop for provider code that ignores cancellation so a
|
|
733
|
+
// late completion still cannot write the session cache.
|
|
701
734
|
let abandoned = false;
|
|
702
735
|
try {
|
|
703
|
-
return await
|
|
736
|
+
return await runWithCaseTimeout(() => resolveSelfTestConnection(execution, operationId, suite, {
|
|
704
737
|
forceLogin,
|
|
705
738
|
isAbandoned: () => abandoned,
|
|
739
|
+
signal: caseController.signal,
|
|
706
740
|
}), remainingCaseTimeoutMs());
|
|
707
741
|
}
|
|
708
742
|
catch (error) {
|
|
@@ -739,7 +773,10 @@ async function executeSelfTestCase(execution, operationId, suite, healthCase) {
|
|
|
739
773
|
// operation attempt, or a slow login reads as a fast healthy case.
|
|
740
774
|
const { startedAtMs, finish } = caseScope;
|
|
741
775
|
try {
|
|
742
|
-
return await
|
|
776
|
+
return await runWithCaseTimeout(async () => {
|
|
777
|
+
if (healthCase.assertions === undefined) {
|
|
778
|
+
throw new Error(`Self-test cannot execute declarative health-check case "${healthCase.name}"; run its scenario through the health monitor.`);
|
|
779
|
+
}
|
|
743
780
|
const resolvedInput = resolveHealthCheckInputDateTokens(healthCase.input);
|
|
744
781
|
const preparedInput = healthCase.prepareInput
|
|
745
782
|
? await healthCase.prepareInput({
|
|
@@ -758,6 +795,7 @@ async function executeSelfTestCase(execution, operationId, suite, healthCase) {
|
|
|
758
795
|
input: gatewayInput,
|
|
759
796
|
connection,
|
|
760
797
|
requestId: `${execution.requestId}-prepare-${randomUUID()}`,
|
|
798
|
+
signal: caseController.signal,
|
|
761
799
|
});
|
|
762
800
|
if (executed.status === 401 || executed.status === 403) {
|
|
763
801
|
prepareAuthStatus = executed.status;
|
|
@@ -777,6 +815,7 @@ async function executeSelfTestCase(execution, operationId, suite, healthCase) {
|
|
|
777
815
|
input: preparedInput,
|
|
778
816
|
connection,
|
|
779
817
|
requestId: `${execution.requestId}-${randomUUID()}`,
|
|
818
|
+
signal: caseController.signal,
|
|
780
819
|
});
|
|
781
820
|
const durationMs = performance.now() - startedAtMs;
|
|
782
821
|
if (executed.status < 200 || executed.status >= 300) {
|
|
@@ -1054,41 +1093,65 @@ export function createSelfTestApp(provider, options) {
|
|
|
1054
1093
|
};
|
|
1055
1094
|
const deadline = performance.now() + requestBudgetMs;
|
|
1056
1095
|
const results = [];
|
|
1096
|
+
const runSignal = c.req.raw.signal;
|
|
1097
|
+
let interruptedCase;
|
|
1057
1098
|
// Sequential execution (parallelism 1): self-tests run on serving pods
|
|
1058
1099
|
// and must never compete with themselves for upstream quota.
|
|
1059
1100
|
for (const selected of selection.cases) {
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1101
|
+
const caseController = new AbortController();
|
|
1102
|
+
const abortFromRun = () => caseController.abort(runSignal.reason);
|
|
1103
|
+
runSignal.addEventListener("abort", abortFromRun, { once: true });
|
|
1104
|
+
if (runSignal.aborted)
|
|
1105
|
+
abortFromRun();
|
|
1106
|
+
try {
|
|
1107
|
+
if (runSignal.aborted) {
|
|
1108
|
+
interruptedCase = selected;
|
|
1109
|
+
break;
|
|
1110
|
+
}
|
|
1111
|
+
if (performance.now() >= deadline) {
|
|
1112
|
+
const now = new Date().toISOString();
|
|
1113
|
+
results.push({
|
|
1114
|
+
operationId: selected.operationId,
|
|
1115
|
+
caseName: selected.healthCase.name,
|
|
1116
|
+
status: "skipped",
|
|
1117
|
+
label: selected.healthCase.name,
|
|
1118
|
+
responseTimeMs: 0,
|
|
1119
|
+
skipReason: "budget_exhausted",
|
|
1120
|
+
startedAt: now,
|
|
1121
|
+
finishedAt: now,
|
|
1122
|
+
});
|
|
1123
|
+
continue;
|
|
1124
|
+
}
|
|
1125
|
+
if (!isSelfTestReadOnlyOperation(selected.operation)) {
|
|
1126
|
+
const now = new Date().toISOString();
|
|
1127
|
+
results.push({
|
|
1128
|
+
operationId: selected.operationId,
|
|
1129
|
+
caseName: selected.healthCase.name,
|
|
1130
|
+
status: "error",
|
|
1131
|
+
label: selected.healthCase.name,
|
|
1132
|
+
responseTimeMs: 0,
|
|
1133
|
+
error: {
|
|
1134
|
+
code: "operation_not_read_only",
|
|
1135
|
+
message: `Operation "${selected.operationId}" is not classified read-only; self-test refuses to execute it.`,
|
|
1136
|
+
},
|
|
1137
|
+
startedAt: now,
|
|
1138
|
+
finishedAt: now,
|
|
1139
|
+
});
|
|
1140
|
+
continue;
|
|
1141
|
+
}
|
|
1142
|
+
results.push(await executeSelfTestCase(execution, selected.operationId, selected.suite, selected.healthCase, caseController));
|
|
1143
|
+
if (runSignal.aborted) {
|
|
1144
|
+
interruptedCase = selected;
|
|
1145
|
+
break;
|
|
1146
|
+
}
|
|
1073
1147
|
}
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
operationId: selected.operationId,
|
|
1078
|
-
caseName: selected.healthCase.name,
|
|
1079
|
-
status: "error",
|
|
1080
|
-
label: selected.healthCase.name,
|
|
1081
|
-
responseTimeMs: 0,
|
|
1082
|
-
error: {
|
|
1083
|
-
code: "operation_not_read_only",
|
|
1084
|
-
message: `Operation "${selected.operationId}" is not classified read-only; self-test refuses to execute it.`,
|
|
1085
|
-
},
|
|
1086
|
-
startedAt: now,
|
|
1087
|
-
finishedAt: now,
|
|
1088
|
-
});
|
|
1089
|
-
continue;
|
|
1148
|
+
finally {
|
|
1149
|
+
runSignal.removeEventListener("abort", abortFromRun);
|
|
1150
|
+
caseController.abort();
|
|
1090
1151
|
}
|
|
1091
|
-
|
|
1152
|
+
}
|
|
1153
|
+
if (interruptedCase) {
|
|
1154
|
+
logSelfTestCancellation(provider, options, request.requestId, interruptedCase, runSignal, execution.sensitiveValues);
|
|
1092
1155
|
}
|
|
1093
1156
|
const singleCase = request.operationId !== undefined && request.caseName !== undefined;
|
|
1094
1157
|
const response = {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ProviderDefinition } from "../types.js";
|
|
2
|
+
export declare const SELF_TEST_SENSITIVE_SOURCE_KINDS: readonly ["selfTestMasterSecrets", "providerSecrets", "healthProbeSecrets", "requestCredentials"];
|
|
3
|
+
/** Explicit source allowlist: no environment-name or payload-shape secret sweep. */
|
|
4
|
+
export declare const DIAGNOSTIC_SENSITIVE_SOURCE_KINDS: readonly ["selfTestMasterSecrets", "providerSecrets", "healthProbeSecrets", "requestCredentials", "engineProxyCredentials", "engineSolverKeys", "engineCeremonyLeaseCredentials", "engineClientCredentials", "ocrCredentials", "sttCredentials", "cdpCredentials", "statefulForwardingSecret", "redisCredentials", "otlpHeaders", "cacheKeyPepper", "sensitiveParams"];
|
|
5
|
+
export type DiagnosticSensitiveSourceKind = (typeof DIAGNOSTIC_SENSITIVE_SOURCE_KINDS)[number];
|
|
6
|
+
/**
|
|
7
|
+
* Startup inventory; request-scoped readers additionally register live values on access.
|
|
8
|
+
*/
|
|
9
|
+
export declare function collectStaticDiagnosticSensitiveValues(provider: ProviderDefinition, options?: {
|
|
10
|
+
env?: Readonly<Record<string, string | undefined>>;
|
|
11
|
+
statefulForwardingSecret?: string;
|
|
12
|
+
}): string[];
|
|
13
|
+
/** Generalised self-test collector, also used to seed and enrich ordinary request scopes. */
|
|
14
|
+
export declare function collectDiagnosticSensitiveValues(provider: ProviderDefinition, options?: {
|
|
15
|
+
env?: Readonly<Record<string, string | undefined>>;
|
|
16
|
+
credentialInputs?: Readonly<Record<string, unknown>>;
|
|
17
|
+
connectionSecrets?: Readonly<Record<string, string | undefined>>;
|
|
18
|
+
sensitiveParams?: readonly string[];
|
|
19
|
+
statefulForwardingSecret?: string;
|
|
20
|
+
sourceKinds?: readonly DiagnosticSensitiveSourceKind[];
|
|
21
|
+
minimumLength?: number;
|
|
22
|
+
/** Preserve the legacy self-test response collector when false. */
|
|
23
|
+
includeResolvedEnvVariants?: boolean;
|
|
24
|
+
}): string[];
|
|
25
|
+
/** Derive the live-read allowlist from the same collector as the startup inventory. */
|
|
26
|
+
export declare function createDiagnosticEnvObserver(provider: ProviderDefinition, register: (values: readonly string[]) => void, has?: (value: string) => boolean): (name: string, value: string) => void;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { resolvedStringVariants, urlCredentialComponents, otlpHeaderCredentialValues, } from "../runtime/diagnostic-env-values.js";
|
|
2
|
+
import { PROVIDER_CACHE_REDIS_URL_ENV, PROVIDER_STATE_REDIS_URL_ENV, REDIS_URL_ENV, } from "../config/loader.js";
|
|
3
|
+
import { ENGINE_OWNED_PROXY_CREDENTIAL_ENV_NAMES, ENGINE_OWNED_RESOLVER_CREDENTIAL_ENV_NAMES, } from "../engine.js";
|
|
4
|
+
import { REMOTE_ENGINE_CLIENT_API_KEY_ENV, REMOTE_ENGINE_CLIENT_URL_ENV, } from "../runtime/engine-mode.js";
|
|
5
|
+
import { APIFUSE__CACHE__KEY_PEPPER_ENV } from "../runtime/cache.js";
|
|
6
|
+
import { APIFUSE__ENGINE__CEREMONY_LEASE_KEY } from "../runtime/egress-lease.js";
|
|
7
|
+
import { APIFUSE__OCR__API_KEY_ENV, APIFUSE__OCR__CLOUDFLARE_API_TOKEN_ENV, } from "../runtime/ocr.js";
|
|
8
|
+
import { OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_TRACES_HEADERS, OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, } from "../runtime/otlp.js";
|
|
9
|
+
import { APIFUSE__CDP_POOL__URL } from "../runtime/resolver-config.js";
|
|
10
|
+
import { APIFUSE__STT__CLOUDFLARE_API_TOKEN_ENV } from "../runtime/stt.js";
|
|
11
|
+
import { PROVIDER_RUNTIME_SELF_TEST_MASTER_SECRET_ENV, PROVIDER_RUNTIME_SELF_TEST_MASTER_SECRET_PREVIOUS_ENV, } from "./self-test-token.js";
|
|
12
|
+
export const SELF_TEST_SENSITIVE_SOURCE_KINDS = [
|
|
13
|
+
"selfTestMasterSecrets",
|
|
14
|
+
"providerSecrets",
|
|
15
|
+
"healthProbeSecrets",
|
|
16
|
+
"requestCredentials",
|
|
17
|
+
];
|
|
18
|
+
/** Explicit source allowlist: no environment-name or payload-shape secret sweep. */
|
|
19
|
+
export const DIAGNOSTIC_SENSITIVE_SOURCE_KINDS = [
|
|
20
|
+
...SELF_TEST_SENSITIVE_SOURCE_KINDS,
|
|
21
|
+
"engineProxyCredentials",
|
|
22
|
+
"engineSolverKeys",
|
|
23
|
+
"engineCeremonyLeaseCredentials",
|
|
24
|
+
"engineClientCredentials",
|
|
25
|
+
"ocrCredentials",
|
|
26
|
+
"sttCredentials",
|
|
27
|
+
"cdpCredentials",
|
|
28
|
+
"statefulForwardingSecret",
|
|
29
|
+
"redisCredentials",
|
|
30
|
+
"otlpHeaders",
|
|
31
|
+
"cacheKeyPepper",
|
|
32
|
+
"sensitiveParams",
|
|
33
|
+
];
|
|
34
|
+
/**
|
|
35
|
+
* Startup inventory; request-scoped readers additionally register live values on access.
|
|
36
|
+
*/
|
|
37
|
+
export function collectStaticDiagnosticSensitiveValues(provider, options = {}) {
|
|
38
|
+
return collectDiagnosticSensitiveValues(provider, {
|
|
39
|
+
...options,
|
|
40
|
+
sourceKinds: DIAGNOSTIC_SENSITIVE_SOURCE_KINDS.filter((kind) => kind !== "requestCredentials" && kind !== "sensitiveParams"),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/** Generalised self-test collector, also used to seed and enrich ordinary request scopes. */
|
|
44
|
+
export function collectDiagnosticSensitiveValues(provider, options = {}) {
|
|
45
|
+
const env = options.env ?? process.env;
|
|
46
|
+
const envValues = (names) => names.map((name) => env[name]);
|
|
47
|
+
const resolvedEnvValues = (names) => envValues(names).flatMap((value) => value === undefined
|
|
48
|
+
? []
|
|
49
|
+
: options.includeResolvedEnvVariants === false
|
|
50
|
+
? [value]
|
|
51
|
+
: [value, value.trim()]);
|
|
52
|
+
const healthProbe = provider.healthProbe ?? provider.healthMonitor;
|
|
53
|
+
const sources = {
|
|
54
|
+
selfTestMasterSecrets: () => resolvedEnvValues([
|
|
55
|
+
PROVIDER_RUNTIME_SELF_TEST_MASTER_SECRET_ENV,
|
|
56
|
+
PROVIDER_RUNTIME_SELF_TEST_MASTER_SECRET_PREVIOUS_ENV,
|
|
57
|
+
]),
|
|
58
|
+
providerSecrets: () => resolvedEnvValues((provider.secrets ?? []).map((secret) => secret.name)),
|
|
59
|
+
healthProbeSecrets: () => resolvedEnvValues([
|
|
60
|
+
...(healthProbe?.requiredSecrets ?? []),
|
|
61
|
+
...Object.values(healthProbe?.credentialInputs ?? {}),
|
|
62
|
+
]),
|
|
63
|
+
requestCredentials: () => [
|
|
64
|
+
...Object.values(options.credentialInputs ?? {}),
|
|
65
|
+
...Object.values(options.connectionSecrets ?? {}),
|
|
66
|
+
],
|
|
67
|
+
engineProxyCredentials: () => resolvedEnvValues(ENGINE_OWNED_PROXY_CREDENTIAL_ENV_NAMES),
|
|
68
|
+
// These are the resolver-config API keys after #251's engine credential projection.
|
|
69
|
+
engineSolverKeys: () => resolvedEnvValues(ENGINE_OWNED_RESOLVER_CREDENTIAL_ENV_NAMES),
|
|
70
|
+
engineCeremonyLeaseCredentials: () => resolvedEnvValues([APIFUSE__ENGINE__CEREMONY_LEASE_KEY]),
|
|
71
|
+
// Remote engine client credential (projected before the ADR-0011 flip). The
|
|
72
|
+
// endpoint itself is an internal service URL, so only credentials embedded
|
|
73
|
+
// in it are inventoried, not the whole URL.
|
|
74
|
+
engineClientCredentials: () => [
|
|
75
|
+
...resolvedEnvValues([REMOTE_ENGINE_CLIENT_API_KEY_ENV]),
|
|
76
|
+
...resolvedStringVariants(env[REMOTE_ENGINE_CLIENT_URL_ENV]).flatMap((url) => urlCredentialComponents(url, { includePathAndQuery: false })),
|
|
77
|
+
],
|
|
78
|
+
ocrCredentials: () => resolvedEnvValues([APIFUSE__OCR__CLOUDFLARE_API_TOKEN_ENV, APIFUSE__OCR__API_KEY_ENV]),
|
|
79
|
+
sttCredentials: () => resolvedEnvValues([APIFUSE__STT__CLOUDFLARE_API_TOKEN_ENV]),
|
|
80
|
+
cdpCredentials: () => resolvedStringVariants(env[APIFUSE__CDP_POOL__URL]).flatMap((url) => [
|
|
81
|
+
url,
|
|
82
|
+
...urlCredentialComponents(url, { includePathAndQuery: true }),
|
|
83
|
+
]),
|
|
84
|
+
statefulForwardingSecret: () => resolvedStringVariants(options.statefulForwardingSecret),
|
|
85
|
+
redisCredentials: () => [PROVIDER_CACHE_REDIS_URL_ENV, PROVIDER_STATE_REDIS_URL_ENV, REDIS_URL_ENV]
|
|
86
|
+
.flatMap((name) => resolvedStringVariants(env[name]))
|
|
87
|
+
.flatMap((url) => urlCredentialComponents(url, { includePathAndQuery: false })),
|
|
88
|
+
otlpHeaders: () => [
|
|
89
|
+
...[OTEL_EXPORTER_OTLP_TRACES_HEADERS, OTEL_EXPORTER_OTLP_HEADERS].flatMap((name) => env[name] === undefined ? [] : otlpHeaderCredentialValues(env[name])),
|
|
90
|
+
...[OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT].flatMap((name) => resolvedStringVariants(env[name]).flatMap((url) => urlCredentialComponents(url, { includePathAndQuery: false }))),
|
|
91
|
+
],
|
|
92
|
+
cacheKeyPepper: () => resolvedEnvValues([APIFUSE__CACHE__KEY_PEPPER_ENV]),
|
|
93
|
+
sensitiveParams: () => options.sensitiveParams ?? [],
|
|
94
|
+
};
|
|
95
|
+
const values = new Set();
|
|
96
|
+
for (const kind of options.sourceKinds ?? DIAGNOSTIC_SENSITIVE_SOURCE_KINDS) {
|
|
97
|
+
for (const value of sources[kind]()) {
|
|
98
|
+
if (typeof value === "string" && value.length >= (options.minimumLength ?? 1))
|
|
99
|
+
values.add(value);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return [...values];
|
|
103
|
+
}
|
|
104
|
+
const diagnosticEnvNames = new WeakMap();
|
|
105
|
+
/** Derive the live-read allowlist from the same collector as the startup inventory. */
|
|
106
|
+
export function createDiagnosticEnvObserver(provider, register, has) {
|
|
107
|
+
let names = diagnosticEnvNames.get(provider);
|
|
108
|
+
if (!names) {
|
|
109
|
+
names = new Set();
|
|
110
|
+
const captured = names;
|
|
111
|
+
collectStaticDiagnosticSensitiveValues(provider, {
|
|
112
|
+
env: new Proxy({}, {
|
|
113
|
+
get: (_target, key) => {
|
|
114
|
+
if (typeof key === "string")
|
|
115
|
+
captured.add(key);
|
|
116
|
+
return undefined;
|
|
117
|
+
},
|
|
118
|
+
}),
|
|
119
|
+
});
|
|
120
|
+
diagnosticEnvNames.set(provider, names);
|
|
121
|
+
}
|
|
122
|
+
const seen = new Map();
|
|
123
|
+
return (name, value) => {
|
|
124
|
+
if (!names.has(name) || seen.get(name) === value)
|
|
125
|
+
return;
|
|
126
|
+
if (has?.(value) && has(value.trim()))
|
|
127
|
+
return;
|
|
128
|
+
// Includes URL userinfo/CDP components and OTLP auth values, using the same rules.
|
|
129
|
+
register([
|
|
130
|
+
...resolvedStringVariants(value),
|
|
131
|
+
...collectStaticDiagnosticSensitiveValues(provider, {
|
|
132
|
+
env: { [name]: value },
|
|
133
|
+
}),
|
|
134
|
+
]);
|
|
135
|
+
seen.set(name, value);
|
|
136
|
+
};
|
|
137
|
+
}
|