@holmes-lab/holmes-kit 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,39 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+ <!-- @implements A-SPEC-209 -->
8
+ ## [0.3.3] - 2026-08-31
9
+
10
+ Docs-only: the README the npm page shows catches up with 0.3.x.
11
+
12
+ ### Changed
13
+
14
+ - README rewritten to 0.3.x: the 3-tier semantic layer (consent ladder + measured recalls), the
15
+ graded impact surface and its pre-registered baselines, the measured-not-claimed grading against
16
+ the modeled-human band (independent blind-judge P 0.727 = 81% of the band), approval-dialog
17
+ expiry visibility, the corrected Codex wiring path (`.codex/config.toml`), the Windows row
18
+ corrected from a CI claim to the 2026-08-31 field validation, a zero-install `npx` one-shot row,
19
+ and the stale-global-shim shadowing warning (field-measured dual global roots on Windows).
20
+ No code changes.
21
+
22
+ <!-- @implements A-SPEC-209 -->
23
+ ## [0.3.2] - 2026-08-31
24
+
25
+ Windows doctor unbroken: the wiring-handshake checks can now actually run the wiring they judge.
26
+
27
+ ### Fixed
28
+
29
+ - **doctor wiring handshake on Windows** (A-SPEC-499.1): the four wiring checks (claude / codex /
30
+ antigravity handshake + mcp wiring spawn) spawned `npx` directly, which on win32 is `npx.cmd`
31
+ and cannot be executed by a plain spawn — every check died `spawn npx ENOENT` on a correctly
32
+ wired target (field-measured on 0.3.1). A pure platform adapter now reroutes execution through
33
+ `cmd.exe /d /s /c` (whitespace-bearing tokens quoted — space-in-username installs included);
34
+ posix spawn arguments are value-identical to before.
35
+ - **ENOENT prescription**: a command the OS cannot find no longer gets "Re-run `holmes-kit init`"
36
+ — re-initing into the identical failure forever was the measured loop. It now says the command
37
+ could not be resolved (PATH/platform) and to try it in a shell; genuine stale-wiring failures
38
+ keep the re-init wording byte-for-byte.
39
+
7
40
  <!-- @implements A-SPEC-209 -->
8
41
  ## [0.3.1] - 2026-08-31
9
42
 
package/README.md CHANGED
@@ -14,11 +14,15 @@
14
14
 
15
15
  ---
16
16
 
17
- ### 🛡️ Currently Supported Features (v0.1.x Production Features)
17
+ ### 🛡️ Currently Supported Features (v0.3.x Production Features)
18
18
 
19
19
  - 📋 **Requirements & Specification Governance**: Strict **"No Spec, No Code"** enforcement with 4-tier spec chain traceability (`REQ ➔ H-SPEC ➔ A-SPEC ➔ T-SPEC`) and `// @implements A-SPEC-XXX` line 1 code anchors.
20
+ - 🧠 **3-Tier Semantic Layer** *(new in 0.3.0)*: knowledge-graph semantic search with an explicit consent ladder — `none` (default, **zero egress**), `local` (bge-m3, no egress, optional module), `cloud` (gemini-embedding-001, opt-in via `GEMINI_API_KEY`). Measured on 305 traceability cases: recall 0.486 (lexical) → 0.667 (local) → **0.887 (cloud)**; on lexical-zero requests: 0% → 52% → **92%**. Surfaced only additively — rerank, evidence (`semCos`), and `semanticAlternates` — never as a hard filter.
21
+ - 🎯 **Graded Impact Surface** *(new in 0.3.0)*: `rankedImpact` (personalized-PageRank over the spec/code graph) beat its pre-registered naive baseline on **both recall and precision across 3 corpora (×1.6–×17)** — the necessary condition for any better-than-a-person phrasing, measured before claimed.
20
22
  - 🐞 **Causal Defect Localization & CPG**: AST Code Property Graph (CPG) & Dataflow Taint reachability analysis across 7 languages (TS/JS, Python, Go, Rust, Java, C/C++, C#).
21
- - 🧪 **Self-Healing & Diagnostic Doctor**: Automated integrity checks and self-healing auto-fix remediation (`holmes-kit doctor --fix` & `spec_remediate`).
23
+ - 📏 **Measured, Not Claimed** *(new in 0.3.x)*: performance is judged against a pre-registered modeled-human band (R 0.67–0.78 / P ≈0.9±). Current official grade: **band entry on recall; division-of-labor precision 0.727 = 81% of the modeled human — reproduced by an independent context-free judge on a fresh blind window.** No superhuman claims until both metrics exceed the band.
24
+ - 🧪 **Self-Healing & Diagnostic Doctor**: Automated integrity checks and self-healing auto-fix remediation (`holmes-kit doctor --fix` & `spec_remediate`) — wiring-handshake checks run on Windows natively as of 0.3.2.
25
+ - 🔔 **Approval UX** *(new in 0.3.1)*: in-session approval dialogs forewarn their 120s deadline and, on expiry, the refusal says exactly where the decision went (`npx holmes-kit approve` out-of-band queue) — no more silently dead dialogs.
22
26
  - 🚦 **CI/CD Governance Gate Runner**: Non-interactive headless CI/CD build gate (`holmes-kit ci`) for GitHub Actions and GitLab CI pipelines.
23
27
  - 📊 **Automated RTM & Taint Heatmap**: Interactive standalone HTML/SVG report generation (`generateRtmHeatmap`) for spec coverage and security dataflow reachability.
24
28
  - 🤖 **CLI-First AI Harness Matrix**: Native process hook gating for Claude Code, Antigravity CLI (AGY), Codex CLI, and Google Antigravity SDK.
@@ -42,7 +46,7 @@ Holmes-Kit prioritizes **CLI-based AI Coding Agents** where OS-level process hoo
42
46
  | :--- | :--- | :--- |
43
47
  | 🤖 **Claude Code CLI** | 🥇 Tier 1 (Native) | OS PreToolUse & Stop hooks (`.claude/settings.local.json`), MCP server (`.mcp.json`) |
44
48
  | 🚀 **Antigravity CLI (AGY)** | 🥇 Tier 1 (Native) | AGY Hooks (`hooks.json`), MCP config (`.agents/mcp_config.json`), Governance Skills |
45
- | 💻 **Codex CLI / Agentic Shell** | 🥇 Tier 1 (Native) | Codex MCP integration (`.codex/mcp_config.json`), Subshell Isolation Gates |
49
+ | 💻 **Codex CLI / Agentic Shell** | 🥇 Tier 1 (Native) | Codex MCP integration (`.codex/config.toml`), plugin-packaged gate hooks (installed via Codex plugin marketplace) |
46
50
  | 🧩 **Google Antigravity SDK** | 🥇 Tier 1 (Native) | Autonomous Agent SDK bindings and cryptographic provenance verification |
47
51
 
48
52
  > **Note**: Holmes-Kit focuses strictly on CLI-based autonomous agents to guarantee 100% deterministic OS hook gating (`deny` enforcement) before file modifications occur.
@@ -69,10 +73,18 @@ Add `-DryRun` to see what it would do without installing. Exit codes: `0` ok / a
69
73
  | Which situation are you in? | Privileges | Command |
70
74
  |---|---|---|
71
75
  | **Using it in one project** (most people) | none | `npm install --save-dev @holmes-lab/holmes-kit` |
76
+ | **Zero-install one-shot** (try it first) | none | `npx -y @holmes-lab/holmes-kit init` — npx fetches and runs, nothing to install beforehand |
72
77
  | Company-managed PC / restricted account | none | same — no system directory is touched |
73
78
  | CI / container | none | same, plus `--prefer-online` right after a release |
74
79
  | CLI across many projects (`-g`) | depends | run `npm config get prefix` first — see below |
75
80
 
81
+ **Stale global shadowing** *(field-measured on Windows, 2026-08-31)*: an old global install makes the
82
+ bare `holmes-kit` command run the OLD version while `npx holmes-kit` runs the local one — and
83
+ Windows has TWO global roots (`C:\Program Files\nodejs` and `%APPDATA%\npm`), so `npm uninstall -g`
84
+ against one root can leave a live shim in the other. If `holmes-kit --version` and
85
+ `npx holmes-kit --version` disagree, run `where.exe holmes-kit` (Windows) / `which -a holmes-kit`
86
+ and remove the stale shim; prefer the `npx` form day-to-day.
87
+
76
88
  **Before `npm install -g`**: if `npm config get prefix` names a protected directory
77
89
  (`C:\Program Files\nodejs`, `/usr/local`), `-g` dies with `EPERM` **before any package file
78
90
  arrives** — no package version can fix that, and elevation is the wrong fix (it runs native
@@ -96,7 +108,7 @@ npx holmes-kit init # drop the npx prefix if you installed with -g
96
108
  ? Select the AI Agent harnesses to wire into this project:
97
109
  [X] 🤖 Claude Code (.claude/settings.local.json, .mcp.json)
98
110
  [X] 🚀 Antigravity CLI (AGY) (.agents/mcp_config.json, hooks.json, skills)
99
- [ ] 💻 Codex CLI (.codex/mcp_config.json)
111
+ [ ] 💻 Codex CLI (.codex/config.toml)
100
112
  ```
101
113
 
102
114
  ### 3. Verify Health
@@ -181,7 +193,7 @@ Holmes-Kit embeds native AST & Code Property Graph (D-CPG) analyzers to track ca
181
193
  | **macOS** | Apple Silicon (arm64) / Intel (x64) | ✅ Tier 1 | macOS 12+ (Full hook enforcement) |
182
194
  | **Linux** | x86_64 / arm64 | ✅ Tier 1 | Ubuntu, Debian, Fedora, Arch, RHEL |
183
195
  | **Windows (WSL2)** | x86_64 | ✅ Tier 1 | WSL2 Ubuntu/Debian recommended |
184
- | **Windows Native** | x86_64 | ✅ Tier 1 | Windows 10/11 (Node.js 20+ with C++ build tools). Gate parity verified from CI see [ADR-015](.ax/decisions/ADR-015_platform-tier-is-decided-by-executed-verification.md) for the graduation criteria and the residual risks (NTFS 8.3 names, reserved device names, 260-char paths) |
196
+ | **Windows Native** | x86_64 | ✅ Tier 1 | Windows 10/11 (Node.js 20+; prebuilt natives, no build tools needed in the common case). **Field-validated 2026-08-31** on a real user machine: registry install, natives (better-sqlite3 + 7 tree-sitter grammars), both OS gates, MCP handshake (30 tools), interactive init TUI, out-of-band approval channel (doctor 25 PASS; the 4 false FAILs it also showed were doctor's own win32 spawn bug, fixed in 0.3.2). See [ADR-015](.ax/decisions/ADR-015_platform-tier-is-decided-by-executed-verification.md) for tier criteria and residual risks (NTFS 8.3 names, reserved device names, 260-char paths; no Windows CI yet) |
185
197
 
186
198
  > **Runtime Requirement**: Node.js `>= 20.0.0` (LTS recommended)
187
199
  >
package/dist/.build-id CHANGED
@@ -1 +1 @@
1
- 9dd2f60-mthaxwnr
1
+ 8c7f0ed-mthde5yw
@@ -95,6 +95,13 @@ export interface ProbeRunner {
95
95
  };
96
96
  }
97
97
  export declare function runDoctor(packageRoot: string, target?: string, opts?: DoctorOptions, extraChecks?: Check[]): Promise<Check[]>;
98
+ /**
99
+ * Drive a real MCP stdio handshake: initialize -> initialized -> tools/list, with a timeout.
100
+ * Async by necessity — the protocol is a ROUND TRIP, so a spawnSync that writes everything at once
101
+ * and closes stdin makes the server exit before answering (a false FAIL this check produced on its
102
+ * very first run against a healthy server).
103
+ */
104
+ export declare function wiringSpawnCheck(command: string, args: string[], timeoutMs?: number, platform?: NodeJS.Platform): Promise<Check>;
98
105
  export declare function formatChecks(checks: Check[]): string;
99
106
  /**
100
107
  * Prove that EVERY wired harness can actually start a server, not merely that its file parses.
@@ -39,6 +39,7 @@ exports.npmCliEntry = npmCliEntry;
39
39
  exports.prefixVerdict = prefixVerdict;
40
40
  exports.probeEnv = probeEnv;
41
41
  exports.runDoctor = runDoctor;
42
+ exports.wiringSpawnCheck = wiringSpawnCheck;
42
43
  exports.formatChecks = formatChecks;
43
44
  exports.wiringHandshakeChecks = wiringHandshakeChecks;
44
45
  exports.semanticTierVerdict = semanticTierVerdict;
@@ -52,6 +53,7 @@ const path = __importStar(require("node:path"));
52
53
  const role_policy_1 = require("../governance/role-policy");
53
54
  const blind_spots_1 = require("../guardrail/blind-spots");
54
55
  const node_child_process_1 = require("node:child_process");
56
+ const spawn_spec_1 = require("./spawn-spec");
55
57
  const os = __importStar(require("node:os"));
56
58
  const settings_merge_1 = require("./settings-merge");
57
59
  const playbook_skills_1 = require("./playbook-skills");
@@ -1026,8 +1028,20 @@ function cleanupOnSignal(dir) {
1026
1028
  // Spawn the TARGET's wiring verbatim and require initialize inside the deadline. Unlike
1027
1029
  // `mcpHandshakeCheck` below (which proves this INSTALL can serve), this proves the WIRING the
1028
1030
  // harness will actually run reaches a server — the gap the dead npx form lived in.
1029
- function wiringSpawnCheck(command, args, timeoutMs = 30000) {
1031
+ // @implements A-SPEC-499.1 exported for the prescription tests; `platform` is injectable so the
1032
+ // win32 branch is testable off-Windows.
1033
+ function wiringSpawnCheck(command, args, timeoutMs = 30000, platform = process.platform) {
1034
+ // The DISPLAYED command stays the original wiring string even when the win32 adapter rewraps the
1035
+ // execution — the user compares this against their wiring file, not against cmd.exe plumbing.
1030
1036
  const quoted = `${command} ${args.join(' ')}`;
1037
+ // @implements A-SPEC-499.1 — Windows field measurement: four wiring checks on a correctly rewired
1038
+ // 0.3.1 target all died `spawn npx ENOENT`, because `npx` is `npx.cmd` there and a plain spawn
1039
+ // cannot execute a .cmd shim. The adapter reroutes through cmd.exe; posix is value-identical.
1040
+ const spec = (0, spawn_spec_1.spawnSpecFor)(command, args, platform);
1041
+ // The re-init prescription is only honest when the wiring might actually be stale. A command the
1042
+ // OS cannot find (ENOENT) re-inits into the identical failure forever — the measured loop.
1043
+ const enoentFix = `\`${command}\` 명령을 찾지 못했습니다(PATH 또는 플랫폼) — 배선 문자열이 옳다면 재-init은 도움이 되지 않습니다. 같은 명령을 셸에서 직접 실행해 확인하십시오.`;
1044
+ const spawnFailFix = (e) => e?.code === 'ENOENT' ? enoentFix : 'Re-run `holmes-kit init` in the target to rewrite the wiring.';
1031
1045
  return new Promise((resolve) => {
1032
1046
  let done = false;
1033
1047
  let out = '';
@@ -1045,13 +1059,13 @@ function wiringSpawnCheck(command, args, timeoutMs = 30000) {
1045
1059
  };
1046
1060
  const timer = setTimeout(() => finish('FAIL', `wiring did not answer initialize within ${timeoutMs / 1000}s: \`${quoted}\``, 'Re-run `holmes-kit init` in the target to rewrite the wiring, then re-run doctor.'), timeoutMs);
1047
1061
  try {
1048
- child = (0, node_child_process_1.spawn)(command, args, { stdio: ['pipe', 'pipe', 'pipe'] });
1062
+ child = (0, node_child_process_1.spawn)(spec.command, spec.args, { stdio: ['pipe', 'pipe', 'pipe'] });
1049
1063
  }
1050
1064
  catch (e) {
1051
- finish('FAIL', `wiring could not be spawned: \`${quoted}\` — ${e.message}`, 'Re-run `holmes-kit init` in the target to rewrite the wiring.');
1065
+ finish('FAIL', `wiring could not be spawned: \`${quoted}\` — ${e.message}`, spawnFailFix(e));
1052
1066
  return;
1053
1067
  }
1054
- child.on('error', (e) => finish('FAIL', `wiring could not be spawned: \`${quoted}\` — ${e.message}`, 'Re-run `holmes-kit init` in the target to rewrite the wiring.'));
1068
+ child.on('error', (e) => finish('FAIL', `wiring could not be spawned: \`${quoted}\` — ${e.message}`, spawnFailFix(e)));
1055
1069
  child.on('exit', (code) => finish('FAIL', `wiring exited (code ${code}) before answering initialize: \`${quoted}\``, 'Re-run `holmes-kit init` in the target to rewrite the wiring.'));
1056
1070
  child.stdin?.on('error', () => { });
1057
1071
  child.stdout?.on('data', (d) => {
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Platform adapter for spawning a WIRING command verbatim. On win32, `npx` is `npx.cmd`, and a
3
+ * plain child_process.spawn cannot execute a .cmd shim (Node's CVE-2024-27980 hardening) — the
4
+ * Windows field measurement: doctor's four wiring-handshake checks all died `spawn npx ENOENT`
5
+ * on a target whose wiring was provably correct. Routing through cmd.exe is what the check's own
6
+ * purpose demands (it executes what the wiring file says), and no interpolation is added: tokens
7
+ * pass through byte-identical, quoted only when they carry whitespace (the measured
8
+ * space-in-username install path).
9
+ *
10
+ * PURE — platform arrives as an argument so every branch is testable off-Windows.
11
+ */
12
+ export declare function spawnSpecFor(command: string, args: string[], platform: NodeJS.Platform): {
13
+ command: string;
14
+ args: string[];
15
+ };
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.spawnSpecFor = spawnSpecFor;
4
+ // @implements A-SPEC-499.1
5
+ /**
6
+ * Platform adapter for spawning a WIRING command verbatim. On win32, `npx` is `npx.cmd`, and a
7
+ * plain child_process.spawn cannot execute a .cmd shim (Node's CVE-2024-27980 hardening) — the
8
+ * Windows field measurement: doctor's four wiring-handshake checks all died `spawn npx ENOENT`
9
+ * on a target whose wiring was provably correct. Routing through cmd.exe is what the check's own
10
+ * purpose demands (it executes what the wiring file says), and no interpolation is added: tokens
11
+ * pass through byte-identical, quoted only when they carry whitespace (the measured
12
+ * space-in-username install path).
13
+ *
14
+ * PURE — platform arrives as an argument so every branch is testable off-Windows.
15
+ */
16
+ function spawnSpecFor(command, args, platform) {
17
+ if (platform !== 'win32')
18
+ return { command, args: [...args] };
19
+ const joined = [command, ...args].map((t) => (/\s/.test(t) ? `"${t}"` : t)).join(' ');
20
+ return { command: 'cmd.exe', args: ['/d', '/s', '/c', joined] };
21
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "//": "@implements A-SPEC-209",
3
3
  "name": "@holmes-lab/holmes-kit",
4
- "version": "0.3.1",
4
+ "version": "0.3.3",
5
5
  "description": "Holmes-Kit — deterministic Agentic Software Engineering (ASE) harness with causal traceability (spec chain + D-CPG + RTM + phase guardrail)",
6
6
  "main": "dist/holmes/mcp/server.js",
7
7
  "types": "dist/holmes/mcp/server.d.ts",