@holmes-lab/holmes-kit 0.1.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 (107) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/LICENSE +21 -0
  3. package/README.md +102 -0
  4. package/bin/holmes-hook-antigravity.js +31 -0
  5. package/bin/holmes-kit.js +23 -0
  6. package/bin/holmes-mcp.js +34 -0
  7. package/bin/holmes-stop-antigravity.js +29 -0
  8. package/dist/.build-id +1 -0
  9. package/dist/holmes/cli/agents.js +168 -0
  10. package/dist/holmes/cli/doctor.js +625 -0
  11. package/dist/holmes/cli/gitignore-merge.js +84 -0
  12. package/dist/holmes/cli/governed-precondition.js +157 -0
  13. package/dist/holmes/cli/index.js +384 -0
  14. package/dist/holmes/cli/init.js +462 -0
  15. package/dist/holmes/cli/playbook-skills.js +711 -0
  16. package/dist/holmes/cli/roles-readme.js +134 -0
  17. package/dist/holmes/cli/settings-merge.js +122 -0
  18. package/dist/holmes/config/config.js +70 -0
  19. package/dist/holmes/context/bundler.js +114 -0
  20. package/dist/holmes/context/render.js +29 -0
  21. package/dist/holmes/context/tiers.js +110 -0
  22. package/dist/holmes/context/tokens.js +8 -0
  23. package/dist/holmes/cpg/cpg-scanner.js +213 -0
  24. package/dist/holmes/cpg/hash-cache.js +86 -0
  25. package/dist/holmes/cpg/language-parser-walk.js +917 -0
  26. package/dist/holmes/cpg/language-parser-worker.js +81 -0
  27. package/dist/holmes/cpg/language-parser.js +234 -0
  28. package/dist/holmes/cpg/scan-cache.js +108 -0
  29. package/dist/holmes/cpg/source-path.js +44 -0
  30. package/dist/holmes/cpg/test-files.js +84 -0
  31. package/dist/holmes/governance/constitution-debt.js +73 -0
  32. package/dist/holmes/governance/constitution-report.js +25 -0
  33. package/dist/holmes/governance/constitution.js +129 -0
  34. package/dist/holmes/governance/identity.js +30 -0
  35. package/dist/holmes/governance/ledger-lock.js +165 -0
  36. package/dist/holmes/governance/ledger-store.conformance.js +90 -0
  37. package/dist/holmes/governance/ledger-store.js +106 -0
  38. package/dist/holmes/governance/progress-ledger.js +83 -0
  39. package/dist/holmes/governance/provenance-chain.js +365 -0
  40. package/dist/holmes/governance/provenance-ledger.js +0 -0
  41. package/dist/holmes/governance/provenance-schema.js +47 -0
  42. package/dist/holmes/governance/replica-id.js +106 -0
  43. package/dist/holmes/governance/role-policy.js +137 -0
  44. package/dist/holmes/governance/trust-score.js +43 -0
  45. package/dist/holmes/guardrail/anchors.js +31 -0
  46. package/dist/holmes/guardrail/blind-spots.js +38 -0
  47. package/dist/holmes/guardrail/decision-ledger.js +107 -0
  48. package/dist/holmes/guardrail/executable-artifact.js +129 -0
  49. package/dist/holmes/guardrail/governance-history.js +101 -0
  50. package/dist/holmes/guardrail/phase.js +169 -0
  51. package/dist/holmes/guardrail/risk-classifier.js +450 -0
  52. package/dist/holmes/guardrail/risk-gate.js +160 -0
  53. package/dist/holmes/guardrail/risk-types.js +6 -0
  54. package/dist/holmes/guardrail/tspec-state.js +392 -0
  55. package/dist/holmes/guardrail/write-target.js +224 -0
  56. package/dist/holmes/hooks/adapters/antigravity.js +194 -0
  57. package/dist/holmes/hooks/pre-tool-use.js +1262 -0
  58. package/dist/holmes/hooks/stop.js +416 -0
  59. package/dist/holmes/mcp/basis.js +162 -0
  60. package/dist/holmes/mcp/handlers.js +1831 -0
  61. package/dist/holmes/mcp/server.js +71 -0
  62. package/dist/holmes/mcp/stdio-client.js +165 -0
  63. package/dist/holmes/mcp/supervisor.js +178 -0
  64. package/dist/holmes/mcp/tool-schemas.js +394 -0
  65. package/dist/holmes/mcp/validate-args.js +281 -0
  66. package/dist/holmes/messages/registry.js +50 -0
  67. package/dist/holmes/project/baseline.js +210 -0
  68. package/dist/holmes/project/change-source.js +233 -0
  69. package/dist/holmes/project/ignore.js +145 -0
  70. package/dist/holmes/project/root.js +113 -0
  71. package/dist/holmes/reverse/anchor.js +162 -0
  72. package/dist/holmes/reverse/cluster.js +187 -0
  73. package/dist/holmes/reverse/draft.js +151 -0
  74. package/dist/holmes/reverse/dynamic-wiring.js +47 -0
  75. package/dist/holmes/reverse/scan.js +194 -0
  76. package/dist/holmes/reverse/surface.js +154 -0
  77. package/dist/holmes/reverse/test-map.js +263 -0
  78. package/dist/holmes/review/coverage.js +33 -0
  79. package/dist/holmes/review/findings.js +123 -0
  80. package/dist/holmes/review/package.js +40 -0
  81. package/dist/holmes/review/review-targets.js +92 -0
  82. package/dist/holmes/review/scope.js +57 -0
  83. package/dist/holmes/review/test-evidence.js +77 -0
  84. package/dist/holmes/review/test-runner.js +572 -0
  85. package/dist/holmes/rtm/dataflow-taint.js +262 -0
  86. package/dist/holmes/rtm/gap-analyzer.js +27 -0
  87. package/dist/holmes/rtm/git-changes.js +72 -0
  88. package/dist/holmes/rtm/incremental.js +45 -0
  89. package/dist/holmes/rtm/localize.js +100 -0
  90. package/dist/holmes/rtm/rtm-builder.js +191 -0
  91. package/dist/holmes/rtm/rtm-check.js +89 -0
  92. package/dist/holmes/rtm/rtm-graph.js +232 -0
  93. package/dist/holmes/rtm/taint.js +92 -0
  94. package/dist/holmes/rtm/test-scope.js +336 -0
  95. package/dist/holmes/spec/approval-blockers.js +204 -0
  96. package/dist/holmes/spec/breaking-change.js +89 -0
  97. package/dist/holmes/spec/legacy-format.js +87 -0
  98. package/dist/holmes/spec/spec-digest.js +71 -0
  99. package/dist/holmes/spec/spec-parser.js +106 -0
  100. package/dist/holmes/spec/spec-store.conformance.js +118 -0
  101. package/dist/holmes/spec/spec-store.js +331 -0
  102. package/dist/holmes/spec/spec-types.js +177 -0
  103. package/dist/holmes/spec/validator.js +280 -0
  104. package/package.json +76 -0
  105. package/playbooks/adopt/PLAYBOOK.md +125 -0
  106. package/playbooks/author-slice/PLAYBOOK.md +119 -0
  107. package/playbooks/promote-slice/PLAYBOOK.md +134 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,22 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2026-08-18
9
+
10
+ ### Added
11
+ - **26 Atomic MCP Tools**: Full suite of MCP tools including `spec_create`, `spec_approve`, `spec_validate`, `spec_list`, `cpg_scan`, `taint_scan`, `rtm_impact`, `context_bundle`, `reverse_scan`, `reverse_draft`, `reverse_anchor`, and `issue_localize`.
12
+ - **Multilingual CPG & Taint Analysis**: Tree-sitter CPG parsers and dataflow reachability engines supporting 7 languages (TypeScript, Python, Java, Go, Rust, C++, C#).
13
+ - **No-Spec-No-Code Gating**: PreToolUse and Stop hooks enforcing strict specification chain (`REQ → H-SPEC → A-SPEC → T-SPEC → Code`) with cryptographic digests.
14
+ - **Centralized Message Registry**: 3-part structured English messages (`[Subsystem] Title — Technical Cause — Next Action`) via `src/holmes/messages/registry.ts`.
15
+ - **System Health Diagnostics**: Automated 8-point health check command (`holmes-kit doctor`).
16
+ - **Brownfield Adoption Toolchain**: Legacy code reverse-engineering and spec recovery via `holmes-adopt` playbook.
17
+
18
+ ### Security
19
+ - **Subprocess Secret Isolation (REQ-194)**: Forcibly scrub `HOLMES_APPROVAL` and `HOLMES_LEDGER_KEY` from all subshell and child process environments spawned by `run_command` and `execFileSync`.
20
+ - **Cryptographic Content Seals**: Cryptographic SHA-256 digest sealing for approved specifications and tamper-evident ledgers.
21
+ - **Adversarial Hardening (REQ-189 ~ REQ-193)**: Schema typo validation (`validate-args`), path traversal containment, and symlink wall protection against out-of-bounds file edits.
22
+ - **Internal Spec ID Masking (REQ-195)**: Mask internal harness Spec IDs in runtime refusal output while preserving target project Spec IDs.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Holmes-Kit
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,102 @@
1
+ # 🔍 Holmes-Kit
2
+
3
+ [![npm version](https://img.shields.io/npm/v/holmes-kit.svg)](https://www.npmjs.com/package/holmes-kit)
4
+ [![node version](https://img.shields.io/node/v/holmes-kit.svg)](https://nodejs.org)
5
+ [![license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
6
+
7
+ **Deterministic Agentic Software Engineering (ASE) harness with causal traceability.**
8
+
9
+ Holmes-Kit is not just a coding assistant — it is a **deterministic control plane** that governs how AI agents build software, so that every line of code is causally traceable back to a requirement, a design, and a decision ("who, when, why"). The governance is enforced in code (not prompts), so an agent cannot rationalize its way past it.
10
+
11
+ > Detective, not autocomplete: like Sherlock Holmes, the harness reasons from evidence — requirements → design → code → tests → decisions — over an exact causal graph, not probabilistic guesses.
12
+
13
+ ## Core Ideas
14
+
15
+ - **Deterministic control plane** — governance/traceability live in code; the LLM is advisory. Phase gating, RTM integrity, and impact analysis are exact queries, never approximations.
16
+ - **Governance spec chain** — `REQ → H-SPEC → A-SPEC → C-SPEC → T-SPEC`, plus a runtime `JOB` ledger. Code anchors to its A-SPEC via `@implements A-SPEC-NNN`.
17
+ - **Phase guardrail (block-and-redirect)** — the current SE phase is *derived from graph state*, not a mutable flag. Out-of-phase actions (e.g. writing code with no approved A-SPEC/T-SPEC) are blocked and the agent is redirected to the correct next step.
18
+ - **D-CPG + RTM** — tree-sitter Code Property Graph + SQLite RTM graph (recursive-CTE reachability). `rtm_impact` answers "which specs does changing this symbol affect?" — the core of causal traceability.
19
+ - **Hexagonal Ports & Adapters** — local Markdown today, enterprise adapters (DB/JIRA/Confluence) later, with no core rework.
20
+ - **Decision provenance** — architecture decisions are recorded as ADRs and linked into the graph.
21
+
22
+ ## Requirements & Prerequisites
23
+
24
+ - **Node.js**: `>= 20.0.0` (Enforced via `.npmrc`)
25
+ - **C++ Build Toolchain**: Xcode Command Line Tools (`xcode-select --install` on macOS) or `build-essential` / `g++` / `make` (Linux) for native `better-sqlite3` and `tree-sitter` C++ Addon compilation.
26
+
27
+ ## Installation & Setup
28
+
29
+ ### 1. Installation
30
+
31
+ #### Option A: Direct Git Release Installation (v0.1.1)
32
+
33
+ ```bash
34
+ # Global CLI install with allowed native C++ build scripts
35
+ npm install -g --allow-scripts=better-sqlite3,tree-sitter,tree-sitter-c-sharp,tree-sitter-cpp,tree-sitter-go,tree-sitter-java,tree-sitter-python,tree-sitter-rust,tree-sitter-typescript \
36
+ "git+https://github.com/snpark-io/holmes-kit.git#v0.1.1"
37
+
38
+ # Verify installation health
39
+ holmes-kit doctor
40
+ ```
41
+
42
+ #### Option B: Clean 1-Line Installation via NPM Registry
43
+
44
+ ```bash
45
+ # Once published to npm registry:
46
+ npm install -g holmes-kit
47
+
48
+ # Verify health
49
+ holmes-kit doctor
50
+ ```
51
+
52
+ ### 2. Project Initialization
53
+
54
+ ```bash
55
+ cd /path/to/your/project
56
+ holmes-kit init --dry-run # Preview configuration without writing
57
+ holmes-kit init # Wire Holmes-Kit hooks into target project
58
+ ```
59
+
60
+ ### 3. MCP Integration
61
+
62
+ Add Holmes-Kit as an MCP server in your editor or agent environment (`.mcp.json`):
63
+
64
+ ```json
65
+ {
66
+ "mcpServers": {
67
+ "holmes-kit": {
68
+ "command": "npx",
69
+ "args": ["-y", "holmes-mcp"]
70
+ }
71
+ }
72
+ }
73
+ ```
74
+
75
+ ### 4. Environment Variables (Optional)
76
+
77
+ ```bash
78
+ cp .env.example .env
79
+ # Edit .env and fill in your values
80
+ ```
81
+
82
+ ## Status
83
+
84
+ Under active development on branch `feat/holmes-kit-ase-design`.
85
+
86
+ - **v0.1** — spec standard + MCP guardrail (spec validation, `rtm_check`, phase guardrail, MCP server, hook).
87
+ - **v0.2** — D-CPG + RTM traceability (tree-sitter symbols/edges, CPG scanner, RTM graph, change-impact, MCP `cpg_scan`/`rtm_impact`). Dogfooded on Holmes-Kit's own source.
88
+
89
+ Target architecture and design records live in [`docs/architecture/`](docs/architecture/) and decisions in [`.ax/decisions/`](.ax/decisions/).
90
+
91
+ ## Build & Test
92
+
93
+ ```bash
94
+ npm install
95
+ npm run typecheck # TypeScript static type check
96
+ npm run build # tsc → dist/holmes/**
97
+ npm test # jest full test suite
98
+ ```
99
+
100
+ ## License
101
+
102
+ MIT
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env node
2
+ // @implements A-SPEC-193
3
+ // Antigravity PreToolUse 진입점 — 번역만 한다. 판정은 dist 의 훅 프로그램이 내린다.
4
+ //
5
+ // 가드는 require 앞에서 Node 내장만으로 돈다(bin/holmes-kit.js 와 같은 이유). 그리고 가드가
6
+ // 걸렸을 때 **열지 않는다**: 게이트를 세우라고 배선해 둔 훅이 실행되지 못했다면 그것은 허용이
7
+ // 아니라 거부다 — 조용히 여는 것이 이 저장소가 반복해서 고쳐 온 실패 유형이다.
8
+ const fs = require('node:fs');
9
+ const path = require('node:path');
10
+
11
+ const deny = (reason) => {
12
+ process.stdout.write(JSON.stringify({ decision: 'deny', reason }));
13
+ process.exit(0);
14
+ };
15
+
16
+ const entry = path.join(__dirname, '..', 'dist', 'holmes', 'hooks', 'adapters', 'antigravity.js');
17
+ if (!fs.existsSync(entry)) {
18
+ deny(`[Holmes-Kit] 빌드 산출물이 없습니다: ${entry} — 게이트를 세울 수 없어 허용하지 않습니다.`
19
+ + ' 저장소에서 쓰는 중이라면 `npm run build`, 설치본이라면 재설치하십시오.');
20
+ }
21
+
22
+ let buf = '';
23
+ process.stdin.on('data', (c) => { buf += c; });
24
+ process.stdin.on('end', () => {
25
+ try {
26
+ const { adaptPreToolUse } = require(entry);
27
+ process.stdout.write(JSON.stringify(adaptPreToolUse(buf, process.cwd())));
28
+ } catch (e) {
29
+ deny(`[Holmes-Kit] 게이트를 실행하지 못했습니다: ${e && e.message ? e.message : String(e)}`);
30
+ }
31
+ });
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ // @implements A-SPEC-100.2
3
+ // @implements A-SPEC-173
4
+ // The guard runs BEFORE the require, using only Node built-ins. `runInit` carries the same guidance
5
+ // but lives inside `dist` — measured 2026-08-12, a package whose `prepare` was blocked emitted
6
+ // `node:internal/modules/cjs/loader` from every entry point and that guidance never ran.
7
+ const fs = require('node:fs');
8
+ const path = require('node:path');
9
+
10
+ const entry = path.join(__dirname, '..', 'dist', 'holmes', 'cli', 'index.js');
11
+ if (!fs.existsSync(entry)) {
12
+ process.stderr.write(
13
+ `holmes-kit is not built: ${entry} is missing.\n`
14
+ + 'The package ships compiled output via its `prepare` script, which npm may have blocked.\n'
15
+ + 'Check `npm config get ignore-scripts` and `npm config get omit`, then reinstall.\n'
16
+ + 'Native dependencies need `npm i <pkg> --allow-scripts` on npm 11+.\n');
17
+ process.exit(1);
18
+ }
19
+
20
+ require('../dist/holmes/cli/index.js')
21
+ .main(process.argv.slice(2))
22
+ .then((code) => process.exit(code))
23
+ .catch((err) => { process.stderr.write(`${err && err.stack ? err.stack : err}\n`); process.exit(1); });
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env node
2
+ // @implements A-SPEC-162
3
+ // @implements A-SPEC-173
4
+ // The guard runs BEFORE the require, using only Node built-ins — see bin/holmes-kit.js. The wording
5
+ // is duplicated rather than shared: reading it from `dist` is exactly the dependency that fails here.
6
+ // `bin-guard.test.ts` pins the two copies to each other so they cannot drift.
7
+ const fs = require('node:fs');
8
+ const path = require('node:path');
9
+
10
+ const entry = path.join(__dirname, '..', 'dist', 'holmes', 'mcp', 'supervisor.js');
11
+ if (!fs.existsSync(entry)) {
12
+ // stderr, never stdout: stdout is the JSON-RPC channel and a diagnostic written there would be
13
+ // read as a malformed protocol message rather than as advice.
14
+ process.stderr.write(
15
+ `holmes-kit is not built: ${entry} is missing.\n`
16
+ + 'The package ships compiled output via its `prepare` script, which npm may have blocked.\n'
17
+ + 'Check `npm config get ignore-scripts` and `npm config get omit`, then reinstall.\n'
18
+ + 'Native dependencies need `npm i <pkg> --allow-scripts` on npm 11+.\n');
19
+ process.exit(1);
20
+ }
21
+
22
+ // Opt-in only. Without HOLMES_MCP_AUTORELOAD this is the same direct require it has always been —
23
+ // swapping the implementation under a shipped user mid-session would be an undeclared change in gate
24
+ // behaviour, which ADR-013 forbids.
25
+ const { AUTORELOAD_ENV, autoreloadEnabled, Supervisor } = require('../dist/holmes/mcp/supervisor.js');
26
+
27
+ if (autoreloadEnabled(process.env)) {
28
+ const sup = new Supervisor(path.resolve(__dirname, '..'), (from, to, replayed) =>
29
+ process.stderr.write(`[Holmes-Kit] MCP 서버 구현을 교체했습니다: ${from} → ${to} (replayed=${replayed})\n`));
30
+ sup.start(process.stdin, process.stdout);
31
+ process.on('exit', () => sup.stop());
32
+ } else {
33
+ require('../dist/holmes/mcp/server.js');
34
+ }
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+ // @implements A-SPEC-193
3
+ // Antigravity Stop 진입점 — 번역만 한다. 판정은 dist 의 Stop 훅이 내린다.
4
+ //
5
+ // PreToolUse 와 달리 여기서는 실패가 **열어 준다**. Stop 훅은 이미 fail-open 계약이다: 턴을
6
+ // 죽이지 않는다. 정지를 막지 못하는 것은 규율의 손실이고, 정지를 막아 놓고 이유를 대지 못하는
7
+ // 것은 사용자를 가두는 것이다 — 둘 중 후자가 더 나쁘다.
8
+ const fs = require('node:fs');
9
+ const path = require('node:path');
10
+
11
+ const pass = () => { process.stdout.write('{}'); process.exit(0); };
12
+
13
+ const entry = path.join(__dirname, '..', 'dist', 'holmes', 'hooks', 'adapters', 'antigravity.js');
14
+ if (!fs.existsSync(entry)) {
15
+ process.stderr.write(`[Holmes-Kit] 빌드 산출물이 없습니다: ${entry}\n`);
16
+ pass();
17
+ }
18
+
19
+ let buf = '';
20
+ process.stdin.on('data', (c) => { buf += c; });
21
+ process.stdin.on('end', () => {
22
+ try {
23
+ const { adaptStop } = require(entry);
24
+ process.stdout.write(JSON.stringify(adaptStop(buf, process.cwd())));
25
+ } catch (e) {
26
+ process.stderr.write(`[Holmes-Kit] Stop 게이트를 실행하지 못했습니다: ${e && e.message ? e.message : String(e)}\n`);
27
+ pass();
28
+ }
29
+ });
package/dist/.build-id ADDED
@@ -0,0 +1 @@
1
+ e26507b-msxetwff
@@ -0,0 +1,168 @@
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.HARNESS_ENFORCES = exports.AGENTS = void 0;
37
+ exports.agentFiles = agentFiles;
38
+ exports.agentLinks = agentLinks;
39
+ // @implements A-SPEC-193
40
+ const path = __importStar(require("node:path"));
41
+ /**
42
+ * 하네스별 배선물.
43
+ *
44
+ * Holmes-Kit 의 명제("승인된 스펙 없이는 코드가 들어가지 않는다")를 **집행**하는 것은 MCP
45
+ * 도구가 아니라 훅이다. 그래서 하네스마다 물어야 할 첫 질문은 "이 도구에 훅이 있는가"이고,
46
+ * 없다면 **집행한다고 말하지 않는 것**이 이 파일의 일이다. 도구는 주되 규율은 못 세우면서
47
+ * 세운다고 적으면, 그 문장을 믿은 사용자가 지켜지지 않는 게이트 위에서 일한다.
48
+ */
49
+ exports.AGENTS = ['claude', 'antigravity', 'codex'];
50
+ /**
51
+ * 그 하네스에서 게이트가 **집행되는가**.
52
+ *
53
+ * - `claude` — PreToolUse/Stop 훅. 이 저장소가 처음부터 배선해 온 하네스.
54
+ * - `antigravity` — PreToolUse/Stop 훅이 있고 `deny`/`continue` 로 막을 수 있다(설치본의
55
+ * `agy-customizations` 규약 문서와 실제 대화 기록에서 실측).
56
+ * - `codex` — 이 기계에 설치되어 있지 않아 훅 규약을 **재지 못했다**. 재지 못한 것을 있다고
57
+ * 적지 않는다. 도구(MCP)와 지침만 준다.
58
+ */
59
+ exports.HARNESS_ENFORCES = {
60
+ claude: true,
61
+ antigravity: true,
62
+ codex: false,
63
+ };
64
+ const q = (p) => p;
65
+ const mcpConfig = (packageRoot, specsDir) => `${JSON.stringify({
66
+ mcpServers: {
67
+ 'holmes-kit': {
68
+ command: 'node',
69
+ args: [q(path.join(packageRoot, 'bin', 'holmes-mcp.js'))],
70
+ env: { HOLMES_SPECS: specsDir },
71
+ },
72
+ },
73
+ }, null, 2)}\n`;
74
+ /**
75
+ * Antigravity 훅 배선.
76
+ *
77
+ * 매처는 `*` 다. 좁히면 그 밖의 도구가 게이트를 지나가고, Antigravity 의 도구 목록은 우리가
78
+ * 통제하지 않는다 — 이름을 열거하는 순간 다음에 추가되는 도구가 무료 통행권을 얻는다.
79
+ * (Claude 배선이 `guardrail` 모드에서 좁은 매처를 쓰는 것과 다른 선택인데, 그쪽은 그 좁힘이
80
+ * 무엇을 뜻하는지 문서화된 모드 선택이고 여기는 기본 배선이기 때문이다.)
81
+ */
82
+ const hooksJson = (packageRoot) => `${JSON.stringify({
83
+ 'holmes-kit': {
84
+ PreToolUse: [{
85
+ matcher: '*',
86
+ hooks: [{
87
+ type: 'command',
88
+ command: `node ${path.join(packageRoot, 'bin', 'holmes-hook-antigravity.js')}`,
89
+ timeout: 30,
90
+ }],
91
+ }],
92
+ Stop: [{
93
+ type: 'command',
94
+ command: `node ${path.join(packageRoot, 'bin', 'holmes-stop-antigravity.js')}`,
95
+ timeout: 30,
96
+ }],
97
+ },
98
+ }, null, 2)}\n`;
99
+ const AGENTS_MD = (enforced) => `# Holmes-Kit — 이 저장소의 작업 규율
100
+
101
+ 이 저장소는 **No Spec, No Code** 로 운영된다. 코드를 쓰기 전에 승인된 스펙이 있어야 한다.
102
+
103
+ ## 절차
104
+
105
+ 1. \`spec_create\` 로 REQ → H-SPEC → A-SPEC 을 쓰고 \`spec_approve\` 로 승인한다.
106
+ 2. **테스트를 먼저** 쓰고 실패(RED)를 확인한다.
107
+ 3. T-SPEC 을 승인한다(거울 규약: \`A-SPEC-188\` → \`T-SPEC-188\`).
108
+ 4. 그 다음에 구현한다.
109
+
110
+ \`spec_next\` 가 다음에 할 일을 말해 준다. \`phase_check\` 로 지금 하려는 행동이 허용되는지
111
+ 미리 물을 수 있다.
112
+
113
+ ## 이 하네스에서의 집행
114
+
115
+ ${enforced
116
+ ? `게이트가 **집행된다**. 승인된 스펙 없이 코드를 쓰려 하면 도구 호출이 거부되고, 해소되지
117
+ 않은 치명 발견이 있으면 턴이 끝나지 않는다. 거부 문면이 다음에 무엇을 하면 되는지 말한다.`
118
+ : `이 하네스에는 우리가 실측한 **훅 집행 지점이 없다**. 그래서 Holmes-Kit 은 여기서 도구와
119
+ 지침만 제공하고 **게이트를 집행하지 않는다** — 규율은 조언으로만 선다. 집행이 필요하면 Claude
120
+ Code 나 Antigravity 하네스에서 작업하라. (이 문장은 우리가 그 도구의 훅 규약을 재지 못했다는
121
+ 사실의 기록이지, 그 도구에 훅이 없다는 단정이 아니다.)`}
122
+ `;
123
+ /**
124
+ * 이 하네스에 써야 할 파일들. **쓰지는 않는다** — 무엇을 쓸지만 말한다.
125
+ *
126
+ * 계산과 쓰기를 나누는 이유는 dry-run 이 실제 실행과 같은 집합을 예고해야 하기 때문이다
127
+ * (A-SPEC-190 §9). 같은 함수가 두 경로에 답하면 둘이 어긋날 수 없다.
128
+ */
129
+ function agentFiles(agent, opts) {
130
+ const { target, packageRoot, specsDir } = opts;
131
+ switch (agent) {
132
+ case 'claude':
133
+ // Claude 배선은 init 이 이미 쓴다(settings*, .mcp.json, .claude/skills) — 여기서 겹쳐
134
+ // 쓰면 그것이 두 번째 진실이 된다.
135
+ return [];
136
+ case 'antigravity':
137
+ return [
138
+ { path: path.join(target, '.agents', 'hooks.json'), content: hooksJson(packageRoot) },
139
+ { path: path.join(target, '.agents', 'mcp_config.json'), content: mcpConfig(packageRoot, specsDir) },
140
+ { path: path.join(target, 'AGENTS.md'), content: AGENTS_MD(exports.HARNESS_ENFORCES.antigravity) },
141
+ ];
142
+ case 'codex':
143
+ return [
144
+ { path: path.join(target, '.codex', 'mcp_config.json'), content: mcpConfig(packageRoot, specsDir) },
145
+ { path: path.join(target, 'AGENTS.md'), content: AGENTS_MD(exports.HARNESS_ENFORCES.codex) },
146
+ ];
147
+ default:
148
+ // 모르는 하네스를 조용히 건너뛰면 "배선했다"는 보고와 실제가 어긋난다.
149
+ throw new Error(`알 수 없는 하네스: ${String(agent)} — 아는 것: ${exports.AGENTS.join(', ')}`);
150
+ }
151
+ }
152
+ /**
153
+ * 하네스가 스킬을 **볼 수 있게** 하는 링크.
154
+ *
155
+ * 스킬 본문은 한 곳(`.claude/skills`)에만 둔다 — 같은 내용을 두 벌 두면 하나가 갱신될 때
156
+ * 다른 하나가 낡고, doctor 는 한쪽만 본다(그 드리프트가 REQ-190 의 출발점이었다). 그래서
157
+ * Antigravity 쪽은 링크로 같은 파일을 가리킨다. 이 배치는 타깃 안에 머물므로 설치 담장을
158
+ * 지나간다(A-SPEC-193 §7 이 그 담장을 '타깃 밖만'으로 좁힌 이유이기도 하다).
159
+ */
160
+ function agentLinks(agent, opts) {
161
+ if (agent !== 'antigravity')
162
+ return [];
163
+ return [{
164
+ path: path.join(opts.target, '.agents', 'skills'),
165
+ target: path.join('..', '.claude', 'skills'),
166
+ why: '스킬 본문은 .claude/skills 한 곳에 둔다 — 두 벌이면 하나가 낡는다',
167
+ }];
168
+ }