@jini-ai/cms 0.3.10 → 0.4.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 (258) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/README.md +47 -19
  3. package/dist/content-types/agent-tools.d.ts +3 -56
  4. package/dist/content-types/agent-tools.js +22 -6
  5. package/dist/content-types/cleanup.d.ts +18 -13
  6. package/dist/content-types/cleanup.js +16 -11
  7. package/dist/content-types/errors.d.ts +57 -24
  8. package/dist/content-types/errors.js +56 -39
  9. package/dist/content-types/field-defs.d.ts +8 -4
  10. package/dist/content-types/field-defs.js +19 -14
  11. package/dist/content-types/index-provisioning.d.ts +61 -47
  12. package/dist/content-types/index-provisioning.js +90 -66
  13. package/dist/content-types/index.d.ts +4 -3
  14. package/dist/content-types/lifecycle-dispatch.d.ts +11 -5
  15. package/dist/content-types/lifecycle-dispatch.js +5 -4
  16. package/dist/content-types/lifecycle.d.ts +23 -18
  17. package/dist/content-types/lifecycle.js +71 -64
  18. package/dist/content-types/repo.memory.d.ts +5 -4
  19. package/dist/content-types/repo.memory.js +3 -2
  20. package/dist/content-types/tool-registrations.d.ts +6 -8
  21. package/dist/content-types/tool-registrations.js +24 -28
  22. package/dist/content-types/types.d.ts +17 -13
  23. package/dist/content-types/types.js +11 -5
  24. package/dist/content-types/write-service.d.ts +20 -22
  25. package/dist/content-types/write-service.js +78 -75
  26. package/dist/core/authorization.d.ts +15 -0
  27. package/dist/core/authorization.js +2 -0
  28. package/dist/core/commands/change-set.d.ts +15 -7
  29. package/dist/core/commands/command.d.ts +45 -26
  30. package/dist/core/commands/command.js +73 -63
  31. package/dist/core/entity-liveness.d.ts +11 -7
  32. package/dist/core/entity-liveness.js +5 -4
  33. package/dist/core/index.d.ts +12 -5
  34. package/dist/core/index.js +10 -4
  35. package/dist/core/ports.d.ts +25 -24
  36. package/dist/core/ports.js +1 -0
  37. package/dist/core/tools/args.d.ts +49 -0
  38. package/dist/core/tools/args.js +46 -0
  39. package/dist/core/tools/index.d.ts +3 -0
  40. package/dist/core/tools/index.js +3 -0
  41. package/dist/entries/agent-tools.d.ts +1 -73
  42. package/dist/entries/agent-tools.js +19 -13
  43. package/dist/entries/errors.d.ts +28 -14
  44. package/dist/entries/errors.js +17 -11
  45. package/dist/entries/field-validation.d.ts +5 -3
  46. package/dist/entries/field-validation.js +7 -5
  47. package/dist/entries/index.d.ts +2 -2
  48. package/dist/entries/lifecycle-dispatch.d.ts +5 -2
  49. package/dist/entries/lifecycle-dispatch.js +2 -1
  50. package/dist/entries/list.d.ts +4 -2
  51. package/dist/entries/list.js +4 -3
  52. package/dist/entries/repo.memory.d.ts +12 -10
  53. package/dist/entries/repo.memory.js +11 -10
  54. package/dist/entries/tool-registrations.d.ts +6 -8
  55. package/dist/entries/tool-registrations.js +42 -41
  56. package/dist/entries/types.d.ts +0 -7
  57. package/dist/entries/write-service.d.ts +28 -29
  58. package/dist/entries/write-service.js +114 -105
  59. package/dist/http/settings/cms-adapter.d.ts +20 -0
  60. package/dist/http/settings/cms-adapter.js +124 -0
  61. package/dist/http/settings/contracts.d.ts +135 -0
  62. package/dist/http/settings/contracts.js +2 -0
  63. package/dist/http/settings/http.d.ts +10 -0
  64. package/dist/http/settings/http.js +211 -0
  65. package/dist/http/settings/index.d.ts +5 -0
  66. package/dist/http/settings/index.js +4 -0
  67. package/dist/http/settings/shared.d.ts +68 -0
  68. package/dist/http/settings/shared.js +54 -0
  69. package/dist/http/settings/stream.d.ts +24 -0
  70. package/dist/http/settings/stream.js +147 -0
  71. package/dist/media/agent-tools.d.ts +1 -66
  72. package/dist/media/agent-tools.js +5 -1
  73. package/dist/media/blob-gc-lock.d.ts +6 -2
  74. package/dist/media/blob-gc-lock.js +4 -2
  75. package/dist/media/blob-gc.d.ts +64 -51
  76. package/dist/media/blob-gc.js +62 -52
  77. package/dist/media/blob-key.d.ts +1 -1
  78. package/dist/media/content-type-sniffer.d.ts +3 -1
  79. package/dist/media/content-type-sniffer.js +1 -1
  80. package/dist/media/html-attributes.d.ts +9 -5
  81. package/dist/media/html-attributes.js +8 -6
  82. package/dist/media/image-transformer.js +1 -1
  83. package/dist/media/image-transformer.sharp.d.ts +6 -0
  84. package/dist/media/image-transformer.sharp.js +12 -6
  85. package/dist/media/import/fetch-image.d.ts +24 -0
  86. package/dist/media/import/fetch-image.js +137 -0
  87. package/dist/media/import/index.d.ts +3 -0
  88. package/dist/media/import/index.js +3 -0
  89. package/dist/media/import/ports.d.ts +38 -0
  90. package/dist/media/index.d.ts +7 -1
  91. package/dist/media/index.js +1 -0
  92. package/dist/media/media-service.d.ts +14 -10
  93. package/dist/media/media-service.js +57 -52
  94. package/dist/media/ports.d.ts +3 -2
  95. package/dist/media/rendition-service.d.ts +3 -3
  96. package/dist/media/rendition-service.js +38 -37
  97. package/dist/media/repo.memory.d.ts +18 -7
  98. package/dist/media/repo.memory.js +12 -6
  99. package/dist/media/tool-registrations.d.ts +16 -15
  100. package/dist/media/tool-registrations.js +84 -72
  101. package/dist/media/transform-lock.d.ts +22 -12
  102. package/dist/media/transform-lock.js +14 -13
  103. package/dist/media/transform-registry.d.ts +3 -3
  104. package/dist/media/transform-registry.js +19 -18
  105. package/dist/media/transform-types.d.ts +8 -3
  106. package/dist/media/transform-types.js +10 -5
  107. package/dist/media/types.d.ts +21 -4
  108. package/dist/media/types.js +15 -2
  109. package/dist/navigation/agent-tools.d.ts +1 -80
  110. package/dist/navigation/agent-tools.js +15 -3
  111. package/dist/navigation/contracts.d.ts +1 -1
  112. package/dist/navigation/index.d.ts +2 -2
  113. package/dist/navigation/menu-service.d.ts +57 -40
  114. package/dist/navigation/menu-service.js +80 -69
  115. package/dist/navigation/ports.d.ts +1 -1
  116. package/dist/navigation/read-model.d.ts +3 -1
  117. package/dist/navigation/read-model.js +2 -2
  118. package/dist/navigation/reconcile.d.ts +2 -2
  119. package/dist/navigation/reconcile.js +2 -1
  120. package/dist/navigation/repo.memory.d.ts +7 -3
  121. package/dist/navigation/repo.memory.js +4 -2
  122. package/dist/navigation/resolver.d.ts +4 -1
  123. package/dist/navigation/resolver.js +1 -1
  124. package/dist/navigation/tool-registrations.d.ts +6 -8
  125. package/dist/navigation/tool-registrations.js +44 -42
  126. package/dist/navigation/types.d.ts +1 -1
  127. package/dist/presentation/presentation.d.ts +11 -3
  128. package/dist/presentation/presentation.js +13 -6
  129. package/dist/presentation/repo.memory.d.ts +6 -2
  130. package/dist/presentation/repo.memory.js +3 -2
  131. package/dist/settings/agent-tools.d.ts +2 -75
  132. package/dist/settings/agent-tools.js +49 -45
  133. package/dist/settings/agent-value-write-tools.d.ts +22 -0
  134. package/dist/settings/agent-value-write-tools.js +154 -0
  135. package/dist/settings/agent-writable-preferences.js +8 -20
  136. package/dist/settings/agent-write-denylist.d.ts +19 -0
  137. package/dist/settings/agent-write-denylist.js +15 -0
  138. package/dist/settings/change-feed.d.ts +11 -2
  139. package/dist/settings/change-feed.js +4 -4
  140. package/dist/settings/definitions-dispatch.d.ts +8 -3
  141. package/dist/settings/definitions-dispatch.js +5 -5
  142. package/dist/settings/dictionaries/index.d.ts +5 -2
  143. package/dist/settings/dictionaries/index.js +2 -2
  144. package/dist/settings/dictionaries/settings-dialog.ar.js +0 -1
  145. package/dist/settings/dictionaries/settings-dialog.bn.js +0 -1
  146. package/dist/settings/dictionaries/settings-dialog.de.js +0 -1
  147. package/dist/settings/dictionaries/settings-dialog.es.js +0 -1
  148. package/dist/settings/dictionaries/settings-dialog.fa.js +0 -1
  149. package/dist/settings/dictionaries/settings-dialog.fr.js +0 -1
  150. package/dist/settings/dictionaries/settings-dialog.hi.js +0 -1
  151. package/dist/settings/dictionaries/settings-dialog.hu.js +0 -1
  152. package/dist/settings/dictionaries/settings-dialog.id.js +0 -1
  153. package/dist/settings/dictionaries/settings-dialog.it.js +0 -1
  154. package/dist/settings/dictionaries/settings-dialog.ja.js +0 -1
  155. package/dist/settings/dictionaries/settings-dialog.ko.js +0 -1
  156. package/dist/settings/dictionaries/settings-dialog.pl.js +0 -1
  157. package/dist/settings/dictionaries/settings-dialog.pt-BR.js +0 -1
  158. package/dist/settings/dictionaries/settings-dialog.ru.js +0 -1
  159. package/dist/settings/dictionaries/settings-dialog.th.js +0 -1
  160. package/dist/settings/dictionaries/settings-dialog.tr.js +0 -1
  161. package/dist/settings/dictionaries/settings-dialog.uk.js +0 -1
  162. package/dist/settings/dictionaries/settings-dialog.ur.js +0 -1
  163. package/dist/settings/dictionaries/settings-dialog.zh-CN.js +0 -1
  164. package/dist/settings/dictionaries/settings-dialog.zh-TW.js +0 -1
  165. package/dist/settings/ensure-definitions.d.ts +5 -5
  166. package/dist/settings/errors.d.ts +7 -1
  167. package/dist/settings/errors.js +7 -1
  168. package/dist/settings/index.d.ts +4 -1
  169. package/dist/settings/index.js +1 -0
  170. package/dist/settings/ports.d.ts +6 -5
  171. package/dist/settings/principal-lookup.d.ts +9 -0
  172. package/dist/settings/principal-lookup.js +2 -0
  173. package/dist/settings/purge-service.d.ts +5 -4
  174. package/dist/settings/purge-service.js +3 -2
  175. package/dist/settings/settings.d.ts +22 -7
  176. package/dist/settings/settings.js +47 -26
  177. package/dist/settings/tool-registrations.d.ts +25 -32
  178. package/dist/settings/tool-registrations.js +66 -56
  179. package/dist/settings/types.d.ts +1 -1
  180. package/dist/settings/ui-tab-definitions.d.ts +1 -1
  181. package/dist/settings/write-service.d.ts +32 -26
  182. package/dist/settings/write-service.js +26 -20
  183. package/dist/taxonomy/agent-tools.d.ts +1 -66
  184. package/dist/taxonomy/agent-tools.js +25 -15
  185. package/dist/taxonomy/content-lookup.js +1 -1
  186. package/dist/taxonomy/index.d.ts +2 -2
  187. package/dist/taxonomy/merge-term.d.ts +7 -4
  188. package/dist/taxonomy/merge-term.js +7 -5
  189. package/dist/taxonomy/repo.memory.d.ts +42 -19
  190. package/dist/taxonomy/repo.memory.js +14 -12
  191. package/dist/taxonomy/validation-chain.d.ts +39 -18
  192. package/dist/taxonomy/validation-chain.js +35 -25
  193. package/dist/taxonomy/write-service.d.ts +106 -45
  194. package/dist/taxonomy/write-service.js +221 -179
  195. package/dist/trash/adapters/record-store.d.ts +52 -0
  196. package/dist/trash/adapters/record-store.js +36 -0
  197. package/dist/trash/cursor.d.ts +20 -0
  198. package/dist/trash/cursor.js +36 -0
  199. package/dist/trash/follow-ups.d.ts +76 -0
  200. package/dist/trash/follow-ups.js +46 -0
  201. package/dist/trash/index.d.ts +8 -0
  202. package/dist/trash/index.js +8 -0
  203. package/dist/trash/ports.d.ts +308 -0
  204. package/dist/trash/ports.js +2 -0
  205. package/dist/trash/repo.memory.d.ts +50 -0
  206. package/dist/trash/repo.memory.js +114 -0
  207. package/dist/trash/sweeper.d.ts +77 -0
  208. package/dist/trash/sweeper.js +127 -0
  209. package/dist/trash/write-service.d.ts +100 -0
  210. package/dist/trash/write-service.js +242 -0
  211. package/dist/workspace/agent-tools.d.ts +1 -59
  212. package/dist/workspace/agent-tools.js +27 -12
  213. package/dist/workspace/create.d.ts +31 -6
  214. package/dist/workspace/create.js +18 -5
  215. package/dist/workspace/delete.d.ts +18 -13
  216. package/dist/workspace/delete.js +20 -12
  217. package/dist/workspace/index.d.ts +1 -1
  218. package/dist/workspace/repo.memory.d.ts +19 -4
  219. package/dist/workspace/repo.memory.js +26 -4
  220. package/dist/workspace/tool-registrations.d.ts +2 -2
  221. package/dist/workspace/tool-registrations.js +13 -13
  222. package/dist/workspace/update.d.ts +6 -5
  223. package/dist/workspace/update.js +9 -8
  224. package/package.json +44 -38
  225. package/dist/identity/admin-crud-service.d.ts +0 -280
  226. package/dist/identity/admin-crud-service.js +0 -468
  227. package/dist/identity/agent-tool-input.d.ts +0 -58
  228. package/dist/identity/agent-tool-input.js +0 -126
  229. package/dist/identity/agent-tools.d.ts +0 -101
  230. package/dist/identity/agent-tools.js +0 -290
  231. package/dist/identity/auth-service.d.ts +0 -118
  232. package/dist/identity/auth-service.js +0 -170
  233. package/dist/identity/authorize.d.ts +0 -90
  234. package/dist/identity/authorize.js +0 -94
  235. package/dist/identity/grant-service.d.ts +0 -198
  236. package/dist/identity/grant-service.js +0 -361
  237. package/dist/identity/hasher.d.ts +0 -39
  238. package/dist/identity/hasher.js +0 -39
  239. package/dist/identity/index.d.ts +0 -62
  240. package/dist/identity/index.js +0 -54
  241. package/dist/identity/password-policy.d.ts +0 -57
  242. package/dist/identity/password-policy.js +0 -66
  243. package/dist/identity/permission-migrations.d.ts +0 -86
  244. package/dist/identity/permission-migrations.js +0 -67
  245. package/dist/identity/permissions.d.ts +0 -35
  246. package/dist/identity/permissions.js +0 -603
  247. package/dist/identity/ports.d.ts +0 -201
  248. package/dist/identity/repo.memory.d.ts +0 -164
  249. package/dist/identity/repo.memory.js +0 -224
  250. package/dist/identity/seed.d.ts +0 -54
  251. package/dist/identity/seed.js +0 -429
  252. package/dist/identity/tool-registrations.d.ts +0 -50
  253. package/dist/identity/tool-registrations.js +0 -419
  254. package/dist/identity/types.d.ts +0 -185
  255. package/dist/identity/types.js +0 -64
  256. package/dist/identity/username.d.ts +0 -12
  257. package/dist/identity/username.js +0 -14
  258. /package/dist/{identity → media/import}/ports.js +0 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,59 @@
1
+ # Changelog
2
+
3
+ ## Unreleased — Trash host adoption
4
+
5
+ - Preserve `adapter-unavailable` for absent domains before checking entity policy; selected purge
6
+ still checks resolved-row authorization first. Added regression coverage for both manual and
7
+ retention purge outcomes.
8
+ - Restore shared rationale for atomic marker/index changes, keyset pagination, retention promises,
9
+ restore races, leases and follow-up no-ops. Move the cursor wire/Unicode/malformed-input suite
10
+ into `src/trash/__tests__/cursor.test.ts`. Move the nine in-memory repository contract cases
11
+ and nine pure sweep decision cases alongside their shared implementations; native timer and
12
+ SQL/dialect integration coverage remains with the host adapters.
13
+
14
+ ## 0.4.0 — 2026-10-02
15
+
16
+ ### BREAKING
17
+
18
+ - Remove the unused `@jini-ai/cms/server` placeholder subpath and its `CMS_SERVER_LAYER` marker; concrete Node adapters remain in domain-specific entries and identity wiring belongs to `@jini-ai/user-management/server`.
19
+ - Identity tools moved to user-management/server; analytics moved to the analytics package and trash to cms/trash. Settings use a principal lookup port, generic tool/HTTP/clock types come from core, and the nonexistent ./widgets entry was removed.
20
+ - Distribution includes runtime output, release documentation and required assets only. Process records and per-job neutrality checks are no longer part of the package surface.
21
+
22
+ ## Unreleased
23
+
24
+ ### Compile repairs
25
+
26
+ - Align settings HTTP adapters and value-write tool errors with current named kernel/domain arguments; import the canonical taxonomy ID generator type.
27
+ - Correct feed callback/mock typing, authorization fixtures, taxonomy delete arguments, workspace update dependencies, and awaited index-identity assertions without removing tests.
28
+
29
+ ### Breaking architecture boundaries
30
+
31
+ - Move identity registrations to `@jini-ai/user-management/server`; remove the user-management dependency.
32
+ - Move generic registration helpers and tool catalog types to `@jini-ai/core`; remove domain type aliases and local primitive/Result/HTTP declarations. Use core primitives and named helper calls.
33
+ - Replace the settings identity repository dependency with a host-owned findActiveById lookup that a raw identity repository cannot satisfy structurally.
34
+ - Require explicitly bound transactions for term rename and workspace deletion.
35
+ - Add `./trash`, moved with its tests from platform. Retention is an option defaulting to 60 days; eager RangeError validation and sweeper bounds are retained. ID allocation uses the kernel `IdGenerator.newId()` port.
36
+ - Remove the unimplemented `./widgets` export and its metadata entry.
37
+
38
+
39
+ - Add `@jini-ai/cms/http/settings`: move the eight settings routes, contracts, CMS
40
+ adapters and resumable change feed with their behavior suites from HTTP kit.
41
+ `express` and `@jini-ai/http-kit` are optional peers used only by HTTP entries.
42
+ - Restore `401 UNAUTHENTICATED` when readiness or principal resolution fails.
43
+ - Isolate throwing diagnostics and individual cleanup failures so subscriptions retry
44
+ safely and cancellation/end still run. Regression tests written, not run.
45
+
46
+ - Remove specification identifiers from runtime refusal messages while preserving the guard, error class and explanatory text; retain rationale references in comments.
47
+
48
+ - Add forms validation, audited definition writes, bounded submissions and notification services in the separate nested `@jini-ai/cms-forms` workspace package.
49
+ - Add `./media/import` URL and binary validation with required MIME/size policy and injected HTTP, sniffer and outbound guard ports.
50
+
51
+ ### CMS integration
52
+
53
+ - The universal `./core/tools` entry now owns CMS permission helpers. Named input, catalog, schema-rejection and registration helpers are exported directly by the kernel.
54
+ - Complete the `./media/import` barrel and runtime metadata, with caller-supplied HTTP, binary validation, MIME/size policy and outbound safety ports.
55
+ - Identity services and hashing now live in `@jini-ai/user-management` and `@jini-ai/user-management/server`; Identity tool registration composition is exported by the user-management server entry. Remove the former identity workspace dependency from CMS and exclude retired identity build output from packaging.
56
+ - BREAKING: CMS domain functions, constructors, lifecycle handlers and scalar/callback repository, event-bus, outbox and change-set methods use `(requiredArgs, optionalArgs)` object arguments. Optional configuration and seeds move to the second object. Entry/content-type transactions use `transaction({ fn })`; their authorization ports use required principal/permission/workspace fields plus optional entity scope in the second object. Error details, validation and ordering are preserved. Hosts must rewire their adapters and calls.
57
+ - BREAKING: Retire `./identity` and `./identity/hasher` CMS export targets after their source migration. Import services from the identity package; import the registration builder from `@jini-ai/user-management/server`.
58
+ - Settings and navigation conversions still owned by their active jobs are pending. Legacy core helpers and authorization callbacks remain compatible until those callers migrate.
59
+ - Correct `./media` runtime metadata to Node because its existing barrel exposes filesystem, crypto and native-transform adapters; `./media/import` remains universal.
package/README.md CHANGED
@@ -2,27 +2,39 @@
2
2
 
3
3
  Content-model capability for Jini-hosted products.
4
4
 
5
- > **Status: implemented, port in progress.** Created 2026-08-02 as an empty shell; the port has
6
- > been landing since. Measured 2026-09-05 at `v0.3.4`: 131 non-test source files / 21,718 lines
7
- > under `src/` (34,938 including tests), 11 domain trees, and 14 public subpath exports wired in
8
- > `package.json`. Some domain modules named under [Port inventory](#port-inventory) have not moved
9
- > yet — check `src/` and the `exports` map for what is actually reachable today rather than
10
- > trusting this paragraph's counts.
5
+ The source tree includes content domains and Node adapters. CMS depends on shared kernel
6
+ contracts and has no user-management dependency. Generic tool wiring is exported by
7
+ `@jini-ai/core`; hosts provide CMS authorization and active-principal lookup ports.
8
+ See [API integration](API-INTEGRATION.md) for current signatures and migration examples, and
9
+ [integration-report.md](integration-report.md) for pending protected work and deferred verification.
11
10
 
12
11
  ## Layers
13
12
 
14
13
  | subpath | runtime | contents |
15
14
  |---|---|---|
16
15
  | `.` / `./core` | universal | Content contracts and types, ports, pure domain services, kernel registries. No Express, no `node:*`, no DOM. |
17
- | `./server` | node | Concrete adapters for the ports in `/core`: SQLite/Postgres repositories, filesystem blob stores, image transformers. |
16
+ | `./media` | node | Media services, filesystem blob stores and image transformers. |
17
+ | `./http/settings` | node | Settings HTTP routes, host policy contracts, CMS adapters and resumable change feed. |
18
18
 
19
- `/server` depends on `/core`. The reverse is a boundary violation — if a core module wants
20
- something from `/server`, the dependency is backwards and the fix is a port (interface) in core,
19
+ Node-bound domain adapters depend on `/core`. The reverse is a boundary violation — if a core module wants
20
+ something from a Node adapter, the dependency is backwards and the fix is a port (interface) in core,
21
21
  not a widened export.
22
22
 
23
- `./server` means *the Node-bound layer*, not *the HTTP server* — same convention as
24
- `@jini-ai/admin`. HTTP transport is out of scope; Jini has `@jini-ai/http-kit` and
25
- `@jini-ai/server`.
23
+ Domain HTTP adapters live under `./http/*`, using the generic transport and host
24
+ composition supplied by `@jini-ai/http-kit` and `@jini-ai/server`.
25
+ Identity tool registration composition belongs to `@jini-ai/user-management/server`.
26
+
27
+ `@jini-ai/cms/http/settings` exports `registerSettingsRoutes`, the settings HTTP
28
+ contracts and the CMS service/change-feed factories. Hosts provide route paths,
29
+ permissions, workspace, readiness, principal resolution, authorization, scheduler,
30
+ service and feed ports. Registration returns a disposer that closes active feeds.
31
+ CMS adapters pass named request objects to settings dispatch and change-feed services;
32
+ queryable index-name helpers return promises that callers must await.
33
+ Install the optional peers `express` and `@jini-ai/http-kit` when using HTTP subpaths;
34
+ the framework-free root and domain entries do not import them.
35
+ Readiness or principal-resolution failures return `401 UNAUTHENTICATED`.
36
+ Stream diagnostics are best-effort: a throwing reporter cannot prevent retries,
37
+ cancellation of other schedules or ending the response.
26
38
 
27
39
  ## Why the split exists before there is any code to split
28
40
 
@@ -57,11 +69,12 @@ history shows they essentially never co-change with each other, so each ports in
57
69
  coordination.
58
70
 
59
71
  **Landed** (directories under `src/`, each with its own subpath export):
60
- `core`, `content-types`, `entries`, `identity`, `media`, `navigation`, `presentation`, `settings`,
61
- `taxonomy`, `workspace`, and the `server` adapter layer.
72
+ `core`, `content-types`, `entries`, `media`, `navigation`, `presentation`, `settings`,
73
+ `taxonomy`, `workspace`, and `trash`. `./core/tools` exports CMS permission helpers; `./media/import` exports bounded image fetching with injected policies and ports.
62
74
 
63
- **Still to move:** `post`, `seo`, `comments`, `forms`, `redirects`, `widgets`, `newsletter`,
64
- `members`. (`widgets` has an `exports` entry but no `src/widgets/` tree yet.)
75
+ **Still to move:** `post`, `seo`, `comments`, `redirects`, `widgets`, `newsletter`,
76
+ `members`. The unimplemented `./widgets` export has been removed.
77
+ The nested forms package is maintained by its separate owner and is excluded from this parent package.
65
78
 
66
79
  **Explicitly not ported:**
67
80
 
@@ -84,6 +97,21 @@ pnpm --filter @jini-ai/cms test
84
97
  - **Add coverage thresholds.** `vitest.config.ts` still has none. That was a deliberate omission
85
98
  while the package was a placeholder; it no longer is, so the reason has expired. Set them against
86
99
  what the ported modules actually measure — siblings run 98–100%.
87
- - **Delete `CMS_SERVER_LAYER`** (`src/server/index.ts`). It existed only to give the `/server`
88
- entry point something real to resolve, and real exports have since landed. Its `/core`
89
- counterpart `CMS_CORE_LAYER` is already gone.
100
+
101
+ ## Design decisions
102
+
103
+ - [Schema indexes use closed fragments and unambiguous identities](docs/decisions/DR-001-safe-schema-and-index-transitions.md).
104
+ - [Content lifecycle separates new authoring from existing-entry writes](docs/decisions/DR-002-content-lifecycle-and-cleanup.md).
105
+ - [Settings preserve total defaults, scope fences and revision evidence](docs/decisions/DR-003-settings-ledger-invariants.md).
106
+ - [Blob collection rechecks references before journaled unlink](docs/decisions/DR-004-journaled-blob-gc.md).
107
+ - [Taxonomy validation preserves first-failure order and full cycle checks](docs/decisions/DR-005-ordered-taxonomy-validation.md).
108
+ - [Mutation, audit record and outbox intent share a commit boundary](docs/decisions/DR-006-mutation-audit-atomicity.md).
109
+ - [Workspace administration preserves tenancy and ownership floors](docs/decisions/DR-007-workspace-and-owner-floors.md).
110
+ - [Navigation mutations enqueue one event only on success](docs/decisions/DR-008-navigation-event-intent.md).
111
+
112
+ The `./trash` surface owns snapshot-only listing, keyset cursors, atomic marker/index writes,
113
+ transactional follow-ups and the retention sweeper. Hosts inject their table adapters, reentrant
114
+ transaction runner, `IdGenerator`, entity policy, `Clock` and scheduler. Native timer `unref` and
115
+ error logging belong to the host. Actor/prior-marker/list filters are passed in the optional second
116
+ object. Purge callers own human confirmation and must authorize each resolved index row; unavailable
117
+ domains remain `adapter-unavailable` after authorization even when their entity policy denies them.
@@ -1,65 +1,12 @@
1
+ import type { AgentToolDefinition } from "@jini-ai/core";
1
2
  /**
2
- * @file REQ-22/REQ-23 — the Collections content-types agent-tool catalog, instantiating
3
- * a REQ-22 naming/callability convention (mirrors `features/database/agent-tools.ts`'s
4
- * shape for this domain).
5
- *
6
- * Purpose:
7
- * A static, in-process catalog describing every agent-callable tool this domain exposes and the
8
- * permission/actor-class rule each one carries. `collections_content_type_list` (admin-UI-backend-
9
- * gap closure, mirroring `routes/admin/content-types/list.ts`) and `collections_plan_cleanup` are
10
- * both free reads (`admin.collections.read`, `sideEffects:'none'`) — the former lists the registry,
11
- * the latter only recomputes and returns an eligibility plan. `collections_execute_cleanup` is the
12
- * one destructive tool, gated to
13
- * `admin.collections.manage` and restricted to `confirmer-must-equal-own-delegatedBy`. There is
14
- * deliberately no `collections_confirm_cleanup` tool and no tool description implying an agent can
15
- * perform the confirm() step — confirmation of a destructive cleanup is human-UI-only (mirrors
16
- * the Database library's "Restore is a Recovery tool, not a Database tool" discipline: a lever an agent must
17
- * never be handed directly).
18
- *
19
- * How it relates to the project:
20
- * The server-side tool filter consumes this catalog to decide which tool names an agent
21
- * session may even see; `authorize()` and the confirmation-token gateway (`core/gated-mutations`)
22
- * enforce the actual permission/actor-class checks at call time — this module only declares the
23
- * catalog shape, it performs no I/O and no enforcement itself.
24
- *
25
- * Architectural role:
26
- * `features/content-types` domain logic. Performs no I/O and no enforcement. Depends only on this
27
- * package's own `types.ts` (the field-kind enum) and `index-provisioning.ts` (the identifier
28
- * grammar pattern) — imported so the published JSON Schemas cannot drift from the single sources
29
- * of those two values, rather than restating either.
30
- */
31
- export type AgentToolSideEffect = "none" | "mutates-durable-state" | "mints-token";
32
- export type AgentToolActorClassRule = "confirmer-must-equal-own-delegatedBy" | "user-only" | "none";
33
- export interface AgentToolDefinition {
34
- name: string;
35
- description: string;
36
- sideEffects: AgentToolSideEffect;
37
- authorization: {
38
- permission: string;
39
- };
40
- actorClassRule?: AgentToolActorClassRule;
41
- /**
42
- * JSON Schema for this tool's `input`, published to the model via `ToolDescriptor.inputSchema`
43
- * (`assistant/tool-registrations.ts`). Optional because the two cleanup entries are not wired to
44
- * handlers yet and their input shape is not designed; `tool-registrations.ts` asserts that every
45
- * tool it DOES wire has one.
46
- *
47
- * These schemas are hand-authored, and enforcement lives elsewhere — `field-defs.ts` for
48
- * structure and `write-service.ts`'s CIC U-002-B1 chain for the domain rules. That is a
49
- * deliberate two-artifact design, so the pair is pinned against drift by a fixture corpus in
50
- * `__tests__/unit/agent-tools.schema-agreement.unit.test.ts`. The two values a schema would
51
- * otherwise duplicate — the field-kind enum and the identifier grammar — are imported from their
52
- * single sources rather than restated.
53
- */
54
- inputSchema?: Readonly<Record<string, unknown>>;
55
- }
56
- /**
57
- * REQ-22/REQ-23 — the Collections content-types domain's fixed agent-tool catalog.
3
+ * — the Collections content-types domain's fixed agent-tool catalog.
58
4
  *
59
5
  * `collections_content_type_list` is ordered first, mirroring `identity/agent-tools.ts`'s
60
6
  * "read-tools-first" convention: a model cannot call `update_fields`/`deprecate`/`reactivate`/
61
7
  * `tombstone` without a `key` and current `expectedVersion`, and this is the only way to learn
62
8
  * either for a content type it did not itself just create.
9
+ * See docs/decisions/DR-001-safe-schema-and-index-transitions.md.
63
10
  */
64
11
  export declare const contentTypesAgentToolCatalog: AgentToolDefinition[];
65
12
  //# sourceMappingURL=agent-tools.d.ts.map
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @file REQ-22/REQ-23 — the Collections content-types agent-tool catalog, instantiating
3
- * a REQ-22 naming/callability convention (mirrors `features/database/agent-tools.ts`'s
2
+ * @file the Collections content-types agent-tool catalog, instantiating
3
+ * a naming/callability convention (mirrors `features/database/agent-tools.ts`'s
4
4
  * shape for this domain).
5
5
  *
6
6
  * Purpose:
@@ -12,13 +12,13 @@
12
12
  * one destructive tool, gated to
13
13
  * `admin.collections.manage` and restricted to `confirmer-must-equal-own-delegatedBy`. There is
14
14
  * deliberately no `collections_confirm_cleanup` tool and no tool description implying an agent can
15
- * perform the confirm() step — confirmation of a destructive cleanup is human-UI-only (mirrors
15
+ * perform the confirm step — confirmation of a destructive cleanup is human-UI-only (mirrors
16
16
  * the Database library's "Restore is a Recovery tool, not a Database tool" discipline: a lever an agent must
17
17
  * never be handed directly).
18
18
  *
19
19
  * How it relates to the project:
20
20
  * The server-side tool filter consumes this catalog to decide which tool names an agent
21
- * session may even see; `authorize()` and the confirmation-token gateway (`core/gated-mutations`)
21
+ * session may even see; `authorize` and the confirmation-token gateway (`core/gated-mutations`)
22
22
  * enforce the actual permission/actor-class checks at call time — this module only declares the
23
23
  * catalog shape, it performs no I/O and no enforcement itself.
24
24
  *
@@ -27,10 +27,25 @@
27
27
  * package's own `types.ts` (the field-kind enum) and `index-provisioning.ts` (the identifier
28
28
  * grammar pattern) — imported so the published JSON Schemas cannot drift from the single sources
29
29
  * of those two values, rather than restating either.
30
+ * See docs/decisions/DR-001-safe-schema-and-index-transitions.md.
30
31
  */
31
32
  import { IDENTIFIER_GRAMMAR_PATTERN } from "./index-provisioning.js";
32
33
  import { CONTENT_TYPE_FIELD_KINDS } from "./types.js";
33
- /** One entry of a `fields` array, as published to the model. Mirrors what `field-defs.ts` enforces. */
34
+ /**
35
+ * JSON Schema for this tool's `input`, published to the model via `ToolDescriptor.inputSchema`
36
+ * (`assistant/tool-registrations.ts`). Optional because the two cleanup entries are not wired to
37
+ * handlers yet and their input shape is not designed; `tool-registrations.ts` asserts that every
38
+ * tool it DOES wire has one.
39
+ *
40
+ * These schemas are hand-authored, and enforcement lives elsewhere — `field-defs.ts` for
41
+ * structure and `write-service.ts`'s chain for the domain rules. That is a
42
+ * deliberate two-artifact design, so the pair is pinned against drift by a fixture corpus in
43
+ * `__tests__/unit/agent-tools.schema-agreement.unit.test.ts`. The two values a schema would
44
+ * otherwise duplicate — the field-kind enum and the identifier grammar — are imported from their
45
+ * single sources rather than restated.
46
+ * See docs/decisions/DR-001-safe-schema-and-index-transitions.md.
47
+ *
48
+ * One entry of a `fields` array, as published to the model. Mirrors what `field-defs.ts` enforces. */
34
49
  const FIELD_DEF_SCHEMA = {
35
50
  type: "object",
36
51
  additionalProperties: false,
@@ -83,12 +98,13 @@ const LIFECYCLE_INPUT_SCHEMA = {
83
98
  },
84
99
  };
85
100
  /**
86
- * REQ-22/REQ-23 — the Collections content-types domain's fixed agent-tool catalog.
101
+ * — the Collections content-types domain's fixed agent-tool catalog.
87
102
  *
88
103
  * `collections_content_type_list` is ordered first, mirroring `identity/agent-tools.ts`'s
89
104
  * "read-tools-first" convention: a model cannot call `update_fields`/`deprecate`/`reactivate`/
90
105
  * `tombstone` without a `key` and current `expectedVersion`, and this is the only way to learn
91
106
  * either for a content type it did not itself just create.
107
+ * See docs/decisions/DR-001-safe-schema-and-index-transitions.md.
92
108
  */
93
109
  export const contentTypesAgentToolCatalog = [
94
110
  {
@@ -1,22 +1,22 @@
1
- import type { ClockPort } from "../core/ports.js";
1
+ import type { Clock } from "@jini-ai/core/primitives";
2
2
  import { CleanupNotEligibleError } from "./errors.js";
3
3
  import type { AuthorizeFn } from "./write-service.js";
4
- import type { Result } from "./types.js";
4
+ import type { Result } from "@jini-ai/core/primitives";
5
5
  /**
6
- * @file REQ-20/REQ-21 — the destructive cleanup ceremony, instantiating the
6
+ * @file the destructive cleanup ceremony, instantiating the
7
7
  * gated-mutation gateway (`domain="collections"`, `action="cleanup"`) around a tombstoned content
8
8
  * type's final, irreversible removal (the disable -> tombstone -> cleanup
9
9
  * lifecycle).
10
10
  *
11
11
  * Purpose:
12
- * `planCleanup` is the eligibility gate (C-405): a content type must be `status='tombstone'`, its
12
+ * `planCleanup` is the eligibility gate : a content type must be `status='tombstone'`, its
13
13
  * retention window (30 days since `tombstonedAt`, inclusive) must have elapsed, and an
14
14
  * `exportReference` must be present — checked in that fixed order, stopping at the first failure
15
- * (behavior.spec.md §2.3), before the actual gated-mutation `plan()` is ever reached. `executeCleanup`
16
- * forwards straight to the gated-mutation gateway's own `execute()` (token redemption, actor-class
15
+ * (behavior.spec.md §2.3), before the actual gated-mutation `plan` is ever reached. `executeCleanup`
16
+ * forwards straight to the gated-mutation gateway's own `execute` (token redemption, actor-class
17
17
  * check, plan-staleness re-check all live there — this module does not re-implement them) and
18
18
  * only performs the actual multi-table removal after the gateway confirms the token; a rejected
19
- * gateway call never triggers any local removal (EC-10, INV-07).
19
+ * gateway call never triggers any local removal.
20
20
  *
21
21
  * How it relates to the project:
22
22
  * `deps.gateway` in `planCleanup`/`executeCleanup` is intentionally two different narrow port
@@ -26,6 +26,7 @@ import type { Result } from "./types.js";
26
26
  *
27
27
  * Architectural role:
28
28
  * `features/content-types` domain logic, composing `write-service.ts`'s `AuthorizeFn` shape.
29
+ * See docs/decisions/DR-002-content-lifecycle-and-cleanup.md.
29
30
  */
30
31
  export interface CleanupEligibilityCheckRepoPort {
31
32
  findByKey(params: {
@@ -52,7 +53,7 @@ export interface PlanCleanupRequired {
52
53
  deps: {
53
54
  repo: CleanupEligibilityCheckRepoPort;
54
55
  gateway: PlanCleanupGatewayPort;
55
- clock: ClockPort;
56
+ clock: Clock;
56
57
  authorize: AuthorizeFn;
57
58
  };
58
59
  input: {
@@ -63,12 +64,13 @@ export interface PlanCleanupRequired {
63
64
  };
64
65
  }
65
66
  /**
66
- * REQ-20 — the fixed-order eligibility gate: `status==='tombstone'` -> retention window elapsed
67
+ * — the fixed-order eligibility gate: `status==='tombstone'` -> retention window elapsed
67
68
  * (>=30 days since `tombstonedAt`, inclusive lower bound) -> `exportReference` present. Only once
68
- * all three pass does this call reach the real `gateway.plan()`.
69
+ * all three pass does this call reach the real `gateway.plan`.
69
70
  *
70
71
  * @complexity O(1) — one repo read, one date diff, one delegated gateway call at most.
71
72
  * @overallScore 100
73
+ * See docs/decisions/DR-002-content-lifecycle-and-cleanup.md.
72
74
  */
73
75
  export declare function planCleanup(required: PlanCleanupRequired): Promise<Result<{
74
76
  planId: string;
@@ -88,7 +90,9 @@ export interface CleanupRemovalRepoPort {
88
90
  }): Promise<{
89
91
  removedEntryCount: number;
90
92
  }>;
91
- transaction<T>(fn: () => Promise<T>): Promise<T>;
93
+ transaction<T>(required: {
94
+ fn: () => Promise<T>;
95
+ }): Promise<T>;
92
96
  }
93
97
  export interface ExecuteCleanupRequired {
94
98
  deps: {
@@ -103,14 +107,15 @@ export interface ExecuteCleanupRequired {
103
107
  };
104
108
  }
105
109
  /**
106
- * REQ-21/INV-07 — forwards straight to the gated-mutation gateway's own `execute()`; only once
110
+ * — forwards straight to the gated-mutation gateway's own `execute`; only once
107
111
  * that confirms (token redeemed, actor-class checked, plan still fresh) does this function perform
108
112
  * the actual atomic multi-table removal. A gateway rejection (expired/already-redeemed token,
109
- * stale plan) is forwarded verbatim and no local removal is ever attempted (EC-10).
113
+ * stale plan) is forwarded verbatim and no local removal is ever attempted.
110
114
  *
111
115
  * @complexity O(1) plus one delegated gateway call and, on success, one same-tx multi-table
112
116
  * removal.
113
117
  * @overallScore 100
118
+ * See docs/decisions/DR-002-content-lifecycle-and-cleanup.md.
114
119
  */
115
120
  export declare function executeCleanup(required: ExecuteCleanupRequired): Promise<Result<{
116
121
  removedEntryCount: number;
@@ -1,30 +1,32 @@
1
+ import { nowIso as kernelNowIso } from "@jini-ai/core/primitives";
1
2
  import { CleanupNotEligibleError } from "./errors.js";
2
3
  const RETENTION_WINDOW_MS = 30 * 24 * 60 * 60 * 1000;
3
4
  /**
4
- * REQ-20 — the fixed-order eligibility gate: `status==='tombstone'` -> retention window elapsed
5
+ * — the fixed-order eligibility gate: `status==='tombstone'` -> retention window elapsed
5
6
  * (>=30 days since `tombstonedAt`, inclusive lower bound) -> `exportReference` present. Only once
6
- * all three pass does this call reach the real `gateway.plan()`.
7
+ * all three pass does this call reach the real `gateway.plan`.
7
8
  *
8
9
  * @complexity O(1) — one repo read, one date diff, one delegated gateway call at most.
9
10
  * @overallScore 100
11
+ * See docs/decisions/DR-002-content-lifecycle-and-cleanup.md.
10
12
  */
11
13
  export async function planCleanup(required) {
12
14
  const { deps, input } = required;
13
15
  const authResult = await deps.authorize({ principalId: input.actorId, permission: "admin.collections.read", workspaceId: input.workspaceId });
14
16
  if (!authResult.allowed) {
15
- return { ok: false, error: new CleanupNotEligibleError("forbidden", `principal '${input.actorId}' is not authorized to plan a cleanup (${authResult.reason})`) };
17
+ return { ok: false, error: new CleanupNotEligibleError({ reason: "forbidden" }, { message: `principal '${input.actorId}' is not authorized to plan a cleanup (${authResult.reason})` }) };
16
18
  }
17
19
  const contentType = await deps.repo.findByKey({ workspaceId: input.workspaceId, key: input.contentTypeKey });
18
20
  if (!contentType || contentType.status !== "tombstone") {
19
- return { ok: false, error: new CleanupNotEligibleError("not_tombstoned") };
21
+ return { ok: false, error: new CleanupNotEligibleError({ reason: "not_tombstoned" }) };
20
22
  }
21
- const now = deps.clock.nowIso();
23
+ const now = kernelNowIso({ clock: deps.clock });
22
24
  const elapsedMs = new Date(now).getTime() - new Date(contentType.tombstonedAt ?? now).getTime();
23
25
  if (elapsedMs < RETENTION_WINDOW_MS) {
24
- return { ok: false, error: new CleanupNotEligibleError("retention_window_not_elapsed") };
26
+ return { ok: false, error: new CleanupNotEligibleError({ reason: "retention_window_not_elapsed" }) };
25
27
  }
26
28
  if (!input.exportReference) {
27
- return { ok: false, error: new CleanupNotEligibleError("export_reference_missing") };
29
+ return { ok: false, error: new CleanupNotEligibleError({ reason: "export_reference_missing" }) };
28
30
  }
29
31
  const planResult = await deps.gateway.plan({
30
32
  principalId: input.actorId,
@@ -34,19 +36,20 @@ export async function planCleanup(required) {
34
36
  action: "cleanup",
35
37
  });
36
38
  if (!planResult.ok) {
37
- return { ok: false, error: new CleanupNotEligibleError("gateway_rejected", String(planResult.error)) };
39
+ return { ok: false, error: new CleanupNotEligibleError({ reason: "gateway_rejected" }, { message: String(planResult.error) }) };
38
40
  }
39
41
  return { ok: true, value: planResult.value };
40
42
  }
41
43
  /**
42
- * REQ-21/INV-07 — forwards straight to the gated-mutation gateway's own `execute()`; only once
44
+ * — forwards straight to the gated-mutation gateway's own `execute`; only once
43
45
  * that confirms (token redeemed, actor-class checked, plan still fresh) does this function perform
44
46
  * the actual atomic multi-table removal. A gateway rejection (expired/already-redeemed token,
45
- * stale plan) is forwarded verbatim and no local removal is ever attempted (EC-10).
47
+ * stale plan) is forwarded verbatim and no local removal is ever attempted.
46
48
  *
47
49
  * @complexity O(1) plus one delegated gateway call and, on success, one same-tx multi-table
48
50
  * removal.
49
51
  * @overallScore 100
52
+ * See docs/decisions/DR-002-content-lifecycle-and-cleanup.md.
50
53
  */
51
54
  export async function executeCleanup(required) {
52
55
  const { deps, input } = required;
@@ -59,7 +62,9 @@ export async function executeCleanup(required) {
59
62
  if (!gatewayResult.ok) {
60
63
  return gatewayResult;
61
64
  }
62
- const removal = await deps.repo.transaction(async () => deps.repo.removeContentTypeAndAllScopedRows({ contentTypeKey: input.contentTypeKey }));
65
+ const removal = await deps.repo.transaction({
66
+ fn: async () => deps.repo.removeContentTypeAndAllScopedRows({ contentTypeKey: input.contentTypeKey }),
67
+ });
63
68
  return { ok: true, value: removal };
64
69
  }
65
70
  //# sourceMappingURL=cleanup.js.map
@@ -30,26 +30,36 @@ import { ToolInputError } from "@jini-ai/core";
30
30
  * marker above.
31
31
  */
32
32
  export declare class ForbiddenError extends ToolInputError {
33
- constructor(message: string);
33
+ constructor({ message }: {
34
+ message: string;
35
+ }, _optional?: Record<string, never>);
34
36
  }
35
- /** CIC U-002-B1 guard 1 — `key`/field-name grammar gate `^[a-z][a-z0-9_]{0,63}$` (U-001-B2). */
37
+ /** guard 1 — `key`/field-name grammar gate `^[a-z][a-z0-9_]{0,63}$`. See docs/decisions/DR-001-safe-schema-and-index-transitions.md. */
36
38
  export declare class InvalidKeyGrammarError extends ToolInputError {
37
- constructor(message: string);
39
+ constructor(requiredArgs: {
40
+ message: string;
41
+ }, optionalArgs?: Record<string, never>);
38
42
  }
39
- /** CIC U-002-B1 guard 2 — `key` is one of the permanently reserved legacy `posts` keys. */
43
+ /** guard 2 — `key` is one of the permanently reserved legacy `posts` keys. See docs/decisions/DR-001-safe-schema-and-index-transitions.md. */
40
44
  export declare class ReservedContentTypeKeyError extends ToolInputError {
41
- constructor(message: string);
45
+ constructor(requiredArgs: {
46
+ message: string;
47
+ }, optionalArgs?: Record<string, never>);
42
48
  }
43
- /** CIC U-002-B1 guard 3 — a field name fails the identifier grammar gate. */
49
+ /** guard 3 — a field name fails the identifier grammar gate. See docs/decisions/DR-001-safe-schema-and-index-transitions.md. */
44
50
  export declare class InvalidFieldNameGrammarError extends ToolInputError {
45
- constructor(message: string);
51
+ constructor(requiredArgs: {
52
+ message: string;
53
+ }, optionalArgs?: Record<string, never>);
46
54
  }
47
- /** CIC U-001-B1 / U-002-B1 guard 4 — a field `kind` is not one of the closed field-kind enum. */
55
+ /** guard 4 — a field `kind` is not one of the closed field-kind enum. See docs/decisions/DR-001-safe-schema-and-index-transitions.md. */
48
56
  export declare class InvalidFieldKindError extends ToolInputError {
49
- constructor(message: string);
57
+ constructor(requiredArgs: {
58
+ message: string;
59
+ }, optionalArgs?: Record<string, never>);
50
60
  }
51
61
  /**
52
- * CIC U-002-B1 guard 4b — a field declares a STORAGE-ONLY `kind` (`json`) together with
62
+ * guard 4b — a field declares a STORAGE-ONLY `kind` (`json`) together with
53
63
  * `queryable: true`. The kind itself is legal and the field may be declared and written; what is
54
64
  * rejected is the pairing, because a storage-only kind has no `CAST` target and therefore no index
55
65
  * to provision.
@@ -62,16 +72,19 @@ export declare class InvalidFieldKindError extends ToolInputError {
62
72
  * `400 VALIDATION_ERROR` with no coordinated change, and the relationship is honest — this IS a
63
73
  * rejection of the field's kind, in the context the kind was used. `.name` still distinguishes it
64
74
  * for any caller that wants the finer signal.
75
+ * See docs/decisions/DR-001-safe-schema-and-index-transitions.md.
65
76
  */
66
77
  export declare class StorageOnlyFieldNotQueryableError extends InvalidFieldKindError {
67
- constructor(message: string);
78
+ constructor(requiredArgs: {
79
+ message: string;
80
+ }, optionalArgs?: Record<string, never>);
68
81
  }
69
82
  /**
70
83
  * A `fields` payload whose STRUCTURE is wrong — not a value that failed a domain rule, but a
71
84
  * shape the `ContentTypeFieldDef[]` contract does not describe at all (a non-array, a non-object
72
85
  * element, a missing/mistyped `name`/`required`/`queryable`, or an unrecognized key).
73
86
  *
74
- * Distinct from the five CIC U-002-B1 guard errors on purpose: those judge a well-formed field
87
+ * Distinct from the five guard errors on purpose: those judge a well-formed field
75
88
  * definition against a domain rule, and they remain the sole owners of the grammar, kind-enum and
76
89
  * queryable-cap decisions. This one fires strictly earlier, at the untrusted-input boundary
77
90
  * (`field-defs.ts`), for payloads the guards could not have judged without either crashing or
@@ -79,6 +92,7 @@ export declare class StorageOnlyFieldNotQueryableError extends InvalidFieldKindE
79
92
  *
80
93
  * `violation.received` names the offending value's TYPE, never the value — a field payload can
81
94
  * carry operator content, and this message reaches both an HTTP client and a model.
95
+ * See docs/decisions/DR-001-safe-schema-and-index-transitions.md.
82
96
  */
83
97
  export declare class InvalidFieldShapeError extends ToolInputError {
84
98
  readonly code: "VALIDATION_ERROR";
@@ -93,29 +107,39 @@ export declare class InvalidFieldShapeError extends ToolInputError {
93
107
  received: string;
94
108
  });
95
109
  }
96
- /** CIC U-002-B1 guard 5 — more than the per-type cap of `queryable` fields were submitted. */
110
+ /** guard 5 — more than the per-type cap of `queryable` fields were submitted. See docs/decisions/DR-001-safe-schema-and-index-transitions.md. */
97
111
  export declare class QueryableFieldCapExceededError extends ToolInputError {
98
- constructor(message: string);
112
+ constructor(requiredArgs: {
113
+ message: string;
114
+ }, optionalArgs?: Record<string, never>);
99
115
  }
100
- /** CIC U-004-B1 — `expectedVersion` did not match the current row's version (OCC conflict). */
116
+ /** — `expectedVersion` did not match the current row's version (OCC conflict). See docs/decisions/DR-001-safe-schema-and-index-transitions.md. */
101
117
  export declare class VersionConflictError extends ToolInputError {
102
- constructor(message: string);
118
+ constructor(requiredArgs: {
119
+ message: string;
120
+ }, optionalArgs?: Record<string, never>);
103
121
  }
104
122
  export declare class ContentTypeNotFoundError extends ToolInputError {
105
- constructor(message: string);
123
+ constructor(requiredArgs: {
124
+ message: string;
125
+ }, optionalArgs?: Record<string, never>);
106
126
  }
107
127
  /**
108
128
  * Row 7 (web-high fix plan, 2026-09-24) — `registerContentType` loaded no existing row before
109
129
  * saving, so two concurrent first-widget creates (or a caller retrying an existing key) could
110
130
  * silently overwrite the current fields, and registering a tombstoned key could resurrect it
111
- * (INV-06 forbids any transition out of tombstone, including via a fresh register). Thrown when
131
+ * ( forbids any transition out of tombstone, including via a fresh register). Thrown when
112
132
  * `deps.repo.findByKey` already returns a row for the key, whether that row is active/deprecated
113
133
  * or tombstoned — `tombstoned` distinguishes the two so a caller/HTTP route can give the right
114
134
  * guidance (retry with update-fields, vs. the key is permanently gone).
135
+ * See docs/decisions/DR-001-safe-schema-and-index-transitions.md.
115
136
  */
116
137
  export declare class ContentTypeAlreadyExistsError extends ToolInputError {
117
138
  readonly tombstoned: boolean;
118
- constructor(key: string, tombstoned: boolean);
139
+ constructor(requiredArgs: {
140
+ key: string;
141
+ tombstoned: boolean;
142
+ }, optionalArgs?: Record<string, never>);
119
143
  }
120
144
  /** A generic validation rejection carrying a stable machine-readable `details.reason`. */
121
145
  export declare class ValidationError extends ToolInputError {
@@ -123,15 +147,24 @@ export declare class ValidationError extends ToolInputError {
123
147
  readonly details: {
124
148
  reason: string;
125
149
  };
126
- constructor(message: string, reason: string);
150
+ constructor(requiredArgs: {
151
+ message: string;
152
+ reason: string;
153
+ }, optionalArgs?: Record<string, never>);
127
154
  }
128
- /** REQ-09..12 lifecycle state-machine guard rejection (INV-06 terminal-tombstone, EC-09 deprecate-first). */
155
+ /**..12 lifecycle state-machine guard rejection ( terminal-tombstone, deprecate-first). See docs/decisions/DR-001-safe-schema-and-index-transitions.md. */
129
156
  export declare class ContentTypeLifecycleError extends ToolInputError {
130
- constructor(message: string);
157
+ constructor(requiredArgs: {
158
+ message: string;
159
+ }, optionalArgs?: Record<string, never>);
131
160
  }
132
- /** REQ-20 `planCleanup` eligibility-gate rejection; `reason` is one of a closed, ordered set. */
161
+ /** `planCleanup` eligibility-gate rejection; `reason` is one of a closed, ordered set. See docs/decisions/DR-001-safe-schema-and-index-transitions.md. */
133
162
  export declare class CleanupNotEligibleError extends Error {
134
163
  readonly reason: string;
135
- constructor(reason: string, message?: string);
164
+ constructor(requiredArgs: {
165
+ reason: string;
166
+ }, optionalArgs?: {
167
+ message?: string;
168
+ });
136
169
  }
137
170
  //# sourceMappingURL=errors.d.ts.map