@holmes-lab/holmes-kit 0.2.1 → 0.3.1

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 (132) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/dist/.build-id +1 -1
  3. package/dist/holmes/assoc/assoc-arm.d.ts +94 -0
  4. package/dist/holmes/assoc/assoc-arm.js +187 -0
  5. package/dist/holmes/assoc/explore.d.ts +21 -0
  6. package/dist/holmes/assoc/explore.js +160 -0
  7. package/dist/holmes/assoc/impact-baseline.d.ts +13 -0
  8. package/dist/holmes/assoc/impact-baseline.js +48 -0
  9. package/dist/holmes/assoc/ppr.d.ts +64 -0
  10. package/dist/holmes/assoc/ppr.js +110 -0
  11. package/dist/holmes/cli/agents.d.ts +24 -11
  12. package/dist/holmes/cli/agents.js +93 -21
  13. package/dist/holmes/cli/doctor.d.ts +56 -0
  14. package/dist/holmes/cli/doctor.js +311 -5
  15. package/dist/holmes/cli/index.js +13 -1
  16. package/dist/holmes/cli/semantic-key.d.ts +19 -0
  17. package/dist/holmes/cli/semantic-key.js +93 -0
  18. package/dist/holmes/config/config.d.ts +9 -0
  19. package/dist/holmes/config/config.js +8 -1
  20. package/dist/holmes/cpg/language-capability.d.ts +65 -0
  21. package/dist/holmes/cpg/language-capability.js +145 -0
  22. package/dist/holmes/cpg/language-parser-walk.js +179 -34
  23. package/dist/holmes/cpg/language-parser.d.ts +1 -1
  24. package/dist/holmes/governance/ledger-rechain.d.ts +12 -0
  25. package/dist/holmes/governance/ledger-rechain.js +17 -2
  26. package/dist/holmes/governance/provenance-ledger.js +21 -0
  27. package/dist/holmes/guardrail/blind-spots.js +12 -1
  28. package/dist/holmes/guardrail/impact-gate.d.ts +77 -0
  29. package/dist/holmes/guardrail/impact-gate.js +263 -0
  30. package/dist/holmes/guardrail/write-target.d.ts +38 -1
  31. package/dist/holmes/guardrail/write-target.js +41 -4
  32. package/dist/holmes/hooks/adapters/antigravity.js +12 -1
  33. package/dist/holmes/hooks/corrupt-state-run.d.ts +33 -0
  34. package/dist/holmes/hooks/corrupt-state-run.js +16 -0
  35. package/dist/holmes/hooks/pre-tool-use.d.ts +26 -0
  36. package/dist/holmes/hooks/pre-tool-use.js +203 -11
  37. package/dist/holmes/hooks/stop.d.ts +65 -0
  38. package/dist/holmes/hooks/stop.js +200 -2
  39. package/dist/holmes/mcp/elicit-approval.d.ts +32 -2
  40. package/dist/holmes/mcp/elicit-approval.js +30 -2
  41. package/dist/holmes/mcp/handlers.d.ts +88 -0
  42. package/dist/holmes/mcp/handlers.js +636 -35
  43. package/dist/holmes/mcp/maintenance-analyze.d.ts +435 -0
  44. package/dist/holmes/mcp/maintenance-analyze.js +994 -0
  45. package/dist/holmes/mcp/maintenance-evidence.d.ts +140 -0
  46. package/dist/holmes/mcp/maintenance-evidence.js +253 -0
  47. package/dist/holmes/mcp/server.js +13 -10
  48. package/dist/holmes/mcp/tool-schemas.js +71 -0
  49. package/dist/holmes/project/root.js +3 -1
  50. package/dist/holmes/review/baseline-arm.d.ts +37 -0
  51. package/dist/holmes/review/baseline-arm.js +51 -0
  52. package/dist/holmes/review/captured-stdin-guard.d.ts +8 -0
  53. package/dist/holmes/review/captured-stdin-guard.js +48 -0
  54. package/dist/holmes/review/coherence-verify.d.ts +31 -0
  55. package/dist/holmes/review/coherence-verify.js +144 -0
  56. package/dist/holmes/review/commit-text.d.ts +50 -0
  57. package/dist/holmes/review/commit-text.js +76 -0
  58. package/dist/holmes/review/confidence-calibration.d.ts +39 -0
  59. package/dist/holmes/review/confidence-calibration.js +39 -0
  60. package/dist/holmes/review/content-baseline.d.ts +38 -0
  61. package/dist/holmes/review/content-baseline.js +103 -0
  62. package/dist/holmes/review/content-verify.d.ts +20 -0
  63. package/dist/holmes/review/content-verify.js +73 -0
  64. package/dist/holmes/review/dense-retrieval.d.ts +66 -0
  65. package/dist/holmes/review/dense-retrieval.js +97 -0
  66. package/dist/holmes/review/edge-quality.d.ts +44 -0
  67. package/dist/holmes/review/edge-quality.js +117 -0
  68. package/dist/holmes/review/evaluation-metrics.d.ts +138 -0
  69. package/dist/holmes/review/evaluation-metrics.js +175 -0
  70. package/dist/holmes/review/graph-verifier.d.ts +34 -0
  71. package/dist/holmes/review/graph-verifier.js +62 -0
  72. package/dist/holmes/review/hop-ablation.d.ts +100 -0
  73. package/dist/holmes/review/hop-ablation.js +89 -0
  74. package/dist/holmes/review/manual-baseline.d.ts +209 -0
  75. package/dist/holmes/review/manual-baseline.js +2846 -0
  76. package/dist/holmes/review/oracle-gap.d.ts +32 -0
  77. package/dist/holmes/review/oracle-gap.js +102 -0
  78. package/dist/holmes/review/point-in-time-replay.d.ts +41 -0
  79. package/dist/holmes/review/point-in-time-replay.js +161 -0
  80. package/dist/holmes/review/rank-diagnosis.d.ts +43 -0
  81. package/dist/holmes/review/rank-diagnosis.js +163 -0
  82. package/dist/holmes/review/replay-calibration.d.ts +62 -0
  83. package/dist/holmes/review/replay-calibration.js +83 -0
  84. package/dist/holmes/review/replay-corpus.d.ts +135 -0
  85. package/dist/holmes/review/replay-corpus.js +210 -0
  86. package/dist/holmes/review/run-replay.d.ts +260 -0
  87. package/dist/holmes/review/run-replay.js +729 -0
  88. package/dist/holmes/review/semantic-arm.d.ts +271 -0
  89. package/dist/holmes/review/semantic-arm.js +717 -0
  90. package/dist/holmes/review/semantic-retrieval.d.ts +55 -0
  91. package/dist/holmes/review/semantic-retrieval.js +156 -0
  92. package/dist/holmes/review/spec-layer-stats.d.ts +38 -0
  93. package/dist/holmes/review/spec-layer-stats.js +52 -0
  94. package/dist/holmes/review/temporal-prior.d.ts +33 -0
  95. package/dist/holmes/review/temporal-prior.js +53 -0
  96. package/dist/holmes/review/test-runner.d.ts +15 -0
  97. package/dist/holmes/review/test-runner.js +41 -4
  98. package/dist/holmes/review/test-selection-breadth.d.ts +75 -0
  99. package/dist/holmes/review/test-selection-breadth.js +57 -0
  100. package/dist/holmes/review/traceability-benchmark.d.ts +81 -0
  101. package/dist/holmes/review/traceability-benchmark.js +135 -0
  102. package/dist/holmes/review/union-verify.d.ts +12 -0
  103. package/dist/holmes/review/union-verify.js +70 -0
  104. package/dist/holmes/rtm/graph-store.d.ts +51 -0
  105. package/dist/holmes/rtm/graph-store.js +122 -0
  106. package/dist/holmes/rtm/incremental.d.ts +25 -1
  107. package/dist/holmes/rtm/incremental.js +18 -1
  108. package/dist/holmes/rtm/localize.d.ts +28 -0
  109. package/dist/holmes/rtm/localize.js +272 -14
  110. package/dist/holmes/rtm/rtm-builder.d.ts +118 -3
  111. package/dist/holmes/rtm/rtm-builder.js +265 -28
  112. package/dist/holmes/rtm/rtm-graph.d.ts +117 -2
  113. package/dist/holmes/rtm/rtm-graph.js +194 -31
  114. package/dist/holmes/rtm/taint-benchmark.d.ts +97 -0
  115. package/dist/holmes/rtm/taint-benchmark.js +141 -0
  116. package/dist/holmes/rtm/test-scope.js +24 -1
  117. package/dist/holmes/semantic/credentials.d.ts +15 -0
  118. package/dist/holmes/semantic/credentials.js +134 -0
  119. package/dist/holmes/semantic/embedder.d.ts +44 -0
  120. package/dist/holmes/semantic/embedder.js +185 -0
  121. package/dist/holmes/semantic/hit-rerank.d.ts +4 -0
  122. package/dist/holmes/semantic/hit-rerank.js +38 -0
  123. package/dist/holmes/semantic/tier.d.ts +37 -0
  124. package/dist/holmes/semantic/tier.js +54 -0
  125. package/dist/holmes/semantic/vector-cache.d.ts +11 -0
  126. package/dist/holmes/semantic/vector-cache.js +91 -0
  127. package/dist/holmes/spec/acceptance-quality.d.ts +81 -0
  128. package/dist/holmes/spec/acceptance-quality.js +169 -0
  129. package/dist/holmes/spec/validator.js +33 -1
  130. package/dist/holmes/spec/yaml-scalar.d.ts +1 -0
  131. package/dist/holmes/spec/yaml-scalar.js +43 -0
  132. package/package.json +1 -1
@@ -0,0 +1,260 @@
1
+ import { evaluationMetrics, impactMetrics, ceilingMetrics } from './evaluation-metrics';
2
+ import { type ReplayCorpus } from './replay-corpus';
3
+ import { type PprArmConfig } from '../assoc/assoc-arm';
4
+ export interface ReplayResult {
5
+ corpus: string;
6
+ cases: number;
7
+ /** Cases whose parent tree could not be materialised — unmeasured, never scored zero. */
8
+ unmeasured: number;
9
+ casesWithoutSpecs: number;
10
+ metrics: ReturnType<typeof evaluationMetrics>;
11
+ impact: ReturnType<typeof impactMetrics>;
12
+ /**
13
+ * @implements A-SPEC-470 — the Phase-B external yardstick for the impact axis: the frozen
14
+ * string-property heuristic (same-dir / stem-share / prefix-depth), scored on the same cases.
15
+ * Beating it is the NECESSARY condition for any better-than-a-person phrasing here.
16
+ */
17
+ impactBaseline: ReturnType<typeof impactMetrics>;
18
+ /** Ranking ∪ impact, the set a caller actually receives (A-SPEC-312). */
19
+ union: ReturnType<typeof impactMetrics>;
20
+ /**
21
+ * The denominators. A recall without its ceiling cannot say whether a corpus scored higher because
22
+ * the analysis did better or because its co-changed files were better connected to begin with —
23
+ * and those two readings call for opposite decisions. `impactCeiling` walks CODE-to-CODE edges
24
+ * only (A-SPEC-307: the permissive walk reaches through SPEC nodes, a path no impact algorithm
25
+ * should follow, and flatters the denominator). `unionCeiling` is the weaker requirement the
26
+ * lexical axis actually has — the file merely had to be in the parent-time scan.
27
+ */
28
+ impactCeiling: ReturnType<typeof ceilingMetrics>;
29
+ unionCeiling: ReturnType<typeof ceilingMetrics>;
30
+ impactAchievement: number | null;
31
+ unionAchievement: number | null;
32
+ /**
33
+ * The Phase C arm, scored on the SAME cases and the same ground truth as `metrics` — added beside
34
+ * the product's ranking, never substituted for it, so both numbers are reported together.
35
+ */
36
+ idfArm: ReturnType<typeof evaluationMetrics>;
37
+ /**
38
+ * @implements A-SPEC-467 — the PPR associative-recall arm, present only when configs were asked
39
+ * for. rerank and admit are scored SEPARATELY: admission is a twice-measured failure mode (the
40
+ * spec layer lost 33% precision to it; caller closure added 59 files with zero correct), so a
41
+ * single blended number would hide exactly the cost that killed the predecessors.
42
+ */
43
+ pprArms?: Array<{
44
+ label: string;
45
+ rerank: ReturnType<typeof evaluationMetrics>;
46
+ admit: ReturnType<typeof evaluationMetrics>;
47
+ }>;
48
+ /**
49
+ * @implements A-SPEC-468 — the impact-axis grading arm: same cases, same expected sets as
50
+ * `impact`, predictions are PPR-mass top-k with the seed file excluded. recall AND precision are
51
+ * both carried — the closure's failure was precision-less expansion, so a recall-only number
52
+ * would repeat the caller-closure mistake.
53
+ */
54
+ pprImpact?: Array<{
55
+ label: string;
56
+ k: number;
57
+ recall: number | null;
58
+ precision: number | null;
59
+ }>;
60
+ /**
61
+ * @implements A-SPEC-471 — the precision frontier: the ADOPTED ranking with only the emission
62
+ * rule (alpha x k) swept, present only when asked. Measures how far mass alone can climb toward
63
+ * the human high-precision profile, and at what recall cost.
64
+ */
65
+ impactFrontier?: Array<{
66
+ alpha: number;
67
+ k: number;
68
+ recall: number | null;
69
+ precision: number | null;
70
+ }>;
71
+ /**
72
+ * @implements A-SPEC-472 — cumulative macro-averaged trajectories of the three iteration arms
73
+ * (A static, B re-seed, C judged expansion) under one emission budget and one oracle. Present
74
+ * only when asked; the oracle feedback is an optimistic upper bound and is scored as such.
75
+ */
76
+ iterative?: Array<{
77
+ arm: 'A' | 'B' | 'C' | 'D';
78
+ round: number;
79
+ recall: number | null;
80
+ precision: number | null;
81
+ emitted: number;
82
+ }>;
83
+ /**
84
+ * @implements A-SPEC-475 — the semantic localization arm: an INJECTED embedder (API, local or
85
+ * cache — the harness is only a consumer of vectors) ranks parent-time files against the commit
86
+ * subject. rerank and admit are scored separately, the same discipline every arm here follows.
87
+ */
88
+ semanticArm?: {
89
+ rerank: ReturnType<typeof evaluationMetrics>;
90
+ admit: ReturnType<typeof evaluationMetrics>;
91
+ };
92
+ /**
93
+ * @implements A-SPEC-488 — per-gate simulation of the PRODUCT rerank policy: a case scored
94
+ * with the sem order when its gate opens, with the product order otherwise. Present only when
95
+ * semanticArm.gates is asked; the plain semanticArm rows are untouched.
96
+ */
97
+ semanticGates?: Array<{
98
+ gate: string;
99
+ metrics: ReturnType<typeof evaluationMetrics>;
100
+ }>;
101
+ /**
102
+ * @implements A-SPEC-493 — the union answer EXTENDED by the semantic admit head: a set union,
103
+ * so recall is monotonically ≥ the product union's by construction; what this block measures
104
+ * is the size of the ceiling gain and the dilution cost the agent would absorb.
105
+ */
106
+ unionPlusAdmit?: Array<{
107
+ k: number;
108
+ recall: number | null;
109
+ precision: number | null;
110
+ }>;
111
+ /**
112
+ * @implements A-SPEC-479 — pre-emission verification of the union answer: an independent
113
+ * per-candidate verdict (semantic cosine or lexical IDF overlap, swept over tau) behind an
114
+ * explicit head guard. Present only when asked. Measures whether precision can be bought with
115
+ * the recall budget the union surface holds above the modeled human band — the S-488 frontier
116
+ * proved rank mass alone cannot climb there.
117
+ */
118
+ unionVerify?: Array<{
119
+ signal: 'sem' | 'lex';
120
+ tau: number;
121
+ guard: number;
122
+ recall: number | null;
123
+ precision: number | null;
124
+ }>;
125
+ /**
126
+ * @implements A-SPEC-480 — structural-coherence verification of the union tail: keep the top-h
127
+ * head, accept a tail candidate only if it shares a CODE edge or a spec anchor with the head.
128
+ * Evidence the ranker never consumed (the emission's internal relations), on the parent-time
129
+ * graph only. Present only when asked.
130
+ */
131
+ unionCoherence?: Array<{
132
+ mode: 'edge' | 'spec' | 'any';
133
+ h: number;
134
+ recall: number | null;
135
+ precision: number | null;
136
+ }>;
137
+ /**
138
+ * @implements A-SPEC-481 — position-independent verdicts over the emission's own structure:
139
+ * degree (keep members coupled to ≥ d others) and cluster (keep the largest coherent component,
140
+ * ties as a union). No head to be wrong about — S-498's head-error mode is removed by design;
141
+ * the guard stays the only positional device. Present only when asked.
142
+ */
143
+ coherenceRobust?: Array<{
144
+ family: 'degree' | 'cluster';
145
+ rel: 'edge' | 'any';
146
+ d: number | null;
147
+ guard: number;
148
+ recall: number | null;
149
+ precision: number | null;
150
+ }>;
151
+ /**
152
+ * @implements A-SPEC-482 — anchor + consensus combinations of the S-498/499 published bests:
153
+ * OR recovers truths a wrong head cut, AND refines coincidental couplings away. The last
154
+ * file-granularity combination; a miss here declares the evidence class exhausted.
155
+ */
156
+ anchoredConsensus?: Array<{
157
+ mode: 'edge' | 'spec' | 'any';
158
+ h: number;
159
+ d: number;
160
+ comb: 'or' | 'and';
161
+ recall: number | null;
162
+ precision: number | null;
163
+ }>;
164
+ /**
165
+ * @implements A-SPEC-483 — content-level verification of the union tail: does the request's
166
+ * rare vocabulary occur in the candidate's BODY, and do candidate and head reference each
167
+ * other by name? Bodies come from the materialized parent tree only. Present only when asked.
168
+ */
169
+ contentVerify?: Array<{
170
+ signal: string;
171
+ guard: number;
172
+ recall: number | null;
173
+ precision: number | null;
174
+ }>;
175
+ elapsedMs: number;
176
+ }
177
+ /**
178
+ * Run the point-in-time replay against ANY corpus.
179
+ *
180
+ * Lifted verbatim from the benchmark that lived inside `maintenance-analyze.test.ts`, where it was
181
+ * bound to this repository's paths. Every verdict in this work came from that single corpus, so the
182
+ * measurements could not be falsified by a second one — this is what makes them falsifiable.
183
+ *
184
+ * Equivalence is the load-bearing property of the extraction: this repository's numbers must come
185
+ * out unchanged, or subsequent comparisons measure the refactor instead of the corpora.
186
+ */
187
+ export declare function runReplay(corpus: ReplayCorpus, limit: number, opts?: {
188
+ pprConfigs?: PprArmConfig[];
189
+ impactFrontier?: boolean;
190
+ iterativeArms?: boolean;
191
+ /** @implements A-SPEC-488 — gates:true adds the gate-simulation rows; absent = unchanged. */
192
+ semanticArm?: {
193
+ embedBatch: (texts: string[], kind: 'query' | 'doc') => Promise<number[][]>;
194
+ gates?: boolean;
195
+ };
196
+ unionVerify?: {
197
+ embedBatch: (texts: string[], kind: 'query' | 'doc') => Promise<number[][]>;
198
+ semTaus?: number[];
199
+ };
200
+ unionCoherence?: boolean;
201
+ coherenceRobust?: boolean;
202
+ anchoredConsensus?: boolean;
203
+ contentVerify?: boolean;
204
+ /** @implements A-SPEC-485 — holdout window start; default 0 is the pinned main window. */
205
+ offset?: number;
206
+ /**
207
+ * @implements A-SPEC-487 — per-case dump for the blind judgment protocol. The pins stay on
208
+ * the 1-pass result; the dump carries the 2-pass (semantic-injected) output when
209
+ * productSemantic is present. The RUNNER owns blinding: truth goes to a separate file.
210
+ */
211
+ caseDump?: (row: {
212
+ commit: string;
213
+ subject: string;
214
+ candidates: Array<{
215
+ file: string;
216
+ score: number;
217
+ symbols: string[];
218
+ evidence: string[];
219
+ }>;
220
+ rankedImpact: Array<{
221
+ file: string;
222
+ score: number;
223
+ semCos?: number;
224
+ }>;
225
+ truthFiles: string[];
226
+ /** @implements A-SPEC-489 — present only when dumpBodies was asked. */
227
+ bodies?: Record<string, string>;
228
+ }) => void;
229
+ /** @implements A-SPEC-487 — 2-pass semantic injection for the dump only, never the pins. */
230
+ productSemantic?: {
231
+ embedBatch: (texts: string[], kind: 'query' | 'doc') => Promise<number[][]>;
232
+ label: string;
233
+ };
234
+ /**
235
+ * @implements A-SPEC-489 — body EXCERPTS for the content-access judgment protocol: the top
236
+ * `top` union-order candidates get their first `chars` characters read from the MATERIALIZED
237
+ * parent tree (never the present one). Meaningful only alongside caseDump; feeds no metric.
238
+ */
239
+ dumpBodies?: {
240
+ top: number;
241
+ chars: number;
242
+ /** @implements A-SPEC-490 — drop leading license blocks before excerpting; default false keeps S-507 bytes. */
243
+ skipLicense?: boolean;
244
+ };
245
+ }): Promise<ReplayResult>;
246
+ /**
247
+ * @implements A-SPEC-475
248
+ * One case of the semantic arm, pure given an embedder: documents follow the S-491 convention
249
+ * (`sourcePath + qualified symbol names`, 2000 chars) so numbers stay comparable across the
250
+ * traceability and localization experiments; the query is the commit subject as-is. rerank reuses
251
+ * `rerankPool` — the pool-stays-fixed invariant is shared code, not a re-promise.
252
+ */
253
+ export declare function semanticCaseRanking(files: ReadonlyArray<{
254
+ sourcePath: string;
255
+ symbolNames: readonly string[];
256
+ }>, subject: string, pool: readonly string[], topN: number, embedBatch: (texts: string[], kind: 'query' | 'doc') => Promise<number[][]>): Promise<{
257
+ rerank: string[];
258
+ admit: string[];
259
+ docTexts: string[];
260
+ }>;