@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,43 +1,27 @@
1
- import type { AggregateStreamHandle, AppendEventArgs, AppendEventFn, FetchForWritingArgs } from "../engine/types/index.ts";
1
+ import type { AppendEventArgs } from "@cosmicdrift/kumiko-types/handlers";
2
+ import type { HandlerEvents } from "../engine/types/index.ts";
2
3
  import { IdempotentAppendConflictError as EventStoreIdempotentAppendConflictError, VersionConflictError as EventStoreVersionConflictError } from "../event-store/errors.ts";
3
4
  import { type StoredEvent } from "../event-store/event-store.ts";
4
- import { type LoadAggregateWithSnapshotOptions, type LoadAggregateWithSnapshotResult, type SnapshotReducer } from "../event-store/snapshot.ts";
5
5
  import type { HandlerContextScope } from "./handler-context-scope.ts";
6
+ import { type ProjectionReader } from "./system-identity-switch.ts";
7
+ declare function buildTryAppendEvent(scope: HandlerContextScope): (args: AppendEventArgs) => Promise<{
8
+ ok: true;
9
+ event: StoredEvent;
10
+ conflict?: undefined;
11
+ } | {
12
+ event?: undefined;
13
+ ok: false;
14
+ conflict: EventStoreVersionConflictError;
15
+ } | {
16
+ event?: undefined;
17
+ ok: false;
18
+ conflict: EventStoreIdempotentAppendConflictError;
19
+ }>;
20
+ type EventsFacet = Omit<HandlerEvents, "tryAppend"> & {
21
+ readonly tryAppend: ReturnType<typeof buildTryAppendEvent>;
22
+ };
6
23
  export declare function buildEventStoreFacet(scope: HandlerContextScope): {
7
- appendEvent: AppendEventFn;
8
- unsafeAppendEvent: (args: AppendEventArgs) => Promise<void>;
9
- tryAppendEvent: (args: AppendEventArgs) => Promise<{
10
- ok: true;
11
- event: StoredEvent;
12
- conflict?: undefined;
13
- } | {
14
- event?: undefined;
15
- ok: false;
16
- conflict: EventStoreVersionConflictError;
17
- } | {
18
- event?: undefined;
19
- ok: false;
20
- conflict: EventStoreIdempotentAppendConflictError;
21
- }>;
22
- fetchForWriting: (args: FetchForWritingArgs) => Promise<AggregateStreamHandle>;
23
- loadAggregate: (aggregateId: string, loadOptions?: {
24
- readonly asOf?: Temporal.Instant;
25
- }) => Promise<readonly StoredEvent[]>;
26
- archiveStream: (aggregateId: string, archiveArgs: {
27
- readonly aggregateType: string;
28
- readonly reason?: string;
29
- }) => Promise<void>;
30
- restoreStream: (aggregateId: string) => Promise<void>;
31
- isStreamArchived: (aggregateId: string) => Promise<boolean>;
32
- snapshotAggregate: (snapshotArgs: {
33
- readonly aggregateId: string;
34
- readonly aggregateType: string;
35
- readonly version: number;
36
- readonly state: Record<string, unknown>;
37
- readonly snapshotVersion?: number;
38
- }) => Promise<void>;
39
- loadAggregateWithSnapshot: <TState extends Record<string, unknown>>(aggregateId: string, reducer: SnapshotReducer<TState>, initial: TState, loadOptions?: Omit<LoadAggregateWithSnapshotOptions, "upcastEvent" | "entityEventVersionOf">) => Promise<LoadAggregateWithSnapshotResult<TState>>;
40
- queryProjection: <T = Record<string, unknown>>(qualifiedName: string, options?: {
41
- readonly unsafeAllTenants?: boolean;
42
- }) => Promise<readonly T[]>;
24
+ readonly events: EventsFacet;
25
+ readonly queryProjection: ProjectionReader;
43
26
  };
27
+ export {};
@@ -1,6 +1,8 @@
1
1
  import { runInSavepoint, selectMany } from "../db/query.js";
2
+ import { runInSystemRowLevelSecurityScope } from "../db/row-level-security-scope.js";
2
3
  import { hasTenantColumn } from "../db/tenant-db.js";
3
- import { InternalError, memberResolutionReadOnlyDenied, VersionConflictError, } from "../errors/index.js";
4
+ import { InternalError, VersionConflictError } from "../errors/index.js";
5
+ import { memberResolutionReadOnlyDenied } from "../errors/member-resolution.js";
4
6
  import { archiveStream as archiveStreamHelper, isStreamArchived, restoreStream as restoreStreamHelper, } from "../event-store/archive.js";
5
7
  import { IdempotentAppendConflictError as EventStoreIdempotentAppendConflictError, VersionConflictError as EventStoreVersionConflictError, } from "../event-store/errors.js";
6
8
  import { loadAggregate, loadAggregateAsOf, loadAggregateForWriting, } from "../event-store/event-store.js";
@@ -9,6 +11,7 @@ import { upcastStoredEvent, upcastStoredEvents } from "../event-store/upcaster.j
9
11
  import { appendDomainEventCore } from "./append-event-core.js";
10
12
  import { isMemberResolutionPrincipal, resolveDbSource, } from "./dispatch-shared.js";
11
13
  import { createGatedProjectionReader } from "./system-identity-switch.js";
14
+ import { asTypedAppendEventFn } from "./typed-append-event.js";
12
15
  function requireDbSource(ctx, tx, surfaceCall) {
13
16
  const dbSource = resolveDbSource(ctx, tx);
14
17
  if (!dbSource) {
@@ -18,7 +21,7 @@ function requireDbSource(ctx, tx, surfaceCall) {
18
21
  }
19
22
  return dbSource;
20
23
  }
21
- // ctx.appendEvent — append a domain event onto a specific aggregate stream
24
+ // ctx.events.append — append a domain event onto a specific aggregate stream
22
25
  // in the current tx, then fire matching inline projections. Core logic
23
26
  // lives in appendDomainEventCore; this wrapper just locates dbSource +
24
27
  // stringifies the SessionUser id for the shared helper.
@@ -27,20 +30,20 @@ async function appendDomainEvent(ctx, args, user, tx, callerFeature) {
27
30
  if (isMemberResolutionPrincipal(user))
28
31
  throw memberResolutionReadOnlyDenied();
29
32
  const { registry } = ctx;
30
- const dbSource = requireDbSource(ctx, tx, `ctx.appendEvent("${args.type}")`);
33
+ const dbSource = requireDbSource(ctx, tx, `ctx.events.append("${args.type}")`);
31
34
  await appendDomainEventCore({
32
35
  registry,
33
36
  db: dbSource,
34
37
  tenantId: user.tenantId,
35
38
  userId: String(user.id),
36
- callSiteLabel: "ctx.appendEvent",
39
+ callSiteLabel: "ctx.events.append",
37
40
  callerFeature,
38
41
  }, args);
39
42
  }
40
43
  // Savepoint-scoped append: catches a losing writer's VersionConflictError
41
- // without poisoning the rest of the handler's transaction. postgres.js
42
- // aborts the WHOLE begin() on an uncaught statement error
43
- // (SQLSTATE 25P02) even if the JS error is caught — runInSavepoint
44
+ // without poisoning the rest of the handler's transaction. Postgres
45
+ // aborts the WHOLE transaction on a statement error
46
+ // (SQLSTATE 25P02 until rollback) even if the JS error is caught — runInSavepoint
44
47
  // wraps the append in a real SAVEPOINT so only that nested scope rolls
45
48
  // back on conflict, and subsequent statements in the outer tx (e.g. a
46
49
  // dedup-anchor insert) still succeed. Use when a handler must react to
@@ -50,7 +53,7 @@ function buildTryAppendEvent(scope) {
50
53
  return async (args) => {
51
54
  if (!tx) {
52
55
  throw new InternalError({
53
- message: `ctx.tryAppendEvent("${args.type}") requires an active transaction — no tx is threaded through this call.`,
56
+ message: `ctx.events.tryAppend("${args.type}") requires an active transaction — no tx is threaded through this call.`,
54
57
  });
55
58
  }
56
59
  try {
@@ -59,7 +62,7 @@ function buildTryAppendEvent(scope) {
59
62
  db: sp,
60
63
  tenantId: user.tenantId,
61
64
  userId: String(user.id),
62
- callSiteLabel: "ctx.tryAppendEvent",
65
+ callSiteLabel: "ctx.events.tryAppend",
63
66
  callerFeature: registry.getHandlerFeature(type),
64
67
  }, args));
65
68
  return { ok: true, event };
@@ -78,7 +81,7 @@ function buildTryAppendEvent(scope) {
78
81
  function buildFetchForWriting(scope) {
79
82
  const { ctx, type, user, tx, registry } = scope;
80
83
  return async (args) => {
81
- const dbSource = requireDbSource(ctx, tx, `ctx.fetchForWriting("${args.aggregateId}")`);
84
+ const dbSource = requireDbSource(ctx, tx, `ctx.events.fetchForWriting("${args.aggregateId}")`);
82
85
  // Stream-version authoritative (same policy as CRUD executor + Block 0), read together
83
86
  // with the events so the pinned version covers exactly what the handler's rules saw.
84
87
  const { events: storedEvents, streamVersion: fetchedVersion } = await loadAggregateForWriting(dbSource, args.aggregateId, user.tenantId, { aggregateType: args.aggregateType });
@@ -124,10 +127,12 @@ function buildFetchForWriting(scope) {
124
127
  function buildLoadAggregate(scope) {
125
128
  const { ctx, user, tx, registry } = scope;
126
129
  return async (aggregateId, loadOptions) => {
127
- const dbSource = requireDbSource(ctx, tx, `ctx.loadAggregate("${aggregateId}")`);
130
+ const dbSource = requireDbSource(ctx, tx, `ctx.events.load("${aggregateId}")`);
128
131
  const events = loadOptions?.asOf
129
132
  ? await loadAggregateAsOf(dbSource, aggregateId, user.tenantId, loadOptions.asOf)
130
- : await loadAggregate(dbSource, aggregateId, user.tenantId);
133
+ : await loadAggregate(dbSource, aggregateId, user.tenantId, {
134
+ ...(loadOptions?.atVersion !== undefined && { atVersion: loadOptions.atVersion }),
135
+ });
131
136
  return upcastStoredEvents(events, registry.getEventUpcasters(), {
132
137
  db: dbSource,
133
138
  tenantId: user.tenantId,
@@ -137,7 +142,7 @@ function buildLoadAggregate(scope) {
137
142
  function buildSnapshotAggregate(scope) {
138
143
  const { ctx, user, tx, registry } = scope;
139
144
  return async (snapshotArgs) => {
140
- const dbSource = requireDbSource(ctx, tx, `ctx.snapshotAggregate("${snapshotArgs.aggregateId}")`);
145
+ const dbSource = requireDbSource(ctx, tx, `ctx.events.snapshot("${snapshotArgs.aggregateId}")`);
141
146
  await saveSnapshot(dbSource, {
142
147
  aggregateId: snapshotArgs.aggregateId,
143
148
  tenantId: user.tenantId,
@@ -151,7 +156,7 @@ function buildSnapshotAggregate(scope) {
151
156
  function buildLoadAggregateWithSnapshot(scope) {
152
157
  const { ctx, user, tx, registry } = scope;
153
158
  return async (aggregateId, reducer, initial, loadOptions) => {
154
- const dbSource = requireDbSource(ctx, tx, `ctx.loadAggregateWithSnapshot("${aggregateId}")`);
159
+ const dbSource = requireDbSource(ctx, tx, `ctx.events.loadWithSnapshot("${aggregateId}")`);
155
160
  // Upcaster-aware: pass an upcastEvent callback so loadAggregateWithSnapshot
156
161
  // walks every delta through the registered chain before invoking the
157
162
  // user's (sync) reducer. Async upcasters (DB-enrichment) are awaited
@@ -180,15 +185,17 @@ function buildHandlerProjectionReader(scope) {
180
185
  const mspNames = [...registry.getAllMultiStreamProjections().keys()].filter((n) => registry.getAllMultiStreamProjections().get(n)?.table);
181
186
  const all = [...singleNames, ...mspNames];
182
187
  throw new InternalError({
183
- message: `ctx.queryProjection("${qualifiedName}") — projection not registered, or it is a ` +
188
+ message: `ctx.dispatch.queryProjection("${qualifiedName}") — projection not registered, or it is a ` +
184
189
  `table-less MSP (side-effect-only). Known queryable projections: ${all.join(", ") || "(none)"}`,
185
190
  });
186
191
  }
187
- const dbSource = requireDbSource(ctx, tx, `ctx.queryProjection("${qualifiedName}")`);
188
- const where = hasTenantColumn(projTable) && queryOptions?.unsafeAllTenants !== true
189
- ? { tenantId: user.tenantId }
190
- : undefined;
191
- const rows = await selectMany(dbSource, projTable, where);
192
+ const dbSource = requireDbSource(ctx, tx, `ctx.dispatch.queryProjection("${qualifiedName}")`);
193
+ const allTenants = queryOptions?.unsafeAllTenants === true;
194
+ const where = hasTenantColumn(projTable) && !allTenants ? { tenantId: user.tenantId } : undefined;
195
+ const read = () => selectMany(dbSource, projTable, where);
196
+ const rows = await (allTenants
197
+ ? runInSystemRowLevelSecurityScope("handler projection read with allTenants spans every tenant", read)
198
+ : read());
192
199
  return rows; // @cast-boundary engine-payload
193
200
  };
194
201
  return createGatedProjectionReader(`handler "${type}"`, hasIdentitySwitchGrant, ungatedQueryProjection, identitySwitchAudit, (qualifiedName) => {
@@ -199,21 +206,21 @@ function buildHandlerProjectionReader(scope) {
199
206
  }
200
207
  export function buildEventStoreFacet(scope) {
201
208
  const { ctx, type, user, tx, registry } = scope;
202
- return {
209
+ const events = {
203
210
  // Strict + unsafe share the same runtime — only the type-surface
204
211
  // differs. The strict signature is what's exposed to typed callers;
205
212
  // unsafe is the explicit escape-hatch for runtime-pluggable events.
206
- appendEvent: (async (args) => {
213
+ append: asTypedAppendEventFn(async (args) => {
207
214
  await appendDomainEvent(ctx, args, user, tx, registry.getHandlerFeature(type));
208
- }), // @cast-boundary engine-bridge
209
- unsafeAppendEvent: async (args) => {
215
+ }),
216
+ unsafeAppend: async (args) => {
210
217
  await appendDomainEvent(ctx, args, user, tx, registry.getHandlerFeature(type));
211
218
  },
212
- tryAppendEvent: buildTryAppendEvent(scope),
219
+ tryAppend: buildTryAppendEvent(scope),
213
220
  fetchForWriting: buildFetchForWriting(scope),
214
- loadAggregate: buildLoadAggregate(scope),
215
- archiveStream: async (aggregateId, archiveArgs) => {
216
- const dbSource = requireDbSource(ctx, tx, `ctx.archiveStream("${aggregateId}")`);
221
+ load: buildLoadAggregate(scope),
222
+ archive: async (aggregateId, archiveArgs) => {
223
+ const dbSource = requireDbSource(ctx, tx, `ctx.events.archive("${aggregateId}")`);
217
224
  await archiveStreamHelper(dbSource, {
218
225
  tenantId: user.tenantId,
219
226
  aggregateId,
@@ -222,16 +229,16 @@ export function buildEventStoreFacet(scope) {
222
229
  reason: archiveArgs.reason,
223
230
  });
224
231
  },
225
- restoreStream: async (aggregateId) => {
226
- const dbSource = requireDbSource(ctx, tx, `ctx.restoreStream("${aggregateId}")`);
232
+ restore: async (aggregateId) => {
233
+ const dbSource = requireDbSource(ctx, tx, `ctx.events.restore("${aggregateId}")`);
227
234
  await restoreStreamHelper(dbSource, user.tenantId, aggregateId);
228
235
  },
229
- isStreamArchived: async (aggregateId) => {
230
- const dbSource = requireDbSource(ctx, tx, `ctx.isStreamArchived("${aggregateId}")`);
236
+ isArchived: async (aggregateId) => {
237
+ const dbSource = requireDbSource(ctx, tx, `ctx.events.isArchived("${aggregateId}")`);
231
238
  return isStreamArchived(dbSource, user.tenantId, aggregateId);
232
239
  },
233
- snapshotAggregate: buildSnapshotAggregate(scope),
234
- loadAggregateWithSnapshot: buildLoadAggregateWithSnapshot(scope),
235
- queryProjection: buildHandlerProjectionReader(scope),
240
+ snapshot: buildSnapshotAggregate(scope),
241
+ loadWithSnapshot: buildLoadAggregateWithSnapshot(scope),
236
242
  };
243
+ return { events, queryProjection: buildHandlerProjectionReader(scope) };
237
244
  }
@@ -0,0 +1,2 @@
1
+ import type { HandlerContext } from "../engine/types/index.ts";
2
+ export declare function applyMemberResolutionReadOnly(handlerContext: HandlerContext): HandlerContext;
@@ -0,0 +1,110 @@
1
+ import { memberResolutionReadOnlyDenied } from "../errors/member-resolution.js";
2
+ import { denyingJobRunnerProxy, dropOutsideTransaction, withoutNotifyFactories, } from "./handler-context-phase-denials.js";
3
+ import { asTypedAppendEventFn } from "./typed-append-event.js";
4
+ async function denyMemberResolutionWrite() {
5
+ throw memberResolutionReadOnlyDenied();
6
+ }
7
+ function throwMemberResolutionDenied() {
8
+ throw memberResolutionReadOnlyDenied();
9
+ }
10
+ // Allowlist (not denylist): a method added to the target later stays denied
11
+ // until someone decides it is read-only.
12
+ function allowlistedReadOnlyProxy(target, allowedMethods) {
13
+ return new Proxy(target, {
14
+ get(inner, prop) {
15
+ if (typeof prop === "string" && allowedMethods.has(prop)) {
16
+ const method = Reflect.get(inner, prop, inner);
17
+ return typeof method === "function" ? method.bind(inner) : method;
18
+ }
19
+ // Symbol reads and "then" come from await/Promise.resolve/inspect, not from handler code.
20
+ if (typeof prop === "symbol" || prop === "then")
21
+ return undefined;
22
+ throw memberResolutionReadOnlyDenied();
23
+ },
24
+ });
25
+ }
26
+ const MEMBER_READ_SEARCH_METHODS = new Set(["search"]);
27
+ const MEMBER_READ_ENTITY_CACHE_METHODS = new Set(["get", "mget"]);
28
+ const MEMBER_READ_REDIS_METHODS = new Set([
29
+ "get",
30
+ "mget",
31
+ "exists",
32
+ "ttl",
33
+ "pttl",
34
+ "strlen",
35
+ "type",
36
+ "hget",
37
+ "hmget",
38
+ "hgetall",
39
+ "hexists",
40
+ "hlen",
41
+ "sismember",
42
+ "smembers",
43
+ "scard",
44
+ "llen",
45
+ "lrange",
46
+ "zscore",
47
+ "zcard",
48
+ "zrange",
49
+ ]);
50
+ function readOnlyServices(services) {
51
+ const { searchAdapter, redis, entityCache, jobRunner } = services;
52
+ // A read as a member gets no file storage, no notify factory and no job runner; the read-only
53
+ // proxies keep the rest. The resolver and factories would reopen what files/notify close.
54
+ const { files: _files, derivatives: _derivatives, _fileProviderResolver: _resolver, ...kept } = withoutNotifyFactories(services);
55
+ const runner = jobRunner && denyingJobRunnerProxy();
56
+ return {
57
+ ...kept,
58
+ ...(runner && { jobRunner: runner }),
59
+ ...(searchAdapter && {
60
+ searchAdapter: allowlistedReadOnlyProxy(searchAdapter, MEMBER_READ_SEARCH_METHODS),
61
+ }),
62
+ ...(redis && { redis: allowlistedReadOnlyProxy(redis, MEMBER_READ_REDIS_METHODS) }),
63
+ ...(entityCache && {
64
+ entityCache: allowlistedReadOnlyProxy(entityCache, MEMBER_READ_ENTITY_CACHE_METHODS),
65
+ }),
66
+ };
67
+ }
68
+ // Every write/side-effect surface throws, so "no writeAsMember" holds even
69
+ // if a handler tries ctx.dispatch.write directly on a resolved member principal.
70
+ // Deliberately open: `db` (guarded by the READ ONLY transaction + memberReadOnly grant),
71
+ // and read-only methods of searchAdapter / redis / entityCache (allowlisted).
72
+ export function applyMemberResolutionReadOnly(handlerContext) {
73
+ // `db` stays open — executeQuery runs the whole handler in a Postgres READ ONLY
74
+ // transaction, and its `memberReadOnly` grant denies every raw-runner handout.
75
+ dropOutsideTransaction(handlerContext);
76
+ const { systemDb: _systemDb, crossTenantReads: _crossTenantReads, ...kept } = handlerContext;
77
+ return {
78
+ ...kept,
79
+ dispatch: {
80
+ ...handlerContext.dispatch,
81
+ write: denyMemberResolutionWrite,
82
+ writeAs: denyMemberResolutionWrite,
83
+ // A resolved member cannot switch identity either — the target would get a normal, writable context.
84
+ queryAs: denyMemberResolutionWrite,
85
+ queryAsMember: denyMemberResolutionWrite,
86
+ },
87
+ events: {
88
+ ...handlerContext.events,
89
+ append: asTypedAppendEventFn(denyMemberResolutionWrite),
90
+ unsafeAppend: denyMemberResolutionWrite,
91
+ tryAppend: denyMemberResolutionWrite,
92
+ fetchForWriting: denyMemberResolutionWrite,
93
+ archive: denyMemberResolutionWrite,
94
+ restore: denyMemberResolutionWrite,
95
+ snapshot: denyMemberResolutionWrite,
96
+ },
97
+ auth: { ...handlerContext.auth, resolveActiveMembership: denyMemberResolutionWrite },
98
+ // A read as a member gets no system-scope DB, preSave pipeline or file storage.
99
+ lifecycle: {
100
+ afterCommit: throwMemberResolutionDenied,
101
+ afterRollback: throwMemberResolutionDenied,
102
+ ...(handlerContext.lifecycle.signal && { signal: handlerContext.lifecycle.signal }),
103
+ },
104
+ tenants: {
105
+ ...(handlerContext.tenants.config && { config: handlerContext.tenants.config }),
106
+ },
107
+ services: readOnlyServices(handlerContext.services),
108
+ ...(handlerContext.notify && { notify: denyMemberResolutionWrite }),
109
+ };
110
+ }
@@ -1,11 +1,12 @@
1
+ import type { NotifyFn } from "@cosmicdrift/kumiko-types/handlers";
1
2
  import type { DbConnection } from "../db/connection.ts";
2
3
  import type { TenantId } from "../engine/types/identifiers.ts";
3
- import type { NotifyFn, SessionUser } from "../engine/types/index.ts";
4
+ import type { SessionUser } from "../engine/types/index.ts";
4
5
  import type { CommitSinks } from "./handler-context-dispatch.ts";
5
6
  import type { HandlerContextScope } from "./handler-context-scope.ts";
6
7
  export declare function buildNotifyFacet(scope: HandlerContextScope, sinks: CommitSinks, outsideTxSource: DbConnection | undefined): {
7
8
  notify: NotifyFn | undefined;
8
- factoryFragment: {
9
+ factoryServices: {
9
10
  _notifyInTransactionFactory?: ((notifyUser: SessionUser, notifyTenantId: TenantId) => NotifyFn) | undefined;
10
11
  _notifyAfterCommitFactory?: ((notifyUser: SessionUser, notifyTenantId: TenantId) => NotifyFn) | undefined;
11
12
  };
@@ -45,7 +45,7 @@ export function buildNotifyFacet(scope, sinks, outsideTxSource) {
45
45
  const notify = buildNotify(scope, sinks, notifyAfterCommitFactory, notifyInTransactionFactory);
46
46
  return {
47
47
  notify,
48
- factoryFragment: {
48
+ factoryServices: {
49
49
  ...(notifyInTransactionFactory && {
50
50
  _notifyInTransactionFactory: notifyInTransactionFactory,
51
51
  }),
@@ -1,7 +1,5 @@
1
+ import type { HandlerObservability } from "../engine/types/index.ts";
1
2
  import type { HandlerContextScope } from "./handler-context-scope.ts";
2
3
  export declare function buildObservabilityFacet(scope: HandlerContextScope): {
3
- log: import("@cosmicdrift/kumiko-types/logger").Logger | undefined;
4
- tracer: import("@cosmicdrift/kumiko-types/observability/span").Tracer;
5
- metrics: import("@cosmicdrift/kumiko-types/observability/metric").MetricsHandle;
6
- metricsFor: (featureName: string) => import("@cosmicdrift/kumiko-types/observability/metric").MetricsHandle;
4
+ readonly obs: HandlerObservability;
7
5
  };
@@ -1,4 +1,6 @@
1
- import { createMetricsForFactory, createMetricsHandle, createNoopMetricsHandle, getFallbackTracer, } from "../observability/index.js";
1
+ import { createFallbackFullLogger } from "../logging/utils.js";
2
+ import { getFallbackTracer } from "../observability/fallback.js";
3
+ import { createMetricsForFactory, createMetricsHandle, createNoopMetricsHandle, } from "../observability/index.js";
2
4
  export function buildObservabilityFacet(scope) {
3
5
  const { type, user, context, reqCtx, featureName } = scope;
4
6
  const log = context.log?.child({
@@ -6,16 +8,16 @@ export function buildObservabilityFacet(scope) {
6
8
  tenantId: user.tenantId,
7
9
  userId: user.id,
8
10
  ...(reqCtx && { requestId: reqCtx.requestId }),
9
- });
10
- // Observability — feature-bound metrics handle, so ctx.metrics.inc("foo")
11
+ }) ?? createFallbackFullLogger("handler");
12
+ // Observability — feature-bound metrics handle, so ctx.obs.metrics.inc("foo")
11
13
  // resolves to kumiko_<feature>_foo. Unknown feature falls back to noop
12
14
  // so legacy internal handlers don't crash.
13
15
  const tracer = context.tracer ?? getFallbackTracer();
14
16
  const meter = context.meter;
15
17
  const metrics = meter && featureName ? createMetricsHandle(meter, featureName) : createNoopMetricsHandle();
16
- // ctx.metricsFor(featureName) — shared/library code binds to a feature
18
+ // obs.metricsFor(featureName) — shared/library code binds to a feature
17
19
  // name of its own choosing instead of the dispatching handler's.
18
20
  // Unregistered names no-op rather than throw.
19
21
  const metricsFor = createMetricsForFactory(meter);
20
- return { log, tracer, metrics, metricsFor };
22
+ return { obs: { log, tracer, metrics, metricsFor, ...(meter && { meter }) } };
21
23
  }
@@ -0,0 +1,11 @@
1
+ import type { JobRunnerRef } from "@cosmicdrift/kumiko-types/handlers";
2
+ import type { HandlerContext } from "../engine/types/index.ts";
3
+ import { InternalError } from "../errors/index.ts";
4
+ export declare function denyingJobRunnerProxy(denied?: () => Error): JobRunnerRef;
5
+ export declare function dropOutsideTransaction(handlerContext: HandlerContext): void;
6
+ export declare function withoutTransactionDenied(surface: string): InternalError;
7
+ export declare function perCommandNestedDenied(targetType: string): InternalError;
8
+ export declare function denyEventStoreSurfaces(handlerContext: HandlerContext, buildError: (surface: string) => InternalError): HandlerContext;
9
+ export declare function denyTransactionBoundSurfaces(handlerContext: HandlerContext): HandlerContext;
10
+ export declare function withoutNotifyFactories(services: HandlerContext["services"]): HandlerContext["services"];
11
+ export declare function applyBeforeTransactionReadOnly(handlerContext: HandlerContext): HandlerContext;
@@ -0,0 +1,98 @@
1
+ import { InternalError } from "../errors/index.js";
2
+ import { memberResolutionReadOnlyDenied } from "../errors/member-resolution.js";
3
+ import { attachOutsideTransaction } from "./attach-outside-transaction.js";
4
+ // Phase denials of the write pipeline: member-resolution, without-transaction and the two
5
+ // pre-transaction phases each strip a different set of ctx surfaces.
6
+ // JobRunnerRef's declared type only carries handleEvent, but callers
7
+ // routinely bracket-access a fuller runner — a Proxy denies ANY property read.
8
+ export function denyingJobRunnerProxy(denied = memberResolutionReadOnlyDenied) {
9
+ const target = {
10
+ handleEvent: async () => {
11
+ throw denied();
12
+ },
13
+ };
14
+ return new Proxy(target, {
15
+ get() {
16
+ throw denied();
17
+ },
18
+ });
19
+ }
20
+ export function dropOutsideTransaction(handlerContext) {
21
+ if (handlerContext.db)
22
+ attachOutsideTransaction(handlerContext.db, undefined);
23
+ }
24
+ function beforeTransactionDenied(surface) {
25
+ return new InternalError({
26
+ message: `ctx.${surface} is not available before the transaction; move it into the handler`,
27
+ });
28
+ }
29
+ export function withoutTransactionDenied(surface) {
30
+ return new InternalError({
31
+ message: `ctx.${surface} is not available without an open transaction; run the write through ctx.dispatch.write so it gets its own transaction`,
32
+ });
33
+ }
34
+ export function perCommandNestedDenied(targetType) {
35
+ return new InternalError({
36
+ message: `handler "${targetType}" runs without a transaction (transaction: "perCommand") and cannot run as a nested write inside an open transaction`,
37
+ });
38
+ }
39
+ function denySurface(buildError, surface) {
40
+ return () => {
41
+ throw buildError(surface);
42
+ };
43
+ }
44
+ export function denyEventStoreSurfaces(handlerContext, buildError) {
45
+ const deny = (surface) => denySurface(buildError, `events.${surface}`);
46
+ return {
47
+ ...handlerContext,
48
+ events: {
49
+ ...handlerContext.events,
50
+ append: deny("append"),
51
+ unsafeAppend: deny("unsafeAppend"),
52
+ tryAppend: deny("tryAppend"),
53
+ fetchForWriting: deny("fetchForWriting"),
54
+ archive: deny("archive"),
55
+ restore: deny("restore"),
56
+ snapshot: deny("snapshot"),
57
+ },
58
+ };
59
+ }
60
+ // Reservations write on purpose through the outside-transaction handles, so they keep those but
61
+ // lose every surface bound to the not-yet-open transaction.
62
+ export function denyTransactionBoundSurfaces(handlerContext) {
63
+ const { lifecycle, services } = handlerContext;
64
+ return {
65
+ ...denyEventStoreSurfaces(handlerContext, beforeTransactionDenied),
66
+ dispatch: {
67
+ ...handlerContext.dispatch,
68
+ write: denySurface(beforeTransactionDenied, "dispatch.write"),
69
+ writeAs: denySurface(beforeTransactionDenied, "dispatch.writeAs"),
70
+ },
71
+ lifecycle: {
72
+ ...lifecycle,
73
+ afterCommit: denySurface(beforeTransactionDenied, "lifecycle.afterCommit"),
74
+ afterRollback: denySurface(beforeTransactionDenied, "lifecycle.afterRollback"),
75
+ },
76
+ ...(handlerContext.notify && { notify: denySurface(beforeTransactionDenied, "notify") }),
77
+ services: {
78
+ ...withoutNotifyFactories(services),
79
+ ...(services.jobRunner && {
80
+ jobRunner: denyingJobRunnerProxy(() => beforeTransactionDenied("services.jobRunner")),
81
+ }),
82
+ },
83
+ };
84
+ }
85
+ // A notify factory builds a working notify, so a phase that denies ctx.notify must drop them too.
86
+ export function withoutNotifyFactories(services) {
87
+ const { _notifyFactory: _factory, _notifyInTransactionFactory: _inTransaction, _notifyAfterCommitFactory: _afterCommit, ...rest } = services;
88
+ return rest;
89
+ }
90
+ // The beforeTransaction phase has no write need at all, so it also loses the outside-transaction
91
+ // handles. systemDb is mutated in place like db: its identity keys the unsafeRaw rebinders, so a
92
+ // spread or proxy would lose them. It is built per call, so no other context shares it.
93
+ export function applyBeforeTransactionReadOnly(handlerContext) {
94
+ dropOutsideTransaction(handlerContext);
95
+ if (handlerContext.systemDb)
96
+ attachOutsideTransaction(handlerContext.systemDb, undefined);
97
+ return denyTransactionBoundSurfaces(handlerContext);
98
+ }
@@ -1,7 +1,8 @@
1
1
  import { type EscapeHatchDeclaration, type EscapeHatchReporter } from "@cosmicdrift/kumiko-types/handlers";
2
- import { type RequestContextData } from "../api/request-context.ts";
2
+ import type { RequestContextData } from "../api/request-context-internals.ts";
3
3
  import type { DbConnection, DbTx } from "../db/connection.ts";
4
- import type { AppContext, Registry, SessionUser } from "../engine/types/index.ts";
4
+ import type { AppContext, HandlerContext, HandlerLifecycle, Registry, SessionUser } from "../engine/types/index.ts";
5
+ import type { ContextServiceOverrides } from "./context-services.ts";
5
6
  import { type DispatchContext, type HandlerTransactionScope } from "./dispatch-shared.ts";
6
7
  import type { WriteOrigin } from "./write-origin.ts";
7
8
  export type HandlerContextScope = {
@@ -37,12 +38,8 @@ export declare function resolveHandlerContextScope(input: {
37
38
  readonly tx: DbTx | undefined;
38
39
  readonly transactionScope: HandlerTransactionScope;
39
40
  }): HandlerContextScope;
40
- export declare function buildPreSaveFragment(scope: HandlerContextScope): {
41
- runPreSave?: ((handlerName: string, changes: Record<string, unknown>, previous: Readonly<Record<string, unknown>>, isNew: boolean) => Promise<Record<string, unknown>>) | undefined;
42
- };
43
- export declare function buildRuntimeFragment(scope: HandlerContextScope): {
44
- signal?: AbortSignal | undefined;
45
- effectiveFeatures?: import("@cosmicdrift/kumiko-framework/engine").EffectiveFeaturesResolver | undefined;
46
- cacheSync?: import("@cosmicdrift/kumiko-types/cache-sync-types").CacheSyncBus | undefined;
47
- jobRunner?: import("@cosmicdrift/kumiko-types/handlers").JobRunnerRef | undefined;
41
+ export declare function buildPreSave(scope: HandlerContextScope, finalContext: () => HandlerContext): HandlerLifecycle["runPreSave"];
42
+ export declare function buildRuntimeServices(scope: HandlerContextScope): ContextServiceOverrides;
43
+ export declare function buildLifecycleSignal(scope: HandlerContextScope): {
44
+ readonly signal?: AbortSignal;
48
45
  };
@@ -1,7 +1,7 @@
1
1
  import { escapeHatchFor, } from "@cosmicdrift/kumiko-types/handlers";
2
2
  import { requestContext } from "../api/request-context.js";
3
3
  import { createFallbackLogger } from "../logging/utils.js";
4
- import { createEscapeHatchReporter } from "../observability/index.js";
4
+ import { createEscapeHatchReporter } from "../observability/escape-hatch-report.js";
5
5
  import { resolveDbSource, } from "./dispatch-shared.js";
6
6
  export function resolveHandlerContextScope(input) {
7
7
  const { ctx, type, user, origin, tx, transactionScope } = input;
@@ -59,30 +59,28 @@ export function resolveHandlerContextScope(input) {
59
59
  }
60
60
  // preSave hooks need `changes`/`previous`/`isNew`, which only exist once
61
61
  // a handler actually starts building its write — bound here so entity
62
- // CRUD handlers (entity-handlers.ts) can forward it to the executor.
63
- export function buildPreSaveFragment(scope) {
62
+ // CRUD handlers (entity-handlers.ts) can forward it to the executor. The hooks receive the
63
+ // final, phase-wrapped context, so the context is resolved lazily at call time.
64
+ export function buildPreSave(scope, finalContext) {
64
65
  const { lifecycle } = scope.ctx;
65
- return {
66
- ...(lifecycle && {
67
- runPreSave: (handlerName, changes, previous, isNew) => lifecycle.runPreSave(handlerName, changes, previous, isNew, scope.context),
68
- }),
69
- };
66
+ if (!lifecycle)
67
+ return undefined;
68
+ return (handlerName, changes, previous, isNew) => lifecycle.runPreSave(handlerName, changes, previous, isNew, finalContext());
70
69
  }
71
- export function buildRuntimeFragment(scope) {
72
- const { ctx, reqCtx } = scope;
73
- const { effectiveFeatures, jobRunner } = ctx;
70
+ // Services the dispatcher resolves itself instead of copying from the boot context.
71
+ export function buildRuntimeServices(scope) {
72
+ const { effectiveFeatures, jobRunner, cacheSync } = scope.ctx;
74
73
  return {
75
- // Cancellation signal flows from the HTTP middleware via
76
- // requestContext. Conditional spread so non-HTTP entry-points
77
- // (jobs, dispatcher MSP-applies) don't get a phantom signal that
78
- // would always read aborted=false but feel meaningful.
79
- ...(reqCtx?.signal ? { signal: reqCtx.signal } : {}),
80
- // Propagate the feature-toggle resolver so the lifecycle pipeline,
81
- // MSP runner, and ctx.hasFeature all pull from the same source.
74
+ // One resolver for the lifecycle pipeline, MSP runner and ctx.hasFeature.
82
75
  ...(effectiveFeatures && { effectiveFeatures }),
83
- ...(ctx.cacheSync && { cacheSync: ctx.cacheSync }),
84
- // Lets write handlers call ctx.jobRunner.dispatch(...) directly, same
76
+ ...(cacheSync && { cacheSync }),
77
+ // Lets write handlers call ctx.services.jobRunner.dispatch(...) directly, same
85
78
  // as a follow-up job would (test-stack.ts wires the matching runner).
86
79
  ...(jobRunner && { jobRunner }),
87
80
  };
88
81
  }
82
+ // Cancellation signal flows from the HTTP middleware via requestContext. Absent for non-HTTP
83
+ // entry points (jobs, dispatcher MSP-applies) so it never reads as a phantom always-live signal.
84
+ export function buildLifecycleSignal(scope) {
85
+ return scope.reqCtx?.signal ? { signal: scope.reqCtx.signal } : {};
86
+ }