daftari 1.17.1 → 1.19.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 (84) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/dist/audit/checks/describes_refs.d.ts +3 -0
  3. package/dist/audit/checks/describes_refs.d.ts.map +1 -0
  4. package/dist/audit/checks/describes_refs.js +27 -0
  5. package/dist/audit/checks/describes_refs.js.map +1 -0
  6. package/dist/audit/checks/staleness.d.ts.map +1 -1
  7. package/dist/audit/checks/staleness.js +4 -0
  8. package/dist/audit/checks/staleness.js.map +1 -1
  9. package/dist/audit/collect.d.ts.map +1 -1
  10. package/dist/audit/collect.js +47 -0
  11. package/dist/audit/collect.js.map +1 -1
  12. package/dist/audit/config.d.ts.map +1 -1
  13. package/dist/audit/config.js +32 -5
  14. package/dist/audit/config.js.map +1 -1
  15. package/dist/audit/describes.d.ts +9 -0
  16. package/dist/audit/describes.d.ts.map +1 -0
  17. package/dist/audit/describes.js +53 -0
  18. package/dist/audit/describes.js.map +1 -0
  19. package/dist/audit/exit.d.ts +1 -0
  20. package/dist/audit/exit.d.ts.map +1 -1
  21. package/dist/audit/exit.js +2 -0
  22. package/dist/audit/exit.js.map +1 -1
  23. package/dist/audit/index.d.ts +5 -1
  24. package/dist/audit/index.d.ts.map +1 -1
  25. package/dist/audit/index.js +112 -6
  26. package/dist/audit/index.js.map +1 -1
  27. package/dist/audit/readtext.d.ts +16 -0
  28. package/dist/audit/readtext.d.ts.map +1 -0
  29. package/dist/audit/readtext.js +50 -0
  30. package/dist/audit/readtext.js.map +1 -0
  31. package/dist/audit/report.d.ts.map +1 -1
  32. package/dist/audit/report.js +38 -1
  33. package/dist/audit/report.js.map +1 -1
  34. package/dist/audit/semantic.d.ts +35 -0
  35. package/dist/audit/semantic.d.ts.map +1 -0
  36. package/dist/audit/semantic.js +151 -0
  37. package/dist/audit/semantic.js.map +1 -0
  38. package/dist/audit/types.d.ts +30 -0
  39. package/dist/audit/types.d.ts.map +1 -1
  40. package/dist/audit/types.js +4 -0
  41. package/dist/audit/types.js.map +1 -1
  42. package/dist/backfill/apply.d.ts.map +1 -1
  43. package/dist/backfill/apply.js +18 -0
  44. package/dist/backfill/apply.js.map +1 -1
  45. package/dist/backfill/collisions.d.ts +3 -0
  46. package/dist/backfill/collisions.d.ts.map +1 -0
  47. package/dist/backfill/collisions.js +39 -0
  48. package/dist/backfill/collisions.js.map +1 -0
  49. package/dist/backfill/coverage.d.ts +3 -0
  50. package/dist/backfill/coverage.d.ts.map +1 -0
  51. package/dist/backfill/coverage.js +25 -0
  52. package/dist/backfill/coverage.js.map +1 -0
  53. package/dist/backfill/derive.d.ts +0 -1
  54. package/dist/backfill/derive.d.ts.map +1 -1
  55. package/dist/backfill/derive.js +32 -9
  56. package/dist/backfill/derive.js.map +1 -1
  57. package/dist/backfill/index.d.ts +4 -0
  58. package/dist/backfill/index.d.ts.map +1 -1
  59. package/dist/backfill/index.js +54 -18
  60. package/dist/backfill/index.js.map +1 -1
  61. package/dist/backfill/plan.d.ts.map +1 -1
  62. package/dist/backfill/plan.js +28 -3
  63. package/dist/backfill/plan.js.map +1 -1
  64. package/dist/backfill/types.d.ts +17 -0
  65. package/dist/backfill/types.d.ts.map +1 -1
  66. package/dist/eval/subgraph.d.ts +1 -0
  67. package/dist/eval/subgraph.d.ts.map +1 -1
  68. package/dist/eval/subgraph.js +67 -5
  69. package/dist/eval/subgraph.js.map +1 -1
  70. package/dist/eval/types.d.ts +1 -1
  71. package/dist/eval/types.d.ts.map +1 -1
  72. package/dist/eval/types.js.map +1 -1
  73. package/dist/frontmatter/schema.d.ts.map +1 -1
  74. package/dist/frontmatter/schema.js +1 -0
  75. package/dist/frontmatter/schema.js.map +1 -1
  76. package/dist/frontmatter/types.d.ts +2 -1
  77. package/dist/frontmatter/types.d.ts.map +1 -1
  78. package/dist/frontmatter/types.js +1 -0
  79. package/dist/frontmatter/types.js.map +1 -1
  80. package/dist/index.js +1 -1
  81. package/dist/tools/write.d.ts.map +1 -1
  82. package/dist/tools/write.js +1 -0
  83. package/dist/tools/write.js.map +1 -1
  84. package/package.json +1 -1
@@ -7,13 +7,48 @@
7
7
  // 3 — runtime error
8
8
  import { writeFile } from "node:fs/promises";
9
9
  import { resolve } from "node:path";
10
+ import { createAnthropicClient } from "../eval/llm.js";
10
11
  import { checkBrokenRefs } from "./checks/broken_refs.js";
12
+ import { checkDescribesRefs } from "./checks/describes_refs.js";
11
13
  import { checkStaleness } from "./checks/staleness.js";
12
14
  import { collectRepos } from "./collect.js";
13
15
  import { parseAuditConfig } from "./config.js";
16
+ import { classifyDescribesEdges } from "./describes.js";
14
17
  import { computeExitCode } from "./exit.js";
15
18
  import { classifyEdges } from "./links.js";
16
19
  import { renderJson, renderMarkdown } from "./report.js";
20
+ import { logSemanticTensions, runSemanticCheck } from "./semantic.js";
21
+ // Latest Sonnet — capable for doc/code comparison, cheaper than Opus for a
22
+ // per-binding classification. Override with --semantic-model.
23
+ const DEFAULT_SEMANTIC_MODEL = "claude-sonnet-4-6";
24
+ function readNumberArg(argv, flag) {
25
+ const raw = argv.find((a) => a === flag || a.startsWith(`${flag}=`));
26
+ if (raw === undefined)
27
+ return undefined;
28
+ const idx = argv.indexOf(raw);
29
+ const value = raw.includes("=") ? raw.slice(raw.indexOf("=") + 1) : argv[idx + 1];
30
+ const n = Number(value);
31
+ return Number.isFinite(n) ? n : undefined;
32
+ }
33
+ function readStringArg(argv, flag) {
34
+ const raw = argv.find((a) => a === flag || a.startsWith(`${flag}=`));
35
+ if (raw === undefined)
36
+ return undefined;
37
+ const idx = argv.indexOf(raw);
38
+ return raw.includes("=") ? raw.slice(raw.indexOf("=") + 1) : argv[idx + 1];
39
+ }
40
+ // The single docs repo that --auto-tension logs into. Tension entries live in a
41
+ // vault's .daftari/tensions.md, so the target vault must be unambiguous.
42
+ function resolveTensionVault(config) {
43
+ const docsRepos = config.repos.filter((r) => r.type !== "code");
44
+ if (docsRepos.length !== 1) {
45
+ return {
46
+ error: "--auto-tension requires exactly one docs repo to log tensions into; " +
47
+ `found ${docsRepos.length}`,
48
+ };
49
+ }
50
+ return docsRepos[0].path;
51
+ }
17
52
  const HELP = `daftari audit — coherence checks across markdown repos.
18
53
 
19
54
  Usage:
@@ -22,14 +57,27 @@ Usage:
22
57
  daftari audit --help
23
58
 
24
59
  Flags:
25
- --repo <path> Add a repo to the audit. May be repeated. Anonymous
26
- CLI repos get no URL patterns — URL-based cross-repo
27
- references to them will not be detected. Use --config
28
- to declare urls explicitly.
60
+ --repo <path> Add a docs repo to the audit. May be repeated.
61
+ Anonymous CLI repos get no URL patterns — URL-based
62
+ cross-repo references to them will not be detected.
63
+ Use --config to declare urls explicitly.
64
+ --code-repo <path> Add a code repo: a raw reference target indexed by
65
+ path only (no frontmatter parsing). May be repeated.
66
+ Doc-to-code \`describes\` bindings resolve against it.
29
67
  --config <path> Load an audit.yaml. CLI flags override its values for
30
68
  output paths (a warning is printed to stderr).
31
69
  --output <md> Markdown report destination (default: stdout).
32
70
  --output-json <json> JSON report destination (default: not written).
71
+ --semantic Opt-in LLM check: for each doc-to-code binding whose
72
+ target exists, ask whether the doc still accurately
73
+ describes the code. Slow and token-costly; off by
74
+ default. Requires ANTHROPIC_API_KEY.
75
+ --semantic-model <id> Model for --semantic (default: ${DEFAULT_SEMANTIC_MODEL}).
76
+ --max-semantic <n> Cap on semantic LLM calls (default: 200). Excess
77
+ bindings are skipped with a logged count.
78
+ --auto-tension With --semantic: log drifted/contradicted bindings as
79
+ tensions in the docs vault. Requires exactly one docs
80
+ repo. Never edits a doc.
33
81
 
34
82
  Exit codes:
35
83
  0 — run succeeded, all findings under configured thresholds
@@ -37,7 +85,7 @@ Exit codes:
37
85
  2 — config error (missing fields, bad paths, malformed YAML)
38
86
  3 — runtime error (IO failure during collection)
39
87
  `;
40
- export async function runAudit(argv) {
88
+ export async function runAudit(argv, overrides = {}) {
41
89
  if (argv.length === 0 || argv.includes("--help") || argv.includes("-h")) {
42
90
  process.stdout.write(HELP);
43
91
  return 0;
@@ -48,6 +96,38 @@ export async function runAudit(argv) {
48
96
  return parsed.error.kind === "config" ? 2 : 3;
49
97
  }
50
98
  const config = parsed.value;
99
+ const semantic = argv.includes("--semantic");
100
+ const autoTension = argv.includes("--auto-tension");
101
+ // --auto-tension only acts on semantic findings; without --semantic there are
102
+ // none, so it would be a silent no-op. Warn rather than do nothing quietly.
103
+ if (autoTension && !semantic) {
104
+ process.stderr.write("daftari audit: --auto-tension has no effect without --semantic (no findings to log)\n");
105
+ }
106
+ // Fail fast on semantic preconditions, before any collection work.
107
+ let tensionVault = null;
108
+ if (autoTension) {
109
+ const resolved = resolveTensionVault(config);
110
+ if (typeof resolved !== "string") {
111
+ process.stderr.write(`daftari audit: ${resolved.error}\n`);
112
+ return 2;
113
+ }
114
+ tensionVault = resolved;
115
+ }
116
+ let llm = null;
117
+ if (semantic) {
118
+ if (overrides.llm) {
119
+ llm = overrides.llm;
120
+ }
121
+ else {
122
+ try {
123
+ llm = createAnthropicClient();
124
+ }
125
+ catch (e) {
126
+ process.stderr.write(`daftari audit: ${e instanceof Error ? e.message : String(e)}\n`);
127
+ return 2;
128
+ }
129
+ }
130
+ }
51
131
  const collected = await collectRepos(config);
52
132
  if (!collected.ok) {
53
133
  process.stderr.write(`daftari audit: ${collected.error.message}\n`);
@@ -57,12 +137,36 @@ export async function runAudit(argv) {
57
137
  const edges = classifyEdges(snapshots);
58
138
  const brokenRefs = checkBrokenRefs(snapshots, edges);
59
139
  const staleness = checkStaleness(snapshots, edges, config.staleness.thresholdDays, new Date());
140
+ const describesEdges = classifyDescribesEdges(snapshots);
141
+ const describesRefs = checkDescribesRefs(snapshots, describesEdges);
142
+ let semanticFindings = [];
143
+ if (semantic && llm) {
144
+ semanticFindings = await runSemanticCheck(describesEdges, snapshots, {
145
+ llm,
146
+ model: readStringArg(argv, "--semantic-model") ?? DEFAULT_SEMANTIC_MODEL,
147
+ maxSemantic: readNumberArg(argv, "--max-semantic"),
148
+ onCap: (dropped) => process.stderr.write(`daftari audit: --semantic capped; ${dropped} binding(s) not checked ` +
149
+ `(raise --max-semantic to include them)\n`),
150
+ });
151
+ if (autoTension && tensionVault) {
152
+ const { logged, errors } = await logSemanticTensions(semanticFindings, tensionVault, "agent:daftari-audit");
153
+ if (logged > 0)
154
+ process.stderr.write(`daftari audit: logged ${logged} tension(s)\n`);
155
+ for (const err of errors)
156
+ process.stderr.write(`daftari audit: tension log: ${err}\n`);
157
+ }
158
+ }
60
159
  const totals = {
61
160
  reposScanned: snapshots.length,
62
- docsScanned: snapshots.reduce((n, s) => n + s.docs.size, 0),
161
+ // Only docs repos hold managed documents; code repos are reference targets.
162
+ docsScanned: snapshots
163
+ .filter((s) => s.config.type !== "code")
164
+ .reduce((n, s) => n + s.docs.size, 0),
63
165
  brokenRefs: brokenRefs.length,
64
166
  directlyStale: staleness.filter((f) => f.kind === "direct").length,
65
167
  transitivelyStale: staleness.filter((f) => f.kind === "transitive").length,
168
+ brokenDescribes: describesRefs.length,
169
+ semanticDrifted: semanticFindings.filter((f) => f.verdict === "drifted" || f.verdict === "contradicted").length,
66
170
  };
67
171
  const report = {
68
172
  generatedAt: new Date().toISOString(),
@@ -70,6 +174,8 @@ export async function runAudit(argv) {
70
174
  totals,
71
175
  brokenRefs,
72
176
  staleness,
177
+ describesRefs,
178
+ semantic: semanticFindings,
73
179
  };
74
180
  const md = renderMarkdown(report);
75
181
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/audit/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/audit/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { type Result } from "../frontmatter/types.js";
2
+ export declare const DEFAULT_MAX_BYTES: number;
3
+ export interface ReadTextOk {
4
+ text: string;
5
+ bytes: number;
6
+ }
7
+ export type ReadTextReason = "too_large" | "binary" | "encoding" | "unreadable";
8
+ export interface ReadTextError {
9
+ reason: ReadTextReason;
10
+ message: string;
11
+ }
12
+ export interface ReadTextOptions {
13
+ maxBytes?: number;
14
+ }
15
+ export declare function readTextFile(absPath: string, opts?: ReadTextOptions): Promise<Result<ReadTextOk, ReadTextError>>;
16
+ //# sourceMappingURL=readtext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readtext.d.ts","sourceRoot":"","sources":["../../src/audit/readtext.ts"],"names":[],"mappings":"AAcA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAE/D,eAAO,MAAM,iBAAiB,QAAa,CAAC;AAE5C,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,YAAY,CAAC;AAEhF,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC,CAmC5C"}
@@ -0,0 +1,50 @@
1
+ // src/audit/readtext.ts
2
+ // Guarded text-file reader for non-markdown reference targets. The audit reads
3
+ // arbitrary code files (semantic.ts; the eval subgraph loader in #121) and hands
4
+ // their contents to an LLM. Those files carry none of the guarantees the
5
+ // markdown path enjoys, so every read is bounded:
6
+ //
7
+ // - size-capped (default 256 KiB) — checked via stat BEFORE reading, so a
8
+ // huge generated/vendored file is never pulled into memory;
9
+ // - binary-sniffed (a NUL byte → not text) — never send raw bytes to a model;
10
+ // - strict UTF-8 — undecodable input is rejected rather than mojibake'd.
11
+ //
12
+ // Content is never stored, indexed, or embedded — it is read ephemerally.
13
+ import { readFile, stat } from "node:fs/promises";
14
+ import { err, ok } from "../frontmatter/types.js";
15
+ export const DEFAULT_MAX_BYTES = 256 * 1024;
16
+ export async function readTextFile(absPath, opts = {}) {
17
+ const maxBytes = opts.maxBytes ?? DEFAULT_MAX_BYTES;
18
+ let size;
19
+ try {
20
+ const st = await stat(absPath);
21
+ if (!st.isFile()) {
22
+ return err({ reason: "unreadable", message: `not a regular file: ${absPath}` });
23
+ }
24
+ size = st.size;
25
+ }
26
+ catch (e) {
27
+ return err({ reason: "unreadable", message: e instanceof Error ? e.message : String(e) });
28
+ }
29
+ if (size > maxBytes) {
30
+ return err({ reason: "too_large", message: `${size} bytes exceeds cap of ${maxBytes}` });
31
+ }
32
+ let buf;
33
+ try {
34
+ buf = await readFile(absPath);
35
+ }
36
+ catch (e) {
37
+ return err({ reason: "unreadable", message: e instanceof Error ? e.message : String(e) });
38
+ }
39
+ if (buf.includes(0)) {
40
+ return err({ reason: "binary", message: "contains NUL byte" });
41
+ }
42
+ try {
43
+ const text = new TextDecoder("utf-8", { fatal: true }).decode(buf);
44
+ return ok({ text, bytes: buf.length });
45
+ }
46
+ catch {
47
+ return err({ reason: "encoding", message: "not valid UTF-8" });
48
+ }
49
+ }
50
+ //# sourceMappingURL=readtext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readtext.js","sourceRoot":"","sources":["../../src/audit/readtext.ts"],"names":[],"mappings":"AAAA,wBAAwB;AACxB,+EAA+E;AAC/E,iFAAiF;AACjF,yEAAyE;AACzE,kDAAkD;AAClD,EAAE;AACF,4EAA4E;AAC5E,gEAAgE;AAChE,gFAAgF;AAChF,2EAA2E;AAC3E,EAAE;AACF,0EAA0E;AAE1E,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,GAAG,EAAE,EAAE,EAAe,MAAM,yBAAyB,CAAC;AAE/D,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,GAAG,IAAI,CAAC;AAkB5C,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAe,EACf,OAAwB,EAAE;IAE1B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,iBAAiB,CAAC;IAEpD,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/B,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC;YACjB,OAAO,GAAG,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,uBAAuB,OAAO,EAAE,EAAE,CAAC,CAAC;QAClF,CAAC;QACD,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC;IACjB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,GAAG,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC5F,CAAC;IAED,IAAI,IAAI,GAAG,QAAQ,EAAE,CAAC;QACpB,OAAO,GAAG,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,IAAI,yBAAyB,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC3F,CAAC;IAED,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,GAAG,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC5F,CAAC;IAED,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;QACpB,OAAO,GAAG,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACnE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC,CAAC;IACjE,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/audit/report.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAsC,MAAM,YAAY,CAAC;AAyBlF,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CA8B1D;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAEtD"}
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/audit/report.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,WAAW,EAIZ,MAAM,YAAY,CAAC;AAuDpB,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CA2C1D;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAEtD"}
@@ -21,9 +21,38 @@ function renderStaleness(rows) {
21
21
  }
22
22
  return `${lines.join("\n")}\n`;
23
23
  }
24
+ function renderDescribesRefs(rows) {
25
+ if (rows.length === 0)
26
+ return "_no broken doc-to-code bindings._\n";
27
+ const lines = ["| source | target | binding |", "|---|---|---|"];
28
+ for (const r of rows) {
29
+ const sym = r.target.symbol ? `::${r.target.symbol}` : "";
30
+ lines.push(`| ${r.source.repo}/${r.source.path} | ${r.target.repo}/${r.target.path}${sym} | \`${r.raw}\` |`);
31
+ }
32
+ return `${lines.join("\n")}\n`;
33
+ }
34
+ function renderSemantic(rows) {
35
+ // Only non-coherent verdicts are worth surfacing (drifted, contradicted, skipped).
36
+ const notable = rows.filter((r) => r.verdict !== "coherent");
37
+ if (notable.length === 0)
38
+ return "_all checked bindings are coherent._\n";
39
+ const lines = ["| verdict | source | target | detail |", "|---|---|---|---|"];
40
+ for (const r of notable) {
41
+ const sym = r.target.symbol ? `::${r.target.symbol}` : "";
42
+ const detail = r.verdict === "skipped"
43
+ ? (r.reason ?? "skipped")
44
+ : r.contradictions.join("; ") || "(no detail)";
45
+ lines.push(`| ${r.verdict} | ${r.source.repo}/${r.source.path} | ${r.target.repo}/${r.target.path}${sym} | ${detail} |`);
46
+ }
47
+ return `${lines.join("\n")}\n`;
48
+ }
24
49
  export function renderMarkdown(report) {
25
50
  const t = report.totals;
26
- const empty = t.brokenRefs === 0 && t.directlyStale === 0 && t.transitivelyStale === 0;
51
+ const empty = t.brokenRefs === 0 &&
52
+ t.directlyStale === 0 &&
53
+ t.transitivelyStale === 0 &&
54
+ t.brokenDescribes === 0 &&
55
+ report.semantic.length === 0;
27
56
  const head = [
28
57
  "# Coherence Audit Report",
29
58
  "",
@@ -36,6 +65,8 @@ export function renderMarkdown(report) {
36
65
  `- broken cross-repo refs: **${t.brokenRefs}**`,
37
66
  `- directly stale docs: **${t.directlyStale}**`,
38
67
  `- transitively stale docs: **${t.transitivelyStale}**`,
68
+ `- broken doc-to-code bindings: **${t.brokenDescribes}**`,
69
+ `- doc-to-code semantic drift: **${t.semanticDrifted}**`,
39
70
  "",
40
71
  ];
41
72
  if (empty) {
@@ -50,6 +81,12 @@ export function renderMarkdown(report) {
50
81
  "## Staleness",
51
82
  "",
52
83
  renderStaleness(report.staleness),
84
+ "## Broken doc-to-code bindings",
85
+ "",
86
+ renderDescribesRefs(report.describesRefs),
87
+ ...(report.semantic.length > 0
88
+ ? ["## Semantic coherence", "", renderSemantic(report.semantic)]
89
+ : []),
53
90
  ].join("\n");
54
91
  }
55
92
  export function renderJson(report) {
@@ -1 +1 @@
1
- {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/audit/report.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/audit/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { LlmClient } from "../eval/llm.js";
2
+ import { readTextFile } from "./readtext.js";
3
+ import type { DescribesEdge, RepoSnapshot } from "./types.js";
4
+ export declare const SEMANTIC_VERDICTS: readonly ["coherent", "drifted", "contradicted", "skipped"];
5
+ export type SemanticVerdict = (typeof SEMANTIC_VERDICTS)[number];
6
+ export interface SemanticFinding {
7
+ source: {
8
+ repo: string;
9
+ path: string;
10
+ };
11
+ target: {
12
+ repo: string;
13
+ path: string;
14
+ symbol: string | null;
15
+ };
16
+ raw: string;
17
+ verdict: SemanticVerdict;
18
+ contradictions: string[];
19
+ reason?: string;
20
+ }
21
+ export interface SemanticDeps {
22
+ llm: LlmClient;
23
+ model: string;
24
+ maxBytes?: number;
25
+ maxSemantic?: number;
26
+ readText?: typeof readTextFile;
27
+ onCap?: (dropped: number) => void;
28
+ }
29
+ export declare const DEFAULT_MAX_SEMANTIC = 200;
30
+ export declare function runSemanticCheck(edges: DescribesEdge[], snapshots: RepoSnapshot[], deps: SemanticDeps): Promise<SemanticFinding[]>;
31
+ export declare function logSemanticTensions(findings: SemanticFinding[], vaultRoot: string, loggedBy: string): Promise<{
32
+ logged: number;
33
+ errors: string[];
34
+ }>;
35
+ //# sourceMappingURL=semantic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic.d.ts","sourceRoot":"","sources":["../../src/audit/semantic.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE9D,eAAO,MAAM,iBAAiB,6DAA8D,CAAC;AAC7F,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAC9D,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,eAAe,CAAC;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,SAAS,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,YAAY,CAAC;IAC/B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAmDxC,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,aAAa,EAAE,EACtB,SAAS,EAAE,YAAY,EAAE,EACzB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,eAAe,EAAE,CAAC,CAmE5B;AAMD,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,eAAe,EAAE,EAC3B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAsB/C"}
@@ -0,0 +1,151 @@
1
+ // src/audit/semantic.ts
2
+ // Opt-in (--semantic) LLM drift check for doc-to-code bindings. For each
3
+ // resolvable `describes` edge it reads the declaring doc and the described code
4
+ // file (guarded by readtext.ts) and asks the model whether the doc still
5
+ // accurately describes the code. Reference integrity (checks/describes_refs.ts)
6
+ // already covers missing files; this catches the harder case — the file exists
7
+ // but the doc lies about it.
8
+ //
9
+ // The module never imports the Anthropic SDK: the LlmClient and the reader are
10
+ // injected, so it is fully unit-testable and the default (non-semantic) audit
11
+ // never pulls in the SDK.
12
+ import { addTension } from "../curation/tension.js";
13
+ import { readTextFile } from "./readtext.js";
14
+ export const SEMANTIC_VERDICTS = ["coherent", "drifted", "contradicted", "skipped"];
15
+ export const DEFAULT_MAX_SEMANTIC = 200;
16
+ const SYSTEM_PROMPT = `You audit whether a documentation file accurately describes a source code
17
+ file. You are given the documentation and the code it claims to describe.
18
+ Compare the doc's specific claims (function names, signatures, parameters,
19
+ behavior, error handling) against the code.
20
+
21
+ Return a verdict:
22
+ coherent — the doc accurately describes the code
23
+ drifted — the doc is partially out of date; some claims no longer match
24
+ contradicted — the doc makes claims the code directly contradicts
25
+
26
+ List the specific claims in the doc that no longer hold (empty when coherent).`;
27
+ // Verdict shape the model is asked to return.
28
+ const VERDICT_SCHEMA = {
29
+ type: "object",
30
+ required: ["verdict", "contradictions"],
31
+ properties: {
32
+ verdict: { enum: ["coherent", "drifted", "contradicted"] },
33
+ contradictions: { type: "array", items: { type: "string" } },
34
+ },
35
+ };
36
+ function buildUser(docPath, docText, codePath, codeText) {
37
+ return [
38
+ `Documentation file: ${docPath}`,
39
+ "```markdown",
40
+ docText,
41
+ "```",
42
+ "",
43
+ `Source code file: ${codePath}`,
44
+ "```",
45
+ codeText,
46
+ "```",
47
+ ].join("\n");
48
+ }
49
+ function parseVerdict(parsed) {
50
+ if (typeof parsed !== "object" || parsed === null)
51
+ return null;
52
+ const v = parsed.verdict;
53
+ const c = parsed.contradictions;
54
+ if (v !== "coherent" && v !== "drifted" && v !== "contradicted")
55
+ return null;
56
+ const contradictions = Array.isArray(c)
57
+ ? c.filter((x) => typeof x === "string")
58
+ : [];
59
+ return { verdict: v, contradictions };
60
+ }
61
+ export async function runSemanticCheck(edges, snapshots, deps) {
62
+ const readText = deps.readText ?? readTextFile;
63
+ const maxSemantic = deps.maxSemantic ?? DEFAULT_MAX_SEMANTIC;
64
+ const byRepo = new Map();
65
+ for (const snap of snapshots)
66
+ byRepo.set(snap.config.name, snap);
67
+ // Only edges whose target file actually exists are semantic candidates —
68
+ // missing targets are reference-integrity findings (#119), not drift.
69
+ const resolvable = edges.filter((e) => byRepo.get(e.targetRepo)?.docs.has(e.targetPath));
70
+ const toProcess = resolvable.slice(0, maxSemantic);
71
+ if (resolvable.length > toProcess.length) {
72
+ deps.onCap?.(resolvable.length - toProcess.length);
73
+ }
74
+ const findings = [];
75
+ for (const e of toProcess) {
76
+ const sourceDoc = byRepo.get(e.sourceRepo)?.docs.get(e.sourcePath);
77
+ const targetFile = byRepo.get(e.targetRepo)?.docs.get(e.targetPath);
78
+ const base = {
79
+ source: { repo: e.sourceRepo, path: e.sourcePath },
80
+ target: { repo: e.targetRepo, path: e.targetPath, symbol: e.symbol },
81
+ raw: e.raw,
82
+ };
83
+ const skip = (reason) => ({
84
+ ...base,
85
+ verdict: "skipped",
86
+ contradictions: [],
87
+ reason,
88
+ });
89
+ if (!sourceDoc || !targetFile) {
90
+ findings.push(skip("source or target snapshot unavailable"));
91
+ continue;
92
+ }
93
+ const codeRead = await readText(targetFile.absPath, { maxBytes: deps.maxBytes });
94
+ if (!codeRead.ok) {
95
+ findings.push(skip(`code unreadable: ${codeRead.error.reason}`));
96
+ continue;
97
+ }
98
+ const docRead = await readText(sourceDoc.absPath, { maxBytes: deps.maxBytes });
99
+ if (!docRead.ok) {
100
+ findings.push(skip(`doc unreadable: ${docRead.error.reason}`));
101
+ continue;
102
+ }
103
+ const res = await deps.llm.completeJson({
104
+ model: deps.model,
105
+ system: SYSTEM_PROMPT,
106
+ user: buildUser(e.sourcePath, docRead.value.text, e.targetPath, codeRead.value.text),
107
+ schema: VERDICT_SCHEMA,
108
+ });
109
+ if (!res.ok) {
110
+ findings.push(skip(`llm error: ${res.error.message}`));
111
+ continue;
112
+ }
113
+ const verdict = parseVerdict(res.value.parsed);
114
+ if (!verdict) {
115
+ findings.push(skip("llm returned an unparseable verdict"));
116
+ continue;
117
+ }
118
+ findings.push({ ...base, verdict: verdict.verdict, contradictions: verdict.contradictions });
119
+ }
120
+ return findings;
121
+ }
122
+ // --auto-tension: record drift/contradiction verdicts in the vault's tension
123
+ // log (the same store backing vault_tension_log). Coherent and skipped verdicts
124
+ // are not tensions. Logging is advisory and never edits a doc; a failed append
125
+ // is collected, not thrown.
126
+ export async function logSemanticTensions(findings, vaultRoot, loggedBy) {
127
+ let logged = 0;
128
+ const errors = [];
129
+ for (const f of findings) {
130
+ if (f.verdict !== "drifted" && f.verdict !== "contradicted")
131
+ continue;
132
+ const target = `${f.target.repo}/${f.target.path}`;
133
+ const res = await addTension(vaultRoot, {
134
+ title: `Doc-code ${f.verdict}: ${f.source.path} ↔ ${target}`,
135
+ kind: "factual",
136
+ sourceA: f.source.path,
137
+ claimA: f.contradictions.length > 0
138
+ ? f.contradictions.join("; ")
139
+ : "doc may no longer match the code it describes",
140
+ sourceB: target,
141
+ claimB: `current implementation (audit verdict: ${f.verdict})`,
142
+ loggedBy,
143
+ });
144
+ if (res.ok)
145
+ logged++;
146
+ else
147
+ errors.push(res.error.message);
148
+ }
149
+ return { logged, errors };
150
+ }
151
+ //# sourceMappingURL=semantic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic.js","sourceRoot":"","sources":["../../src/audit/semantic.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { SemanticFinding } from "./semantic.js";
1
2
  export type AuditConfig = {
2
3
  repos: RepoConfig[];
3
4
  output: {
@@ -10,13 +11,17 @@ export type AuditConfig = {
10
11
  failOn: {
11
12
  brokenRefs: number;
12
13
  transitiveStaleness: number;
14
+ brokenDescribes: number;
13
15
  };
14
16
  };
17
+ export declare const REPO_TYPES: readonly ["docs", "code"];
18
+ export type RepoType = (typeof REPO_TYPES)[number];
15
19
  export type RepoConfig = {
16
20
  name: string;
17
21
  path: string;
18
22
  docsGlob: string;
19
23
  urls: string[];
24
+ type: RepoType;
20
25
  };
21
26
  export type DocSnapshot = {
22
27
  relPath: string;
@@ -25,6 +30,7 @@ export type DocSnapshot = {
25
30
  mtimeSource: "git" | "fs";
26
31
  headings: Set<string>;
27
32
  links: LinkRef[];
33
+ describes: string[];
28
34
  };
29
35
  export type LinkRef = {
30
36
  rawHref: string;
@@ -45,6 +51,26 @@ export type LinkEdge = {
45
51
  targetAnchor: string | null;
46
52
  rawHref: string;
47
53
  };
54
+ export type DescribesEdge = {
55
+ sourceRepo: string;
56
+ sourcePath: string;
57
+ targetRepo: string;
58
+ targetPath: string;
59
+ symbol: string | null;
60
+ raw: string;
61
+ };
62
+ export type DescribesRefFinding = {
63
+ source: {
64
+ repo: string;
65
+ path: string;
66
+ };
67
+ target: {
68
+ repo: string;
69
+ path: string;
70
+ symbol: string | null;
71
+ };
72
+ raw: string;
73
+ };
48
74
  export type BrokenRefFinding = {
49
75
  kind: "missing_file" | "missing_anchor";
50
76
  source: {
@@ -78,9 +104,13 @@ export type AuditReport = {
78
104
  brokenRefs: number;
79
105
  directlyStale: number;
80
106
  transitivelyStale: number;
107
+ brokenDescribes: number;
108
+ semanticDrifted: number;
81
109
  };
82
110
  brokenRefs: BrokenRefFinding[];
83
111
  staleness: StalenessFinding[];
112
+ describesRefs: DescribesRefFinding[];
113
+ semantic: SemanticFinding[];
84
114
  };
85
115
  export type AuditError = {
86
116
  kind: "config";
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/audit/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/audit/types.ts"],"names":[],"mappings":"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"}