@cosmicdrift/kumiko-framework 0.388.0 → 0.390.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (711) hide show
  1. package/AGENTS.md +12 -4
  2. package/README.md +1 -1
  3. package/agents/examples/apex-surface-auth.md +2 -3
  4. package/agents/examples/api-worker-split.md +9 -2
  5. package/agents/examples/auth-claims.md +1 -1
  6. package/agents/examples/cross-feature-events.md +12 -12
  7. package/agents/examples/crypto-shredding-hr.md +2 -2
  8. package/agents/examples/encrypted-tenant-config.md +1 -1
  9. package/agents/examples/error-contract.md +12 -7
  10. package/agents/examples/event-sourcing.md +29 -29
  11. package/agents/examples/files-post-processing.md +10 -8
  12. package/agents/examples/golden-path.md +13 -1
  13. package/agents/examples/inbound-mail-triage.md +1 -0
  14. package/agents/examples/lane-routing.md +2 -1
  15. package/agents/examples/legal-pages.md +2 -2
  16. package/agents/examples/lifecycle-hooks.md +55 -2
  17. package/agents/examples/list-table-options.md +466 -0
  18. package/agents/examples/managed-config.md +4 -4
  19. package/agents/examples/managed-pages.md +1 -1
  20. package/agents/examples/pdf-audit-export.md +4 -2
  21. package/agents/examples/relations.md +19 -4
  22. package/agents/examples/search.md +4 -4
  23. package/agents/examples/secrets-demo.md +9 -6
  24. package/agents/examples/state-machine.md +5 -4
  25. package/agents/examples/tenant-isolation.md +73 -1
  26. package/agents/examples/tenant-settings.md +1 -1
  27. package/agents/examples/user-data-rights.md +3 -6
  28. package/agents/examples/workflow-engine.md +53 -47
  29. package/agents/examples.md +5 -4
  30. package/agents/features.md +1 -1
  31. package/agents/widgets.md +1 -0
  32. package/dist/api/api-constants.d.ts +1 -0
  33. package/dist/api/api-constants.js +2 -0
  34. package/dist/api/auth-middleware.js +1 -1
  35. package/dist/api/auth-routes-invite.js +2 -1
  36. package/dist/api/auth-routes-shared.d.ts +2 -0
  37. package/dist/api/auth-routes-shared.js +5 -0
  38. package/dist/api/client-error-route.js +2 -3
  39. package/dist/api/entity-read-access.d.ts +4 -1
  40. package/dist/api/entity-read-access.js +14 -0
  41. package/dist/api/export/export-cells-reference.d.ts +9 -0
  42. package/dist/api/export/export-cells-reference.js +21 -0
  43. package/dist/api/export/export-cells.d.ts +11 -0
  44. package/dist/api/export/export-cells.js +136 -0
  45. package/dist/api/export/export-ciphertext-guard.d.ts +2 -0
  46. package/dist/api/export/export-ciphertext-guard.js +27 -0
  47. package/dist/api/export/export-columns.d.ts +31 -0
  48. package/dist/api/export/export-columns.js +85 -0
  49. package/dist/api/export/export-errors.d.ts +4 -0
  50. package/dist/api/export/export-errors.js +14 -0
  51. package/dist/api/export/export-route.d.ts +4 -0
  52. package/dist/api/export/export-route.js +75 -0
  53. package/dist/api/export/export-rows.d.ts +13 -0
  54. package/dist/api/export/export-rows.js +62 -0
  55. package/dist/api/export/export-screen.d.ts +13 -0
  56. package/dist/api/export/export-screen.js +47 -0
  57. package/dist/api/export/export-xlsx-writer.d.ts +4 -0
  58. package/dist/api/export/export-xlsx-writer.js +21 -0
  59. package/dist/api/extra-route.d.ts +7 -1
  60. package/dist/api/index.d.ts +23 -27
  61. package/dist/api/index.js +13 -15
  62. package/dist/api/jwt.js +1 -1
  63. package/dist/api/observability-middleware.d.ts +1 -1
  64. package/dist/api/observability-middleware.js +2 -1
  65. package/dist/api/pii-leak-guard.d.ts +3 -0
  66. package/dist/api/pii-leak-guard.js +3 -2
  67. package/dist/api/request-context-internals.d.ts +31 -0
  68. package/dist/api/request-context-internals.js +11 -0
  69. package/dist/api/request-context-scopes.d.ts +14 -0
  70. package/dist/api/request-context-scopes.js +69 -0
  71. package/dist/api/request-context.d.ts +1 -40
  72. package/dist/api/request-context.js +22 -51
  73. package/dist/api/request-id-middleware.d.ts +1 -1
  74. package/dist/api/route-registrars.d.ts +2 -1
  75. package/dist/api/route-registrars.js +1 -1
  76. package/dist/api/routes.d.ts +16 -0
  77. package/dist/api/routes.js +9 -5
  78. package/dist/api/server-boot-checks.d.ts +1 -1
  79. package/dist/api/server-boot-checks.js +2 -2
  80. package/dist/api/server-event-dispatcher.d.ts +6 -1
  81. package/dist/api/server-event-dispatcher.js +3 -4
  82. package/dist/api/server-extra-routes.d.ts +1 -1
  83. package/dist/api/server-extra-routes.js +5 -1
  84. package/dist/api/server-middleware.js +3 -1
  85. package/dist/api/server-routes.d.ts +3 -2
  86. package/dist/api/server-routes.js +8 -2
  87. package/dist/api/server-wiring.js +8 -4
  88. package/dist/api/server.d.ts +2 -1
  89. package/dist/api/sse-route.d.ts +3 -1
  90. package/dist/api/sse-route.js +11 -1
  91. package/dist/api/tenant-scoped-secrets.d.ts +2 -0
  92. package/dist/api/tenant-scoped-secrets.js +13 -0
  93. package/dist/api/websocket-route.d.ts +1 -1
  94. package/dist/auth/index.d.ts +0 -1
  95. package/dist/auth/roles.d.ts +0 -5
  96. package/dist/compliance/duration-spec.d.ts +0 -1
  97. package/dist/compliance/duration-spec.js +0 -5
  98. package/dist/compliance/index.d.ts +4 -4
  99. package/dist/compliance/index.js +2 -2
  100. package/dist/compliance/profiles.d.ts +0 -15
  101. package/dist/compliance/profiles.js +0 -23
  102. package/dist/config/index.d.ts +11 -9
  103. package/dist/config/index.js +13 -1
  104. package/dist/config/internals.d.ts +9 -0
  105. package/dist/config/internals.js +1 -0
  106. package/dist/consumer-cli-internals.d.ts +4 -0
  107. package/dist/consumer-cli-internals.js +1 -0
  108. package/dist/consumer-cli.d.ts +1 -4
  109. package/dist/consumer-cli.js +5 -1
  110. package/dist/crypto/event-pii.js +1 -1
  111. package/dist/crypto/index.d.ts +8 -9
  112. package/dist/crypto/index.js +7 -8
  113. package/dist/crypto/pg-kms-adapter.d.ts +1 -0
  114. package/dist/crypto/pg-kms-adapter.js +17 -18
  115. package/dist/db/aggregate-sql.d.ts +2 -0
  116. package/dist/db/aggregate-sql.js +10 -0
  117. package/dist/db/apply-entity-event.d.ts +1 -1
  118. package/dist/db/apply-entity-event.js +15 -47
  119. package/dist/db/blind-index-cleanup.js +91 -77
  120. package/dist/db/closed-connection.js +12 -19
  121. package/dist/db/collect-table-metas.js +1 -1
  122. package/dist/db/compound-types.d.ts +1 -1
  123. package/dist/db/compound-types.js +0 -7
  124. package/dist/db/config-seed.d.ts +2 -1
  125. package/dist/db/config-seed.js +6 -1
  126. package/dist/db/connection.d.ts +7 -6
  127. package/dist/db/connection.js +43 -24
  128. package/dist/db/cross-tenant-reads.d.ts +1 -1
  129. package/dist/db/cross-tenant-reads.js +1 -1
  130. package/dist/db/dialect.d.ts +0 -5
  131. package/dist/db/dialect.js +0 -3
  132. package/dist/db/driver-row-coercion.js +4 -4
  133. package/dist/db/driver-value-preparation.js +6 -4
  134. package/dist/db/eagerload.d.ts +2 -1
  135. package/dist/db/entity-field-encryption.d.ts +1 -1
  136. package/dist/db/entity-table-meta.d.ts +1 -1
  137. package/dist/db/event-store-executor-context.d.ts +3 -1
  138. package/dist/db/event-store-executor-context.js +4 -3
  139. package/dist/db/event-store-executor-read-aggregate-currencies.d.ts +17 -0
  140. package/dist/db/event-store-executor-read-aggregate-currencies.js +40 -0
  141. package/dist/db/event-store-executor-read-aggregate.js +36 -5
  142. package/dist/db/event-store-executor-read-filter.d.ts +1 -1
  143. package/dist/db/event-store-executor-read-filter.js +6 -3
  144. package/dist/db/event-store-executor-read-rows.d.ts +2 -1
  145. package/dist/db/event-store-executor-read-search.d.ts +2 -1
  146. package/dist/db/event-store-executor-read-sort.d.ts +2 -1
  147. package/dist/db/event-store-executor-read.js +2 -2
  148. package/dist/db/event-store-executor-write-atomic.d.ts +4 -0
  149. package/dist/db/event-store-executor-write-atomic.js +42 -0
  150. package/dist/db/event-store-executor-write-steps.d.ts +3 -5
  151. package/dist/db/event-store-executor-write-steps.js +0 -5
  152. package/dist/db/event-store-executor-write.js +22 -19
  153. package/dist/db/event-store-executor.d.ts +1 -1
  154. package/dist/db/event-store-executor.js +2 -1
  155. package/dist/db/executor-managed-tables.d.ts +7 -1
  156. package/dist/db/executor-managed-tables.js +12 -3
  157. package/dist/db/index.d.ts +29 -28
  158. package/dist/db/index.js +22 -20
  159. package/dist/db/known-table-names.d.ts +6 -0
  160. package/dist/db/known-table-names.js +21 -0
  161. package/dist/db/list-aggregate-labels.d.ts +1 -1
  162. package/dist/db/located-timestamp.d.ts +1 -1
  163. package/dist/db/located-timestamp.js +0 -5
  164. package/dist/db/migrate-generator.d.ts +17 -1
  165. package/dist/db/migrate-generator.js +50 -20
  166. package/dist/db/migrate-primary-key.d.ts +12 -0
  167. package/dist/db/migrate-primary-key.js +45 -0
  168. package/dist/db/migrate-rls-diff.d.ts +20 -0
  169. package/dist/db/migrate-rls-diff.js +61 -0
  170. package/dist/db/migrate-runner.js +7 -3
  171. package/dist/db/money.d.ts +1 -1
  172. package/dist/db/money.js +1 -1
  173. package/dist/db/parent-ref-clause.d.ts +2 -1
  174. package/dist/db/pg-error.d.ts +2 -0
  175. package/dist/db/pg-error.js +37 -21
  176. package/dist/db/queries/backfill-pii.js +3 -6
  177. package/dist/db/queries/database-now.js +2 -1
  178. package/dist/db/queries/ddl.d.ts +3 -0
  179. package/dist/db/queries/ddl.js +34 -1
  180. package/dist/db/queries/event-store.js +4 -2
  181. package/dist/db/queries/event-tenants.d.ts +2 -0
  182. package/dist/db/queries/event-tenants.js +17 -0
  183. package/dist/db/queries/rebuild-rls-guard.d.ts +2 -0
  184. package/dist/db/queries/rebuild-rls-guard.js +29 -0
  185. package/dist/db/queries/rls-boot-catalog.d.ts +16 -0
  186. package/dist/db/queries/rls-boot-catalog.js +39 -0
  187. package/dist/db/queries/rls-catalog.d.ts +6 -0
  188. package/dist/db/queries/rls-catalog.js +82 -0
  189. package/dist/db/queries/rls-scope.d.ts +3 -0
  190. package/dist/db/queries/rls-scope.js +17 -0
  191. package/dist/db/queries/rls-shape.d.ts +10 -0
  192. package/dist/db/queries/rls-shape.js +42 -0
  193. package/dist/db/queries/session-advisory-lock.d.ts +2 -0
  194. package/dist/db/queries/session-advisory-lock.js +23 -0
  195. package/dist/db/queries/shadow-swap.d.ts +1 -2
  196. package/dist/db/queries/shadow-swap.js +11 -28
  197. package/dist/db/queries/test-stack.d.ts +4 -1
  198. package/dist/db/queries/test-stack.js +83 -2
  199. package/dist/db/query.d.ts +14 -0
  200. package/dist/db/query.js +77 -48
  201. package/dist/db/reference-data.d.ts +1 -1
  202. package/dist/db/reference-data.js +20 -3
  203. package/dist/db/render-ddl.d.ts +6 -2
  204. package/dist/db/render-ddl.js +7 -7
  205. package/dist/db/render-rls-ddl.d.ts +35 -0
  206. package/dist/db/render-rls-ddl.js +127 -0
  207. package/dist/db/replay-migration-sql.d.ts +3 -1
  208. package/dist/db/replay-migration-sql.js +22 -5
  209. package/dist/db/replay-rls.d.ts +25 -0
  210. package/dist/db/replay-rls.js +156 -0
  211. package/dist/db/row-level-security-boot-check.d.ts +5 -0
  212. package/dist/db/row-level-security-boot-check.js +85 -0
  213. package/dist/db/row-level-security-connection.d.ts +3 -0
  214. package/dist/db/row-level-security-connection.js +213 -0
  215. package/dist/db/row-level-security-scope.d.ts +33 -0
  216. package/dist/db/row-level-security-scope.js +127 -0
  217. package/dist/db/scope-tenant-db-to-tenant.d.ts +3 -0
  218. package/dist/db/scope-tenant-db-to-tenant.js +14 -0
  219. package/dist/db/sql-identifier.d.ts +1 -0
  220. package/dist/db/sql-identifier.js +3 -0
  221. package/dist/db/statement-timeout.js +2 -1
  222. package/dist/db/table-builder.d.ts +2 -1
  223. package/dist/db/table-builder.js +1 -1
  224. package/dist/db/table-info.js +1 -1
  225. package/dist/db/table-push.d.ts +11 -2
  226. package/dist/db/table-push.js +15 -2
  227. package/dist/db/tenant-db-runner.d.ts +3 -1
  228. package/dist/db/tenant-db-runner.js +4 -3
  229. package/dist/db/tenant-db-scoped-rebind.d.ts +10 -0
  230. package/dist/db/tenant-db-scoped-rebind.js +33 -0
  231. package/dist/db/tenant-db-statement-runner.d.ts +13 -0
  232. package/dist/db/tenant-db-statement-runner.js +48 -0
  233. package/dist/db/tenant-db-upsert.d.ts +5 -0
  234. package/dist/db/tenant-db-upsert.js +91 -0
  235. package/dist/db/tenant-db.d.ts +17 -12
  236. package/dist/db/tenant-db.js +60 -121
  237. package/dist/db/tenant-id-filter.d.ts +3 -0
  238. package/dist/db/tenant-id-filter.js +30 -0
  239. package/dist/db/transaction-serialization.d.ts +6 -0
  240. package/dist/db/transaction-serialization.js +60 -0
  241. package/dist/derivatives/delete-stored-file.js +1 -1
  242. package/dist/derivatives/index.d.ts +2 -5
  243. package/dist/derivatives/index.js +2 -3
  244. package/dist/engine/access.d.ts +2 -1
  245. package/dist/engine/access.js +1 -1
  246. package/dist/engine/boot-validator/bundled-lists-table.d.ts +2 -0
  247. package/dist/engine/boot-validator/bundled-lists-table.js +36 -0
  248. package/dist/engine/boot-validator/entity-handler.d.ts +2 -1
  249. package/dist/engine/boot-validator/entity-handler.js +1 -1
  250. package/dist/engine/boot-validator/entity-list-aggregate-options.d.ts +3 -0
  251. package/dist/engine/boot-validator/entity-list-aggregate-options.js +23 -0
  252. package/dist/engine/boot-validator/list-bulk-actions.d.ts +3 -0
  253. package/dist/engine/boot-validator/list-bulk-actions.js +49 -0
  254. package/dist/engine/boot-validator/list-column-layout.d.ts +8 -0
  255. package/dist/engine/boot-validator/list-column-layout.js +41 -0
  256. package/dist/engine/boot-validator/list-table-aggregate-options.d.ts +24 -0
  257. package/dist/engine/boot-validator/list-table-aggregate-options.js +145 -0
  258. package/dist/engine/boot-validator/list-table-aggregate-query.d.ts +11 -0
  259. package/dist/engine/boot-validator/list-table-aggregate-query.js +31 -0
  260. package/dist/engine/boot-validator/list-table-export-options.d.ts +1 -0
  261. package/dist/engine/boot-validator/list-table-export-options.js +27 -0
  262. package/dist/engine/boot-validator/list-table-options.d.ts +3 -0
  263. package/dist/engine/boot-validator/list-table-options.js +77 -0
  264. package/dist/engine/boot-validator/list-table-reject-unknown-keys.d.ts +1 -0
  265. package/dist/engine/boot-validator/list-table-reject-unknown-keys.js +7 -0
  266. package/dist/engine/boot-validator/nav.d.ts +3 -1
  267. package/dist/engine/boot-validator/nav.js +1 -1
  268. package/dist/engine/boot-validator/ownership.d.ts +2 -1
  269. package/dist/engine/boot-validator/parent-ref.d.ts +2 -1
  270. package/dist/engine/boot-validator/projection-list-screens.d.ts +2 -1
  271. package/dist/engine/boot-validator/projection-list-screens.js +3 -13
  272. package/dist/engine/boot-validator/query-refs.d.ts +2 -1
  273. package/dist/engine/boot-validator/related-list-table-rules.d.ts +4 -0
  274. package/dist/engine/boot-validator/related-list-table-rules.js +42 -0
  275. package/dist/engine/boot-validator/screens-forms.d.ts +2 -1
  276. package/dist/engine/boot-validator/screens-kind-entity-list.js +7 -0
  277. package/dist/engine/boot-validator/screens-kind-projection-list.js +4 -0
  278. package/dist/engine/boot-validator/screens-kind-shared.d.ts +3 -1
  279. package/dist/engine/boot-validator/screens-lists.js +12 -2
  280. package/dist/engine/boot-validator/screens.d.ts +2 -1
  281. package/dist/engine/boot-validator/workspaces.d.ts +3 -1
  282. package/dist/engine/bridge-stub.d.ts +5 -2
  283. package/dist/engine/bridge-stub.js +39 -24
  284. package/dist/engine/build-app-schema.d.ts +2 -1
  285. package/dist/engine/build-app-schema.js +9 -1
  286. package/dist/engine/build-config-feature-schema.js +6 -1
  287. package/dist/engine/config-helpers.d.ts +2 -2
  288. package/dist/engine/config-helpers.js +0 -9
  289. package/dist/engine/constants.d.ts +0 -10
  290. package/dist/engine/constants.js +0 -8
  291. package/dist/engine/create-app.js +1 -1
  292. package/dist/engine/define-feature.d.ts +2 -1
  293. package/dist/engine/define-feature.js +5 -2
  294. package/dist/engine/define-handler.d.ts +1 -1
  295. package/dist/engine/define-step.d.ts +0 -1
  296. package/dist/engine/define-step.js +0 -3
  297. package/dist/engine/embedded-derived.d.ts +1 -1
  298. package/dist/engine/entity-handlers.d.ts +2 -1
  299. package/dist/engine/entity-handlers.js +7 -7
  300. package/dist/engine/entity-list-runtime-options.js +3 -1
  301. package/dist/engine/entity-list-searchability.d.ts +2 -1
  302. package/dist/engine/event-def.d.ts +2 -1
  303. package/dist/engine/event-helpers.d.ts +3 -1
  304. package/dist/engine/event-helpers.js +3 -3
  305. package/dist/engine/extension-names.d.ts +2 -8
  306. package/dist/engine/extension-names.js +2 -2
  307. package/dist/engine/extension-selector-plugins.d.ts +1 -1
  308. package/dist/engine/extensions/storage-provider.d.ts +1 -2
  309. package/dist/engine/extensions/user-data.d.ts +0 -8
  310. package/dist/engine/factories.d.ts +2 -1
  311. package/dist/engine/feature-builder-state.d.ts +9 -1
  312. package/dist/engine/feature-builder-state.js +1 -0
  313. package/dist/engine/feature-changelog.d.ts +1 -1
  314. package/dist/engine/feature-config-events-jobs.d.ts +4 -1
  315. package/dist/engine/feature-entity-handlers.d.ts +5 -1
  316. package/dist/engine/feature-manifest.d.ts +1 -0
  317. package/dist/engine/feature-manifest.js +2 -1
  318. package/dist/engine/feature-ui-extensions.d.ts +7 -1
  319. package/dist/engine/feature-ui-extensions.js +6 -4
  320. package/dist/engine/field-access.d.ts +3 -1
  321. package/dist/engine/field-access.js +12 -0
  322. package/dist/engine/handler-field-references.d.ts +0 -4
  323. package/dist/engine/index.d.ts +58 -55
  324. package/dist/engine/index.js +23 -28
  325. package/dist/engine/instruction-fields.d.ts +1 -1
  326. package/dist/engine/personal-data-fields.d.ts +1 -1
  327. package/dist/engine/qualified-name.d.ts +0 -1
  328. package/dist/engine/read-claim.d.ts +2 -1
  329. package/dist/engine/registry-facade.js +0 -3
  330. package/dist/engine/registry-ingest.d.ts +2 -1
  331. package/dist/engine/registry-ingest.js +1 -2
  332. package/dist/engine/registry-state.d.ts +12 -2
  333. package/dist/engine/registry-state.js +2 -3
  334. package/dist/engine/registry-validate.d.ts +3 -1
  335. package/dist/engine/registry-validate.js +7 -7
  336. package/dist/engine/run-in.d.ts +1 -1
  337. package/dist/engine/run-in.js +0 -1
  338. package/dist/engine/schema-builder.d.ts +1 -1
  339. package/dist/engine/schema-builder.js +1 -1
  340. package/dist/engine/screen-filter-ops.d.ts +2 -1
  341. package/dist/engine/screen-filter-ops.js +2 -5
  342. package/dist/engine/soft-delete-cleanup.d.ts +1 -1
  343. package/dist/engine/soft-delete-cleanup.js +4 -4
  344. package/dist/engine/state-machine.js +2 -1
  345. package/dist/engine/steps/_read-source.js +1 -1
  346. package/dist/engine/steps/aggregate-append-event.js +2 -2
  347. package/dist/engine/steps/call-feature.js +2 -2
  348. package/dist/engine/steps/mail-send.js +1 -1
  349. package/dist/engine/steps/retry.js +1 -1
  350. package/dist/engine/steps/wait-for-event.js +1 -1
  351. package/dist/engine/steps/wait.js +1 -1
  352. package/dist/engine/steps/webhook-send.js +1 -1
  353. package/dist/engine/strip-disabled-features-from-app-schema.js +7 -3
  354. package/dist/engine/template-variables.d.ts +2 -1
  355. package/dist/engine/transfer-adjacency.d.ts +1 -1
  356. package/dist/engine/types/feature.d.ts +1 -0
  357. package/dist/engine/types/index.d.ts +8 -30
  358. package/dist/engine/types/index.js +2 -10
  359. package/dist/engine/types/screen.d.ts +1 -1
  360. package/dist/engine/types/screen.js +1 -1
  361. package/dist/engine/validation.d.ts +2 -1
  362. package/dist/entrypoint/index.d.ts +9 -35
  363. package/dist/entrypoint/index.js +10 -1
  364. package/dist/entrypoint/internals.d.ts +40 -0
  365. package/dist/entrypoint/internals.js +1 -0
  366. package/dist/entrypoint/row-level-security-mode-check.d.ts +3 -0
  367. package/dist/entrypoint/row-level-security-mode-check.js +19 -0
  368. package/dist/env/dry-run-internals.d.ts +10 -0
  369. package/dist/env/dry-run-internals.js +1 -0
  370. package/dist/env/dry-run.d.ts +1 -10
  371. package/dist/env/dry-run.js +2 -1
  372. package/dist/env/index.d.ts +1 -85
  373. package/dist/env/index.js +6 -50
  374. package/dist/env/internals.d.ts +87 -0
  375. package/dist/env/internals.js +53 -0
  376. package/dist/errors/classes.js +2 -2
  377. package/dist/errors/index.d.ts +5 -14
  378. package/dist/errors/index.js +4 -9
  379. package/dist/errors/member-resolution.js +1 -1
  380. package/dist/errors/reasons.d.ts +0 -1
  381. package/dist/errors/reasons.js +7 -7
  382. package/dist/errors/serialize.d.ts +0 -18
  383. package/dist/errors/serialize.js +0 -27
  384. package/dist/es-ops/index.d.ts +4 -4
  385. package/dist/es-ops/index.js +2 -2
  386. package/dist/es-ops/operations-schema.d.ts +1 -1
  387. package/dist/es-ops/types.d.ts +4 -5
  388. package/dist/event-store/admin-api-internals.d.ts +14 -0
  389. package/dist/event-store/admin-api-internals.js +1 -0
  390. package/dist/event-store/admin-api.d.ts +1 -14
  391. package/dist/event-store/admin-api.js +11 -6
  392. package/dist/event-store/archive.js +4 -2
  393. package/dist/event-store/errors.js +2 -2
  394. package/dist/event-store/event-store.d.ts +1 -0
  395. package/dist/event-store/event-store.js +42 -32
  396. package/dist/event-store/events-schema.js +4 -1
  397. package/dist/event-store/index.d.ts +11 -13
  398. package/dist/event-store/index.js +7 -9
  399. package/dist/event-store/provenance-append.js +1 -1
  400. package/dist/event-store/rebuild-dead-letter.js +4 -2
  401. package/dist/event-store/snapshot.js +4 -3
  402. package/dist/event-store/stream-scope.d.ts +2 -0
  403. package/dist/event-store/stream-scope.js +6 -0
  404. package/dist/event-store/upcaster-dead-letter.js +4 -2
  405. package/dist/event-store/upcaster.d.ts +2 -1
  406. package/dist/files/action-form-upload.d.ts +2 -1
  407. package/dist/files/action-form-upload.js +1 -1
  408. package/dist/files/assert-file-refs-belong-to-tenant.d.ts +2 -1
  409. package/dist/files/assert-file-refs-belong-to-tenant.js +1 -1
  410. package/dist/files/bind-pending-file-refs.d.ts +2 -1
  411. package/dist/files/bind-pending-file-refs.js +2 -1
  412. package/dist/files/bind-referenced-files.write.js +1 -1
  413. package/dist/files/create-file-ref-from-bytes.d.ts +6 -3
  414. package/dist/files/create-file-ref-from-bytes.js +6 -3
  415. package/dist/files/create-file-ref.d.ts +6 -2
  416. package/dist/files/create-file-ref.js +13 -4
  417. package/dist/files/dispose-removed-file-refs.d.ts +2 -1
  418. package/dist/files/dispose-removed-file-refs.js +1 -1
  419. package/dist/files/feature.js +2 -2
  420. package/dist/files/file-handle.js +1 -1
  421. package/dist/files/file-routes.d.ts +3 -1
  422. package/dist/files/file-routes.js +41 -4
  423. package/dist/files/index.d.ts +11 -13
  424. package/dist/files/index.js +5 -7
  425. package/dist/files/load-save-file-refs.d.ts +2 -1
  426. package/dist/files/load-save-file-refs.js +1 -1
  427. package/dist/files/provider-resolver.d.ts +6 -4
  428. package/dist/files/provider-resolver.js +5 -5
  429. package/dist/files/record-write-check.d.ts +6 -0
  430. package/dist/files/record-write-check.js +13 -0
  431. package/dist/files/storage-tracking.js +4 -2
  432. package/dist/files/sweep-orphaned-uploads.d.ts +1 -1
  433. package/dist/files/sweep-orphaned-uploads.js +1 -1
  434. package/dist/files/upload-ledger.d.ts +2 -2
  435. package/dist/files/upload-ledger.js +4 -4
  436. package/dist/i18n/index.d.ts +2 -8
  437. package/dist/i18n/index.js +1 -1
  438. package/dist/i18n/internals.d.ts +7 -0
  439. package/dist/i18n/internals.js +1 -0
  440. package/dist/i18n/required-surface-keys.d.ts +4 -1
  441. package/dist/i18n/required-surface-keys.js +7 -2
  442. package/dist/internal/row-level-security.d.ts +3 -0
  443. package/dist/internal/row-level-security.js +3 -0
  444. package/dist/internal/stack-support.d.ts +1 -1
  445. package/dist/internal/stack-support.js +1 -1
  446. package/dist/internal/testing.d.ts +1 -0
  447. package/dist/internal/testing.js +10 -6
  448. package/dist/jobs/index.d.ts +1 -1
  449. package/dist/jobs/job-append-event.d.ts +12 -0
  450. package/dist/jobs/job-append-event.js +30 -0
  451. package/dist/jobs/job-runner-context.d.ts +2 -2
  452. package/dist/jobs/job-runner-context.js +46 -16
  453. package/dist/jobs/job-runner-execution.d.ts +1 -1
  454. package/dist/jobs/job-runner-execution.js +6 -4
  455. package/dist/jobs/job-runner-gates.d.ts +1 -1
  456. package/dist/jobs/job-runner-gates.js +0 -1
  457. package/dist/jobs/job-runner-helpers.d.ts +11 -4
  458. package/dist/jobs/job-runner-helpers.js +10 -1
  459. package/dist/jobs/job-runner-scope.d.ts +5 -2
  460. package/dist/jobs/job-runner-scope.js +6 -6
  461. package/dist/jobs/job-runner-types.d.ts +2 -1
  462. package/dist/jobs/job-runner.js +22 -6
  463. package/dist/jobs/max-per-tenant.d.ts +1 -1
  464. package/dist/logging/index.d.ts +1 -2
  465. package/dist/logging/index.js +1 -1
  466. package/dist/logging/pino-logger.js +1 -1
  467. package/dist/logging/utils.d.ts +1 -0
  468. package/dist/logging/utils.js +6 -0
  469. package/dist/migrations/index.d.ts +3 -3
  470. package/dist/migrations/index.js +3 -3
  471. package/dist/migrations/pending-rebuilds.d.ts +1 -1
  472. package/dist/migrations/pending-rebuilds.js +1 -1
  473. package/dist/migrations/pii-event-backfill.js +4 -1
  474. package/dist/observability/escape-hatch-report.d.ts +2 -1
  475. package/dist/observability/escape-hatch-report.js +9 -2
  476. package/dist/observability/index.d.ts +7 -15
  477. package/dist/observability/index.js +4 -12
  478. package/dist/observability/metric-validator.js +1 -1
  479. package/dist/observability/metrics-handle.d.ts +0 -1
  480. package/dist/observability/metrics-handle.js +2 -15
  481. package/dist/observability/recording-tracer.d.ts +1 -2
  482. package/dist/observability/recording-tracer.js +0 -6
  483. package/dist/observability/sensitive-filter.d.ts +0 -2
  484. package/dist/observability/sensitive-filter.js +0 -29
  485. package/dist/pipeline/active-membership.d.ts +2 -1
  486. package/dist/pipeline/active-membership.js +6 -2
  487. package/dist/pipeline/after-rollback-sink.d.ts +6 -0
  488. package/dist/pipeline/after-rollback-sink.js +32 -0
  489. package/dist/pipeline/append-event-core.d.ts +2 -1
  490. package/dist/pipeline/append-event-core.js +2 -2
  491. package/dist/pipeline/attach-outside-transaction.d.ts +3 -0
  492. package/dist/pipeline/attach-outside-transaction.js +13 -0
  493. package/dist/pipeline/auth-claims-resolver.d.ts +2 -1
  494. package/dist/pipeline/cascade-handler.d.ts +2 -1
  495. package/dist/pipeline/cascade-handler.js +3 -2
  496. package/dist/pipeline/config-accessor-factory.d.ts +1 -1
  497. package/dist/pipeline/config-accessor-factory.js +1 -1
  498. package/dist/pipeline/context-services.d.ts +56 -0
  499. package/dist/pipeline/context-services.js +73 -0
  500. package/dist/pipeline/dispatch-batch.d.ts +2 -1
  501. package/dist/pipeline/dispatch-batch.js +39 -19
  502. package/dist/pipeline/dispatch-query.js +5 -4
  503. package/dist/pipeline/dispatch-scope.d.ts +6 -0
  504. package/dist/pipeline/dispatch-scope.js +27 -0
  505. package/dist/pipeline/dispatch-shared.d.ts +13 -9
  506. package/dist/pipeline/dispatch-shared.js +75 -194
  507. package/dist/pipeline/dispatch-stream.js +8 -4
  508. package/dist/pipeline/dispatch-write.d.ts +2 -1
  509. package/dist/pipeline/dispatch-write.js +10 -8
  510. package/dist/pipeline/dispatcher-utils.d.ts +3 -1
  511. package/dist/pipeline/dispatcher-utils.js +8 -2
  512. package/dist/pipeline/dispatcher.d.ts +3 -2
  513. package/dist/pipeline/dispatcher.js +4 -3
  514. package/dist/pipeline/event-consumer-state.d.ts +0 -1
  515. package/dist/pipeline/event-dispatcher-delivery.d.ts +1 -1
  516. package/dist/pipeline/event-dispatcher-delivery.js +7 -3
  517. package/dist/pipeline/event-dispatcher.d.ts +3 -2
  518. package/dist/pipeline/event-dispatcher.js +13 -12
  519. package/dist/pipeline/event-retention.js +59 -56
  520. package/dist/pipeline/handler-access-error.js +2 -1
  521. package/dist/pipeline/handler-context-auth.d.ts +5 -6
  522. package/dist/pipeline/handler-context-auth.js +7 -4
  523. package/dist/pipeline/handler-context-config.d.ts +2 -5
  524. package/dist/pipeline/handler-context-config.js +2 -2
  525. package/dist/pipeline/handler-context-db.d.ts +32 -7
  526. package/dist/pipeline/handler-context-db.js +26 -17
  527. package/dist/pipeline/handler-context-dispatch.d.ts +14 -6
  528. package/dist/pipeline/handler-context-dispatch.js +18 -5
  529. package/dist/pipeline/handler-context-events.d.ts +22 -38
  530. package/dist/pipeline/handler-context-events.js +42 -35
  531. package/dist/pipeline/handler-context-member-resolution.d.ts +2 -0
  532. package/dist/pipeline/handler-context-member-resolution.js +110 -0
  533. package/dist/pipeline/handler-context-notify.d.ts +3 -2
  534. package/dist/pipeline/handler-context-notify.js +1 -1
  535. package/dist/pipeline/handler-context-observability.d.ts +2 -4
  536. package/dist/pipeline/handler-context-observability.js +7 -5
  537. package/dist/pipeline/handler-context-phase-denials.d.ts +11 -0
  538. package/dist/pipeline/handler-context-phase-denials.js +98 -0
  539. package/dist/pipeline/handler-context-scope.d.ts +7 -10
  540. package/dist/pipeline/handler-context-scope.js +18 -20
  541. package/dist/pipeline/index.d.ts +9 -21
  542. package/dist/pipeline/index.js +5 -7
  543. package/dist/pipeline/irreversible-operation-gate.d.ts +1 -1
  544. package/dist/pipeline/irreversible-operation-gate.js +2 -2
  545. package/dist/pipeline/lifecycle-pipeline.d.ts +8 -7
  546. package/dist/pipeline/lifecycle-pipeline.js +9 -15
  547. package/dist/pipeline/member-read-only-transaction.js +11 -3
  548. package/dist/pipeline/member-reader.d.ts +1 -1
  549. package/dist/pipeline/member-reader.js +2 -2
  550. package/dist/pipeline/msp-rebuild.js +5 -3
  551. package/dist/pipeline/multi-stream-apply-context.js +3 -2
  552. package/dist/pipeline/notify-scope.d.ts +2 -1
  553. package/dist/pipeline/pre-handler-gates.d.ts +2 -1
  554. package/dist/pipeline/pre-transaction-reservations.d.ts +3 -3
  555. package/dist/pipeline/pre-transaction-reservations.js +9 -7
  556. package/dist/pipeline/projection-rebuild.js +12 -5
  557. package/dist/pipeline/projection-state.d.ts +0 -6
  558. package/dist/pipeline/projection-state.js +0 -5
  559. package/dist/pipeline/projections-runner.d.ts +2 -1
  560. package/dist/pipeline/projections-runner.js +10 -6
  561. package/dist/pipeline/system-hooks.d.ts +6 -2
  562. package/dist/pipeline/system-hooks.js +61 -10
  563. package/dist/pipeline/system-identity-switch.d.ts +4 -2
  564. package/dist/pipeline/system-identity-switch.js +51 -36
  565. package/dist/pipeline/typed-append-event.d.ts +2 -0
  566. package/dist/pipeline/typed-append-event.js +4 -0
  567. package/dist/pipeline/write-origin.js +2 -2
  568. package/dist/pipeline/write-result-masking.d.ts +1 -1
  569. package/dist/pipeline/write-result-masking.js +13 -10
  570. package/dist/random/index.d.ts +1 -2
  571. package/dist/random/index.js +1 -2
  572. package/dist/rate-limit/bucket.d.ts +2 -1
  573. package/dist/rate-limit/middleware.js +2 -1
  574. package/dist/redis/index.d.ts +3 -4
  575. package/dist/redis/index.js +2 -2
  576. package/dist/schema-cli/apply-command.js +5 -2
  577. package/dist/schema-cli/baseline-command.js +7 -2
  578. package/dist/schema-cli/generate-command.js +7 -9
  579. package/dist/schema-cli/shared.d.ts +4 -0
  580. package/dist/schema-cli/shared.js +21 -2
  581. package/dist/schema-cli/status-command.js +8 -2
  582. package/dist/schema-cli/validate-command.js +52 -4
  583. package/dist/schema-cli.d.ts +0 -1
  584. package/dist/search/configure-tenant-index.d.ts +1 -3
  585. package/dist/search/configure-tenant-index.js +0 -4
  586. package/dist/search/index.d.ts +1 -4
  587. package/dist/search/index.js +0 -2
  588. package/dist/search/meilisearch-adapter-internals.d.ts +8 -0
  589. package/dist/search/meilisearch-adapter-internals.js +9 -0
  590. package/dist/search/meilisearch-adapter.d.ts +1 -8
  591. package/dist/search/meilisearch-adapter.js +6 -7
  592. package/dist/search/meilisearch-peer.d.ts +2 -0
  593. package/dist/search/meilisearch-peer.js +5 -0
  594. package/dist/search/reindex-entity.js +107 -91
  595. package/dist/secrets/index.d.ts +3 -4
  596. package/dist/secrets/index.js +2 -3
  597. package/dist/seeding/index.d.ts +2 -2
  598. package/dist/seeding/index.js +1 -2
  599. package/dist/time/index.d.ts +2 -2
  600. package/dist/time/index.js +1 -1
  601. package/dist/time/tz-context.d.ts +0 -5
  602. package/dist/time/tz-context.js +0 -9
  603. package/dist/ui-types/index.d.ts +8 -11
  604. package/dist/ui-types/index.js +3 -3
  605. package/dist/upgrade-changelog.d.ts +3 -0
  606. package/dist/upgrade-changelog.js +18 -0
  607. package/dist/upgrade-cli-internals.d.ts +8 -0
  608. package/dist/upgrade-cli-internals.js +63 -0
  609. package/dist/upgrade-cli.d.ts +1 -18
  610. package/dist/upgrade-cli.js +29 -137
  611. package/dist/upgrade-marker-parse.d.ts +32 -0
  612. package/dist/upgrade-marker-parse.js +73 -0
  613. package/dist/utils/import-optional-peer.d.ts +6 -0
  614. package/dist/utils/import-optional-peer.js +19 -0
  615. package/dist/utils/index.d.ts +1 -4
  616. package/dist/utils/index.js +1 -4
  617. package/package.json +27 -20
  618. package/src/changes.json +451 -0
  619. package/dist/crypto/request-kms-cache.d.ts +0 -8
  620. package/dist/crypto/request-kms-cache.js +0 -21
  621. package/dist/engine/codemod/index.d.ts +0 -2
  622. package/dist/engine/codemod/index.js +0 -1
  623. package/dist/engine/codemod/pipeline-codemod.d.ts +0 -50
  624. package/dist/engine/codemod/pipeline-codemod.js +0 -536
  625. package/dist/engine/feature-ast/entity-field-types.d.ts +0 -13
  626. package/dist/engine/feature-ast/entity-field-types.js +0 -35
  627. package/dist/engine/feature-ast/extractors/ai-steps.d.ts +0 -6
  628. package/dist/engine/feature-ast/extractors/ai-steps.js +0 -254
  629. package/dist/engine/feature-ast/extractors/events.d.ts +0 -5
  630. package/dist/engine/feature-ast/extractors/events.js +0 -275
  631. package/dist/engine/feature-ast/extractors/handlers.d.ts +0 -24
  632. package/dist/engine/feature-ast/extractors/handlers.js +0 -358
  633. package/dist/engine/feature-ast/extractors/hooks.d.ts +0 -24
  634. package/dist/engine/feature-ast/extractors/hooks.js +0 -248
  635. package/dist/engine/feature-ast/extractors/index.d.ts +0 -14
  636. package/dist/engine/feature-ast/extractors/index.js +0 -13
  637. package/dist/engine/feature-ast/extractors/jobs-routes.d.ts +0 -7
  638. package/dist/engine/feature-ast/extractors/jobs-routes.js +0 -145
  639. package/dist/engine/feature-ast/extractors/projections-screens.d.ts +0 -10
  640. package/dist/engine/feature-ast/extractors/projections-screens.js +0 -195
  641. package/dist/engine/feature-ast/extractors/resolve-import.d.ts +0 -21
  642. package/dist/engine/feature-ast/extractors/resolve-import.js +0 -180
  643. package/dist/engine/feature-ast/extractors/round1.d.ts +0 -10
  644. package/dist/engine/feature-ast/extractors/round1.js +0 -81
  645. package/dist/engine/feature-ast/extractors/round2.d.ts +0 -7
  646. package/dist/engine/feature-ast/extractors/round2.js +0 -191
  647. package/dist/engine/feature-ast/extractors/round3.d.ts +0 -23
  648. package/dist/engine/feature-ast/extractors/round3.js +0 -292
  649. package/dist/engine/feature-ast/extractors/round5.d.ts +0 -9
  650. package/dist/engine/feature-ast/extractors/round5.js +0 -68
  651. package/dist/engine/feature-ast/extractors/round6.d.ts +0 -4
  652. package/dist/engine/feature-ast/extractors/round6.js +0 -17
  653. package/dist/engine/feature-ast/extractors/shared.d.ts +0 -94
  654. package/dist/engine/feature-ast/extractors/shared.js +0 -343
  655. package/dist/engine/feature-ast/index.d.ts +0 -16
  656. package/dist/engine/feature-ast/index.js +0 -10
  657. package/dist/engine/feature-ast/parse.d.ts +0 -31
  658. package/dist/engine/feature-ast/parse.js +0 -483
  659. package/dist/engine/feature-ast/patch.d.ts +0 -210
  660. package/dist/engine/feature-ast/patch.js +0 -610
  661. package/dist/engine/feature-ast/patcher.d.ts +0 -217
  662. package/dist/engine/feature-ast/patcher.js +0 -281
  663. package/dist/engine/feature-ast/pattern-change-schema.d.ts +0 -1476
  664. package/dist/engine/feature-ast/pattern-change-schema.js +0 -1226
  665. package/dist/engine/feature-ast/pattern-id-matchers.d.ts +0 -7
  666. package/dist/engine/feature-ast/pattern-id-matchers.js +0 -210
  667. package/dist/engine/feature-ast/patterns.d.ts +0 -318
  668. package/dist/engine/feature-ast/patterns.js +0 -106
  669. package/dist/engine/feature-ast/render.d.ts +0 -47
  670. package/dist/engine/feature-ast/render.js +0 -662
  671. package/dist/engine/feature-ast/source-location.d.ts +0 -17
  672. package/dist/engine/feature-ast/source-location.js +0 -27
  673. package/dist/engine/pattern-library/index.d.ts +0 -2
  674. package/dist/engine/pattern-library/index.js +0 -3
  675. package/dist/engine/pattern-library/library.d.ts +0 -14
  676. package/dist/engine/pattern-library/library.js +0 -93
  677. package/dist/engine/pattern-library/mixed-schemas.d.ts +0 -16
  678. package/dist/engine/pattern-library/mixed-schemas.js +0 -559
  679. package/dist/engine/pattern-library/opaque-schemas.d.ts +0 -7
  680. package/dist/engine/pattern-library/opaque-schemas.js +0 -115
  681. package/dist/engine/pattern-library/shared-fields.d.ts +0 -122
  682. package/dist/engine/pattern-library/shared-fields.js +0 -88
  683. package/dist/engine/pattern-library/static-schemas.d.ts +0 -20
  684. package/dist/engine/pattern-library/static-schemas.js +0 -478
  685. package/dist/engine/pattern-library/types.d.ts +0 -158
  686. package/dist/engine/pattern-library/types.js +0 -36
  687. package/dist/engine/provider-plugin-context.d.ts +0 -3
  688. package/dist/engine/provider-plugin-context.js +0 -28
  689. package/dist/engine/resolve-config-or-param.d.ts +0 -18
  690. package/dist/engine/resolve-config-or-param.js +0 -76
  691. package/src/scripts/codemod/README.md +0 -187
  692. package/src/scripts/codemod/codemod-support.ts +0 -334
  693. package/src/scripts/codemod/collect-source-files.ts +0 -48
  694. package/src/scripts/codemod/crypto-shredding-testing-move.ts +0 -119
  695. package/src/scripts/codemod/db-factory.ts +0 -810
  696. package/src/scripts/codemod/feature-factory.ts +0 -429
  697. package/src/scripts/codemod/feature-layout.ts +0 -424
  698. package/src/scripts/codemod/import-extensions.ts +0 -118
  699. package/src/scripts/codemod/migrate-cross-tenant.ts +0 -328
  700. package/src/scripts/codemod/migrate-db-raw.ts +0 -401
  701. package/src/scripts/codemod/migrate-open-to-all.ts +0 -235
  702. package/src/scripts/codemod/object-form.ts +0 -746
  703. package/src/scripts/codemod/package-merge.ts +0 -299
  704. package/src/scripts/codemod/pii-personal-migration.ts +0 -816
  705. package/src/scripts/codemod/remove-engine-payload-casts.ts +0 -318
  706. package/src/scripts/codemod/s3-imports.ts +0 -236
  707. package/src/scripts/codemod/tenant-db-options.ts +0 -454
  708. package/src/scripts/codemod/testing-injection.ts +0 -215
  709. package/src/scripts/codemod/testing-move-targets.ts +0 -161
  710. package/src/scripts/codemod/testing-move.ts +0 -542
  711. package/src/scripts/codemod/unprocessable-error-details-reason.ts +0 -411
@@ -1,7 +1,9 @@
1
1
  import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
2
2
  import { readNonEmptyStringArray, } from "../api/sse-broker.js";
3
- import { collectSearchableSubjectFields, configuredPiiSubjectKms, decryptPiiFieldValues, isPiiCiphertext, PII_ERASED_SENTINEL, } from "../crypto/index.js";
4
- import { createTenantDb, entityTableFromRegistry, rehydrateCompoundTypes } from "../db/index.js";
3
+ import { configuredPiiSubjectKms, decryptPiiFieldValues, isPiiCiphertext, PII_ERASED_SENTINEL, } from "../crypto/index.js";
4
+ import { collectSearchableSubjectFields } from "../crypto/subject-resolver.js";
5
+ import { rehydrateCompoundTypes } from "../db/compound-types.js";
6
+ import { createTenantDb, entityTableFromRegistry } from "../db/index.js";
5
7
  import { tenantChannel } from "../engine/constants.js";
6
8
  import { InternalError } from "../errors/index.js";
7
9
  import { createFallbackLogger } from "../logging/utils.js";
@@ -422,7 +424,7 @@ export function createSseBroadcastEventConsumer(sseBroker) {
422
424
  // r.job's `trigger.on` historically only fired via the synchronous
423
425
  // write-handler dispatch path (dispatch-write.ts's afterCommitHooks calling
424
426
  // jobRunner.handleEvent). Events appended any other way — an
425
- // r.multiStreamProjection's ctx.unsafeAppendEvent, or a raw
427
+ // r.multiStreamProjection's ctx.events.unsafeAppend, or a raw
426
428
  // event-store-executor write (e.g. `files`' fileRef.created) — never
427
429
  // reached it, so a job could never trigger on an r.defineEvent-registered
428
430
  // event.
@@ -431,7 +433,7 @@ export function createSseBroadcastEventConsumer(sseBroker) {
431
433
  // committed event off the shared cursor and re-check job triggers. It is
432
434
  // scoped EXACTLY to the gap — the write/query-handler-QN skip below is
433
435
  // defense-in-depth: no stored event's `type` is a handler QN today (entity
434
- // events are "entity.verb"; ctx.appendEvent enforces defineEvent-only
436
+ // events are "entity.verb"; ctx.events.append enforces defineEvent-only
435
437
  // ownership), but if that ever changes, this consumer must not re-fire a
436
438
  // trigger the synchronous dispatch-write.ts path already handled.
437
439
  //
@@ -552,9 +554,58 @@ function readPatRevokedScope(payload) {
552
554
  const tokenIds = readNonEmptyStringArray(payload["tokenIds"]);
553
555
  return tokenIds ? { kind: "pat-tokens", tokenIds } : { kind: "user" };
554
556
  }
555
- export function createAccessInvalidationEventConsumer(sseBroker) {
557
+ const ACCESS_INVALIDATION_BACKOFF_INITIAL_MS = 250;
558
+ const ACCESS_INVALIDATION_BACKOFF_MAX_MS = 10_000;
559
+ // Only the publish can fail because Redis is unreachable. The consumer must keep retrying those
560
+ // until Redis is back (dead-lettering would silently stop every later revocation reaching open
561
+ // streams), while any other failure keeps the dispatcher's attempt limit so one poison event
562
+ // cannot hold back every later revocation for good.
563
+ class AccessInvalidationTransportError extends Error {
564
+ constructor(cause) {
565
+ super(cause instanceof Error ? cause.message : String(cause), { cause });
566
+ this.name = "AccessInvalidationTransportError";
567
+ }
568
+ }
569
+ function isAccessInvalidationTransportError(error) {
570
+ return error instanceof AccessInvalidationTransportError;
571
+ }
572
+ // The gate rethrows without touching Redis until the backoff elapsed.
573
+ function withTransportBackoff(handle, now) {
574
+ let delayMs = ACCESS_INVALIDATION_BACKOFF_INITIAL_MS;
575
+ let retryNotBefore = 0;
576
+ let transportError = null;
577
+ return async (event) => {
578
+ if (transportError !== null && now() < retryNotBefore)
579
+ throw transportError;
580
+ try {
581
+ await handle(event);
582
+ delayMs = ACCESS_INVALIDATION_BACKOFF_INITIAL_MS;
583
+ transportError = null;
584
+ }
585
+ catch (err) {
586
+ if (isAccessInvalidationTransportError(err)) {
587
+ transportError = err;
588
+ retryNotBefore = now() + delayMs;
589
+ delayMs = Math.min(delayMs * 2, ACCESS_INVALIDATION_BACKOFF_MAX_MS);
590
+ }
591
+ throw err;
592
+ }
593
+ };
594
+ }
595
+ export function createAccessInvalidationEventConsumer(sseBroker, opts = {}) {
596
+ const now = opts.now ?? Date.now;
597
+ const publish = async (userId, scope) => {
598
+ try {
599
+ await sseBroker.publishAccessInvalidation(userId, scope);
600
+ }
601
+ catch (cause) {
602
+ throw new AccessInvalidationTransportError(cause);
603
+ }
604
+ };
556
605
  return {
557
606
  name: ACCESS_INVALIDATION_CONSUMER_NAME,
607
+ // Count-based dead-lettering would end after a few seconds of Redis downtime.
608
+ errorPolicy: { isTransientError: isAccessInvalidationTransportError },
558
609
  // Shared delivery, same reasoning as SSE broadcast: one
559
610
  // cursor reads every event once and calls sseBroker.publishAccessInvalidation
560
611
  // below, which a Redis-backed broker republishes to every replica's
@@ -565,7 +616,7 @@ export function createAccessInvalidationEventConsumer(sseBroker) {
565
616
  // existed has nothing to invalidate — replaying it would be a no-op at
566
617
  // best and a spurious stream-close at worst.
567
618
  startFrom: "now",
568
- handler: async (event) => {
619
+ handler: withTransportBackoff(async (event) => {
569
620
  if (event.type === SESSION_REVOKED_EVENT_TYPE) {
570
621
  const userId = event.payload["userId"];
571
622
  // skip: malformed session-revoked payload — fail open on this one
@@ -574,7 +625,7 @@ export function createAccessInvalidationEventConsumer(sseBroker) {
574
625
  // every user behind one bad row).
575
626
  if (typeof userId !== "string" || userId.length === 0)
576
627
  return;
577
- await sseBroker.publishAccessInvalidation(userId, readSessionRevokedScope(event.payload));
628
+ await publish(userId, readSessionRevokedScope(event.payload));
578
629
  }
579
630
  if (event.type === PAT_REVOKED_EVENT_TYPE) {
580
631
  const userId = event.payload["userId"];
@@ -582,7 +633,7 @@ export function createAccessInvalidationEventConsumer(sseBroker) {
582
633
  // session-revoked above.
583
634
  if (typeof userId !== "string" || userId.length === 0)
584
635
  return;
585
- await sseBroker.publishAccessInvalidation(userId, readPatRevokedScope(event.payload));
636
+ await publish(userId, readPatRevokedScope(event.payload));
586
637
  }
587
638
  if (event.type === TENANT_MEMBERSHIP_UPDATED_EVENT_TYPE ||
588
639
  event.type === TENANT_MEMBERSHIP_DELETED_EVENT_TYPE) {
@@ -591,8 +642,8 @@ export function createAccessInvalidationEventConsumer(sseBroker) {
591
642
  // reasoning as above.
592
643
  if (userId === undefined)
593
644
  return;
594
- await sseBroker.publishAccessInvalidation(userId);
645
+ await publish(userId);
595
646
  }
596
- },
647
+ }, now),
597
648
  };
598
649
  }
@@ -1,10 +1,12 @@
1
+ import type { ActiveMembershipResult, EscapeHatchDeclaration, EscapeHatchReporter, MemberReader, WriteResult } from "@cosmicdrift/kumiko-types/handlers";
2
+ import type { LifecycleHookFn } from "@cosmicdrift/kumiko-types/hooks";
1
3
  import type { TenantId } from "../engine/types/identifiers.ts";
2
- import type { ActiveMembershipResult, EscapeHatchDeclaration, EscapeHatchReporter, HandlerContext, LifecycleHookFn, MemberReader, SessionUser, WriteResult } from "../engine/types/index.ts";
4
+ import type { HandlerContext, SessionUser } from "../engine/types/index.ts";
3
5
  import { AccessDeniedError } from "../errors/index.ts";
4
6
  export type QueryAsFn = (user: SessionUser, qn: string, payload: unknown) => Promise<unknown>;
5
7
  export type WriteAsFn = (user: SessionUser, qn: string, payload: unknown) => Promise<WriteResult>;
6
8
  export type ResolveActiveMembershipFn = (userId: string, tenantId: TenantId) => Promise<ActiveMembershipResult>;
7
- export type ProjectionReader = HandlerContext["queryProjection"];
9
+ export type ProjectionReader = HandlerContext["dispatch"]["queryProjection"];
8
10
  export type IdentitySwitch = {
9
11
  readonly queryAs: QueryAsFn;
10
12
  readonly writeAs: WriteAsFn;
@@ -2,6 +2,7 @@ import { escapeHatchFor } from "@cosmicdrift/kumiko-types/handlers";
2
2
  import { withSystemDbUnsafeRawGrant, withUnsafeRawGrant } from "../db/tenant-db.js";
3
3
  import { SYSTEM_ROLE, SYSTEM_USER_ID } from "../engine/system-user.js";
4
4
  import { AccessDeniedError, FrameworkReasons, InternalError } from "../errors/index.js";
5
+ import { attachOutsideTransaction } from "./attach-outside-transaction.js";
5
6
  export function isSystemIdentity(user) {
6
7
  return user.id === SYSTEM_USER_ID || user.roles.includes(SYSTEM_ROLE);
7
8
  }
@@ -49,14 +50,14 @@ export function identitySwitchDenied(callerLabel, asUser) {
49
50
  }
50
51
  export function unsafeAllTenantsDenied(callerLabel) {
51
52
  return new AccessDeniedError({
52
- message: `${callerLabel} may not call ctx.queryProjection(..., { unsafeAllTenants: true }) — declare ` +
53
+ message: `${callerLabel} may not call ctx.dispatch.queryProjection(..., { unsafeAllTenants: true }) — declare ` +
53
54
  "r.systemScope() or escapeHatch: { reason } on it",
54
55
  details: { reason: FrameworkReasons.unsafeAllTenantsDenied },
55
56
  });
56
57
  }
57
58
  // Reverse-lookup so withHookEscapeHatchGrant can re-gate the SAME ungated pair (and caller) under a narrower grant.
58
59
  const sourceByGated = new WeakMap();
59
- // Same idea, for ctx.queryAsMember — a single function rather than a pair.
60
+ // Same idea, for ctx.dispatch.queryAsMember — a single function rather than a pair.
60
61
  const ungatedMemberReaderByGated = new WeakMap();
61
62
  function reportGrantedSwitch(caller, asUser, hasGrant, audit) {
62
63
  // skip: no audit wired, switch wasn't grant-gated, or grant carries no reason to report
@@ -88,7 +89,7 @@ export function createGatedIdentitySwitch(callerLabel, caller, hasGrant, ungated
88
89
  sourceByGated.set(writeAs, source);
89
90
  return gated;
90
91
  }
91
- // ctx.queryAsMember's gate: the caller never names the target identity up
92
+ // ctx.dispatch.queryAsMember's gate: the caller never names the target identity up
92
93
  // front (it's resolved internally), so this is a flat allow/deny.
93
94
  export function createGatedMemberReader(callerLabel, allowSystemIdentity, ungated, audit) {
94
95
  const gated = async (userId, qn, payload) => {
@@ -102,9 +103,9 @@ export function createGatedMemberReader(callerLabel, allowSystemIdentity, ungate
102
103
  ungatedMemberReaderByGated.set(gated, { ungated, audit });
103
104
  return gated;
104
105
  }
105
- // Same idea, for ctx.queryProjection — a single function rather than a pair.
106
+ // Same idea, for ctx.dispatch.queryProjection — a single function rather than a pair.
106
107
  const ungatedProjectionReaderByGated = new WeakMap();
107
- // ctx.queryProjection's gate: only { unsafeAllTenants: true } on a projection with a
108
+ // ctx.dispatch.queryProjection's gate: only { unsafeAllTenants: true } on a projection with a
108
109
  // tenant column is grant-checked — a plain call always passes through, tenant-scoped
109
110
  // by the projection's own table, and the flag is a no-op on a tenant-less one.
110
111
  export function createGatedProjectionReader(callerLabel, hasGrant, ungated, audit, projectionHasTenantColumn = () => true) {
@@ -121,19 +122,20 @@ export function createGatedProjectionReader(callerLabel, hasGrant, ungated, audi
121
122
  ungatedProjectionReaderByGated.set(gated, { ungated, report: audit?.report });
122
123
  return gated;
123
124
  }
124
- function readIdentitySwitchFn(context, key) {
125
- if (!(key in context))
125
+ // Reads own keys only — never touch a property of a resolved value, which may be a Proxy that throws on any get.
126
+ function readMember(namespace, key) {
127
+ if (namespace === undefined || !(key in namespace))
126
128
  return undefined;
127
- const value = Reflect.get(context, key);
128
- return typeof value === "function" ? value : undefined; // @cast-boundary engine-bridge — checked via typeof above
129
+ return Reflect.get(namespace, key);
129
130
  }
130
- // context's own keys only — never touch a property of the resolved value, which may be a Proxy that throws on any get.
131
- function readDbLikeValue(context, key) {
132
- if (!(key in context))
133
- return undefined;
134
- const value = Reflect.get(context, key);
131
+ function readObjectMember(namespace, key) {
132
+ const value = readMember(namespace, key);
135
133
  return typeof value === "object" && value !== null ? value : undefined;
136
134
  }
135
+ function readFunctionMember(namespace, key) {
136
+ const value = readMember(namespace, key);
137
+ return typeof value === "function" ? value : undefined; // @cast-boundary engine-bridge — checked via typeof above
138
+ }
137
139
  function unavailableIdentitySwitchFn(callerLabel, kind) {
138
140
  return async () => {
139
141
  throw new InternalError({
@@ -179,8 +181,8 @@ function gatedIdentitySwitchFields(callerLabel, escapeHatch, ctxQueryAs, ctxWrit
179
181
  ...(ctxWriteAs && { writeAs: gated.writeAs }),
180
182
  };
181
183
  }
182
- // Unlike ctx.resolveActiveMembership (deny-only), a hook's own escapeHatch
183
- // can grant queryAsMember even when the enclosing handler has none.
184
+ // Unlike ctx.auth.resolveActiveMembership (deny-only), a hook's own escapeHatch
185
+ // can grant dispatch.queryAsMember even when the enclosing handler has none.
184
186
  function gatedMemberReaderField(callerLabel, escapeHatch, ctxQueryAsMember) {
185
187
  if (!ctxQueryAsMember)
186
188
  return {};
@@ -193,7 +195,7 @@ function gatedMemberReaderField(callerLabel, escapeHatch, ctxQueryAsMember) {
193
195
  queryAsMember: createGatedMemberReader(callerLabel, escapeHatch !== undefined, ungated, audit),
194
196
  };
195
197
  }
196
- // Re-gates ctx.queryProjection under the hook's own escapeHatch, same
198
+ // Re-gates ctx.dispatch.queryProjection under the hook's own escapeHatch, same
197
199
  // re-gating rule as the other fields below — see withHookEscapeHatchGrant.
198
200
  function gatedProjectionReaderField(callerLabel, escapeHatch, ctxQueryProjection) {
199
201
  if (!ctxQueryProjection)
@@ -205,15 +207,26 @@ function gatedProjectionReaderField(callerLabel, escapeHatch, ctxQueryProjection
205
207
  queryProjection: createGatedProjectionReader(callerLabel, escapeHatch !== undefined, ungated, audit),
206
208
  };
207
209
  }
210
+ // A rebound db is a new object, so the outsideTransaction property has to be carried over; an input
211
+ // withUnsafeRawGrant passes through unchanged keeps its own.
212
+ function regatedDb(ctxDb, ctxDbOutsideTransaction, rawHatch) {
213
+ const gatedDb = withUnsafeRawGrant(ctxDb, rawHatch);
214
+ if (gatedDb !== ctxDb && ctxDbOutsideTransaction) {
215
+ attachOutsideTransaction(gatedDb, withUnsafeRawGrant(ctxDbOutsideTransaction, rawHatch));
216
+ }
217
+ return gatedDb;
218
+ }
208
219
  export function withHookEscapeHatchGrant(context, callerLabel, escapeHatch) {
209
- const ctxQueryAs = readIdentitySwitchFn(context, "queryAs");
210
- const ctxWriteAs = readIdentitySwitchFn(context, "writeAs");
211
- const ctxResolveActiveMembership = readIdentitySwitchFn(context, "resolveActiveMembership");
212
- const ctxQueryAsMember = readIdentitySwitchFn(context, "queryAsMember");
213
- const ctxQueryProjection = readIdentitySwitchFn(context, "queryProjection");
214
- const ctxDb = readDbLikeValue(context, "db");
215
- const ctxDbOutsideTransaction = readDbLikeValue(context, "dbOutsideTransaction");
216
- const ctxSystemDb = readDbLikeValue(context, "systemDb");
220
+ const dispatch = readObjectMember(context, "dispatch");
221
+ const auth = readObjectMember(context, "auth");
222
+ const ctxQueryAs = readFunctionMember(dispatch, "queryAs");
223
+ const ctxWriteAs = readFunctionMember(dispatch, "writeAs");
224
+ const ctxResolveActiveMembership = readFunctionMember(auth, "resolveActiveMembership");
225
+ const ctxQueryAsMember = readFunctionMember(dispatch, "queryAsMember");
226
+ const ctxQueryProjection = readFunctionMember(dispatch, "queryProjection");
227
+ const ctxDb = readObjectMember(context, "db");
228
+ const ctxDbOutsideTransaction = readObjectMember(ctxDb, "outsideTransaction");
229
+ const ctxSystemDb = readObjectMember(context, "systemDb");
217
230
  const identityHatch = escapeHatchFor(escapeHatch, "systemIdentity");
218
231
  const rawHatch = escapeHatchFor(escapeHatch, "unsafeRaw");
219
232
  if (!ctxQueryAs &&
@@ -222,29 +235,31 @@ export function withHookEscapeHatchGrant(context, callerLabel, escapeHatch) {
222
235
  !ctxQueryAsMember &&
223
236
  !ctxQueryProjection &&
224
237
  !ctxDb &&
225
- !ctxDbOutsideTransaction &&
226
238
  !ctxSystemDb) {
227
239
  return context;
228
240
  }
229
241
  return {
230
242
  ...context,
231
- ...gatedIdentitySwitchFields(callerLabel, identityHatch, ctxQueryAs, ctxWriteAs),
232
- ...(ctxResolveActiveMembership &&
233
- identityHatch === undefined && {
234
- resolveActiveMembership: deniedResolveActiveMembership(callerLabel),
243
+ ...(dispatch && {
244
+ dispatch: {
245
+ ...dispatch,
246
+ ...gatedIdentitySwitchFields(callerLabel, identityHatch, ctxQueryAs, ctxWriteAs),
247
+ ...gatedMemberReaderField(callerLabel, identityHatch, ctxQueryAsMember),
248
+ ...gatedProjectionReaderField(callerLabel, identityHatch, ctxQueryProjection),
249
+ },
235
250
  }),
236
- ...gatedMemberReaderField(callerLabel, identityHatch, ctxQueryAsMember),
237
- ...gatedProjectionReaderField(callerLabel, identityHatch, ctxQueryProjection),
238
- ...(ctxDb && { db: withUnsafeRawGrant(ctxDb, rawHatch) }),
239
- ...(ctxDbOutsideTransaction && {
240
- dbOutsideTransaction: withUnsafeRawGrant(ctxDbOutsideTransaction, rawHatch),
251
+ ...(auth &&
252
+ ctxResolveActiveMembership &&
253
+ identityHatch === undefined && {
254
+ auth: { ...auth, resolveActiveMembership: deniedResolveActiveMembership(callerLabel) },
241
255
  }),
256
+ ...(ctxDb && { db: regatedDb(ctxDb, ctxDbOutsideTransaction, rawHatch) }),
242
257
  ...(ctxSystemDb && {
243
258
  systemDb: withSystemDbUnsafeRawGrant(ctxSystemDb, rawHatch, callerLabel),
244
259
  }),
245
260
  };
246
261
  }
247
- // Re-gates a hook's own ctx.queryAs/ctx.writeAs/ctx.queryProjection/ctx.db/ctx.dbOutsideTransaction/ctx.systemDb instead of inheriting the handler's grant.
262
+ // Re-gates a hook's own ctx.dispatch.*/ctx.auth.resolveActiveMembership/ctx.db (incl. db.outsideTransaction)/ctx.systemDb instead of inheriting the handler's grant.
248
263
  export function bindHookEscapeHatchGrant(fn, label, escapeHatch) {
249
264
  return ((payload, context) => fn(payload, withHookEscapeHatchGrant(context, label, escapeHatch))); // @cast-boundary engine-bridge — LifecycleHookFn union, same (payload, context) shape at runtime
250
265
  }
@@ -0,0 +1,2 @@
1
+ import type { AppendEventFn, UnsafeAppendEventFn } from "@cosmicdrift/kumiko-types/handlers";
2
+ export declare function asTypedAppendEventFn(append: UnsafeAppendEventFn): AppendEventFn;
@@ -0,0 +1,4 @@
1
+ // The per-event-type signature is only enforced at the call site; at runtime the payload is validated against the registered schema.
2
+ export function asTypedAppendEventFn(append) {
3
+ return append; // @cast-boundary engine-bridge
4
+ }
@@ -1,5 +1,5 @@
1
1
  // The static check in boot-validator/access-declarations.ts only sees a handler's own
2
- // input schema; writes reached via ctx.write/writeAs/queryAs, hooks or foreign-feature
2
+ // input schema; writes reached via ctx.dispatch.write/writeAs/queryAs, hooks or foreign-feature
3
3
  // tables are only visible at the actual write, so the gate runs there at runtime.
4
4
  import { isPersonalDataGated } from "@cosmicdrift/kumiko-types/event-store-types";
5
5
  import * as z from "zod";
@@ -37,7 +37,7 @@ function declaresPublicIntake(access) {
37
37
  return accessAllowsAnonymous(access) && declaredPersonalData(access) === "public-intake";
38
38
  }
39
39
  // Only the public dispatcher entry points compute a root; every nested call inherits
40
- // it, so switching identity via ctx.writeAs(SYSTEM, ...) cannot shed an anonymous root.
40
+ // it, so switching identity via ctx.dispatch.writeAs(SYSTEM, ...) cannot shed an anonymous root.
41
41
  export function rootWriteOrigin(registry, type, user) {
42
42
  const rootHandler = registry.getWriteHandler(type) ?? registry.getQueryHandler(type);
43
43
  return {
@@ -1,4 +1,4 @@
1
- import type { WriteResult } from "../engine/types/index.ts";
1
+ import type { WriteResult } from "@cosmicdrift/kumiko-types/handlers";
2
2
  import type { BatchCommand, BatchResult, DispatchContext } from "./dispatch-shared.ts";
3
3
  type EntityLookup = Pick<DispatchContext["registry"], "getHandlerEntity" | "getEntity">;
4
4
  export declare function maskWriteResultForClient(registry: EntityLookup, handlerType: string, result: WriteResult): WriteResult;
@@ -1,19 +1,24 @@
1
1
  import { maskWriteOnlyFields } from "../engine/field-access.js";
2
2
  import { isLifecycleResult } from "./dispatcher-utils.js";
3
+ // The echoed event carries plaintext entity data; only hooks and projections may read it.
3
4
  function maskLifecycleOrRow(entity, data) {
4
5
  if (typeof data !== "object" || data === null || Array.isArray(data))
5
6
  return data;
6
- if (!isLifecycleResult(data))
7
- return maskWriteOnlyFields(entity, data); // @cast-boundary engine-payload
8
- if (data.kind === "save") {
7
+ if (!isLifecycleResult(data)) {
8
+ return entity ? maskWriteOnlyFields(entity, data) : data; // @cast-boundary engine-payload
9
+ }
10
+ const { event: _event, ...lifecycle } = data;
11
+ if (!entity)
12
+ return lifecycle;
13
+ if (lifecycle.kind === "save") {
9
14
  return {
10
- ...data,
11
- data: maskWriteOnlyFields(entity, data.data),
12
- changes: maskWriteOnlyFields(entity, data.changes),
13
- previous: maskWriteOnlyFields(entity, data.previous),
15
+ ...lifecycle,
16
+ data: maskWriteOnlyFields(entity, lifecycle.data),
17
+ changes: maskWriteOnlyFields(entity, lifecycle.changes),
18
+ previous: maskWriteOnlyFields(entity, lifecycle.previous),
14
19
  };
15
20
  }
16
- return { ...data, data: maskWriteOnlyFields(entity, data.data) };
21
+ return { ...lifecycle, data: maskWriteOnlyFields(entity, lifecycle.data) };
17
22
  }
18
23
  // Copy-on-mask: the original results still feed postSaveBatch hooks, which
19
24
  // need the plaintext. Only what leaves the dispatcher is masked.
@@ -22,8 +27,6 @@ export function maskWriteResultForClient(registry, handlerType, result) {
22
27
  return result;
23
28
  const entityName = registry.getHandlerEntity(handlerType);
24
29
  const entity = entityName ? registry.getEntity(entityName) : undefined;
25
- if (!entity)
26
- return result;
27
30
  const data = maskLifecycleOrRow(entity, result.data);
28
31
  return data === result.data ? result : { ...result, data };
29
32
  }
@@ -1,2 +1 @@
1
- export { type AdjNounNameOptions, type GenerateUniqueNameOptions, generateAdjNounName, generateNoConfusableId, generateUniqueName, } from "./generate.ts";
2
- export { ADJECTIVES, NOUNS } from "./words.ts";
1
+ export { generateUniqueName } from "./generate.ts";
@@ -1,2 +1 @@
1
- export { generateAdjNounName, generateNoConfusableId, generateUniqueName, } from "./generate.js";
2
- export { ADJECTIVES, NOUNS } from "./words.js";
1
+ export { generateUniqueName } from "./generate.js";
@@ -1,4 +1,5 @@
1
- import type { PayloadBucketNormalization, RateLimitOption, SessionUser } from "../engine/types/index.ts";
1
+ import type { PayloadBucketNormalization, RateLimitOption } from "@cosmicdrift/kumiko-types/handlers";
2
+ import type { SessionUser } from "../engine/types/index.ts";
2
3
  export type BucketContext = {
3
4
  readonly handlerName: string;
4
5
  readonly user: SessionUser;
@@ -1,7 +1,8 @@
1
1
  import { isAuthRateLimitExempt } from "../api/api-constants.js";
2
2
  import { clientIpSourceFromHonoContext, createClientIpResolver, } from "../api/client-ip.js";
3
3
  import { requestContext } from "../api/request-context.js";
4
- import { RateLimitError, serializeError } from "../errors/index.js";
4
+ import { RateLimitError } from "../errors/index.js";
5
+ import { serializeError } from "../errors/serialize.js";
5
6
  import { createFallbackLogger, scrubLogText } from "../logging/index.js";
6
7
  import { emitRateLimitFailOpen } from "../observability/standard-metrics.js";
7
8
  import { toPublicBucketName } from "./bucket.js";
@@ -1,8 +1,7 @@
1
- export type { CacheSyncBus, CacheSyncBusOverSignalOptions, ClosableCacheSyncBus, RedisCacheSyncBusOptions, ResolvedCacheSyncBus, } from "./cache-sync-bus.ts";
2
- export { createCacheSyncBusOverSignal, createDefaultCacheSyncBus, createLocalCacheSyncBus, createRedisCacheSyncBus, resolveCacheSyncBus, } from "./cache-sync-bus.ts";
1
+ export type { CacheSyncBus, ClosableCacheSyncBus, } from "./cache-sync-bus.ts";
2
+ export { createDefaultCacheSyncBus, createLocalCacheSyncBus, createRedisCacheSyncBus, } from "./cache-sync-bus.ts";
3
3
  export type { TenantConfigSyncMessage, TierAssignmentSyncMessage } from "./cache-sync-topics.ts";
4
- export { CACHE_SYNC_TOPICS, isTenantConfigSyncMessage, isTierAssignmentSyncMessage, } from "./cache-sync-topics.ts";
4
+ export { CACHE_SYNC_TOPICS, isTierAssignmentSyncMessage, } from "./cache-sync-topics.ts";
5
5
  export type { RedisClientOptions } from "./client.ts";
6
6
  export { createRedisClient, logRedisConnectionState, redisChannelPrefixFromEnv, redisClientOptionsFromEnv, } from "./client.ts";
7
- export type { PubSubSignal, PubSubSignalOptions } from "./pubsub-signal.ts";
8
7
  export { createRedisPubSubSignal } from "./pubsub-signal.ts";
@@ -1,4 +1,4 @@
1
- export { createCacheSyncBusOverSignal, createDefaultCacheSyncBus, createLocalCacheSyncBus, createRedisCacheSyncBus, resolveCacheSyncBus, } from "./cache-sync-bus.js";
2
- export { CACHE_SYNC_TOPICS, isTenantConfigSyncMessage, isTierAssignmentSyncMessage, } from "./cache-sync-topics.js";
1
+ export { createDefaultCacheSyncBus, createLocalCacheSyncBus, createRedisCacheSyncBus, } from "./cache-sync-bus.js";
2
+ export { CACHE_SYNC_TOPICS, isTierAssignmentSyncMessage, } from "./cache-sync-topics.js";
3
3
  export { createRedisClient, logRedisConnectionState, redisChannelPrefixFromEnv, redisClientOptionsFromEnv, } from "./client.js";
4
4
  export { createRedisPubSubSignal } from "./pubsub-signal.js";
@@ -4,7 +4,7 @@ import { createRegistry } from "../engine/registry.js";
4
4
  import { createEventsTable } from "../event-store/index.js";
5
5
  import { queueRebuildsFromMarkers, reportPendingRebuildRun, runPendingRebuilds, } from "../migrations/index.js";
6
6
  import { createEventConsumerStateTable, createProjectionStateTable } from "../pipeline/index.js";
7
- import { migrationsDirExistsOrReport, readDatabaseUrlOrReport, } from "./shared.js";
7
+ import { loadRowLevelSecurityModeOrReport, migrationsDirExistsOrReport, readDatabaseUrlOrReport, } from "./shared.js";
8
8
  async function ensureFrameworkInfrastructureTables(db) {
9
9
  // Framework infrastructure tables (event store + pipeline state) are not captured by
10
10
  // `generate`, which handles only entity read tables. Existing databases have them
@@ -52,7 +52,10 @@ export async function runApplyCommand(ctx) {
52
52
  return 1;
53
53
  if (!migrationsDirExistsOrReport(ctx))
54
54
  return 1;
55
- const { db, close } = createDbConnection({ url: dbUrl });
55
+ const rowLevelSecurity = await loadRowLevelSecurityModeOrReport(ctx);
56
+ if (rowLevelSecurity === undefined)
57
+ return 1;
58
+ const { db, close } = createDbConnection({ url: dbUrl, rowLevelSecurity });
56
59
  let wiring;
57
60
  try {
58
61
  const result = await runMigrationsFromDir(db, migrationsDir);
@@ -1,4 +1,5 @@
1
- import { baselineMigrations, createDbConnection, loadMigrationsFromDir } from "../db/index.js";
1
+ import { createDbConnection } from "../db/index.js";
2
+ import { baselineMigrations, loadMigrationsFromDir } from "../db/migrate-runner.js";
2
3
  import { describeThrown, migrationsDirExistsOrReport, readDatabaseUrlOrReport, } from "./shared.js";
3
4
  export async function runBaselineCommand(ctx) {
4
5
  const { out, migrationsDir } = ctx;
@@ -10,7 +11,11 @@ export async function runBaselineCommand(ctx) {
10
11
  return 1;
11
12
  if (!migrationsDirExistsOrReport(ctx))
12
13
  return 1;
13
- const { db, close } = createDbConnection({ url: dbUrl });
14
+ const { db, close } = createDbConnection({
15
+ url: dbUrl,
16
+ maxConnections: 1,
17
+ rowLevelSecurity: "off", // journal-only tool: touches no tenant rows
18
+ });
14
19
  try {
15
20
  const result = await baselineMigrations(db, loadMigrationsFromDir(migrationsDir));
16
21
  out.log("");
@@ -1,6 +1,9 @@
1
1
  import { existsSync, mkdirSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
- import { assertValidMigrationName, generateMigration, readMigrationSqlTexts, rebuildTablesFromDiff, writeRebuildMarker, writeSnapshotJson, } from "../db/index.js";
3
+ import { generateMigration, writeSnapshotJson } from "../db/index.js";
4
+ import { assertValidMigrationName, hasNoSchemaChanges } from "../db/migrate-generator.js";
5
+ import { readMigrationSqlTexts } from "../db/migrate-runner.js";
6
+ import { rebuildTablesFromDiff, writeRebuildMarker } from "../db/rebuild-marker.js";
4
7
  import { describeThrown, loadPreviousSnapshot, loadSchemaModOrReport, nextSequenceNumber, SNAPSHOT_FILENAME, } from "./shared.js";
5
8
  const GENERATE_USAGE = " Usage: schema generate <name>";
6
9
  function parseGenerateName(ctx) {
@@ -35,12 +38,6 @@ function parseGenerateName(ctx) {
35
38
  }
36
39
  return { kind: "name", name };
37
40
  }
38
- function isEmptyMigration(result) {
39
- return (result.diff.newTables.length === 0 &&
40
- result.diff.changedTables.length === 0 &&
41
- result.diff.droppedTables.length === 0 &&
42
- result.retiredDrops.length === 0);
43
- }
44
41
  function writeMigrationFiles(migrationsDir, snapshotPath, result) {
45
42
  if (!existsSync(migrationsDir))
46
43
  mkdirSync(migrationsDir, { recursive: true });
@@ -50,7 +47,7 @@ function writeMigrationFiles(migrationsDir, snapshotPath, result) {
50
47
  function reportGeneratedMigration(out, result, rebuildTables) {
51
48
  out.log("");
52
49
  out.log(` ✓ ${result.filename}`);
53
- out.log(` new tables: ${result.diff.newTables.length}, changed: ${result.diff.changedTables.length}, dropped: ${result.diff.droppedTables.length}, retired framework tables dropped: ${result.retiredDrops.length}`);
50
+ out.log(` new tables: ${result.diff.newTables.length}, changed: ${result.diff.changedTables.length}, dropped: ${result.diff.droppedTables.length}, retired framework tables dropped: ${result.retiredDrops.length}, row level security changes: ${result.rowLevelSecurityChanges.length}`);
54
51
  if (rebuildTables.length > 0) {
55
52
  out.log(` rebuild-marker: ${result.filename.replace(/\.sql$/, ".rebuild.json")} (${rebuildTables.length} table(s))`);
56
53
  }
@@ -70,12 +67,13 @@ export async function runGenerateCommand(ctx) {
70
67
  const prevSnapshot = loadPreviousSnapshot(snapshotPath);
71
68
  const result = generateMigration({
72
69
  metas: schemaMod.entityMetas,
70
+ rowLevelSecurity: schemaMod.rowLevelSecurity,
73
71
  prevSnapshot,
74
72
  name: parsed.name,
75
73
  sequenceNumber: nextSequenceNumber(migrationsDir),
76
74
  priorMigrationsSql: readMigrationSqlTexts(migrationsDir),
77
75
  });
78
- if (isEmptyMigration(result)) {
76
+ if (hasNoSchemaChanges(result)) {
79
77
  out.log(" No schema changes detected — no new migration file written.");
80
78
  return 0;
81
79
  }
@@ -1,4 +1,5 @@
1
1
  import { type renderTablesDdl } from "../db/index.ts";
2
+ import { type RowLevelSecurityMode } from "../db/render-rls-ddl.ts";
2
3
  import type { FeatureDefinition } from "../engine/types/feature.ts";
3
4
  export type SchemaCliOut = {
4
5
  readonly log: (line: string) => void;
@@ -30,10 +31,13 @@ export type SchemaMod = {
30
31
  readonly entityMetas: Parameters<typeof renderTablesDdl>[0];
31
32
  readonly features?: unknown;
32
33
  readonly validateBootOptions?: unknown;
34
+ readonly rowLevelSecurity: RowLevelSecurityMode;
33
35
  };
36
+ export declare function parseSchemaRowLevelSecurity(value: unknown, schemaFile: string): RowLevelSecurityMode;
34
37
  export declare function describeThrown(e: unknown): string;
35
38
  export declare function nextSequenceNumber(migrationsDir: string): number;
36
39
  export declare function loadPreviousSnapshot(snapshotPath: string): import("../db/migrate-generator.ts").Snapshot | null;
37
40
  export declare function loadSchemaModOrReport(ctx: SchemaCliContext): Promise<SchemaMod | undefined>;
41
+ export declare function loadRowLevelSecurityModeOrReport(ctx: SchemaCliContext): Promise<RowLevelSecurityMode | undefined>;
38
42
  export declare function readDatabaseUrlOrReport(out: SchemaCliOut): string | undefined;
39
43
  export declare function migrationsDirExistsOrReport(ctx: SchemaCliContext): boolean;
@@ -7,10 +7,20 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
7
7
  return path;
8
8
  };
9
9
  import { existsSync, readdirSync } from "node:fs";
10
- import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
11
- import { assertUniqueTableNames, loadSnapshotJson } from "../db/index.js";
10
+ import { isOneOf, isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
11
+ import { loadSnapshotJson } from "../db/index.js";
12
+ import { assertUniqueTableNames } from "../db/migrate-generator.js";
13
+ import { DEFAULT_ROW_LEVEL_SECURITY_MODE, ROW_LEVEL_SECURITY_MODES, } from "../db/render-rls-ddl.js";
12
14
  import { isEntityTableMeta } from "../db/table-introspection.js";
13
15
  export const SNAPSHOT_FILENAME = ".snapshot.json";
16
+ // An absent export means the default mode; a typo must not silently switch tenant isolation off.
17
+ export function parseSchemaRowLevelSecurity(value, schemaFile) {
18
+ if (value === undefined)
19
+ return DEFAULT_ROW_LEVEL_SECURITY_MODE;
20
+ if (isOneOf(ROW_LEVEL_SECURITY_MODES, value))
21
+ return value;
22
+ throw new Error(`Schema file ${schemaFile}: ROW_LEVEL_SECURITY must be one of ${ROW_LEVEL_SECURITY_MODES.join(", ")}, got ${String(value)}.`);
23
+ }
14
24
  export function describeThrown(e) {
15
25
  return e instanceof Error ? e.message : String(e);
16
26
  }
@@ -43,6 +53,7 @@ async function loadSchemaModFromApp(schemaFile) {
43
53
  entityMetas: validMetas,
44
54
  features: mod["FEATURES"],
45
55
  validateBootOptions: mod["VALIDATE_BOOT_OPTIONS"],
56
+ rowLevelSecurity: parseSchemaRowLevelSecurity(mod["ROW_LEVEL_SECURITY"], schemaFile),
46
57
  };
47
58
  }
48
59
  export function nextSequenceNumber(migrationsDir) {
@@ -79,6 +90,14 @@ export async function loadSchemaModOrReport(ctx) {
79
90
  return undefined;
80
91
  }
81
92
  }
93
+ // `apply` needs only the mode: migrations and rebuilds on a role that RLS binds see nothing unless
94
+ // the connection runs in system scope, which only an "on" connection sets. Without a schema file
95
+ // (dev CLI against a bare checkout) there is nothing to enforce.
96
+ export async function loadRowLevelSecurityModeOrReport(ctx) {
97
+ if (!existsSync(ctx.schemaFile))
98
+ return "off";
99
+ return (await loadSchemaModOrReport(ctx))?.rowLevelSecurity;
100
+ }
82
101
  export function readDatabaseUrlOrReport(out) {
83
102
  const dbUrl = process.env["DATABASE_URL"];
84
103
  if (!dbUrl) {
@@ -1,6 +1,8 @@
1
1
  import { existsSync } from "node:fs";
2
2
  import { join } from "node:path";
3
- import { createDbConnection, fetchAppliedMigrations, findCommentedDropTables, isRetiredFrameworkTable, loadMigrationsFromDir, readMigrationSqlTexts, tableExists, } from "../db/index.js";
3
+ import { createDbConnection, tableExists } from "../db/index.js";
4
+ import { fetchAppliedMigrations, loadMigrationsFromDir, readMigrationSqlTexts, } from "../db/migrate-runner.js";
5
+ import { findCommentedDropTables, isRetiredFrameworkTable, } from "../db/retired-framework-tables.js";
4
6
  import { describeThrown, loadPreviousSnapshot, readDatabaseUrlOrReport, SNAPSHOT_FILENAME, } from "./shared.js";
5
7
  // A table that a migration only drops as a commented DESTRUCTIVE marker and
6
8
  // that the snapshot no longer has is gone on paper but still in the live DB.
@@ -42,7 +44,11 @@ export async function runStatusCommand(ctx) {
42
44
  return 0;
43
45
  }
44
46
  const local = loadMigrationsFromDir(migrationsDir);
45
- const { db, close } = createDbConnection({ url: dbUrl });
47
+ const { db, close } = createDbConnection({
48
+ url: dbUrl,
49
+ maxConnections: 1,
50
+ rowLevelSecurity: "off", // journal-only tool: touches no tenant rows
51
+ });
46
52
  try {
47
53
  const applied = await fetchAppliedMigrationIds(db);
48
54
  out.log("");