@cosmicdrift/kumiko-framework 0.386.0 → 0.387.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 (288) hide show
  1. package/LICENSE +21 -57
  2. package/README.md +2 -2
  3. package/agents/widgets.md +39 -39
  4. package/dist/api/api-constants.js +2 -2
  5. package/dist/api/auth-middleware.js +7 -7
  6. package/dist/api/auth-rate-limiters.js +7 -3
  7. package/dist/api/auth-routes-mfa.js +1 -1
  8. package/dist/api/auth-routes-session.js +1 -1
  9. package/dist/api/auth-routes-shared.js +7 -3
  10. package/dist/api/auth-routes-signup.js +1 -1
  11. package/dist/api/client-ip.js +3 -1
  12. package/dist/api/extra-route.js +1 -1
  13. package/dist/api/pii-leak-guard.js +4 -2
  14. package/dist/api/readiness.js +5 -5
  15. package/dist/api/redis-sse-broker.js +8 -6
  16. package/dist/api/routes.js +2 -2
  17. package/dist/api/server.js +34 -33
  18. package/dist/api/sse-broker.js +1 -1
  19. package/dist/api/sse-route.d.ts +13 -13
  20. package/dist/api/sse-route.js +15 -15
  21. package/dist/auth/index.js +4 -4
  22. package/dist/auth/roles.d.ts +4 -4
  23. package/dist/auth/roles.js +24 -24
  24. package/dist/compliance/duration-spec.js +18 -20
  25. package/dist/compliance/index.js +2 -3
  26. package/dist/compliance/override-schema.d.ts +4 -4
  27. package/dist/compliance/override-schema.js +19 -22
  28. package/dist/compliance/profiles.d.ts +26 -29
  29. package/dist/compliance/profiles.js +62 -69
  30. package/dist/compliance/sub-processors.d.ts +28 -30
  31. package/dist/compliance/sub-processors.js +17 -21
  32. package/dist/consumer-cli.js +4 -4
  33. package/dist/crypto/blind-index.js +18 -17
  34. package/dist/crypto/ciphertext-pattern.js +1 -1
  35. package/dist/crypto/event-pii.js +3 -3
  36. package/dist/crypto/kek-source.d.ts +1 -1
  37. package/dist/crypto/kek-source.js +3 -2
  38. package/dist/crypto/kms-adapter.d.ts +1 -1
  39. package/dist/crypto/kms-adapter.js +4 -6
  40. package/dist/crypto/kms-wiring.d.ts +1 -2
  41. package/dist/crypto/kms-wiring.js +2 -2
  42. package/dist/crypto/pg-kms-adapter.js +2 -6
  43. package/dist/crypto/pii-field-encryption.js +4 -4
  44. package/dist/crypto/subject-resolver.d.ts +1 -1
  45. package/dist/crypto/subject-resolver.js +2 -2
  46. package/dist/db/apply-entity-event.d.ts +6 -6
  47. package/dist/db/apply-entity-event.js +55 -55
  48. package/dist/db/blind-index-cleanup.js +7 -7
  49. package/dist/db/collect-table-metas.js +10 -11
  50. package/dist/db/compound-types.d.ts +1 -1
  51. package/dist/db/compound-types.js +12 -12
  52. package/dist/db/cursor.js +3 -4
  53. package/dist/db/dialect.d.ts +2 -2
  54. package/dist/db/dialect.js +2 -2
  55. package/dist/db/eagerload.d.ts +3 -3
  56. package/dist/db/eagerload.js +21 -12
  57. package/dist/db/entity-table-meta.d.ts +2 -2
  58. package/dist/db/entity-table-meta.js +4 -4
  59. package/dist/db/event-store-executor-context.d.ts +1 -1
  60. package/dist/db/event-store-executor-context.js +13 -13
  61. package/dist/db/event-store-executor-read.js +27 -28
  62. package/dist/db/event-store-executor-write.js +65 -70
  63. package/dist/db/located-timestamp.d.ts +11 -11
  64. package/dist/db/located-timestamp.js +29 -30
  65. package/dist/db/migrate-generator.d.ts +1 -1
  66. package/dist/db/migrate-generator.js +26 -19
  67. package/dist/db/migrate-runner.js +25 -25
  68. package/dist/db/money.d.ts +6 -6
  69. package/dist/db/money.js +29 -27
  70. package/dist/db/queries/backfill-pii.js +5 -5
  71. package/dist/db/queries/ddl.js +1 -1
  72. package/dist/db/queries/es-ops.d.ts +1 -1
  73. package/dist/db/queries/es-ops.js +1 -1
  74. package/dist/db/queries/event-consumer.js +3 -3
  75. package/dist/db/queries/event-store.js +4 -2
  76. package/dist/db/queries/projection-rebuild.js +3 -3
  77. package/dist/db/queries/raw-sql.d.ts +2 -2
  78. package/dist/db/queries/raw-sql.js +2 -2
  79. package/dist/db/queries/shadow-swap.js +19 -19
  80. package/dist/db/query.d.ts +1 -1
  81. package/dist/db/query.js +6 -6
  82. package/dist/db/rebuild-marker.js +20 -21
  83. package/dist/db/replay-migration-sql.js +2 -2
  84. package/dist/db/schema-inspection.js +4 -5
  85. package/dist/db/table-builder.d.ts +1 -2
  86. package/dist/db/table-builder.js +82 -82
  87. package/dist/db/tenant-db.d.ts +2 -2
  88. package/dist/db/tenant-db.js +9 -2
  89. package/dist/derivatives/delete-stored-file.js +5 -2
  90. package/dist/derivatives/derivatives-context.js +1 -1
  91. package/dist/engine/boot-validator/access-roles.js +4 -3
  92. package/dist/engine/boot-validator/api-ext.js +14 -14
  93. package/dist/engine/boot-validator/config-deps.js +7 -6
  94. package/dist/engine/boot-validator/detail-screens.js +3 -3
  95. package/dist/engine/boot-validator/entity-handler.js +60 -61
  96. package/dist/engine/boot-validator/gdpr-storage.js +4 -4
  97. package/dist/engine/boot-validator/i18n-keys.js +1 -1
  98. package/dist/engine/boot-validator/index.d.ts +2 -2
  99. package/dist/engine/boot-validator/index.js +20 -20
  100. package/dist/engine/boot-validator/nav.js +5 -5
  101. package/dist/engine/boot-validator/ownership.js +12 -9
  102. package/dist/engine/boot-validator/parent-ref.js +1 -1
  103. package/dist/engine/boot-validator/pii-retention.js +50 -57
  104. package/dist/engine/boot-validator/projection-list-screens.js +7 -7
  105. package/dist/engine/boot-validator/query-refs.js +1 -1
  106. package/dist/engine/boot-validator/screens-actions.js +15 -16
  107. package/dist/engine/boot-validator/screens-forms.js +10 -11
  108. package/dist/engine/boot-validator/screens-lists.js +14 -15
  109. package/dist/engine/boot-validator/screens.js +34 -40
  110. package/dist/engine/boot-validator/security-baseline.js +3 -2
  111. package/dist/engine/boot-validator/transfer-graph.js +2 -2
  112. package/dist/engine/boot-validator/workspaces.js +3 -3
  113. package/dist/engine/bridge-stub.js +3 -4
  114. package/dist/engine/build-app-schema.js +75 -75
  115. package/dist/engine/build-config-feature-schema.js +50 -50
  116. package/dist/engine/build-target.js +20 -23
  117. package/dist/engine/codemod/pipeline-codemod.js +20 -13
  118. package/dist/engine/config-helpers.js +4 -4
  119. package/dist/engine/constants.js +2 -2
  120. package/dist/engine/create-app.js +2 -2
  121. package/dist/engine/define-feature.js +12 -11
  122. package/dist/engine/define-handler.js +12 -11
  123. package/dist/engine/define-step.js +1 -1
  124. package/dist/engine/define-workflow.d.ts +5 -5
  125. package/dist/engine/define-workflow.js +6 -6
  126. package/dist/engine/entity-handlers.js +13 -14
  127. package/dist/engine/event-def.js +2 -2
  128. package/dist/engine/extension-names.d.ts +16 -17
  129. package/dist/engine/extension-names.js +37 -38
  130. package/dist/engine/extensions/escape-hatch-usage.js +1 -1
  131. package/dist/engine/extensions/tenant-data.js +2 -2
  132. package/dist/engine/extensions/user-data.d.ts +23 -24
  133. package/dist/engine/factories.d.ts +14 -13
  134. package/dist/engine/factories.js +38 -37
  135. package/dist/engine/feature-ast/entity-field-types.js +1 -1
  136. package/dist/engine/feature-ast/extractors/handlers.js +1 -1
  137. package/dist/engine/feature-ast/extractors/hooks.js +1 -1
  138. package/dist/engine/feature-ast/extractors/shared.d.ts +2 -3
  139. package/dist/engine/feature-ast/extractors/shared.js +2 -3
  140. package/dist/engine/feature-ast/parse.js +13 -13
  141. package/dist/engine/feature-ast/patch.js +1 -1
  142. package/dist/engine/feature-ast/pattern-change-schema.js +1 -1
  143. package/dist/engine/feature-ast/patterns.d.ts +2 -2
  144. package/dist/engine/feature-ast/render.js +2 -2
  145. package/dist/engine/feature-config-events-jobs.js +15 -12
  146. package/dist/engine/feature-entity-handlers.js +9 -5
  147. package/dist/engine/feature-manifest.d.ts +9 -9
  148. package/dist/engine/feature-manifest.js +6 -7
  149. package/dist/engine/feature-ui-extensions.d.ts +3 -3
  150. package/dist/engine/feature-ui-extensions.js +30 -22
  151. package/dist/engine/field-access.js +5 -6
  152. package/dist/engine/index.d.ts +1 -0
  153. package/dist/engine/index.js +4 -4
  154. package/dist/engine/object-form.d.ts +1 -0
  155. package/dist/engine/object-form.js +14 -4
  156. package/dist/engine/ownership.js +3 -3
  157. package/dist/engine/parse-ref-target.js +5 -7
  158. package/dist/engine/pattern-library/index.js +2 -2
  159. package/dist/engine/pattern-library/library.js +2 -2
  160. package/dist/engine/pattern-library/types.js +3 -3
  161. package/dist/engine/pipeline.js +2 -2
  162. package/dist/engine/project-app-schema-for-roles.js +1 -1
  163. package/dist/engine/projection-helpers.js +9 -9
  164. package/dist/engine/qualified-name.js +2 -2
  165. package/dist/engine/registry-facade.js +1 -1
  166. package/dist/engine/registry-ingest.js +12 -12
  167. package/dist/engine/registry-state.js +17 -19
  168. package/dist/engine/registry-validate.js +12 -12
  169. package/dist/engine/run-in.js +2 -2
  170. package/dist/engine/run-pipeline.js +7 -0
  171. package/dist/engine/schema-builder.js +40 -38
  172. package/dist/engine/screen-filter-ops.js +17 -20
  173. package/dist/engine/screen-helpers.js +4 -3
  174. package/dist/engine/state-machine.d.ts +12 -12
  175. package/dist/engine/state-machine.js +7 -7
  176. package/dist/engine/steps/_resolver-utils.js +4 -3
  177. package/dist/engine/steps/for-each.js +4 -4
  178. package/dist/engine/steps/unsafe-projection-delete.js +1 -1
  179. package/dist/engine/steps/unsafe-projection-upsert.js +4 -4
  180. package/dist/engine/steps/wait-for-event.js +4 -4
  181. package/dist/engine/steps/workflow-system-events.js +3 -3
  182. package/dist/engine/tier-resolver-extension.d.ts +29 -27
  183. package/dist/engine/tier-resolver-extension.js +26 -26
  184. package/dist/engine/transfer-adjacency.js +2 -2
  185. package/dist/engine/validate-projection-allowlist.js +7 -27
  186. package/dist/engine/walk-step-instances.d.ts +2 -0
  187. package/dist/engine/walk-step-instances.js +38 -0
  188. package/dist/engine/where-rule-lint.js +1 -1
  189. package/dist/engine/write-handler-qn-extract.js +1 -1
  190. package/dist/entrypoint/index.js +3 -3
  191. package/dist/env/index.d.ts +7 -6
  192. package/dist/env/index.js +10 -9
  193. package/dist/errors/transition-details.js +7 -7
  194. package/dist/errors/write-error-info.d.ts +6 -6
  195. package/dist/errors/write-error-info.js +6 -6
  196. package/dist/es-ops/context.d.ts +9 -9
  197. package/dist/es-ops/context.js +28 -28
  198. package/dist/es-ops/index.js +7 -9
  199. package/dist/es-ops/operations-schema.js +4 -10
  200. package/dist/es-ops/runner.d.ts +11 -11
  201. package/dist/es-ops/runner.js +49 -53
  202. package/dist/es-ops/types.d.ts +55 -55
  203. package/dist/es-ops/types.js +11 -11
  204. package/dist/event-store/admin-api.js +6 -7
  205. package/dist/event-store/errors.js +1 -1
  206. package/dist/event-store/event-store.js +2 -2
  207. package/dist/event-store/rebuild-dead-letter.js +1 -1
  208. package/dist/files/feature.js +9 -10
  209. package/dist/files/file-handle.js +5 -6
  210. package/dist/files/file-ref-entity.js +15 -15
  211. package/dist/files/file-ref-table.js +7 -8
  212. package/dist/files/file-routes.d.ts +7 -0
  213. package/dist/files/file-routes.js +11 -5
  214. package/dist/files/in-memory-provider.js +8 -9
  215. package/dist/files/local-provider.js +18 -25
  216. package/dist/files/provider-resolver.d.ts +7 -7
  217. package/dist/files/storage-tracking.js +2 -2
  218. package/dist/files/zip-stream.d.ts +12 -19
  219. package/dist/files/zip-stream.js +44 -63
  220. package/dist/i18n/required-surface-keys.d.ts +1 -1
  221. package/dist/i18n/required-surface-keys.js +8 -8
  222. package/dist/jobs/job-runner-helpers.js +8 -2
  223. package/dist/jobs/job-runner-schedulers.d.ts +1 -1
  224. package/dist/jobs/job-runner-schedulers.js +3 -4
  225. package/dist/jobs/job-runner.js +13 -15
  226. package/dist/lifecycle/lifecycle.js +3 -5
  227. package/dist/lifecycle/signal-handlers.js +5 -4
  228. package/dist/logging/utils.d.ts +2 -1
  229. package/dist/logging/utils.js +38 -10
  230. package/dist/migrations/index.js +1 -1
  231. package/dist/migrations/kumiko-drift.js +14 -13
  232. package/dist/migrations/pending-rebuilds.d.ts +21 -20
  233. package/dist/migrations/pending-rebuilds.js +27 -27
  234. package/dist/migrations/projection-table-index.d.ts +3 -3
  235. package/dist/migrations/projection-table-index.js +8 -8
  236. package/dist/observability/metric-validator.js +1 -1
  237. package/dist/observability/metrics-handle.js +3 -3
  238. package/dist/pipeline/append-event-core.js +11 -2
  239. package/dist/pipeline/cascade-handler.d.ts +1 -1
  240. package/dist/pipeline/dispatch-batch.js +2 -2
  241. package/dist/pipeline/dispatch-query.js +10 -10
  242. package/dist/pipeline/dispatch-shared.d.ts +1 -0
  243. package/dist/pipeline/dispatch-shared.js +15 -17
  244. package/dist/pipeline/dispatch-stream.js +1 -1
  245. package/dist/pipeline/dispatch-write.js +3 -3
  246. package/dist/pipeline/dispatcher-utils.d.ts +1 -1
  247. package/dist/pipeline/dispatcher-utils.js +1 -1
  248. package/dist/pipeline/event-consumer-state.js +2 -2
  249. package/dist/pipeline/event-dispatcher-delivery.js +1 -1
  250. package/dist/pipeline/event-dispatcher.js +17 -28
  251. package/dist/pipeline/irreversible-operation-gate.js +1 -1
  252. package/dist/pipeline/lifecycle-pipeline.js +9 -9
  253. package/dist/pipeline/member-read-only-transaction.js +1 -3
  254. package/dist/pipeline/msp-rebuild.js +1 -1
  255. package/dist/pipeline/projection-rebuild.js +13 -12
  256. package/dist/pipeline/system-hooks.js +39 -41
  257. package/dist/pipeline/system-identity-switch.js +1 -3
  258. package/dist/pipeline/tenant-timezone-cache.js +1 -1
  259. package/dist/random/generate.d.ts +29 -29
  260. package/dist/random/generate.js +30 -30
  261. package/dist/random/words.js +20 -20
  262. package/dist/rate-limit/middleware.js +9 -5
  263. package/dist/redis/client.js +2 -2
  264. package/dist/redis/pubsub-signal.js +14 -17
  265. package/dist/schema-cli.js +116 -22
  266. package/dist/search/index.js +4 -4
  267. package/dist/search/purge-subject.js +4 -5
  268. package/dist/search/reindex-entity.js +6 -9
  269. package/dist/time/boot-tz-warning.d.ts +2 -2
  270. package/dist/time/boot-tz-warning.js +8 -8
  271. package/dist/time/iana.js +10 -10
  272. package/dist/time/index.js +9 -9
  273. package/dist/time/legacy-date.d.ts +2 -2
  274. package/dist/time/legacy-date.js +6 -8
  275. package/dist/time/polyfill.js +1 -1
  276. package/dist/time/tz-context.d.ts +1 -1
  277. package/dist/time/tz-context.js +1 -1
  278. package/dist/ui-types/app-schema.js +7 -7
  279. package/dist/ui-types/list-row-meta.js +4 -4
  280. package/dist/upgrade-cli.js +10 -9
  281. package/dist/utils/compare.js +1 -1
  282. package/package.json +4 -4
  283. package/src/changes.json +48 -0
  284. package/src/scripts/codemod/crypto-shredding-testing-move.ts +2 -2
  285. package/src/scripts/codemod/migrate-cross-tenant.ts +1 -1
  286. package/src/scripts/codemod/migrate-open-to-all.ts +1 -1
  287. package/src/scripts/codemod/pii-personal-migration.ts +17 -8
  288. package/src/scripts/codemod/unprocessable-error-details-reason.ts +2 -2
@@ -8,14 +8,14 @@ import type { UserDataExtensionOptions } from "./extensions/user-data.ts";
8
8
  import type { AssignableFromRole } from "./role-assignment.ts";
9
9
  import { TENANT_TIER_RESOLVER_EXT, type TierResolverPlugin } from "./tier-resolver-extension.ts";
10
10
  /**
11
- * `userData` — User-Daten-Rights-Hooks (DSGVO Art. 15 + 17 + 20).
11
+ * `userData` — user-data rights hooks (GDPR Articles 15, 17, and 20).
12
12
  *
13
- * Erwartete Hook-Methoden:
13
+ * Expected hook methods:
14
14
  * - `export(userId, ctx) => Promise<UserDataExport>`
15
15
  * - `delete(userId, strategy: "delete" | "anonymize", ctx) => Promise<void>`
16
16
  *
17
- * Registriert von: `user-data-rights` (Sprint 2).
18
- * Genutzt von: jedes Feature mit User-Referenzen (tasks, comments, files, ...).
17
+ * Registered by: `user-data-rights`.
18
+ * Used by: every feature with user references (tasks, comments, files, ...).
19
19
  */
20
20
  export declare const EXT_USER_DATA: "userData";
21
21
  export declare const EXT_USER_DATA_ORDER: {
@@ -41,17 +41,16 @@ export declare const EXT_TENANT_DATA: "tenantData";
41
41
  */
42
42
  export declare const EXT_STORAGE_PROVIDER: "storageProvider";
43
43
  /**
44
- * `fileProvider` — File-Storage-Provider-Plugin-Selection (file-foundation).
44
+ * `fileProvider` — file-storage provider plugin selection (file-foundation).
45
45
  *
46
- * Provider-Features (file-provider-s3, -inmemory, -s3-env) registrieren eine
47
- * Implementierung via `r.useExtension(EXT_FILE_PROVIDER, "<name>", { build })`;
48
- * der per-Tenant Config-Key `provider` waehlt zur Runtime eine aus. Der
49
- * Framework-Resolver (`createFileProviderForTenant`) liest das, damit Upload-
50
- * Routes, `ctx.files` UND die DSGVO-Jobs denselben Store treffen.
46
+ * Provider features (file-provider-s3, -inmemory, -s3-env) register an
47
+ * implementation via `r.useExtension(EXT_FILE_PROVIDER, "<name>", { build })`;
48
+ * the per-tenant config key `provider` selects one at runtime. The framework
49
+ * resolver (`createFileProviderForTenant`) reads it so upload routes,
50
+ * `ctx.files`, and GDPR jobs all use the same store.
51
51
  *
52
- * Framework-seitig besessen, damit kein String-Drift entsteht — file-
53
- * foundation MUSS Extension-Point + Config-Key unter genau diesen Namen
54
- * registrieren.
52
+ * The framework owns this contract to prevent string drift — file-foundation
53
+ * MUST register the extension point and config key under exactly these names.
55
54
  */
56
55
  export declare const EXT_FILE_PROVIDER: "fileProvider";
57
56
  export declare const FILE_PROVIDER_CONFIG_KEY: "file-foundation:config:provider";
@@ -85,7 +84,7 @@ export declare const EXT_DERIVATIVE_RENDERER: "derivativeRenderer";
85
84
  * serves nothing for that entityType, not even a 403 (404, so existence isn't
86
85
  * confirmed to an unauthorised caller).
87
86
  *
88
- * Registered/consumed by: `file-derivatives`' public variant route (#1951).
87
+ * Registered/consumed by: `file-derivatives`' public variant route.
89
88
  */
90
89
  export declare const EXT_DERIVATIVE_PUBLIC_PREDICATE: "derivativePublicPredicate";
91
90
  /**
@@ -150,9 +149,9 @@ export declare const EXT_TENANT_LIFECYCLE_STATUS: "tenantLifecycleStatus";
150
149
  export declare const EXT_ASSIGNABLE_ROLE: "assignableRole";
151
150
  export declare const TENANT_MEMBERSHIPS_QUERY: "tenant:query:memberships";
152
151
  /**
153
- * Union aller standardisierten Extension-Namen der Datenschutz-Surface.
154
- * Nicht alle Extensions im System sind in dieser Liste — andere
155
- * Features koennen weiterhin eigene Extension-Namen registrieren.
152
+ * Union of standardized extension names for the privacy surface.
153
+ * Not every extension in the system is included — other features can still
154
+ * register their own extension names.
156
155
  */
157
156
  export type KumikoExtensionName = typeof EXT_USER_DATA | typeof EXT_TENANT_DATA | typeof EXT_STORAGE_PROVIDER | typeof EXT_SEARCH_ADAPTER | typeof EXT_EXTERNAL_RESOURCE | typeof EXT_INFRA_RESOURCE | typeof EXT_FILE_PROVIDER | typeof EXT_DERIVATIVE_RENDERER | typeof EXT_DERIVATIVE_PUBLIC_PREDICATE | typeof EXT_DERIVATIVE_OVERLAY_RESOLVER | typeof EXT_PRINCIPAL_STATUS | typeof EXT_TENANT_LIFECYCLE_STATUS | typeof EXT_ASSIGNABLE_ROLE;
158
157
  /** The four `destroyTenant(tenantId, ctx)`-only resource-cleanup extension points. */
@@ -1,42 +1,42 @@
1
1
  import { TENANT_TIER_RESOLVER_EXT } from "./tier-resolver-extension.js";
2
- // Standardisierte Extension-Namen fuer Datenschutz-Hook-Achsen.
2
+ // Standardized extension names for privacy-hook axes.
3
3
  //
4
- // Features registrieren Extensions via:
4
+ // Features register extensions via:
5
5
  // r.extendsRegistrar(EXT_USER_DATA, { hooks: { ... } });
6
6
  //
7
- // Andere Features haengen sich ein via:
7
+ // Other features attach to them via:
8
8
  // r.useExtension(EXT_USER_DATA, "myEntity", { ...hookImpls });
9
9
  //
10
- // Hintergrund: Magic-Strings driften zwischen Bundled-Features (Beispiel:
11
- // text-content nutzt "Admin" als Rolle, tenant-handler nutzt "TenantAdmin").
12
- // Constants sind die einzige Quelle der Wahrheit; String-Literale werden
13
- // in den Sprint-Touchpoints schrittweise ersetzt. Boot-Validator
14
- // (validateExtensionUsages) checkt dass jedes useExtension einen
15
- // passenden extendsRegistrar findet — Tippfehler in Constants →
16
- // Compile-Time-Fail.
10
+ // Background: magic strings drift between bundled features (for example,
11
+ // text-content uses "Admin" as a role, while tenant-handler uses
12
+ // "TenantAdmin"). Constants are the single source of truth; string literals
13
+ // are gradually replaced at the relevant integration points. The boot
14
+ // validator (validateExtensionUsages) checks that every useExtension has a
15
+ // matching extendsRegistrar, so typos in constants cause a compile-time
16
+ // failure.
17
17
  //
18
- // Hook-Signaturen + Boot-Validation pro Extension-Achse kommen mit dem
19
- // jeweiligen registrierenden Sprint:
20
- // userData / tenantData → Sprint 2 (user-data-rights, retention)
21
- // storageProvider → Sprint 4 (storage-encryption)
22
- // searchAdapter / external / → Sprint 5 (tenant-lifecycle)
18
+ // Hook signatures and boot validation for each extension axis are added by
19
+ // the feature that registers that axis:
20
+ // userData / tenantData → (user-data-rights, retention)
21
+ // storageProvider → (storage-encryption)
22
+ // searchAdapter / external / → (tenant-lifecycle)
23
23
  // infraResource
24
24
  /**
25
- * `userData` — User-Daten-Rights-Hooks (DSGVO Art. 15 + 17 + 20).
25
+ * `userData` — user-data rights hooks (GDPR Articles 15, 17, and 20).
26
26
  *
27
- * Erwartete Hook-Methoden:
27
+ * Expected hook methods:
28
28
  * - `export(userId, ctx) => Promise<UserDataExport>`
29
29
  * - `delete(userId, strategy: "delete" | "anonymize", ctx) => Promise<void>`
30
30
  *
31
- * Registriert von: `user-data-rights` (Sprint 2).
32
- * Genutzt von: jedes Feature mit User-Referenzen (tasks, comments, files, ...).
31
+ * Registered by: `user-data-rights`.
32
+ * Used by: every feature with user references (tasks, comments, files, ...).
33
33
  */
34
34
  export const EXT_USER_DATA = "userData";
35
- // Order-Bänder für EXT_USER_DATA-Hooks (forget-Pipeline). Der Kontrakt war
36
- // implizit über zwei Packages verteilt (-100 in custom-fields, 0 in
37
- // user-data-rights) — ein Host-Hook mit order < REDACT_BEFORE_OWNER liefe
38
- // VOR den Redaktoren und brächte den Strip-nach-owner-null-Bug zurück
39
- // (DSGVO-Art.-17-Regression). Regel: Redaktoren < 0 <= owner-mutierende Hooks.
35
+ // Ordering bands for EXT_USER_DATA hooks (forget pipeline). The contract was
36
+ // implicit across two packages (-100 in custom-fields, 0 in
37
+ // user-data-rights), so a host hook with order < REDACT_BEFORE_OWNER would run
38
+ // BEFORE the redactors and reintroduce the strip-after-owner-null bug
39
+ // (GDPR Article 17 regression). Rule: redactors < 0 <= owner-mutating hooks.
40
40
  export const EXT_USER_DATA_ORDER = {
41
41
  REDACT_BEFORE_OWNER: -100,
42
42
  DEFAULT: 0,
@@ -60,23 +60,22 @@ export const EXT_TENANT_DATA = "tenantData";
60
60
  */
61
61
  export const EXT_STORAGE_PROVIDER = "storageProvider";
62
62
  /**
63
- * `fileProvider` — File-Storage-Provider-Plugin-Selection (file-foundation).
63
+ * `fileProvider` — file-storage provider plugin selection (file-foundation).
64
64
  *
65
- * Provider-Features (file-provider-s3, -inmemory, -s3-env) registrieren eine
66
- * Implementierung via `r.useExtension(EXT_FILE_PROVIDER, "<name>", { build })`;
67
- * der per-Tenant Config-Key `provider` waehlt zur Runtime eine aus. Der
68
- * Framework-Resolver (`createFileProviderForTenant`) liest das, damit Upload-
69
- * Routes, `ctx.files` UND die DSGVO-Jobs denselben Store treffen.
65
+ * Provider features (file-provider-s3, -inmemory, -s3-env) register an
66
+ * implementation via `r.useExtension(EXT_FILE_PROVIDER, "<name>", { build })`;
67
+ * the per-tenant config key `provider` selects one at runtime. The framework
68
+ * resolver (`createFileProviderForTenant`) reads it so upload routes,
69
+ * `ctx.files`, and GDPR jobs all use the same store.
70
70
  *
71
- * Framework-seitig besessen, damit kein String-Drift entsteht — file-
72
- * foundation MUSS Extension-Point + Config-Key unter genau diesen Namen
73
- * registrieren.
71
+ * The framework owns this contract to prevent string drift — file-foundation
72
+ * MUST register the extension point and config key under exactly these names.
74
73
  */
75
74
  export const EXT_FILE_PROVIDER = "fileProvider";
76
- // Qualifizierter Config-Key, den das file-foundation-Feature registriert
77
- // (Format `<feature>:config:<key>`). Akzeptierte Kopplung: der Framework-
78
- // Resolver liegt UNTER dem Feature und liest den Key per String. Umbenennen
79
- // des file-foundation-Features MUSS diese Konstante mitziehen.
75
+ // Qualified config key registered by the file-foundation feature
76
+ // (format `<feature>:config:<key>`). This coupling is intentional: the
77
+ // framework resolver is below the feature and reads the key by string. Renaming
78
+ // the file-foundation feature MUST be accompanied by changing this constant.
80
79
  export const FILE_PROVIDER_CONFIG_KEY = "file-foundation:config:provider";
81
80
  // Two roles: boot gate (validateBoot requires its presence once file/image
82
81
  // fields are in use) AND the ENV source of the config key above, bridged via
@@ -114,7 +113,7 @@ export const EXT_DERIVATIVE_RENDERER = "derivativeRenderer";
114
113
  * serves nothing for that entityType, not even a 403 (404, so existence isn't
115
114
  * confirmed to an unauthorised caller).
116
115
  *
117
- * Registered/consumed by: `file-derivatives`' public variant route (#1951).
116
+ * Registered/consumed by: `file-derivatives`' public variant route.
118
117
  */
119
118
  export const EXT_DERIVATIVE_PUBLIC_PREDICATE = "derivativePublicPredicate";
120
119
  /**
@@ -1,4 +1,4 @@
1
- // fw#2914 — reads the { escapeHatch: { reason } } convention off a
1
+ // reads the { escapeHatch: { reason } } convention off a
2
2
  // `r.useExtension(...)` registration's untyped options bag. Registration-time
3
3
  // validation (feature-ui-extensions.ts's useExtension) already rejects an
4
4
  // empty reason, but options stays `Record<string, unknown>`, so orchestrators
@@ -1,7 +1,7 @@
1
- // Hook-Signatur-Types für EXT_TENANT_DATA (DSGVO tenant-scoped destroy).
1
+ // Hook signature types for EXT_TENANT_DATA (GDPR tenant-scoped destruction).
2
2
  //
3
3
  // Mirror of engine/extensions/user-data.ts at tenant granularity.
4
- // tenant-lifecycle orchestrates destroy via registry.getExtensionUsages(EXT_TENANT_DATA).
4
+ // tenant-lifecycle orchestrates destruction via registry.getExtensionUsages(EXT_TENANT_DATA).
5
5
  export function isTenantDataExtensionHooks(o) {
6
6
  return typeof o === "object" && o !== null && "destroy" in o && typeof o.destroy === "function";
7
7
  }
@@ -2,15 +2,15 @@ import type { TenantDb } from "../../db/tenant-db.ts";
2
2
  import type { Registry, TenantId } from "../types/index.ts";
3
3
  type UserId = string;
4
4
  /**
5
- * Strategie für den Forget-Pfad pro Entity:
6
- * - "delete": Row physisch entfernen (Profil, Eigene Notizen, Sessions).
7
- * - "anonymize": User-Reference auf null + Display-Felder auf
8
- * "[Geloescht]" — typisch für geteilte Daten (Tasks,
9
- * Comments) damit andere User die History nicht verlieren.
5
+ * Strategy for the forget path per entity:
6
+ * - "delete": Physically remove the row (profile, personal notes, sessions).
7
+ * - "anonymize": Set the user reference to null and display fields to
8
+ * "[Geloescht]" — typical for shared data (tasks,
9
+ * comments) so other users do not lose the history.
10
10
  *
11
- * Cleanup-Job (Sprint 2 data-retention) entscheidet pro Entity über
12
- * Retention-Policy, welche Strategie greift. blockDelete-Entries lösen
13
- * IMMER `anonymize` aus damit Aufbewahrungs-Pflicht respektiert wird.
11
+ * The cleanup job applies the retention policy per entity to select the
12
+ * strategy. blockDelete entries ALWAYS use `anonymize` to respect retention
13
+ * obligations.
14
14
  */
15
15
  export type UserDataDeleteStrategy = "delete" | "anonymize";
16
16
  /**
@@ -27,7 +27,7 @@ export type UserDataDeleteStrategy = "delete" | "anonymize";
27
27
  */
28
28
  export type TenantUserModel = "single-user" | "multi-user";
29
29
  /**
30
- * fw#2914 — `db` is a tenant-filtered `TenantDb`, bound to `tenantId`
30
+ * `db` is a tenant-filtered `TenantDb`, bound to `tenantId`
31
31
  * (or the per-user sub-tx in the forget path). Unfiltered access needs
32
32
  * `escapeHatch: { reason }` on the `r.useExtension(...)` registration,
33
33
  * then `ctx.db.unsafeRaw()`.
@@ -82,15 +82,15 @@ export interface UserDataHookCtx {
82
82
  readonly userEmailBeforeDelete?: string | null;
83
83
  }
84
84
  /**
85
- * Pro Feature/Entity-Snippet das im Export-Bundle landet. Sprint 2
86
- * orchestriert die JSON-Serialisierung; Hooks geben Plain-Records.
85
+ * Feature/entity snippet included in the export bundle. The export job
86
+ * orchestrates JSON serialization; hooks return plain records.
87
87
  */
88
88
  export interface UserDataExportSnippet {
89
89
  readonly entity: string;
90
90
  readonly rows: ReadonlyArray<Record<string, unknown>>;
91
91
  /**
92
- * Optional: signed-URLs für File-Refs. user-data-rights packt sie
93
- * separat ins ZIP unter `files/`. Andere Hooks lassen das leer.
92
+ * Optional signed URLs for file references. user-data-rights puts them
93
+ * separately in the ZIP under `files/`. Other hooks leave this empty.
94
94
  */
95
95
  readonly fileRefs?: ReadonlyArray<{
96
96
  readonly fileRefId: string;
@@ -99,22 +99,21 @@ export interface UserDataExportSnippet {
99
99
  }>;
100
100
  }
101
101
  /**
102
- * Export-Hook: Sammelt alle Daten einer Entity die zu einem User
103
- * gehören. Wird im Daten-Export-Job pro registrierter Entity einmal
104
- * aufgerufen. Idempotent — kann mehrfach aufgerufen werden ohne
105
- * Side-Effects.
102
+ * Export hook: collects all data belonging to a user for an entity. It is
103
+ * called once per registered entity by the data export job. Idempotent — it
104
+ * can be called multiple times without side effects.
106
105
  *
107
- * Sprint 2 user-data-rights ruft das via Iteration über alle
108
- * `r.useExtension(EXT_USER_DATA, ...)`-Registrierungen.
106
+ * The data-rights runner invokes this by iterating over all
107
+ * `r.useExtension(EXT_USER_DATA, ...)` registrations.
109
108
  */
110
109
  export type UserDataExportHook = (ctx: UserDataHookCtx) => Promise<UserDataExportSnippet | null>;
111
110
  /**
112
- * Forget-Hook: Löscht oder anonymisiert die Entity-Rows die zu einem
113
- * User gehören. Strategy kommt vom Cleanup-Job (kann per Entity
114
- * unterschiedlich sein wegen Retention-Policy).
111
+ * Forget hook: deletes or anonymizes entity rows belonging to a user. The
112
+ * cleanup job supplies the strategy, which may differ by entity because of
113
+ * the retention policy.
115
114
  *
116
- * Idempotent — wenn der Job zweimal läuft (Crash-Recovery), darf der
117
- * Hook nicht crashen.
115
+ * Idempotent — if the job runs twice during crash recovery, the hook must not
116
+ * crash.
118
117
  *
119
118
  * Return additive to `void`: a hook can return `{status:"ok"}` or
120
119
  * `{status:"incomplete", reason}` to signal a partial success to the
@@ -7,13 +7,13 @@ export declare function createTextField<R extends true | false = false>(override
7
7
  };
8
8
  /**
9
9
  * Long-form text field for source-code, markdown, blog-posts, email-
10
- * templates — anything that can be megabytes large. Type-level differs
11
- * from `text`: keine sortable/searchable/filterable/format options.
12
- * DB-mapping ist identisch zu text (PG text ist unbounded).
10
+ * templates — anything that can be megabytes large. Its type-level API
11
+ * differs from `text`: it has no sortable/searchable/filterable/format options.
12
+ * The DB mapping is identical to text (`PG text` is unbounded).
13
13
  *
14
- * Soft-cap default: kein maxLength (PG text ist 1 GB hart begrenzt).
15
- * Setze einen explicit `maxLength` wenn du ein verirrtes Browser-Paste
16
- * früh ablehnen willst (z.B. 1_000_000 = 1 MB).
14
+ * Soft-cap default: no maxLength (`PG text` has a 1 GB hard limit).
15
+ * Set an explicit `maxLength` to reject an accidental browser paste early
16
+ * (for example, `1_000_000 = 1 MB`).
17
17
  */
18
18
  /**
19
19
  * Read-time computed field for `EntityDefinition.derivedFields` (NOT `fields`).
@@ -112,12 +112,12 @@ export declare function createDateField<R extends true | false = false>(override
112
112
  required: R;
113
113
  };
114
114
  /**
115
- * UTC-Instant — für Ereignisse die zu einem bestimmten Zeitpunkt passieren
116
- * (createdAt, loginAt, actualPickupAt). Temporal.Instant intern.
115
+ * UTC instant for events occurring at a specific point in time
116
+ * (createdAt, loginAt, actualPickupAt). Uses Temporal.Instant internally.
117
117
  *
118
- * Mit `locatedBy: "<name>Tz"` wird das Feld zum Wall-Clock-Pair eines
119
- * Termins an einem Ort — bevorzuge dafür `createLocatedTimestampField()`,
120
- * das EIN atomares Feld statt eines lose verdrahteten Pairs erzeugt.
118
+ * With `locatedBy: "<name>Tz"`, the field becomes a wall-clock pair for an
119
+ * appointment at a location — prefer `createLocatedTimestampField()` instead,
120
+ * which creates one atomic field rather than a loosely connected pair.
121
121
  */
122
122
  export declare function createTimestampField<R extends true | false = false>(overrides?: Partial<Omit<TimestampFieldDef, "type" | "required" | keyof ResolvedPiiFlags>> & PersonalAnnotationsNoFind & {
123
123
  required?: R;
@@ -125,8 +125,9 @@ export declare function createTimestampField<R extends true | false = false>(ove
125
125
  required: R;
126
126
  };
127
127
  /**
128
- * IANA-Zonenname (z.B. "Europe/Berlin"). Wird im Boot/Schema-Validator
129
- * via `Intl.supportedValuesOf("timeZone")` geprüft (kommt im Zod-Schritt).
128
+ * IANA time-zone name (for example, "Europe/Berlin"). The boot/schema
129
+ * validator checks it using `Intl.supportedValuesOf("timeZone")` during the
130
+ * Zod step.
130
131
  */
131
132
  export declare function createTzField<R extends true | false = false>(overrides?: Partial<Omit<TzFieldDef, "type" | "required" | keyof ResolvedPiiFlags>> & PersonalAnnotationsNoFind & {
132
133
  required?: R;
@@ -24,7 +24,7 @@ function resolvePersonalFlags(personal, reason) {
24
24
  userOwned: { ownerField: personal.of, ...(whenAbsent !== undefined && { whenAbsent }) },
25
25
  };
26
26
  }
27
- // Resolves the author-facing `personal`/`find` annotations (kumiko-framework#2250)
27
+ // Resolves the author-facing `personal`/`find` annotations
28
28
  // into the internal ResolvedPiiFlags every factory below merges into its
29
29
  // return value. `personal`, `find`, `reason` never survive into the field def.
30
30
  function expandPersonalAnnotations(overrides) {
@@ -73,7 +73,7 @@ function missingTextFieldStanceError(factoryName) {
73
73
  function isNonEmptyString(value) {
74
74
  return typeof value === "string" && value.trim().length > 0;
75
75
  }
76
- // Fail-closed stance gate (kumiko-framework#2921) for the two text-shaped
76
+ // Fail-closed stance gate for the two text-shaped
77
77
  // factories — runs before expandPersonalAnnotations so an untyped JS caller
78
78
  // (no compiler to stop it) can't slip an unannotated text field past the
79
79
  // type layer either. The typed signature above already rejects a
@@ -109,13 +109,12 @@ function assertTextFieldStance(factoryName, overrides) {
109
109
  throw missingTextFieldStanceError(factoryName);
110
110
  }
111
111
  }
112
- // Generic über `R extends true | false` (statt `boolean`) damit
113
- // `createTextField({ required: true })` literal `required: true` im
114
- // Return-Type behält. `boolean` würde widenen — EntityTable<E>'s
115
- // Mapped-Type könnte dann nicht zwischen `required: true` und
116
- // `required: false` dispatchen, jede Column würde zu nullable
117
- // degradieren. Default `R = false` matcht den runtime-default. Pattern
118
- // in jeder required-bearing factory unten.
112
+ // Use generic `R extends true | false` instead of `boolean` so
113
+ // `createTextField({ required: true })` preserves the literal `required: true`
114
+ // in the return type. Widening to `boolean` would prevent EntityTable<E>'s
115
+ // Mapped-Type from distinguishing `required: true` from `required: false`,
116
+ // making every column nullable. Default `R = false` matches the runtime
117
+ // default. This pattern is used in every required-bearing factory below.
119
118
  export function createTextField(overrides) {
120
119
  assertTextFieldStance("createTextField", overrides);
121
120
  return {
@@ -129,13 +128,13 @@ export function createTextField(overrides) {
129
128
  }
130
129
  /**
131
130
  * Long-form text field for source-code, markdown, blog-posts, email-
132
- * templates — anything that can be megabytes large. Type-level differs
133
- * from `text`: keine sortable/searchable/filterable/format options.
134
- * DB-mapping ist identisch zu text (PG text ist unbounded).
131
+ * templates — anything that can be megabytes large. Its type-level API
132
+ * differs from `text`: it has no sortable/searchable/filterable/format options.
133
+ * The DB mapping is identical to text (`PG text` is unbounded).
135
134
  *
136
- * Soft-cap default: kein maxLength (PG text ist 1 GB hart begrenzt).
137
- * Setze einen explicit `maxLength` wenn du ein verirrtes Browser-Paste
138
- * früh ablehnen willst (z.B. 1_000_000 = 1 MB).
135
+ * Soft-cap default: no maxLength (`PG text` has a 1 GB hard limit).
136
+ * Set an explicit `maxLength` to reject an accidental browser paste early
137
+ * (for example, `1_000_000 = 1 MB`).
139
138
  */
140
139
  /**
141
140
  * Read-time computed field for `EntityDefinition.derivedFields` (NOT `fields`).
@@ -277,10 +276,10 @@ export function createEmbeddedListField(schema, overrides) {
277
276
  multiple: true,
278
277
  };
279
278
  }
280
- // Free-form jsonb-Spalte — siehe `JsonbFieldDef`-Doku. Schema-less, default
281
- // `{}`, NOT NULL. Hauptnutzer: custom-fields-Bundle (host-entity's
282
- // `customFields`-Spalte). Andere valid uses: tenant-config-blobs, AI-
283
- // inferred-metadata, future tags-arrays.
279
+ // Free-form jsonb column — see the `JsonbFieldDef` documentation. Schema-less,
280
+ // defaults to `{}`, and is NOT NULL. Primarily used by the custom-fields
281
+ // bundle for the host entity's `customFields` column; other valid uses include
282
+ // tenant configuration blobs, AI-inferred metadata, and future tag arrays.
284
283
  export function createJsonbField(overrides) {
285
284
  return {
286
285
  type: "jsonb",
@@ -295,17 +294,17 @@ export function createDateField(overrides) {
295
294
  }; // @cast-boundary engine-payload
296
295
  }
297
296
  /**
298
- * UTC-Instant — für Ereignisse die zu einem bestimmten Zeitpunkt passieren
299
- * (createdAt, loginAt, actualPickupAt). Temporal.Instant intern.
297
+ * UTC instant for events occurring at a specific point in time
298
+ * (createdAt, loginAt, actualPickupAt). Uses Temporal.Instant internally.
300
299
  *
301
- * Mit `locatedBy: "<name>Tz"` wird das Feld zum Wall-Clock-Pair eines
302
- * Termins an einem Ort — bevorzuge dafür `createLocatedTimestampField()`,
303
- * das EIN atomares Feld statt eines lose verdrahteten Pairs erzeugt.
300
+ * With `locatedBy: "<name>Tz"`, the field becomes a wall-clock pair for an
301
+ * appointment at a location — prefer `createLocatedTimestampField()` instead,
302
+ * which creates one atomic field rather than a loosely connected pair.
304
303
  */
305
304
  export function createTimestampField(overrides) {
306
- // Object-Build vermeidet hartcodiertes `required: false` im literal —
307
- // das würde TS dazu bringen, R auf `boolean` zu widenen statt das
308
- // literal `true`/`false` aus dem overrides-Argument zu inferieren.
305
+ // Building the object this way avoids hardcoding `required: false` in the
306
+ // literal, which would make TypeScript widen R to `boolean` instead of
307
+ // inferring the `true`/`false` literal from the overrides argument.
309
308
  return {
310
309
  ...expandPersonalAnnotations(overrides),
311
310
  type: "timestamp",
@@ -313,8 +312,9 @@ export function createTimestampField(overrides) {
313
312
  };
314
313
  }
315
314
  /**
316
- * IANA-Zonenname (z.B. "Europe/Berlin"). Wird im Boot/Schema-Validator
317
- * via `Intl.supportedValuesOf("timeZone")` geprüft (kommt im Zod-Schritt).
315
+ * IANA time-zone name (for example, "Europe/Berlin"). The boot/schema
316
+ * validator checks it using `Intl.supportedValuesOf("timeZone")` during the
317
+ * Zod step.
318
318
  */
319
319
  export function createTzField(overrides) {
320
320
  return {
@@ -372,14 +372,15 @@ export function createFilesField(overrides) {
372
372
  export function createImagesField(overrides) {
373
373
  return { type: "images", ...expandPersonalAnnotations(overrides) };
374
374
  }
375
- // `F` läuft OHNE Constraint im Generic-Param damit TS die literal-types
376
- // einzelner Field-Defs durchzieht (required: true bleibt true, nicht
377
- // boolean). Constraint-Match gegen FieldsMap würde widenen — siehe TS-
378
- // Issue um Constraint-Inferenz auf strukturellen Records. Stattdessen
379
- // validieren wir die Conformance via conditional return type: wenn F
380
- // nicht FieldsMap-compat ist, kollabiert der Return zu `never`.
381
- // `const F`: inline field literals (`{ type: "reference", ... }`) keep their
382
- // `type` literal without `as const`; otherwise it widens to string → `never`.
375
+ // Leave `F` unconstrained so TypeScript preserves the literal types of
376
+ // individual field definitions (`required: true` remains `true`, not
377
+ // `boolean`). Constraining it to FieldsMap would widen them — see the
378
+ // TypeScript issue concerning constraint inference for structural records.
379
+ // Instead, conformance is validated through the conditional return type: if F
380
+ // is not compatible with FieldsMap, the return type collapses to `never`.
381
+ // `const F` preserves the `type` literal in inline field literals
382
+ // (`{ type: "reference", ... }`) without `as const`; otherwise it widens to
383
+ // string and produces `never`.
383
384
  export function createEntity(def) {
384
385
  return {
385
386
  softDelete: false,
@@ -1,7 +1,7 @@
1
1
  // Shared field-type validation for EntityDefinition. Used by both the
2
2
  // static extractor (extractEntity, parse-time ParseError) and the runtime
3
3
  // PatternChange validator (pattern-change-schema.ts) so the two never drift
4
- // into reporting different "unknown field type" catalogues (#3137).
4
+ // into reporting different "unknown field type" catalogues.
5
5
  import { FIELD_TYPE_NAMES } from "@cosmicdrift/kumiko-types/fields";
6
6
  import { isPlainObject, isRawRefSentinel } from "./extractors/shared.js";
7
7
  /**
@@ -256,7 +256,7 @@ export function parseHandlerCall(call, sourceFile, methodName) {
256
256
  // (`r.writeHandler(eventCreateHandler)`, `r.queryHandler(someQuery())`)
257
257
  // that resolveObjectLiteralArg above couldn't turn into an object literal
258
258
  // (imported binding, factory call, ...). Keep it recognised as this kind
259
- // instead of ParseErroring — see #1007. Opaque: renderWriteHandler/
259
+ // instead of ParseErroring. Opaque: renderWriteHandler/
260
260
  // renderQueryHandler re-emit `source.raw` verbatim when handlerName is
261
261
  // undefined.
262
262
  if (args.length === 1 && isRawRefSentinel(readDataLiteralNode(first))) {
@@ -230,7 +230,7 @@ export function extractHook(call, sourceFile) {
230
230
  ...escapeHatchOutcome,
231
231
  });
232
232
  }
233
- // guard:dup-ok — intentionale Parallele zu extractTree (round6); verschiedene Feature-AST-Extraktoren by design
233
+ // guard:dup-ok — intentional parallel to extractTree; different Feature-AST extractors by design
234
234
  export function extractAuthClaims(call, sourceFile) {
235
235
  const arg = call.getArguments()[0];
236
236
  if (!arg) {
@@ -47,8 +47,7 @@ export declare function readStringOrRaw(node: Node): string | RawRefSentinel | u
47
47
  * Like readStringLiteralArgs, but an argument that resolves to a raw-ref
48
48
  * sentinel is kept as that sentinel instead of failing the whole call. Used
49
49
  * where a value stands in for a single name/key and inlining its resolved
50
- * string would corrupt the render roundtrip (e.g. `r.requires(someFeature.name)`
51
- * — see #1009).
50
+ * string would corrupt the render roundtrip (e.g. `r.requires(someFeature.name)`).
52
51
  */
53
52
  export declare function readStringOrRawArgs(call: CallExpression): readonly (string | RawRefSentinel)[] | undefined;
54
53
  export { isPlainObject } from "../../../utils/is-plain-object.ts";
@@ -67,7 +66,7 @@ export type NameLiteralRef = {
67
66
  };
68
67
  /**
69
68
  * Like `readNameLiteral`, but for callers that must preserve an
70
- * identifier-authored name across a render → parse round-trip (see #2111).
69
+ * identifier-authored name across a render → parse round-trip.
71
70
  * `raw` is populated only when the node resolved via an identifier — a
72
71
  * string-literal node has nothing worth preserving beyond its value, and
73
72
  * setting `raw` for it too would make `JSON.stringify(value)` and
@@ -147,8 +147,7 @@ export function readStringOrRaw(node) {
147
147
  * Like readStringLiteralArgs, but an argument that resolves to a raw-ref
148
148
  * sentinel is kept as that sentinel instead of failing the whole call. Used
149
149
  * where a value stands in for a single name/key and inlining its resolved
150
- * string would corrupt the render roundtrip (e.g. `r.requires(someFeature.name)`
151
- * — see #1009).
150
+ * string would corrupt the render roundtrip (e.g. `r.requires(someFeature.name)`).
152
151
  */
153
152
  export function readStringOrRawArgs(call) {
154
153
  const out = [];
@@ -229,7 +228,7 @@ function resolveIdentifierToStringLiteral(identifier) {
229
228
  }
230
229
  /**
231
230
  * Like `readNameLiteral`, but for callers that must preserve an
232
- * identifier-authored name across a render → parse round-trip (see #2111).
231
+ * identifier-authored name across a render → parse round-trip.
233
232
  * `raw` is populated only when the node resolved via an identifier — a
234
233
  * string-literal node has nothing worth preserving beyond its value, and
235
234
  * setting `raw` for it too would make `JSON.stringify(value)` and