daftari 1.14.0 → 1.15.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.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,51 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.15.0] - 2026-05-31
11
+
12
+ ### Added
13
+
14
+ - **Blast radius of stale tensions** (Step 5 of the Tension Graph plan,
15
+ cross-feature integration). `vault_lint`'s tension health surface now
16
+ reports `blastRadiusOfStaleTensions`: the cardinality of the
17
+ deduplicated `primary_blast` set (sources channel only — the same
18
+ primary set `vault_tension_blast` returns) over the union of contested
19
+ docs from every entry where `resolved: false` AND
20
+ `agingTier === "stale"`. Renders as "Blast radius of stale tensions: N
21
+ downstream documents". When there are no stale unresolved tensions the
22
+ metric is 0; the line always renders for consistency with the rest of
23
+ the tension health section. Reuses `computeBlast` from
24
+ `tension-blast.ts` — advisory link edges still participate in BFS
25
+ traversal, but the published metric stays disciplined to the primary
26
+ channel.
27
+
28
+ - **Tension blast radius** (Phase 3 of the Tension Graph plan). New
29
+ `vault_tension_blast` tool computes the transitive closure of
30
+ downstream documents that cite or link a contested document — or the
31
+ union over a contested cluster. Accepts exactly one of `document` or
32
+ `cluster_id`. Two confidence channels: `primary_blast` (via `sources`
33
+ frontmatter) is authoritative; `advisory_blast` (via in-vault markdown
34
+ links) is suggestive. `superseded_by` is not a blast edge — the doc
35
+ that supersedes a contested doc is the replacement, not an inheritor.
36
+
37
+ - **Tension clusters** (Phase 2 of the Tension Graph plan). New
38
+ `vault_tension_clusters` tool computes connected components of the
39
+ tension graph over unresolved, non-accepted tensions. Cluster IDs are
40
+ content-addressed (`cluster:` + first 8 hex chars of sha256 of
41
+ canonical-sorted member paths) — stable across runs for unchanged
42
+ membership; a different ID encodes a different membership. `vault_lint`
43
+ reports cluster count, max size, and flags clusters that are large
44
+ (>5 docs, smell) or aged (oldest tension >90 days, tech debt).
45
+
46
+ - **Tension aging tiers** (Phase 4 of the Tension Graph plan). Tensions
47
+ in the tension log now report aging tiers (Fresh 0–30d / Aging 31–90d
48
+ / Stale 90+d) in `vault_lint`, with kind-specific lint copy at the
49
+ stale tier. Unspecified tensions and tensions resolved with kind
50
+ `accepted` are excluded from the aging pipeline — the former because
51
+ they predate classification, the latter because explicitly accepted
52
+ persistent disagreements are stable epistemic features rather than
53
+ debt.
54
+
10
55
  ## [1.14.0] - 2026-05-31
11
56
 
12
57
  ### Added
@@ -6,6 +6,19 @@ export interface LintFinding {
6
6
  path: string;
7
7
  detail: string;
8
8
  }
9
+ export interface TensionAging {
10
+ fresh: number;
11
+ aging: number;
12
+ stale: number;
13
+ staleByKind: Record<TensionKind, number>;
14
+ staleMessages: Partial<Record<Exclude<TensionKind, "unspecified">, string>>;
15
+ }
16
+ export interface TensionClustersHealth {
17
+ count: number;
18
+ maxSize: number;
19
+ large: number;
20
+ aged: number;
21
+ }
9
22
  export interface TensionHealth {
10
23
  total: number;
11
24
  byKind: Record<TensionKind, number>;
@@ -13,6 +26,9 @@ export interface TensionHealth {
13
26
  byResolutionKind: Record<ResolutionKind, number>;
14
27
  stableAcknowledged: number;
15
28
  unspecifiedLegacy: number;
29
+ aging: TensionAging;
30
+ clusters: TensionClustersHealth;
31
+ blastRadiusOfStaleTensions: number;
16
32
  }
17
33
  export interface LintReport {
18
34
  generatedAt: string;
@@ -25,6 +41,5 @@ export interface LintOptions {
25
41
  draftMaxDays?: number;
26
42
  lowConfidenceMaxDays?: number;
27
43
  }
28
- export declare function extractLinks(content: string): string[];
29
44
  export declare function runLint(vaultRoot: string, opts?: LintOptions): Promise<Result<LintReport, Error>>;
30
45
  //# sourceMappingURL=lint.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/curation/lint.ts"],"names":[],"mappings":"AASA,OAAO,EAAwB,KAAK,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAI5E,OAAO,EAGL,KAAK,cAAc,EAEnB,KAAK,WAAW,EACjB,MAAM,cAAc,CAAC;AAEtB,eAAO,MAAM,WAAW,8HAOd,CAAC;AACX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAiBD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IACjD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,WAAW,EAAE,CAAC,CAAC;IAC7C,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,aAAa,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAYD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAiBtD;AAgFD,wBAAsB,OAAO,CAC3B,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAqHpC"}
1
+ {"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/curation/lint.ts"],"names":[],"mappings":"AAOA,OAAO,EAAM,KAAK,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAG1D,OAAO,EAIL,KAAK,cAAc,EAGnB,KAAK,WAAW,EACjB,MAAM,cAAc,CAAC;AAWtB,eAAO,MAAM,WAAW,8HAOd,CAAC;AACX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAyBD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACzC,aAAa,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;CAC7E;AAOD,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IACjD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,qBAAqB,CAAC;IAMhC,0BAA0B,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,WAAW,EAAE,CAAC,CAAC;IAC7C,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,aAAa,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AA8BD,wBAAsB,OAAO,CAC3B,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAqHpC"}
@@ -4,13 +4,13 @@
4
4
  // runs six checks. It only ever *reports*: no file is edited, no status is
5
5
  // changed, nothing is auto-fixed. The output is a structured report grouped by
6
6
  // check, for a human (or an agent acting on a human's behalf) to triage.
7
- import { posix } from "node:path";
8
- import { parseDocument } from "../frontmatter/parser.js";
9
7
  import { ok } from "../frontmatter/types.js";
10
- import { listFiles, readFile, resolveVaultPath } from "../storage/local.js";
11
8
  import { DRAFT_MAX_DAYS, LOW_CONFIDENCE_MAX_DAYS } from "./decay.js";
12
9
  import { ageInDays, computeStaleness } from "./staleness.js";
13
- import { listTensions, RESOLUTION_KINDS, TENSION_KINDS, } from "./tension.js";
10
+ import { agingTier, listTensions, RESOLUTION_KINDS, STALE_TIER_LINT_COPY, TENSION_KINDS, } from "./tension.js";
11
+ import { buildReverseLinkMap, buildReverseSourceMap, computeBlast } from "./tension-blast.js";
12
+ import { computeTensionClusters } from "./tension-clusters.js";
13
+ import { buildPathIndexes, extractLinks, loadDocuments, resolveLink, } from "./vault-docs.js";
14
14
  export const LINT_CHECKS = [
15
15
  "staleFiles",
16
16
  "orphanFiles",
@@ -19,45 +19,6 @@ export const LINT_CHECKS = [
19
19
  "deprecatedStillLinked",
20
20
  "unansweredQuestions",
21
21
  ];
22
- // --- link extraction ------------------------------------------------------
23
- // Pulls every internal link target out of a markdown body: both [[wikilinks]]
24
- // and [text](target) markdown links. External URLs and anchors are dropped.
25
- export function extractLinks(content) {
26
- const targets = [];
27
- for (const m of content.matchAll(/\[\[([^\]]+)\]\]/g)) {
28
- // A wikilink may carry a |display alias and/or a #heading anchor.
29
- const raw = m[1].split("|")[0]?.split("#")[0]?.trim();
30
- if (raw)
31
- targets.push(raw);
32
- }
33
- for (const m of content.matchAll(/\[[^\]]*\]\(([^)\s]+)\)/g)) {
34
- const raw = m[1].split("#")[0]?.trim();
35
- if (!raw)
36
- continue;
37
- if (/^(https?:|mailto:|#)/i.test(raw))
38
- continue;
39
- targets.push(raw);
40
- }
41
- return targets;
42
- }
43
- // Resolves a raw link target to a vault-relative path, or null if it points
44
- // nowhere. Tries, in order: the target as-is, with a .md suffix, resolved
45
- // relative to the linking file's directory, then a bare basename match (the
46
- // common [[note-name]] wikilink form).
47
- function resolveLink(rawTarget, fromPath, byPath, byBasename) {
48
- const withMd = (p) => (p.endsWith(".md") ? p : `${p}.md`);
49
- if (byPath.has(rawTarget))
50
- return rawTarget;
51
- if (byPath.has(withMd(rawTarget)))
52
- return withMd(rawTarget);
53
- const relual = posix.normalize(posix.join(posix.dirname(fromPath), rawTarget));
54
- if (byPath.has(relual))
55
- return relual;
56
- if (byPath.has(withMd(relual)))
57
- return withMd(relual);
58
- const base = posix.basename(rawTarget).replace(/\.md$/, "");
59
- return byBasename.get(base) ?? null;
60
- }
61
22
  // --- question matching ----------------------------------------------------
62
23
  // Normalizes a question for cross-document matching: trimmed, lower-cased,
63
24
  // internal whitespace collapsed. Exact (normalized) equality is the matching
@@ -66,39 +27,9 @@ function normalizeQuestion(q) {
66
27
  return q.trim().toLowerCase().replace(/\s+/g, " ");
67
28
  }
68
29
  // --- check orchestration --------------------------------------------------
69
- async function loadDocuments(vaultRoot) {
70
- const list = await listFiles(vaultRoot);
71
- if (!list.ok)
72
- return list;
73
- const docs = [];
74
- for (const relPath of list.value) {
75
- const resolved = resolveVaultPath(vaultRoot, relPath);
76
- if (!resolved.ok)
77
- continue;
78
- const file = await readFile(resolved.value);
79
- if (!file.ok)
80
- continue;
81
- const parsed = parseDocument(file.value);
82
- if (!parsed.ok)
83
- continue;
84
- docs.push({
85
- path: relPath,
86
- frontmatter: parsed.value.frontmatter,
87
- content: parsed.value.content,
88
- });
89
- }
90
- return ok(docs);
91
- }
92
30
  // Maps each document to the set of documents that link to it.
93
31
  function buildInboundMap(docs) {
94
- const byPath = new Set(docs.map((d) => d.path));
95
- const byBasename = new Map();
96
- for (const d of docs) {
97
- const base = posix.basename(d.path).replace(/\.md$/, "");
98
- // First write wins, so a basename collision resolves deterministically.
99
- if (!byBasename.has(base))
100
- byBasename.set(base, d.path);
101
- }
32
+ const { byPath, byBasename } = buildPathIndexes(docs);
102
33
  const inbound = new Map();
103
34
  for (const d of docs) {
104
35
  for (const raw of extractLinks(d.content)) {
@@ -206,7 +137,7 @@ export async function runLint(vaultRoot, opts = {}) {
206
137
  }
207
138
  }
208
139
  const totalFindings = LINT_CHECKS.reduce((n, name) => n + checks[name].length, 0);
209
- const tensionHealth = await computeTensionHealth(vaultRoot);
140
+ const tensionHealth = await computeTensionHealth(vaultRoot, docs, now);
210
141
  if (!tensionHealth.ok)
211
142
  return tensionHealth;
212
143
  return ok({
@@ -216,18 +147,29 @@ export async function runLint(vaultRoot, opts = {}) {
216
147
  tensionHealth: tensionHealth.value,
217
148
  });
218
149
  }
219
- // Aggregates the tension log into the Phase 1 health summary. A missing log
220
- // is not an error — every counter is just zero.
221
- async function computeTensionHealth(vaultRoot) {
150
+ // Aggregates the tension log into the Phase 1 health summary plus the Phase 4
151
+ // aging breakdown. A missing log is not an error — every counter is zero.
152
+ //
153
+ // Aging scope: tiers are counted over the active surface only. An entry
154
+ // contributes to fresh / aging / stale iff it is unresolved AND `agingTier`
155
+ // returns a non-null tier (which already excludes `unspecified`). Resolved
156
+ // entries — including `resolution.kind: accepted` — do not appear in any
157
+ // aging tier; they show up in the Phase 1 stable-acknowledged and resolved
158
+ // totals instead.
159
+ async function computeTensionHealth(vaultRoot, docs, now) {
222
160
  const tensions = await listTensions(vaultRoot);
223
161
  if (!tensions.ok)
224
162
  return tensions;
225
163
  const byKind = Object.fromEntries(TENSION_KINDS.map((k) => [k, 0]));
226
164
  const byResolutionKind = Object.fromEntries(RESOLUTION_KINDS.map((k) => [k, 0]));
165
+ const staleByKind = Object.fromEntries(TENSION_KINDS.map((k) => [k, 0]));
227
166
  let total = 0;
228
167
  let resolvedLifetime = 0;
229
168
  let stableAcknowledged = 0;
230
169
  let unspecifiedLegacy = 0;
170
+ let fresh = 0;
171
+ let aging = 0;
172
+ let stale = 0;
231
173
  for (const t of tensions.value) {
232
174
  total += 1;
233
175
  byKind[t.kind] += 1;
@@ -239,7 +181,75 @@ async function computeTensionHealth(vaultRoot) {
239
181
  if (t.resolution.kind === "accepted")
240
182
  stableAcknowledged += 1;
241
183
  }
184
+ if (t.resolved)
185
+ continue;
186
+ const tier = agingTier(t, now);
187
+ if (tier === "fresh")
188
+ fresh += 1;
189
+ else if (tier === "aging")
190
+ aging += 1;
191
+ else if (tier === "stale") {
192
+ stale += 1;
193
+ staleByKind[t.kind] += 1;
194
+ }
195
+ }
196
+ // Render kind-specific stale-tier copy only for kinds with a nonzero count.
197
+ // `unspecified` never produces a message even if the count somehow appears
198
+ // (it can't, since unspecified entries get tier null — defense in depth).
199
+ const staleMessages = {};
200
+ for (const kind of ["temporal", "factual", "interpretive"]) {
201
+ if (staleByKind[kind] > 0) {
202
+ staleMessages[kind] = STALE_TIER_LINT_COPY[kind];
203
+ }
204
+ }
205
+ // Cluster surface (Phase 2). computeTensionClusters applies the same scope
206
+ // filter the cluster tool does — unresolved AND non-accepted — so the lint
207
+ // metrics line up exactly with what `vault_tension_clusters` reports.
208
+ const clusterResult = computeTensionClusters(tensions.value, now);
209
+ let maxSize = 0;
210
+ let large = 0;
211
+ let aged = 0;
212
+ for (const c of clusterResult.clusters) {
213
+ if (c.size > maxSize)
214
+ maxSize = c.size;
215
+ if (c.size > 5)
216
+ large += 1;
217
+ if (c.oldest_tension_age_days > 90)
218
+ aged += 1;
242
219
  }
220
+ const clusters = {
221
+ count: clusterResult.cluster_count,
222
+ maxSize,
223
+ large,
224
+ aged,
225
+ };
226
+ // Step 5 of the tension graph plan (2026-05-31). Collect every contested
227
+ // doc from every entry where `resolved: false` AND `agingTier === "stale"`,
228
+ // then reuse computeBlast to walk the dependency graph from that union as
229
+ // seeds. We report the count of the `primary_blast` channel — the same
230
+ // sources-only primary set that vault_tension_blast returns. Advisory link
231
+ // edges still participate in BFS traversal (so a doc reached via a link
232
+ // edge can still gain `source` classification from a separate incoming
233
+ // source edge), but the published metric is the primary count only — the
234
+ // top-level lint metric stays disciplined against advisory inflation.
235
+ const staleSeeds = new Set();
236
+ for (const t of tensions.value) {
237
+ if (t.resolved)
238
+ continue;
239
+ if (agingTier(t, now) !== "stale")
240
+ continue;
241
+ if (t.sourceA)
242
+ staleSeeds.add(t.sourceA);
243
+ if (t.sourceB)
244
+ staleSeeds.add(t.sourceB);
245
+ }
246
+ const reverseSource = buildReverseSourceMap(docs);
247
+ const reverseLink = buildReverseLinkMap(docs);
248
+ const blast = computeBlast({
249
+ seeds: [...staleSeeds],
250
+ reverseSource,
251
+ reverseLink,
252
+ });
243
253
  return ok({
244
254
  total,
245
255
  byKind,
@@ -247,6 +257,9 @@ async function computeTensionHealth(vaultRoot) {
247
257
  byResolutionKind,
248
258
  stableAcknowledged,
249
259
  unspecifiedLegacy,
260
+ aging: { fresh, aging, stale, staleByKind, staleMessages },
261
+ clusters,
262
+ blastRadiusOfStaleTensions: blast.primary_blast,
250
263
  });
251
264
  }
252
265
  //# sourceMappingURL=lint.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lint.js","sourceRoot":"","sources":["../../src/curation/lint.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lint.js","sourceRoot":"","sources":["../../src/curation/lint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { type Result } from "../frontmatter/types.js";
2
+ import { type LoadedDoc } from "./vault-docs.js";
3
+ export type BlastDependencyType = "source" | "link";
4
+ export interface BlastDownstreamEntry {
5
+ path: string;
6
+ dependency_type: BlastDependencyType;
7
+ distance: number;
8
+ }
9
+ export interface TensionBlastResult {
10
+ contested_document: string | null;
11
+ cluster_id: string | null;
12
+ cluster_documents: string[];
13
+ downstream: BlastDownstreamEntry[];
14
+ primary_blast: number;
15
+ advisory_blast: number;
16
+ max_depth: number;
17
+ }
18
+ export interface TensionBlastInput {
19
+ document?: string;
20
+ cluster_id?: string;
21
+ }
22
+ export declare function buildReverseSourceMap(docs: LoadedDoc[]): Map<string, Set<string>>;
23
+ export declare function buildReverseLinkMap(docs: LoadedDoc[]): Map<string, Set<string>>;
24
+ export interface ComputeBlastArgs {
25
+ seeds: string[];
26
+ reverseSource: Map<string, Set<string>>;
27
+ reverseLink: Map<string, Set<string>>;
28
+ }
29
+ export interface ComputeBlastOutput {
30
+ downstream: BlastDownstreamEntry[];
31
+ primary_blast: number;
32
+ advisory_blast: number;
33
+ max_depth: number;
34
+ }
35
+ export declare function computeBlast(args: ComputeBlastArgs): ComputeBlastOutput;
36
+ export declare function computeTensionBlast(vaultRoot: string, input: TensionBlastInput): Promise<Result<TensionBlastResult, Error>>;
37
+ //# sourceMappingURL=tension-blast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tension-blast.d.ts","sourceRoot":"","sources":["../../src/curation/tension-blast.ts"],"names":[],"mappings":"AAuCA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,EAGL,KAAK,SAAS,EAGf,MAAM,iBAAiB,CAAC;AAEzB,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,mBAAmB,CAAC;IACrC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAQD,MAAM,WAAW,kBAAkB;IACjC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,UAAU,EAAE,oBAAoB,EAAE,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAQD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAYjF;AAKD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAY/E;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IACxC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,oBAAoB,EAAE,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAaD,wBAAgB,YAAY,CAAC,IAAI,EAAE,gBAAgB,GAAG,kBAAkB,CA8DvE;AAKD,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC,CAoE5C"}
@@ -0,0 +1,223 @@
1
+ // Tension blast radius — Phase 3 of the tension graph plan (2026-05-31).
2
+ //
3
+ // "Blast" is the transitive closure of downstream documents that cite or
4
+ // depend on a contested node. Given either a single document or a tension
5
+ // cluster, this surface walks the dependency graph and reports the docs
6
+ // exposed to that contested state.
7
+ //
8
+ // Two edge types (spec, Gap 5):
9
+ // - frontmatter `sources` array → "source" edges (primary, high-confidence).
10
+ // - in-vault markdown links → "link" edges (advisory).
11
+ //
12
+ // `superseded_by` is NOT a blast edge. A doc that supersedes a contested doc
13
+ // is the *replacement*, not an inheritor — walking the blast through that
14
+ // relationship would falsely contaminate the resolution path. The existing
15
+ // `deprecated-still-linked` lint check covers the related-but-different
16
+ // question of deprecated docs still being cited.
17
+ //
18
+ // Two confidence channels (spec, Gap 6):
19
+ // - `primary_blast`: count of downstream docs that have at least one
20
+ // incoming source edge from a visited node (a contested member or a doc
21
+ // already in the downstream set).
22
+ // - `advisory_blast`: count of downstream docs reached only via link edges.
23
+ //
24
+ // A doc reachable via both edge types counts as primary — higher-confidence
25
+ // wins. The per-immediate-edge rule matches the spec's "reached via both edge
26
+ // types" wording: from the downstream doc's perspective, does any visited
27
+ // predecessor cite it via the `sources` frontmatter array?
28
+ //
29
+ // Two input modes (spec, Gap 7):
30
+ // - document mode: blast for a single doc. Response also identifies the
31
+ // containing cluster (if any) so the agent sees the broader region.
32
+ // - cluster mode: blast for the union of all cluster members. Seeds are
33
+ // never reported as downstream of themselves.
34
+ //
35
+ // Computation is on-demand — we build the reverse-source and reverse-link
36
+ // maps at tool-call time from the loaded docs. There is no maintained graph.
37
+ // Cycle protection is implicit: BFS marks nodes visited; a node is never
38
+ // re-queued, so a sources b sources a terminates after one round trip.
39
+ import { err, ok } from "../frontmatter/types.js";
40
+ import { loadTensionClusters } from "./tension-clusters.js";
41
+ import { buildPathIndexes, extractLinks, loadDocuments, resolveLink, } from "./vault-docs.js";
42
+ // Reverse-source map: target doc → docs whose frontmatter `sources` cites
43
+ // the target. Source paths are resolved through the same path-resolution
44
+ // rules as in-vault links (exact match, .md suffix, relative-to-from,
45
+ // basename), so author-written shorthand paths like `pricing/foo` line up
46
+ // with the canonical `pricing/foo.md`. Unresolved sources (typos, links to
47
+ // non-vault material) and self-citations are dropped.
48
+ export function buildReverseSourceMap(docs) {
49
+ const reverse = new Map();
50
+ const { byPath, byBasename } = buildPathIndexes(docs);
51
+ for (const d of docs) {
52
+ for (const raw of d.frontmatter.sources ?? []) {
53
+ const target = resolveLink(raw, d.path, byPath, byBasename);
54
+ if (!target || target === d.path)
55
+ continue;
56
+ if (!reverse.has(target))
57
+ reverse.set(target, new Set());
58
+ reverse.get(target).add(d.path);
59
+ }
60
+ }
61
+ return reverse;
62
+ }
63
+ // Reverse-link map: target doc → docs whose body contains an in-vault
64
+ // markdown or wikilink to the target. Mirrors lint's inbound-link map but
65
+ // exposed as its own helper so blast and lint can't drift.
66
+ export function buildReverseLinkMap(docs) {
67
+ const reverse = new Map();
68
+ const { byPath, byBasename } = buildPathIndexes(docs);
69
+ for (const d of docs) {
70
+ for (const raw of extractLinks(d.content)) {
71
+ const target = resolveLink(raw, d.path, byPath, byBasename);
72
+ if (!target || target === d.path)
73
+ continue;
74
+ if (!reverse.has(target))
75
+ reverse.set(target, new Set());
76
+ reverse.get(target).add(d.path);
77
+ }
78
+ }
79
+ return reverse;
80
+ }
81
+ // Pure BFS over the combined edge set. Returns the sorted downstream list,
82
+ // the two channel counts, and the max depth observed.
83
+ //
84
+ // Layered BFS guarantees `distance` is the minimum hop count from any seed;
85
+ // the `visited` set is the cycle guard, so a doc is never re-queued.
86
+ //
87
+ // Channel assignment is per-immediate-edge: a downstream doc D is "source"
88
+ // iff some visited node V (a seed or another downstream doc) has D in its
89
+ // reverse-source successor list, i.e. D's frontmatter cites V. Otherwise D
90
+ // is "link". This matches the spec's "reached via both edge types counts as
91
+ // primary" wording while staying decidable from the dependency graph alone.
92
+ export function computeBlast(args) {
93
+ const { seeds, reverseSource, reverseLink } = args;
94
+ const seedSet = new Set(seeds);
95
+ const visited = new Set(seeds);
96
+ const distance = new Map();
97
+ let frontier = new Set(seeds);
98
+ let depth = 0;
99
+ while (frontier.size > 0) {
100
+ const next = new Set();
101
+ for (const node of frontier) {
102
+ const successors = new Set();
103
+ for (const s of reverseSource.get(node) ?? [])
104
+ successors.add(s);
105
+ for (const s of reverseLink.get(node) ?? [])
106
+ successors.add(s);
107
+ for (const succ of successors) {
108
+ if (visited.has(succ))
109
+ continue;
110
+ visited.add(succ);
111
+ distance.set(succ, depth + 1);
112
+ next.add(succ);
113
+ }
114
+ }
115
+ frontier = next;
116
+ depth += 1;
117
+ }
118
+ // primaryDownstream: every doc that has at least one incoming source edge
119
+ // from a visited node. Built by iterating each visited node's
120
+ // reverse-source successors; we exclude seeds because the response only
121
+ // surfaces downstream-of-the-contested-set, never the contested set
122
+ // itself.
123
+ const primaryDownstream = new Set();
124
+ for (const v of visited) {
125
+ for (const child of reverseSource.get(v) ?? []) {
126
+ if (seedSet.has(child))
127
+ continue;
128
+ primaryDownstream.add(child);
129
+ }
130
+ }
131
+ const entries = [];
132
+ for (const [path, dist] of distance) {
133
+ const dependency_type = primaryDownstream.has(path) ? "source" : "link";
134
+ entries.push({ path, dependency_type, distance: dist });
135
+ }
136
+ entries.sort((a, b) => {
137
+ if (a.distance !== b.distance)
138
+ return a.distance - b.distance;
139
+ if (a.dependency_type !== b.dependency_type) {
140
+ return a.dependency_type === "source" ? -1 : 1;
141
+ }
142
+ return a.path < b.path ? -1 : a.path > b.path ? 1 : 0;
143
+ });
144
+ let primary_blast = 0;
145
+ let advisory_blast = 0;
146
+ let max_depth = 0;
147
+ for (const e of entries) {
148
+ if (e.dependency_type === "source")
149
+ primary_blast += 1;
150
+ else
151
+ advisory_blast += 1;
152
+ if (e.distance > max_depth)
153
+ max_depth = e.distance;
154
+ }
155
+ return { downstream: entries, primary_blast, advisory_blast, max_depth };
156
+ }
157
+ // Orchestration: validate the exactly-one-of input, load the docs and
158
+ // clusters, resolve seeds, build the reverse maps, run the BFS, and assemble
159
+ // the response. Returns a Result — tool handlers never throw.
160
+ export async function computeTensionBlast(vaultRoot, input) {
161
+ const hasDoc = typeof input.document === "string" && input.document.length > 0;
162
+ const hasCluster = typeof input.cluster_id === "string" && input.cluster_id.length > 0;
163
+ if (hasDoc && hasCluster) {
164
+ return err(new Error("vault_tension_blast accepts exactly one of 'document' or 'cluster_id', not both"));
165
+ }
166
+ if (!hasDoc && !hasCluster) {
167
+ return err(new Error("vault_tension_blast requires exactly one of 'document' or 'cluster_id'"));
168
+ }
169
+ const docsResult = await loadDocuments(vaultRoot);
170
+ if (!docsResult.ok)
171
+ return docsResult;
172
+ const docs = docsResult.value;
173
+ const knownPaths = new Set(docs.map((d) => d.path));
174
+ const clustersResult = await loadTensionClusters(vaultRoot);
175
+ if (!clustersResult.ok)
176
+ return clustersResult;
177
+ const clusters = clustersResult.value.clusters;
178
+ let seeds;
179
+ let contested_document;
180
+ let cluster_id = null;
181
+ let cluster_documents = [];
182
+ if (hasDoc) {
183
+ const doc = input.document;
184
+ if (!knownPaths.has(doc)) {
185
+ return err(new Error(`vault_tension_blast: document not found in vault: ${doc}`));
186
+ }
187
+ contested_document = doc;
188
+ const containing = clusters.find((c) => c.documents.includes(doc));
189
+ if (containing) {
190
+ cluster_id = containing.id;
191
+ cluster_documents = [...containing.documents];
192
+ }
193
+ seeds = [doc];
194
+ }
195
+ else {
196
+ const id = input.cluster_id;
197
+ const found = clusters.find((c) => c.id === id);
198
+ if (!found) {
199
+ return err(new Error(`vault_tension_blast: cluster_id not found: ${id}`));
200
+ }
201
+ contested_document = null;
202
+ cluster_id = found.id;
203
+ cluster_documents = [...found.documents];
204
+ seeds = [...found.documents];
205
+ }
206
+ const reverseSource = buildReverseSourceMap(docs);
207
+ const reverseLink = buildReverseLinkMap(docs);
208
+ const { downstream, primary_blast, advisory_blast, max_depth } = computeBlast({
209
+ seeds,
210
+ reverseSource,
211
+ reverseLink,
212
+ });
213
+ return ok({
214
+ contested_document,
215
+ cluster_id,
216
+ cluster_documents,
217
+ downstream,
218
+ primary_blast,
219
+ advisory_blast,
220
+ max_depth,
221
+ });
222
+ }
223
+ //# sourceMappingURL=tension-blast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tension-blast.js","sourceRoot":"","sources":["../../src/curation/tension-blast.ts"],"names":[],"mappings":"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"}