@seanhogg/builderforce-memory 2026.10.28 → 2026.10.29

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 (253) hide show
  1. package/dist/ingest/IngestionPipeline.d.ts +1 -8
  2. package/dist/ingest/IngestionPipeline.d.ts.map +1 -1
  3. package/dist/ingest/IngestionPipeline.js +3 -15
  4. package/dist/ingest/IngestionPipeline.js.map +1 -1
  5. package/dist/ingest/docsExtract.d.ts +30 -0
  6. package/dist/ingest/docsExtract.d.ts.map +1 -0
  7. package/dist/ingest/docsExtract.js +221 -0
  8. package/dist/ingest/docsExtract.js.map +1 -0
  9. package/dist/ingest/hash.d.ts +15 -0
  10. package/dist/ingest/hash.d.ts.map +1 -0
  11. package/dist/ingest/hash.js +22 -0
  12. package/dist/ingest/hash.js.map +1 -0
  13. package/dist/ingest/parsers.d.ts.map +1 -1
  14. package/dist/ingest/parsers.js +4 -0
  15. package/dist/ingest/parsers.js.map +1 -1
  16. package/dist/ingest/types.d.ts +7 -0
  17. package/dist/ingest/types.d.ts.map +1 -1
  18. package/dist/ingest/types.js.map +1 -1
  19. package/dist/knowledge/build.d.ts +24 -0
  20. package/dist/knowledge/build.d.ts.map +1 -0
  21. package/dist/knowledge/build.js +263 -0
  22. package/dist/knowledge/build.js.map +1 -0
  23. package/dist/knowledge/cards.d.ts +17 -0
  24. package/dist/knowledge/cards.d.ts.map +1 -0
  25. package/dist/knowledge/cards.js +118 -0
  26. package/dist/knowledge/cards.js.map +1 -0
  27. package/dist/knowledge/findings.d.ts +24 -0
  28. package/dist/knowledge/findings.d.ts.map +1 -0
  29. package/dist/knowledge/findings.js +152 -0
  30. package/dist/knowledge/findings.js.map +1 -0
  31. package/dist/knowledge/importance.d.ts +21 -0
  32. package/dist/knowledge/importance.d.ts.map +1 -0
  33. package/dist/knowledge/importance.js +70 -0
  34. package/dist/knowledge/importance.js.map +1 -0
  35. package/dist/knowledge/index.d.ts +31 -0
  36. package/dist/knowledge/index.d.ts.map +1 -0
  37. package/dist/knowledge/index.js +26 -0
  38. package/dist/knowledge/index.js.map +1 -0
  39. package/dist/knowledge/judge.d.ts +86 -0
  40. package/dist/knowledge/judge.d.ts.map +1 -0
  41. package/dist/knowledge/judge.js +213 -0
  42. package/dist/knowledge/judge.js.map +1 -0
  43. package/dist/knowledge/model.d.ts +333 -0
  44. package/dist/knowledge/model.d.ts.map +1 -0
  45. package/dist/knowledge/model.js +13 -0
  46. package/dist/knowledge/model.js.map +1 -0
  47. package/dist/knowledge/packs/docs.d.ts +17 -0
  48. package/dist/knowledge/packs/docs.d.ts.map +1 -0
  49. package/dist/knowledge/packs/docs.js +89 -0
  50. package/dist/knowledge/packs/docs.js.map +1 -0
  51. package/dist/knowledge/partitions.d.ts +31 -0
  52. package/dist/knowledge/partitions.d.ts.map +1 -0
  53. package/dist/knowledge/partitions.js +135 -0
  54. package/dist/knowledge/partitions.js.map +1 -0
  55. package/dist/knowledge/plan.d.ts +33 -0
  56. package/dist/knowledge/plan.d.ts.map +1 -0
  57. package/dist/knowledge/plan.js +89 -0
  58. package/dist/knowledge/plan.js.map +1 -0
  59. package/dist/knowledge/refs.d.ts +40 -0
  60. package/dist/knowledge/refs.d.ts.map +1 -0
  61. package/dist/knowledge/refs.js +102 -0
  62. package/dist/knowledge/refs.js.map +1 -0
  63. package/dist/knowledge/resolve.d.ts +35 -0
  64. package/dist/knowledge/resolve.d.ts.map +1 -0
  65. package/dist/knowledge/resolve.js +67 -0
  66. package/dist/knowledge/resolve.js.map +1 -0
  67. package/dist/knowledge/review.d.ts +23 -0
  68. package/dist/knowledge/review.d.ts.map +1 -0
  69. package/dist/knowledge/review.js +233 -0
  70. package/dist/knowledge/review.js.map +1 -0
  71. package/dist/knowledge/sources.d.ts +47 -0
  72. package/dist/knowledge/sources.d.ts.map +1 -0
  73. package/dist/knowledge/sources.js +136 -0
  74. package/dist/knowledge/sources.js.map +1 -0
  75. package/dist/knowledge/stores/localSnapshotStore.d.ts +50 -0
  76. package/dist/knowledge/stores/localSnapshotStore.d.ts.map +1 -0
  77. package/dist/knowledge/stores/localSnapshotStore.js +125 -0
  78. package/dist/knowledge/stores/localSnapshotStore.js.map +1 -0
  79. package/dist/knowledge/trace.d.ts +32 -0
  80. package/dist/knowledge/trace.d.ts.map +1 -0
  81. package/dist/knowledge/trace.js +102 -0
  82. package/dist/knowledge/trace.js.map +1 -0
  83. package/dist/knowledge/truncate.d.ts +24 -0
  84. package/dist/knowledge/truncate.d.ts.map +1 -0
  85. package/dist/knowledge/truncate.js +128 -0
  86. package/dist/knowledge/truncate.js.map +1 -0
  87. package/dist/memory/SemanticRecall.d.ts.map +1 -1
  88. package/dist/memory/SemanticRecall.js +3 -1
  89. package/dist/memory/SemanticRecall.js.map +1 -1
  90. package/dist/retrieval/HybridRetriever.d.ts.map +1 -1
  91. package/dist/retrieval/HybridRetriever.js +3 -1
  92. package/dist/retrieval/HybridRetriever.js.map +1 -1
  93. package/dist/retrieval/bm25.d.ts +3 -2
  94. package/dist/retrieval/bm25.d.ts.map +1 -1
  95. package/dist/retrieval/bm25.js +5 -3
  96. package/dist/retrieval/bm25.js.map +1 -1
  97. package/dist/retrieval/fusion.d.ts +2 -1
  98. package/dist/retrieval/fusion.d.ts.map +1 -1
  99. package/dist/retrieval/fusion.js +4 -2
  100. package/dist/retrieval/fusion.js.map +1 -1
  101. package/dist/retrieval/hnsw.d.ts +49 -11
  102. package/dist/retrieval/hnsw.d.ts.map +1 -1
  103. package/dist/retrieval/hnsw.js +57 -29
  104. package/dist/retrieval/hnsw.js.map +1 -1
  105. package/dist/retrieval/index.d.ts +7 -3
  106. package/dist/retrieval/index.d.ts.map +1 -1
  107. package/dist/retrieval/index.js +5 -2
  108. package/dist/retrieval/index.js.map +1 -1
  109. package/dist/retrieval/knowledge-index/bytes.d.ts +43 -0
  110. package/dist/retrieval/knowledge-index/bytes.d.ts.map +1 -0
  111. package/dist/retrieval/knowledge-index/bytes.js +151 -0
  112. package/dist/retrieval/knowledge-index/bytes.js.map +1 -0
  113. package/dist/retrieval/knowledge-index/cascade.d.ts +37 -0
  114. package/dist/retrieval/knowledge-index/cascade.d.ts.map +1 -0
  115. package/dist/retrieval/knowledge-index/cascade.js +111 -0
  116. package/dist/retrieval/knowledge-index/cascade.js.map +1 -0
  117. package/dist/retrieval/knowledge-index/compact.d.ts +18 -0
  118. package/dist/retrieval/knowledge-index/compact.d.ts.map +1 -0
  119. package/dist/retrieval/knowledge-index/compact.js +64 -0
  120. package/dist/retrieval/knowledge-index/compact.js.map +1 -0
  121. package/dist/retrieval/knowledge-index/csr.d.ts +41 -0
  122. package/dist/retrieval/knowledge-index/csr.d.ts.map +1 -0
  123. package/dist/retrieval/knowledge-index/csr.js +76 -0
  124. package/dist/retrieval/knowledge-index/csr.js.map +1 -0
  125. package/dist/retrieval/knowledge-index/digest.d.ts +21 -0
  126. package/dist/retrieval/knowledge-index/digest.d.ts.map +1 -0
  127. package/dist/retrieval/knowledge-index/digest.js +50 -0
  128. package/dist/retrieval/knowledge-index/digest.js.map +1 -0
  129. package/dist/retrieval/knowledge-index/embeddings.d.ts +32 -0
  130. package/dist/retrieval/knowledge-index/embeddings.d.ts.map +1 -0
  131. package/dist/retrieval/knowledge-index/embeddings.js +78 -0
  132. package/dist/retrieval/knowledge-index/embeddings.js.map +1 -0
  133. package/dist/retrieval/knowledge-index/expand.d.ts +19 -0
  134. package/dist/retrieval/knowledge-index/expand.d.ts.map +1 -0
  135. package/dist/retrieval/knowledge-index/expand.js +49 -0
  136. package/dist/retrieval/knowledge-index/expand.js.map +1 -0
  137. package/dist/retrieval/knowledge-index/index.d.ts +40 -0
  138. package/dist/retrieval/knowledge-index/index.d.ts.map +1 -0
  139. package/dist/retrieval/knowledge-index/index.js +134 -0
  140. package/dist/retrieval/knowledge-index/index.js.map +1 -0
  141. package/dist/retrieval/knowledge-index/lexical.d.ts +26 -0
  142. package/dist/retrieval/knowledge-index/lexical.d.ts.map +1 -0
  143. package/dist/retrieval/knowledge-index/lexical.js +76 -0
  144. package/dist/retrieval/knowledge-index/lexical.js.map +1 -0
  145. package/dist/retrieval/knowledge-index/pairs.d.ts +22 -0
  146. package/dist/retrieval/knowledge-index/pairs.d.ts.map +1 -0
  147. package/dist/retrieval/knowledge-index/pairs.js +51 -0
  148. package/dist/retrieval/knowledge-index/pairs.js.map +1 -0
  149. package/dist/retrieval/knowledge-index/prune.d.ts +21 -0
  150. package/dist/retrieval/knowledge-index/prune.d.ts.map +1 -0
  151. package/dist/retrieval/knowledge-index/prune.js +43 -0
  152. package/dist/retrieval/knowledge-index/prune.js.map +1 -0
  153. package/dist/retrieval/knowledge-index/quantize.d.ts +37 -0
  154. package/dist/retrieval/knowledge-index/quantize.d.ts.map +1 -0
  155. package/dist/retrieval/knowledge-index/quantize.js +77 -0
  156. package/dist/retrieval/knowledge-index/quantize.js.map +1 -0
  157. package/dist/retrieval/knowledge-index/serialize.d.ts +18 -0
  158. package/dist/retrieval/knowledge-index/serialize.d.ts.map +1 -0
  159. package/dist/retrieval/knowledge-index/serialize.js +123 -0
  160. package/dist/retrieval/knowledge-index/serialize.js.map +1 -0
  161. package/dist/retrieval/knowledge-index/sha256.d.ts +30 -0
  162. package/dist/retrieval/knowledge-index/sha256.d.ts.map +1 -0
  163. package/dist/retrieval/knowledge-index/sha256.js +130 -0
  164. package/dist/retrieval/knowledge-index/sha256.js.map +1 -0
  165. package/dist/retrieval/knowledge-index/state.d.ts +55 -0
  166. package/dist/retrieval/knowledge-index/state.d.ts.map +1 -0
  167. package/dist/retrieval/knowledge-index/state.js +67 -0
  168. package/dist/retrieval/knowledge-index/state.js.map +1 -0
  169. package/dist/retrieval/knowledge-index/tokenize.d.ts +20 -0
  170. package/dist/retrieval/knowledge-index/tokenize.d.ts.map +1 -0
  171. package/dist/retrieval/knowledge-index/tokenize.js +42 -0
  172. package/dist/retrieval/knowledge-index/tokenize.js.map +1 -0
  173. package/dist/retrieval/knowledge-index/traverse.d.ts +26 -0
  174. package/dist/retrieval/knowledge-index/traverse.d.ts.map +1 -0
  175. package/dist/retrieval/knowledge-index/traverse.js +90 -0
  176. package/dist/retrieval/knowledge-index/traverse.js.map +1 -0
  177. package/dist/retrieval/knowledge-index/types.d.ts +85 -0
  178. package/dist/retrieval/knowledge-index/types.d.ts.map +1 -0
  179. package/dist/retrieval/knowledge-index/types.js +9 -0
  180. package/dist/retrieval/knowledge-index/types.js.map +1 -0
  181. package/dist/retrieval/mmr.d.ts +11 -4
  182. package/dist/retrieval/mmr.d.ts.map +1 -1
  183. package/dist/retrieval/mmr.js +28 -8
  184. package/dist/retrieval/mmr.js.map +1 -1
  185. package/dist/retrieval/order.d.ts +41 -0
  186. package/dist/retrieval/order.d.ts.map +1 -0
  187. package/dist/retrieval/order.js +54 -0
  188. package/dist/retrieval/order.js.map +1 -0
  189. package/dist/retrieval/weightedFusion.d.ts +2 -1
  190. package/dist/retrieval/weightedFusion.d.ts.map +1 -1
  191. package/dist/retrieval/weightedFusion.js +7 -5
  192. package/dist/retrieval/weightedFusion.js.map +1 -1
  193. package/dist/vectorstore/MemoryVectorStore.d.ts.map +1 -1
  194. package/dist/vectorstore/MemoryVectorStore.js +2 -1
  195. package/dist/vectorstore/MemoryVectorStore.js.map +1 -1
  196. package/package.json +8 -3
  197. package/src/ingest/IngestionPipeline.ts +3 -15
  198. package/src/ingest/docsExtract.ts +219 -0
  199. package/src/ingest/hash.ts +22 -0
  200. package/src/ingest/parsers.ts +4 -0
  201. package/src/ingest/types.ts +7 -0
  202. package/src/knowledge/build.test.ts +150 -0
  203. package/src/knowledge/build.ts +266 -0
  204. package/src/knowledge/cards.ts +130 -0
  205. package/src/knowledge/docs.test.ts +118 -0
  206. package/src/knowledge/findings.ts +159 -0
  207. package/src/knowledge/importance.ts +72 -0
  208. package/src/knowledge/index.ts +53 -0
  209. package/src/knowledge/judge.ts +231 -0
  210. package/src/knowledge/model.ts +312 -0
  211. package/src/knowledge/packs/docs.ts +91 -0
  212. package/src/knowledge/partitions.test.ts +98 -0
  213. package/src/knowledge/partitions.ts +119 -0
  214. package/src/knowledge/plan.ts +115 -0
  215. package/src/knowledge/refs.ts +108 -0
  216. package/src/knowledge/resolve.ts +78 -0
  217. package/src/knowledge/review.test.ts +180 -0
  218. package/src/knowledge/review.ts +235 -0
  219. package/src/knowledge/sources.ts +146 -0
  220. package/src/knowledge/stores/localSnapshotStore.test.ts +82 -0
  221. package/src/knowledge/stores/localSnapshotStore.ts +159 -0
  222. package/src/knowledge/testkit.test-util.ts +92 -0
  223. package/src/knowledge/trace.test.ts +91 -0
  224. package/src/knowledge/trace.ts +111 -0
  225. package/src/knowledge/truncate.ts +118 -0
  226. package/src/memory/SemanticRecall.ts +3 -1
  227. package/src/retrieval/HybridRetriever.ts +3 -1
  228. package/src/retrieval/bm25.ts +5 -3
  229. package/src/retrieval/fusion.ts +5 -2
  230. package/src/retrieval/hnsw.ts +82 -35
  231. package/src/retrieval/index.ts +17 -3
  232. package/src/retrieval/knowledge-index/bytes.ts +166 -0
  233. package/src/retrieval/knowledge-index/cascade.ts +125 -0
  234. package/src/retrieval/knowledge-index/compact.ts +68 -0
  235. package/src/retrieval/knowledge-index/csr.ts +102 -0
  236. package/src/retrieval/knowledge-index/digest.ts +54 -0
  237. package/src/retrieval/knowledge-index/embeddings.ts +85 -0
  238. package/src/retrieval/knowledge-index/expand.ts +55 -0
  239. package/src/retrieval/knowledge-index/index.ts +162 -0
  240. package/src/retrieval/knowledge-index/lexical.ts +78 -0
  241. package/src/retrieval/knowledge-index/pairs.ts +57 -0
  242. package/src/retrieval/knowledge-index/prune.ts +48 -0
  243. package/src/retrieval/knowledge-index/quantize.ts +78 -0
  244. package/src/retrieval/knowledge-index/serialize.ts +124 -0
  245. package/src/retrieval/knowledge-index/sha256.ts +122 -0
  246. package/src/retrieval/knowledge-index/state.ts +108 -0
  247. package/src/retrieval/knowledge-index/tokenize.ts +41 -0
  248. package/src/retrieval/knowledge-index/traverse.ts +95 -0
  249. package/src/retrieval/knowledge-index/types.ts +78 -0
  250. package/src/retrieval/mmr.ts +35 -10
  251. package/src/retrieval/order.ts +68 -0
  252. package/src/retrieval/weightedFusion.ts +8 -5
  253. package/src/vectorstore/MemoryVectorStore.ts +2 -1
@@ -0,0 +1,263 @@
1
+ /**
2
+ * knowledge/build.ts — `buildGraph`: join perception (extracted, computed) with memory
3
+ * (stored facts and relations) into one bounded {@link KnowledgeGraph} (PRD 38 §4.1).
4
+ *
5
+ * 1. extracted nodes/edges (analyzer output merges its badges into the same refs);
6
+ * 2. facts become nodes, joined to sources by `fileAnchors.path`; a model fact whose
7
+ * anchor hash differs from the source's current hash is `stale`;
8
+ * 3. stored relations become edges; near-duplicate pairs become `near-duplicate` edges
9
+ * (an exact `duplicate` between the same pair wins); live changes badge nodes and
10
+ * `runFiles` become `co-changed` edges;
11
+ * 4. partitions, areas, verdicts; PageRank importance; findings; then truncation.
12
+ *
13
+ * Deterministic: equal input ⇒ byte-identical JSON. Every list is sorted, every sort ends
14
+ * on ref, objects are built with a fixed key order.
15
+ */
16
+ import { areaOfPath } from '../working/codemapAreas.js';
17
+ import { sha256Hex } from '../retrieval/knowledge-index/sha256.js';
18
+ import { computeFindings } from './findings.js';
19
+ import { pageRank } from './importance.js';
20
+ import { loadPartitions, partitionOf, verdictOf } from './partitions.js';
21
+ import { entityName } from './resolve.js';
22
+ import { basenameOf, canonicalJson, compareStr, factRef, pathOfRef, round6, sortBy, srcRef, } from './refs.js';
23
+ import { truncateGraph } from './truncate.js';
24
+ export const DEFAULT_MAX_NODES = 400;
25
+ export const MAX_NODES_CAP = 2000;
26
+ const LABEL_CHARS = 120;
27
+ const edgeId = (from, to, kind) => `${from}\u0000${to}\u0000${kind}`;
28
+ export const compareEdges = (a, b) => compareStr(a.from, b.from) || compareStr(a.to, b.to) || compareStr(a.kind, b.kind);
29
+ /** sha-256 over the canonical input: equal inputs (in any order) ⇒ equal digests. */
30
+ export function graphDigest(input) {
31
+ return sha256Hex(canonicalJson({
32
+ rootId: input.rootId,
33
+ packs: input.packs.map((p) => p.id).sort(compareStr),
34
+ extracted: sortBy(input.extracted, (e) => e.sourceRef, (e) => e.sourceHash).map(canonicalExtracted),
35
+ facts: sortBy(input.facts, (f) => f.key).map((f) => ({ ...f, fileAnchors: sortBy(f.fileAnchors, (a) => a.path) })),
36
+ relations: sortBy(input.relations, (r) => r.from, (r) => r.to, (r) => r.kind),
37
+ live: input.live && {
38
+ changes: sortBy(input.live.changes, (c) => c.path),
39
+ runFiles: nonEmpty(input.live.runFiles) && [...input.live.runFiles].sort(compareStr),
40
+ },
41
+ nearDuplicates: nonEmpty(input.nearDuplicates) && sortBy(input.nearDuplicates, (p) => p.a, (p) => p.b),
42
+ }));
43
+ }
44
+ /** An absent list and an empty list mean the same input, so they hash the same. */
45
+ const nonEmpty = (xs) => (xs && xs.length > 0) || undefined;
46
+ function canonicalExtracted(e) {
47
+ return {
48
+ sourceRef: e.sourceRef, sourceHash: e.sourceHash,
49
+ nodes: sortBy(e.nodes, (n) => n.ref),
50
+ edges: [...e.edges].sort(compareEdges),
51
+ keys: sortBy(e.keys, (k) => k.ref, (k) => k.key),
52
+ };
53
+ }
54
+ function mergeBadges(a, b) {
55
+ if (!a)
56
+ return b && { ...b };
57
+ if (!b)
58
+ return { ...a };
59
+ const out = { ...a };
60
+ // Commutative: on a conflict the larger value (as a string) wins, whatever the order.
61
+ for (const [k, v] of Object.entries(b))
62
+ out[k] = k in out && String(out[k]) >= String(v) ? out[k] : v;
63
+ return out;
64
+ }
65
+ function oneLine(text) {
66
+ const flat = text.replace(/\s+/g, ' ').trim();
67
+ return flat.length > LABEL_CHARS ? `${flat.slice(0, LABEL_CHARS - 1)}…` : flat;
68
+ }
69
+ class GraphBuilder {
70
+ nodes = new Map();
71
+ edges = new Map();
72
+ node(n) {
73
+ const prior = this.nodes.get(n.ref);
74
+ if (!prior) {
75
+ this.nodes.set(n.ref, { ...n, ...(n.badges ? { badges: { ...n.badges } } : {}) });
76
+ return;
77
+ }
78
+ const badges = mergeBadges(prior.badges, n.badges);
79
+ if (badges)
80
+ prior.badges = badges;
81
+ }
82
+ edge(e) {
83
+ const id = edgeId(e.from, e.to, e.kind);
84
+ const prior = this.edges.get(id);
85
+ if (!prior) {
86
+ this.edges.set(id, { ...e });
87
+ return;
88
+ }
89
+ prior.weight = Math.max(prior.weight, e.weight);
90
+ if (e.cycle)
91
+ prior.cycle = true;
92
+ if (e.confidence !== undefined)
93
+ prior.confidence = Math.max(prior.confidence ?? 0, e.confidence);
94
+ }
95
+ has(from, to, kind) {
96
+ return this.edges.has(edgeId(from, to, kind));
97
+ }
98
+ }
99
+ function factNode(f, rootId, g) {
100
+ const ref = factRef(f.key);
101
+ const kind = f.key.startsWith('ent:') ? 'entity' : f.key.startsWith('claim:') ? 'claim' : 'fact';
102
+ const anchors = sortBy(f.fileAnchors, (a) => a.path);
103
+ const anchoredPack = anchors.map((a) => g.nodes.get(srcRef(rootId, a.path))?.pack).find(Boolean);
104
+ const pack = kind === 'entity' ? f.key.split(':')[1] || 'memory' : anchoredPack ?? 'memory';
105
+ const stale = f.origin === 'model' && anchors.some((a) => {
106
+ const current = g.nodes.get(srcRef(rootId, a.path))?.sourceHash;
107
+ return !!a.contentHash && !!current && current !== a.contentHash;
108
+ });
109
+ const first = anchors[0];
110
+ return {
111
+ ref, kind, label: oneLine(kind === 'entity' ? f.content || entityName(ref) : f.content), pack,
112
+ importance: 0, origin: f.origin,
113
+ ...(first?.contentHash ? { sourceHash: first.contentHash } : {}),
114
+ ...(stale ? { stale: true } : {}),
115
+ ...(first?.line !== undefined ? { badges: { line: first.line } } : {}),
116
+ };
117
+ }
118
+ export function buildGraph(input, opts = {}) {
119
+ const { rootId } = input;
120
+ const g = new GraphBuilder();
121
+ const sources = new Set();
122
+ for (const ex of sortBy(input.extracted, (e) => e.sourceRef, (e) => e.sourceHash)) {
123
+ if (ex.sourceRef.startsWith('src:'))
124
+ sources.add(ex.sourceRef);
125
+ for (const n of sortBy(ex.nodes, (x) => x.ref))
126
+ g.node({ ...n, origin: 'extracted' });
127
+ for (const e of [...ex.edges].sort(compareEdges))
128
+ g.edge({ ...e, origin: 'extracted' });
129
+ }
130
+ const facts = sortBy(input.facts, (f) => f.key);
131
+ for (const f of facts)
132
+ g.node(factNode(f, rootId, g));
133
+ for (const f of facts) {
134
+ for (const a of sortBy(f.fileAnchors, (x) => x.path)) {
135
+ const to = srcRef(rootId, a.path);
136
+ if (g.nodes.has(to))
137
+ g.edge({ from: factRef(f.key), to, kind: 'about', weight: 1, origin: f.origin });
138
+ }
139
+ }
140
+ for (const r of sortBy(input.relations, (x) => x.from, (x) => x.to, (x) => x.kind)) {
141
+ g.edge({
142
+ from: r.from, to: r.to, kind: r.kind, weight: r.weight, origin: r.origin,
143
+ ...(r.confidence !== undefined ? { confidence: r.confidence } : {}),
144
+ });
145
+ }
146
+ for (const p of sortBy(input.nearDuplicates ?? [], (x) => x.a, (x) => x.b)) {
147
+ if (p.a === p.b || p.a.startsWith('ent:') || p.b.startsWith('ent:'))
148
+ continue;
149
+ const [a, b] = (compareStr(p.a, p.b) < 0 ? [p.a, p.b] : [p.b, p.a]);
150
+ if (!g.nodes.has(a) || !g.nodes.has(b) || g.has(a, b, 'duplicate') || g.has(b, a, 'duplicate'))
151
+ continue;
152
+ g.edge({ from: a, to: b, kind: 'near-duplicate', weight: round6(p.similarity), origin: 'extracted' });
153
+ }
154
+ const changed = applyLive(input, g);
155
+ closeEndpoints(g);
156
+ const registries = new Map(input.packs.map((p) => [p.id, loadPartitions(p)]));
157
+ placeNodes(rootId, g, registries);
158
+ const rank = pageRank([...g.nodes.keys()], [...g.edges.values()]);
159
+ for (const n of g.nodes.values())
160
+ n.importance = rank.get(n.ref) ?? 0;
161
+ const allNodes = [...g.nodes.values()].map(finalNode).sort((a, b) => compareStr(a.ref, b.ref));
162
+ const allEdges = [...g.edges.values()].map(finalEdge).sort(compareEdges);
163
+ const packs = input.packs.map((p) => p.id).sort(compareStr);
164
+ const full = {
165
+ scope: { rootId, packs, digest: graphDigest(input) },
166
+ nodes: allNodes, edges: allEdges, findings: [],
167
+ stats: { sources: sources.size, nodes: allNodes.length, edges: allEdges.length, stale: 0, truncated: false },
168
+ };
169
+ full.findings = computeFindings(full, input.packs, registries, input.nearDuplicates ?? []);
170
+ full.stats.stale = allNodes.filter((n) => n.stale).length;
171
+ const maxNodes = Math.min(MAX_NODES_CAP, Math.max(1, Math.floor(opts.maxNodes ?? DEFAULT_MAX_NODES)));
172
+ const cut = truncateGraph(full, { maxNodes, focus: opts.focus ?? [], changed });
173
+ return {
174
+ ...full,
175
+ nodes: cut.nodes,
176
+ edges: cut.edges,
177
+ stats: { ...full.stats, nodes: cut.nodes.length, edges: cut.edges.length, truncated: cut.truncated },
178
+ };
179
+ }
180
+ function applyLive(input, g) {
181
+ const changed = [];
182
+ if (!input.live)
183
+ return changed;
184
+ for (const c of sortBy(input.live.changes, (x) => x.path)) {
185
+ const ref = srcRef(input.rootId, c.path);
186
+ if (!g.nodes.has(ref))
187
+ continue;
188
+ g.node({ ...g.nodes.get(ref), badges: { added: c.added, removed: c.removed, status: c.status } });
189
+ changed.push(ref);
190
+ }
191
+ const run = [...new Set(input.live.runFiles ?? [])].sort(compareStr)
192
+ .map((p) => srcRef(input.rootId, p)).filter((r) => g.nodes.has(r));
193
+ for (let i = 0; i < run.length; i++) {
194
+ for (let j = i + 1; j < run.length; j++) {
195
+ g.edge({ from: run[i], to: run[j], kind: 'co-changed', weight: 1, origin: 'agent' });
196
+ }
197
+ }
198
+ return changed;
199
+ }
200
+ /** A missing `src:` endpoint becomes a `missing` placeholder (a broken link); a missing fact drops the edge. */
201
+ function closeEndpoints(g) {
202
+ for (const [id, e] of [...g.edges.entries()].sort((a, b) => compareStr(a[0], b[0]))) {
203
+ const ends = [e.from, e.to].filter((end) => !g.nodes.has(end));
204
+ if (ends.some((end) => pathOfRef(end) === undefined)) {
205
+ g.edges.delete(id);
206
+ continue;
207
+ }
208
+ for (const end of ends) {
209
+ const path = pathOfRef(end);
210
+ const other = g.nodes.get(end === e.from ? e.to : e.from);
211
+ g.node({
212
+ ref: end, kind: 'missing', label: basenameOf(path) || path, pack: other?.pack ?? 'memory',
213
+ importance: 0, origin: 'extracted', badges: { missing: 1 },
214
+ });
215
+ }
216
+ }
217
+ }
218
+ function placeNodes(rootId, g, registries) {
219
+ for (const n of g.nodes.values()) {
220
+ const path = pathOfRef(n.ref);
221
+ if (path === undefined)
222
+ continue;
223
+ const reg = registries.get(n.pack);
224
+ const partition = reg ? partitionOf(path, reg) : undefined;
225
+ if (partition !== undefined)
226
+ n.partition = partition;
227
+ const area = areaOfPath(path);
228
+ if (area)
229
+ n.area = srcRef(rootId, area);
230
+ }
231
+ for (const e of g.edges.values()) {
232
+ const from = g.nodes.get(e.from), to = g.nodes.get(e.to);
233
+ const reg = from && registries.get(from.pack);
234
+ if (!from || !to || !reg || from.pack !== to.pack)
235
+ continue;
236
+ const verdict = verdictOf(from.partition, to.partition, reg);
237
+ if (verdict)
238
+ e.verdict = verdict;
239
+ }
240
+ }
241
+ function finalNode(n) {
242
+ const badges = n.badges && Object.keys(n.badges).length
243
+ ? Object.fromEntries(Object.keys(n.badges).sort(compareStr).map((k) => [k, n.badges[k]]))
244
+ : undefined;
245
+ return {
246
+ ref: n.ref, kind: n.kind, label: n.label, pack: n.pack,
247
+ ...(n.partition !== undefined ? { partition: n.partition } : {}),
248
+ ...(n.area !== undefined ? { area: n.area } : {}),
249
+ importance: n.importance, origin: n.origin,
250
+ ...(n.sourceHash !== undefined ? { sourceHash: n.sourceHash } : {}),
251
+ ...(n.stale ? { stale: true } : {}),
252
+ ...(badges ? { badges } : {}),
253
+ };
254
+ }
255
+ export function finalEdge(e) {
256
+ return {
257
+ from: e.from, to: e.to, kind: e.kind, weight: round6(e.weight), origin: e.origin,
258
+ ...(e.confidence !== undefined ? { confidence: round6(e.confidence) } : {}),
259
+ ...(e.verdict ? { verdict: e.verdict } : {}),
260
+ ...(e.cycle ? { cycle: true } : {}),
261
+ };
262
+ }
263
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/knowledge/build.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * knowledge/cards.ts — `toCards`: one knowledge-index card per graph node
3
+ * (design: Builderforce.ai/docs/design/deterministic-knowledge-index.md, "Cards").
4
+ *
5
+ * | kind | text | keys |
6
+ * |-----------------|-------------------------------------------------------------------|-------------------------------|
7
+ * | file | path · area · partition · symbols · doc line · top-5 neighbours | path, basename, symbols, area |
8
+ * | section | file · breadcrumb · first 400 chars · outgoing link targets | file path, slug, front matter |
9
+ * | entity (ent:) | name · type · top-5 mentioning sources | normalized name, aliases |
10
+ * | claim | subject predicate object · quote · source section | subject/object entity keys |
11
+ * | area | path · partition · top-10 members | path |
12
+ *
13
+ * `hash` is the index's own text hash (`hashDocText`), so an unchanged card is never re-embedded.
14
+ */
15
+ import type { IndexDoc, KnowledgeGraph } from './model.js';
16
+ export declare function toCards(g: KnowledgeGraph): IndexDoc[];
17
+ //# sourceMappingURL=cards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cards.d.ts","sourceRoot":"","sources":["../../src/knowledge/cards.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAgB,cAAc,EAAW,MAAM,YAAY,CAAC;AAQlF,wBAAgB,OAAO,CAAC,CAAC,EAAE,cAAc,GAAG,QAAQ,EAAE,CAkBrD"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * knowledge/cards.ts — `toCards`: one knowledge-index card per graph node
3
+ * (design: Builderforce.ai/docs/design/deterministic-knowledge-index.md, "Cards").
4
+ *
5
+ * | kind | text | keys |
6
+ * |-----------------|-------------------------------------------------------------------|-------------------------------|
7
+ * | file | path · area · partition · symbols · doc line · top-5 neighbours | path, basename, symbols, area |
8
+ * | section | file · breadcrumb · first 400 chars · outgoing link targets | file path, slug, front matter |
9
+ * | entity (ent:) | name · type · top-5 mentioning sources | normalized name, aliases |
10
+ * | claim | subject predicate object · quote · source section | subject/object entity keys |
11
+ * | area | path · partition · top-10 members | path |
12
+ *
13
+ * `hash` is the index's own text hash (`hashDocText`), so an unchanged card is never re-embedded.
14
+ */
15
+ import { hashDocText } from '../retrieval/knowledge-index/digest.js';
16
+ import { byImportance } from './importance.js';
17
+ import { entityName } from './resolve.js';
18
+ import { basenameOf, compareStr, fileRefOf, normalizeKey, pathOfRef, slugOf } from './refs.js';
19
+ const SEP = ' · ';
20
+ const EXCERPT_CHARS = 400;
21
+ export function toCards(g) {
22
+ const byRef = new Map(g.nodes.map((n) => [n.ref, n]));
23
+ const outEdges = new Map();
24
+ const inEdges = new Map();
25
+ const push = (m, k, e) => {
26
+ const l = m.get(k) ?? [];
27
+ l.push(e);
28
+ m.set(k, l);
29
+ };
30
+ for (const e of g.edges) {
31
+ push(outEdges, e.from, e);
32
+ push(inEdges, e.to, e);
33
+ }
34
+ const label = (r) => byRef.get(r)?.label ?? pathOfRef(r) ?? r;
35
+ const ctx = { byRef, outEdges, inEdges, label, members: membersByArea(g.nodes) };
36
+ return g.nodes.map((n) => {
37
+ const { text, keys } = cardOf(n, ctx);
38
+ const uniqueKeys = [...new Set(keys.filter(Boolean))].sort(compareStr);
39
+ return { id: n.ref, text, ...(uniqueKeys.length ? { keys: uniqueKeys } : {}), hash: hashDocText(text) };
40
+ }).sort((a, b) => compareStr(a.id, b.id));
41
+ }
42
+ function membersByArea(nodes) {
43
+ const out = new Map();
44
+ for (const n of nodes) {
45
+ if (!n.area || n.kind !== 'file')
46
+ continue;
47
+ const l = out.get(n.area) ?? [];
48
+ l.push(n);
49
+ out.set(n.area, l);
50
+ }
51
+ return out;
52
+ }
53
+ /** Neighbour refs (either direction), heaviest first, then by ref. */
54
+ function topNeighbours(ref, ctx, n) {
55
+ const scored = new Map();
56
+ for (const e of ctx.outEdges.get(ref) ?? [])
57
+ scored.set(e.to, Math.max(scored.get(e.to) ?? 0, e.weight));
58
+ for (const e of ctx.inEdges.get(ref) ?? [])
59
+ scored.set(e.from, Math.max(scored.get(e.from) ?? 0, e.weight));
60
+ return [...scored].sort((a, b) => b[1] - a[1] || compareStr(a[0], b[0])).slice(0, n).map(([r]) => r);
61
+ }
62
+ const badge = (n, k) => {
63
+ const v = n?.badges?.[k];
64
+ return v === undefined || v === '' ? undefined : String(v);
65
+ };
66
+ const frontMatter = (n) => Object.keys(n?.badges ?? {}).filter((k) => k.startsWith('fm.')).sort(compareStr)
67
+ .flatMap((k) => String(n.badges[k]).split(',').map((v) => normalizeKey(v)));
68
+ function cardOf(n, ctx) {
69
+ const path = pathOfRef(n.ref) ?? '';
70
+ const join = (parts) => parts.filter((p) => p !== undefined && p !== '').join(SEP);
71
+ switch (n.kind) {
72
+ case 'file': {
73
+ const contained = (ctx.outEdges.get(n.ref) ?? []).filter((e) => e.kind === 'contains')
74
+ .map((e) => ctx.byRef.get(e.to)).filter((c) => c?.kind === 'symbol');
75
+ const symbols = contained.map((s) => s.label).sort(compareStr);
76
+ return {
77
+ text: join([path, n.area && pathOfRef(n.area), n.partition, symbols.join(', '), badge(n, 'doc'),
78
+ topNeighbours(n.ref, ctx, 5).map(ctx.label).join(', ')]),
79
+ keys: [path, basenameOf(path), ...symbols, n.area ? pathOfRef(n.area) ?? '' : ''],
80
+ };
81
+ }
82
+ case 'section': {
83
+ const file = ctx.byRef.get(fileRefOf(n.ref));
84
+ const links = (ctx.outEdges.get(n.ref) ?? []).filter((e) => e.kind === 'links')
85
+ .map((e) => pathOfRef(e.to) ?? e.to).sort(compareStr);
86
+ return {
87
+ text: join([path, badge(n, 'breadcrumb') ?? n.label, badge(n, 'excerpt')?.slice(0, EXCERPT_CHARS), links.join(', ')]),
88
+ keys: [path, slugOf(n.label), ...frontMatter(file)],
89
+ };
90
+ }
91
+ case 'entity': {
92
+ const sources = (ctx.inEdges.get(n.ref) ?? []).filter((e) => e.kind === 'mentions' || e.kind === 'about')
93
+ .map((e) => ctx.byRef.get(e.from)).filter((s) => !!s);
94
+ const about = (ctx.outEdges.get(n.ref) ?? []).filter((e) => e.kind === 'about')
95
+ .map((e) => ctx.byRef.get(e.to)).filter((s) => !!s);
96
+ const top = [...new Map([...sources, ...about].map((s) => [s.ref, s])).values()].sort(byImportance).slice(0, 5);
97
+ const name = entityName(n.ref);
98
+ return {
99
+ text: join([n.label, badge(n, 'type'), top.map((s) => s.label).join(', ')]),
100
+ keys: [normalizeKey(name), normalizeKey(n.label.replace(/\s*\([^)]*\)\s*$/, '')),
101
+ ...String(badge(n, 'aliases') ?? '').split(',').map(normalizeKey)],
102
+ };
103
+ }
104
+ case 'claim': {
105
+ const out = ctx.outEdges.get(n.ref) ?? [];
106
+ const sections = out.filter((e) => e.kind === 'about').map((e) => ctx.label(e.to)).sort(compareStr);
107
+ const entities = out.filter((e) => e.kind === 'mentions' && e.to.startsWith('ent:')).map((e) => normalizeKey(entityName(e.to)));
108
+ return { text: join([n.label, sections.join(', ')]), keys: entities };
109
+ }
110
+ case 'area': {
111
+ const members = [...(ctx.members.get(n.ref) ?? [])].sort(byImportance).slice(0, 10).map((m) => m.label);
112
+ return { text: join([path, n.partition, members.join(', ')]), keys: [path] };
113
+ }
114
+ default:
115
+ return { text: join([n.label, n.kind, path]), keys: [normalizeKey(n.label), path] };
116
+ }
117
+ }
118
+ //# sourceMappingURL=cards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cards.js","sourceRoot":"","sources":["../../src/knowledge/cards.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * knowledge/findings.ts — what a person can act on (PRD 38 §3.5).
3
+ *
4
+ * Generic findings, for every pack: cycle, clone group, near-duplicate, partition
5
+ * violation, unpartitioned share, stale knowledge — plus `possible-same` entities. Packs
6
+ * add their own through {@link FindingRule}s. Every finding has a stable id (a hash of its
7
+ * kind and refs) and a `requestKey` under `knowledgeGraph.fix.*`: the fixed, prefilled
8
+ * Fix-with-agent request, never a model call.
9
+ */
10
+ import type { Finding, KEdge, KnowledgeGraph, KnowledgePack, NodeRef, PartitionRegistry } from './model.js';
11
+ import type { SimilarPair } from '../retrieval/knowledge-index/types.js';
12
+ /** Node badge naming the clone group (e.g. a jscpd issue id) its `duplicate` edges belong to. */
13
+ export declare const CLONE_GROUP_BADGE = "cloneGroup";
14
+ /** Refs listed on one grouped finding, at most (the count rides in params). */
15
+ export declare const MAX_FINDING_NODES = 50;
16
+ export declare function findingId(kind: string, refs: readonly string[]): string;
17
+ /** `clone-group` → `knowledgeGraph.fix.cloneGroup`. */
18
+ export declare function requestKeyFor(kind: string): string;
19
+ /** Connected components over edges, each sorted; components sorted by first ref. */
20
+ export declare function components(edges: readonly KEdge[]): NodeRef[][];
21
+ export declare function genericFindings(g: KnowledgeGraph, registries: ReadonlyMap<string, PartitionRegistry>): Finding[];
22
+ /** Generic + possible-same + every pack's rules; deduped by id; severity, then id. */
23
+ export declare function computeFindings(g: KnowledgeGraph, packs: readonly KnowledgePack[], registries: ReadonlyMap<string, PartitionRegistry>, nearDuplicates: readonly SimilarPair[]): Finding[];
24
+ //# sourceMappingURL=findings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findings.d.ts","sourceRoot":"","sources":["../../src/knowledge/findings.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAS,cAAc,EAAE,aAAa,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACnH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAIzE,iGAAiG;AACjG,eAAO,MAAM,iBAAiB,eAAe,CAAC;AAC9C,+EAA+E;AAC/E,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAIpC,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAEvE;AAED,uDAAuD;AACvD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAUD,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,KAAK,EAAE,GAAG,OAAO,EAAE,EAAE,CAqB/D;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,OAAO,EAAE,CAqDhH;AAkBD,sFAAsF;AACtF,wBAAgB,eAAe,CAC3B,CAAC,EAAE,cAAc,EACjB,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAClD,cAAc,EAAE,SAAS,WAAW,EAAE,GACvC,OAAO,EAAE,CAiBX"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * knowledge/findings.ts — what a person can act on (PRD 38 §3.5).
3
+ *
4
+ * Generic findings, for every pack: cycle, clone group, near-duplicate, partition
5
+ * violation, unpartitioned share, stale knowledge — plus `possible-same` entities. Packs
6
+ * add their own through {@link FindingRule}s. Every finding has a stable id (a hash of its
7
+ * kind and refs) and a `requestKey` under `knowledgeGraph.fix.*`: the fixed, prefilled
8
+ * Fix-with-agent request, never a model call.
9
+ */
10
+ import { hashText } from '../ingest/hash.js';
11
+ import { possibleSameFindings } from './resolve.js';
12
+ import { compareStr, round6 } from './refs.js';
13
+ /** Node badge naming the clone group (e.g. a jscpd issue id) its `duplicate` edges belong to. */
14
+ export const CLONE_GROUP_BADGE = 'cloneGroup';
15
+ /** Refs listed on one grouped finding, at most (the count rides in params). */
16
+ export const MAX_FINDING_NODES = 50;
17
+ const SEVERITY_RANK = { error: 0, warn: 1, info: 2 };
18
+ export function findingId(kind, refs) {
19
+ return `${kind}:${hashText([...refs].sort(compareStr).join('\u0000'))}`;
20
+ }
21
+ /** `clone-group` → `knowledgeGraph.fix.cloneGroup`. */
22
+ export function requestKeyFor(kind) {
23
+ return `knowledgeGraph.fix.${kind.replace(/-([a-z])/g, (_, c) => c.toUpperCase())}`;
24
+ }
25
+ function finding(kind, pack, nodes, severity, params) {
26
+ const sorted = [...new Set(nodes)].sort(compareStr);
27
+ return {
28
+ id: findingId(kind, sorted), kind, pack, nodes: sorted.slice(0, MAX_FINDING_NODES), severity, params,
29
+ requestKey: requestKeyFor(kind),
30
+ };
31
+ }
32
+ /** Connected components over edges, each sorted; components sorted by first ref. */
33
+ export function components(edges) {
34
+ const parent = new Map();
35
+ const find = (x) => {
36
+ let r = x;
37
+ while (parent.get(r) !== r)
38
+ r = parent.get(r);
39
+ parent.set(x, r);
40
+ return r;
41
+ };
42
+ for (const e of edges) {
43
+ for (const r of [e.from, e.to])
44
+ if (!parent.has(r))
45
+ parent.set(r, r);
46
+ const a = find(e.from), b = find(e.to);
47
+ if (a !== b)
48
+ parent.set(compareStr(a, b) < 0 ? b : a, compareStr(a, b) < 0 ? a : b);
49
+ }
50
+ const groups = new Map();
51
+ for (const r of [...parent.keys()].sort(compareStr)) {
52
+ const root = find(r);
53
+ let g = groups.get(root);
54
+ if (!g)
55
+ groups.set(root, (g = []));
56
+ g.push(r);
57
+ }
58
+ return [...groups.values()].sort((a, b) => compareStr(a[0], b[0]));
59
+ }
60
+ export function genericFindings(g, registries) {
61
+ const byRef = new Map(g.nodes.map((n) => [n.ref, n]));
62
+ const packOf = (ref) => byRef.get(ref)?.pack ?? 'memory';
63
+ const out = [];
64
+ for (const refs of components(g.edges.filter((e) => e.cycle))) {
65
+ out.push(finding('cycle', packOf(refs[0]), refs, 'warn', { nodes: refs.length }));
66
+ }
67
+ // Clone groups: duplicate edges grouped by the clone-group badge, else by component.
68
+ const dup = g.edges.filter((e) => e.kind === 'duplicate');
69
+ const byBadge = new Map();
70
+ const unbadged = [];
71
+ for (const e of dup) {
72
+ const badge = byRef.get(e.from)?.badges?.[CLONE_GROUP_BADGE] ?? byRef.get(e.to)?.badges?.[CLONE_GROUP_BADGE];
73
+ if (badge === undefined) {
74
+ unbadged.push(e);
75
+ continue;
76
+ }
77
+ const list = byBadge.get(String(badge)) ?? [];
78
+ list.push(e);
79
+ byBadge.set(String(badge), list);
80
+ }
81
+ const groups = [
82
+ ...[...byBadge].map(([group, es]) => ({ group, refs: es.flatMap((e) => [e.from, e.to]) })),
83
+ ...components(unbadged).map((refs) => ({ group: '', refs })),
84
+ ];
85
+ for (const { group, refs } of groups) {
86
+ const unique = [...new Set(refs)];
87
+ out.push(finding('clone-group', packOf(unique.sort(compareStr)[0]), unique, 'warn', { group, members: unique.length }));
88
+ }
89
+ for (const e of g.edges) {
90
+ if (e.kind === 'near-duplicate') {
91
+ out.push(finding('near-duplicate', packOf(e.from), [e.from, e.to], 'info', { similarity: round6(e.weight) }));
92
+ }
93
+ if (e.verdict === 'upward' || e.verdict === 'skips') {
94
+ const from = byRef.get(e.from), to = byRef.get(e.to);
95
+ out.push(finding('partition-violation', packOf(e.from), [e.from, e.to], e.verdict === 'upward' ? 'error' : 'warn', {
96
+ verdict: e.verdict, from: from?.partition ?? '', to: to?.partition ?? '', kind: e.kind,
97
+ }));
98
+ }
99
+ }
100
+ for (const [pack, reg] of [...registries].sort((a, b) => compareStr(a[0], b[0]))) {
101
+ if (!reg.allow)
102
+ continue;
103
+ const files = g.nodes.filter((n) => n.pack === pack && n.kind === 'file');
104
+ const loose = files.filter((n) => n.partition === undefined).map((n) => n.ref);
105
+ if (loose.length === 0)
106
+ continue;
107
+ out.push(finding('unpartitioned', pack, loose, 'info', {
108
+ count: loose.length, total: files.length, share: Math.round((loose.length / files.length) * 100),
109
+ }));
110
+ }
111
+ out.push(...staleFindings(g, byRef));
112
+ return out;
113
+ }
114
+ /** One finding per source whose stored knowledge went stale (unanchored stale nodes: one each). */
115
+ function staleFindings(g, byRef) {
116
+ const about = new Map();
117
+ for (const e of g.edges)
118
+ if (e.kind === 'about' && !about.has(e.from))
119
+ about.set(e.from, e.to);
120
+ const bySource = new Map();
121
+ for (const n of g.nodes) {
122
+ if (!n.stale)
123
+ continue;
124
+ const target = about.get(n.ref) ?? n.ref;
125
+ const list = bySource.get(target) ?? [];
126
+ list.push(n.ref);
127
+ bySource.set(target, list);
128
+ }
129
+ return [...bySource].map(([source, refs]) => finding('stale', byRef.get(source)?.pack ?? 'memory', [source, ...refs], 'warn', { count: refs.length }));
130
+ }
131
+ /** Generic + possible-same + every pack's rules; deduped by id; severity, then id. */
132
+ export function computeFindings(g, packs, registries, nearDuplicates) {
133
+ const all = [...genericFindings(g, registries), ...possibleSameFindings(nearDuplicates)];
134
+ for (const pack of [...packs].sort((a, b) => compareStr(a.id, b.id))) {
135
+ for (const rule of pack.findings ?? []) {
136
+ for (const f of rule.find(g)) {
137
+ all.push({
138
+ ...f,
139
+ id: f.id || findingId(f.kind, f.nodes),
140
+ nodes: [...new Set(f.nodes)].sort(compareStr),
141
+ requestKey: f.requestKey ?? requestKeyFor(f.kind),
142
+ });
143
+ }
144
+ }
145
+ }
146
+ const byId = new Map();
147
+ for (const f of all)
148
+ if (!byId.has(f.id))
149
+ byId.set(f.id, f);
150
+ return [...byId.values()].sort((a, b) => SEVERITY_RANK[a.severity] - SEVERITY_RANK[b.severity] || compareStr(a.id, b.id));
151
+ }
152
+ //# sourceMappingURL=findings.js.map