@tuzi-ince/hi-loop 0.2.1 → 0.3.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/README.md +319 -119
- package/bin/hi-loop.js +70 -5
- package/bin/setup.js +54 -1
- package/docs/design.md +12 -1
- package/docs/spec.md +3 -1
- package/package.json +2 -1
- package/skills/hi-loop/SKILL.md +117 -0
- package/src/args.js +18 -5
- package/src/blast.js +42 -0
- package/src/build.js +74 -62
- package/src/check.js +169 -0
- package/src/checkpoint.js +88 -4
- package/src/checks.js +122 -0
- package/src/cli-options.js +19 -1
- package/src/config.js +112 -0
- package/src/gates.js +104 -0
- package/src/integrity.js +30 -1
- package/src/loop.js +46 -44
- package/src/metrics.js +140 -0
- package/src/outcome.js +76 -0
- package/src/report.js +73 -7
- package/src/resume.js +93 -0
- package/src/seal.js +85 -0
- package/src/stages.js +47 -3
- package/src/state.js +21 -39
- package/src/treekey.js +63 -0
- package/src/vcs.js +167 -0
- package/src/verdict.js +54 -0
- package/src/verify.js +6 -5
- package/src/wiring.js +74 -0
package/README.md
CHANGED
|
@@ -4,26 +4,44 @@
|
|
|
4
4
|
|
|
5
5
|
날것의 아이디어(goal)를 던지면, AI 에이전트를 PDCA 루프로 반복 구동해
|
|
6
6
|
**테스트가 실제로 통과할 때까지** 스스로 고쳐 나간다.
|
|
7
|
+
|
|
7
8
|
- 요구사항(무엇을): [`docs/spec.md`](docs/spec.md)
|
|
8
9
|
- 설계(어떻게·왜): [`docs/design.md`](docs/design.md)
|
|
9
10
|
- 배포·설치·사용: [`docs/guide.md`](docs/guide.md)
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
## 루프 엔지니어링 — 우리의 개발 철학
|
|
13
|
+
|
|
14
|
+
이 엔진은 "AI가 코드를 잘 짜준다"에 기대지 않는다. AI는 자주 틀리고, 더 자주
|
|
15
|
+
**틀린 것을 다 됐다고 말한다.** 그래서 우리는 모델의 자기보고를 판정에서 배제하고,
|
|
16
|
+
기계가 검증할 수 있는 종료 조건 위에 루프를 세운다. 세 문장이 전부다.
|
|
17
|
+
|
|
18
|
+
1. **산문은 요청이고, 메커니즘은 사실이다.**
|
|
19
|
+
보고서에 "이건 검증 안 됨"이라고 적는 것은 요청일 뿐이다. 한 번 더 돌려서 측정하면
|
|
20
|
+
그 문장이 사실이 된다. 그래서 이 엔진은 문장을 늘리기보다 검사를 하나 더 돌린다.
|
|
21
|
+
2. **에이전트의 "다 됐어요"는 판정이 아니다.**
|
|
22
|
+
성패는 언제나 `testCommand`의 exit code다. 엔진이 직접 실행해서 확인한다.
|
|
23
|
+
3. **종료 조건 없는 단계는 엔진의 단계가 아니라 문서 생성기다.**
|
|
24
|
+
모든 단계는 기계가 판정할 통과 기준을 가진다. 없으면 그 단계는 만들지 않는다.
|
|
25
|
+
|
|
26
|
+
이 세 원칙에서 뒤의 [안전장치](#안전장치--루프-엔지니어링-원칙)들이 전부 파생된다.
|
|
14
27
|
|
|
15
28
|
## 설치
|
|
16
29
|
|
|
17
|
-
|
|
18
|
-
|
|
30
|
+
```bash
|
|
31
|
+
# 1) 전역 설치 — hi-loop / hi-loop-setup 명령 등록
|
|
32
|
+
npm install -g @tuzi-ince/hi-loop
|
|
33
|
+
|
|
34
|
+
# 2) 프로젝트에 주입 (멱등 — 여러 번 돌려도 안전)
|
|
35
|
+
cd /path/to/my-project
|
|
36
|
+
hi-loop-setup # .mcp.json / .gitignore / docs / tests 자동 주입
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
소스에서 개발용으로 설치하려면:
|
|
19
40
|
|
|
20
41
|
```bash
|
|
21
42
|
git clone <이 저장소> hi-loop && cd hi-loop
|
|
22
|
-
npm install && npm test #
|
|
43
|
+
npm install && npm test # node:test, devDependency 0개
|
|
23
44
|
npm link # hi-loop / hi-loop-setup 명령 등록
|
|
24
|
-
|
|
25
|
-
cd /path/to/my-project
|
|
26
|
-
hi-loop-setup # .mcp.json / .gitignore / docs / tests 자동 주입 (멱등)
|
|
27
45
|
```
|
|
28
46
|
|
|
29
47
|
자세한 절차·문제해결·배포는 [`docs/guide.md`](docs/guide.md).
|
|
@@ -51,30 +69,22 @@ CHECK ──► 엔진이 testCommand 를 직접 실행 (에이전트의 "다
|
|
|
51
69
|
ACT ──► stderr 를 그대로 에이전트에 들이밀고 "이 에러를 고쳐라" (최대 10회)
|
|
52
70
|
```
|
|
53
71
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
기본은 위의 자가 치유 루프 하나다. `--full` 을 붙이면 앞뒤 단계까지 돈다.
|
|
72
|
+
기본은 이 자가 치유 루프 하나다. `--full` 을 붙이면 앞뒤 단계까지 돈다.
|
|
57
73
|
|
|
58
74
|
```
|
|
59
|
-
DISCOVER → PLAN → DESIGN_REVIEW → DO ⇄ CHECK ⇄ HEAL → CODE_REVIEW → SHIP → WATCH → DONE
|
|
60
|
-
▲ │
|
|
61
|
-
└── reject ┘
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
```bash
|
|
65
|
-
# 아이디어 한 줄 → 발굴 → 스펙 → 구현 → 리뷰 → 배포 → 감시. 사람 개입 최소.
|
|
66
|
-
hi-loop run --goal "JWT 인증 미들웨어" --full \
|
|
67
|
-
--ship "npm publish --access public" \
|
|
68
|
-
--watch "curl -f https://api.example.com/health" --watch-for 5m
|
|
75
|
+
DISCOVER → PLAN → DESIGN_REVIEW → BUILD(DO ⇄ CHECK ⇄ HEAL) → CODE_REVIEW → SHIP → WATCH → DONE
|
|
76
|
+
▲ │ │ │
|
|
77
|
+
└── reject ┘ reject ──┘ fail ────┘
|
|
69
78
|
```
|
|
70
79
|
|
|
71
|
-
**추가되는 모든 단계는 기계가 판정할 종료 조건을 가진다.**
|
|
72
|
-
아니라 문서 생성기다.
|
|
80
|
+
**추가되는 모든 단계는 기계가 판정할 종료 조건을 가진다.**
|
|
73
81
|
|
|
74
82
|
| 단계 | 무엇을 하는가 | 종료 조건 |
|
|
75
83
|
|---|---|---|
|
|
76
84
|
| DISCOVER | goal 의 모호함을 **가정으로 확정**하고 문서화 | 가정 목록 확정 |
|
|
85
|
+
| PLAN | 스펙 + 테스트를 먼저 쓴다 (구현 금지) | 산출물 작성 |
|
|
77
86
|
| DESIGN_REVIEW | 구현 착수 **전** 스펙을 심판 | 독립 검증자 pass |
|
|
87
|
+
| BUILD | DO ⇄ CHECK ⇄ HEAL 자가 치유 루프 | testCommand exit 0 |
|
|
78
88
|
| CODE_REVIEW | diff 를 정확성·보안·YAGNI 축으로 심판 | 독립 검증자 pass |
|
|
79
89
|
| SHIP | 배포 명령 실행 | **exit code 0** |
|
|
80
90
|
| WATCH | 헬스체크 반복 | 지정 시간 동안 버팀 |
|
|
@@ -82,106 +92,287 @@ hi-loop run --goal "JWT 인증 미들웨어" --full \
|
|
|
82
92
|
배포·감시는 **에이전트를 부르지 않는다.** "배포했다고 모델이 말했다"가 아니라
|
|
83
93
|
"헬스체크 exit code 가 0이다"가 통과 조건이다. 그래서 이 두 단계의 비용은 0이다.
|
|
84
94
|
|
|
85
|
-
|
|
95
|
+
---
|
|
86
96
|
|
|
87
|
-
|
|
88
|
-
설계 리뷰가 기각하면 PLAN 을 다시 쓰고, 코드 리뷰가 기각하면 그 지적이 HEAL 의 연료가 된다.
|
|
97
|
+
# 실전 활용 가이드 (프로젝트 관리 관점)
|
|
89
98
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
2. SHIP 직전 (비가역 외부 행위. `--yes` 로 생략)
|
|
99
|
+
무엇을 하려는지에 따라 **어떻게 goal을 쓰고 어떤 플래그를 켜는지**가 달라진다.
|
|
100
|
+
아래는 실제 프로젝트를 굴리며 자주 만나는 상황별 레시피다.
|
|
93
101
|
|
|
102
|
+
## 1. 프로젝트 생성 — 아이디어 한 줄 → 동작하는 코드
|
|
103
|
+
|
|
104
|
+
모호한 요구를 발굴부터 구현·리뷰까지 한 번에 돌린다. `--full` 이 앞뒤 단계를 켠다.
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
hi-loop run --goal "JWT 인증 미들웨어를 만들어라" --full --budget-usd 5
|
|
94
108
|
```
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
109
|
+
|
|
110
|
+
- **DISCOVER** 가 goal의 빈칸(토큰 저장 위치, 만료 정책 등)을 가정으로 확정하고 문서화한다.
|
|
111
|
+
- **PLAN** 이 스펙과 테스트를 먼저 쓴다 — 구현보다 판정 기준이 앞선다.
|
|
112
|
+
- **DESIGN_REVIEW → BUILD → CODE_REVIEW** 순으로 만들고, 만든 것을 스스로 심판한다.
|
|
113
|
+
- 상호배타 분기(예: "users 확장 vs auth_tokens 신설")를 만나면 거기서만 사람에게 묻는다.
|
|
114
|
+
|
|
115
|
+
**기존 파일을 덮어쓰지 않는다.** `docs/spec.md` / `tests/app.test.js` 가 비어 있으면 그대로
|
|
116
|
+
쓰고, 이미 뭔가 있으면 goal 해시로 비켜간다(`docs/spec-5d88cc7f.md`). 같은 프로젝트에서
|
|
117
|
+
goal만 바꿔 여러 번 돌려도 앞의 산출물이 살아남는다.
|
|
118
|
+
|
|
119
|
+
> 발굴 단계만 먼저 돌려 요구사항을 확정하고 싶다면:
|
|
120
|
+
> ```bash
|
|
121
|
+
> hi-loop discover --goal "..." # 가정 확정 + 문서만, 구현은 안 함
|
|
122
|
+
> ```
|
|
123
|
+
|
|
124
|
+
## 2. 프로젝트 개선 — 기존 코드베이스 손질
|
|
125
|
+
|
|
126
|
+
리팩터링·성능 개선·기술부채 정리처럼 **이미 테스트가 있는 코드**를 고칠 때.
|
|
127
|
+
기존 테스트를 가드레일로 두고, 스펙 대비 검증을 더 얹는다.
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
hi-loop run --goal "결제 모듈의 중복 검증 로직을 하나로 합쳐라" \
|
|
131
|
+
--test "npm test" \
|
|
132
|
+
--verify-spec
|
|
103
133
|
```
|
|
104
134
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
135
|
+
- 기존 `npm test` 가 회귀 방지선이다 — 개선하다 무언가 깨면 Tier 1에서 걸린다.
|
|
136
|
+
- `--verify-spec` 은 테스트 통과 **후** 별도 검증자가 스펙 대비 구현을 심판한다.
|
|
137
|
+
구조가 아니라 **의도**를 본다("리팩터링했다"는데 동작이 달라졌으면 기각).
|
|
138
|
+
- 개선 중 락파일·설정·마이그레이션을 건드리면 보고서 Gaps에 ⚠️로 공개된다
|
|
139
|
+
(→ [영향도 분석](#4-영향도-분석--변경-위험-파악)).
|
|
108
140
|
|
|
109
|
-
|
|
141
|
+
## 3. 장애 분석 — 버그·회귀 재현 → 수정
|
|
110
142
|
|
|
111
|
-
|
|
143
|
+
버그를 "고쳤다"가 아니라 "재현 테스트로 못박고 고쳤다"로 끝낸다. 회귀 방지가 공짜로 남는다.
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
hi-loop run --goal "재현 테스트를 먼저 작성하고, 동시 요청 시 잔액이 음수가 되는 버그를 고쳐라" \
|
|
147
|
+
--test "npm test" \
|
|
148
|
+
--stagnation 3
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
- PLAN이 **실패하는 재현 테스트**를 먼저 강제한다 → 버그가 테스트로 고정된다.
|
|
152
|
+
- HEAL이 실제 stderr를 연료로 삼아 고친다. 모델의 추측이 아니라 진짜 에러를 본다.
|
|
153
|
+
- **같은 벽에 열 번 부딪히지 않는다**: 같은 실패가 3회 연속이면 `stagnated` 로 조기 종료한다
|
|
154
|
+
— "이 접근으론 안 된다"를 `--max-loops` 소진 전에 잡는다. `--no-stagnation` 으로 끈다.
|
|
155
|
+
- 에이전트가 멀쩡한 코드를 오히려 망가뜨렸으면 되돌린다:
|
|
156
|
+
```bash
|
|
157
|
+
hi-loop rollback # 최신 체크포인트로 파일 복원
|
|
158
|
+
hi-loop rollback --to 3 # 3회차 직전 상태로
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## 4. 영향도 분석 — 변경 위험 파악
|
|
162
|
+
|
|
163
|
+
이 변경이 **어디까지 번지는가**를 두 층위로 잡는다.
|
|
164
|
+
|
|
165
|
+
**(a) 블라스트 반경 — 자동, 비용 0.** 실행이 위험 분류 파일을 건드리면 판정과 무관하게
|
|
166
|
+
보고서 Gaps에 ⚠️로 공개한다. 분류: 의존성(lock/package.json), 스키마 마이그레이션,
|
|
167
|
+
CI·배포 설정, 빌드·러너 설정, 환경 변수. "테스트는 통과했는데 왜 락파일이 바뀌었지"를
|
|
168
|
+
사람이 놓치지 않게 한다.
|
|
169
|
+
|
|
170
|
+
**(b) 조건부 검사 — 바뀐 파일에 따라 게이트를 켠다.** 무거운 검사(e2e 등)를 매 회차 돌리는
|
|
171
|
+
대신, 특정 경로가 바뀐 회차에만 돌린다.
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
hi-loop run --goal "..." \
|
|
175
|
+
--check "npm test" \
|
|
176
|
+
--check "npm run typecheck" \
|
|
177
|
+
--check "npx playwright test" --when "src/ui/**"
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
- 검사는 **short-circuit 하지 않는다.** 유닛이 깨져도 typecheck·e2e 결과를 같은 회차에 다 본다
|
|
181
|
+
(`&&` 로 이으면 첫 실패에서 멈춰 나머지를 영영 모른다).
|
|
182
|
+
- `--when` 글롭에 안 맞은 검사는 **건너뜀으로 기록**된다 — 안 돌린 것이 통과처럼 보이지 않게
|
|
183
|
+
Gaps에 남는다.
|
|
184
|
+
|
|
185
|
+
**diff만 리뷰하고 싶다면** — 지금 워킹트리 변경분을 정확성·보안·YAGNI 축으로 심판:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
hi-loop review # 현재 변경분만 코드 리뷰 (구현/배포는 안 함)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## 5. 테스트·품질 게이트
|
|
192
|
+
|
|
193
|
+
**테스트 설계만** 뽑고 싶을 때 (구현은 사람이 하거나 나중에):
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
hi-loop plan --goal "장바구니 할인 규칙" # 스펙 + 테스트까지만, 구현 전
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**플레이키(불안정) 테스트를 걸러내고 싶을 때:**
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
hi-loop run --goal "..." --flaky-probe
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
- 통과한 회차에서만 같은 테스트를 **한 번 더** 돌린다. 두 번의 결과가 갈리면 통과로 인정하지
|
|
206
|
+
않는다("두 번 돌려 갈리는 초록불은 초록불이 아니다"). 에이전트 호출 0 — 비용은 테스트 한 번뿐.
|
|
207
|
+
|
|
208
|
+
**여러 게이트를 한 판정에 묶고 싶을 때** — 위 [조건부 검사](#4-영향도-분석--변경-위험-파악)의
|
|
209
|
+
`--check` 를 여러 번 준다. lint·typecheck·유닛·e2e를 각각 독립된 게이트로 세운다.
|
|
210
|
+
|
|
211
|
+
## 6. 배포 & 감시 — 사람 개입 최소
|
|
212
|
+
|
|
213
|
+
리뷰를 통과한 변경을 배포하고, 배포 후 일정 시간 헬스체크로 버티는지 지켜본다.
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
hi-loop run --goal "..." --full \
|
|
217
|
+
--ship "npm publish --access public" \
|
|
218
|
+
--watch "curl -f https://api.example.com/health" --watch-for 5m
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
- `--ship` 을 주면 리뷰 단계들이 **자동으로 켜진다** ("리뷰 없는 자동 배포는 위험하다"의
|
|
222
|
+
근거가 여기서만 성립).
|
|
223
|
+
- SHIP/WATCH는 에이전트를 부르지 않는다 — 통과 조건은 오직 exit code다.
|
|
224
|
+
- 실패 대응을 지정할 수 있다: `--on-ship-fail stop|heal`, `--on-watch-fail stop|rollback|heal`.
|
|
225
|
+
- 비가역 배포 직전에는 사람에게 확인을 구한다. CI·봇에서는 `--yes` 로 생략.
|
|
226
|
+
|
|
227
|
+
## 7. 단계별로 따로 부르기
|
|
228
|
+
|
|
229
|
+
전체를 한 번에 돌리지 않고, 필요한 구간만 실행할 수 있다. 어느 경로로 들어와도 **같은 상태
|
|
230
|
+
머신**을 쓴다.
|
|
112
231
|
|
|
113
232
|
```bash
|
|
114
233
|
hi-loop discover --goal "..." # 발굴만 (가정 확정 + 문서)
|
|
115
|
-
hi-loop plan
|
|
234
|
+
hi-loop plan --goal "..." # 스펙·테스트까지만 (구현 전)
|
|
116
235
|
hi-loop review # 현재 변경분만 코드 리뷰
|
|
117
|
-
hi-loop ship
|
|
118
|
-
hi-loop watch
|
|
236
|
+
hi-loop ship --ship "npm publish"
|
|
237
|
+
hi-loop watch --watch "curl -f ..."
|
|
119
238
|
```
|
|
120
239
|
|
|
121
|
-
|
|
122
|
-
저장된 상태에서 읽는다(한 글자만 달라도 새 루프로 인식돼 진행 상황이 버려지기 때문).
|
|
240
|
+
또는 `--start-from` / `--stop-after` 로 한 실행의 구간을 자른다:
|
|
123
241
|
|
|
124
|
-
|
|
242
|
+
```bash
|
|
243
|
+
hi-loop run --goal "..." --start-from BUILD --stop-after CODE_REVIEW
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
> 후반 단계는 `--goal` 을 다시 받지 않는다 — 저장된 상태에서 읽는다(goal이 한 글자만 달라도
|
|
247
|
+
> 새 루프로 인식돼 진행 상황이 버려진다). PLAN은 BUILD 안쪽의 회차라 `--start-from` 대상이
|
|
248
|
+
> 아니다 — BUILD로 시작하면 자연히 PLAN부터 돈다.
|
|
125
249
|
|
|
126
|
-
|
|
127
|
-
기존 사용자의 실행 비용이 조용히 는다. 그래서:
|
|
250
|
+
## 8. MCP에서 팀으로 쓰기 (클로드코드/커서)
|
|
128
251
|
|
|
129
|
-
-
|
|
130
|
-
|
|
131
|
-
- `--ship` → 리뷰들만 자동 켜짐 ("리뷰 없는 자동 배포가 위험하다"는 근거가 여기서만 성립).
|
|
132
|
-
- `--review/--no-review`, `--design-review/--no-design-review`, `--discover/--no-discover`
|
|
133
|
-
가 위 자동을 양방향으로 덮는다.
|
|
252
|
+
`hi-loop mcp` 로 띄우면 호스트 LLM이 위 시나리오를 도구로 호출한다. 차단형 입력을 쓰지 않고
|
|
253
|
+
**상태를 저장하고 종료**하므로(exit 3) 대화형 세션·백그라운드 데몬·봇에서 그대로 성립한다.
|
|
134
254
|
|
|
135
|
-
|
|
255
|
+
```
|
|
256
|
+
호스트 LLM ──hiloop_run──► 루프 구동
|
|
257
|
+
◄──분기 질문─── (상호배타 선택 필요)
|
|
258
|
+
──hiloop_answer──► 사람의 선택을 "가정"으로 기록하고 재개
|
|
259
|
+
──hiloop_status──► 진행/비용/Gaps 조회
|
|
260
|
+
```
|
|
136
261
|
|
|
137
|
-
|
|
138
|
-
그래서 4회마다 세션을 **버리고**, `.agent-state.json`에 압축된 상태
|
|
139
|
-
(goal / 스펙 요약 / 마지막 에러 / 최근 이력 5건)만 새 세션에 넘겨 이어서 작업한다(auto-resume).
|
|
140
|
-
같은 goal로 다시 실행하면 중단 지점부터 재개한다.
|
|
262
|
+
## 9. 코드 어시스턴트가 요청을 처리하는 방식 — 직접 호출 vs 평문 요청
|
|
141
263
|
|
|
142
|
-
|
|
264
|
+
클로드코드·커서 같은 코드 어시스턴트(호스트 LLM) 안에서 hi-loop은 두 갈래로 불린다.
|
|
265
|
+
**핵심은 "LLM이 요청을 읽는 순간, hi-loop을 떠올릴 근거가 눈앞에 있느냐"** 다.
|
|
143
266
|
|
|
144
|
-
|
|
267
|
+
### (a) 직접 호출 — 명시적으로 엔진을 지목
|
|
268
|
+
사용자가 hi-loop을 대놓고 부른다. LLM은 **바로 `hiloop_run`을 구동**한다(목표만 확정).
|
|
145
269
|
|
|
146
|
-
|
|
270
|
+
| 사용자가 이렇게 말하면 | LLM이 하는 일 |
|
|
271
|
+
|---|---|
|
|
272
|
+
| `/hi-loop 로그인 폼 만들어줘` (슬래시 스킬) | hi-loop 스킬 기동 → `hiloop_run(full=true)` 실행 |
|
|
273
|
+
| "hiloop_run 도구로 결제 버그 고쳐줘" | 지목된 MCP 도구를 로드해 바로 호출 |
|
|
274
|
+
| 터미널에서 `hi-loop run --goal "..." --full` | 엔진을 CLI로 직접 구동(LLM 개입 없음) |
|
|
275
|
+
|
|
276
|
+
### (b) 평문 요청 — 그냥 하고 싶은 일을 말함
|
|
277
|
+
사용자는 hi-loop을 언급하지 않는다. 이때 자동으로 hi-loop에 걸리는 건 **트리거가 박힌
|
|
278
|
+
스킬 description + `CLAUDE.md` 지침**이 매 세션 떠 있기 때문이다(설치 + `hi-loop-setup` 전제).
|
|
279
|
+
그 표면이 없으면 LLM은 hi-loop을 모른 채 그냥 직접 구현한다.
|
|
147
280
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
281
|
+
| 사용자가 이렇게 말하면 | 어디에 걸리나 | LLM이 하는 일 |
|
|
282
|
+
|---|---|---|
|
|
283
|
+
| "워크스페이스 폴더 드래그앤드롭 **개선**해줘" | 트리거 `개선` | hi-loop 스킬 후보로 뜸 → 기획·설계 필요 판단 → `hiloop_run(full=true)` 제안·실행 |
|
|
284
|
+
| "장바구니 **기능** 하나 **만들어**줘" | 트리거 `기능/design` | 발굴→스펙·테스트 우선(PLAN)→구현·리뷰 루프 |
|
|
285
|
+
| "결제 모듈 **리팩터**해줘" | 트리거 `리팩터` | 기존 테스트를 가드레일로 `--verify-spec` 성격의 개선 루프 |
|
|
286
|
+
| "동시 요청 시 잔액 음수 **버그** 고쳐줘" | 트리거 `구현/버그성` | **재현 테스트 먼저** → HEAL 루프로 수정 |
|
|
287
|
+
| "이 **오타** 고쳐줘" / "변수명 바꿔줘" | 예외(사소) | 루프 없이 **바로** 처리 — README·CLAUDE.md가 사소한 작업은 제외하라고 명시 |
|
|
288
|
+
|
|
289
|
+
### 왜 이렇게 갈리나 (push vs pull)
|
|
290
|
+
- **트리거 스킬 description·CLAUDE.md = push 표면.** LLM이 찾지 않아도 매 세션 상주하며,
|
|
291
|
+
평문에 `개선/설계/버그` 같은 단어가 있으면 **자동으로** hi-loop을 후보로 올린다.
|
|
292
|
+
- **MCP 도구 = pull 표면.** 세션에선 이름만 있고(때로 deferred), LLM이 먼저 "hi-loop이
|
|
293
|
+
필요하다"고 떠올려 `ToolSearch`로 끌어와야 설명이 보인다.
|
|
294
|
+
- 그래서 **평문 요청이 자동 라우팅되려면 push 표면이 반드시 있어야 한다.** `hi-loop-setup`이
|
|
295
|
+
`CLAUDE.md` 지침을 심고, 플러그인이 트리거 스킬을 등록하는 이유가 이것이다. 이게 없으면
|
|
296
|
+
"개선해줘"라고 해도 LLM은 hi-loop을 거치지 않고 곧장 코드부터 짠다.
|
|
297
|
+
|
|
298
|
+
> 확실히 hi-loop을 태우고 싶으면 **(a) 직접 호출**이 가장 안전하다. **(b) 평문 자동 라우팅**은
|
|
299
|
+
> 편하지만, 설치·주입이 안 됐거나 트리거에 안 걸리는 표현이면 우회될 수 있다.
|
|
300
|
+
|
|
301
|
+
## 브랜치 & 커밋 워크플로 (FR-16)
|
|
302
|
+
|
|
303
|
+
코드 변경 작업을 **보호 브랜치에서 분기 → 구현·테스트 → 로컬 커밋**으로 감싼다. push/PR 은 하지 않는다.
|
|
304
|
+
|
|
305
|
+
**정책은 커밋되는 `.hi-loop.json` 한 파일**에 산다(팀 공유, 스킬·엔진 공용). `.agent-state.json`
|
|
306
|
+
(임시·gitignore)과 다르다. 기본값:
|
|
307
|
+
|
|
308
|
+
```json
|
|
309
|
+
{
|
|
310
|
+
"protectedBranches": ["main", "master", "develop", "dev"],
|
|
311
|
+
"branchPolicy": "ask", // always=자동 분기 | ask=매번 확인 | never
|
|
312
|
+
"commitPolicy": "confirm", // confirm=메시지+diff 확인 후 | auto | off
|
|
313
|
+
"commitStyle": "match-log" // match-log=git log 관행 미러 | conventional | korean
|
|
314
|
+
}
|
|
315
|
+
```
|
|
151
316
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
(
|
|
317
|
+
**두 실행 층 (같은 정책 파일):**
|
|
318
|
+
- **대화형(스킬/코드 어시스턴트)**: 코드변경 요청 시 `.hi-loop.json` 이 없으면 **최초 1회** 정책을
|
|
319
|
+
묻고 저장(지연 발동). 이후 보호 브랜치면 분기 게이트, 테스트 통과 후 커밋 게이트(diff 보여주고
|
|
320
|
+
승인)를 태운다. "이번만 커밋하지 마"(일회성)와 "앞으로 커밋하지 마"(정책 변경)를 구분한다.
|
|
321
|
+
- **헤드리스(CLI/봇/CI)**: 물어볼 수 없으니 **플래그 = 동의**.
|
|
155
322
|
|
|
156
323
|
```bash
|
|
157
|
-
hi-loop run --goal "..." --
|
|
158
|
-
|
|
324
|
+
hi-loop run --goal "..." --branch --commit # 보호 브랜치면 자동 분기 + 통과 후 자동 커밋
|
|
325
|
+
hi-loop run --goal "..." --branch feature/login # 브랜치명 지정
|
|
326
|
+
hi-loop run --goal "..." --commit --commit-message "feat: 로그인"
|
|
159
327
|
```
|
|
160
328
|
|
|
161
|
-
|
|
162
|
-
`
|
|
329
|
+
`.hi-loop.json` 의 `branchPolicy: always` / `commitPolicy: auto` 는 CLI 에서 플래그 없이도 발동한다
|
|
330
|
+
(플래그가 우선). 커밋 스테이지는 상태 머신에서 `CODE_REVIEW → COMMIT → SHIP` 사이에 든다 —
|
|
331
|
+
리뷰된 코드를 커밋한 뒤 배포한다.
|
|
163
332
|
|
|
164
|
-
|
|
333
|
+
**정책 관리:**
|
|
165
334
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
335
|
+
```bash
|
|
336
|
+
hi-loop config # 현재 정책 출력
|
|
337
|
+
hi-loop config set commitPolicy auto # 정책 변경 (branchPolicy|commitPolicy|commitStyle)
|
|
338
|
+
hi-loop config add-branch release # 보호 브랜치 추가
|
|
339
|
+
hi-loop config remove-branch dev # 보호 브랜치 제거
|
|
340
|
+
```
|
|
169
341
|
|
|
170
|
-
|
|
342
|
+
## 상태 초기화
|
|
171
343
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
344
|
+
새 goal로 깨끗이 다시 시작하려면 상태 파일을 지운다:
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
hi-loop reset # .agent-state.json 삭제 (CLI)
|
|
348
|
+
# MCP: hiloop_reset
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
---
|
|
176
352
|
|
|
177
|
-
|
|
353
|
+
# 안전장치 — 루프 엔지니어링 원칙
|
|
178
354
|
|
|
179
|
-
|
|
180
|
-
`--max-loops` 소진 전에 잡는다. `--stagnation N` 으로 조절, `--no-stagnation` 으로 끈다.
|
|
355
|
+
위 세 원칙에서 파생된, 이 엔진이 **false green을 막는** 구체적 장치들이다.
|
|
181
356
|
|
|
182
|
-
###
|
|
357
|
+
### 세션 핸드오프 & 컨텍스트 다이어트
|
|
358
|
+
|
|
359
|
+
에이전트는 같은 세션에서 오래 굴릴수록 토큰이 쌓여 멍청해진다. 그래서 4회마다 세션을
|
|
360
|
+
**버리고**, `.agent-state.json` 에 압축된 상태(goal / 스펙 요약 / 마지막 에러 / 최근 이력 5건)만
|
|
361
|
+
새 세션에 넘겨 이어서 작업한다(auto-resume). 같은 goal로 다시 실행하면 중단 지점부터 재개한다.
|
|
362
|
+
|
|
363
|
+
### TDD 자가 치유
|
|
364
|
+
|
|
365
|
+
성패 판정은 항상 `testCommand` 의 exit code다. 에이전트의 자기보고는 판정에 쓰지 않는다.
|
|
366
|
+
|
|
367
|
+
### 테스트를 지워서 통과하는 것을 막는다
|
|
368
|
+
|
|
369
|
+
CHECK는 2단이다 — `check.ok && integrity.ok` 여야 통과. 판정 기준인 테스트를 에이전트가
|
|
370
|
+
지우거나 skip/always-true로 무력화하면 exit 0이 나와도 **통과로 인정하지 않는다.**
|
|
371
|
+
탐지 패턴은 케이스 감소, `.skip`, `.only`, `assert.ok(true)` 등이다. 테스트 **추가**는 위반이 아니다.
|
|
183
372
|
|
|
184
|
-
|
|
373
|
+
### 통과가 무엇을 확인 안 했는지 공개한다
|
|
374
|
+
|
|
375
|
+
이 엔진의 `passed` 는 조용한 거짓말이 될 수 있다 — 테스트를 PLAN 단계에서 **에이전트 자신이**
|
|
185
376
|
썼기 때문이다. 그래서 통과할 때마다 Evidence와 Gaps를 함께 출력한다:
|
|
186
377
|
|
|
187
378
|
```
|
|
@@ -191,33 +382,38 @@ CHECK는 2단이다 — `check.ok && integrity.ok`여야 통과. 판정 기준
|
|
|
191
382
|
- 런타임·성능·보안은 관측 범위 밖이다.
|
|
192
383
|
```
|
|
193
384
|
|
|
194
|
-
|
|
385
|
+
false green을 disclosed green으로 바꾼다.
|
|
195
386
|
|
|
196
|
-
### 망가뜨려도 되돌린다
|
|
387
|
+
### 망가뜨려도 되돌린다
|
|
197
388
|
|
|
198
|
-
각 에이전트 호출 **전에** `git stash create
|
|
199
|
-
안 건드리고 SHA만 남긴다). 에이전트가 멀쩡한 코드를
|
|
389
|
+
각 에이전트 호출 **전에** `git stash create` 로 워킹트리를 스냅샷한다(비파괴 — 워킹트리를
|
|
390
|
+
안 건드리고 SHA만 남긴다). 에이전트가 멀쩡한 코드를 망가뜨리면 `hi-loop rollback` 으로
|
|
391
|
+
복원한다. **자동 롤백은 없다** — 전경 실행이 기본이라 사람이 본다. git 저장소가 아니면
|
|
392
|
+
조용히 생략한다.
|
|
200
393
|
|
|
201
|
-
|
|
202
|
-
hi-loop rollback # 최신 체크포인트로 파일 복원
|
|
203
|
-
hi-loop rollback --to 3 # 3회차 직전 상태로
|
|
204
|
-
```
|
|
394
|
+
### 스펙을 오라클로 — 2단 판정 (`--verify-spec`)
|
|
205
395
|
|
|
206
|
-
|
|
207
|
-
|
|
396
|
+
이 엔진의 exit 0은 "에이전트가 자기가 쓴 테스트를 통과시켰다"일 뿐이다. `--verify-spec` 을
|
|
397
|
+
켜면 통과 후 **별도 검증자**가 스펙 대비 구현을 심판한다.
|
|
208
398
|
|
|
209
|
-
|
|
399
|
+
- **Tier 1 (기계)**: exit code + 무결성. 최종 권한. 실패면 끝.
|
|
400
|
+
- **Tier 2 (모델)**: 스펙 대조. **오직 기각만 가능** — 통과를 되돌릴 순 있어도 Tier 1 실패를
|
|
401
|
+
통과로 못 올린다. 쓰기 권한 없이(`--permission-mode plan`) 새 세션으로 호출.
|
|
210
402
|
|
|
211
|
-
|
|
212
|
-
이 엔진의 exit 0은 "에이전트가 자기가 쓴 테스트를 통과시켰다"일 뿐이므로:
|
|
403
|
+
구조가 아니라 의도를 본다. 비용이 늘어 opt-in이다.
|
|
213
404
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
405
|
+
### 💸 비용은 엔진이 센다 — 그리고 싸지 않다
|
|
406
|
+
|
|
407
|
+
**`--max-loops` 는 비용 상한이 아니다.** 실패 루프가 10회를 다 쓰면 비용이 크게 뛸 수 있다.
|
|
408
|
+
그래서 `--budget-usd` 를 쓴다 — 누적이 상한에 닿으면 **다음 에이전트 호출 전에** 멈춘다.
|
|
409
|
+
|
|
410
|
+
```bash
|
|
411
|
+
hi-loop run --goal "..." --max-loops 5 --budget-usd 1 --no-stagnation
|
|
412
|
+
# [hi-loop] 💸 예산 $1 소진 (누적 $1.61) — 2회차에서 중단합니다.
|
|
413
|
+
```
|
|
217
414
|
|
|
218
|
-
|
|
219
|
-
`
|
|
220
|
-
반환한다"*고 정확히 기각했다. 구조가 아니라 의도를 본다. opt-in(비용 증가).
|
|
415
|
+
`hi-loop status` 와 완료 로그에 누적 비용이 찍힌다. 모델은 사용자 기본값을 상속하므로
|
|
416
|
+
`HILOOP_AGENT_ARGS="--model sonnet"` 으로 낮출 수 있다.
|
|
221
417
|
|
|
222
418
|
## 환경변수
|
|
223
419
|
|
|
@@ -226,7 +422,7 @@ hi-loop rollback --to 3 # 3회차 직전 상태로
|
|
|
226
422
|
| `HILOOP_AGENT_CMD` | 에이전트 실행 명령 (기본 `claude`) |
|
|
227
423
|
| `HILOOP_AGENT_ARGS` | 에이전트에 덧붙일 인자 (공백 구분). 예: `--model sonnet` — 비용에 직결된다 |
|
|
228
424
|
| `HILOOP_PERMISSION_MODE` | 권한 모드 (기본 `acceptEdits`). 편집 허용이 이 엔진의 전제다 |
|
|
229
|
-
| `HILOOP_VERIFY_CMD` / `HILOOP_VERIFY_MODEL` | `--verify-spec` 검증자의 실행 명령·모델 (미설정 시 구현자와 동일).
|
|
425
|
+
| `HILOOP_VERIFY_CMD` / `HILOOP_VERIFY_MODEL` | `--verify-spec` 검증자의 실행 명령·모델 (미설정 시 구현자와 동일). 검증에 더 센 모델을 쓸 수 있다 |
|
|
230
426
|
| `HILOOP_REVIEW_CMD` / `HILOOP_REVIEW_MODEL` | 설계·코드 리뷰어의 실행 명령·모델 (미설정 시 `HILOOP_VERIFY_*` → 구현자 순으로 폴백) |
|
|
231
427
|
| `HILOOP_DISCOVER_CMD` / `HILOOP_DISCOVER_MODEL` | 발굴 단계의 실행 명령·모델 |
|
|
232
428
|
| `HILOOP_AGENT_TIMEOUT_MS` / `HILOOP_TEST_TIMEOUT_MS` | 에이전트(30분)·테스트(10분) 타임아웃. 쓰레기값은 기본값으로 되돌림 |
|
|
@@ -241,24 +437,28 @@ npm test # node:test, devDependency 0개
|
|
|
241
437
|
## 구조
|
|
242
438
|
|
|
243
439
|
```
|
|
244
|
-
bin/hi-loop.js
|
|
440
|
+
bin/hi-loop.js CLI 엔트리포인트 (CLI / MCP 분기 + rollback + answer + 단계별 실행)
|
|
245
441
|
bin/setup.js 프로젝트·클로드코드 설정 자동 주입
|
|
246
442
|
src/loop.js 라이프사이클 stage 머신 — 다음 stage 를 정하는 권한은 여기 한 곳뿐
|
|
247
443
|
src/build.js 안쪽 자가 치유 루프 — 예산·정체·무결성·2단 판정·핸드오프 집행
|
|
248
444
|
src/stages.js DISCOVER / CODE_REVIEW / SHIP / WATCH 핸들러 (지시만 반환)
|
|
249
|
-
src/discover.js DISCOVER — 요구사항 발굴, 가정 확정, 분기 감지
|
|
250
|
-
src/review.js DESIGN_REVIEW / CODE_REVIEW — 격리된 Tier 2 심판
|
|
251
|
-
src/ship.js SHIP / WATCH — 배포·헬스체크. 에이전트를 부르지 않는다
|
|
252
|
-
src/
|
|
253
|
-
src/
|
|
445
|
+
src/discover.js DISCOVER — 요구사항 발굴, 가정 확정, 분기 감지
|
|
446
|
+
src/review.js DESIGN_REVIEW / CODE_REVIEW — 격리된 Tier 2 심판
|
|
447
|
+
src/ship.js SHIP / WATCH — 배포·헬스체크. 에이전트를 부르지 않는다
|
|
448
|
+
src/vcs.js 브랜치·커밋 메커니즘 — 프리스텝·COMMIT 스테이지·git log 스타일 감지
|
|
449
|
+
src/config.js .hi-loop.json 정책 저장소 — 브랜치·커밋 정책의 단일 진실 원천
|
|
450
|
+
src/ask.js ask 모드 — pause/resume 상태머신, 가정 기록
|
|
451
|
+
src/checks.js 다중 조건 검사 — --check/--when, short-circuit 없음
|
|
452
|
+
src/blast.js 블라스트 반경 — 변경의 위험 분류를 공개
|
|
453
|
+
src/report.js 완료 보고 — Gaps 공개 + 상태 요약
|
|
254
454
|
src/cli-options.js CLI 인자 → runLoop 옵션 번역 (잘못된 값은 조용히 흘리지 않는다)
|
|
255
455
|
src/state.js .agent-state.json (원자적 저장 + 다이어트 + 산출물 경로 + resume + Gaps)
|
|
256
|
-
src/runners.js 에이전트/테스트 실행 어댑터 (주입 가능) + 비용 파싱 + 타임아웃
|
|
456
|
+
src/runners.js 에이전트/테스트 실행 어댑터 (주입 가능) + 비용 파싱 + 타임아웃
|
|
257
457
|
src/prompts.js PDCA 단계별 프롬프트 + 검증자 프롬프트
|
|
258
|
-
src/integrity.js 테스트 무결성 지문·비교 — 보상 해킹 방어
|
|
259
|
-
src/checkpoint.js git stash 체크포인트·롤백
|
|
260
|
-
src/verify.js 스펙 오라클 — Tier 2 검증자
|
|
261
|
-
src/lock.js 동시 실행 pid 락
|
|
458
|
+
src/integrity.js 테스트 무결성 지문·비교 — 보상 해킹 방어
|
|
459
|
+
src/checkpoint.js git stash 체크포인트·롤백 + 삭제 관측
|
|
460
|
+
src/verify.js 스펙 오라클 — Tier 2 검증자
|
|
461
|
+
src/lock.js 동시 실행 pid 락
|
|
262
462
|
src/mcp-server.js MCP 프로토콜 통신
|
|
263
463
|
src/telegram.js 텔레그램 비동기 알림
|
|
264
464
|
src/args.js 의존성 없는 인자 파서
|