@pikku/core 0.12.143 → 0.12.144

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 (700) hide show
  1. package/dist/analytics/analytics.d.ts +14 -0
  2. package/dist/analytics/analytics.js +14 -0
  3. package/dist/analytics/analytics.types.d.ts +1 -0
  4. package/dist/analytics/anonymous-analytics-identity.d.ts +1 -0
  5. package/dist/analytics/cookie-analytics-identity.d.ts +1 -0
  6. package/dist/analytics/mint-cookie.d.ts +1 -0
  7. package/dist/{wirings/channel/channel-middleware-runner.d.ts → channel-middleware-runner.d.ts} +17 -3
  8. package/dist/{wirings/channel/channel-middleware-runner.js → channel-middleware-runner.js} +24 -8
  9. package/dist/classification/data-classification.d.ts +13 -0
  10. package/dist/classification/secret-value.d.ts +7 -0
  11. package/dist/classification/secret-value.js +7 -0
  12. package/dist/crypto-utils.d.ts +93 -0
  13. package/dist/crypto-utils.js +92 -0
  14. package/dist/dev/hot-reload.d.ts +16 -0
  15. package/dist/dev/hot-reload.js +16 -1
  16. package/dist/dev/module-runner.js +7 -3
  17. package/dist/dev/reload-meta.js +1 -1
  18. package/dist/errors/error-handler.d.ts +9 -0
  19. package/dist/errors/error-handler.js +8 -0
  20. package/dist/errors/errors.d.ts +219 -0
  21. package/dist/errors/errors.js +227 -0
  22. package/dist/errors/serialized-error.d.ts +4 -0
  23. package/dist/function/abort-scope.d.ts +5 -0
  24. package/dist/function/function-meta.types.d.ts +20 -0
  25. package/dist/function/function-runner.d.ts +41 -0
  26. package/dist/function/function-runner.js +57 -11
  27. package/dist/function/functions.types.d.ts +59 -0
  28. package/dist/function/functions.types.js +23 -0
  29. package/dist/function/list.types.d.ts +4 -0
  30. package/dist/lifecycle.d.ts +12 -1
  31. package/dist/lifecycle.js +12 -1
  32. package/dist/middleware/addon-scope-cap.d.ts +4 -0
  33. package/dist/middleware/addon-scope-cap.js +7 -3
  34. package/dist/middleware/auth-apikey.js +3 -3
  35. package/dist/middleware/auth-bearer.js +5 -13
  36. package/dist/middleware/auth-cookie.js +3 -3
  37. package/dist/middleware/middleware-factories.d.ts +17 -0
  38. package/dist/middleware/middleware-factories.js +17 -0
  39. package/dist/middleware/middleware.types.d.ts +23 -0
  40. package/dist/middleware/remote-auth.d.ts +15 -0
  41. package/dist/middleware/remote-auth.js +18 -3
  42. package/dist/middleware/remote-jobs-secret.js +2 -10
  43. package/dist/middleware-runner.d.ts +7 -0
  44. package/dist/middleware-runner.js +23 -7
  45. package/dist/permissions.d.ts +13 -0
  46. package/dist/permissions.js +13 -0
  47. package/dist/pikku-state.d.ts +49 -0
  48. package/dist/pikku-state.js +49 -0
  49. package/dist/remote.js +20 -5
  50. package/dist/schema.d.ts +36 -0
  51. package/dist/schema.js +36 -0
  52. package/dist/services/agent-run-state-service.d.ts +8 -0
  53. package/dist/services/agent-runner-service.d.ts +24 -0
  54. package/dist/services/agent-storage-service.d.ts +8 -0
  55. package/dist/services/ai-embedding-service.d.ts +4 -0
  56. package/dist/services/audit-service.d.ts +48 -0
  57. package/dist/services/audit-service.js +22 -0
  58. package/dist/services/content-service.d.ts +34 -0
  59. package/dist/services/credential-wire-service.d.ts +9 -0
  60. package/dist/services/credential-wire-service.js +9 -0
  61. package/dist/services/deployment-service.d.ts +14 -0
  62. package/dist/services/email-service.d.ts +20 -0
  63. package/dist/services/email-template.d.ts +24 -0
  64. package/dist/services/email-template.js +12 -0
  65. package/dist/services/file-scenario-run-store.d.ts +5 -0
  66. package/dist/services/file-scenario-run-store.js +4 -0
  67. package/dist/services/gateway-service.d.ts +5 -0
  68. package/dist/services/in-memory-agent-run-state-service.d.ts +5 -0
  69. package/dist/services/in-memory-agent-run-state-service.js +5 -0
  70. package/dist/services/in-memory-lease-service.d.ts +5 -0
  71. package/dist/services/in-memory-lease-service.js +5 -0
  72. package/dist/services/in-memory-session-store.d.ts +4 -0
  73. package/dist/services/in-memory-session-store.js +4 -0
  74. package/dist/services/incoming-webhook-queue.d.ts +2 -0
  75. package/dist/services/incoming-webhook-queue.js +2 -0
  76. package/dist/services/incoming-webhook-service.d.ts +9 -1
  77. package/dist/services/incoming-webhook-service.js +1 -1
  78. package/dist/services/index.d.ts +1 -5
  79. package/dist/services/index.js +1 -5
  80. package/dist/services/jwt-service.d.ts +8 -0
  81. package/dist/services/lease-service.d.ts +5 -0
  82. package/dist/services/lease-service.js +1 -0
  83. package/dist/services/local-content-request-handler.d.ts +20 -0
  84. package/dist/services/local-content-request-handler.js +11 -0
  85. package/dist/services/local-content.d.ts +45 -0
  86. package/dist/services/local-content.js +35 -0
  87. package/dist/services/local-credential-service.d.ts +5 -0
  88. package/dist/services/local-credential-service.js +5 -0
  89. package/dist/services/local-email-service.d.ts +7 -0
  90. package/dist/services/local-email-service.js +7 -0
  91. package/dist/services/local-secrets.d.ts +8 -0
  92. package/dist/services/local-secrets.js +8 -0
  93. package/dist/services/local-variables.d.ts +6 -0
  94. package/dist/services/local-variables.js +6 -0
  95. package/dist/services/logger.d.ts +4 -0
  96. package/dist/services/logger.js +4 -0
  97. package/dist/services/meta-service.d.ts +38 -0
  98. package/dist/services/meta-service.js +6 -0
  99. package/dist/services/queue-webhook-service.d.ts +19 -0
  100. package/dist/services/queue-webhook-service.js +19 -0
  101. package/dist/services/remote-jobs.d.ts +8 -13
  102. package/dist/services/remote-jobs.js +3 -54
  103. package/dist/services/scenario-cookie-jar.d.ts +4 -0
  104. package/dist/services/scheduler-service.d.ts +13 -0
  105. package/dist/services/scheduler-service.js +8 -0
  106. package/dist/services/schema-service.d.ts +9 -0
  107. package/dist/services/scope-service.d.ts +10 -0
  108. package/dist/services/scoped-secret-service.d.ts +5 -0
  109. package/dist/services/scoped-secret-service.js +5 -0
  110. package/dist/services/secret-host-binding.d.ts +5 -0
  111. package/dist/services/secret-host-binding.js +5 -0
  112. package/dist/services/secret-service.d.ts +19 -1
  113. package/dist/services/secretless.d.ts +6 -0
  114. package/dist/services/secretless.js +6 -0
  115. package/dist/services/session-store.d.ts +5 -0
  116. package/dist/services/stub-tracker.d.ts +1 -0
  117. package/dist/services/temporary-file-service.d.ts +9 -0
  118. package/dist/services/temporary-file-service.js +9 -0
  119. package/dist/services/trigger-service.d.ts +4 -0
  120. package/dist/services/trigger-source-store.d.ts +13 -0
  121. package/dist/services/trigger-source-store.js +7 -0
  122. package/dist/services/typed-credential-service.d.ts +6 -0
  123. package/dist/services/typed-credential-service.js +5 -0
  124. package/dist/services/typed-secret-service.d.ts +12 -0
  125. package/dist/services/typed-secret-service.js +11 -0
  126. package/dist/services/typed-variables-service.d.ts +1 -0
  127. package/dist/services/user-session-service.d.ts +31 -1
  128. package/dist/services/user-session-service.js +29 -3
  129. package/dist/services/v8-coverage-service.d.ts +27 -0
  130. package/dist/services/v8-coverage-service.js +5 -0
  131. package/dist/services/variables-service.d.ts +8 -0
  132. package/dist/services/virtual-user-sign-in.d.ts +1 -0
  133. package/dist/services/virtual-user-statement.d.ts +8 -0
  134. package/dist/services/virtual-user-statement.js +4 -0
  135. package/dist/services/webhook-service.d.ts +25 -0
  136. package/dist/services/webhook-service.js +15 -0
  137. package/dist/services/workflow-service.d.ts +6 -0
  138. package/dist/test-utils.js +1 -1
  139. package/dist/testing/service-tests.d.ts +4 -0
  140. package/dist/time-utils.d.ts +15 -0
  141. package/dist/time-utils.js +14 -0
  142. package/dist/types/core.types.d.ts +80 -0
  143. package/dist/types/state.types.d.ts +4 -0
  144. package/dist/utils/hmac.d.ts +3 -0
  145. package/dist/utils/safe-fetch.d.ts +14 -0
  146. package/dist/utils/safe-fetch.js +13 -0
  147. package/dist/utils/stable-stringify.d.ts +11 -0
  148. package/dist/utils/stable-stringify.js +33 -0
  149. package/dist/utils.d.ts +28 -0
  150. package/dist/utils.js +22 -0
  151. package/dist/version.d.ts +7 -0
  152. package/dist/version.js +7 -0
  153. package/dist/wirings/addon/define-screens.d.ts +2 -0
  154. package/dist/wirings/addon/remote-addon-auth.d.ts +9 -0
  155. package/dist/wirings/addon/remote-addon-auth.js +5 -0
  156. package/dist/wirings/addon/wire-addon.d.ts +4 -0
  157. package/dist/wirings/addon/wire-remote-addon.d.ts +1 -0
  158. package/dist/wirings/agent/agent-agui.d.ts +14 -5
  159. package/dist/wirings/agent/agent-agui.js +17 -6
  160. package/dist/wirings/agent/agent-helpers.d.ts +61 -1
  161. package/dist/wirings/agent/agent-helpers.js +62 -2
  162. package/dist/wirings/agent/agent-interrupt.d.ts +5 -0
  163. package/dist/wirings/agent/agent-output.d.ts +20 -0
  164. package/dist/wirings/agent/agent-output.js +69 -0
  165. package/dist/wirings/agent/agent-prepare.d.ts +41 -0
  166. package/dist/wirings/agent/agent-prepare.js +38 -2
  167. package/dist/wirings/agent/agent-registry.d.ts +8 -0
  168. package/dist/wirings/agent/agent-registry.js +10 -4
  169. package/dist/wirings/agent/agent-runner.d.ts +33 -0
  170. package/dist/wirings/agent/agent-runner.js +40 -7
  171. package/dist/wirings/agent/agent-stream.d.ts +30 -0
  172. package/dist/wirings/agent/agent-stream.js +33 -11
  173. package/dist/wirings/agent/agent.types.d.ts +43 -0
  174. package/dist/wirings/agent/voice-input.d.ts +12 -0
  175. package/dist/wirings/agent/voice-input.js +12 -0
  176. package/dist/wirings/agent/voice-output.d.ts +14 -0
  177. package/dist/wirings/agent/voice-output.js +10 -0
  178. package/dist/wirings/agent-scorer/agent-scorer-judge.js +1 -2
  179. package/dist/wirings/agent-scorer/agent-scorer-registry.d.ts +10 -0
  180. package/dist/wirings/agent-scorer/agent-scorer-registry.js +10 -0
  181. package/dist/wirings/agent-scorer/agent-scorer-snapshots.d.ts +1 -0
  182. package/dist/wirings/agent-scorer/agent-scorer-snapshots.js +1 -0
  183. package/dist/wirings/agent-scorer/agent-scorer.types.d.ts +7 -0
  184. package/dist/wirings/channel/channel-common.js +1 -1
  185. package/dist/wirings/channel/channel-rpc.types.d.ts +5 -0
  186. package/dist/wirings/channel/channel-runner.d.ts +22 -0
  187. package/dist/wirings/channel/channel-runner.js +22 -0
  188. package/dist/wirings/channel/channel-store.d.ts +8 -0
  189. package/dist/wirings/channel/channel-store.js +7 -0
  190. package/dist/wirings/channel/channel.types.d.ts +18 -0
  191. package/dist/wirings/channel/define-channel-routes.d.ts +5 -0
  192. package/dist/wirings/channel/define-channel-routes.js +5 -0
  193. package/dist/wirings/channel/eventhub-service.d.ts +9 -0
  194. package/dist/wirings/channel/eventhub-store.d.ts +1 -0
  195. package/dist/wirings/channel/eventhub-store.js +1 -0
  196. package/dist/wirings/channel/index.d.ts +1 -1
  197. package/dist/wirings/channel/index.js +1 -1
  198. package/dist/wirings/channel/local/local-channel-handler.d.ts +1 -0
  199. package/dist/wirings/channel/local/local-channel-handler.js +1 -0
  200. package/dist/wirings/channel/local/local-channel-runner.d.ts +13 -0
  201. package/dist/wirings/channel/local/local-channel-runner.js +13 -0
  202. package/dist/wirings/channel/local/local-eventhub-service.d.ts +1 -0
  203. package/dist/wirings/channel/local/local-eventhub-service.js +1 -0
  204. package/dist/wirings/channel/log-channels.d.ts +1 -0
  205. package/dist/wirings/channel/log-channels.js +1 -0
  206. package/dist/wirings/channel/pikku-abstract-channel-handler.d.ts +5 -0
  207. package/dist/wirings/channel/pikku-abstract-channel-handler.js +5 -0
  208. package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +32 -0
  209. package/dist/wirings/channel/serverless/serverless-channel-runner.js +31 -0
  210. package/dist/wirings/cli/channel/cli-channel-runner.d.ts +8 -0
  211. package/dist/wirings/cli/channel/cli-channel-runner.js +8 -0
  212. package/dist/wirings/cli/channel/cli-raw-channel-runner.d.ts +1 -0
  213. package/dist/wirings/cli/cli-runner.d.ts +43 -0
  214. package/dist/wirings/cli/cli-runner.js +43 -0
  215. package/dist/wirings/cli/command-parser.d.ts +13 -0
  216. package/dist/wirings/cli/command-parser.js +12 -0
  217. package/dist/wirings/credential/credential-overrides.d.ts +1 -0
  218. package/dist/wirings/credential/credential.types.d.ts +7 -0
  219. package/dist/wirings/credential/validate-credential-definitions.d.ts +7 -0
  220. package/dist/wirings/credential/validate-credential-definitions.js +7 -0
  221. package/dist/wirings/flag/cached-flag-source.d.ts +1 -0
  222. package/dist/wirings/flag/flag.types.d.ts +3 -0
  223. package/dist/wirings/gateway/gateway-runner.d.ts +23 -0
  224. package/dist/wirings/gateway/gateway-runner.js +23 -0
  225. package/dist/wirings/gateway/gateway.types.d.ts +3 -0
  226. package/dist/wirings/gateway/local-gateway-service.d.ts +10 -0
  227. package/dist/{services → wirings/gateway}/local-gateway-service.js +6 -2
  228. package/dist/wirings/http/http-routes.d.ts +21 -0
  229. package/dist/wirings/http/http-routes.js +11 -0
  230. package/dist/wirings/http/http-runner.d.ts +71 -0
  231. package/dist/wirings/http/http-runner.js +73 -5
  232. package/dist/wirings/http/http.types.d.ts +27 -0
  233. package/dist/wirings/http/index.d.ts +1 -0
  234. package/dist/wirings/http/index.js +1 -0
  235. package/dist/wirings/http/log-http-routes.d.ts +1 -0
  236. package/dist/wirings/http/log-http-routes.js +1 -0
  237. package/dist/wirings/http/merge-request-data.d.ts +12 -0
  238. package/dist/wirings/http/merge-request-data.js +42 -0
  239. package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -0
  240. package/dist/wirings/http/pikku-fetch-http-request.js +3 -32
  241. package/dist/wirings/http/pikku-fetch-http-response.d.ts +1 -0
  242. package/dist/wirings/http/pikku-fetch-http-response.js +1 -0
  243. package/dist/wirings/http/routers/http-router.d.ts +6 -0
  244. package/dist/wirings/http/routers/http-router.js +6 -0
  245. package/dist/wirings/http/web-request.d.ts +17 -0
  246. package/dist/wirings/http/web-request.js +17 -0
  247. package/dist/wirings/mcp/mcp-endpoint-registry.d.ts +7 -0
  248. package/dist/wirings/mcp/mcp-endpoint-registry.js +7 -0
  249. package/dist/wirings/mcp/mcp-runner.d.ts +63 -0
  250. package/dist/wirings/mcp/mcp-runner.js +62 -0
  251. package/dist/wirings/mcp/mcp.types.d.ts +12 -0
  252. package/dist/wirings/node/node.types.d.ts +4 -0
  253. package/dist/wirings/oauth2/oauth2.types.d.ts +2 -0
  254. package/dist/{services → wirings/queue}/in-memory-queue-service.d.ts +9 -1
  255. package/dist/{services → wirings/queue}/in-memory-queue-service.js +9 -1
  256. package/dist/wirings/queue/index.d.ts +1 -0
  257. package/dist/wirings/queue/index.js +1 -0
  258. package/dist/wirings/queue/queue-identity.js +2 -14
  259. package/dist/wirings/queue/queue-runner.d.ts +37 -0
  260. package/dist/wirings/queue/queue-runner.js +37 -0
  261. package/dist/wirings/queue/queue.types.d.ts +35 -0
  262. package/dist/wirings/queue/register-queue-helper.d.ts +12 -0
  263. package/dist/wirings/queue/register-queue-helper.js +11 -0
  264. package/dist/wirings/queue/remote-queue-job.d.ts +11 -0
  265. package/dist/wirings/queue/remote-queue-job.js +41 -0
  266. package/dist/wirings/queue/validate-worker-config.d.ts +1 -0
  267. package/dist/wirings/role/role.types.d.ts +3 -0
  268. package/dist/wirings/rpc/rpc-runner.d.ts +24 -0
  269. package/dist/wirings/rpc/rpc-runner.js +37 -2
  270. package/dist/wirings/rpc/rpc-types.d.ts +2 -0
  271. package/dist/wirings/scheduler/index.d.ts +1 -0
  272. package/dist/wirings/scheduler/index.js +1 -0
  273. package/dist/wirings/scheduler/log-schedulers.d.ts +1 -0
  274. package/dist/wirings/scheduler/log-schedulers.js +1 -0
  275. package/dist/wirings/scheduler/remote-scheduled-job.d.ts +11 -0
  276. package/dist/wirings/scheduler/remote-scheduled-job.js +20 -0
  277. package/dist/wirings/scheduler/scheduler-runner.d.ts +29 -0
  278. package/dist/wirings/scheduler/scheduler-runner.js +28 -0
  279. package/dist/wirings/scheduler/scheduler.types.d.ts +3 -0
  280. package/dist/wirings/scope/scope.types.d.ts +5 -0
  281. package/dist/wirings/secret/index.d.ts +2 -2
  282. package/dist/wirings/secret/index.js +1 -1
  283. package/dist/wirings/secret/secret.types.d.ts +26 -1
  284. package/dist/wirings/secret/secret.types.js +1 -0
  285. package/dist/wirings/secret/validate-secret-definitions.d.ts +8 -0
  286. package/dist/wirings/secret/validate-secret-definitions.js +15 -0
  287. package/dist/wirings/trigger/in-memory-trigger-service.d.ts +11 -0
  288. package/dist/{services → wirings/trigger}/in-memory-trigger-service.js +10 -3
  289. package/dist/wirings/trigger/index.d.ts +1 -1
  290. package/dist/wirings/trigger/pikku-trigger-service.d.ts +8 -3
  291. package/dist/wirings/trigger/pikku-trigger-service.js +14 -3
  292. package/dist/wirings/trigger/trigger-runner.d.ts +27 -2
  293. package/dist/wirings/trigger/trigger-runner.js +35 -2
  294. package/dist/wirings/trigger/trigger.types.d.ts +26 -4
  295. package/dist/wirings/trigger/webhook-source-runner.d.ts +24 -0
  296. package/dist/wirings/trigger/webhook-source-runner.js +19 -0
  297. package/dist/wirings/trigger/webhook-source.types.d.ts +12 -2
  298. package/dist/wirings/trigger/webhook-source.types.js +1 -1
  299. package/dist/wirings/variable/validate-variable-definitions.d.ts +7 -0
  300. package/dist/wirings/variable/validate-variable-definitions.js +7 -0
  301. package/dist/wirings/variable/variable.types.d.ts +7 -0
  302. package/dist/wirings/virtual-user/conversation/conversation.types.d.ts +5 -0
  303. package/dist/wirings/virtual-user/conversation/run-conversation.d.ts +6 -0
  304. package/dist/wirings/virtual-user/conversation/run-conversation.js +1 -1
  305. package/dist/{services → wirings/virtual-user}/http-virtual-users.d.ts +4 -3
  306. package/dist/{services → wirings/virtual-user}/http-virtual-users.js +6 -6
  307. package/dist/wirings/virtual-user/index.d.ts +1 -1
  308. package/dist/wirings/virtual-user/index.js +1 -1
  309. package/dist/wirings/virtual-user/run-virtual-user.d.ts +2 -1
  310. package/dist/wirings/virtual-user/run-virtual-user.js +1 -14
  311. package/dist/wirings/virtual-user/virtual-user-declaration.types.d.ts +4 -0
  312. package/dist/wirings/virtual-user/virtual-user-scaffold.d.ts +10 -1
  313. package/dist/wirings/virtual-user/virtual-user-scaffold.js +5 -0
  314. package/dist/wirings/virtual-user/virtual-user-schedule.d.ts +5 -0
  315. package/dist/wirings/virtual-user/virtual-user-schedule.js +1 -0
  316. package/dist/wirings/virtual-user/virtual-user-target.d.ts +1 -0
  317. package/dist/wirings/webhook/define-outgoing-webhook.d.ts +20 -0
  318. package/dist/wirings/webhook/define-outgoing-webhook.js +9 -0
  319. package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +8 -4
  320. package/dist/wirings/workflow/dsl/workflow-runner.d.ts +7 -0
  321. package/dist/wirings/workflow/dsl/workflow-runner.js +7 -0
  322. package/dist/wirings/workflow/feature.d.ts +12 -0
  323. package/dist/wirings/workflow/feature.js +12 -0
  324. package/dist/wirings/workflow/graph/graph-node.d.ts +5 -0
  325. package/dist/wirings/workflow/graph/graph-node.js +5 -0
  326. package/dist/wirings/workflow/graph/template.d.ts +6 -0
  327. package/dist/wirings/workflow/graph/template.js +5 -0
  328. package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +12 -0
  329. package/dist/wirings/workflow/graph/wire-workflow-graph.js +10 -0
  330. package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +11 -0
  331. package/dist/wirings/workflow/graph/workflow-graph.types.js +1 -0
  332. package/dist/{services → wirings/workflow}/in-memory-workflow-service.d.ts +8 -3
  333. package/dist/{services → wirings/workflow}/in-memory-workflow-service.js +9 -4
  334. package/dist/wirings/workflow/pikku-scenario-service.d.ts +1 -1
  335. package/dist/wirings/workflow/pikku-scenario-service.js +2 -2
  336. package/dist/wirings/workflow/pikku-workflow-service.d.ts +1 -0
  337. package/dist/wirings/workflow/pikku-workflow-service.js +1 -0
  338. package/dist/wirings/workflow/run-timeline.d.ts +21 -0
  339. package/dist/wirings/workflow/run-timeline.js +15 -7
  340. package/dist/wirings/workflow/scenario-coverage.d.ts +1 -0
  341. package/dist/wirings/workflow/scenario-poll.d.ts +1 -0
  342. package/dist/wirings/workflow/scenario-prose.d.ts +6 -0
  343. package/dist/wirings/workflow/scenario-prose.js +6 -0
  344. package/dist/wirings/workflow/scenario-run.types.d.ts +3 -0
  345. package/dist/wirings/workflow/scenario-step.types.d.ts +1 -0
  346. package/dist/wirings/workflow/scenario-step.types.js +1 -0
  347. package/dist/wirings/workflow/scenario-surface.js +1 -13
  348. package/dist/wirings/workflow/scenario.types.d.ts +6 -0
  349. package/dist/wirings/workflow/workflow-approval-policy.d.ts +6 -0
  350. package/dist/wirings/workflow/workflow-approval-policy.js +6 -0
  351. package/dist/wirings/workflow/workflow-constants.d.ts +7 -1
  352. package/dist/wirings/workflow/workflow-constants.js +10 -1
  353. package/dist/wirings/workflow/workflow-errors.d.ts +13 -0
  354. package/dist/wirings/workflow/workflow-errors.js +13 -0
  355. package/dist/wirings/workflow/workflow-invocation-id.d.ts +4 -0
  356. package/dist/wirings/workflow/workflow-invocation-id.js +4 -0
  357. package/dist/wirings/workflow/workflow-queue-workers.d.ts +3 -0
  358. package/dist/wirings/workflow/workflow-run-ownership.d.ts +1 -0
  359. package/dist/wirings/workflow/workflow-run-ownership.js +1 -0
  360. package/dist/wirings/workflow/workflow-status-stream.d.ts +1 -0
  361. package/dist/wirings/workflow/workflow-unwind-plan.js +2 -7
  362. package/dist/wirings/workflow/workflow.types.d.ts +40 -0
  363. package/package.json +26 -9
  364. package/CHANGELOG.md +0 -6978
  365. package/dist/services/in-memory-trigger-service.d.ts +0 -4
  366. package/dist/services/local-gateway-service.d.ts +0 -6
  367. package/dist/utils/hash.d.ts +0 -2
  368. package/dist/utils/hash.js +0 -23
  369. package/knowledge/decisions/index.md +0 -19
  370. package/knowledge/decisions/internals/a-credential-name-declared-twice-must-agree-on-schema-and-type.md +0 -29
  371. package/knowledge/decisions/internals/a-grant-can-name-a-scope-declared-without-its-addon.md +0 -29
  372. package/knowledge/decisions/internals/a-held-run-is-woken-later-not-retried.md +0 -28
  373. package/knowledge/decisions/internals/a-latency-budget-is-asserted-by-its-cause.md +0 -32
  374. package/knowledge/decisions/internals/a-non-streaming-agent-run-registers-with-agentrunstate-too.md +0 -22
  375. package/knowledge/decisions/internals/a-reset-suite-makes-the-dev-seed-the-fixture.md +0 -50
  376. package/knowledge/decisions/internals/a-resumed-agent-turn-is-as-interruptible-as-the-first.md +0 -20
  377. package/knowledge/decisions/internals/a-scenario-step-template-is-offered-unfilled.md +0 -21
  378. package/knowledge/decisions/internals/a-scheduled-task-writes-its-caller-session-before-it-runs.md +0 -22
  379. package/knowledge/decisions/internals/a-secret-set-in-memory-shadows-the-variable-of-the-same-name.md +0 -28
  380. package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +0 -49
  381. package/knowledge/decisions/internals/a-virtual-user-acts-through-invokeraw-so-a-refusal-is-data.md +0 -32
  382. package/knowledge/decisions/internals/a-virtual-user-cadence-is-a-row-not-a-timer.md +0 -66
  383. package/knowledge/decisions/internals/a-virtual-user-converse-signs-in-before-its-first-turn.md +0 -24
  384. package/knowledge/decisions/internals/a-virtual-user-decides-whether-to-trust-memory-once-per-turn.md +0 -21
  385. package/knowledge/decisions/internals/a-virtual-user-email-is-computed-with-the-run-id-as-a-sub-address.md +0 -34
  386. package/knowledge/decisions/internals/a-virtual-user-run-is-not-a-workflow-but-it-needs-a-trigger.md +0 -65
  387. package/knowledge/decisions/internals/a-wall-clock-threshold-is-a-load-test-in-disguise.md +0 -49
  388. package/knowledge/decisions/internals/a-workflow-wire-is-built-from-the-run-not-from-the-rpc-service.md +0 -45
  389. package/knowledge/decisions/internals/addon-package-roots-resolve-by-walking-node-module-search-paths.md +0 -26
  390. package/knowledge/decisions/internals/addon-pikku-meta-ships-at-the-package-root-or-under-dist.md +0 -32
  391. package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +0 -33
  392. package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +0 -28
  393. package/knowledge/decisions/internals/agent-agui-bridge-obeys-the-client-ordering-contract.md +0 -29
  394. package/knowledge/decisions/internals/agent-audio-chunks-carry-the-format-the-provider-returned.md +0 -20
  395. package/knowledge/decisions/internals/agent-context-waits-for-a-tool-result-still-being-written.md +0 -21
  396. package/knowledge/decisions/internals/agent-credential-suspensions-hide-the-tool-result.md +0 -26
  397. package/knowledge/decisions/internals/agent-delegate-and-supervise-hide-different-text.md +0 -26
  398. package/knowledge/decisions/internals/agent-llm-tool-arguments-have-nulls-stripped.md +0 -23
  399. package/knowledge/decisions/internals/agent-model-config-stays-a-single-resolution-seam.md +0 -25
  400. package/knowledge/decisions/internals/agent-onerror-hooks-cannot-change-the-failure.md +0 -22
  401. package/knowledge/decisions/internals/agent-runner-methods-must-keep-their-receiver.md +0 -22
  402. package/knowledge/decisions/internals/agent-speech-travels-as-a-custom-agui-event.md +0 -22
  403. package/knowledge/decisions/internals/agent-stream-persistence-is-best-effort.md +0 -27
  404. package/knowledge/decisions/internals/agent-sub-agents-inherit-the-parent-context-block.md +0 -26
  405. package/knowledge/decisions/internals/agent-tool-execute-failures-are-logged-unconditionally.md +0 -25
  406. package/knowledge/decisions/internals/agent-voice-input-transcribes-audio-parts-in-place.md +0 -22
  407. package/knowledge/decisions/internals/agent-working-memory-is-persisted-only-when-valid.md +0 -25
  408. package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +0 -39
  409. package/knowledge/decisions/internals/an-agent-interrupt-is-not-a-failure.md +0 -23
  410. package/knowledge/decisions/internals/an-agent-is-offered-under-its-registry-key-and-only-within-the-virtual-users-scopes.md +0 -27
  411. package/knowledge/decisions/internals/an-agent-run-owned-by-another-instance-says-so.md +0 -25
  412. package/knowledge/decisions/internals/an-agent-stream-send-must-return-the-inner-sends-promise.md +0 -22
  413. package/knowledge/decisions/internals/an-empty-text-part-is-omitted-from-an-agent-message.md +0 -20
  414. package/knowledge/decisions/internals/an-empty-transcript-is-not-recorded.md +0 -22
  415. package/knowledge/decisions/internals/an-oauth2-credential-implies-an-optional-app-secret.md +0 -26
  416. package/knowledge/decisions/internals/an-unref-d-timer-cannot-be-awaited-under-node-test.md +0 -66
  417. package/knowledge/decisions/internals/analytics-identity-resolvers-run-in-declared-order.md +0 -22
  418. package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +0 -30
  419. package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +0 -31
  420. package/knowledge/decisions/internals/channel-state-accessors-are-unsound-generics-that-every-implementation-asserts.md +0 -33
  421. package/knowledge/decisions/internals/channel-state-is-per-socket-session-state-is-per-user.md +0 -29
  422. package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +0 -28
  423. package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +0 -27
  424. package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +0 -28
  425. package/knowledge/decisions/internals/cli-stdout-is-reserved-for-machine-readable-output.md +0 -34
  426. package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +0 -29
  427. package/knowledge/decisions/internals/core-column-form-is-an-axis-of-its-own.md +0 -84
  428. package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +0 -41
  429. package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +0 -44
  430. package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +0 -39
  431. package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +0 -42
  432. package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +0 -39
  433. package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +0 -43
  434. package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +0 -38
  435. package/knowledge/decisions/internals/core-state-is-a-global-map-written-only-at-registration-time.md +0 -44
  436. package/knowledge/decisions/internals/email-meta-is-read-uncached-because-codegen-rewrites-it-mid-session.md +0 -27
  437. package/knowledge/decisions/internals/feature-flag-declarations-refuse-an-empty-anyof-and-conflicting-scopes.md +0 -22
  438. package/knowledge/decisions/internals/feature-flags-fail-open-and-never-enforce-access.md +0 -28
  439. package/knowledge/decisions/internals/flag-sync-rewrites-only-the-declared-text.md +0 -24
  440. package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +0 -32
  441. package/knowledge/decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md +0 -43
  442. package/knowledge/decisions/internals/gateway-webhook-challenges-echo-bytes-not-json.md +0 -28
  443. package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +0 -31
  444. package/knowledge/decisions/internals/generated-src-paths-in-pikku-meta-are-absolute.md +0 -26
  445. package/knowledge/decisions/internals/global-middleware-resolves-from-the-root-namespace-too.md +0 -32
  446. package/knowledge/decisions/internals/hot-reload-reads-the-changed-source-never-a-compiled-copy.md +0 -38
  447. package/knowledge/decisions/internals/hot-reload-writes-into-the-function-map-captured-at-startup.md +0 -26
  448. package/knowledge/decisions/internals/http-request-bodies-are-read-once-and-shared.md +0 -32
  449. package/knowledge/decisions/internals/http-route-groups-cascade-config-in-a-fixed-order.md +0 -28
  450. package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +0 -30
  451. package/knowledge/decisions/internals/http-runner-logs-through-a-trace-scoped-logger-functions-do-not.md +0 -26
  452. package/knowledge/decisions/internals/http-set-cookie-headers-are-appended-never-joined.md +0 -28
  453. package/knowledge/decisions/internals/http-sse-streams-flush-headers-only-after-middleware.md +0 -32
  454. package/knowledge/decisions/internals/http-wiring-without-metadata-is-skipped-not-fatal.md +0 -26
  455. package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +0 -25
  456. package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +0 -26
  457. package/knowledge/decisions/internals/index.md +0 -182
  458. package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +0 -25
  459. package/knowledge/decisions/internals/local-trigger-and-gateway-services-assume-a-single-process.md +0 -26
  460. package/knowledge/decisions/internals/mcp-wire-names-are-assigned-over-the-whole-registry.md +0 -39
  461. package/knowledge/decisions/internals/node-only-builtins-are-imported-dynamically.md +0 -24
  462. package/knowledge/decisions/internals/one-project-shape-check-two-validators.md +0 -53
  463. package/knowledge/decisions/internals/only-exposed-functions-enter-a-virtual-user-catalogue.md +0 -21
  464. package/knowledge/decisions/internals/queue-group-concurrency-keeps-one-shared-queue-fair.md +0 -28
  465. package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +0 -27
  466. package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +0 -31
  467. package/knowledge/decisions/internals/role-names-cannot-contain-the-scope-separator.md +0 -30
  468. package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +0 -32
  469. package/knowledge/decisions/internals/scenario-agent-calls-sign-in-on-401-only.md +0 -31
  470. package/knowledge/decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md +0 -24
  471. package/knowledge/decisions/internals/scenario-meta-lives-apart-from-app-meta-but-merges-when-read-off-disk.md +0 -26
  472. package/knowledge/decisions/internals/scenario-steps-return-drained-response-records.md +0 -27
  473. package/knowledge/decisions/internals/scenarios-live-in-files-named-for-them.md +0 -48
  474. package/knowledge/decisions/internals/scope-roots-may-be-co-declared-by-an-addon-and-its-host-app.md +0 -30
  475. package/knowledge/decisions/internals/serverless-channel-disconnect-must-tolerate-a-missing-channel.md +0 -28
  476. package/knowledge/decisions/internals/side-effects-are-an-allowlist-not-a-boolean.md +0 -34
  477. package/knowledge/decisions/internals/speech-synthesis-picks-a-voice-per-sentence-and-warns-once.md +0 -24
  478. package/knowledge/decisions/internals/the-agent-done-event-goes-through-the-middleware-and-is-awaited.md +0 -26
  479. package/knowledge/decisions/internals/the-api-report-pins-members-not-just-names.md +0 -43
  480. package/knowledge/decisions/internals/the-core-scope-validator-refuses-separator-wildcard-and-empty-segments.md +0 -22
  481. package/knowledge/decisions/internals/the-dev-queue-copies-prod-timing-and-serialization-semantics.md +0 -30
  482. package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md +0 -83
  483. package/knowledge/decisions/internals/the-embedding-model-is-pinned-per-service-and-doc-query-embedding-is-split.md +0 -29
  484. package/knowledge/decisions/internals/the-in-memory-workflow-service-is-inline-only-and-single-process.md +0 -27
  485. package/knowledge/decisions/internals/the-kek-salt-is-scoped-to-the-key-version.md +0 -40
  486. package/knowledge/decisions/internals/the-mcp-handshake-is-challenged-only-when-every-target-is-gated.md +0 -29
  487. package/knowledge/decisions/internals/the-middleware-resolution-cache-is-deliberately-unbounded.md +0 -40
  488. package/knowledge/decisions/internals/the-per-invocation-rpc-view-is-a-class.md +0 -40
  489. package/knowledge/decisions/internals/the-pikku-user-id-resolves-in-a-fixed-order.md +0 -24
  490. package/knowledge/decisions/internals/the-runner-resolves-wire-services-itself.md +0 -31
  491. package/knowledge/decisions/internals/the-schema-service-is-never-stubbed.md +0 -26
  492. package/knowledge/decisions/internals/the-transcript-event-is-sent-ahead-of-the-run.md +0 -25
  493. package/knowledge/decisions/internals/the-virtual-user-catalogue-is-the-only-gate-on-what-may-be-called.md +0 -21
  494. package/knowledge/decisions/internals/the-virtual-user-prompt-says-json-because-of-json-object-mode.md +0 -22
  495. package/knowledge/decisions/internals/the-virtual-user-runtime-is-exported-from-the-virtual-user-entry-point.md +0 -28
  496. package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +0 -22
  497. package/knowledge/decisions/internals/thread-history-records-the-transcript-not-the-audio.md +0 -25
  498. package/knowledge/decisions/internals/trigger-declaration-is-split-from-trigger-source.md +0 -33
  499. package/knowledge/decisions/internals/typed-secret-service-caches-for-the-process-lifetime.md +0 -26
  500. package/knowledge/decisions/internals/validate-checks-virtual-users-through-a-shared-module.md +0 -43
  501. package/knowledge/decisions/internals/validate-runs-checks-by-precondition.md +0 -115
  502. package/knowledge/decisions/internals/virtual-user-conversation-drives-the-target-through-a-transport-seam.md +0 -24
  503. package/knowledge/decisions/internals/virtual-user-conversation-verdicts-are-llm-self-evaluations.md +0 -25
  504. package/knowledge/decisions/internals/virtual-user-conversations-seed-a-hidden-kickoff-message.md +0 -23
  505. package/knowledge/decisions/internals/virtual-user-step-order-comes-from-insertion-order.md +0 -21
  506. package/knowledge/decisions/internals/virtual-users-are-declared-in-one-definevirtualusers-call-per-codebase.md +0 -30
  507. package/knowledge/decisions/internals/voice-output-speaks-unless-voice-input-explicitly-says-otherwise.md +0 -24
  508. package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +0 -26
  509. package/knowledge/decisions/internals/webhook-service-collaborators-are-constructor-args-not-locator-lookups.md +0 -25
  510. package/knowledge/decisions/internals/whether-a-run-is-inline-is-read-from-the-run-record.md +0 -58
  511. package/knowledge/decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md +0 -35
  512. package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +0 -34
  513. package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +0 -42
  514. package/knowledge/decisions/internals/workflow-dsl-meta-separates-runtime-expressions-from-literals.md +0 -38
  515. package/knowledge/decisions/internals/workflow-features-resolve-scenarios-by-object-identity.md +0 -29
  516. package/knowledge/decisions/internals/workflow-graph-inline-and-queued-runs-share-one-planner.md +0 -42
  517. package/knowledge/decisions/internals/workflow-graph-node-notes-are-excluded-from-the-graph-hash.md +0 -25
  518. package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +0 -29
  519. package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +0 -43
  520. package/knowledge/decisions/internals/workflow-queued-step-dispatch-requires-an-explicit-opt-in.md +0 -29
  521. package/knowledge/decisions/internals/workflow-queues-are-per-workflow-by-default.md +0 -42
  522. package/knowledge/decisions/internals/workflow-repeated-step-names-get-an-ordinal-suffix.md +0 -33
  523. package/knowledge/decisions/internals/workflow-replay-reads-its-steps-once-and-caches-only-the-immutable-half.md +0 -32
  524. package/knowledge/decisions/internals/workflow-retries-are-owned-by-the-workflow-not-the-queue.md +0 -31
  525. package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +0 -39
  526. package/knowledge/decisions/internals/workflow-run-mirror-is-never-a-source-of-truth.md +0 -29
  527. package/knowledge/decisions/internals/workflow-run-polling-backs-off-to-the-callers-ceiling.md +0 -33
  528. package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +0 -37
  529. package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +0 -54
  530. package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +0 -43
  531. package/knowledge/decisions/internals/workflow-scenario-prose-is-rendered-from-typed-calls-not-parsed-from-english.md +0 -32
  532. package/knowledge/decisions/internals/workflow-scenario-quarantine-reason-lives-in-code.md +0 -18
  533. package/knowledge/decisions/internals/workflow-scenario-step-targets-are-string-literals-for-the-inspector.md +0 -34
  534. package/knowledge/decisions/internals/workflow-step-compensation-runs-as-its-own-durable-step.md +0 -29
  535. package/knowledge/decisions/internals/workflow-step-dispatch-failure-is-transient-not-a-run-failure.md +0 -33
  536. package/knowledge/decisions/internals/workflow-step-lock-is-held-only-to-claim-the-step.md +0 -34
  537. package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +0 -34
  538. package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +0 -38
  539. package/knowledge/decisions/internals/workflow-suspended-runs-keep-their-in-process-context.md +0 -30
  540. package/knowledge/decisions/security/a-bearer-token-checked-against-a-secret-reads-it-per-request.md +0 -26
  541. package/knowledge/decisions/security/a-call-without-a-session-raises-missing-session-not-forbidden.md +0 -20
  542. package/knowledge/decisions/security/a-caller-cookie-wins-over-the-jar-for-the-same-name.md +0 -23
  543. package/knowledge/decisions/security/a-channel-lifecycle-acts-as-the-socket-upgrade-session.md +0 -16
  544. package/knowledge/decisions/security/a-channel-requires-a-session-unless-it-says-auth-false.md +0 -26
  545. package/knowledge/decisions/security/a-credential-read-path-follows-its-declared-type-not-absence.md +0 -32
  546. package/knowledge/decisions/security/a-credential-type-is-a-literal-the-inspector-checks-at-declaration.md +0 -27
  547. package/knowledge/decisions/security/a-dropped-audit-write-is-always-logged.md +0 -28
  548. package/knowledge/decisions/security/a-first-party-cookie-is-written-only-after-its-purposes-consent.md +0 -33
  549. package/knowledge/decisions/security/a-function-never-receives-the-secret-service.md +0 -37
  550. package/knowledge/decisions/security/a-graph-run-starts-at-an-entry-node-the-graph-declared.md +0 -33
  551. package/knowledge/decisions/security/a-permission-gets-a-wire-it-cannot-reply-on.md +0 -33
  552. package/knowledge/decisions/security/a-public-function-says-so-with-auth-false.md +0 -34
  553. package/knowledge/decisions/security/a-readonly-session-reaches-only-readonly-functions.md +0 -25
  554. package/knowledge/decisions/security/a-scaffold-flag-says-a-surface-exists-not-who-may-call-it.md +0 -52
  555. package/knowledge/decisions/security/a-scheduled-virtual-user-run-needs-no-admin-at-run-time.md +0 -27
  556. package/knowledge/decisions/security/a-scoped-credential-view-is-limited-to-declared-names.md +0 -26
  557. package/knowledge/decisions/security/a-scoped-secret-view-reads-only-declared-keys-and-never-writes.md +0 -25
  558. package/knowledge/decisions/security/a-secret-is-sent-only-to-the-hosts-it-declares.md +0 -29
  559. package/knowledge/decisions/security/a-step-can-name-an-identity-no-virtual-user-holds-through-per-call-headers.md +0 -25
  560. package/knowledge/decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md +0 -37
  561. package/knowledge/decisions/security/a-stopped-run-by-id-skips-the-ownership-check.md +0 -24
  562. package/knowledge/decisions/security/a-vault-secret-redacts-on-serialization-and-throws-on-coercion.md +0 -29
  563. package/knowledge/decisions/security/a-virtual-user-catalogue-entry-is-filtered-by-scope-and-approval-is-denied-by-default.md +0 -30
  564. package/knowledge/decisions/security/a-virtual-user-environment-fails-closed.md +0 -38
  565. package/knowledge/decisions/security/a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md +0 -27
  566. package/knowledge/decisions/security/a-virtual-user-never-runs-against-production.md +0 -23
  567. package/knowledge/decisions/security/a-virtual-user-reads-its-roles-from-the-apps-own-rpc-before-better-auth.md +0 -27
  568. package/knowledge/decisions/security/a-virtual-user-run-treats-an-unresolved-environment-as-production.md +0 -41
  569. package/knowledge/decisions/security/a-virtual-user-scopes-are-expanded-from-its-roles-once-at-run-preparation.md +0 -25
  570. package/knowledge/decisions/security/a-virtual-user-whose-roles-drift-from-the-declaration-refuses-to-run.md +0 -32
  571. package/knowledge/decisions/security/a-workflow-run-is-read-and-approved-by-its-owner.md +0 -50
  572. package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +0 -43
  573. package/knowledge/decisions/security/addon-config-gates-apply-only-at-the-namespaced-rpc-boundary.md +0 -52
  574. package/knowledge/decisions/security/addon-scopes-are-resolved-where-the-function-runs.md +0 -46
  575. package/knowledge/decisions/security/addon-screen-scopes-hide-and-do-not-enforce.md +0 -20
  576. package/knowledge/decisions/security/agent-approval-forwarding-requires-a-symbol-brand.md +0 -27
  577. package/knowledge/decisions/security/agent-credential-requests-are-symbol-branded.md +0 -37
  578. package/knowledge/decisions/security/agent-gate-requires-a-session-only-when-auth-is-true.md +0 -31
  579. package/knowledge/decisions/security/agent-ownership-failures-never-echo-the-resource.md +0 -23
  580. package/knowledge/decisions/security/agent-resume-re-runs-the-authorization-gate.md +0 -22
  581. package/knowledge/decisions/security/agent-sessionless-deployments-have-no-thread-ownership.md +0 -39
  582. package/knowledge/decisions/security/agent-thread-ownership-composes-the-session-principal.md +0 -30
  583. package/knowledge/decisions/security/agent-tool-filtering-reads-the-live-function-config.md +0 -24
  584. package/knowledge/decisions/security/an-addon-header-can-only-narrow-the-session.md +0 -26
  585. package/knowledge/decisions/security/an-addon-instance-reads-only-the-secrets-and-credentials-it-is-named.md +0 -33
  586. package/knowledge/decisions/security/an-addon-may-reach-only-itself-and-the-addons-it-uses.md +0 -16
  587. package/knowledge/decisions/security/an-agent-approval-is-claimed-before-the-tool-runs.md +0 -33
  588. package/knowledge/decisions/security/an-api-key-is-jwt-decoded-into-the-session.md +0 -26
  589. package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +0 -59
  590. package/knowledge/decisions/security/an-empty-owners-constraint-matches-nothing.md +0 -30
  591. package/knowledge/decisions/security/an-exposed-ungated-function-is-a-codegen-warning.md +0 -52
  592. package/knowledge/decisions/security/an-external-virtual-user-caller-presents-one-signed-statement.md +0 -38
  593. package/knowledge/decisions/security/an-inbound-webhook-source-dispatches-only-verified-requests.md +0 -31
  594. package/knowledge/decisions/security/an-mcp-call-with-no-http-request-stays-anonymous.md +0 -18
  595. package/knowledge/decisions/security/an-mcp-refusal-is-decided-before-dispatch.md +0 -48
  596. package/knowledge/decisions/security/an-oauth2-credential-is-read-by-its-account-row.md +0 -40
  597. package/knowledge/decisions/security/an-omitted-user-id-addresses-the-platform-credential.md +0 -32
  598. package/knowledge/decisions/security/an-upload-is-counted-as-it-arrives-not-buffered-then-measured.md +0 -24
  599. package/knowledge/decisions/security/analytics-identity-is-stamped-from-the-session-not-the-event.md +0 -24
  600. package/knowledge/decisions/security/app-access-is-a-scope-tree-synthesised-from-virtual-users.md +0 -26
  601. package/knowledge/decisions/security/approval-policy-decides-who-answers-a-tool-call.md +0 -27
  602. package/knowledge/decisions/security/auth-false-on-a-session-function-warns-and-still-requires-one.md +0 -25
  603. package/knowledge/decisions/security/bearer-token-hashes-are-unpeppered-sha256.md +0 -18
  604. package/knowledge/decisions/security/consent-is-read-from-a-cookie-and-a-recognised-denial-counts-as-refusal.md +0 -29
  605. package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +0 -84
  606. package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +0 -39
  607. package/knowledge/decisions/security/core-secrets-use-a-per-secret-dek-wrapped-by-a-kek.md +0 -37
  608. package/knowledge/decisions/security/cors-defaults-to-any-origin-and-refuses-the-wildcard-with-credentials.md +0 -22
  609. package/knowledge/decisions/security/credential-backends-share-one-conformance-suite-for-per-user-isolation.md +0 -29
  610. package/knowledge/decisions/security/each-stage-has-one-virtual-user-key-pair.md +0 -27
  611. package/knowledge/decisions/security/gateway-handlers-run-through-the-function-runner-gate.md +0 -41
  612. package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +0 -30
  613. package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +0 -40
  614. package/knowledge/decisions/security/hmac-verification-fails-closed-on-empty-inputs.md +0 -25
  615. package/knowledge/decisions/security/http-error-detail-is-withheld-from-clients-in-production.md +0 -33
  616. package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +0 -46
  617. package/knowledge/decisions/security/index.md +0 -135
  618. package/knowledge/decisions/security/local-content-refuses-private-buckets-under-the-public-segment.md +0 -21
  619. package/knowledge/decisions/security/mail-is-allowlisted-before-a-virtual-user-run-sees-it.md +0 -38
  620. package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +0 -27
  621. package/knowledge/decisions/security/mcp-resources-tools-and-prompts-take-sessionless-functions.md +0 -18
  622. package/knowledge/decisions/security/origin-locked-routes-match-the-origin-exactly.md +0 -22
  623. package/knowledge/decisions/security/oss-auth-works-without-pikku-studio-cloud.md +0 -26
  624. package/knowledge/decisions/security/outbound-webhooks-use-an-allowlist-when-configured.md +0 -24
  625. package/knowledge/decisions/security/passphrases-are-stretched-key-material-is-expanded.md +0 -40
  626. package/knowledge/decisions/security/permission-auth-filtering-requires-live-permission-functions.md +0 -31
  627. package/knowledge/decisions/security/pikku-carries-virtual-user-scopes-as-data-and-the-app-grants-them.md +0 -35
  628. package/knowledge/decisions/security/queue-job-identities-are-signed-at-enqueue.md +0 -69
  629. package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +0 -39
  630. package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +0 -34
  631. package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +0 -55
  632. package/knowledge/decisions/security/scenario-step-functions-are-never-externally-invocable.md +0 -30
  633. package/knowledge/decisions/security/scope-resolution-happens-at-the-session-boundary-and-sync-never-deletes.md +0 -28
  634. package/knowledge/decisions/security/scoped-content-access-is-a-root-folder-with-longest-prefix-grants.md +0 -31
  635. package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +0 -34
  636. package/knowledge/decisions/security/services-without-secrets-get-a-throwing-secrets-accessor.md +0 -22
  637. package/knowledge/decisions/security/shared-guards-refuse-to-mutate-or-shadow-a-system-role.md +0 -34
  638. package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +0 -37
  639. package/knowledge/decisions/security/signed-uploads-are-verified-by-the-same-check-as-signed-reads.md +0 -26
  640. package/knowledge/decisions/security/system-role-scopes-must-be-declared-with-define-scope.md +0 -24
  641. package/knowledge/decisions/security/system-roles-are-additive-and-immutable.md +0 -16
  642. package/knowledge/decisions/security/the-channel-rpc-does-not-send-the-callers-session.md +0 -21
  643. package/knowledge/decisions/security/the-remote-jobs-inbox-fails-closed-without-a-secret.md +0 -24
  644. package/knowledge/decisions/security/the-remote-rpc-gate-fails-closed-and-binds-the-token-to-its-function.md +0 -34
  645. package/knowledge/decisions/security/the-workflow-status-stream-rechecks-ownership-on-every-poll.md +0 -16
  646. package/knowledge/decisions/security/two-credentials-on-one-key-must-share-a-read-mode.md +0 -29
  647. package/knowledge/decisions/security/verified-bearer-claims-are-pass-through-data-that-core-never-fills.md +0 -23
  648. package/knowledge/decisions/security/virtual-user-catalogue-excludes-the-machinery-that-runs-virtual-users.md +0 -25
  649. package/knowledge/decisions/security/virtual-user-conversation-missing-approval-decisions-default-to-denied.md +0 -22
  650. package/knowledge/decisions/security/virtual-user-run-records-are-gated-behind-a-read-scope.md +0 -18
  651. package/knowledge/decisions/security/virtual-user-sign-in-does-not-exist-in-production.md +0 -25
  652. package/knowledge/decisions/security/virtual-user-sign-in-has-one-door.md +0 -42
  653. package/knowledge/decisions/security/virtual-user-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +0 -29
  654. package/knowledge/decisions/security/virtual-user-sign-in-only-works-for-virtual-user-flagged-users.md +0 -29
  655. package/knowledge/decisions/security/webhook-bodies-are-signed-before-they-are-enqueued.md +0 -25
  656. package/knowledge/decisions/security/wire-addon-expose-selects-the-rpc-surface.md +0 -51
  657. package/knowledge/decisions/security/workflow-approval-payloads-are-validated-on-replay-inside-the-workflow.md +0 -40
  658. package/knowledge/decisions/security/workflow-helper-functions-are-sessionless-by-declaration.md +0 -18
  659. package/knowledge/decisions/security/workflow-queued-steps-rehydrate-their-session-from-the-run-wire.md +0 -32
  660. package/knowledge/decisions/security/workflow-scenario-sessions-are-isolated-per-virtual-user-and-per-scenario.md +0 -32
  661. package/knowledge/decisions/security/workflow-scenario-steps-are-never-network-invocable.md +0 -31
  662. package/knowledge/decisions/security/workflow-virtual-user-steps-always-use-the-real-transport.md +0 -34
  663. package/knowledge/decisions/security/writing-a-virtual-user-schedule-is-gated-by-its-own-scope.md +0 -18
  664. package/knowledge/index.md +0 -24
  665. package/knowledge/questions/a-bearer-jwt-with-no-identity-becomes-a-session.md +0 -24
  666. package/knowledge/questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md +0 -35
  667. package/knowledge/questions/dev-quick-login-as-impersonation.md +0 -25
  668. package/knowledge/questions/does-a-delayed-rpc-run-as-the-session-it-was-scheduled-with.md +0 -26
  669. package/knowledge/questions/does-a-user-id-with-a-colon-read-another-users-credentials.md +0 -27
  670. package/knowledge/questions/does-a-wirecli-command-need-a-session-by-default.md +0 -26
  671. package/knowledge/questions/does-an-adversarial-in-scope-success-count-as-a-finding.md +0 -26
  672. package/knowledge/questions/does-approve-step-need-the-run-owners-session-or-the-gates-approvers.md +0 -34
  673. package/knowledge/questions/does-cors-origin-true-reflect-any-origin-with-credentials.md +0 -20
  674. package/knowledge/questions/does-skip-user-session-do-anything-on-a-channel.md +0 -24
  675. package/knowledge/questions/does-the-store-session-match-the-other-two.md +0 -19
  676. package/knowledge/questions/index.md +0 -41
  677. package/knowledge/questions/is-the-agent-score-worker-reachable-without-a-session.md +0 -21
  678. package/knowledge/questions/live-scheduled-tests-may-write.md +0 -19
  679. package/knowledge/questions/provision-virtual-users-has-no-caller-in-this-repo.md +0 -23
  680. package/knowledge/questions/remote-secret-refuses-requests-without-a-remote-token-on-every-path.md +0 -32
  681. package/knowledge/questions/should-a-middleware-set-session-persist-to-the-store.md +0 -25
  682. package/knowledge/questions/should-a-scoped-secret-view-throw-from-has-secret-for-a-disallowed-key.md +0 -23
  683. package/knowledge/questions/should-a-wrong-bearer-token-be-anonymous-or-refused.md +0 -35
  684. package/knowledge/questions/should-an-empty-webhook-signing-secret-send-unsigned.md +0 -23
  685. package/knowledge/questions/should-http-virtual-user-sessions-reset-between-scenarios-in-one-run.md +0 -27
  686. package/knowledge/questions/should-the-cookie-jar-scope-cookies-to-the-api-origin.md +0 -26
  687. package/knowledge/questions/should-voice-input-fetch-audio-urls-without-a-host-allowlist.md +0 -20
  688. package/knowledge/questions/staging-impersonation-rules.md +0 -27
  689. package/knowledge/questions/unauthorized-channel-replies-escape-the-declared-out-type.md +0 -44
  690. package/knowledge/questions/virtual-user-keys-on-cloud-stages-are-pikku-studios-to-build.md +0 -33
  691. package/knowledge/questions/virtual-user-statement-replay-is-per-process.md +0 -20
  692. package/knowledge/questions/what-an-impersonated-session-carries.md +0 -22
  693. package/run-tests.sh +0 -68
  694. package/scripts/generate-api-report.d.mts +0 -1
  695. package/scripts/generate-api-report.mjs +0 -96
  696. package/scripts/generate-api-report.mts +0 -333
  697. package/src/public-surface.json +0 -637
  698. package/src/public-surface.json.README +0 -43
  699. /package/dist/{function/compensation-name.d.ts → compensation-name.d.ts} +0 -0
  700. /package/dist/{function/compensation-name.js → compensation-name.js} +0 -0
@@ -1,42 +0,0 @@
1
- ---
2
- type: decision
3
- title: Virtual user sign-in has one door, reached two ways
4
- description: Only the app's virtual user sign-in handler creates a virtual user session; runs reach it in-process and everything else reaches it with a signed statement
5
- tags: services
6
- ---
7
-
8
- # Virtual user sign-in has one door, reached two ways
9
-
10
- The `signIn` closure in the Better Auth virtual user plugin
11
- (`packages/services/better-auth/src/virtual-user-plugin.ts`) is the only thing that
12
- creates a virtual user session. It refuses any user row not flagged `virtualUser`,
13
- creates a row only under `pikku dev` (`mayProvision`), and sets the session cookie.
14
- Every route below ends in it; nothing else mints a session for a virtual user.
15
-
16
- **Runs go in-process.** A run — started by a person, or by the scheduled tick as
17
- `pikku-platform` holding only `virtualUser:run` — already executes inside the app, so
18
- it has nothing to prove to itself. It calls `auth.api.signInVirtualUserInternal`, an
19
- endpoint marked `metadata: { SERVER_ONLY: true }`: better-call leaves it out of the
20
- router, so `auth.handler` answers 404 for its path while `auth.api` can still call it.
21
- The seam is `services.auth`, which core already types structurally, so core imports
22
- nothing from Better Auth and a project without it gets an error that says so.
23
-
24
- **Everything outside the app presents a signed statement** — see
25
- [an external caller presents one signed statement](an-external-virtual-user-caller-presents-one-signed-statement.md).
26
- That covers the dev switcher, `pikku scenario run`, `pikku virtual-user run` and
27
- `rpc`, `pikku pages screenshot --as`, and the Playwright provider.
28
-
29
- Two choices fall out of this and are deliberate:
30
-
31
- - **Cookie, not bearer.** The run takes the `Set-Cookie` values from the in-process
32
- call into the cookie jar core already has, then drives the app over HTTP with it.
33
- Apps do not register Better Auth's bearer plugin and this does not make them.
34
- - **A public URL, not a service binding.** The run is a queue worker unit and the
35
- existing bindings carry RPC, not HTTP. It reads `VIRTUAL_USER_API_URL` from
36
- variables; `pikku dev` sets it once the port is bound, and a stage's deployer sets it
37
- there. A missing value fails the run naming the variable. The same variable works on
38
- a dev machine, a node box and a Worker.
39
-
40
- **What this rules out:** a second sign-in route with its own checks, a credential that
41
- is shared with, or derived for, a caller inside the app, and a bearer token handed
42
- back to a run.
@@ -1,29 +0,0 @@
1
- ---
2
- type: decision
3
- title: Virtual user sign-in is proven by Set-Cookie, not a non-empty jar
4
- description: HttpVirtualUser tracks its own signedIn flag and both VirtualUserSignIn implementations require the sign-in response itself to set a cookie, because a populated jar proves nothing
5
- tags: services
6
- ---
7
-
8
- # Virtual user sign-in is proven by Set-Cookie, not a non-empty jar
9
-
10
- `HttpVirtualUser` (`packages/core/src/services/http-virtual-users.ts`) keeps a
11
- private `signedIn` boolean rather than inferring the session from its cookie
12
- jar. Both `VirtualUserSignIn` implementations in
13
- `packages/core/src/services/virtual-user-sign-in.ts` — `statementSignIn` and
14
- `inProcessSignIn` — throw when the sign-in response carries no `Set-Cookie`
15
- header, even though the response was a 2xx.
16
-
17
- A cookie jar cannot answer "did sign-in happen". A target app may set a cookie on
18
- any request — a CSRF token, an anonymous session, a locale — so a non-empty jar
19
- after a failed or skipped sign-in looks exactly like a successful one. What
20
- actually proves a session was established is _this_ response setting a cookie. A
21
- 2xx alone is not enough either: an endpoint that returns 200 while quietly
22
- declining to issue a session would leave the virtual user running every subsequent
23
- request unauthenticated, and the scenario would report the resulting refusals as
24
- genuine permission failures.
25
-
26
- **What this rules out:** replacing `signedIn` with a `jar.isEmpty()` check,
27
- dropping the `getSetCookie().length === 0` guard as redundant with `res.ok`, and
28
- treating `signOut()` as jar-clearing only — it must reset the flag too, or the
29
- next call proceeds believing it has a session.
@@ -1,29 +0,0 @@
1
- ---
2
- type: decision
3
- title: Virtual user sign-in only works for virtual-user-flagged users
4
- description: A virtual user statement mints sessions for user rows flagged virtual user and nothing else, so holding one never impersonates a real user
5
- tags: services
6
- ---
7
-
8
- # Virtual user sign-in only works for virtual-user-flagged users
9
-
10
- A statement or an in-process call signs in only user rows flagged `virtualUser: true`
11
- (see [virtual user sign-in has one door](virtual-user-sign-in-has-one-door.md)). That
12
- could look like a master key, and it deliberately is not one — for two independent
13
- reasons.
14
-
15
- The first is the flag. The Better Auth virtual user plugin upserts and signs in only
16
- rows flagged `virtualUser: true`. A statement naming a real customer's address does not
17
- mint that customer's session — it is refused. The flag also flows into the minted
18
- session, so audits and analytics can tell scenario traffic from human traffic.
19
-
20
- The second is that a statement names one virtual user: `sub` must be a declared virtual
21
- user, and it expires and is accepted once — see
22
- [an external caller presents one signed statement](an-external-virtual-user-caller-presents-one-signed-statement.md).
23
- A leaked statement opens one synthetic account for a few minutes, not the population.
24
-
25
- **What this rules out:** widening the sign-in endpoint to accept any email "so
26
- scenarios can test as a real user", and treating a statement as
27
- equivalent to a session-signing key. It also rules out dropping the `virtualUser` flag
28
- from the minted session — the audit trail's ability to separate synthetic from
29
- real activity depends on it.
@@ -1,25 +0,0 @@
1
- ---
2
- type: decision
3
- title: Webhook bodies are signed before they are enqueued
4
- description: QueueWebhookService computes the HMAC at enqueue time so the signing key never travels in the queue payload
5
- tags: services
6
- ---
7
-
8
- # Webhook bodies are signed before they are enqueued
9
-
10
- `QueueWebhookService.prepareDelivery`
11
- (`packages/core/src/services/queue-webhook-service.ts`) serialises the payload,
12
- resolves the signing secret, computes the signature and writes it into the job's
13
- `headers` — all before `queueService.add` is called. The worker,
14
- `pikkuWebhookWorkerFunc`, POSTs headers it was handed and never sees a secret.
15
-
16
- Signing in the worker instead would mean the key has to reach the worker, and the
17
- only channel between the two is the queue payload: an SQS body, a Redis value, a
18
- `jsonb` column, all of which are at rest, replicated, and visible to anyone who
19
- can read the queue. The signature is not sensitive; the key is.
20
-
21
- **What this rules out:** moving signing into the worker so it can re-sign on
22
- retry, and putting `secret` (or a resolved key of any kind) onto `WebhookJobData`.
23
- Note the related consequence: because the signature is fixed at enqueue time, a
24
- key rotated between enqueue and delivery does not change an in-flight job's
25
- signature — that is intended, not a bug to fix by carrying the key.
@@ -1,51 +0,0 @@
1
- ---
2
- type: decision
3
- title: wireAddon expose selects the RPC surface, and a list may widen it
4
- description: The consuming app decides which addon functions rpc.exposed reaches per instance — unset keeps the addon's own expose, false closes the instance, a list names exactly what is callable — and the deploy analyzer applies the same rule
5
- tags: addon, rpc, expose, authorization
6
- ---
7
-
8
- # wireAddon expose selects the RPC surface, and a list may widen it
9
-
10
- `rpc.exposed('<name>:<fn>')` — what the generated `POST /rpc/:rpcName` forwards
11
- to — used to consult only the addon's own `expose: true`. The app installing the
12
- addon had no say: it could not close an addon whose author marked functions
13
- exposed, and it could not open one the author had not. `mcp` already worked the
14
- other way (the wiring decides), and the two now match.
15
-
16
- `expose` on `wireAddon` is `boolean | string[]`, resolved per instance by
17
- `isAddonFunctionExposed`:
18
-
19
- - **unset or `true`** — the addon's declaration decides, as before. Keeping the
20
- default unchanged means no existing app gains or loses a route on upgrade.
21
- - **`false`** — nothing in this instance is reachable through `rpc.exposed`.
22
- - **a list** — exactly those functions, whether or not the addon declared them.
23
- The list can widen the addon's surface, the same power `mcp` has, because the
24
- app is the one that knows what its deployment should offer. The generated
25
- `#pikku/addon` types the list against the package's function names, and a name
26
- that survives to the build unpublished fails it with PKU343.
27
- The value has to be written inline (`true`, `false` or an array of string
28
- literals): the build reads it statically, and a variable or spread fails it
29
- with PKU344 rather than being read as unset, which would leave the deploy
30
- units disagreeing with the runtime.
31
-
32
- The decision is per **instance**, not per package: two `wireAddon` calls for one
33
- package may expose different things, and the gate reads the config the
34
- namespace resolved to.
35
-
36
- The deploy analyzer's per-addon unit applies the same rule, since that unit is
37
- what the dispatcher can forward to. A function the wiring refuses gets no unit
38
- and no dispatch entry, so the `deploymentService` fallback in `rpc.exposed` —
39
- which forwards namespaced names with no local metadata — has nothing to reach.
40
- Where the dispatcher does hold the wiring, it also refuses locally before
41
- forwarding.
42
-
43
- `expose` is reachability, not authorization. A listed function still runs
44
- through `runPikkuFunc` with its own `auth`, permissions and the instance's
45
- `auth`/`scopes`/`tags` — see
46
- [addon auth and tags](./addon-auth-and-tags-only-tighten.md). Widening the list
47
- to a sessionless function makes it public unless one of those gates it.
48
-
49
- **What this rules out:** letting the addon's `expose: true` override a wiring's
50
- `false`; treating an unknown list entry as a silent no-op; and a deploy unit
51
- that carries functions the runtime gate would refuse.
@@ -1,40 +0,0 @@
1
- ---
2
- type: decision
3
- title: An approval decision is stored raw and validated on replay, and an invalid one closes the gate rather than failing the run
4
- description: The schema only exists inside the workflow body, and letting an external payload fail the run would let any caller kill a workflow
5
- tags: workflow
6
- ---
7
-
8
- # An approval decision is stored raw and validated on replay, and an invalid one closes the gate rather than failing the run
9
-
10
- `approveStep` in `pikku-workflow-service.ts` is called from outside the workflow
11
- — an HTTP route, an RPC — where the approval's schema value is not in scope. It
12
- therefore stores the decision payload raw in run state and does nothing else.
13
- Validation happens on replay inside `approvalStep`, in the workflow body, which
14
- is the only place the schema exists.
15
-
16
- When validation fails, the bad decision is dropped, the issues are recorded on
17
- the gate's state record, and a `WorkflowSuspendedException` re-closes the gate.
18
- The failure stays legible to whoever tries next, and — the security point —
19
- failing the run instead would let any caller kill a workflow with a malformed
20
- payload. A later valid decision still lands normally.
21
-
22
- `WorkflowApprovalOptions.schema` is a VALUE, not a type generic, for the same
23
- reason: the payload arrives from an untrusted caller over the approve wire, and
24
- a generic is erased at compile time, so it would validate nothing. Any
25
- standard-schema library (zod, valibot, arktype) satisfies it. The contract is
26
- the `~standard` spec and nothing more: `@pikku/core` deliberately carries no
27
- zod dependency, which is why `pikku-workflow-service.test.ts` hand-rolls a
28
- minimal `StandardSchemaV1` rather than importing a validation library.
29
-
30
- A decision arriving for a gate that has already resolved is rejected with
31
- `WorkflowApprovalResolvedError` (409) rather than accepted and dropped. The gate
32
- caches its outcome as the step result and never re-reads run state, so a
33
- decision recorded after resolution could not take effect — most obviously when
34
- it loses the race with expiry — and the approver has to be told their decision
35
- did not land.
36
-
37
- **What this rules out:** validating in `approveStep` (the schema is not there),
38
- failing the run on an invalid payload, turning `schema` into a type parameter,
39
- accepting a decision on a resolved gate, or making a resolved gate re-read run
40
- state so a late decision "wins".
@@ -1,18 +0,0 @@
1
- ---
2
- type: decision
3
- title: Workflow helper functions are registered sessionless by declaration
4
- description: Queue-worker helpers and the workflow sleeper get meta with sessionless true, so the runner requires a session for them only where their own auth flag says so
5
- tags: core, workflow, queue, sessions
6
- ---
7
-
8
- # Workflow helper functions are registered sessionless by declaration
9
-
10
- `helperFunctionMeta` in `packages/core/src/wirings/workflow/workflow-queue-wiring.ts` returns the function meta for internal workflow helpers. It sets `sessionless: true` and `functionType: 'helper'`, and sets no `expose` flag (`workflow-queue-wiring.ts:19-25`).
11
-
12
- It is applied to each queue worker function that has no meta yet (`workflow-queue-wiring.ts:66-68`), and to the built-in `pikkuWorkflowSleeper` (`workflow-queue-wiring.ts:122-129`).
13
-
14
- With `sessionless` set, the runner requires a session only when the wiring, the function config, or the addon says `auth: true` (`packages/core/src/function/function-runner.ts:385-395`). The helpers therefore run without a session unless one of those says otherwise.
15
-
16
- The helpers are internal. Their safety rests on the absence of `expose`, and on the scenario and workflow rules that keep such functions off the network surface ([scenario-step functions are never externally invocable](scenario-step-functions-are-never-externally-invocable.md)).
17
-
18
- **What this rules out:** declaring a function that acts on a user's behalf as a workflow helper to skip its session requirement, and exposing a helper over RPC by adding `expose` to its meta.
@@ -1,32 +0,0 @@
1
- ---
2
- type: decision
3
- title: A queued workflow step rehydrates its session from the persisted run wire
4
- description: The queue job payload is just `{ runId }`, so without threading `pikkuUserId` an authed step sees no session and throws
5
- tags: workflow
6
- ---
7
-
8
- # A queued workflow step rehydrates its session from the persisted run wire
9
-
10
- A queued workflow step is executed with the bare job wire — the payload is just
11
- `{ runId }` (or `{ runId, stepName, rpcName, data, fromStepName }`) — so it
12
- carries no `pikkuUserId`. `invokeStepRpc` in `pikku-workflow-service.ts`
13
- therefore merges the run's own `wire.pikkuUserId` into the step wire override
14
- before calling `rpcWithWire`. Without it, a step written as an authed
15
- `pikkuFunc` sees no session and fails with "Authentication required" on the
16
- queued path while passing inline, which is the worst possible split: it looks
17
- like a transport bug rather than an auth one.
18
-
19
- `invokeStepRpc` is shared by the queue executor and the inline executor
20
- precisely so the two cannot drift. The only thing that differs between
21
- transports is who calls it, not the call itself. `createWorkflowWire` and
22
- `runWorkflowJobInner` propagate the same `pikkuUserId` onto the workflow wire
23
- for the workflow body.
24
-
25
- The user id is the only identity carried. It is a reference for credential
26
- resolution, not a serialized session — the session itself is rehydrated on the
27
- far side.
28
-
29
- **What this rules out:** giving the queued path its own invocation helper,
30
- dropping the `pikkuUserId` merge because "the wire already has a session"
31
- inline, or widening the run wire to persist session tokens instead of a user id
32
- reference.
@@ -1,32 +0,0 @@
1
- ---
2
- type: decision
3
- title: Scenario sessions are isolated per virtual user and reset between scenarios
4
- description: One jar per virtual user keeps two virtual users from sharing a session; a browser reset keeps one scenario from leaving the next signed in as somebody else
5
- tags: workflow
6
- ---
7
-
8
- # Scenario sessions are isolated per virtual user and reset between scenarios
9
-
10
- `createCookieJar` in `services/scenario-cookie-jar.ts` holds its `Map` as a closure
11
- local, so two jars can never share a session. That is precisely what lets one
12
- scenario sign in as several people without one of them inheriting another's
13
- session. Every response is read, not just the sign-in, so a cookie the target
14
- rotates mid-session is followed rather than dropped, and an empty `Set-Cookie`
15
- value is treated as a deletion — the name is dropped rather than held as a
16
- cookie whose value says it is gone. The jar also stamps `Origin`, because Better
17
- Auth rejects a state-changing POST whose Origin does not match its baseURL.
18
-
19
- `ScenarioCookieJar.empty` reports a fact about the jar, not about the session: a
20
- target that sets a CSRF or locale cookie before anyone signs in fills the jar
21
- without establishing a session. Anything needing to know whether a sign-in
22
- happened has to track the sign-in itself.
23
-
24
- The browser side has the same requirement. `ScenarioBrowserProvider.reset`
25
- discards every virtual user's per-scenario state — cookies, storage, open pages — while
26
- keeping the browser, and is called between scenarios so one scenario cannot
27
- leave the next signed in as somebody else.
28
-
29
- **What this rules out:** hoisting the jar to a module-level or per-service map,
30
- sharing one jar across virtual users, reading `Set-Cookie` only from the sign-in
31
- response, treating `empty === false` as "signed in", or skipping `reset` between
32
- scenarios as an optimisation.
@@ -1,31 +0,0 @@
1
- ---
2
- type: decision
3
- title: A scenario step is never registered as a callable RPC and never dispatched on the queue
4
- description: A step drives a browser and holds a virtual user's session, so exposing it as an RPC would put that reach on the network
5
- tags: workflow
6
- ---
7
-
8
- # A scenario step is never registered as a callable RPC and never dispatched on the queue
9
-
10
- `ScenarioStepMeta` in `dsl/workflow-dsl.types.ts` is a distinct meta type from
11
- `RpcStepMeta` on purpose. A scenario step runs locally through `runPikkuFunc`
12
- and must never be treated as dispatchable on the queue or replay path, nor
13
- registered as a callable RPC — a browser-driving step must not be
14
- network-invocable. It executes with a browser handle and a virtual user's
15
- authenticated session in hand; exposed as an RPC it would hand a remote caller
16
- that reach.
17
-
18
- `PikkuScenarioService.scenarioStep` reflects this at runtime: it always runs
19
- through `engine.inlineStep` with `runPikkuFunc`, never through `rpcStep`, so no
20
- transport is involved. A step declaring `browser: true` is refused outright
21
- unless both a browser provider is registered and a virtual user was supplied, with an
22
- error saying which is missing.
23
-
24
- Scenario steps are also modelled as sessionless pikku functions (see
25
- `scenario-step.test.ts`) because a step is driven by a virtual user, not by a wire
26
- session.
27
-
28
- **What this rules out:** collapsing `ScenarioStepMeta` into `RpcStepMeta`,
29
- registering step functions in the RPC map so they "can be tested directly",
30
- routing a scenario step through `rpcStep`/`dispatchStep`, or defaulting a
31
- `browser: true` step to run without a virtual user.
@@ -1,34 +0,0 @@
1
- ---
2
- type: decision
3
- title: A scenario virtual user step always goes over the real transport and never through internal dispatch
4
- description: Internal dispatch would bypass auth middleware and permissions, turning a scenario into a green health check that proves nothing
5
- tags: workflow
6
- ---
7
-
8
- # A scenario virtual user step always goes over the real transport and never through internal dispatch
9
-
10
- When a workflow step carries `options.virtualUser`, `rpcStep` in
11
- `pikku-workflow-service.ts` calls `virtualUser.invoke(rpcName, data)` — the virtual user's
12
- authenticated client, over the real network transport — and never falls back to
13
- internal dispatch. Internal dispatch skips auth middleware and permission
14
- checks, so a scenario that "passed" that way would prove only that the function
15
- body runs, not that the virtual user is allowed to run it. That is a green health
16
- check for a system that may be wide open.
17
-
18
- For the same reason, virtual user steps never queue: `rpcStep` short-circuits
19
- `dispatchStep` to `false` whenever `options.virtualUser` is set. A virtual user step is an
20
- outbound HTTP call made by the runner itself, and the virtual user's session lives in
21
- this process — a queued worker in another process would have no session to make
22
- it with. The step is still recorded durably like any RPC step, so replay and
23
- reporting are unaffected.
24
-
25
- Virtual user identity is process-local by nature. `PikkuScenarioService.runVirtualUsers` maps
26
- run id to live authenticated clients (cookie jars), and those ride that map
27
- only, never the persisted run wire — a serialized session on a durable run row
28
- would be a credential at rest.
29
-
30
- **What this rules out:** adding an "internal dispatch is faster" fast path for
31
- virtual user steps, routing a virtual user step through the queue, serializing virtual user sessions
32
- onto the run wire, or letting `virtualUser.invoke` degrade to `rpcWithWire` when the
33
- transport is unavailable. Each turns an end-to-end authorization test into one
34
- that cannot fail.
@@ -1,18 +0,0 @@
1
- ---
2
- type: decision
3
- title: Writing a virtual user schedule is gated by its own scope, separate from running one
4
- description: setVirtualUserSchedule carries virtualUser:schedule, because a schedule write spends money on every future tick while a run spends it once with a caller watching
5
- tags: core, cli, virtual-users, scopes, security
6
- ---
7
-
8
- # Writing a virtual user schedule is gated by its own scope, separate from running one
9
-
10
- `packages/core/src/wirings/virtual-user/virtual-user-schedule-store.ts` defines the store that keeps a virtual user's cadence. Its SECURITY note says a written row "spends money on every future tick, without a caller present to see it happen", and that the scaffold therefore "gates writes behind a scope of their own" (`virtual-user-schedule-store.ts:60-63`). Reading findings is "a much smaller permission than deciding they should keep going" (`virtual-user-schedule-store.ts:62-63`).
11
-
12
- The gate is generated by the CLI. `packages/cli/src/functions/wirings/virtual-user/serialize-virtual-user-functions.ts` emits `setVirtualUserSchedule` with `scopes: ['virtualUser:schedule']` (line 456), with a comment saying a run "spends money once with a caller present to see it, while writing a schedule spends it repeatedly with nobody there". `listVirtualUserSchedules` needs only `virtualUser:read` (line 477). The tests assert the scope in `virtual-user-functions.test.ts:66`.
13
-
14
- A scheduled tick has no caller. It runs as the reserved `pikku-platform` principal, whose session carries only `virtualUser:run` (`packages/cli/src/functions/wirings/virtual-user/serialize-virtual-user-functions.ts:510-519`), so a tick can start a run and cannot write a schedule.
15
-
16
- The store's own design is related. `claim` is a compare-and-set on `nextRunAt`, so two processes on the same cron cannot both dispatch the same virtual user (`virtual-user-schedule-store.ts:78-91`). Its doc says a second dispatch would mean "the same user acting twice over, at twice the budget" (`virtual-user-schedule-store.ts:82-86`).
17
-
18
- **What this rules out:** letting a caller who can read runs also create or change a schedule, and treating a schedule write as the same permission as a run.
@@ -1,24 +0,0 @@
1
- ---
2
- type: overview
3
- title: Knowledge
4
- description: Why @pikku/core is built the way it is — the reasoning that used to live in comments
5
- ---
6
-
7
- # Knowledge
8
-
9
- Pikku's source says _what_ it does. These notes say _why_, for the handful of
10
- choices where the code alone reads as arbitrary or, worse, reads as a mistake.
11
-
12
- The rule that produced this directory: **reasoning never lives in code.** A
13
- comment that restates the line below it is deleted. A comment that records a
14
- decision — a constraint, a trade-off, a thing that was tried and failed — moves
15
- here and gets a name, so it can be linked to and argued with.
16
-
17
- Everything mechanical is generated or inspectable: the wirings, the schemas, the
18
- meta files, the export surface. A note that repeats them is a copy that will
19
- drift.
20
-
21
- <!-- pikku:knowledge-index -->
22
- - [decisions](decisions/index.md) — a rule that was chosen, and what it rules out
23
- - [questions](questions/index.md) — something asked and not yet answered
24
- <!-- /pikku:knowledge-index -->
@@ -1,24 +0,0 @@
1
- ---
2
- type: question
3
- title: Does a bearer JWT with no identity claim count as a session?
4
- description: The cookie middleware refuses an identity-less JWT, but authBearer sets whatever decode returns, so the two paths disagree
5
- tags: core, auth, middleware
6
- ---
7
-
8
- # Does a bearer JWT with no identity claim count as a session?
9
-
10
- `authCookie` (`packages/core/src/middleware/auth-cookie.ts`) only sets a session
11
- when `hasSessionIdentity` is true, meaning the decoded payload has a key that is
12
- not a registered JWT claim. Its test comment says a JWT of an absent session
13
- still decodes to a truthy `{ iat, exp }` that "the runner accepts", and it guards
14
- against that.
15
-
16
- `authBearer` (`packages/core/src/middleware/auth-bearer.ts`) has no such check.
17
- In JWT mode it calls `jwtService.decode(bearerToken)` and calls `setSession` on
18
- any truthy result. Its test only covers a `null` decode.
19
-
20
- What is asked: should a bearer token that decodes to `{ iat, exp }` alone be
21
- treated as anonymous, as the cookie path does, or as an authenticated session?
22
- Current behaviour: it becomes the request session. Whether a signed token of that
23
- shape can be minted is not checked in core, because the `JWTService`
24
- implementation is not in this package.
@@ -1,35 +0,0 @@
1
- ---
2
- type: question
3
- title: A channel's middleware list accepts bare factories that nothing ever resolves
4
- description: CoreChannel.channelMiddleware admits CorePikkuChannelMiddlewareFactory, but no runner calls one, so a bare factory would stall the chain
5
- tags: core, channel
6
- ---
7
-
8
- # A channel's middleware list accepts bare factories that nothing resolves
9
-
10
- `CoreChannel.channelMiddleware` is typed as
11
- `(CorePikkuChannelMiddleware | CorePikkuChannelMiddlewareFactory)[]`, but
12
- `runPikkuFunc`'s `wireChannelMiddleware` parameter admits only
13
- `CorePikkuChannelMiddleware[]`. The two call sites that bridge them —
14
- `channel-common.ts` and `channel-handler.ts` — assert across the gap.
15
-
16
- A factory is `(input: In) => CorePikkuChannelMiddleware`: the author is meant to
17
- _call_ it at wiring time and put the result in the array.
18
- `combineChannelMiddleware` contains no factory-resolution branch, and neither
19
- does `combineMiddleware` for ordinary middleware — that is consistent and
20
- deliberate. So a bare, uncalled factory in `channelMiddleware` would be pushed
21
- into the chain and then invoked as if it were middleware: it would receive
22
- `(services, channel, next)` as its single `input` argument, return a middleware
23
- function that nothing runs, and never call `next` — stalling the chain silently.
24
-
25
- Nothing in this repository puts a bare factory there, so the failure is
26
- hypothetical today. The type is what invites it.
27
-
28
- **What would settle it:** deciding whether `channelMiddleware` should accept
29
- only resolved middleware — in which case the union is simply wrong and should
30
- lose its factory arm, and both assertions disappear — or whether the runner
31
- should resolve factories, in which case `combineChannelMiddleware` needs a
32
- branch and the ordinary middleware path probably needs the matching one.
33
-
34
- Until then the assertions name the exact target type rather than `as any`, so
35
- the gap is visible at both call sites.
@@ -1,25 +0,0 @@
1
- ---
2
- type: question
3
- title: Can dev quick login become impersonation?
4
- description: Dev quick login signs in a fixed admin account; making it an impersonation step needs an existing admin session it does not have, so it would need a new bypass
5
- tags: auth, services
6
- ---
7
-
8
- # Can dev quick login become impersonation?
9
-
10
- Today `/dev/quick-login` (`packages/services/better-auth/src/dev-quick-login.ts`)
11
- provisions a fixed `admin@pikku.dev` account with a fixed password and grants it
12
- the admin and console roots. It is refused outside loopback, behind a proxy, and
13
- in production.
14
-
15
- The proposal is that quick login should just be impersonation. Impersonation
16
- (`resolveImpersonatedSession`) only applies on top of an existing session, and
17
- the caller must hold `admin:impersonate`. Quick login has no session before it
18
- runs, so making it impersonation needs one of:
19
-
20
- - an unauthenticated dev-only route that accepts a user id, which is a new
21
- bypass of the check that impersonation exists to keep, or
22
- - quick login keeps minting the dev admin session, and virtual users are
23
- impersonated from there.
24
-
25
- The second keeps one mechanism for virtual users. Undecided.
@@ -1,26 +0,0 @@
1
- ---
2
- type: question
3
- title: Does a delayed RPC run as the session it was scheduled with?
4
- description: The in-memory scheduler stores the session it is given and returns it from getTask, but the delayed run invokes the RPC with no session
5
- tags: core, scheduler, sessions
6
- ---
7
-
8
- # Does a delayed RPC run as the session it was scheduled with?
9
-
10
- The contract takes an optional session. `SchedulerService.scheduleRPC` in
11
- `packages/core/src/services/scheduler-service.ts:19-24` accepts `session`, and
12
- `ScheduledTaskInfo` exposes it (`:9-13`).
13
-
14
- The in-memory implementation in `packages/schedule/src/in-memory-scheduler-service.ts`
15
- accepts it (`:41-46`), stores it on the delayed task (`:85-92`), and returns it from
16
- `getTask` (`:107-118`). The timer callback runs `rpc.invoke(rpcName, data)` on a
17
- context built with an empty wire (`:69-75`). The session is not passed to that
18
- call, and the file does not read it on the run path.
19
-
20
- The comment at `:67-68` says the BullMQ and pg-boss schedulers enqueue
21
- `{ rpcName, data, session }` and invoke the RPC with it. This file does not do so.
22
- The caller in the workflow sleeper passes no session (`packages/core/src/wirings/workflow/pikku-workflow-service.ts:852-856`).
23
-
24
- **Question:** should a delayed RPC run under the session captured at scheduling
25
- time, as the comment describes for the other schedulers, or run with none? The
26
- code stores the session, reports it, and does not use it.
@@ -1,27 +0,0 @@
1
- ---
2
- type: question
3
- title: Can a user id containing a colon read another user's credentials?
4
- description: LocalCredentialService joins user id and name with a colon and matches users by prefix, so an id containing a colon may collide with another user's keys
5
- tags: core, credentials, local-dev, isolation
6
- ---
7
-
8
- # Can a user id containing a colon read another user's credentials?
9
-
10
- `packages/core/src/services/local-credential-service.ts` stores each credential
11
- under the key `userId:name`, or just `name` when there is no user
12
- (`local-credential-service.ts:6-8`).
13
-
14
- `getAll(userId)` returns every key that starts with `${userId}:`, and strips that
15
- prefix to get the credential name (`local-credential-service.ts:31-39`). If one
16
- user's id contains a colon, its keys also start with the prefix of the id before
17
- the colon. For example, user `a` would list the key of user `a:b`, credential `c`
18
- (stored as `a:b:c`), under the name `b:c`.
19
-
20
- `getUsersWithCredential` (`local-credential-service.ts:42-51`) and `getAllUsers`
21
- (`local-credential-service.ts:53-62`) both split on the first colon, so they would
22
- report user `a:b` as `a`.
23
-
24
- Nothing in this file validates a user id. What is asked: can a user id contain a
25
- colon in practice? If it can, is a user with id `a` meant to see keys belonging
26
- to `a:b`? The code currently allows it, and no comment or test in this file says
27
- which is intended.
@@ -1,26 +0,0 @@
1
- ---
2
- type: question
3
- title: Does a wireCLI command need a session when it sets no auth?
4
- description: The channel default is documented as requiring a session, but a CLI command has no default of its own; its session need comes from whether the function is sessionless
5
- tags: core, cli, auth
6
- ---
7
-
8
- # Does a wireCLI command need a session when it sets no auth?
9
-
10
- For channels, an absent `auth` requires a session. `packages/core/src/wirings/channel/channel.types.ts:67-76`
11
- and `packages/core/src/wirings/channel/channel-runner.ts:142` both say so.
12
-
13
- `wireCLI` in `packages/core/src/wirings/cli/cli-runner.ts` copies `auth` and
14
- `permissions` from the function (`:89-90`, `:105`). It merges a command-level
15
- `auth` onto the registration as `commandAuth ?? existing.auth` (`:176`, `:190`,
16
- `:201`). No default is set anywhere in that path.
17
-
18
- When the command runs, `runPikkuFunc` is called with `auth: false` (`:393-397`).
19
- In `packages/core/src/function/function-runner.ts:385-404`, a sessionless function
20
- requires a session only when the wiring or the function sets `auth: true` (`:386-392`).
21
- A function that is not sessionless always requires one and throws when there is none
22
- (`:401-403`). `auth: false` on such a function only logs a warning (`:396-400`).
23
-
24
- **Question:** should a CLI command with no `auth` require a session as a channel
25
- does? The code does not set that default for CLI commands. Whether a command needs
26
- one depends on whether the function is declared sessionless.
@@ -1,26 +0,0 @@
1
- ---
2
- type: question
3
- title: Does an adversarial user's in-scope success count as a finding?
4
- description: The disposition doc says a 2xx is a finding for an inverted oracle, but the engine only flags successes outside the virtual user's scopes, and in-scope 2xx depends on the app's classifier
5
- tags: core, virtual-user, authorization
6
- ---
7
-
8
- # Does an adversarial user's in-scope success count as a finding?
9
-
10
- `dispositionProfile` in `packages/core/src/wirings/virtual-user/virtual-user-dispositions.ts`
11
- documents `invertedOracle` as meaning "a 2xx is a finding rather than a success".
12
- The comment on the field says the engine "flags the success and leaves ownership
13
- to the app's classifier".
14
-
15
- In `run-virtual-user.ts` the flag does one thing: at line 302 it drops the
16
- scope narrowing, so an adversarial user is offered the whole catalogue. The
17
- finding that fires on a 2xx is the `unexpected-success` check around lines
18
- 627-645. It requires `response.ok` and a scope the virtual user does not hold. A
19
- 2xx on an endpoint the virtual user is entitled to produces no engine finding. Only the
20
- app's `classify` hook can flag it, and that is the ownership check the comment
21
- describes.
22
-
23
- So the flag's name and doc describe a stronger oracle than the engine applies.
24
- What is asked: should `invertedOracle` make every 2xx a finding in the engine, as
25
- its doc says, or is the classifier meant to be the only place a 2xx becomes a
26
- finding, with the doc corrected?