@cosmicdrift/kumiko-framework 0.388.0 → 0.390.0

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 (711) hide show
  1. package/AGENTS.md +12 -4
  2. package/README.md +1 -1
  3. package/agents/examples/apex-surface-auth.md +2 -3
  4. package/agents/examples/api-worker-split.md +9 -2
  5. package/agents/examples/auth-claims.md +1 -1
  6. package/agents/examples/cross-feature-events.md +12 -12
  7. package/agents/examples/crypto-shredding-hr.md +2 -2
  8. package/agents/examples/encrypted-tenant-config.md +1 -1
  9. package/agents/examples/error-contract.md +12 -7
  10. package/agents/examples/event-sourcing.md +29 -29
  11. package/agents/examples/files-post-processing.md +10 -8
  12. package/agents/examples/golden-path.md +13 -1
  13. package/agents/examples/inbound-mail-triage.md +1 -0
  14. package/agents/examples/lane-routing.md +2 -1
  15. package/agents/examples/legal-pages.md +2 -2
  16. package/agents/examples/lifecycle-hooks.md +55 -2
  17. package/agents/examples/list-table-options.md +466 -0
  18. package/agents/examples/managed-config.md +4 -4
  19. package/agents/examples/managed-pages.md +1 -1
  20. package/agents/examples/pdf-audit-export.md +4 -2
  21. package/agents/examples/relations.md +19 -4
  22. package/agents/examples/search.md +4 -4
  23. package/agents/examples/secrets-demo.md +9 -6
  24. package/agents/examples/state-machine.md +5 -4
  25. package/agents/examples/tenant-isolation.md +73 -1
  26. package/agents/examples/tenant-settings.md +1 -1
  27. package/agents/examples/user-data-rights.md +3 -6
  28. package/agents/examples/workflow-engine.md +53 -47
  29. package/agents/examples.md +5 -4
  30. package/agents/features.md +1 -1
  31. package/agents/widgets.md +1 -0
  32. package/dist/api/api-constants.d.ts +1 -0
  33. package/dist/api/api-constants.js +2 -0
  34. package/dist/api/auth-middleware.js +1 -1
  35. package/dist/api/auth-routes-invite.js +2 -1
  36. package/dist/api/auth-routes-shared.d.ts +2 -0
  37. package/dist/api/auth-routes-shared.js +5 -0
  38. package/dist/api/client-error-route.js +2 -3
  39. package/dist/api/entity-read-access.d.ts +4 -1
  40. package/dist/api/entity-read-access.js +14 -0
  41. package/dist/api/export/export-cells-reference.d.ts +9 -0
  42. package/dist/api/export/export-cells-reference.js +21 -0
  43. package/dist/api/export/export-cells.d.ts +11 -0
  44. package/dist/api/export/export-cells.js +136 -0
  45. package/dist/api/export/export-ciphertext-guard.d.ts +2 -0
  46. package/dist/api/export/export-ciphertext-guard.js +27 -0
  47. package/dist/api/export/export-columns.d.ts +31 -0
  48. package/dist/api/export/export-columns.js +85 -0
  49. package/dist/api/export/export-errors.d.ts +4 -0
  50. package/dist/api/export/export-errors.js +14 -0
  51. package/dist/api/export/export-route.d.ts +4 -0
  52. package/dist/api/export/export-route.js +75 -0
  53. package/dist/api/export/export-rows.d.ts +13 -0
  54. package/dist/api/export/export-rows.js +62 -0
  55. package/dist/api/export/export-screen.d.ts +13 -0
  56. package/dist/api/export/export-screen.js +47 -0
  57. package/dist/api/export/export-xlsx-writer.d.ts +4 -0
  58. package/dist/api/export/export-xlsx-writer.js +21 -0
  59. package/dist/api/extra-route.d.ts +7 -1
  60. package/dist/api/index.d.ts +23 -27
  61. package/dist/api/index.js +13 -15
  62. package/dist/api/jwt.js +1 -1
  63. package/dist/api/observability-middleware.d.ts +1 -1
  64. package/dist/api/observability-middleware.js +2 -1
  65. package/dist/api/pii-leak-guard.d.ts +3 -0
  66. package/dist/api/pii-leak-guard.js +3 -2
  67. package/dist/api/request-context-internals.d.ts +31 -0
  68. package/dist/api/request-context-internals.js +11 -0
  69. package/dist/api/request-context-scopes.d.ts +14 -0
  70. package/dist/api/request-context-scopes.js +69 -0
  71. package/dist/api/request-context.d.ts +1 -40
  72. package/dist/api/request-context.js +22 -51
  73. package/dist/api/request-id-middleware.d.ts +1 -1
  74. package/dist/api/route-registrars.d.ts +2 -1
  75. package/dist/api/route-registrars.js +1 -1
  76. package/dist/api/routes.d.ts +16 -0
  77. package/dist/api/routes.js +9 -5
  78. package/dist/api/server-boot-checks.d.ts +1 -1
  79. package/dist/api/server-boot-checks.js +2 -2
  80. package/dist/api/server-event-dispatcher.d.ts +6 -1
  81. package/dist/api/server-event-dispatcher.js +3 -4
  82. package/dist/api/server-extra-routes.d.ts +1 -1
  83. package/dist/api/server-extra-routes.js +5 -1
  84. package/dist/api/server-middleware.js +3 -1
  85. package/dist/api/server-routes.d.ts +3 -2
  86. package/dist/api/server-routes.js +8 -2
  87. package/dist/api/server-wiring.js +8 -4
  88. package/dist/api/server.d.ts +2 -1
  89. package/dist/api/sse-route.d.ts +3 -1
  90. package/dist/api/sse-route.js +11 -1
  91. package/dist/api/tenant-scoped-secrets.d.ts +2 -0
  92. package/dist/api/tenant-scoped-secrets.js +13 -0
  93. package/dist/api/websocket-route.d.ts +1 -1
  94. package/dist/auth/index.d.ts +0 -1
  95. package/dist/auth/roles.d.ts +0 -5
  96. package/dist/compliance/duration-spec.d.ts +0 -1
  97. package/dist/compliance/duration-spec.js +0 -5
  98. package/dist/compliance/index.d.ts +4 -4
  99. package/dist/compliance/index.js +2 -2
  100. package/dist/compliance/profiles.d.ts +0 -15
  101. package/dist/compliance/profiles.js +0 -23
  102. package/dist/config/index.d.ts +11 -9
  103. package/dist/config/index.js +13 -1
  104. package/dist/config/internals.d.ts +9 -0
  105. package/dist/config/internals.js +1 -0
  106. package/dist/consumer-cli-internals.d.ts +4 -0
  107. package/dist/consumer-cli-internals.js +1 -0
  108. package/dist/consumer-cli.d.ts +1 -4
  109. package/dist/consumer-cli.js +5 -1
  110. package/dist/crypto/event-pii.js +1 -1
  111. package/dist/crypto/index.d.ts +8 -9
  112. package/dist/crypto/index.js +7 -8
  113. package/dist/crypto/pg-kms-adapter.d.ts +1 -0
  114. package/dist/crypto/pg-kms-adapter.js +17 -18
  115. package/dist/db/aggregate-sql.d.ts +2 -0
  116. package/dist/db/aggregate-sql.js +10 -0
  117. package/dist/db/apply-entity-event.d.ts +1 -1
  118. package/dist/db/apply-entity-event.js +15 -47
  119. package/dist/db/blind-index-cleanup.js +91 -77
  120. package/dist/db/closed-connection.js +12 -19
  121. package/dist/db/collect-table-metas.js +1 -1
  122. package/dist/db/compound-types.d.ts +1 -1
  123. package/dist/db/compound-types.js +0 -7
  124. package/dist/db/config-seed.d.ts +2 -1
  125. package/dist/db/config-seed.js +6 -1
  126. package/dist/db/connection.d.ts +7 -6
  127. package/dist/db/connection.js +43 -24
  128. package/dist/db/cross-tenant-reads.d.ts +1 -1
  129. package/dist/db/cross-tenant-reads.js +1 -1
  130. package/dist/db/dialect.d.ts +0 -5
  131. package/dist/db/dialect.js +0 -3
  132. package/dist/db/driver-row-coercion.js +4 -4
  133. package/dist/db/driver-value-preparation.js +6 -4
  134. package/dist/db/eagerload.d.ts +2 -1
  135. package/dist/db/entity-field-encryption.d.ts +1 -1
  136. package/dist/db/entity-table-meta.d.ts +1 -1
  137. package/dist/db/event-store-executor-context.d.ts +3 -1
  138. package/dist/db/event-store-executor-context.js +4 -3
  139. package/dist/db/event-store-executor-read-aggregate-currencies.d.ts +17 -0
  140. package/dist/db/event-store-executor-read-aggregate-currencies.js +40 -0
  141. package/dist/db/event-store-executor-read-aggregate.js +36 -5
  142. package/dist/db/event-store-executor-read-filter.d.ts +1 -1
  143. package/dist/db/event-store-executor-read-filter.js +6 -3
  144. package/dist/db/event-store-executor-read-rows.d.ts +2 -1
  145. package/dist/db/event-store-executor-read-search.d.ts +2 -1
  146. package/dist/db/event-store-executor-read-sort.d.ts +2 -1
  147. package/dist/db/event-store-executor-read.js +2 -2
  148. package/dist/db/event-store-executor-write-atomic.d.ts +4 -0
  149. package/dist/db/event-store-executor-write-atomic.js +42 -0
  150. package/dist/db/event-store-executor-write-steps.d.ts +3 -5
  151. package/dist/db/event-store-executor-write-steps.js +0 -5
  152. package/dist/db/event-store-executor-write.js +22 -19
  153. package/dist/db/event-store-executor.d.ts +1 -1
  154. package/dist/db/event-store-executor.js +2 -1
  155. package/dist/db/executor-managed-tables.d.ts +7 -1
  156. package/dist/db/executor-managed-tables.js +12 -3
  157. package/dist/db/index.d.ts +29 -28
  158. package/dist/db/index.js +22 -20
  159. package/dist/db/known-table-names.d.ts +6 -0
  160. package/dist/db/known-table-names.js +21 -0
  161. package/dist/db/list-aggregate-labels.d.ts +1 -1
  162. package/dist/db/located-timestamp.d.ts +1 -1
  163. package/dist/db/located-timestamp.js +0 -5
  164. package/dist/db/migrate-generator.d.ts +17 -1
  165. package/dist/db/migrate-generator.js +50 -20
  166. package/dist/db/migrate-primary-key.d.ts +12 -0
  167. package/dist/db/migrate-primary-key.js +45 -0
  168. package/dist/db/migrate-rls-diff.d.ts +20 -0
  169. package/dist/db/migrate-rls-diff.js +61 -0
  170. package/dist/db/migrate-runner.js +7 -3
  171. package/dist/db/money.d.ts +1 -1
  172. package/dist/db/money.js +1 -1
  173. package/dist/db/parent-ref-clause.d.ts +2 -1
  174. package/dist/db/pg-error.d.ts +2 -0
  175. package/dist/db/pg-error.js +37 -21
  176. package/dist/db/queries/backfill-pii.js +3 -6
  177. package/dist/db/queries/database-now.js +2 -1
  178. package/dist/db/queries/ddl.d.ts +3 -0
  179. package/dist/db/queries/ddl.js +34 -1
  180. package/dist/db/queries/event-store.js +4 -2
  181. package/dist/db/queries/event-tenants.d.ts +2 -0
  182. package/dist/db/queries/event-tenants.js +17 -0
  183. package/dist/db/queries/rebuild-rls-guard.d.ts +2 -0
  184. package/dist/db/queries/rebuild-rls-guard.js +29 -0
  185. package/dist/db/queries/rls-boot-catalog.d.ts +16 -0
  186. package/dist/db/queries/rls-boot-catalog.js +39 -0
  187. package/dist/db/queries/rls-catalog.d.ts +6 -0
  188. package/dist/db/queries/rls-catalog.js +82 -0
  189. package/dist/db/queries/rls-scope.d.ts +3 -0
  190. package/dist/db/queries/rls-scope.js +17 -0
  191. package/dist/db/queries/rls-shape.d.ts +10 -0
  192. package/dist/db/queries/rls-shape.js +42 -0
  193. package/dist/db/queries/session-advisory-lock.d.ts +2 -0
  194. package/dist/db/queries/session-advisory-lock.js +23 -0
  195. package/dist/db/queries/shadow-swap.d.ts +1 -2
  196. package/dist/db/queries/shadow-swap.js +11 -28
  197. package/dist/db/queries/test-stack.d.ts +4 -1
  198. package/dist/db/queries/test-stack.js +83 -2
  199. package/dist/db/query.d.ts +14 -0
  200. package/dist/db/query.js +77 -48
  201. package/dist/db/reference-data.d.ts +1 -1
  202. package/dist/db/reference-data.js +20 -3
  203. package/dist/db/render-ddl.d.ts +6 -2
  204. package/dist/db/render-ddl.js +7 -7
  205. package/dist/db/render-rls-ddl.d.ts +35 -0
  206. package/dist/db/render-rls-ddl.js +127 -0
  207. package/dist/db/replay-migration-sql.d.ts +3 -1
  208. package/dist/db/replay-migration-sql.js +22 -5
  209. package/dist/db/replay-rls.d.ts +25 -0
  210. package/dist/db/replay-rls.js +156 -0
  211. package/dist/db/row-level-security-boot-check.d.ts +5 -0
  212. package/dist/db/row-level-security-boot-check.js +85 -0
  213. package/dist/db/row-level-security-connection.d.ts +3 -0
  214. package/dist/db/row-level-security-connection.js +213 -0
  215. package/dist/db/row-level-security-scope.d.ts +33 -0
  216. package/dist/db/row-level-security-scope.js +127 -0
  217. package/dist/db/scope-tenant-db-to-tenant.d.ts +3 -0
  218. package/dist/db/scope-tenant-db-to-tenant.js +14 -0
  219. package/dist/db/sql-identifier.d.ts +1 -0
  220. package/dist/db/sql-identifier.js +3 -0
  221. package/dist/db/statement-timeout.js +2 -1
  222. package/dist/db/table-builder.d.ts +2 -1
  223. package/dist/db/table-builder.js +1 -1
  224. package/dist/db/table-info.js +1 -1
  225. package/dist/db/table-push.d.ts +11 -2
  226. package/dist/db/table-push.js +15 -2
  227. package/dist/db/tenant-db-runner.d.ts +3 -1
  228. package/dist/db/tenant-db-runner.js +4 -3
  229. package/dist/db/tenant-db-scoped-rebind.d.ts +10 -0
  230. package/dist/db/tenant-db-scoped-rebind.js +33 -0
  231. package/dist/db/tenant-db-statement-runner.d.ts +13 -0
  232. package/dist/db/tenant-db-statement-runner.js +48 -0
  233. package/dist/db/tenant-db-upsert.d.ts +5 -0
  234. package/dist/db/tenant-db-upsert.js +91 -0
  235. package/dist/db/tenant-db.d.ts +17 -12
  236. package/dist/db/tenant-db.js +60 -121
  237. package/dist/db/tenant-id-filter.d.ts +3 -0
  238. package/dist/db/tenant-id-filter.js +30 -0
  239. package/dist/db/transaction-serialization.d.ts +6 -0
  240. package/dist/db/transaction-serialization.js +60 -0
  241. package/dist/derivatives/delete-stored-file.js +1 -1
  242. package/dist/derivatives/index.d.ts +2 -5
  243. package/dist/derivatives/index.js +2 -3
  244. package/dist/engine/access.d.ts +2 -1
  245. package/dist/engine/access.js +1 -1
  246. package/dist/engine/boot-validator/bundled-lists-table.d.ts +2 -0
  247. package/dist/engine/boot-validator/bundled-lists-table.js +36 -0
  248. package/dist/engine/boot-validator/entity-handler.d.ts +2 -1
  249. package/dist/engine/boot-validator/entity-handler.js +1 -1
  250. package/dist/engine/boot-validator/entity-list-aggregate-options.d.ts +3 -0
  251. package/dist/engine/boot-validator/entity-list-aggregate-options.js +23 -0
  252. package/dist/engine/boot-validator/list-bulk-actions.d.ts +3 -0
  253. package/dist/engine/boot-validator/list-bulk-actions.js +49 -0
  254. package/dist/engine/boot-validator/list-column-layout.d.ts +8 -0
  255. package/dist/engine/boot-validator/list-column-layout.js +41 -0
  256. package/dist/engine/boot-validator/list-table-aggregate-options.d.ts +24 -0
  257. package/dist/engine/boot-validator/list-table-aggregate-options.js +145 -0
  258. package/dist/engine/boot-validator/list-table-aggregate-query.d.ts +11 -0
  259. package/dist/engine/boot-validator/list-table-aggregate-query.js +31 -0
  260. package/dist/engine/boot-validator/list-table-export-options.d.ts +1 -0
  261. package/dist/engine/boot-validator/list-table-export-options.js +27 -0
  262. package/dist/engine/boot-validator/list-table-options.d.ts +3 -0
  263. package/dist/engine/boot-validator/list-table-options.js +77 -0
  264. package/dist/engine/boot-validator/list-table-reject-unknown-keys.d.ts +1 -0
  265. package/dist/engine/boot-validator/list-table-reject-unknown-keys.js +7 -0
  266. package/dist/engine/boot-validator/nav.d.ts +3 -1
  267. package/dist/engine/boot-validator/nav.js +1 -1
  268. package/dist/engine/boot-validator/ownership.d.ts +2 -1
  269. package/dist/engine/boot-validator/parent-ref.d.ts +2 -1
  270. package/dist/engine/boot-validator/projection-list-screens.d.ts +2 -1
  271. package/dist/engine/boot-validator/projection-list-screens.js +3 -13
  272. package/dist/engine/boot-validator/query-refs.d.ts +2 -1
  273. package/dist/engine/boot-validator/related-list-table-rules.d.ts +4 -0
  274. package/dist/engine/boot-validator/related-list-table-rules.js +42 -0
  275. package/dist/engine/boot-validator/screens-forms.d.ts +2 -1
  276. package/dist/engine/boot-validator/screens-kind-entity-list.js +7 -0
  277. package/dist/engine/boot-validator/screens-kind-projection-list.js +4 -0
  278. package/dist/engine/boot-validator/screens-kind-shared.d.ts +3 -1
  279. package/dist/engine/boot-validator/screens-lists.js +12 -2
  280. package/dist/engine/boot-validator/screens.d.ts +2 -1
  281. package/dist/engine/boot-validator/workspaces.d.ts +3 -1
  282. package/dist/engine/bridge-stub.d.ts +5 -2
  283. package/dist/engine/bridge-stub.js +39 -24
  284. package/dist/engine/build-app-schema.d.ts +2 -1
  285. package/dist/engine/build-app-schema.js +9 -1
  286. package/dist/engine/build-config-feature-schema.js +6 -1
  287. package/dist/engine/config-helpers.d.ts +2 -2
  288. package/dist/engine/config-helpers.js +0 -9
  289. package/dist/engine/constants.d.ts +0 -10
  290. package/dist/engine/constants.js +0 -8
  291. package/dist/engine/create-app.js +1 -1
  292. package/dist/engine/define-feature.d.ts +2 -1
  293. package/dist/engine/define-feature.js +5 -2
  294. package/dist/engine/define-handler.d.ts +1 -1
  295. package/dist/engine/define-step.d.ts +0 -1
  296. package/dist/engine/define-step.js +0 -3
  297. package/dist/engine/embedded-derived.d.ts +1 -1
  298. package/dist/engine/entity-handlers.d.ts +2 -1
  299. package/dist/engine/entity-handlers.js +7 -7
  300. package/dist/engine/entity-list-runtime-options.js +3 -1
  301. package/dist/engine/entity-list-searchability.d.ts +2 -1
  302. package/dist/engine/event-def.d.ts +2 -1
  303. package/dist/engine/event-helpers.d.ts +3 -1
  304. package/dist/engine/event-helpers.js +3 -3
  305. package/dist/engine/extension-names.d.ts +2 -8
  306. package/dist/engine/extension-names.js +2 -2
  307. package/dist/engine/extension-selector-plugins.d.ts +1 -1
  308. package/dist/engine/extensions/storage-provider.d.ts +1 -2
  309. package/dist/engine/extensions/user-data.d.ts +0 -8
  310. package/dist/engine/factories.d.ts +2 -1
  311. package/dist/engine/feature-builder-state.d.ts +9 -1
  312. package/dist/engine/feature-builder-state.js +1 -0
  313. package/dist/engine/feature-changelog.d.ts +1 -1
  314. package/dist/engine/feature-config-events-jobs.d.ts +4 -1
  315. package/dist/engine/feature-entity-handlers.d.ts +5 -1
  316. package/dist/engine/feature-manifest.d.ts +1 -0
  317. package/dist/engine/feature-manifest.js +2 -1
  318. package/dist/engine/feature-ui-extensions.d.ts +7 -1
  319. package/dist/engine/feature-ui-extensions.js +6 -4
  320. package/dist/engine/field-access.d.ts +3 -1
  321. package/dist/engine/field-access.js +12 -0
  322. package/dist/engine/handler-field-references.d.ts +0 -4
  323. package/dist/engine/index.d.ts +58 -55
  324. package/dist/engine/index.js +23 -28
  325. package/dist/engine/instruction-fields.d.ts +1 -1
  326. package/dist/engine/personal-data-fields.d.ts +1 -1
  327. package/dist/engine/qualified-name.d.ts +0 -1
  328. package/dist/engine/read-claim.d.ts +2 -1
  329. package/dist/engine/registry-facade.js +0 -3
  330. package/dist/engine/registry-ingest.d.ts +2 -1
  331. package/dist/engine/registry-ingest.js +1 -2
  332. package/dist/engine/registry-state.d.ts +12 -2
  333. package/dist/engine/registry-state.js +2 -3
  334. package/dist/engine/registry-validate.d.ts +3 -1
  335. package/dist/engine/registry-validate.js +7 -7
  336. package/dist/engine/run-in.d.ts +1 -1
  337. package/dist/engine/run-in.js +0 -1
  338. package/dist/engine/schema-builder.d.ts +1 -1
  339. package/dist/engine/schema-builder.js +1 -1
  340. package/dist/engine/screen-filter-ops.d.ts +2 -1
  341. package/dist/engine/screen-filter-ops.js +2 -5
  342. package/dist/engine/soft-delete-cleanup.d.ts +1 -1
  343. package/dist/engine/soft-delete-cleanup.js +4 -4
  344. package/dist/engine/state-machine.js +2 -1
  345. package/dist/engine/steps/_read-source.js +1 -1
  346. package/dist/engine/steps/aggregate-append-event.js +2 -2
  347. package/dist/engine/steps/call-feature.js +2 -2
  348. package/dist/engine/steps/mail-send.js +1 -1
  349. package/dist/engine/steps/retry.js +1 -1
  350. package/dist/engine/steps/wait-for-event.js +1 -1
  351. package/dist/engine/steps/wait.js +1 -1
  352. package/dist/engine/steps/webhook-send.js +1 -1
  353. package/dist/engine/strip-disabled-features-from-app-schema.js +7 -3
  354. package/dist/engine/template-variables.d.ts +2 -1
  355. package/dist/engine/transfer-adjacency.d.ts +1 -1
  356. package/dist/engine/types/feature.d.ts +1 -0
  357. package/dist/engine/types/index.d.ts +8 -30
  358. package/dist/engine/types/index.js +2 -10
  359. package/dist/engine/types/screen.d.ts +1 -1
  360. package/dist/engine/types/screen.js +1 -1
  361. package/dist/engine/validation.d.ts +2 -1
  362. package/dist/entrypoint/index.d.ts +9 -35
  363. package/dist/entrypoint/index.js +10 -1
  364. package/dist/entrypoint/internals.d.ts +40 -0
  365. package/dist/entrypoint/internals.js +1 -0
  366. package/dist/entrypoint/row-level-security-mode-check.d.ts +3 -0
  367. package/dist/entrypoint/row-level-security-mode-check.js +19 -0
  368. package/dist/env/dry-run-internals.d.ts +10 -0
  369. package/dist/env/dry-run-internals.js +1 -0
  370. package/dist/env/dry-run.d.ts +1 -10
  371. package/dist/env/dry-run.js +2 -1
  372. package/dist/env/index.d.ts +1 -85
  373. package/dist/env/index.js +6 -50
  374. package/dist/env/internals.d.ts +87 -0
  375. package/dist/env/internals.js +53 -0
  376. package/dist/errors/classes.js +2 -2
  377. package/dist/errors/index.d.ts +5 -14
  378. package/dist/errors/index.js +4 -9
  379. package/dist/errors/member-resolution.js +1 -1
  380. package/dist/errors/reasons.d.ts +0 -1
  381. package/dist/errors/reasons.js +7 -7
  382. package/dist/errors/serialize.d.ts +0 -18
  383. package/dist/errors/serialize.js +0 -27
  384. package/dist/es-ops/index.d.ts +4 -4
  385. package/dist/es-ops/index.js +2 -2
  386. package/dist/es-ops/operations-schema.d.ts +1 -1
  387. package/dist/es-ops/types.d.ts +4 -5
  388. package/dist/event-store/admin-api-internals.d.ts +14 -0
  389. package/dist/event-store/admin-api-internals.js +1 -0
  390. package/dist/event-store/admin-api.d.ts +1 -14
  391. package/dist/event-store/admin-api.js +11 -6
  392. package/dist/event-store/archive.js +4 -2
  393. package/dist/event-store/errors.js +2 -2
  394. package/dist/event-store/event-store.d.ts +1 -0
  395. package/dist/event-store/event-store.js +42 -32
  396. package/dist/event-store/events-schema.js +4 -1
  397. package/dist/event-store/index.d.ts +11 -13
  398. package/dist/event-store/index.js +7 -9
  399. package/dist/event-store/provenance-append.js +1 -1
  400. package/dist/event-store/rebuild-dead-letter.js +4 -2
  401. package/dist/event-store/snapshot.js +4 -3
  402. package/dist/event-store/stream-scope.d.ts +2 -0
  403. package/dist/event-store/stream-scope.js +6 -0
  404. package/dist/event-store/upcaster-dead-letter.js +4 -2
  405. package/dist/event-store/upcaster.d.ts +2 -1
  406. package/dist/files/action-form-upload.d.ts +2 -1
  407. package/dist/files/action-form-upload.js +1 -1
  408. package/dist/files/assert-file-refs-belong-to-tenant.d.ts +2 -1
  409. package/dist/files/assert-file-refs-belong-to-tenant.js +1 -1
  410. package/dist/files/bind-pending-file-refs.d.ts +2 -1
  411. package/dist/files/bind-pending-file-refs.js +2 -1
  412. package/dist/files/bind-referenced-files.write.js +1 -1
  413. package/dist/files/create-file-ref-from-bytes.d.ts +6 -3
  414. package/dist/files/create-file-ref-from-bytes.js +6 -3
  415. package/dist/files/create-file-ref.d.ts +6 -2
  416. package/dist/files/create-file-ref.js +13 -4
  417. package/dist/files/dispose-removed-file-refs.d.ts +2 -1
  418. package/dist/files/dispose-removed-file-refs.js +1 -1
  419. package/dist/files/feature.js +2 -2
  420. package/dist/files/file-handle.js +1 -1
  421. package/dist/files/file-routes.d.ts +3 -1
  422. package/dist/files/file-routes.js +41 -4
  423. package/dist/files/index.d.ts +11 -13
  424. package/dist/files/index.js +5 -7
  425. package/dist/files/load-save-file-refs.d.ts +2 -1
  426. package/dist/files/load-save-file-refs.js +1 -1
  427. package/dist/files/provider-resolver.d.ts +6 -4
  428. package/dist/files/provider-resolver.js +5 -5
  429. package/dist/files/record-write-check.d.ts +6 -0
  430. package/dist/files/record-write-check.js +13 -0
  431. package/dist/files/storage-tracking.js +4 -2
  432. package/dist/files/sweep-orphaned-uploads.d.ts +1 -1
  433. package/dist/files/sweep-orphaned-uploads.js +1 -1
  434. package/dist/files/upload-ledger.d.ts +2 -2
  435. package/dist/files/upload-ledger.js +4 -4
  436. package/dist/i18n/index.d.ts +2 -8
  437. package/dist/i18n/index.js +1 -1
  438. package/dist/i18n/internals.d.ts +7 -0
  439. package/dist/i18n/internals.js +1 -0
  440. package/dist/i18n/required-surface-keys.d.ts +4 -1
  441. package/dist/i18n/required-surface-keys.js +7 -2
  442. package/dist/internal/row-level-security.d.ts +3 -0
  443. package/dist/internal/row-level-security.js +3 -0
  444. package/dist/internal/stack-support.d.ts +1 -1
  445. package/dist/internal/stack-support.js +1 -1
  446. package/dist/internal/testing.d.ts +1 -0
  447. package/dist/internal/testing.js +10 -6
  448. package/dist/jobs/index.d.ts +1 -1
  449. package/dist/jobs/job-append-event.d.ts +12 -0
  450. package/dist/jobs/job-append-event.js +30 -0
  451. package/dist/jobs/job-runner-context.d.ts +2 -2
  452. package/dist/jobs/job-runner-context.js +46 -16
  453. package/dist/jobs/job-runner-execution.d.ts +1 -1
  454. package/dist/jobs/job-runner-execution.js +6 -4
  455. package/dist/jobs/job-runner-gates.d.ts +1 -1
  456. package/dist/jobs/job-runner-gates.js +0 -1
  457. package/dist/jobs/job-runner-helpers.d.ts +11 -4
  458. package/dist/jobs/job-runner-helpers.js +10 -1
  459. package/dist/jobs/job-runner-scope.d.ts +5 -2
  460. package/dist/jobs/job-runner-scope.js +6 -6
  461. package/dist/jobs/job-runner-types.d.ts +2 -1
  462. package/dist/jobs/job-runner.js +22 -6
  463. package/dist/jobs/max-per-tenant.d.ts +1 -1
  464. package/dist/logging/index.d.ts +1 -2
  465. package/dist/logging/index.js +1 -1
  466. package/dist/logging/pino-logger.js +1 -1
  467. package/dist/logging/utils.d.ts +1 -0
  468. package/dist/logging/utils.js +6 -0
  469. package/dist/migrations/index.d.ts +3 -3
  470. package/dist/migrations/index.js +3 -3
  471. package/dist/migrations/pending-rebuilds.d.ts +1 -1
  472. package/dist/migrations/pending-rebuilds.js +1 -1
  473. package/dist/migrations/pii-event-backfill.js +4 -1
  474. package/dist/observability/escape-hatch-report.d.ts +2 -1
  475. package/dist/observability/escape-hatch-report.js +9 -2
  476. package/dist/observability/index.d.ts +7 -15
  477. package/dist/observability/index.js +4 -12
  478. package/dist/observability/metric-validator.js +1 -1
  479. package/dist/observability/metrics-handle.d.ts +0 -1
  480. package/dist/observability/metrics-handle.js +2 -15
  481. package/dist/observability/recording-tracer.d.ts +1 -2
  482. package/dist/observability/recording-tracer.js +0 -6
  483. package/dist/observability/sensitive-filter.d.ts +0 -2
  484. package/dist/observability/sensitive-filter.js +0 -29
  485. package/dist/pipeline/active-membership.d.ts +2 -1
  486. package/dist/pipeline/active-membership.js +6 -2
  487. package/dist/pipeline/after-rollback-sink.d.ts +6 -0
  488. package/dist/pipeline/after-rollback-sink.js +32 -0
  489. package/dist/pipeline/append-event-core.d.ts +2 -1
  490. package/dist/pipeline/append-event-core.js +2 -2
  491. package/dist/pipeline/attach-outside-transaction.d.ts +3 -0
  492. package/dist/pipeline/attach-outside-transaction.js +13 -0
  493. package/dist/pipeline/auth-claims-resolver.d.ts +2 -1
  494. package/dist/pipeline/cascade-handler.d.ts +2 -1
  495. package/dist/pipeline/cascade-handler.js +3 -2
  496. package/dist/pipeline/config-accessor-factory.d.ts +1 -1
  497. package/dist/pipeline/config-accessor-factory.js +1 -1
  498. package/dist/pipeline/context-services.d.ts +56 -0
  499. package/dist/pipeline/context-services.js +73 -0
  500. package/dist/pipeline/dispatch-batch.d.ts +2 -1
  501. package/dist/pipeline/dispatch-batch.js +39 -19
  502. package/dist/pipeline/dispatch-query.js +5 -4
  503. package/dist/pipeline/dispatch-scope.d.ts +6 -0
  504. package/dist/pipeline/dispatch-scope.js +27 -0
  505. package/dist/pipeline/dispatch-shared.d.ts +13 -9
  506. package/dist/pipeline/dispatch-shared.js +75 -194
  507. package/dist/pipeline/dispatch-stream.js +8 -4
  508. package/dist/pipeline/dispatch-write.d.ts +2 -1
  509. package/dist/pipeline/dispatch-write.js +10 -8
  510. package/dist/pipeline/dispatcher-utils.d.ts +3 -1
  511. package/dist/pipeline/dispatcher-utils.js +8 -2
  512. package/dist/pipeline/dispatcher.d.ts +3 -2
  513. package/dist/pipeline/dispatcher.js +4 -3
  514. package/dist/pipeline/event-consumer-state.d.ts +0 -1
  515. package/dist/pipeline/event-dispatcher-delivery.d.ts +1 -1
  516. package/dist/pipeline/event-dispatcher-delivery.js +7 -3
  517. package/dist/pipeline/event-dispatcher.d.ts +3 -2
  518. package/dist/pipeline/event-dispatcher.js +13 -12
  519. package/dist/pipeline/event-retention.js +59 -56
  520. package/dist/pipeline/handler-access-error.js +2 -1
  521. package/dist/pipeline/handler-context-auth.d.ts +5 -6
  522. package/dist/pipeline/handler-context-auth.js +7 -4
  523. package/dist/pipeline/handler-context-config.d.ts +2 -5
  524. package/dist/pipeline/handler-context-config.js +2 -2
  525. package/dist/pipeline/handler-context-db.d.ts +32 -7
  526. package/dist/pipeline/handler-context-db.js +26 -17
  527. package/dist/pipeline/handler-context-dispatch.d.ts +14 -6
  528. package/dist/pipeline/handler-context-dispatch.js +18 -5
  529. package/dist/pipeline/handler-context-events.d.ts +22 -38
  530. package/dist/pipeline/handler-context-events.js +42 -35
  531. package/dist/pipeline/handler-context-member-resolution.d.ts +2 -0
  532. package/dist/pipeline/handler-context-member-resolution.js +110 -0
  533. package/dist/pipeline/handler-context-notify.d.ts +3 -2
  534. package/dist/pipeline/handler-context-notify.js +1 -1
  535. package/dist/pipeline/handler-context-observability.d.ts +2 -4
  536. package/dist/pipeline/handler-context-observability.js +7 -5
  537. package/dist/pipeline/handler-context-phase-denials.d.ts +11 -0
  538. package/dist/pipeline/handler-context-phase-denials.js +98 -0
  539. package/dist/pipeline/handler-context-scope.d.ts +7 -10
  540. package/dist/pipeline/handler-context-scope.js +18 -20
  541. package/dist/pipeline/index.d.ts +9 -21
  542. package/dist/pipeline/index.js +5 -7
  543. package/dist/pipeline/irreversible-operation-gate.d.ts +1 -1
  544. package/dist/pipeline/irreversible-operation-gate.js +2 -2
  545. package/dist/pipeline/lifecycle-pipeline.d.ts +8 -7
  546. package/dist/pipeline/lifecycle-pipeline.js +9 -15
  547. package/dist/pipeline/member-read-only-transaction.js +11 -3
  548. package/dist/pipeline/member-reader.d.ts +1 -1
  549. package/dist/pipeline/member-reader.js +2 -2
  550. package/dist/pipeline/msp-rebuild.js +5 -3
  551. package/dist/pipeline/multi-stream-apply-context.js +3 -2
  552. package/dist/pipeline/notify-scope.d.ts +2 -1
  553. package/dist/pipeline/pre-handler-gates.d.ts +2 -1
  554. package/dist/pipeline/pre-transaction-reservations.d.ts +3 -3
  555. package/dist/pipeline/pre-transaction-reservations.js +9 -7
  556. package/dist/pipeline/projection-rebuild.js +12 -5
  557. package/dist/pipeline/projection-state.d.ts +0 -6
  558. package/dist/pipeline/projection-state.js +0 -5
  559. package/dist/pipeline/projections-runner.d.ts +2 -1
  560. package/dist/pipeline/projections-runner.js +10 -6
  561. package/dist/pipeline/system-hooks.d.ts +6 -2
  562. package/dist/pipeline/system-hooks.js +61 -10
  563. package/dist/pipeline/system-identity-switch.d.ts +4 -2
  564. package/dist/pipeline/system-identity-switch.js +51 -36
  565. package/dist/pipeline/typed-append-event.d.ts +2 -0
  566. package/dist/pipeline/typed-append-event.js +4 -0
  567. package/dist/pipeline/write-origin.js +2 -2
  568. package/dist/pipeline/write-result-masking.d.ts +1 -1
  569. package/dist/pipeline/write-result-masking.js +13 -10
  570. package/dist/random/index.d.ts +1 -2
  571. package/dist/random/index.js +1 -2
  572. package/dist/rate-limit/bucket.d.ts +2 -1
  573. package/dist/rate-limit/middleware.js +2 -1
  574. package/dist/redis/index.d.ts +3 -4
  575. package/dist/redis/index.js +2 -2
  576. package/dist/schema-cli/apply-command.js +5 -2
  577. package/dist/schema-cli/baseline-command.js +7 -2
  578. package/dist/schema-cli/generate-command.js +7 -9
  579. package/dist/schema-cli/shared.d.ts +4 -0
  580. package/dist/schema-cli/shared.js +21 -2
  581. package/dist/schema-cli/status-command.js +8 -2
  582. package/dist/schema-cli/validate-command.js +52 -4
  583. package/dist/schema-cli.d.ts +0 -1
  584. package/dist/search/configure-tenant-index.d.ts +1 -3
  585. package/dist/search/configure-tenant-index.js +0 -4
  586. package/dist/search/index.d.ts +1 -4
  587. package/dist/search/index.js +0 -2
  588. package/dist/search/meilisearch-adapter-internals.d.ts +8 -0
  589. package/dist/search/meilisearch-adapter-internals.js +9 -0
  590. package/dist/search/meilisearch-adapter.d.ts +1 -8
  591. package/dist/search/meilisearch-adapter.js +6 -7
  592. package/dist/search/meilisearch-peer.d.ts +2 -0
  593. package/dist/search/meilisearch-peer.js +5 -0
  594. package/dist/search/reindex-entity.js +107 -91
  595. package/dist/secrets/index.d.ts +3 -4
  596. package/dist/secrets/index.js +2 -3
  597. package/dist/seeding/index.d.ts +2 -2
  598. package/dist/seeding/index.js +1 -2
  599. package/dist/time/index.d.ts +2 -2
  600. package/dist/time/index.js +1 -1
  601. package/dist/time/tz-context.d.ts +0 -5
  602. package/dist/time/tz-context.js +0 -9
  603. package/dist/ui-types/index.d.ts +8 -11
  604. package/dist/ui-types/index.js +3 -3
  605. package/dist/upgrade-changelog.d.ts +3 -0
  606. package/dist/upgrade-changelog.js +18 -0
  607. package/dist/upgrade-cli-internals.d.ts +8 -0
  608. package/dist/upgrade-cli-internals.js +63 -0
  609. package/dist/upgrade-cli.d.ts +1 -18
  610. package/dist/upgrade-cli.js +29 -137
  611. package/dist/upgrade-marker-parse.d.ts +32 -0
  612. package/dist/upgrade-marker-parse.js +73 -0
  613. package/dist/utils/import-optional-peer.d.ts +6 -0
  614. package/dist/utils/import-optional-peer.js +19 -0
  615. package/dist/utils/index.d.ts +1 -4
  616. package/dist/utils/index.js +1 -4
  617. package/package.json +27 -20
  618. package/src/changes.json +451 -0
  619. package/dist/crypto/request-kms-cache.d.ts +0 -8
  620. package/dist/crypto/request-kms-cache.js +0 -21
  621. package/dist/engine/codemod/index.d.ts +0 -2
  622. package/dist/engine/codemod/index.js +0 -1
  623. package/dist/engine/codemod/pipeline-codemod.d.ts +0 -50
  624. package/dist/engine/codemod/pipeline-codemod.js +0 -536
  625. package/dist/engine/feature-ast/entity-field-types.d.ts +0 -13
  626. package/dist/engine/feature-ast/entity-field-types.js +0 -35
  627. package/dist/engine/feature-ast/extractors/ai-steps.d.ts +0 -6
  628. package/dist/engine/feature-ast/extractors/ai-steps.js +0 -254
  629. package/dist/engine/feature-ast/extractors/events.d.ts +0 -5
  630. package/dist/engine/feature-ast/extractors/events.js +0 -275
  631. package/dist/engine/feature-ast/extractors/handlers.d.ts +0 -24
  632. package/dist/engine/feature-ast/extractors/handlers.js +0 -358
  633. package/dist/engine/feature-ast/extractors/hooks.d.ts +0 -24
  634. package/dist/engine/feature-ast/extractors/hooks.js +0 -248
  635. package/dist/engine/feature-ast/extractors/index.d.ts +0 -14
  636. package/dist/engine/feature-ast/extractors/index.js +0 -13
  637. package/dist/engine/feature-ast/extractors/jobs-routes.d.ts +0 -7
  638. package/dist/engine/feature-ast/extractors/jobs-routes.js +0 -145
  639. package/dist/engine/feature-ast/extractors/projections-screens.d.ts +0 -10
  640. package/dist/engine/feature-ast/extractors/projections-screens.js +0 -195
  641. package/dist/engine/feature-ast/extractors/resolve-import.d.ts +0 -21
  642. package/dist/engine/feature-ast/extractors/resolve-import.js +0 -180
  643. package/dist/engine/feature-ast/extractors/round1.d.ts +0 -10
  644. package/dist/engine/feature-ast/extractors/round1.js +0 -81
  645. package/dist/engine/feature-ast/extractors/round2.d.ts +0 -7
  646. package/dist/engine/feature-ast/extractors/round2.js +0 -191
  647. package/dist/engine/feature-ast/extractors/round3.d.ts +0 -23
  648. package/dist/engine/feature-ast/extractors/round3.js +0 -292
  649. package/dist/engine/feature-ast/extractors/round5.d.ts +0 -9
  650. package/dist/engine/feature-ast/extractors/round5.js +0 -68
  651. package/dist/engine/feature-ast/extractors/round6.d.ts +0 -4
  652. package/dist/engine/feature-ast/extractors/round6.js +0 -17
  653. package/dist/engine/feature-ast/extractors/shared.d.ts +0 -94
  654. package/dist/engine/feature-ast/extractors/shared.js +0 -343
  655. package/dist/engine/feature-ast/index.d.ts +0 -16
  656. package/dist/engine/feature-ast/index.js +0 -10
  657. package/dist/engine/feature-ast/parse.d.ts +0 -31
  658. package/dist/engine/feature-ast/parse.js +0 -483
  659. package/dist/engine/feature-ast/patch.d.ts +0 -210
  660. package/dist/engine/feature-ast/patch.js +0 -610
  661. package/dist/engine/feature-ast/patcher.d.ts +0 -217
  662. package/dist/engine/feature-ast/patcher.js +0 -281
  663. package/dist/engine/feature-ast/pattern-change-schema.d.ts +0 -1476
  664. package/dist/engine/feature-ast/pattern-change-schema.js +0 -1226
  665. package/dist/engine/feature-ast/pattern-id-matchers.d.ts +0 -7
  666. package/dist/engine/feature-ast/pattern-id-matchers.js +0 -210
  667. package/dist/engine/feature-ast/patterns.d.ts +0 -318
  668. package/dist/engine/feature-ast/patterns.js +0 -106
  669. package/dist/engine/feature-ast/render.d.ts +0 -47
  670. package/dist/engine/feature-ast/render.js +0 -662
  671. package/dist/engine/feature-ast/source-location.d.ts +0 -17
  672. package/dist/engine/feature-ast/source-location.js +0 -27
  673. package/dist/engine/pattern-library/index.d.ts +0 -2
  674. package/dist/engine/pattern-library/index.js +0 -3
  675. package/dist/engine/pattern-library/library.d.ts +0 -14
  676. package/dist/engine/pattern-library/library.js +0 -93
  677. package/dist/engine/pattern-library/mixed-schemas.d.ts +0 -16
  678. package/dist/engine/pattern-library/mixed-schemas.js +0 -559
  679. package/dist/engine/pattern-library/opaque-schemas.d.ts +0 -7
  680. package/dist/engine/pattern-library/opaque-schemas.js +0 -115
  681. package/dist/engine/pattern-library/shared-fields.d.ts +0 -122
  682. package/dist/engine/pattern-library/shared-fields.js +0 -88
  683. package/dist/engine/pattern-library/static-schemas.d.ts +0 -20
  684. package/dist/engine/pattern-library/static-schemas.js +0 -478
  685. package/dist/engine/pattern-library/types.d.ts +0 -158
  686. package/dist/engine/pattern-library/types.js +0 -36
  687. package/dist/engine/provider-plugin-context.d.ts +0 -3
  688. package/dist/engine/provider-plugin-context.js +0 -28
  689. package/dist/engine/resolve-config-or-param.d.ts +0 -18
  690. package/dist/engine/resolve-config-or-param.js +0 -76
  691. package/src/scripts/codemod/README.md +0 -187
  692. package/src/scripts/codemod/codemod-support.ts +0 -334
  693. package/src/scripts/codemod/collect-source-files.ts +0 -48
  694. package/src/scripts/codemod/crypto-shredding-testing-move.ts +0 -119
  695. package/src/scripts/codemod/db-factory.ts +0 -810
  696. package/src/scripts/codemod/feature-factory.ts +0 -429
  697. package/src/scripts/codemod/feature-layout.ts +0 -424
  698. package/src/scripts/codemod/import-extensions.ts +0 -118
  699. package/src/scripts/codemod/migrate-cross-tenant.ts +0 -328
  700. package/src/scripts/codemod/migrate-db-raw.ts +0 -401
  701. package/src/scripts/codemod/migrate-open-to-all.ts +0 -235
  702. package/src/scripts/codemod/object-form.ts +0 -746
  703. package/src/scripts/codemod/package-merge.ts +0 -299
  704. package/src/scripts/codemod/pii-personal-migration.ts +0 -816
  705. package/src/scripts/codemod/remove-engine-payload-casts.ts +0 -318
  706. package/src/scripts/codemod/s3-imports.ts +0 -236
  707. package/src/scripts/codemod/tenant-db-options.ts +0 -454
  708. package/src/scripts/codemod/testing-injection.ts +0 -215
  709. package/src/scripts/codemod/testing-move-targets.ts +0 -161
  710. package/src/scripts/codemod/testing-move.ts +0 -542
  711. package/src/scripts/codemod/unprocessable-error-details-reason.ts +0 -411
@@ -1,6 +1,5 @@
1
1
  import type { Meter, MetricsHandle } from "./types/index.ts";
2
2
  export declare function createMetricsHandle(meter: Meter, featureName: string): MetricsHandle;
3
3
  export declare function createSafeMetricsHandle(meter: Meter, featureName: string): MetricsHandle;
4
- export declare function createUnboundMetricsHandle(meter: Meter): MetricsHandle;
5
4
  export declare function createNoopMetricsHandle(): MetricsHandle;
6
5
  export declare function createMetricsForFactory(meter: Meter | undefined): (featureName: string) => MetricsHandle;
@@ -26,7 +26,7 @@ export function createMetricsHandle(meter, featureName) {
26
26
  // Same feature-bound resolution as createMetricsHandle, but for an
27
27
  // explicit `featureName` chosen by the caller rather than the dispatching
28
28
  // handler's own feature. Meant for shared/library code
29
- // invoked from many features' HandlerContext (ctx.metricsFor) — the
29
+ // invoked from many features' HandlerContext (ctx.obs.metricsFor) — the
30
30
  // library owns one stable metric name instead of splintering into
31
31
  // kumiko_<caller>_x per consumer.
32
32
  //
@@ -77,19 +77,6 @@ export function createSafeMetricsHandle(meter, featureName) {
77
77
  // Fallback for contexts where the feature is unknown (e.g. system-hooks,
78
78
  // internal pipeline code). Short names are used verbatim — useful for
79
79
  // framework-level usage, but rejected by the Meter unless pre-registered.
80
- export function createUnboundMetricsHandle(meter) {
81
- return {
82
- inc(name, labels, value) {
83
- meter.counter(name).inc(value, labels);
84
- },
85
- observe(name, value, labels) {
86
- meter.histogram(name).observe(value, labels);
87
- },
88
- set(name, value, labels) {
89
- meter.gauge(name).set(value, labels);
90
- },
91
- };
92
- }
93
80
  // Noop fallback used when no provider is configured and for safety in
94
81
  // contexts where we can't determine the feature. Every call is a no-op —
95
82
  // tests and non-observability-aware features never crash.
@@ -100,7 +87,7 @@ export function createNoopMetricsHandle() {
100
87
  set(_name, _value, _labels) { },
101
88
  };
102
89
  }
103
- // Shared factory behind ctx.metricsFor for handler and job contexts, so both
90
+ // Shared factory behind ctx.obs.metricsFor for handler and job contexts, so both
104
91
  // keep the same no-op-on-unregistered contract.
105
92
  export function createMetricsForFactory(meter) {
106
93
  return meter
@@ -1,4 +1,4 @@
1
- import type { SensitiveFilterConfig, SerializedTraceContext, Span, SpanAttributeValue, SpanKind, SpanStatus, StartSpanOptions, Tracer } from "./types/index.ts";
1
+ import type { SensitiveFilterConfig, Span, SpanAttributeValue, SpanKind, SpanStatus, StartSpanOptions, Tracer } from "./types/index.ts";
2
2
  export type RecordedSpan = {
3
3
  readonly traceId: string;
4
4
  readonly spanId: string;
@@ -28,5 +28,4 @@ export declare class RecordingTracer implements Tracer {
28
28
  withSpan<T>(name: string, optionsOrFn: StartSpanOptions | ((span: Span) => Promise<T>), fn?: (span: Span) => Promise<T>): Promise<T>;
29
29
  getActiveSpan(): Span | undefined;
30
30
  }
31
- export declare function serializeSpanContext(span: Span): SerializedTraceContext;
32
31
  export {};
@@ -127,9 +127,3 @@ export class RecordingTracer {
127
127
  }
128
128
  }
129
129
  // Helper to serialize an active Span into the cross-process format.
130
- export function serializeSpanContext(span) {
131
- return {
132
- traceId: span.traceId,
133
- spanId: span.spanId,
134
- };
135
- }
@@ -2,8 +2,6 @@ import type { SensitiveFilterConfig, SpanAttributeValue } from "./types/index.ts
2
2
  export declare const REDACTED = "[REDACTED]";
3
3
  export declare const DEFAULT_SENSITIVE_CONFIG: SensitiveFilterConfig;
4
4
  export declare function mergeSensitiveConfig(override: Partial<SensitiveFilterConfig> | undefined): SensitiveFilterConfig;
5
- export declare function redactHeaders(headers: Readonly<Record<string, string>>, config: SensitiveFilterConfig): Record<string, string>;
6
- export declare function redactQueryString(input: string, config: SensitiveFilterConfig): string;
7
5
  export declare function shouldRedactAttribute(key: string, config: SensitiveFilterConfig): boolean;
8
6
  export declare function redactValue(value: SpanAttributeValue): SpanAttributeValue;
9
7
  export declare function redactAttributes(attrs: Readonly<Record<string, SpanAttributeValue>>, config: SensitiveFilterConfig): Record<string, SpanAttributeValue>;
@@ -32,35 +32,6 @@ export function mergeSensitiveConfig(override) {
32
32
  DEFAULT_SENSITIVE_CONFIG.redactedAttributeKeyPatterns,
33
33
  };
34
34
  }
35
- function lowercaseSet(names) {
36
- return new Set(names.map((n) => n.toLowerCase()));
37
- }
38
- export function redactHeaders(headers, config) {
39
- const redacted = lowercaseSet(config.redactedHeaders);
40
- const out = {};
41
- for (const [key, value] of Object.entries(headers)) {
42
- out[key] = redacted.has(key.toLowerCase()) ? REDACTED : value;
43
- }
44
- return out;
45
- }
46
- // Redact sensitive query params in a URL or query string. Returns a new URL
47
- // string with the same shape — path, fragment, and ordering preserved.
48
- export function redactQueryString(input, config) {
49
- const redacted = lowercaseSet(config.redactedQueryParams);
50
- // URL wants absolute; handle both absolute and path-only forms.
51
- const hasScheme = /^[a-z][a-z0-9+\-.]*:/i.test(input);
52
- const base = hasScheme ? undefined : "http://_internal";
53
- const url = base ? new URL(input, base) : new URL(input);
54
- for (const key of Array.from(url.searchParams.keys())) {
55
- if (redacted.has(key.toLowerCase())) {
56
- url.searchParams.set(key, REDACTED);
57
- }
58
- }
59
- if (!hasScheme) {
60
- return `${url.pathname}${url.search}${url.hash}`;
61
- }
62
- return url.toString();
63
- }
64
35
  // Check a single attribute key against the redaction patterns.
65
36
  // Used by the Span implementation when setAttribute is called.
66
37
  export function shouldRedactAttribute(key, config) {
@@ -1,6 +1,7 @@
1
+ import type { ActiveMembershipResult } from "@cosmicdrift/kumiko-types/handlers";
1
2
  import { type PrincipalStatusPlugin, type TenantLifecycleStatusPlugin } from "../engine/active-membership.ts";
2
3
  import type { TenantId } from "../engine/types/identifiers.ts";
3
- import type { ActiveMembershipResult, Registry } from "../engine/types/index.ts";
4
+ import type { Registry } from "../engine/types/index.ts";
4
5
  import { type DispatchContext } from "./dispatch-shared.ts";
5
6
  export type ActiveMembershipPolicy = {
6
7
  readonly allowPendingDestruction: boolean;
@@ -1,5 +1,6 @@
1
1
  // One framework-owned composition of membership / principal-status /
2
2
  // tenant-lifecycle checks so login, switch-tenant and MFA completion can't independently drift.
3
+ import { runInSystemRowLevelSecurityScope } from "../db/row-level-security-scope.js";
3
4
  import { isPrincipalStatusPlugin, isTenantLifecycleStatusPlugin, TENANT_TEARDOWN_STATUSES, } from "../engine/active-membership.js";
4
5
  import { EXT_PRINCIPAL_STATUS, EXT_TENANT_LIFECYCLE_STATUS } from "../engine/extension-names.js";
5
6
  import { createSystemUser } from "../engine/system-user.js";
@@ -41,7 +42,7 @@ async function findMembership(ctx, userId, tenantId) {
41
42
  }
42
43
  return rawMemberships.find((m) => m.tenantId === tenantId);
43
44
  }
44
- // Exported so member-reader.ts (ctx.queryAsMember) can reach the registered
45
+ // Exported so member-reader.ts (ctx.dispatch.queryAsMember) can reach the registered
45
46
  // PrincipalStatusPlugin's resolveProfile without duplicating this lookup.
46
47
  export function resolvePrincipalPlugin(registry) {
47
48
  const usages = registry.getExtensionUsages(EXT_PRINCIPAL_STATUS);
@@ -84,7 +85,10 @@ function isTeardownRejected(status, policy) {
84
85
  }
85
86
  // Order is load-bearing: a non-member must never learn a foreign tenant's
86
87
  // lifecycle/blocked state, so membership is resolved and checked FIRST.
87
- export async function resolveActiveMembershipFn(ctx, userId, tenantId, policy) {
88
+ export function resolveActiveMembershipFn(ctx, userId, tenantId, policy) {
89
+ return runInSystemRowLevelSecurityScope("active membership lookup runs before the request tenant is established", () => resolveActiveMembershipInScope(ctx, userId, tenantId, policy));
90
+ }
91
+ async function resolveActiveMembershipInScope(ctx, userId, tenantId, policy) {
88
92
  const { registry } = ctx;
89
93
  const membership = await findMembership(ctx, userId, tenantId);
90
94
  if (!membership) {
@@ -0,0 +1,6 @@
1
+ import type { createFallbackLogger } from "../logging/utils.ts";
2
+ import type { AfterCommitHook } from "./dispatcher-utils.ts";
3
+ export type AfterRollbackHook = () => Promise<void>;
4
+ export declare function afterRollbackHooksOf(commitSink: AfterCommitHook[]): AfterRollbackHook[];
5
+ export declare function carrySavepointRollbackHooks(innerCommitSink: AfterCommitHook[], outerCommitSink: AfterCommitHook[], savepointRolledBack: boolean): void;
6
+ export declare function flushAfterRollback(commitSink: AfterCommitHook[], logError: Pick<ReturnType<typeof createFallbackLogger>, "error">): Promise<void>;
@@ -0,0 +1,32 @@
1
+ // Side channel keyed by the afterCommit sink array, so executeWrite and friends keep their signatures.
2
+ // Invariant: every registration runs at most once, and only if the work it compensates was discarded.
3
+ const rollbackSinks = new WeakMap();
4
+ export function afterRollbackHooksOf(commitSink) {
5
+ const existing = rollbackSinks.get(commitSink);
6
+ if (existing)
7
+ return existing;
8
+ const created = [];
9
+ rollbackSinks.set(commitSink, created);
10
+ return created;
11
+ }
12
+ // A rolled-back savepoint is not compensated immediately: the compensation could wait on locks of
13
+ // the still-open outer transaction. It runs once after that transaction ends, via the commit sink
14
+ // on commit or the rollback sink on rollback.
15
+ export function carrySavepointRollbackHooks(innerCommitSink, outerCommitSink, savepointRolledBack) {
16
+ const innerHooks = rollbackSinks.get(innerCommitSink) ?? [];
17
+ if (innerHooks.length > 0) {
18
+ if (savepointRolledBack)
19
+ outerCommitSink.push(...innerHooks);
20
+ afterRollbackHooksOf(outerCommitSink).push(...innerHooks);
21
+ }
22
+ }
23
+ export async function flushAfterRollback(commitSink, logError) {
24
+ const hooks = rollbackSinks.get(commitSink) ?? [];
25
+ const outcomes = await Promise.allSettled(hooks.map((hook) => hook()));
26
+ for (const outcome of outcomes) {
27
+ if (outcome.status === "rejected") {
28
+ const detail = outcome.reason instanceof Error ? outcome.reason.message : String(outcome.reason);
29
+ logError.error("afterRollback hook failed", { error: detail });
30
+ }
31
+ }
32
+ }
@@ -1,5 +1,6 @@
1
+ import type { AppendEventArgs } from "@cosmicdrift/kumiko-types/handlers";
1
2
  import type { DbRunner } from "../db/connection.ts";
2
- import type { AppendEventArgs, Registry, TenantId } from "../engine/types/index.ts";
3
+ import type { Registry, TenantId } from "../engine/types/index.ts";
3
4
  import { type StoredEvent } from "../event-store/event-store.ts";
4
5
  export type AppendDomainEventCoreDeps = {
5
6
  readonly registry: Registry;
@@ -63,7 +63,7 @@ export async function appendDomainEventCore(deps, args) {
63
63
  throw new ArchivedStreamError(deps.tenantId, args.aggregateId);
64
64
  }
65
65
  // Stream-version authoritative. See Block 0 / getStreamVersion doc for
66
- // why row.version isn't sufficient once ctx.appendEvent enters the picture.
66
+ // why row.version isn't sufficient once ctx.events.append enters the picture.
67
67
  // A caller-pinned version (fetchForWriting handles) must reach append() so a
68
68
  // write landing between fetch and append conflicts instead of being re-read.
69
69
  const expectedVersion = args.expectedVersion ?? (await getStreamVersion(deps.db, args.aggregateId, deps.tenantId));
@@ -91,7 +91,7 @@ export async function appendDomainEventCore(deps, args) {
91
91
  });
92
92
  // Inline projections fire in the same tx — a throw rolls everything back
93
93
  // together. Same semantics regardless of which call-site triggered the
94
- // append (write-handler ctx.appendEvent vs. MSP-apply ctx.appendEvent).
94
+ // append (write-handler ctx.events.append vs. MSP-apply ctx.appendEvent).
95
95
  await runProjectionsForEvent(stored, deps.registry, deps.db);
96
96
  return stored;
97
97
  }
@@ -0,0 +1,3 @@
1
+ export declare function attachOutsideTransaction<T extends object, O extends object | undefined>(db: T, outsideTransaction: O): T & {
2
+ readonly outsideTransaction: O;
3
+ };
@@ -0,0 +1,13 @@
1
+ // TenantDb identity keys WeakMaps (rebinders, personal-data gates), so the exposed db is never
2
+ // wrapped or spread; the non-enumerable property keeps spreads and logging of the db unchanged.
3
+ function defineOutsideTransaction(db, outsideTransaction) {
4
+ Object.defineProperty(db, "outsideTransaction", {
5
+ value: outsideTransaction,
6
+ enumerable: false,
7
+ configurable: true,
8
+ });
9
+ }
10
+ export function attachOutsideTransaction(db, outsideTransaction) {
11
+ defineOutsideTransaction(db, outsideTransaction);
12
+ return db;
13
+ }
@@ -1,4 +1,5 @@
1
- import type { AuthClaimsContext, AuthClaimsHookDef, SessionUser } from "../engine/types/index.ts";
1
+ import type { AuthClaimsContext, AuthClaimsHookDef } from "@cosmicdrift/kumiko-types/handlers";
2
+ import type { SessionUser } from "../engine/types/index.ts";
2
3
  import type { Logger } from "../logging/types.ts";
3
4
  export type ResolveAuthClaimsArgs = {
4
5
  readonly user: SessionUser;
@@ -1,5 +1,6 @@
1
+ import type { PreDeleteHookFn } from "@cosmicdrift/kumiko-types/hooks";
1
2
  import type { TableColumns } from "../db/dialect.ts";
2
- import type { PreDeleteHookFn, Registry } from "../engine/types/index.ts";
3
+ import type { Registry } from "../engine/types/index.ts";
3
4
  import type { SystemHookDef } from "./lifecycle-pipeline.ts";
4
5
  type TableMap = ReadonlyMap<string, TableColumns>;
5
6
  export declare function createCascadeDeleteHook(registry: Registry, tables: TableMap): SystemHookDef<PreDeleteHookFn>;
@@ -4,7 +4,8 @@ import { isBoundTenantDb } from "../db/tenant-db-runner.js";
4
4
  import { OnDeleteStrategies, SystemHookNames, SystemHookPriorities } from "../engine/constants.js";
5
5
  import { isRecordLocked } from "../engine/screen-helpers.js";
6
6
  import { createSystemUser } from "../engine/system-user.js";
7
- import { ConflictError, FrameworkReasons, InternalError, RecordLockedError, reraiseAsKumikoError, } from "../errors/index.js";
7
+ import { RecordLockedError } from "../errors/classes.js";
8
+ import { ConflictError, FrameworkReasons, InternalError, reraiseAsKumikoError, } from "../errors/index.js";
8
9
  // The cascade is a consequence of the parent delete the caller was already authorized for, so the
9
10
  // children are written as the framework system user and the lock decision is taken once, up front.
10
11
  const CASCADE_CHILD_WRITE_OPTIONS = { unsafeSkipLockGuard: true };
@@ -18,7 +19,7 @@ export function createCascadeDeleteHook(registry, tables) {
18
19
  ? ctx.systemDb.acknowledgeCrossTenant(`cascade delete for r.systemScope() write handler (${entityName ?? "unknown"})`)
19
20
  : ctx.db;
20
21
  if (!entityName || !db) {
21
- ctx.log?.debug(`cascadeDelete: skipping — ${!entityName ? "no entityName" : "no db"} on payload ${payload.id}`);
22
+ ctx.obs.log?.debug(`cascadeDelete: skipping — ${!entityName ? "no entityName" : "no db"} on payload ${payload.id}`);
22
23
  return;
23
24
  }
24
25
  const writeDb = isBoundTenantDb(db) ? db : undefined;
@@ -1,3 +1,3 @@
1
1
  import type { ConfigAccessorFactory } from "@cosmicdrift/kumiko-types/config";
2
2
  import type { AppContext } from "@cosmicdrift/kumiko-types/handlers";
3
- export declare function configAccessorFactoryOf(context: Pick<AppContext, "configAccessorFactory" | "_configAccessorFactory">): ConfigAccessorFactory | undefined;
3
+ export declare function configAccessorFactoryOf(context: Pick<AppContext, "configAccessorFactory">): ConfigAccessorFactory | undefined;
@@ -1,3 +1,3 @@
1
1
  export function configAccessorFactoryOf(context) {
2
- return context.configAccessorFactory ?? context._configAccessorFactory;
2
+ return context.configAccessorFactory;
3
3
  }
@@ -0,0 +1,56 @@
1
+ import type { AppContext, ContextServices } from "../engine/types/index.ts";
2
+ type ServiceKey = Exclude<keyof ContextServices, "extensions">;
3
+ export declare const APP_CONTEXT_KEY_ROLES: {
4
+ readonly redis: "service";
5
+ readonly cacheSync: "service";
6
+ readonly jobRunner: "service";
7
+ readonly searchAdapter: "service";
8
+ readonly entityCache: "service";
9
+ readonly secrets: "service";
10
+ readonly kms: "service";
11
+ readonly files: "service";
12
+ readonly derivatives: "service";
13
+ readonly configResolver: "service";
14
+ readonly configEncryption: "service";
15
+ readonly rateLimit: "service";
16
+ readonly effectiveFeatures: "service";
17
+ readonly masterKeyProvider: "service";
18
+ readonly _fileProviderResolver: "service";
19
+ readonly _notifyFactory: "service";
20
+ readonly _notifyInTransactionFactory: "service";
21
+ readonly _notifyAfterCommitFactory: "service";
22
+ readonly _escapeHatchAuditSink: "service";
23
+ readonly db: "wiring";
24
+ readonly systemDb: "wiring";
25
+ readonly registry: "wiring";
26
+ readonly systemUser: "wiring";
27
+ readonly log: "wiring";
28
+ readonly triggeredBy: "wiring";
29
+ readonly triggerName: "wiring";
30
+ readonly geoTzProvider: "wiring";
31
+ readonly clock: "wiring";
32
+ readonly _tenantId: "wiring";
33
+ readonly defaultLocale: "wiring";
34
+ readonly configAccessorFactory: "wiring";
35
+ readonly _rateLimitPayloadDigest: "wiring";
36
+ readonly tracer: "wiring";
37
+ readonly meter: "wiring";
38
+ readonly config: "wiring";
39
+ readonly configFor: "wiring";
40
+ readonly forTenant: "wiring";
41
+ readonly notify: "wiring";
42
+ readonly signal: "wiring";
43
+ readonly scheduleAfterCommit: "wiring";
44
+ readonly scheduleAfterRollback: "wiring";
45
+ };
46
+ type ServiceRoleKey = {
47
+ [Key in keyof typeof APP_CONTEXT_KEY_ROLES]: (typeof APP_CONTEXT_KEY_ROLES)[Key] extends "service" ? Key : never;
48
+ }[keyof typeof APP_CONTEXT_KEY_ROLES];
49
+ type IsSame<Left, Right> = [Left] extends [Right] ? ([Right] extends [Left] ? true : false) : false;
50
+ type MustBeTrue<Value extends true> = Value;
51
+ export type ServiceRolesMatchContextServices = MustBeTrue<IsSame<ServiceRoleKey, ServiceKey>>;
52
+ export type ContextServiceOverrides = {
53
+ -readonly [Key in ServiceKey]?: ContextServices[Key];
54
+ };
55
+ export declare function buildContextServices(context: AppContext, overrides?: ContextServiceOverrides): ContextServices;
56
+ export {};
@@ -0,0 +1,73 @@
1
+ // Every AppContext key is either a service a handler or job may use, or boot wiring the framework
2
+ // consumes itself. The satisfies clause makes a new AppContext key a compile error until it is classified.
3
+ export const APP_CONTEXT_KEY_ROLES = {
4
+ redis: "service",
5
+ cacheSync: "service",
6
+ jobRunner: "service",
7
+ searchAdapter: "service",
8
+ entityCache: "service",
9
+ secrets: "service",
10
+ kms: "service",
11
+ files: "service",
12
+ derivatives: "service",
13
+ configResolver: "service",
14
+ configEncryption: "service",
15
+ rateLimit: "service",
16
+ effectiveFeatures: "service",
17
+ masterKeyProvider: "service",
18
+ _fileProviderResolver: "service",
19
+ _notifyFactory: "service",
20
+ _notifyInTransactionFactory: "service",
21
+ _notifyAfterCommitFactory: "service",
22
+ _escapeHatchAuditSink: "service",
23
+ db: "wiring",
24
+ systemDb: "wiring",
25
+ registry: "wiring",
26
+ systemUser: "wiring",
27
+ log: "wiring",
28
+ triggeredBy: "wiring",
29
+ triggerName: "wiring",
30
+ geoTzProvider: "wiring",
31
+ clock: "wiring",
32
+ _tenantId: "wiring",
33
+ defaultLocale: "wiring",
34
+ configAccessorFactory: "wiring",
35
+ _rateLimitPayloadDigest: "wiring",
36
+ tracer: "wiring",
37
+ meter: "wiring",
38
+ config: "wiring",
39
+ configFor: "wiring",
40
+ forTenant: "wiring",
41
+ notify: "wiring",
42
+ signal: "wiring",
43
+ scheduleAfterCommit: "wiring",
44
+ scheduleAfterRollback: "wiring",
45
+ };
46
+ function isAppContextKey(key) {
47
+ return Object.hasOwn(APP_CONTEXT_KEY_ROLES, key);
48
+ }
49
+ function isServiceKey(key) {
50
+ return isAppContextKey(key) && APP_CONTEXT_KEY_ROLES[key] === "service";
51
+ }
52
+ // The dispatcher binds these two to one call's transaction; a factory inherited from an outer
53
+ // context must not leak into a context that has none of its own.
54
+ const PER_CALL_FACTORY_KEYS = new Set([
55
+ "_notifyInTransactionFactory",
56
+ "_notifyAfterCommitFactory",
57
+ ]);
58
+ function copyService(target, source, key) {
59
+ const value = source[key];
60
+ if (value !== undefined)
61
+ target[key] = value;
62
+ }
63
+ const SERVICE_KEYS = Object.keys(APP_CONTEXT_KEY_ROLES).filter(isServiceKey);
64
+ export function buildContextServices(context, overrides = {}) {
65
+ const services = {};
66
+ for (const key of SERVICE_KEYS) {
67
+ if (!PER_CALL_FACTORY_KEYS.has(key))
68
+ copyService(services, context, key);
69
+ copyService(services, overrides, key);
70
+ }
71
+ const extensions = Object.fromEntries(Object.entries(context).filter(([key]) => key !== "services" && !isAppContextKey(key)));
72
+ return { ...services, extensions };
73
+ }
@@ -1,5 +1,6 @@
1
1
  import type { WriteOrigin } from "@cosmicdrift/kumiko-types/event-store-types";
2
- import type { SessionUser, WriteResult } from "../engine/types/index.ts";
2
+ import type { WriteResult } from "@cosmicdrift/kumiko-types/handlers";
3
+ import type { SessionUser } from "../engine/types/index.ts";
3
4
  import type { BatchCommand, BatchResult, DispatchContext } from "./dispatch-shared.ts";
4
5
  export declare function runBatch(ctx: DispatchContext, commands: readonly BatchCommand[], user: SessionUser, requestId?: string, inheritedOrigin?: WriteOrigin): Promise<BatchResult>;
5
6
  export declare function unwrapSingle(batchResult: BatchResult): WriteResult;
@@ -1,9 +1,13 @@
1
- import { requestContext, runWithWriteOrigin } from "../api/request-context.js";
1
+ import { requestContext } from "../api/request-context.js";
2
+ import { runWithWriteOrigin } from "../api/request-context-scopes.js";
2
3
  import { transaction } from "../db/query.js";
3
- import { InternalError, toWriteErrorInfo, UnprocessableError, writeFailure, } from "../errors/index.js";
4
+ import { InternalError, UnprocessableError, writeFailure, } from "../errors/index.js";
5
+ import { toWriteErrorInfo } from "../errors/write-error-info.js";
4
6
  import { createFallbackLogger } from "../logging/utils.js";
5
7
  import { parseJsonSafe } from "../utils/safe-json.js";
6
- import { resolveAppPoolDb } from "./dispatch-shared.js";
8
+ import { flushAfterRollback } from "./after-rollback-sink.js";
9
+ import { runInDispatchScope } from "./dispatch-scope.js";
10
+ import { buildHandlerContext, resolveAppPoolDb } from "./dispatch-shared.js";
7
11
  import { executeNestedWrite, executeWrite } from "./dispatch-write.js";
8
12
  import { BatchRollback, isLifecycleResult, wrapToKumiko, } from "./dispatcher-utils.js";
9
13
  import { reserveBeforeTransaction, runAsCommand, } from "./pre-transaction-reservations.js";
@@ -32,10 +36,13 @@ async function runReservedCommand(scope, cmd, index, tx) {
32
36
  const hookStart = afterCommitHooks.length;
33
37
  // Nested-write children would run inline with the in-transaction scope, so a perCommand command skips the expansion.
34
38
  const execute = isPerCommandHandler(ctx, cmd.type) ? executeWrite : executeNestedWrite;
35
- const res = await runAsCommand(toReservedScope(reservations, index, cmd), () => runWithWriteOrigin(origin, () => execute(ctx, cmd.type, cmd.payload, user, origin, tx, afterCommitHooks)));
39
+ const res = await runAsCommand(toReservedScope(reservations, index, cmd), () => runWithWriteOrigin(origin, () => runInDispatchScope(ctx.registry, [cmd.type], user, () => execute(ctx, cmd.type, cmd.payload, user, origin, tx, afterCommitHooks))));
36
40
  rewrapHooksWithOrigin(afterCommitHooks, hookStart, origin);
37
41
  return res;
38
42
  }
43
+ function rollbackLogger(scope) {
44
+ return createFallbackLogger("dispatcher", scope.ctx.appContext.log);
45
+ }
39
46
  // Sequential fallback without an outer transaction. A failure result and a throw both end the
40
47
  // batch, so both give the reserved capacity back.
41
48
  async function runCommandsWithoutTransaction(scope, commands, results) {
@@ -50,12 +57,14 @@ async function runCommandsWithoutTransaction(scope, commands, results) {
50
57
  // No tx means no rollback — but we still drop afterCommit hooks,
51
58
  // matching the semantic "failure = side-effects don't fire".
52
59
  await scope.reservations.releaseAll();
60
+ await flushAfterRollback(scope.afterCommitHooks, rollbackLogger(scope));
53
61
  return { index: i, error: res.error };
54
62
  }
55
63
  }
56
64
  }
57
65
  catch (e) {
58
66
  await scope.reservations.releaseAll();
67
+ await flushAfterRollback(scope.afterCommitHooks, rollbackLogger(scope));
59
68
  throw e;
60
69
  }
61
70
  return undefined;
@@ -63,14 +72,16 @@ async function runCommandsWithoutTransaction(scope, commands, results) {
63
72
  // Core batch logic extracted so write() and command() can reuse it
64
73
  // (a single write = batch of one, running in its own transaction).
65
74
  export async function runBatch(ctx, commands, user, requestId, inheritedOrigin) {
66
- const current = requestContext.get();
67
- if (!current?.signal) {
68
- return runBatchBody(ctx, commands, user, requestId, inheritedOrigin);
69
- }
70
- // Strip the signal: a client disconnect must not roll back a write whose
71
- // afterCommit effects would then be lost.
72
- const { signal: _signal, ...withoutSignal } = current;
73
- return requestContext.run(withoutSignal, () => runBatchBody(ctx, commands, user, requestId, inheritedOrigin));
75
+ return runInDispatchScope(ctx.registry, commands.map((command) => command.type), user, () => {
76
+ const current = requestContext.get();
77
+ if (!current?.signal) {
78
+ return runBatchBody(ctx, commands, user, requestId, inheritedOrigin);
79
+ }
80
+ // Strip the signal: a client disconnect must not roll back a write whose
81
+ // afterCommit effects would then be lost.
82
+ const { signal: _signal, ...withoutSignal } = current;
83
+ return requestContext.run(withoutSignal, () => runBatchBody(ctx, commands, user, requestId, inheritedOrigin));
84
+ });
74
85
  }
75
86
  function perCommandBatchRejection(ctx, commands) {
76
87
  const index = commands.findIndex((cmd) => isPerCommandHandler(ctx, cmd.type));
@@ -96,6 +107,7 @@ async function checkBatchIdempotency(ctx, user, requestId) {
96
107
  // corrupted cache entry — treat as miss, let the request re-run
97
108
  return parsed ? { cached: parsed } : {};
98
109
  }
110
+ const BATCH_HOOKS_CONTEXT_TYPE = "dispatcher:batch-hooks";
99
111
  async function runBatchBody(ctx, commands, user, requestId, inheritedOrigin) {
100
112
  const { idempotency, lifecycle, appContext: context } = ctx;
101
113
  if (commands.length === 0) {
@@ -157,7 +169,7 @@ async function runBatchBody(ctx, commands, user, requestId, inheritedOrigin) {
157
169
  // Fires the batch-level system hooks with every successful save/delete
158
170
  // context from this run. Called after flushAfterCommit so per-save hooks
159
171
  // have all completed first; errors are isolated inside lifecycleHooks.
160
- const flushBatchHooksInner = async () => {
172
+ const flushBatchHooksInner = async (origin) => {
161
173
  try {
162
174
  const saves = [];
163
175
  const deletes = [];
@@ -171,10 +183,17 @@ async function runBatchBody(ctx, commands, user, requestId, inheritedOrigin) {
171
183
  else if (r.data.kind === "delete")
172
184
  deletes.push(r.data);
173
185
  }
174
- if (saves.length > 0 && lifecycle)
175
- await lifecycle.runPostSaveBatch(saves, context);
176
- if (deletes.length > 0 && lifecycle)
177
- await lifecycle.runPostDeleteBatch(deletes, context);
186
+ // skip: nothing to flush when there are no lifecycle hooks or no successful save/delete
187
+ if (!lifecycle || (saves.length === 0 && deletes.length === 0))
188
+ return;
189
+ // Post-commit context: batch hooks may write, but nothing is left to roll back.
190
+ const hookContext = await buildHandlerContext(ctx, BATCH_HOOKS_CONTEXT_TYPE, user, origin, {
191
+ transactionScope: "postCommit",
192
+ });
193
+ if (saves.length > 0)
194
+ await lifecycle.runPostSaveBatch(saves, hookContext);
195
+ if (deletes.length > 0)
196
+ await lifecycle.runPostDeleteBatch(deletes, hookContext);
178
197
  }
179
198
  catch (e) {
180
199
  // Batch hooks must never fail the batch — the commit already happened.
@@ -190,7 +209,7 @@ async function runBatchBody(ctx, commands, user, requestId, inheritedOrigin) {
190
209
  // skip: no command ran, so batch hooks have no saves or deletes to see
191
210
  if (!strictest)
192
211
  return;
193
- await runWithWriteOrigin(strictest, flushBatchHooksInner);
212
+ await runWithWriteOrigin(strictest, () => flushBatchHooksInner(strictest));
194
213
  };
195
214
  const perCommandRejection = perCommandBatchRejection(ctx, commands);
196
215
  if (perCommandRejection)
@@ -208,7 +227,7 @@ async function runBatchBody(ctx, commands, user, requestId, inheritedOrigin) {
208
227
  }, reservations.error.httpStatus >= 500);
209
228
  }
210
229
  // batch() opens its own outer transaction — needs the top-level
211
- // connection's `.begin()` (TransactionSql exposes only `.savepoint()`).
230
+ // connection's `.begin()` (a transaction handle cannot begin another one).
212
231
  const db = resolveAppPoolDb(ctx);
213
232
  if (!db || runsWithoutTransaction) {
214
233
  // Without a DB connection (or for a perCommand handler, whose writes open their own transactions)
@@ -250,6 +269,7 @@ async function runBatchBody(ctx, commands, user, requestId, inheritedOrigin) {
250
269
  // Rollback or failed COMMIT: the transaction is over, so the reserved capacity goes back.
251
270
  // The release is outcome-safe: it only gives back a reservation row the handler tx did not delete.
252
271
  await reservations.releaseAll();
272
+ await flushAfterRollback(afterCommitHooks, createFallbackLogger("dispatcher", context.log));
253
273
  if (e instanceof BatchRollback) {
254
274
  // Thrown inside the callback, so the tx rolled back. A 4xx is
255
275
  // deterministic and stays cached; a 5xx may be transient.
@@ -4,15 +4,16 @@ import { hasAccess } from "../engine/access.js";
4
4
  import { tenantOverrideDenied } from "../engine/cross-tenant.js";
5
5
  import { filterReadFields } from "../engine/field-access.js";
6
6
  import { NotFoundError, validationErrorFromZod } from "../errors/index.js";
7
- import { assertNoSecretLeak } from "../secrets/index.js";
7
+ import { assertNoSecretLeak } from "../secrets/leak-guard.js";
8
+ import { runInDispatchScope } from "./dispatch-scope.js";
8
9
  import { buildHandlerContext, enforceRateLimit, ensureFeatureEnabled, isMemberResolutionPrincipal, runHandlerInstrumented, } from "./dispatch-shared.js";
9
10
  import { handlerAccessError } from "./handler-access-error.js";
10
11
  import { runInMemberReadOnlyTransaction } from "./member-read-only-transaction.js";
11
12
  // Standalone query execution — used by the public dispatcher.query() and
12
- // by ctx.query/ctx.queryAs inside handlers. Runs the handler, applies
13
+ // by ctx.dispatch.query/ctx.dispatch.queryAs inside handlers. Runs the handler, applies
13
14
  // field-level read filters for the given user, logs the event.
14
15
  export async function executeQuery(ctx, type, payload, user, origin, tx, outerNotifySink) {
15
- return runHandlerInstrumented(ctx, type, "query", user, () => executeQueryInner(ctx, type, payload, user, origin, tx, outerNotifySink));
16
+ return runInDispatchScope(ctx.registry, [type], user, () => runHandlerInstrumented(ctx, type, "query", user, () => executeQueryInner(ctx, type, payload, user, origin, tx, outerNotifySink)));
16
17
  }
17
18
  async function executeQueryInner(ctx, type, payload, user, origin, tx, outerNotifySink) {
18
19
  const { registry } = ctx;
@@ -52,7 +53,7 @@ async function executeQueryInner(ctx, type, payload, user, origin, tx, outerNoti
52
53
  // so other handlers never see the flag. Visibility filters still apply
53
54
  // downstream (see HandlerContext.includeDeleted) — safe from raw input.
54
55
  const includeDeleted = propertyOf(parsed.data, "includeDeleted") === true;
55
- // A resolved member (ctx.queryAsMember) runs in a Postgres READ ONLY transaction, not just the ctx surface below.
56
+ // A resolved member (ctx.dispatch.queryAsMember) runs in a Postgres READ ONLY transaction, not just the ctx surface below.
56
57
  return isMemberResolutionPrincipal(user)
57
58
  ? runInMemberReadOnlyTransaction(ctx, tx, (readOnlyTx) => runQueryHandler(ctx, type, handler, parsed.data, includeDeleted, user, origin, readOnlyTx))
58
59
  : runQueryHandler(ctx, type, handler, parsed.data, includeDeleted, user, origin, tx, outerNotifySink);
@@ -0,0 +1,6 @@
1
+ import type { SessionUser } from "@cosmicdrift/kumiko-types/handlers";
2
+ import { type RowLevelSecurityScope } from "../db/row-level-security-scope.ts";
3
+ import type { Registry } from "../engine/types/index.ts";
4
+ export declare function dispatchRowLevelSecurityScope(registry: Registry, types: readonly string[], user: SessionUser): RowLevelSecurityScope;
5
+ export declare function runInDispatchScope<T>(registry: Registry, types: readonly string[], user: SessionUser, fn: () => T): T;
6
+ export declare function streamInDispatchScope<T>(scope: RowLevelSecurityScope, source: AsyncGenerator<T>): AsyncGenerator<T>;