@jini-ai/cms 0.3.11 → 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 +103 -44
  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
@@ -1,69 +1,4 @@
1
- /**
2
- * @file The Taxonomy agent-tool catalog — this domain's instance of the per-domain
3
- * `agent-tools.ts` convention `features/content-types/agent-tools.ts`,
4
- * `features/database/agent-tools.ts`, and every other domain catalog already use.
5
- *
6
- * Purpose:
7
- * A static, in-process catalog describing every agent-callable tool this domain exposes. Every
8
- * WRITE entry maps 1:1 onto a real exported function of `features/taxonomy/write-service.ts`
9
- * (`createTaxonomy`, `createTerm`, `renameTerm`, `assignTerms`); the one read maps onto
10
- * `features/taxonomy/list.ts`'s `listTaxonomiesWithTerms`.
11
- *
12
- * `mergeTerm` (`merge-term.ts`) — read carefully, treated with the same scrutiny Database's
13
- * `migrate-forward` and Recovery's `restore` ceremonies got:
14
- * Merge is destructive and can silently lose pre-merge `entry_terms` assignment history for content
15
- * already assigned to both terms (`merge-term.ts`'s own file header: "Destructive term
16
- * merge" failure mode). That is why it alone, of every taxonomy mutation, gets a plan/confirm/
17
- * execute ceremony through `core/gated-mutations` rather than an ordinary authorize-then-write.
18
- * Reading `core/gated-mutations/gateway.ts` directly settles what is and is not safe to hand an
19
- * agent:
20
- * - `plan()` "Never invokes `hooks.executeMutation()` — a plan is read-only by construction
21
- * (AC-10)" (`gateway.ts`'s own doc comment). It authorizes `admin.taxonomy.manage`, recomputes
22
- * the live overlap-loss disclosure, and returns a plan. Persists nothing. Safe to wire as a
23
- * READ, mirroring `features/database/agent-tools.ts`'s identical `database_plan_migrate_forward`
24
- * precedent (same file's own comment: "the step that actually redeems a plan into a mutation
25
- * (confirm()) can never be reached by an agent principal at all").
26
- * - `confirm()` structurally refuses an agent: `gateway.ts`'s own body — "if (principalKind ===
27
- * 'agent') throw new ForbiddenError('agent principals may not confirm a gated mutation', ...)"
28
- * — before any permission check even runs. No `taxonomy_confirm_merge_term`-equivalent tool
29
- * exists in this catalog.
30
- * - `taxonomy_execute_merge_term` (2026-09-24) asks the human in chat before it runs: the host
31
- * wires it with the kit's `humanConfirmedHandler`, which shows a confirm dialog and only on the
32
- * human's own click confirms as that human (`kind='user'`) and executes as the agent acting for
33
- * them — the `confirmer-must-equal-own-delegatedBy` rule. The model never sees or supplies a
34
- * token. A merge deletes the source term's assignments with no Trash or undo, so it is gated.
35
- *
36
- * Naming: `taxonomy_*`, matching this package's own name — distinct from `features/content-types`'
37
- * `collections_*` prefix (a different pairing) and from `features/entries`' own
38
- * `collections_entry_*` prefix.
39
- *
40
- * How it relates to the project:
41
- * `features/taxonomy/tool-registrations.ts` maps these entries into `@jini-ai/core`
42
- * `ToolRegistration`s.
43
- *
44
- * Architectural role:
45
- * `features/taxonomy` domain declaration. As of A2 (taxonomy plan) it imports nothing from its own
46
- * `write-service.ts` — `contentType` is published as an open string (see `CONTENT_TYPE_SCHEMA`
47
- * below), since Collections entries widened the set of legal values past the fixed `post`/`page`
48
- * allow-list this file used to mirror as an `enum`.
49
- */
50
- export type AgentToolSideEffect = "none" | "mutates-durable-state" | "mints-token";
51
- export type AgentToolActorClassRule = "confirmer-must-equal-own-delegatedBy" | "user-only" | "none";
52
- export interface AgentToolDefinition {
53
- name: string;
54
- description: string;
55
- sideEffects: AgentToolSideEffect;
56
- authorization: {
57
- permission: string;
58
- };
59
- actorClassRule?: AgentToolActorClassRule;
60
- /**
61
- * JSON Schema for this tool's `input`, published to the model via `ToolDescriptor.inputSchema`
62
- * (`assistant/tool-registration-kit.ts`'s `buildDomainRegistrations`, which refuses to wire any
63
- * tool lacking one).
64
- */
65
- inputSchema?: Readonly<Record<string, unknown>>;
66
- }
1
+ import type { AgentToolDefinition } from "@jini-ai/core";
67
2
  /** The Taxonomy domain's fixed agent-tool catalog: 7 wired (1 read, 5 ordinary writes, 1 gated-plan
68
3
  * read) + 1 declared-but-never-wired destructive tool — see this file's header for the full
69
4
  * `mergeTerm` safety analysis. */
@@ -17,21 +17,21 @@
17
17
  * execute ceremony through `core/gated-mutations` rather than an ordinary authorize-then-write.
18
18
  * Reading `core/gated-mutations/gateway.ts` directly settles what is and is not safe to hand an
19
19
  * agent:
20
- * - `plan()` "Never invokes `hooks.executeMutation()` — a plan is read-only by construction
21
- * (AC-10)" (`gateway.ts`'s own doc comment). It authorizes `admin.taxonomy.manage`, recomputes
22
- * the live overlap-loss disclosure, and returns a plan. Persists nothing. Safe to wire as a
23
- * READ, mirroring `features/database/agent-tools.ts`'s identical `database_plan_migrate_forward`
24
- * precedent (same file's own comment: "the step that actually redeems a plan into a mutation
25
- * (confirm()) can never be reached by an agent principal at all").
26
- * - `confirm()` structurally refuses an agent: `gateway.ts`'s own body — "if (principalKind ===
27
- * 'agent') throw new ForbiddenError('agent principals may not confirm a gated mutation', ...)"
28
- * — before any permission check even runs. No `taxonomy_confirm_merge_term`-equivalent tool
29
- * exists in this catalog.
30
- * - `taxonomy_execute_merge_term` (2026-09-24) asks the human in chat before it runs: the host
31
- * wires it with the kit's `humanConfirmedHandler`, which shows a confirm dialog and only on the
32
- * human's own click confirms as that human (`kind='user'`) and executes as the agent acting for
33
- * them — the `confirmer-must-equal-own-delegatedBy` rule. The model never sees or supplies a
34
- * token. A merge deletes the source term's assignments with no Trash or undo, so it is gated.
20
+ * - `plan` "Never invokes `hooks.executeMutation` — a plan is read-only by construction
21
+ * " (`gateway.ts`'s own doc comment). It authorizes `admin.taxonomy.manage`, recomputes
22
+ * the live overlap-loss disclosure, and returns a plan. Persists nothing. Safe to wire as a
23
+ * READ, mirroring `features/database/agent-tools.ts`'s identical `database_plan_migrate_forward`
24
+ * precedent (same file's own comment: "the step that actually redeems a plan into a mutation
25
+ * (confirm) can never be reached by an agent principal at all").
26
+ * - `confirm` structurally refuses an agent: `gateway.ts`'s own body — "if (principalKind ===
27
+ * 'agent') throw new ForbiddenError('agent principals may not confirm a gated mutation',...)"
28
+ * — before any permission check even runs. No `taxonomy_confirm_merge_term`-equivalent tool
29
+ * exists in this catalog.
30
+ * - `taxonomy_execute_merge_term` (2026-09-24) asks the human in chat before it runs: the host
31
+ * wires it with the kit's `humanConfirmedHandler`, which shows a confirm dialog and only on the
32
+ * human's own click confirms as that human (`kind='user'`) and executes as the agent acting for
33
+ * them — the `confirmer-must-equal-own-delegatedBy` rule. The model never sees or supplies a
34
+ * token. A merge deletes the source term's assignments with no Trash or undo, so it is gated.
35
35
  *
36
36
  * Naming: `taxonomy_*`, matching this package's own name — distinct from `features/content-types`'
37
37
  * `collections_*` prefix (a different pairing) and from `features/entries`' own
@@ -46,7 +46,17 @@
46
46
  * `write-service.ts` — `contentType` is published as an open string (see `CONTENT_TYPE_SCHEMA`
47
47
  * below), since Collections entries widened the set of legal values past the fixed `post`/`page`
48
48
  * allow-list this file used to mirror as an `enum`.
49
+ * See docs/decisions/DR-005-ordered-taxonomy-validation.md.
49
50
  */
51
+ // A2 (taxonomy plan) — no longer imported: `CONTENT_TYPE_SCHEMA` used to build its `enum` from
52
+ // this set, which would reject a Collection key (any `contentType` other than `post`/`page`) at
53
+ // the agent's own input-schema validation, before the write-service's `contentTypeTaxonomyPolicy`
54
+ // ever gets a chance to decide eligibility. See `CONTENT_TYPE_SCHEMA`'s doc comment below.
55
+ /**
56
+ * JSON Schema for this tool's `input`, published to the model via `ToolDescriptor.inputSchema`
57
+ * (`@jini-ai/core`'s `registration-kit.ts`'s `buildDomainRegistrations`, which refuses to wire any
58
+ * tool lacking one).
59
+ */
50
60
  const TAXONOMY_ID_SCHEMA = {
51
61
  type: "string",
52
62
  minLength: 1,
@@ -40,7 +40,7 @@ export function createContentLookup(deps) {
40
40
  const entryLookup = createEntryBackedContentLookup({ entryRepo: deps.entryRepo, workspaceId: deps.workspaceId });
41
41
  return {
42
42
  async resolve(params) {
43
- return isContentTypeOnAllowList(params.contentType) ? postLookup.resolve(params) : entryLookup.resolve(params);
43
+ return isContentTypeOnAllowList({ contentType: params.contentType }) ? postLookup.resolve(params) : entryLookup.resolve(params);
44
44
  },
45
45
  };
46
46
  }
@@ -19,7 +19,7 @@
19
19
  * has no imports at all: the ceremony is a parameter, not a dependency.
20
20
  */
21
21
  export { TaxonomyNotApplicableError, WorkspaceMismatchError, ContentTypeMismatchError, TaxonomyNotHierarchicalError, ParentCrossTaxonomyError, TermNotFoundError, HierarchyCycleDetectedError, wouldCreateCycle, validateContentJoin, validateHierarchyAssignment, type TermTreeLookup, } from "./validation-chain.js";
22
- export { TAXONOMY_ALLOWED_CONTENT_TYPES, isContentTypeOnAllowList, TaxonomyRecordNotFoundError, TermRecordNotFoundError, ContentRecordNotFoundError, TermHasAssignedContentError, TermHasChildTermsError, TaxonomyHasAssignedContentError, TaxonomyVersionConflictError, createTaxonomy, createTerm, renameTerm, assignTerms, unassignTerms, deleteTerm, deleteTaxonomy, onContentDeleted, importTaxonomy, importTerm, type AuthorizeFn, type Taxonomy, type Term, type TaxonomyRepoPort, type TermRepoPort, type EntryTermRepoPort, type ContentLookupPort, type ContentTypeTaxonomyPolicyPort, type UnassignableEntryTermRepoPort, type TaxonomyRevisionRow, type TaxonomyRevisionRepoPort, type ClockPort, type IdGeneratorPort, type WriteServiceDeps, type CreateTaxonomyRequired, type CreateTermRequired, type RenameTermRequired, type AssignTermsRequired, type UnassignTermsRequired, type DeleteTermRequired, type DeleteTaxonomyRequired, type DeletableTaxonomyRepoPort, type DeletableTermRepoPort, type AssignmentCountEntryTermRepoPort, type TransactionalRepoPort, type EntryTermsCleanupPort, type OnContentDeletedRequired, type ImportableTaxonomyRepoPort, type ImportableTermRepoPort, type ImportTaxonomyRequired, type ImportTermRequired, } from "./write-service.js";
22
+ export { TAXONOMY_ALLOWED_CONTENT_TYPES, isContentTypeOnAllowList, TaxonomyRecordNotFoundError, TermRecordNotFoundError, ContentRecordNotFoundError, TermHasAssignedContentError, TermHasChildTermsError, TaxonomyHasAssignedContentError, TaxonomyVersionConflictError, createTaxonomy, createTerm, renameTerm, assignTerms, unassignTerms, deleteTerm, deleteTaxonomy, onContentDeleted, importTaxonomy, importTerm, type AuthorizeFn, type Taxonomy, type Term, type TaxonomyRepoPort, type TermRepoPort, type EntryTermRepoPort, type ContentLookupPort, type ContentTypeTaxonomyPolicyPort, type UnassignableEntryTermRepoPort, type TaxonomyRevisionRow, type TaxonomyRevisionRepoPort, type WriteServiceDeps, type CreateTaxonomyRequired, type CreateTermRequired, type CreateTermOptional, type RenameTermRequired, type AssignTermsRequired, type UnassignTermsRequired, type DeleteTermRequired, type DeleteTaxonomyRequired, type DeletableTaxonomyRepoPort, type DeletableTermRepoPort, type AssignmentCountEntryTermRepoPort, type TransactionalRepoPort, type EntryTermsCleanupPort, type OnContentDeletedRequired, type ImportableTaxonomyRepoPort, type ImportableTermRepoPort, type ImportTaxonomyRequired, type ImportTermRequired, type ImportTermOptional, } from "./write-service.js";
23
23
  export { listTaxonomiesWithTerms, type TaxonomyListPort, type TermListPort, type TaxonomyWithTerms, } from "./list.js";
24
24
  /**
25
25
  * The domain half of the `mergeTerm` ceremony — see this file's header for why the gateway itself
@@ -34,5 +34,5 @@ export { InMemoryTaxonomyRepo, InMemoryTermRepo, InMemoryEntryTermRepo, InMemory
34
34
  */
35
35
  export { createPostBackedContentLookup, createEntryBackedContentLookup, createContentLookup, type ContentRecordLookupPort, type EntryRecordLookupPort, } from "./content-lookup.js";
36
36
  /** The agent-tool surface for this domain (see `agent-tools.ts` for what is deliberately omitted). */
37
- export { taxonomyAgentToolCatalog, type AgentToolDefinition as TaxonomyAgentToolDefinition, type AgentToolSideEffect as TaxonomyAgentToolSideEffect, type AgentToolActorClassRule as TaxonomyAgentToolActorClassRule, } from "./agent-tools.js";
37
+ export { taxonomyAgentToolCatalog, } from "./agent-tools.js";
38
38
  //# sourceMappingURL=index.d.ts.map
@@ -17,7 +17,9 @@
17
17
  * enforced by `merge-term.unit.test.ts`'s own export-surface inspection.
18
18
  */
19
19
  export declare class SameTermMergeError extends Error {
20
- constructor(message: string);
20
+ constructor(requiredArgs: {
21
+ message: string;
22
+ }, optionalArgs?: Record<string, never>);
21
23
  }
22
24
  export interface MergeTermPlanDetails {
23
25
  fromTermId: string;
@@ -43,13 +45,14 @@ export interface PlanMergeTermRequired {
43
45
  }>;
44
46
  }
45
47
  /**
46
- * AC-22a/REQ-15a/INV-08 — rejects `fromTermId === intoTermId` structurally BEFORE
47
- * `computeOverlap()` ever runs (no plan, therefore no token, can ever exist for a self-merge).
48
- * AC-23/AC-24/REQ-16 — the returned plan discloses whether the merge would lose any pre-existing
48
+ * — rejects `fromTermId === intoTermId` structurally BEFORE
49
+ * `computeOverlap` ever runs (no plan, therefore no token, can ever exist for a self-merge).
50
+ * — the returned plan discloses whether the merge would lose any pre-existing
49
51
  * overlapping assignment (never a false "no loss" when `overlappingContentCount > 0`).
50
52
  *
51
53
  * @complexity O(1) plus the caller-supplied `computeOverlap`/`gatewayPlan` costs.
52
54
  * @overallScore 100
55
+ * See docs/decisions/DR-005-ordered-taxonomy-validation.md.
53
56
  */
54
57
  export declare function planMergeTerm(required: PlanMergeTermRequired, _optional?: Record<string, never>): Promise<{
55
58
  planId: string;
@@ -17,24 +17,26 @@
17
17
  * enforced by `merge-term.unit.test.ts`'s own export-surface inspection.
18
18
  */
19
19
  export class SameTermMergeError extends Error {
20
- constructor(message) {
20
+ constructor(requiredArgs, optionalArgs = {}) {
21
+ const { message } = requiredArgs;
21
22
  super(message);
22
23
  this.name = "SameTermMergeError";
23
24
  }
24
25
  }
25
26
  /**
26
- * AC-22a/REQ-15a/INV-08 — rejects `fromTermId === intoTermId` structurally BEFORE
27
- * `computeOverlap()` ever runs (no plan, therefore no token, can ever exist for a self-merge).
28
- * AC-23/AC-24/REQ-16 — the returned plan discloses whether the merge would lose any pre-existing
27
+ * — rejects `fromTermId === intoTermId` structurally BEFORE
28
+ * `computeOverlap` ever runs (no plan, therefore no token, can ever exist for a self-merge).
29
+ * — the returned plan discloses whether the merge would lose any pre-existing
29
30
  * overlapping assignment (never a false "no loss" when `overlappingContentCount > 0`).
30
31
  *
31
32
  * @complexity O(1) plus the caller-supplied `computeOverlap`/`gatewayPlan` costs.
32
33
  * @overallScore 100
34
+ * See docs/decisions/DR-005-ordered-taxonomy-validation.md.
33
35
  */
34
36
  export async function planMergeTerm(required, _optional = {}) {
35
37
  const { fromTermId, intoTermId, computeOverlap, gatewayPlan } = required;
36
38
  if (fromTermId === intoTermId) {
37
- throw new SameTermMergeError(`cannot merge term '${fromTermId}' into itself`);
39
+ throw new SameTermMergeError({ message: `cannot merge term '${fromTermId}' into itself` });
38
40
  }
39
41
  const { overlappingContentCount } = await computeOverlap();
40
42
  const details = {
@@ -1,3 +1,4 @@
1
+ import type { Clock } from "@jini-ai/core/primitives";
1
2
  import type { ContentLookupPort, EntryTermRepoPort, TaxonomyRepoPort, TaxonomyRevisionRepoPort, TaxonomyRevisionRow, Term, TermRepoPort, UnassignableEntryTermRepoPort } from "./write-service.js";
2
3
  import type { Taxonomy } from "./write-service.js";
3
4
  import type { TaxonomyListPort, TermListPort } from "./list.js";
@@ -8,20 +9,26 @@ import type { TaxonomyListPort, TermListPort } from "./list.js";
8
9
  export declare class InMemoryTaxonomyRepo implements TaxonomyRepoPort, TaxonomyListPort {
9
10
  private readonly rows;
10
11
  insert(row: Taxonomy): Promise<unknown>;
11
- findById(id: string): Promise<{
12
+ findById({ id }: {
13
+ id: string;
14
+ }): Promise<{
12
15
  id: string;
13
16
  hierarchical: boolean;
14
17
  allowList?: string[] | undefined;
15
18
  } | null>;
16
19
  /** `ImportableTaxonomyRepoPort` — additive capability for `importTaxonomy`'s CAS check and
17
20
  * update-in-place, see `write-service.ts`'s doc comment on that interface. */
18
- findByIdFull(id: string): Promise<Taxonomy | null>;
21
+ findByIdFull({ id }: {
22
+ id: string;
23
+ }): Promise<Taxonomy | null>;
19
24
  /** `ImportableTaxonomyRepoPort` — writes an existing row back in place, preserving its id. */
20
25
  update(row: Taxonomy): Promise<unknown>;
21
26
  list(): Promise<Taxonomy[]>;
22
27
  /** `DeletableTaxonomyRepoPort` — additive capability for `deleteTaxonomy`, see
23
28
  * `write-service.ts`'s doc comment on that interface. */
24
- delete(id: string): Promise<void>;
29
+ delete({ id }: {
30
+ id: string;
31
+ }): Promise<void>;
25
32
  /**
26
33
  * `TransactionalRepoPort` — disclosed narrowing, not a silently-wrong implementation of a real
27
34
  * capability (same disclosure style as `noopStampWatermark` below): a plain in-process `Map` has
@@ -38,30 +45,40 @@ export declare class InMemoryTaxonomyRepo implements TaxonomyRepoPort, TaxonomyL
38
45
  * app.ts`'s hermetic composition), never the host of a real workspace's real content, which is
39
46
  * why this gap is accepted here rather than closed.
40
47
  */
41
- transaction<T>(fn: () => Promise<T>): Promise<T>;
48
+ transaction<T>({ fn }: {
49
+ fn: () => Promise<T>;
50
+ }): Promise<T>;
42
51
  }
43
52
  export declare class InMemoryTermRepo implements TermRepoPort, TermListPort {
44
53
  private readonly rows;
45
54
  insert(row: Term): Promise<unknown>;
46
55
  update(row: Term): Promise<unknown>;
47
- findById(id: string): Promise<{
56
+ findById({ id }: {
57
+ id: string;
58
+ }): Promise<{
48
59
  id: string;
49
60
  taxonomyId: string;
50
61
  name?: string | undefined;
51
62
  } | null>;
52
63
  /** `ImportableTermRepoPort` — additive capability for `importTerm`'s CAS check, see
53
64
  * `write-service.ts`'s doc comment on that interface. */
54
- findByIdFull(id: string): Promise<Term | null>;
65
+ findByIdFull({ id }: {
66
+ id: string;
67
+ }): Promise<Term | null>;
55
68
  listByTaxonomy(params: {
56
69
  taxonomyId: string;
57
70
  }): Promise<Term[]>;
58
71
  /** Ancestor-chain lookup for `validation-chain.ts`'s `wouldCreateCycle` — not required by any
59
72
  * currently-wired route (reparent has no route this pass, design-spec.md §2.8), kept here so a
60
73
  * future reparent route has a ready-made `TermTreeLookup` to inject. */
61
- getParentId(termId: string): string | null;
74
+ getParentId({ termId }: {
75
+ termId: string;
76
+ }): string | null;
62
77
  /** `DeletableTermRepoPort` — additive capability for `deleteTerm`/`deleteTaxonomy`, see
63
78
  * `write-service.ts`'s doc comment on that interface. */
64
- delete(id: string): Promise<void>;
79
+ delete({ id }: {
80
+ id: string;
81
+ }): Promise<void>;
65
82
  /** `DeletableTermRepoPort.countChildren` — direct children only (one level), matching
66
83
  * `deleteTerm`'s guard (it does not recurse past the first level; a grandchild whose direct
67
84
  * parent is itself already blocked from deletion is caught when that intermediate term's own
@@ -124,15 +141,21 @@ export declare class InMemoryTaxonomyRevisionRepo implements TaxonomyRevisionRep
124
141
  */
125
142
  export declare class InMemoryContentLookup implements ContentLookupPort {
126
143
  private readonly rows;
127
- constructor(seed?: Array<{
144
+ constructor(requiredArgs: Record<string, never>, optionalArgs?: {
145
+ seed?: Array<{
146
+ contentType: string;
147
+ contentId: string;
148
+ workspaceId: string;
149
+ kind: string;
150
+ }>;
151
+ });
152
+ set({ contentType, contentId, value }: {
128
153
  contentType: string;
129
154
  contentId: string;
130
- workspaceId: string;
131
- kind: string;
132
- }>);
133
- set(contentType: string, contentId: string, value: {
134
- workspaceId: string;
135
- kind: string;
155
+ value: {
156
+ workspaceId: string;
157
+ kind: string;
158
+ };
136
159
  }): void;
137
160
  resolve(params: {
138
161
  contentType: string;
@@ -161,9 +184,7 @@ export declare function toTaxonomyOutbox(deps: {
161
184
  payload: Record<string, unknown>;
162
185
  }): Promise<void>;
163
186
  };
164
- clock: {
165
- nowIso(): string;
166
- };
187
+ clock: Clock;
167
188
  idGen: {
168
189
  newId(): string;
169
190
  };
@@ -172,6 +193,8 @@ export declare function toTaxonomyOutbox(deps: {
172
193
  * (`{name, taxonomyId, actorId, occurredAt}`) carry no `workspaceId` at all. */
173
194
  workspaceId: string;
174
195
  }): {
175
- enqueue: (event: unknown) => Promise<void>;
196
+ enqueue: ({ event }: {
197
+ event: unknown;
198
+ }) => Promise<void>;
176
199
  };
177
200
  //# sourceMappingURL=repo.memory.d.ts.map
@@ -1,3 +1,4 @@
1
+ import { nowIso as kernelNowIso } from "@jini-ai/core/primitives";
1
2
  /**
2
3
  * @file In-memory adapters for the `taxonomy` package's write/list ports — same disclosed
3
4
  * rule-of-two-until-a-real-adapter-exists precedent as `features/content-types/repo.memory.ts`.
@@ -8,13 +9,13 @@ export class InMemoryTaxonomyRepo {
8
9
  this.rows.set(row.id, { ...row });
9
10
  return row;
10
11
  }
11
- async findById(id) {
12
+ async findById({ id }) {
12
13
  const row = this.rows.get(id);
13
14
  return row ? { id: row.id, hierarchical: row.hierarchical } : null;
14
15
  }
15
16
  /** `ImportableTaxonomyRepoPort` — additive capability for `importTaxonomy`'s CAS check and
16
17
  * update-in-place, see `write-service.ts`'s doc comment on that interface. */
17
- async findByIdFull(id) {
18
+ async findByIdFull({ id }) {
18
19
  const row = this.rows.get(id);
19
20
  return row ? { ...row } : null;
20
21
  }
@@ -28,7 +29,7 @@ export class InMemoryTaxonomyRepo {
28
29
  }
29
30
  /** `DeletableTaxonomyRepoPort` — additive capability for `deleteTaxonomy`, see
30
31
  * `write-service.ts`'s doc comment on that interface. */
31
- async delete(id) {
32
+ async delete({ id }) {
32
33
  this.rows.delete(id);
33
34
  }
34
35
  /**
@@ -47,7 +48,7 @@ export class InMemoryTaxonomyRepo {
47
48
  * app.ts`'s hermetic composition), never the host of a real workspace's real content, which is
48
49
  * why this gap is accepted here rather than closed.
49
50
  */
50
- async transaction(fn) {
51
+ async transaction({ fn }) {
51
52
  return fn();
52
53
  }
53
54
  }
@@ -61,13 +62,13 @@ export class InMemoryTermRepo {
61
62
  this.rows.set(row.id, { ...row });
62
63
  return row;
63
64
  }
64
- async findById(id) {
65
+ async findById({ id }) {
65
66
  const row = this.rows.get(id);
66
67
  return row ? { id: row.id, taxonomyId: row.taxonomyId, name: row.name } : null;
67
68
  }
68
69
  /** `ImportableTermRepoPort` — additive capability for `importTerm`'s CAS check, see
69
70
  * `write-service.ts`'s doc comment on that interface. */
70
- async findByIdFull(id) {
71
+ async findByIdFull({ id }) {
71
72
  const row = this.rows.get(id);
72
73
  return row ? { ...row } : null;
73
74
  }
@@ -77,12 +78,12 @@ export class InMemoryTermRepo {
77
78
  /** Ancestor-chain lookup for `validation-chain.ts`'s `wouldCreateCycle` — not required by any
78
79
  * currently-wired route (reparent has no route this pass, design-spec.md §2.8), kept here so a
79
80
  * future reparent route has a ready-made `TermTreeLookup` to inject. */
80
- getParentId(termId) {
81
+ getParentId({ termId }) {
81
82
  return this.rows.get(termId)?.parentId ?? null;
82
83
  }
83
84
  /** `DeletableTermRepoPort` — additive capability for `deleteTerm`/`deleteTaxonomy`, see
84
85
  * `write-service.ts`'s doc comment on that interface. */
85
- async delete(id) {
86
+ async delete({ id }) {
86
87
  this.rows.delete(id);
87
88
  }
88
89
  /** `DeletableTermRepoPort.countChildren` — direct children only (one level), matching
@@ -167,10 +168,11 @@ export class InMemoryTaxonomyRevisionRepo {
167
168
  */
168
169
  export class InMemoryContentLookup {
169
170
  rows;
170
- constructor(seed = []) {
171
+ constructor(requiredArgs, optionalArgs = {}) {
172
+ const { seed = [] } = optionalArgs;
171
173
  this.rows = new Map(seed.map((s) => [`${s.contentType}::${s.contentId}`, { workspaceId: s.workspaceId, kind: s.kind }]));
172
174
  }
173
- set(contentType, contentId, value) {
175
+ set({ contentType, contentId, value }) {
174
176
  this.rows.set(`${contentType}::${contentId}`, value);
175
177
  }
176
178
  async resolve(params) {
@@ -188,10 +190,10 @@ export function noopStampWatermark() { }
188
190
  * shape), so this wrapper forwards them as the full event payload rather than re-nesting. */
189
191
  export function toTaxonomyOutbox(deps) {
190
192
  return {
191
- enqueue: async (event) => {
193
+ enqueue: async ({ event }) => {
192
194
  const record = event;
193
195
  const name = typeof record.name === "string" ? record.name : "taxonomy.event";
194
- const occurredAt = typeof record.occurredAt === "string" ? record.occurredAt : deps.clock.nowIso();
196
+ const occurredAt = typeof record.occurredAt === "string" ? record.occurredAt : kernelNowIso({ clock: deps.clock });
195
197
  await deps.outbox.enqueue({ id: deps.idGen.newId(), workspaceId: deps.workspaceId, name, occurredAt, payload: record });
196
198
  },
197
199
  };
@@ -25,35 +25,51 @@
25
25
  * their own repo lookups, so the ordering guarantee holds regardless of how a caller wires them.
26
26
  */
27
27
  export declare class TaxonomyNotApplicableError extends Error {
28
- constructor(message: string);
28
+ constructor(requiredArgs: {
29
+ message: string;
30
+ }, optionalArgs?: Record<string, never>);
29
31
  }
30
32
  export declare class WorkspaceMismatchError extends Error {
31
- constructor(message: string);
33
+ constructor(requiredArgs: {
34
+ message: string;
35
+ }, optionalArgs?: Record<string, never>);
32
36
  }
33
37
  export declare class ContentTypeMismatchError extends Error {
34
- constructor(message: string);
38
+ constructor(requiredArgs: {
39
+ message: string;
40
+ }, optionalArgs?: Record<string, never>);
35
41
  }
36
42
  export declare class TaxonomyNotHierarchicalError extends Error {
37
- constructor(message: string);
43
+ constructor(requiredArgs: {
44
+ message: string;
45
+ }, optionalArgs?: Record<string, never>);
38
46
  }
39
47
  export declare class ParentCrossTaxonomyError extends Error {
40
- constructor(message: string);
48
+ constructor(requiredArgs: {
49
+ message: string;
50
+ }, optionalArgs?: Record<string, never>);
41
51
  }
42
52
  export declare class TermNotFoundError extends Error {
43
- constructor(message: string);
53
+ constructor(requiredArgs: {
54
+ message: string;
55
+ }, optionalArgs?: Record<string, never>);
44
56
  }
45
57
  export declare class HierarchyCycleDetectedError extends Error {
46
- constructor(message: string);
58
+ constructor(requiredArgs: {
59
+ message: string;
60
+ }, optionalArgs?: Record<string, never>);
47
61
  }
48
62
  /** Ancestor-chain lookup a cycle check walks. `null` marks a root (no parent). */
49
63
  export interface TermTreeLookup {
50
- getParentId(termId: string): string | null;
64
+ getParentId({ termId }: {
65
+ termId: string;
66
+ }): string | null;
51
67
  }
52
68
  /**
53
- * CIC U-002 — true if assigning `candidateParentId` as `termId`'s parent would create a cycle:
69
+ * — true if assigning `candidateParentId` as `termId`'s parent would create a cycle:
54
70
  * either immediate self-parenting, or `termId` appearing anywhere in `candidateParentId`'s own
55
71
  * ancestor chain. A full recursive walk, not a fixed-depth or immediate-parent-only comparison
56
- * (U-002-B1) — the exact shape a naive implementation gets wrong (a 3+-hop cycle is the
72
+ * — the exact shape a naive implementation gets wrong (a 3+-hop cycle is the
57
73
  * regression case this exists to catch).
58
74
  *
59
75
  * A `visited` guard bounds the walk even against a pre-existing malformed tree (defensive; no
@@ -62,6 +78,7 @@ export interface TermTreeLookup {
62
78
  *
63
79
  * @complexity O(depth) — one `getParentId` call per ancestor hop, each hop visited at most once.
64
80
  * @overallScore 100
81
+ * See docs/decisions/DR-005-ordered-taxonomy-validation.md.
65
82
  */
66
83
  export declare function wouldCreateCycle(required: {
67
84
  termId: string;
@@ -69,13 +86,14 @@ export declare function wouldCreateCycle(required: {
69
86
  tree: TermTreeLookup;
70
87
  }, _optional?: Record<string, never>): boolean;
71
88
  /**
72
- * U-001-B1/ORD1/ORD2 — the content-join chain: allow-list, THEN workspace, THEN lens, in that
73
- * fixed order. A combined-failure case always reports the first-in-order failure (U-001-ORD1:
74
- * not-on-allow-list always wins over a simultaneous workspace mismatch; U-001-ORD2: a workspace
89
+ * /ORD1/ORD2 — the content-join chain: allow-list, THEN workspace, THEN lens, in that
90
+ * fixed order. A combined-failure case always reports the first-in-order failure (:
91
+ * not-on-allow-list always wins over a simultaneous workspace mismatch; : a workspace
75
92
  * mismatch always wins over a simultaneous lens mismatch).
76
93
  *
77
94
  * @complexity O(1) — three independent comparisons, no loop.
78
95
  * @overallScore 100
96
+ * See docs/decisions/DR-005-ordered-taxonomy-validation.md.
79
97
  */
80
98
  export declare function validateContentJoin(required: {
81
99
  taxonomyId: string;
@@ -87,18 +105,19 @@ export declare function validateContentJoin(required: {
87
105
  resolvedContentKind: string;
88
106
  }, _optional?: Record<string, never>): void;
89
107
  /**
90
- * U-001-B2/B3/ORD3 — the hierarchy chain: hierarchical-mode, THEN same-taxonomy (distinguishing
108
+ * /B3/ORD3 — the hierarchy chain: hierarchical-mode, THEN same-taxonomy (distinguishing
91
109
  * not-found from wrong-taxonomy), THEN cycle, in that fixed order. `null` `candidateParentId`
92
- * (no parent assignment attempted) always short-circuits to a pass regardless of mode (RT-012's
110
+ * (no parent assignment attempted) always short-circuits to a pass regardless of mode (
93
111
  * regression: a no-op parent write must never be rejected).
94
112
  *
95
- * The compound RT-001 regression this chain exists to prevent: a flat taxonomy's candidate parent
113
+ * The compound regression this chain exists to prevent: a flat taxonomy's candidate parent
96
114
  * that ALSO happens to exist in a different taxonomy must report `TAXONOMY_NOT_HIERARCHICAL`,
97
115
  * never `PARENT_CROSS_TAXONOMY` — hierarchical-mode is checked first and is decisive on its own.
98
116
  *
99
- * @complexity O(1) plus the injected `wouldCreateCycle` closure's own cost (U-002, only reached
117
+ * @complexity O(1) plus the injected `wouldCreateCycle` closure's own cost (only reached
100
118
  * once hierarchical-mode and same-taxonomy both pass).
101
119
  * @overallScore 100
120
+ * See docs/decisions/DR-005-ordered-taxonomy-validation.md.
102
121
  */
103
122
  export declare function validateHierarchyAssignment(required: {
104
123
  childTaxonomyId: string;
@@ -108,7 +127,9 @@ export declare function validateHierarchyAssignment(required: {
108
127
  id: string;
109
128
  taxonomyId: string;
110
129
  } | null | "not-applicable";
111
- wouldCreateCycle: (candidateParentId: string) => boolean;
130
+ wouldCreateCycle: (required: {
131
+ candidateParentId: string;
132
+ }) => boolean;
112
133
  termId: string;
113
134
  }, _optional?: Record<string, never>): void;
114
135
  //# sourceMappingURL=validation-chain.d.ts.map