@pikku/core 0.12.143 → 0.12.144

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (700) hide show
  1. package/dist/analytics/analytics.d.ts +14 -0
  2. package/dist/analytics/analytics.js +14 -0
  3. package/dist/analytics/analytics.types.d.ts +1 -0
  4. package/dist/analytics/anonymous-analytics-identity.d.ts +1 -0
  5. package/dist/analytics/cookie-analytics-identity.d.ts +1 -0
  6. package/dist/analytics/mint-cookie.d.ts +1 -0
  7. package/dist/{wirings/channel/channel-middleware-runner.d.ts → channel-middleware-runner.d.ts} +17 -3
  8. package/dist/{wirings/channel/channel-middleware-runner.js → channel-middleware-runner.js} +24 -8
  9. package/dist/classification/data-classification.d.ts +13 -0
  10. package/dist/classification/secret-value.d.ts +7 -0
  11. package/dist/classification/secret-value.js +7 -0
  12. package/dist/crypto-utils.d.ts +93 -0
  13. package/dist/crypto-utils.js +92 -0
  14. package/dist/dev/hot-reload.d.ts +16 -0
  15. package/dist/dev/hot-reload.js +16 -1
  16. package/dist/dev/module-runner.js +7 -3
  17. package/dist/dev/reload-meta.js +1 -1
  18. package/dist/errors/error-handler.d.ts +9 -0
  19. package/dist/errors/error-handler.js +8 -0
  20. package/dist/errors/errors.d.ts +219 -0
  21. package/dist/errors/errors.js +227 -0
  22. package/dist/errors/serialized-error.d.ts +4 -0
  23. package/dist/function/abort-scope.d.ts +5 -0
  24. package/dist/function/function-meta.types.d.ts +20 -0
  25. package/dist/function/function-runner.d.ts +41 -0
  26. package/dist/function/function-runner.js +57 -11
  27. package/dist/function/functions.types.d.ts +59 -0
  28. package/dist/function/functions.types.js +23 -0
  29. package/dist/function/list.types.d.ts +4 -0
  30. package/dist/lifecycle.d.ts +12 -1
  31. package/dist/lifecycle.js +12 -1
  32. package/dist/middleware/addon-scope-cap.d.ts +4 -0
  33. package/dist/middleware/addon-scope-cap.js +7 -3
  34. package/dist/middleware/auth-apikey.js +3 -3
  35. package/dist/middleware/auth-bearer.js +5 -13
  36. package/dist/middleware/auth-cookie.js +3 -3
  37. package/dist/middleware/middleware-factories.d.ts +17 -0
  38. package/dist/middleware/middleware-factories.js +17 -0
  39. package/dist/middleware/middleware.types.d.ts +23 -0
  40. package/dist/middleware/remote-auth.d.ts +15 -0
  41. package/dist/middleware/remote-auth.js +18 -3
  42. package/dist/middleware/remote-jobs-secret.js +2 -10
  43. package/dist/middleware-runner.d.ts +7 -0
  44. package/dist/middleware-runner.js +23 -7
  45. package/dist/permissions.d.ts +13 -0
  46. package/dist/permissions.js +13 -0
  47. package/dist/pikku-state.d.ts +49 -0
  48. package/dist/pikku-state.js +49 -0
  49. package/dist/remote.js +20 -5
  50. package/dist/schema.d.ts +36 -0
  51. package/dist/schema.js +36 -0
  52. package/dist/services/agent-run-state-service.d.ts +8 -0
  53. package/dist/services/agent-runner-service.d.ts +24 -0
  54. package/dist/services/agent-storage-service.d.ts +8 -0
  55. package/dist/services/ai-embedding-service.d.ts +4 -0
  56. package/dist/services/audit-service.d.ts +48 -0
  57. package/dist/services/audit-service.js +22 -0
  58. package/dist/services/content-service.d.ts +34 -0
  59. package/dist/services/credential-wire-service.d.ts +9 -0
  60. package/dist/services/credential-wire-service.js +9 -0
  61. package/dist/services/deployment-service.d.ts +14 -0
  62. package/dist/services/email-service.d.ts +20 -0
  63. package/dist/services/email-template.d.ts +24 -0
  64. package/dist/services/email-template.js +12 -0
  65. package/dist/services/file-scenario-run-store.d.ts +5 -0
  66. package/dist/services/file-scenario-run-store.js +4 -0
  67. package/dist/services/gateway-service.d.ts +5 -0
  68. package/dist/services/in-memory-agent-run-state-service.d.ts +5 -0
  69. package/dist/services/in-memory-agent-run-state-service.js +5 -0
  70. package/dist/services/in-memory-lease-service.d.ts +5 -0
  71. package/dist/services/in-memory-lease-service.js +5 -0
  72. package/dist/services/in-memory-session-store.d.ts +4 -0
  73. package/dist/services/in-memory-session-store.js +4 -0
  74. package/dist/services/incoming-webhook-queue.d.ts +2 -0
  75. package/dist/services/incoming-webhook-queue.js +2 -0
  76. package/dist/services/incoming-webhook-service.d.ts +9 -1
  77. package/dist/services/incoming-webhook-service.js +1 -1
  78. package/dist/services/index.d.ts +1 -5
  79. package/dist/services/index.js +1 -5
  80. package/dist/services/jwt-service.d.ts +8 -0
  81. package/dist/services/lease-service.d.ts +5 -0
  82. package/dist/services/lease-service.js +1 -0
  83. package/dist/services/local-content-request-handler.d.ts +20 -0
  84. package/dist/services/local-content-request-handler.js +11 -0
  85. package/dist/services/local-content.d.ts +45 -0
  86. package/dist/services/local-content.js +35 -0
  87. package/dist/services/local-credential-service.d.ts +5 -0
  88. package/dist/services/local-credential-service.js +5 -0
  89. package/dist/services/local-email-service.d.ts +7 -0
  90. package/dist/services/local-email-service.js +7 -0
  91. package/dist/services/local-secrets.d.ts +8 -0
  92. package/dist/services/local-secrets.js +8 -0
  93. package/dist/services/local-variables.d.ts +6 -0
  94. package/dist/services/local-variables.js +6 -0
  95. package/dist/services/logger.d.ts +4 -0
  96. package/dist/services/logger.js +4 -0
  97. package/dist/services/meta-service.d.ts +38 -0
  98. package/dist/services/meta-service.js +6 -0
  99. package/dist/services/queue-webhook-service.d.ts +19 -0
  100. package/dist/services/queue-webhook-service.js +19 -0
  101. package/dist/services/remote-jobs.d.ts +8 -13
  102. package/dist/services/remote-jobs.js +3 -54
  103. package/dist/services/scenario-cookie-jar.d.ts +4 -0
  104. package/dist/services/scheduler-service.d.ts +13 -0
  105. package/dist/services/scheduler-service.js +8 -0
  106. package/dist/services/schema-service.d.ts +9 -0
  107. package/dist/services/scope-service.d.ts +10 -0
  108. package/dist/services/scoped-secret-service.d.ts +5 -0
  109. package/dist/services/scoped-secret-service.js +5 -0
  110. package/dist/services/secret-host-binding.d.ts +5 -0
  111. package/dist/services/secret-host-binding.js +5 -0
  112. package/dist/services/secret-service.d.ts +19 -1
  113. package/dist/services/secretless.d.ts +6 -0
  114. package/dist/services/secretless.js +6 -0
  115. package/dist/services/session-store.d.ts +5 -0
  116. package/dist/services/stub-tracker.d.ts +1 -0
  117. package/dist/services/temporary-file-service.d.ts +9 -0
  118. package/dist/services/temporary-file-service.js +9 -0
  119. package/dist/services/trigger-service.d.ts +4 -0
  120. package/dist/services/trigger-source-store.d.ts +13 -0
  121. package/dist/services/trigger-source-store.js +7 -0
  122. package/dist/services/typed-credential-service.d.ts +6 -0
  123. package/dist/services/typed-credential-service.js +5 -0
  124. package/dist/services/typed-secret-service.d.ts +12 -0
  125. package/dist/services/typed-secret-service.js +11 -0
  126. package/dist/services/typed-variables-service.d.ts +1 -0
  127. package/dist/services/user-session-service.d.ts +31 -1
  128. package/dist/services/user-session-service.js +29 -3
  129. package/dist/services/v8-coverage-service.d.ts +27 -0
  130. package/dist/services/v8-coverage-service.js +5 -0
  131. package/dist/services/variables-service.d.ts +8 -0
  132. package/dist/services/virtual-user-sign-in.d.ts +1 -0
  133. package/dist/services/virtual-user-statement.d.ts +8 -0
  134. package/dist/services/virtual-user-statement.js +4 -0
  135. package/dist/services/webhook-service.d.ts +25 -0
  136. package/dist/services/webhook-service.js +15 -0
  137. package/dist/services/workflow-service.d.ts +6 -0
  138. package/dist/test-utils.js +1 -1
  139. package/dist/testing/service-tests.d.ts +4 -0
  140. package/dist/time-utils.d.ts +15 -0
  141. package/dist/time-utils.js +14 -0
  142. package/dist/types/core.types.d.ts +80 -0
  143. package/dist/types/state.types.d.ts +4 -0
  144. package/dist/utils/hmac.d.ts +3 -0
  145. package/dist/utils/safe-fetch.d.ts +14 -0
  146. package/dist/utils/safe-fetch.js +13 -0
  147. package/dist/utils/stable-stringify.d.ts +11 -0
  148. package/dist/utils/stable-stringify.js +33 -0
  149. package/dist/utils.d.ts +28 -0
  150. package/dist/utils.js +22 -0
  151. package/dist/version.d.ts +7 -0
  152. package/dist/version.js +7 -0
  153. package/dist/wirings/addon/define-screens.d.ts +2 -0
  154. package/dist/wirings/addon/remote-addon-auth.d.ts +9 -0
  155. package/dist/wirings/addon/remote-addon-auth.js +5 -0
  156. package/dist/wirings/addon/wire-addon.d.ts +4 -0
  157. package/dist/wirings/addon/wire-remote-addon.d.ts +1 -0
  158. package/dist/wirings/agent/agent-agui.d.ts +14 -5
  159. package/dist/wirings/agent/agent-agui.js +17 -6
  160. package/dist/wirings/agent/agent-helpers.d.ts +61 -1
  161. package/dist/wirings/agent/agent-helpers.js +62 -2
  162. package/dist/wirings/agent/agent-interrupt.d.ts +5 -0
  163. package/dist/wirings/agent/agent-output.d.ts +20 -0
  164. package/dist/wirings/agent/agent-output.js +69 -0
  165. package/dist/wirings/agent/agent-prepare.d.ts +41 -0
  166. package/dist/wirings/agent/agent-prepare.js +38 -2
  167. package/dist/wirings/agent/agent-registry.d.ts +8 -0
  168. package/dist/wirings/agent/agent-registry.js +10 -4
  169. package/dist/wirings/agent/agent-runner.d.ts +33 -0
  170. package/dist/wirings/agent/agent-runner.js +40 -7
  171. package/dist/wirings/agent/agent-stream.d.ts +30 -0
  172. package/dist/wirings/agent/agent-stream.js +33 -11
  173. package/dist/wirings/agent/agent.types.d.ts +43 -0
  174. package/dist/wirings/agent/voice-input.d.ts +12 -0
  175. package/dist/wirings/agent/voice-input.js +12 -0
  176. package/dist/wirings/agent/voice-output.d.ts +14 -0
  177. package/dist/wirings/agent/voice-output.js +10 -0
  178. package/dist/wirings/agent-scorer/agent-scorer-judge.js +1 -2
  179. package/dist/wirings/agent-scorer/agent-scorer-registry.d.ts +10 -0
  180. package/dist/wirings/agent-scorer/agent-scorer-registry.js +10 -0
  181. package/dist/wirings/agent-scorer/agent-scorer-snapshots.d.ts +1 -0
  182. package/dist/wirings/agent-scorer/agent-scorer-snapshots.js +1 -0
  183. package/dist/wirings/agent-scorer/agent-scorer.types.d.ts +7 -0
  184. package/dist/wirings/channel/channel-common.js +1 -1
  185. package/dist/wirings/channel/channel-rpc.types.d.ts +5 -0
  186. package/dist/wirings/channel/channel-runner.d.ts +22 -0
  187. package/dist/wirings/channel/channel-runner.js +22 -0
  188. package/dist/wirings/channel/channel-store.d.ts +8 -0
  189. package/dist/wirings/channel/channel-store.js +7 -0
  190. package/dist/wirings/channel/channel.types.d.ts +18 -0
  191. package/dist/wirings/channel/define-channel-routes.d.ts +5 -0
  192. package/dist/wirings/channel/define-channel-routes.js +5 -0
  193. package/dist/wirings/channel/eventhub-service.d.ts +9 -0
  194. package/dist/wirings/channel/eventhub-store.d.ts +1 -0
  195. package/dist/wirings/channel/eventhub-store.js +1 -0
  196. package/dist/wirings/channel/index.d.ts +1 -1
  197. package/dist/wirings/channel/index.js +1 -1
  198. package/dist/wirings/channel/local/local-channel-handler.d.ts +1 -0
  199. package/dist/wirings/channel/local/local-channel-handler.js +1 -0
  200. package/dist/wirings/channel/local/local-channel-runner.d.ts +13 -0
  201. package/dist/wirings/channel/local/local-channel-runner.js +13 -0
  202. package/dist/wirings/channel/local/local-eventhub-service.d.ts +1 -0
  203. package/dist/wirings/channel/local/local-eventhub-service.js +1 -0
  204. package/dist/wirings/channel/log-channels.d.ts +1 -0
  205. package/dist/wirings/channel/log-channels.js +1 -0
  206. package/dist/wirings/channel/pikku-abstract-channel-handler.d.ts +5 -0
  207. package/dist/wirings/channel/pikku-abstract-channel-handler.js +5 -0
  208. package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +32 -0
  209. package/dist/wirings/channel/serverless/serverless-channel-runner.js +31 -0
  210. package/dist/wirings/cli/channel/cli-channel-runner.d.ts +8 -0
  211. package/dist/wirings/cli/channel/cli-channel-runner.js +8 -0
  212. package/dist/wirings/cli/channel/cli-raw-channel-runner.d.ts +1 -0
  213. package/dist/wirings/cli/cli-runner.d.ts +43 -0
  214. package/dist/wirings/cli/cli-runner.js +43 -0
  215. package/dist/wirings/cli/command-parser.d.ts +13 -0
  216. package/dist/wirings/cli/command-parser.js +12 -0
  217. package/dist/wirings/credential/credential-overrides.d.ts +1 -0
  218. package/dist/wirings/credential/credential.types.d.ts +7 -0
  219. package/dist/wirings/credential/validate-credential-definitions.d.ts +7 -0
  220. package/dist/wirings/credential/validate-credential-definitions.js +7 -0
  221. package/dist/wirings/flag/cached-flag-source.d.ts +1 -0
  222. package/dist/wirings/flag/flag.types.d.ts +3 -0
  223. package/dist/wirings/gateway/gateway-runner.d.ts +23 -0
  224. package/dist/wirings/gateway/gateway-runner.js +23 -0
  225. package/dist/wirings/gateway/gateway.types.d.ts +3 -0
  226. package/dist/wirings/gateway/local-gateway-service.d.ts +10 -0
  227. package/dist/{services → wirings/gateway}/local-gateway-service.js +6 -2
  228. package/dist/wirings/http/http-routes.d.ts +21 -0
  229. package/dist/wirings/http/http-routes.js +11 -0
  230. package/dist/wirings/http/http-runner.d.ts +71 -0
  231. package/dist/wirings/http/http-runner.js +73 -5
  232. package/dist/wirings/http/http.types.d.ts +27 -0
  233. package/dist/wirings/http/index.d.ts +1 -0
  234. package/dist/wirings/http/index.js +1 -0
  235. package/dist/wirings/http/log-http-routes.d.ts +1 -0
  236. package/dist/wirings/http/log-http-routes.js +1 -0
  237. package/dist/wirings/http/merge-request-data.d.ts +12 -0
  238. package/dist/wirings/http/merge-request-data.js +42 -0
  239. package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -0
  240. package/dist/wirings/http/pikku-fetch-http-request.js +3 -32
  241. package/dist/wirings/http/pikku-fetch-http-response.d.ts +1 -0
  242. package/dist/wirings/http/pikku-fetch-http-response.js +1 -0
  243. package/dist/wirings/http/routers/http-router.d.ts +6 -0
  244. package/dist/wirings/http/routers/http-router.js +6 -0
  245. package/dist/wirings/http/web-request.d.ts +17 -0
  246. package/dist/wirings/http/web-request.js +17 -0
  247. package/dist/wirings/mcp/mcp-endpoint-registry.d.ts +7 -0
  248. package/dist/wirings/mcp/mcp-endpoint-registry.js +7 -0
  249. package/dist/wirings/mcp/mcp-runner.d.ts +63 -0
  250. package/dist/wirings/mcp/mcp-runner.js +62 -0
  251. package/dist/wirings/mcp/mcp.types.d.ts +12 -0
  252. package/dist/wirings/node/node.types.d.ts +4 -0
  253. package/dist/wirings/oauth2/oauth2.types.d.ts +2 -0
  254. package/dist/{services → wirings/queue}/in-memory-queue-service.d.ts +9 -1
  255. package/dist/{services → wirings/queue}/in-memory-queue-service.js +9 -1
  256. package/dist/wirings/queue/index.d.ts +1 -0
  257. package/dist/wirings/queue/index.js +1 -0
  258. package/dist/wirings/queue/queue-identity.js +2 -14
  259. package/dist/wirings/queue/queue-runner.d.ts +37 -0
  260. package/dist/wirings/queue/queue-runner.js +37 -0
  261. package/dist/wirings/queue/queue.types.d.ts +35 -0
  262. package/dist/wirings/queue/register-queue-helper.d.ts +12 -0
  263. package/dist/wirings/queue/register-queue-helper.js +11 -0
  264. package/dist/wirings/queue/remote-queue-job.d.ts +11 -0
  265. package/dist/wirings/queue/remote-queue-job.js +41 -0
  266. package/dist/wirings/queue/validate-worker-config.d.ts +1 -0
  267. package/dist/wirings/role/role.types.d.ts +3 -0
  268. package/dist/wirings/rpc/rpc-runner.d.ts +24 -0
  269. package/dist/wirings/rpc/rpc-runner.js +37 -2
  270. package/dist/wirings/rpc/rpc-types.d.ts +2 -0
  271. package/dist/wirings/scheduler/index.d.ts +1 -0
  272. package/dist/wirings/scheduler/index.js +1 -0
  273. package/dist/wirings/scheduler/log-schedulers.d.ts +1 -0
  274. package/dist/wirings/scheduler/log-schedulers.js +1 -0
  275. package/dist/wirings/scheduler/remote-scheduled-job.d.ts +11 -0
  276. package/dist/wirings/scheduler/remote-scheduled-job.js +20 -0
  277. package/dist/wirings/scheduler/scheduler-runner.d.ts +29 -0
  278. package/dist/wirings/scheduler/scheduler-runner.js +28 -0
  279. package/dist/wirings/scheduler/scheduler.types.d.ts +3 -0
  280. package/dist/wirings/scope/scope.types.d.ts +5 -0
  281. package/dist/wirings/secret/index.d.ts +2 -2
  282. package/dist/wirings/secret/index.js +1 -1
  283. package/dist/wirings/secret/secret.types.d.ts +26 -1
  284. package/dist/wirings/secret/secret.types.js +1 -0
  285. package/dist/wirings/secret/validate-secret-definitions.d.ts +8 -0
  286. package/dist/wirings/secret/validate-secret-definitions.js +15 -0
  287. package/dist/wirings/trigger/in-memory-trigger-service.d.ts +11 -0
  288. package/dist/{services → wirings/trigger}/in-memory-trigger-service.js +10 -3
  289. package/dist/wirings/trigger/index.d.ts +1 -1
  290. package/dist/wirings/trigger/pikku-trigger-service.d.ts +8 -3
  291. package/dist/wirings/trigger/pikku-trigger-service.js +14 -3
  292. package/dist/wirings/trigger/trigger-runner.d.ts +27 -2
  293. package/dist/wirings/trigger/trigger-runner.js +35 -2
  294. package/dist/wirings/trigger/trigger.types.d.ts +26 -4
  295. package/dist/wirings/trigger/webhook-source-runner.d.ts +24 -0
  296. package/dist/wirings/trigger/webhook-source-runner.js +19 -0
  297. package/dist/wirings/trigger/webhook-source.types.d.ts +12 -2
  298. package/dist/wirings/trigger/webhook-source.types.js +1 -1
  299. package/dist/wirings/variable/validate-variable-definitions.d.ts +7 -0
  300. package/dist/wirings/variable/validate-variable-definitions.js +7 -0
  301. package/dist/wirings/variable/variable.types.d.ts +7 -0
  302. package/dist/wirings/virtual-user/conversation/conversation.types.d.ts +5 -0
  303. package/dist/wirings/virtual-user/conversation/run-conversation.d.ts +6 -0
  304. package/dist/wirings/virtual-user/conversation/run-conversation.js +1 -1
  305. package/dist/{services → wirings/virtual-user}/http-virtual-users.d.ts +4 -3
  306. package/dist/{services → wirings/virtual-user}/http-virtual-users.js +6 -6
  307. package/dist/wirings/virtual-user/index.d.ts +1 -1
  308. package/dist/wirings/virtual-user/index.js +1 -1
  309. package/dist/wirings/virtual-user/run-virtual-user.d.ts +2 -1
  310. package/dist/wirings/virtual-user/run-virtual-user.js +1 -14
  311. package/dist/wirings/virtual-user/virtual-user-declaration.types.d.ts +4 -0
  312. package/dist/wirings/virtual-user/virtual-user-scaffold.d.ts +10 -1
  313. package/dist/wirings/virtual-user/virtual-user-scaffold.js +5 -0
  314. package/dist/wirings/virtual-user/virtual-user-schedule.d.ts +5 -0
  315. package/dist/wirings/virtual-user/virtual-user-schedule.js +1 -0
  316. package/dist/wirings/virtual-user/virtual-user-target.d.ts +1 -0
  317. package/dist/wirings/webhook/define-outgoing-webhook.d.ts +20 -0
  318. package/dist/wirings/webhook/define-outgoing-webhook.js +9 -0
  319. package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +8 -4
  320. package/dist/wirings/workflow/dsl/workflow-runner.d.ts +7 -0
  321. package/dist/wirings/workflow/dsl/workflow-runner.js +7 -0
  322. package/dist/wirings/workflow/feature.d.ts +12 -0
  323. package/dist/wirings/workflow/feature.js +12 -0
  324. package/dist/wirings/workflow/graph/graph-node.d.ts +5 -0
  325. package/dist/wirings/workflow/graph/graph-node.js +5 -0
  326. package/dist/wirings/workflow/graph/template.d.ts +6 -0
  327. package/dist/wirings/workflow/graph/template.js +5 -0
  328. package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +12 -0
  329. package/dist/wirings/workflow/graph/wire-workflow-graph.js +10 -0
  330. package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +11 -0
  331. package/dist/wirings/workflow/graph/workflow-graph.types.js +1 -0
  332. package/dist/{services → wirings/workflow}/in-memory-workflow-service.d.ts +8 -3
  333. package/dist/{services → wirings/workflow}/in-memory-workflow-service.js +9 -4
  334. package/dist/wirings/workflow/pikku-scenario-service.d.ts +1 -1
  335. package/dist/wirings/workflow/pikku-scenario-service.js +2 -2
  336. package/dist/wirings/workflow/pikku-workflow-service.d.ts +1 -0
  337. package/dist/wirings/workflow/pikku-workflow-service.js +1 -0
  338. package/dist/wirings/workflow/run-timeline.d.ts +21 -0
  339. package/dist/wirings/workflow/run-timeline.js +15 -7
  340. package/dist/wirings/workflow/scenario-coverage.d.ts +1 -0
  341. package/dist/wirings/workflow/scenario-poll.d.ts +1 -0
  342. package/dist/wirings/workflow/scenario-prose.d.ts +6 -0
  343. package/dist/wirings/workflow/scenario-prose.js +6 -0
  344. package/dist/wirings/workflow/scenario-run.types.d.ts +3 -0
  345. package/dist/wirings/workflow/scenario-step.types.d.ts +1 -0
  346. package/dist/wirings/workflow/scenario-step.types.js +1 -0
  347. package/dist/wirings/workflow/scenario-surface.js +1 -13
  348. package/dist/wirings/workflow/scenario.types.d.ts +6 -0
  349. package/dist/wirings/workflow/workflow-approval-policy.d.ts +6 -0
  350. package/dist/wirings/workflow/workflow-approval-policy.js +6 -0
  351. package/dist/wirings/workflow/workflow-constants.d.ts +7 -1
  352. package/dist/wirings/workflow/workflow-constants.js +10 -1
  353. package/dist/wirings/workflow/workflow-errors.d.ts +13 -0
  354. package/dist/wirings/workflow/workflow-errors.js +13 -0
  355. package/dist/wirings/workflow/workflow-invocation-id.d.ts +4 -0
  356. package/dist/wirings/workflow/workflow-invocation-id.js +4 -0
  357. package/dist/wirings/workflow/workflow-queue-workers.d.ts +3 -0
  358. package/dist/wirings/workflow/workflow-run-ownership.d.ts +1 -0
  359. package/dist/wirings/workflow/workflow-run-ownership.js +1 -0
  360. package/dist/wirings/workflow/workflow-status-stream.d.ts +1 -0
  361. package/dist/wirings/workflow/workflow-unwind-plan.js +2 -7
  362. package/dist/wirings/workflow/workflow.types.d.ts +40 -0
  363. package/package.json +26 -9
  364. package/CHANGELOG.md +0 -6978
  365. package/dist/services/in-memory-trigger-service.d.ts +0 -4
  366. package/dist/services/local-gateway-service.d.ts +0 -6
  367. package/dist/utils/hash.d.ts +0 -2
  368. package/dist/utils/hash.js +0 -23
  369. package/knowledge/decisions/index.md +0 -19
  370. package/knowledge/decisions/internals/a-credential-name-declared-twice-must-agree-on-schema-and-type.md +0 -29
  371. package/knowledge/decisions/internals/a-grant-can-name-a-scope-declared-without-its-addon.md +0 -29
  372. package/knowledge/decisions/internals/a-held-run-is-woken-later-not-retried.md +0 -28
  373. package/knowledge/decisions/internals/a-latency-budget-is-asserted-by-its-cause.md +0 -32
  374. package/knowledge/decisions/internals/a-non-streaming-agent-run-registers-with-agentrunstate-too.md +0 -22
  375. package/knowledge/decisions/internals/a-reset-suite-makes-the-dev-seed-the-fixture.md +0 -50
  376. package/knowledge/decisions/internals/a-resumed-agent-turn-is-as-interruptible-as-the-first.md +0 -20
  377. package/knowledge/decisions/internals/a-scenario-step-template-is-offered-unfilled.md +0 -21
  378. package/knowledge/decisions/internals/a-scheduled-task-writes-its-caller-session-before-it-runs.md +0 -22
  379. package/knowledge/decisions/internals/a-secret-set-in-memory-shadows-the-variable-of-the-same-name.md +0 -28
  380. package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +0 -49
  381. package/knowledge/decisions/internals/a-virtual-user-acts-through-invokeraw-so-a-refusal-is-data.md +0 -32
  382. package/knowledge/decisions/internals/a-virtual-user-cadence-is-a-row-not-a-timer.md +0 -66
  383. package/knowledge/decisions/internals/a-virtual-user-converse-signs-in-before-its-first-turn.md +0 -24
  384. package/knowledge/decisions/internals/a-virtual-user-decides-whether-to-trust-memory-once-per-turn.md +0 -21
  385. package/knowledge/decisions/internals/a-virtual-user-email-is-computed-with-the-run-id-as-a-sub-address.md +0 -34
  386. package/knowledge/decisions/internals/a-virtual-user-run-is-not-a-workflow-but-it-needs-a-trigger.md +0 -65
  387. package/knowledge/decisions/internals/a-wall-clock-threshold-is-a-load-test-in-disguise.md +0 -49
  388. package/knowledge/decisions/internals/a-workflow-wire-is-built-from-the-run-not-from-the-rpc-service.md +0 -45
  389. package/knowledge/decisions/internals/addon-package-roots-resolve-by-walking-node-module-search-paths.md +0 -26
  390. package/knowledge/decisions/internals/addon-pikku-meta-ships-at-the-package-root-or-under-dist.md +0 -32
  391. package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +0 -33
  392. package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +0 -28
  393. package/knowledge/decisions/internals/agent-agui-bridge-obeys-the-client-ordering-contract.md +0 -29
  394. package/knowledge/decisions/internals/agent-audio-chunks-carry-the-format-the-provider-returned.md +0 -20
  395. package/knowledge/decisions/internals/agent-context-waits-for-a-tool-result-still-being-written.md +0 -21
  396. package/knowledge/decisions/internals/agent-credential-suspensions-hide-the-tool-result.md +0 -26
  397. package/knowledge/decisions/internals/agent-delegate-and-supervise-hide-different-text.md +0 -26
  398. package/knowledge/decisions/internals/agent-llm-tool-arguments-have-nulls-stripped.md +0 -23
  399. package/knowledge/decisions/internals/agent-model-config-stays-a-single-resolution-seam.md +0 -25
  400. package/knowledge/decisions/internals/agent-onerror-hooks-cannot-change-the-failure.md +0 -22
  401. package/knowledge/decisions/internals/agent-runner-methods-must-keep-their-receiver.md +0 -22
  402. package/knowledge/decisions/internals/agent-speech-travels-as-a-custom-agui-event.md +0 -22
  403. package/knowledge/decisions/internals/agent-stream-persistence-is-best-effort.md +0 -27
  404. package/knowledge/decisions/internals/agent-sub-agents-inherit-the-parent-context-block.md +0 -26
  405. package/knowledge/decisions/internals/agent-tool-execute-failures-are-logged-unconditionally.md +0 -25
  406. package/knowledge/decisions/internals/agent-voice-input-transcribes-audio-parts-in-place.md +0 -22
  407. package/knowledge/decisions/internals/agent-working-memory-is-persisted-only-when-valid.md +0 -25
  408. package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +0 -39
  409. package/knowledge/decisions/internals/an-agent-interrupt-is-not-a-failure.md +0 -23
  410. package/knowledge/decisions/internals/an-agent-is-offered-under-its-registry-key-and-only-within-the-virtual-users-scopes.md +0 -27
  411. package/knowledge/decisions/internals/an-agent-run-owned-by-another-instance-says-so.md +0 -25
  412. package/knowledge/decisions/internals/an-agent-stream-send-must-return-the-inner-sends-promise.md +0 -22
  413. package/knowledge/decisions/internals/an-empty-text-part-is-omitted-from-an-agent-message.md +0 -20
  414. package/knowledge/decisions/internals/an-empty-transcript-is-not-recorded.md +0 -22
  415. package/knowledge/decisions/internals/an-oauth2-credential-implies-an-optional-app-secret.md +0 -26
  416. package/knowledge/decisions/internals/an-unref-d-timer-cannot-be-awaited-under-node-test.md +0 -66
  417. package/knowledge/decisions/internals/analytics-identity-resolvers-run-in-declared-order.md +0 -22
  418. package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +0 -30
  419. package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +0 -31
  420. package/knowledge/decisions/internals/channel-state-accessors-are-unsound-generics-that-every-implementation-asserts.md +0 -33
  421. package/knowledge/decisions/internals/channel-state-is-per-socket-session-state-is-per-user.md +0 -29
  422. package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +0 -28
  423. package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +0 -27
  424. package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +0 -28
  425. package/knowledge/decisions/internals/cli-stdout-is-reserved-for-machine-readable-output.md +0 -34
  426. package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +0 -29
  427. package/knowledge/decisions/internals/core-column-form-is-an-axis-of-its-own.md +0 -84
  428. package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +0 -41
  429. package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +0 -44
  430. package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +0 -39
  431. package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +0 -42
  432. package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +0 -39
  433. package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +0 -43
  434. package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +0 -38
  435. package/knowledge/decisions/internals/core-state-is-a-global-map-written-only-at-registration-time.md +0 -44
  436. package/knowledge/decisions/internals/email-meta-is-read-uncached-because-codegen-rewrites-it-mid-session.md +0 -27
  437. package/knowledge/decisions/internals/feature-flag-declarations-refuse-an-empty-anyof-and-conflicting-scopes.md +0 -22
  438. package/knowledge/decisions/internals/feature-flags-fail-open-and-never-enforce-access.md +0 -28
  439. package/knowledge/decisions/internals/flag-sync-rewrites-only-the-declared-text.md +0 -24
  440. package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +0 -32
  441. package/knowledge/decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md +0 -43
  442. package/knowledge/decisions/internals/gateway-webhook-challenges-echo-bytes-not-json.md +0 -28
  443. package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +0 -31
  444. package/knowledge/decisions/internals/generated-src-paths-in-pikku-meta-are-absolute.md +0 -26
  445. package/knowledge/decisions/internals/global-middleware-resolves-from-the-root-namespace-too.md +0 -32
  446. package/knowledge/decisions/internals/hot-reload-reads-the-changed-source-never-a-compiled-copy.md +0 -38
  447. package/knowledge/decisions/internals/hot-reload-writes-into-the-function-map-captured-at-startup.md +0 -26
  448. package/knowledge/decisions/internals/http-request-bodies-are-read-once-and-shared.md +0 -32
  449. package/knowledge/decisions/internals/http-route-groups-cascade-config-in-a-fixed-order.md +0 -28
  450. package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +0 -30
  451. package/knowledge/decisions/internals/http-runner-logs-through-a-trace-scoped-logger-functions-do-not.md +0 -26
  452. package/knowledge/decisions/internals/http-set-cookie-headers-are-appended-never-joined.md +0 -28
  453. package/knowledge/decisions/internals/http-sse-streams-flush-headers-only-after-middleware.md +0 -32
  454. package/knowledge/decisions/internals/http-wiring-without-metadata-is-skipped-not-fatal.md +0 -26
  455. package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +0 -25
  456. package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +0 -26
  457. package/knowledge/decisions/internals/index.md +0 -182
  458. package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +0 -25
  459. package/knowledge/decisions/internals/local-trigger-and-gateway-services-assume-a-single-process.md +0 -26
  460. package/knowledge/decisions/internals/mcp-wire-names-are-assigned-over-the-whole-registry.md +0 -39
  461. package/knowledge/decisions/internals/node-only-builtins-are-imported-dynamically.md +0 -24
  462. package/knowledge/decisions/internals/one-project-shape-check-two-validators.md +0 -53
  463. package/knowledge/decisions/internals/only-exposed-functions-enter-a-virtual-user-catalogue.md +0 -21
  464. package/knowledge/decisions/internals/queue-group-concurrency-keeps-one-shared-queue-fair.md +0 -28
  465. package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +0 -27
  466. package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +0 -31
  467. package/knowledge/decisions/internals/role-names-cannot-contain-the-scope-separator.md +0 -30
  468. package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +0 -32
  469. package/knowledge/decisions/internals/scenario-agent-calls-sign-in-on-401-only.md +0 -31
  470. package/knowledge/decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md +0 -24
  471. package/knowledge/decisions/internals/scenario-meta-lives-apart-from-app-meta-but-merges-when-read-off-disk.md +0 -26
  472. package/knowledge/decisions/internals/scenario-steps-return-drained-response-records.md +0 -27
  473. package/knowledge/decisions/internals/scenarios-live-in-files-named-for-them.md +0 -48
  474. package/knowledge/decisions/internals/scope-roots-may-be-co-declared-by-an-addon-and-its-host-app.md +0 -30
  475. package/knowledge/decisions/internals/serverless-channel-disconnect-must-tolerate-a-missing-channel.md +0 -28
  476. package/knowledge/decisions/internals/side-effects-are-an-allowlist-not-a-boolean.md +0 -34
  477. package/knowledge/decisions/internals/speech-synthesis-picks-a-voice-per-sentence-and-warns-once.md +0 -24
  478. package/knowledge/decisions/internals/the-agent-done-event-goes-through-the-middleware-and-is-awaited.md +0 -26
  479. package/knowledge/decisions/internals/the-api-report-pins-members-not-just-names.md +0 -43
  480. package/knowledge/decisions/internals/the-core-scope-validator-refuses-separator-wildcard-and-empty-segments.md +0 -22
  481. package/knowledge/decisions/internals/the-dev-queue-copies-prod-timing-and-serialization-semantics.md +0 -30
  482. package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md +0 -83
  483. package/knowledge/decisions/internals/the-embedding-model-is-pinned-per-service-and-doc-query-embedding-is-split.md +0 -29
  484. package/knowledge/decisions/internals/the-in-memory-workflow-service-is-inline-only-and-single-process.md +0 -27
  485. package/knowledge/decisions/internals/the-kek-salt-is-scoped-to-the-key-version.md +0 -40
  486. package/knowledge/decisions/internals/the-mcp-handshake-is-challenged-only-when-every-target-is-gated.md +0 -29
  487. package/knowledge/decisions/internals/the-middleware-resolution-cache-is-deliberately-unbounded.md +0 -40
  488. package/knowledge/decisions/internals/the-per-invocation-rpc-view-is-a-class.md +0 -40
  489. package/knowledge/decisions/internals/the-pikku-user-id-resolves-in-a-fixed-order.md +0 -24
  490. package/knowledge/decisions/internals/the-runner-resolves-wire-services-itself.md +0 -31
  491. package/knowledge/decisions/internals/the-schema-service-is-never-stubbed.md +0 -26
  492. package/knowledge/decisions/internals/the-transcript-event-is-sent-ahead-of-the-run.md +0 -25
  493. package/knowledge/decisions/internals/the-virtual-user-catalogue-is-the-only-gate-on-what-may-be-called.md +0 -21
  494. package/knowledge/decisions/internals/the-virtual-user-prompt-says-json-because-of-json-object-mode.md +0 -22
  495. package/knowledge/decisions/internals/the-virtual-user-runtime-is-exported-from-the-virtual-user-entry-point.md +0 -28
  496. package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +0 -22
  497. package/knowledge/decisions/internals/thread-history-records-the-transcript-not-the-audio.md +0 -25
  498. package/knowledge/decisions/internals/trigger-declaration-is-split-from-trigger-source.md +0 -33
  499. package/knowledge/decisions/internals/typed-secret-service-caches-for-the-process-lifetime.md +0 -26
  500. package/knowledge/decisions/internals/validate-checks-virtual-users-through-a-shared-module.md +0 -43
  501. package/knowledge/decisions/internals/validate-runs-checks-by-precondition.md +0 -115
  502. package/knowledge/decisions/internals/virtual-user-conversation-drives-the-target-through-a-transport-seam.md +0 -24
  503. package/knowledge/decisions/internals/virtual-user-conversation-verdicts-are-llm-self-evaluations.md +0 -25
  504. package/knowledge/decisions/internals/virtual-user-conversations-seed-a-hidden-kickoff-message.md +0 -23
  505. package/knowledge/decisions/internals/virtual-user-step-order-comes-from-insertion-order.md +0 -21
  506. package/knowledge/decisions/internals/virtual-users-are-declared-in-one-definevirtualusers-call-per-codebase.md +0 -30
  507. package/knowledge/decisions/internals/voice-output-speaks-unless-voice-input-explicitly-says-otherwise.md +0 -24
  508. package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +0 -26
  509. package/knowledge/decisions/internals/webhook-service-collaborators-are-constructor-args-not-locator-lookups.md +0 -25
  510. package/knowledge/decisions/internals/whether-a-run-is-inline-is-read-from-the-run-record.md +0 -58
  511. package/knowledge/decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md +0 -35
  512. package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +0 -34
  513. package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +0 -42
  514. package/knowledge/decisions/internals/workflow-dsl-meta-separates-runtime-expressions-from-literals.md +0 -38
  515. package/knowledge/decisions/internals/workflow-features-resolve-scenarios-by-object-identity.md +0 -29
  516. package/knowledge/decisions/internals/workflow-graph-inline-and-queued-runs-share-one-planner.md +0 -42
  517. package/knowledge/decisions/internals/workflow-graph-node-notes-are-excluded-from-the-graph-hash.md +0 -25
  518. package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +0 -29
  519. package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +0 -43
  520. package/knowledge/decisions/internals/workflow-queued-step-dispatch-requires-an-explicit-opt-in.md +0 -29
  521. package/knowledge/decisions/internals/workflow-queues-are-per-workflow-by-default.md +0 -42
  522. package/knowledge/decisions/internals/workflow-repeated-step-names-get-an-ordinal-suffix.md +0 -33
  523. package/knowledge/decisions/internals/workflow-replay-reads-its-steps-once-and-caches-only-the-immutable-half.md +0 -32
  524. package/knowledge/decisions/internals/workflow-retries-are-owned-by-the-workflow-not-the-queue.md +0 -31
  525. package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +0 -39
  526. package/knowledge/decisions/internals/workflow-run-mirror-is-never-a-source-of-truth.md +0 -29
  527. package/knowledge/decisions/internals/workflow-run-polling-backs-off-to-the-callers-ceiling.md +0 -33
  528. package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +0 -37
  529. package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +0 -54
  530. package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +0 -43
  531. package/knowledge/decisions/internals/workflow-scenario-prose-is-rendered-from-typed-calls-not-parsed-from-english.md +0 -32
  532. package/knowledge/decisions/internals/workflow-scenario-quarantine-reason-lives-in-code.md +0 -18
  533. package/knowledge/decisions/internals/workflow-scenario-step-targets-are-string-literals-for-the-inspector.md +0 -34
  534. package/knowledge/decisions/internals/workflow-step-compensation-runs-as-its-own-durable-step.md +0 -29
  535. package/knowledge/decisions/internals/workflow-step-dispatch-failure-is-transient-not-a-run-failure.md +0 -33
  536. package/knowledge/decisions/internals/workflow-step-lock-is-held-only-to-claim-the-step.md +0 -34
  537. package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +0 -34
  538. package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +0 -38
  539. package/knowledge/decisions/internals/workflow-suspended-runs-keep-their-in-process-context.md +0 -30
  540. package/knowledge/decisions/security/a-bearer-token-checked-against-a-secret-reads-it-per-request.md +0 -26
  541. package/knowledge/decisions/security/a-call-without-a-session-raises-missing-session-not-forbidden.md +0 -20
  542. package/knowledge/decisions/security/a-caller-cookie-wins-over-the-jar-for-the-same-name.md +0 -23
  543. package/knowledge/decisions/security/a-channel-lifecycle-acts-as-the-socket-upgrade-session.md +0 -16
  544. package/knowledge/decisions/security/a-channel-requires-a-session-unless-it-says-auth-false.md +0 -26
  545. package/knowledge/decisions/security/a-credential-read-path-follows-its-declared-type-not-absence.md +0 -32
  546. package/knowledge/decisions/security/a-credential-type-is-a-literal-the-inspector-checks-at-declaration.md +0 -27
  547. package/knowledge/decisions/security/a-dropped-audit-write-is-always-logged.md +0 -28
  548. package/knowledge/decisions/security/a-first-party-cookie-is-written-only-after-its-purposes-consent.md +0 -33
  549. package/knowledge/decisions/security/a-function-never-receives-the-secret-service.md +0 -37
  550. package/knowledge/decisions/security/a-graph-run-starts-at-an-entry-node-the-graph-declared.md +0 -33
  551. package/knowledge/decisions/security/a-permission-gets-a-wire-it-cannot-reply-on.md +0 -33
  552. package/knowledge/decisions/security/a-public-function-says-so-with-auth-false.md +0 -34
  553. package/knowledge/decisions/security/a-readonly-session-reaches-only-readonly-functions.md +0 -25
  554. package/knowledge/decisions/security/a-scaffold-flag-says-a-surface-exists-not-who-may-call-it.md +0 -52
  555. package/knowledge/decisions/security/a-scheduled-virtual-user-run-needs-no-admin-at-run-time.md +0 -27
  556. package/knowledge/decisions/security/a-scoped-credential-view-is-limited-to-declared-names.md +0 -26
  557. package/knowledge/decisions/security/a-scoped-secret-view-reads-only-declared-keys-and-never-writes.md +0 -25
  558. package/knowledge/decisions/security/a-secret-is-sent-only-to-the-hosts-it-declares.md +0 -29
  559. package/knowledge/decisions/security/a-step-can-name-an-identity-no-virtual-user-holds-through-per-call-headers.md +0 -25
  560. package/knowledge/decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md +0 -37
  561. package/knowledge/decisions/security/a-stopped-run-by-id-skips-the-ownership-check.md +0 -24
  562. package/knowledge/decisions/security/a-vault-secret-redacts-on-serialization-and-throws-on-coercion.md +0 -29
  563. package/knowledge/decisions/security/a-virtual-user-catalogue-entry-is-filtered-by-scope-and-approval-is-denied-by-default.md +0 -30
  564. package/knowledge/decisions/security/a-virtual-user-environment-fails-closed.md +0 -38
  565. package/knowledge/decisions/security/a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md +0 -27
  566. package/knowledge/decisions/security/a-virtual-user-never-runs-against-production.md +0 -23
  567. package/knowledge/decisions/security/a-virtual-user-reads-its-roles-from-the-apps-own-rpc-before-better-auth.md +0 -27
  568. package/knowledge/decisions/security/a-virtual-user-run-treats-an-unresolved-environment-as-production.md +0 -41
  569. package/knowledge/decisions/security/a-virtual-user-scopes-are-expanded-from-its-roles-once-at-run-preparation.md +0 -25
  570. package/knowledge/decisions/security/a-virtual-user-whose-roles-drift-from-the-declaration-refuses-to-run.md +0 -32
  571. package/knowledge/decisions/security/a-workflow-run-is-read-and-approved-by-its-owner.md +0 -50
  572. package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +0 -43
  573. package/knowledge/decisions/security/addon-config-gates-apply-only-at-the-namespaced-rpc-boundary.md +0 -52
  574. package/knowledge/decisions/security/addon-scopes-are-resolved-where-the-function-runs.md +0 -46
  575. package/knowledge/decisions/security/addon-screen-scopes-hide-and-do-not-enforce.md +0 -20
  576. package/knowledge/decisions/security/agent-approval-forwarding-requires-a-symbol-brand.md +0 -27
  577. package/knowledge/decisions/security/agent-credential-requests-are-symbol-branded.md +0 -37
  578. package/knowledge/decisions/security/agent-gate-requires-a-session-only-when-auth-is-true.md +0 -31
  579. package/knowledge/decisions/security/agent-ownership-failures-never-echo-the-resource.md +0 -23
  580. package/knowledge/decisions/security/agent-resume-re-runs-the-authorization-gate.md +0 -22
  581. package/knowledge/decisions/security/agent-sessionless-deployments-have-no-thread-ownership.md +0 -39
  582. package/knowledge/decisions/security/agent-thread-ownership-composes-the-session-principal.md +0 -30
  583. package/knowledge/decisions/security/agent-tool-filtering-reads-the-live-function-config.md +0 -24
  584. package/knowledge/decisions/security/an-addon-header-can-only-narrow-the-session.md +0 -26
  585. package/knowledge/decisions/security/an-addon-instance-reads-only-the-secrets-and-credentials-it-is-named.md +0 -33
  586. package/knowledge/decisions/security/an-addon-may-reach-only-itself-and-the-addons-it-uses.md +0 -16
  587. package/knowledge/decisions/security/an-agent-approval-is-claimed-before-the-tool-runs.md +0 -33
  588. package/knowledge/decisions/security/an-api-key-is-jwt-decoded-into-the-session.md +0 -26
  589. package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +0 -59
  590. package/knowledge/decisions/security/an-empty-owners-constraint-matches-nothing.md +0 -30
  591. package/knowledge/decisions/security/an-exposed-ungated-function-is-a-codegen-warning.md +0 -52
  592. package/knowledge/decisions/security/an-external-virtual-user-caller-presents-one-signed-statement.md +0 -38
  593. package/knowledge/decisions/security/an-inbound-webhook-source-dispatches-only-verified-requests.md +0 -31
  594. package/knowledge/decisions/security/an-mcp-call-with-no-http-request-stays-anonymous.md +0 -18
  595. package/knowledge/decisions/security/an-mcp-refusal-is-decided-before-dispatch.md +0 -48
  596. package/knowledge/decisions/security/an-oauth2-credential-is-read-by-its-account-row.md +0 -40
  597. package/knowledge/decisions/security/an-omitted-user-id-addresses-the-platform-credential.md +0 -32
  598. package/knowledge/decisions/security/an-upload-is-counted-as-it-arrives-not-buffered-then-measured.md +0 -24
  599. package/knowledge/decisions/security/analytics-identity-is-stamped-from-the-session-not-the-event.md +0 -24
  600. package/knowledge/decisions/security/app-access-is-a-scope-tree-synthesised-from-virtual-users.md +0 -26
  601. package/knowledge/decisions/security/approval-policy-decides-who-answers-a-tool-call.md +0 -27
  602. package/knowledge/decisions/security/auth-false-on-a-session-function-warns-and-still-requires-one.md +0 -25
  603. package/knowledge/decisions/security/bearer-token-hashes-are-unpeppered-sha256.md +0 -18
  604. package/knowledge/decisions/security/consent-is-read-from-a-cookie-and-a-recognised-denial-counts-as-refusal.md +0 -29
  605. package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +0 -84
  606. package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +0 -39
  607. package/knowledge/decisions/security/core-secrets-use-a-per-secret-dek-wrapped-by-a-kek.md +0 -37
  608. package/knowledge/decisions/security/cors-defaults-to-any-origin-and-refuses-the-wildcard-with-credentials.md +0 -22
  609. package/knowledge/decisions/security/credential-backends-share-one-conformance-suite-for-per-user-isolation.md +0 -29
  610. package/knowledge/decisions/security/each-stage-has-one-virtual-user-key-pair.md +0 -27
  611. package/knowledge/decisions/security/gateway-handlers-run-through-the-function-runner-gate.md +0 -41
  612. package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +0 -30
  613. package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +0 -40
  614. package/knowledge/decisions/security/hmac-verification-fails-closed-on-empty-inputs.md +0 -25
  615. package/knowledge/decisions/security/http-error-detail-is-withheld-from-clients-in-production.md +0 -33
  616. package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +0 -46
  617. package/knowledge/decisions/security/index.md +0 -135
  618. package/knowledge/decisions/security/local-content-refuses-private-buckets-under-the-public-segment.md +0 -21
  619. package/knowledge/decisions/security/mail-is-allowlisted-before-a-virtual-user-run-sees-it.md +0 -38
  620. package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +0 -27
  621. package/knowledge/decisions/security/mcp-resources-tools-and-prompts-take-sessionless-functions.md +0 -18
  622. package/knowledge/decisions/security/origin-locked-routes-match-the-origin-exactly.md +0 -22
  623. package/knowledge/decisions/security/oss-auth-works-without-pikku-studio-cloud.md +0 -26
  624. package/knowledge/decisions/security/outbound-webhooks-use-an-allowlist-when-configured.md +0 -24
  625. package/knowledge/decisions/security/passphrases-are-stretched-key-material-is-expanded.md +0 -40
  626. package/knowledge/decisions/security/permission-auth-filtering-requires-live-permission-functions.md +0 -31
  627. package/knowledge/decisions/security/pikku-carries-virtual-user-scopes-as-data-and-the-app-grants-them.md +0 -35
  628. package/knowledge/decisions/security/queue-job-identities-are-signed-at-enqueue.md +0 -69
  629. package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +0 -39
  630. package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +0 -34
  631. package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +0 -55
  632. package/knowledge/decisions/security/scenario-step-functions-are-never-externally-invocable.md +0 -30
  633. package/knowledge/decisions/security/scope-resolution-happens-at-the-session-boundary-and-sync-never-deletes.md +0 -28
  634. package/knowledge/decisions/security/scoped-content-access-is-a-root-folder-with-longest-prefix-grants.md +0 -31
  635. package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +0 -34
  636. package/knowledge/decisions/security/services-without-secrets-get-a-throwing-secrets-accessor.md +0 -22
  637. package/knowledge/decisions/security/shared-guards-refuse-to-mutate-or-shadow-a-system-role.md +0 -34
  638. package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +0 -37
  639. package/knowledge/decisions/security/signed-uploads-are-verified-by-the-same-check-as-signed-reads.md +0 -26
  640. package/knowledge/decisions/security/system-role-scopes-must-be-declared-with-define-scope.md +0 -24
  641. package/knowledge/decisions/security/system-roles-are-additive-and-immutable.md +0 -16
  642. package/knowledge/decisions/security/the-channel-rpc-does-not-send-the-callers-session.md +0 -21
  643. package/knowledge/decisions/security/the-remote-jobs-inbox-fails-closed-without-a-secret.md +0 -24
  644. package/knowledge/decisions/security/the-remote-rpc-gate-fails-closed-and-binds-the-token-to-its-function.md +0 -34
  645. package/knowledge/decisions/security/the-workflow-status-stream-rechecks-ownership-on-every-poll.md +0 -16
  646. package/knowledge/decisions/security/two-credentials-on-one-key-must-share-a-read-mode.md +0 -29
  647. package/knowledge/decisions/security/verified-bearer-claims-are-pass-through-data-that-core-never-fills.md +0 -23
  648. package/knowledge/decisions/security/virtual-user-catalogue-excludes-the-machinery-that-runs-virtual-users.md +0 -25
  649. package/knowledge/decisions/security/virtual-user-conversation-missing-approval-decisions-default-to-denied.md +0 -22
  650. package/knowledge/decisions/security/virtual-user-run-records-are-gated-behind-a-read-scope.md +0 -18
  651. package/knowledge/decisions/security/virtual-user-sign-in-does-not-exist-in-production.md +0 -25
  652. package/knowledge/decisions/security/virtual-user-sign-in-has-one-door.md +0 -42
  653. package/knowledge/decisions/security/virtual-user-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +0 -29
  654. package/knowledge/decisions/security/virtual-user-sign-in-only-works-for-virtual-user-flagged-users.md +0 -29
  655. package/knowledge/decisions/security/webhook-bodies-are-signed-before-they-are-enqueued.md +0 -25
  656. package/knowledge/decisions/security/wire-addon-expose-selects-the-rpc-surface.md +0 -51
  657. package/knowledge/decisions/security/workflow-approval-payloads-are-validated-on-replay-inside-the-workflow.md +0 -40
  658. package/knowledge/decisions/security/workflow-helper-functions-are-sessionless-by-declaration.md +0 -18
  659. package/knowledge/decisions/security/workflow-queued-steps-rehydrate-their-session-from-the-run-wire.md +0 -32
  660. package/knowledge/decisions/security/workflow-scenario-sessions-are-isolated-per-virtual-user-and-per-scenario.md +0 -32
  661. package/knowledge/decisions/security/workflow-scenario-steps-are-never-network-invocable.md +0 -31
  662. package/knowledge/decisions/security/workflow-virtual-user-steps-always-use-the-real-transport.md +0 -34
  663. package/knowledge/decisions/security/writing-a-virtual-user-schedule-is-gated-by-its-own-scope.md +0 -18
  664. package/knowledge/index.md +0 -24
  665. package/knowledge/questions/a-bearer-jwt-with-no-identity-becomes-a-session.md +0 -24
  666. package/knowledge/questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md +0 -35
  667. package/knowledge/questions/dev-quick-login-as-impersonation.md +0 -25
  668. package/knowledge/questions/does-a-delayed-rpc-run-as-the-session-it-was-scheduled-with.md +0 -26
  669. package/knowledge/questions/does-a-user-id-with-a-colon-read-another-users-credentials.md +0 -27
  670. package/knowledge/questions/does-a-wirecli-command-need-a-session-by-default.md +0 -26
  671. package/knowledge/questions/does-an-adversarial-in-scope-success-count-as-a-finding.md +0 -26
  672. package/knowledge/questions/does-approve-step-need-the-run-owners-session-or-the-gates-approvers.md +0 -34
  673. package/knowledge/questions/does-cors-origin-true-reflect-any-origin-with-credentials.md +0 -20
  674. package/knowledge/questions/does-skip-user-session-do-anything-on-a-channel.md +0 -24
  675. package/knowledge/questions/does-the-store-session-match-the-other-two.md +0 -19
  676. package/knowledge/questions/index.md +0 -41
  677. package/knowledge/questions/is-the-agent-score-worker-reachable-without-a-session.md +0 -21
  678. package/knowledge/questions/live-scheduled-tests-may-write.md +0 -19
  679. package/knowledge/questions/provision-virtual-users-has-no-caller-in-this-repo.md +0 -23
  680. package/knowledge/questions/remote-secret-refuses-requests-without-a-remote-token-on-every-path.md +0 -32
  681. package/knowledge/questions/should-a-middleware-set-session-persist-to-the-store.md +0 -25
  682. package/knowledge/questions/should-a-scoped-secret-view-throw-from-has-secret-for-a-disallowed-key.md +0 -23
  683. package/knowledge/questions/should-a-wrong-bearer-token-be-anonymous-or-refused.md +0 -35
  684. package/knowledge/questions/should-an-empty-webhook-signing-secret-send-unsigned.md +0 -23
  685. package/knowledge/questions/should-http-virtual-user-sessions-reset-between-scenarios-in-one-run.md +0 -27
  686. package/knowledge/questions/should-the-cookie-jar-scope-cookies-to-the-api-origin.md +0 -26
  687. package/knowledge/questions/should-voice-input-fetch-audio-urls-without-a-host-allowlist.md +0 -20
  688. package/knowledge/questions/staging-impersonation-rules.md +0 -27
  689. package/knowledge/questions/unauthorized-channel-replies-escape-the-declared-out-type.md +0 -44
  690. package/knowledge/questions/virtual-user-keys-on-cloud-stages-are-pikku-studios-to-build.md +0 -33
  691. package/knowledge/questions/virtual-user-statement-replay-is-per-process.md +0 -20
  692. package/knowledge/questions/what-an-impersonated-session-carries.md +0 -22
  693. package/run-tests.sh +0 -68
  694. package/scripts/generate-api-report.d.mts +0 -1
  695. package/scripts/generate-api-report.mjs +0 -96
  696. package/scripts/generate-api-report.mts +0 -333
  697. package/src/public-surface.json +0 -637
  698. package/src/public-surface.json.README +0 -43
  699. /package/dist/{function/compensation-name.d.ts → compensation-name.d.ts} +0 -0
  700. /package/dist/{function/compensation-name.js → compensation-name.js} +0 -0
@@ -1,39 +0,0 @@
1
- ---
2
- type: decision
3
- title: Agent thread ownership fails closed when there is no principal
4
- description: A sessionless caller gets an ephemeral owner and reaches no stored thread, rather than reaching all of them
5
- tags: agent
6
- ---
7
-
8
- # Agent thread ownership fails closed when there is no principal
9
-
10
- `canAccessThread` returns `false` and `threadOwnerConstraint` returns `[]` when
11
- the session carries neither `userId` nor `orgId`
12
- (`packages/core/src/wirings/agent/agent-prepare.ts`).
13
- `resolveOwnerResourceId` never accepts the client-supplied `resourceId` as an
14
- ownership key; without a principal it mints an ephemeral `anon-<uuid>` owner
15
- memoized on the request's params object.
16
-
17
- Agent wirings default to `auth: false`, so "no session" is the common case
18
- rather than an exotic one. Treating it as "no ownership model to enforce" made
19
- every ownership check vacuous: a caller named any `resourceId` and reached that
20
- thread, and because `undefined` on `AgentRunService.listThreads` means _no
21
- filter_ rather than _no rows_, a sessionless `getAgentThreads` returned every
22
- thread in the deployment. The ephemeral owner is what keeps one-shot
23
- conversations working while denying continuity — it is unguessable, so nothing
24
- stored can be reached, and it is stable within a request, so a sub-agent
25
- re-entering `resolveOwnerResourceId` reuses its parent's thread.
26
-
27
- Memoizing on the params object rather than a module-level Map is what keeps this
28
- serverless-safe: the identity dies with the request and is never shared between
29
- instances. `canAccessThread` stays a predicate rather than an assertion so it can
30
- back a `pikkuPermission` — authorization belongs in a function's `permissions`
31
- field, never in its body.
32
-
33
- **What this rules out:** returning `undefined` from `threadOwnerConstraint` for
34
- any caller; deriving `owners` from request input instead of the session; reading
35
- `auth: false` as permission to skip ownership on a _stored_ thread; and
36
- persisting the anonymous owner anywhere, which would turn an ephemeral identity
37
- into a forgeable one. Cross-request thread continuity without a session is not
38
- available by design — wire a session to get it back. See
39
- [[an-empty-owners-constraint-matches-nothing]].
@@ -1,30 +0,0 @@
1
- ---
2
- type: decision
3
- title: An agent thread key is always prefixed with the trusted principal
4
- description: Ownership keys are composed as principal:resourceId, so a client id can sub-divide its own boundary but never widen it
5
- tags: agent
6
- ---
7
-
8
- # An agent thread key is always prefixed with the trusted principal
9
-
10
- `resolveOwnerResourceId` in `packages/core/src/wirings/agent/agent-prepare.ts`
11
- composes the ownership key for a thread or run as `principal:resourceId`. The
12
- principal is the trusted one — `session.userId` for the default `'user'`
13
- `SessionScope`, `session.orgId` for `'org'` — and the client-supplied
14
- `resourceId` is only ever a sub-partition inside it. Composition is idempotent:
15
- a value already inside the caller's namespace (top-level re-entry, sub-agent
16
- recursion, resume — all of which pass an already-composite id) is returned
17
- unchanged rather than composed twice.
18
-
19
- `'org'` scope with no org on the session throws `ForbiddenError` instead of
20
- falling back to a bare or shared key, because a shared key leaks threads across
21
- organizations. A sessionless `'user'` wiring has no trusted principal at all and
22
- falls back to the requested `resourceId` as a best-effort partition.
23
- `isOwnedByPrincipal` requires the `:` separator when matching sub-partitions so
24
- that a principal `alice` does not match a lookalike `alice-evil:…` key.
25
-
26
- **What this rules out:** storing threads under the client's `resourceId`
27
- directly; making the composition non-idempotent (resume and sub-agent recursion
28
- would double-prefix and lose their own threads); testing ownership with a bare
29
- `startsWith(principal)` that omits the separator; and letting `'org'` scope
30
- degrade to a shared key when the session carries no organization.
@@ -1,24 +0,0 @@
1
- ---
2
- type: decision
3
- title: Agent tool permission filtering reads the live function config, not the metadata
4
- description: The pikkuAuth brand survives only on live permission objects, so a metadata-driven check would silently admit every gated tool
5
- tags: agent
6
- ---
7
-
8
- # Agent tool permission filtering reads the live function config, not the metadata
9
-
10
- `buildToolDefs` in `packages/core/src/wirings/agent/agent-prepare.ts`
11
- decides which tools and sub-agents to expose to the model by calling
12
- `checkAuthPermissions` against the permission objects held in the live function
13
- (or agent) config in `pikkuState`, using the metadata only to learn that a
14
- permission exists at all.
15
-
16
- The `pikkuAuth` brand that marks a permission as an authorization gate exists
17
- only on those live objects. The metadata's by-name permission registry is never
18
- populated, so resolving names through it collects no predicates — and a filter
19
- that collects no predicates admits everything. The failure is silent: every gated
20
- tool would be handed to the model for any session.
21
-
22
- **What this rules out:** simplifying the filter to read
23
- `fnMeta.permissions` / `subMeta.permissions` directly, and caching a
24
- name-to-predicate map derived from metadata.
@@ -1,26 +0,0 @@
1
- ---
2
- type: decision
3
- title: An addon header can only narrow the session, and an unknown addon is refused
4
- description: addon-scope-cap intersects the session's scopes with the named addon's role, so naming an addon never widens access, and a name the host does not know is a 403
5
- tags: core, middleware, scopes, addons
6
- ---
7
-
8
- # An addon header can only narrow the session, and an unknown addon is refused
9
-
10
- `packages/core/src/middleware/addon-scope-cap.ts` reads the `x-pikku-addon`
11
- header (`addon-scope-cap.ts:8`, `31`). When a session is present, it resolves
12
- the addon's role and replaces the session's scopes with
13
- `intersectScopes(session.scopes, role)` (`addon-scope-cap.ts:37-45`).
14
-
15
- The doc comment says the header "is a selector, not a credential: naming an
16
- addon can only reduce a session" (`addon-scope-cap.ts:16-17`). An addon the host
17
- does not know throws `ForbiddenError` (`addon-scope-cap.ts:38-40`), because the
18
- comment says ignoring it "would let a misspelt name run uncapped"
19
- (`addon-scope-cap.ts:18-19`).
20
-
21
- With no header, or no session, the middleware calls `next()` and changes
22
- nothing (`addon-scope-cap.ts:33-34`). The comment says to register it after the
23
- session middleware (`addon-scope-cap.ts:21-22`).
24
-
25
- **What this rules out:** using the header to gain scopes, and treating an
26
- unrecognised addon name as "no cap".
@@ -1,33 +0,0 @@
1
- ---
2
- type: decision
3
- title: An addon instance reads only the secrets and credentials it is named
4
- description: An addon's secret and credential views are its declared names plus the consuming app's grants and override keys; the global flags opt out of scoping
5
- tags: core, addons, secrets, credentials
6
- ---
7
-
8
- # An addon instance reads only the secrets and credentials it is named
9
-
10
- The consuming app decides which secrets and credentials an addon instance may
11
- read. The grant fields are declared on the wiring as "set by the consuming app"
12
- (`packages/core/src/wirings/rpc/rpc-types.ts:73-76`) and carried through
13
- `wireAddon` (`packages/core/src/wirings/addon/wire-addon.ts:123-126`) into the
14
- instance (`packages/core/src/wirings/addon/addon-runner.ts:20-22`).
15
-
16
- The allowed set is built by `allowedNames` in `addon-runner.ts:40-49`: the names
17
- the package declared, plus the grants, plus the keys of the overrides. An
18
- override key therefore grants the name; the override value is the key the
19
- lookup is pointed at. `wire-addon.ts:71` says the grant check runs before
20
- `secretOverrides` rename a name.
21
-
22
- Scoping is applied when the instance's services are built
23
- (`addon-runner.ts:200-227`). Unless `globalSecrets` is set, the secret service
24
- is wrapped in `ScopedSecretService`; unless `globalCredentials` is set, the
25
- credential service is wrapped in `ScopedCredentialService`. The global options
26
- hand over the unscoped service, and their value is a reason string
27
- (`wire-addon.ts:75-82`). The comments say the reason is recorded in the deploy
28
- manifest; that recording was not traced here.
29
-
30
- **What this rules out:** an addon reading a name neither it declared nor the
31
- host named, including through an override value; and an unscoped service
32
- reaching an addon without the consuming app setting a `globalSecrets` or
33
- `globalCredentials` reason.
@@ -1,16 +0,0 @@
1
- ---
2
- type: decision
3
- title: An addon may reach only itself and the addons it declares in uses
4
- description: An RPC call that arrives tagged with an addon header is refused unless the target is the caller or one of the caller's declared uses, and an unknown addon name is refused outright
5
- tags: core, addons, rpc, scopes
6
- ---
7
-
8
- # An addon may reach only itself and the addons it declares in uses
9
-
10
- `addonMayReach` in `packages/core/src/wirings/addon/addon-reach.ts` takes the caller addon and the target function name (`addon-reach.ts:6`). It takes the target from the part of the name before `:` (`addon-reach.ts:7`). It returns `false` for an empty target (`:8`), `true` when the target is the caller (`:9`), and otherwise `true` only when the caller's declared `uses` includes the target (`:10-11`).
11
-
12
- `addonCallerOf` reads the addon header from the HTTP request (`addon-reach.ts:14-16`). A name that is not a registered addon is refused with `ForbiddenError` (`addon-reach.ts:17-18`).
13
-
14
- `ContextAwareRPCService.rpcExposed` applies the check before resolving the function. A caller that fails `addonMayReach` gets `AddonNotUsedError` (`packages/core/src/wirings/rpc/rpc-runner.ts:189-192`).
15
-
16
- **What this rules out:** an addon calling into another addon it does not declare in `uses`, and an addon header naming an unregistered addon being treated as anonymous rather than refused.
@@ -1,33 +0,0 @@
1
- ---
2
- type: decision
3
- title: An agent approval is claimed before the tool runs
4
- description: resolveApproval is a compare-and-swap returning whether this caller won, because the read that precedes it is not a claim and ten concurrent approvals would otherwise mean ten refunds
5
- tags: agent
6
- ---
7
-
8
- # An agent approval is claimed before the tool runs
9
-
10
- Resuming a suspended agent run read the run, checked `status === 'suspended'`,
11
- snapshotted `pendingApprovals`, called `resolveApproval`, executed the tool, and
12
- only then wrote `status: 'running'`. Nothing spanned that sequence — no
13
- transaction, no row lock, no conditional update — so concurrent approvals of the
14
- same tool call all observed `suspended`, all snapshotted the same list, and all
15
- reached `execute`. `resolveApproval` returned `void`, so a loser could not even
16
- tell.
17
-
18
- `resolveApproval` is now the claim, and returns whether _this_ caller made it.
19
- The stores implement it as a compare-and-swap: Kysely updates the run row only
20
- while `status = 'suspended'` and `pendingApprovals` still equals the list it
21
- read; the tool-call stores move the row off `approvalStatus = 'pending'` and
22
- count the rows they changed. Both resume paths run the tool only for the ids they
23
- claimed, and a caller that claimed nothing gets an error rather than a silent
24
- re-run.
25
-
26
- The claim is per tool call, not per run, so concurrent approvals of _different_
27
- tool calls on one run all proceed — which is the case that made a run-level
28
- `claimSuspendedRun` the worse fit.
29
-
30
- **What this rules out:** treating `getRun` as a claim, adding a resume path that
31
- executes a tool without a `true` from `resolveApproval`, and implementing
32
- `resolveApproval` as a read-modify-write in any new store — the return value is
33
- a promise about atomicity, not a convenience.
@@ -1,26 +0,0 @@
1
- ---
2
- type: decision
3
- title: An API key is JWT-decoded into the session, from a header or a query parameter
4
- description: authAPIKey reads x-api-key or the apiKey query parameter, decodes it as a JWT, and sets the session only when no session exists yet
5
- tags: core, auth, middleware, api-keys
6
- ---
7
-
8
- # An API key is JWT-decoded into the session, from a header or a query parameter
9
-
10
- `packages/core/src/middleware/auth-apikey.ts` takes an API key from the
11
- `x-api-key` header, the `apiKey` query parameter, or both, depending on the
12
- `source` option (`auth-apikey.ts:11-13`, `21-27`). The header is tried first;
13
- the query is read only when no header value was found (`auth-apikey.ts:25`).
14
-
15
- The key is decoded with `jwtService.decode` and, if that returns a value, passed
16
- to `setSession` (`auth-apikey.ts:29-33`). The middleware does nothing when a
17
- session already exists (`auth-apikey.ts:17`), which the doc comment describes as
18
- leaving "an existing session alone, so it composes with other auth middleware"
19
- (`auth-apikey.ts:6-7`).
20
-
21
- Nothing is decoded when no `jwtService` is wired (`auth-apikey.ts:29`).
22
-
23
- **What this rules out:** an API key overriding a session that is already set,
24
- and a key being accepted without a JWT service to verify it. The code also
25
- accepts a key from the query string (`auth-apikey.ts:26`), so keys can appear in
26
- URLs when `source` includes `query`.
@@ -1,59 +0,0 @@
1
- ---
2
- type: decision
3
- title: An approval answer outlives the run it answered
4
- description: Run state holds a decision only while the gate is open, so the settled answer carries decidedBy/decidedAt into the step result and every attempt is written to the audit sink, which has no foreign key to the run
5
- tags: workflow, audit
6
- ---
7
-
8
- # An approval answer outlives the run it answered
9
-
10
- An approval gate is asked for so it can be answered for afterwards. "Who
11
- released the funds" is the entire point of four-eyes sign-off, and until this
12
- change none of it was kept.
13
-
14
- Run state is where a decision _waits_, not where it is kept. The record under
15
- `workflowRuns.state.__approval_<hex>` is overwritten by the next write to that
16
- key, and cleared outright — `decidedBy: undefined` included — whenever a
17
- decision is refused on replay. A trail that erases exactly the events worth
18
- keeping is not a trail.
19
-
20
- So the answer is recorded twice, in two places with different lifetimes.
21
-
22
- ## The settled decision keeps its provenance
23
-
24
- `ApprovalOutcome<T>` carries `decidedBy` and `decidedAt` alongside `data`, so
25
- the answer reaches `workflowStep.result` and, through it,
26
- `workflowStepHistory` — append-only, and already the per-step event log. Both
27
- are spread in only when present, so a gate answered without a session keeps the
28
- shape it had before there was anything to record.
29
-
30
- ## The audit sink is what survives deletion
31
-
32
- `deleteRun` cascades: `workflowStep` is `onDelete('cascade')` from
33
- `workflowRuns`, and `workflowStepHistory` from `workflowStep`. Deleting a run
34
- therefore deletes the sign-off with it — and a _refused_ attempt never reaches a
35
- step at all, so it was never in that trail to begin with.
36
-
37
- Every answer — accepted, refused at submission, or cleared on replay — is
38
- written to the `AuditService` as `workflow.approval.decided`, with
39
- `outcome: 'success' | 'denied'`, the decider under `userIdentity.pikkuUserId`,
40
- and the run, reason, scopes and refusal in `metadata`. The `audit` table holds
41
- no foreign key to any workflow table, which is precisely why it is the right
42
- home.
43
-
44
- `auditApprovalDecision`
45
- (`packages/core/src/wirings/workflow/workflow-approval-audit.ts`) is a module of
46
- its own rather than a method on `PikkuWorkflowService`: the trail is a separate
47
- concern from running the workflow, and the service is already at the 2000-line
48
- limit `source-files-stay-composable.test.ts` enforces.
49
-
50
- **A sink that fails is logged, never thrown.** The trail must not be the reason a
51
- decision is lost. A project with no `audit` service wired records nothing and is
52
- otherwise unaffected — the sink is opt-in, and `auditSchema` is deliberately not
53
- in `pikkuSchemas`.
54
-
55
- **What this rules out:** a dedicated `workflowApprovals` table. It would have to
56
- be implemented in all seven backends and would still be deleted with the run
57
- unless it deliberately broke the cascade — at which point it is the audit table
58
- with extra steps. If approvals later need to be _queried_ as a first-class
59
- entity rather than read back from the trail, that is when to revisit.
@@ -1,30 +0,0 @@
1
- ---
2
- type: decision
3
- title: An empty owners constraint matches nothing
4
- description: owners is an authorization boundary, so every storage backend must treat [] as no rows rather than no filter
5
- tags: agent, storage
6
- ---
7
-
8
- # An empty owners constraint matches nothing
9
-
10
- Every `AgentRunService.listThreads` implementation returns `[]` immediately when
11
- `owners` is present and empty — `kysely-agent-run-service.ts`,
12
- `redis-agent-run-service.ts`, `mongodb-agent-run-service.ts`. The conformance
13
- suite in `packages/core/src/testing/service-tests.ts` pins it, so a new backend
14
- inherits the requirement instead of rediscovering it.
15
-
16
- `owners` is an authorization boundary, not an optional filter. The natural way
17
- to write a query builder is to skip a clause when its list is empty, which
18
- silently converts "this caller may see nothing" into "this caller may see
19
- everything" — the failure is invisible in review because the omitted clause
20
- looks like an optimization. Placing the guard before the query is built, in
21
- every backend, means the dangerous shape never exists.
22
-
23
- This is what makes the sessionless `[]` from `threadOwnerConstraint` safe to
24
- return; the two decisions only hold together.
25
-
26
- **What this rules out:** folding the empty case into the query builder's normal
27
- `if (owners)` path; treating `owners: []` as equivalent to `owners: undefined`
28
- at any layer; and adding a backend without the conformance suite.
29
-
30
- See [[agent-sessionless-deployments-have-no-thread-ownership]].
@@ -1,52 +0,0 @@
1
- ---
2
- type: decision
3
- title: An exposed function with no gate is reported at codegen, not at boot
4
- description: The check runs in the inspector where function meta and every wireAddon declaration are both in hand, because neither source alone can tell a gated function from an ungated one
5
- tags: authorization, inspector, addon, rpc
6
- ---
7
-
8
- # An exposed function with no gate is reported at codegen, not at boot
9
-
10
- The generated `POST /rpc/:rpcName` dispatcher forwards to `rpc.exposed`, which
11
- refuses anything without `expose: true`. That makes the reachable set small and
12
- deliberate — someone typed it. What it does not do is check whether the target
13
- is gated, because a dispatcher cannot know what it is dispatching to. The
14
- console shipped ~54 privileged functions through exactly this gap, and nothing
15
- in the toolchain said so.
16
-
17
- The check belongs next to `validateAuthSessionless`, in the inspector, for one
18
- reason: it needs two sources that only meet there.
19
-
20
- `sessionless` records the baseline — a `pikkuFunc` always requires a session —
21
- but a `pikkuSessionlessFunc` may still tighten itself with `auth: true`, which
22
- the inspector previously discarded. It is now recorded on function meta, so
23
- "sessionless and ungated" is distinguishable from "sessionless and
24
- self-gated" without running anything.
25
-
26
- The second source is `wireAddon`. Its `scopes` and `auth` apply to every
27
- function in the package on every wiring path (see
28
- [addon scopes](./addon-scopes-are-resolved-where-the-function-runs.md)), so a
29
- function with no gate of its own may still be fully covered. The inspector
30
- already parsed `wireAddon` for its endpoint and its secret, variable and
31
- credential overrides, and dropped `scopes`, `auth` and `tags` — the addon's
32
- plumbing was recorded in full and its authorization was not. Reading function
33
- meta alone would have reported every console function as open.
34
-
35
- An addon whose gates are not statically knowable — a spread, a const reference —
36
- is recorded as absent, and absent is read as **gated**. This is deliberately the
37
- wrong way round from how a runtime gate fails: a false negative costs one
38
- missing warning, while a false positive on a correctly-secured addon costs
39
- confidence in every warning the tool emits, which is worth more than the one
40
- case it would catch.
41
-
42
- Severity is `warn`, not `critical`. `expose: true` on an ungated sessionless
43
- function is legitimate for a genuinely public endpoint — a health check, a
44
- sign-up — so this cannot block a build without breaking correct programs. It
45
- fails a build only under `--fail-on-warn`. And the public endpoint is not left
46
- warning forever: an explicit `auth: false` on a sessionless function declares it
47
- public on purpose and silences the check (see
48
- [public is declared with auth: false](./a-public-function-says-so-with-auth-false.md)).
49
-
50
- **What this rules out:** checking at boot, where the report arrives after
51
- deployment; checking in `pikku validate` from `.pikku` JSON, which does not
52
- carry `wireAddon` at all; and treating an unparseable addon gate as no gate.
@@ -1,38 +0,0 @@
1
- ---
2
- type: decision
3
- title: An external virtual user caller presents one signed statement
4
- description: Callers outside the app sign an EdDSA statement naming the virtual user; the app verifies it against a public key and accepts each statement once
5
- tags: services
6
- ---
7
-
8
- # An external virtual user caller presents one signed statement
9
-
10
- The statement is an EdDSA (Ed25519) JWT: `sub` is the virtual user id, `aud` is the
11
- app's origin, `iat`, `exp` a few minutes out (default 180 seconds, ceiling 300), and
12
- `jti`, a one-time id. The CLI signs it with `node:crypto`; the app verifies it with
13
- `JoseVirtualUserStatementVerifier` (`packages/services/jose`), `jwtVerify` pinned to
14
- `algorithms: ['EdDSA']`, against a public key. `POST /sign-in/virtual-user` takes
15
- `{ statement }`, maps `sub` to a declared virtual user, and signs it in.
16
-
17
- It is rejected for a wrong algorithm (`none` and HS256 included), a wrong key, a wrong
18
- audience, expiry, a lifetime beyond the ceiling, a missing `sub` or `jti`, and a `jti`
19
- already accepted. The replay store is a per-process map of `jti` to expiry, purged on
20
- each call, so it never outgrows the last few minutes of statements.
21
-
22
- One statement replaces three older credentials — a secret derived per virtual user from
23
- a root, an operator token with impersonation, and an app-wired sign-in hook — because
24
- each of them put something the app could mint a session from in the hands of a caller,
25
- or in the app's own configuration. A public key lets the app check a statement and
26
- nothing else; capturing the app's environment yields no ability to sign one.
27
-
28
- The **id-only dev switcher** (`/sign-in/switch-virtual-user`) is unchanged under
29
- `pikku dev`. Anywhere else it also needs a `statement` naming the same id, so no
30
- deployed stage has a credential-free way in.
31
-
32
- The statement endpoint needs the declared virtual users to map an id to an address, so
33
- it is registered only when the app passes `virtualUserSignIn.virtualUsers`, which the
34
- generated `virtualUserList` supplies.
35
-
36
- **What this rules out:** the app holding a private key, a statement without an
37
- expiry or one-time id, an algorithm negotiated by the token, and a switcher that works
38
- on a stage without proof.
@@ -1,31 +0,0 @@
1
- ---
2
- type: decision
3
- title: An inbound webhook source dispatches only requests verified against its credential
4
- description: A webhook source with verify refuses a body-carrying request that fails its check, fails closed on an empty secret, and does not dispatch events from a body-less request
5
- tags: core, webhooks, trigger, security
6
- ---
7
-
8
- # An inbound webhook source dispatches only requests verified against its credential
9
-
10
- `verifyRequest` in `packages/core/src/wirings/trigger/webhook-source-runner.ts:173-200`
11
- decides whether a request counts as signed. A source with no `verify` returns
12
- true (`:178`). Otherwise the secret is read from the credential named by
13
- `source.credential`, or from `webhookSecretCredentialName` (`:180-182`).
14
-
15
- When the secret is missing or empty, a body-less request is treated as
16
- unverified (`:184`), and a request with a body throws `UnauthorizedError`
17
- (`:185-187`). `signedWith` also fails closed on an empty secret (`:127-128`).
18
- The token form compares with `timingSafeStringEqual` (`:153-155`), which is
19
- defined in `packages/core/src/utils/hmac.ts:57-63`.
20
-
21
- A mismatch on a request with a body throws (`:199`). A body-less request is not
22
- an error, but the runner refuses any events it produces: if `verified` is false
23
- and `receive` returned events, it throws `UnauthorizedError` (`:273-276`). The
24
- same contract is documented for authors at
25
- `packages/core/src/wirings/trigger/webhook-source.types.ts:130-135`, and the
26
- helper that runs the source's steps calls `runPikkuFunc` with `auth: false`
27
- (`webhook-source-runner.ts:96-101`), so the signature, not a session, is the
28
- gate.
29
-
30
- **What this rules out:** dispatching events from a body-carrying request that did
31
- not verify, and treating an empty signing secret as a valid key.
@@ -1,18 +0,0 @@
1
- ---
2
- type: decision
3
- title: An MCP call with no HTTP request stays anonymous by transport design
4
- description: MCP calls that arrive without an HTTP request, such as stdio, reach the function with no session because auth middleware reads the session only from the request
5
- tags: core, mcp, auth, transport
6
- ---
7
-
8
- # An MCP call with no HTTP request stays anonymous by transport design
9
-
10
- `RunMCPEndpointParams.http` in `packages/core/src/wirings/mcp/mcp-runner.ts` is the HTTP request an MCP call arrived on (`mcp-runner.ts:39-41`, field at `:52`).
11
-
12
- The comment gives the mechanism. Auth middleware reads the session off `wire.http.request`, and every implementation returns early when there is no request (`mcp-runner.ts:42-46`). Without the request, an MCP call reaches the function unauthenticated whatever middleware is registered (`mcp-runner.ts:43-46`).
13
-
14
- The field is left undefined for transports with no request, such as stdio. The comment says those calls remain anonymous, and that this is a property of the transport rather than a default chosen in the runner (`mcp-runner.ts:48-50`).
15
-
16
- The surrounding decision about sessionless MCP entry points is in [MCP resources, tools and prompts take sessionless functions](mcp-resources-tools-and-prompts-take-sessionless-functions.md). The refusal for an HTTP call that needs a session is in [an MCP refusal is decided before dispatch](an-mcp-refusal-is-decided-before-dispatch.md).
17
-
18
- **What this rules out:** treating a request-less MCP call as carrying a session, and filling in a fake HTTP request to make middleware run for a stdio caller.
@@ -1,48 +0,0 @@
1
- ---
2
- type: decision
3
- title: An MCP refusal is decided before dispatch, not raised from the tool
4
- description: mcpTargetRequiresSession lets the transport answer 401 with an OAuth challenge, because the MCP response streams and the status is gone by the time the runner refuses
5
- tags: mcp, permissions, transport
6
- ---
7
-
8
- # An MCP refusal is decided before dispatch, not raised from the tool
9
-
10
- An MCP client discovers how to authenticate from a `401` carrying a
11
- `WWW-Authenticate` challenge — that header names the RFC 9728 Protected Resource
12
- Metadata document, which names the authorization server, which is where OAuth
13
- starts. Delivered any other way, the refusal is not a refusal: a `MissingSessionError`
14
- flattened into a JSON-RPC result arrives as `200` with `isError: true`, which a
15
- client reads as a tool that failed, and no discovery happens.
16
-
17
- The obvious implementation — catch the refusal in `tools/call` and set the status
18
- afterwards — cannot work, and not for a reason a test makes obvious. The MCP HTTP
19
- response **streams**: the entry returns a `Response` whose body the transport is
20
- still writing when the JSON-RPC handler runs. Instrumenting both ends shows the
21
- entry observing its own flag as unset *before* the tool ever refuses. Status and
22
- headers are chosen at the top of the response; by the time anything knows a
23
- session was missing, they are already on the wire.
24
-
25
- So the decision moves earlier, to the only two things knowable before dispatch:
26
- which target the request body names, and whether the request presents anything to
27
- authenticate with. `mcpTargetRequiresSession` answers the first from the same
28
- declarations the runner enforces — a `pikkuFunc` always needs a session, a
29
- `pikkuSessionlessFunc` needs one only where it says `auth: true` — so the
30
- transport's answer and the runner's cannot disagree. An unregistered name is
31
- treated as open, because a name nobody registered is a `Method not found`, and
32
- challenging it invites a client to authenticate its way towards a tool that does
33
- not exist.
34
-
35
- This is what makes a single endpoint serve public and private tools together,
36
- which the MCP spec allows and pikku's per-function `auth` flag already describes.
37
- `tools/list` stays ungated, so a client can see the menu before it has a token.
38
-
39
- **What this rules out:** verifying tokens in the transport. Only a request with
40
- *no* credentials is challenged; a present-but-expired token is dispatched and its
41
- refusal reaches the client as a tool error. Doing better means resolving the
42
- session before dispatch, which runs the app's middleware twice per call and puts
43
- the transport in the business of second-guessing the middleware that owns session
44
- resolution. The cheaper half — no credentials at all — covers the case that
45
- actually matters, because that is the state every client starts in.
46
-
47
- Also ruled out: gating the endpoint as a whole with `requireBearerAuth`. It would
48
- work, and it would make every public tool private, which is a different product.
@@ -1,40 +0,0 @@
1
- ---
2
- type: decision
3
- title: An OAuth2 credential is read by its account row, not by its provider name
4
- description: better-auth 1.7.5 selects an account by row id under a strict body schema, so BetterAuthCredentialService resolves the row through the internal adapter before asking for a token
5
- tags: better-auth, credentials, oauth2
6
- ---
7
-
8
- # An OAuth2 credential is read by its account row, not by its provider name
9
-
10
- A pikku OAuth2 credential is named — `user-oauth`, `company-slack` — and that
11
- name is the better-auth `providerId` its account row carries. Reading the
12
- credential used to mean handing better-auth the name:
13
- `getAccessToken({ body: { providerId, userId } })`.
14
-
15
- better-auth 1.7.5 stopped accepting that. `get-access-token` and
16
- `unlink-account` both take a strict union selecting the account by its **own row
17
- id**, so a provider name is not merely ignored, it is rejected — `[body] Invalid
18
- input`, a 500 on every read of a linked credential: a tool's token, an agent's,
19
- the console's status card. An agent that cannot resolve its credential never
20
- makes a model call, so the failure surfaces far from its cause.
21
-
22
- So the name is resolved to a row first, through
23
- `context.internalAdapter.findAccounts(userId)` — the same lookup the link
24
- callback writes the row with and `unlinkAccount` already used. That is also the
25
- only account lookup that takes a userId at all: `listUserAccounts` resolves the
26
- *caller's session* and throws UNAUTHORIZED server-side, which is no use for the
27
- two revocations that have no session — a platform credential, whose owner never
28
- signs in, and an admin acting on someone else's.
29
-
30
- A useful consequence: an unlinked provider is now answered before better-auth is
31
- asked, rather than by catching its `ACCOUNT_NOT_FOUND`. The catch stays, because
32
- a failed refresh must still not read as "not connected yet" — that would show a
33
- connect button for an account that is linked but broken.
34
-
35
- **What this rules out:** treating `providerId` as a credential's address
36
- anywhere a token is read or revoked. It remains the credential's *name* — what
37
- an app declares and what the link flow writes — but the row id is what
38
- better-auth is spoken to in. A fake of better-auth that keys tokens by provider
39
- name will pass while the real thing rejects every call, which is how this
40
- survived a bump with 222 green unit tests behind it.
@@ -1,32 +0,0 @@
1
- ---
2
- type: decision
3
- title: An omitted userId on CredentialService addresses the platform credential
4
- description: The CredentialService contract reads and writes the platform-level credential whenever a per-credential call omits userId, and the better-auth implementation defaults its platform owner to pikku-platform
5
- tags: core, credentials, security, interface
6
- ---
7
-
8
- # An omitted userId on CredentialService addresses the platform credential
9
-
10
- `CredentialService` in `packages/core/src/services/credential-service.ts` is the store for dynamic
11
- credentials such as OAuth tokens and per-user keys. Its doc comment says that throughout the interface,
12
- an omitted `userId` means the platform-level credential (`packages/core/src/services/credential-service.ts:4`).
13
-
14
- The per-credential methods take an optional `userId`: `get` (`credential-service.ts:7`), `set` (`:9`),
15
- `delete` (`:11`) and `has` (`:13`). Omitting it selects the platform credential, so the caller chooses
16
- the identity by whether it passes one.
17
-
18
- The methods that enumerate users are different. `getAll` requires `userId` (`credential-service.ts:15`),
19
- and `getUsersWithCredential` and `getAllUsers` take a credential name or nothing
20
- (`credential-service.ts:17` and `:19`). They do not have a platform default.
21
-
22
- The better-auth implementation applies the platform default only to some credentials. It takes an optional
23
- `platformUserId` that falls back to `PLATFORM_USER_ID` (`packages/services/better-auth/src/better-auth-credential.service.ts:58`).
24
- Its owner lookup returns null for a name that is not an OAuth2 credential (`better-auth-credential.service.ts:69-70`),
25
- returns that platform owner only for a singleton OAuth2 name (`better-auth-credential.service.ts:72-73`),
26
- and otherwise returns the `userId` passed in, or null when none was passed (`better-auth-credential.service.ts:75`).
27
- So for a non-singleton credential, an omitted `userId` reads as no owner, not as the platform credential. The
28
- interface comment describes the platform case more widely than this implementation does. Who may link the
29
- singleton is covered by [a singleton credential belongs to a reserved platform user](../../../../services/better-auth/knowledge/decisions/a-singleton-credential-belongs-to-a-reserved-platform-user.md).
30
-
31
- **What this rules out:** a sentinel string or an empty value to mean the platform credential, and relying on an
32
- omitted `userId` to reach the platform credential for a credential that is not a singleton.
@@ -1,24 +0,0 @@
1
- ---
2
- type: decision
3
- title: An upload is counted as it arrives, not buffered and then measured
4
- description: Reading the whole body before checking its size hands an unauthenticated caller a way to spend the server's memory
5
- tags: core, content
6
- ---
7
-
8
- # An upload is counted as it arrives, not buffered and then measured
9
-
10
- The local content request handler accumulates the request body chunk by chunk,
11
- tracking the running total, and abandons the read the moment it crosses the
12
- limit. An oversized upload therefore costs the limit, not its own size.
13
-
14
- The obvious alternative — `await request.arrayBuffer()` and then check
15
- `byteLength` — has to hold the entire body in memory before it can decide the
16
- body is too large. For an endpoint reachable before authentication that is a
17
- way to spend the server's memory for the price of one request, and no size limit
18
- configured anywhere prevents it.
19
-
20
- `readRequestBody` in the node HTTP server aborts on the same terms, for the same
21
- reason.
22
-
23
- **What this rules out:** replacing the streaming accumulation with a single
24
- buffered read because the limit check "still happens".