@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.
Files changed (478) hide show
  1. package/AUTHORING.md +943 -51
  2. package/CHANGELOG.md +273 -1
  3. package/LICENSE +21 -0
  4. package/README.md +117 -29
  5. package/SUBMISSION.md +3 -2
  6. package/bin/apifuse-check.ts +293 -13
  7. package/bin/apifuse-dev.ts +42 -19
  8. package/bin/apifuse-migrate-deployment.ts +200 -0
  9. package/bin/apifuse-migrate-operation-declaration.ts +55 -0
  10. package/bin/apifuse-migrate-shape.ts +202 -0
  11. package/bin/apifuse-pack-check.ts +19 -6
  12. package/bin/apifuse-pack-smoke.ts +57 -2
  13. package/bin/apifuse-pack-types.ts +736 -38
  14. package/bin/apifuse-perf.ts +59 -23
  15. package/bin/apifuse-record.ts +923 -94
  16. package/bin/apifuse-submit-check.ts +2313 -281
  17. package/bin/apifuse-test.ts +3 -1
  18. package/bin/submit-check-delimited-text.ts +50 -0
  19. package/dist/auth-turn/index.d.ts +3 -3
  20. package/dist/auth-turn/index.js +1 -1
  21. package/dist/auth.d.ts +14 -0
  22. package/dist/auth.js +67 -0
  23. package/dist/ceremonies/index.d.ts +16 -0
  24. package/dist/ceremonies/index.js +141 -36
  25. package/dist/cli/commands.d.ts +1 -1
  26. package/dist/cli/commands.js +30 -0
  27. package/dist/cli/create.d.ts +1 -1
  28. package/dist/cli/create.js +8 -2
  29. package/dist/cli/deployment-intent.d.ts +178 -0
  30. package/dist/cli/deployment-intent.js +277 -0
  31. package/dist/cli/local-connection.d.ts +111 -0
  32. package/dist/cli/local-connection.js +151 -0
  33. package/dist/cli/migrate-deployment-intent.d.ts +132 -0
  34. package/dist/cli/migrate-deployment-intent.js +1552 -0
  35. package/dist/cli/migrate-operation-declaration.d.ts +70 -0
  36. package/dist/cli/migrate-operation-declaration.js +2206 -0
  37. package/dist/cli/migrate-operation-shape.d.ts +44 -0
  38. package/dist/cli/migrate-operation-shape.js +113 -0
  39. package/dist/cli/migrate-provider-shape.d.ts +56 -0
  40. package/dist/cli/migrate-provider-shape.js +580 -0
  41. package/dist/cli/resolver-runtime.d.ts +21 -0
  42. package/dist/cli/resolver-runtime.js +31 -0
  43. package/dist/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl +141 -23
  44. package/dist/cli/templates/provider/Dockerfile.tpl +1 -1
  45. package/dist/cli/templates/provider/README.md.tpl +41 -19
  46. package/dist/cli/templates/provider/index.ts.tpl +6 -3
  47. package/dist/cli/templates/provider/operations/ping.ts.tpl +4 -1
  48. package/dist/cli/templates/provider/provider.json.tpl +6 -0
  49. package/dist/config/loader.d.ts +202 -16
  50. package/dist/config/loader.js +491 -141
  51. package/dist/contract-serialization.js +4 -8
  52. package/dist/contract-types.d.ts +12 -5
  53. package/dist/contract.js +24 -10
  54. package/dist/declaration-validation.d.ts +34 -0
  55. package/dist/declaration-validation.js +305 -0
  56. package/dist/define.d.ts +71 -29
  57. package/dist/define.js +807 -69
  58. package/dist/dev.d.ts +5 -0
  59. package/dist/dev.js +8 -1
  60. package/dist/engine.d.ts +129 -0
  61. package/dist/engine.js +209 -0
  62. package/dist/error-observability.d.ts +7 -0
  63. package/dist/error-observability.js +61 -0
  64. package/dist/error-resolution.d.ts +18 -0
  65. package/dist/error-resolution.js +243 -0
  66. package/dist/errors.d.ts +74 -0
  67. package/dist/errors.js +99 -0
  68. package/dist/fixture-sanitization.d.ts +28 -0
  69. package/dist/fixture-sanitization.js +371 -0
  70. package/dist/handle-meta.d.ts +90 -0
  71. package/dist/handle-meta.js +73 -0
  72. package/dist/handle.d.ts +226 -0
  73. package/dist/handle.js +345 -0
  74. package/dist/health-scenario.d.ts +1901 -0
  75. package/dist/health-scenario.js +653 -0
  76. package/dist/i18n/catalog.js +21 -1
  77. package/dist/i18n/error-messages.d.ts +86 -0
  78. package/dist/i18n/error-messages.js +192 -0
  79. package/dist/i18n/index.d.ts +1 -0
  80. package/dist/i18n/index.js +1 -0
  81. package/dist/i18n/keys.d.ts +12 -0
  82. package/dist/i18n/keys.js +76 -5
  83. package/dist/i18n/operation-locale-namespace.d.ts +2 -0
  84. package/dist/i18n/operation-locale-namespace.js +7 -0
  85. package/dist/index.d.ts +40 -15
  86. package/dist/index.js +29 -11
  87. package/dist/lint.d.ts +43 -11
  88. package/dist/lint.js +2512 -177
  89. package/dist/native-address.d.ts +43 -0
  90. package/dist/native-address.js +281 -0
  91. package/dist/native-egress-policy.d.ts +31 -0
  92. package/dist/native-egress-policy.js +288 -0
  93. package/dist/observability.d.ts +5 -2
  94. package/dist/observability.js +48 -1
  95. package/dist/provider.d.ts +18 -8
  96. package/dist/provider.js +11 -6
  97. package/dist/runtime/auth-flow.d.ts +6 -1
  98. package/dist/runtime/auth-flow.js +8 -0
  99. package/dist/runtime/bounded-expiring-map.d.ts +21 -0
  100. package/dist/runtime/bounded-expiring-map.js +64 -0
  101. package/dist/runtime/browser-telemetry-binding.d.ts +5 -0
  102. package/dist/runtime/browser-telemetry-binding.js +83 -0
  103. package/dist/runtime/browser-telemetry.d.ts +76 -0
  104. package/dist/runtime/browser-telemetry.js +165 -0
  105. package/dist/runtime/browser.d.ts +4 -0
  106. package/dist/runtime/browser.js +688 -83
  107. package/dist/runtime/cache-telemetry.d.ts +71 -0
  108. package/dist/runtime/cache-telemetry.js +177 -0
  109. package/dist/runtime/cache.d.ts +3 -0
  110. package/dist/runtime/cache.js +245 -23
  111. package/dist/runtime/capability-response.d.ts +3 -0
  112. package/dist/runtime/capability-response.js +56 -0
  113. package/dist/runtime/capability-telemetry.d.ts +46 -0
  114. package/dist/runtime/capability-telemetry.js +68 -0
  115. package/dist/runtime/chrome149-header-order.d.ts +58 -0
  116. package/dist/runtime/chrome149-header-order.js +289 -0
  117. package/dist/runtime/diagnostic-env-values.d.ts +5 -0
  118. package/dist/runtime/diagnostic-env-values.js +57 -0
  119. package/dist/runtime/diagnostic-env.d.ts +14 -0
  120. package/dist/runtime/diagnostic-env.js +44 -0
  121. package/dist/runtime/diagnostic-redactor.d.ts +54 -0
  122. package/dist/runtime/diagnostic-redactor.js +571 -0
  123. package/dist/runtime/egress-lease.d.ts +65 -0
  124. package/dist/runtime/egress-lease.js +236 -0
  125. package/dist/runtime/engine-mode.d.ts +74 -0
  126. package/dist/runtime/engine-mode.js +152 -0
  127. package/dist/runtime/env.js +14 -1
  128. package/dist/runtime/executor.d.ts +3 -2
  129. package/dist/runtime/executor.js +23 -26
  130. package/dist/runtime/handle-wordlist.d.ts +43 -0
  131. package/dist/runtime/handle-wordlist.js +256 -0
  132. package/dist/runtime/handle.d.ts +71 -0
  133. package/dist/runtime/handle.js +908 -0
  134. package/dist/runtime/http-telemetry-binding.d.ts +10 -0
  135. package/dist/runtime/http-telemetry-binding.js +152 -0
  136. package/dist/runtime/http-telemetry-guard.d.ts +16 -0
  137. package/dist/runtime/http-telemetry-guard.js +202 -0
  138. package/dist/runtime/http-telemetry.d.ts +104 -0
  139. package/dist/runtime/http-telemetry.js +190 -0
  140. package/dist/runtime/http.d.ts +34 -0
  141. package/dist/runtime/http.js +680 -121
  142. package/dist/runtime/insights.js +2 -2
  143. package/dist/runtime/instrumentation.d.ts +2 -2
  144. package/dist/runtime/instrumentation.js +462 -19
  145. package/dist/runtime/native-network-errors.d.ts +33 -0
  146. package/dist/runtime/native-network-errors.js +69 -0
  147. package/dist/runtime/native-network.d.ts +105 -0
  148. package/dist/runtime/native-network.js +1433 -0
  149. package/dist/runtime/native-telemetry.d.ts +142 -0
  150. package/dist/runtime/native-telemetry.js +231 -0
  151. package/dist/runtime/ocr-telemetry.d.ts +82 -0
  152. package/dist/runtime/ocr-telemetry.js +192 -0
  153. package/dist/runtime/ocr.d.ts +29 -0
  154. package/dist/runtime/ocr.js +468 -0
  155. package/dist/runtime/otlp.d.ts +71 -2
  156. package/dist/runtime/otlp.js +398 -16
  157. package/dist/runtime/provider.d.ts +7 -0
  158. package/dist/runtime/provider.js +14 -0
  159. package/dist/runtime/proxy-errors.js +6 -2
  160. package/dist/runtime/proxy-nodemaven.d.ts +56 -0
  161. package/dist/runtime/proxy-nodemaven.js +147 -0
  162. package/dist/runtime/proxy-retry-policy.d.ts +4 -1
  163. package/dist/runtime/proxy-retry-policy.js +11 -2
  164. package/dist/runtime/proxy-telemetry.d.ts +133 -3
  165. package/dist/runtime/proxy-telemetry.js +218 -70
  166. package/dist/runtime/redirect-hop-headers.d.ts +19 -0
  167. package/dist/runtime/redirect-hop-headers.js +58 -0
  168. package/dist/runtime/redirects.d.ts +61 -0
  169. package/dist/runtime/redirects.js +149 -0
  170. package/dist/runtime/redis.d.ts +1 -1
  171. package/dist/runtime/redis.js +4 -2
  172. package/dist/runtime/request-options.d.ts +75 -1
  173. package/dist/runtime/request-options.js +588 -0
  174. package/dist/runtime/request-telemetry.d.ts +70 -0
  175. package/dist/runtime/request-telemetry.js +229 -0
  176. package/dist/runtime/resolver-config.d.ts +13 -0
  177. package/dist/runtime/resolver-config.js +14 -0
  178. package/dist/runtime/resolver-public.d.ts +3 -0
  179. package/dist/runtime/resolver-public.js +1 -0
  180. package/dist/runtime/resolver-runtime-options.d.ts +14 -0
  181. package/dist/runtime/resolver-runtime-options.js +33 -0
  182. package/dist/runtime/resolver-shared.d.ts +24 -0
  183. package/dist/runtime/resolver-shared.js +69 -0
  184. package/dist/runtime/resolver-span-attributes.d.ts +34 -0
  185. package/dist/runtime/resolver-span-attributes.js +93 -0
  186. package/dist/runtime/resolver-telemetry.d.ts +135 -0
  187. package/dist/runtime/resolver-telemetry.js +204 -0
  188. package/dist/runtime/resolver-usage.d.ts +32 -0
  189. package/dist/runtime/resolver-usage.js +54 -0
  190. package/dist/runtime/resolver-vendors/bindings.d.ts +53 -0
  191. package/dist/runtime/resolver-vendors/bindings.js +45 -0
  192. package/dist/runtime/resolver-vendors/browser.d.ts +24 -0
  193. package/dist/runtime/resolver-vendors/browser.js +423 -0
  194. package/dist/runtime/resolver-vendors/capsolver.d.ts +22 -0
  195. package/dist/runtime/resolver-vendors/capsolver.js +544 -0
  196. package/dist/runtime/resolver-vendors/hosts.d.ts +23 -0
  197. package/dist/runtime/resolver-vendors/hosts.js +68 -0
  198. package/dist/runtime/resolver-vendors/hypersolutions.d.ts +27 -0
  199. package/dist/runtime/resolver-vendors/hypersolutions.js +369 -0
  200. package/dist/runtime/resolver-vendors/twocaptcha.d.ts +24 -0
  201. package/dist/runtime/resolver-vendors/twocaptcha.js +425 -0
  202. package/dist/runtime/resolver-vendors/types.d.ts +125 -0
  203. package/dist/runtime/resolver-vendors/types.js +106 -0
  204. package/dist/runtime/resolver.d.ts +79 -0
  205. package/dist/runtime/resolver.js +1094 -0
  206. package/dist/runtime/state-telemetry.d.ts +79 -0
  207. package/dist/runtime/state-telemetry.js +194 -0
  208. package/dist/runtime/state.d.ts +10 -1
  209. package/dist/runtime/state.js +322 -82
  210. package/dist/runtime/stealth-akamai-sbsd.d.ts +54 -0
  211. package/dist/runtime/stealth-akamai-sbsd.js +142 -0
  212. package/dist/runtime/stealth-cookies.d.ts +24 -0
  213. package/dist/runtime/stealth-cookies.js +131 -0
  214. package/dist/runtime/stealth-owned-headers.d.ts +39 -0
  215. package/dist/runtime/stealth-owned-headers.js +57 -0
  216. package/dist/runtime/stealth-telemetry.d.ts +92 -0
  217. package/dist/runtime/stealth-telemetry.js +179 -0
  218. package/dist/runtime/stealth.d.ts +45 -6
  219. package/dist/runtime/stealth.js +1775 -320
  220. package/dist/runtime/stt-telemetry.d.ts +77 -0
  221. package/dist/runtime/stt-telemetry.js +176 -0
  222. package/dist/runtime/stt.js +18 -19
  223. package/dist/runtime/timeout.d.ts +5 -0
  224. package/dist/runtime/timeout.js +12 -0
  225. package/dist/runtime/trace-config.d.ts +12 -0
  226. package/dist/runtime/trace-config.js +62 -0
  227. package/dist/runtime/trace.d.ts +17 -0
  228. package/dist/runtime/trace.js +176 -25
  229. package/dist/runtime-boundary-lint.d.ts +137 -0
  230. package/dist/runtime-boundary-lint.js +590 -0
  231. package/dist/schema.d.ts +20 -0
  232. package/dist/schema.js +72 -2
  233. package/dist/serve.d.ts +1 -1
  234. package/dist/serve.js +1 -1
  235. package/dist/server/error-observability.d.ts +1 -0
  236. package/dist/server/error-observability.js +1 -0
  237. package/dist/server/error-stack-frames.d.ts +35 -0
  238. package/dist/server/error-stack-frames.js +219 -0
  239. package/dist/server/index.d.ts +21 -2
  240. package/dist/server/index.js +11 -2
  241. package/dist/server/runtime-diagnostics.d.ts +165 -0
  242. package/dist/server/runtime-diagnostics.js +360 -0
  243. package/dist/server/sdk-version.d.ts +3 -0
  244. package/dist/server/sdk-version.js +19 -0
  245. package/dist/server/self-test-input-tokens.d.ts +2 -1
  246. package/dist/server/self-test-input-tokens.js +18 -14
  247. package/dist/server/self-test-redaction.js +8 -33
  248. package/dist/server/self-test.d.ts +18 -3
  249. package/dist/server/self-test.js +139 -76
  250. package/dist/server/sensitive-values.d.ts +26 -0
  251. package/dist/server/sensitive-values.js +137 -0
  252. package/dist/server/serve-implementation.d.ts +285 -0
  253. package/dist/server/serve-implementation.js +3172 -0
  254. package/dist/server/serve.d.ts +1 -75
  255. package/dist/server/serve.js +1 -1170
  256. package/dist/server/state-backend-report.d.ts +70 -0
  257. package/dist/server/state-backend-report.js +113 -0
  258. package/dist/server/trace-output.d.ts +7 -0
  259. package/dist/server/trace-output.js +111 -0
  260. package/dist/server/types.d.ts +37 -5
  261. package/dist/server/types.js +34 -1
  262. package/dist/stateful/errors.d.ts +19 -0
  263. package/dist/stateful/errors.js +24 -0
  264. package/dist/stateful/http-provider-event-emitter.d.ts +40 -0
  265. package/dist/stateful/http-provider-event-emitter.js +237 -0
  266. package/dist/stateful/http-session-owner-registry.d.ts +44 -0
  267. package/dist/stateful/http-session-owner-registry.js +210 -0
  268. package/dist/stateful/index.d.ts +18 -0
  269. package/dist/stateful/index.js +18 -0
  270. package/dist/stateful/provider-event-delivery-failures.d.ts +32 -0
  271. package/dist/stateful/provider-event-delivery-failures.js +43 -0
  272. package/dist/stateful/provider-event-pipeline-metrics.d.ts +46 -0
  273. package/dist/stateful/provider-event-pipeline-metrics.js +48 -0
  274. package/dist/stateful/provider-event-pipeline.d.ts +50 -0
  275. package/dist/stateful/provider-event-pipeline.js +1 -0
  276. package/dist/stateful/provider-events.d.ts +101 -0
  277. package/dist/stateful/provider-events.js +289 -0
  278. package/dist/stateful/session-key.d.ts +15 -0
  279. package/dist/stateful/session-key.js +86 -0
  280. package/dist/stateful/stateful-provider-adapter-context.d.ts +5 -0
  281. package/dist/stateful/stateful-provider-adapter-context.js +42 -0
  282. package/dist/stateful/stateful-provider-adapter-metrics.d.ts +15 -0
  283. package/dist/stateful/stateful-provider-adapter-metrics.js +21 -0
  284. package/dist/stateful/stateful-provider-adapter.d.ts +98 -0
  285. package/dist/stateful/stateful-provider-adapter.js +287 -0
  286. package/dist/stateful/stateful-provider-observability.d.ts +62 -0
  287. package/dist/stateful/stateful-provider-observability.js +161 -0
  288. package/dist/stateful/stateful-provider-owner-forwarder.d.ts +41 -0
  289. package/dist/stateful/stateful-provider-owner-forwarder.js +237 -0
  290. package/dist/stateful/stateful-provider-runtime-context.d.ts +35 -0
  291. package/dist/stateful/stateful-provider-runtime-context.js +61 -0
  292. package/dist/stateful/stateful-provider-runtime-executor.d.ts +34 -0
  293. package/dist/stateful/stateful-provider-runtime-executor.js +52 -0
  294. package/dist/stateful/stateful-provider-session-routing.d.ts +67 -0
  295. package/dist/stateful/stateful-provider-session-routing.js +345 -0
  296. package/dist/stateful/stateful-provider-session-runtime.d.ts +98 -0
  297. package/dist/stateful/stateful-provider-session-runtime.js +245 -0
  298. package/dist/stateful-signing.d.ts +18 -0
  299. package/dist/stateful-signing.js +27 -0
  300. package/dist/stealth/profiles.d.ts +15 -4
  301. package/dist/stealth/profiles.js +169 -211
  302. package/dist/stream-evidence.d.ts +74 -0
  303. package/dist/stream-evidence.js +785 -0
  304. package/dist/stream.js +7 -1
  305. package/dist/testing/index.d.ts +2 -1
  306. package/dist/testing/index.js +2 -1
  307. package/dist/testing/run.d.ts +32 -2
  308. package/dist/testing/run.js +509 -25
  309. package/dist/trace-sanitization.d.ts +6 -0
  310. package/dist/trace-sanitization.js +68 -0
  311. package/dist/types.d.ts +899 -210
  312. package/dist/types.js +1 -0
  313. package/dist/typescript-module.d.ts +39 -0
  314. package/dist/typescript-module.js +72 -0
  315. package/package.json +52 -6
  316. package/src/auth-turn/index.ts +1 -1
  317. package/src/auth.ts +118 -0
  318. package/src/ceremonies/index.ts +189 -46
  319. package/src/cli/commands.ts +37 -0
  320. package/src/cli/create.ts +8 -2
  321. package/src/cli/deployment-intent.ts +364 -0
  322. package/src/cli/local-connection.ts +221 -0
  323. package/src/cli/migrate-deployment-intent.ts +1908 -0
  324. package/src/cli/migrate-operation-declaration.ts +3026 -0
  325. package/src/cli/migrate-operation-shape.ts +184 -0
  326. package/src/cli/migrate-provider-shape.ts +778 -0
  327. package/src/cli/resolver-runtime.ts +72 -0
  328. package/src/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl +141 -23
  329. package/src/cli/templates/provider/Dockerfile.tpl +1 -1
  330. package/src/cli/templates/provider/README.md.tpl +41 -19
  331. package/src/cli/templates/provider/index.ts.tpl +6 -3
  332. package/src/cli/templates/provider/operations/ping.ts.tpl +4 -1
  333. package/src/cli/templates/provider/provider.json.tpl +6 -0
  334. package/src/config/loader.ts +774 -181
  335. package/src/contract-serialization.ts +5 -7
  336. package/src/contract-types.ts +12 -5
  337. package/src/contract.ts +24 -10
  338. package/src/declaration-validation.ts +376 -0
  339. package/src/define.ts +1105 -131
  340. package/src/dev.ts +13 -1
  341. package/src/engine.ts +390 -0
  342. package/src/error-observability.ts +64 -0
  343. package/src/error-resolution.ts +269 -0
  344. package/src/errors.ts +157 -0
  345. package/src/fixture-sanitization.ts +422 -0
  346. package/src/handle-meta.ts +143 -0
  347. package/src/handle.ts +694 -0
  348. package/src/health-scenario.ts +960 -0
  349. package/src/i18n/catalog.ts +23 -1
  350. package/src/i18n/error-messages.ts +255 -0
  351. package/src/i18n/index.ts +1 -0
  352. package/src/i18n/keys.ts +80 -6
  353. package/src/i18n/operation-locale-namespace.ts +10 -0
  354. package/src/index.ts +390 -23
  355. package/src/lint.ts +2975 -234
  356. package/src/native-address.ts +340 -0
  357. package/src/native-egress-policy.ts +358 -0
  358. package/src/observability.ts +51 -1
  359. package/src/provider.ts +207 -27
  360. package/src/runtime/auth-flow.ts +15 -0
  361. package/src/runtime/bounded-expiring-map.ts +67 -0
  362. package/src/runtime/browser-telemetry-binding.ts +92 -0
  363. package/src/runtime/browser-telemetry.ts +289 -0
  364. package/src/runtime/browser.ts +882 -99
  365. package/src/runtime/cache-telemetry.ts +247 -0
  366. package/src/runtime/cache.ts +258 -22
  367. package/src/runtime/capability-response.ts +53 -0
  368. package/src/runtime/capability-telemetry.ts +101 -0
  369. package/src/runtime/chrome149-header-order.ts +330 -0
  370. package/src/runtime/diagnostic-env-values.ts +56 -0
  371. package/src/runtime/diagnostic-env.ts +65 -0
  372. package/src/runtime/diagnostic-redactor.ts +668 -0
  373. package/src/runtime/egress-lease.ts +341 -0
  374. package/src/runtime/engine-mode.ts +233 -0
  375. package/src/runtime/env.ts +15 -1
  376. package/src/runtime/executor.ts +39 -32
  377. package/src/runtime/handle-wordlist.ts +266 -0
  378. package/src/runtime/handle.ts +1180 -0
  379. package/src/runtime/http-telemetry-binding.ts +162 -0
  380. package/src/runtime/http-telemetry-guard.ts +208 -0
  381. package/src/runtime/http-telemetry.ts +292 -0
  382. package/src/runtime/http.ts +896 -150
  383. package/src/runtime/insights.ts +2 -2
  384. package/src/runtime/instrumentation.ts +628 -28
  385. package/src/runtime/native-network-errors.ts +99 -0
  386. package/src/runtime/native-network.ts +1853 -0
  387. package/src/runtime/native-telemetry.ts +366 -0
  388. package/src/runtime/ocr-telemetry.ts +308 -0
  389. package/src/runtime/ocr.ts +564 -0
  390. package/src/runtime/otlp.ts +468 -21
  391. package/src/runtime/provider.ts +15 -0
  392. package/src/runtime/proxy-errors.ts +12 -4
  393. package/src/runtime/proxy-nodemaven.ts +222 -0
  394. package/src/runtime/proxy-retry-policy.ts +12 -1
  395. package/src/runtime/proxy-telemetry.ts +358 -103
  396. package/src/runtime/redirect-hop-headers.ts +71 -0
  397. package/src/runtime/redirects.ts +215 -0
  398. package/src/runtime/redis.ts +7 -2
  399. package/src/runtime/request-options.ts +728 -1
  400. package/src/runtime/request-telemetry.ts +375 -0
  401. package/src/runtime/resolver-config.ts +18 -0
  402. package/src/runtime/resolver-public.ts +44 -0
  403. package/src/runtime/resolver-runtime-options.ts +50 -0
  404. package/src/runtime/resolver-shared.ts +113 -0
  405. package/src/runtime/resolver-span-attributes.ts +139 -0
  406. package/src/runtime/resolver-telemetry.ts +362 -0
  407. package/src/runtime/resolver-usage.ts +99 -0
  408. package/src/runtime/resolver-vendors/bindings.ts +61 -0
  409. package/src/runtime/resolver-vendors/browser.ts +591 -0
  410. package/src/runtime/resolver-vendors/capsolver.ts +727 -0
  411. package/src/runtime/resolver-vendors/hosts.ts +81 -0
  412. package/src/runtime/resolver-vendors/hypersolutions.ts +480 -0
  413. package/src/runtime/resolver-vendors/twocaptcha.ts +555 -0
  414. package/src/runtime/resolver-vendors/types.ts +261 -0
  415. package/src/runtime/resolver.ts +1543 -0
  416. package/src/runtime/state-telemetry.ts +298 -0
  417. package/src/runtime/state.ts +435 -89
  418. package/src/runtime/stealth-akamai-sbsd.ts +207 -0
  419. package/src/runtime/stealth-cookies.ts +155 -0
  420. package/src/runtime/stealth-owned-headers.ts +67 -0
  421. package/src/runtime/stealth-telemetry.ts +309 -0
  422. package/src/runtime/stealth.ts +2275 -372
  423. package/src/runtime/stt-telemetry.ts +282 -0
  424. package/src/runtime/stt.ts +96 -91
  425. package/src/runtime/timeout.ts +18 -0
  426. package/src/runtime/trace-config.ts +78 -0
  427. package/src/runtime/trace.ts +257 -35
  428. package/src/runtime-boundary-lint.ts +707 -0
  429. package/src/schema.ts +80 -2
  430. package/src/serve.ts +6 -1
  431. package/src/server/error-observability.ts +1 -0
  432. package/src/server/error-stack-frames.ts +214 -0
  433. package/src/server/index.ts +184 -2
  434. package/src/server/runtime-diagnostics.ts +522 -0
  435. package/src/server/sdk-version.ts +22 -0
  436. package/src/server/self-test-input-tokens.ts +29 -14
  437. package/src/server/self-test-redaction.ts +10 -40
  438. package/src/server/self-test.ts +205 -89
  439. package/src/server/sensitive-values.ts +211 -0
  440. package/src/server/serve-implementation.ts +4596 -0
  441. package/src/server/serve.ts +1 -1685
  442. package/src/server/state-backend-report.ts +185 -0
  443. package/src/server/trace-output.ts +189 -0
  444. package/src/server/types.ts +34 -1
  445. package/src/stateful/README.md +146 -0
  446. package/src/stateful/errors.ts +35 -0
  447. package/src/stateful/http-provider-event-emitter.ts +314 -0
  448. package/src/stateful/http-session-owner-registry.ts +306 -0
  449. package/src/stateful/index.ts +18 -0
  450. package/src/stateful/provider-event-delivery-failures.ts +80 -0
  451. package/src/stateful/provider-event-pipeline-metrics.ts +95 -0
  452. package/src/stateful/provider-event-pipeline.ts +61 -0
  453. package/src/stateful/provider-events.ts +462 -0
  454. package/src/stateful/session-key.ts +111 -0
  455. package/src/stateful/stateful-provider-adapter-context.ts +59 -0
  456. package/src/stateful/stateful-provider-adapter-metrics.ts +48 -0
  457. package/src/stateful/stateful-provider-adapter.ts +562 -0
  458. package/src/stateful/stateful-provider-observability.ts +261 -0
  459. package/src/stateful/stateful-provider-owner-forwarder.ts +310 -0
  460. package/src/stateful/stateful-provider-runtime-context.ts +96 -0
  461. package/src/stateful/stateful-provider-runtime-executor.ts +96 -0
  462. package/src/stateful/stateful-provider-session-routing.ts +546 -0
  463. package/src/stateful/stateful-provider-session-runtime.ts +403 -0
  464. package/src/stateful-signing.ts +46 -0
  465. package/src/stealth/profiles.ts +212 -231
  466. package/src/stream-evidence.ts +988 -0
  467. package/src/stream.ts +8 -1
  468. package/src/testing/index.ts +10 -1
  469. package/src/testing/run.ts +685 -19
  470. package/src/trace-sanitization.ts +110 -0
  471. package/src/types.ts +1014 -273
  472. package/src/typescript-module.ts +100 -0
  473. package/dist/choice-token.d.ts +0 -24
  474. package/dist/choice-token.js +0 -74
  475. package/dist/runtime/choice.d.ts +0 -15
  476. package/dist/runtime/choice.js +0 -413
  477. package/src/choice-token.ts +0 -165
  478. package/src/runtime/choice.ts +0 -686
@@ -0,0 +1,960 @@
1
+ import { z } from "zod";
2
+ import type { JsonPrimitive, JsonValue } from "./contract-json.js";
3
+ export type NonEmpty<T> = readonly [T, ...T[]];
4
+
5
+ const finiteInt = (min: number, max?: number) => {
6
+ const schema = z.number().finite().int().min(min);
7
+ return max === undefined ? schema : schema.max(max);
8
+ };
9
+
10
+ const nonEmptyArray = <T>(schema: z.ZodType<T>) =>
11
+ z
12
+ .array(schema)
13
+ .min(1)
14
+ .transform((value) => value as [T, ...T[]]);
15
+
16
+ const jsonValueSchema: z.ZodType<JsonValue> = z.lazy(() =>
17
+ z.union([
18
+ z.null(),
19
+ z.boolean(),
20
+ z.number().finite(),
21
+ z.string(),
22
+ z.array(jsonValueSchema),
23
+ z.record(z.string(), jsonValueSchema),
24
+ ]),
25
+ );
26
+
27
+ const pathPartSchema = z.union([z.string().min(1), finiteInt(0, 10_000)]);
28
+
29
+ const propertyNameSchema = z
30
+ .string()
31
+ .min(1)
32
+ .superRefine((value, ctx) => {
33
+ if (new TextEncoder().encode(value).byteLength > 128)
34
+ ctx.addIssue({ code: "custom", message: "property name exceeds 128 UTF-8 bytes" });
35
+ });
36
+
37
+ const pathSegmentSchema = z.union([
38
+ z.object({ kind: z.literal("property"), name: propertyNameSchema }).strict(),
39
+ z.object({ kind: z.literal("index"), index: finiteInt(0, 10_000) }).strict(),
40
+ ]);
41
+
42
+ export const BoundedJsonPathSchema = z
43
+ .object({ root: z.literal("$"), segments: z.array(pathSegmentSchema).max(12) })
44
+ .strict();
45
+ export type BoundedJsonPath = z.infer<typeof BoundedJsonPathSchema>;
46
+
47
+ const valueTypeSchema = z.enum([
48
+ "null",
49
+ "boolean",
50
+ "number",
51
+ "string",
52
+ "object",
53
+ "array",
54
+ "json",
55
+ "established_connection",
56
+ ]);
57
+ export const ValueTypeSchema = valueTypeSchema;
58
+ export type ValueType = z.infer<typeof valueTypeSchema>;
59
+
60
+ const stepReferenceSchema = z
61
+ .object({
62
+ namespace: z.literal("steps"),
63
+ binding: z.string().min(1),
64
+ path: z.array(pathPartSchema).min(1).max(12),
65
+ })
66
+ .strict();
67
+ export const StepReferenceSchema = stepReferenceSchema;
68
+ export type StepReference = z.infer<typeof stepReferenceSchema>;
69
+
70
+ const credentialReferenceSchema = z
71
+ .object({
72
+ namespace: z.literal("credentials"),
73
+ alias: z.string().min(1),
74
+ field: z.literal("connection"),
75
+ })
76
+ .strict();
77
+ const attemptReferenceSchema = z
78
+ .object({
79
+ namespace: z.literal("attempt"),
80
+ field: z.enum([
81
+ "id",
82
+ "external_ref",
83
+ "provider_id",
84
+ "scenario_id",
85
+ "started_at",
86
+ "deadline_at",
87
+ ]),
88
+ })
89
+ .strict();
90
+ const candidateReferenceSchema = z
91
+ .object({
92
+ namespace: z.literal("candidate"),
93
+ binding: z.string().min(1),
94
+ path: z.union([
95
+ z.tuple([z.literal("item")]).rest(pathPartSchema),
96
+ z.tuple([z.literal("result")]).rest(pathPartSchema),
97
+ ]),
98
+ })
99
+ .strict();
100
+
101
+ export type CredentialReference = z.infer<typeof credentialReferenceSchema>;
102
+ export type EstablishedConnectionReference = CredentialReference & { field: "connection" };
103
+ export type AttemptReference = z.infer<typeof attemptReferenceSchema>;
104
+ export type CandidateReference = z.infer<typeof candidateReferenceSchema>;
105
+ export type Reference = StepReference | CredentialReference | AttemptReference | CandidateReference;
106
+ const referenceSchema = z.discriminatedUnion("namespace", [
107
+ stepReferenceSchema,
108
+ credentialReferenceSchema,
109
+ attemptReferenceSchema,
110
+ candidateReferenceSchema,
111
+ ]);
112
+ export const ReferenceSchema = referenceSchema;
113
+
114
+ const relativeDateNodeSchema = z
115
+ .object({
116
+ relativeDate: z
117
+ .object({
118
+ anchor: z.literal("operation_started_at"),
119
+ offsetDays: finiteInt(1, 365),
120
+ timeZone: z.literal("Asia/Seoul"),
121
+ format: z.enum(["YYYY-MM-DD", "YYYYMMDD"]),
122
+ })
123
+ .strict(),
124
+ })
125
+ .strict();
126
+ export type RelativeDateNode = z.infer<typeof relativeDateNodeSchema>;
127
+ export const RelativeDateNodeSchema = relativeDateNodeSchema;
128
+ const referenceNodeSchema = z.object({ ref: referenceSchema }).strict();
129
+
130
+ export type ReferenceNode = { ref: Reference };
131
+ export type JsonTemplate =
132
+ | JsonPrimitive
133
+ | ReferenceNode
134
+ | RelativeDateNode
135
+ | JsonTemplate[]
136
+ | { [key: string]: JsonTemplate };
137
+ // Reserved template keys may only occur in their exact, single-key node forms.
138
+ const templateRecordSchema = z
139
+ .record(
140
+ z.string(),
141
+ z.lazy(() => jsonTemplateSchema),
142
+ )
143
+ .superRefine((value, ctx) => {
144
+ if (Object.hasOwn(value, "ref") || Object.hasOwn(value, "relativeDate"))
145
+ ctx.addIssue({ code: "custom", message: "reserved template keys require a sole-key node" });
146
+ });
147
+ const jsonTemplateSchema: z.ZodType<JsonTemplate> = z.lazy(() =>
148
+ z.union([
149
+ z.null(),
150
+ z.boolean(),
151
+ z.number().finite(),
152
+ z.string(),
153
+ referenceNodeSchema,
154
+ relativeDateNodeSchema,
155
+ z.array(jsonTemplateSchema),
156
+ templateRecordSchema,
157
+ ]),
158
+ );
159
+ export const JsonTemplateSchema = jsonTemplateSchema;
160
+
161
+ export type SafeRegex = {
162
+ readonly engine: "re2";
163
+ readonly pattern: string;
164
+ readonly flags: "" | "i";
165
+ };
166
+ function containsNestedRegexQuantifier(pattern: string): boolean {
167
+ const groups: boolean[] = [];
168
+ let escaped = false;
169
+ let inClass = false;
170
+ let closedQuantified = false;
171
+ for (let i = 0; i < pattern.length; i += 1) {
172
+ const c = pattern[i];
173
+ if (escaped) {
174
+ escaped = false;
175
+ closedQuantified = false;
176
+ continue;
177
+ }
178
+ if (c === "\\") {
179
+ escaped = true;
180
+ closedQuantified = false;
181
+ continue;
182
+ }
183
+ if (c === "[" && !inClass) {
184
+ inClass = true;
185
+ continue;
186
+ }
187
+ if (c === "]" && inClass) {
188
+ inClass = false;
189
+ continue;
190
+ }
191
+ if (inClass) continue;
192
+ if (c === "(") {
193
+ groups.push(false);
194
+ closedQuantified = false;
195
+ continue;
196
+ }
197
+ if (c === ")") {
198
+ closedQuantified = groups.pop() ?? false;
199
+ if (closedQuantified && groups.length > 0) groups[groups.length - 1] = true;
200
+ continue;
201
+ }
202
+ const brace = c === "{" && /^\{\d+(?:,\d*)?\}/.test(pattern.slice(i));
203
+ if (c === "*" || c === "+" || brace || (c === "?" && pattern[i - 1] !== "(")) {
204
+ if (closedQuantified) return true;
205
+ if (groups.length > 0) groups[groups.length - 1] = true;
206
+ }
207
+ closedQuantified = false;
208
+ }
209
+ return false;
210
+ }
211
+ export const SafeRegexSchema = z
212
+ .object({ engine: z.literal("re2"), pattern: z.string().max(256), flags: z.enum(["", "i"]) })
213
+ .strict()
214
+ .superRefine((value, ctx) => {
215
+ if (/\\[1-9kg]/.test(value.pattern))
216
+ ctx.addIssue({
217
+ code: "custom",
218
+ path: ["pattern"],
219
+ message: "backreferences are not supported by RE2",
220
+ });
221
+ if (/\(\?/.test(value.pattern))
222
+ ctx.addIssue({
223
+ code: "custom",
224
+ path: ["pattern"],
225
+ message: "extended groups are not supported by RE2",
226
+ });
227
+ if (containsNestedRegexQuantifier(value.pattern))
228
+ ctx.addIssue({
229
+ code: "custom",
230
+ path: ["pattern"],
231
+ message: "nested regex quantifiers are not permitted",
232
+ });
233
+ try {
234
+ new RegExp(value.pattern, value.flags);
235
+ } catch {
236
+ ctx.addIssue({
237
+ code: "custom",
238
+ path: ["pattern"],
239
+ message: "pattern must be valid regular-expression syntax",
240
+ });
241
+ }
242
+ });
243
+
244
+ const operandLiteralSchema = jsonValueSchema.superRefine((value, ctx) => {
245
+ if (
246
+ value !== null &&
247
+ typeof value === "object" &&
248
+ !Array.isArray(value) &&
249
+ Object.hasOwn(value, "ref")
250
+ )
251
+ ctx.addIssue({
252
+ code: "custom",
253
+ message: 'the object key "ref" is reserved for a validated reference',
254
+ });
255
+ });
256
+ const operandSchema = z.union([operandLiteralSchema, referenceNodeSchema]);
257
+ export const OperandSchema = operandSchema;
258
+ export type Operand = JsonValue | ReferenceNode;
259
+
260
+ const predicateSchema = z.union([
261
+ z
262
+ .object({
263
+ kind: z.literal("predicate"),
264
+ operator: z.enum(["exists", "not_exists", "non_empty", "is_true"]),
265
+ actual: operandSchema,
266
+ })
267
+ .strict(),
268
+ z
269
+ .object({
270
+ kind: z.literal("predicate"),
271
+ operator: z.enum(["equals", "not_equals", "contains"]),
272
+ actual: operandSchema,
273
+ expected: operandSchema,
274
+ })
275
+ .strict(),
276
+ z
277
+ .object({
278
+ kind: z.literal("predicate"),
279
+ operator: z.literal("matches"),
280
+ actual: operandSchema,
281
+ pattern: SafeRegexSchema,
282
+ })
283
+ .strict(),
284
+ z
285
+ .object({
286
+ kind: z.literal("predicate"),
287
+ operator: z.enum(["number_gt", "number_gte", "number_lt", "number_lte"]),
288
+ actual: operandSchema,
289
+ expected: operandSchema,
290
+ })
291
+ .strict(),
292
+ z
293
+ .object({
294
+ kind: z.literal("predicate"),
295
+ operator: z.enum(["array_length_eq", "array_length_gte", "array_length_lte"]),
296
+ actual: operandSchema,
297
+ expected: z.number().finite().int().nonnegative(),
298
+ })
299
+ .strict(),
300
+ z
301
+ .object({
302
+ kind: z.literal("predicate"),
303
+ operator: z.literal("status_2xx"),
304
+ actual: operandSchema,
305
+ })
306
+ .strict(),
307
+ z
308
+ .object({
309
+ kind: z.literal("predicate"),
310
+ operator: z.literal("type_is"),
311
+ actual: operandSchema,
312
+ expected: z.enum(["null", "boolean", "number", "string", "object", "array"]),
313
+ })
314
+ .strict(),
315
+ ]);
316
+ export const AssertionPredicateSchema = predicateSchema;
317
+ export type AssertionPredicate = z.infer<typeof predicateSchema>;
318
+
319
+ const scopedItemReferenceSchema = z
320
+ .object({
321
+ namespace: z.literal("item"),
322
+ binding: z.string().min(1),
323
+ path: z.array(pathPartSchema).max(12),
324
+ })
325
+ .strict();
326
+ export const ScopedItemReferenceSchema = scopedItemReferenceSchema;
327
+ export type ScopedItemReference = z.infer<typeof scopedItemReferenceSchema>;
328
+
329
+ const scopedOperandSchema = z.union([
330
+ operandLiteralSchema,
331
+ z.object({ ref: scopedItemReferenceSchema }).strict(),
332
+ referenceNodeSchema,
333
+ ]);
334
+ export const ScopedOperandSchema = scopedOperandSchema;
335
+ export type ScopedOperand = z.infer<typeof scopedOperandSchema>;
336
+
337
+ const scopedPredicateSchema = z.union([
338
+ z
339
+ .object({
340
+ kind: z.literal("predicate"),
341
+ operator: z.enum(["exists", "not_exists", "non_empty", "is_true"]),
342
+ actual: scopedOperandSchema,
343
+ })
344
+ .strict(),
345
+ z
346
+ .object({
347
+ kind: z.literal("predicate"),
348
+ operator: z.enum(["equals", "not_equals", "contains"]),
349
+ actual: scopedOperandSchema,
350
+ expected: scopedOperandSchema,
351
+ })
352
+ .strict(),
353
+ z
354
+ .object({
355
+ kind: z.literal("predicate"),
356
+ operator: z.literal("matches"),
357
+ actual: scopedOperandSchema,
358
+ pattern: SafeRegexSchema,
359
+ })
360
+ .strict(),
361
+ z
362
+ .object({
363
+ kind: z.literal("predicate"),
364
+ operator: z.enum(["number_gt", "number_gte", "number_lt", "number_lte"]),
365
+ actual: scopedOperandSchema,
366
+ expected: scopedOperandSchema,
367
+ })
368
+ .strict(),
369
+ z
370
+ .object({
371
+ kind: z.literal("predicate"),
372
+ operator: z.enum(["array_length_eq", "array_length_gte", "array_length_lte"]),
373
+ actual: scopedOperandSchema,
374
+ expected: z.number().finite().int().nonnegative(),
375
+ })
376
+ .strict(),
377
+ z
378
+ .object({
379
+ kind: z.literal("predicate"),
380
+ operator: z.literal("status_2xx"),
381
+ actual: scopedOperandSchema,
382
+ })
383
+ .strict(),
384
+ z
385
+ .object({
386
+ kind: z.literal("predicate"),
387
+ operator: z.literal("type_is"),
388
+ actual: scopedOperandSchema,
389
+ expected: z.enum(["null", "boolean", "number", "string", "object", "array"]),
390
+ })
391
+ .strict(),
392
+ ]);
393
+ export const ScopedAssertionPredicateSchema = scopedPredicateSchema;
394
+ export type ScopedAssertionPredicate = z.infer<typeof scopedPredicateSchema>;
395
+
396
+ export type ScopedAssertionExpression =
397
+ | { kind: "all" | "any"; clauses: NonEmpty<ScopedAssertionExpression> }
398
+ | { kind: "not"; clause: ScopedAssertionExpression }
399
+ | ScopedAssertionPredicate;
400
+ const scopedExpressionSchema: z.ZodType<ScopedAssertionExpression> = z.lazy(() =>
401
+ z.union([
402
+ z.object({ kind: z.literal("all"), clauses: nonEmptyArray(scopedExpressionSchema) }).strict(),
403
+ z.object({ kind: z.literal("any"), clauses: nonEmptyArray(scopedExpressionSchema) }).strict(),
404
+ z.object({ kind: z.literal("not"), clause: scopedExpressionSchema }).strict(),
405
+ scopedPredicateSchema,
406
+ ]),
407
+ );
408
+ export const ScopedAssertionExpressionSchema = scopedExpressionSchema;
409
+
410
+ export type Quantifier = {
411
+ kind: "quantifier";
412
+ quantifier: "every" | "any";
413
+ items: { ref: StepReference | CandidateReference };
414
+ itemBinding: string;
415
+ maxItems: number;
416
+ clause: ScopedAssertionExpression;
417
+ };
418
+ const quantifierSchema: z.ZodType<Quantifier> = z
419
+ .object({
420
+ kind: z.literal("quantifier"),
421
+ quantifier: z.enum(["every", "any"]),
422
+ items: z.object({ ref: z.union([stepReferenceSchema, candidateReferenceSchema]) }).strict(),
423
+ itemBinding: z.string().min(1),
424
+ maxItems: finiteInt(1, 100),
425
+ clause: scopedExpressionSchema,
426
+ })
427
+ .strict();
428
+ export const QuantifierSchema = quantifierSchema;
429
+
430
+ export type AssertionExpression =
431
+ | { kind: "all" | "any"; clauses: NonEmpty<AssertionExpression> }
432
+ | { kind: "not"; clause: AssertionExpression }
433
+ | AssertionPredicate
434
+ | Quantifier;
435
+ const expressionSchema: z.ZodType<AssertionExpression> = z.lazy(() =>
436
+ z.union([
437
+ z.object({ kind: z.literal("all"), clauses: nonEmptyArray(expressionSchema) }).strict(),
438
+ z.object({ kind: z.literal("any"), clauses: nonEmptyArray(expressionSchema) }).strict(),
439
+ z.object({ kind: z.literal("not"), clause: expressionSchema }).strict(),
440
+ predicateSchema,
441
+ quantifierSchema,
442
+ ]),
443
+ );
444
+ export const AssertionExpressionSchema = expressionSchema;
445
+
446
+ export type RetryPolicy = {
447
+ maxAttempts: number;
448
+ retryOn: NonEmpty<"transport_error" | "timeout" | "http_429" | "http_5xx">;
449
+ backoff:
450
+ | { kind: "fixed"; delayMs: number }
451
+ | { kind: "exponential"; initialDelayMs: number; maxDelayMs: number };
452
+ attemptTimeoutMs?: number;
453
+ };
454
+ const retryPolicySchema: z.ZodType<RetryPolicy> = z
455
+ .object({
456
+ maxAttempts: finiteInt(1, 3),
457
+ retryOn: nonEmptyArray(z.enum(["transport_error", "timeout", "http_429", "http_5xx"])),
458
+ backoff: z.union([
459
+ z
460
+ .object({ kind: z.literal("fixed"), delayMs: z.number().finite().int().nonnegative() })
461
+ .strict(),
462
+ z
463
+ .object({
464
+ kind: z.literal("exponential"),
465
+ initialDelayMs: z.number().finite().int().nonnegative(),
466
+ maxDelayMs: z.number().finite().int().nonnegative(),
467
+ })
468
+ .strict(),
469
+ ]),
470
+ attemptTimeoutMs: finiteInt(1, 600_000).optional(),
471
+ })
472
+ .strict();
473
+ export const RetryPolicySchema = retryPolicySchema;
474
+
475
+ export type CandidatePolicy = {
476
+ items: StepReference;
477
+ itemBinding: string;
478
+ itemType: "string" | "number" | "object";
479
+ maxAttempts: number;
480
+ accept: AssertionExpression;
481
+ };
482
+ const candidatePolicySchema: z.ZodType<CandidatePolicy> = z
483
+ .object({
484
+ items: stepReferenceSchema,
485
+ itemBinding: z.string().min(1),
486
+ itemType: z.enum(["string", "number", "object"]),
487
+ maxAttempts: finiteInt(1, 10),
488
+ accept: expressionSchema,
489
+ })
490
+ .strict();
491
+ export const CandidatePolicySchema = candidatePolicySchema;
492
+
493
+ export type CandidateBlock = {
494
+ scope: "step_block";
495
+ items: StepReference;
496
+ itemBinding: string;
497
+ itemType: "string" | "number" | "object";
498
+ members: readonly [string, string, ...string[]];
499
+ maxAttempts: number;
500
+ accept: AssertionExpression;
501
+ };
502
+ const candidateBlockSchema: z.ZodType<CandidateBlock> = z
503
+ .object({
504
+ scope: z.literal("step_block"),
505
+ items: stepReferenceSchema,
506
+ itemBinding: z.string().min(1),
507
+ itemType: z.enum(["string", "number", "object"]),
508
+ members: z
509
+ .array(z.string().min(1))
510
+ .min(2)
511
+ .max(16)
512
+ .transform((value) => value as [string, string, ...string[]]),
513
+ maxAttempts: finiteInt(1, 10),
514
+ accept: expressionSchema,
515
+ })
516
+ .strict();
517
+ export const CandidateBlockSchema = candidateBlockSchema;
518
+
519
+ export type JournalPolicy = {
520
+ kind: "side_effect_barrier";
521
+ version: 1;
522
+ key: Reference;
523
+ before: "required";
524
+ after: "required";
525
+ replay: "deny_after_started";
526
+ };
527
+ const journalPolicySchema: z.ZodType<JournalPolicy> = z
528
+ .object({
529
+ kind: z.literal("side_effect_barrier"),
530
+ version: z.literal(1),
531
+ key: referenceSchema,
532
+ before: z.literal("required"),
533
+ after: z.literal("required"),
534
+ replay: z.literal("deny_after_started"),
535
+ })
536
+ .strict();
537
+ export const JournalPolicySchema = journalPolicySchema;
538
+
539
+ export type StepBase = { id: string; result: string; timeoutMs?: number };
540
+ const stepBaseSchema = z
541
+ .object({
542
+ id: z.string().min(1),
543
+ result: z.string().min(1),
544
+ timeoutMs: finiteInt(1, 600_000).optional(),
545
+ })
546
+ .strict();
547
+ /**
548
+ * Why a guard stopped the scenario. The platform decides what each reason
549
+ * publishes; the attribution's `status` is only the scenario rollup.
550
+ *
551
+ * - `expected_absence`: the upstream answered exactly as this provider says it
552
+ * does when there is nothing to return — no weather alert today, an empty
553
+ * shelf, a transit feed outside its operating hours. Published as the
554
+ * non-incident status `expected_absence`: neither ok nor degraded, excluded
555
+ * from uptime, never an incident. Use it only for an absence the provider
556
+ * can declare in advance. Data that must be there (a product that must have
557
+ * options) is a failing assertion, not an expected absence.
558
+ * - `served_stale_cache`: the operation step was answered from the
559
+ * stale-if-error window (`served_stale_cache` on the step result) instead
560
+ * of a live read. A measured upstream verdict: published `degraded`, opens
561
+ * incidents.
562
+ */
563
+ export type GuardReasonCode = "expected_absence" | "served_stale_cache";
564
+ /**
565
+ * Every member of the union, pinned in both directions: a code missing here
566
+ * fails `satisfies Record<GuardReasonCode, true>`, a code added here without
567
+ * the union fails the excess-property check. The union itself stays a
568
+ * literal so the type-only entry points (contract, server, testing) do not
569
+ * have to re-export the runtime tuple.
570
+ */
571
+ const GUARD_REASON_CODE_SET = {
572
+ expected_absence: true,
573
+ served_stale_cache: true,
574
+ } as const satisfies Record<GuardReasonCode, true>;
575
+ /** The closed vocabulary as a non-empty tuple, for schema and lint consumers. */
576
+ export const GUARD_REASON_CODES = Object.keys(GUARD_REASON_CODE_SET) as [
577
+ GuardReasonCode,
578
+ ...GuardReasonCode[],
579
+ ];
580
+ export type GuardAttribution = {
581
+ operationId: string;
582
+ status: "degraded";
583
+ reasonCode: GuardReasonCode;
584
+ reasonKey: string;
585
+ };
586
+ export type OperationResult = {
587
+ kind: "operation_result";
588
+ status_code: number;
589
+ data: JsonValue;
590
+ request_id: string;
591
+ duration_ms: number;
592
+ /**
593
+ * Whether the monitor's operation step was answered from a stale-if-error
594
+ * cache serve — the runtime's projection of the response envelope's
595
+ * `meta.stale`.
596
+ *
597
+ * An operation that reads its upstream through `ctx.cache.getOrSet(...,
598
+ * { staleIfErrorMs })` answers an upstream outage with HTTP 200 and a
599
+ * well-formed, fully schema-valid body for the whole stale window. Every
600
+ * assertion over `status_code` and `data` therefore passes, and the probe
601
+ * rolls up `ok` while the upstream is down. This boolean is the only thing
602
+ * in the step result that separates that from a live read.
603
+ *
604
+ * Always present, so a reference to it resolves to `false` rather than
605
+ * raising `reference_unresolvable`; a response whose `meta` is malformed
606
+ * fails the step rather than projecting as fresh.
607
+ *
608
+ * Providers that serve stale-if-error should guard on it, so an outage the
609
+ * cache is absorbing stops reading as green. Attribute it
610
+ * `served_stale_cache`, not `expected_absence`: a stale serve is an upstream
611
+ * fault the platform publishes as `degraded`, while an expected absence is
612
+ * published as a non-incident status.
613
+ *
614
+ * ```ts
615
+ * {
616
+ * id: "guard-freshness",
617
+ * result: "freshness-guarded",
618
+ * kind: "guard",
619
+ * condition: {
620
+ * kind: "predicate",
621
+ * operator: "not_equals",
622
+ * actual: { ref: { namespace: "steps", binding: "case", path: ["served_stale_cache"] } },
623
+ * expected: true,
624
+ * },
625
+ * onFail: {
626
+ * attribute: [{ operationId, status: "degraded", reasonCode: "served_stale_cache", reasonKey }],
627
+ * stop: "scenario",
628
+ * },
629
+ * }
630
+ * ```
631
+ */
632
+ served_stale_cache: boolean;
633
+ candidate?: { attempts: number; selected_index: number | null };
634
+ };
635
+ export type ExtractResult<T extends JsonValue = JsonValue> = {
636
+ kind: "extract_result";
637
+ found: boolean;
638
+ value: T | null;
639
+ };
640
+ export type AssertResult = {
641
+ kind: "assert_result";
642
+ passed: boolean;
643
+ failed_clause_paths: string[];
644
+ };
645
+ export type GuardResult = { kind: "guard_result"; passed: true };
646
+
647
+ const attributionSchema = z
648
+ .object({
649
+ operationId: z.string().min(1),
650
+ status: z.literal("degraded"),
651
+ reasonCode: z.enum(GUARD_REASON_CODES),
652
+ reasonKey: z.string().min(1),
653
+ })
654
+ .strict();
655
+
656
+ export type FindFirst = {
657
+ kind: "find_first";
658
+ itemBinding: string;
659
+ predicate: ScopedAssertionExpression;
660
+ maxScan: number;
661
+ };
662
+ const findFirstSchema: z.ZodType<FindFirst> = z
663
+ .object({
664
+ kind: z.literal("find_first"),
665
+ itemBinding: z.string().min(1),
666
+ predicate: scopedExpressionSchema,
667
+ maxScan: finiteInt(1, 100),
668
+ })
669
+ .strict();
670
+ export const FindFirstSchema = findFirstSchema;
671
+
672
+ export type OperationStep = StepBase & {
673
+ kind: "operation";
674
+ operationId: string;
675
+ inputTemplate: JsonTemplate;
676
+ connection?: CredentialReference;
677
+ retry?: RetryPolicy;
678
+ candidate?: CandidatePolicy | CandidateBlock;
679
+ journal?: JournalPolicy;
680
+ };
681
+ export type ExtractStep = StepBase & {
682
+ kind: "extract";
683
+ from: StepReference;
684
+ selector: BoundedJsonPath | FindFirst;
685
+ valueType: ValueType;
686
+ required: boolean;
687
+ };
688
+ export type AssertStep = StepBase & {
689
+ kind: "assert";
690
+ coversOperations: NonEmpty<string>;
691
+ expression: AssertionExpression;
692
+ };
693
+ export type GuardStep = StepBase & {
694
+ kind: "guard";
695
+ condition: AssertionExpression;
696
+ onFail: { attribute: NonEmpty<GuardAttribution>; stop: "scenario" };
697
+ };
698
+ export type HealthStep = OperationStep | ExtractStep | AssertStep | GuardStep;
699
+
700
+ const operationStepSchema = stepBaseSchema
701
+ .extend({
702
+ kind: z.literal("operation"),
703
+ operationId: z.string().min(1),
704
+ inputTemplate: jsonTemplateSchema,
705
+ connection: credentialReferenceSchema.optional(),
706
+ retry: retryPolicySchema.optional(),
707
+ candidate: z.union([candidatePolicySchema, candidateBlockSchema]).optional(),
708
+ journal: journalPolicySchema.optional(),
709
+ })
710
+ .strict();
711
+ const extractStepSchema = stepBaseSchema
712
+ .extend({
713
+ kind: z.literal("extract"),
714
+ from: stepReferenceSchema,
715
+ selector: z.union([BoundedJsonPathSchema, findFirstSchema]),
716
+ valueType: valueTypeSchema,
717
+ required: z.boolean(),
718
+ })
719
+ .strict();
720
+ const assertStepSchema = stepBaseSchema
721
+ .extend({
722
+ kind: z.literal("assert"),
723
+ coversOperations: nonEmptyArray(z.string().min(1)),
724
+ expression: expressionSchema,
725
+ })
726
+ .strict();
727
+ const guardStepSchema = stepBaseSchema
728
+ .extend({
729
+ kind: z.literal("guard"),
730
+ condition: expressionSchema,
731
+ onFail: z
732
+ .object({ attribute: nonEmptyArray(attributionSchema), stop: z.literal("scenario") })
733
+ .strict(),
734
+ })
735
+ .strict();
736
+ export const HealthStepSchema = z.discriminatedUnion("kind", [
737
+ operationStepSchema,
738
+ extractStepSchema,
739
+ assertStepSchema,
740
+ guardStepSchema,
741
+ ]);
742
+ export const OperationStepSchema = operationStepSchema;
743
+ export const ExtractStepSchema = extractStepSchema;
744
+ export const AssertStepSchema = assertStepSchema;
745
+ export const GuardStepSchema = guardStepSchema;
746
+
747
+ export type ManualTriggerPolicy =
748
+ | { enabled: false; reasonKey: string }
749
+ | {
750
+ enabled: true;
751
+ requiresAcknowledgement: boolean;
752
+ risk: "read_only" | "writes_external_state";
753
+ minManualIntervalMs: number;
754
+ publicRationaleKey: string;
755
+ };
756
+ const manualTriggerSchema: z.ZodType<ManualTriggerPolicy> = z.union([
757
+ z.object({ enabled: z.literal(false), reasonKey: z.string().min(1) }).strict(),
758
+ z
759
+ .object({
760
+ enabled: z.literal(true),
761
+ requiresAcknowledgement: z.boolean(),
762
+ risk: z.enum(["read_only", "writes_external_state"]),
763
+ minManualIntervalMs: finiteInt(1000, 86_400_000),
764
+ publicRationaleKey: z.string().min(1),
765
+ })
766
+ .strict(),
767
+ ]);
768
+ export const ManualTriggerPolicySchema = manualTriggerSchema;
769
+
770
+ export type CredentialRefDeclaration = { alias: string; kind: "connection" };
771
+ const credentialRefDeclarationSchema = z
772
+ .object({ alias: z.string().min(1), kind: z.literal("connection") })
773
+ .strict();
774
+ export const CredentialRefDeclarationSchema = credentialRefDeclarationSchema;
775
+
776
+ export type HealthScenario = {
777
+ scenarioVersion: 2;
778
+ id: string;
779
+ display: { titleKey: string; descriptionKey?: string };
780
+ schedule: { kind: "interval"; intervalMs: number; jitterMs: number };
781
+ timeoutMs: number;
782
+ cooldownMs?: number;
783
+ manualTrigger?: ManualTriggerPolicy;
784
+ coversOperations: NonEmpty<string>;
785
+ credentialRefs: CredentialRefDeclaration[];
786
+ steps: NonEmpty<HealthStep>;
787
+ };
788
+
789
+ export const HealthScenarioSchema: z.ZodType<HealthScenario> = z
790
+ .object({
791
+ scenarioVersion: z.literal(2),
792
+ id: z.string().min(1),
793
+ display: z
794
+ .object({ titleKey: z.string().min(1), descriptionKey: z.string().min(1).optional() })
795
+ .strict(),
796
+ schedule: z
797
+ .object({
798
+ kind: z.literal("interval"),
799
+ intervalMs: finiteInt(30_000, 604_800_000),
800
+ jitterMs: finiteInt(0),
801
+ })
802
+ .strict(),
803
+ timeoutMs: finiteInt(1000, 600_000),
804
+ cooldownMs: finiteInt(0, 86_400_000).optional(),
805
+ manualTrigger: manualTriggerSchema.optional(),
806
+ coversOperations: nonEmptyArray(z.string().min(1)),
807
+ credentialRefs: z.array(credentialRefDeclarationSchema),
808
+ steps: z
809
+ .array(HealthStepSchema)
810
+ .min(1)
811
+ .max(64)
812
+ .transform((value) => value as [HealthStep, ...HealthStep[]]),
813
+ })
814
+ .strict()
815
+ .superRefine((value, ctx) => {
816
+ if (value.schedule.jitterMs > value.schedule.intervalMs)
817
+ ctx.addIssue({
818
+ code: "custom",
819
+ path: ["schedule", "jitterMs"],
820
+ message: "jitterMs must not exceed intervalMs",
821
+ });
822
+ if (value.timeoutMs > value.schedule.intervalMs)
823
+ ctx.addIssue({
824
+ code: "custom",
825
+ path: ["timeoutMs"],
826
+ message: "timeoutMs must not exceed intervalMs",
827
+ });
828
+ const ids = new Set<string>();
829
+ const bindings = new Set<string>();
830
+ for (const [index, step] of value.steps.entries()) {
831
+ if (ids.has(step.id))
832
+ ctx.addIssue({
833
+ code: "custom",
834
+ path: ["steps", index, "id"],
835
+ message: `duplicate step ${step.id}`,
836
+ });
837
+ ids.add(step.id);
838
+ if (bindings.has(step.result))
839
+ ctx.addIssue({
840
+ code: "custom",
841
+ path: ["steps", index, "result"],
842
+ message: `duplicate result binding ${step.result}`,
843
+ });
844
+ bindings.add(step.result);
845
+ if (step.timeoutMs !== undefined && step.timeoutMs > value.timeoutMs)
846
+ ctx.addIssue({
847
+ code: "custom",
848
+ path: ["steps", index, "timeoutMs"],
849
+ message: "step timeout must not exceed the scenario timeout",
850
+ });
851
+ if (
852
+ step.kind === "operation" &&
853
+ step.retry?.retryOn.includes("timeout") &&
854
+ step.retry.attemptTimeoutMs === undefined
855
+ )
856
+ ctx.addIssue({
857
+ code: "custom",
858
+ path: ["steps", index, "retry", "attemptTimeoutMs"],
859
+ message: "timeout retry requires attemptTimeoutMs",
860
+ });
861
+
862
+ const expression =
863
+ step.kind === "assert"
864
+ ? step.expression
865
+ : step.kind === "guard"
866
+ ? step.condition
867
+ : step.kind === "operation" && step.candidate
868
+ ? step.candidate.accept
869
+ : undefined;
870
+ if (expression) walkExpression(expression, ctx, ["steps", index], 0, { count: 0 }, true);
871
+ if (step.kind === "extract" && "kind" in step.selector && step.selector.kind === "find_first")
872
+ walkExpression(
873
+ step.selector.predicate,
874
+ ctx,
875
+ ["steps", index, "selector", "predicate"],
876
+ 0,
877
+ { count: 0 },
878
+ false,
879
+ step.selector.itemBinding,
880
+ );
881
+ }
882
+ try {
883
+ const serialized = JSON.stringify(value);
884
+ if (new TextEncoder().encode(serialized).byteLength > 128 * 1024)
885
+ ctx.addIssue({ code: "custom", path: [], message: "serialized scenario exceeds 128 KiB" });
886
+ } catch {
887
+ ctx.addIssue({ code: "custom", path: [], message: "scenario must be JSON-serializable" });
888
+ }
889
+ });
890
+
891
+ function walkExpression(
892
+ expression: AssertionExpression | ScopedAssertionExpression,
893
+ ctx: z.RefinementCtx,
894
+ path: PropertyKey[],
895
+ depth: number,
896
+ leaves: { count: number },
897
+ allowQuantifier: boolean,
898
+ scopedBinding?: string,
899
+ ): void {
900
+ if (depth > 8) {
901
+ ctx.addIssue({ code: "custom", path, message: "expression depth exceeds 8" });
902
+ return;
903
+ }
904
+ if (expression.kind === "quantifier") {
905
+ if (!allowQuantifier) {
906
+ ctx.addIssue({ code: "custom", path, message: "quantifiers may not be nested" });
907
+ return;
908
+ }
909
+ if (expression.itemBinding === scopedBinding) {
910
+ ctx.addIssue({
911
+ code: "custom",
912
+ path: [...path, "itemBinding"],
913
+ message: "item binding is invalid or shadows an enclosing binding",
914
+ });
915
+ return;
916
+ }
917
+ walkExpression(
918
+ expression.clause,
919
+ ctx,
920
+ [...path, "clause"],
921
+ depth + 1,
922
+ leaves,
923
+ false,
924
+ expression.itemBinding,
925
+ );
926
+ return;
927
+ }
928
+ if (expression.kind === "all" || expression.kind === "any") {
929
+ for (const [index, clause] of expression.clauses.entries())
930
+ walkExpression(
931
+ clause,
932
+ ctx,
933
+ [...path, "clauses", index],
934
+ depth + 1,
935
+ leaves,
936
+ allowQuantifier,
937
+ scopedBinding,
938
+ );
939
+ return;
940
+ }
941
+ if (expression.kind === "not") {
942
+ walkExpression(
943
+ expression.clause,
944
+ ctx,
945
+ [...path, "clause"],
946
+ depth + 1,
947
+ leaves,
948
+ allowQuantifier,
949
+ scopedBinding,
950
+ );
951
+ return;
952
+ }
953
+ leaves.count += 1;
954
+ if (leaves.count > 64)
955
+ ctx.addIssue({ code: "custom", path, message: "expression contains more than 64 leaves" });
956
+ }
957
+
958
+ export function defineHealthScenario(input: unknown): HealthScenario {
959
+ return HealthScenarioSchema.parse(input);
960
+ }