@holmes-lab/holmes-kit 0.19.6 → 0.20.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 (128) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/README.md +8 -1
  3. package/dist/.build-id +1 -1
  4. package/dist/holmes/cli/approve-status.d.ts +24 -0
  5. package/dist/holmes/cli/approve-status.js +166 -0
  6. package/dist/holmes/cli/approve-watch.d.ts +6 -0
  7. package/dist/holmes/cli/approve-watch.js +6 -0
  8. package/dist/holmes/cli/approve.d.ts +27 -0
  9. package/dist/holmes/cli/approve.js +68 -7
  10. package/dist/holmes/cli/cli-execution.d.ts +2 -0
  11. package/dist/holmes/cli/cli-execution.js +24 -0
  12. package/dist/holmes/cli/gitignore-merge.d.ts +0 -5
  13. package/dist/holmes/cli/gitignore-merge.js +6 -2
  14. package/dist/holmes/cli/index.js +176 -139
  15. package/dist/holmes/cli/playbook-skills.d.ts +2 -22
  16. package/dist/holmes/cli/playbook-skills.js +10 -54
  17. package/dist/holmes/governance/approval-grants.d.ts +22 -0
  18. package/dist/holmes/governance/approval-grants.js +55 -1
  19. package/dist/holmes/governance/approval-queue.d.ts +43 -4
  20. package/dist/holmes/governance/approval-queue.js +86 -12
  21. package/dist/holmes/governance/display-id-aliases.d.ts +29 -0
  22. package/dist/holmes/governance/display-id-aliases.js +86 -0
  23. package/dist/holmes/governance/ledger-store.d.ts +42 -14
  24. package/dist/holmes/governance/ledger-store.js +49 -3
  25. package/dist/holmes/governance/ledger-timeline.d.ts +3 -1
  26. package/dist/holmes/governance/ledger-timeline.js +11 -1
  27. package/dist/holmes/governance/provenance-chain.d.ts +2 -0
  28. package/dist/holmes/governance/provenance-chain.js +13 -2
  29. package/dist/holmes/governance/provenance-ledger.d.ts +28 -0
  30. package/dist/holmes/governance/provenance-ledger.js +69 -16
  31. package/dist/holmes/governance/session-context.d.ts +3 -0
  32. package/dist/holmes/governance/session-context.js +26 -8
  33. package/dist/holmes/guardrail/risk-classifier.js +2 -2
  34. package/dist/holmes/guardrail/write-target.js +2 -1
  35. package/dist/holmes/hooks/pre-tool-use.js +12 -1
  36. package/dist/holmes/hooks/stop.js +14 -3
  37. package/dist/holmes/mcp/handlers/adoption.d.ts +118 -0
  38. package/dist/holmes/mcp/handlers/adoption.js +186 -0
  39. package/dist/holmes/mcp/handlers/entity-integration.d.ts +100 -0
  40. package/dist/holmes/mcp/handlers/entity-integration.js +324 -0
  41. package/dist/holmes/mcp/handlers/entity-renumber.d.ts +137 -0
  42. package/dist/holmes/mcp/handlers/entity-renumber.js +228 -0
  43. package/dist/holmes/mcp/handlers/entity-store.d.ts +78 -0
  44. package/dist/holmes/mcp/handlers/entity-store.js +212 -0
  45. package/dist/holmes/mcp/handlers/graph-operations.d.ts +90 -0
  46. package/dist/holmes/mcp/handlers/graph-operations.js +260 -0
  47. package/dist/holmes/mcp/handlers/maintenance-analysis.d.ts +34 -0
  48. package/dist/holmes/mcp/handlers/maintenance-analysis.js +288 -0
  49. package/dist/holmes/mcp/handlers/maintenance-evidence.d.ts +40 -0
  50. package/dist/holmes/mcp/handlers/maintenance-evidence.js +104 -0
  51. package/dist/holmes/mcp/handlers/operator-inspection.d.ts +167 -0
  52. package/dist/holmes/mcp/handlers/operator-inspection.js +284 -0
  53. package/dist/holmes/mcp/handlers/phase-queries.d.ts +34 -0
  54. package/dist/holmes/mcp/handlers/phase-queries.js +86 -0
  55. package/dist/holmes/mcp/handlers/review-evidence.d.ts +47 -0
  56. package/dist/holmes/mcp/handlers/review-evidence.js +370 -0
  57. package/dist/holmes/mcp/handlers/review-queries.d.ts +68 -0
  58. package/dist/holmes/mcp/handlers/review-queries.js +79 -0
  59. package/dist/holmes/mcp/handlers/risk-assessment.d.ts +25 -0
  60. package/dist/holmes/mcp/handlers/risk-assessment.js +181 -0
  61. package/dist/holmes/mcp/handlers/slice-orchestration.d.ts +55 -0
  62. package/dist/holmes/mcp/handlers/slice-orchestration.js +324 -0
  63. package/dist/holmes/mcp/handlers/spec-approval.d.ts +105 -0
  64. package/dist/holmes/mcp/handlers/spec-approval.js +504 -0
  65. package/dist/holmes/mcp/handlers/spec-authoring.d.ts +57 -0
  66. package/dist/holmes/mcp/handlers/spec-authoring.js +326 -0
  67. package/dist/holmes/mcp/handlers/spec-lifecycle.d.ts +122 -0
  68. package/dist/holmes/mcp/handlers/spec-lifecycle.js +339 -0
  69. package/dist/holmes/mcp/handlers/spec-queries.d.ts +30 -0
  70. package/dist/holmes/mcp/handlers/spec-queries.js +74 -0
  71. package/dist/holmes/mcp/handlers/taint-screening.d.ts +48 -0
  72. package/dist/holmes/mcp/handlers/taint-screening.js +183 -0
  73. package/dist/holmes/mcp/handlers/test-execution.d.ts +63 -0
  74. package/dist/holmes/mcp/handlers/test-execution.js +210 -0
  75. package/dist/holmes/mcp/handlers/workspace-identity.d.ts +30 -0
  76. package/dist/holmes/mcp/handlers/workspace-identity.js +68 -0
  77. package/dist/holmes/mcp/handlers/workspace-queries.d.ts +77 -0
  78. package/dist/holmes/mcp/handlers/workspace-queries.js +193 -0
  79. package/dist/holmes/mcp/handlers.d.ts +653 -424
  80. package/dist/holmes/mcp/handlers.js +267 -3250
  81. package/dist/holmes/mcp/server.js +2 -1
  82. package/dist/holmes/mcp/tool-schemas.js +43 -2
  83. package/dist/holmes/project/execution-context.d.ts +17 -0
  84. package/dist/holmes/project/execution-context.js +120 -0
  85. package/dist/holmes/project/installer-markers.d.ts +34 -0
  86. package/dist/holmes/project/installer-markers.js +65 -0
  87. package/dist/holmes/project/root.d.ts +3 -1
  88. package/dist/holmes/project/root.js +4 -3
  89. package/dist/holmes/project/workspace-identity.d.ts +29 -0
  90. package/dist/holmes/project/workspace-identity.js +181 -0
  91. package/dist/holmes/review/test-outcomes.d.ts +6 -1
  92. package/dist/holmes/review/test-outcomes.js +23 -5
  93. package/dist/holmes/review/test-runner.d.ts +18 -0
  94. package/dist/holmes/review/test-runner.js +132 -4
  95. package/dist/holmes/rtm/graph-store.d.ts +50 -1
  96. package/dist/holmes/rtm/graph-store.js +244 -3
  97. package/dist/holmes/rtm/incremental.d.ts +1 -0
  98. package/dist/holmes/rtm/incremental.js +12 -3
  99. package/dist/holmes/rtm/localize.js +7 -0
  100. package/dist/holmes/rtm/rtm-graph.d.ts +9 -0
  101. package/dist/holmes/rtm/rtm-graph.js +13 -0
  102. package/dist/holmes/semantic/vector-cache.d.ts +16 -1
  103. package/dist/holmes/semantic/vector-cache.js +155 -19
  104. package/dist/holmes/spec/approval-status.d.ts +10 -0
  105. package/dist/holmes/spec/approval-status.js +7 -3
  106. package/dist/holmes/spec/entity-git-snapshot.d.ts +50 -0
  107. package/dist/holmes/spec/entity-git-snapshot.js +276 -0
  108. package/dist/holmes/spec/entity-integration-discharge.d.ts +73 -0
  109. package/dist/holmes/spec/entity-integration-discharge.js +233 -0
  110. package/dist/holmes/spec/entity-integration-transaction.d.ts +179 -0
  111. package/dist/holmes/spec/entity-integration-transaction.js +1221 -0
  112. package/dist/holmes/spec/entity-integration.d.ts +207 -0
  113. package/dist/holmes/spec/entity-integration.js +747 -0
  114. package/dist/holmes/spec/entity-renumber-transaction.d.ts +82 -0
  115. package/dist/holmes/spec/entity-renumber-transaction.js +711 -0
  116. package/dist/holmes/spec/entity-renumber.d.ts +32 -0
  117. package/dist/holmes/spec/entity-renumber.js +156 -0
  118. package/dist/holmes/spec/entity-store.d.ts +135 -0
  119. package/dist/holmes/spec/entity-store.js +1051 -0
  120. package/dist/holmes/spec/entity-transaction.d.ts +89 -0
  121. package/dist/holmes/spec/entity-transaction.js +701 -0
  122. package/dist/holmes/spec/renumber.d.ts +58 -0
  123. package/dist/holmes/spec/renumber.js +200 -1
  124. package/dist/holmes/spec/spec-store.d.ts +3 -2
  125. package/dist/holmes/spec/spec-store.js +23 -2
  126. package/dist/holmes/spec/transition-policy.d.ts +36 -0
  127. package/dist/holmes/spec/transition-policy.js +135 -0
  128. package/package.json +1 -1
@@ -0,0 +1,193 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.createWorkspaceQueryHandlers = createWorkspaceQueryHandlers;
37
+ // @implements A-SPEC-610, A-SPEC-100.2, A-SPEC-121.2, A-SPEC-128, A-SPEC-131, A-SPEC-146, A-SPEC-189, A-SPEC-419, A-SPEC-461, A-SPEC-496, A-SPEC-506.1
38
+ const fs = __importStar(require("node:fs"));
39
+ const path = __importStar(require("node:path"));
40
+ const validator_1 = require("../../spec/validator");
41
+ const rtm_check_1 = require("../../rtm/rtm-check");
42
+ const test_scope_1 = require("../../rtm/test-scope");
43
+ const gap_analyzer_1 = require("../../rtm/gap-analyzer");
44
+ const spec_types_1 = require("../../spec/spec-types");
45
+ const breaking_change_1 = require("../../spec/breaking-change");
46
+ const consistency_lints_1 = require("../../cpg/consistency-lints");
47
+ const localize_1 = require("../../rtm/localize");
48
+ const tier_1 = require("../../semantic/tier");
49
+ const vector_cache_1 = require("../../semantic/vector-cache");
50
+ const embedder_1 = require("../../semantic/embedder");
51
+ // @implements A-SPEC-496 — policy parity: the direct localization path reranks with the exact
52
+ // A-SPEC-478 math, extracted pure.
53
+ const hit_rerank_1 = require("../../semantic/hit-rerank");
54
+ function createWorkspaceQueryHandlers(context) {
55
+ return {
56
+ async rtm_check(a) {
57
+ // @implements A-SPEC-461 — a root that names a different project would check THIS project's
58
+ // specs against THAT project's files and report clean — A-SPEC-191 §15. foreignRootReason
59
+ // returns null for an absent or matching root, so the spec-only and correct-root paths are
60
+ // unaffected. Shared guard (citation_pin/maintenance_analyze use it), not a copy (A-SPEC-449).
61
+ {
62
+ const foreign = context.foreignRootReason(a?.root);
63
+ if (foreign)
64
+ return { ok: false, reason: foreign };
65
+ }
66
+ const specs = await context.listSpecs();
67
+ // rtm_check runs on the GOVERNED set only (excludes archived legacy +
68
+ // JOB specs, which otherwise flood orphan/dangling results; see
69
+ // ADR-010).
70
+ const issues = (0, rtm_check_1.rtmCheck)((0, spec_types_1.filterGoverned)(specs));
71
+ // @implements A-SPEC-146 — a REPORT, not a verdict: ADR-013 named formulaic `none` a
72
+ // revisit trigger for a human, and `(unset)` shows how far the corpus has converged.
73
+ const breakingChangeDistribution_ = (0, breaking_change_1.breakingChangeDistribution)((0, spec_types_1.filterGoverned)(specs));
74
+ if (a?.root) {
75
+ // @implements A-SPEC-189 §14 (round 13) — the derivation was computed and discarded, so the
76
+ // advertised "a subdirectory resolves up to it" held for `taint_scan` and no one else.
77
+ const root = context.projectRootOf(a.root);
78
+ // Citation drift: a REQ's cited source may have been edited since it was read, which silently
79
+ // invalidates the requirement derived from it. Only refs that resolve to a file INSIDE the
80
+ // repo are re-hashed — an unresolvable ref (external ticket, no adapter configured) is not
81
+ // evidence of drift, and a path escaping the repo is not ours to read.
82
+ const readLocal = (ref) => {
83
+ const abs = path.resolve(root, ref);
84
+ if (!abs.startsWith(path.resolve(root) + path.sep))
85
+ return null;
86
+ try {
87
+ return fs.readFileSync(abs, 'utf8');
88
+ }
89
+ catch {
90
+ return null;
91
+ }
92
+ };
93
+ for (const s of specs) {
94
+ if (s.type !== 'REQ' || s.frontmatter.source == null)
95
+ continue;
96
+ for (const d of (0, validator_1.verifyCitationDigests)(s.frontmatter.source, readLocal)) {
97
+ issues.push({ level: d.level, code: d.code, message: `${s.id}: ${d.message}` });
98
+ }
99
+ }
100
+ const scanned = context.cachedScan(root, root);
101
+ // checkImplements checks @implements A-SPEC refs against the FULL
102
+ // spec id set (not filterGoverned) — it's an existence check: any
103
+ // existing spec id is a valid anchor target.
104
+ issues.push(...(0, rtm_check_1.checkImplements)(scanned, specs));
105
+ // L6 convergence gaps (ADVISORY, not issues): where implementation and the governed spec set
106
+ // have drifted apart — unimplemented approved specs, unanchored source, untested specs. Feeds
107
+ // the convergence loop's "pick next work"; an unimplemented spec is normal mid-development.
108
+ const gaps = (0, gap_analyzer_1.computeConvergenceGaps)(scanned, (0, spec_types_1.filterGoverned)(specs), (0, test_scope_1.scanTestAnchors)(root));
109
+ return { issues, gaps, breakingChangeDistribution: breakingChangeDistribution_ };
110
+ }
111
+ return { issues, breakingChangeDistribution: breakingChangeDistribution_ };
112
+ },
113
+ async cpg_scan(a) {
114
+ // @implements A-SPEC-189 §14 (round 13) — the derivation was computed and discarded, so the
115
+ // advertised "a subdirectory resolves up to it" held for `taint_scan` and no one else.
116
+ const root = context.projectRootOf(a.root);
117
+ // @implements A-SPEC-131
118
+ // The skip report is part of the answer: a caller cannot distinguish "clean tree" from "tree
119
+ // with casualties" by counts alone. Bounded listing (50), complete count.
120
+ const { scanned, skipped } = context.cachedScanWithReport(root);
121
+ const symbols = scanned.reduce((n, f) => n + f.symbols.length, 0);
122
+ const base = { files: scanned.length, symbols, skipped: skipped.slice(0, 50), skippedCount: skipped.length };
123
+ if (!a.lints)
124
+ return base;
125
+ // @implements A-SPEC-506.1 — opt-in consistency lints (P-G/P-J field incidents): WARNING
126
+ // signals only, additive field only, Python only; the default path above is byte-identical.
127
+ const defined = new Set();
128
+ for (const f of scanned)
129
+ for (const s of f.symbols) {
130
+ defined.add(s.name);
131
+ const last = s.name.split('.').pop();
132
+ if (last)
133
+ defined.add(last);
134
+ }
135
+ const dynamicRef = [];
136
+ const asyncBlocking = [];
137
+ for (const f of scanned) {
138
+ if (!f.sourcePath.endsWith('.py'))
139
+ continue;
140
+ let code;
141
+ try {
142
+ code = fs.readFileSync(path.join(root, f.sourcePath), 'utf8');
143
+ }
144
+ catch {
145
+ continue;
146
+ }
147
+ for (const hit of (0, consistency_lints_1.dynamicRefFindings)(code, defined))
148
+ dynamicRef.push({ file: f.sourcePath, ...hit });
149
+ for (const hit of (0, consistency_lints_1.asyncBlockingFindings)(code))
150
+ asyncBlocking.push({ file: f.sourcePath, ...hit });
151
+ }
152
+ return { ...base, lints: { dynamicRef, asyncBlocking, limits: [...consistency_lints_1.LINT_LIMITS] } };
153
+ },
154
+ async issue_localize(a) {
155
+ context.assertStoreReachable('issue_localize', a.root); // @implements A-SPEC-419
156
+ // N1: deterministic localization report — CPG lexical match fused with the RTM spec hop.
157
+ // @implements A-SPEC-189 §14 (round 13) — `context.projectRootOf(a.root)` was called as a bare
158
+ // statement: its only effect was to throw on a bad path, and the advertised contract ("a
159
+ // subdirectory resolves up to it") was dropped on the floor. `taint_scan` one function away
160
+ // honours it, so the same argument answered about two different trees depending on which tool
161
+ // was asked. Bind the derivation and use it.
162
+ const root = context.projectRootOf(a.root);
163
+ const scanned = context.cachedScan(root, root);
164
+ const specs = await context.listSpecs();
165
+ const governed = (0, spec_types_1.filterGoverned)(specs);
166
+ const report = (0, localize_1.localizeIssue)(a.issue, scanned, governed, a.topN ?? 10);
167
+ // @implements A-SPEC-496 — parity with A-SPEC-478: the SAME uncited gate, the SAME math
168
+ // (cached vectors only, set fixed, covered hits move, why-line attached). Any missing
169
+ // signal — no tier, no key, cold cache, embed failure — leaves the report untouched;
170
+ // localization itself never fails because of the semantic layer.
171
+ //
172
+ // A spec-intent-vector assist (REQ-568 S3) was wired ahead of localizeIssue here and REVERTED
173
+ // on its pre-registered replay — see rtm/localize.ts at the matchedSpecs join for the numbers.
174
+ try {
175
+ if (report.hits.length > 1
176
+ && (0, localize_1.citationsIn)(a.issue, new Set(governed.map((s) => s.id))).cited.length === 0) {
177
+ const rt = (0, embedder_1.makeTierEmbedder)((0, tier_1.resolveSemanticTier)(), new vector_cache_1.VectorCache(root));
178
+ if (rt !== null) {
179
+ const qv = await rt.embedQuery(a.issue);
180
+ const docTextOf = new Map(scanned.map((f) => [f.sourcePath,
181
+ (f.sourcePath + ' ' + f.symbols.map((sy) => sy.qualifiedName).join(' ')).slice(0, 2000)]));
182
+ (0, hit_rerank_1.rerankHitsBySemantic)(report.hits, qv, (file) => {
183
+ const dt = docTextOf.get(file);
184
+ return dt !== undefined ? rt.cachedDocVector(dt) : null;
185
+ }, rt.label);
186
+ }
187
+ }
188
+ }
189
+ catch { /* semantic layer is additive — never block the report */ }
190
+ return report;
191
+ },
192
+ };
193
+ }