@pikku/core 0.12.84 → 0.12.88

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 (577) hide show
  1. package/CHANGELOG.md +503 -0
  2. package/dist/bootstrap-compat/root.d.ts +20 -0
  3. package/dist/classification/column-form.d.ts +32 -0
  4. package/dist/classification/column-form.js +42 -0
  5. package/dist/classification/data-classification.d.ts +64 -0
  6. package/dist/classification/index.d.ts +13 -0
  7. package/dist/classification/index.js +2 -0
  8. package/dist/classification/secret-value.d.ts +56 -0
  9. package/dist/classification/secret-value.js +46 -0
  10. package/dist/crypto-utils.d.ts +1 -1
  11. package/dist/dev/hot-reload.d.ts +1 -1
  12. package/dist/dev/hot-reload.js +1 -1
  13. package/dist/ecosystem/agent-scorer.d.ts +1 -1
  14. package/dist/ecosystem/agent.d.ts +4 -1
  15. package/dist/ecosystem/channel/local.d.ts +2 -0
  16. package/dist/ecosystem/channel/local.js +2 -0
  17. package/dist/ecosystem/channel/serverless.d.ts +9 -0
  18. package/dist/ecosystem/channel/serverless.js +1 -0
  19. package/dist/ecosystem/channel.d.ts +3 -0
  20. package/dist/ecosystem/channel.js +1 -0
  21. package/dist/ecosystem/cli.d.ts +1 -1
  22. package/dist/ecosystem/cli.js +1 -1
  23. package/dist/ecosystem/credential.d.ts +1 -0
  24. package/dist/ecosystem/crypto-utils.d.ts +8 -0
  25. package/dist/ecosystem/crypto-utils.js +1 -0
  26. package/dist/ecosystem/dev.d.ts +1 -0
  27. package/dist/ecosystem/dev.js +1 -0
  28. package/{src/ecosystem/testing.ts → dist/ecosystem/errors.d.ts} +3 -3
  29. package/dist/ecosystem/errors.js +2 -0
  30. package/dist/ecosystem/function.d.ts +1 -1
  31. package/dist/ecosystem/function.js +1 -1
  32. package/dist/ecosystem/http.d.ts +3 -1
  33. package/dist/ecosystem/http.js +3 -1
  34. package/dist/ecosystem/mcp.d.ts +1 -1
  35. package/dist/ecosystem/mcp.js +1 -1
  36. package/dist/ecosystem/middleware.d.ts +2 -1
  37. package/dist/ecosystem/middleware.js +2 -1
  38. package/dist/ecosystem/persona.d.ts +4 -2
  39. package/dist/ecosystem/persona.js +2 -1
  40. package/dist/ecosystem/queue.d.ts +4 -2
  41. package/dist/ecosystem/queue.js +3 -1
  42. package/dist/ecosystem/role.d.ts +1 -0
  43. package/dist/ecosystem/rpc.d.ts +2 -0
  44. package/dist/ecosystem/rpc.js +1 -0
  45. package/dist/ecosystem/scenario.d.ts +8 -2
  46. package/dist/ecosystem/scenario.js +5 -1
  47. package/dist/ecosystem/scheduler.d.ts +2 -1
  48. package/dist/ecosystem/scheduler.js +2 -1
  49. package/dist/ecosystem/schema.d.ts +2 -1
  50. package/dist/ecosystem/schema.js +1 -1
  51. package/dist/ecosystem/scope.d.ts +2 -0
  52. package/dist/ecosystem/scope.js +1 -0
  53. package/dist/ecosystem/secret.d.ts +2 -0
  54. package/dist/ecosystem/secret.js +1 -0
  55. package/dist/ecosystem/services/local-content.d.ts +2 -1
  56. package/dist/ecosystem/services/local-content.js +1 -1
  57. package/dist/ecosystem/services/local-meta.d.ts +1 -0
  58. package/dist/ecosystem/services/local-meta.js +1 -0
  59. package/dist/ecosystem/services.d.ts +11 -3
  60. package/dist/ecosystem/services.js +7 -1
  61. package/dist/ecosystem/trigger.d.ts +1 -0
  62. package/dist/ecosystem/trigger.js +1 -1
  63. package/dist/ecosystem/types.d.ts +6 -3
  64. package/dist/ecosystem/types.js +3 -2
  65. package/dist/ecosystem/variable.d.ts +1 -0
  66. package/dist/ecosystem/virtual-user.d.ts +3 -0
  67. package/dist/ecosystem/virtual-user.js +3 -0
  68. package/dist/ecosystem/workflow.d.ts +2 -0
  69. package/dist/ecosystem/workflow.js +2 -0
  70. package/dist/errors/index.d.ts +8 -0
  71. package/dist/errors/index.js +1 -0
  72. package/dist/errors/serialized-error.d.ts +7 -0
  73. package/dist/function/function-meta.types.d.ts +139 -0
  74. package/dist/function/function-runner.d.ts +3 -2
  75. package/dist/function/function-runner.js +31 -11
  76. package/dist/function/functions.types.d.ts +10 -2
  77. package/dist/function/index.d.ts +8 -2
  78. package/dist/function/index.js +4 -1
  79. package/dist/function/pikku-request.d.ts +8 -0
  80. package/dist/function/pikku-request.js +15 -0
  81. package/dist/middleware/auth-apikey.d.ts +2 -10
  82. package/dist/middleware/auth-apikey.js +1 -1
  83. package/dist/middleware/auth-bearer.d.ts +2 -10
  84. package/dist/middleware/auth-bearer.js +1 -1
  85. package/dist/middleware/auth-cookie.d.ts +2 -10
  86. package/dist/middleware/auth-cookie.js +1 -1
  87. package/dist/middleware/cors.d.ts +5 -11
  88. package/dist/middleware/cors.js +13 -6
  89. package/dist/middleware/index.d.ts +3 -0
  90. package/dist/middleware/index.js +1 -0
  91. package/dist/middleware/middleware-factories.d.ts +9 -0
  92. package/dist/middleware/middleware-factories.js +19 -0
  93. package/dist/middleware/middleware.types.d.ts +27 -0
  94. package/dist/middleware/middleware.types.js +1 -0
  95. package/dist/middleware/remote-auth.d.ts +2 -2
  96. package/dist/middleware/remote-auth.js +1 -1
  97. package/dist/middleware/telemetry.d.ts +4 -20
  98. package/dist/middleware/telemetry.js +1 -1
  99. package/dist/middleware-runner.d.ts +2 -1
  100. package/dist/pikku-state.d.ts +2 -1
  101. package/dist/services/audit-service.d.ts +1 -1
  102. package/dist/services/credential-wire-service.js +1 -1
  103. package/dist/services/email-service.d.ts +1 -1
  104. package/dist/services/file-scenario-run-store.d.ts +58 -0
  105. package/dist/services/file-scenario-run-store.js +214 -0
  106. package/dist/services/in-memory-workflow-service.d.ts +1 -1
  107. package/dist/services/index.d.ts +5 -1
  108. package/dist/services/index.js +3 -0
  109. package/dist/services/local-secrets.d.ts +1 -1
  110. package/dist/services/local-secrets.js +1 -1
  111. package/dist/services/logger.d.ts +7 -7
  112. package/dist/services/meta-service.d.ts +2 -1
  113. package/dist/services/scoped-secret-service.d.ts +1 -1
  114. package/dist/services/secret-service.d.ts +1 -1
  115. package/dist/services/typed-secret-service.d.ts +16 -2
  116. package/dist/services/typed-secret-service.js +5 -0
  117. package/dist/services/webhook-service.d.ts +1 -1
  118. package/dist/services/workflow-service.d.ts +2 -1
  119. package/dist/testing/index.d.ts +1 -0
  120. package/dist/testing/index.js +1 -0
  121. package/dist/types/core.types.d.ts +30 -180
  122. package/dist/types/core.types.js +1 -19
  123. package/dist/types/index.d.ts +2 -0
  124. package/dist/types/index.js +1 -0
  125. package/dist/types/state.types.d.ts +3 -1
  126. package/dist/utils.d.ts +13 -0
  127. package/dist/utils.js +2 -0
  128. package/dist/wirings/addon/addon-runner.d.ts +17 -0
  129. package/dist/wirings/addon/addon-runner.js +150 -0
  130. package/dist/wirings/addon/index.d.ts +6 -0
  131. package/dist/wirings/addon/index.js +3 -0
  132. package/dist/wirings/addon/remote-addon-auth.d.ts +16 -0
  133. package/dist/wirings/addon/remote-addon-auth.js +39 -0
  134. package/dist/wirings/addon/wire-addon.d.ts +80 -0
  135. package/dist/wirings/addon/wire-addon.js +120 -0
  136. package/dist/wirings/addon/wire-remote-addon.d.ts +22 -0
  137. package/dist/wirings/addon/wire-remote-addon.js +11 -0
  138. package/dist/wirings/agent/agent-memory.d.ts +11 -0
  139. package/dist/wirings/agent/agent-memory.js +17 -2
  140. package/dist/wirings/agent/agent-prepare.d.ts +3 -3
  141. package/dist/wirings/agent/agent-prepare.js +1 -1
  142. package/dist/wirings/agent/agent-runner.js +2 -3
  143. package/dist/wirings/agent/agent-stream.js +117 -93
  144. package/dist/wirings/agent/agent-utils.d.ts +13 -0
  145. package/dist/wirings/agent/agent-utils.js +16 -0
  146. package/dist/wirings/agent/agent.types.d.ts +12 -10
  147. package/dist/wirings/agent/index.d.ts +1 -1
  148. package/dist/wirings/agent/voice-input.js +1 -1
  149. package/dist/wirings/agent/voice-output.js +1 -1
  150. package/dist/wirings/agent-scorer/agent-scorer-judge.d.ts +13 -0
  151. package/dist/wirings/agent-scorer/agent-scorer-judge.js +52 -0
  152. package/dist/wirings/agent-scorer/agent-scorer.d.ts +7 -1
  153. package/dist/wirings/agent-scorer/agent-scorer.js +1 -0
  154. package/dist/wirings/agent-scorer/agent-scorer.types.d.ts +20 -0
  155. package/dist/wirings/agent-scorer/index.d.ts +1 -1
  156. package/dist/wirings/channel/channel-common.d.ts +2 -1
  157. package/dist/wirings/channel/channel-middleware-runner.d.ts +2 -1
  158. package/dist/wirings/channel/channel.types.d.ts +1 -1
  159. package/dist/wirings/channel/serverless/index.d.ts +1 -0
  160. package/dist/wirings/cli/channel/index.d.ts +1 -1
  161. package/dist/wirings/cli/cli-runner.d.ts +2 -1
  162. package/dist/wirings/cli/cli-runner.js +4 -1
  163. package/dist/wirings/cli/cli.types.d.ts +21 -2
  164. package/dist/wirings/cli/command-parser.js +157 -23
  165. package/dist/wirings/gateway/gateway.types.d.ts +2 -1
  166. package/dist/wirings/http/http-runner.d.ts +1 -1
  167. package/dist/wirings/http/http-runner.js +1 -1
  168. package/dist/wirings/http/http.types.d.ts +2 -2
  169. package/dist/wirings/http/index.d.ts +1 -0
  170. package/dist/wirings/http/index.js +1 -0
  171. package/dist/wirings/http/pikku-fetch-http-request.js +1 -1
  172. package/dist/wirings/http/pikku-fetch-http-response.js +2 -2
  173. package/dist/wirings/mcp/mcp.types.d.ts +1 -1
  174. package/dist/wirings/persona/index.d.ts +1 -1
  175. package/dist/wirings/persona/index.js +1 -1
  176. package/dist/wirings/persona/persona.types.d.ts +14 -0
  177. package/dist/wirings/queue/queue.types.d.ts +1 -1
  178. package/dist/wirings/queue/signed-queue-service.d.ts +1 -1
  179. package/dist/wirings/rpc/index.d.ts +0 -6
  180. package/dist/wirings/rpc/index.js +0 -3
  181. package/dist/wirings/rpc/remote-addon-auth.d.ts +1 -1
  182. package/dist/wirings/rpc/remote-addon-auth.js +1 -1
  183. package/dist/wirings/rpc/rpc-runner.js +2 -2
  184. package/dist/wirings/rpc/wire-addon.d.ts +1 -1
  185. package/dist/wirings/scheduler/scheduler.types.d.ts +2 -1
  186. package/dist/wirings/scope/index.d.ts +1 -0
  187. package/dist/wirings/scope/index.js +1 -0
  188. package/dist/wirings/secret/secret.types.d.ts +10 -0
  189. package/dist/wirings/secret/validate-secret-definitions.js +2 -0
  190. package/dist/wirings/variable/validate-variable-definitions.js +2 -0
  191. package/dist/wirings/variable/variable.types.d.ts +15 -0
  192. package/dist/wirings/virtual-user/index.d.ts +1 -1
  193. package/dist/wirings/virtual-user/index.js +1 -1
  194. package/dist/wirings/virtual-user/prepare-virtual-user-run.d.ts +1 -1
  195. package/dist/wirings/virtual-user/virtual-user-derive.d.ts +1 -1
  196. package/dist/wirings/workflow/graph/graph-node.d.ts +9 -2
  197. package/dist/wirings/workflow/graph/graph-node.js +2 -0
  198. package/dist/wirings/workflow/graph/graph-runner.d.ts +1 -0
  199. package/dist/wirings/workflow/graph/graph-runner.js +283 -31
  200. package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +16 -1
  201. package/dist/wirings/workflow/index.d.ts +2 -0
  202. package/dist/wirings/workflow/index.js +1 -0
  203. package/dist/wirings/workflow/pikku-scenario-service.d.ts +15 -5
  204. package/dist/wirings/workflow/pikku-scenario-service.js +44 -16
  205. package/dist/wirings/workflow/pikku-workflow-service.d.ts +22 -7
  206. package/dist/wirings/workflow/pikku-workflow-service.js +28 -29
  207. package/dist/wirings/workflow/run-timeline.d.ts +1 -1
  208. package/dist/wirings/workflow/scenario-run.types.d.ts +171 -0
  209. package/dist/wirings/workflow/scenario-run.types.js +1 -0
  210. package/dist/wirings/workflow/scenario-step-guards.d.ts +1 -2
  211. package/dist/wirings/workflow/scenario-step-guards.js +0 -8
  212. package/dist/wirings/workflow/scenario-step.types.d.ts +27 -12
  213. package/dist/wirings/workflow/workflow-approval.js +2 -1
  214. package/dist/wirings/workflow/workflow-run-engine.types.d.ts +2 -1
  215. package/dist/wirings/workflow/workflow-step-claim.d.ts +16 -0
  216. package/dist/wirings/workflow/workflow-step-claim.js +27 -0
  217. package/dist/wirings/workflow/workflow.types.d.ts +2 -1
  218. package/knowledge/decisions/index.md +2 -0
  219. package/knowledge/decisions/internals/a-scenario-step-template-is-offered-unfilled.md +1 -1
  220. package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +1 -1
  221. package/knowledge/decisions/internals/a-virtual-user-run-is-not-a-workflow-and-not-a-queued-job.md +2 -2
  222. package/knowledge/decisions/internals/a-wall-clock-threshold-is-a-load-test-in-disguise.md +6 -6
  223. package/knowledge/decisions/internals/a-workflow-wire-is-built-from-the-run-not-from-the-rpc-service.md +1 -1
  224. package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +1 -1
  225. package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +1 -1
  226. package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +1 -1
  227. package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +1 -1
  228. package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +1 -1
  229. package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +1 -1
  230. package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +1 -1
  231. package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +1 -1
  232. package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +1 -1
  233. package/knowledge/decisions/internals/core-column-form-is-an-axis-of-its-own.md +4 -4
  234. package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +1 -1
  235. package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +3 -3
  236. package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +2 -2
  237. package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +2 -2
  238. package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +1 -1
  239. package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +1 -1
  240. package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +3 -3
  241. package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +1 -1
  242. package/knowledge/decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md +4 -4
  243. package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +1 -1
  244. package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +1 -1
  245. package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +1 -1
  246. package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +1 -1
  247. package/knowledge/decisions/internals/index.md +4 -2
  248. package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +1 -1
  249. package/knowledge/decisions/internals/one-project-shape-check-two-validators.md +1 -1
  250. package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +1 -1
  251. package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +1 -1
  252. package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +1 -1
  253. package/knowledge/decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md +2 -2
  254. package/knowledge/decisions/internals/scenarios-live-in-files-named-for-them.md +5 -5
  255. package/knowledge/decisions/internals/the-actor-prompt-says-json-because-of-json-object-mode.md +1 -1
  256. package/knowledge/decisions/internals/the-api-report-pins-members-not-just-names.md +1 -1
  257. package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md +43 -19
  258. package/knowledge/decisions/internals/the-persona-runtime-is-exported-from-the-persona-entry-point.md +1 -1
  259. package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +1 -1
  260. package/knowledge/decisions/internals/validate-runs-checks-by-precondition.md +3 -3
  261. package/knowledge/decisions/internals/virtual-user-step-order-comes-from-insertion-order.md +1 -1
  262. package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +1 -1
  263. package/knowledge/decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md +1 -1
  264. package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +1 -1
  265. package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +1 -1
  266. package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +1 -1
  267. package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +1 -1
  268. package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +1 -1
  269. package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +1 -1
  270. package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +9 -5
  271. package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +1 -1
  272. package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +2 -2
  273. package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +1 -1
  274. package/knowledge/decisions/security/a-function-never-receives-the-secret-service.md +1 -1
  275. package/knowledge/decisions/security/a-scaffold-flag-says-a-surface-exists-not-who-may-call-it.md +47 -0
  276. package/knowledge/decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md +1 -1
  277. package/knowledge/decisions/security/a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md +2 -3
  278. package/knowledge/decisions/security/actor-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +1 -1
  279. package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +1 -1
  280. package/knowledge/decisions/security/agent-gate-requires-a-session-only-when-auth-is-true.md +1 -1
  281. package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +3 -3
  282. package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +4 -3
  283. package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +1 -1
  284. package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +2 -2
  285. package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +1 -1
  286. package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +2 -2
  287. package/knowledge/decisions/security/index.md +4 -1
  288. package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +1 -1
  289. package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +3 -3
  290. package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +1 -1
  291. package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +8 -2
  292. package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +1 -1
  293. package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +2 -2
  294. package/knowledge/index.md +3 -1
  295. package/knowledge/questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md +1 -1
  296. package/knowledge/questions/index.md +2 -0
  297. package/package.json +14 -13
  298. package/run-tests.sh +0 -0
  299. package/scripts/generate-api-report.d.mts +1 -1
  300. package/scripts/generate-api-report.mjs +67 -60
  301. package/scripts/generate-api-report.mts +11 -45
  302. package/src/api-report.test.ts +70 -1
  303. package/src/app-alias-surface.test.ts +179 -0
  304. package/src/app-leaf-surface.test.ts +217 -0
  305. package/src/bootstrap-compat/root.ts +20 -0
  306. package/src/{column-form.test.ts → classification/column-form.test.ts} +2 -2
  307. package/src/{data-classification.ts → classification/data-classification.ts} +1 -5
  308. package/src/classification/index.ts +38 -0
  309. package/src/{secret-value.test.ts → classification/secret-value.test.ts} +2 -2
  310. package/src/{secret-value.ts → classification/secret-value.ts} +1 -6
  311. package/src/crypto-utils.ts +1 -1
  312. package/src/dev/hot-reload.ts +1 -1
  313. package/src/dev/reload-meta.test.ts +1 -1
  314. package/src/errors/index.ts +9 -0
  315. package/src/errors/serialized-error.ts +9 -0
  316. package/src/factory-functions.test.ts +4 -2
  317. package/src/function/function-meta.types.ts +151 -0
  318. package/src/function/function-runner.test.ts +4 -2
  319. package/src/function/function-runner.ts +47 -14
  320. package/src/function/functions.types.ts +11 -7
  321. package/src/function/index.ts +24 -5
  322. package/src/function/list.types.ts +1 -3
  323. package/src/middleware/auth-apikey.ts +4 -2
  324. package/src/middleware/auth-bearer.test.ts +1 -1
  325. package/src/middleware/auth-bearer.ts +4 -2
  326. package/src/middleware/auth-cookie.ts +4 -1
  327. package/src/middleware/cors.test.ts +126 -5
  328. package/src/middleware/cors.ts +19 -8
  329. package/src/middleware/index.ts +16 -0
  330. package/src/middleware/middleware-factories.ts +62 -0
  331. package/src/middleware/middleware.types.ts +61 -0
  332. package/src/middleware/remote-auth.test.ts +1 -1
  333. package/src/middleware/remote-auth.ts +1 -1
  334. package/src/middleware/telemetry.ts +4 -2
  335. package/src/middleware-runner.test.ts +2 -3
  336. package/src/middleware-runner.ts +2 -2
  337. package/src/no-root-barrel.test.ts +114 -0
  338. package/src/permissions.ts +2 -4
  339. package/src/pikku-state.ts +3 -1
  340. package/src/public-surface.json +56 -241
  341. package/src/public-surface.json.README +3 -3
  342. package/src/public-surface.test.ts +5 -5
  343. package/src/remote.test.ts +1 -1
  344. package/src/removed-legacy-exports.test.ts +5 -1
  345. package/src/services/audit-service.ts +1 -1
  346. package/src/services/credential-wire-service.ts +1 -1
  347. package/src/services/email-service.ts +2 -4
  348. package/src/services/file-scenario-run-store.test.ts +349 -0
  349. package/src/services/file-scenario-run-store.ts +282 -0
  350. package/src/services/in-memory-workflow-service.ts +1 -1
  351. package/src/services/index.ts +13 -1
  352. package/src/services/local-content-request-handler.ts +1 -2
  353. package/src/services/local-secrets.ts +1 -1
  354. package/src/services/logger.ts +7 -7
  355. package/src/services/meta-service.ts +2 -2
  356. package/src/services/queue-webhook-service.test.ts +1 -1
  357. package/src/services/scoped-secret-service.ts +1 -1
  358. package/src/services/secret-service.ts +1 -1
  359. package/src/services/typed-secret-service.test.ts +52 -0
  360. package/src/services/typed-secret-service.ts +26 -2
  361. package/src/services/webhook-service.ts +1 -1
  362. package/src/services/workflow-service.ts +2 -1
  363. package/src/template-alias-surface.test.ts +240 -0
  364. package/src/testing/index.ts +1 -0
  365. package/src/types/core.types.ts +33 -285
  366. package/src/types/index.ts +25 -0
  367. package/src/types/state.types.ts +6 -5
  368. package/src/types/typed-credentials.test.ts +72 -0
  369. package/src/utils.ts +34 -0
  370. package/src/wirings/{rpc → addon}/addon-scopes.test.ts +1 -1
  371. package/src/wirings/addon/index.ts +12 -0
  372. package/src/wirings/{rpc → addon}/remote-addon-auth.ts +4 -1
  373. package/src/wirings/{rpc → addon}/wire-addon.ts +37 -2
  374. package/src/wirings/agent/agent-memory.test.ts +73 -0
  375. package/src/wirings/agent/agent-memory.ts +16 -2
  376. package/src/wirings/agent/agent-middleware.types.test.ts +41 -0
  377. package/src/wirings/agent/agent-prepare.ts +8 -5
  378. package/src/wirings/agent/agent-runner.ts +2 -3
  379. package/src/wirings/agent/agent-stream-delegate.test.ts +381 -0
  380. package/src/wirings/agent/agent-stream.ts +160 -81
  381. package/src/wirings/agent/agent-utils.ts +19 -0
  382. package/src/wirings/agent/agent.types.ts +12 -11
  383. package/src/wirings/agent/index.ts +1 -0
  384. package/src/wirings/agent/voice-input.ts +1 -1
  385. package/src/wirings/agent/voice-output.test.ts +2 -4
  386. package/src/wirings/agent/voice-output.ts +1 -1
  387. package/src/wirings/agent-scorer/agent-scorer-judge.test.ts +145 -0
  388. package/src/wirings/agent-scorer/agent-scorer-judge.ts +60 -0
  389. package/src/wirings/agent-scorer/agent-scorer.ts +8 -0
  390. package/src/wirings/agent-scorer/agent-scorer.types.ts +21 -0
  391. package/src/wirings/agent-scorer/index.ts +1 -0
  392. package/src/wirings/channel/channel-common.ts +4 -2
  393. package/src/wirings/channel/channel-handler.ts +2 -5
  394. package/src/wirings/channel/channel-middleware-runner.ts +1 -1
  395. package/src/wirings/channel/channel-rpc.types.ts +1 -5
  396. package/src/wirings/channel/channel.types.ts +1 -2
  397. package/src/wirings/channel/local/local-channel-runner.test.ts +1 -2
  398. package/src/wirings/channel/serverless/index.ts +1 -0
  399. package/src/wirings/cli/channel/cli-raw-channel-runner.ts +2 -2
  400. package/src/wirings/cli/channel/index.ts +1 -3
  401. package/src/wirings/cli/cli-runner.test.ts +1 -1
  402. package/src/wirings/cli/cli-runner.ts +11 -7
  403. package/src/wirings/cli/cli.types.ts +24 -3
  404. package/src/wirings/cli/command-parser.test.ts +388 -1
  405. package/src/wirings/cli/command-parser.ts +189 -29
  406. package/src/wirings/gateway/gateway-runner.test.ts +1 -2
  407. package/src/wirings/gateway/gateway-runner.ts +3 -6
  408. package/src/wirings/gateway/gateway.types.ts +5 -4
  409. package/src/wirings/http/http-routes.test.ts +1 -2
  410. package/src/wirings/http/http-runner-addon-ref.test.ts +238 -0
  411. package/src/wirings/http/http-runner.test.ts +3 -8
  412. package/src/wirings/http/http-runner.ts +9 -3
  413. package/src/wirings/http/http.types.ts +3 -12
  414. package/src/wirings/http/index.ts +1 -0
  415. package/src/wirings/http/pikku-fetch-http-request.ts +1 -1
  416. package/src/wirings/http/pikku-fetch-http-response.ts +3 -2
  417. package/src/wirings/mcp/mcp-runner.test.ts +1 -1
  418. package/src/wirings/mcp/mcp.types.ts +1 -2
  419. package/src/wirings/persona/index.ts +1 -4
  420. package/src/wirings/persona/persona.types.ts +14 -0
  421. package/src/wirings/queue/queue-identity.test.ts +1 -1
  422. package/src/wirings/queue/queue.types.ts +2 -6
  423. package/src/wirings/queue/signed-queue-service.ts +1 -1
  424. package/src/wirings/rpc/index.ts +0 -12
  425. package/src/wirings/rpc/rpc-runner.test.ts +4 -4
  426. package/src/wirings/rpc/rpc-runner.ts +3 -3
  427. package/src/wirings/scheduler/scheduler.types.ts +2 -5
  428. package/src/wirings/scope/index.ts +1 -0
  429. package/src/wirings/secret/secret.types.ts +10 -0
  430. package/src/wirings/secret/validate-secret-definitions.test.ts +23 -0
  431. package/src/wirings/secret/validate-secret-definitions.ts +2 -0
  432. package/src/wirings/variable/validate-variable-definitions.test.ts +24 -0
  433. package/src/wirings/variable/validate-variable-definitions.ts +2 -0
  434. package/src/wirings/variable/variable.types.ts +15 -0
  435. package/src/wirings/virtual-user/index.ts +1 -4
  436. package/src/wirings/virtual-user/prepare-virtual-user-run.ts +1 -1
  437. package/src/wirings/virtual-user/virtual-user-derive.test.ts +1 -1
  438. package/src/wirings/virtual-user/virtual-user-derive.ts +1 -1
  439. package/src/wirings/virtual-user/virtual-user.types.ts +1 -5
  440. package/src/wirings/workflow/graph/graph-foreach-queued.test.ts +569 -0
  441. package/src/wirings/workflow/graph/graph-foreach.test.ts +626 -0
  442. package/src/wirings/workflow/graph/graph-node.ts +16 -1
  443. package/src/wirings/workflow/graph/graph-runner.ts +387 -61
  444. package/src/wirings/workflow/graph/workflow-graph.types.ts +28 -3
  445. package/src/wirings/workflow/index.ts +8 -0
  446. package/src/wirings/workflow/pikku-scenario-service.ts +83 -20
  447. package/src/wirings/workflow/pikku-workflow-service.ts +37 -35
  448. package/src/wirings/workflow/run-timeline.ts +1 -1
  449. package/src/wirings/workflow/scenario-expectations.test.ts +28 -13
  450. package/src/wirings/workflow/scenario-run.types.ts +186 -0
  451. package/src/wirings/workflow/scenario-step-guards.ts +1 -14
  452. package/src/wirings/workflow/scenario-step.test.ts +32 -7
  453. package/src/wirings/workflow/scenario-step.types.ts +27 -12
  454. package/src/wirings/workflow/workflow-approval-policy.test.ts +117 -47
  455. package/src/wirings/workflow/workflow-approval.ts +2 -1
  456. package/src/wirings/workflow/workflow-run-engine.types.ts +2 -1
  457. package/src/wirings/workflow/workflow-step-claim.ts +46 -0
  458. package/src/wirings/workflow/workflow.types.ts +4 -12
  459. package/src/wirings-stay-decoupled.test.ts +6 -3
  460. package/tsconfig.tsbuildinfo +1 -1
  461. package/tsconfig.type-tests.json +4 -2
  462. package/dist/ecosystem/ai-agent.d.ts +0 -18
  463. package/dist/ecosystem/ai-agent.js +0 -6
  464. package/dist/ecosystem/ai-scorer.d.ts +0 -12
  465. package/dist/ecosystem/ai-scorer.js +0 -5
  466. package/dist/services/ai-agent-runner-service.d.ts +0 -220
  467. package/dist/services/ai-run-state-service.d.ts +0 -29
  468. package/dist/services/ai-storage-service.d.ts +0 -18
  469. package/dist/services/in-memory-ai-run-state-service.d.ts +0 -19
  470. package/dist/services/in-memory-ai-run-state-service.js +0 -54
  471. package/dist/testing/service-tests/ai-storage-service-tests.d.ts +0 -3
  472. package/dist/testing/service-tests/ai-storage-service-tests.js +0 -302
  473. package/dist/wirings/ai-agent/agent-rpc.d.ts +0 -15
  474. package/dist/wirings/ai-agent/agent-rpc.js +0 -53
  475. package/dist/wirings/ai-agent/ai-agent-agui.d.ts +0 -79
  476. package/dist/wirings/ai-agent/ai-agent-agui.js +0 -327
  477. package/dist/wirings/ai-agent/ai-agent-finalize.d.ts +0 -58
  478. package/dist/wirings/ai-agent/ai-agent-finalize.js +0 -138
  479. package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +0 -35
  480. package/dist/wirings/ai-agent/ai-agent-helpers.js +0 -47
  481. package/dist/wirings/ai-agent/ai-agent-interrupt.d.ts +0 -153
  482. package/dist/wirings/ai-agent/ai-agent-interrupt.js +0 -257
  483. package/dist/wirings/ai-agent/ai-agent-memory.d.ts +0 -42
  484. package/dist/wirings/ai-agent/ai-agent-memory.js +0 -333
  485. package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +0 -16
  486. package/dist/wirings/ai-agent/ai-agent-model-config.js +0 -51
  487. package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +0 -117
  488. package/dist/wirings/ai-agent/ai-agent-prepare.js +0 -728
  489. package/dist/wirings/ai-agent/ai-agent-registry.d.ts +0 -16
  490. package/dist/wirings/ai-agent/ai-agent-registry.js +0 -51
  491. package/dist/wirings/ai-agent/ai-agent-runner.d.ts +0 -7
  492. package/dist/wirings/ai-agent/ai-agent-runner.js +0 -580
  493. package/dist/wirings/ai-agent/ai-agent-stream.d.ts +0 -41
  494. package/dist/wirings/ai-agent/ai-agent-stream.js +0 -1029
  495. package/dist/wirings/ai-agent/ai-agent-turn.d.ts +0 -57
  496. package/dist/wirings/ai-agent/ai-agent-turn.js +0 -82
  497. package/dist/wirings/ai-agent/ai-agent-utils.d.ts +0 -1
  498. package/dist/wirings/ai-agent/ai-agent-utils.js +0 -1
  499. package/dist/wirings/ai-agent/ai-agent.types.d.ts +0 -625
  500. package/dist/wirings/ai-agent/index.d.ts +0 -12
  501. package/dist/wirings/ai-agent/index.js +0 -10
  502. package/dist/wirings/ai-agent/voice-input.d.ts +0 -69
  503. package/dist/wirings/ai-agent/voice-input.js +0 -150
  504. package/dist/wirings/ai-agent/voice-output.d.ts +0 -85
  505. package/dist/wirings/ai-agent/voice-output.js +0 -196
  506. package/dist/wirings/ai-scorer/ai-scorer-grade.d.ts +0 -26
  507. package/dist/wirings/ai-scorer/ai-scorer-grade.js +0 -33
  508. package/dist/wirings/ai-scorer/ai-scorer-judge.d.ts +0 -17
  509. package/dist/wirings/ai-scorer/ai-scorer-judge.js +0 -92
  510. package/dist/wirings/ai-scorer/ai-scorer-live.d.ts +0 -15
  511. package/dist/wirings/ai-scorer/ai-scorer-live.js +0 -38
  512. package/dist/wirings/ai-scorer/ai-scorer-registry.d.ts +0 -18
  513. package/dist/wirings/ai-scorer/ai-scorer-registry.js +0 -46
  514. package/dist/wirings/ai-scorer/ai-scorer-sampling.d.ts +0 -8
  515. package/dist/wirings/ai-scorer/ai-scorer-sampling.js +0 -31
  516. package/dist/wirings/ai-scorer/ai-scorer-snapshots.d.ts +0 -10
  517. package/dist/wirings/ai-scorer/ai-scorer-snapshots.js +0 -40
  518. package/dist/wirings/ai-scorer/ai-scorer-worker.d.ts +0 -15
  519. package/dist/wirings/ai-scorer/ai-scorer-worker.js +0 -58
  520. package/dist/wirings/ai-scorer/ai-scorer.d.ts +0 -39
  521. package/dist/wirings/ai-scorer/ai-scorer.js +0 -40
  522. package/dist/wirings/ai-scorer/ai-scorer.types.d.ts +0 -90
  523. package/dist/wirings/ai-scorer/ai-scorer.types.js +0 -4
  524. package/dist/wirings/ai-scorer/index.d.ts +0 -6
  525. package/dist/wirings/ai-scorer/index.js +0 -5
  526. package/src/ecosystem/agent-scorer.ts +0 -24
  527. package/src/ecosystem/agent.ts +0 -42
  528. package/src/ecosystem/channel/local.ts +0 -1
  529. package/src/ecosystem/channel.ts +0 -22
  530. package/src/ecosystem/cli/channel.ts +0 -25
  531. package/src/ecosystem/cli.ts +0 -21
  532. package/src/ecosystem/credential.ts +0 -10
  533. package/src/ecosystem/dev.ts +0 -12
  534. package/src/ecosystem/function.ts +0 -28
  535. package/src/ecosystem/gateway.ts +0 -4
  536. package/src/ecosystem/hmac.ts +0 -1
  537. package/src/ecosystem/http.ts +0 -22
  538. package/src/ecosystem/mcp.ts +0 -17
  539. package/src/ecosystem/middleware.ts +0 -27
  540. package/src/ecosystem/node-host-resolver.ts +0 -1
  541. package/src/ecosystem/node.ts +0 -5
  542. package/src/ecosystem/oauth2.ts +0 -4
  543. package/src/ecosystem/persona.ts +0 -30
  544. package/src/ecosystem/queue.ts +0 -23
  545. package/src/ecosystem/remote.ts +0 -9
  546. package/src/ecosystem/role.ts +0 -13
  547. package/src/ecosystem/rpc.ts +0 -7
  548. package/src/ecosystem/safe-fetch.ts +0 -8
  549. package/src/ecosystem/scenario.ts +0 -32
  550. package/src/ecosystem/scheduler.ts +0 -5
  551. package/src/ecosystem/schema.ts +0 -1
  552. package/src/ecosystem/scope.ts +0 -14
  553. package/src/ecosystem/secret.ts +0 -15
  554. package/src/ecosystem/services/istanbul-coverage.ts +0 -1
  555. package/src/ecosystem/services/local-content-request-handler.ts +0 -16
  556. package/src/ecosystem/services/local-content.ts +0 -1
  557. package/src/ecosystem/services/v8-coverage.ts +0 -1
  558. package/src/ecosystem/services.ts +0 -82
  559. package/src/ecosystem/trigger.ts +0 -7
  560. package/src/ecosystem/types.ts +0 -34
  561. package/src/ecosystem/variable.ts +0 -14
  562. package/src/ecosystem/virtual-user.ts +0 -48
  563. package/src/ecosystem/workflow.ts +0 -68
  564. package/src/ecosystem.ts +0 -40
  565. package/src/index.ts +0 -244
  566. /package/dist/{services/ai-agent-runner-service.js → bootstrap-compat/root.js} +0 -0
  567. /package/dist/{services/ai-run-state-service.js → classification/data-classification.js} +0 -0
  568. /package/dist/{services/ai-storage-service.js → errors/serialized-error.js} +0 -0
  569. /package/dist/{wirings/ai-agent/ai-agent.types.js → function/function-meta.types.js} +0 -0
  570. /package/src/{column-form.ts → classification/column-form.ts} +0 -0
  571. /package/src/{pikku-request.test.ts → function/pikku-request.test.ts} +0 -0
  572. /package/src/{pikku-request.ts → function/pikku-request.ts} +0 -0
  573. /package/src/wirings/{rpc → addon}/addon-auth-tags.test.ts +0 -0
  574. /package/src/wirings/{rpc → addon}/addon-runner.ts +0 -0
  575. /package/src/wirings/{rpc → addon}/addon-secrets.test.ts +0 -0
  576. /package/src/wirings/{rpc → addon}/wire-addon.test.ts +0 -0
  577. /package/src/wirings/{rpc → addon}/wire-remote-addon.ts +0 -0
@@ -8,7 +8,7 @@ import { addFunction } from '../../function/function-runner.js'
8
8
  import type { ScenarioPersona } from '../../services/personas-service.js'
9
9
  import type { PikkuWire } from '../../types/core.types.js'
10
10
  import type { ScenarioSurface } from './scenario-step.types.js'
11
- import { requireActor, requireScenarioEnv } from './scenario-step-guards.js'
11
+ import { requireScenarioEnv } from './scenario-step-guards.js'
12
12
 
13
13
  const noopLogger = { error() {}, info() {}, warn() {}, debug() {} }
14
14
 
@@ -145,6 +145,7 @@ const registerStep = (
145
145
  config: {
146
146
  description?: string
147
147
  surfaces?: ScenarioSurface[]
148
+ requiresActor?: boolean
148
149
  func: (services: any, data: any, wire: PikkuWire) => Promise<unknown>
149
150
  }
150
151
  ) => {
@@ -215,7 +216,7 @@ describe('pikkuScenarioStep (scenario.given/when/then)', () => {
215
216
  let received: unknown
216
217
  registerStep('checksOut', {
217
218
  func: async (_services, _data, wire) => {
218
- received = wire.scenarioStep!.actor
219
+ received = wire.actor
219
220
  return null
220
221
  },
221
222
  })
@@ -712,16 +713,17 @@ describe('the scenario environment reaches the step wire', () => {
712
713
  })
713
714
  })
714
715
 
715
- describe('requireActor / requireScenarioEnv', () => {
716
+ describe('a step driven by a persona is given its actor', () => {
716
717
  beforeEach(() => resetPikkuState())
717
718
 
718
- test('requireActor returns the actor a step was called with', async () => {
719
+ test('the actor is on the wire, not something the body unwraps', async () => {
719
720
  const { workflowService: ws, scenarioService } = createScenarioRunner()
720
721
  const shopper = fakeActor('shopper', async () => null)
721
722
  let resolved: unknown
722
723
  registerStep('needsAnActor', {
724
+ requiresActor: true,
723
725
  func: async (_services, _data, wire) => {
724
- resolved = requireActor(wire.scenarioStep)
726
+ resolved = wire.actor
725
727
  return null
726
728
  },
727
729
  })
@@ -735,10 +737,15 @@ describe('requireActor / requireScenarioEnv', () => {
735
737
  assert.equal(resolved, shopper)
736
738
  })
737
739
 
738
- test('requireActor names the step when it was called without one', async () => {
740
+ test('one dispatched without an actor is refused before its body runs', async () => {
739
741
  const { workflowService: ws, scenarioService } = createScenarioRunner()
742
+ let bodyRan = false
740
743
  registerStep('needsAnActor', {
741
- func: async (_services, _data, wire) => requireActor(wire.scenarioStep),
744
+ requiresActor: true,
745
+ func: async () => {
746
+ bodyRan = true
747
+ return null
748
+ },
742
749
  })
743
750
 
744
751
  const runId = await setup(ws)
@@ -747,6 +754,24 @@ describe('requireActor / requireScenarioEnv', () => {
747
754
  wire.when('nobody acts', 'needsAnActor'),
748
755
  /needsAnActor.*actor/s
749
756
  )
757
+ assert.equal(bodyRan, false)
758
+ })
759
+
760
+ test('a step that declares no persona runs without one', async () => {
761
+ const { workflowService: ws, scenarioService } = createScenarioRunner()
762
+ let seen: unknown = 'unset'
763
+ registerStep('assertsSomething', {
764
+ func: async (_services, _data, wire) => {
765
+ seen = wire.actor
766
+ return null
767
+ },
768
+ })
769
+
770
+ const runId = await setup(ws)
771
+ const wire = ws.createWorkflowWire('scenarioTest', runId, {})
772
+ await wire.then('it holds', 'assertsSomething')
773
+
774
+ assert.equal(seen, undefined)
750
775
  })
751
776
 
752
777
  test('requireScenarioEnv returns the environment, or says how to declare one', async () => {
@@ -1,4 +1,4 @@
1
- import type { ScenarioPersona } from '../../services/personas-service.js'
1
+ import type { ScenarioArtifact } from './scenario-run.types.js'
2
2
 
3
3
  /**
4
4
  * Scenario steps: named, typed units of scenario behaviour.
@@ -99,7 +99,10 @@ export type ScenarioSurfaceResolution =
99
99
  * default to no retries.
100
100
  */
101
101
  export interface ScenarioStepOptions {
102
- /** The actor this step runs as. Required for steps declaring a `browser` binding. */
102
+ /**
103
+ * The actor this step runs as. Required for a step that declares `actor: true`
104
+ * or a `browser` binding; the runner refuses to dispatch one without it.
105
+ */
103
106
  actor?: unknown
104
107
  /** Overrides the step's own `description` for this call site only. */
105
108
  description?: string
@@ -122,11 +125,12 @@ export interface ScenarioEnvironment {
122
125
  /**
123
126
  * The `scenarioStep` wire, present on every scenario step invocation.
124
127
  *
125
- * `TActor` is the project's own actor type, so a step reaches only the RPCs its
126
- * actors can actually call. It defaults to the open `ScenarioPersona` for a
127
- * project that declares no registry.
128
+ * The persona a step runs as is not here: it arrives as `wire.actor`, injected
129
+ * by the runner and typed as present exactly on the bindings that declared they
130
+ * need one. Keeping it off this interface is what makes that possible a wire
131
+ * member can be required per binding, a property of one cannot.
128
132
  */
129
- export interface PikkuScenarioStepWire<TActor = ScenarioPersona> {
133
+ export interface PikkuScenarioStepWire {
130
134
  /** Registered step name (also its pikkuFuncId) */
131
135
  name: string
132
136
  /** Durable key within the run; may carry an `#ordinal` suffix when repeated */
@@ -138,12 +142,6 @@ export interface PikkuScenarioStepWire<TActor = ScenarioPersona> {
138
142
  * per witness, so its body sees this change between invocations.
139
143
  */
140
144
  surface: ScenarioSurface
141
- /**
142
- * The actor this step runs as, when one was given. Call RPCs through it
143
- * (`actor.invoke(...)`) so they run against the target environment as that
144
- * persona.
145
- */
146
- actor?: TActor
147
145
  /**
148
146
  * The environment this run targets. A step runs in the CLI process, where
149
147
  * there is no `variables` service — this is how a raw-HTTP step learns the
@@ -237,11 +235,28 @@ export interface ScenarioBrowserProvider {
237
235
  * folder — findable only by timestamp.
238
236
  */
239
237
  beginScenario?(scenario: string): void
238
+ /**
239
+ * Report how the scenario that just ran finished.
240
+ *
241
+ * Called after each scenario, and separate from `reset()` because artifacts
242
+ * that only exist once a window closes — a video — are produced by the NEXT
243
+ * scenario's reset, long after the outcome that decides whether to keep them.
244
+ */
245
+ endScenario?(outcome: 'passed' | 'failed'): void
240
246
  /**
241
247
  * Snapshot every open window for a failed scenario. `label` identifies the
242
248
  * scenario in artifact filenames. Never throws: a failure to capture must
243
249
  * not replace the failure being captured.
244
250
  */
245
251
  captureFailure?(label: string): Promise<ScenarioBrowserFailure[]>
252
+ /**
253
+ * Everything the run filed, each entry naming the scenario it belongs to.
254
+ *
255
+ * Reported by the driver rather than discovered by scanning the directory:
256
+ * only the driver knows which window produced a file and under what caption,
257
+ * and a video's final name is not settled until the run closes. Read after
258
+ * `close()`, which is the first moment the answer is complete.
259
+ */
260
+ artifacts?(): ScenarioArtifact[]
246
261
  close(): Promise<void>
247
262
  }
@@ -166,9 +166,14 @@ describe('approval policy enforcement', () => {
166
166
  })
167
167
  await runToGate(ws, runId)
168
168
 
169
- await ws.approveStep(runId, 'Release funds', { ok: true }, {
170
- userId: 'someone-else',
171
- })
169
+ await ws.approveStep(
170
+ runId,
171
+ 'Release funds',
172
+ { ok: true },
173
+ {
174
+ userId: 'someone-else',
175
+ }
176
+ )
172
177
  await ws.runWorkflowJob(runId, {})
173
178
 
174
179
  assert.equal((await ws.getRun(runId))?.status, 'completed')
@@ -188,15 +193,25 @@ describe('approval policy enforcement', () => {
188
193
  await runToGate(ws, runId)
189
194
 
190
195
  await assert.rejects(
191
- ws.approveStep(runId, 'Release funds', { ok: true }, {
192
- userId: 'initiator',
193
- }),
196
+ ws.approveStep(
197
+ runId,
198
+ 'Release funds',
199
+ { ok: true },
200
+ {
201
+ userId: 'initiator',
202
+ }
203
+ ),
194
204
  WorkflowApprovalForbiddenError
195
205
  )
196
206
 
197
- await ws.approveStep(runId, 'Release funds', { ok: true }, {
198
- userId: 'reviewer',
199
- })
207
+ await ws.approveStep(
208
+ runId,
209
+ 'Release funds',
210
+ { ok: true },
211
+ {
212
+ userId: 'reviewer',
213
+ }
214
+ )
200
215
  await ws.runWorkflowJob(runId, {})
201
216
 
202
217
  assert.equal((await ws.getRun(runId))?.status, 'completed')
@@ -216,15 +231,25 @@ describe('approval policy enforcement', () => {
216
231
  await runToGate(ws, runId)
217
232
 
218
233
  await assert.rejects(
219
- ws.approveStep(runId, 'Release funds', { ok: true }, {
220
- userId: 'attacker',
221
- }),
234
+ ws.approveStep(
235
+ runId,
236
+ 'Release funds',
237
+ { ok: true },
238
+ {
239
+ userId: 'attacker',
240
+ }
241
+ ),
222
242
  WorkflowApprovalForbiddenError
223
243
  )
224
244
 
225
- await ws.approveStep(runId, 'Release funds', { ok: true }, {
226
- userId: 'initiator',
227
- })
245
+ await ws.approveStep(
246
+ runId,
247
+ 'Release funds',
248
+ { ok: true },
249
+ {
250
+ userId: 'initiator',
251
+ }
252
+ )
228
253
  await ws.runWorkflowJob(runId, {})
229
254
 
230
255
  assert.equal((await ws.getRun(runId))?.status, 'completed')
@@ -244,17 +269,27 @@ describe('approval policy enforcement', () => {
244
269
  await runToGate(ws, runId)
245
270
 
246
271
  await assert.rejects(
247
- ws.approveStep(runId, 'Release funds', { ok: true }, {
248
- userId: 'reviewer',
249
- scopes: ['payments:read'],
250
- }),
272
+ ws.approveStep(
273
+ runId,
274
+ 'Release funds',
275
+ { ok: true },
276
+ {
277
+ userId: 'reviewer',
278
+ scopes: ['payments:read'],
279
+ }
280
+ ),
251
281
  WorkflowApprovalForbiddenError
252
282
  )
253
283
 
254
- await ws.approveStep(runId, 'Release funds', { ok: true }, {
255
- userId: 'reviewer',
256
- scopes: ['payments:approve'],
257
- })
284
+ await ws.approveStep(
285
+ runId,
286
+ 'Release funds',
287
+ { ok: true },
288
+ {
289
+ userId: 'reviewer',
290
+ scopes: ['payments:approve'],
291
+ }
292
+ )
258
293
  await ws.runWorkflowJob(runId, {})
259
294
 
260
295
  assert.equal((await ws.getRun(runId))?.status, 'completed')
@@ -280,10 +315,15 @@ describe('approval policy enforcement', () => {
280
315
  })
281
316
  await runToGate(ws, runId)
282
317
 
283
- await ws.approveStep(runId, 'Release funds', { ok: true }, {
284
- userId: 'reviewer',
285
- scopes: ['payments:approve'],
286
- })
318
+ await ws.approveStep(
319
+ runId,
320
+ 'Release funds',
321
+ { ok: true },
322
+ {
323
+ userId: 'reviewer',
324
+ scopes: ['payments:approve'],
325
+ }
326
+ )
287
327
  await ws.runWorkflowJob(runId, {})
288
328
 
289
329
  const step = await ws.getStepState(
@@ -343,9 +383,14 @@ describe('approval policy enforcement', () => {
343
383
 
344
384
  // The gate has not been reached, so no policy has been published and the
345
385
  // submission cannot be judged here — it is accepted and judged on replay.
346
- await ws.approveStep(runId, 'Release funds', { ok: true }, {
347
- userId: 'initiator',
348
- })
386
+ await ws.approveStep(
387
+ runId,
388
+ 'Release funds',
389
+ { ok: true },
390
+ {
391
+ userId: 'initiator',
392
+ }
393
+ )
349
394
 
350
395
  await runToGate(ws, runId)
351
396
 
@@ -392,10 +437,15 @@ describe('approval audit trail', () => {
392
437
  pikkuUserId: 'initiator',
393
438
  })
394
439
  await runToGate(ws, runId)
395
- await ws.approveStep(runId, 'Release funds', { ok: true }, {
396
- userId: 'reviewer',
397
- scopes: ['payments:approve'],
398
- })
440
+ await ws.approveStep(
441
+ runId,
442
+ 'Release funds',
443
+ { ok: true },
444
+ {
445
+ userId: 'reviewer',
446
+ scopes: ['payments:approve'],
447
+ }
448
+ )
399
449
  await ws.runWorkflowJob(runId, {})
400
450
 
401
451
  assert.equal(events.length, 1)
@@ -428,9 +478,14 @@ describe('approval audit trail', () => {
428
478
  await runToGate(ws, runId)
429
479
 
430
480
  await assert.rejects(
431
- ws.approveStep(runId, 'Release funds', { ok: true }, {
432
- userId: 'initiator',
433
- }),
481
+ ws.approveStep(
482
+ runId,
483
+ 'Release funds',
484
+ { ok: true },
485
+ {
486
+ userId: 'initiator',
487
+ }
488
+ ),
434
489
  WorkflowApprovalForbiddenError
435
490
  )
436
491
 
@@ -462,9 +517,14 @@ describe('approval audit trail', () => {
462
517
 
463
518
  // Submitted before the gate published its policy, so it is accepted here
464
519
  // and only refused on replay.
465
- await ws.approveStep(runId, 'Release funds', { ok: true }, {
466
- userId: 'initiator',
467
- })
520
+ await ws.approveStep(
521
+ runId,
522
+ 'Release funds',
523
+ { ok: true },
524
+ {
525
+ userId: 'initiator',
526
+ }
527
+ )
468
528
  assert.equal(events[0].outcome, 'success')
469
529
 
470
530
  await runToGate(ws, runId)
@@ -495,9 +555,14 @@ describe('approval audit trail', () => {
495
555
  pikkuUserId: 'initiator',
496
556
  })
497
557
  await runToGate(ws, runId)
498
- await ws.approveStep(runId, 'Release funds', { ok: true }, {
499
- userId: 'reviewer',
500
- })
558
+ await ws.approveStep(
559
+ runId,
560
+ 'Release funds',
561
+ { ok: true },
562
+ {
563
+ userId: 'reviewer',
564
+ }
565
+ )
501
566
  await ws.runWorkflowJob(runId, {})
502
567
 
503
568
  assert.equal((await ws.getRun(runId))?.status, 'completed')
@@ -513,12 +578,17 @@ describe('approval audit trail', () => {
513
578
  pikkuUserId: 'initiator',
514
579
  })
515
580
  await runToGate(ws, runId)
516
- await ws.approveStep(runId, 'Release funds', { ok: true }, {
517
- userId: 'reviewer',
518
- })
581
+ await ws.approveStep(
582
+ runId,
583
+ 'Release funds',
584
+ { ok: true },
585
+ {
586
+ userId: 'reviewer',
587
+ }
588
+ )
519
589
  await ws.runWorkflowJob(runId, {})
520
590
 
521
591
  assert.equal((await ws.getRun(runId))?.status, 'completed')
522
592
  cleanup()
523
593
  })
524
- })
594
+ })
@@ -202,7 +202,8 @@ export const evaluateApprovalStep = async (
202
202
  }
203
203
 
204
204
  const stateKey = approvalStateKey(approvalStepName)
205
- let record = ((await store.getRunState(runId))[stateKey] ?? {}) as ApprovalRecord
205
+ let record = ((await store.getRunState(runId))[stateKey] ??
206
+ {}) as ApprovalRecord
206
207
 
207
208
  const policy: WorkflowApprovalPolicy = {
208
209
  approvers: options.approvers,
@@ -1,4 +1,5 @@
1
- import type { PikkuRawWire, SerializedError } from '../../types/core.types.js'
1
+ import type { PikkuRawWire } from '../../types/core.types.js'
2
+ import type { SerializedError } from '../../errors/serialized-error.js'
2
3
  import type {
3
4
  CoreWorkflow,
4
5
  PikkuWorkflowWire,
@@ -0,0 +1,46 @@
1
+ import { WorkflowStepFunctionMismatchError } from './workflow-errors.js'
2
+ import type { StepState } from './workflow.types.js'
3
+
4
+ /** What claiming a step needs from the workflow service. */
5
+ export type StepClaimStore = {
6
+ getStepState(runId: string, stepName: string): Promise<StepState>
7
+ setStepRunning(stepId: string): Promise<void>
8
+ createRetryAttempt(
9
+ failedStepId: string,
10
+ status: 'pending' | 'running'
11
+ ): Promise<StepState>
12
+ }
13
+
14
+ /**
15
+ * Decide whether this dispatch owns the step, by reading its state and then
16
+ * writing it — which only excludes a concurrent dispatch when the caller holds
17
+ * a lock that genuinely excludes one.
18
+ *
19
+ * A store that can express the whole decision as a single conditional write
20
+ * should do that instead of calling this.
21
+ */
22
+ export const claimStepByReadThenWrite = async (
23
+ store: StepClaimStore,
24
+ runId: string,
25
+ stepName: string,
26
+ rpcName: string
27
+ ): Promise<StepState | null> => {
28
+ const stepState = await store.getStepState(runId, stepName)
29
+ // knowledge: decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md
30
+ if (
31
+ stepState.rpcName !== undefined &&
32
+ stepState.rpcName !== (rpcName ?? null)
33
+ ) {
34
+ throw new WorkflowStepFunctionMismatchError(runId, stepName)
35
+ }
36
+ if (stepState.status === 'succeeded' || stepState.status === 'running') {
37
+ return null
38
+ }
39
+ if (stepState.status === 'failed') {
40
+ return store.createRetryAttempt(stepState.stepId, 'running')
41
+ }
42
+ if (stepState.status === 'pending' || stepState.status === 'scheduled') {
43
+ await store.setStepRunning(stepState.stepId)
44
+ }
45
+ return stepState
46
+ }
@@ -1,4 +1,5 @@
1
- import type { SerializedError, CommonWireMeta } from '../../types/core.types.js'
1
+ import type { CommonWireMeta } from '../../types/core.types.js'
2
+ import type { SerializedError } from '../../errors/serialized-error.js'
2
3
  import type { CorePikkuFunctionConfig } from '../../function/functions.types.js'
3
4
  import type { GroupConcurrencyConfig } from '../queue/queue.types.js'
4
5
 
@@ -62,21 +63,12 @@ export interface WorkflowPlannedStep {
62
63
  }
63
64
 
64
65
  export type WorkflowStatus =
65
- | 'running'
66
- | 'suspended'
67
- | 'completed'
68
- | 'failed'
69
- | 'cancelled'
66
+ 'running' | 'suspended' | 'completed' | 'failed' | 'cancelled'
70
67
 
71
68
  export type WorkflowVersionStatus = 'draft' | 'active' | 'declined'
72
69
 
73
70
  export type StepStatus =
74
- | 'pending'
75
- | 'running'
76
- | 'scheduled'
77
- | 'succeeded'
78
- | 'failed'
79
- | 'suspended'
71
+ 'pending' | 'running' | 'scheduled' | 'succeeded' | 'failed' | 'suspended'
80
72
 
81
73
  export interface WorkflowRun {
82
74
  id: string
@@ -25,13 +25,16 @@ const ALLOWED: Record<string, string[]> = {
25
25
  http: ['channel'],
26
26
  cli: ['channel'],
27
27
  // An agent streams over a channel and is invoked over rpc, and grades itself
28
- // as the last thing a finished run does.
29
- agent: ['channel', 'rpc', 'agent-scorer'],
28
+ // as the last thing a finished run does. Its own functions may come from an
29
+ // installed addon, so it builds that addon's services the same way rpc does.
30
+ agent: ['channel', 'rpc', 'agent-scorer', 'addon'],
30
31
  // A judge is a degenerate agent — it builds agent messages and runs them —
31
32
  // and a grade is dispatched to a queue.
32
33
  'agent-scorer': ['agent', 'queue'],
33
34
  // `wire.rpc.agent` — the facade lives with the agent runtime it delegates to.
34
- rpc: ['agent'],
35
+ // An rpc call is how an installed addon's function is reached, so the runner
36
+ // resolves the addon instance that owns the namespace.
37
+ rpc: ['agent', 'addon'],
35
38
  gateway: ['http'],
36
39
  mcp: ['rpc'],
37
40
  trigger: ['rpc'],