daftari 1.30.0 → 1.31.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 (282) hide show
  1. package/CHANGELOG.md +106 -0
  2. package/README.md +139 -4
  3. package/dist/access/rbac.d.ts +1 -0
  4. package/dist/access/rbac.d.ts.map +1 -1
  5. package/dist/access/rbac.js +7 -0
  6. package/dist/access/rbac.js.map +1 -1
  7. package/dist/audit/checks/broken_refs.d.ts +1 -1
  8. package/dist/audit/checks/broken_refs.d.ts.map +1 -1
  9. package/dist/audit/checks/broken_refs.js +77 -22
  10. package/dist/audit/checks/broken_refs.js.map +1 -1
  11. package/dist/audit/collect.d.ts +1 -0
  12. package/dist/audit/collect.d.ts.map +1 -1
  13. package/dist/audit/collect.js +22 -2
  14. package/dist/audit/collect.js.map +1 -1
  15. package/dist/audit/index.d.ts.map +1 -1
  16. package/dist/audit/index.js +9 -3
  17. package/dist/audit/index.js.map +1 -1
  18. package/dist/audit/links.d.ts.map +1 -1
  19. package/dist/audit/links.js +9 -3
  20. package/dist/audit/links.js.map +1 -1
  21. package/dist/audit/report.d.ts.map +1 -1
  22. package/dist/audit/report.js +2 -0
  23. package/dist/audit/report.js.map +1 -1
  24. package/dist/audit/types.d.ts +4 -1
  25. package/dist/audit/types.d.ts.map +1 -1
  26. package/dist/audit/types.js.map +1 -1
  27. package/dist/backfill/derive.d.ts.map +1 -1
  28. package/dist/backfill/derive.js +1 -0
  29. package/dist/backfill/derive.js.map +1 -1
  30. package/dist/cli.d.ts.map +1 -1
  31. package/dist/cli.js +18 -0
  32. package/dist/cli.js.map +1 -1
  33. package/dist/court/precedent.d.ts.map +1 -1
  34. package/dist/court/precedent.js +6 -1
  35. package/dist/court/precedent.js.map +1 -1
  36. package/dist/curation/consumes.d.ts +24 -0
  37. package/dist/curation/consumes.d.ts.map +1 -0
  38. package/dist/curation/consumes.js +122 -0
  39. package/dist/curation/consumes.js.map +1 -0
  40. package/dist/curation/edge-staleness.d.ts +47 -0
  41. package/dist/curation/edge-staleness.d.ts.map +1 -0
  42. package/dist/curation/edge-staleness.js +258 -0
  43. package/dist/curation/edge-staleness.js.map +1 -0
  44. package/dist/curation/edges.d.ts.map +1 -1
  45. package/dist/curation/edges.js +164 -10
  46. package/dist/curation/edges.js.map +1 -1
  47. package/dist/curation/lint.d.ts +4 -1
  48. package/dist/curation/lint.d.ts.map +1 -1
  49. package/dist/curation/lint.js +61 -6
  50. package/dist/curation/lint.js.map +1 -1
  51. package/dist/curation/provenance.d.ts +2 -0
  52. package/dist/curation/provenance.d.ts.map +1 -1
  53. package/dist/curation/provenance.js +2 -0
  54. package/dist/curation/provenance.js.map +1 -1
  55. package/dist/curation/read-log.d.ts +19 -0
  56. package/dist/curation/read-log.d.ts.map +1 -0
  57. package/dist/curation/read-log.js +120 -0
  58. package/dist/curation/read-log.js.map +1 -0
  59. package/dist/curation/review-throughput.d.ts +24 -0
  60. package/dist/curation/review-throughput.d.ts.map +1 -0
  61. package/dist/curation/review-throughput.js +102 -0
  62. package/dist/curation/review-throughput.js.map +1 -0
  63. package/dist/curation/staged-actions.d.ts +11 -1
  64. package/dist/curation/staged-actions.d.ts.map +1 -1
  65. package/dist/curation/staged-actions.js +102 -24
  66. package/dist/curation/staged-actions.js.map +1 -1
  67. package/dist/curation/structural.d.ts +16 -0
  68. package/dist/curation/structural.d.ts.map +1 -0
  69. package/dist/curation/structural.js +64 -0
  70. package/dist/curation/structural.js.map +1 -0
  71. package/dist/curation/tension-blast.d.ts +4 -0
  72. package/dist/curation/tension-blast.d.ts.map +1 -1
  73. package/dist/curation/tension-blast.js +9 -0
  74. package/dist/curation/tension-blast.js.map +1 -1
  75. package/dist/curation/tension.d.ts +5 -2
  76. package/dist/curation/tension.d.ts.map +1 -1
  77. package/dist/curation/tension.js +68 -25
  78. package/dist/curation/tension.js.map +1 -1
  79. package/dist/curation/tier0.d.ts +27 -0
  80. package/dist/curation/tier0.d.ts.map +1 -0
  81. package/dist/curation/tier0.js +196 -0
  82. package/dist/curation/tier0.js.map +1 -0
  83. package/dist/curation/tier1.d.ts +30 -0
  84. package/dist/curation/tier1.d.ts.map +1 -0
  85. package/dist/curation/tier1.js +142 -0
  86. package/dist/curation/tier1.js.map +1 -0
  87. package/dist/curation/tier2.d.ts +43 -0
  88. package/dist/curation/tier2.d.ts.map +1 -0
  89. package/dist/curation/tier2.js +182 -0
  90. package/dist/curation/tier2.js.map +1 -0
  91. package/dist/curation/vault-docs.d.ts +5 -1
  92. package/dist/curation/vault-docs.d.ts.map +1 -1
  93. package/dist/curation/vault-docs.js +14 -0
  94. package/dist/curation/vault-docs.js.map +1 -1
  95. package/dist/eval/generate.js +22 -5
  96. package/dist/eval/generate.js.map +1 -1
  97. package/dist/eval/index.d.ts.map +1 -1
  98. package/dist/eval/index.js +173 -25
  99. package/dist/eval/index.js.map +1 -1
  100. package/dist/eval/llm.js +1 -1
  101. package/dist/eval/llm.js.map +1 -1
  102. package/dist/eval/prune.d.ts +24 -0
  103. package/dist/eval/prune.d.ts.map +1 -0
  104. package/dist/eval/prune.js +83 -0
  105. package/dist/eval/prune.js.map +1 -0
  106. package/dist/eval/storage.d.ts +3 -0
  107. package/dist/eval/storage.d.ts.map +1 -1
  108. package/dist/eval/storage.js +14 -0
  109. package/dist/eval/storage.js.map +1 -1
  110. package/dist/frontmatter/schema.d.ts.map +1 -1
  111. package/dist/frontmatter/schema.js +19 -1
  112. package/dist/frontmatter/schema.js.map +1 -1
  113. package/dist/frontmatter/types.d.ts +4 -1
  114. package/dist/frontmatter/types.d.ts.map +1 -1
  115. package/dist/frontmatter/types.js +8 -0
  116. package/dist/frontmatter/types.js.map +1 -1
  117. package/dist/import/index.d.ts.map +1 -1
  118. package/dist/import/index.js +44 -9
  119. package/dist/import/index.js.map +1 -1
  120. package/dist/import/langgraph-store.d.ts +53 -0
  121. package/dist/import/langgraph-store.d.ts.map +1 -0
  122. package/dist/import/langgraph-store.js +292 -0
  123. package/dist/import/langgraph-store.js.map +1 -0
  124. package/dist/index.d.ts +5 -0
  125. package/dist/index.d.ts.map +1 -1
  126. package/dist/index.js +56 -18
  127. package/dist/index.js.map +1 -1
  128. package/dist/lifecycle/lock.d.ts +9 -1
  129. package/dist/lifecycle/lock.d.ts.map +1 -1
  130. package/dist/lifecycle/lock.js +34 -9
  131. package/dist/lifecycle/lock.js.map +1 -1
  132. package/dist/okf/export.d.ts +12 -0
  133. package/dist/okf/export.d.ts.map +1 -0
  134. package/dist/okf/export.js +115 -0
  135. package/dist/okf/export.js.map +1 -0
  136. package/dist/okf/import.d.ts +24 -0
  137. package/dist/okf/import.d.ts.map +1 -0
  138. package/dist/okf/import.js +107 -0
  139. package/dist/okf/import.js.map +1 -0
  140. package/dist/okf/index.d.ts +2 -0
  141. package/dist/okf/index.d.ts.map +1 -0
  142. package/dist/okf/index.js +147 -0
  143. package/dist/okf/index.js.map +1 -0
  144. package/dist/okf/map.d.ts +16 -0
  145. package/dist/okf/map.d.ts.map +1 -0
  146. package/dist/okf/map.js +149 -0
  147. package/dist/okf/map.js.map +1 -0
  148. package/dist/okf/types.d.ts +9 -0
  149. package/dist/okf/types.d.ts.map +1 -0
  150. package/dist/okf/types.js +48 -0
  151. package/dist/okf/types.js.map +1 -0
  152. package/dist/search/coverage.d.ts.map +1 -1
  153. package/dist/search/coverage.js +1 -1
  154. package/dist/search/coverage.js.map +1 -1
  155. package/dist/search/hybrid.d.ts +19 -0
  156. package/dist/search/hybrid.d.ts.map +1 -1
  157. package/dist/search/hybrid.js +58 -10
  158. package/dist/search/hybrid.js.map +1 -1
  159. package/dist/search/reindex.d.ts +1 -0
  160. package/dist/search/reindex.d.ts.map +1 -1
  161. package/dist/search/reindex.js +41 -11
  162. package/dist/search/reindex.js.map +1 -1
  163. package/dist/search/watcher.d.ts +2 -0
  164. package/dist/search/watcher.d.ts.map +1 -1
  165. package/dist/search/watcher.js +21 -10
  166. package/dist/search/watcher.js.map +1 -1
  167. package/dist/serve/index.d.ts +36 -0
  168. package/dist/serve/index.d.ts.map +1 -0
  169. package/dist/serve/index.js +507 -0
  170. package/dist/serve/index.js.map +1 -0
  171. package/dist/server.d.ts +10 -1
  172. package/dist/server.d.ts.map +1 -1
  173. package/dist/server.js +89 -14
  174. package/dist/server.js.map +1 -1
  175. package/dist/sleep/index.d.ts +2 -0
  176. package/dist/sleep/index.d.ts.map +1 -1
  177. package/dist/sleep/index.js +212 -21
  178. package/dist/sleep/index.js.map +1 -1
  179. package/dist/sleep/report.d.ts +3 -0
  180. package/dist/sleep/report.d.ts.map +1 -1
  181. package/dist/sleep/report.js +52 -0
  182. package/dist/sleep/report.js.map +1 -1
  183. package/dist/sleep/tension-scan-state.d.ts +19 -0
  184. package/dist/sleep/tension-scan-state.d.ts.map +1 -0
  185. package/dist/sleep/tension-scan-state.js +0 -0
  186. package/dist/sleep/tension-scan-state.js.map +1 -0
  187. package/dist/sleep/tension-scan.d.ts +44 -0
  188. package/dist/sleep/tension-scan.d.ts.map +1 -0
  189. package/dist/sleep/tension-scan.js +0 -0
  190. package/dist/sleep/tension-scan.js.map +1 -0
  191. package/dist/storage/backend.d.ts +12 -0
  192. package/dist/storage/backend.d.ts.map +1 -0
  193. package/dist/storage/backend.js +231 -0
  194. package/dist/storage/backend.js.map +1 -0
  195. package/dist/storage/backends/fs.d.ts +4 -0
  196. package/dist/storage/backends/fs.d.ts.map +1 -0
  197. package/dist/storage/backends/fs.js +99 -0
  198. package/dist/storage/backends/fs.js.map +1 -0
  199. package/dist/storage/fs-walk.d.ts +5 -0
  200. package/dist/storage/fs-walk.d.ts.map +1 -0
  201. package/dist/storage/fs-walk.js +28 -0
  202. package/dist/storage/fs-walk.js.map +1 -0
  203. package/dist/storage/index-db.d.ts +16 -0
  204. package/dist/storage/index-db.d.ts.map +1 -1
  205. package/dist/storage/index-db.js +94 -5
  206. package/dist/storage/index-db.js.map +1 -1
  207. package/dist/storage/local.d.ts +1 -0
  208. package/dist/storage/local.d.ts.map +1 -1
  209. package/dist/storage/local.js +12 -0
  210. package/dist/storage/local.js.map +1 -1
  211. package/dist/storage/sync.d.ts +25 -0
  212. package/dist/storage/sync.d.ts.map +1 -0
  213. package/dist/storage/sync.js +308 -0
  214. package/dist/storage/sync.js.map +1 -0
  215. package/dist/sync/index.d.ts +2 -0
  216. package/dist/sync/index.d.ts.map +1 -0
  217. package/dist/sync/index.js +136 -0
  218. package/dist/sync/index.js.map +1 -0
  219. package/dist/themes/clustering.d.ts +6 -11
  220. package/dist/themes/clustering.d.ts.map +1 -1
  221. package/dist/themes/clustering.js +76 -84
  222. package/dist/themes/clustering.js.map +1 -1
  223. package/dist/tools/consumes.d.ts +14 -0
  224. package/dist/tools/consumes.d.ts.map +1 -0
  225. package/dist/tools/consumes.js +99 -0
  226. package/dist/tools/consumes.js.map +1 -0
  227. package/dist/tools/curation.d.ts +2 -0
  228. package/dist/tools/curation.d.ts.map +1 -1
  229. package/dist/tools/curation.js +53 -15
  230. package/dist/tools/curation.js.map +1 -1
  231. package/dist/tools/edge-staleness.d.ts +28 -0
  232. package/dist/tools/edge-staleness.d.ts.map +1 -0
  233. package/dist/tools/edge-staleness.js +205 -0
  234. package/dist/tools/edge-staleness.js.map +1 -0
  235. package/dist/tools/edges.d.ts.map +1 -1
  236. package/dist/tools/edges.js +27 -21
  237. package/dist/tools/edges.js.map +1 -1
  238. package/dist/tools/read.d.ts +15 -1
  239. package/dist/tools/read.d.ts.map +1 -1
  240. package/dist/tools/read.js +142 -29
  241. package/dist/tools/read.js.map +1 -1
  242. package/dist/tools/receipt.d.ts.map +1 -1
  243. package/dist/tools/receipt.js +16 -7
  244. package/dist/tools/receipt.js.map +1 -1
  245. package/dist/tools/search.d.ts +1 -0
  246. package/dist/tools/search.d.ts.map +1 -1
  247. package/dist/tools/search.js +147 -5
  248. package/dist/tools/search.js.map +1 -1
  249. package/dist/tools/staged-actions.d.ts +3 -0
  250. package/dist/tools/staged-actions.d.ts.map +1 -1
  251. package/dist/tools/staged-actions.js +227 -22
  252. package/dist/tools/staged-actions.js.map +1 -1
  253. package/dist/tools/themes.d.ts +8 -0
  254. package/dist/tools/themes.d.ts.map +1 -1
  255. package/dist/tools/themes.js +208 -122
  256. package/dist/tools/themes.js.map +1 -1
  257. package/dist/tools/tier1.d.ts +14 -0
  258. package/dist/tools/tier1.d.ts.map +1 -0
  259. package/dist/tools/tier1.js +169 -0
  260. package/dist/tools/tier1.js.map +1 -0
  261. package/dist/tools/tier2.d.ts +27 -0
  262. package/dist/tools/tier2.d.ts.map +1 -0
  263. package/dist/tools/tier2.js +344 -0
  264. package/dist/tools/tier2.js.map +1 -0
  265. package/dist/tools/write.d.ts +9 -1
  266. package/dist/tools/write.d.ts.map +1 -1
  267. package/dist/tools/write.js +492 -6
  268. package/dist/tools/write.js.map +1 -1
  269. package/dist/utils/config.d.ts +52 -0
  270. package/dist/utils/config.d.ts.map +1 -1
  271. package/dist/utils/config.js +372 -2
  272. package/dist/utils/config.js.map +1 -1
  273. package/dist/utils/run-id.d.ts +3 -0
  274. package/dist/utils/run-id.d.ts.map +1 -0
  275. package/dist/utils/run-id.js +19 -0
  276. package/dist/utils/run-id.js.map +1 -0
  277. package/dist/utils/vault-gitignore.d.ts +1 -1
  278. package/dist/utils/vault-gitignore.d.ts.map +1 -1
  279. package/dist/utils/vault-gitignore.js +4 -1
  280. package/dist/utils/vault-gitignore.js.map +1 -1
  281. package/package.json +21 -1
  282. package/templates/config.yaml +8 -0
@@ -6,6 +6,12 @@
6
6
  // it. If the index is empty (first run after a fresh clone) they trigger a
7
7
  // reindex first, so search works without an explicit setup step.
8
8
  import { canRead } from "../access/rbac.js";
9
+ import { currentConsumesEdges } from "../curation/consumes.js";
10
+ import { compiledUpstreamStaleness, loadCompiledStaleContext, splitUpstreamVisibility, } from "../curation/edge-staleness.js";
11
+ import { recordReads } from "../curation/read-log.js";
12
+ import { structuralDecay } from "../curation/structural.js";
13
+ import { sourceReadable } from "../curation/tension-access.js";
14
+ import { bucketHiddenDownstream } from "../curation/tension-blast.js";
9
15
  import { err, ok } from "../frontmatter/types.js";
10
16
  import { contestedFor } from "../search/contested.js";
11
17
  import { applyCoveragePass, DEFAULT_COVERAGE_OPTIONS, enforceTokenCap, } from "../search/coverage.js";
@@ -25,6 +31,15 @@ import { documentCount, openIndexDb } from "../storage/index-db.js";
25
31
  export function openIndexForActiveProvider(vaultRoot) {
26
32
  return openIndexDb(vaultRoot, getProvider().dim);
27
33
  }
34
+ // Read-only index handle for RBAC collection lookups. openIndexForActiveProvider
35
+ // ONLY — never ensureIndexReady, which reindexes on an empty index; visibility
36
+ // gates must never reindex. Open failure degrades to null: visibility then
37
+ // gates on the pure first-segment rule (fail-closed), and the tool call
38
+ // itself never fails for RBAC-lookup reasons.
39
+ export function openIndexForAccessOrNull(vaultRoot) {
40
+ const opened = openIndexForActiveProvider(vaultRoot);
41
+ return opened.ok ? opened.value : null;
42
+ }
28
43
  // Gate every index-backed tool on the current indexing state.
29
44
  //
30
45
  // - "indexing": refuse with a progress-bearing message. The server is still
@@ -78,11 +93,92 @@ function parseWeights(raw) {
78
93
  }
79
94
  return DEFAULT_WEIGHTS;
80
95
  }
81
- function parseLimit(raw) {
96
+ // Shared numeric-arg posture: a positive finite number floors and clamps to
97
+ // `max`; anything else silently takes `fallback`.
98
+ function clampPositiveInt(raw, max, fallback) {
82
99
  if (typeof raw === "number" && Number.isFinite(raw) && raw > 0) {
83
- return Math.min(Math.floor(raw), 50);
100
+ return Math.min(Math.floor(raw), max);
101
+ }
102
+ return fallback;
103
+ }
104
+ function parseLimit(raw) {
105
+ return clampPositiveInt(raw, 50, 10);
106
+ }
107
+ // #3: rerank pool size. 0 = feature off (the default — absent or invalid
108
+ // mirrors parseLimit's silent-fallback posture). Capped: the pool is token
109
+ // cost in the caller's context window, and past ~30 snippets judgment
110
+ // quality decays faster than recall improves.
111
+ const RERANK_CANDIDATES_MAX = 30;
112
+ function parseRerankCandidates(raw) {
113
+ return clampPositiveInt(raw, RERANK_CANDIDATES_MAX, 0);
114
+ }
115
+ // The agent-as-judge protocol text (#3), one fixed string like the #169
116
+ // supersede hint: the signal is the field's presence and a stable text is
117
+ // grep-able in agent traces. The server never calls a model — the same
118
+ // division of labor the tier-2 protocol settled: it prepares constrained
119
+ // judging context; the CALLING agent is the judge.
120
+ const RERANK_INSTRUCTIONS = "You are the reranker. The candidates below are the fused hybrid ranking " +
121
+ "(BM25 + vector); their scores measure retrieval proximity, NOT whether a " +
122
+ "candidate answers the query. Judge each candidate's snippet against the " +
123
+ "query and reorder by how well it answers. Candidates ranked past the " +
124
+ "returned hits may outrank them — promote them if they answer better. " +
125
+ "Read any candidate you promote with vault_read before relying on it: " +
126
+ "candidates carry no enrichment (tensions, staleness, structural flags); " +
127
+ "the served hits and vault_read do.";
128
+ // #234 serve instrumentation, shared by every snippet-serving tool
129
+ // (vault_search AND vault_search_related — the broken-read rate's
130
+ // denominator counts serves, whichever tool served them). Each SERVED hit
131
+ // becomes one read-log entry carrying its pending-broken upstream count —
132
+ // the TRUE count, unfiltered, because the log is local operator telemetry —
133
+ // batched into a single append so N hits do not pay N fs writes.
134
+ //
135
+ // The caller-facing hit uses the shared #217 split (splitUpstreamVisibility):
136
+ // the "broken" (incident) classification is disclosed only for upstream
137
+ // units the caller can read — pendingBrokenUpstream buckets the VISIBLE
138
+ // broken count. Edges to unreadable units contribute only the generic
139
+ // hiddenPendingUpstream bucket, which never carries severity: an incident
140
+ // verdict derived from a hidden unit would leak that unit's change activity
141
+ // across the ACL boundary. The visible count is bucketed for hit-payload
142
+ // compactness, not disclosure — vault_read's exact pending_broken is the
143
+ // drill-down. Best-effort: a telemetry failure never fails the search.
144
+ async function annotateAndLogServedHits(vaultRoot, db, tool, hits, access) {
145
+ if (hits.length === 0)
146
+ return;
147
+ // The newest-compile-group collapse is O(total edges); do it ONCE per
148
+ // call, not per hit. Passing the pre-collapsed set through is sound
149
+ // because currentConsumesEdges is idempotent. An empty consumes log
150
+ // short-circuits before the provenance log is read at all — with zero
151
+ // compiled edges every broken count is zero (same posture as vault_read).
152
+ const loaded = await loadCompiledStaleContext(vaultRoot);
153
+ const staleCtx = loaded
154
+ ? { consumes: currentConsumesEdges(loaded.consumes), provenance: loaded.provenance }
155
+ : null;
156
+ const entries = [];
157
+ for (const hit of hits) {
158
+ let broken;
159
+ if (staleCtx) {
160
+ const rows = compiledUpstreamStaleness(hit.path, staleCtx.consumes, staleCtx.provenance);
161
+ broken = rows.filter((r) => r.staleness === "pending-broken").length;
162
+ // `db` is the caller's already-open index handle — the same one the
163
+ // other RBAC enrichments (resolveCurrentSource, contestedFor) read.
164
+ const { visible, hiddenPending } = access
165
+ ? splitUpstreamVisibility(rows, (unit) => sourceReadable(db, access, unit))
166
+ : { visible: rows, hiddenPending: "none" };
167
+ const visibleBroken = visible.filter((r) => r.staleness === "pending-broken").length;
168
+ const brokenBucket = bucketHiddenDownstream(visibleBroken);
169
+ if (brokenBucket !== "none")
170
+ hit.pendingBrokenUpstream = brokenBucket;
171
+ if (hiddenPending !== "none")
172
+ hit.hiddenPendingUpstream = hiddenPending;
173
+ }
174
+ entries.push({
175
+ tool,
176
+ file: hit.path,
177
+ ...(access?.user != null ? { principal: access.user } : {}),
178
+ ...(broken !== undefined ? { broken_upstream: broken } : {}),
179
+ });
84
180
  }
85
- return 10;
181
+ await recordReads(vaultRoot, entries);
86
182
  }
87
183
  // ---------------------------------------------------------------------------
88
184
  // vault_search
@@ -152,11 +248,45 @@ export async function vaultSearch(vaultRoot, args, access) {
152
248
  hit.contested = ct.contested;
153
249
  hit.contestedCount = ct.contestedCount;
154
250
  }
251
+ // #8: structural decay flags from the materialized inbound-link graph —
252
+ // one indexed query per hit on the same open handle, vantage-filtered.
253
+ const sd = structuralDecay({ db, path: hit.path, status: hit.status, access });
254
+ if (sd?.orphan)
255
+ hit.orphan = true;
256
+ if (sd?.deprecated_still_linked)
257
+ hit.deprecatedStillLinked = true;
155
258
  }
156
259
  // Token-cap backstop: evict coverage-added docs (stale first, then oldest) if
157
260
  // their combined snippets exceed the budget. Never drops ranked hits.
158
261
  const capped = enforceTokenCap(permitted, DEFAULT_COVERAGE_OPTIONS);
159
- return ok({ ...result.value, count: capped.length, hits: capped });
262
+ await annotateAndLogServedHits(vaultRoot, db, "vault_search", capped, access);
263
+ // #3: opt-in agent-as-judge rerank pool — the top-K of the SAME
264
+ // RBAC-filtered fused ranking the hits were sliced from (never coverage
265
+ // additions; those are recall, not ranking). Compact judging records
266
+ // only: no enrichment joins, per the protocol text.
267
+ const rerankK = parseRerankCandidates(args.rerank_candidates);
268
+ const rerank = rerankK > 0
269
+ ? {
270
+ instructions: RERANK_INSTRUCTIONS,
271
+ candidates: permittedRanked.slice(0, rerankK).map((h, i) => ({
272
+ rank: i + 1,
273
+ path: h.path,
274
+ title: h.title,
275
+ collection: h.collection,
276
+ status: h.status,
277
+ score: h.score,
278
+ bm25Score: h.bm25Score,
279
+ vectorScore: h.vectorScore,
280
+ snippet: h.snippet,
281
+ })),
282
+ }
283
+ : undefined;
284
+ return ok({
285
+ ...result.value,
286
+ count: capped.length,
287
+ hits: capped,
288
+ ...(rerank ? { rerank } : {}),
289
+ });
160
290
  }
161
291
  finally {
162
292
  db.close();
@@ -198,6 +328,7 @@ export async function vaultSearchRelated(vaultRoot, args, access) {
198
328
  ? result.value.hits.filter((h) => canRead(access.role, h.collection))
199
329
  : result.value.hits;
200
330
  const hits = permitted.slice(0, limit);
331
+ await annotateAndLogServedHits(vaultRoot, db, "vault_search_related", hits, access);
201
332
  return ok({ ...result.value, count: hits.length, hits });
202
333
  }
203
334
  finally {
@@ -244,7 +375,12 @@ export const searchTools = [
244
375
  "Falls back to lexical-only ranking if embeddings are unavailable. " +
245
376
  "Hits may carry `contested`: unresolved recorded tensions involving " +
246
377
  "the document, with both claims shown (`claimSelf`/`claimOther`), " +
247
- "capped at 3 per hit; `contestedCount` reports the true total.",
378
+ "capped at 3 per hit; `contestedCount` reports the true total. " +
379
+ "Pass rerank_candidates to also receive a `rerank` block — the top-K " +
380
+ "of the fused ranking as compact judging records plus instructions — " +
381
+ "and act as the reranker yourself: fusion scores measure retrieval " +
382
+ "proximity, not answer quality, so judging the pool against the query " +
383
+ "can surface candidates ranked past the returned hits.",
248
384
  inputSchema: {
249
385
  type: "object",
250
386
  properties: {
@@ -254,6 +390,12 @@ export const searchTools = [
254
390
  description: "Maximum results to return (default 10, max 50)",
255
391
  },
256
392
  weights: weightsSchema,
393
+ rerank_candidates: {
394
+ type: "number",
395
+ description: "Opt-in agent-as-judge rerank: return the top-K fused candidates " +
396
+ "(max 30) with judging context so YOU reorder by answer quality. " +
397
+ "Omit to skip.",
398
+ },
257
399
  },
258
400
  required: ["query"],
259
401
  additionalProperties: false,
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,9 @@ import type { ToolDefinition } from "./read.js";
4
4
  export interface StageActionResult {
5
5
  id: string;
6
6
  expires_at: string;
7
+ conflicts_with: string[];
8
+ tension_id: string | null;
9
+ tension_error?: string;
7
10
  }
8
11
  export declare function vaultStageAction(vaultRoot: string, args: Record<string, unknown>, access?: AccessContext): Promise<Result<StageActionResult, Error>>;
9
12
  export interface RatifyResult {
@@ -1 +1 @@
1
- {"version":3,"file":"staged-actions.d.ts","sourceRoot":"","sources":["../../src/tools/staged-actions.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,KAAK,aAAa,EAAuB,MAAM,mBAAmB,CAAC;AAU5E,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AA0BhD,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,CAAC,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC,CAyE3C;AAMD,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAGhB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,CAAC,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CA6LtC;AAMD,eAAO,MAAM,iBAAiB,EAAE,cAAc,EA4F7C,CAAC"}
1
+ {"version":3,"file":"staged-actions.d.ts","sourceRoot":"","sources":["../../src/tools/staged-actions.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,KAAK,aAAa,EAA+C,MAAM,mBAAmB,CAAC;AAcpG,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAI/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AA2BhD,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IAInB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAI1B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,CAAC,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC,CA2G3C;AAMD,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAGhB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,CAAC,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CA6XtC;AAMD,eAAO,MAAM,iBAAiB,EAAE,cAAc,EA8G7C,CAAC"}
@@ -12,12 +12,18 @@
12
12
  // vault_supersede, confidence-up → vault_set_confidence, merge → vault_merge
13
13
  // (the §11.4 write tools). A dispatch failure (including a malformed
14
14
  // proposed_diff) leaves the action pending so it can be retried.
15
- import { canRatify, canWrite } from "../access/rbac.js";
16
- import { getStagedActionById, nowISO, recordDecision, STAGED_ACTION_TYPES, stageAction, } from "../curation/staged-actions.js";
15
+ import { canRatify, canRead, canWrite, isProposeOnly } from "../access/rbac.js";
16
+ import { getStagedActionById, nowISO, recordDecision, STAGED_ACTION_TYPES, stageActionWithConflictCheck, } from "../curation/staged-actions.js";
17
+ import { bucketHiddenDownstream } from "../curation/tension-blast.js";
18
+ import { tier0DeprecateGate, tier0PromoteGate } from "../curation/tier0.js";
19
+ import { loadDocuments } from "../curation/vault-docs.js";
17
20
  import { parseDocument } from "../frontmatter/parser.js";
21
+ import { validateFrontmatter } from "../frontmatter/schema.js";
18
22
  import { err, ok } from "../frontmatter/types.js";
19
23
  import { readFile, resolveVaultPath } from "../storage/local.js";
20
- import { vaultDeprecate, vaultMerge, vaultPromote, vaultSetConfidence, vaultSupersede, } from "./write.js";
24
+ import { loadConfig } from "../utils/config.js";
25
+ import { readRunId } from "../utils/run-id.js";
26
+ import { vaultDeprecate, vaultMerge, vaultPromote, vaultSetConfidence, vaultSupersede, vaultWrite, } from "./write.js";
21
27
  function requireString(args, field, tool) {
22
28
  const v = args[field];
23
29
  if (typeof v !== "string" || v.trim().length === 0) {
@@ -44,6 +50,22 @@ export async function vaultStageAction(vaultRoot, args, access) {
44
50
  if (args.proposed_diff === undefined || args.proposed_diff === null) {
45
51
  return err(new Error("vault_stage_action requires a 'proposed_diff' object argument"));
46
52
  }
53
+ const runId = readRunId(args, "vault_stage_action");
54
+ if (!runId.ok)
55
+ return runId;
56
+ // A `write` proposal carries full content; validate the payload shape at
57
+ // stage time so a malformed one never sits in the queue until ratify.
58
+ const isWrite = actionType.value === "write";
59
+ if (isWrite) {
60
+ const diff = args.proposed_diff;
61
+ if (typeof args.proposed_diff !== "object" ||
62
+ diff.frontmatter === null ||
63
+ typeof diff.frontmatter !== "object" ||
64
+ typeof diff.body !== "string") {
65
+ return err(new Error("vault_stage_action: a 'write' action needs proposed_diff.frontmatter " +
66
+ "(object) and proposed_diff.body (string)"));
67
+ }
68
+ }
47
69
  const resolved = resolveVaultPath(vaultRoot, targetPath.value);
48
70
  if (!resolved.ok)
49
71
  return resolved;
@@ -56,21 +78,28 @@ export async function vaultStageAction(vaultRoot, args, access) {
56
78
  // to the queue. The gate runs BEFORE the not-found branch so a role lacking
57
79
  // write cannot probe document existence (not-found vs access-denied). The
58
80
  // collection is authoritative from the document's own frontmatter when it is
59
- // readable; for a not-yet-existing target it falls back to the path's leading
60
- // segment (the same convention the write tools use).
81
+ // readable; for a not-yet-existing target it falls back to the leading
82
+ // segment of the NORMALIZED path (resolved.relPath), never the raw caller
83
+ // string — `pricing/../competitive-intel/x.md` splits to "pricing" raw but
84
+ // resolves to competitive-intel, and with `write` targets allowed to not
85
+ // exist, gating on the raw string would let a pricing-only role queue
86
+ // proposals into collections it cannot write (same S1 rule as write.ts's
87
+ // targetCollection).
61
88
  if (access) {
62
89
  const parsed = exists.ok ? parseDocument(exists.value) : null;
63
90
  const collection = (parsed?.ok ? parsed.value.frontmatter.collection : "") ||
64
- (targetPath.value.split("/")[0] ?? "");
91
+ (resolved.value.relPath.split("/")[0] ?? "");
65
92
  if (!canWrite(access.role, collection)) {
66
93
  return err(new Error(`access denied: role '${access.roleName}' cannot stage actions for collection '${collection}'`));
67
94
  }
68
95
  }
69
- // Fail fast: an action that targets a non-existent document can never be
70
- // ratified (the write-tool dispatch would reject "document not found"). Catch
71
- // it at stage time so a bad target never sits in the queue for 14 days. This
72
- // is reached only by callers that already hold write access (checked above).
73
- if (!exists.ok) {
96
+ // Fail fast: a lifecycle action that targets a non-existent document can
97
+ // never be ratified (the write-tool dispatch would reject "document not
98
+ // found"). Catch it at stage time so a bad target never sits in the queue
99
+ // for 14 days. This is reached only by callers that already hold write
100
+ // access (checked above). `write` proposals are exempt — creating a new
101
+ // document is their point.
102
+ if (!exists.ok && !isWrite) {
74
103
  return err(new Error(`vault_stage_action: target document not found: ${targetPath.value}`));
75
104
  }
76
105
  let ttlDays;
@@ -80,12 +109,16 @@ export async function vaultStageAction(vaultRoot, args, access) {
80
109
  }
81
110
  ttlDays = args.ttl_days;
82
111
  }
83
- return stageAction(vaultRoot, {
112
+ // Stage the CANONICAL relPath, not the raw caller string, so aliased
113
+ // spellings of one target contend in conflict detection and the queued
114
+ // target matches what dispatch will actually write (#127/#128 rule).
115
+ return stageActionWithConflictCheck(vaultRoot, {
84
116
  actionType: actionType.value,
85
- targetPath: targetPath.value,
117
+ targetPath: resolved.value.relPath,
86
118
  proposedBy: proposedBy.value,
87
119
  rationale: rationale.value,
88
120
  proposedDiff: args.proposed_diff,
121
+ ...(runId.value !== undefined ? { runId: runId.value } : {}),
89
122
  ...(ttlDays !== undefined ? { ttlDays } : {}),
90
123
  });
91
124
  }
@@ -96,6 +129,15 @@ export async function vaultRatify(vaultRoot, args, access) {
96
129
  if (access && !canRatify(access.role)) {
97
130
  return err(new Error(`access denied: role '${access.roleName}' cannot ratify staged actions`));
98
131
  }
132
+ // A propose-only role must never ratify, even if a hand-built role grants
133
+ // both (config load rejects the combination, but AccessContexts constructed
134
+ // in code bypass that). Without this, approving a `write` action would be
135
+ // coerced by vaultWrite's propose-only path into staging a NEW proposal
136
+ // while the original got marked ratified/applied — a silent no-op.
137
+ if (access && isProposeOnly(access.role)) {
138
+ return err(new Error(`access denied: role '${access.roleName}' is propose-only — it cannot ` +
139
+ `ratify staged actions`));
140
+ }
99
141
  const id = requireString(args, "id", "vault_ratify");
100
142
  if (!id.ok)
101
143
  return id;
@@ -150,8 +192,155 @@ export async function vaultRatify(vaultRoot, args, access) {
150
192
  const diff = action.proposedDiff && typeof action.proposedDiff === "object"
151
193
  ? action.proposedDiff
152
194
  : {};
195
+ // Tier 0 ratify gate (#232; quick win 1 of #236). Ratification is already a
196
+ // gate, so blocking here does not violate the advisory-curation rule — the
197
+ // direct write tools stay unblocked. A blocked approval is an error, which
198
+ // leaves the action pending (same contract as a dispatch failure): fix the
199
+ // underlying state and re-approve, or reject. Under RBAC the error names
200
+ // only docs the ratifier can read; a hidden remainder is coarsened
201
+ // (#217 B′), never reported as an exact count.
202
+ // A `write` proposal's payload shape is needed by both the gate and the
203
+ // dispatch — validate it once, up front. A malformed payload errors and
204
+ // leaves the action pending, same contract as a malformed supersede diff.
205
+ let writePayload = null;
206
+ if (action.actionType === "write") {
207
+ if (diff.frontmatter === null || typeof diff.frontmatter !== "object") {
208
+ return err(new Error(`vault_ratify: write action ${id.value} needs proposed_diff.frontmatter`));
209
+ }
210
+ if (typeof diff.body !== "string") {
211
+ return err(new Error(`vault_ratify: write action ${id.value} needs proposed_diff.body`));
212
+ }
213
+ writePayload = { frontmatter: diff.frontmatter, body: diff.body };
214
+ }
215
+ if (action.actionType === "promote" ||
216
+ action.actionType === "deprecate" ||
217
+ action.actionType === "write") {
218
+ const loaded = await loadDocuments(vaultRoot);
219
+ // Fail closed: without the doc set there is no gate, so no dispatch.
220
+ if (!loaded.ok)
221
+ return loaded;
222
+ const visible = access
223
+ ? (d) => canRead(access.role, d.frontmatter.collection)
224
+ : undefined;
225
+ if (action.actionType === "write" && writePayload) {
226
+ // A write proposal whose POST-state is canonical is a promote in one
227
+ // step — hold it to the same tier-0 bar. The post-state is NOT the
228
+ // payload as submitted: vaultWrite's update path merges the payload
229
+ // UNDER the existing frontmatter (#113 — omitted keys are inherited,
230
+ // explicit nulls delete), so gate the same merge. Judging the payload
231
+ // alone has two bypasses: omitted `sources` inherit the on-disk value
232
+ // unseen, and an omitted `status` on an already-canonical doc keeps it
233
+ // canonical while dodging a payload-declared-status check.
234
+ const existing = loaded.value.find((d) => d.path === action.targetPath);
235
+ const mergedRaw = existing
236
+ ? { ...existing.frontmatter }
237
+ : {};
238
+ for (const [key, value] of Object.entries(writePayload.frontmatter)) {
239
+ if (value === null)
240
+ delete mergedRaw[key];
241
+ else
242
+ mergedRaw[key] = value;
243
+ }
244
+ // Validate with the vault's schema extensions, same as the dispatch —
245
+ // without them a required extension field missing from a canonical
246
+ // write proposal would slip past the tier-0 schema check and only fail
247
+ // later with the generic invalid-frontmatter error.
248
+ const gateConfig = loadConfig(vaultRoot);
249
+ if (!gateConfig.ok)
250
+ return gateConfig;
251
+ const { frontmatter, report } = validateFrontmatter(mergedRaw, gateConfig.value.schemaExtensions);
252
+ if (frontmatter.status === "canonical") {
253
+ // Splice the merged post-state in as a synthetic doc (replacing any
254
+ // existing doc at the target) and reuse the promote gate wholesale.
255
+ const synthetic = {
256
+ path: action.targetPath,
257
+ frontmatter,
258
+ content: writePayload.body,
259
+ validation: report,
260
+ };
261
+ const docs = [...loaded.value.filter((d) => d.path !== action.targetPath), synthetic];
262
+ const gate = tier0PromoteGate(docs, action.targetPath, visible);
263
+ const problems = [...gate.violations];
264
+ if (gate.hiddenConflicts > 0) {
265
+ problems.push(`non-canonical sources hidden from your role: ${bucketHiddenDownstream(gate.hiddenConflicts)}`);
266
+ }
267
+ if (problems.length > 0) {
268
+ return err(new Error(`vault_ratify: tier-0 gate blocked canonical write of ${action.targetPath}: ` +
269
+ `${problems.join("; ")} — the action stays pending`));
270
+ }
271
+ }
272
+ else if (existing?.frontmatter.status === "canonical" &&
273
+ !(typeof frontmatter.superseded_by === "string" && frontmatter.superseded_by.length > 0)) {
274
+ // The mirror case: a write whose merged post-state moves an
275
+ // already-canonical doc AWAY from canonical is a deprecate in one
276
+ // step — without a superseded_by forward it strands canonical
277
+ // dependents exactly like an unforwarded staged deprecate, so it
278
+ // gets the same gate. A merged superseded_by provides the
279
+ // resolution path and passes, same as a forwarded deprecate.
280
+ const gate = tier0DeprecateGate(loaded.value, action.targetPath, visible);
281
+ const problems = [];
282
+ if (gate.dependents.length > 0) {
283
+ problems.push(`cited as a source by canonical: ${gate.dependents.join(", ")}`);
284
+ }
285
+ if (gate.hiddenDependents > 0) {
286
+ problems.push(`hidden canonical dependents: ${bucketHiddenDownstream(gate.hiddenDependents)}`);
287
+ }
288
+ if (problems.length > 0) {
289
+ return err(new Error(`vault_ratify: tier-0 gate blocked demoting write of ${action.targetPath} ` +
290
+ `(canonical → ${frontmatter.status}): ${problems.join("; ")} — supersede ` +
291
+ `with a successor or update the dependents first; the action stays pending`));
292
+ }
293
+ }
294
+ }
295
+ else if (action.actionType === "promote") {
296
+ const gate = tier0PromoteGate(loaded.value, action.targetPath, visible);
297
+ const problems = [...gate.violations];
298
+ if (gate.hiddenConflicts > 0) {
299
+ problems.push(`non-canonical sources hidden from your role: ${bucketHiddenDownstream(gate.hiddenConflicts)}`);
300
+ }
301
+ if (problems.length > 0) {
302
+ return err(new Error(`vault_ratify: tier-0 gate blocked promote of ${action.targetPath}: ` +
303
+ `${problems.join("; ")} — the action stays pending`));
304
+ }
305
+ }
306
+ else if (typeof diff.superseded_by !== "string") {
307
+ // A deprecate carrying a superseded_by hint forwards dependents to a
308
+ // successor (same as supersede) — only an unforwarded deprecate can
309
+ // strand canonical dependents on a retired source.
310
+ const gate = tier0DeprecateGate(loaded.value, action.targetPath, visible);
311
+ const problems = [];
312
+ if (gate.dependents.length > 0) {
313
+ problems.push(`cited as a source by canonical: ${gate.dependents.join(", ")}`);
314
+ }
315
+ if (gate.hiddenDependents > 0) {
316
+ problems.push(`hidden canonical dependents: ${bucketHiddenDownstream(gate.hiddenDependents)}`);
317
+ }
318
+ if (problems.length > 0) {
319
+ return err(new Error(`vault_ratify: tier-0 gate blocked deprecate of ${action.targetPath}: ` +
320
+ `${problems.join("; ")} — supersede with a successor or update the ` +
321
+ `dependents first; the action stays pending`));
322
+ }
323
+ }
324
+ }
153
325
  let dispatched;
154
326
  switch (action.actionType) {
327
+ case "write": {
328
+ // Payload validated above (writePayload is always set for this type).
329
+ // The proposer's run_id (stamped at stage time) is carried into the
330
+ // write so provenance correlates the landed content with the run that
331
+ // proposed it (#235 → #233).
332
+ if (!writePayload) {
333
+ return err(new Error(`vault_ratify: write action ${id.value} lost its payload`));
334
+ }
335
+ dispatched = await vaultWrite(vaultRoot, {
336
+ path: action.targetPath,
337
+ frontmatter: writePayload.frontmatter,
338
+ body: writePayload.body,
339
+ agent: principal.value,
340
+ ...(action.runId ? { run_id: action.runId } : {}),
341
+ }, access);
342
+ break;
343
+ }
155
344
  case "promote":
156
345
  dispatched = await vaultPromote(vaultRoot, { path: action.targetPath, agent: principal.value }, access);
157
346
  break;
@@ -199,8 +388,7 @@ export async function vaultRatify(vaultRoot, args, access) {
199
388
  // proposed_diff = { merge_from: [path_a, path_b], body, frontmatter? };
200
389
  // the staged target_path is the merge target.
201
390
  const mergeFrom = Array.isArray(diff.merge_from) ? diff.merge_from : null;
202
- if (!mergeFrom ||
203
- mergeFrom.length !== 2 ||
391
+ if (mergeFrom?.length !== 2 ||
204
392
  typeof mergeFrom[0] !== "string" ||
205
393
  typeof mergeFrom[1] !== "string" ||
206
394
  typeof diff.body !== "string") {
@@ -259,11 +447,15 @@ export const stagedActionTools = [
259
447
  description: "Record a proposed change to the vault for later human ratification via " +
260
448
  "vault_ratify. The action waits in a pending queue and auto-expires after " +
261
449
  "ttl_days (default 14). This is the producer side of the staged-action " +
262
- "queue — normally called by the curation loop, not by a human directly. " +
263
- "Action types: promote, deprecate, supersede, merge, confidence-up. " +
264
- "proposed_diff carries the per-action payload replayed on ratification: " +
265
- "supersede → {superseded_by}, confidence-up → {confidence}, " +
266
- "merge → {merge_from: [path_a, path_b], body, frontmatter?}.",
450
+ "queue — normally called by the curation loop or an agent, not by a human " +
451
+ "directly. Action types: promote, deprecate, supersede, merge, " +
452
+ "confidence-up, write. proposed_diff carries the per-action payload " +
453
+ "replayed on ratification: supersede → {superseded_by}, confidence-up → " +
454
+ "{confidence}, merge → {merge_from: [path_a, path_b], body, frontmatter?}, " +
455
+ "write → {frontmatter, body} (full content; the target may be a new " +
456
+ "document). If other pending proposals already target the same document, " +
457
+ "the new one still lands — both stay pending — and an inter-proposal " +
458
+ "tension is logged; the result carries conflicts_with and tension_id.",
267
459
  inputSchema: {
268
460
  type: "object",
269
461
  properties: {
@@ -294,6 +486,12 @@ export const stagedActionTools = [
294
486
  type: "number",
295
487
  description: "Days until the action auto-expires if not ratified (default 14)",
296
488
  },
489
+ run_id: {
490
+ type: "string",
491
+ description: "Optional trace/run identifier of the proposing run. Recorded on " +
492
+ "the proposal and carried into provenance when a write action is " +
493
+ "ratified.",
494
+ },
297
495
  },
298
496
  required: ["action_type", "target_path", "proposed_by", "rationale", "proposed_diff"],
299
497
  additionalProperties: false,
@@ -307,9 +505,16 @@ export const stagedActionTools = [
307
505
  description: "Approve or reject a single pending staged action. On approve, dispatches " +
308
506
  "to the matching write tool (promote → vault_promote, deprecate → " +
309
507
  "vault_deprecate, supersede → vault_supersede, confidence-up → " +
310
- "vault_set_confidence, merge → vault_merge) and auto-commits. On reject, " +
508
+ "vault_set_confidence, merge → vault_merge, write vault_write) and " +
509
+ "auto-commits. On reject, " +
311
510
  "records the rejection and applies nothing. A dispatch failure leaves the " +
312
- "action pending. Errors if the id is unknown or the action is not pending " +
511
+ "action pending. Approving a promote, an unforwarded deprecate, or a " +
512
+ "write that declares status canonical runs the " +
513
+ "tier-0 gate first (#232): if applying would create a certain structural " +
514
+ "violation (broken source refs, canonical citing draft/deprecated/archived, " +
515
+ "schema-invalid frontmatter, stranded canonical dependents), the approval " +
516
+ "errors and the action stays pending — fix the state and re-approve, or " +
517
+ "reject. Errors if the id is unknown or the action is not pending " +
313
518
  "(already decided or expired). Requires the role's 'ratify' grant. If " +
314
519
  "the vault runs shadow_mode, an approved dispatch is computed and " +
315
520
  "shadow-logged but NOT applied — the result carries shadow: true and " +