@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,23 +1,32 @@
1
- import { requestContext, runWithOrigin } from "../api/request-context.js";
1
+ import { resolveAgentExposure } from "@cosmicdrift/kumiko-types/agent-exposure";
2
+ import { declaredRateLimitOptions, isRateLimitDisabled } from "@cosmicdrift/kumiko-types/handlers";
3
+ import { requestContext } from "../api/request-context.js";
4
+ import { runWithOrigin } from "../api/request-context-scopes.js";
5
+ import { runInSystemRowLevelSecurityScope } from "../db/row-level-security-scope.js";
2
6
  import { createTenantDb } from "../db/tenant-db.js";
3
- import { declaredRateLimitOptions, isRateLimitDisabled, resolveAgentExposure, } from "../engine/types/index.js";
4
- import { FeatureDisabledError, InternalError, memberResolutionReadOnlyDenied, RateLimitError, RateLimitUnavailableError, } from "../errors/index.js";
7
+ import { RateLimitUnavailableError } from "../errors/classes.js";
8
+ import { FeatureDisabledError, InternalError, RateLimitError, } from "../errors/index.js";
5
9
  import { createFallbackLogger } from "../logging/utils.js";
6
- import { createEscapeHatchReporter, emitDispatcherError, emitDispatcherHandler, observabilityContext, } from "../observability/index.js";
10
+ import { observabilityContext } from "../observability/context.js";
11
+ import { createEscapeHatchReporter } from "../observability/escape-hatch-report.js";
12
+ import { emitDispatcherError, emitDispatcherHandler } from "../observability/standard-metrics.js";
7
13
  import { buildBucketKey, buildPayloadBucketKey, normalizePayloadBucketValue, } from "../rate-limit/index.js";
8
14
  import { isPlainObject } from "../utils/is-plain-object.js";
9
15
  import { resolveAuthClaims as runAuthClaimsResolver } from "./auth-claims-resolver.js";
10
16
  import { configAccessorFactoryOf } from "./config-accessor-factory.js";
17
+ import { buildContextServices } from "./context-services.js";
11
18
  import { executeQuery } from "./dispatch-query.js";
12
19
  import { dispatcherSpanAttributes, isFailedWriteResult, } from "./dispatcher-utils.js";
13
20
  import { buildAuthFacet } from "./handler-context-auth.js";
14
21
  import { buildConfigFacet, resolveHandlerLocale, resolveHandlerTz, } from "./handler-context-config.js";
15
- import { buildFileFragment, buildForTenantFragment, buildHandlerDbFacet, } from "./handler-context-db.js";
22
+ import { buildFileFragment, buildHandlerDbFacet, buildWriteTarget } from "./handler-context-db.js";
16
23
  import { buildDispatchFacet, createCommitSinks } from "./handler-context-dispatch.js";
17
24
  import { buildEventStoreFacet } from "./handler-context-events.js";
25
+ import { applyMemberResolutionReadOnly } from "./handler-context-member-resolution.js";
18
26
  import { buildNotifyFacet } from "./handler-context-notify.js";
19
27
  import { buildObservabilityFacet } from "./handler-context-observability.js";
20
- import { buildPreSaveFragment, buildRuntimeFragment, resolveHandlerContextScope, } from "./handler-context-scope.js";
28
+ import { applyBeforeTransactionReadOnly, denyEventStoreSurfaces, denyTransactionBoundSurfaces, withoutTransactionDenied, } from "./handler-context-phase-denials.js";
29
+ import { buildLifecycleSignal, buildPreSave, buildRuntimeServices, resolveHandlerContextScope, } from "./handler-context-scope.js";
21
30
  import { createGatedIdentitySwitch, isSystemIdentity } from "./system-identity-switch.js";
22
31
  import { TENANT_TIMEZONE_CONFIG_KEY } from "./tenant-timezone-config-key.js";
23
32
  import { rootWriteOrigin } from "./write-origin.js";
@@ -42,14 +51,17 @@ export function resolveAppPoolDb(ctx) {
42
51
  // r.systemScope() handlers must go through ctx.systemDb's guarded methods
43
52
  // (assertTenantMatch / acknowledgeCrossTenant) instead of plain ctx.db —
44
53
  // "system" mode has no tenant filter at all, so silent ctx.db or
45
- // ctx.dbOutsideTransaction use there is a cross-tenant leak. HandlerContext
54
+ // ctx.db.outsideTransaction use there is a cross-tenant leak. HandlerContext
46
55
  // has no way to make either field optional per handler (isSystem is a
47
56
  // runtime-only registry lookup, not a type-level discriminant), so instead
48
57
  // of omitting the key we hand back a Proxy that throws on first touch,
49
58
  // naming the handler and pointing at the matching ctx.systemDb escape hatch.
59
+ // Only the db guard answers `outsideTransaction` (the inner guard, set by attachOutsideTransaction).
50
60
  export function createSystemScopedDbGuard(handlerType, fieldName, hint) {
51
61
  return new Proxy({}, {
52
- get(_target, prop) {
62
+ get(target, prop) {
63
+ if (fieldName === "db" && prop === "outsideTransaction")
64
+ return Reflect.get(target, prop);
53
65
  throw new InternalError({
54
66
  message: `Handler "${handlerType}" is r.systemScope()'d — ctx.${fieldName} is unavailable ` +
55
67
  `(it would be unfiltered across every tenant). Use ${hint} ` +
@@ -61,223 +73,85 @@ export function createSystemScopedDbGuard(handlerType, fieldName, hint) {
61
73
  export function isMemberResolutionPrincipal(user) {
62
74
  return user.origin === "member-resolution";
63
75
  }
64
- async function denyMemberResolutionWrite() {
65
- throw memberResolutionReadOnlyDenied();
66
- }
67
- // JobRunnerRef's declared type only carries handleEvent, but callers
68
- // routinely bracket-access a fuller runner — a Proxy denies ANY property read.
69
- function denyingJobRunnerProxy(denied = memberResolutionReadOnlyDenied) {
70
- return new Proxy({}, {
71
- get() {
72
- throw denied();
73
- },
74
- });
75
- }
76
- // Allowlist (not denylist): a method added to the target later stays denied
77
- // until someone decides it is read-only.
78
- function allowlistedReadOnlyProxy(target, allowedMethods) {
79
- return new Proxy(target, {
80
- get(inner, prop) {
81
- if (typeof prop === "string" && allowedMethods.has(prop)) {
82
- const method = Reflect.get(inner, prop, inner);
83
- return typeof method === "function" ? method.bind(inner) : method;
84
- }
85
- // Symbol reads and "then" come from await/Promise.resolve/inspect, not from handler code.
86
- if (typeof prop === "symbol" || prop === "then")
87
- return undefined;
88
- throw memberResolutionReadOnlyDenied();
89
- },
90
- });
91
- }
92
- const MEMBER_READ_SEARCH_METHODS = new Set(["search"]);
93
- const MEMBER_READ_ENTITY_CACHE_METHODS = new Set(["get", "mget"]);
94
- const MEMBER_READ_REDIS_METHODS = new Set([
95
- "get",
96
- "mget",
97
- "exists",
98
- "ttl",
99
- "pttl",
100
- "strlen",
101
- "type",
102
- "hget",
103
- "hmget",
104
- "hgetall",
105
- "hexists",
106
- "hlen",
107
- "sismember",
108
- "smembers",
109
- "scard",
110
- "llen",
111
- "lrange",
112
- "zscore",
113
- "zcard",
114
- "zrange",
115
- ]);
116
- // Every write/side-effect surface throws, so "no writeAsMember" holds even
117
- // if a handler tries ctx.write directly on a resolved member principal.
118
- // Deliberately open: `db` (guarded by the READ ONLY transaction + memberReadOnly grant),
119
- // and read-only methods of searchAdapter / redis / entityCache (allowlisted).
120
- export function applyMemberResolutionReadOnly(handlerContext) {
121
- return {
122
- ...handlerContext,
123
- // `db` stays open — executeQuery runs the whole handler in a Postgres READ ONLY
124
- // transaction, and its `memberReadOnly` grant denies every raw-runner handout.
125
- dbOutsideTransaction: undefined,
126
- write: denyMemberResolutionWrite,
127
- writeAs: denyMemberResolutionWrite,
128
- // A resolved member cannot switch identity either — the target would get a normal, writable context.
129
- queryAs: denyMemberResolutionWrite,
130
- appendEvent: denyMemberResolutionWrite, // @cast-boundary engine-bridge
131
- unsafeAppendEvent: denyMemberResolutionWrite,
132
- tryAppendEvent: denyMemberResolutionWrite,
133
- fetchForWriting: denyMemberResolutionWrite,
134
- archiveStream: denyMemberResolutionWrite,
135
- restoreStream: denyMemberResolutionWrite,
136
- snapshotAggregate: denyMemberResolutionWrite,
137
- queryAsMember: denyMemberResolutionWrite,
138
- forTenant: undefined,
139
- resolveActiveMembership: denyMemberResolutionWrite,
140
- scheduleAfterCommit: () => {
141
- throw memberResolutionReadOnlyDenied();
142
- },
143
- scheduleAfterRollback: () => {
144
- throw memberResolutionReadOnlyDenied();
145
- },
146
- // A read as a member gets no system-scope DB, preSave pipeline or file storage.
147
- runPreSave: undefined,
148
- systemDb: undefined,
149
- crossTenantReads: undefined,
150
- files: undefined,
151
- derivatives: undefined,
152
- ...(handlerContext.jobRunner && { jobRunner: denyingJobRunnerProxy() }),
153
- ...(handlerContext.notify && { notify: denyMemberResolutionWrite }),
154
- ...(handlerContext.searchAdapter && {
155
- searchAdapter: allowlistedReadOnlyProxy(handlerContext.searchAdapter, MEMBER_READ_SEARCH_METHODS),
156
- }),
157
- ...(handlerContext.redis && {
158
- redis: allowlistedReadOnlyProxy(handlerContext.redis, MEMBER_READ_REDIS_METHODS),
159
- }),
160
- ...(handlerContext.entityCache && {
161
- entityCache: allowlistedReadOnlyProxy(handlerContext.entityCache, MEMBER_READ_ENTITY_CACHE_METHODS),
162
- }),
163
- };
164
- }
165
- function beforeTransactionDenied(surface) {
166
- return new InternalError({
167
- message: `ctx.${surface} is not available before the transaction; move it into the handler`,
168
- });
169
- }
170
- function withoutTransactionDenied(surface) {
171
- return new InternalError({
172
- message: `ctx.${surface} is not available without an open transaction; run the write through ctx.write so it gets its own transaction`,
173
- });
174
- }
175
- export function perCommandNestedDenied(targetType) {
176
- return new InternalError({
177
- message: `handler "${targetType}" runs without a transaction (transaction: "perCommand") and cannot run as a nested write inside an open transaction`,
178
- });
179
- }
180
- function denySurface(buildError, surface) {
181
- return () => {
182
- throw buildError(surface);
183
- };
184
- }
185
- function denyEventStoreSurfaces(handlerContext, buildError) {
186
- return {
187
- ...handlerContext,
188
- appendEvent: denySurface(buildError, "appendEvent"),
189
- unsafeAppendEvent: denySurface(buildError, "unsafeAppendEvent"),
190
- tryAppendEvent: denySurface(buildError, "tryAppendEvent"),
191
- fetchForWriting: denySurface(buildError, "fetchForWriting"),
192
- archiveStream: denySurface(buildError, "archiveStream"),
193
- restoreStream: denySurface(buildError, "restoreStream"),
194
- snapshotAggregate: denySurface(buildError, "snapshotAggregate"),
195
- };
196
- }
197
- // Reservations write on purpose through the outside-transaction handles, so they keep those but
198
- // lose every surface bound to the not-yet-open transaction.
199
- export function denyTransactionBoundSurfaces(handlerContext) {
200
- return {
201
- ...denyEventStoreSurfaces(handlerContext, beforeTransactionDenied),
202
- write: denySurface(beforeTransactionDenied, "write"),
203
- writeAs: denySurface(beforeTransactionDenied, "writeAs"),
204
- scheduleAfterCommit: denySurface(beforeTransactionDenied, "scheduleAfterCommit"),
205
- scheduleAfterRollback: denySurface(beforeTransactionDenied, "scheduleAfterRollback"),
206
- ...(handlerContext.notify && { notify: denySurface(beforeTransactionDenied, "notify") }),
207
- ...(handlerContext.jobRunner && {
208
- jobRunner: denyingJobRunnerProxy(() => beforeTransactionDenied("jobRunner")),
209
- }),
210
- };
211
- }
212
- // The beforeTransaction phase has no write need at all, so it also loses the outside-transaction handles.
213
- export function applyBeforeTransactionReadOnly(handlerContext) {
214
- return {
215
- ...denyTransactionBoundSurfaces(handlerContext),
216
- dbOutsideTransaction: undefined,
217
- };
218
- }
219
76
  export async function buildHandlerContext(ctx, type, user, origin, options = {}) {
220
- const { tx, afterCommitHooks, includeDeleted, outerNotifySink, readOnlyForTenant = false, transactionScope = tx ? "inTransaction" : "withoutTransaction", } = options;
77
+ const { tx, afterCommitHooks, includeDeleted, outerNotifySink, phase = "handler", transactionScope = tx ? "inTransaction" : "withoutTransaction", } = options;
78
+ const readOnlyForTenant = phase === "beforeTransaction";
221
79
  const scope = resolveHandlerContextScope({ ctx, type, user, origin, tx, transactionScope });
222
80
  const dbFacet = buildHandlerDbFacet(scope);
223
81
  const observability = buildObservabilityFacet(scope);
224
82
  const sinks = createCommitSinks(afterCommitHooks, transactionScope, outerNotifySink);
225
83
  const notifyFacet = buildNotifyFacet(scope, sinks, dbFacet.outsideTxSource);
226
84
  const configFacet = buildConfigFacet(scope, dbFacet.db);
227
- const forTenantFragment = buildForTenantFragment(scope, dbFacet.exposedDb, readOnlyForTenant);
85
+ const writeTarget = buildWriteTarget(scope, dbFacet.exposedDb, readOnlyForTenant);
228
86
  const fileFragment = buildFileFragment(scope, dbFacet.db);
229
- const dispatchFacet = buildDispatchFacet(scope, sinks);
230
87
  const authFacet = buildAuthFacet(scope);
231
88
  const eventStoreFacet = buildEventStoreFacet(scope);
89
+ const dispatchFacet = buildDispatchFacet(scope, sinks, {
90
+ queryAsMember: authFacet.queryAsMember,
91
+ queryProjection: eventStoreFacet.queryProjection,
92
+ });
232
93
  const tz = await resolveHandlerTz(scope, configFacet.config);
233
94
  const locale = resolveHandlerLocale(scope);
234
- // The payload-bucket digest is dispatcher-internal; handlers must not be
235
- // able to compute bucket keys.
236
- const { _rateLimitPayloadDigest: payloadDigest,
237
- // Bound to this call's tx: an outer context's factory must not leak into a tx-less one.
238
- _notifyInTransactionFactory: _omitOuterNotifyInTransactionFactory, _notifyAfterCommitFactory: _omitOuterNotifyAfterCommitFactory, ...contextForHandler } = scope.context;
95
+ const { _rateLimitPayloadDigest: payloadDigest } = scope.context;
96
+ // The final context (after the phase wrappers below) is what preSave hooks must see.
97
+ const finalContext = {};
98
+ const runPreSave = buildPreSave(scope, () => {
99
+ if (finalContext.current === undefined) {
100
+ throw new InternalError({
101
+ message: "lifecycle.runPreSave called before the context was built",
102
+ });
103
+ }
104
+ return finalContext.current;
105
+ });
239
106
  const handlerContext = {
240
- ...contextForHandler,
241
- ...(payloadDigest && { rateLimitDigest: createHandlerBoundDigest(payloadDigest, type) }),
242
- ...notifyFacet.factoryFragment,
243
107
  // Registry is always the dispatcher's registry — injecting it here lets
244
108
  // tests/callers pass `context` without `registry` and still get a valid
245
- // HandlerContext. The spread-then-assign order matters: anything in
246
- // `context` can be overridden, but we want the authoritative registry
247
- // from the dispatcher's own closure to win.
109
+ // HandlerContext.
248
110
  registry: scope.registry,
249
111
  ...dbFacet.fragment,
250
- log: observability.log,
251
- notify: notifyFacet.notify,
252
- ...configFacet.fragment,
253
- ...forTenantFragment,
254
- ...fileFragment,
255
- ...buildPreSaveFragment(scope),
256
- tracer: observability.tracer,
257
- metrics: observability.metrics,
258
- metricsFor: observability.metricsFor,
112
+ // The payload-bucket digest is dispatcher-internal; handlers get one bound to their own name.
113
+ ...(payloadDigest && { rateLimitDigest: createHandlerBoundDigest(payloadDigest, type) }),
114
+ ...observability,
115
+ ...(notifyFacet.notify && { notify: notifyFacet.notify }),
116
+ ...(configFacet.config && { config: configFacet.config }),
117
+ services: buildContextServices(scope.context, {
118
+ ...fileFragment,
119
+ ...buildRuntimeServices(scope),
120
+ ...notifyFacet.factoryServices,
121
+ }),
122
+ lifecycle: {
123
+ ...(runPreSave && { runPreSave }),
124
+ ...dispatchFacet.commitHooks,
125
+ ...buildLifecycleSignal(scope),
126
+ },
127
+ tenants: {
128
+ ...(configFacet.configFor && { config: configFacet.configFor }),
129
+ ...(writeTarget && { writeTarget }),
130
+ },
259
131
  tz,
260
132
  locale,
261
- ...buildRuntimeFragment(scope),
262
- // ctx.user as a convenience alias for event.user. The intuitive path—"the
263
- // context knows its user"—lets handlers avoid writing `event.user.tenantId`
264
- // and reduces errors in ctx.user access patterns. It is identical to
265
- // event.user; identity switches still use queryAs/writeAs.
133
+ // ctx.user as a convenience alias for event.user. Identity switches still use queryAs/writeAs.
266
134
  user,
267
- _tenantId: user.tenantId,
268
- ...dispatchFacet.scheduleFragment,
269
135
  ...(includeDeleted && { includeDeleted: true }),
270
- ...dispatchFacet.bridge,
271
- ...eventStoreFacet,
272
- ...authFacet,
136
+ dispatch: dispatchFacet.dispatch,
137
+ events: eventStoreFacet.events,
138
+ auth: authFacet.auth,
139
+ hasFeature: authFacet.hasFeature,
273
140
  }; // @cast-boundary engine-bridge
274
141
  const scopedContext = transactionScope === "withoutTransaction"
275
142
  ? denyEventStoreSurfaces(handlerContext, withoutTransactionDenied)
276
143
  : handlerContext;
277
144
  // A resolved member principal is read-only by construction.
278
- return isMemberResolutionPrincipal(user)
145
+ const memberSafeContext = isMemberResolutionPrincipal(user)
279
146
  ? applyMemberResolutionReadOnly(scopedContext)
280
147
  : scopedContext;
148
+ const phasedContext = phase === "reservation"
149
+ ? denyTransactionBoundSurfaces(memberSafeContext)
150
+ : phase === "beforeTransaction"
151
+ ? applyBeforeTransactionReadOnly(memberSafeContext)
152
+ : memberSafeContext;
153
+ finalContext.current = phasedContext;
154
+ return phasedContext;
281
155
  }
282
156
  // The handler-name prefix keeps a handler from reproducing the digests the
283
157
  // dispatcher uses for payload buckets (those hash the bare normalized value).
@@ -659,7 +533,10 @@ function buildAuthClaimsContext(ctx, user) {
659
533
  ...(configAccessor && { config: configAccessor }),
660
534
  };
661
535
  }
662
- export async function resolveAuthClaimsFn(ctx, user) {
536
+ export function resolveAuthClaimsFn(ctx, user) {
537
+ return runInSystemRowLevelSecurityScope("auth claims resolution reads memberships before a tenant is known", () => resolveAuthClaimsInScope(ctx, user));
538
+ }
539
+ async function resolveAuthClaimsInScope(ctx, user) {
663
540
  const { registry, appContext: context } = ctx;
664
541
  const hooks = registry.getAuthClaimsHooks();
665
542
  if (hooks.length === 0)
@@ -2,8 +2,11 @@ import { accessInvalidationCredentialFor } from "../api/sse-broker.js";
2
2
  import { scheduleTokenExpiry } from "../api/token-expiry-timer.js";
3
3
  import { hasAccess } from "../engine/access.js";
4
4
  import { tenantOverrideDenied } from "../engine/cross-tenant.js";
5
- import { AccessDeniedError, memberResolutionReadOnlyDenied, NotFoundError, UnauthenticatedError, validationErrorFromZod, } from "../errors/index.js";
6
- import { assertNoSecretLeak } from "../secrets/index.js";
5
+ import { UnauthenticatedError } from "../errors/classes.js";
6
+ import { AccessDeniedError, NotFoundError, validationErrorFromZod } from "../errors/index.js";
7
+ import { memberResolutionReadOnlyDenied } from "../errors/member-resolution.js";
8
+ import { assertNoSecretLeak } from "../secrets/leak-guard.js";
9
+ import { dispatchRowLevelSecurityScope, streamInDispatchScope } from "./dispatch-scope.js";
7
10
  import { buildHandlerContext, enforceRateLimit, ensureFeatureEnabled, isMemberResolutionPrincipal, runStreamInstrumented, } from "./dispatch-shared.js";
8
11
  import { handlerAccessError } from "./handler-access-error.js";
9
12
  // Standalone stream execution — used by the public dispatcher.stream().
@@ -13,14 +16,15 @@ import { handlerAccessError } from "./handler-access-error.js";
13
16
  // write/queryHandler — see feature-entity-handlers.ts), so there's no
14
17
  // field-access filter or postQuery-hook stage to run here.
15
18
  export async function* executeStream(ctx, type, payload, user, origin, options) {
16
- yield* runStreamInstrumented(ctx, type, user, () => executeStreamInner(ctx, type, payload, user, origin, options));
19
+ const scope = dispatchRowLevelSecurityScope(ctx.registry, [type], user);
20
+ yield* streamInDispatchScope(scope, runStreamInstrumented(ctx, type, user, () => executeStreamInner(ctx, type, payload, user, origin, options)));
17
21
  }
18
22
  async function* executeStreamInner(ctx, type, payload, user, origin, options) {
19
23
  const { registry } = ctx;
20
24
  const handler = registry.getStreamHandler(type);
21
25
  if (!handler)
22
26
  throw new NotFoundError("handler", type);
23
- // A resolved member principal (ctx.queryAsMember) is read-only — streams
27
+ // A resolved member principal (ctx.dispatch.queryAsMember) is read-only — streams
24
28
  // are excluded the same way executeWriteInner excludes writes.
25
29
  if (isMemberResolutionPrincipal(user)) {
26
30
  throw memberResolutionReadOnlyDenied();
@@ -1,5 +1,6 @@
1
+ import type { WriteResult } from "@cosmicdrift/kumiko-types/handlers";
1
2
  import type { DbTx } from "../db/connection.ts";
2
- import type { SessionUser, WriteResult } from "../engine/types/index.ts";
3
+ import type { SessionUser } from "../engine/types/index.ts";
3
4
  import type { DispatchContext, WriteOrigin } from "./dispatch-shared.ts";
4
5
  import { type AfterCommitHook } from "./dispatcher-utils.ts";
5
6
  export declare function executeWrite(ctx: DispatchContext, type: string, payload: unknown, user: SessionUser, origin: WriteOrigin, tx: DbTx | undefined, afterCommitHooks: AfterCommitHook[]): Promise<WriteResult>;
@@ -5,17 +5,19 @@ import { createTenantDb, hasTenantColumn } from "../db/tenant-db.js";
5
5
  import { tenantDbRunner } from "../db/tenant-db-runner.js";
6
6
  import { ConfigScopes } from "../engine/constants.js";
7
7
  import { checkWriteFieldOwnership, maskWriteOnlyFields } from "../engine/field-access.js";
8
+ import { HookPhases } from "../engine/hook-helpers.js";
8
9
  import { defineTransitions, guardTransition } from "../engine/state-machine.js";
9
- import { HookPhases } from "../engine/types/index.js";
10
- import { AccessDeniedError, FrameworkReasons, InternalError, memberResolutionReadOnlyDenied, NotFoundError, ValidationError, writeFailure, } from "../errors/index.js";
10
+ import { AccessDeniedError, FrameworkReasons, InternalError, NotFoundError, ValidationError, writeFailure, } from "../errors/index.js";
11
+ import { memberResolutionReadOnlyDenied } from "../errors/member-resolution.js";
11
12
  import { assertFileRefsBelongToTenant } from "../files/assert-file-refs-belong-to-tenant.js";
12
13
  import { bindPendingFileRefs } from "../files/bind-pending-file-refs.js";
13
14
  import { disposeRemovedFileRefs } from "../files/dispose-removed-file-refs.js";
14
15
  import { loadSaveFileRefs } from "../files/load-save-file-refs.js";
15
16
  import { CACHE_SYNC_TOPICS } from "../redis/cache-sync-topics.js";
16
- import { assertNoSecretLeak } from "../secrets/index.js";
17
- import { buildHandlerContext, CONFIG_WRITE_RESET_TYPE, CONFIG_WRITE_SET_TYPE, isMemberResolutionPrincipal, perCommandNestedDenied, resolveDbSource, runHandlerInstrumented, TENANT_TIMEZONE_CONFIG_KEY, } from "./dispatch-shared.js";
17
+ import { assertNoSecretLeak } from "../secrets/leak-guard.js";
18
+ import { buildHandlerContext, CONFIG_WRITE_RESET_TYPE, CONFIG_WRITE_SET_TYPE, isMemberResolutionPrincipal, resolveDbSource, runHandlerInstrumented, TENANT_TIMEZONE_CONFIG_KEY, } from "./dispatch-shared.js";
18
19
  import { describeShape, extractNestedSpecs, isLifecycleResult, isWriteResultShape, prefixValidationPath, wrapToKumiko, } from "./dispatcher-utils.js";
20
+ import { perCommandNestedDenied } from "./handler-context-phase-denials.js";
19
21
  import { runPreHandlerGates } from "./pre-handler-gates.js";
20
22
  import { consumeReservation, hasPreTransactionPhase, } from "./pre-transaction-reservations.js";
21
23
  import { runProjections } from "./projections-runner.js";
@@ -108,11 +110,11 @@ async function settleSaveFileRefs(handlerContext, result, user) {
108
110
  async function runLifecycle(ctx, type, data, handlerContext, user, origin, afterCommitHooks, runner) {
109
111
  const { lifecycle } = ctx;
110
112
  if (!lifecycle) {
111
- handlerContext.log?.debug(`runLifecycle: skipping ${type} — no lifecycle pipeline`);
113
+ handlerContext.obs.log.debug(`runLifecycle: skipping ${type} — no lifecycle pipeline`);
112
114
  return;
113
115
  }
114
116
  if (!isLifecycleResult(data)) {
115
- handlerContext.log?.debug(`runLifecycle: skipping ${type} — result is not a lifecycle kind`);
117
+ handlerContext.obs.log.debug(`runLifecycle: skipping ${type} — result is not a lifecycle kind`);
116
118
  return;
117
119
  }
118
120
  const result = data;
@@ -369,7 +371,7 @@ function resolveWriteEntry(ctx, type, user, tx) {
369
371
  if (!handler)
370
372
  return failedStep(writeFailure(new NotFoundError("handler", type)));
371
373
  // Defense in depth — covers runBatch and a spread-copied user that kept
372
- // `origin`, beyond buildHandlerContext's own ctx.write replacement.
374
+ // `origin`, beyond buildHandlerContext's own ctx.dispatch.write replacement.
373
375
  if (isMemberResolutionPrincipal(user)) {
374
376
  return failedStep(writeFailure(memberResolutionReadOnlyDenied()));
375
377
  }
@@ -389,7 +391,7 @@ async function runWriteGates(ctx, handler, type, payload, user) {
389
391
  return failedStep(gates);
390
392
  const parsedPayload = reservation ? reservation.parsedPayload : gates.payload;
391
393
  // A handler with a pre-transaction phase cannot run that phase from inside an open transaction;
392
- // running it without would skip the reservation or the prepared data, so a nested ctx.write of
394
+ // running it without would skip the reservation or the prepared data, so a nested ctx.dispatch.write of
393
395
  // such a handler is rejected instead.
394
396
  if (needsPreTransactionPhase && !reservation) {
395
397
  return failedStep(writeFailure(new InternalError({
@@ -1,4 +1,6 @@
1
- import type { HandlerRef, LifecycleResult, Registry, SessionUser, WriteResult } from "../engine/types/index.ts";
1
+ import type { HandlerRef, WriteResult } from "@cosmicdrift/kumiko-types/handlers";
2
+ import type { LifecycleResult } from "@cosmicdrift/kumiko-types/hooks";
3
+ import type { Registry, SessionUser } from "../engine/types/index.ts";
2
4
  import { type KumikoError, type WriteErrorInfo } from "../errors/index.ts";
3
5
  export type FailedWriteResult = Extract<WriteResult, {
4
6
  isSuccess: false;
@@ -1,5 +1,7 @@
1
+ import { isInvalidDateTimeValue } from "../db/pg-error.js";
1
2
  import { parseQn, qn } from "../engine/qualified-name.js";
2
- import { toKumikoError, VersionConflictError, } from "../errors/index.js";
3
+ import { ValidationError, VersionConflictError, } from "../errors/index.js";
4
+ import { toKumikoError } from "../errors/to-kumiko-error.js";
3
5
  import { VersionConflictError as EventStoreVersionConflictError } from "../event-store/errors.js";
4
6
  export function isFailedWriteResult(result) {
5
7
  return (!!result && typeof result === "object" && "isSuccess" in result && result.isSuccess === false);
@@ -140,7 +142,7 @@ export class NestedWriteRollback extends Error {
140
142
  export function resolveType(type) {
141
143
  return typeof type === "string" ? type : type.name;
142
144
  }
143
- // A custom write losing an append race (ctx.appendEvent, stream.append) is a
145
+ // A custom write losing an append race (ctx.events.append, stream.append) is a
144
146
  // retryable 409 like the CRUD executor's, not an internal error. Mapped here
145
147
  // because errors/ is client code and must not import the event store.
146
148
  // currentVersion -1 is the "not looked up" sentinel for a bare 23505 fallback.
@@ -152,5 +154,9 @@ export function wrapToKumiko(e) {
152
154
  currentVersion: e.currentVersion ?? -1,
153
155
  }, { cause: e });
154
156
  }
157
+ // Payload schemas without z.iso.date() let impossible dates reach the column; that is bad input, not a 500.
158
+ if (isInvalidDateTimeValue(e)) {
159
+ return new ValidationError({ fields: [] }, { cause: e instanceof Error ? e : undefined });
160
+ }
155
161
  return toKumikoError(e);
156
162
  }
@@ -1,15 +1,16 @@
1
1
  import type { CacheSyncBus } from "@cosmicdrift/kumiko-types/cache-sync-types";
2
+ import type { ActiveMembershipResult, DispatchWriteRef, JobRunnerRef, MemberReader, WriteResult } from "@cosmicdrift/kumiko-types/handlers";
2
3
  import type { SseBroker } from "../api/sse-broker.ts";
3
4
  import type { DbConnection } from "../db/connection.ts";
4
5
  import type { EffectiveFeaturesResolver } from "../engine/tier-resolver-extension.ts";
5
6
  import type { TenantId } from "../engine/types/identifiers.ts";
6
- import type { ActiveMembershipResult, AppContext, DispatchWriteRef, JobRunnerRef, MemberReader, Registry, SessionUser, WriteResult } from "../engine/types/index.ts";
7
+ import type { AppContext, Registry, SessionUser } from "../engine/types/index.ts";
7
8
  import type { BatchCommand, BatchResult } from "./dispatch-shared.ts";
8
9
  import { type StreamOptions } from "./dispatch-stream.ts";
9
10
  import { type HandlerType } from "./dispatcher-utils.ts";
10
11
  import type { IdempotencyGuard } from "./idempotency.ts";
11
12
  import type { LifecycleHooks } from "./lifecycle-pipeline.ts";
12
- export type { WriteResult } from "../engine/types/index.ts";
13
+ export type { WriteResult } from "@cosmicdrift/kumiko-types/handlers";
13
14
  export type { BatchCommand, BatchResult } from "./dispatch-shared.ts";
14
15
  export type DispatcherOptions = {
15
16
  idempotency?: IdempotencyGuard;
@@ -1,8 +1,9 @@
1
- import { runWithWriteOrigin } from "../api/request-context.js";
1
+ import { runWithWriteOrigin } from "../api/request-context-scopes.js";
2
2
  import { TENANT_MEMBERSHIPS_QUERY } from "../engine/extension-names.js";
3
3
  import { InternalError, reraiseAsKumikoError } from "../errors/index.js";
4
- import { withEscapeHatchAuditScopeStream } from "../observability/escape-hatch-report.js";
5
- import { createEscapeHatchReportWindow, getFallbackMeter, getFallbackTracer, registerStandardMetrics, withEscapeHatchAuditScope, } from "../observability/index.js";
4
+ import { createEscapeHatchReportWindow, withEscapeHatchAuditScope, withEscapeHatchAuditScopeStream, } from "../observability/escape-hatch-report.js";
5
+ import { getFallbackMeter, getFallbackTracer } from "../observability/fallback.js";
6
+ import { registerStandardMetrics } from "../observability/standard-metrics.js";
6
7
  import { CACHE_SYNC_TOPICS, isTenantConfigSyncMessage } from "../redis/cache-sync-topics.js";
7
8
  import { INTERACTIVE_SIGN_IN_POLICY, resolveActiveMembershipFn } from "./active-membership.js";
8
9
  import { runBatch, unwrapSingle } from "./dispatch-batch.js";
@@ -12,5 +12,4 @@ export declare const ConsumerStatuses: {
12
12
  readonly dead: "dead";
13
13
  readonly disabled: "disabled";
14
14
  };
15
- export type ConsumerStatus = (typeof ConsumerStatuses)[keyof typeof ConsumerStatuses];
16
15
  export declare function createEventConsumerStateTable(db: DbConnection): Promise<void>;
@@ -1,9 +1,9 @@
1
1
  /// <reference types="temporal-polyfill/global" preserve="true" />
2
+ import type { Meter } from "@cosmicdrift/kumiko-types/observability";
2
3
  import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
3
4
  import type { DbConnection, DbRunner, DbTx } from "../db/connection.ts";
4
5
  import { type PendingIdRange } from "../db/queries/event-store.ts";
5
6
  import type { AppContext } from "../engine/types/index.ts";
6
- import { type Meter } from "../observability/index.ts";
7
7
  import { type PendingGapEntry } from "./event-consumer-state.ts";
8
8
  import type { EventConsumer } from "./event-dispatcher.ts";
9
9
  export type ConsumerStateRowShape = {
@@ -6,8 +6,10 @@ import { selectEventsHeadId, selectPendingAndNewEventRows, } from "../db/queries
6
6
  import { coerceRow } from "../db/query.js";
7
7
  import { extractTableInfo } from "../db/table-info.js";
8
8
  import { qnScope } from "../engine/qualified-name.js";
9
- import { eventsTable, toStoredEvent as rowToStoredEvent, } from "../event-store/index.js";
10
- import { emitDispatcherError, emitEventConsumerLag, emitEventConsumerPendingGaps, getFallbackMeter, } from "../observability/index.js";
9
+ import { eventsTable } from "../event-store/index.js";
10
+ import { toStoredEvent as rowToStoredEvent } from "../event-store/row-to-stored-event.js";
11
+ import { getFallbackMeter } from "../observability/fallback.js";
12
+ import { emitDispatcherError, emitEventConsumerLag, emitEventConsumerPendingGaps, } from "../observability/standard-metrics.js";
11
13
  import { ConsumerStatuses, eventConsumerStateTable, SHARED_INSTANCE_SENTINEL, } from "./event-consumer-state.js";
12
14
  import { parseWriteOrigin } from "./write-origin.js";
13
15
  // Fails closed without throwing: a throw would poison the event for every consumer.
@@ -1,7 +1,7 @@
1
+ import type { Meter, Tracer } from "@cosmicdrift/kumiko-types/observability";
1
2
  import type { PgListenClient } from "../db/connection.ts";
2
3
  import type { AppContext } from "../engine/types/index.ts";
3
- import { type StoredEvent } from "../event-store/index.ts";
4
- import { type Meter, type Tracer } from "../observability/index.ts";
4
+ import type { StoredEvent } from "../event-store/index.ts";
5
5
  export type EventConsumerHandler = (event: StoredEvent, ctx: AppContext) => Promise<void>;
6
6
  export type EventConsumerBatchHandler = (events: readonly StoredEvent[], ctx: AppContext) => Promise<void>;
7
7
  export type EventConsumerErrorPolicy = {
@@ -1,9 +1,11 @@
1
1
  import { extractPgError } from "../db/pg-error.js";
2
2
  import { recordConsumerPassFailure, selectSnapshotXmax, selectSnapshotXmin, } from "../db/queries/event-consumer.js";
3
+ import { assertNoActiveRowLevelSecurityScope, runInSystemRowLevelSecurityScope, } from "../db/row-level-security-scope.js";
3
4
  import { SYSTEM_TENANT_ID } from "../engine/types/identifiers.js";
4
- import { EVENTS_PUBSUB_CHANNEL } from "../event-store/index.js";
5
+ import { EVENTS_PUBSUB_CHANNEL } from "../event-store/event-store.js";
5
6
  import { createFallbackLogger } from "../logging/utils.js";
6
- import { emitEventConsumerPassOutcome, emitEventConsumerPassSkipped, emitEventConsumerRearmExhausted, emitEventDispatcherListenConnected, getFallbackMeter, getFallbackTracer, } from "../observability/index.js";
7
+ import { getFallbackMeter, getFallbackTracer } from "../observability/fallback.js";
8
+ import { emitEventConsumerPassOutcome, emitEventConsumerPassSkipped, emitEventConsumerRearmExhausted, emitEventDispatcherListenConnected, } from "../observability/standard-metrics.js";
7
9
  import { SHARED_INSTANCE_SENTINEL } from "./event-consumer-state.js";
8
10
  import { acquireConsumerState, consumerInstanceId, deliverEvents, emitLagFromTx, fetchPendingEvents, markProcessing, persistConsumerOutcome, preRegisterConsumers, selectIdleConsumerKeys, } from "./event-dispatcher-delivery.js";
9
11
  import { mergeContiguousGapRanges, partitionBurntGaps, splitRangeExcludingIds, toIdRanges, } from "./pending-gap-ranges.js";
@@ -221,7 +223,8 @@ export function createEventDispatcher(options) {
221
223
  if (!preRegistered) {
222
224
  throw new Error("EventDispatcher.runOnce() called before start() — consumer state rows are not registered. Call start() first (production) or ensureRegistered() (tests after truncating kumiko_event_consumers).");
223
225
  }
224
- const pass = doPass();
226
+ // Per pass, never around start(): the poll loop itself must stay outside any scope.
227
+ const pass = runInSystemRowLevelSecurityScope("event dispatcher pass runs consumers for every tenant", doPass);
225
228
  inFlightPasses.add(pass);
226
229
  try {
227
230
  return await pass;
@@ -457,6 +460,7 @@ export function createEventDispatcher(options) {
457
460
  return {
458
461
  consumers,
459
462
  async start() {
463
+ assertNoActiveRowLevelSecurityScope("EventDispatcher");
460
464
  // skip: already running, idempotent
461
465
  if (running)
462
466
  return;