@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.
- package/CHANGELOG.md +22 -0
- package/LICENSE +21 -0
- package/README.md +102 -0
- package/bin/holmes-hook-antigravity.js +31 -0
- package/bin/holmes-kit.js +23 -0
- package/bin/holmes-mcp.js +34 -0
- package/bin/holmes-stop-antigravity.js +29 -0
- package/dist/.build-id +1 -0
- package/dist/holmes/cli/agents.js +168 -0
- package/dist/holmes/cli/doctor.js +625 -0
- package/dist/holmes/cli/gitignore-merge.js +84 -0
- package/dist/holmes/cli/governed-precondition.js +157 -0
- package/dist/holmes/cli/index.js +384 -0
- package/dist/holmes/cli/init.js +462 -0
- package/dist/holmes/cli/playbook-skills.js +711 -0
- package/dist/holmes/cli/roles-readme.js +134 -0
- package/dist/holmes/cli/settings-merge.js +122 -0
- package/dist/holmes/config/config.js +70 -0
- package/dist/holmes/context/bundler.js +114 -0
- package/dist/holmes/context/render.js +29 -0
- package/dist/holmes/context/tiers.js +110 -0
- package/dist/holmes/context/tokens.js +8 -0
- package/dist/holmes/cpg/cpg-scanner.js +213 -0
- package/dist/holmes/cpg/hash-cache.js +86 -0
- package/dist/holmes/cpg/language-parser-walk.js +917 -0
- package/dist/holmes/cpg/language-parser-worker.js +81 -0
- package/dist/holmes/cpg/language-parser.js +234 -0
- package/dist/holmes/cpg/scan-cache.js +108 -0
- package/dist/holmes/cpg/source-path.js +44 -0
- package/dist/holmes/cpg/test-files.js +84 -0
- package/dist/holmes/governance/constitution-debt.js +73 -0
- package/dist/holmes/governance/constitution-report.js +25 -0
- package/dist/holmes/governance/constitution.js +129 -0
- package/dist/holmes/governance/identity.js +30 -0
- package/dist/holmes/governance/ledger-lock.js +165 -0
- package/dist/holmes/governance/ledger-store.conformance.js +90 -0
- package/dist/holmes/governance/ledger-store.js +106 -0
- package/dist/holmes/governance/progress-ledger.js +83 -0
- package/dist/holmes/governance/provenance-chain.js +365 -0
- package/dist/holmes/governance/provenance-ledger.js +0 -0
- package/dist/holmes/governance/provenance-schema.js +47 -0
- package/dist/holmes/governance/replica-id.js +106 -0
- package/dist/holmes/governance/role-policy.js +137 -0
- package/dist/holmes/governance/trust-score.js +43 -0
- package/dist/holmes/guardrail/anchors.js +31 -0
- package/dist/holmes/guardrail/blind-spots.js +38 -0
- package/dist/holmes/guardrail/decision-ledger.js +107 -0
- package/dist/holmes/guardrail/executable-artifact.js +129 -0
- package/dist/holmes/guardrail/governance-history.js +101 -0
- package/dist/holmes/guardrail/phase.js +169 -0
- package/dist/holmes/guardrail/risk-classifier.js +450 -0
- package/dist/holmes/guardrail/risk-gate.js +160 -0
- package/dist/holmes/guardrail/risk-types.js +6 -0
- package/dist/holmes/guardrail/tspec-state.js +392 -0
- package/dist/holmes/guardrail/write-target.js +224 -0
- package/dist/holmes/hooks/adapters/antigravity.js +194 -0
- package/dist/holmes/hooks/pre-tool-use.js +1262 -0
- package/dist/holmes/hooks/stop.js +416 -0
- package/dist/holmes/mcp/basis.js +162 -0
- package/dist/holmes/mcp/handlers.js +1831 -0
- package/dist/holmes/mcp/server.js +71 -0
- package/dist/holmes/mcp/stdio-client.js +165 -0
- package/dist/holmes/mcp/supervisor.js +178 -0
- package/dist/holmes/mcp/tool-schemas.js +394 -0
- package/dist/holmes/mcp/validate-args.js +281 -0
- package/dist/holmes/messages/registry.js +50 -0
- package/dist/holmes/project/baseline.js +210 -0
- package/dist/holmes/project/change-source.js +233 -0
- package/dist/holmes/project/ignore.js +145 -0
- package/dist/holmes/project/root.js +113 -0
- package/dist/holmes/reverse/anchor.js +162 -0
- package/dist/holmes/reverse/cluster.js +187 -0
- package/dist/holmes/reverse/draft.js +151 -0
- package/dist/holmes/reverse/dynamic-wiring.js +47 -0
- package/dist/holmes/reverse/scan.js +194 -0
- package/dist/holmes/reverse/surface.js +154 -0
- package/dist/holmes/reverse/test-map.js +263 -0
- package/dist/holmes/review/coverage.js +33 -0
- package/dist/holmes/review/findings.js +123 -0
- package/dist/holmes/review/package.js +40 -0
- package/dist/holmes/review/review-targets.js +92 -0
- package/dist/holmes/review/scope.js +57 -0
- package/dist/holmes/review/test-evidence.js +77 -0
- package/dist/holmes/review/test-runner.js +572 -0
- package/dist/holmes/rtm/dataflow-taint.js +262 -0
- package/dist/holmes/rtm/gap-analyzer.js +27 -0
- package/dist/holmes/rtm/git-changes.js +72 -0
- package/dist/holmes/rtm/incremental.js +45 -0
- package/dist/holmes/rtm/localize.js +100 -0
- package/dist/holmes/rtm/rtm-builder.js +191 -0
- package/dist/holmes/rtm/rtm-check.js +89 -0
- package/dist/holmes/rtm/rtm-graph.js +232 -0
- package/dist/holmes/rtm/taint.js +92 -0
- package/dist/holmes/rtm/test-scope.js +336 -0
- package/dist/holmes/spec/approval-blockers.js +204 -0
- package/dist/holmes/spec/breaking-change.js +89 -0
- package/dist/holmes/spec/legacy-format.js +87 -0
- package/dist/holmes/spec/spec-digest.js +71 -0
- package/dist/holmes/spec/spec-parser.js +106 -0
- package/dist/holmes/spec/spec-store.conformance.js +118 -0
- package/dist/holmes/spec/spec-store.js +331 -0
- package/dist/holmes/spec/spec-types.js +177 -0
- package/dist/holmes/spec/validator.js +280 -0
- package/package.json +76 -0
- package/playbooks/adopt/PLAYBOOK.md +125 -0
- package/playbooks/author-slice/PLAYBOOK.md +119 -0
- package/playbooks/promote-slice/PLAYBOOK.md +134 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: holmes-promote-slice
|
|
3
|
+
description: >-
|
|
4
|
+
Use when a Holmes-Kit gate denies with "approved H-SPEC이 없습니다", "approved A-SPEC이 없습니다",
|
|
5
|
+
"구현 대상 A-SPEC(...)이 approved가 아닙니다", or "…를 depends_on에 담은 T-SPEC이 없습니다(테스트 먼저)" —
|
|
6
|
+
the spec already exists but its status still blocks the next action, or an approved T-SPEC leaves
|
|
7
|
+
the code gate shut.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# promote-slice
|
|
11
|
+
|
|
12
|
+
승인은 **내용을 봉인하는 행위**다. `spec_approve`가 그 행위를 수행한다 — 검증 → 본문 다이제스트
|
|
13
|
+
계산 → `status: approved` + `approved_digest` + 부모 봉인 스냅샷 기록 → 원장 append를 한 번에.
|
|
14
|
+
손으로 `status:`만 바꾸는 것으로는 부족하다: 봉인 없이 approved가 된 스펙은 `unsealed-approval`로
|
|
15
|
+
검증에 걸리고, 봉인 후 본문을 고치면 `post-approval-edit`으로, 부모가 움직이면 `stale-parent`로
|
|
16
|
+
걸린다(REQ-132). `spec_approve`는 **서버 환경의** 유효한 `HOLMES_APPROVAL`을 요구한다(fail-closed) —
|
|
17
|
+
요청 인자로는 대체되지 않는다.
|
|
18
|
+
|
|
19
|
+
이 플레이북은 그 승인을 **언제·무엇에·어떤 근거로** 하는지를 다룬다. 문서를 새로 쓰는 일이라면
|
|
20
|
+
이것이 아니라 `author-slice`다 — 판별은 3단계에 있다.
|
|
21
|
+
|
|
22
|
+
## 게이트가 실제로 요구하는 것
|
|
23
|
+
|
|
24
|
+
`phaseCheck`의 조건은 동작마다 다르고, 그 차이가 이 플레이북의 전부다.
|
|
25
|
+
|
|
26
|
+
| 하려는 동작 | 요구 조건 | 비직관적인 점 |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| H-SPEC 작성 | REQ가 **존재**만 하면 됨 | `draft` REQ로 충분하다. 승인이 불필요한 유일한 칸 |
|
|
29
|
+
| A-SPEC 작성 | approved H-SPEC **아무거나 하나** | 지금 쓰는 A-SPEC의 부모일 필요가 없다 |
|
|
30
|
+
| C-SPEC / T-SPEC 작성 | approved A-SPEC **아무거나 하나** | 대상 A-SPEC이 draft여도 T-SPEC은 쓸 수 있다 |
|
|
31
|
+
| 테스트 작성 | **대상** A-SPEC이 approved | 여기서 "아무거나"가 "바로 그것"으로 바뀐다 |
|
|
32
|
+
| 코드 작성 | 대상 A-SPEC approved **+** 그것을 `depends_on` 하는 approved T-SPEC | 유일한 2조건 게이트 |
|
|
33
|
+
|
|
34
|
+
위 세 줄은 **파이프라인이 열렸는가**를 묻는다 — 아무 승인 하나가 그 칸을 연다. 아래 두 줄은
|
|
35
|
+
**이 슬라이스가 준비됐는가**를 묻는다 — 대상으로 지정된 바로 그 문서여야 한다. 승인 하나로 여러
|
|
36
|
+
칸이 동시에 열리는 것은 위쪽에서만 일어나는 일이다.
|
|
37
|
+
|
|
38
|
+
## 절차
|
|
39
|
+
|
|
40
|
+
1. **무엇이 막혔는지 deny에서 읽는다.** `phase` 필드는 지금 있는 곳이 아니라 **되돌아가야 할 곳**을
|
|
41
|
+
가리킨다(`WRITE_CODE` 거부 → `TEST-SPEC`). `missing`은 결핍의 *종류*까지만 말하고 그 이상은
|
|
42
|
+
말하지 않는다 — 두 개의 서로 다른 실패가 같은 `missing`을 낸다. 「T-SPEC 거부는 상태를 구별해 말한다」를 함께 읽는다.
|
|
43
|
+
2. **대상을 특정한다.** `구현 대상 A-SPEC(미지정)` 이 나왔다면 스펙이 아니라 호출이 문제다 —
|
|
44
|
+
`targetAspecId`를 넘기지 않은 것이고, 승인할 것은 없다.
|
|
45
|
+
3. **그 스펙이 존재하는가.** `spec_list`로 확인한다. 없으면 이것은 승격이 아니라 저작이다 →
|
|
46
|
+
`author-slice`. 있으면 계속한다.
|
|
47
|
+
4. **검증을 확인한다 — 부르는 게 아니라 받는 것이다.** `spec_validate`는 기본 프로파일에서
|
|
48
|
+
**광고되지 않는다**. `phase_check` · `risk_check` · `rtm_check`와 함께 훅이 push로 강제하는
|
|
49
|
+
집합(`HOOK_ENFORCED_TOOLS`)이라 도구 목록에서 빠져 있고, 이름으로는 여전히 호출 가능하지만
|
|
50
|
+
스키마가 없어 실질적으로 부를 수 없다. 명시적 호출이 필요하면 `HOLMES_MCP_PROFILE=full`이다.
|
|
51
|
+
보통은 Stop 훅이 dangling parent와 결측 필드를 잡아 주므로, 확인할 것은 **직전 턴이 조용했는가**다.
|
|
52
|
+
깨진 채로 승인하면 게이트는 통과하고 그래프만 깨진 상태로 남는다.
|
|
53
|
+
5. **승인 바(bar)를 대고 판단한다.** 아래 「승인의 기준」. 못 넘으면 먼저 문서를 보완한다 — 보완
|
|
54
|
+
후 6으로 돌아온다.
|
|
55
|
+
6. **`spec_approve(id)`로 봉인-승인한다.** 이 도구가 검증·다이제스트·status 전이·원장 기록을
|
|
56
|
+
한 행위로 묶는다. **`root`는 생략해도 된다**(REQ-188) — 원장 위치는 서버가 바인딩된 스토어에서
|
|
57
|
+
파생되며, 명시하면 같은 프로젝트인지 확인되고 다르면 봉인 전에 거부된다. 과거에는 root를
|
|
58
|
+
빼면 봉인만 서고 원장 기록이 누락됐는데(REQ-182 체인 4건이 실제로 겪음), 이제 그 경로는
|
|
59
|
+
구조적으로 없다: 원장 목적지를 확정할 수 없으면 봉인도 서지 않는다. 승인 진행 중 문서가
|
|
60
|
+
바뀌면 편집이 이기고 승인이 거부된다 — 다시 읽고 다시 승인하면 된다. 부모부터 승인한다 —
|
|
61
|
+
봉인 안 된 approved 부모가 있으면 도구가 그 부모를 지목하며 거부한다. `status:`만 손으로
|
|
62
|
+
바꾸면 봉인이 없어 `unsealed-approval`로 되돌아온다.
|
|
63
|
+
|
|
64
|
+
승인이 거부하는 것(REQ-182 이후 게이트도 같은 사실을 미리 말한다):
|
|
65
|
+
- 부모가 draft이거나, 승인됐지만 봉인이 없다
|
|
66
|
+
- `breaking_change`가 없거나 등급이 허용값 밖이다(A-SPEC)
|
|
67
|
+
- **절이 생성기 자리표시자 그대로다** — `spec_create`의 맨 `TODO`이든 `reverse_draft`의
|
|
68
|
+
`TODO — …` + inferred 주석이든. 거부 문면이 어느 절인지 지목하므로 그 절만 채우면 된다.
|
|
69
|
+
7. **같은 동작을 다시 시도한다.** 여전히 막히면 거부 문면을 그대로 읽는다 — 어느 상황인지 게이트가 말한다.
|
|
70
|
+
|
|
71
|
+
## T-SPEC 거부는 상태를 구별해 말한다
|
|
72
|
+
|
|
73
|
+
`WRITE_CODE`가 T-SPEC 때문에 막히면 문면이 **어느 상황인지** 알려준다. 두 갈래이고 조치가 다르다.
|
|
74
|
+
|
|
75
|
+
| 문면이 이렇게 시작하면 | 상황 | 할 일 |
|
|
76
|
+
|---|---|---|
|
|
77
|
+
| `A-SPEC …를 depends_on에 담은 T-SPEC이 없습니다(테스트 먼저).` | 간선이 없다 — 아직 안 썼거나, 썼는데 안 걸었다 | 문면이 두 조치를 모두 말한다: 작성·승인하거나, 기존 T-SPEC의 `depends_on`에 추가 |
|
|
78
|
+
| `T-SPEC …가 A-SPEC …를 시험한다고 선언했으나 approved가 아닙니다.` | 간선은 있고 승인이 없다 | 그 T-SPEC을 승인. 문면에 **왜 승인이 안 되는지**가 함께 온다 |
|
|
79
|
+
|
|
80
|
+
게이트는 "아직 안 썼다"와 "썼는데 간선이 없다"를 **구별할 수 없다** — 그건 저자만 아는 사실이다.
|
|
81
|
+
그래서 한 문면이 두 조치를 모두 제시한다. 다만 **A-SPEC 간선이 하나도 없는 T-SPEC**이 있으면
|
|
82
|
+
그것만은 이름과 현재 `depends_on`으로 지목한다. 정상 저장소에 그런 문서는 없으므로(실측 73개 중 0),
|
|
83
|
+
있다는 것은 방금 쓴 그 문서라는 뜻이다.
|
|
84
|
+
|
|
85
|
+
```yaml
|
|
86
|
+
# A-SPEC-129를 대상으로 코드를 쓰려면
|
|
87
|
+
depends_on:
|
|
88
|
+
- A-SPEC-129 # 이 줄이 없으면 approved여도 게이트는 닫힌 채다
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
이전에는 세 상황이 글자 하나 다르지 않은 한 문장을 냈고, 이 절이 그 구별을 사람에게 대신
|
|
92
|
+
설명했다. 이제 게이트가 말하므로 문서가 대신할 일이 없다(REQ-183).
|
|
93
|
+
|
|
94
|
+
## 승인의 기준
|
|
95
|
+
|
|
96
|
+
승인은 완벽함이 아니라 **다음 층이 이 문서를 근거로 삼을 수 있는가**다.
|
|
97
|
+
|
|
98
|
+
- **REQ** — Problem / Desired Outcome / Constraints / Success Criteria / Out of Scope가 채워지고,
|
|
99
|
+
`source:`가 실재하는 것을 가리킨다. 대화에서 나온 지시는 `kind: conversation`으로, 문서가 없으면
|
|
100
|
+
없다고 적는다.
|
|
101
|
+
- **H-SPEC** — 부모 REQ의 Success Criteria가 이 설계로 어떻게 달성되는지가 추적된다.
|
|
102
|
+
- **A-SPEC** — Test Points가 검증 가능한 문장이고, Files to Touch가 실제 경로이며, Done When이
|
|
103
|
+
관측 가능하다. "잘 동작한다"는 Test Point가 아니다.
|
|
104
|
+
- **T-SPEC** — 4분면(normal / negative / corner / boundary)이 모두 있고, `depends_on`이 대상
|
|
105
|
+
A-SPEC을 가리킨다.
|
|
106
|
+
|
|
107
|
+
승인 후에 발견된 것은 **새 리비전**이지 승인 취소가 아니다. 되돌리는 비용이 승인을 미루게 만들면,
|
|
108
|
+
게이트는 품질 장치가 아니라 지연 장치가 된다.
|
|
109
|
+
|
|
110
|
+
## 흔한 오해
|
|
111
|
+
|
|
112
|
+
| 오해 | 사실 |
|
|
113
|
+
|---|---|
|
|
114
|
+
| "`status:`만 손으로 바꾸면 된다" | 봉인이 없어 `unsealed-approval`로 걸린다. `spec_approve`가 봉인한다 |
|
|
115
|
+
| "REQ를 승인해야 H-SPEC을 쓴다" | 아니다. REQ는 존재만 하면 된다 |
|
|
116
|
+
| "A-SPEC을 승인했으니 코드를 쓸 수 있다" | 테스트는 그렇다. 코드는 T-SPEC이 남았다 |
|
|
117
|
+
| "T-SPEC 승인했는데 막힌다 = 게이트 버그" | `depends_on` 누락. 메시지가 동일해서 구별되지 않는다 |
|
|
118
|
+
| "일단 승인하고 검증은 나중에" | 통과한 채 깨진 그래프가 남는다. 4단계 참조 |
|
|
119
|
+
| "`missing`이 'approved A-SPEC'이니 A-SPEC을 승인하면 된다" | `AUTHOR_TSPEC`이면 아무거나 하나, `WRITE_TEST`면 대상 그것. 같은 문자열이 두 가지를 뜻한다 |
|
|
120
|
+
|
|
121
|
+
## 검증
|
|
122
|
+
|
|
123
|
+
`src/holmes/playbooks/promote-slice.test.ts` — 20개 단언, 상시 스위트에 포함. 고정하는 것:
|
|
124
|
+
|
|
125
|
+
- 위 조건표의 다섯 칸 전부를, **양방향으로**. 게이트를 여는 상태와 열지 못하는 상태를 함께 단언한다.
|
|
126
|
+
- 이 문서가 인용한 모든 deny 문자열을 **완전 일치**로. 부분 일치는 문자열이 사라진 것을 숨긴다.
|
|
127
|
+
- `depends_on` 누락과 T-SPEC 부재가 `message` · `missing` · `phase` 셋 다 같다는 사실을, 두 결과의
|
|
128
|
+
동일성으로. 주장이 "구별되지 않는다"이므로 고정하는 것도 구별되지 않음 자체다.
|
|
129
|
+
- `spec_approve`가 표면에 존재하며 봉인을 설명한다는 것과 `spec_validate`가 광고 집합 밖이라는
|
|
130
|
+
것을, 전사(轉寫)가 아니라 `TOOL_SCHEMAS` · `HOOK_ENFORCED_TOOLS`를 직접 읽어서.
|
|
131
|
+
|
|
132
|
+
**변이 검사로 판별력을 확인했다**(2026-08-05): `phase.ts`의 거부 문자열 하나를 바꾸자 3개 단언이
|
|
133
|
+
red로 떨어졌고, 원복 후 파일은 HEAD와 바이트 동일했다. 현재 상태를 그대로 베끼기만 하는 공허한
|
|
134
|
+
테스트가 아니라는 증명이다.
|