@cosmicdrift/kumiko-framework 0.389.0 → 0.390.1

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 (617) hide show
  1. package/AGENTS.md +9 -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/inbound-mail-triage.md +1 -0
  13. package/agents/examples/lane-routing.md +2 -1
  14. package/agents/examples/legal-pages.md +2 -2
  15. package/agents/examples/lifecycle-hooks.md +3 -3
  16. package/agents/examples/managed-config.md +4 -4
  17. package/agents/examples/managed-pages.md +1 -1
  18. package/agents/examples/relations.md +19 -4
  19. package/agents/examples/search.md +4 -4
  20. package/agents/examples/secrets-demo.md +9 -6
  21. package/agents/examples/state-machine.md +2 -2
  22. package/agents/examples/tenant-settings.md +1 -1
  23. package/agents/examples/user-data-rights.md +3 -6
  24. package/agents/examples/workflow-engine.md +53 -47
  25. package/agents/examples.md +4 -4
  26. package/agents/features.md +1 -1
  27. package/dist/api/auth-middleware.js +1 -1
  28. package/dist/api/auth-routes-invite.js +2 -1
  29. package/dist/api/entity-read-access.d.ts +3 -1
  30. package/dist/api/export/export-columns.d.ts +3 -1
  31. package/dist/api/export/export-route.js +3 -2
  32. package/dist/api/export/export-screen.d.ts +2 -1
  33. package/dist/api/extra-route.d.ts +3 -1
  34. package/dist/api/index.d.ts +23 -27
  35. package/dist/api/index.js +13 -15
  36. package/dist/api/jwt.js +1 -1
  37. package/dist/api/observability-middleware.d.ts +1 -1
  38. package/dist/api/observability-middleware.js +2 -1
  39. package/dist/api/request-context-internals.d.ts +31 -0
  40. package/dist/api/request-context-internals.js +11 -0
  41. package/dist/api/request-context-scopes.d.ts +14 -0
  42. package/dist/api/request-context-scopes.js +69 -0
  43. package/dist/api/request-context.d.ts +1 -40
  44. package/dist/api/request-context.js +22 -51
  45. package/dist/api/request-id-middleware.d.ts +1 -1
  46. package/dist/api/route-registrars.d.ts +2 -1
  47. package/dist/api/route-registrars.js +1 -1
  48. package/dist/api/routes.js +7 -3
  49. package/dist/api/server-boot-checks.d.ts +1 -1
  50. package/dist/api/server-boot-checks.js +2 -2
  51. package/dist/api/server-event-dispatcher.d.ts +6 -1
  52. package/dist/api/server-event-dispatcher.js +3 -4
  53. package/dist/api/server-extra-routes.d.ts +1 -1
  54. package/dist/api/server-extra-routes.js +2 -1
  55. package/dist/api/server-middleware.js +3 -1
  56. package/dist/api/server-routes.d.ts +2 -1
  57. package/dist/api/server-wiring.js +6 -4
  58. package/dist/api/server.d.ts +2 -1
  59. package/dist/api/sse-route.d.ts +2 -1
  60. package/dist/api/tenant-scoped-secrets.d.ts +2 -0
  61. package/dist/api/tenant-scoped-secrets.js +13 -0
  62. package/dist/api/websocket-route.d.ts +1 -1
  63. package/dist/auth/index.d.ts +0 -1
  64. package/dist/auth/roles.d.ts +0 -5
  65. package/dist/compliance/duration-spec.d.ts +0 -1
  66. package/dist/compliance/duration-spec.js +0 -5
  67. package/dist/compliance/index.d.ts +4 -4
  68. package/dist/compliance/index.js +2 -2
  69. package/dist/compliance/profiles.d.ts +0 -15
  70. package/dist/compliance/profiles.js +0 -23
  71. package/dist/config/index.d.ts +10 -10
  72. package/dist/config/index.js +13 -1
  73. package/dist/config/internals.d.ts +9 -0
  74. package/dist/config/internals.js +1 -0
  75. package/dist/consumer-cli-internals.d.ts +4 -0
  76. package/dist/consumer-cli-internals.js +1 -0
  77. package/dist/consumer-cli.d.ts +1 -4
  78. package/dist/consumer-cli.js +5 -1
  79. package/dist/crypto/event-pii.js +1 -1
  80. package/dist/crypto/index.d.ts +8 -9
  81. package/dist/crypto/index.js +7 -8
  82. package/dist/crypto/pg-kms-adapter.js +6 -1
  83. package/dist/db/apply-entity-event.d.ts +1 -1
  84. package/dist/db/apply-entity-event.js +15 -47
  85. package/dist/db/blind-index-cleanup.js +91 -77
  86. package/dist/db/collect-table-metas.js +1 -1
  87. package/dist/db/compound-types.d.ts +1 -1
  88. package/dist/db/compound-types.js +0 -7
  89. package/dist/db/config-seed.d.ts +2 -1
  90. package/dist/db/config-seed.js +6 -1
  91. package/dist/db/connection.d.ts +3 -1
  92. package/dist/db/connection.js +15 -5
  93. package/dist/db/cross-tenant-reads.d.ts +1 -1
  94. package/dist/db/cross-tenant-reads.js +1 -1
  95. package/dist/db/dialect.d.ts +0 -5
  96. package/dist/db/dialect.js +0 -3
  97. package/dist/db/driver-value-preparation.js +23 -2
  98. package/dist/db/eagerload.d.ts +2 -1
  99. package/dist/db/entity-field-encryption.d.ts +1 -1
  100. package/dist/db/entity-table-meta.d.ts +1 -1
  101. package/dist/db/event-store-executor-context.d.ts +3 -1
  102. package/dist/db/event-store-executor-context.js +4 -3
  103. package/dist/db/event-store-executor-read-filter.d.ts +1 -1
  104. package/dist/db/event-store-executor-read-rows.d.ts +2 -1
  105. package/dist/db/event-store-executor-read-search.d.ts +2 -1
  106. package/dist/db/event-store-executor-read-sort.d.ts +2 -1
  107. package/dist/db/event-store-executor-read.js +2 -2
  108. package/dist/db/event-store-executor-write-atomic.js +8 -7
  109. package/dist/db/event-store-executor-write-steps.d.ts +3 -2
  110. package/dist/db/event-store-executor-write.js +7 -4
  111. package/dist/db/event-store-executor.d.ts +1 -1
  112. package/dist/db/executor-managed-tables.d.ts +7 -1
  113. package/dist/db/executor-managed-tables.js +11 -2
  114. package/dist/db/index.d.ts +29 -28
  115. package/dist/db/index.js +22 -20
  116. package/dist/db/known-table-names.d.ts +6 -0
  117. package/dist/db/known-table-names.js +21 -0
  118. package/dist/db/list-aggregate-labels.d.ts +1 -1
  119. package/dist/db/located-timestamp.d.ts +1 -1
  120. package/dist/db/located-timestamp.js +0 -5
  121. package/dist/db/migrate-generator.d.ts +17 -1
  122. package/dist/db/migrate-generator.js +50 -20
  123. package/dist/db/migrate-primary-key.d.ts +12 -0
  124. package/dist/db/migrate-primary-key.js +45 -0
  125. package/dist/db/migrate-rls-diff.d.ts +20 -0
  126. package/dist/db/migrate-rls-diff.js +61 -0
  127. package/dist/db/migrate-runner.js +4 -0
  128. package/dist/db/money.d.ts +1 -1
  129. package/dist/db/money.js +1 -1
  130. package/dist/db/parent-ref-clause.d.ts +2 -1
  131. package/dist/db/pg-error.d.ts +2 -0
  132. package/dist/db/pg-error.js +11 -0
  133. package/dist/db/queries/ddl.d.ts +3 -0
  134. package/dist/db/queries/ddl.js +34 -1
  135. package/dist/db/queries/event-store.js +4 -2
  136. package/dist/db/queries/event-tenants.d.ts +2 -0
  137. package/dist/db/queries/event-tenants.js +17 -0
  138. package/dist/db/queries/rebuild-rls-guard.d.ts +2 -0
  139. package/dist/db/queries/rebuild-rls-guard.js +29 -0
  140. package/dist/db/queries/rls-boot-catalog.d.ts +16 -0
  141. package/dist/db/queries/rls-boot-catalog.js +39 -0
  142. package/dist/db/queries/rls-catalog.d.ts +6 -0
  143. package/dist/db/queries/rls-catalog.js +82 -0
  144. package/dist/db/queries/rls-scope.d.ts +3 -0
  145. package/dist/db/queries/rls-scope.js +17 -0
  146. package/dist/db/queries/rls-shape.d.ts +10 -0
  147. package/dist/db/queries/rls-shape.js +42 -0
  148. package/dist/db/queries/session-advisory-lock.d.ts +2 -0
  149. package/dist/db/queries/session-advisory-lock.js +23 -0
  150. package/dist/db/queries/shadow-swap.d.ts +1 -2
  151. package/dist/db/queries/shadow-swap.js +9 -25
  152. package/dist/db/queries/test-stack.d.ts +4 -1
  153. package/dist/db/queries/test-stack.js +84 -2
  154. package/dist/db/query.js +11 -7
  155. package/dist/db/reference-data.d.ts +1 -1
  156. package/dist/db/reference-data.js +6 -1
  157. package/dist/db/render-ddl.d.ts +6 -2
  158. package/dist/db/render-ddl.js +7 -7
  159. package/dist/db/render-rls-ddl.d.ts +35 -0
  160. package/dist/db/render-rls-ddl.js +127 -0
  161. package/dist/db/replay-migration-sql.d.ts +3 -1
  162. package/dist/db/replay-migration-sql.js +22 -5
  163. package/dist/db/replay-rls.d.ts +25 -0
  164. package/dist/db/replay-rls.js +156 -0
  165. package/dist/db/row-level-security-boot-check.d.ts +6 -0
  166. package/dist/db/row-level-security-boot-check.js +86 -0
  167. package/dist/db/row-level-security-connection.d.ts +3 -0
  168. package/dist/db/row-level-security-connection.js +213 -0
  169. package/dist/db/row-level-security-scope.d.ts +33 -0
  170. package/dist/db/row-level-security-scope.js +127 -0
  171. package/dist/db/scope-tenant-db-to-tenant.d.ts +3 -0
  172. package/dist/db/scope-tenant-db-to-tenant.js +14 -0
  173. package/dist/db/sql-identifier.d.ts +1 -0
  174. package/dist/db/sql-identifier.js +3 -0
  175. package/dist/db/table-builder.d.ts +2 -1
  176. package/dist/db/table-builder.js +1 -1
  177. package/dist/db/table-info.js +1 -1
  178. package/dist/db/table-push.d.ts +11 -2
  179. package/dist/db/table-push.js +15 -2
  180. package/dist/db/tenant-db-runner.d.ts +3 -1
  181. package/dist/db/tenant-db-runner.js +4 -3
  182. package/dist/db/tenant-db-scoped-rebind.d.ts +10 -0
  183. package/dist/db/tenant-db-scoped-rebind.js +33 -0
  184. package/dist/db/tenant-db-statement-runner.d.ts +13 -0
  185. package/dist/db/tenant-db-statement-runner.js +48 -0
  186. package/dist/db/tenant-db.d.ts +17 -12
  187. package/dist/db/tenant-db.js +49 -120
  188. package/dist/db/tenant-id-filter.d.ts +3 -0
  189. package/dist/db/tenant-id-filter.js +30 -0
  190. package/dist/db/transaction-serialization.d.ts +6 -0
  191. package/dist/db/transaction-serialization.js +60 -0
  192. package/dist/derivatives/delete-stored-file.js +1 -1
  193. package/dist/derivatives/index.d.ts +2 -5
  194. package/dist/derivatives/index.js +2 -3
  195. package/dist/engine/access.d.ts +2 -1
  196. package/dist/engine/access.js +1 -1
  197. package/dist/engine/boot-validator/entity-handler.d.ts +2 -1
  198. package/dist/engine/boot-validator/entity-handler.js +1 -1
  199. package/dist/engine/boot-validator/entity-list-aggregate-options.d.ts +1 -1
  200. package/dist/engine/boot-validator/list-table-aggregate-options.d.ts +1 -1
  201. package/dist/engine/boot-validator/list-table-aggregate-query.d.ts +2 -1
  202. package/dist/engine/boot-validator/nav.d.ts +3 -1
  203. package/dist/engine/boot-validator/nav.js +1 -1
  204. package/dist/engine/boot-validator/ownership.d.ts +2 -1
  205. package/dist/engine/boot-validator/parent-ref.d.ts +2 -1
  206. package/dist/engine/boot-validator/projection-list-screens.d.ts +2 -1
  207. package/dist/engine/boot-validator/query-refs.d.ts +2 -1
  208. package/dist/engine/boot-validator/screens-forms.d.ts +2 -1
  209. package/dist/engine/boot-validator/screens-kind-shared.d.ts +3 -1
  210. package/dist/engine/boot-validator/screens.d.ts +2 -1
  211. package/dist/engine/boot-validator/workspaces.d.ts +3 -1
  212. package/dist/engine/bridge-stub.d.ts +5 -2
  213. package/dist/engine/bridge-stub.js +39 -24
  214. package/dist/engine/config-helpers.d.ts +2 -2
  215. package/dist/engine/config-helpers.js +0 -9
  216. package/dist/engine/constants.d.ts +0 -10
  217. package/dist/engine/constants.js +0 -8
  218. package/dist/engine/create-app.js +1 -1
  219. package/dist/engine/define-feature.d.ts +2 -1
  220. package/dist/engine/define-feature.js +1 -2
  221. package/dist/engine/define-handler.d.ts +1 -1
  222. package/dist/engine/define-step.d.ts +0 -1
  223. package/dist/engine/define-step.js +0 -3
  224. package/dist/engine/embedded-derived.d.ts +1 -1
  225. package/dist/engine/entity-handlers.d.ts +2 -1
  226. package/dist/engine/entity-handlers.js +7 -7
  227. package/dist/engine/entity-list-runtime-options.js +3 -1
  228. package/dist/engine/entity-list-searchability.d.ts +2 -1
  229. package/dist/engine/event-def.d.ts +2 -1
  230. package/dist/engine/event-helpers.d.ts +3 -1
  231. package/dist/engine/event-helpers.js +3 -3
  232. package/dist/engine/extension-names.d.ts +2 -8
  233. package/dist/engine/extension-names.js +2 -2
  234. package/dist/engine/extension-selector-plugins.d.ts +1 -1
  235. package/dist/engine/extensions/storage-provider.d.ts +1 -2
  236. package/dist/engine/extensions/user-data.d.ts +0 -8
  237. package/dist/engine/factories.d.ts +2 -1
  238. package/dist/engine/feature-builder-state.d.ts +8 -1
  239. package/dist/engine/feature-changelog.d.ts +1 -1
  240. package/dist/engine/feature-config-events-jobs.d.ts +4 -1
  241. package/dist/engine/feature-entity-handlers.d.ts +5 -1
  242. package/dist/engine/feature-manifest.js +1 -1
  243. package/dist/engine/feature-ui-extensions.d.ts +7 -1
  244. package/dist/engine/feature-ui-extensions.js +6 -4
  245. package/dist/engine/field-access.d.ts +2 -1
  246. package/dist/engine/handler-field-references.d.ts +0 -4
  247. package/dist/engine/index.d.ts +57 -54
  248. package/dist/engine/index.js +22 -27
  249. package/dist/engine/instruction-fields.d.ts +1 -1
  250. package/dist/engine/personal-data-fields.d.ts +1 -1
  251. package/dist/engine/qualified-name.d.ts +0 -1
  252. package/dist/engine/read-claim.d.ts +2 -1
  253. package/dist/engine/registry-facade.js +0 -3
  254. package/dist/engine/registry-ingest.d.ts +2 -1
  255. package/dist/engine/registry-ingest.js +1 -2
  256. package/dist/engine/registry-state.d.ts +12 -2
  257. package/dist/engine/registry-state.js +2 -3
  258. package/dist/engine/registry-validate.d.ts +3 -1
  259. package/dist/engine/registry-validate.js +7 -7
  260. package/dist/engine/run-in.d.ts +1 -1
  261. package/dist/engine/run-in.js +0 -1
  262. package/dist/engine/schema-builder.d.ts +1 -1
  263. package/dist/engine/schema-builder.js +1 -1
  264. package/dist/engine/screen-filter-ops.d.ts +2 -1
  265. package/dist/engine/screen-filter-ops.js +0 -5
  266. package/dist/engine/soft-delete-cleanup.d.ts +1 -1
  267. package/dist/engine/soft-delete-cleanup.js +4 -4
  268. package/dist/engine/state-machine.js +2 -1
  269. package/dist/engine/steps/_read-source.js +1 -1
  270. package/dist/engine/steps/aggregate-append-event.js +2 -2
  271. package/dist/engine/steps/call-feature.js +2 -2
  272. package/dist/engine/steps/mail-send.js +1 -1
  273. package/dist/engine/steps/retry.js +1 -1
  274. package/dist/engine/steps/wait-for-event.js +1 -1
  275. package/dist/engine/steps/wait.js +1 -1
  276. package/dist/engine/steps/webhook-send.js +1 -1
  277. package/dist/engine/template-variables.d.ts +2 -1
  278. package/dist/engine/transfer-adjacency.d.ts +1 -1
  279. package/dist/engine/types/index.d.ts +8 -31
  280. package/dist/engine/types/index.js +2 -10
  281. package/dist/engine/validation.d.ts +2 -1
  282. package/dist/entrypoint/index.d.ts +7 -35
  283. package/dist/entrypoint/index.js +7 -1
  284. package/dist/entrypoint/internals.d.ts +40 -0
  285. package/dist/entrypoint/internals.js +1 -0
  286. package/dist/entrypoint/row-level-security-mode-check.d.ts +3 -0
  287. package/dist/entrypoint/row-level-security-mode-check.js +19 -0
  288. package/dist/env/dry-run-internals.d.ts +10 -0
  289. package/dist/env/dry-run-internals.js +1 -0
  290. package/dist/env/dry-run.d.ts +1 -10
  291. package/dist/env/dry-run.js +2 -1
  292. package/dist/env/index.d.ts +1 -85
  293. package/dist/env/index.js +6 -50
  294. package/dist/env/internals.d.ts +87 -0
  295. package/dist/env/internals.js +53 -0
  296. package/dist/errors/classes.js +2 -2
  297. package/dist/errors/index.d.ts +5 -14
  298. package/dist/errors/index.js +4 -9
  299. package/dist/errors/member-resolution.js +1 -1
  300. package/dist/errors/reasons.d.ts +0 -1
  301. package/dist/errors/reasons.js +7 -7
  302. package/dist/errors/serialize.d.ts +0 -18
  303. package/dist/errors/serialize.js +0 -27
  304. package/dist/es-ops/index.d.ts +4 -4
  305. package/dist/es-ops/index.js +2 -2
  306. package/dist/es-ops/operations-schema.d.ts +1 -1
  307. package/dist/es-ops/types.d.ts +4 -5
  308. package/dist/event-store/admin-api-internals.d.ts +14 -0
  309. package/dist/event-store/admin-api-internals.js +1 -0
  310. package/dist/event-store/admin-api.d.ts +1 -14
  311. package/dist/event-store/admin-api.js +11 -6
  312. package/dist/event-store/archive.js +4 -2
  313. package/dist/event-store/errors.js +2 -2
  314. package/dist/event-store/event-store.js +41 -34
  315. package/dist/event-store/events-schema.js +4 -1
  316. package/dist/event-store/index.d.ts +11 -13
  317. package/dist/event-store/index.js +7 -9
  318. package/dist/event-store/rebuild-dead-letter.js +4 -2
  319. package/dist/event-store/snapshot.js +4 -3
  320. package/dist/event-store/stream-scope.d.ts +2 -0
  321. package/dist/event-store/stream-scope.js +6 -0
  322. package/dist/event-store/upcaster-dead-letter.js +4 -2
  323. package/dist/event-store/upcaster.d.ts +2 -1
  324. package/dist/files/action-form-upload.d.ts +2 -1
  325. package/dist/files/action-form-upload.js +1 -1
  326. package/dist/files/assert-file-refs-belong-to-tenant.d.ts +2 -1
  327. package/dist/files/assert-file-refs-belong-to-tenant.js +1 -1
  328. package/dist/files/bind-pending-file-refs.d.ts +2 -1
  329. package/dist/files/bind-pending-file-refs.js +2 -1
  330. package/dist/files/bind-referenced-files.write.js +1 -1
  331. package/dist/files/create-file-ref-from-bytes.d.ts +6 -3
  332. package/dist/files/create-file-ref-from-bytes.js +3 -3
  333. package/dist/files/create-file-ref.d.ts +3 -2
  334. package/dist/files/create-file-ref.js +2 -2
  335. package/dist/files/dispose-removed-file-refs.d.ts +2 -1
  336. package/dist/files/dispose-removed-file-refs.js +1 -1
  337. package/dist/files/feature.js +2 -2
  338. package/dist/files/file-handle.js +1 -1
  339. package/dist/files/file-routes.d.ts +1 -1
  340. package/dist/files/file-routes.js +12 -2
  341. package/dist/files/index.d.ts +11 -13
  342. package/dist/files/index.js +5 -7
  343. package/dist/files/load-save-file-refs.d.ts +2 -1
  344. package/dist/files/load-save-file-refs.js +1 -1
  345. package/dist/files/provider-resolver.d.ts +5 -4
  346. package/dist/files/provider-resolver.js +4 -4
  347. package/dist/files/storage-tracking.js +4 -2
  348. package/dist/files/sweep-orphaned-uploads.d.ts +1 -1
  349. package/dist/files/sweep-orphaned-uploads.js +1 -1
  350. package/dist/i18n/index.d.ts +2 -8
  351. package/dist/i18n/index.js +1 -1
  352. package/dist/i18n/internals.d.ts +7 -0
  353. package/dist/i18n/internals.js +1 -0
  354. package/dist/i18n/required-surface-keys.d.ts +4 -1
  355. package/dist/internal/row-level-security.d.ts +3 -0
  356. package/dist/internal/row-level-security.js +3 -0
  357. package/dist/internal/stack-support.d.ts +1 -1
  358. package/dist/internal/stack-support.js +1 -1
  359. package/dist/internal/testing.d.ts +1 -0
  360. package/dist/internal/testing.js +9 -5
  361. package/dist/jobs/index.d.ts +1 -1
  362. package/dist/jobs/job-append-event.d.ts +12 -0
  363. package/dist/jobs/job-append-event.js +30 -0
  364. package/dist/jobs/job-runner-context.d.ts +2 -2
  365. package/dist/jobs/job-runner-context.js +46 -16
  366. package/dist/jobs/job-runner-execution.d.ts +1 -1
  367. package/dist/jobs/job-runner-execution.js +6 -4
  368. package/dist/jobs/job-runner-gates.d.ts +1 -1
  369. package/dist/jobs/job-runner-gates.js +0 -1
  370. package/dist/jobs/job-runner-helpers.d.ts +11 -4
  371. package/dist/jobs/job-runner-helpers.js +10 -1
  372. package/dist/jobs/job-runner-scope.d.ts +5 -2
  373. package/dist/jobs/job-runner-types.d.ts +2 -1
  374. package/dist/jobs/job-runner.js +19 -6
  375. package/dist/jobs/max-per-tenant.d.ts +1 -1
  376. package/dist/logging/index.d.ts +1 -2
  377. package/dist/logging/index.js +1 -1
  378. package/dist/logging/pino-logger.js +1 -1
  379. package/dist/logging/utils.d.ts +1 -0
  380. package/dist/logging/utils.js +6 -0
  381. package/dist/migrations/index.d.ts +3 -3
  382. package/dist/migrations/index.js +3 -3
  383. package/dist/migrations/pending-rebuilds.d.ts +1 -1
  384. package/dist/migrations/pending-rebuilds.js +1 -1
  385. package/dist/migrations/pii-event-backfill.js +4 -1
  386. package/dist/observability/escape-hatch-report.d.ts +2 -1
  387. package/dist/observability/index.d.ts +7 -15
  388. package/dist/observability/index.js +4 -12
  389. package/dist/observability/metric-validator.js +1 -1
  390. package/dist/observability/metrics-handle.d.ts +0 -1
  391. package/dist/observability/metrics-handle.js +2 -15
  392. package/dist/observability/recording-tracer.d.ts +1 -2
  393. package/dist/observability/recording-tracer.js +0 -6
  394. package/dist/observability/sensitive-filter.d.ts +0 -2
  395. package/dist/observability/sensitive-filter.js +0 -29
  396. package/dist/pipeline/active-membership.d.ts +2 -1
  397. package/dist/pipeline/active-membership.js +6 -2
  398. package/dist/pipeline/append-event-core.d.ts +2 -1
  399. package/dist/pipeline/append-event-core.js +2 -2
  400. package/dist/pipeline/attach-outside-transaction.d.ts +3 -0
  401. package/dist/pipeline/attach-outside-transaction.js +13 -0
  402. package/dist/pipeline/auth-claims-resolver.d.ts +2 -1
  403. package/dist/pipeline/cascade-handler.d.ts +2 -1
  404. package/dist/pipeline/cascade-handler.js +3 -2
  405. package/dist/pipeline/config-accessor-factory.d.ts +1 -1
  406. package/dist/pipeline/config-accessor-factory.js +1 -1
  407. package/dist/pipeline/context-services.d.ts +56 -0
  408. package/dist/pipeline/context-services.js +73 -0
  409. package/dist/pipeline/dispatch-batch.d.ts +2 -1
  410. package/dist/pipeline/dispatch-batch.js +31 -18
  411. package/dist/pipeline/dispatch-query.js +5 -4
  412. package/dist/pipeline/dispatch-scope.d.ts +6 -0
  413. package/dist/pipeline/dispatch-scope.js +27 -0
  414. package/dist/pipeline/dispatch-shared.d.ts +13 -9
  415. package/dist/pipeline/dispatch-shared.js +75 -198
  416. package/dist/pipeline/dispatch-stream.js +8 -4
  417. package/dist/pipeline/dispatch-write.d.ts +2 -1
  418. package/dist/pipeline/dispatch-write.js +10 -8
  419. package/dist/pipeline/dispatcher-utils.d.ts +3 -1
  420. package/dist/pipeline/dispatcher-utils.js +8 -2
  421. package/dist/pipeline/dispatcher.d.ts +3 -2
  422. package/dist/pipeline/dispatcher.js +4 -3
  423. package/dist/pipeline/event-consumer-state.d.ts +0 -1
  424. package/dist/pipeline/event-dispatcher-delivery.d.ts +1 -1
  425. package/dist/pipeline/event-dispatcher-delivery.js +4 -2
  426. package/dist/pipeline/event-dispatcher.d.ts +2 -2
  427. package/dist/pipeline/event-dispatcher.js +7 -3
  428. package/dist/pipeline/event-retention.js +59 -56
  429. package/dist/pipeline/handler-access-error.js +2 -1
  430. package/dist/pipeline/handler-context-auth.d.ts +5 -6
  431. package/dist/pipeline/handler-context-auth.js +7 -4
  432. package/dist/pipeline/handler-context-config.d.ts +2 -5
  433. package/dist/pipeline/handler-context-config.js +2 -2
  434. package/dist/pipeline/handler-context-db.d.ts +32 -7
  435. package/dist/pipeline/handler-context-db.js +26 -17
  436. package/dist/pipeline/handler-context-dispatch.d.ts +13 -7
  437. package/dist/pipeline/handler-context-dispatch.js +9 -8
  438. package/dist/pipeline/handler-context-events.d.ts +22 -36
  439. package/dist/pipeline/handler-context-events.js +36 -31
  440. package/dist/pipeline/handler-context-member-resolution.d.ts +2 -0
  441. package/dist/pipeline/handler-context-member-resolution.js +110 -0
  442. package/dist/pipeline/handler-context-notify.d.ts +3 -2
  443. package/dist/pipeline/handler-context-notify.js +1 -1
  444. package/dist/pipeline/handler-context-observability.d.ts +2 -4
  445. package/dist/pipeline/handler-context-observability.js +7 -5
  446. package/dist/pipeline/handler-context-phase-denials.d.ts +11 -0
  447. package/dist/pipeline/handler-context-phase-denials.js +98 -0
  448. package/dist/pipeline/handler-context-scope.d.ts +7 -10
  449. package/dist/pipeline/handler-context-scope.js +18 -20
  450. package/dist/pipeline/index.d.ts +9 -21
  451. package/dist/pipeline/index.js +5 -7
  452. package/dist/pipeline/irreversible-operation-gate.d.ts +1 -1
  453. package/dist/pipeline/irreversible-operation-gate.js +2 -2
  454. package/dist/pipeline/lifecycle-pipeline.d.ts +8 -7
  455. package/dist/pipeline/lifecycle-pipeline.js +9 -15
  456. package/dist/pipeline/member-read-only-transaction.js +11 -3
  457. package/dist/pipeline/member-reader.d.ts +1 -1
  458. package/dist/pipeline/member-reader.js +2 -2
  459. package/dist/pipeline/msp-rebuild.js +5 -3
  460. package/dist/pipeline/multi-stream-apply-context.js +3 -2
  461. package/dist/pipeline/notify-scope.d.ts +2 -1
  462. package/dist/pipeline/pre-handler-gates.d.ts +2 -1
  463. package/dist/pipeline/pre-transaction-reservations.d.ts +3 -3
  464. package/dist/pipeline/pre-transaction-reservations.js +9 -7
  465. package/dist/pipeline/projection-rebuild.js +12 -5
  466. package/dist/pipeline/projection-state.d.ts +0 -6
  467. package/dist/pipeline/projection-state.js +0 -5
  468. package/dist/pipeline/projections-runner.d.ts +2 -1
  469. package/dist/pipeline/projections-runner.js +10 -6
  470. package/dist/pipeline/system-hooks.d.ts +3 -1
  471. package/dist/pipeline/system-hooks.js +6 -4
  472. package/dist/pipeline/system-identity-switch.d.ts +4 -2
  473. package/dist/pipeline/system-identity-switch.js +51 -36
  474. package/dist/pipeline/typed-append-event.d.ts +2 -0
  475. package/dist/pipeline/typed-append-event.js +4 -0
  476. package/dist/pipeline/write-origin.js +2 -2
  477. package/dist/pipeline/write-result-masking.d.ts +1 -1
  478. package/dist/random/index.d.ts +1 -2
  479. package/dist/random/index.js +1 -2
  480. package/dist/rate-limit/bucket.d.ts +2 -1
  481. package/dist/rate-limit/middleware.js +2 -1
  482. package/dist/redis/index.d.ts +3 -4
  483. package/dist/redis/index.js +2 -2
  484. package/dist/schema-cli/apply-command.js +5 -2
  485. package/dist/schema-cli/baseline-command.js +7 -2
  486. package/dist/schema-cli/generate-command.js +7 -9
  487. package/dist/schema-cli/shared.d.ts +12 -2
  488. package/dist/schema-cli/shared.js +24 -2
  489. package/dist/schema-cli/status-command.js +8 -2
  490. package/dist/schema-cli/validate-command.js +48 -4
  491. package/dist/schema-cli.d.ts +0 -1
  492. package/dist/search/configure-tenant-index.d.ts +1 -3
  493. package/dist/search/configure-tenant-index.js +0 -4
  494. package/dist/search/index.d.ts +1 -4
  495. package/dist/search/index.js +0 -2
  496. package/dist/search/meilisearch-adapter-internals.d.ts +8 -0
  497. package/dist/search/meilisearch-adapter-internals.js +9 -0
  498. package/dist/search/meilisearch-adapter.d.ts +1 -8
  499. package/dist/search/meilisearch-adapter.js +6 -7
  500. package/dist/search/meilisearch-peer.d.ts +2 -0
  501. package/dist/search/meilisearch-peer.js +5 -0
  502. package/dist/search/reindex-entity.js +93 -87
  503. package/dist/secrets/index.d.ts +3 -4
  504. package/dist/secrets/index.js +2 -3
  505. package/dist/seeding/index.d.ts +2 -2
  506. package/dist/seeding/index.js +1 -2
  507. package/dist/time/index.d.ts +2 -2
  508. package/dist/time/index.js +1 -1
  509. package/dist/time/tz-context.d.ts +0 -5
  510. package/dist/time/tz-context.js +0 -9
  511. package/dist/ui-types/index.d.ts +8 -11
  512. package/dist/ui-types/index.js +3 -3
  513. package/dist/upgrade-changelog.d.ts +3 -2
  514. package/dist/upgrade-changelog.js +12 -8
  515. package/dist/upgrade-cli-internals.d.ts +8 -0
  516. package/dist/upgrade-cli-internals.js +63 -0
  517. package/dist/upgrade-cli.d.ts +2 -9
  518. package/dist/upgrade-cli.js +28 -70
  519. package/dist/utils/import-optional-peer.d.ts +6 -0
  520. package/dist/utils/import-optional-peer.js +19 -0
  521. package/dist/utils/index.d.ts +1 -4
  522. package/dist/utils/index.js +1 -4
  523. package/package.json +23 -19
  524. package/src/changes.json +236 -0
  525. package/dist/crypto/request-kms-cache.d.ts +0 -8
  526. package/dist/crypto/request-kms-cache.js +0 -21
  527. package/dist/engine/codemod/index.d.ts +0 -2
  528. package/dist/engine/codemod/index.js +0 -1
  529. package/dist/engine/codemod/pipeline-codemod.d.ts +0 -50
  530. package/dist/engine/codemod/pipeline-codemod.js +0 -536
  531. package/dist/engine/feature-ast/entity-field-types.d.ts +0 -13
  532. package/dist/engine/feature-ast/entity-field-types.js +0 -35
  533. package/dist/engine/feature-ast/extractors/ai-steps.d.ts +0 -6
  534. package/dist/engine/feature-ast/extractors/ai-steps.js +0 -254
  535. package/dist/engine/feature-ast/extractors/events.d.ts +0 -5
  536. package/dist/engine/feature-ast/extractors/events.js +0 -275
  537. package/dist/engine/feature-ast/extractors/handlers.d.ts +0 -24
  538. package/dist/engine/feature-ast/extractors/handlers.js +0 -358
  539. package/dist/engine/feature-ast/extractors/hooks.d.ts +0 -24
  540. package/dist/engine/feature-ast/extractors/hooks.js +0 -248
  541. package/dist/engine/feature-ast/extractors/index.d.ts +0 -14
  542. package/dist/engine/feature-ast/extractors/index.js +0 -13
  543. package/dist/engine/feature-ast/extractors/jobs-routes.d.ts +0 -7
  544. package/dist/engine/feature-ast/extractors/jobs-routes.js +0 -145
  545. package/dist/engine/feature-ast/extractors/projections-screens.d.ts +0 -10
  546. package/dist/engine/feature-ast/extractors/projections-screens.js +0 -195
  547. package/dist/engine/feature-ast/extractors/resolve-import.d.ts +0 -21
  548. package/dist/engine/feature-ast/extractors/resolve-import.js +0 -180
  549. package/dist/engine/feature-ast/extractors/round1.d.ts +0 -11
  550. package/dist/engine/feature-ast/extractors/round1.js +0 -87
  551. package/dist/engine/feature-ast/extractors/round2.d.ts +0 -7
  552. package/dist/engine/feature-ast/extractors/round2.js +0 -191
  553. package/dist/engine/feature-ast/extractors/round3.d.ts +0 -23
  554. package/dist/engine/feature-ast/extractors/round3.js +0 -292
  555. package/dist/engine/feature-ast/extractors/round5.d.ts +0 -9
  556. package/dist/engine/feature-ast/extractors/round5.js +0 -68
  557. package/dist/engine/feature-ast/extractors/round6.d.ts +0 -4
  558. package/dist/engine/feature-ast/extractors/round6.js +0 -17
  559. package/dist/engine/feature-ast/extractors/shared.d.ts +0 -94
  560. package/dist/engine/feature-ast/extractors/shared.js +0 -343
  561. package/dist/engine/feature-ast/index.d.ts +0 -16
  562. package/dist/engine/feature-ast/index.js +0 -10
  563. package/dist/engine/feature-ast/parse.d.ts +0 -31
  564. package/dist/engine/feature-ast/parse.js +0 -485
  565. package/dist/engine/feature-ast/patch.d.ts +0 -212
  566. package/dist/engine/feature-ast/patch.js +0 -611
  567. package/dist/engine/feature-ast/patcher.d.ts +0 -217
  568. package/dist/engine/feature-ast/patcher.js +0 -281
  569. package/dist/engine/feature-ast/pattern-change-schema.d.ts +0 -1238
  570. package/dist/engine/feature-ast/pattern-change-schema.js +0 -1072
  571. package/dist/engine/feature-ast/pattern-id-matchers.d.ts +0 -7
  572. package/dist/engine/feature-ast/pattern-id-matchers.js +0 -211
  573. package/dist/engine/feature-ast/pattern-id-schema.d.ts +0 -251
  574. package/dist/engine/feature-ast/pattern-id-schema.js +0 -166
  575. package/dist/engine/feature-ast/patterns.d.ts +0 -322
  576. package/dist/engine/feature-ast/patterns.js +0 -107
  577. package/dist/engine/feature-ast/render.d.ts +0 -47
  578. package/dist/engine/feature-ast/render.js +0 -666
  579. package/dist/engine/feature-ast/source-location.d.ts +0 -17
  580. package/dist/engine/feature-ast/source-location.js +0 -27
  581. package/dist/engine/pattern-library/index.d.ts +0 -2
  582. package/dist/engine/pattern-library/index.js +0 -3
  583. package/dist/engine/pattern-library/library.d.ts +0 -14
  584. package/dist/engine/pattern-library/library.js +0 -94
  585. package/dist/engine/pattern-library/mixed-schemas.d.ts +0 -16
  586. package/dist/engine/pattern-library/mixed-schemas.js +0 -559
  587. package/dist/engine/pattern-library/opaque-schemas.d.ts +0 -7
  588. package/dist/engine/pattern-library/opaque-schemas.js +0 -115
  589. package/dist/engine/pattern-library/shared-fields.d.ts +0 -122
  590. package/dist/engine/pattern-library/shared-fields.js +0 -88
  591. package/dist/engine/pattern-library/static-schemas.d.ts +0 -21
  592. package/dist/engine/pattern-library/static-schemas.js +0 -487
  593. package/dist/engine/pattern-library/types.d.ts +0 -158
  594. package/dist/engine/pattern-library/types.js +0 -36
  595. package/dist/engine/resolve-config-or-param.d.ts +0 -18
  596. package/dist/engine/resolve-config-or-param.js +0 -76
  597. package/src/scripts/codemod/README.md +0 -187
  598. package/src/scripts/codemod/codemod-support.ts +0 -334
  599. package/src/scripts/codemod/collect-source-files.ts +0 -48
  600. package/src/scripts/codemod/crypto-shredding-testing-move.ts +0 -119
  601. package/src/scripts/codemod/db-factory.ts +0 -810
  602. package/src/scripts/codemod/feature-factory.ts +0 -429
  603. package/src/scripts/codemod/feature-layout.ts +0 -424
  604. package/src/scripts/codemod/import-extensions.ts +0 -118
  605. package/src/scripts/codemod/migrate-cross-tenant.ts +0 -328
  606. package/src/scripts/codemod/migrate-db-raw.ts +0 -401
  607. package/src/scripts/codemod/migrate-open-to-all.ts +0 -235
  608. package/src/scripts/codemod/object-form.ts +0 -746
  609. package/src/scripts/codemod/package-merge.ts +0 -299
  610. package/src/scripts/codemod/pii-personal-migration.ts +0 -816
  611. package/src/scripts/codemod/remove-engine-payload-casts.ts +0 -318
  612. package/src/scripts/codemod/s3-imports.ts +0 -236
  613. package/src/scripts/codemod/tenant-db-options.ts +0 -454
  614. package/src/scripts/codemod/testing-injection.ts +0 -215
  615. package/src/scripts/codemod/testing-move-targets.ts +0 -161
  616. package/src/scripts/codemod/testing-move.ts +0 -542
  617. package/src/scripts/codemod/unprocessable-error-details-reason.ts +0 -411
@@ -1,26 +1,24 @@
1
- export { createEscapeHatchReporter, createEscapeHatchReportWindow, ESCAPE_HATCH_USED_SIGNAL, fallbackEscapeHatchReporter, flushEscapeHatchAudits, reportEscapeHatchUse, UNATTRIBUTED_ACTOR, withEscapeHatchAuditScope, } from "../observability/escape-hatch-report.js";
1
+ export { createEscapeHatchReporter, ESCAPE_HATCH_USED_SIGNAL, flushEscapeHatchAudits, UNATTRIBUTED_ACTOR, } from "../observability/escape-hatch-report.js";
2
2
  export { normalizePayloadBucketValue } from "../rate-limit/bucket.js";
3
3
  export { createUnlimitedRateLimitResolver } from "../rate-limit/unlimited-resolver.js";
4
4
  export { appendDomainEventCore } from "./append-event-core.js";
5
5
  export { resolveAuthClaims } from "./auth-claims-resolver.js";
6
6
  export { createCascadeDeleteHook } from "./cascade-handler.js";
7
7
  export { createDispatcher, dispatcherToWriteRef } from "./dispatcher.js";
8
- export { isFailedWriteResult } from "./dispatcher-utils.js";
9
8
  export { createDistributedLock } from "./distributed-lock.js";
10
9
  export { createEntityCache } from "./entity-cache.js";
11
10
  export { ConsumerStatuses, createEventConsumerStateTable, eventConsumerStateTable, SHARED_INSTANCE_SENTINEL, } from "./event-consumer-state.js";
12
11
  export { createEventDedup } from "./event-dedup.js";
13
- export { ConsumerTransitionError, createEventDispatcher, disableConsumer, enableConsumer, getAllConsumerProgress, getConsumerState, listConsumersWithState, restartConsumer, skipPoisonEvent, } from "./event-dispatcher.js";
14
- export { selectConsumerCursorForUpdate } from "./event-dispatcher-delivery.js";
12
+ export { ConsumerTransitionError, disableConsumer, enableConsumer, getAllConsumerProgress, getConsumerState, listConsumersWithState, restartConsumer, skipPoisonEvent, } from "./event-dispatcher.js";
15
13
  export { ConsumerLagError, pruneEvents } from "./event-retention.js";
16
14
  export { createIdempotencyGuard } from "./idempotency.js";
17
- export { assertInstructionFieldWriteAllowed, assertIrreversibleOperationAllowed, isIrreversibleEntityVerb, } from "./irreversible-operation-gate.js";
15
+ export { assertIrreversibleOperationAllowed } from "./irreversible-operation-gate.js";
18
16
  export { createLifecycleHooks } from "./lifecycle-pipeline.js";
19
17
  export { rebuildMultiStreamProjection } from "./msp-rebuild.js";
20
18
  export { createMultiStreamApplyContext } from "./multi-stream-apply-context.js";
21
19
  export { assertNotifyTargetsOwnTenant, createDeferringNotify } from "./notify-scope.js";
22
20
  export { getAllProjectionProgress, getProjectionState, listProjectionsWithState, rebuildProjection, } from "./projection-rebuild.js";
23
- export { createProjectionStateTable, ProjectionStatuses, projectionStateTable, } from "./projection-state.js";
21
+ export { createProjectionStateTable, projectionStateTable, } from "./projection-state.js";
24
22
  export { runProjectionsForEvent } from "./projections-runner.js";
25
- export { ACCESS_INVALIDATION_CONSUMER_NAME, createAccessInvalidationEventConsumer, createSearchEventConsumer, createSseBroadcastEventConsumer, SEARCH_CONSUMER_NAME, SSE_BROADCAST_CONSUMER_NAME, } from "./system-hooks.js";
23
+ export { SEARCH_CONSUMER_NAME, SSE_BROADCAST_CONSUMER_NAME, } from "./system-hooks.js";
26
24
  export { TENANT_TIMEZONE_CONFIG_KEY } from "./tenant-timezone-config-key.js";
@@ -1,4 +1,4 @@
1
- import type { EntityDefinition } from "../engine/types/index.ts";
1
+ import type { EntityDefinition } from "@cosmicdrift/kumiko-types/fields";
2
2
  export declare function isIrreversibleEntityVerb(verb: "delete" | "forget", entity: EntityDefinition): boolean;
3
3
  export declare function assertIrreversibleOperationAllowed(operation: string): void;
4
4
  export declare function assertInstructionFieldWriteAllowed(entityName: string, verb: "create" | "update", writtenFieldNames: readonly string[], instructionFieldNames: readonly string[]): void;
@@ -39,7 +39,7 @@ export function assertIrreversibleOperationAllowed(operation) {
39
39
  reason: FrameworkReasons.irreversibleOperationRequiresHighRisk,
40
40
  buildMessage: (entryHandler) => `Handler "${entryHandler.qn}" performs an irreversible ${operation} but resolves agent risk ` +
41
41
  `"${entryHandler.risk}" — ${highRiskRemedy(entryHandler)}. The ` +
42
- "directly called handler must carry it; delegating via ctx.write/writeAs does not.",
42
+ "directly called handler must carry it; delegating via ctx.dispatch.write/writeAs does not.",
43
43
  details: { operation },
44
44
  });
45
45
  }
@@ -57,7 +57,7 @@ export function assertInstructionFieldWriteAllowed(entityName, verb, writtenFiel
57
57
  buildMessage: (entryHandler) => `Handler "${entryHandler.qn}" ${verb}s "${entityName}" field(s) ${fields.join(", ")} ` +
58
58
  `flagged readAsInstruction: true but resolves agent risk "${entryHandler.risk}" — ` +
59
59
  `${highRiskRemedy(entryHandler)}. The directly called handler must carry ` +
60
- "it; delegating via ctx.write/writeAs does not.",
60
+ "it; delegating via ctx.dispatch.write/writeAs does not.",
61
61
  details: { entityName, verb, fields },
62
62
  });
63
63
  }
@@ -1,4 +1,5 @@
1
- import type { AppContext, DeleteContext, HookPhase, PostDeleteBatchHookFn, PostDeleteHookFn, PostSaveBatchHookFn, PostSaveHookFn, PreDeleteHookFn, PreSaveHookFn, Registry, SaveContext } from "../engine/types/index.ts";
1
+ import type { DeleteContext, HookPhase, PostDeleteBatchHookFn, PostDeleteHookFn, PostSaveBatchHookFn, PostSaveHookFn, PreDeleteHookFn, PreSaveHookFn, SaveContext } from "@cosmicdrift/kumiko-types/hooks";
2
+ import type { HandlerContext, Registry } from "../engine/types/index.ts";
2
3
  import type { EventDedup } from "./event-dedup.ts";
3
4
  export type SystemHookDef<TFn> = {
4
5
  readonly name: string;
@@ -15,12 +16,12 @@ export type SystemHooks = {
15
16
  readonly postDeleteBatch?: readonly SystemHookDef<PostDeleteBatchHookFn>[];
16
17
  };
17
18
  export type LifecycleHooks = {
18
- runPreSave(handlerName: string, changes: Record<string, unknown>, previous: Readonly<Record<string, unknown>>, isNew: boolean, context: AppContext): Promise<Record<string, unknown>>;
19
- runPostSave(handlerName: string, result: SaveContext, context: AppContext, phase?: HookPhase): Promise<void>;
20
- runPreDelete(handlerName: string, payload: DeleteContext, context: AppContext): Promise<void>;
21
- runPostDelete(handlerName: string, payload: DeleteContext, context: AppContext, phase?: HookPhase): Promise<void>;
22
- runPostSaveBatch(results: readonly SaveContext[], context: AppContext): Promise<void>;
23
- runPostDeleteBatch(payloads: readonly DeleteContext[], context: AppContext): Promise<void>;
19
+ runPreSave(handlerName: string, changes: Record<string, unknown>, previous: Readonly<Record<string, unknown>>, isNew: boolean, context: HandlerContext): Promise<Record<string, unknown>>;
20
+ runPostSave(handlerName: string, result: SaveContext, context: HandlerContext, phase?: HookPhase): Promise<void>;
21
+ runPreDelete(handlerName: string, payload: DeleteContext, context: HandlerContext): Promise<void>;
22
+ runPostDelete(handlerName: string, payload: DeleteContext, context: HandlerContext, phase?: HookPhase): Promise<void>;
23
+ runPostSaveBatch(results: readonly SaveContext[], context: HandlerContext): Promise<void>;
24
+ runPostDeleteBatch(payloads: readonly DeleteContext[], context: HandlerContext): Promise<void>;
24
25
  };
25
26
  export type LifecycleOptions = {
26
27
  eventDedup?: EventDedup;
@@ -1,16 +1,12 @@
1
- import { HookPhases } from "../engine/types/index.js";
1
+ import { HookPhases } from "../engine/hook-helpers.js";
2
2
  import { createFallbackLogger } from "../logging/utils.js";
3
- import { getFallbackTracer } from "../observability/index.js";
4
3
  function resolveTracer(context) {
5
- return context.tracer ?? getFallbackTracer();
4
+ return context.obs.tracer;
6
5
  }
7
6
  /**
8
7
  * Resolves the effective feature set for the active context's tenant.
9
8
  *
10
- * `_tenantId` is copied from `user.tenantId` when the dispatcher builds the
11
- * HandlerContext. Legacy call sites without a user (system jobs, boot-time
12
- * pipeline) leave it undefined; `effectiveFeatures(undefined)` is type-unsafe,
13
- * so this returns undefined and treats that as "all features on" (registry
9
+ * Without a wired resolver this returns undefined, which means "all features on" (registry
14
10
  * filter hooks accept undefined to skip filtering).
15
11
  *
16
12
  * This is the single path used by all four lifecycle-hook call sites
@@ -18,9 +14,7 @@ function resolveTracer(context) {
18
14
  * consistent.
19
15
  */
20
16
  function currentEffectiveFeatures(context) {
21
- if (context._tenantId === undefined)
22
- return undefined;
23
- return context.effectiveFeatures?.(context._tenantId);
17
+ return context.services.effectiveFeatures?.(context.user.tenantId);
24
18
  }
25
19
  export function createLifecycleHooks(registry, systemHooks = {}, options = {}) {
26
20
  const { eventDedup } = options;
@@ -46,14 +40,14 @@ export function createLifecycleHooks(registry, systemHooks = {}, options = {}) {
46
40
  // best-effort side-effects like Search Index, SSE broadcast, Audit — a
47
41
  // missed hook is preferable to a duplicate notification. Features that
48
42
  // need at-least-once semantics must not rely on this path; use
49
- // ctx.appendEvent + r.multiStreamProjection instead, which the
43
+ // ctx.events.append + r.multiStreamProjection instead, which the
50
44
  // event-dispatcher retries until the consumer advances.
51
45
  if (eventDedup && opts.hookPhase === HookPhases.afterCommit) {
52
46
  const eventId = buildEventId(opts.handlerName, opts.payload, opts.phaseLabel);
53
47
  if (eventId) {
54
48
  const acquired = await eventDedup.tryAcquire(eventId);
55
49
  if (!acquired) {
56
- opts.context.log?.debug(`${opts.phaseLabel}: skipping ${opts.handlerName} — event ${eventId} already processed (dedup)`);
50
+ opts.context.obs.log.debug(`${opts.phaseLabel}: skipping ${opts.handlerName} — event ${eventId} already processed (dedup)`);
57
51
  return;
58
52
  }
59
53
  }
@@ -62,7 +56,7 @@ export function createLifecycleHooks(registry, systemHooks = {}, options = {}) {
62
56
  // always returns one. Log so we can spot framework/feature bugs where
63
57
  // a handler emits a non-standard LifecycleResult and accidentally
64
58
  // bypasses dedup.
65
- opts.context.log?.warn(`${opts.phaseLabel}: ${opts.handlerName} has no dedup id (payload missing \`id\`) — hook may run multiple times on retry`);
59
+ opts.context.obs.log.warn(`${opts.phaseLabel}: ${opts.handlerName} has no dedup id (payload missing \`id\`) — hook may run multiple times on retry`);
66
60
  }
67
61
  }
68
62
  const errors = [];
@@ -128,7 +122,7 @@ export function createLifecycleHooks(registry, systemHooks = {}, options = {}) {
128
122
  await runHooks(applicable, (h) => ({ "kumiko.hook_source": "system", "kumiko.hook_name": h.name }), (h) => h.name, (h) => h.fn(opts.payload, opts.context));
129
123
  }
130
124
  if (errors.length > 0) {
131
- const logError = createFallbackLogger("lifecycle", opts.context.log);
125
+ const logError = createFallbackLogger("lifecycle", opts.context.obs.log);
132
126
  const msg = `${opts.phaseLabel} errors for ${opts.handlerName}`;
133
127
  logError.error(msg, { details: errors.map((e) => `${e.name}: ${e.error}`) });
134
128
  }
@@ -235,7 +229,7 @@ export function createLifecycleHooks(registry, systemHooks = {}, options = {}) {
235
229
  // skip: all batch hooks succeeded, nothing to log
236
230
  if (failures.length === 0)
237
231
  return;
238
- const logError = createFallbackLogger("lifecycle", opts.context.log);
232
+ const logError = createFallbackLogger("lifecycle", opts.context.obs.log);
239
233
  const msg = `${opts.phaseLabel} errors`;
240
234
  logError.error(msg, { details: failures.map((f) => `${f.name}: ${f.outcome.reason}`) });
241
235
  }
@@ -1,6 +1,9 @@
1
1
  import { extractPgError } from "../db/pg-error.js";
2
2
  import { asRawClient, runInSavepoint, transaction } from "../db/query.js";
3
- import { AccessDeniedError, InternalError, MemberReadTimeoutError, memberResolutionReadOnlyDenied, } from "../errors/index.js";
3
+ import { activeRowLevelSecurityScope, runInCapturedRowLevelSecurityScope, runInSystemRowLevelSecurityScope, } from "../db/row-level-security-scope.js";
4
+ import { MemberReadTimeoutError } from "../errors/classes.js";
5
+ import { AccessDeniedError, InternalError } from "../errors/index.js";
6
+ import { memberResolutionReadOnlyDenied } from "../errors/member-resolution.js";
4
7
  import { resolveDbSource } from "./dispatch-shared.js";
5
8
  const PG_READ_ONLY_SQLSTATE = "25006";
6
9
  const PG_QUERY_CANCELED_SQLSTATE = "57014";
@@ -51,7 +54,12 @@ async function runInDiscardedReadOnlySavepoint(tx, timeoutMs, bindIdleTimeout, f
51
54
  }
52
55
  return settled.outcome.value;
53
56
  }
54
- export async function runInMemberReadOnlyTransaction(ctx, tx, fn) {
57
+ export function runInMemberReadOnlyTransaction(ctx, tx, fn) {
58
+ // Only the transaction plumbing (savepoint, SET) runs system-scoped; the caller's fn keeps the dispatch scope it came in with.
59
+ const incoming = activeRowLevelSecurityScope();
60
+ return runInSystemRowLevelSecurityScope("member read-only transaction opens its connection under system scope, then restores the caller scope", () => runInMemberReadOnlyTransactionScoped(ctx, tx, (readOnlyTx) => runInCapturedRowLevelSecurityScope(incoming, () => fn(readOnlyTx))));
61
+ }
62
+ async function runInMemberReadOnlyTransactionScoped(ctx, tx, fn) {
55
63
  const timeoutMs = ctx.memberReadTimeoutMs;
56
64
  try {
57
65
  if (tx)
@@ -59,7 +67,7 @@ export async function runInMemberReadOnlyTransaction(ctx, tx, fn) {
59
67
  const pool = resolveDbSource(ctx, undefined);
60
68
  if (!pool) {
61
69
  throw new InternalError({
62
- message: "ctx.queryAsMember requires a database connection — none is configured.",
70
+ message: "ctx.dispatch.queryAsMember requires a database connection — none is configured.",
63
71
  });
64
72
  }
65
73
  // Savepoint even on the pool path: Postgres rejects a READ WRITE reset (SQLSTATE 25001) inside a subtransaction.
@@ -1,6 +1,6 @@
1
+ import type { MemberReader } from "@cosmicdrift/kumiko-types/handlers";
1
2
  import type { DbTx } from "../db/connection.ts";
2
3
  import type { TenantId } from "../engine/types/identifiers.ts";
3
- import type { MemberReader } from "../engine/types/index.ts";
4
4
  import { type ActiveMembershipPolicy } from "./active-membership.ts";
5
5
  import { type DispatchContext } from "./dispatch-shared.ts";
6
6
  export declare const BACKGROUND_READ_POLICY: ActiveMembershipPolicy;
@@ -1,4 +1,4 @@
1
- // ctx.queryAsMember — reads a query handler as a stored tenant member. The
1
+ // ctx.dispatch.queryAsMember — reads a query handler as a stored tenant member. The
2
2
  // resolved SessionUser never leaves this module.
3
3
  import { buildSessionRoles } from "../engine/membership-roles.js";
4
4
  import { SYSTEM_TENANT_ID } from "../engine/types/index.js";
@@ -32,7 +32,7 @@ async function resolveMember(ctx, tenantId, userId) {
32
32
  const dbSource = resolveDbSource(ctx, undefined);
33
33
  if (!dbSource) {
34
34
  throw new InternalError({
35
- message: "ctx.queryAsMember requires a database connection — none is configured.",
35
+ message: "ctx.dispatch.queryAsMember requires a database connection — none is configured.",
36
36
  });
37
37
  }
38
38
  // resolveDbSource(ctx, undefined) never returns a tx, only AppContext.db.
@@ -1,6 +1,8 @@
1
1
  import { markConsumerRebuildFailed, resetConsumerForMspRebuild, selectConsumerForUpdate, selectEventIdHorizonWithMissingRanges, selectSnapshotXmax, updateConsumerRebuildCursor, } from "../db/queries/event-consumer.js";
2
- import { assertLiveColumnsMatchMeta, assertLiveTableHasNoRowLevelSecurity, buildShadowTable, ensureRebuildSchema, rebuildMetaOrThrow, swapShadowIntoLive, } from "../db/queries/shadow-swap.js";
2
+ import { assertRebuildableRowLevelSecurity } from "../db/queries/rebuild-rls-guard.js";
3
+ import { assertLiveColumnsMatchMeta, buildShadowTable, ensureRebuildSchema, rebuildMetaOrThrow, swapShadowIntoLive, } from "../db/queries/shadow-swap.js";
3
4
  import { runInSavepoint, selectMany } from "../db/query.js";
5
+ import { runInSystemRowLevelSecurityScope } from "../db/row-level-security-scope.js";
4
6
  import { withoutStatementTimeout } from "../db/statement-timeout.js";
5
7
  import { withExecutorManagedWrites } from "../db/tenant-db.js";
6
8
  import { InternalError } from "../errors/index.js";
@@ -31,7 +33,7 @@ function createRebuildCtx(registry, db, tenantId) {
31
33
  };
32
34
  }
33
35
  export function rebuildMultiStreamProjection(mspName, deps) {
34
- return withoutStatementTimeout(deps.db, (db) => replayMultiStreamProjectionIntoShadow(mspName, { ...deps, db }));
36
+ return withoutStatementTimeout(deps.db, (db) => runInSystemRowLevelSecurityScope("multi-stream projection rebuild replays events of all tenants", () => replayMultiStreamProjectionIntoShadow(mspName, { ...deps, db })));
35
37
  }
36
38
  async function replayMultiStreamProjectionIntoShadow(mspName, deps) {
37
39
  const { db, registry } = deps;
@@ -62,11 +64,11 @@ async function replayMultiStreamProjectionIntoShadow(mspName, deps) {
62
64
  await createRebuildDeadLetterTable(db);
63
65
  const replayedIds = [];
64
66
  await db.begin(async (tx) => {
67
+ await assertRebuildableRowLevelSecurity(tx, meta.tableName);
65
68
  await resetConsumerForMspRebuild(tx, mspName, SHARED_INSTANCE_SENTINEL);
66
69
  await selectConsumerForUpdate(tx, mspName, SHARED_INSTANCE_SENTINEL);
67
70
  const { horizon, gaps: seededGaps } = await selectEventIdHorizonWithMissingRanges(tx);
68
71
  await assertLiveColumnsMatchMeta(tx, meta, mspName);
69
- await assertLiveTableHasNoRowLevelSecurity(tx, meta.tableName, mspName);
70
72
  await buildShadowTable(tx, meta);
71
73
  const subscribedTypes = Object.keys(msp.apply);
72
74
  if (subscribedTypes.length > 0) {
@@ -1,6 +1,7 @@
1
1
  import { loadAggregate, loadAggregateAsOf } from "../event-store/event-store.js";
2
2
  import { upcastStoredEvents } from "../event-store/upcaster.js";
3
3
  import { appendDomainEventCore } from "./append-event-core.js";
4
+ import { asTypedAppendEventFn } from "./typed-append-event.js";
4
5
  export function createMultiStreamApplyContext(deps) {
5
6
  return {
6
7
  registry: deps.registry,
@@ -8,7 +9,7 @@ export function createMultiStreamApplyContext(deps) {
8
9
  ...(deps.derivatives ? { derivatives: deps.derivatives } : {}),
9
10
  ...(deps.secrets ? { secrets: deps.secrets } : {}),
10
11
  ...(deps.jobs ? { jobs: deps.jobs } : {}),
11
- appendEvent: (async (args) => {
12
+ appendEvent: asTypedAppendEventFn(async (args) => {
12
13
  await appendDomainEventCore({
13
14
  registry: deps.registry,
14
15
  db: deps.db,
@@ -17,7 +18,7 @@ export function createMultiStreamApplyContext(deps) {
17
18
  callSiteLabel: "MSP-apply ctx.appendEvent",
18
19
  ...(deps.callerFeature && { callerFeature: deps.callerFeature }),
19
20
  }, args);
20
- }), // @cast-boundary engine-bridge
21
+ }),
21
22
  unsafeAppendEvent: async (args) => {
22
23
  await appendDomainEventCore({
23
24
  registry: deps.registry,
@@ -1,5 +1,6 @@
1
+ import type { NotifyFn, NotifyOptions } from "@cosmicdrift/kumiko-types/handlers";
1
2
  import type { TenantId } from "../engine/types/identifiers.ts";
2
- import type { NotifyFn, NotifyOptions, Registry } from "../engine/types/index.ts";
3
+ import type { Registry } from "../engine/types/index.ts";
3
4
  import type { AfterCommitHook } from "./dispatcher-utils.ts";
4
5
  export declare function assertNotifyTargetsOwnTenant(options: NotifyOptions, tenantId: TenantId): void;
5
6
  type DeferringNotifyDeps = {
@@ -1,4 +1,5 @@
1
- import type { SessionUser, WriteHandlerDef } from "../engine/types/index.ts";
1
+ import type { WriteHandlerDef } from "@cosmicdrift/kumiko-types/handlers";
2
+ import type { SessionUser } from "../engine/types/index.ts";
2
3
  import { type WriteFailure } from "../errors/index.ts";
3
4
  import type { DispatchContext } from "./dispatch-shared.ts";
4
5
  export type PreHandlerGateMode = "charge" | "recheck";
@@ -1,6 +1,6 @@
1
- import type { ReservationHandle } from "@cosmicdrift/kumiko-types/handlers";
2
- import type { SessionUser, WriteHandlerDef } from "../engine/types/index.ts";
3
- import { type WriteErrorInfo } from "../errors/index.ts";
1
+ import type { ReservationHandle, WriteHandlerDef } from "@cosmicdrift/kumiko-types/handlers";
2
+ import type { SessionUser } from "../engine/types/index.ts";
3
+ import type { WriteErrorInfo } from "../errors/index.ts";
4
4
  import type { BatchCommand, DispatchContext } from "./dispatch-shared.ts";
5
5
  import type { WriteOrigin } from "./write-origin.ts";
6
6
  type ReservationConfirm = ReservationHandle["confirmInTransaction"];
@@ -1,7 +1,7 @@
1
1
  import { AsyncLocalStorage } from "node:async_hooks";
2
- import { toWriteErrorInfo } from "../errors/index.js";
2
+ import { toWriteErrorInfo } from "../errors/write-error-info.js";
3
3
  import { createFallbackLogger } from "../logging/utils.js";
4
- import { applyBeforeTransactionReadOnly, buildHandlerContext, denyTransactionBoundSurfaces, isMemberResolutionPrincipal, } from "./dispatch-shared.js";
4
+ import { buildHandlerContext, isMemberResolutionPrincipal } from "./dispatch-shared.js";
5
5
  import { wrapToKumiko } from "./dispatcher-utils.js";
6
6
  import { runPreHandlerGates } from "./pre-handler-gates.js";
7
7
  import { effectiveWriteOrigin, rootWriteOrigin } from "./write-origin.js";
@@ -9,7 +9,7 @@ export function hasPreTransactionPhase(handler) {
9
9
  return handler.reserveBeforeTransaction !== undefined || handler.beforeTransaction !== undefined;
10
10
  }
11
11
  // One-shot permission per top-level command: the handler that reserved before the transaction
12
- // consumes it on entry. A capped handler reached any other way (nested ctx.write, writeAs, a
12
+ // consumes it on entry. A capped handler reached any other way (nested ctx.dispatch.write, writeAs, a
13
13
  // second execution of the same type) finds it spent and is rejected instead of running unreserved.
14
14
  const reservedForCommand = new AsyncLocalStorage();
15
15
  export function runAsCommand(reserved, fn) {
@@ -65,8 +65,10 @@ export async function reserveBeforeTransaction(ctx, commands, user, inheritedOri
65
65
  const event = { type: command.type, payload: gates.payload, user };
66
66
  let confirmInTransaction;
67
67
  if (handler.reserveBeforeTransaction) {
68
- const handlerContext = await buildHandlerContext(ctx, command.type, user, origin);
69
- const handle = toReservationHandle(await handler.reserveBeforeTransaction(event, denyTransactionBoundSurfaces(handlerContext)));
68
+ const reservationContext = await buildHandlerContext(ctx, command.type, user, origin, {
69
+ phase: "reservation",
70
+ });
71
+ const handle = toReservationHandle(await handler.reserveBeforeTransaction(event, reservationContext));
70
72
  if (handle)
71
73
  releases.push(handle.release);
72
74
  confirmInTransaction = handle?.confirmInTransaction;
@@ -74,9 +76,9 @@ export async function reserveBeforeTransaction(ctx, commands, user, inheritedOri
74
76
  let prepared;
75
77
  if (handler.beforeTransaction) {
76
78
  const phaseContext = await buildHandlerContext(ctx, command.type, user, origin, {
77
- readOnlyForTenant: true,
79
+ phase: "beforeTransaction",
78
80
  });
79
- const phase = await handler.beforeTransaction(event, applyBeforeTransactionReadOnly(phaseContext));
81
+ const phase = await handler.beforeTransaction(event, phaseContext);
80
82
  if (!phase.isSuccess) {
81
83
  await releaseAll(ctx, releases);
82
84
  return { isSuccess: false, error: phase.error, failedIndex: index };
@@ -1,6 +1,8 @@
1
1
  import { countSubscribedEvents, finalizeProjectionRebuild, markProjectionRebuildFailed, markProjectionRebuilding, selectEventsForProjectionRebuildBatch, } from "../db/queries/projection-rebuild.js";
2
- import { assertLiveColumnsMatchMeta, assertLiveTableHasNoRowLevelSecurity, assertNoBlindIndexLoss, assertNoUnreachableLiveRows, buildShadowTable, countColumnDrift, ensureRebuildSchema, fenceLiveTable, rebuildMetaOrThrow, swapShadowIntoLive, } from "../db/queries/shadow-swap.js";
2
+ import { assertRebuildableRowLevelSecurity } from "../db/queries/rebuild-rls-guard.js";
3
+ import { assertLiveColumnsMatchMeta, assertNoBlindIndexLoss, assertNoUnreachableLiveRows, buildShadowTable, countColumnDrift, ensureRebuildSchema, fenceLiveTable, rebuildMetaOrThrow, swapShadowIntoLive, } from "../db/queries/shadow-swap.js";
3
4
  import { coerceRow, runInSavepoint, selectMany } from "../db/query.js";
5
+ import { runInSystemRowLevelSecurityScope } from "../db/row-level-security-scope.js";
4
6
  import { withoutStatementTimeout } from "../db/statement-timeout.js";
5
7
  import { extractTableInfo } from "../db/table-info.js";
6
8
  import { withExecutorManagedWrites } from "../db/tenant-db.js";
@@ -35,6 +37,7 @@ function rowToStoredEvent(row) {
35
37
  createdBy: row.createdBy,
36
38
  };
37
39
  }
40
+ const TENANT_COLUMN_SUFFIX = ".tenant_id";
38
41
  // Ops-facing log line for countColumnDrift's result. No-op when clean.
39
42
  function warnOnColumnDrift(projectionName, tableName, drift) {
40
43
  // skip: no drift found — nothing to warn about
@@ -44,13 +47,17 @@ function warnOnColumnDrift(projectionName, tableName, drift) {
44
47
  const countLabel = sampledIds.size < drift.rowCount
45
48
  ? `${drift.rowCount} (sample truncated)`
46
49
  : String(drift.rowCount);
50
+ // A stream-tenant move (boot backfill) changes the stream's tenant, so the replayed row differs only in tenant_id.
51
+ const onlyTenantColumn = drift.sample.every((s) => s.endsWith(TENANT_COLUMN_SUFFIX));
52
+ const likelyCause = onlyTenantColumn
53
+ ? "Expected cause: a stream-tenant move by the boot backfill (the replay carries the new stream tenant)."
54
+ : "Likely cause: a legacy direct-write predating the row's event history (#494), or a sensitive custom field pending #972. Investigate if unexpected.";
47
55
  log.warn(`projection "${projectionName}": ${countLabel} live row(s) in "${tableName}" have ` +
48
56
  `column values that differ from the freshly-replayed shadow (sample: ${drift.sample.join(", ")}). ` +
49
- "Not blocking — replay wins on swap. Likely cause: a legacy direct-write predating the row's " +
50
- "event history (#494), or a sensitive custom field pending #972. Investigate if unexpected.");
57
+ `Not blocking — replay wins on swap. ${likelyCause}`);
51
58
  }
52
59
  export function rebuildProjection(projectionName, deps) {
53
- return withoutStatementTimeout(deps.db, (db) => replayProjectionIntoShadow(projectionName, { ...deps, db }));
60
+ return withoutStatementTimeout(deps.db, (db) => runInSystemRowLevelSecurityScope("projection rebuild scans events of all tenants", () => replayProjectionIntoShadow(projectionName, { ...deps, db })));
54
61
  }
55
62
  async function replayProjectionIntoShadow(projectionName, deps) {
56
63
  const { db, registry } = deps;
@@ -124,9 +131,9 @@ async function replayProjectionIntoShadow(projectionName, deps) {
124
131
  if (skipApplyErrors)
125
132
  await createRebuildDeadLetterTable(db);
126
133
  await db.begin(async (tx) => {
134
+ await assertRebuildableRowLevelSecurity(tx, meta.tableName);
127
135
  await markProjectionRebuilding(tx, projectionName);
128
136
  await assertLiveColumnsMatchMeta(tx, meta, projectionName);
129
- await assertLiveTableHasNoRowLevelSecurity(tx, meta.tableName, projectionName);
130
137
  await buildShadowTable(tx, meta);
131
138
  deps.__test_onBuildShadowTable?.();
132
139
  // A projection that subscribes to nothing has no events to replay and no
@@ -1,9 +1,3 @@
1
1
  import type { DbConnection } from "../db/connection.ts";
2
2
  export declare const projectionStateTable: import("@cosmicdrift/kumiko-types/executor-brand").WritableSchemaTable;
3
- export declare const ProjectionStatuses: {
4
- readonly idle: "idle";
5
- readonly rebuilding: "rebuilding";
6
- readonly failed: "failed";
7
- };
8
- export type ProjectionStatus = (typeof ProjectionStatuses)[keyof typeof ProjectionStatuses];
9
3
  export declare function createProjectionStateTable(db: DbConnection): Promise<void>;
@@ -34,11 +34,6 @@ export const projectionStateTable = pgTable("kumiko_projections", {
34
34
  }, (t) => ({
35
35
  statusIdx: index("kumiko_projections_status_idx").on(t.status),
36
36
  }));
37
- export const ProjectionStatuses = {
38
- idle: "idle",
39
- rebuilding: "rebuilding",
40
- failed: "failed",
41
- };
42
37
  // Idempotent table bootstrap. Called by setupTestStack (and createApp once
43
38
  // that wires it up) — same pattern as createEventsTable. If the table is
44
39
  // already there (second stack in same test DB, production boot after
@@ -1,5 +1,6 @@
1
+ import type { LifecycleResult } from "@cosmicdrift/kumiko-types/hooks";
1
2
  import type { DbRunner } from "../db/index.ts";
2
- import type { LifecycleResult, Registry } from "../engine/types/index.ts";
3
+ import type { Registry } from "../engine/types/index.ts";
3
4
  import type { StoredEvent } from "../event-store/index.ts";
4
5
  export declare function runProjections(result: LifecycleResult, registry: Registry, runner: DbRunner | undefined): Promise<void>;
5
6
  export declare function hasLiveProjectionsForEvent(event: StoredEvent, registry: Registry): boolean;
@@ -1,5 +1,6 @@
1
1
  import { withExecutorManagedWrites } from "../db/tenant-db.js";
2
2
  import { InternalError } from "../errors/index.js";
3
+ import { inEventStreamScope } from "../event-store/stream-scope.js";
3
4
  // Run custom projections for a save or delete result. Lives INSIDE the
4
5
  // transaction that appended the event — a throw from apply() rolls the event
5
6
  // back along with any auto-projection write.
@@ -33,7 +34,7 @@ export async function runProjections(result, registry, runner) {
33
34
  }
34
35
  // Fire every projection whose source matches the event's aggregate type AND
35
36
  // that declares an apply-handler for the event's type. Used by both the
36
- // CRUD path (via runProjections) and the ctx.appendEvent path (domain events
37
+ // CRUD path (via runProjections) and the ctx.events.append path (domain events
37
38
  // emitted inside a write handler). Keeping one function means an auto-event
38
39
  // and a r.defineEvent-event land in the same inline-projection pipeline.
39
40
  // Events whose projections already ran. The EventStoreExecutor projects right
@@ -57,10 +58,13 @@ export async function runProjectionsForEvent(event, registry, tx) {
57
58
  // skip: this event object was already projected in this write
58
59
  if (projectedEvents.has(event))
59
60
  return;
60
- for (const proj of liveProjectionsForEvent(event, registry)) {
61
- const applyFn = proj.apply[event.type];
62
- if (applyFn)
63
- await applyFn(event, withExecutorManagedWrites(tx), proj.table);
64
- }
61
+ // Inline projections write the event's own tenant, which differs from the caller's scope for system-actor events.
62
+ await inEventStreamScope(event.tenantId, async () => {
63
+ for (const proj of liveProjectionsForEvent(event, registry)) {
64
+ const applyFn = proj.apply[event.type];
65
+ if (applyFn)
66
+ await applyFn(event, withExecutorManagedWrites(tx), proj.table);
67
+ }
68
+ });
65
69
  projectedEvents.add(event);
66
70
  }
@@ -1,5 +1,7 @@
1
+ import type { JobRunnerRef } from "@cosmicdrift/kumiko-types/handlers";
2
+ import type { EntityId } from "@cosmicdrift/kumiko-types/identifiers";
1
3
  import { type SseBroker } from "../api/sse-broker.ts";
2
- import type { EntityId, JobRunnerRef, Registry, TenantId } from "../engine/types/index.ts";
4
+ import type { Registry, TenantId } from "../engine/types/index.ts";
3
5
  import type { SearchAdapter, SearchDocument } from "../search/types.ts";
4
6
  import type { EventConsumer } from "./event-dispatcher.ts";
5
7
  export declare const SEARCH_CONSUMER_NAME = "system:consumer:search";
@@ -1,7 +1,9 @@
1
1
  import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
2
2
  import { readNonEmptyStringArray, } from "../api/sse-broker.js";
3
- import { collectSearchableSubjectFields, configuredPiiSubjectKms, decryptPiiFieldValues, isPiiCiphertext, PII_ERASED_SENTINEL, } from "../crypto/index.js";
4
- import { createTenantDb, entityTableFromRegistry, rehydrateCompoundTypes } from "../db/index.js";
3
+ import { configuredPiiSubjectKms, decryptPiiFieldValues, isPiiCiphertext, PII_ERASED_SENTINEL, } from "../crypto/index.js";
4
+ import { collectSearchableSubjectFields } from "../crypto/subject-resolver.js";
5
+ import { rehydrateCompoundTypes } from "../db/compound-types.js";
6
+ import { createTenantDb, entityTableFromRegistry } from "../db/index.js";
5
7
  import { tenantChannel } from "../engine/constants.js";
6
8
  import { InternalError } from "../errors/index.js";
7
9
  import { createFallbackLogger } from "../logging/utils.js";
@@ -422,7 +424,7 @@ export function createSseBroadcastEventConsumer(sseBroker) {
422
424
  // r.job's `trigger.on` historically only fired via the synchronous
423
425
  // write-handler dispatch path (dispatch-write.ts's afterCommitHooks calling
424
426
  // jobRunner.handleEvent). Events appended any other way — an
425
- // r.multiStreamProjection's ctx.unsafeAppendEvent, or a raw
427
+ // r.multiStreamProjection's ctx.events.unsafeAppend, or a raw
426
428
  // event-store-executor write (e.g. `files`' fileRef.created) — never
427
429
  // reached it, so a job could never trigger on an r.defineEvent-registered
428
430
  // event.
@@ -431,7 +433,7 @@ export function createSseBroadcastEventConsumer(sseBroker) {
431
433
  // committed event off the shared cursor and re-check job triggers. It is
432
434
  // scoped EXACTLY to the gap — the write/query-handler-QN skip below is
433
435
  // defense-in-depth: no stored event's `type` is a handler QN today (entity
434
- // events are "entity.verb"; ctx.appendEvent enforces defineEvent-only
436
+ // events are "entity.verb"; ctx.events.append enforces defineEvent-only
435
437
  // ownership), but if that ever changes, this consumer must not re-fire a
436
438
  // trigger the synchronous dispatch-write.ts path already handled.
437
439
  //
@@ -1,10 +1,12 @@
1
+ import type { ActiveMembershipResult, EscapeHatchDeclaration, EscapeHatchReporter, MemberReader, WriteResult } from "@cosmicdrift/kumiko-types/handlers";
2
+ import type { LifecycleHookFn } from "@cosmicdrift/kumiko-types/hooks";
1
3
  import type { TenantId } from "../engine/types/identifiers.ts";
2
- import type { ActiveMembershipResult, EscapeHatchDeclaration, EscapeHatchReporter, HandlerContext, LifecycleHookFn, MemberReader, SessionUser, WriteResult } from "../engine/types/index.ts";
4
+ import type { HandlerContext, SessionUser } from "../engine/types/index.ts";
3
5
  import { AccessDeniedError } from "../errors/index.ts";
4
6
  export type QueryAsFn = (user: SessionUser, qn: string, payload: unknown) => Promise<unknown>;
5
7
  export type WriteAsFn = (user: SessionUser, qn: string, payload: unknown) => Promise<WriteResult>;
6
8
  export type ResolveActiveMembershipFn = (userId: string, tenantId: TenantId) => Promise<ActiveMembershipResult>;
7
- export type ProjectionReader = HandlerContext["queryProjection"];
9
+ export type ProjectionReader = HandlerContext["dispatch"]["queryProjection"];
8
10
  export type IdentitySwitch = {
9
11
  readonly queryAs: QueryAsFn;
10
12
  readonly writeAs: WriteAsFn;