@pikku/core 0.12.142 → 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 (703) 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 +11 -1
  77. package/dist/services/incoming-webhook-service.js +5 -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 +16 -0
  105. package/dist/services/scheduler-service.js +12 -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/wirings/queue/in-memory-queue-service.d.ts +23 -0
  255. package/dist/wirings/queue/in-memory-queue-service.js +129 -0
  256. package/dist/wirings/queue/index.d.ts +2 -1
  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 +56 -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/signed-queue-service.d.ts +4 -1
  267. package/dist/wirings/queue/signed-queue-service.js +3 -0
  268. package/dist/wirings/queue/validate-worker-config.d.ts +1 -0
  269. package/dist/wirings/role/role.types.d.ts +3 -0
  270. package/dist/wirings/rpc/rpc-runner.d.ts +24 -0
  271. package/dist/wirings/rpc/rpc-runner.js +37 -2
  272. package/dist/wirings/rpc/rpc-types.d.ts +2 -0
  273. package/dist/wirings/scheduler/index.d.ts +2 -1
  274. package/dist/wirings/scheduler/index.js +1 -0
  275. package/dist/wirings/scheduler/log-schedulers.d.ts +1 -0
  276. package/dist/wirings/scheduler/log-schedulers.js +1 -0
  277. package/dist/wirings/scheduler/remote-scheduled-job.d.ts +11 -0
  278. package/dist/wirings/scheduler/remote-scheduled-job.js +20 -0
  279. package/dist/wirings/scheduler/scheduler-runner.d.ts +29 -0
  280. package/dist/wirings/scheduler/scheduler-runner.js +28 -0
  281. package/dist/wirings/scheduler/scheduler.types.d.ts +15 -0
  282. package/dist/wirings/scope/scope.types.d.ts +5 -0
  283. package/dist/wirings/secret/index.d.ts +2 -2
  284. package/dist/wirings/secret/index.js +1 -1
  285. package/dist/wirings/secret/secret.types.d.ts +26 -1
  286. package/dist/wirings/secret/secret.types.js +1 -0
  287. package/dist/wirings/secret/validate-secret-definitions.d.ts +8 -0
  288. package/dist/wirings/secret/validate-secret-definitions.js +15 -0
  289. package/dist/wirings/trigger/in-memory-trigger-service.d.ts +11 -0
  290. package/dist/{services → wirings/trigger}/in-memory-trigger-service.js +10 -3
  291. package/dist/wirings/trigger/index.d.ts +1 -1
  292. package/dist/wirings/trigger/pikku-trigger-service.d.ts +8 -3
  293. package/dist/wirings/trigger/pikku-trigger-service.js +14 -3
  294. package/dist/wirings/trigger/trigger-runner.d.ts +27 -2
  295. package/dist/wirings/trigger/trigger-runner.js +35 -2
  296. package/dist/wirings/trigger/trigger.types.d.ts +26 -4
  297. package/dist/wirings/trigger/webhook-source-runner.d.ts +24 -0
  298. package/dist/wirings/trigger/webhook-source-runner.js +19 -0
  299. package/dist/wirings/trigger/webhook-source.types.d.ts +12 -2
  300. package/dist/wirings/trigger/webhook-source.types.js +1 -1
  301. package/dist/wirings/variable/validate-variable-definitions.d.ts +7 -0
  302. package/dist/wirings/variable/validate-variable-definitions.js +7 -0
  303. package/dist/wirings/variable/variable.types.d.ts +7 -0
  304. package/dist/wirings/virtual-user/conversation/conversation.types.d.ts +5 -0
  305. package/dist/wirings/virtual-user/conversation/run-conversation.d.ts +6 -0
  306. package/dist/wirings/virtual-user/conversation/run-conversation.js +1 -1
  307. package/dist/{services → wirings/virtual-user}/http-virtual-users.d.ts +4 -3
  308. package/dist/{services → wirings/virtual-user}/http-virtual-users.js +6 -6
  309. package/dist/wirings/virtual-user/index.d.ts +1 -1
  310. package/dist/wirings/virtual-user/index.js +1 -1
  311. package/dist/wirings/virtual-user/run-virtual-user.d.ts +2 -1
  312. package/dist/wirings/virtual-user/run-virtual-user.js +1 -14
  313. package/dist/wirings/virtual-user/virtual-user-declaration.types.d.ts +4 -0
  314. package/dist/wirings/virtual-user/virtual-user-scaffold.d.ts +10 -1
  315. package/dist/wirings/virtual-user/virtual-user-scaffold.js +5 -0
  316. package/dist/wirings/virtual-user/virtual-user-schedule.d.ts +5 -0
  317. package/dist/wirings/virtual-user/virtual-user-schedule.js +1 -0
  318. package/dist/wirings/virtual-user/virtual-user-target.d.ts +1 -0
  319. package/dist/wirings/webhook/define-outgoing-webhook.d.ts +20 -0
  320. package/dist/wirings/webhook/define-outgoing-webhook.js +9 -0
  321. package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +8 -4
  322. package/dist/wirings/workflow/dsl/workflow-runner.d.ts +7 -0
  323. package/dist/wirings/workflow/dsl/workflow-runner.js +7 -0
  324. package/dist/wirings/workflow/feature.d.ts +12 -0
  325. package/dist/wirings/workflow/feature.js +12 -0
  326. package/dist/wirings/workflow/graph/graph-node.d.ts +5 -0
  327. package/dist/wirings/workflow/graph/graph-node.js +5 -0
  328. package/dist/wirings/workflow/graph/template.d.ts +6 -0
  329. package/dist/wirings/workflow/graph/template.js +5 -0
  330. package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +12 -0
  331. package/dist/wirings/workflow/graph/wire-workflow-graph.js +10 -0
  332. package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +11 -0
  333. package/dist/wirings/workflow/graph/workflow-graph.types.js +1 -0
  334. package/dist/{services → wirings/workflow}/in-memory-workflow-service.d.ts +8 -3
  335. package/dist/{services → wirings/workflow}/in-memory-workflow-service.js +9 -4
  336. package/dist/wirings/workflow/pikku-scenario-service.d.ts +1 -1
  337. package/dist/wirings/workflow/pikku-scenario-service.js +2 -2
  338. package/dist/wirings/workflow/pikku-workflow-service.d.ts +1 -0
  339. package/dist/wirings/workflow/pikku-workflow-service.js +1 -0
  340. package/dist/wirings/workflow/run-timeline.d.ts +21 -0
  341. package/dist/wirings/workflow/run-timeline.js +15 -7
  342. package/dist/wirings/workflow/scenario-coverage.d.ts +1 -0
  343. package/dist/wirings/workflow/scenario-poll.d.ts +1 -0
  344. package/dist/wirings/workflow/scenario-prose.d.ts +6 -0
  345. package/dist/wirings/workflow/scenario-prose.js +6 -0
  346. package/dist/wirings/workflow/scenario-run.types.d.ts +3 -0
  347. package/dist/wirings/workflow/scenario-step.types.d.ts +1 -0
  348. package/dist/wirings/workflow/scenario-step.types.js +1 -0
  349. package/dist/wirings/workflow/scenario-surface.js +1 -13
  350. package/dist/wirings/workflow/scenario.types.d.ts +6 -0
  351. package/dist/wirings/workflow/workflow-approval-policy.d.ts +6 -0
  352. package/dist/wirings/workflow/workflow-approval-policy.js +6 -0
  353. package/dist/wirings/workflow/workflow-constants.d.ts +7 -1
  354. package/dist/wirings/workflow/workflow-constants.js +10 -1
  355. package/dist/wirings/workflow/workflow-errors.d.ts +13 -0
  356. package/dist/wirings/workflow/workflow-errors.js +13 -0
  357. package/dist/wirings/workflow/workflow-invocation-id.d.ts +4 -0
  358. package/dist/wirings/workflow/workflow-invocation-id.js +4 -0
  359. package/dist/wirings/workflow/workflow-queue-workers.d.ts +3 -0
  360. package/dist/wirings/workflow/workflow-run-ownership.d.ts +1 -0
  361. package/dist/wirings/workflow/workflow-run-ownership.js +1 -0
  362. package/dist/wirings/workflow/workflow-status-stream.d.ts +1 -0
  363. package/dist/wirings/workflow/workflow-unwind-plan.js +2 -7
  364. package/dist/wirings/workflow/workflow.types.d.ts +40 -0
  365. package/package.json +26 -9
  366. package/CHANGELOG.md +0 -6961
  367. package/dist/services/in-memory-queue-service.d.ts +0 -8
  368. package/dist/services/in-memory-queue-service.js +0 -54
  369. package/dist/services/in-memory-trigger-service.d.ts +0 -4
  370. package/dist/services/local-gateway-service.d.ts +0 -6
  371. package/dist/utils/hash.d.ts +0 -2
  372. package/dist/utils/hash.js +0 -23
  373. package/knowledge/decisions/index.md +0 -19
  374. package/knowledge/decisions/internals/a-credential-name-declared-twice-must-agree-on-schema-and-type.md +0 -29
  375. package/knowledge/decisions/internals/a-grant-can-name-a-scope-declared-without-its-addon.md +0 -29
  376. package/knowledge/decisions/internals/a-held-run-is-woken-later-not-retried.md +0 -28
  377. package/knowledge/decisions/internals/a-non-streaming-agent-run-registers-with-agentrunstate-too.md +0 -22
  378. package/knowledge/decisions/internals/a-reset-suite-makes-the-dev-seed-the-fixture.md +0 -50
  379. package/knowledge/decisions/internals/a-resumed-agent-turn-is-as-interruptible-as-the-first.md +0 -20
  380. package/knowledge/decisions/internals/a-scenario-step-template-is-offered-unfilled.md +0 -21
  381. package/knowledge/decisions/internals/a-scheduled-task-writes-its-caller-session-before-it-runs.md +0 -22
  382. package/knowledge/decisions/internals/a-secret-set-in-memory-shadows-the-variable-of-the-same-name.md +0 -28
  383. package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +0 -49
  384. package/knowledge/decisions/internals/a-virtual-user-acts-through-invokeraw-so-a-refusal-is-data.md +0 -32
  385. package/knowledge/decisions/internals/a-virtual-user-cadence-is-a-row-not-a-timer.md +0 -66
  386. package/knowledge/decisions/internals/a-virtual-user-converse-signs-in-before-its-first-turn.md +0 -24
  387. package/knowledge/decisions/internals/a-virtual-user-decides-whether-to-trust-memory-once-per-turn.md +0 -21
  388. package/knowledge/decisions/internals/a-virtual-user-email-is-computed-with-the-run-id-as-a-sub-address.md +0 -34
  389. package/knowledge/decisions/internals/a-virtual-user-run-is-not-a-workflow-but-it-needs-a-trigger.md +0 -65
  390. package/knowledge/decisions/internals/a-wall-clock-threshold-is-a-load-test-in-disguise.md +0 -46
  391. package/knowledge/decisions/internals/a-workflow-wire-is-built-from-the-run-not-from-the-rpc-service.md +0 -45
  392. package/knowledge/decisions/internals/addon-package-roots-resolve-by-walking-node-module-search-paths.md +0 -26
  393. package/knowledge/decisions/internals/addon-pikku-meta-ships-at-the-package-root-or-under-dist.md +0 -32
  394. package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +0 -33
  395. package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +0 -28
  396. package/knowledge/decisions/internals/agent-agui-bridge-obeys-the-client-ordering-contract.md +0 -29
  397. package/knowledge/decisions/internals/agent-audio-chunks-carry-the-format-the-provider-returned.md +0 -20
  398. package/knowledge/decisions/internals/agent-context-waits-for-a-tool-result-still-being-written.md +0 -21
  399. package/knowledge/decisions/internals/agent-credential-suspensions-hide-the-tool-result.md +0 -26
  400. package/knowledge/decisions/internals/agent-delegate-and-supervise-hide-different-text.md +0 -26
  401. package/knowledge/decisions/internals/agent-llm-tool-arguments-have-nulls-stripped.md +0 -23
  402. package/knowledge/decisions/internals/agent-model-config-stays-a-single-resolution-seam.md +0 -25
  403. package/knowledge/decisions/internals/agent-onerror-hooks-cannot-change-the-failure.md +0 -22
  404. package/knowledge/decisions/internals/agent-runner-methods-must-keep-their-receiver.md +0 -22
  405. package/knowledge/decisions/internals/agent-speech-travels-as-a-custom-agui-event.md +0 -22
  406. package/knowledge/decisions/internals/agent-stream-persistence-is-best-effort.md +0 -27
  407. package/knowledge/decisions/internals/agent-sub-agents-inherit-the-parent-context-block.md +0 -26
  408. package/knowledge/decisions/internals/agent-tool-execute-failures-are-logged-unconditionally.md +0 -25
  409. package/knowledge/decisions/internals/agent-voice-input-transcribes-audio-parts-in-place.md +0 -22
  410. package/knowledge/decisions/internals/agent-working-memory-is-persisted-only-when-valid.md +0 -25
  411. package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +0 -39
  412. package/knowledge/decisions/internals/an-agent-interrupt-is-not-a-failure.md +0 -23
  413. package/knowledge/decisions/internals/an-agent-is-offered-under-its-registry-key-and-only-within-the-virtual-users-scopes.md +0 -27
  414. package/knowledge/decisions/internals/an-agent-run-owned-by-another-instance-says-so.md +0 -25
  415. package/knowledge/decisions/internals/an-agent-stream-send-must-return-the-inner-sends-promise.md +0 -22
  416. package/knowledge/decisions/internals/an-empty-text-part-is-omitted-from-an-agent-message.md +0 -20
  417. package/knowledge/decisions/internals/an-empty-transcript-is-not-recorded.md +0 -22
  418. package/knowledge/decisions/internals/an-oauth2-credential-implies-an-optional-app-secret.md +0 -26
  419. package/knowledge/decisions/internals/an-unref-d-timer-cannot-be-awaited-under-node-test.md +0 -66
  420. package/knowledge/decisions/internals/analytics-identity-resolvers-run-in-declared-order.md +0 -22
  421. package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +0 -30
  422. package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +0 -31
  423. package/knowledge/decisions/internals/channel-state-accessors-are-unsound-generics-that-every-implementation-asserts.md +0 -33
  424. package/knowledge/decisions/internals/channel-state-is-per-socket-session-state-is-per-user.md +0 -29
  425. package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +0 -28
  426. package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +0 -27
  427. package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +0 -28
  428. package/knowledge/decisions/internals/cli-stdout-is-reserved-for-machine-readable-output.md +0 -34
  429. package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +0 -29
  430. package/knowledge/decisions/internals/core-column-form-is-an-axis-of-its-own.md +0 -84
  431. package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +0 -41
  432. package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +0 -44
  433. package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +0 -39
  434. package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +0 -42
  435. package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +0 -39
  436. package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +0 -43
  437. package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +0 -38
  438. package/knowledge/decisions/internals/core-state-is-a-global-map-written-only-at-registration-time.md +0 -44
  439. package/knowledge/decisions/internals/email-meta-is-read-uncached-because-codegen-rewrites-it-mid-session.md +0 -27
  440. package/knowledge/decisions/internals/feature-flag-declarations-refuse-an-empty-anyof-and-conflicting-scopes.md +0 -22
  441. package/knowledge/decisions/internals/feature-flags-fail-open-and-never-enforce-access.md +0 -28
  442. package/knowledge/decisions/internals/flag-sync-rewrites-only-the-declared-text.md +0 -24
  443. package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +0 -32
  444. package/knowledge/decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md +0 -43
  445. package/knowledge/decisions/internals/gateway-webhook-challenges-echo-bytes-not-json.md +0 -28
  446. package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +0 -31
  447. package/knowledge/decisions/internals/generated-src-paths-in-pikku-meta-are-absolute.md +0 -26
  448. package/knowledge/decisions/internals/global-middleware-resolves-from-the-root-namespace-too.md +0 -32
  449. package/knowledge/decisions/internals/hot-reload-reads-the-changed-source-never-a-compiled-copy.md +0 -38
  450. package/knowledge/decisions/internals/hot-reload-writes-into-the-function-map-captured-at-startup.md +0 -26
  451. package/knowledge/decisions/internals/http-request-bodies-are-read-once-and-shared.md +0 -32
  452. package/knowledge/decisions/internals/http-route-groups-cascade-config-in-a-fixed-order.md +0 -28
  453. package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +0 -30
  454. package/knowledge/decisions/internals/http-runner-logs-through-a-trace-scoped-logger-functions-do-not.md +0 -26
  455. package/knowledge/decisions/internals/http-set-cookie-headers-are-appended-never-joined.md +0 -28
  456. package/knowledge/decisions/internals/http-sse-streams-flush-headers-only-after-middleware.md +0 -32
  457. package/knowledge/decisions/internals/http-wiring-without-metadata-is-skipped-not-fatal.md +0 -26
  458. package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +0 -25
  459. package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +0 -26
  460. package/knowledge/decisions/internals/index.md +0 -181
  461. package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +0 -25
  462. package/knowledge/decisions/internals/local-trigger-and-gateway-services-assume-a-single-process.md +0 -26
  463. package/knowledge/decisions/internals/mcp-wire-names-are-assigned-over-the-whole-registry.md +0 -39
  464. package/knowledge/decisions/internals/node-only-builtins-are-imported-dynamically.md +0 -24
  465. package/knowledge/decisions/internals/one-project-shape-check-two-validators.md +0 -53
  466. package/knowledge/decisions/internals/only-exposed-functions-enter-a-virtual-user-catalogue.md +0 -21
  467. package/knowledge/decisions/internals/queue-group-concurrency-keeps-one-shared-queue-fair.md +0 -28
  468. package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +0 -27
  469. package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +0 -31
  470. package/knowledge/decisions/internals/role-names-cannot-contain-the-scope-separator.md +0 -30
  471. package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +0 -32
  472. package/knowledge/decisions/internals/scenario-agent-calls-sign-in-on-401-only.md +0 -31
  473. package/knowledge/decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md +0 -24
  474. package/knowledge/decisions/internals/scenario-meta-lives-apart-from-app-meta-but-merges-when-read-off-disk.md +0 -26
  475. package/knowledge/decisions/internals/scenario-steps-return-drained-response-records.md +0 -27
  476. package/knowledge/decisions/internals/scenarios-live-in-files-named-for-them.md +0 -48
  477. package/knowledge/decisions/internals/scope-roots-may-be-co-declared-by-an-addon-and-its-host-app.md +0 -30
  478. package/knowledge/decisions/internals/serverless-channel-disconnect-must-tolerate-a-missing-channel.md +0 -28
  479. package/knowledge/decisions/internals/side-effects-are-an-allowlist-not-a-boolean.md +0 -34
  480. package/knowledge/decisions/internals/speech-synthesis-picks-a-voice-per-sentence-and-warns-once.md +0 -24
  481. package/knowledge/decisions/internals/the-agent-done-event-goes-through-the-middleware-and-is-awaited.md +0 -26
  482. package/knowledge/decisions/internals/the-api-report-pins-members-not-just-names.md +0 -43
  483. package/knowledge/decisions/internals/the-core-scope-validator-refuses-separator-wildcard-and-empty-segments.md +0 -22
  484. package/knowledge/decisions/internals/the-dev-queue-copies-prod-timing-and-serialization-semantics.md +0 -30
  485. package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md +0 -83
  486. package/knowledge/decisions/internals/the-embedding-model-is-pinned-per-service-and-doc-query-embedding-is-split.md +0 -29
  487. package/knowledge/decisions/internals/the-in-memory-workflow-service-is-inline-only-and-single-process.md +0 -27
  488. package/knowledge/decisions/internals/the-kek-salt-is-scoped-to-the-key-version.md +0 -40
  489. package/knowledge/decisions/internals/the-mcp-handshake-is-challenged-only-when-every-target-is-gated.md +0 -29
  490. package/knowledge/decisions/internals/the-middleware-resolution-cache-is-deliberately-unbounded.md +0 -40
  491. package/knowledge/decisions/internals/the-per-invocation-rpc-view-is-a-class.md +0 -40
  492. package/knowledge/decisions/internals/the-pikku-user-id-resolves-in-a-fixed-order.md +0 -24
  493. package/knowledge/decisions/internals/the-runner-resolves-wire-services-itself.md +0 -31
  494. package/knowledge/decisions/internals/the-schema-service-is-never-stubbed.md +0 -26
  495. package/knowledge/decisions/internals/the-transcript-event-is-sent-ahead-of-the-run.md +0 -25
  496. package/knowledge/decisions/internals/the-virtual-user-catalogue-is-the-only-gate-on-what-may-be-called.md +0 -21
  497. package/knowledge/decisions/internals/the-virtual-user-prompt-says-json-because-of-json-object-mode.md +0 -22
  498. package/knowledge/decisions/internals/the-virtual-user-runtime-is-exported-from-the-virtual-user-entry-point.md +0 -28
  499. package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +0 -22
  500. package/knowledge/decisions/internals/thread-history-records-the-transcript-not-the-audio.md +0 -25
  501. package/knowledge/decisions/internals/trigger-declaration-is-split-from-trigger-source.md +0 -33
  502. package/knowledge/decisions/internals/typed-secret-service-caches-for-the-process-lifetime.md +0 -26
  503. package/knowledge/decisions/internals/validate-checks-virtual-users-through-a-shared-module.md +0 -43
  504. package/knowledge/decisions/internals/validate-runs-checks-by-precondition.md +0 -115
  505. package/knowledge/decisions/internals/virtual-user-conversation-drives-the-target-through-a-transport-seam.md +0 -24
  506. package/knowledge/decisions/internals/virtual-user-conversation-verdicts-are-llm-self-evaluations.md +0 -25
  507. package/knowledge/decisions/internals/virtual-user-conversations-seed-a-hidden-kickoff-message.md +0 -23
  508. package/knowledge/decisions/internals/virtual-user-step-order-comes-from-insertion-order.md +0 -21
  509. package/knowledge/decisions/internals/virtual-users-are-declared-in-one-definevirtualusers-call-per-codebase.md +0 -30
  510. package/knowledge/decisions/internals/voice-output-speaks-unless-voice-input-explicitly-says-otherwise.md +0 -24
  511. package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +0 -26
  512. package/knowledge/decisions/internals/webhook-service-collaborators-are-constructor-args-not-locator-lookups.md +0 -25
  513. package/knowledge/decisions/internals/whether-a-run-is-inline-is-read-from-the-run-record.md +0 -58
  514. package/knowledge/decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md +0 -35
  515. package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +0 -34
  516. package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +0 -42
  517. package/knowledge/decisions/internals/workflow-dsl-meta-separates-runtime-expressions-from-literals.md +0 -38
  518. package/knowledge/decisions/internals/workflow-features-resolve-scenarios-by-object-identity.md +0 -29
  519. package/knowledge/decisions/internals/workflow-graph-inline-and-queued-runs-share-one-planner.md +0 -42
  520. package/knowledge/decisions/internals/workflow-graph-node-notes-are-excluded-from-the-graph-hash.md +0 -25
  521. package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +0 -29
  522. package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +0 -43
  523. package/knowledge/decisions/internals/workflow-queued-step-dispatch-requires-an-explicit-opt-in.md +0 -29
  524. package/knowledge/decisions/internals/workflow-queues-are-per-workflow-by-default.md +0 -42
  525. package/knowledge/decisions/internals/workflow-repeated-step-names-get-an-ordinal-suffix.md +0 -33
  526. package/knowledge/decisions/internals/workflow-replay-reads-its-steps-once-and-caches-only-the-immutable-half.md +0 -32
  527. package/knowledge/decisions/internals/workflow-retries-are-owned-by-the-workflow-not-the-queue.md +0 -31
  528. package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +0 -39
  529. package/knowledge/decisions/internals/workflow-run-mirror-is-never-a-source-of-truth.md +0 -29
  530. package/knowledge/decisions/internals/workflow-run-polling-backs-off-to-the-callers-ceiling.md +0 -33
  531. package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +0 -37
  532. package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +0 -54
  533. package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +0 -43
  534. package/knowledge/decisions/internals/workflow-scenario-prose-is-rendered-from-typed-calls-not-parsed-from-english.md +0 -32
  535. package/knowledge/decisions/internals/workflow-scenario-quarantine-reason-lives-in-code.md +0 -18
  536. package/knowledge/decisions/internals/workflow-scenario-step-targets-are-string-literals-for-the-inspector.md +0 -34
  537. package/knowledge/decisions/internals/workflow-step-compensation-runs-as-its-own-durable-step.md +0 -29
  538. package/knowledge/decisions/internals/workflow-step-dispatch-failure-is-transient-not-a-run-failure.md +0 -33
  539. package/knowledge/decisions/internals/workflow-step-lock-is-held-only-to-claim-the-step.md +0 -34
  540. package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +0 -34
  541. package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +0 -38
  542. package/knowledge/decisions/internals/workflow-suspended-runs-keep-their-in-process-context.md +0 -30
  543. package/knowledge/decisions/security/a-bearer-token-checked-against-a-secret-reads-it-per-request.md +0 -26
  544. package/knowledge/decisions/security/a-call-without-a-session-raises-missing-session-not-forbidden.md +0 -20
  545. package/knowledge/decisions/security/a-caller-cookie-wins-over-the-jar-for-the-same-name.md +0 -23
  546. package/knowledge/decisions/security/a-channel-lifecycle-acts-as-the-socket-upgrade-session.md +0 -16
  547. package/knowledge/decisions/security/a-channel-requires-a-session-unless-it-says-auth-false.md +0 -26
  548. package/knowledge/decisions/security/a-credential-read-path-follows-its-declared-type-not-absence.md +0 -32
  549. package/knowledge/decisions/security/a-credential-type-is-a-literal-the-inspector-checks-at-declaration.md +0 -27
  550. package/knowledge/decisions/security/a-dropped-audit-write-is-always-logged.md +0 -28
  551. package/knowledge/decisions/security/a-first-party-cookie-is-written-only-after-its-purposes-consent.md +0 -33
  552. package/knowledge/decisions/security/a-function-never-receives-the-secret-service.md +0 -37
  553. package/knowledge/decisions/security/a-graph-run-starts-at-an-entry-node-the-graph-declared.md +0 -33
  554. package/knowledge/decisions/security/a-permission-gets-a-wire-it-cannot-reply-on.md +0 -33
  555. package/knowledge/decisions/security/a-public-function-says-so-with-auth-false.md +0 -34
  556. package/knowledge/decisions/security/a-readonly-session-reaches-only-readonly-functions.md +0 -25
  557. package/knowledge/decisions/security/a-scaffold-flag-says-a-surface-exists-not-who-may-call-it.md +0 -52
  558. package/knowledge/decisions/security/a-scheduled-virtual-user-run-needs-no-admin-at-run-time.md +0 -27
  559. package/knowledge/decisions/security/a-scoped-credential-view-is-limited-to-declared-names.md +0 -26
  560. package/knowledge/decisions/security/a-scoped-secret-view-reads-only-declared-keys-and-never-writes.md +0 -25
  561. package/knowledge/decisions/security/a-secret-is-sent-only-to-the-hosts-it-declares.md +0 -29
  562. package/knowledge/decisions/security/a-step-can-name-an-identity-no-virtual-user-holds-through-per-call-headers.md +0 -25
  563. package/knowledge/decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md +0 -37
  564. package/knowledge/decisions/security/a-stopped-run-by-id-skips-the-ownership-check.md +0 -24
  565. package/knowledge/decisions/security/a-vault-secret-redacts-on-serialization-and-throws-on-coercion.md +0 -29
  566. package/knowledge/decisions/security/a-virtual-user-catalogue-entry-is-filtered-by-scope-and-approval-is-denied-by-default.md +0 -30
  567. package/knowledge/decisions/security/a-virtual-user-environment-fails-closed.md +0 -38
  568. package/knowledge/decisions/security/a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md +0 -27
  569. package/knowledge/decisions/security/a-virtual-user-never-runs-against-production.md +0 -23
  570. package/knowledge/decisions/security/a-virtual-user-reads-its-roles-from-the-apps-own-rpc-before-better-auth.md +0 -27
  571. package/knowledge/decisions/security/a-virtual-user-run-treats-an-unresolved-environment-as-production.md +0 -41
  572. package/knowledge/decisions/security/a-virtual-user-scopes-are-expanded-from-its-roles-once-at-run-preparation.md +0 -25
  573. package/knowledge/decisions/security/a-virtual-user-whose-roles-drift-from-the-declaration-refuses-to-run.md +0 -32
  574. package/knowledge/decisions/security/a-workflow-run-is-read-and-approved-by-its-owner.md +0 -50
  575. package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +0 -43
  576. package/knowledge/decisions/security/addon-config-gates-apply-only-at-the-namespaced-rpc-boundary.md +0 -52
  577. package/knowledge/decisions/security/addon-scopes-are-resolved-where-the-function-runs.md +0 -46
  578. package/knowledge/decisions/security/addon-screen-scopes-hide-and-do-not-enforce.md +0 -20
  579. package/knowledge/decisions/security/agent-approval-forwarding-requires-a-symbol-brand.md +0 -27
  580. package/knowledge/decisions/security/agent-credential-requests-are-symbol-branded.md +0 -37
  581. package/knowledge/decisions/security/agent-gate-requires-a-session-only-when-auth-is-true.md +0 -31
  582. package/knowledge/decisions/security/agent-ownership-failures-never-echo-the-resource.md +0 -23
  583. package/knowledge/decisions/security/agent-resume-re-runs-the-authorization-gate.md +0 -22
  584. package/knowledge/decisions/security/agent-sessionless-deployments-have-no-thread-ownership.md +0 -39
  585. package/knowledge/decisions/security/agent-thread-ownership-composes-the-session-principal.md +0 -30
  586. package/knowledge/decisions/security/agent-tool-filtering-reads-the-live-function-config.md +0 -24
  587. package/knowledge/decisions/security/an-addon-header-can-only-narrow-the-session.md +0 -26
  588. package/knowledge/decisions/security/an-addon-instance-reads-only-the-secrets-and-credentials-it-is-named.md +0 -33
  589. package/knowledge/decisions/security/an-addon-may-reach-only-itself-and-the-addons-it-uses.md +0 -16
  590. package/knowledge/decisions/security/an-agent-approval-is-claimed-before-the-tool-runs.md +0 -33
  591. package/knowledge/decisions/security/an-api-key-is-jwt-decoded-into-the-session.md +0 -26
  592. package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +0 -59
  593. package/knowledge/decisions/security/an-empty-owners-constraint-matches-nothing.md +0 -30
  594. package/knowledge/decisions/security/an-exposed-ungated-function-is-a-codegen-warning.md +0 -52
  595. package/knowledge/decisions/security/an-external-virtual-user-caller-presents-one-signed-statement.md +0 -38
  596. package/knowledge/decisions/security/an-inbound-webhook-source-dispatches-only-verified-requests.md +0 -31
  597. package/knowledge/decisions/security/an-mcp-call-with-no-http-request-stays-anonymous.md +0 -18
  598. package/knowledge/decisions/security/an-mcp-refusal-is-decided-before-dispatch.md +0 -48
  599. package/knowledge/decisions/security/an-oauth2-credential-is-read-by-its-account-row.md +0 -40
  600. package/knowledge/decisions/security/an-omitted-user-id-addresses-the-platform-credential.md +0 -32
  601. package/knowledge/decisions/security/an-upload-is-counted-as-it-arrives-not-buffered-then-measured.md +0 -24
  602. package/knowledge/decisions/security/analytics-identity-is-stamped-from-the-session-not-the-event.md +0 -24
  603. package/knowledge/decisions/security/app-access-is-a-scope-tree-synthesised-from-virtual-users.md +0 -26
  604. package/knowledge/decisions/security/approval-policy-decides-who-answers-a-tool-call.md +0 -27
  605. package/knowledge/decisions/security/auth-false-on-a-session-function-warns-and-still-requires-one.md +0 -25
  606. package/knowledge/decisions/security/bearer-token-hashes-are-unpeppered-sha256.md +0 -18
  607. package/knowledge/decisions/security/consent-is-read-from-a-cookie-and-a-recognised-denial-counts-as-refusal.md +0 -29
  608. package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +0 -84
  609. package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +0 -39
  610. package/knowledge/decisions/security/core-secrets-use-a-per-secret-dek-wrapped-by-a-kek.md +0 -37
  611. package/knowledge/decisions/security/cors-defaults-to-any-origin-and-refuses-the-wildcard-with-credentials.md +0 -22
  612. package/knowledge/decisions/security/credential-backends-share-one-conformance-suite-for-per-user-isolation.md +0 -29
  613. package/knowledge/decisions/security/each-stage-has-one-virtual-user-key-pair.md +0 -27
  614. package/knowledge/decisions/security/gateway-handlers-run-through-the-function-runner-gate.md +0 -41
  615. package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +0 -30
  616. package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +0 -40
  617. package/knowledge/decisions/security/hmac-verification-fails-closed-on-empty-inputs.md +0 -25
  618. package/knowledge/decisions/security/http-error-detail-is-withheld-from-clients-in-production.md +0 -33
  619. package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +0 -46
  620. package/knowledge/decisions/security/index.md +0 -135
  621. package/knowledge/decisions/security/local-content-refuses-private-buckets-under-the-public-segment.md +0 -21
  622. package/knowledge/decisions/security/mail-is-allowlisted-before-a-virtual-user-run-sees-it.md +0 -38
  623. package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +0 -27
  624. package/knowledge/decisions/security/mcp-resources-tools-and-prompts-take-sessionless-functions.md +0 -18
  625. package/knowledge/decisions/security/origin-locked-routes-match-the-origin-exactly.md +0 -22
  626. package/knowledge/decisions/security/oss-auth-works-without-pikku-studio-cloud.md +0 -26
  627. package/knowledge/decisions/security/outbound-webhooks-use-an-allowlist-when-configured.md +0 -24
  628. package/knowledge/decisions/security/passphrases-are-stretched-key-material-is-expanded.md +0 -40
  629. package/knowledge/decisions/security/permission-auth-filtering-requires-live-permission-functions.md +0 -31
  630. package/knowledge/decisions/security/pikku-carries-virtual-user-scopes-as-data-and-the-app-grants-them.md +0 -35
  631. package/knowledge/decisions/security/queue-job-identities-are-signed-at-enqueue.md +0 -69
  632. package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +0 -39
  633. package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +0 -34
  634. package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +0 -55
  635. package/knowledge/decisions/security/scenario-step-functions-are-never-externally-invocable.md +0 -30
  636. package/knowledge/decisions/security/scope-resolution-happens-at-the-session-boundary-and-sync-never-deletes.md +0 -28
  637. package/knowledge/decisions/security/scoped-content-access-is-a-root-folder-with-longest-prefix-grants.md +0 -31
  638. package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +0 -34
  639. package/knowledge/decisions/security/services-without-secrets-get-a-throwing-secrets-accessor.md +0 -22
  640. package/knowledge/decisions/security/shared-guards-refuse-to-mutate-or-shadow-a-system-role.md +0 -34
  641. package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +0 -37
  642. package/knowledge/decisions/security/signed-uploads-are-verified-by-the-same-check-as-signed-reads.md +0 -26
  643. package/knowledge/decisions/security/system-role-scopes-must-be-declared-with-define-scope.md +0 -24
  644. package/knowledge/decisions/security/system-roles-are-additive-and-immutable.md +0 -16
  645. package/knowledge/decisions/security/the-channel-rpc-does-not-send-the-callers-session.md +0 -21
  646. package/knowledge/decisions/security/the-remote-jobs-inbox-fails-closed-without-a-secret.md +0 -24
  647. package/knowledge/decisions/security/the-remote-rpc-gate-fails-closed-and-binds-the-token-to-its-function.md +0 -34
  648. package/knowledge/decisions/security/the-workflow-status-stream-rechecks-ownership-on-every-poll.md +0 -16
  649. package/knowledge/decisions/security/two-credentials-on-one-key-must-share-a-read-mode.md +0 -29
  650. package/knowledge/decisions/security/verified-bearer-claims-are-pass-through-data-that-core-never-fills.md +0 -23
  651. package/knowledge/decisions/security/virtual-user-catalogue-excludes-the-machinery-that-runs-virtual-users.md +0 -25
  652. package/knowledge/decisions/security/virtual-user-conversation-missing-approval-decisions-default-to-denied.md +0 -22
  653. package/knowledge/decisions/security/virtual-user-run-records-are-gated-behind-a-read-scope.md +0 -18
  654. package/knowledge/decisions/security/virtual-user-sign-in-does-not-exist-in-production.md +0 -25
  655. package/knowledge/decisions/security/virtual-user-sign-in-has-one-door.md +0 -42
  656. package/knowledge/decisions/security/virtual-user-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +0 -29
  657. package/knowledge/decisions/security/virtual-user-sign-in-only-works-for-virtual-user-flagged-users.md +0 -29
  658. package/knowledge/decisions/security/webhook-bodies-are-signed-before-they-are-enqueued.md +0 -25
  659. package/knowledge/decisions/security/wire-addon-expose-selects-the-rpc-surface.md +0 -51
  660. package/knowledge/decisions/security/workflow-approval-payloads-are-validated-on-replay-inside-the-workflow.md +0 -40
  661. package/knowledge/decisions/security/workflow-helper-functions-are-sessionless-by-declaration.md +0 -18
  662. package/knowledge/decisions/security/workflow-queued-steps-rehydrate-their-session-from-the-run-wire.md +0 -32
  663. package/knowledge/decisions/security/workflow-scenario-sessions-are-isolated-per-virtual-user-and-per-scenario.md +0 -32
  664. package/knowledge/decisions/security/workflow-scenario-steps-are-never-network-invocable.md +0 -31
  665. package/knowledge/decisions/security/workflow-virtual-user-steps-always-use-the-real-transport.md +0 -34
  666. package/knowledge/decisions/security/writing-a-virtual-user-schedule-is-gated-by-its-own-scope.md +0 -18
  667. package/knowledge/index.md +0 -24
  668. package/knowledge/questions/a-bearer-jwt-with-no-identity-becomes-a-session.md +0 -24
  669. package/knowledge/questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md +0 -35
  670. package/knowledge/questions/dev-quick-login-as-impersonation.md +0 -25
  671. package/knowledge/questions/does-a-delayed-rpc-run-as-the-session-it-was-scheduled-with.md +0 -26
  672. package/knowledge/questions/does-a-user-id-with-a-colon-read-another-users-credentials.md +0 -27
  673. package/knowledge/questions/does-a-wirecli-command-need-a-session-by-default.md +0 -26
  674. package/knowledge/questions/does-an-adversarial-in-scope-success-count-as-a-finding.md +0 -26
  675. package/knowledge/questions/does-approve-step-need-the-run-owners-session-or-the-gates-approvers.md +0 -34
  676. package/knowledge/questions/does-cors-origin-true-reflect-any-origin-with-credentials.md +0 -20
  677. package/knowledge/questions/does-skip-user-session-do-anything-on-a-channel.md +0 -24
  678. package/knowledge/questions/does-the-store-session-match-the-other-two.md +0 -19
  679. package/knowledge/questions/index.md +0 -41
  680. package/knowledge/questions/is-the-agent-score-worker-reachable-without-a-session.md +0 -21
  681. package/knowledge/questions/live-scheduled-tests-may-write.md +0 -19
  682. package/knowledge/questions/provision-virtual-users-has-no-caller-in-this-repo.md +0 -23
  683. package/knowledge/questions/remote-secret-refuses-requests-without-a-remote-token-on-every-path.md +0 -32
  684. package/knowledge/questions/should-a-middleware-set-session-persist-to-the-store.md +0 -25
  685. package/knowledge/questions/should-a-scoped-secret-view-throw-from-has-secret-for-a-disallowed-key.md +0 -23
  686. package/knowledge/questions/should-a-wrong-bearer-token-be-anonymous-or-refused.md +0 -35
  687. package/knowledge/questions/should-an-empty-webhook-signing-secret-send-unsigned.md +0 -23
  688. package/knowledge/questions/should-http-virtual-user-sessions-reset-between-scenarios-in-one-run.md +0 -27
  689. package/knowledge/questions/should-the-cookie-jar-scope-cookies-to-the-api-origin.md +0 -26
  690. package/knowledge/questions/should-voice-input-fetch-audio-urls-without-a-host-allowlist.md +0 -20
  691. package/knowledge/questions/staging-impersonation-rules.md +0 -27
  692. package/knowledge/questions/unauthorized-channel-replies-escape-the-declared-out-type.md +0 -44
  693. package/knowledge/questions/virtual-user-keys-on-cloud-stages-are-pikku-studios-to-build.md +0 -34
  694. package/knowledge/questions/virtual-user-statement-replay-is-per-process.md +0 -20
  695. package/knowledge/questions/what-an-impersonated-session-carries.md +0 -22
  696. package/run-tests.sh +0 -68
  697. package/scripts/generate-api-report.d.mts +0 -1
  698. package/scripts/generate-api-report.mjs +0 -96
  699. package/scripts/generate-api-report.mts +0 -333
  700. package/src/public-surface.json +0 -637
  701. package/src/public-surface.json.README +0 -43
  702. /package/dist/{function/compensation-name.d.ts → compensation-name.d.ts} +0 -0
  703. /package/dist/{function/compensation-name.js → compensation-name.js} +0 -0
@@ -1,24 +0,0 @@
1
- ---
2
- type: decision
3
- title: Analytics identity is stamped from the session and resolvers, never from the event body
4
- description: Each analytics record takes userId and orgId from the wire session, pikkuUserId from the wire, and the rest from the identity resolvers, not from the event payload
5
- tags: core, analytics, security
6
- ---
7
-
8
- # Analytics identity is stamped from the session and resolvers, never from the event body
9
-
10
- `resolveEvent` in `packages/core/src/analytics/analytics.ts:55-72` builds
11
- `userIdentity` from the wire session (`:59`, `:67-69`), `this.wire.pikkuUserId`
12
- (`:70`), and the output of the identity resolver (`:61`, `:71`). The event's own
13
- fields are `name`, `props` and the optional `at` (`:60`, `:66`). The identity
14
- fields are not read from the event.
15
-
16
- `packages/core/src/analytics/analytics.types.ts:26-29` gives the reason: identity
17
- is stamped server-side and never read from the request body, which is what makes
18
- an unauthenticated ingest safe to expose.
19
-
20
- The consent notes in this folder cover the cookie side of identity. They do not
21
- cover how the record's identity is attached.
22
-
23
- **What this rules out:** a client supplying `userId`, `orgId` or `pikkuUserId` in
24
- an analytics event and having it recorded as the caller's identity.
@@ -1,26 +0,0 @@
1
- ---
2
- type: decision
3
- title: App access is a scope tree synthesised from the virtual users that name an app
4
- description: buildAppScopeDefinition creates one app:<name> scope per app any virtual user names, so which frontend a person may sign into is a runtime-revocable grant rather than a column per app
5
- tags: core, virtual-users, scopes, access
6
- ---
7
-
8
- # App access is a scope tree synthesised from the virtual users that name an app
9
-
10
- `packages/core/src/wirings/virtual-user/virtual-user-app-scopes.ts` builds an `app` scope
11
- tree from the virtual users. `declaredApps` returns the app names used by virtual users,
12
- sorted and without duplicates (`virtual-user-app-scopes.ts:23-30`).
13
- `buildAppScopeDefinition` creates one child scope per app, with the origin
14
- `generated` (`virtual-user-app-scopes.ts:60-74`). It returns `null` when no virtual user
15
- names an app (`virtual-user-app-scopes.ts:55-58`).
16
-
17
- The doc comment gives the reasons. Which frontend a person may use is the same
18
- kind of question as a scope: an admin can grant and revoke it at runtime, it
19
- resolves at the session boundary, and a restricted API key can decline to inherit
20
- it (`virtual-user-app-scopes.ts:35-41`). The tree is synthesised, not written by hand,
21
- because a hand-written copy could drift from the virtual users. The comment says that
22
- failure "is one `pikku scopes prune` away from silently revoking sign-in"
23
- (`virtual-user-app-scopes.ts:45-47`).
24
-
25
- **What this rules out:** a separate per-app access column, and a hand-maintained
26
- list of apps that has to match the virtual users.
@@ -1,27 +0,0 @@
1
- ---
2
- type: decision
3
- title: The approval policy decides who answers a tool call
4
- description: The conversation approvals option picks either a fixed answer or the virtual user's model for each pending tool call, and a call with no answer is denied
5
- tags: core, virtual-users, approvals, security
6
- ---
7
-
8
- # The approval policy decides who answers a tool call
9
-
10
- `ConversationApprovalPolicy` in
11
- `packages/core/src/wirings/virtual-user/conversation/conversation.types.ts:1` has
12
- three values, and `approvals` is an optional field on `ConverseOptions` (`:9`).
13
-
14
- `decideApprovals` in
15
- `packages/core/src/wirings/virtual-user/conversation/run-conversation.ts:133-181`
16
- applies it. The default is `in-virtual-user` (`:138`). `always` approves every
17
- pending call and `never` denies every one (`:139-144`). `in-virtual-user` sends the
18
- pending calls to the virtual user's model with `tools: []` and `toolChoice: 'none'`
19
- (`:153-169`), and the model's decisions are what get applied.
20
-
21
- Every pending call must get a decision. The code maps the answers by `toolCallId`
22
- and a call with no answer is denied (`:176-180`). The missing-decision rule has
23
- its own note,
24
- [missing approval decisions default to denied](virtual-user-conversation-missing-approval-decisions-default-to-denied.md).
25
-
26
- **What this rules out:** reading a missing answer as consent, and an
27
- `in-virtual-user` run approving a call the virtual user's model did not name.
@@ -1,25 +0,0 @@
1
- ---
2
- type: decision
3
- title: auth false on a session-required function warns and still requires a session
4
- description: Writing auth: false on a function that is not sessionless does not open it; the runner logs a warning and still throws MissingSessionError without a session
5
- tags: core, auth, function-runner
6
- ---
7
-
8
- # auth false on a session-required function warns and still requires a session
9
-
10
- In `runPikkuFunc` (`packages/core/src/function/function-runner.ts`), a function
11
- that is not `sessionless` is session-required. If the wiring or the function
12
- config says `auth: false`, the runner logs
13
- "requires a session but auth was explicitly disabled — use pikkuSessionlessFunc
14
- instead." and then still throws `MissingSessionError` when no session is present.
15
-
16
- The test "should warn when auth is disabled for a session-required function but
17
- still enforce session" in `function-runner.test.ts` states the intent. The
18
- warning points the author at the function kind that actually means "no session",
19
- which is `pikkuSessionlessFunc`. The same flag on a sessionless function is the
20
- opposite declaration and is covered by
21
- [A public function says so with auth: false](a-public-function-says-so-with-auth-false.md).
22
-
23
- **What this rules out:** treating `auth: false` on a `pikkuFunc` as making it
24
- public. Making a function public means using `pikkuSessionlessFunc`, and a
25
- session-required function that disables auth still fails closed.
@@ -1,18 +0,0 @@
1
- ---
2
- type: decision
3
- title: Bearer token hashes are unpeppered SHA-256
4
- description: hashToken stores bearer tokens as plain SHA-256 hex because they are high-entropy random values; a low-entropy secret is not a hashed column
5
- tags: core, classification, security
6
- ---
7
-
8
- # Bearer token hashes are unpeppered SHA-256
9
-
10
- `hashToken` in `packages/core/src/classification/column-form.ts:21-32` returns the
11
- lowercase hex SHA-256 of its input through WebCrypto. The doc comment at `:8-15`
12
- gives the reason: bearer tokens are high-entropy random values with no candidate
13
- set to search, so a pepper would add a key to manage and a rotation story while
14
- buying nothing. The same comment says a column that holds a low-entropy secret is
15
- not a `hashed` column and needs a password KDF instead.
16
-
17
- **What this rules out:** adding a pepper or key to token hashes, and using this
18
- hash for passwords or other low-entropy values.
@@ -1,29 +0,0 @@
1
- ---
2
- type: decision
3
- title: Consent is read from a cookie, and a recognised denial value counts as a refusal
4
- description: cookieAnalyticsIdentity grants a consent purpose only when its cookie is present and not one of a fixed set of denial values, and resolves no identity off a non-HTTP wire
5
- tags: core, analytics, consent, cookies
6
- ---
7
-
8
- # Consent is read from a cookie, and a recognised denial value counts as a refusal
9
-
10
- `packages/core/src/analytics/cookie-analytics-identity.ts` reads consent and
11
- vendor identifiers from first-party cookies. The doc comment says a purpose is
12
- true "only when the cookie is present and is not a recognised denial", so a
13
- consent tool that writes a refusal rather than deleting the cookie is read as a
14
- refusal (`cookie-analytics-identity.ts:7-11`).
15
-
16
- The denial values are `0`, `false`, `denied`, `deny` and `no`
17
- (`cookie-analytics-identity.ts:15`). The comparison is case-insensitive
18
- (`cookie-analytics-identity.ts:49`).
19
-
20
- A purpose whose cookie is absent is left out of the consent record entirely
21
- (`cookie-analytics-identity.ts:47-48`). Since `mintCookie` requires `=== true`
22
- (`mint-cookie.ts:34`), an absent cookie is a refusal there.
23
-
24
- A wire with no HTTP request resolves nothing (`cookie-analytics-identity.ts:34-35`).
25
- The doc comment says a cron task or queue worker has no browser, so "any vendor
26
- id they produced would be invented" (`cookie-analytics-identity.ts:24-25`).
27
-
28
- **What this rules out:** treating any present cookie value as consent, and
29
- inventing a vendor identity for a non-browser caller.
@@ -1,84 +0,0 @@
1
- ---
2
- type: decision
3
- title: The console addon's privileged functions gate themselves
4
- description: Thread listing is owner-scoped unless the caller holds admin, and addon installation requires an admin session, rather than trusting the host to register a global permission
5
- tags: addon, agent, rpc
6
- ---
7
-
8
- # The console addon's privileged functions gate themselves
9
-
10
- `@pikku/addon-console` is wired into the consuming application by the generated
11
- `console.gen.ts` that `scaffold.console` produces — `wireAddon({ name:
12
- 'console', package: '@pikku/addon-console' })`. That file is compiled into the
13
- app and ships wherever the app ships, so every `expose: true` console function
14
- is reachable over the app's own `POST /rpc/:rpcName` route in production, not
15
- only from `pikku dev`. `pikku serve --console` binds `127.0.0.1` and adds a
16
- static SPA mount; it wires no functions. The console UI being a development tool
17
- is a convention about who opens the browser tab; it is not a deployment
18
- boundary.
19
-
20
- The transport in front of that route is configured separately from the console:
21
- `scaffold.rpc` defaults to `"no-auth"` in `templates/functions/pikku.config.json`
22
- and in `e2e/pikku.config.json`, which generates `wireHTTP({ route:
23
- '/rpc/:rpcName', auth: false })`. `scaffold.console: "auth"` does not raise it,
24
- and the generated `wireAddon` carries no `auth` key, so `addonConfig.auth` is
25
- undefined at the addon boundary too. The remaining session check is the function
26
- runner's, which for a `pikkuSessionlessFunc` fires only when the function itself
27
- sets `auth: true`.
28
-
29
- The addon's original authorization story was a single package-scoped
30
- `addGlobalPermission([isAdmin], '@pikku/addon-console')` that the _host_
31
- registered, which `runPermissions` resolves in the callee's package namespace and
32
- applies to every function at once. Nothing generated that call — the scaffold
33
- emitted only a comment recommending it, and `resolveGlobalPermissions` returns an
34
- empty list when the host registered none, which `runPermissions` treats as
35
- allow. An app that followed the scaffold and stopped there had a fully open
36
- console surface. Every console function now declares its own
37
- `pikku:console:<area>:<action>` scope instead, which the function runner
38
- enforces per call. A blanket `wireAddon({ …, scopes: ['admin'] })` stood in for
39
- that briefly; it is gone, because a single grant covering secrets, source
40
- editing and the audit trail alike is not something an operator can reason
41
- about.
42
-
43
- The two functions whose failure mode is worst still do not depend on any
44
- package-wide gate:
45
-
46
- `getAgentThreads` derives `owners` from the session with core's
47
- `threadOwnerConstraint` and passes it on every call, omitting it only when the
48
- session holds the `admin` scope root — listing every thread is the legitimate
49
- purpose of an admin console, and `hasScopes` accepts the umbrella grant and its
50
- wildcards. The `owners` value is never read from input, so a caller cannot name
51
- someone else's principal. A session with no principal yields `[]`, which every
52
- storage backend already treats as no rows.
53
-
54
- `installAddon` and `installOpenapiAddon` run a package manager against an
55
- attacker-chosen package name and write a wiring file into the project. They were
56
- `pikkuSessionlessFunc` with `auth: false`, which — behind a `no-auth` RPC route
57
- and with no host global permission — meant an unauthenticated POST reached
58
- `execFileSync`. They now declare `auth: true` and
59
- `scopes: ['pikku:console:addons:install']`, enforced by `verifyScopes` in the
60
- function runner before the body runs. Both gates are
61
- checked whether or not the host registered a global permission — an app that
62
- hand-wires `wireAddon({ name: 'console', package: '@pikku/addon-console' })`
63
- still cannot reach `execFileSync` unauthenticated.
64
-
65
- The scopes are spelled as literals here because they are scope ids in this
66
- addon's own `wireScope` tree. The `admin:scopes:*` gates on the scope-admin
67
- functions come from a different tree — those functions now live in
68
- `@pikku/addon-admin`, which declares its own. The generated secret and variable
69
- brokers live in the app's own scaffold rather than the addon, so the addon
70
- boundary never covered them; they carry `pikku:console:secrets:*` and
71
- `pikku:console:variables:*` themselves.
72
-
73
- **What this rules out:** treating the host's `addGlobalPermission` as the only
74
- gate in front of an operation that installs code or reads another principal's
75
- data; deriving `owners` from request input; returning `owners: undefined` for a
76
- caller who simply has no principal; and gating these functions on a
77
- `metaService.basePath` check — that is a filesystem-availability test which the
78
- generated `PikkuMetaService` satisfies in any unbundled Node deployment, not an
79
- is-this-localhost test.
80
-
81
- See [[addon-scopes-are-resolved-where-the-function-runs]],
82
- [[an-empty-owners-constraint-matches-nothing]],
83
- [[agent-sessionless-deployments-have-no-thread-ownership]] and
84
- [[global-permissions-and-function-permissions-are-independent-gates]].
@@ -1,39 +0,0 @@
1
- ---
2
- type: decision
3
- title: Core's SSRF guard matches host literals because edge runtimes have no DNS
4
- description: safeFetch rejects internal address literals and re-validates every redirect hop; it cannot stop DNS rebinding
5
- tags: core
6
- ---
7
-
8
- # Core's SSRF guard matches host literals because edge runtimes have no DNS
9
-
10
- `packages/core/src/utils/safe-fetch.ts` guards every outbound fetch that core
11
- makes on a caller-supplied URL. `@pikku/core` runs in edge runtimes (Cloudflare
12
- Workers) that have no Node `dns` module, so the guard cannot resolve a hostname
13
- and inspect the resulting address. It instead rejects address _literals_ that are
14
- obviously internal — loopback, `10/8`, `172.16/12`, `192.168/16`, `0.0.0.0/8`,
15
- link-local `169.254/16` (the cloud metadata endpoint), IPv6 `::`, `::1`,
16
- `fe80::/10` and `fc00::/7` — plus the alias forms that reach the same targets:
17
- trailing-dot FQDNs, the reserved `*.localhost` names, IPv4-mapped IPv6, and the
18
- `inet_aton`-style octal/hex/32-bit-integer encodings that `fetch` and `undici`
19
- accept (`0177.0.0.1`, `0x7f000001`, `2130706433`).
20
-
21
- Literal matching alone is not enough, because the classic bypass is a public URL
22
- that 302s to `169.254.169.254`. So `safeFetch` sets `redirect: 'manual'` and
23
- re-validates every hop through `assertFetchableUrl` before following it, follows
24
- only the statuses in `REDIRECT_STATUSES` (301/302/303/307/308 — `300`, `304`,
25
- `305` and `306` are returned to the caller as-is), applies the WHATWG
26
- method/body transform per hop, cancels each intermediate response body, and
27
- strips `Authorization` and `Cookie` whenever a hop crosses origin. What it
28
- deliberately does **not** cover is DNS rebinding: a public hostname that itself
29
- resolves to a private IP passes, because catching that needs resolution the
30
- runtime does not offer.
31
-
32
- **What this rules out:** "simplifying" `isPrivateHost` down to a `localhost` /
33
- `127.0.0.1` string check — the octal, hex, integer and IPv4-mapped-IPv6 branches
34
- are each a live bypass, not defensive noise. It equally rules out replacing the
35
- manual redirect loop with `redirect: 'follow'` to shorten the function: the
36
- platform would then follow a `Location` into the internal network with no
37
- validation and no credential stripping, which is the entire attack this file
38
- exists to block. Do not add DNS-based checks either without gating them —
39
- importing `node:dns` breaks the Workers build.
@@ -1,37 +0,0 @@
1
- ---
2
- type: decision
3
- title: Core secrets are encrypted with a per-secret DEK wrapped by a KEK
4
- description: Envelope encryption keeps ciphertext untouched during key rotation, at the cost of storing two blobs per secret
5
- tags: core
6
- ---
7
-
8
- # Core secrets are encrypted with a per-secret DEK wrapped by a KEK
9
-
10
- `packages/core/src/crypto-utils.ts` exposes two layers. `encryptJSON` /
11
- `decryptJSON` are the direct layer: a passphrase is hashed to an AES-GCM key and
12
- the output is `base64url(iv || ciphertext)` with a 12-byte IV. On top of that sit
13
- `envelopeEncrypt`, `envelopeDecrypt` and `envelopeRewrap`, which give every stored
14
- secret its own random 32-byte DEK (data encryption key). The secret is encrypted
15
- with the DEK; the DEK is then encrypted with a KEK (key encryption key) — in
16
- practice an environment variable or platform secret — and the pair
17
- `{ ciphertext, wrappedDEK }` is what gets persisted.
18
-
19
- The split exists so that rotating the KEK is cheap and non-destructive.
20
- `envelopeRewrap` unwraps the DEK under the old KEK and re-wraps it under the new
21
- one; the ciphertext of the secret itself is never read, never re-encrypted, and
22
- never re-written. A store holding a million secrets rotates by touching a million
23
- short blobs rather than re-encrypting every payload, and a rotation that fails
24
- part-way leaves both halves independently decryptable by whichever KEK still
25
- wraps them. The `keyVersion` / `previousKey` / `rotateKEK` shape that
26
- `ServiceTestConfig` requires of every `SecretService` and `CredentialService`
27
- implementation (`packages/core/src/testing/service-tests.ts`) is the storage-side
28
- contract that falls out of this.
29
-
30
- **What this rules out:** collapsing the envelope back to a single
31
- `encryptJSON(kek, secret)` call, or deriving the DEK from the KEK rather than
32
- generating it randomly. Either change makes the ciphertext depend on the KEK, so
33
- rotation becomes a full re-encrypt of every stored secret and `envelopeRewrap`
34
- stops being correct. It also rules out changing the `iv || ciphertext` layout or
35
- the 12-byte IV length in either layer — the length is hard-coded on the decrypt
36
- side (`data.slice(0, 12)`, minimum length 13), so any change silently fails to
37
- read every previously stored value.
@@ -1,22 +0,0 @@
1
- ---
2
- type: decision
3
- title: CORS defaults to any origin and refuses the wildcard when credentials are on
4
- description: The cors middleware's origin defaults to *, and a resolved wildcard origin combined with credentials throws when the middleware is built
5
- tags: core, middleware, cors, security
6
- ---
7
-
8
- # CORS defaults to any origin and refuses the wildcard when credentials are on
9
-
10
- In `packages/core/src/middleware/cors.ts`, `origin` defaults to `'*'` (`:29`) and
11
- `credentials` defaults to `false` (`:33`). The factory throws when the resolved
12
- origin is `'*'` and credentials are on (`:36-40`). Because the check runs on the
13
- resolved value, the default origin with `credentials: true` throws too.
14
-
15
- A `true` origin reflects the request's own origin, or `*` when none is sent
16
- (`:55-56`). An array origin answers with the request origin only when it is in the
17
- list (`:57-61`). Any other request origin is left out of the response, with a debug
18
- log (`:62-65`).
19
-
20
- **What this rules out:** a wildcard origin together with credentials.
21
- `questions/does-cors-origin-true-reflect-any-origin-with-credentials.md` records
22
- the `true` case, which this check does not refuse.
@@ -1,29 +0,0 @@
1
- ---
2
- type: decision
3
- title: Credential backends are checked by one conformance suite that proves per-user isolation
4
- description: defineCredentialServiceTests asserts that one user's credential is invisible to another and that KEK rotation re-wraps stored values, for any backend that supplies a credential service
5
- tags: core, credentials, testing, isolation
6
- ---
7
-
8
- # Credential backends are checked by one conformance suite that proves per-user isolation
9
-
10
- `defineCredentialServiceTests` in `packages/core/src/testing/service-tests/credential-service-tests.ts`
11
- is the shared conformance suite for `credentialService`. Its doc comment says it
12
- "runs only when a backend supplies one" (`credential-service-tests.ts:6`), so a
13
- backend without a credential service is not checked by it.
14
-
15
- Per-user isolation is asserted directly. A value set for `user-1` is read back
16
- only for `user-1`, and `user-2` gets its own value (`credential-service-tests.ts:53-62`).
17
- A delete for one user leaves the other user's credential in place
18
- (`credential-service-tests.ts:64-72`). `getAll` for one user returns that user's
19
- credentials and omits another user's (`credential-service-tests.ts:85-95`), and
20
- returns `{}` for an unknown user (`credential-service-tests.ts:97-101`).
21
-
22
- KEK rotation is asserted too. After rotation to a new key version, a credential
23
- written under the old key is still readable, and the new key alone can read it
24
- (`credential-service-tests.ts:103-133`). Rotation without a `previousKey` throws
25
- (`credential-service-tests.ts:135-141`).
26
-
27
- **What this rules out:** a credential backend that returns one user's stored value
28
- to another user, or that rotates keys without re-wrapping existing credentials,
29
- while still passing the suite.
@@ -1,27 +0,0 @@
1
- ---
2
- type: decision
3
- title: Each stage has one virtual user key pair, and the app holds only the public half
4
- description: The deployer holds the private key, the app reads the public key from an unreserved variable, and users never see either
5
- tags: services
6
- ---
7
-
8
- # Each stage has one virtual user key pair, and the app holds only the public half
9
-
10
- | Environment | Private key held by | Public key reaches the app as |
11
- | --- | --- | --- |
12
- | `pikku dev` | Generated on first start into `<runtimeDir>/virtual-user/signing.key` (mode 0600, a `.gitignore` of `*` beside it); the CLI reads it there | `process.env.VIRTUAL_USER_VERIFY_KEY`, set before services are built |
13
- | Pikku Studio Cloud stage | Pikku Studio Cloud's backend, one pair per stage | the stage variable `VIRTUAL_USER_VERIFY_KEY`, set by Pikku Studio Cloud |
14
- | Open source deploy | The deployer's machine, as `VIRTUAL_USER_SIGNING_KEY` in the environment of whoever runs the CLI | the variable `VIRTUAL_USER_VERIFY_KEY`, set by the deployer |
15
-
16
- The app reads it with `variables.get('VIRTUAL_USER_VERIFY_KEY')`: the SPKI DER, base64
17
- on one line (a PEM is also accepted). A stage without it registers no statement
18
- endpoint, and the CLI's error for that says which variable to set.
19
-
20
- **One pair per stage** so a statement for one stage verifies nowhere else; the
21
- audience check is a second line, not the first. **Unreserved names**: neither starts
22
- with `PIKKU_` or `PIKKUSTUDIO_`, which a platform may refuse to let an app or a deployer
23
- set. **Users never manage keys**: `pikku dev` makes them and a deploy supplies them.
24
-
25
- **What this rules out:** one key shared across stages, a private key stored in the
26
- app's variables or secrets, and a key a person has to generate or paste to run
27
- scenarios locally.
@@ -1,41 +0,0 @@
1
- ---
2
- type: decision
3
- title: Gateway handlers run through the function runner gate
4
- description: A gateway's handler is registered as a real pikku function and invoked via runPikkuFunc, because calling it directly skips auth, scopes and permissions
5
- tags: gateway
6
- ---
7
-
8
- # Gateway handlers run through the function runner gate
9
-
10
- `registerGatewayHandler` in
11
- `packages/core/src/wirings/gateway/gateway-runner.ts` registers `config.func`
12
- under a synthetic function id (`gateway__<name>__handler`) and every transport —
13
- webhook POST, websocket message, listener callback — invokes it via
14
- `runPikkuFunc`. This looks like an unnecessary indirection: the handler is right
15
- there in the config and could be awaited directly. It cannot. The function
16
- runner's gate is the only thing that evaluates a function's declared `auth`,
17
- `scopes` and `permissions`; a direct call runs the handler with none of them
18
- checked.
19
-
20
- The synthetic registration **inherits the wired function's own metadata** —
21
- `sessionless`, input and output schema names, `scopes`, tag middleware — read
22
- back from `pikkuState(null, 'gateway', 'meta')[name].pikkuFuncId`, which the
23
- inspector already records. The synthetic id exists so the gate runs; it is not a
24
- licence to run the handler under metadata its author never wrote. A handler
25
- declared with `pikkuFunc` says session-required in meta rather than through an
26
- `auth` property, and that declaration is honoured.
27
-
28
- When nothing was declared — no inspector entry, as when a gateway is wired by
29
- hand — the handler falls back to `sessionless: true`. Gateway inbound traffic is
30
- authenticated by the platform adapter (webhook signature verification, platform
31
- tokens), not by a user session, so defaulting to session-required would reject
32
- every legitimate webhook. `CoreGateway.auth` and the handler's own `auth: true`
33
- opt back into requiring a session. `scopes` and `permissions` are enforced
34
- whenever declared, session or not.
35
-
36
- **What this rules out:** invoking `config.func` directly from any gateway
37
- transport as an optimisation, and "simplifying" the synthetic function
38
- registration away. It also rules out fabricating the handler's metadata rather
39
- than inheriting it, and flipping the _fallback_ to session-required as a
40
- hardening measure — that breaks every webhook that declared nothing, rather than
41
- securing it; require auth per gateway via `CoreGateway.auth` instead.
@@ -1,30 +0,0 @@
1
- ---
2
- type: decision
3
- title: Gateway middleware sessions must be bridged onto the wire
4
- description: Gateway middleware calling wire.setSession writes to a session service the handler's invocation never reads, so the session is copied onto wire.session before the gate runs
5
- tags: gateway
6
- ---
7
-
8
- # Gateway middleware sessions must be bridged onto the wire
9
-
10
- `bridgeMiddlewareSession` in
11
- `packages/core/src/wirings/gateway/gateway-runner.ts` runs immediately before
12
- every `runPikkuFunc` call in the gateway runner, copying `await wire.getSession()`
13
- onto `wire.session` when the latter is unset. Gateway middleware is the only
14
- place a webhook can acquire a session at all — typically by mapping a verified
15
- platform sender id to a user. Middleware that assigns `wire.session` directly
16
- needs no help, but the idiomatic `wire.setSession()` writes into the _enclosing
17
- wiring's_ session service, and the handler's own invocation does not read that
18
- service.
19
-
20
- Without the bridge, the failure mode is silent and it fails open in the way that
21
- matters: `auth` and `scopes` on the handler see no session, so a gateway whose
22
- middleware successfully authenticated the sender still evaluates its gate as
23
- unauthenticated. Nothing throws; the session is simply invisible.
24
-
25
- **What this rules out:** removing the `bridgeMiddlewareSession` call from any of
26
- the three transports (webhook POST, websocket message, listener) on the grounds
27
- that middleware "already set the session", and adding a fourth gateway transport
28
- that calls `runPikkuFunc` without bridging first. It also rules out relying on
29
- `wire.setSession()` alone anywhere the callee is a separately-registered pikku
30
- function.
@@ -1,40 +0,0 @@
1
- ---
2
- type: decision
3
- title: Global permissions and function permissions are independent gates
4
- description: Globals AND together and can only narrow access; a function's own group ORs internally and is never satisfied by a global
5
- tags: permissions
6
- ---
7
-
8
- # Global permissions and function permissions are independent gates
9
-
10
- `runPermissions` in `packages/core/src/permissions.ts` runs two gates and both
11
- must pass. Every requirement registered through `addGlobalPermission` is checked
12
- in turn and any failure throws `ForbiddenError` — globals AND, so a global can
13
- only ever narrow access, never grant it. The function's own `permissions` group
14
- is then evaluated by `verifyPermissions`, which ORs the group's branches and ANDs
15
- the entries within a branch: the group passes if at least one branch is
16
- satisfied.
17
-
18
- That OR inside `verifyPermissions` is the only OR in authorization. Everything
19
- cross-cutting — globals, scopes, auth — ANDs. A function's own group is the sole
20
- place where "owner OR admin"-style alternatives belong. Crucially, a global that
21
- passed contributes nothing to the function gate: a broad `signedIn` global cannot
22
- satisfy an admin-only function's requirements, because the two gates are
23
- evaluated independently against separate inputs. An empty or absent group passes,
24
- so declaring no permissions means "globals only", not "deny".
25
-
26
- Globals are bucketed per package, and a function reads _both_ the root bucket and
27
- its own package's — root first. The generated `addGlobalPermission` wrapper takes
28
- no package argument, so an application's rules only ever land in the root bucket;
29
- resolving the package bucket alone meant a host rule like "every request needs a
30
- signed-in user" silently stopped at the addon boundary, while the bucket an
31
- addon's functions actually read was one no host could write to. Unioning is safe
32
- in a way that nothing else here would be: globals AND, so adding the root ones
33
- can only tighten. Package buckets stay one-way — a package's globals never apply
34
- to root functions, or an installed addon could gate the whole application.
35
-
36
- **What this rules out:** short-circuiting the function gate when the globals
37
- passed, merging the global requirements into the function group (which would turn
38
- AND into OR and let any global satisfy any function), and giving
39
- `verifyPermissions` AND-across-branches semantics to "make it consistent" with
40
- the global gate.
@@ -1,25 +0,0 @@
1
- ---
2
- type: decision
3
- title: HMAC verification fails closed on empty or malformed inputs
4
- description: verifyHmacSignature returns false for an empty secret, a missing signature, an unknown algorithm, an empty key, a malformed hex signature or an empty signature
5
- tags: core, security, webhooks
6
- ---
7
-
8
- # HMAC verification fails closed on empty or malformed inputs
9
-
10
- `verifyHmacSignature` in `packages/core/src/utils/hmac.ts:142-161` returns `false`
11
- in each of these cases:
12
-
13
- - an empty secret or a missing signature (`:150`);
14
- - an algorithm with no entry in `HMAC_HASH` (`:153`);
15
- - a secret that decodes to an empty key (`:155`);
16
- - a hex encoding whose signature does not match `^(?:[0-9a-fA-F]{2})+$` (`:156-158`);
17
- - a signature that decodes to zero bytes (`:161`).
18
-
19
- The key is imported with WebCrypto `importKey` (`:162-166`). The doc comment at
20
- `:139-140` says the comparison is `crypto.subtle.verify('HMAC', ...)`, which runs
21
- in the platform's constant-time implementation. `timingSafeStringEqual`
22
- (`:52-63`) is a separate helper for opaque tokens and is not used for HMACs.
23
-
24
- **What this rules out:** treating an empty secret, or a signature that does not
25
- decode, as a match.
@@ -1,33 +0,0 @@
1
- ---
2
- type: decision
3
- title: HTTP error detail is withheld from clients in production
4
- description: 5xx bodies carry only a trace id in production; exposeErrors can widen that in development but never in production
5
- tags: http
6
- ---
7
-
8
- # HTTP error detail is withheld from clients in production
9
-
10
- `fetchData` in `packages/core/src/wirings/http/http-runner.ts` defaults
11
- `exposeErrors` to `!isProduction()`, and `handleHTTPError` in
12
- `packages/core/src/handle-error.ts` computes `clientFacing` as
13
- `errorResponse.status < 500 || (exposeErrors && !isProduction())`. Registered
14
- errors below 500 always return their own message and `payload`, because they
15
- describe something the caller did. Anything 500 and above returns only the
16
- registered generic message and the `errorId` trace id; the original `e.message`,
17
- `e.stack` and `payload` are dropped. The unregistered-error path is stricter
18
- still — it emits `{ errorId }` alone and attaches `message`/`stack` only when
19
- `exposeErrors && !isProduction()`.
20
-
21
- Unexpected 5xx messages are the ones that leak: driver errors carrying
22
- connection strings, ORM errors quoting rows, assertion text naming internal
23
- services. The trace id is the deliberate substitute — the operator correlates it
24
- with the logged error, which does carry the full message.
25
-
26
- Note the double gate. `exposeErrors` is re-checked against `isProduction()`
27
- inside `handleHTTPError` even though its default already accounts for it, so a
28
- runtime that passes `exposeErrors: true` explicitly still cannot open up a
29
- production deployment.
30
-
31
- **What this rules out:** collapsing the two `isProduction()` checks into the
32
- default value, letting a caller-supplied `exposeErrors` win in production, and
33
- "improving" the 5xx body by echoing `e.message` unconditionally.
@@ -1,46 +0,0 @@
1
- ---
2
- type: decision
3
- title: HTTP request bodies are bounded before they are buffered
4
- description: Content-Length is rejected up front and the stream is measured as it arrives, because that header is optional and attacker-controlled
5
- tags: http
6
- ---
7
-
8
- # HTTP request bodies are bounded before they are buffered
9
-
10
- `PikkuFetchHTTPRequest.#readBoundedBuffer` in
11
- `packages/core/src/wirings/http/pikku-fetch-http-request.ts` enforces
12
- `maxBodySize` twice. A declared `content-length` above the limit is rejected
13
- before a single byte is transferred, which is the cheap path. The body stream is
14
- then measured chunk by chunk anyway, cancelling the reader and throwing
15
- `PayloadTooLargeError` the moment the running total crosses the limit — because
16
- `content-length` is optional (chunked encoding omits it) and, when present, is
17
- whatever the client chose to write. Trusting it alone would let a request declare
18
- 1 KB and stream a gigabyte.
19
-
20
- `DEFAULT_MAX_BODY_SIZE` is 10 MB: ample for JSON APIs and ordinary uploads while
21
- keeping one request's memory footprint bounded, since the whole body is
22
- materialised in memory.
23
-
24
- Every adapter enforces the same limit and the same `PayloadTooLargeError`, but
25
- they divide into two kinds, and the difference is what can actually be
26
- prevented rather than merely reported:
27
-
28
- - **Prevention.** uWebSockets drives `res.onData` itself, so it counts bytes and
29
- _drops_ chunks past the limit rather than concatenating, replying 413 before
30
- routing — the only point at which the buffering can be stopped, which is why
31
- it deviates from the fetch adapter's 404-an-unmatched-route order. Fastify
32
- delegates to native `bodyLimit`, set only when `maxBodySize` is configured so
33
- the default never _loosens_ fastify's stricter 1 MB. `PikkuExpressServer`
34
- feeds the limit into `express.json`/`text`/`urlencoded`.
35
- - **Rejection only.** `express-middleware` is handed an already-parsed body, so
36
- its guard makes the rejection uniform but cannot reclaim the memory; a
37
- deployment mounting it on its own app must bound its own parser. Next server
38
- actions receive a decoded JS value with no wire size left to measure — the
39
- limit there is `experimental.serverActions.bodySizeLimit`.
40
-
41
- **What this rules out:** dropping the streaming measurement once the
42
- `content-length` check exists; raising the default because "10 MB is small" —
43
- raise it per-route via `maxBodySize` instead; reading the body with a plain
44
- `request.arrayBuffer()` anywhere that bypasses this method; and adding an
45
- adapter that buffers a body without a bound, on the assumption that some layer
46
- downstream will catch it.