@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 +33 -0
- package/README.md +17 -5
- package/dist/.build-id +1 -1
- package/dist/holmes/cli/doctor.d.ts +7 -0
- package/dist/holmes/cli/doctor.js +18 -4
- package/dist/holmes/cli/spawn-spec.d.ts +15 -0
- package/dist/holmes/cli/spawn-spec.js +21 -0
- package/package.json +1 -1
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.
|
|
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
|
-
-
|
|
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/
|
|
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/
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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}`,
|
|
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}`,
|
|
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.
|
|
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",
|