@cosmicdrift/kumiko-framework 0.389.0 → 0.390.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (616) hide show
  1. package/AGENTS.md +9 -4
  2. package/README.md +1 -1
  3. package/agents/examples/apex-surface-auth.md +2 -3
  4. package/agents/examples/api-worker-split.md +9 -2
  5. package/agents/examples/auth-claims.md +1 -1
  6. package/agents/examples/cross-feature-events.md +12 -12
  7. package/agents/examples/crypto-shredding-hr.md +2 -2
  8. package/agents/examples/encrypted-tenant-config.md +1 -1
  9. package/agents/examples/error-contract.md +12 -7
  10. package/agents/examples/event-sourcing.md +29 -29
  11. package/agents/examples/files-post-processing.md +10 -8
  12. package/agents/examples/inbound-mail-triage.md +1 -0
  13. package/agents/examples/lane-routing.md +2 -1
  14. package/agents/examples/legal-pages.md +2 -2
  15. package/agents/examples/lifecycle-hooks.md +3 -3
  16. package/agents/examples/managed-config.md +4 -4
  17. package/agents/examples/managed-pages.md +1 -1
  18. package/agents/examples/relations.md +19 -4
  19. package/agents/examples/search.md +4 -4
  20. package/agents/examples/secrets-demo.md +9 -6
  21. package/agents/examples/state-machine.md +2 -2
  22. package/agents/examples/tenant-settings.md +1 -1
  23. package/agents/examples/user-data-rights.md +3 -6
  24. package/agents/examples/workflow-engine.md +53 -47
  25. package/agents/examples.md +4 -4
  26. package/agents/features.md +1 -1
  27. package/dist/api/auth-middleware.js +1 -1
  28. package/dist/api/auth-routes-invite.js +2 -1
  29. package/dist/api/entity-read-access.d.ts +3 -1
  30. package/dist/api/export/export-columns.d.ts +3 -1
  31. package/dist/api/export/export-route.js +3 -2
  32. package/dist/api/export/export-screen.d.ts +2 -1
  33. package/dist/api/extra-route.d.ts +3 -1
  34. package/dist/api/index.d.ts +23 -27
  35. package/dist/api/index.js +13 -15
  36. package/dist/api/jwt.js +1 -1
  37. package/dist/api/observability-middleware.d.ts +1 -1
  38. package/dist/api/observability-middleware.js +2 -1
  39. package/dist/api/request-context-internals.d.ts +31 -0
  40. package/dist/api/request-context-internals.js +11 -0
  41. package/dist/api/request-context-scopes.d.ts +14 -0
  42. package/dist/api/request-context-scopes.js +69 -0
  43. package/dist/api/request-context.d.ts +1 -40
  44. package/dist/api/request-context.js +22 -51
  45. package/dist/api/request-id-middleware.d.ts +1 -1
  46. package/dist/api/route-registrars.d.ts +2 -1
  47. package/dist/api/route-registrars.js +1 -1
  48. package/dist/api/routes.js +7 -3
  49. package/dist/api/server-boot-checks.d.ts +1 -1
  50. package/dist/api/server-boot-checks.js +2 -2
  51. package/dist/api/server-event-dispatcher.d.ts +6 -1
  52. package/dist/api/server-event-dispatcher.js +3 -4
  53. package/dist/api/server-extra-routes.d.ts +1 -1
  54. package/dist/api/server-extra-routes.js +2 -1
  55. package/dist/api/server-middleware.js +3 -1
  56. package/dist/api/server-routes.d.ts +2 -1
  57. package/dist/api/server-wiring.js +6 -4
  58. package/dist/api/server.d.ts +2 -1
  59. package/dist/api/sse-route.d.ts +2 -1
  60. package/dist/api/tenant-scoped-secrets.d.ts +2 -0
  61. package/dist/api/tenant-scoped-secrets.js +13 -0
  62. package/dist/api/websocket-route.d.ts +1 -1
  63. package/dist/auth/index.d.ts +0 -1
  64. package/dist/auth/roles.d.ts +0 -5
  65. package/dist/compliance/duration-spec.d.ts +0 -1
  66. package/dist/compliance/duration-spec.js +0 -5
  67. package/dist/compliance/index.d.ts +4 -4
  68. package/dist/compliance/index.js +2 -2
  69. package/dist/compliance/profiles.d.ts +0 -15
  70. package/dist/compliance/profiles.js +0 -23
  71. package/dist/config/index.d.ts +10 -10
  72. package/dist/config/index.js +13 -1
  73. package/dist/config/internals.d.ts +9 -0
  74. package/dist/config/internals.js +1 -0
  75. package/dist/consumer-cli-internals.d.ts +4 -0
  76. package/dist/consumer-cli-internals.js +1 -0
  77. package/dist/consumer-cli.d.ts +1 -4
  78. package/dist/consumer-cli.js +5 -1
  79. package/dist/crypto/event-pii.js +1 -1
  80. package/dist/crypto/index.d.ts +8 -9
  81. package/dist/crypto/index.js +7 -8
  82. package/dist/crypto/pg-kms-adapter.js +6 -1
  83. package/dist/db/apply-entity-event.d.ts +1 -1
  84. package/dist/db/apply-entity-event.js +15 -47
  85. package/dist/db/blind-index-cleanup.js +91 -77
  86. package/dist/db/collect-table-metas.js +1 -1
  87. package/dist/db/compound-types.d.ts +1 -1
  88. package/dist/db/compound-types.js +0 -7
  89. package/dist/db/config-seed.d.ts +2 -1
  90. package/dist/db/config-seed.js +6 -1
  91. package/dist/db/connection.d.ts +3 -1
  92. package/dist/db/connection.js +15 -5
  93. package/dist/db/cross-tenant-reads.d.ts +1 -1
  94. package/dist/db/cross-tenant-reads.js +1 -1
  95. package/dist/db/dialect.d.ts +0 -5
  96. package/dist/db/dialect.js +0 -3
  97. package/dist/db/eagerload.d.ts +2 -1
  98. package/dist/db/entity-field-encryption.d.ts +1 -1
  99. package/dist/db/entity-table-meta.d.ts +1 -1
  100. package/dist/db/event-store-executor-context.d.ts +3 -1
  101. package/dist/db/event-store-executor-context.js +4 -3
  102. package/dist/db/event-store-executor-read-filter.d.ts +1 -1
  103. package/dist/db/event-store-executor-read-rows.d.ts +2 -1
  104. package/dist/db/event-store-executor-read-search.d.ts +2 -1
  105. package/dist/db/event-store-executor-read-sort.d.ts +2 -1
  106. package/dist/db/event-store-executor-read.js +2 -2
  107. package/dist/db/event-store-executor-write-atomic.js +8 -7
  108. package/dist/db/event-store-executor-write-steps.d.ts +3 -2
  109. package/dist/db/event-store-executor-write.js +7 -4
  110. package/dist/db/event-store-executor.d.ts +1 -1
  111. package/dist/db/executor-managed-tables.d.ts +7 -1
  112. package/dist/db/executor-managed-tables.js +11 -2
  113. package/dist/db/index.d.ts +29 -28
  114. package/dist/db/index.js +22 -20
  115. package/dist/db/known-table-names.d.ts +6 -0
  116. package/dist/db/known-table-names.js +21 -0
  117. package/dist/db/list-aggregate-labels.d.ts +1 -1
  118. package/dist/db/located-timestamp.d.ts +1 -1
  119. package/dist/db/located-timestamp.js +0 -5
  120. package/dist/db/migrate-generator.d.ts +17 -1
  121. package/dist/db/migrate-generator.js +50 -20
  122. package/dist/db/migrate-primary-key.d.ts +12 -0
  123. package/dist/db/migrate-primary-key.js +45 -0
  124. package/dist/db/migrate-rls-diff.d.ts +20 -0
  125. package/dist/db/migrate-rls-diff.js +61 -0
  126. package/dist/db/migrate-runner.js +4 -0
  127. package/dist/db/money.d.ts +1 -1
  128. package/dist/db/money.js +1 -1
  129. package/dist/db/parent-ref-clause.d.ts +2 -1
  130. package/dist/db/pg-error.d.ts +2 -0
  131. package/dist/db/pg-error.js +11 -0
  132. package/dist/db/queries/ddl.d.ts +3 -0
  133. package/dist/db/queries/ddl.js +34 -1
  134. package/dist/db/queries/event-store.js +4 -2
  135. package/dist/db/queries/event-tenants.d.ts +2 -0
  136. package/dist/db/queries/event-tenants.js +17 -0
  137. package/dist/db/queries/rebuild-rls-guard.d.ts +2 -0
  138. package/dist/db/queries/rebuild-rls-guard.js +29 -0
  139. package/dist/db/queries/rls-boot-catalog.d.ts +16 -0
  140. package/dist/db/queries/rls-boot-catalog.js +39 -0
  141. package/dist/db/queries/rls-catalog.d.ts +6 -0
  142. package/dist/db/queries/rls-catalog.js +82 -0
  143. package/dist/db/queries/rls-scope.d.ts +3 -0
  144. package/dist/db/queries/rls-scope.js +17 -0
  145. package/dist/db/queries/rls-shape.d.ts +10 -0
  146. package/dist/db/queries/rls-shape.js +42 -0
  147. package/dist/db/queries/session-advisory-lock.d.ts +2 -0
  148. package/dist/db/queries/session-advisory-lock.js +23 -0
  149. package/dist/db/queries/shadow-swap.d.ts +1 -2
  150. package/dist/db/queries/shadow-swap.js +9 -25
  151. package/dist/db/queries/test-stack.d.ts +4 -1
  152. package/dist/db/queries/test-stack.js +83 -2
  153. package/dist/db/query.js +11 -7
  154. package/dist/db/reference-data.d.ts +1 -1
  155. package/dist/db/reference-data.js +6 -1
  156. package/dist/db/render-ddl.d.ts +6 -2
  157. package/dist/db/render-ddl.js +7 -7
  158. package/dist/db/render-rls-ddl.d.ts +35 -0
  159. package/dist/db/render-rls-ddl.js +127 -0
  160. package/dist/db/replay-migration-sql.d.ts +3 -1
  161. package/dist/db/replay-migration-sql.js +22 -5
  162. package/dist/db/replay-rls.d.ts +25 -0
  163. package/dist/db/replay-rls.js +156 -0
  164. package/dist/db/row-level-security-boot-check.d.ts +5 -0
  165. package/dist/db/row-level-security-boot-check.js +85 -0
  166. package/dist/db/row-level-security-connection.d.ts +3 -0
  167. package/dist/db/row-level-security-connection.js +213 -0
  168. package/dist/db/row-level-security-scope.d.ts +33 -0
  169. package/dist/db/row-level-security-scope.js +127 -0
  170. package/dist/db/scope-tenant-db-to-tenant.d.ts +3 -0
  171. package/dist/db/scope-tenant-db-to-tenant.js +14 -0
  172. package/dist/db/sql-identifier.d.ts +1 -0
  173. package/dist/db/sql-identifier.js +3 -0
  174. package/dist/db/table-builder.d.ts +2 -1
  175. package/dist/db/table-builder.js +1 -1
  176. package/dist/db/table-info.js +1 -1
  177. package/dist/db/table-push.d.ts +11 -2
  178. package/dist/db/table-push.js +15 -2
  179. package/dist/db/tenant-db-runner.d.ts +3 -1
  180. package/dist/db/tenant-db-runner.js +4 -3
  181. package/dist/db/tenant-db-scoped-rebind.d.ts +10 -0
  182. package/dist/db/tenant-db-scoped-rebind.js +33 -0
  183. package/dist/db/tenant-db-statement-runner.d.ts +13 -0
  184. package/dist/db/tenant-db-statement-runner.js +48 -0
  185. package/dist/db/tenant-db.d.ts +17 -12
  186. package/dist/db/tenant-db.js +49 -120
  187. package/dist/db/tenant-id-filter.d.ts +3 -0
  188. package/dist/db/tenant-id-filter.js +30 -0
  189. package/dist/db/transaction-serialization.d.ts +6 -0
  190. package/dist/db/transaction-serialization.js +60 -0
  191. package/dist/derivatives/delete-stored-file.js +1 -1
  192. package/dist/derivatives/index.d.ts +2 -5
  193. package/dist/derivatives/index.js +2 -3
  194. package/dist/engine/access.d.ts +2 -1
  195. package/dist/engine/access.js +1 -1
  196. package/dist/engine/boot-validator/entity-handler.d.ts +2 -1
  197. package/dist/engine/boot-validator/entity-handler.js +1 -1
  198. package/dist/engine/boot-validator/entity-list-aggregate-options.d.ts +1 -1
  199. package/dist/engine/boot-validator/list-table-aggregate-options.d.ts +1 -1
  200. package/dist/engine/boot-validator/list-table-aggregate-query.d.ts +2 -1
  201. package/dist/engine/boot-validator/nav.d.ts +3 -1
  202. package/dist/engine/boot-validator/nav.js +1 -1
  203. package/dist/engine/boot-validator/ownership.d.ts +2 -1
  204. package/dist/engine/boot-validator/parent-ref.d.ts +2 -1
  205. package/dist/engine/boot-validator/projection-list-screens.d.ts +2 -1
  206. package/dist/engine/boot-validator/query-refs.d.ts +2 -1
  207. package/dist/engine/boot-validator/screens-forms.d.ts +2 -1
  208. package/dist/engine/boot-validator/screens-kind-shared.d.ts +3 -1
  209. package/dist/engine/boot-validator/screens.d.ts +2 -1
  210. package/dist/engine/boot-validator/workspaces.d.ts +3 -1
  211. package/dist/engine/bridge-stub.d.ts +5 -2
  212. package/dist/engine/bridge-stub.js +39 -24
  213. package/dist/engine/config-helpers.d.ts +2 -2
  214. package/dist/engine/config-helpers.js +0 -9
  215. package/dist/engine/constants.d.ts +0 -10
  216. package/dist/engine/constants.js +0 -8
  217. package/dist/engine/create-app.js +1 -1
  218. package/dist/engine/define-feature.d.ts +2 -1
  219. package/dist/engine/define-feature.js +1 -2
  220. package/dist/engine/define-handler.d.ts +1 -1
  221. package/dist/engine/define-step.d.ts +0 -1
  222. package/dist/engine/define-step.js +0 -3
  223. package/dist/engine/embedded-derived.d.ts +1 -1
  224. package/dist/engine/entity-handlers.d.ts +2 -1
  225. package/dist/engine/entity-handlers.js +7 -7
  226. package/dist/engine/entity-list-runtime-options.js +3 -1
  227. package/dist/engine/entity-list-searchability.d.ts +2 -1
  228. package/dist/engine/event-def.d.ts +2 -1
  229. package/dist/engine/event-helpers.d.ts +3 -1
  230. package/dist/engine/event-helpers.js +3 -3
  231. package/dist/engine/extension-names.d.ts +2 -8
  232. package/dist/engine/extension-names.js +2 -2
  233. package/dist/engine/extension-selector-plugins.d.ts +1 -1
  234. package/dist/engine/extensions/storage-provider.d.ts +1 -2
  235. package/dist/engine/extensions/user-data.d.ts +0 -8
  236. package/dist/engine/factories.d.ts +2 -1
  237. package/dist/engine/feature-builder-state.d.ts +8 -1
  238. package/dist/engine/feature-changelog.d.ts +1 -1
  239. package/dist/engine/feature-config-events-jobs.d.ts +4 -1
  240. package/dist/engine/feature-entity-handlers.d.ts +5 -1
  241. package/dist/engine/feature-manifest.js +1 -1
  242. package/dist/engine/feature-ui-extensions.d.ts +7 -1
  243. package/dist/engine/feature-ui-extensions.js +6 -4
  244. package/dist/engine/field-access.d.ts +2 -1
  245. package/dist/engine/handler-field-references.d.ts +0 -4
  246. package/dist/engine/index.d.ts +57 -54
  247. package/dist/engine/index.js +22 -27
  248. package/dist/engine/instruction-fields.d.ts +1 -1
  249. package/dist/engine/personal-data-fields.d.ts +1 -1
  250. package/dist/engine/qualified-name.d.ts +0 -1
  251. package/dist/engine/read-claim.d.ts +2 -1
  252. package/dist/engine/registry-facade.js +0 -3
  253. package/dist/engine/registry-ingest.d.ts +2 -1
  254. package/dist/engine/registry-ingest.js +1 -2
  255. package/dist/engine/registry-state.d.ts +12 -2
  256. package/dist/engine/registry-state.js +2 -3
  257. package/dist/engine/registry-validate.d.ts +3 -1
  258. package/dist/engine/registry-validate.js +7 -7
  259. package/dist/engine/run-in.d.ts +1 -1
  260. package/dist/engine/run-in.js +0 -1
  261. package/dist/engine/schema-builder.d.ts +1 -1
  262. package/dist/engine/schema-builder.js +1 -1
  263. package/dist/engine/screen-filter-ops.d.ts +2 -1
  264. package/dist/engine/screen-filter-ops.js +0 -5
  265. package/dist/engine/soft-delete-cleanup.d.ts +1 -1
  266. package/dist/engine/soft-delete-cleanup.js +4 -4
  267. package/dist/engine/state-machine.js +2 -1
  268. package/dist/engine/steps/_read-source.js +1 -1
  269. package/dist/engine/steps/aggregate-append-event.js +2 -2
  270. package/dist/engine/steps/call-feature.js +2 -2
  271. package/dist/engine/steps/mail-send.js +1 -1
  272. package/dist/engine/steps/retry.js +1 -1
  273. package/dist/engine/steps/wait-for-event.js +1 -1
  274. package/dist/engine/steps/wait.js +1 -1
  275. package/dist/engine/steps/webhook-send.js +1 -1
  276. package/dist/engine/template-variables.d.ts +2 -1
  277. package/dist/engine/transfer-adjacency.d.ts +1 -1
  278. package/dist/engine/types/index.d.ts +8 -31
  279. package/dist/engine/types/index.js +2 -10
  280. package/dist/engine/validation.d.ts +2 -1
  281. package/dist/entrypoint/index.d.ts +7 -35
  282. package/dist/entrypoint/index.js +7 -1
  283. package/dist/entrypoint/internals.d.ts +40 -0
  284. package/dist/entrypoint/internals.js +1 -0
  285. package/dist/entrypoint/row-level-security-mode-check.d.ts +3 -0
  286. package/dist/entrypoint/row-level-security-mode-check.js +19 -0
  287. package/dist/env/dry-run-internals.d.ts +10 -0
  288. package/dist/env/dry-run-internals.js +1 -0
  289. package/dist/env/dry-run.d.ts +1 -10
  290. package/dist/env/dry-run.js +2 -1
  291. package/dist/env/index.d.ts +1 -85
  292. package/dist/env/index.js +6 -50
  293. package/dist/env/internals.d.ts +87 -0
  294. package/dist/env/internals.js +53 -0
  295. package/dist/errors/classes.js +2 -2
  296. package/dist/errors/index.d.ts +5 -14
  297. package/dist/errors/index.js +4 -9
  298. package/dist/errors/member-resolution.js +1 -1
  299. package/dist/errors/reasons.d.ts +0 -1
  300. package/dist/errors/reasons.js +7 -7
  301. package/dist/errors/serialize.d.ts +0 -18
  302. package/dist/errors/serialize.js +0 -27
  303. package/dist/es-ops/index.d.ts +4 -4
  304. package/dist/es-ops/index.js +2 -2
  305. package/dist/es-ops/operations-schema.d.ts +1 -1
  306. package/dist/es-ops/types.d.ts +4 -5
  307. package/dist/event-store/admin-api-internals.d.ts +14 -0
  308. package/dist/event-store/admin-api-internals.js +1 -0
  309. package/dist/event-store/admin-api.d.ts +1 -14
  310. package/dist/event-store/admin-api.js +11 -6
  311. package/dist/event-store/archive.js +4 -2
  312. package/dist/event-store/errors.js +2 -2
  313. package/dist/event-store/event-store.js +41 -34
  314. package/dist/event-store/events-schema.js +4 -1
  315. package/dist/event-store/index.d.ts +11 -13
  316. package/dist/event-store/index.js +7 -9
  317. package/dist/event-store/rebuild-dead-letter.js +4 -2
  318. package/dist/event-store/snapshot.js +4 -3
  319. package/dist/event-store/stream-scope.d.ts +2 -0
  320. package/dist/event-store/stream-scope.js +6 -0
  321. package/dist/event-store/upcaster-dead-letter.js +4 -2
  322. package/dist/event-store/upcaster.d.ts +2 -1
  323. package/dist/files/action-form-upload.d.ts +2 -1
  324. package/dist/files/action-form-upload.js +1 -1
  325. package/dist/files/assert-file-refs-belong-to-tenant.d.ts +2 -1
  326. package/dist/files/assert-file-refs-belong-to-tenant.js +1 -1
  327. package/dist/files/bind-pending-file-refs.d.ts +2 -1
  328. package/dist/files/bind-pending-file-refs.js +2 -1
  329. package/dist/files/bind-referenced-files.write.js +1 -1
  330. package/dist/files/create-file-ref-from-bytes.d.ts +6 -3
  331. package/dist/files/create-file-ref-from-bytes.js +3 -3
  332. package/dist/files/create-file-ref.d.ts +3 -2
  333. package/dist/files/create-file-ref.js +2 -2
  334. package/dist/files/dispose-removed-file-refs.d.ts +2 -1
  335. package/dist/files/dispose-removed-file-refs.js +1 -1
  336. package/dist/files/feature.js +2 -2
  337. package/dist/files/file-handle.js +1 -1
  338. package/dist/files/file-routes.d.ts +1 -1
  339. package/dist/files/file-routes.js +12 -2
  340. package/dist/files/index.d.ts +11 -13
  341. package/dist/files/index.js +5 -7
  342. package/dist/files/load-save-file-refs.d.ts +2 -1
  343. package/dist/files/load-save-file-refs.js +1 -1
  344. package/dist/files/provider-resolver.d.ts +5 -4
  345. package/dist/files/provider-resolver.js +4 -4
  346. package/dist/files/storage-tracking.js +4 -2
  347. package/dist/files/sweep-orphaned-uploads.d.ts +1 -1
  348. package/dist/files/sweep-orphaned-uploads.js +1 -1
  349. package/dist/i18n/index.d.ts +2 -8
  350. package/dist/i18n/index.js +1 -1
  351. package/dist/i18n/internals.d.ts +7 -0
  352. package/dist/i18n/internals.js +1 -0
  353. package/dist/i18n/required-surface-keys.d.ts +4 -1
  354. package/dist/internal/row-level-security.d.ts +3 -0
  355. package/dist/internal/row-level-security.js +3 -0
  356. package/dist/internal/stack-support.d.ts +1 -1
  357. package/dist/internal/stack-support.js +1 -1
  358. package/dist/internal/testing.d.ts +1 -0
  359. package/dist/internal/testing.js +9 -5
  360. package/dist/jobs/index.d.ts +1 -1
  361. package/dist/jobs/job-append-event.d.ts +12 -0
  362. package/dist/jobs/job-append-event.js +30 -0
  363. package/dist/jobs/job-runner-context.d.ts +2 -2
  364. package/dist/jobs/job-runner-context.js +46 -16
  365. package/dist/jobs/job-runner-execution.d.ts +1 -1
  366. package/dist/jobs/job-runner-execution.js +6 -4
  367. package/dist/jobs/job-runner-gates.d.ts +1 -1
  368. package/dist/jobs/job-runner-gates.js +0 -1
  369. package/dist/jobs/job-runner-helpers.d.ts +11 -4
  370. package/dist/jobs/job-runner-helpers.js +10 -1
  371. package/dist/jobs/job-runner-scope.d.ts +5 -2
  372. package/dist/jobs/job-runner-types.d.ts +2 -1
  373. package/dist/jobs/job-runner.js +19 -6
  374. package/dist/jobs/max-per-tenant.d.ts +1 -1
  375. package/dist/logging/index.d.ts +1 -2
  376. package/dist/logging/index.js +1 -1
  377. package/dist/logging/pino-logger.js +1 -1
  378. package/dist/logging/utils.d.ts +1 -0
  379. package/dist/logging/utils.js +6 -0
  380. package/dist/migrations/index.d.ts +3 -3
  381. package/dist/migrations/index.js +3 -3
  382. package/dist/migrations/pending-rebuilds.d.ts +1 -1
  383. package/dist/migrations/pending-rebuilds.js +1 -1
  384. package/dist/migrations/pii-event-backfill.js +4 -1
  385. package/dist/observability/escape-hatch-report.d.ts +2 -1
  386. package/dist/observability/index.d.ts +7 -15
  387. package/dist/observability/index.js +4 -12
  388. package/dist/observability/metric-validator.js +1 -1
  389. package/dist/observability/metrics-handle.d.ts +0 -1
  390. package/dist/observability/metrics-handle.js +2 -15
  391. package/dist/observability/recording-tracer.d.ts +1 -2
  392. package/dist/observability/recording-tracer.js +0 -6
  393. package/dist/observability/sensitive-filter.d.ts +0 -2
  394. package/dist/observability/sensitive-filter.js +0 -29
  395. package/dist/pipeline/active-membership.d.ts +2 -1
  396. package/dist/pipeline/active-membership.js +6 -2
  397. package/dist/pipeline/append-event-core.d.ts +2 -1
  398. package/dist/pipeline/append-event-core.js +2 -2
  399. package/dist/pipeline/attach-outside-transaction.d.ts +3 -0
  400. package/dist/pipeline/attach-outside-transaction.js +13 -0
  401. package/dist/pipeline/auth-claims-resolver.d.ts +2 -1
  402. package/dist/pipeline/cascade-handler.d.ts +2 -1
  403. package/dist/pipeline/cascade-handler.js +3 -2
  404. package/dist/pipeline/config-accessor-factory.d.ts +1 -1
  405. package/dist/pipeline/config-accessor-factory.js +1 -1
  406. package/dist/pipeline/context-services.d.ts +56 -0
  407. package/dist/pipeline/context-services.js +73 -0
  408. package/dist/pipeline/dispatch-batch.d.ts +2 -1
  409. package/dist/pipeline/dispatch-batch.js +31 -18
  410. package/dist/pipeline/dispatch-query.js +5 -4
  411. package/dist/pipeline/dispatch-scope.d.ts +6 -0
  412. package/dist/pipeline/dispatch-scope.js +27 -0
  413. package/dist/pipeline/dispatch-shared.d.ts +13 -9
  414. package/dist/pipeline/dispatch-shared.js +75 -198
  415. package/dist/pipeline/dispatch-stream.js +8 -4
  416. package/dist/pipeline/dispatch-write.d.ts +2 -1
  417. package/dist/pipeline/dispatch-write.js +10 -8
  418. package/dist/pipeline/dispatcher-utils.d.ts +3 -1
  419. package/dist/pipeline/dispatcher-utils.js +8 -2
  420. package/dist/pipeline/dispatcher.d.ts +3 -2
  421. package/dist/pipeline/dispatcher.js +4 -3
  422. package/dist/pipeline/event-consumer-state.d.ts +0 -1
  423. package/dist/pipeline/event-dispatcher-delivery.d.ts +1 -1
  424. package/dist/pipeline/event-dispatcher-delivery.js +4 -2
  425. package/dist/pipeline/event-dispatcher.d.ts +2 -2
  426. package/dist/pipeline/event-dispatcher.js +7 -3
  427. package/dist/pipeline/event-retention.js +59 -56
  428. package/dist/pipeline/handler-access-error.js +2 -1
  429. package/dist/pipeline/handler-context-auth.d.ts +5 -6
  430. package/dist/pipeline/handler-context-auth.js +7 -4
  431. package/dist/pipeline/handler-context-config.d.ts +2 -5
  432. package/dist/pipeline/handler-context-config.js +2 -2
  433. package/dist/pipeline/handler-context-db.d.ts +32 -7
  434. package/dist/pipeline/handler-context-db.js +26 -17
  435. package/dist/pipeline/handler-context-dispatch.d.ts +13 -7
  436. package/dist/pipeline/handler-context-dispatch.js +9 -8
  437. package/dist/pipeline/handler-context-events.d.ts +22 -36
  438. package/dist/pipeline/handler-context-events.js +36 -31
  439. package/dist/pipeline/handler-context-member-resolution.d.ts +2 -0
  440. package/dist/pipeline/handler-context-member-resolution.js +110 -0
  441. package/dist/pipeline/handler-context-notify.d.ts +3 -2
  442. package/dist/pipeline/handler-context-notify.js +1 -1
  443. package/dist/pipeline/handler-context-observability.d.ts +2 -4
  444. package/dist/pipeline/handler-context-observability.js +7 -5
  445. package/dist/pipeline/handler-context-phase-denials.d.ts +11 -0
  446. package/dist/pipeline/handler-context-phase-denials.js +98 -0
  447. package/dist/pipeline/handler-context-scope.d.ts +7 -10
  448. package/dist/pipeline/handler-context-scope.js +18 -20
  449. package/dist/pipeline/index.d.ts +9 -21
  450. package/dist/pipeline/index.js +5 -7
  451. package/dist/pipeline/irreversible-operation-gate.d.ts +1 -1
  452. package/dist/pipeline/irreversible-operation-gate.js +2 -2
  453. package/dist/pipeline/lifecycle-pipeline.d.ts +8 -7
  454. package/dist/pipeline/lifecycle-pipeline.js +9 -15
  455. package/dist/pipeline/member-read-only-transaction.js +11 -3
  456. package/dist/pipeline/member-reader.d.ts +1 -1
  457. package/dist/pipeline/member-reader.js +2 -2
  458. package/dist/pipeline/msp-rebuild.js +5 -3
  459. package/dist/pipeline/multi-stream-apply-context.js +3 -2
  460. package/dist/pipeline/notify-scope.d.ts +2 -1
  461. package/dist/pipeline/pre-handler-gates.d.ts +2 -1
  462. package/dist/pipeline/pre-transaction-reservations.d.ts +3 -3
  463. package/dist/pipeline/pre-transaction-reservations.js +9 -7
  464. package/dist/pipeline/projection-rebuild.js +12 -5
  465. package/dist/pipeline/projection-state.d.ts +0 -6
  466. package/dist/pipeline/projection-state.js +0 -5
  467. package/dist/pipeline/projections-runner.d.ts +2 -1
  468. package/dist/pipeline/projections-runner.js +10 -6
  469. package/dist/pipeline/system-hooks.d.ts +3 -1
  470. package/dist/pipeline/system-hooks.js +6 -4
  471. package/dist/pipeline/system-identity-switch.d.ts +4 -2
  472. package/dist/pipeline/system-identity-switch.js +51 -36
  473. package/dist/pipeline/typed-append-event.d.ts +2 -0
  474. package/dist/pipeline/typed-append-event.js +4 -0
  475. package/dist/pipeline/write-origin.js +2 -2
  476. package/dist/pipeline/write-result-masking.d.ts +1 -1
  477. package/dist/random/index.d.ts +1 -2
  478. package/dist/random/index.js +1 -2
  479. package/dist/rate-limit/bucket.d.ts +2 -1
  480. package/dist/rate-limit/middleware.js +2 -1
  481. package/dist/redis/index.d.ts +3 -4
  482. package/dist/redis/index.js +2 -2
  483. package/dist/schema-cli/apply-command.js +5 -2
  484. package/dist/schema-cli/baseline-command.js +7 -2
  485. package/dist/schema-cli/generate-command.js +7 -9
  486. package/dist/schema-cli/shared.d.ts +4 -0
  487. package/dist/schema-cli/shared.js +21 -2
  488. package/dist/schema-cli/status-command.js +8 -2
  489. package/dist/schema-cli/validate-command.js +52 -4
  490. package/dist/schema-cli.d.ts +0 -1
  491. package/dist/search/configure-tenant-index.d.ts +1 -3
  492. package/dist/search/configure-tenant-index.js +0 -4
  493. package/dist/search/index.d.ts +1 -4
  494. package/dist/search/index.js +0 -2
  495. package/dist/search/meilisearch-adapter-internals.d.ts +8 -0
  496. package/dist/search/meilisearch-adapter-internals.js +9 -0
  497. package/dist/search/meilisearch-adapter.d.ts +1 -8
  498. package/dist/search/meilisearch-adapter.js +6 -7
  499. package/dist/search/meilisearch-peer.d.ts +2 -0
  500. package/dist/search/meilisearch-peer.js +5 -0
  501. package/dist/search/reindex-entity.js +93 -87
  502. package/dist/secrets/index.d.ts +3 -4
  503. package/dist/secrets/index.js +2 -3
  504. package/dist/seeding/index.d.ts +2 -2
  505. package/dist/seeding/index.js +1 -2
  506. package/dist/time/index.d.ts +2 -2
  507. package/dist/time/index.js +1 -1
  508. package/dist/time/tz-context.d.ts +0 -5
  509. package/dist/time/tz-context.js +0 -9
  510. package/dist/ui-types/index.d.ts +8 -11
  511. package/dist/ui-types/index.js +3 -3
  512. package/dist/upgrade-changelog.d.ts +3 -2
  513. package/dist/upgrade-changelog.js +12 -8
  514. package/dist/upgrade-cli-internals.d.ts +8 -0
  515. package/dist/upgrade-cli-internals.js +63 -0
  516. package/dist/upgrade-cli.d.ts +1 -9
  517. package/dist/upgrade-cli.js +10 -64
  518. package/dist/utils/import-optional-peer.d.ts +6 -0
  519. package/dist/utils/import-optional-peer.js +19 -0
  520. package/dist/utils/index.d.ts +1 -4
  521. package/dist/utils/index.js +1 -4
  522. package/package.json +22 -18
  523. package/src/changes.json +206 -0
  524. package/dist/crypto/request-kms-cache.d.ts +0 -8
  525. package/dist/crypto/request-kms-cache.js +0 -21
  526. package/dist/engine/codemod/index.d.ts +0 -2
  527. package/dist/engine/codemod/index.js +0 -1
  528. package/dist/engine/codemod/pipeline-codemod.d.ts +0 -50
  529. package/dist/engine/codemod/pipeline-codemod.js +0 -536
  530. package/dist/engine/feature-ast/entity-field-types.d.ts +0 -13
  531. package/dist/engine/feature-ast/entity-field-types.js +0 -35
  532. package/dist/engine/feature-ast/extractors/ai-steps.d.ts +0 -6
  533. package/dist/engine/feature-ast/extractors/ai-steps.js +0 -254
  534. package/dist/engine/feature-ast/extractors/events.d.ts +0 -5
  535. package/dist/engine/feature-ast/extractors/events.js +0 -275
  536. package/dist/engine/feature-ast/extractors/handlers.d.ts +0 -24
  537. package/dist/engine/feature-ast/extractors/handlers.js +0 -358
  538. package/dist/engine/feature-ast/extractors/hooks.d.ts +0 -24
  539. package/dist/engine/feature-ast/extractors/hooks.js +0 -248
  540. package/dist/engine/feature-ast/extractors/index.d.ts +0 -14
  541. package/dist/engine/feature-ast/extractors/index.js +0 -13
  542. package/dist/engine/feature-ast/extractors/jobs-routes.d.ts +0 -7
  543. package/dist/engine/feature-ast/extractors/jobs-routes.js +0 -145
  544. package/dist/engine/feature-ast/extractors/projections-screens.d.ts +0 -10
  545. package/dist/engine/feature-ast/extractors/projections-screens.js +0 -195
  546. package/dist/engine/feature-ast/extractors/resolve-import.d.ts +0 -21
  547. package/dist/engine/feature-ast/extractors/resolve-import.js +0 -180
  548. package/dist/engine/feature-ast/extractors/round1.d.ts +0 -11
  549. package/dist/engine/feature-ast/extractors/round1.js +0 -87
  550. package/dist/engine/feature-ast/extractors/round2.d.ts +0 -7
  551. package/dist/engine/feature-ast/extractors/round2.js +0 -191
  552. package/dist/engine/feature-ast/extractors/round3.d.ts +0 -23
  553. package/dist/engine/feature-ast/extractors/round3.js +0 -292
  554. package/dist/engine/feature-ast/extractors/round5.d.ts +0 -9
  555. package/dist/engine/feature-ast/extractors/round5.js +0 -68
  556. package/dist/engine/feature-ast/extractors/round6.d.ts +0 -4
  557. package/dist/engine/feature-ast/extractors/round6.js +0 -17
  558. package/dist/engine/feature-ast/extractors/shared.d.ts +0 -94
  559. package/dist/engine/feature-ast/extractors/shared.js +0 -343
  560. package/dist/engine/feature-ast/index.d.ts +0 -16
  561. package/dist/engine/feature-ast/index.js +0 -10
  562. package/dist/engine/feature-ast/parse.d.ts +0 -31
  563. package/dist/engine/feature-ast/parse.js +0 -485
  564. package/dist/engine/feature-ast/patch.d.ts +0 -212
  565. package/dist/engine/feature-ast/patch.js +0 -611
  566. package/dist/engine/feature-ast/patcher.d.ts +0 -217
  567. package/dist/engine/feature-ast/patcher.js +0 -281
  568. package/dist/engine/feature-ast/pattern-change-schema.d.ts +0 -1238
  569. package/dist/engine/feature-ast/pattern-change-schema.js +0 -1072
  570. package/dist/engine/feature-ast/pattern-id-matchers.d.ts +0 -7
  571. package/dist/engine/feature-ast/pattern-id-matchers.js +0 -211
  572. package/dist/engine/feature-ast/pattern-id-schema.d.ts +0 -251
  573. package/dist/engine/feature-ast/pattern-id-schema.js +0 -166
  574. package/dist/engine/feature-ast/patterns.d.ts +0 -322
  575. package/dist/engine/feature-ast/patterns.js +0 -107
  576. package/dist/engine/feature-ast/render.d.ts +0 -47
  577. package/dist/engine/feature-ast/render.js +0 -666
  578. package/dist/engine/feature-ast/source-location.d.ts +0 -17
  579. package/dist/engine/feature-ast/source-location.js +0 -27
  580. package/dist/engine/pattern-library/index.d.ts +0 -2
  581. package/dist/engine/pattern-library/index.js +0 -3
  582. package/dist/engine/pattern-library/library.d.ts +0 -14
  583. package/dist/engine/pattern-library/library.js +0 -94
  584. package/dist/engine/pattern-library/mixed-schemas.d.ts +0 -16
  585. package/dist/engine/pattern-library/mixed-schemas.js +0 -559
  586. package/dist/engine/pattern-library/opaque-schemas.d.ts +0 -7
  587. package/dist/engine/pattern-library/opaque-schemas.js +0 -115
  588. package/dist/engine/pattern-library/shared-fields.d.ts +0 -122
  589. package/dist/engine/pattern-library/shared-fields.js +0 -88
  590. package/dist/engine/pattern-library/static-schemas.d.ts +0 -21
  591. package/dist/engine/pattern-library/static-schemas.js +0 -487
  592. package/dist/engine/pattern-library/types.d.ts +0 -158
  593. package/dist/engine/pattern-library/types.js +0 -36
  594. package/dist/engine/resolve-config-or-param.d.ts +0 -18
  595. package/dist/engine/resolve-config-or-param.js +0 -76
  596. package/src/scripts/codemod/README.md +0 -187
  597. package/src/scripts/codemod/codemod-support.ts +0 -334
  598. package/src/scripts/codemod/collect-source-files.ts +0 -48
  599. package/src/scripts/codemod/crypto-shredding-testing-move.ts +0 -119
  600. package/src/scripts/codemod/db-factory.ts +0 -810
  601. package/src/scripts/codemod/feature-factory.ts +0 -429
  602. package/src/scripts/codemod/feature-layout.ts +0 -424
  603. package/src/scripts/codemod/import-extensions.ts +0 -118
  604. package/src/scripts/codemod/migrate-cross-tenant.ts +0 -328
  605. package/src/scripts/codemod/migrate-db-raw.ts +0 -401
  606. package/src/scripts/codemod/migrate-open-to-all.ts +0 -235
  607. package/src/scripts/codemod/object-form.ts +0 -746
  608. package/src/scripts/codemod/package-merge.ts +0 -299
  609. package/src/scripts/codemod/pii-personal-migration.ts +0 -816
  610. package/src/scripts/codemod/remove-engine-payload-casts.ts +0 -318
  611. package/src/scripts/codemod/s3-imports.ts +0 -236
  612. package/src/scripts/codemod/tenant-db-options.ts +0 -454
  613. package/src/scripts/codemod/testing-injection.ts +0 -215
  614. package/src/scripts/codemod/testing-move-targets.ts +0 -161
  615. package/src/scripts/codemod/testing-move.ts +0 -542
  616. package/src/scripts/codemod/unprocessable-error-details-reason.ts +0 -411
package/AGENTS.md CHANGED
@@ -76,7 +76,7 @@ Parents may belong to another feature; refer to them by QN.
76
76
 
77
77
  **Events.** Declare a domain event with `r.defineEvent(name, zodSchema)`.
78
78
  Emit it inside a write handler with `emitEvent(ctx, def, { ... })` or
79
- `ctx.appendEvent(...)`; it commits in the same transaction as the write.
79
+ `ctx.events.append(...)`; it commits in the same transaction as the write.
80
80
  React to it with `r.projection(...)` (state on the same stream) or
81
81
  `r.multiStreamProjection({ name, apply })` (async consumer across streams,
82
82
  at least once, ordered).
@@ -195,7 +195,7 @@ produces code that compiles and then fails in production.
195
195
  - Never `INSERT`, `UPDATE` or `DELETE` on an entity table or the events
196
196
  table, and never call a raw database client for it. Write through a
197
197
  handler: `r.crud`, the `defineEntity*Handler` helpers, the executor from
198
- `createEntityExecutor`, or `emitEvent` / `ctx.appendEvent`. The query
198
+ `createEntityExecutor`, or `emitEvent` / `ctx.events.append`. The query
199
199
  helpers and `ctx.db` throw `AccessDeniedError` on such a write, also
200
200
  through `ctx.db.unsafeRaw()`. Test seeds use `seedRow` / `deleteRows` from
201
201
  `@cosmicdrift/kumiko-testing`.
@@ -203,7 +203,12 @@ produces code that compiles and then fails in production.
203
203
  projection.
204
204
  - Never hand-write SQL for reads that an executor `list` or `detail` covers.
205
205
  Use `r.queryHandler` with the executor, or a projection with
206
- `ctx.queryProjection`.
206
+ `ctx.dispatch.queryProjection`.
207
+ - Never pass a JS array as a parameter to `.unsafe(sql, [...])`. Bun.SQL
208
+ binds it as `"a,b"` on Linux (CI) and passes on macOS, so `ANY($n)` only
209
+ fails in CI. Pass `toPostgresArrayLiteral(values)` from
210
+ `@cosmicdrift/kumiko-framework/db` and cast the placeholder (`$1::text[]`);
211
+ the Unsafe Array Param guard warns about array literals.
207
212
  - Never filter or count the rows of one `list` page in code. `list` returns
208
213
  one page (default 50, `limit` at most 200). Pass
209
214
  `filter: { field, op, value }` (`eq`, `ne`, `lt`, `gt`, `lte`, `gte`, `in`)
@@ -305,7 +310,7 @@ as bundled features.
305
310
  | Public or anonymous endpoints | `anonymous` role | `agents/examples/anonymous-access.md` |
306
311
  | Allowed state changes | Entity transitions | `agents/examples/state-machine.md` |
307
312
  | React to a write in another feature | `r.defineEvent` + `emitEvent` + `r.multiStreamProjection` | `agents/examples/cross-feature-events.md` |
308
- | Projections, event versions, history | `r.projection`, `ctx.loadAggregate`, `ctx.queryProjection` | `agents/examples/event-sourcing.md` |
313
+ | Projections, event versions, history | `r.projection`, `ctx.events.load`, `ctx.dispatch.queryProjection` | `agents/examples/event-sourcing.md` |
309
314
  | Before or after save logic | Lifecycle hooks | `agents/examples/lifecycle-hooks.md` |
310
315
  | Typed errors with reasons | `@cosmicdrift/kumiko-framework/errors` | `agents/examples/error-contract.md` |
311
316
  | Translations | `r.translations` + client translations | `agents/examples/i18n.md` |
package/README.md CHANGED
@@ -108,7 +108,7 @@ export const taskFeature = defineFeature("tasks", (r) => {
108
108
  - **Event-sourced by default.** Every write goes through `createEventStoreExecutor`
109
109
  and appends a domain event to the aggregate stream. Auto-generated CRUD
110
110
  events (`<entity>.created/updated/deleted/restored`) for record writes,
111
- explicit `ctx.appendEvent` for domain events with intent. Projections feed
111
+ explicit `ctx.events.append` for domain events with intent. Projections feed
112
112
  off the stream for same-TX read-after-write consistency.
113
113
  - **Async side-effects via cursor.** SSE broadcast, search indexing, and
114
114
  feature-registered `r.multiStreamProjection` consumers run on a single
@@ -141,7 +141,7 @@ import type { SendDeletionVerificationEmailFn } from "@cosmicdrift/kumiko-bundle
141
141
  import { selectMany } from "@cosmicdrift/kumiko-framework/db";
142
142
  import { createEventsTable, eventsTable } from "@cosmicdrift/kumiko-framework/event-store";
143
143
  import { createTestUser, testTenantId } from "@cosmicdrift/kumiko-framework/seeding";
144
- import { resetTestTables, seedRow } from "@cosmicdrift/kumiko-testing/helpers";
144
+ import { resetTestTables, seedRowViaEventStore } from "@cosmicdrift/kumiko-testing/helpers";
145
145
  import {
146
146
  setupTestStack,
147
147
  type TestStack,
@@ -186,9 +186,8 @@ afterAll(async () => {
186
186
  beforeEach(async () => {
187
187
  verifyCalls.length = 0;
188
188
  await resetTestTables(stack.db, [userTable, tenantComplianceProfileTable, eventsTable]);
189
- await seedRow(stack.db, userTable, {
189
+ await seedRowViaEventStore(stack.db, userTable, {
190
190
  id: user.id,
191
- tenantId: tenant,
192
191
  email: EMAIL,
193
192
  passwordHash: "hashed",
194
193
  displayName: "User",
@@ -68,7 +68,8 @@ row and the `read_fulfillments` row appear.
68
68
  is re-run after `ms` on the same queue job: no retry attempt is used, no failure is logged
69
69
  or recorded, and the run log shows only the runs that actually executed. `maxDefers`
70
70
  (default 100) bounds it; beyond that the run fails. It needs a queued run: an inline boot
71
- gate throws.
71
+ gate throws. `context.canDefer` is false in both cases, so the job checks it and calls the
72
+ carrier anyway instead of failing.
72
73
 
73
74
  ## Test
74
75
 
@@ -257,6 +258,7 @@ describe("api-worker-split", () => {
257
258
  test("API-only: write lands, but the worker-applied read side stays empty", async () => {
258
259
  const prefix = uniquePrefix();
259
260
  const api = createApiEntrypoint({
261
+ rowLevelSecurity: "off",
260
262
  registry: createRegistry([createApiWorkerSplitFeature()]),
261
263
  context: { db: testDb.db, redis: testRedis.redis },
262
264
  jwtSecret: JWT,
@@ -288,12 +290,14 @@ describe("api-worker-split", () => {
288
290
  test("worker joins: consumes the job, applies the projection, writes the result back", async () => {
289
291
  const prefix = uniquePrefix();
290
292
  const api = createApiEntrypoint({
293
+ rowLevelSecurity: "off",
291
294
  registry: createRegistry([createApiWorkerSplitFeature()]),
292
295
  context: { db: testDb.db, redis: testRedis.redis },
293
296
  jwtSecret: JWT,
294
297
  jobs: { redisUrl: redisUrl(), queueNamePrefix: prefix },
295
298
  });
296
299
  const worker = createWorkerEntrypoint({
300
+ rowLevelSecurity: "off",
297
301
  registry: createRegistry([createApiWorkerSplitFeature()]),
298
302
  context: { db: testDb.db, redis: testRedis.redis },
299
303
  jwtSecret: JWT,
@@ -335,12 +339,14 @@ describe("api-worker-split", () => {
335
339
  test("a busy carrier defers the job without failing it, then the fulfillment lands", async () => {
336
340
  const prefix = uniquePrefix();
337
341
  const api = createApiEntrypoint({
342
+ rowLevelSecurity: "off",
338
343
  registry: createRegistry([createApiWorkerSplitFeature()]),
339
344
  context: { db: testDb.db, redis: testRedis.redis },
340
345
  jwtSecret: JWT,
341
346
  jobs: { redisUrl: redisUrl(), queueNamePrefix: prefix },
342
347
  });
343
348
  const worker = createWorkerEntrypoint({
349
+ rowLevelSecurity: "off",
344
350
  registry: createRegistry([createApiWorkerSplitFeature()]),
345
351
  context: { db: testDb.db, redis: testRedis.redis },
346
352
  jwtSecret: JWT,
@@ -508,8 +514,9 @@ export function createApiWorkerSplitFeature() {
508
514
  }
509
515
  const { customerName } = processOrderPayloadSchema.parse(payload);
510
516
  // Busy is not a failure: ctx.defer re-runs the job later without burning a retry.
517
+ // Once the defer budget is used up (or the run is inline), try anyway and let a failure retry.
511
518
  const retryAfterMs = carrierRetryAfterMs();
512
- if (retryAfterMs > 0) return context.defer(retryAfterMs);
519
+ if (retryAfterMs > 0 && context.canDefer) return context.defer(retryAfterMs);
513
520
  const result = await fulfillWrite({
514
521
  handlerQn: "orders:write:fulfillment:create",
515
522
  payload: {
@@ -91,7 +91,7 @@ beforeEach(() => {
91
91
  });
92
92
 
93
93
  // The resolver needs an AuthClaimsContext per hook run. This sample doesn't
94
- // exercise ctx.db or ctx.queryAs — real features would, and that's the
94
+ // exercise ctx.db or ctx.dispatch.queryAs — real features would, and that's the
95
95
  // point of the fresh TenantDb the dispatcher builds. A stub is fine here.
96
96
  const stubContext: AuthClaimsContext = {
97
97
  db: {} as AuthClaimsContext["db"],
@@ -2,7 +2,7 @@
2
2
 
3
3
  # cross-feature-events
4
4
 
5
- Feature appends a typed domain event via ctx.appendEvent; a r.multiStreamProjection reacts asynchronously.
5
+ Feature appends a typed domain event via ctx.events.append; a r.multiStreamProjection reacts asynchronously.
6
6
 
7
7
  ## README
8
8
 
@@ -19,10 +19,10 @@ Three building blocks:
19
19
 
20
20
  - **`r.defineEvent("name", zodSchema)`** declares the name and payload.
21
21
  The qualified name (e.g. `pubsub-orders:event:order-placed`) comes
22
- back as `.name` — pass it directly to `ctx.appendEvent`. Events that
23
- aren't registered are rejected by `ctx.appendEvent` at the emit site.
22
+ back as `.name` — pass it directly to `ctx.events.append`. Events that
23
+ aren't registered are rejected by `ctx.events.append` at the emit site.
24
24
 
25
- - **`ctx.appendEvent({ aggregateId, aggregateType, type, payload })`**
25
+ - **`ctx.events.append({ aggregateId, aggregateType, type, payload })`**
26
26
  appends the event onto the aggregate stream within the same TX.
27
27
  Version lineage is continued automatically — no synthetic
28
28
  `"pubsub"` stream anymore, the event truly lives on the aggregate.
@@ -40,7 +40,7 @@ Three building blocks:
40
40
  HTTP → writeHandler
41
41
  ↓ TX begin
42
42
  orderExecutor.create(...) ← business row + auto-event (pubsubOrder.created, v1)
43
- ctx.appendEvent({...}) ← domain event (pubsub-orders:event:order-placed, v2)
43
+ ctx.events.append({...}) ← domain event (pubsub-orders:event:order-placed, v2)
44
44
  ↓ TX commit
45
45
  (async, post-commit)
46
46
  event-dispatcher runOnce
@@ -50,7 +50,7 @@ HTTP → writeHandler
50
50
 
51
51
  ## Migration note
52
52
 
53
- `r.postEvent` was removed in Sprint E.2. `ctx.appendEvent` +
53
+ `r.postEvent` was removed in Sprint E.2. `ctx.events.append` +
54
54
  `r.multiStreamProjection` is the unified Marten API for CRUD events,
55
55
  domain events, and cross-feature reactions.
56
56
 
@@ -78,7 +78,7 @@ bun kumiko test integration samples/cross-feature-events
78
78
  // Cross-Feature Reactions Sample — Integration Test
79
79
  //
80
80
  // Proves:
81
- // 1. ctx.appendEvent persists the domain event into the events-table
81
+ // 1. ctx.events.append persists the domain event into the events-table
82
82
  // inside the same TX as the business write, on the aggregate's own
83
83
  // stream (aggregateType = "pubsub-order", not the legacy "pubsub").
84
84
  // 2. The event-dispatcher picks it up and invokes the
@@ -119,7 +119,7 @@ beforeEach(async () => {
119
119
  await resetEventStore(stack, ["read_sample_pubsub_orders"]);
120
120
  });
121
121
 
122
- describe("cross-feature reactions via ctx.appendEvent + r.multiStreamProjection", () => {
122
+ describe("cross-feature reactions via ctx.events.append + r.multiStreamProjection", () => {
123
123
  test("write commits → event on aggregate stream → MSP handler receives it", async () => {
124
124
  const data = await stack.http.writeOk(
125
125
  "pubsub-orders:write:order:place",
@@ -195,7 +195,7 @@ describe("cross-feature reactions via ctx.appendEvent + r.multiStreamProjection"
195
195
  // Cross-Feature Reactions Sample (Marten gold-standard path)
196
196
  //
197
197
  // Demonstrates the Sprint-E pattern for reacting to events across features:
198
- // a writeHandler emits a DOMAIN event via `ctx.appendEvent(...)` onto the
198
+ // a writeHandler emits a DOMAIN event via `ctx.events.append(...)` onto the
199
199
  // aggregate's own stream, and a `r.multiStreamProjection` picks it up
200
200
  // asynchronously through the event-dispatcher.
201
201
  //
@@ -203,11 +203,11 @@ describe("cross-feature reactions via ctx.appendEvent + r.multiStreamProjection"
203
203
  //
204
204
  // 1. `r.defineEvent("short-name", zodSchema)` declares the event shape.
205
205
  // Returns a def whose `.name` is the fully-qualified event name —
206
- // pass that straight to `ctx.appendEvent` so there's no string to
206
+ // pass that straight to `ctx.events.append` so there's no string to
207
207
  // hand-type (and no way to emit an unregistered event: appendEvent
208
208
  // rejects at the emit site).
209
209
  //
210
- // 2. `ctx.appendEvent({ aggregateId, aggregateType, type, payload })`
210
+ // 2. `ctx.events.append({ aggregateId, aggregateType, type, payload })`
211
211
  // writes the event onto the aggregate's own stream inside the same
212
212
  // transaction as the business write. Commit both or roll back both —
213
213
  // no lost events, no orphan events. The event carries real
@@ -261,7 +261,7 @@ export const pubsubOrderFeature = defineFeature("pubsubOrders", (r) => {
261
261
  r.entity({ name: "pubsub-order", ...orderEntity });
262
262
 
263
263
  // Define the event shape once. The returned `.name` is the qualified
264
- // name ("pubsub-orders:event:order-placed") — pass it to ctx.appendEvent.
264
+ // name ("pubsub-orders:event:order-placed") — pass it to ctx.events.append.
265
265
  const orderPlaced = r.defineEvent(
266
266
  "order-placed",
267
267
  z.object({ id: z.string(), customer: z.string(), product: z.string() }),
@@ -108,7 +108,7 @@ import {
108
108
  nullBlindIndexesForSubject,
109
109
  } from "@cosmicdrift/kumiko-framework/db";
110
110
  import type { SaveContext } from "@cosmicdrift/kumiko-framework/engine";
111
- import { createEventsTable } from "@cosmicdrift/kumiko-framework/event-store";
111
+ import { createEventsTable, eventsTable } from "@cosmicdrift/kumiko-framework/event-store";
112
112
  import { TestUsers } from "@cosmicdrift/kumiko-framework/seeding";
113
113
  import {
114
114
  resetBlindIndexKeyForTests,
@@ -144,7 +144,7 @@ beforeEach(async () => {
144
144
  // Fresh adapter per test = fresh key universe. Rows from earlier tests
145
145
  // would name subjects this adapter never minted (fail-loud KeyNotFound),
146
146
  // so the tables reset alongside the KMS.
147
- await resetTestTables(stack.db, ["read_hr_employees", "read_hr_comments"]);
147
+ await resetTestTables(stack.db, ["read_hr_employees", "read_hr_comments", eventsTable]);
148
148
  kms = new InMemoryKmsAdapter();
149
149
  configurePiiSubjectKms(kms);
150
150
  // Blind-index key: what runProdApp({ blindIndexKey }) wires in production.
@@ -181,7 +181,7 @@ beforeAll(async () => {
181
181
  extraContext: ({ registry }) => ({
182
182
  configResolver: resolver,
183
183
  configEncryption: encryption,
184
- _configAccessorFactory: createConfigAccessorFactory(registry, resolver),
184
+ configAccessorFactory: createConfigAccessorFactory(registry, resolver),
185
185
  }),
186
186
  });
187
187
  await unsafePushTables(stack.db, { configValuesTable });
@@ -119,7 +119,7 @@ import { afterAll, beforeAll, describe, expect, test } from "bun:test";
119
119
  import { buildEntityTable } from "@cosmicdrift/kumiko-framework/db";
120
120
  import { createEventsTable } from "@cosmicdrift/kumiko-framework/event-store";
121
121
  import { createTestUser, TestUsers } from "@cosmicdrift/kumiko-framework/seeding";
122
- import { updateRows } from "@cosmicdrift/kumiko-testing/helpers";
122
+ import { updateRowViaEventStore } from "@cosmicdrift/kumiko-testing/helpers";
123
123
  import {
124
124
  setupTestStack,
125
125
  type TestStack,
@@ -139,7 +139,7 @@ beforeAll(async () => {
139
139
  await unsafeCreateEntityTable(stack.db, orderEntity);
140
140
  await createEventsTable(stack.db);
141
141
  });
142
- afterAll(async () => stack.cleanup());
142
+ afterAll(async () => stack?.cleanup());
143
143
 
144
144
  // --- 1) Zod validation error via schema: empty cart rejected ---
145
145
 
@@ -222,11 +222,16 @@ describe("ConflictError → 409", () => {
222
222
  { totalCents: 100 },
223
223
  alice,
224
224
  );
225
- // Force the row into `paid` via direct DB update. The sample feature
226
- // doesn't expose a "place" action, so we can't walk the state machine —
227
- // the point of this test is ConflictError semantics, not the transition
228
- // path itself.
229
- await updateRows(stack.db, orderTable, { status: "paid" }, { id: order.id });
225
+ // The sample feature doesn't expose a "place" action, so we can't walk the
226
+ // state machine — the point of this test is ConflictError semantics, not the
227
+ // transition path itself.
228
+ await updateRowViaEventStore(
229
+ stack.db,
230
+ { table: orderTable, entity: orderEntity, entityName: "order" },
231
+ { id: order.id },
232
+ { status: "paid" },
233
+ { tenantId: alice.tenantId },
234
+ );
230
235
 
231
236
  const error = await stack.http.writeErr(
232
237
  "orders-lite:write:order:cancel",
@@ -2,7 +2,7 @@
2
2
 
3
3
  # event-sourcing
4
4
 
5
- Production-pattern ES sample: r.defineEvent (versioned + migrations) + ctx.appendEvent + r.projection + r.multiStreamProjection + ctx.loadAggregate (asOf) + ctx.archiveStream + ctx.queryProjection.
5
+ Production-pattern ES sample: r.defineEvent (versioned + migrations) + ctx.events.append + r.projection + r.multiStreamProjection + ctx.events.load (asOf) + ctx.events.archive + ctx.dispatch.queryProjection.
6
6
 
7
7
  ## README
8
8
 
@@ -17,12 +17,12 @@ blocks Kumiko provides.
17
17
  | API | Purpose |
18
18
  |---|---|
19
19
  | `r.defineEvent(name, schema, { version, migrations })` | Event schema with version number + upcaster chain |
20
- | `ctx.appendEvent({ aggregateId, aggregateType, type, payload })` | Domain event on aggregate stream |
20
+ | `ctx.events.append({ aggregateId, aggregateType, type, payload })` | Domain event on aggregate stream |
21
21
  | `r.projection(...)` | Single-stream read model, inline in the write TX |
22
22
  | `r.multiStreamProjection(...)` | Cross-aggregate read model, async via dispatcher |
23
- | `ctx.loadAggregate(id, { asOf })` | Live aggregation with point-in-time |
24
- | `ctx.archiveStream(id, { aggregateType })` | Archive a stream (Marten `ArchiveStream`) |
25
- | `ctx.queryProjection(name)` | Tenant-scoped read-model query |
23
+ | `ctx.events.load(id, { asOf })` | Live aggregation with point-in-time |
24
+ | `ctx.events.archive(id, { aggregateType })` | Archive a stream (Marten `ArchiveStream`) |
25
+ | `ctx.dispatch.queryProjection(name)` | Tenant-scoped read-model query |
26
26
 
27
27
  ## Domain
28
28
 
@@ -53,7 +53,7 @@ HTTP POST /api/write { type: "showcase:write:invoice:approve", ... }
53
53
  ↓
54
54
  writeHandler("invoice:approve")
55
55
  ↓ TX begin
56
- ctx.appendEvent({ type: "showcase:event:invoice-approved", ... })
56
+ ctx.events.append({ type: "showcase:event:invoice-approved", ... })
57
57
  r.projection("invoice-detail") ← updates status = "approved"
58
58
  ↓ TX commit
59
59
  (async)
@@ -86,12 +86,12 @@ Six integration tests pin everything at once:
86
86
  //
87
87
  // Exercises every Sprint-E Marten gold-standard API end-to-end:
88
88
  // - r.defineEvent with version + migrations (sync + async upcaster)
89
- // - ctx.appendEvent onto the aggregate stream (incl. headers metadata)
89
+ // - ctx.events.append onto the aggregate stream (incl. headers metadata)
90
90
  // - r.projection (single-stream, inline)
91
91
  // - r.multiStreamProjection (async)
92
- // - ctx.loadAggregate with { asOf }
93
- // - ctx.archiveStream
94
- // - ctx.queryProjection
92
+ // - ctx.events.load with { asOf }
93
+ // - ctx.events.archive
94
+ // - ctx.dispatch.queryProjection
95
95
  // - streamAllEventsByType (memory-bounded ops iteration)
96
96
  // - getAllProjectionProgress (projection lag for ops dashboards)
97
97
 
@@ -364,7 +364,7 @@ describe("Event Sourcing Showcase", () => {
364
364
  expect(beforeSnapshot.state.status).toBe("paid");
365
365
  expect(beforeSnapshot.state.amountCents).toBe(3300);
366
366
 
367
- // Take a snapshot after the pay event. ctx.snapshotAggregate writes
367
+ // Take a snapshot after the pay event. ctx.events.snapshot writes
368
368
  // kumiko_snapshots with the committed state + version.
369
369
  const snapResult = await stack.http.writeOk<{ id: string; snapshotVersion: number }>(
370
370
  "showcase:write:invoice:take-snapshot",
@@ -494,7 +494,7 @@ describe("Event Sourcing Showcase", () => {
494
494
  expect(otherView[0]?.totalCents).toBe(200);
495
495
  });
496
496
 
497
- test("ctx.appendEvent with headers: Marten free key/value metadata lands in stored event", async () => {
497
+ test("ctx.events.append with headers: Marten free key/value metadata lands in stored event", async () => {
498
498
  const { id } = await stack.http.writeOk<{ id: string }>(
499
499
  "showcase:write:invoice:create",
500
500
  { customer: "MetaCo" },
@@ -535,7 +535,7 @@ describe("Event Sourcing Showcase", () => {
535
535
  });
536
536
 
537
537
  // Append a v1 acknowledged event directly to simulate a pre-migration
538
- // payload on disk. ctx.appendEvent always writes the current version,
538
+ // payload on disk. ctx.events.append always writes the current version,
539
539
  // so the only way to test the read-time upcaster is to write the older
540
540
  // shape via the raw event-store.
541
541
  const invoiceId = "00000000-0000-4000-8000-00000000ac01";
@@ -591,7 +591,7 @@ describe("Event Sourcing Showcase", () => {
591
591
  approverDisplayName: "Quincy Acknowledger",
592
592
  });
593
593
 
594
- // Sanity check the ctx.appendEvent path too: it writes the current
594
+ // Sanity check the ctx.events.append path too: it writes the current
595
595
  // shape directly (handler resolved displayName synchronously), so
596
596
  // the upcaster is a no-op on these events.
597
597
  const { id: liveId } = await stack.http.writeOk<{ id: string }>(
@@ -836,10 +836,10 @@ describe("role-restricted write handlers", () => {
836
836
  // - emitEvent with headers — Marten free key/value metadata
837
837
  // - r.projection — single-stream read model (inline in the write TX)
838
838
  // - r.multiStreamProjection — cross-aggregate async read model
839
- // - ctx.loadAggregate with { asOf } — point-in-time aggregate state
840
- // - ctx.archiveStream / ctx.restoreStream — Marten ArchiveStream
841
- // - ctx.queryProjection — tenant-scoped read of a projection table
842
- // - ctx.snapshotAggregate + ctx.loadAggregateWithSnapshot — perf path
839
+ // - ctx.events.load with { asOf } — point-in-time aggregate state
840
+ // - ctx.events.archive / ctx.events.restore — Marten ArchiveStream
841
+ // - ctx.dispatch.queryProjection — tenant-scoped read of a projection table
842
+ // - ctx.events.snapshot + ctx.events.loadWithSnapshot — perf path
843
843
  // for aggregates with long event tails (O(1) vs O(N) reduce), incl.
844
844
  // the auto-snapshot policy ({ snapshotEvery, snapshotVersion })
845
845
  // - streamAllEventsByType — memory-bounded iteration for ops/export jobs
@@ -1166,7 +1166,7 @@ export const invoiceFeature = defineFeature("showcase", (r) => {
1166
1166
  name: "invoice:archive",
1167
1167
  schema: z.object({ id: z.uuid() }),
1168
1168
  handler: async (event, ctx) => {
1169
- await ctx.archiveStream(event.payload.id, { aggregateType: "showcase-invoice" });
1169
+ await ctx.events.archive(event.payload.id, { aggregateType: "showcase-invoice" });
1170
1170
  return { isSuccess: true as const, data: { id: event.payload.id } };
1171
1171
  },
1172
1172
  access: { roles: ["Admin"] },
@@ -1181,14 +1181,14 @@ export const invoiceFeature = defineFeature("showcase", (r) => {
1181
1181
  handler: async (event, ctx) => {
1182
1182
  // Rebuild the state from the current stream so the snapshot reflects
1183
1183
  // the committed event log, not an in-memory guess. Use the upcaster-
1184
- // aware ctx.loadAggregate to stay consistent with read-time semantics.
1185
- const events = await ctx.loadAggregate(event.payload.id);
1184
+ // aware ctx.events.load to stay consistent with read-time semantics.
1185
+ const events = await ctx.events.load(event.payload.id);
1186
1186
  const state: InvoiceState = { ...initialInvoiceState };
1187
1187
  for (const evt of events) {
1188
1188
  reduceInvoice(state, evt);
1189
1189
  }
1190
1190
  const version = events.length > 0 ? (events[events.length - 1]?.version ?? 0) : 0;
1191
- await ctx.snapshotAggregate({
1191
+ await ctx.events.snapshot({
1192
1192
  aggregateId: event.payload.id,
1193
1193
  aggregateType: "showcase-invoice",
1194
1194
  version,
@@ -1201,13 +1201,13 @@ export const invoiceFeature = defineFeature("showcase", (r) => {
1201
1201
 
1202
1202
  // --- Query handlers ---
1203
1203
 
1204
- // Live aggregation via ctx.loadAggregate — reduces events into a state
1204
+ // Live aggregation via ctx.events.load — reduces events into a state
1205
1205
  // snapshot. Supports asOf for point-in-time reads.
1206
1206
  r.queryHandler({
1207
1207
  name: "invoice:state",
1208
1208
  schema: z.object({ id: z.uuid(), asOf: z.iso.datetime().optional() }),
1209
1209
  handler: async (query, ctx) => {
1210
- const events = await ctx.loadAggregate(query.payload.id, {
1210
+ const events = await ctx.events.load(query.payload.id, {
1211
1211
  ...(query.payload.asOf ? { asOf: Temporal.Instant.from(query.payload.asOf) } : {}),
1212
1212
  });
1213
1213
  const state: InvoiceState = { ...initialInvoiceState };
@@ -1232,7 +1232,7 @@ export const invoiceFeature = defineFeature("showcase", (r) => {
1232
1232
  name: "invoice:fast-state",
1233
1233
  schema: z.object({ id: z.uuid() }),
1234
1234
  handler: async (query, ctx) => {
1235
- const result = await ctx.loadAggregateWithSnapshot<InvoiceStateRecord>(
1235
+ const result = await ctx.events.loadWithSnapshot<InvoiceStateRecord>(
1236
1236
  query.payload.id,
1237
1237
  (state, evt) => {
1238
1238
  const next: InvoiceStateRecord = { ...state };
@@ -1261,7 +1261,7 @@ export const invoiceFeature = defineFeature("showcase", (r) => {
1261
1261
  },
1262
1262
  });
1263
1263
 
1264
- // Read-model query via ctx.queryProjection — auto-tenant-scoped. The
1264
+ // Read-model query via ctx.dispatch.queryProjection — auto-tenant-scoped. The
1265
1265
  // helper collapses the zero-argument "return this projection" pattern
1266
1266
  // into a single call; returns { rows } so the response shape stays
1267
1267
  // consistent with other list handlers.
@@ -1277,11 +1277,11 @@ export const invoiceFeature = defineFeature("showcase", (r) => {
1277
1277
  }),
1278
1278
  );
1279
1279
 
1280
- // Slow synthetic export — demonstrates ctx.signal honouring inside a
1280
+ // Slow synthetic export — demonstrates ctx.lifecycle.signal honouring inside a
1281
1281
  // long-running handler loop. Real-world equivalents: PDF batch export,
1282
1282
  // bulk CSV download, multi-stream audit walk. Mobile clients that
1283
1283
  // navigate away mid-export should NOT keep the server busy producing
1284
- // bytes nobody will read. The handler checks ctx.signal at every
1284
+ // bytes nobody will read. The handler checks ctx.lifecycle.signal at every
1285
1285
  // iteration; on abort, throws and the dispatcher returns an error to
1286
1286
  // the (already-disconnected) client.
1287
1287
  r.queryHandler({
@@ -1290,7 +1290,7 @@ export const invoiceFeature = defineFeature("showcase", (r) => {
1290
1290
  handler: async (query, ctx) => {
1291
1291
  const accumulated: number[] = [];
1292
1292
  for (let i = 0; i < query.payload.chunks; i++) {
1293
- ctx.signal?.throwIfAborted();
1293
+ ctx.lifecycle.signal?.throwIfAborted();
1294
1294
  // Fake "work per chunk". Realistic handler would assemble a row,
1295
1295
  // hit a remote service, etc.
1296
1296
  await new Promise((resolve) => setTimeout(resolve, 10));
@@ -2,7 +2,7 @@
2
2
 
3
3
  # files-post-processing
4
4
 
5
- The three ways to generate an image variant: declarative field variants, imperative ctx.derivatives.variant() with region-blur, and the public route behind a default-deny predicate.
5
+ The three ways to generate an image variant: declarative field variants, imperative ctx.services.derivatives.variant() with region-blur, and the public route behind a default-deny predicate.
6
6
 
7
7
  ## README
8
8
 
@@ -13,7 +13,7 @@ File upload plus post-processing hooks.
13
13
  ## What it shows
14
14
 
15
15
  - Declarative `variants` on `createImageField` (file-derivatives)
16
- - Imperative `ctx.derivatives.variant()` path and the public variant route (`EXT_DERIVATIVE_PUBLIC_PREDICATE`)
16
+ - Imperative `ctx.services.derivatives.variant()` path and the public variant route (`EXT_DERIVATIVE_PUBLIC_PREDICATE`)
17
17
 
18
18
  ## Source
19
19
 
@@ -41,7 +41,7 @@ bun test
41
41
  // 1. declarative — GET /api/files/:id/variant/:name resolves a field's
42
42
  // declared variant.
43
43
  // 2. imperative — the `set-cover` write-handler calls
44
- // ctx.derivatives.variant() directly, with a region-blur.
44
+ // ctx.services.derivatives.variant() directly, with a region-blur.
45
45
  // 3. public route — GET /media/:fileRefId/:variant, default-deny until a
46
46
  // photo is explicitly published.
47
47
 
@@ -178,7 +178,7 @@ describe("entry point 1 — declarative field variant", () => {
178
178
  });
179
179
  });
180
180
 
181
- describe("entry point 2 — imperative ctx.derivatives.variant() with region-blur", () => {
181
+ describe("entry point 2 — imperative ctx.services.derivatives.variant() with region-blur", () => {
182
182
  test("set-cover derives a variant with no field declaration involved, and tracks order", async () => {
183
183
  const fileId = await uploadPhoto(null);
184
184
 
@@ -292,7 +292,7 @@ describe("event emission contract", () => {
292
292
  // resolves + caches the variant behind the auth-gated
293
293
  // `GET /api/files/:id/variant/:name` route, no handler code needed.
294
294
  // 2. Imperative — the `set-cover` write-handler calls
295
- // `ctx.derivatives.variant()` directly. This is for apps that track
295
+ // `ctx.services.derivatives.variant()` directly. This is for apps that track
296
296
  // images as their own records (ordering, a chosen cover image) and for
297
297
  // region-blur, whose coordinates are runtime data that can't live in a
298
298
  // static field declaration.
@@ -371,13 +371,15 @@ export const filesPostProcessingFeature = defineFeature("files-post-processing",
371
371
  .optional(),
372
372
  }),
373
373
  handler: async (event, ctx) => {
374
- if (!ctx.derivatives) {
374
+ if (!ctx.services.derivatives) {
375
375
  return writeFailure(
376
- new InternalError({ message: "ctx.derivatives missing — is file-derivatives mounted?" }),
376
+ new InternalError({
377
+ message: "ctx.services.derivatives missing — is file-derivatives mounted?",
378
+ }),
377
379
  );
378
380
  }
379
381
  const { fileRefId, blurRegion } = event.payload;
380
- const result = await ctx.derivatives.variant(
382
+ const result = await ctx.services.derivatives.variant(
381
383
  fileRefId,
382
384
  {
383
385
  maxEdge: 800,
@@ -153,6 +153,7 @@ describe("inbound-mail triage sample", () => {
153
153
  ]);
154
154
  const redisUrl = `redis://${testRedis.redis.options.host}:${testRedis.redis.options.port}/${testRedis.redis.options.db}`;
155
155
  const entry = createAllInOneEntrypoint({
156
+ rowLevelSecurity: "off",
156
157
  registry,
157
158
  context: { db: testDb.db, redis: testRedis.redis },
158
159
  jwtSecret: JWT,
@@ -2,7 +2,7 @@
2
2
 
3
3
  # lane-routing
4
4
 
5
- runIn lane-routing: r.job pinned to api/worker deploy-lanes, event-chain via ctx.appendEvent, verified end-to-end through createAllInOneEntrypoint.
5
+ runIn lane-routing: r.job pinned to api/worker deploy-lanes, event-chain via ctx.events.append, verified end-to-end through createAllInOneEntrypoint.
6
6
 
7
7
  ## README
8
8
 
@@ -94,6 +94,7 @@ describe("lane-routing sample", () => {
94
94
  const registry = createRegistry([createLaneRoutingFeature()]);
95
95
  const redisUrl = `redis://${testRedis.redis.options.host}:${testRedis.redis.options.port}/${testRedis.redis.options.db}`;
96
96
  const entry = createAllInOneEntrypoint({
97
+ rowLevelSecurity: "off",
97
98
  registry,
98
99
  context: { db: testDb.db, redis: testRedis.redis },
99
100
  jwtSecret: JWT,
@@ -108,9 +108,9 @@ A one-shot setup routine that runs on first boot or via the CLI:
108
108
  // bin/seed-legal.ts
109
109
  import { seedTextBlock } from "@cosmicdrift/kumiko-bundled-features/template-resolver/seeding";
110
110
  import { SYSTEM_TENANT_ID } from "@cosmicdrift/kumiko-framework/engine";
111
- import { createDb } from "@cosmicdrift/kumiko-framework/db";
111
+ import { createDbConnection } from "@cosmicdrift/kumiko-framework/db";
112
112
 
113
- const db = createDb(process.env.DATABASE_URL!);
113
+ const { db } = createDbConnection({ url: process.env.DATABASE_URL! });
114
114
 
115
115
  await seedTextBlock(db, {
116
116
  tenantId: SYSTEM_TENANT_ID,
@@ -35,8 +35,8 @@ back.
35
35
  - **`r.hook({ type: "postDelete", target: { allOf: entityRef }, handler })`** — fires after commit.
36
36
  External side effects (logs, notifications) belong here because
37
37
  failures cannot roll the delete back.
38
- - **`ctx.scheduleAfterRollback(fn)`** — the counterpart of `scheduleAfterCommit`: runs `fn` when
39
- the handler transaction (or the enclosing savepoint of a nested `ctx.write`) does not commit.
38
+ - **`ctx.lifecycle.afterRollback(fn)`** — the counterpart of `ctx.lifecycle.afterCommit`: runs `fn` when
39
+ the handler transaction (or the enclosing savepoint of a nested `ctx.dispatch.write`) does not commit.
40
40
  Use it to give back something reserved outside the transaction, like the slot in
41
41
  `article:reserve-slot`. A failed COMMIT triggers it too, so write the callback idempotent.
42
42
 
@@ -356,7 +356,7 @@ export const articlesFeature = defineFeature("blog", (r) => {
356
356
  handler: async (event, ctx) => {
357
357
  const { slot, reject } = event.payload;
358
358
  reservedSlots.add(slot);
359
- ctx.scheduleAfterRollback?.(async () => {
359
+ ctx.lifecycle.afterRollback?.(async () => {
360
360
  reservedSlots.delete(slot);
361
361
  });
362
362
  if (reject) return writeFailure(new UnprocessableError("slot_rejected"));
@@ -51,7 +51,7 @@ r.config({
51
51
 
52
52
  - **`backing: "secrets"`** — the value lives in the secrets store (envelope
53
53
  encryption, KEK rotation, audit-on-read) instead of `config_values`. Set/read/
54
- reset dispatch through `ctx.secrets`; the query handlers mask the value while
54
+ reset dispatch through `ctx.services.secrets`; the query handlers mask the value while
55
55
  the owning feature still reads the revealed plaintext via `ctx.config`. Only
56
56
  valid for `scope: "system"` — secrets are flat per `(tenant, key)` with no
57
57
  cascade, so a tenant override would be incoherent and is rejected at boot.
@@ -80,7 +80,7 @@ await runProdApp({
80
80
  envSchema, // composeEnvSchema({ core: frameworkCoreEnvSchema, features })
81
81
  extraContext: ({ db, registry }) => ({
82
82
  configResolver: resolver,
83
- _configAccessorFactory: createConfigAccessorFactory(registry, resolver),
83
+ configAccessorFactory: createConfigAccessorFactory(registry, resolver),
84
84
  // Required whenever a key declares backing:"secrets" — without it the set
85
85
  // and read paths fail loud, never silently miss.
86
86
  secrets: createSecretsContext({ db, masterKeyProvider, registry }),
@@ -90,7 +90,7 @@ await runProdApp({
90
90
  ```
91
91
 
92
92
  Register the `secrets` feature too so its `tenant_secrets` table is migrated;
93
- the config backing only needs the `ctx.secrets` context shown above.
93
+ the config backing only needs the `ctx.services.secrets` context shown above.
94
94
 
95
95
  ## Vs. the neighbouring recipes
96
96
 
@@ -211,7 +211,7 @@ beforeAll(async () => {
211
211
  const resolver = createConfigResolver();
212
212
  return {
213
213
  configResolver: resolver,
214
- _configAccessorFactory: createConfigAccessorFactory(registry, resolver),
214
+ configAccessorFactory: createConfigAccessorFactory(registry, resolver),
215
215
  secrets: createSecretsContext({ db, masterKeyProvider, registry }),
216
216
  };
217
217
  },