@cosmicdrift/kumiko-framework 1.0.0 → 2.0.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 (424) hide show
  1. package/README.md +9 -38
  2. package/package.json +21 -2
  3. package/src/__tests__/anonymous-access.integration.test.ts +185 -0
  4. package/src/__tests__/consumer-cli.integration.test.ts +172 -0
  5. package/src/__tests__/entity-permalink-open.integration.test.ts +94 -0
  6. package/src/__tests__/full-stack.integration.test.ts +1 -1
  7. package/src/__tests__/schema-cli-temporal-polyfill.test.ts +48 -0
  8. package/src/__tests__/schema-cli.integration.test.ts +50 -0
  9. package/src/__tests__/store-table.integration.test.ts +93 -0
  10. package/src/api/__tests__/api.test.ts +373 -0
  11. package/src/api/__tests__/auth-middleware-anonymous-access-boot.test.ts +40 -0
  12. package/src/api/__tests__/auth-routes-cookie.test.ts +17 -1
  13. package/src/api/__tests__/auth-routes-invalid-body-invite.test.ts +253 -0
  14. package/src/api/__tests__/auth-routes-mfa-preauth-confirm.test.ts +222 -0
  15. package/src/api/__tests__/auth-routes-mfa-preauth-enable-start.test.ts +249 -0
  16. package/src/api/__tests__/auth-routes-mfa-verify.test.ts +202 -0
  17. package/src/api/__tests__/auth-routes-trusted-proxy.test.ts +135 -0
  18. package/src/api/__tests__/batch.integration.test.ts +101 -11
  19. package/src/api/__tests__/csrf-constants-sync.test.ts +20 -0
  20. package/src/api/__tests__/dispatcher-live.integration.test.ts +74 -0
  21. package/src/api/__tests__/jwt.test.ts +200 -1
  22. package/src/api/__tests__/login-rate-limiter-sweep.test.ts +50 -0
  23. package/src/api/__tests__/pat-scope.test.ts +36 -0
  24. package/src/api/__tests__/pii-leak-guard.integration.test.ts +103 -0
  25. package/src/api/__tests__/redis-login-rate-limiter.integration.test.ts +138 -0
  26. package/src/api/__tests__/request-id-middleware.test.ts +51 -0
  27. package/src/api/__tests__/server-boot-guards.test.ts +71 -0
  28. package/src/api/__tests__/server-jwt-ttl.test.ts +58 -0
  29. package/src/api/__tests__/sse-broker.test.ts +57 -0
  30. package/src/api/__tests__/sse-route.test.ts +4 -0
  31. package/src/api/api-constants.ts +11 -0
  32. package/src/api/auth-middleware.ts +248 -40
  33. package/src/api/auth-routes.ts +576 -95
  34. package/src/api/index.ts +13 -4
  35. package/src/api/jwt.ts +170 -11
  36. package/src/api/pat-scope.ts +14 -0
  37. package/src/api/pii-leak-guard.ts +47 -0
  38. package/src/api/request-context.ts +3 -0
  39. package/src/api/request-id-middleware.ts +2 -0
  40. package/src/api/routes.ts +169 -2
  41. package/src/api/server.ts +112 -16
  42. package/src/api/sse-broker.ts +39 -0
  43. package/src/bun-db/__tests__/PATTERN.md +0 -1
  44. package/src/bun-db/__tests__/coerce-row-temporal.test.ts +41 -0
  45. package/src/bun-db/__tests__/select-many-retry.test.ts +79 -0
  46. package/src/bun-db/__tests__/write-brand.test.ts +21 -0
  47. package/src/bun-db/connection.ts +3 -3
  48. package/src/bun-db/index.ts +2 -0
  49. package/src/bun-db/query.ts +105 -32
  50. package/src/consumer-cli.ts +134 -0
  51. package/src/crypto/__tests__/blind-index.test.ts +130 -0
  52. package/src/crypto/__tests__/event-pii.test.ts +161 -0
  53. package/src/crypto/__tests__/kek-rotation.integration.test.ts +180 -0
  54. package/src/crypto/__tests__/kms-adapter-contract.ts +134 -0
  55. package/src/crypto/__tests__/kms-adapter.contract.test.ts +4 -0
  56. package/src/crypto/__tests__/pg-kms-adapter.integration.test.ts +117 -0
  57. package/src/crypto/__tests__/pii-field-encryption.test.ts +376 -0
  58. package/src/crypto/__tests__/request-kms-cache.test.ts +74 -0
  59. package/src/crypto/__tests__/subject-resolver.test.ts +108 -0
  60. package/src/crypto/blind-index.ts +118 -0
  61. package/src/crypto/event-pii.ts +70 -0
  62. package/src/crypto/in-memory-kms-adapter.ts +50 -0
  63. package/src/crypto/index.ts +67 -0
  64. package/src/crypto/kms-adapter.ts +2 -0
  65. package/src/crypto/pg-kms-adapter.ts +295 -0
  66. package/src/crypto/pii-field-encryption.ts +248 -0
  67. package/src/crypto/request-kms-cache.ts +38 -0
  68. package/src/crypto/subject-resolver.ts +91 -0
  69. package/src/db/__tests__/assert-no-unreachable-live-rows.integration.test.ts +191 -0
  70. package/src/db/__tests__/blind-index.integration.test.ts +248 -0
  71. package/src/db/__tests__/build-filter-where.test.ts +34 -0
  72. package/src/db/__tests__/collect-table-metas.test.ts +10 -10
  73. package/src/db/__tests__/config-seed.integration.test.ts +13 -5
  74. package/src/db/__tests__/dialect-instant.test.ts +1 -4
  75. package/src/db/__tests__/entity-field-encryption.test.ts +7 -7
  76. package/src/db/__tests__/entity-table-meta-source.test.ts +50 -0
  77. package/src/db/__tests__/event-store-executor-context.pii-roundtrip.test.ts +67 -0
  78. package/src/db/__tests__/event-store-executor-write-verbs.integration.test.ts +402 -0
  79. package/src/db/__tests__/event-store-executor.integration.test.ts +299 -29
  80. package/src/db/__tests__/feature-table-sources.test.ts +34 -0
  81. package/src/db/__tests__/implicit-projection-equivalence.integration.test.ts +118 -39
  82. package/src/db/__tests__/instant-to-driver-temporal.test.ts +21 -0
  83. package/src/db/__tests__/located-timestamp.test.ts +19 -0
  84. package/src/db/__tests__/migrate-generator.test.ts +21 -0
  85. package/src/db/__tests__/migrate-runner.test.ts +61 -0
  86. package/src/db/__tests__/number-field-fractional.integration.test.ts +58 -0
  87. package/src/db/__tests__/rebuild-marker.test.ts +13 -3
  88. package/src/db/__tests__/replay-migration-sql.test.ts +384 -0
  89. package/src/db/__tests__/schema-inspection.test.ts +7 -0
  90. package/src/db/__tests__/schema-migration.integration.test.ts +1 -1
  91. package/src/db/__tests__/table-builder-meta-lockstep.test.ts +39 -0
  92. package/src/db/__tests__/tenant-db-where-merge.test.ts +49 -3
  93. package/src/db/__tests__/tenant-db.integration.test.ts +6 -2
  94. package/src/db/api.ts +2 -2
  95. package/src/db/apply-entity-event.ts +18 -14
  96. package/src/db/blind-index-cleanup.ts +55 -0
  97. package/src/db/bun-provider.ts +2 -2
  98. package/src/db/collect-table-metas.ts +6 -7
  99. package/src/db/config-seed.ts +9 -9
  100. package/src/db/connection.ts +7 -12
  101. package/src/db/cursor.ts +1 -18
  102. package/src/db/dialect.ts +20 -26
  103. package/src/db/entity-field-encryption.ts +81 -24
  104. package/src/db/entity-table-meta-types.ts +2 -0
  105. package/src/db/entity-table-meta.ts +63 -90
  106. package/src/db/event-store-executor-context.ts +404 -0
  107. package/src/db/event-store-executor-read.ts +275 -0
  108. package/src/db/event-store-executor-write.ts +644 -0
  109. package/src/db/event-store-executor.ts +28 -1155
  110. package/src/db/feature-table-sources.ts +6 -5
  111. package/src/db/index.ts +20 -3
  112. package/src/db/located-timestamp.ts +4 -0
  113. package/src/db/migrate-generator.ts +39 -6
  114. package/src/db/migrate-runner.ts +107 -11
  115. package/src/db/pg-error.ts +9 -1
  116. package/src/db/postgres-provider.ts +2 -2
  117. package/src/db/queries/__tests__/event-store-idempotency-index.integration.test.ts +80 -0
  118. package/src/db/queries/backfill-pii.ts +277 -0
  119. package/src/db/queries/ddl.ts +45 -0
  120. package/src/db/queries/event-consumer.ts +35 -2
  121. package/src/db/queries/event-store.ts +126 -19
  122. package/src/db/queries/projection-rebuild.ts +22 -8
  123. package/src/db/queries/shadow-swap.ts +183 -0
  124. package/src/db/queries/test-stack.ts +4 -30
  125. package/src/db/query-api.ts +1 -0
  126. package/src/db/query.ts +1 -0
  127. package/src/db/rebuild-marker.ts +18 -2
  128. package/src/db/reference-data.ts +2 -3
  129. package/src/db/replay-migration-sql.ts +257 -0
  130. package/src/db/schema-inspection.ts +1 -1
  131. package/src/db/table-builder.ts +102 -71
  132. package/src/db/tenant-db.ts +15 -53
  133. package/src/engine/__tests__/boot-validator-action-wiring.test.ts +242 -0
  134. package/src/engine/__tests__/boot-validator-boot-check.test.ts +99 -0
  135. package/src/engine/__tests__/boot-validator-dashboard.test.ts +237 -0
  136. package/src/engine/__tests__/boot-validator-entity-list.test.ts +104 -0
  137. package/src/engine/__tests__/boot-validator-gdpr-storage.test.ts +7 -69
  138. package/src/engine/__tests__/boot-validator-i18n-keys.test.ts +26 -5
  139. package/src/engine/__tests__/boot-validator-located-timestamps.test.ts +3 -19
  140. package/src/engine/__tests__/boot-validator-pii-retention.test.ts +246 -4
  141. package/src/engine/__tests__/boot-validator.test.ts +219 -15
  142. package/src/engine/__tests__/build-app-schema.test.ts +82 -0
  143. package/src/engine/__tests__/build-config-feature-schema.test.ts +125 -0
  144. package/src/engine/__tests__/build-target.test.ts +3 -11
  145. package/src/engine/__tests__/codemod-pipeline.test.ts +152 -21
  146. package/src/engine/__tests__/config-helpers.test.ts +16 -0
  147. package/src/engine/__tests__/define-feature-entity-mapping.test.ts +6 -0
  148. package/src/engine/__tests__/define-roles.test.ts +21 -0
  149. package/src/engine/__tests__/engine.test.ts +163 -1
  150. package/src/engine/__tests__/entity-handlers.test.ts +80 -0
  151. package/src/engine/__tests__/event-migration-declarative.test.ts +65 -0
  152. package/src/engine/__tests__/event-type-map-augmentation.test.ts +24 -0
  153. package/src/engine/__tests__/extend-entity-projection.test.ts +123 -0
  154. package/src/engine/__tests__/factories-time.test.ts +2 -66
  155. package/src/engine/__tests__/feature-crud-shorthand.test.ts +28 -0
  156. package/src/engine/__tests__/feature-manifest.test.ts +31 -1
  157. package/src/engine/__tests__/field-access.test.ts +23 -1
  158. package/src/engine/__tests__/hook-phases.test.ts +5 -5
  159. package/src/engine/__tests__/membership-roles.test.ts +4 -10
  160. package/src/engine/__tests__/nav.test.ts +86 -1
  161. package/src/engine/__tests__/pipeline-engine.test.ts +9 -9
  162. package/src/engine/__tests__/pipeline-handler.integration.test.ts +18 -18
  163. package/src/engine/__tests__/pipeline-observability.integration.test.ts +2 -2
  164. package/src/engine/__tests__/pipeline-performance.integration.test.ts +3 -3
  165. package/src/engine/__tests__/pipeline-sub-pipelines.test.ts +9 -9
  166. package/src/engine/__tests__/post-query-hook.test.ts +7 -7
  167. package/src/engine/__tests__/registrar-object-form.test.ts +141 -0
  168. package/src/engine/__tests__/registry.test.ts +144 -0
  169. package/src/engine/__tests__/schema-builder.test.ts +18 -0
  170. package/src/engine/__tests__/screen.test.ts +147 -1
  171. package/src/engine/__tests__/soft-delete-cleanup.test.ts +3 -0
  172. package/src/engine/__tests__/store-table.test.ts +229 -0
  173. package/src/engine/__tests__/tier-resolver-extension.test.ts +19 -1
  174. package/src/engine/__tests__/{visual-tree-patterns.test.ts → tree-actions-patterns.test.ts} +7 -95
  175. package/src/engine/__tests__/validate-projection-allowlist.test.ts +15 -15
  176. package/src/engine/boot-validator/__tests__/config-deps.test.ts +92 -0
  177. package/src/engine/boot-validator/action-wiring.ts +149 -0
  178. package/src/engine/boot-validator/boot-check.ts +21 -0
  179. package/src/engine/boot-validator/config-deps.ts +40 -4
  180. package/src/engine/boot-validator/entity-handler.ts +20 -21
  181. package/src/engine/boot-validator/entity-list-screens.ts +88 -0
  182. package/src/engine/boot-validator/gdpr-storage.ts +0 -20
  183. package/src/engine/boot-validator/i18n-keys.ts +58 -4
  184. package/src/engine/boot-validator/index.ts +33 -12
  185. package/src/engine/boot-validator/nav.ts +125 -0
  186. package/src/engine/boot-validator/pii-retention.ts +95 -10
  187. package/src/engine/boot-validator/{screens-nav.ts → screens.ts} +214 -191
  188. package/src/engine/boot-validator/workspaces.ts +68 -0
  189. package/src/engine/build-app-schema.ts +16 -0
  190. package/src/engine/build-config-feature-schema.ts +44 -7
  191. package/src/engine/codemod/pipeline-codemod.ts +5 -5
  192. package/src/engine/config-helpers.ts +15 -0
  193. package/src/engine/constants.ts +32 -6
  194. package/src/engine/create-app.ts +11 -0
  195. package/src/engine/define-feature.ts +95 -947
  196. package/src/engine/define-handler.ts +28 -94
  197. package/src/engine/define-workflow.ts +1 -1
  198. package/src/engine/effective-features.ts +12 -2
  199. package/src/engine/entity-handlers.ts +76 -11
  200. package/src/engine/extensions/tenant-data.ts +19 -0
  201. package/src/engine/extensions/user-data.ts +29 -2
  202. package/src/engine/factories.ts +8 -49
  203. package/src/engine/feature-ast/__tests__/canonical-form.test.ts +26 -29
  204. package/src/engine/feature-ast/__tests__/fixtures/cross-file-registrar/feature.ts +9 -0
  205. package/src/engine/feature-ast/__tests__/fixtures/cross-file-registrar/screens.ts +4 -0
  206. package/src/engine/feature-ast/__tests__/parse-happy-path.test.ts +1 -2
  207. package/src/engine/feature-ast/__tests__/parse-real-features.test.ts +18 -8
  208. package/src/engine/feature-ast/__tests__/parse.test.ts +1640 -160
  209. package/src/engine/feature-ast/__tests__/patch.test.ts +206 -12
  210. package/src/engine/feature-ast/__tests__/patcher.test.ts +20 -23
  211. package/src/engine/feature-ast/__tests__/render-roundtrip.test.ts +380 -5
  212. package/src/engine/feature-ast/extractors/events.ts +322 -0
  213. package/src/engine/feature-ast/extractors/handlers.ts +234 -0
  214. package/src/engine/feature-ast/extractors/hooks.ts +243 -0
  215. package/src/engine/feature-ast/extractors/index.ts +34 -31
  216. package/src/engine/feature-ast/extractors/jobs-routes.ts +221 -0
  217. package/src/engine/feature-ast/extractors/projections-screens.ts +269 -0
  218. package/src/engine/feature-ast/extractors/round1.ts +3 -3
  219. package/src/engine/feature-ast/extractors/round5.ts +3 -3
  220. package/src/engine/feature-ast/extractors/round6.ts +2 -36
  221. package/src/engine/feature-ast/extractors/shared.ts +64 -6
  222. package/src/engine/feature-ast/index.ts +2 -4
  223. package/src/engine/feature-ast/parse.ts +130 -23
  224. package/src/engine/feature-ast/patch.ts +39 -50
  225. package/src/engine/feature-ast/patcher.ts +37 -38
  226. package/src/engine/feature-ast/patterns.ts +50 -62
  227. package/src/engine/feature-ast/render.ts +67 -44
  228. package/src/engine/feature-builder-state.ts +168 -0
  229. package/src/engine/feature-config-events-jobs.ts +403 -0
  230. package/src/engine/feature-entity-handlers.ts +208 -0
  231. package/src/engine/feature-manifest.ts +2 -1
  232. package/src/engine/feature-ui-extensions.ts +500 -0
  233. package/src/engine/field-access.ts +13 -2
  234. package/src/engine/field-helpers.ts +31 -0
  235. package/src/engine/handler-helpers.ts +26 -0
  236. package/src/engine/hook-helpers.ts +16 -0
  237. package/src/engine/index.ts +23 -7
  238. package/src/engine/membership-roles.ts +13 -0
  239. package/src/engine/object-form.ts +27 -0
  240. package/src/engine/ownership.ts +26 -79
  241. package/src/engine/pattern-library/__tests__/library.test.ts +7 -20
  242. package/src/engine/pattern-library/library.ts +44 -1152
  243. package/src/engine/pattern-library/mixed-schemas.ts +450 -0
  244. package/src/engine/pattern-library/opaque-schemas.ts +124 -0
  245. package/src/engine/pattern-library/shared-fields.ts +75 -0
  246. package/src/engine/pattern-library/static-schemas.ts +456 -0
  247. package/src/engine/pipeline.ts +6 -11
  248. package/src/engine/registry-facade.ts +362 -0
  249. package/src/engine/registry-ingest.ts +478 -0
  250. package/src/engine/registry-state.ts +388 -0
  251. package/src/engine/registry-validate.ts +642 -0
  252. package/src/engine/registry.ts +78 -1658
  253. package/src/engine/run-pipeline.ts +1 -1
  254. package/src/engine/schema-builder.ts +1 -0
  255. package/src/engine/screen-helpers.ts +54 -0
  256. package/src/engine/soft-delete-cleanup.ts +6 -2
  257. package/src/engine/steps/__tests__/duration-utils.test.ts +20 -0
  258. package/src/engine/steps/_duration-utils.ts +2 -0
  259. package/src/engine/steps/unsafe-projection-upsert.ts +1 -4
  260. package/src/engine/tier-resolver-extension.ts +3 -2
  261. package/src/engine/types/config.ts +2 -482
  262. package/src/engine/types/define-handler.ts +2 -0
  263. package/src/engine/types/entity-handlers.ts +2 -0
  264. package/src/engine/types/event-type-map.ts +1 -37
  265. package/src/engine/types/feature.ts +2 -972
  266. package/src/engine/types/fields.ts +2 -675
  267. package/src/engine/types/handlers.ts +2 -774
  268. package/src/engine/types/hooks.ts +2 -184
  269. package/src/engine/types/http-route.ts +1 -54
  270. package/src/engine/types/identifiers.ts +1 -47
  271. package/src/engine/types/index.ts +86 -40
  272. package/src/engine/types/nav.ts +2 -63
  273. package/src/engine/types/ownership.ts +2 -0
  274. package/src/engine/types/projection.ts +2 -138
  275. package/src/engine/types/relations.ts +1 -51
  276. package/src/engine/types/screen.ts +2 -574
  277. package/src/engine/types/step.ts +2 -334
  278. package/src/engine/types/target-ref.ts +1 -21
  279. package/src/engine/types/tree-node.ts +1 -132
  280. package/src/engine/types/workspace.ts +2 -49
  281. package/src/engine/validate-projection-allowlist.ts +6 -6
  282. package/src/entrypoint/__tests__/entrypoint-job-wiring.integration.test.ts +120 -1
  283. package/src/entrypoint/index.ts +49 -6
  284. package/src/errors/classes.ts +22 -1
  285. package/src/errors/field-issue.ts +0 -3
  286. package/src/errors/index.ts +1 -1
  287. package/src/errors/write-error-info.ts +10 -22
  288. package/src/es-ops/README.md +1 -1
  289. package/src/es-ops/__tests__/runner.integration.test.ts +74 -0
  290. package/src/es-ops/context.ts +4 -2
  291. package/src/es-ops/types.ts +8 -1
  292. package/src/event-store/__tests__/admin-api.integration.test.ts +27 -1
  293. package/src/event-store/__tests__/backfill-pii.integration.test.ts +279 -0
  294. package/src/event-store/__tests__/event-store.integration.test.ts +201 -0
  295. package/src/event-store/__tests__/row-to-stored-event.test.ts +2 -2
  296. package/src/event-store/__tests__/snapshot.integration.test.ts +86 -0
  297. package/src/event-store/__tests__/unscoped-stream-primitives.guard.test.ts +58 -0
  298. package/src/event-store/__tests__/upcaster.integration.test.ts +77 -45
  299. package/src/event-store/admin-api.ts +11 -4
  300. package/src/event-store/errors.ts +2 -35
  301. package/src/event-store/event-store.ts +64 -78
  302. package/src/event-store/events-schema.ts +11 -13
  303. package/src/event-store/index.ts +18 -3
  304. package/src/event-store/rebuild-dead-letter.ts +111 -0
  305. package/src/event-store/snapshot.ts +63 -40
  306. package/src/event-store/types.ts +2 -0
  307. package/src/files/__tests__/build-storage-key.test.ts +28 -0
  308. package/src/files/__tests__/file-ref-entity.test.ts +8 -0
  309. package/src/files/__tests__/files.integration.test.ts +24 -0
  310. package/src/files/__tests__/in-memory-provider.contract.test.ts +4 -0
  311. package/src/files/__tests__/local-provider.test.ts +31 -0
  312. package/src/files/__tests__/provider-resolver.test.ts +70 -0
  313. package/src/files/__tests__/write-stream.test.ts +13 -0
  314. package/src/files/file-handle.ts +2 -19
  315. package/src/files/file-ref-entity.ts +2 -2
  316. package/src/files/file-routes.ts +13 -0
  317. package/src/files/index.ts +1 -1
  318. package/src/files/local-provider.ts +27 -8
  319. package/src/files/provider-resolver.ts +31 -20
  320. package/src/files/types.ts +13 -55
  321. package/src/i18n/__tests__/required-surface-keys.test.ts +17 -0
  322. package/src/i18n/required-surface-keys.ts +120 -1
  323. package/src/jobs/__tests__/job-queue-depth.integration.test.ts +82 -0
  324. package/src/jobs/__tests__/jobs.integration.test.ts +329 -3
  325. package/src/jobs/job-runner.ts +82 -12
  326. package/src/logging/types.ts +1 -7
  327. package/src/migrations/pending-rebuilds.ts +1 -1
  328. package/src/observability/__tests__/observability.integration.test.ts +4 -1
  329. package/src/observability/__tests__/recording-tracer.test.ts +6 -4
  330. package/src/observability/index.ts +2 -0
  331. package/src/observability/noop-provider.ts +0 -9
  332. package/src/observability/recording-tracer.ts +0 -12
  333. package/src/observability/standard-metrics.ts +64 -2
  334. package/src/observability/types/index.ts +1 -29
  335. package/src/observability/types/metric.ts +1 -56
  336. package/src/observability/types/provider.ts +1 -32
  337. package/src/observability/types/span.ts +1 -64
  338. package/src/pipeline/__tests__/ctx-bridge.integration.test.ts +2 -2
  339. package/src/pipeline/__tests__/dispatcher.test.ts +366 -1
  340. package/src/pipeline/__tests__/event-consumer-state.integration.test.ts +31 -0
  341. package/src/pipeline/__tests__/event-dispatcher-delivery-max-attempts.test.ts +126 -0
  342. package/src/pipeline/__tests__/event-dispatcher-rearm.integration.test.ts +263 -0
  343. package/src/pipeline/__tests__/event-dispatcher.integration.test.ts +10 -0
  344. package/src/pipeline/__tests__/job-trigger-consumer.integration.test.ts +106 -0
  345. package/src/pipeline/__tests__/lifecycle-pipeline.test.ts +308 -77
  346. package/src/pipeline/__tests__/load-aggregate-query.integration.test.ts +16 -8
  347. package/src/pipeline/__tests__/post-query-hook.integration.test.ts +3 -3
  348. package/src/pipeline/__tests__/projection-rebuild.integration.test.ts +80 -2
  349. package/src/pipeline/__tests__/rebuild-poison-quarantine.integration.test.ts +274 -0
  350. package/src/pipeline/__tests__/try-append-event.integration.test.ts +166 -0
  351. package/src/pipeline/dispatch-batch.ts +187 -0
  352. package/src/pipeline/dispatch-query.ts +165 -0
  353. package/src/pipeline/dispatch-shared.ts +826 -0
  354. package/src/pipeline/dispatch-stream.ts +90 -0
  355. package/src/pipeline/dispatch-write.ts +451 -0
  356. package/src/pipeline/dispatcher-utils.ts +1 -1
  357. package/src/pipeline/dispatcher.ts +44 -1372
  358. package/src/pipeline/entity-cache.ts +2 -33
  359. package/src/pipeline/event-consumer-state.ts +30 -2
  360. package/src/pipeline/event-dispatcher-admin.ts +293 -0
  361. package/src/pipeline/event-dispatcher-delivery.ts +305 -0
  362. package/src/pipeline/event-dispatcher.ts +85 -542
  363. package/src/pipeline/index.ts +2 -0
  364. package/src/pipeline/msp-rebuild.ts +42 -3
  365. package/src/pipeline/multi-stream-apply-context.ts +4 -42
  366. package/src/pipeline/projection-rebuild.ts +105 -3
  367. package/src/pipeline/system-hooks.ts +144 -1
  368. package/src/rate-limit/__tests__/resolver.integration.test.ts +18 -0
  369. package/src/rate-limit/resolver.ts +16 -32
  370. package/src/schema-cli.ts +76 -16
  371. package/src/search/__tests__/meilisearch-adapter.integration.test.ts +207 -185
  372. package/src/search/__tests__/meilisearch-ids.test.ts +30 -0
  373. package/src/search/__tests__/reindex-entity.integration.test.ts +144 -0
  374. package/src/search/index.ts +6 -0
  375. package/src/search/meilisearch-adapter.ts +13 -12
  376. package/src/search/reindex-entity.ts +177 -0
  377. package/src/search/types.ts +1 -39
  378. package/src/secrets/__tests__/contains-secret.test.ts +34 -0
  379. package/src/secrets/__tests__/envelope-cipher.test.ts +59 -0
  380. package/src/secrets/__tests__/envelope.test.ts +1 -1
  381. package/src/secrets/dek-cache.ts +26 -5
  382. package/src/secrets/envelope-cipher.ts +53 -0
  383. package/src/secrets/envelope.ts +5 -3
  384. package/src/secrets/index.ts +13 -1
  385. package/src/secrets/stored-envelope.ts +46 -0
  386. package/src/secrets/types.ts +2 -162
  387. package/src/stack/__tests__/event-collector.test.ts +42 -0
  388. package/src/stack/__tests__/setup-test-stack-jobs.integration.test.ts +125 -0
  389. package/src/stack/db.ts +2 -1
  390. package/src/stack/push-entity-projection-tables.ts +4 -3
  391. package/src/stack/redis.ts +8 -0
  392. package/src/stack/request-helper.ts +38 -2
  393. package/src/stack/table-helpers.ts +6 -4
  394. package/src/stack/test-stack.ts +249 -131
  395. package/src/testing/__tests__/late-bound.test.ts +32 -0
  396. package/src/testing/__tests__/wait-for.test.ts +59 -0
  397. package/src/testing/boot-validator-fixture.ts +121 -0
  398. package/src/testing/e2e-generator.ts +8 -0
  399. package/src/testing/file-provider-contract.ts +104 -0
  400. package/src/testing/handler-context.ts +3 -1
  401. package/src/testing/index.ts +5 -0
  402. package/src/testing/late-bound.ts +5 -3
  403. package/src/testing/mutable-master-key-provider.ts +29 -3
  404. package/src/testing/wait-for.ts +3 -0
  405. package/src/testing/without-ambient-temporal.ts +14 -0
  406. package/src/time/__tests__/tz-dateline.test.ts +8 -10
  407. package/src/time/geo-tz.ts +1 -32
  408. package/src/time/index.ts +1 -0
  409. package/src/time/legacy-date.ts +18 -0
  410. package/src/time/polyfill.ts +21 -38
  411. package/src/time/tz-context.ts +44 -85
  412. package/src/ui-types/app-schema.ts +12 -0
  413. package/src/ui-types/index.ts +20 -7
  414. package/src/utils/__tests__/safe-json-temporal.test.ts +18 -0
  415. package/src/utils/safe-json.ts +13 -1
  416. package/src/__tests__/raw-table.integration.test.ts +0 -116
  417. package/src/bun-db/__tests__/bun-test-stack.ts +0 -6
  418. package/src/db/__tests__/encryption.test.ts +0 -39
  419. package/src/db/encryption.ts +0 -39
  420. package/src/db/row-helpers.ts +0 -4
  421. package/src/engine/__tests__/raw-table.test.ts +0 -150
  422. package/src/engine/__tests__/unmanaged-table.test.ts +0 -127
  423. package/src/engine/feature-ast/__tests__/visual-tree-parse.test.ts +0 -184
  424. package/src/engine/feature-ast/extractors/round4.ts +0 -1366
@@ -9,7 +9,8 @@
9
9
  // up at canonical positions). We compare every other field.
10
10
 
11
11
  import { describe, expect, test } from "bun:test";
12
- import { Project } from "ts-morph";
12
+ import * as path from "node:path";
13
+ import { Project, ts } from "ts-morph";
13
14
  import { parseSourceFile } from "../parse";
14
15
  import type { FeaturePattern } from "../patterns";
15
16
  import { renderFeatureFile, renderPattern } from "../render";
@@ -29,10 +30,10 @@ defineFeature("inventory", (r) => {
29
30
  },
30
31
  });
31
32
 
32
- r.relation("item", "supplier", { kind: "belongsTo", to: "user" });
33
+ r.relation("item", "supplier", { type: "belongsTo", target: "user", foreignKey: "supplierId" });
33
34
 
34
35
  r.metric("created", { type: "counter" });
35
- r.secret("apiKey", { description: "Stripe key" });
36
+ r.secret("apiKey", { label: { en: "Stripe API Key" }, scope: "tenant" });
36
37
  r.claimKey("teamId", { type: "string" });
37
38
 
38
39
  r.referenceData(
@@ -44,7 +45,16 @@ defineFeature("inventory", (r) => {
44
45
  { upsertKey: "id" },
45
46
  );
46
47
 
47
- r.config({ keys: { maxRows: { type: "number", default: 50 } } });
48
+ r.config({
49
+ keys: {
50
+ maxRows: {
51
+ type: "number",
52
+ default: 50,
53
+ scope: "tenant",
54
+ access: { read: ["user"], write: ["admin"] },
55
+ },
56
+ },
57
+ });
48
58
  });
49
59
  `;
50
60
 
@@ -114,7 +124,7 @@ function stripLocations(value: unknown): unknown {
114
124
  out[k] = { raw: normalizeBodyRaw((v as { raw: string }).raw) };
115
125
  continue;
116
126
  }
117
- if (k === "opaqueProps" && v && typeof v === "object") {
127
+ if ((k === "opaqueProps" || k === "migrations") && v && typeof v === "object") {
118
128
  const op: Record<string, unknown> = {};
119
129
  for (const [pk, pv] of Object.entries(v as Record<string, unknown>)) {
120
130
  if (pv && typeof pv === "object" && "raw" in pv) {
@@ -196,6 +206,15 @@ defineFeature("workflow", (r) => {
196
206
  { access: { openToAll: true } },
197
207
  );
198
208
 
209
+ r.streamHandler(
210
+ "step:stream",
211
+ z.object({ prompt: z.string() }),
212
+ async function* (input, ctx) {
213
+ yield "token";
214
+ },
215
+ { access: { roles: ["user"] } },
216
+ );
217
+
199
218
  r.hook("postSave", "step", async (event, ctx) => {
200
219
  console.log("step saved");
201
220
  });
@@ -237,6 +256,83 @@ describe("render → parse roundtrip — mixed patterns (header data + opaque bo
237
256
  // guarantee than parse → render → parse, because it pins that the renderer
238
257
  // never depends on the input file's whitespace — its output is deterministic
239
258
  // from the parsed FeaturePattern shape alone.
259
+ const RAW_REF_FEATURE = `
260
+ import { defineFeature } from "@cosmicdrift/kumiko-framework/engine";
261
+ import { chatCompleteHandler } from "./handlers";
262
+
263
+ const eventEntity = {
264
+ fields: { name: { type: "text", required: true } },
265
+ };
266
+
267
+ function buildFields() {
268
+ return { title: { type: "text" } };
269
+ }
270
+
271
+ const someFeature = { name: "mail-foundation" };
272
+
273
+ const eventListScreen = {
274
+ id: "event-list",
275
+ type: "entityList",
276
+ entity: "event",
277
+ };
278
+
279
+ function makeHandler() {
280
+ return { name: "task:create", schema: null, handler: () => {} };
281
+ }
282
+
283
+ defineFeature("refs", (r) => {
284
+ r.requires(someFeature.name, "config");
285
+ r.entity("event", eventEntity);
286
+ r.entity("task", { fields: buildFields() });
287
+ r.writeHandler(makeHandler());
288
+ r.streamHandler(chatCompleteHandler);
289
+ r.screen(eventListScreen);
290
+ });
291
+ `;
292
+
293
+ describe("render → parse roundtrip — unresolved references (raw-ref sentinel)", () => {
294
+ const initial = parse(RAW_REF_FEATURE);
295
+
296
+ test("parses requires + both entities + the opaque handler without error, keeping references unresolved", () => {
297
+ expect(initial.patterns).toMatchObject([
298
+ { kind: "requires", featureNames: [{ __raw: "someFeature.name" }, "config"] },
299
+ { kind: "entity", entityName: "event", definition: { __raw: "eventEntity" } },
300
+ { kind: "entity", entityName: "task", definition: { fields: { __raw: "buildFields()" } } },
301
+ { kind: "writeHandler", handlerName: undefined },
302
+ { kind: "streamHandler", handlerName: undefined },
303
+ { kind: "screen", definition: { __raw: "eventListScreen" } },
304
+ ]);
305
+ });
306
+
307
+ test("rendered output re-emits references verbatim, never inlines them", () => {
308
+ const rendered = renderFeatureFile({
309
+ featureName: initial.featureName ?? "",
310
+ patterns: initial.patterns,
311
+ });
312
+ expect(rendered).toContain("someFeature.name");
313
+ expect(rendered).toContain("eventEntity");
314
+ expect(rendered).toContain("buildFields()");
315
+ expect(rendered).toContain("r.writeHandler(makeHandler())");
316
+ expect(rendered).toContain("r.streamHandler(chatCompleteHandler)");
317
+ expect(rendered).toContain("r.screen(eventListScreen);");
318
+ // Would only appear if buildFields()'s return value got inlined.
319
+ expect(rendered).not.toContain("title:");
320
+ expect(rendered).not.toContain("mail-foundation");
321
+ expect(rendered).not.toContain("task:create");
322
+ // Would only appear if the screen ref got resolved/inlined.
323
+ expect(rendered).not.toContain("entityList");
324
+ });
325
+
326
+ test("pattern shape survives a full render → reparse cycle", () => {
327
+ const rendered = renderFeatureFile({
328
+ featureName: initial.featureName ?? "",
329
+ patterns: initial.patterns,
330
+ });
331
+ const reparsed = parse(rendered);
332
+ expect(reparsed.patterns.map(stripLocations)).toEqual(initial.patterns.map(stripLocations));
333
+ });
334
+ });
335
+
240
336
  describe("render idempotence", () => {
241
337
  test("rendered file → parse → render === rendered file", () => {
242
338
  const initial = parse(STATIC_FEATURE);
@@ -285,3 +381,282 @@ describe("renderPattern — single-pattern shape", () => {
285
381
  expect(out).toBe('r.metric({ name: "requests", type: "counter" });');
286
382
  });
287
383
  });
384
+
385
+ // Regression guard for the class of bug the r.exposesApi/r.usesApi fold
386
+ // hit: a registrar-shape change must survive the Designer's parse→render→
387
+ // parse cycle, not just a TS compile of the framework itself. r.hook()'s
388
+ // `{ allOf: entity }` target (replacing r.entityHook) reuses HookPattern's
389
+ // already-generic target field, so this is the cheap case — but proving it
390
+ // beats assuming it.
391
+ const HOOK_ALL_OF_FEATURE = `
392
+ import { defineFeature } from "@cosmicdrift/kumiko-framework/engine";
393
+
394
+ defineFeature("shop", (r) => {
395
+ r.entity("product", { fields: { name: { type: "text" } } });
396
+ r.hook("postSave", { allOf: "product" }, async (result) => {
397
+ console.log(result);
398
+ });
399
+ });
400
+ `;
401
+
402
+ describe("render → parse roundtrip — r.hook({ allOf }) entity-wide target", () => {
403
+ test("allOf target survives parse → render → parse unchanged", () => {
404
+ const initial = parse(HOOK_ALL_OF_FEATURE);
405
+ const rendered = renderFeatureFile({
406
+ featureName: initial.featureName ?? "",
407
+ patterns: initial.patterns,
408
+ });
409
+ const reparsed = parse(rendered);
410
+ expect(reparsed.patterns.map(stripLocations)).toEqual(initial.patterns.map(stripLocations));
411
+
412
+ const hookPattern = reparsed.patterns.find((p) => p.kind === "hook");
413
+ expect(hookPattern?.kind).toBe("hook");
414
+ if (hookPattern?.kind === "hook") {
415
+ expect(hookPattern.target).toEqual({ allOf: "product" });
416
+ }
417
+ });
418
+ });
419
+
420
+ // Regression guard for the class of bug the r.exposesApi/r.usesApi fold
421
+ // hit: a registrar-shape change (there, removing a method; here, adding a
422
+ // nested optional field) must survive the Designer's parse→render→parse
423
+ // cycle, not just a TS compile of the framework itself. r.screen()'s `nav`
424
+ // sugar is a generic nested object on an already-generic pattern (no
425
+ // per-field extractor/renderer), so this is the cheap case — but proving
426
+ // it beats assuming it.
427
+ const SCREEN_WITH_NAV_FEATURE = `
428
+ import { defineFeature } from "@cosmicdrift/kumiko-framework/engine";
429
+
430
+ defineFeature("shop", (r) => {
431
+ r.entity("product", { fields: { name: { type: "text" } } });
432
+ r.screen({
433
+ id: "products",
434
+ type: "entityList",
435
+ entity: "product",
436
+ columns: ["name"],
437
+ nav: { label: "shop:nav.products", icon: "box", order: 5 },
438
+ });
439
+ });
440
+ `;
441
+
442
+ describe("render → parse roundtrip — r.screen({ nav }) inline sugar", () => {
443
+ test("nested nav object survives parse → render → parse unchanged", () => {
444
+ const initial = parse(SCREEN_WITH_NAV_FEATURE);
445
+ const rendered = renderFeatureFile({
446
+ featureName: initial.featureName ?? "",
447
+ patterns: initial.patterns,
448
+ });
449
+ const reparsed = parse(rendered);
450
+ expect(reparsed.patterns.map(stripLocations)).toEqual(initial.patterns.map(stripLocations));
451
+
452
+ const screenPattern = reparsed.patterns.find((p) => p.kind === "screen");
453
+ expect(screenPattern?.kind).toBe("screen");
454
+ if (screenPattern?.kind === "screen") {
455
+ expect(screenPattern.definition).toMatchObject({
456
+ nav: { label: "shop:nav.products", icon: "box", order: 5 },
457
+ });
458
+ }
459
+ });
460
+ });
461
+
462
+ const DEFINE_EVENT_WITH_MIGRATIONS_FEATURE = `
463
+ import { defineFeature } from "@cosmicdrift/kumiko-framework/engine";
464
+ import { z } from "zod";
465
+
466
+ defineFeature("billing", (r) => {
467
+ r.defineEvent("invoicePaid", z.object({ totalCents: z.number() }), {
468
+ version: 2,
469
+ migrations: [
470
+ {
471
+ fromVersion: 1,
472
+ toVersion: 2,
473
+ transform: (payload: unknown) => ({ totalCents: Math.round((payload as { total: number }).total * 100) }),
474
+ },
475
+ ],
476
+ });
477
+ });
478
+ `;
479
+
480
+ describe("render → parse roundtrip — r.defineEvent({ migrations }) fold", () => {
481
+ test("migrations array survives parse → render → parse unchanged", () => {
482
+ const initial = parse(DEFINE_EVENT_WITH_MIGRATIONS_FEATURE);
483
+ const rendered = renderFeatureFile({
484
+ featureName: initial.featureName ?? "",
485
+ patterns: initial.patterns,
486
+ });
487
+ const reparsed = parse(rendered);
488
+ expect(reparsed.patterns.map(stripLocations)).toEqual(initial.patterns.map(stripLocations));
489
+
490
+ const eventPattern = reparsed.patterns.find((p) => p.kind === "defineEvent");
491
+ expect(eventPattern?.kind).toBe("defineEvent");
492
+ if (eventPattern?.kind === "defineEvent") {
493
+ expect(eventPattern.version).toBe(2);
494
+ expect(Object.keys(eventPattern.migrations ?? {})).toEqual(["1"]);
495
+ }
496
+ });
497
+ });
498
+
499
+ // --- Real-compile check ---------------------------------------------------
500
+ //
501
+ // Everything above proves parse(render(patterns)) is structurally faithful.
502
+ // It does NOT prove the rendered code actually compiles against the real
503
+ // FeatureRegistrar type — parse() runs against a bare in-memory Project with
504
+ // no lib/module resolution, so a rendered call can be well-formed AST and
505
+ // still be a type error against the real registrar (e.g. a removed method).
506
+ // That gap let the r.usesApi removal (folded into r.requires({apis})) pass
507
+ // the full 4960-test suite silently; only the visual Designer would have hit
508
+ // the broken shape.
509
+ //
510
+ // This Project resolves `@cosmicdrift/kumiko-framework/*` against the real
511
+ // framework source (unlike parse()'s Project, dependency resolution is NOT
512
+ // skipped), so `r` in a compiled fixture is the real FeatureRegistrar, not a
513
+ // structural stand-in.
514
+ const FRAMEWORK_TSCONFIG_PATH = path.join(import.meta.dir, "../../../../tsconfig.json");
515
+
516
+ const compileProject = new Project({
517
+ tsConfigFilePath: FRAMEWORK_TSCONFIG_PATH,
518
+ skipAddingFilesFromTsConfig: true,
519
+ });
520
+
521
+ let compileCheckCounter = 0;
522
+
523
+ function compileAgainstRegistrar(source: string): readonly string[] {
524
+ compileCheckCounter += 1;
525
+ const filePath = path.join(
526
+ import.meta.dir,
527
+ `__generated__/compile-check-${compileCheckCounter}.gen.ts`,
528
+ );
529
+ const sourceFile = compileProject.createSourceFile(filePath, source, { overwrite: true });
530
+ const diagnostics = sourceFile.getPreEmitDiagnostics().map((d) => {
531
+ const text = ts.flattenDiagnosticMessageText(d.compilerObject.messageText, "\n");
532
+ return `${d.getLineNumber()}: ${text}`;
533
+ });
534
+ sourceFile.forget();
535
+ return diagnostics;
536
+ }
537
+
538
+ function renderAndCompile(source: string): readonly string[] {
539
+ const { featureName, patterns } = parse(source);
540
+ const rendered = renderFeatureFile({ featureName: featureName ?? "", patterns });
541
+ return compileAgainstRegistrar(rendered);
542
+ }
543
+
544
+ describe("render → compiles against the real FeatureRegistrar type", () => {
545
+ test("compile check has teeth: an unknown registrar method is reported", () => {
546
+ const diagnostics = compileAgainstRegistrar(`
547
+ import { defineFeature } from "@cosmicdrift/kumiko-framework/engine";
548
+
549
+ defineFeature("teeth-check", (r) => {
550
+ r.methodThatDoesNotExist({ nope: true });
551
+ });
552
+ `);
553
+ expect(diagnostics.length).toBeGreaterThan(0);
554
+ expect(diagnostics.join("\n")).toContain("methodThatDoesNotExist");
555
+ }, 20_000);
556
+
557
+ test("positive control: a minimal always-matched-the-real-shape fixture compiles clean", () => {
558
+ const diagnostics = compileAgainstRegistrar(`
559
+ import { defineFeature } from "@cosmicdrift/kumiko-framework/engine";
560
+
561
+ defineFeature("teeth-check-positive", (r) => {
562
+ r.systemScope();
563
+ r.describe("Minimal fixture proving the harness returns [] on real success.");
564
+ r.toggleable({ default: true });
565
+ });
566
+ `);
567
+ expect(diagnostics).toEqual([]);
568
+ }, 20_000);
569
+
570
+ test("STATIC_FEATURE's rendered header-data patterns compile clean", () => {
571
+ expect(renderAndCompile(STATIC_FEATURE)).toEqual([]);
572
+ }, 20_000);
573
+
574
+ test("r.defineEvent's rendered migrations array compiles against the real registrar", () => {
575
+ expect(renderAndCompile(DEFINE_EVENT_WITH_MIGRATIONS_FEATURE)).toEqual([]);
576
+ }, 20_000);
577
+ });
578
+
579
+ // One self-contained, compile-clean fixture per remaining pattern kind not
580
+ // already exercised above (STATIC_FEATURE / MIXED_FEATURE / HOOK_ALL_OF /
581
+ // SCREEN_WITH_NAV / DEFINE_EVENT_WITH_MIGRATIONS). Deliberately separate
582
+ // from the parse-roundtrip fixtures above: those were written to test
583
+ // parse/render symmetry, not to be type-correct (e.g. DEFINE_EVENT_WITH_
584
+ // MIGRATIONS_FEATURE uses `z` without importing it) — reusing them here
585
+ // would produce diagnostics unrelated to the registrar shape and defeat the
586
+ // point of an exact-match assertion.
587
+ //
588
+ // RAW_REF_FEATURE and the "unknown" pattern kind are excluded on purpose:
589
+ // raw-ref sentinels reference symbols that don't exist by design, and
590
+ // "unknown" is the parser's catch-all bucket for unrecognized r.calls, not
591
+ // a real user-authored pattern.
592
+ const MANIFEST_AND_CONFIG_FEATURE = `
593
+ import { defineFeature } from "@cosmicdrift/kumiko-framework/engine";
594
+ import { z } from "zod";
595
+
596
+ defineFeature("catalog", (r) => {
597
+ r.systemScope();
598
+ r.describe("Product catalog and pricing.");
599
+ r.optionalRequires("promotions");
600
+ r.uiHints({ displayLabel: "Catalog", category: "Commerce", recommended: true });
601
+ r.readsConfig("auth.smtpHost");
602
+ r.translations({ keys: { en: { title: "Catalog" } } });
603
+ r.useExtension("audit-log", "item");
604
+ r.extendsRegistrar("audit-log", {});
605
+ r.envSchema(z.object({ CATALOG_API_KEY: z.string() }));
606
+ r.usesApi("compliance.forTenant");
607
+ r.exposesApi("catalog.pricingFor");
608
+ });
609
+ `;
610
+
611
+ // r.projection is deliberately excluded here: its `table` field (a Drizzle
612
+ // table reference) is dropped by the feature-ast renderer independent of
613
+ // the object-form/positional-form issue this fixture targets — a
614
+ // pre-existing, separately tracked gap (public-api-registrar-consolidation
615
+ // plan doc, kumiko-platform). multiStreamProjection below covers the
616
+ // `apply`-map shape without hitting it (its `table` is optional).
617
+ const INTEGRATION_FEATURE = `
618
+ import { defineFeature } from "@cosmicdrift/kumiko-framework/engine";
619
+
620
+ defineFeature("fulfillment", (r) => {
621
+ r.job("reconcile-counts", { trigger: { manual: true } }, async (payload, context) => {
622
+ console.log(payload, context);
623
+ });
624
+
625
+ r.notification("itemLowStock", {
626
+ trigger: { on: "item:lowStock" },
627
+ recipient: () => null,
628
+ data: () => ({}),
629
+ });
630
+
631
+ r.authClaims(async () => ({}));
632
+
633
+ r.httpRoute({
634
+ method: "GET",
635
+ path: "/fulfillment/feed.xml",
636
+ handler: (c) => c.text("ok"),
637
+ });
638
+
639
+ r.multiStreamProjection({
640
+ name: "item-audit",
641
+ apply: {
642
+ "item.created": async (event, tx, ctx) => {
643
+ console.log(event, tx, ctx);
644
+ },
645
+ },
646
+ });
647
+
648
+ r.workspace({ id: "ops", label: "fulfillment:workspace.ops" });
649
+
650
+ r.treeActions({ list: {} });
651
+ });
652
+ `;
653
+
654
+ describe("render → compiles against the real FeatureRegistrar type — full pattern-kind coverage", () => {
655
+ test("manifest/config-only patterns compile clean", () => {
656
+ expect(renderAndCompile(MANIFEST_AND_CONFIG_FEATURE)).toEqual([]);
657
+ }, 20_000);
658
+
659
+ test("job/notification/httpRoute/projection/workspace patterns compile clean", () => {
660
+ expect(renderAndCompile(INTEGRATION_FEATURE)).toEqual([]);
661
+ }, 20_000);
662
+ });