@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,5 +1,5 @@
1
1
  import { type DbConnection } from "../db/index.ts";
2
- export type EsOperationType = "seed-migration";
2
+ export type EsOperationType = "seed-migration" | "stream-migration";
3
3
  export type EsOperationAppliedBy = "boot" | "cli" | "ci-pipeline";
4
4
  export declare const esOperationsTable: import("@cosmicdrift/kumiko-types/executor-brand").WritableSchemaTable;
5
5
  export declare function createEsOperationsTable(db: DbConnection): Promise<void>;
@@ -30,10 +30,9 @@ export type SeedUserRow = {
30
30
  /** Read shape of a membership entry exposed to seed helpers.
31
31
  * Distinguishes two tenantIds: the logical one from the read projection
32
32
  * (`tenantId`) and the physical one from the aggregate stream
33
- * (`streamTenantId`). They differ when the aggregate was created by an
34
- * executor with a different tenantId (for example,
35
- * seedTenantMembership-by=systemAdmin), which is a typical
36
- * publicstatus driver use case. */
33
+ * (`streamTenantId`). They only differ for memberships written by an admin
34
+ * of another tenant before `backfillTenantStreamTenants` ran; afterwards
35
+ * `streamTenantId = tenantId`. */
37
36
  export type SeedMembershipRow = {
38
37
  readonly userId: string;
39
38
  /** Payload tenant from `read_tenant_memberships.tenant_id`; it is used
@@ -74,7 +73,7 @@ export type SeedMigrationContext = {
74
73
  * user executes it while bypassing access checks. Events have
75
74
  * inserted_by_id = SYSTEM_TENANT_ID-user, making them auditable.
76
75
  *
77
- * The type signature follows existing ctx.writeAs (with payload as unknown).
76
+ * The type signature follows existing ctx.dispatch.writeAs (with payload as unknown).
78
77
  * Type safety comes from handler-specific wrappers in the caller; do not
79
78
  * attempt generic magic.
80
79
  *
@@ -0,0 +1,14 @@
1
+ import type { TenantId } from "../engine/types/index.ts";
2
+ import type { EventMetadata } from "./event-store.ts";
3
+ export type RawEventToAppend = {
4
+ readonly aggregateId: string;
5
+ readonly aggregateType: string;
6
+ readonly tenantId: TenantId;
7
+ readonly expectedVersion: number;
8
+ readonly type: string;
9
+ readonly eventVersion?: number;
10
+ readonly payload: Record<string, unknown>;
11
+ readonly metadata: EventMetadata;
12
+ readonly createdAt: Temporal.Instant;
13
+ readonly createdBy: string;
14
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,18 +1,5 @@
1
1
  /// <reference types="temporal-polyfill/global" preserve="true" />
2
2
  import type { DbRunner } from "../db/index.ts";
3
- import type { TenantId } from "../engine/types/index.ts";
4
- import type { EventMetadata } from "./event-store.ts";
5
- export type RawEventToAppend = {
6
- readonly aggregateId: string;
7
- readonly aggregateType: string;
8
- readonly tenantId: TenantId;
9
- readonly expectedVersion: number;
10
- readonly type: string;
11
- readonly eventVersion?: number;
12
- readonly payload: Record<string, unknown>;
13
- readonly metadata: EventMetadata;
14
- readonly createdAt: Temporal.Instant;
15
- readonly createdBy: string;
16
- };
3
+ import type { RawEventToAppend } from "./admin-api-internals.ts";
17
4
  export declare function appendRaw(runner: DbRunner, event: RawEventToAppend): Promise<void>;
18
5
  export declare function appendRawBatch(runner: DbRunner, events: readonly RawEventToAppend[]): Promise<void>;
@@ -10,7 +10,9 @@ import { instantToTimestamptzParam } from "../db/driver-value-preparation.js";
10
10
  import { constraintOf, isUniqueViolation } from "../db/pg-error.js";
11
11
  import { claimXactId, runAtomicEventWrite } from "../db/queries/event-store.js";
12
12
  import { eventPredecessorExists, findExistingEventVersion, insertRawEventBatch, insertRawFirstEvent, insertRawSubsequentEvent, } from "../db/queries/event-store-admin.js";
13
+ import { runInSystemRowLevelSecurityScope } from "../db/row-level-security-scope.js";
13
14
  import { IdempotentAppendConflictError, VersionConflictError } from "./errors.js";
15
+ import { inEventStreamScope } from "./stream-scope.js";
14
16
  function mapEventUniqueViolation(e, event) {
15
17
  if (constraintOf(e) === "events_idempotency_uq" && event.metadata.idempotencyKey) {
16
18
  return new IdempotentAppendConflictError(event.tenantId, event.metadata.idempotencyKey);
@@ -26,7 +28,7 @@ export async function appendRaw(runner, event) {
26
28
  try {
27
29
  // See db/queries/event-store.ts's claimXactId — gap-finality needs a
28
30
  // real xact id assigned before this holder's insert.
29
- await runAtomicEventWrite(runner, async (tx) => {
31
+ await inEventStreamScope(event.tenantId, () => runAtomicEventWrite(runner, async (tx) => {
30
32
  await claimXactId(tx);
31
33
  if (event.expectedVersion === 0) {
32
34
  await insertRawFirst(tx, event, newVersion, eventVersion);
@@ -34,7 +36,7 @@ export async function appendRaw(runner, event) {
34
36
  else {
35
37
  await insertRawSubsequent(tx, event, newVersion, eventVersion);
36
38
  }
37
- });
39
+ }));
38
40
  }
39
41
  catch (e) {
40
42
  if (isUniqueViolation(e)) {
@@ -81,8 +83,11 @@ export async function appendRawBatch(runner, events) {
81
83
  if (!firstEvent)
82
84
  return;
83
85
  verifyContiguousWithinBatch(events);
84
- await verifyPredecessors(runner, events);
85
- await verifyNoDuplicates(runner, events);
86
+ // A batch may span tenants (replay, transfer), so its pre-flight reads and the insert are system scoped.
87
+ await runInSystemRowLevelSecurityScope("raw event batch append writes events for arbitrary tenants", async () => {
88
+ await verifyPredecessors(runner, events);
89
+ await verifyNoDuplicates(runner, events);
90
+ });
86
91
  const params = [];
87
92
  const valuesClauses = events.map((e) => {
88
93
  const newVersion = e.expectedVersion + 1;
@@ -92,10 +97,10 @@ export async function appendRawBatch(runner, events) {
92
97
  return `($${baseIdx + 1}::uuid, $${baseIdx + 2}, $${baseIdx + 3}::uuid, $${baseIdx + 4}, $${baseIdx + 5}, $${baseIdx + 6}, $${baseIdx + 7}::jsonb, $${baseIdx + 8}::jsonb, $${baseIdx + 9}::timestamptz, $${baseIdx + 10})`;
93
98
  });
94
99
  try {
95
- await runAtomicEventWrite(runner, async (tx) => {
100
+ await runInSystemRowLevelSecurityScope("raw event batch append refreshes stream state across tenants", () => runAtomicEventWrite(runner, async (tx) => {
96
101
  await claimXactId(tx);
97
102
  await insertRawEventBatch(tx, valuesClauses.join(", "), params);
98
- });
103
+ }));
99
104
  }
100
105
  catch (e) {
101
106
  if (isUniqueViolation(e)) {
@@ -3,7 +3,7 @@ import { instant, table as pgTable, sql, text, uniqueIndex, uuid } from "../db/d
3
3
  import { upsertArchivedStream } from "../db/queries/event-store.js";
4
4
  import { deleteMany, fetchOne } from "../db/query.js";
5
5
  import { tableExists } from "../db/schema-inspection.js";
6
- import { unsafePushTables } from "../db/table-push.js";
6
+ import { ensureTableRowLevelSecurity, unsafePushTables } from "../db/table-push.js";
7
7
  // Marten-aligned stream archival. Archived streams become read-only: fresh
8
8
  // appendEvent on an archived aggregate throws, and loadAggregate returns
9
9
  // an empty slice unless the caller passes { includeArchived: true }.
@@ -24,8 +24,10 @@ export const archivedStreamsTable = pgTable("kumiko_archived_streams", {
24
24
  // guard:dup-ok — intentionale Parallele zu createSnapshotsTable; verschiedene Tabellen-Schemas by design
25
25
  export async function createArchivedStreamsTable(db) {
26
26
  // skip: table already exists — idempotent boot + test-setup call
27
- if (await tableExists(db, "public.kumiko_archived_streams"))
27
+ if (await tableExists(db, "public.kumiko_archived_streams")) {
28
+ await ensureTableRowLevelSecurity(db, archivedStreamsTable);
28
29
  return;
30
+ }
29
31
  await unsafePushTables(db, { kumikoArchivedStreams: archivedStreamsTable });
30
32
  }
31
33
  // Mark a stream as archived. Idempotent — re-archiving (same tenant +
@@ -55,11 +55,11 @@ export class SeedTimeOrderError extends Error {
55
55
  this.predecessorCreatedAt = predecessorCreatedAt;
56
56
  }
57
57
  }
58
- // Thrown when ctx.appendEvent targets an archived stream. Archived aggregates
58
+ // Thrown when ctx.events.append targets an archived stream. Archived aggregates
59
59
  // are read-only — restoreStream() makes them writable again. The archive
60
60
  // state is not carried on the events themselves; it lives on the sparse
61
61
  // kumiko_archived_streams table. Handlers that need to branch on archive
62
- // state should call ctx.isStreamArchived(id) first.
62
+ // state should call ctx.events.isArchived(id) first.
63
63
  export class ArchivedStreamError extends Error {
64
64
  tenantId;
65
65
  aggregateId;
@@ -12,6 +12,7 @@ import { IdempotentAppendConflictError, SeedTimeOrderError, VersionConflictError
12
12
  import { eventsTable } from "./events-schema.js";
13
13
  import { toStoredEvent } from "./row-to-stored-event.js";
14
14
  import { currentSeedCreatedAt } from "./seed-clock.js";
15
+ import { inEventStreamScope } from "./stream-scope.js";
15
16
  // Append one event atomically. Two guarantees combined:
16
17
  //
17
18
  // 1. UNIQUE (tenant_id, aggregate_id, version) serializes concurrent writers
@@ -51,7 +52,7 @@ export async function append(db, event) {
51
52
  const newVersion = toStore.expectedVersion + 1;
52
53
  const eventVersion = toStore.eventVersion ?? 1;
53
54
  try {
54
- const row = await runAtomicEventWrite(db, async (runner) => {
55
+ const row = await inEventStreamScope(toStore.tenantId, () => runAtomicEventWrite(db, async (runner) => {
55
56
  await claimXactId(runner);
56
57
  // Inside the write transaction so a concurrent live append cannot slip
57
58
  // between the check and the insert.
@@ -65,7 +66,7 @@ export async function append(db, event) {
65
66
  // commit, so the dispatcher cannot wake before the row is visible.
66
67
  await notifyPgChannel(runner, EVENTS_PUBSUB_CHANNEL);
67
68
  return inserted;
68
- });
69
+ }));
69
70
  return buildStoredEvent(toStore, newVersion, eventVersion, row);
70
71
  }
71
72
  catch (e) {
@@ -208,18 +209,20 @@ export async function loadAggregate(db, aggregateId, tenantId, options) {
208
209
  if (options?.aggregateType === "") {
209
210
  throw new Error("loadAggregate: aggregateType must be a non-empty string when provided");
210
211
  }
211
- if (!options?.includeArchived) {
212
- const archived = await isStreamArchived(db, tenantId, aggregateId);
213
- if (archived)
214
- return [];
215
- }
216
- const rows = await selectMany(db, eventsTable, {
217
- aggregateId,
218
- tenantId,
219
- ...(options?.aggregateType !== undefined && { aggregateType: options.aggregateType }),
220
- ...(options?.atVersion !== undefined && { version: options.atVersion }),
221
- }, { orderBy: { col: "version", direction: "asc" } });
222
- return rows.map(toStoredEvent);
212
+ return inEventStreamScope(tenantId, async () => {
213
+ if (!options?.includeArchived) {
214
+ const archived = await isStreamArchived(db, tenantId, aggregateId);
215
+ if (archived)
216
+ return [];
217
+ }
218
+ const rows = await selectMany(db, eventsTable, {
219
+ aggregateId,
220
+ tenantId,
221
+ ...(options?.aggregateType !== undefined && { aggregateType: options.aggregateType }),
222
+ ...(options?.atVersion !== undefined && { version: options.atVersion }),
223
+ }, { orderBy: { col: "version", direction: "asc" } });
224
+ return rows.map(toStoredEvent);
225
+ });
223
226
  }
224
227
  // Events and the stream's latest version from ONE read, so both come from the same
225
228
  // snapshot: a commit landing between two separate statements would leave the caller
@@ -230,40 +233,44 @@ export async function loadAggregateForWriting(db, aggregateId, tenantId, options
230
233
  if (options.aggregateType === "") {
231
234
  throw new Error("loadAggregateForWriting: aggregateType must be a non-empty string");
232
235
  }
233
- if (await isStreamArchived(db, tenantId, aggregateId)) {
234
- return { events: [], streamVersion: await getStreamVersion(db, aggregateId, tenantId) };
235
- }
236
- const rows = await selectMany(db, eventsTable, { aggregateId, tenantId }, { orderBy: { col: "version", direction: "asc" } });
237
- const all = rows.map(toStoredEvent);
238
- return {
239
- events: all.filter((e) => e.aggregateType === options.aggregateType),
240
- streamVersion: all.at(-1)?.version ?? 0,
241
- };
236
+ return inEventStreamScope(tenantId, async () => {
237
+ if (await isStreamArchived(db, tenantId, aggregateId)) {
238
+ return { events: [], streamVersion: await getStreamVersion(db, aggregateId, tenantId) };
239
+ }
240
+ const rows = await selectMany(db, eventsTable, { aggregateId, tenantId }, { orderBy: { col: "version", direction: "asc" } });
241
+ const all = rows.map(toStoredEvent);
242
+ return {
243
+ events: all.filter((e) => e.aggregateType === options.aggregateType),
244
+ streamVersion: all.at(-1)?.version ?? 0,
245
+ };
246
+ });
242
247
  }
243
248
  // Load events up to a point in time. Used for asOf queries that reconstruct
244
249
  // historical state. Includes events whose created_at is <= asOf. Same
245
250
  // archive semantics as loadAggregate.
246
251
  export async function loadAggregateAsOf(db, aggregateId, tenantId, asOf, options) {
247
- if (!options?.includeArchived) {
248
- const archived = await isStreamArchived(db, tenantId, aggregateId);
249
- if (archived)
250
- return [];
251
- }
252
- const rows = await selectMany(db, eventsTable, { aggregateId, tenantId, createdAt: { lte: asOf } }, { orderBy: { col: "version", direction: "asc" } });
253
- return rows.map(toStoredEvent);
252
+ return inEventStreamScope(tenantId, async () => {
253
+ if (!options?.includeArchived) {
254
+ const archived = await isStreamArchived(db, tenantId, aggregateId);
255
+ if (archived)
256
+ return [];
257
+ }
258
+ const rows = await selectMany(db, eventsTable, { aggregateId, tenantId, createdAt: { lte: asOf } }, { orderBy: { col: "version", direction: "asc" } });
259
+ return rows.map(toStoredEvent);
260
+ });
254
261
  }
255
262
  // Cheapest possible read of "what's the latest version on this stream?". The
256
263
  // CRUD executor uses this as expectedVersion for its append, so a domain
257
- // event appended via ctx.appendEvent between two CRUD writes doesn't cause
264
+ // event appended via ctx.events.append between two CRUD writes doesn't cause
258
265
  // the next CRUD write to fail with version_conflict. Indexed lookup on the
259
266
  // existing (aggregate_id, version) unique index. Returns 0 for empty/unknown
260
267
  // streams (matches create()'s expectedVersion=0 convention).
261
268
  // @wrapper-known semantic-alias
262
269
  export async function getStreamVersion(db, aggregateId, tenantId) {
263
- return selectStreamMaxVersion(db, aggregateId, tenantId);
270
+ return inEventStreamScope(tenantId, () => selectStreamMaxVersion(db, aggregateId, tenantId));
264
271
  }
265
272
  export async function getStreamVersions(db, aggregateIds, tenantId) {
266
- return selectStreamMaxVersions(db, aggregateIds, tenantId);
273
+ return inEventStreamScope(tenantId, () => selectStreamMaxVersions(db, aggregateIds, tenantId));
267
274
  }
268
275
  /** MAX(version) for one aggregate — no tenant filter. SECURITY: existence-oracle,
269
276
  * a caller can probe whether an aggregateId has any events regardless of tenant
@@ -310,7 +317,7 @@ export async function loadEventsAfterVersion(db, aggregateId, tenantId, afterVer
310
317
  // The caller may pause / do async work between yields; the next batch is
311
318
  // only fetched when consumed.
312
319
  //
313
- // Cancellation: pass `signal` (typically `ctx.signal` from a handler) to
320
+ // Cancellation: pass `signal` (typically `ctx.lifecycle.signal` from a handler) to
314
321
  // abort iteration. Checked both at batch boundaries (before the next
315
322
  // fetch) AND between yields (so abort lands within one event regardless
316
323
  // of batch size). Throws AbortError on the first check after abort;
@@ -2,7 +2,7 @@
2
2
  import { bigserial, index, instant, integer, jsonb, table as pgTable, sql, text, uniqueIndex, uuid, } from "../db/dialect.js";
3
3
  import { tableExists } from "../db/index.js";
4
4
  import { ensureIdempotencyKeyIndex, ensureMembershipPayloadTenantIndex, } from "../db/queries/event-store.js";
5
- import { unsafePushTables } from "../db/table-push.js";
5
+ import { ensureTableRowLevelSecurity, unsafePushTables } from "../db/table-push.js";
6
6
  import { createArchivedStreamsTable } from "./archive.js";
7
7
  import { createSnapshotsTable } from "./snapshot.js";
8
8
  // Event-store schema as a Drizzle table. The typed select/insert path handles
@@ -57,6 +57,9 @@ export async function createEventsTable(db) {
57
57
  if (!(await tableExists(db, "public.kumiko_events"))) {
58
58
  await unsafePushTables(db, { kumikoEvents: eventsTable });
59
59
  }
60
+ else {
61
+ await ensureTableRowLevelSecurity(db, eventsTable);
62
+ }
60
63
  // Runs unconditionally (both fresh + already-existing table) so installs
61
64
  // that predate the idempotency-key index get healed the same way
62
65
  // ensureSnapshotVersionColumn heals kumiko_snapshots.
@@ -1,16 +1,14 @@
1
1
  export { APP_INSTANCE_STREAM_TYPE, APP_STARTED_EVENT_TYPE } from "../crypto/system-event-pii.ts";
2
- export { backfillEventPiiEncryption, backfillEventPiiEncryptionBatch, type PiiBackfillBatchOptions, type PiiBackfillBatchResult, type PiiBackfillFailure, type PiiBackfillOptions, type PiiBackfillResult, type PiiBackfillScanCache, } from "../db/queries/backfill-pii.ts";
3
- export { type DeleteRowsWithoutReplayableStreamArgs, deleteRowsWithoutReplayableStream, } from "../db/queries/event-store-orphan-rows.ts";
4
- export { type ArchiveStreamArgs, archivedStreamsTable, archiveStream, createArchivedStreamsTable, isStreamArchived, restoreStream, } from "./archive.ts";
5
- export { ArchivedStreamError, IdempotentAppendConflictError, SeedTimeOrderError, VersionConflictError, } from "./errors.ts";
6
- export { append, EVENTS_PUBSUB_CHANNEL, type EventMetadata, type EventToAppend, getEventsHighWaterMark, getStreamVersion, getStreamVersions, getUnscopedAggregateStreamMaxVersion, getUnscopedStreamMaxVersionForSeed, loadAggregate, loadAggregateAsOf, loadEventsAfterVersion, type StoredEvent, streamAllEventsByType, } from "./event-store.ts";
2
+ export { backfillEventPiiEncryption, backfillEventPiiEncryptionBatch, } from "../db/queries/backfill-pii.ts";
3
+ export { deleteRowsWithoutReplayableStream } from "../db/queries/event-store-orphan-rows.ts";
4
+ export { archivedStreamsTable, archiveStream, createArchivedStreamsTable, isStreamArchived, } from "./archive.ts";
5
+ export { SeedTimeOrderError, VersionConflictError, } from "./errors.ts";
6
+ export { append, type EventMetadata, getEventsHighWaterMark, getStreamVersion, getStreamVersions, getUnscopedAggregateStreamMaxVersion, getUnscopedStreamMaxVersionForSeed, loadAggregate, type StoredEvent, streamAllEventsByType, } from "./event-store.ts";
7
7
  export { createEventsTable, eventsTable } from "./events-schema.ts";
8
- export { appendProvenanceEvent, type ProvenanceEventInput } from "./provenance-append.ts";
9
- export { createRebuildDeadLetterTable, listRebuildDeadLetters, type RebuildDeadLetterRow, rebuildDeadLetterTable, recordRebuildDeadLetters, type SkippedApply, } from "./rebuild-dead-letter.ts";
10
- export { toStoredEvent } from "./row-to-stored-event.ts";
8
+ export { appendProvenanceEvent } from "./provenance-append.ts";
11
9
  export { assertSeedModeNotInProduction, isSeedModeEnabled, runSeedWritesAt, SEED_MODE_ENV, SeedModeDisabledError, } from "./seed-clock.ts";
12
- export { createSnapshotsTable, type LoadAggregateWithSnapshotOptions, type LoadAggregateWithSnapshotResult, loadAggregateWithSnapshot, loadLatestSnapshot, type SaveSnapshotArgs, type Snapshot, type SnapshotReducer, saveSnapshot, snapshotsTable, } from "./snapshot.ts";
13
- export { type AppendEventInTenantDbOptions, appendEventInTenantDb, getStreamVersionInTenantDb, } from "./tenant-db-append.ts";
14
- export { AGGREGATE_TRANSFER_STREAM_TYPE, AGGREGATE_TRANSFERRED_EVENT_TYPE, type TransferAggregateStreamsArgs, transferAggregateStreams, } from "./transfer.ts";
15
- export { type EventUpcasters, makeUpcastCtx, type UpcasterErrorPolicy, type UpcastOptions, upcastStoredEvent, upcastStoredEvents, } from "./upcaster.ts";
16
- export { createUpcasterDeadLetterTable, type DeadLetterRow, listDeadLetters, recordUpcasterDeadLetter, upcasterDeadLetterTable, } from "./upcaster-dead-letter.ts";
10
+ export { snapshotsTable } from "./snapshot.ts";
11
+ export { appendEventInTenantDb, getStreamVersionInTenantDb, } from "./tenant-db-append.ts";
12
+ export { AGGREGATE_TRANSFER_STREAM_TYPE, AGGREGATE_TRANSFERRED_EVENT_TYPE, transferAggregateStreams, } from "./transfer.ts";
13
+ export { makeUpcastCtx, upcastStoredEvent, } from "./upcaster.ts";
14
+ export { upcasterDeadLetterTable } from "./upcaster-dead-letter.ts";
@@ -1,16 +1,14 @@
1
1
  export { APP_INSTANCE_STREAM_TYPE, APP_STARTED_EVENT_TYPE } from "../crypto/system-event-pii.js";
2
2
  export { backfillEventPiiEncryption, backfillEventPiiEncryptionBatch, } from "../db/queries/backfill-pii.js";
3
- export { deleteRowsWithoutReplayableStream, } from "../db/queries/event-store-orphan-rows.js";
4
- export { archivedStreamsTable, archiveStream, createArchivedStreamsTable, isStreamArchived, restoreStream, } from "./archive.js";
5
- export { ArchivedStreamError, IdempotentAppendConflictError, SeedTimeOrderError, VersionConflictError, } from "./errors.js";
6
- export { append, EVENTS_PUBSUB_CHANNEL, getEventsHighWaterMark, getStreamVersion, getStreamVersions, getUnscopedAggregateStreamMaxVersion, getUnscopedStreamMaxVersionForSeed, loadAggregate, loadAggregateAsOf, loadEventsAfterVersion, streamAllEventsByType, } from "./event-store.js";
3
+ export { deleteRowsWithoutReplayableStream } from "../db/queries/event-store-orphan-rows.js";
4
+ export { archivedStreamsTable, archiveStream, createArchivedStreamsTable, isStreamArchived, } from "./archive.js";
5
+ export { SeedTimeOrderError, VersionConflictError, } from "./errors.js";
6
+ export { append, getEventsHighWaterMark, getStreamVersion, getStreamVersions, getUnscopedAggregateStreamMaxVersion, getUnscopedStreamMaxVersionForSeed, loadAggregate, streamAllEventsByType, } from "./event-store.js";
7
7
  export { createEventsTable, eventsTable } from "./events-schema.js";
8
8
  export { appendProvenanceEvent } from "./provenance-append.js";
9
- export { createRebuildDeadLetterTable, listRebuildDeadLetters, rebuildDeadLetterTable, recordRebuildDeadLetters, } from "./rebuild-dead-letter.js";
10
- export { toStoredEvent } from "./row-to-stored-event.js";
11
9
  export { assertSeedModeNotInProduction, isSeedModeEnabled, runSeedWritesAt, SEED_MODE_ENV, SeedModeDisabledError, } from "./seed-clock.js";
12
- export { createSnapshotsTable, loadAggregateWithSnapshot, loadLatestSnapshot, saveSnapshot, snapshotsTable, } from "./snapshot.js";
10
+ export { snapshotsTable } from "./snapshot.js";
13
11
  export { appendEventInTenantDb, getStreamVersionInTenantDb, } from "./tenant-db-append.js";
14
12
  export { AGGREGATE_TRANSFER_STREAM_TYPE, AGGREGATE_TRANSFERRED_EVENT_TYPE, transferAggregateStreams, } from "./transfer.js";
15
- export { makeUpcastCtx, upcastStoredEvent, upcastStoredEvents, } from "./upcaster.js";
16
- export { createUpcasterDeadLetterTable, listDeadLetters, recordUpcasterDeadLetter, upcasterDeadLetterTable, } from "./upcaster-dead-letter.js";
13
+ export { makeUpcastCtx, upcastStoredEvent, } from "./upcaster.js";
14
+ export { upcasterDeadLetterTable } from "./upcaster-dead-letter.js";
@@ -14,7 +14,7 @@
14
14
  // is a separate ops step — same stance as the upcaster dead-letter.
15
15
  import { bigint, index, jsonb, table as pgTable, text, timestamp, uuid } from "../db/dialect.js";
16
16
  import { tableExists } from "../db/schema-inspection.js";
17
- import { unsafePushTables } from "../db/table-push.js";
17
+ import { ensureTableRowLevelSecurity, unsafePushTables } from "../db/table-push.js";
18
18
  export const rebuildDeadLetterTable = pgTable("kumiko_rebuild_dead_letters", {
19
19
  // Surrogate PK — the same event can land here across multiple rebuild
20
20
  // attempts before the fix ships, without unique-violation noise.
@@ -39,8 +39,10 @@ export const rebuildDeadLetterTable = pgTable("kumiko_rebuild_dead_letters", {
39
39
  // provisioned before this table existed.
40
40
  export async function createRebuildDeadLetterTable(db) {
41
41
  // skip: table already exists — bootstrap called from multiple paths
42
- if (await tableExists(db, "public.kumiko_rebuild_dead_letters"))
42
+ if (await tableExists(db, "public.kumiko_rebuild_dead_letters")) {
43
+ await ensureTableRowLevelSecurity(db, rebuildDeadLetterTable);
43
44
  return;
45
+ }
44
46
  await unsafePushTables(db, { kumikoRebuildDeadLetters: rebuildDeadLetterTable });
45
47
  }
46
48
  // Bulk-write, called ONCE at the end of a quarantining rebuild (inside its
@@ -4,7 +4,7 @@ import { index, instant, integer, jsonb, table as pgTable, primaryKey, sql, text
4
4
  import { ensureSnapshotVersionColumn, upsertSnapshot } from "../db/queries/event-store.js";
5
5
  import { selectMany } from "../db/query.js";
6
6
  import { tableExists } from "../db/schema-inspection.js";
7
- import { unsafePushTables } from "../db/table-push.js";
7
+ import { ensureTableRowLevelSecurity, unsafePushTables } from "../db/table-push.js";
8
8
  import { createFallbackLogger, scrubLogText } from "../logging/index.js";
9
9
  import { isStreamArchived } from "./archive.js";
10
10
  import { loadEventsAfterVersion } from "./event-store.js";
@@ -18,7 +18,7 @@ import { loadEventsAfterVersion } from "./event-store.js";
18
18
  // 3. loadEventsAfterVersion(aggregate, N) → only the delta
19
19
  // 4. reducer(snapshot, delta) → current state
20
20
  //
21
- // Write path: manual via ctx.snapshotAggregate, or automatic via the
21
+ // Write path: manual via ctx.events.snapshot, or automatic via the
22
22
  // { snapshotEvery: N } load option — the read path persists a fresh
23
23
  // snapshot whenever it folded at least N delta events.
24
24
  //
@@ -32,7 +32,7 @@ import { loadEventsAfterVersion } from "./event-store.js";
32
32
  //
33
33
  // Upcaster interaction: the raw API (loadAggregateWithSnapshot below) does
34
34
  // NOT apply the upcaster chain on delta events — same layering as raw
35
- // loadAggregate. The Dispatcher wraps this into ctx.loadAggregateWithSnapshot
35
+ // loadAggregate. The Dispatcher wraps this into ctx.events.loadWithSnapshot
36
36
  // and runs upcastStoredEvents on the delta before calling the reducer, so
37
37
  // feature authors always see current-version payloads.
38
38
  export const snapshotsTable = pgTable("kumiko_snapshots", {
@@ -64,6 +64,7 @@ export async function createSnapshotsTable(db) {
64
64
  // Installs that predate snapshot_version get healed by the same
65
65
  // idempotent ensure that `kumiko schema apply` / test-setup already runs.
66
66
  await ensureSnapshotVersionColumn(db);
67
+ await ensureTableRowLevelSecurity(db, snapshotsTable);
67
68
  // skip: table already ensured — only the column heal above was needed
68
69
  return;
69
70
  }
@@ -0,0 +1,2 @@
1
+ import type { TenantId } from "../engine/types/index.ts";
2
+ export declare function inEventStreamScope<T>(streamTenantId: TenantId, work: () => Promise<T>): Promise<T>;
@@ -0,0 +1,6 @@
1
+ import { runInRowLevelSecurityScope, tenantRowLevelSecurityScope, } from "../db/row-level-security-scope.js";
2
+ // A stream belongs to exactly one tenant; its rows are only writable and reliably readable in
3
+ // that tenant's scope, which differs from the caller's for systemStream entities and ctx.tenants.writeTarget.
4
+ export function inEventStreamScope(streamTenantId, work) {
5
+ return runInRowLevelSecurityScope(tenantRowLevelSecurityScope(streamTenantId), work);
6
+ }
@@ -13,7 +13,7 @@
13
13
  // separate CLI step — not implemented here, tracked as follow-up.
14
14
  import { bigint, index, integer, jsonb, table as pgTable, text, timestamp, uuid, } from "../db/dialect.js";
15
15
  import { tableExists } from "../db/schema-inspection.js";
16
- import { unsafePushTables } from "../db/table-push.js";
16
+ import { ensureTableRowLevelSecurity, unsafePushTables } from "../db/table-push.js";
17
17
  export const upcasterDeadLetterTable = pgTable("kumiko_upcaster_dead_letters", {
18
18
  // Surrogate PK. We don't reuse eventId so a single event can land
19
19
  // here multiple times (retry attempts across deploys before the fix
@@ -40,8 +40,10 @@ export const upcasterDeadLetterTable = pgTable("kumiko_upcaster_dead_letters", {
40
40
  // exercise the quarantine path; production boot uses drizzle-kit push.
41
41
  export async function createUpcasterDeadLetterTable(db) {
42
42
  // skip: table already exists — bootstrap called from multiple paths
43
- if (await tableExists(db, "public.kumiko_upcaster_dead_letters"))
43
+ if (await tableExists(db, "public.kumiko_upcaster_dead_letters")) {
44
+ await ensureTableRowLevelSecurity(db, upcasterDeadLetterTable);
44
45
  return;
46
+ }
45
47
  await unsafePushTables(db, { kumikoUpcasterDeadLetters: upcasterDeadLetterTable });
46
48
  }
47
49
  // Writes a dead-letter row. Called by upcastStoredEvent when errorPolicy
@@ -1,5 +1,6 @@
1
+ import type { EventUpcastCtx, EventUpcastFn } from "@cosmicdrift/kumiko-types/handlers";
1
2
  import type { DbRunner } from "../db/index.ts";
2
- import type { EventUpcastCtx, EventUpcastFn, TenantId } from "../engine/types/index.ts";
3
+ import type { TenantId } from "../engine/types/index.ts";
3
4
  import type { StoredEvent } from "./event-store.ts";
4
5
  export type UpcasterErrorPolicy = "throw" | "quarantine";
5
6
  export type UpcastOptions = {
@@ -1,4 +1,5 @@
1
- import { type AnyFileFieldDef, type Registry, type SessionUser } from "../engine/types/index.ts";
1
+ import type { AnyFileFieldDef } from "@cosmicdrift/kumiko-types/fields";
2
+ import type { Registry, SessionUser } from "../engine/types/index.ts";
2
3
  export declare function isActionFormScreenQn(value: string): boolean;
3
4
  /** The files/images field `fieldName` of the registered actionForm screen `screenQn`, if any. */
4
5
  export declare function resolveActionFormFileField(registry: Pick<Registry, "getScreen"> | undefined, screenQn: string, fieldName: string): AnyFileFieldDef | undefined;
@@ -1,5 +1,5 @@
1
1
  import { hasAccess } from "../engine/access.js";
2
- import { isFileField, } from "../engine/types/index.js";
2
+ import { isFileField } from "../engine/field-helpers.js";
3
3
  // Same character set as the other upload identifiers: the screen QN is stored as the pending
4
4
  // upload's entityType and compared by exact match, never interpolated into a storage key.
5
5
  const ACTION_FORM_SCREEN_QN = /^[A-Za-z0-9_-]+:screen:[A-Za-z0-9_-]+$/;
@@ -1,4 +1,5 @@
1
- import { type Registry, type SaveContext } from "../engine/types/index.ts";
1
+ import type { SaveContext } from "@cosmicdrift/kumiko-types/hooks";
2
+ import type { Registry } from "../engine/types/index.ts";
2
3
  import type { FileRefRows } from "./load-save-file-refs.ts";
3
4
  export declare function assertFileRefsBelongToTenant(args: {
4
5
  readonly registry: Registry;
@@ -1,4 +1,4 @@
1
- import { isFileField } from "../engine/types/index.js";
1
+ import { isFileField } from "../engine/field-helpers.js";
2
2
  import { ValidationError } from "../errors/index.js";
3
3
  import { fileRefIdsOf } from "./bind-pending-file-refs.js";
4
4
  import { FILE_REF_ENTITY_NAME } from "./file-ref-entity.js";
@@ -1,5 +1,6 @@
1
+ import type { SaveContext } from "@cosmicdrift/kumiko-types/hooks";
1
2
  import type { TenantDb } from "../db/tenant-db.ts";
2
- import { type Registry, type SaveContext, type SessionUser } from "../engine/types/index.ts";
3
+ import type { Registry, SessionUser } from "../engine/types/index.ts";
3
4
  import { type FileRefRows } from "./load-save-file-refs.ts";
4
5
  export declare function fileRefIdsOf(value: unknown): readonly string[];
5
6
  type FileRefRow = Readonly<Record<string, unknown>>;
@@ -1,5 +1,6 @@
1
+ import { isUuid } from "@cosmicdrift/kumiko-types/identifiers";
2
+ import { isFileField } from "../engine/field-helpers.js";
1
3
  import { isAnonymousSessionUser } from "../engine/system-user.js";
2
- import { isFileField, isUuid, } from "../engine/types/index.js";
3
4
  import { FrameworkReasons, InternalError, reraiseAsKumikoError, UnprocessableError, } from "../errors/index.js";
4
5
  import { getFileRefExecutor, resolveAttachedField } from "./create-file-ref.js";
5
6
  import { FILE_REF_ENTITY_NAME } from "./file-ref-entity.js";
@@ -1,6 +1,6 @@
1
1
  import * as z from "zod";
2
+ import { isFileField } from "../engine/field-helpers.js";
2
3
  import { defineWriteHandler, SYSTEM_ROLE, SYSTEM_USER_ID } from "../engine/index.js";
3
- import { isFileField } from "../engine/types/index.js";
4
4
  import { ValidationError } from "../errors/index.js";
5
5
  import { fileRefIdsOf } from "./bind-pending-file-refs.js";
6
6
  import { getFileRefExecutor } from "./create-file-ref.js";
@@ -1,11 +1,14 @@
1
+ import type { BeforeTransactionResult, WriteResult } from "@cosmicdrift/kumiko-types/handlers";
1
2
  import type { TenantDb } from "../db/tenant-db.ts";
2
- import type { BeforeTransactionResult, Registry, SessionUser, WriteResult } from "../engine/types/index.ts";
3
+ import type { Registry, SessionUser } from "../engine/types/index.ts";
3
4
  import { type CreatedFileRef, type UploadedFileBytes } from "./create-file-ref.ts";
4
5
  import type { FileContext } from "./file-handle.ts";
5
6
  export type { CreatedFileRef, UploadedFileBytes };
6
7
  export type CreateFileRefContext = {
7
8
  readonly db: TenantDb;
8
- readonly files?: FileContext | undefined;
9
+ readonly services: {
10
+ readonly files?: FileContext | undefined;
11
+ };
9
12
  readonly registry: Registry;
10
13
  readonly user: SessionUser;
11
14
  };
@@ -21,6 +24,6 @@ export type CreateFileRefInput = {
21
24
  };
22
25
  export declare function filesUnavailableMessage(caller: string): string;
23
26
  export declare function createFileRefFromBytes(ctx: CreateFileRefContext, input: CreateFileRefInput): Promise<WriteResult<CreatedFileRef>>;
24
- export type UploadFileBytesContext = Pick<CreateFileRefContext, "db" | "files" | "registry" | "user">;
27
+ export type UploadFileBytesContext = Pick<CreateFileRefContext, "db" | "services" | "registry" | "user">;
25
28
  export declare function uploadFileBytesBeforeTransaction(ctx: UploadFileBytesContext, input: CreateFileRefInput): Promise<BeforeTransactionResult<UploadedFileBytes>>;
26
29
  export declare function createFileRefFromUploadedBytes(ctx: Pick<CreateFileRefContext, "db" | "user">, uploaded: UploadedFileBytes): Promise<WriteResult<CreatedFileRef>>;
@@ -8,13 +8,13 @@ import { assertSafeStorageKey } from "./types.js";
8
8
  // The handler context has no HTTP/job/seed marker to name, so the message states the actual
9
9
  // cause: the dispatcher's AppContext carries no file-provider resolver.
10
10
  export function filesUnavailableMessage(caller) {
11
- return `${caller}: ctx.files is unavailable because no file-provider resolver is wired on this dispatcher context. Mount a file-provider-* feature and build the dispatcher context with withFileProviderResolver (HTTP, job and seed dispatchers each need it)`;
11
+ return `${caller}: ctx.services.files is unavailable because no file-provider resolver is wired on this dispatcher context. Mount a file-provider-* feature and build the dispatcher context with withFileProviderResolver (HTTP, job and seed dispatchers each need it)`;
12
12
  }
13
13
  // Server-side counterpart of POST /files for handlers/jobs that produce bytes
14
14
  // themselves (generated PDFs, exports). Same validation, storage layout and
15
15
  // fileRef.created event as an upload; the tenant is always ctx.user.tenantId.
16
16
  export async function createFileRefFromBytes(ctx, input) {
17
- const { files } = ctx;
17
+ const { files } = ctx.services;
18
18
  if (!files) {
19
19
  return writeFailure(new InternalError({
20
20
  message: filesUnavailableMessage("createFileRefFromBytes"),
@@ -59,7 +59,7 @@ function fileRejectedFailure(error) {
59
59
  // A crash between this phase and the commit leaves the bytes in storage; the upload ledger sweep
60
60
  // removes them after its grace period.
61
61
  export async function uploadFileBytesBeforeTransaction(ctx, input) {
62
- const { files } = ctx;
62
+ const { files } = ctx.services;
63
63
  if (!files) {
64
64
  return writeFailure(new InternalError({
65
65
  message: filesUnavailableMessage("uploadFileBytesBeforeTransaction"),
@@ -1,5 +1,6 @@
1
- import { type TenantDb } from "../db/tenant-db.ts";
2
- import { type AnyFileFieldDef, type Registry, type SessionUser } from "../engine/types/index.ts";
1
+ import type { AnyFileFieldDef } from "@cosmicdrift/kumiko-types/fields";
2
+ import type { TenantDb } from "../db/tenant-db.ts";
3
+ import type { Registry, SessionUser } from "../engine/types/index.ts";
3
4
  import { type WriteFailure } from "../errors/index.ts";
4
5
  export declare const DEFAULT_MAX_UPLOAD_SIZE = "10mb";
5
6
  declare function buildFileRefExecutor(): import("@cosmicdrift/kumiko-types/event-store-executor-types").EventStoreExecutor<{
@@ -1,6 +1,6 @@
1
1
  import { createEventStoreExecutor } from "../db/event-store-executor.js";
2
- import { runInOwnTransaction } from "../db/tenant-db.js";
3
- import { isFileField, } from "../engine/types/index.js";
2
+ import { runInOwnTransaction } from "../db/tenant-db-scoped-rebind.js";
3
+ import { isFileField } from "../engine/field-helpers.js";
4
4
  import { InternalError } from "../errors/index.js";
5
5
  import { generateId } from "../utils/index.js";
6
6
  import { isActionFormScreenQn, resolveActionFormFileField } from "./action-form-upload.js";