@cosmicdrift/kumiko-framework 0.389.0 → 0.390.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (616) 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/eagerload.d.ts +2 -1
  98. package/dist/db/entity-field-encryption.d.ts +1 -1
  99. package/dist/db/entity-table-meta.d.ts +1 -1
  100. package/dist/db/event-store-executor-context.d.ts +3 -1
  101. package/dist/db/event-store-executor-context.js +4 -3
  102. package/dist/db/event-store-executor-read-filter.d.ts +1 -1
  103. package/dist/db/event-store-executor-read-rows.d.ts +2 -1
  104. package/dist/db/event-store-executor-read-search.d.ts +2 -1
  105. package/dist/db/event-store-executor-read-sort.d.ts +2 -1
  106. package/dist/db/event-store-executor-read.js +2 -2
  107. package/dist/db/event-store-executor-write-atomic.js +8 -7
  108. package/dist/db/event-store-executor-write-steps.d.ts +3 -2
  109. package/dist/db/event-store-executor-write.js +7 -4
  110. package/dist/db/event-store-executor.d.ts +1 -1
  111. package/dist/db/executor-managed-tables.d.ts +7 -1
  112. package/dist/db/executor-managed-tables.js +11 -2
  113. package/dist/db/index.d.ts +29 -28
  114. package/dist/db/index.js +22 -20
  115. package/dist/db/known-table-names.d.ts +6 -0
  116. package/dist/db/known-table-names.js +21 -0
  117. package/dist/db/list-aggregate-labels.d.ts +1 -1
  118. package/dist/db/located-timestamp.d.ts +1 -1
  119. package/dist/db/located-timestamp.js +0 -5
  120. package/dist/db/migrate-generator.d.ts +17 -1
  121. package/dist/db/migrate-generator.js +50 -20
  122. package/dist/db/migrate-primary-key.d.ts +12 -0
  123. package/dist/db/migrate-primary-key.js +45 -0
  124. package/dist/db/migrate-rls-diff.d.ts +20 -0
  125. package/dist/db/migrate-rls-diff.js +61 -0
  126. package/dist/db/migrate-runner.js +4 -0
  127. package/dist/db/money.d.ts +1 -1
  128. package/dist/db/money.js +1 -1
  129. package/dist/db/parent-ref-clause.d.ts +2 -1
  130. package/dist/db/pg-error.d.ts +2 -0
  131. package/dist/db/pg-error.js +11 -0
  132. package/dist/db/queries/ddl.d.ts +3 -0
  133. package/dist/db/queries/ddl.js +34 -1
  134. package/dist/db/queries/event-store.js +4 -2
  135. package/dist/db/queries/event-tenants.d.ts +2 -0
  136. package/dist/db/queries/event-tenants.js +17 -0
  137. package/dist/db/queries/rebuild-rls-guard.d.ts +2 -0
  138. package/dist/db/queries/rebuild-rls-guard.js +29 -0
  139. package/dist/db/queries/rls-boot-catalog.d.ts +16 -0
  140. package/dist/db/queries/rls-boot-catalog.js +39 -0
  141. package/dist/db/queries/rls-catalog.d.ts +6 -0
  142. package/dist/db/queries/rls-catalog.js +82 -0
  143. package/dist/db/queries/rls-scope.d.ts +3 -0
  144. package/dist/db/queries/rls-scope.js +17 -0
  145. package/dist/db/queries/rls-shape.d.ts +10 -0
  146. package/dist/db/queries/rls-shape.js +42 -0
  147. package/dist/db/queries/session-advisory-lock.d.ts +2 -0
  148. package/dist/db/queries/session-advisory-lock.js +23 -0
  149. package/dist/db/queries/shadow-swap.d.ts +1 -2
  150. package/dist/db/queries/shadow-swap.js +9 -25
  151. package/dist/db/queries/test-stack.d.ts +4 -1
  152. package/dist/db/queries/test-stack.js +83 -2
  153. package/dist/db/query.js +11 -7
  154. package/dist/db/reference-data.d.ts +1 -1
  155. package/dist/db/reference-data.js +6 -1
  156. package/dist/db/render-ddl.d.ts +6 -2
  157. package/dist/db/render-ddl.js +7 -7
  158. package/dist/db/render-rls-ddl.d.ts +35 -0
  159. package/dist/db/render-rls-ddl.js +127 -0
  160. package/dist/db/replay-migration-sql.d.ts +3 -1
  161. package/dist/db/replay-migration-sql.js +22 -5
  162. package/dist/db/replay-rls.d.ts +25 -0
  163. package/dist/db/replay-rls.js +156 -0
  164. package/dist/db/row-level-security-boot-check.d.ts +5 -0
  165. package/dist/db/row-level-security-boot-check.js +85 -0
  166. package/dist/db/row-level-security-connection.d.ts +3 -0
  167. package/dist/db/row-level-security-connection.js +213 -0
  168. package/dist/db/row-level-security-scope.d.ts +33 -0
  169. package/dist/db/row-level-security-scope.js +127 -0
  170. package/dist/db/scope-tenant-db-to-tenant.d.ts +3 -0
  171. package/dist/db/scope-tenant-db-to-tenant.js +14 -0
  172. package/dist/db/sql-identifier.d.ts +1 -0
  173. package/dist/db/sql-identifier.js +3 -0
  174. package/dist/db/table-builder.d.ts +2 -1
  175. package/dist/db/table-builder.js +1 -1
  176. package/dist/db/table-info.js +1 -1
  177. package/dist/db/table-push.d.ts +11 -2
  178. package/dist/db/table-push.js +15 -2
  179. package/dist/db/tenant-db-runner.d.ts +3 -1
  180. package/dist/db/tenant-db-runner.js +4 -3
  181. package/dist/db/tenant-db-scoped-rebind.d.ts +10 -0
  182. package/dist/db/tenant-db-scoped-rebind.js +33 -0
  183. package/dist/db/tenant-db-statement-runner.d.ts +13 -0
  184. package/dist/db/tenant-db-statement-runner.js +48 -0
  185. package/dist/db/tenant-db.d.ts +17 -12
  186. package/dist/db/tenant-db.js +49 -120
  187. package/dist/db/tenant-id-filter.d.ts +3 -0
  188. package/dist/db/tenant-id-filter.js +30 -0
  189. package/dist/db/transaction-serialization.d.ts +6 -0
  190. package/dist/db/transaction-serialization.js +60 -0
  191. package/dist/derivatives/delete-stored-file.js +1 -1
  192. package/dist/derivatives/index.d.ts +2 -5
  193. package/dist/derivatives/index.js +2 -3
  194. package/dist/engine/access.d.ts +2 -1
  195. package/dist/engine/access.js +1 -1
  196. package/dist/engine/boot-validator/entity-handler.d.ts +2 -1
  197. package/dist/engine/boot-validator/entity-handler.js +1 -1
  198. package/dist/engine/boot-validator/entity-list-aggregate-options.d.ts +1 -1
  199. package/dist/engine/boot-validator/list-table-aggregate-options.d.ts +1 -1
  200. package/dist/engine/boot-validator/list-table-aggregate-query.d.ts +2 -1
  201. package/dist/engine/boot-validator/nav.d.ts +3 -1
  202. package/dist/engine/boot-validator/nav.js +1 -1
  203. package/dist/engine/boot-validator/ownership.d.ts +2 -1
  204. package/dist/engine/boot-validator/parent-ref.d.ts +2 -1
  205. package/dist/engine/boot-validator/projection-list-screens.d.ts +2 -1
  206. package/dist/engine/boot-validator/query-refs.d.ts +2 -1
  207. package/dist/engine/boot-validator/screens-forms.d.ts +2 -1
  208. package/dist/engine/boot-validator/screens-kind-shared.d.ts +3 -1
  209. package/dist/engine/boot-validator/screens.d.ts +2 -1
  210. package/dist/engine/boot-validator/workspaces.d.ts +3 -1
  211. package/dist/engine/bridge-stub.d.ts +5 -2
  212. package/dist/engine/bridge-stub.js +39 -24
  213. package/dist/engine/config-helpers.d.ts +2 -2
  214. package/dist/engine/config-helpers.js +0 -9
  215. package/dist/engine/constants.d.ts +0 -10
  216. package/dist/engine/constants.js +0 -8
  217. package/dist/engine/create-app.js +1 -1
  218. package/dist/engine/define-feature.d.ts +2 -1
  219. package/dist/engine/define-feature.js +1 -2
  220. package/dist/engine/define-handler.d.ts +1 -1
  221. package/dist/engine/define-step.d.ts +0 -1
  222. package/dist/engine/define-step.js +0 -3
  223. package/dist/engine/embedded-derived.d.ts +1 -1
  224. package/dist/engine/entity-handlers.d.ts +2 -1
  225. package/dist/engine/entity-handlers.js +7 -7
  226. package/dist/engine/entity-list-runtime-options.js +3 -1
  227. package/dist/engine/entity-list-searchability.d.ts +2 -1
  228. package/dist/engine/event-def.d.ts +2 -1
  229. package/dist/engine/event-helpers.d.ts +3 -1
  230. package/dist/engine/event-helpers.js +3 -3
  231. package/dist/engine/extension-names.d.ts +2 -8
  232. package/dist/engine/extension-names.js +2 -2
  233. package/dist/engine/extension-selector-plugins.d.ts +1 -1
  234. package/dist/engine/extensions/storage-provider.d.ts +1 -2
  235. package/dist/engine/extensions/user-data.d.ts +0 -8
  236. package/dist/engine/factories.d.ts +2 -1
  237. package/dist/engine/feature-builder-state.d.ts +8 -1
  238. package/dist/engine/feature-changelog.d.ts +1 -1
  239. package/dist/engine/feature-config-events-jobs.d.ts +4 -1
  240. package/dist/engine/feature-entity-handlers.d.ts +5 -1
  241. package/dist/engine/feature-manifest.js +1 -1
  242. package/dist/engine/feature-ui-extensions.d.ts +7 -1
  243. package/dist/engine/feature-ui-extensions.js +6 -4
  244. package/dist/engine/field-access.d.ts +2 -1
  245. package/dist/engine/handler-field-references.d.ts +0 -4
  246. package/dist/engine/index.d.ts +57 -54
  247. package/dist/engine/index.js +22 -27
  248. package/dist/engine/instruction-fields.d.ts +1 -1
  249. package/dist/engine/personal-data-fields.d.ts +1 -1
  250. package/dist/engine/qualified-name.d.ts +0 -1
  251. package/dist/engine/read-claim.d.ts +2 -1
  252. package/dist/engine/registry-facade.js +0 -3
  253. package/dist/engine/registry-ingest.d.ts +2 -1
  254. package/dist/engine/registry-ingest.js +1 -2
  255. package/dist/engine/registry-state.d.ts +12 -2
  256. package/dist/engine/registry-state.js +2 -3
  257. package/dist/engine/registry-validate.d.ts +3 -1
  258. package/dist/engine/registry-validate.js +7 -7
  259. package/dist/engine/run-in.d.ts +1 -1
  260. package/dist/engine/run-in.js +0 -1
  261. package/dist/engine/schema-builder.d.ts +1 -1
  262. package/dist/engine/schema-builder.js +1 -1
  263. package/dist/engine/screen-filter-ops.d.ts +2 -1
  264. package/dist/engine/screen-filter-ops.js +0 -5
  265. package/dist/engine/soft-delete-cleanup.d.ts +1 -1
  266. package/dist/engine/soft-delete-cleanup.js +4 -4
  267. package/dist/engine/state-machine.js +2 -1
  268. package/dist/engine/steps/_read-source.js +1 -1
  269. package/dist/engine/steps/aggregate-append-event.js +2 -2
  270. package/dist/engine/steps/call-feature.js +2 -2
  271. package/dist/engine/steps/mail-send.js +1 -1
  272. package/dist/engine/steps/retry.js +1 -1
  273. package/dist/engine/steps/wait-for-event.js +1 -1
  274. package/dist/engine/steps/wait.js +1 -1
  275. package/dist/engine/steps/webhook-send.js +1 -1
  276. package/dist/engine/template-variables.d.ts +2 -1
  277. package/dist/engine/transfer-adjacency.d.ts +1 -1
  278. package/dist/engine/types/index.d.ts +8 -31
  279. package/dist/engine/types/index.js +2 -10
  280. package/dist/engine/validation.d.ts +2 -1
  281. package/dist/entrypoint/index.d.ts +7 -35
  282. package/dist/entrypoint/index.js +7 -1
  283. package/dist/entrypoint/internals.d.ts +40 -0
  284. package/dist/entrypoint/internals.js +1 -0
  285. package/dist/entrypoint/row-level-security-mode-check.d.ts +3 -0
  286. package/dist/entrypoint/row-level-security-mode-check.js +19 -0
  287. package/dist/env/dry-run-internals.d.ts +10 -0
  288. package/dist/env/dry-run-internals.js +1 -0
  289. package/dist/env/dry-run.d.ts +1 -10
  290. package/dist/env/dry-run.js +2 -1
  291. package/dist/env/index.d.ts +1 -85
  292. package/dist/env/index.js +6 -50
  293. package/dist/env/internals.d.ts +87 -0
  294. package/dist/env/internals.js +53 -0
  295. package/dist/errors/classes.js +2 -2
  296. package/dist/errors/index.d.ts +5 -14
  297. package/dist/errors/index.js +4 -9
  298. package/dist/errors/member-resolution.js +1 -1
  299. package/dist/errors/reasons.d.ts +0 -1
  300. package/dist/errors/reasons.js +7 -7
  301. package/dist/errors/serialize.d.ts +0 -18
  302. package/dist/errors/serialize.js +0 -27
  303. package/dist/es-ops/index.d.ts +4 -4
  304. package/dist/es-ops/index.js +2 -2
  305. package/dist/es-ops/operations-schema.d.ts +1 -1
  306. package/dist/es-ops/types.d.ts +4 -5
  307. package/dist/event-store/admin-api-internals.d.ts +14 -0
  308. package/dist/event-store/admin-api-internals.js +1 -0
  309. package/dist/event-store/admin-api.d.ts +1 -14
  310. package/dist/event-store/admin-api.js +11 -6
  311. package/dist/event-store/archive.js +4 -2
  312. package/dist/event-store/errors.js +2 -2
  313. package/dist/event-store/event-store.js +41 -34
  314. package/dist/event-store/events-schema.js +4 -1
  315. package/dist/event-store/index.d.ts +11 -13
  316. package/dist/event-store/index.js +7 -9
  317. package/dist/event-store/rebuild-dead-letter.js +4 -2
  318. package/dist/event-store/snapshot.js +4 -3
  319. package/dist/event-store/stream-scope.d.ts +2 -0
  320. package/dist/event-store/stream-scope.js +6 -0
  321. package/dist/event-store/upcaster-dead-letter.js +4 -2
  322. package/dist/event-store/upcaster.d.ts +2 -1
  323. package/dist/files/action-form-upload.d.ts +2 -1
  324. package/dist/files/action-form-upload.js +1 -1
  325. package/dist/files/assert-file-refs-belong-to-tenant.d.ts +2 -1
  326. package/dist/files/assert-file-refs-belong-to-tenant.js +1 -1
  327. package/dist/files/bind-pending-file-refs.d.ts +2 -1
  328. package/dist/files/bind-pending-file-refs.js +2 -1
  329. package/dist/files/bind-referenced-files.write.js +1 -1
  330. package/dist/files/create-file-ref-from-bytes.d.ts +6 -3
  331. package/dist/files/create-file-ref-from-bytes.js +3 -3
  332. package/dist/files/create-file-ref.d.ts +3 -2
  333. package/dist/files/create-file-ref.js +2 -2
  334. package/dist/files/dispose-removed-file-refs.d.ts +2 -1
  335. package/dist/files/dispose-removed-file-refs.js +1 -1
  336. package/dist/files/feature.js +2 -2
  337. package/dist/files/file-handle.js +1 -1
  338. package/dist/files/file-routes.d.ts +1 -1
  339. package/dist/files/file-routes.js +12 -2
  340. package/dist/files/index.d.ts +11 -13
  341. package/dist/files/index.js +5 -7
  342. package/dist/files/load-save-file-refs.d.ts +2 -1
  343. package/dist/files/load-save-file-refs.js +1 -1
  344. package/dist/files/provider-resolver.d.ts +5 -4
  345. package/dist/files/provider-resolver.js +4 -4
  346. package/dist/files/storage-tracking.js +4 -2
  347. package/dist/files/sweep-orphaned-uploads.d.ts +1 -1
  348. package/dist/files/sweep-orphaned-uploads.js +1 -1
  349. package/dist/i18n/index.d.ts +2 -8
  350. package/dist/i18n/index.js +1 -1
  351. package/dist/i18n/internals.d.ts +7 -0
  352. package/dist/i18n/internals.js +1 -0
  353. package/dist/i18n/required-surface-keys.d.ts +4 -1
  354. package/dist/internal/row-level-security.d.ts +3 -0
  355. package/dist/internal/row-level-security.js +3 -0
  356. package/dist/internal/stack-support.d.ts +1 -1
  357. package/dist/internal/stack-support.js +1 -1
  358. package/dist/internal/testing.d.ts +1 -0
  359. package/dist/internal/testing.js +9 -5
  360. package/dist/jobs/index.d.ts +1 -1
  361. package/dist/jobs/job-append-event.d.ts +12 -0
  362. package/dist/jobs/job-append-event.js +30 -0
  363. package/dist/jobs/job-runner-context.d.ts +2 -2
  364. package/dist/jobs/job-runner-context.js +46 -16
  365. package/dist/jobs/job-runner-execution.d.ts +1 -1
  366. package/dist/jobs/job-runner-execution.js +6 -4
  367. package/dist/jobs/job-runner-gates.d.ts +1 -1
  368. package/dist/jobs/job-runner-gates.js +0 -1
  369. package/dist/jobs/job-runner-helpers.d.ts +11 -4
  370. package/dist/jobs/job-runner-helpers.js +10 -1
  371. package/dist/jobs/job-runner-scope.d.ts +5 -2
  372. package/dist/jobs/job-runner-types.d.ts +2 -1
  373. package/dist/jobs/job-runner.js +19 -6
  374. package/dist/jobs/max-per-tenant.d.ts +1 -1
  375. package/dist/logging/index.d.ts +1 -2
  376. package/dist/logging/index.js +1 -1
  377. package/dist/logging/pino-logger.js +1 -1
  378. package/dist/logging/utils.d.ts +1 -0
  379. package/dist/logging/utils.js +6 -0
  380. package/dist/migrations/index.d.ts +3 -3
  381. package/dist/migrations/index.js +3 -3
  382. package/dist/migrations/pending-rebuilds.d.ts +1 -1
  383. package/dist/migrations/pending-rebuilds.js +1 -1
  384. package/dist/migrations/pii-event-backfill.js +4 -1
  385. package/dist/observability/escape-hatch-report.d.ts +2 -1
  386. package/dist/observability/index.d.ts +7 -15
  387. package/dist/observability/index.js +4 -12
  388. package/dist/observability/metric-validator.js +1 -1
  389. package/dist/observability/metrics-handle.d.ts +0 -1
  390. package/dist/observability/metrics-handle.js +2 -15
  391. package/dist/observability/recording-tracer.d.ts +1 -2
  392. package/dist/observability/recording-tracer.js +0 -6
  393. package/dist/observability/sensitive-filter.d.ts +0 -2
  394. package/dist/observability/sensitive-filter.js +0 -29
  395. package/dist/pipeline/active-membership.d.ts +2 -1
  396. package/dist/pipeline/active-membership.js +6 -2
  397. package/dist/pipeline/append-event-core.d.ts +2 -1
  398. package/dist/pipeline/append-event-core.js +2 -2
  399. package/dist/pipeline/attach-outside-transaction.d.ts +3 -0
  400. package/dist/pipeline/attach-outside-transaction.js +13 -0
  401. package/dist/pipeline/auth-claims-resolver.d.ts +2 -1
  402. package/dist/pipeline/cascade-handler.d.ts +2 -1
  403. package/dist/pipeline/cascade-handler.js +3 -2
  404. package/dist/pipeline/config-accessor-factory.d.ts +1 -1
  405. package/dist/pipeline/config-accessor-factory.js +1 -1
  406. package/dist/pipeline/context-services.d.ts +56 -0
  407. package/dist/pipeline/context-services.js +73 -0
  408. package/dist/pipeline/dispatch-batch.d.ts +2 -1
  409. package/dist/pipeline/dispatch-batch.js +31 -18
  410. package/dist/pipeline/dispatch-query.js +5 -4
  411. package/dist/pipeline/dispatch-scope.d.ts +6 -0
  412. package/dist/pipeline/dispatch-scope.js +27 -0
  413. package/dist/pipeline/dispatch-shared.d.ts +13 -9
  414. package/dist/pipeline/dispatch-shared.js +75 -198
  415. package/dist/pipeline/dispatch-stream.js +8 -4
  416. package/dist/pipeline/dispatch-write.d.ts +2 -1
  417. package/dist/pipeline/dispatch-write.js +10 -8
  418. package/dist/pipeline/dispatcher-utils.d.ts +3 -1
  419. package/dist/pipeline/dispatcher-utils.js +8 -2
  420. package/dist/pipeline/dispatcher.d.ts +3 -2
  421. package/dist/pipeline/dispatcher.js +4 -3
  422. package/dist/pipeline/event-consumer-state.d.ts +0 -1
  423. package/dist/pipeline/event-dispatcher-delivery.d.ts +1 -1
  424. package/dist/pipeline/event-dispatcher-delivery.js +4 -2
  425. package/dist/pipeline/event-dispatcher.d.ts +2 -2
  426. package/dist/pipeline/event-dispatcher.js +7 -3
  427. package/dist/pipeline/event-retention.js +59 -56
  428. package/dist/pipeline/handler-access-error.js +2 -1
  429. package/dist/pipeline/handler-context-auth.d.ts +5 -6
  430. package/dist/pipeline/handler-context-auth.js +7 -4
  431. package/dist/pipeline/handler-context-config.d.ts +2 -5
  432. package/dist/pipeline/handler-context-config.js +2 -2
  433. package/dist/pipeline/handler-context-db.d.ts +32 -7
  434. package/dist/pipeline/handler-context-db.js +26 -17
  435. package/dist/pipeline/handler-context-dispatch.d.ts +13 -7
  436. package/dist/pipeline/handler-context-dispatch.js +9 -8
  437. package/dist/pipeline/handler-context-events.d.ts +22 -36
  438. package/dist/pipeline/handler-context-events.js +36 -31
  439. package/dist/pipeline/handler-context-member-resolution.d.ts +2 -0
  440. package/dist/pipeline/handler-context-member-resolution.js +110 -0
  441. package/dist/pipeline/handler-context-notify.d.ts +3 -2
  442. package/dist/pipeline/handler-context-notify.js +1 -1
  443. package/dist/pipeline/handler-context-observability.d.ts +2 -4
  444. package/dist/pipeline/handler-context-observability.js +7 -5
  445. package/dist/pipeline/handler-context-phase-denials.d.ts +11 -0
  446. package/dist/pipeline/handler-context-phase-denials.js +98 -0
  447. package/dist/pipeline/handler-context-scope.d.ts +7 -10
  448. package/dist/pipeline/handler-context-scope.js +18 -20
  449. package/dist/pipeline/index.d.ts +9 -21
  450. package/dist/pipeline/index.js +5 -7
  451. package/dist/pipeline/irreversible-operation-gate.d.ts +1 -1
  452. package/dist/pipeline/irreversible-operation-gate.js +2 -2
  453. package/dist/pipeline/lifecycle-pipeline.d.ts +8 -7
  454. package/dist/pipeline/lifecycle-pipeline.js +9 -15
  455. package/dist/pipeline/member-read-only-transaction.js +11 -3
  456. package/dist/pipeline/member-reader.d.ts +1 -1
  457. package/dist/pipeline/member-reader.js +2 -2
  458. package/dist/pipeline/msp-rebuild.js +5 -3
  459. package/dist/pipeline/multi-stream-apply-context.js +3 -2
  460. package/dist/pipeline/notify-scope.d.ts +2 -1
  461. package/dist/pipeline/pre-handler-gates.d.ts +2 -1
  462. package/dist/pipeline/pre-transaction-reservations.d.ts +3 -3
  463. package/dist/pipeline/pre-transaction-reservations.js +9 -7
  464. package/dist/pipeline/projection-rebuild.js +12 -5
  465. package/dist/pipeline/projection-state.d.ts +0 -6
  466. package/dist/pipeline/projection-state.js +0 -5
  467. package/dist/pipeline/projections-runner.d.ts +2 -1
  468. package/dist/pipeline/projections-runner.js +10 -6
  469. package/dist/pipeline/system-hooks.d.ts +3 -1
  470. package/dist/pipeline/system-hooks.js +6 -4
  471. package/dist/pipeline/system-identity-switch.d.ts +4 -2
  472. package/dist/pipeline/system-identity-switch.js +51 -36
  473. package/dist/pipeline/typed-append-event.d.ts +2 -0
  474. package/dist/pipeline/typed-append-event.js +4 -0
  475. package/dist/pipeline/write-origin.js +2 -2
  476. package/dist/pipeline/write-result-masking.d.ts +1 -1
  477. package/dist/random/index.d.ts +1 -2
  478. package/dist/random/index.js +1 -2
  479. package/dist/rate-limit/bucket.d.ts +2 -1
  480. package/dist/rate-limit/middleware.js +2 -1
  481. package/dist/redis/index.d.ts +3 -4
  482. package/dist/redis/index.js +2 -2
  483. package/dist/schema-cli/apply-command.js +5 -2
  484. package/dist/schema-cli/baseline-command.js +7 -2
  485. package/dist/schema-cli/generate-command.js +7 -9
  486. package/dist/schema-cli/shared.d.ts +4 -0
  487. package/dist/schema-cli/shared.js +21 -2
  488. package/dist/schema-cli/status-command.js +8 -2
  489. package/dist/schema-cli/validate-command.js +52 -4
  490. package/dist/schema-cli.d.ts +0 -1
  491. package/dist/search/configure-tenant-index.d.ts +1 -3
  492. package/dist/search/configure-tenant-index.js +0 -4
  493. package/dist/search/index.d.ts +1 -4
  494. package/dist/search/index.js +0 -2
  495. package/dist/search/meilisearch-adapter-internals.d.ts +8 -0
  496. package/dist/search/meilisearch-adapter-internals.js +9 -0
  497. package/dist/search/meilisearch-adapter.d.ts +1 -8
  498. package/dist/search/meilisearch-adapter.js +6 -7
  499. package/dist/search/meilisearch-peer.d.ts +2 -0
  500. package/dist/search/meilisearch-peer.js +5 -0
  501. package/dist/search/reindex-entity.js +93 -87
  502. package/dist/secrets/index.d.ts +3 -4
  503. package/dist/secrets/index.js +2 -3
  504. package/dist/seeding/index.d.ts +2 -2
  505. package/dist/seeding/index.js +1 -2
  506. package/dist/time/index.d.ts +2 -2
  507. package/dist/time/index.js +1 -1
  508. package/dist/time/tz-context.d.ts +0 -5
  509. package/dist/time/tz-context.js +0 -9
  510. package/dist/ui-types/index.d.ts +8 -11
  511. package/dist/ui-types/index.js +3 -3
  512. package/dist/upgrade-changelog.d.ts +3 -2
  513. package/dist/upgrade-changelog.js +12 -8
  514. package/dist/upgrade-cli-internals.d.ts +8 -0
  515. package/dist/upgrade-cli-internals.js +63 -0
  516. package/dist/upgrade-cli.d.ts +1 -9
  517. package/dist/upgrade-cli.js +10 -64
  518. package/dist/utils/import-optional-peer.d.ts +6 -0
  519. package/dist/utils/import-optional-peer.js +19 -0
  520. package/dist/utils/index.d.ts +1 -4
  521. package/dist/utils/index.js +1 -4
  522. package/package.json +22 -18
  523. package/src/changes.json +206 -0
  524. package/dist/crypto/request-kms-cache.d.ts +0 -8
  525. package/dist/crypto/request-kms-cache.js +0 -21
  526. package/dist/engine/codemod/index.d.ts +0 -2
  527. package/dist/engine/codemod/index.js +0 -1
  528. package/dist/engine/codemod/pipeline-codemod.d.ts +0 -50
  529. package/dist/engine/codemod/pipeline-codemod.js +0 -536
  530. package/dist/engine/feature-ast/entity-field-types.d.ts +0 -13
  531. package/dist/engine/feature-ast/entity-field-types.js +0 -35
  532. package/dist/engine/feature-ast/extractors/ai-steps.d.ts +0 -6
  533. package/dist/engine/feature-ast/extractors/ai-steps.js +0 -254
  534. package/dist/engine/feature-ast/extractors/events.d.ts +0 -5
  535. package/dist/engine/feature-ast/extractors/events.js +0 -275
  536. package/dist/engine/feature-ast/extractors/handlers.d.ts +0 -24
  537. package/dist/engine/feature-ast/extractors/handlers.js +0 -358
  538. package/dist/engine/feature-ast/extractors/hooks.d.ts +0 -24
  539. package/dist/engine/feature-ast/extractors/hooks.js +0 -248
  540. package/dist/engine/feature-ast/extractors/index.d.ts +0 -14
  541. package/dist/engine/feature-ast/extractors/index.js +0 -13
  542. package/dist/engine/feature-ast/extractors/jobs-routes.d.ts +0 -7
  543. package/dist/engine/feature-ast/extractors/jobs-routes.js +0 -145
  544. package/dist/engine/feature-ast/extractors/projections-screens.d.ts +0 -10
  545. package/dist/engine/feature-ast/extractors/projections-screens.js +0 -195
  546. package/dist/engine/feature-ast/extractors/resolve-import.d.ts +0 -21
  547. package/dist/engine/feature-ast/extractors/resolve-import.js +0 -180
  548. package/dist/engine/feature-ast/extractors/round1.d.ts +0 -11
  549. package/dist/engine/feature-ast/extractors/round1.js +0 -87
  550. package/dist/engine/feature-ast/extractors/round2.d.ts +0 -7
  551. package/dist/engine/feature-ast/extractors/round2.js +0 -191
  552. package/dist/engine/feature-ast/extractors/round3.d.ts +0 -23
  553. package/dist/engine/feature-ast/extractors/round3.js +0 -292
  554. package/dist/engine/feature-ast/extractors/round5.d.ts +0 -9
  555. package/dist/engine/feature-ast/extractors/round5.js +0 -68
  556. package/dist/engine/feature-ast/extractors/round6.d.ts +0 -4
  557. package/dist/engine/feature-ast/extractors/round6.js +0 -17
  558. package/dist/engine/feature-ast/extractors/shared.d.ts +0 -94
  559. package/dist/engine/feature-ast/extractors/shared.js +0 -343
  560. package/dist/engine/feature-ast/index.d.ts +0 -16
  561. package/dist/engine/feature-ast/index.js +0 -10
  562. package/dist/engine/feature-ast/parse.d.ts +0 -31
  563. package/dist/engine/feature-ast/parse.js +0 -485
  564. package/dist/engine/feature-ast/patch.d.ts +0 -212
  565. package/dist/engine/feature-ast/patch.js +0 -611
  566. package/dist/engine/feature-ast/patcher.d.ts +0 -217
  567. package/dist/engine/feature-ast/patcher.js +0 -281
  568. package/dist/engine/feature-ast/pattern-change-schema.d.ts +0 -1238
  569. package/dist/engine/feature-ast/pattern-change-schema.js +0 -1072
  570. package/dist/engine/feature-ast/pattern-id-matchers.d.ts +0 -7
  571. package/dist/engine/feature-ast/pattern-id-matchers.js +0 -211
  572. package/dist/engine/feature-ast/pattern-id-schema.d.ts +0 -251
  573. package/dist/engine/feature-ast/pattern-id-schema.js +0 -166
  574. package/dist/engine/feature-ast/patterns.d.ts +0 -322
  575. package/dist/engine/feature-ast/patterns.js +0 -107
  576. package/dist/engine/feature-ast/render.d.ts +0 -47
  577. package/dist/engine/feature-ast/render.js +0 -666
  578. package/dist/engine/feature-ast/source-location.d.ts +0 -17
  579. package/dist/engine/feature-ast/source-location.js +0 -27
  580. package/dist/engine/pattern-library/index.d.ts +0 -2
  581. package/dist/engine/pattern-library/index.js +0 -3
  582. package/dist/engine/pattern-library/library.d.ts +0 -14
  583. package/dist/engine/pattern-library/library.js +0 -94
  584. package/dist/engine/pattern-library/mixed-schemas.d.ts +0 -16
  585. package/dist/engine/pattern-library/mixed-schemas.js +0 -559
  586. package/dist/engine/pattern-library/opaque-schemas.d.ts +0 -7
  587. package/dist/engine/pattern-library/opaque-schemas.js +0 -115
  588. package/dist/engine/pattern-library/shared-fields.d.ts +0 -122
  589. package/dist/engine/pattern-library/shared-fields.js +0 -88
  590. package/dist/engine/pattern-library/static-schemas.d.ts +0 -21
  591. package/dist/engine/pattern-library/static-schemas.js +0 -487
  592. package/dist/engine/pattern-library/types.d.ts +0 -158
  593. package/dist/engine/pattern-library/types.js +0 -36
  594. package/dist/engine/resolve-config-or-param.d.ts +0 -18
  595. package/dist/engine/resolve-config-or-param.js +0 -76
  596. package/src/scripts/codemod/README.md +0 -187
  597. package/src/scripts/codemod/codemod-support.ts +0 -334
  598. package/src/scripts/codemod/collect-source-files.ts +0 -48
  599. package/src/scripts/codemod/crypto-shredding-testing-move.ts +0 -119
  600. package/src/scripts/codemod/db-factory.ts +0 -810
  601. package/src/scripts/codemod/feature-factory.ts +0 -429
  602. package/src/scripts/codemod/feature-layout.ts +0 -424
  603. package/src/scripts/codemod/import-extensions.ts +0 -118
  604. package/src/scripts/codemod/migrate-cross-tenant.ts +0 -328
  605. package/src/scripts/codemod/migrate-db-raw.ts +0 -401
  606. package/src/scripts/codemod/migrate-open-to-all.ts +0 -235
  607. package/src/scripts/codemod/object-form.ts +0 -746
  608. package/src/scripts/codemod/package-merge.ts +0 -299
  609. package/src/scripts/codemod/pii-personal-migration.ts +0 -816
  610. package/src/scripts/codemod/remove-engine-payload-casts.ts +0 -318
  611. package/src/scripts/codemod/s3-imports.ts +0 -236
  612. package/src/scripts/codemod/tenant-db-options.ts +0 -454
  613. package/src/scripts/codemod/testing-injection.ts +0 -215
  614. package/src/scripts/codemod/testing-move-targets.ts +0 -161
  615. package/src/scripts/codemod/testing-move.ts +0 -542
  616. package/src/scripts/codemod/unprocessable-error-details-reason.ts +0 -411
@@ -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";
@@ -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
  export declare function disposeRemovedFileRefs(args: {
4
5
  readonly registry: Registry;
5
6
  readonly result: SaveContext;
@@ -1,4 +1,4 @@
1
- import { isFileField, } from "../engine/types/index.js";
1
+ import { isFileField } from "../engine/field-helpers.js";
2
2
  import { reraiseAsKumikoError } from "../errors/index.js";
3
3
  import { fileRefIdsOf } from "./bind-pending-file-refs.js";
4
4
  import { getFileRefExecutor } from "./create-file-ref.js";
@@ -41,10 +41,10 @@ export function createFilesFeature(options = {}) {
41
41
  handler: async (_payload, ctx) => {
42
42
  await sweepOrphanedUploads({
43
43
  db: ctx.db,
44
- files: ctx.files,
44
+ files: ctx.services.files,
45
45
  now: ctx.tz.now(),
46
46
  graceHours: uploadSweepGraceHours,
47
- log: ctx.log,
47
+ log: ctx.obs.log,
48
48
  });
49
49
  },
50
50
  });
@@ -3,7 +3,7 @@
3
3
  // The contract the framework exposes to hook/handler code: a FileHandle lets
4
4
  // you read/write/delete the binary behind a storage key without ever passing
5
5
  // the binary through event payloads, job queues, or hook signatures. Events
6
- // carry the key, hooks reach for `ctx.files.ref(key)` when they actually need
6
+ // carry the key, hooks reach for `ctx.services.files.ref(key)` when they actually need
7
7
  // the bytes, and big files stay in the storage layer where they belong.
8
8
  //
9
9
  // `derive(suffix)` is the primitive for thumbnail/variant keys: it inserts a
@@ -2,7 +2,7 @@ import type { RateLimitResolver } from "@cosmicdrift/kumiko-types/rate-limit-typ
2
2
  import type { WriteErrorInfo } from "@cosmicdrift/kumiko-types/write-error-info-types";
3
3
  import { Hono } from "hono";
4
4
  import type { DbConnection } from "../db/connection.ts";
5
- import { type Registry, type SessionUser, type TenantId } from "../engine/types/index.ts";
5
+ import type { Registry, SessionUser, TenantId } from "../engine/types/index.ts";
6
6
  import type { FileProviderResolver } from "./provider-resolver.ts";
7
7
  import type { RecordReadCheck } from "./record-read-check.ts";
8
8
  import { type RecordWriteCheck } from "./record-write-check.ts";