@su-record/vibe 3.2.50 → 3.2.52
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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/dist/tools/loop/validateLoopDefinition.d.ts +17 -1
- package/dist/tools/loop/validateLoopDefinition.d.ts.map +1 -1
- package/dist/tools/loop/validateLoopDefinition.js +47 -3
- package/dist/tools/loop/validateLoopDefinition.js.map +1 -1
- package/package.json +1 -1
- package/skills/vibe.loop/SKILL.md +8 -1
- package/vibe/rules/loop-contract.md +16 -0
- package/vibe/templates/loop-template.md +4 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibe",
|
|
3
3
|
"displayName": "Vibe",
|
|
4
|
-
"version": "3.2.
|
|
4
|
+
"version": "3.2.52",
|
|
5
5
|
"description": "Verification harness for AI coding agents — \"done\" is decided by deterministic gates (test exit codes, run-ledger, regression memory), not the model self-report.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "su-record",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibe",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.52",
|
|
4
4
|
"description": "Verification harness for AI coding agents — \"done\" is decided by deterministic gates (test exit codes, run-ledger, regression memory), not the model self-report.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "su-record",
|
|
@@ -5,7 +5,21 @@
|
|
|
5
5
|
* 조건부 필드(schedule, test_command)를 결정론적으로 검증한다.
|
|
6
6
|
*/
|
|
7
7
|
export type LoopTrigger = 'scheduled' | 'manual' | 'on-event';
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* 완료를 무엇으로 판정하는가.
|
|
10
|
+
*
|
|
11
|
+
* - `ledger` — run-ledger 의 `verifyPassed`
|
|
12
|
+
* - `tests` — `test_command` 의 exit code
|
|
13
|
+
* - `visual` — `visual_command` 의 exit code **+ 사람이 볼 산출물**
|
|
14
|
+
* - `none` — 판정 생략(보고만)
|
|
15
|
+
*
|
|
16
|
+
* ⚠️ `visual` 이 "모델이 스크린샷을 보고 판단한다" 는 뜻이 **아니다.** 그건
|
|
17
|
+
* 자기보고이고, loop-contract 가 배제하는 바로 그것이다. 게이트는 명령의 exit
|
|
18
|
+
* code 다 — 베이스라인 diff·접근성 감사·토큰 드리프트처럼 임계값으로 떨어지는
|
|
19
|
+
* 검사여야 한다. `tests` 와 갈리는 지점은 **증거를 남긴다**는 것이다: 스크린샷이나
|
|
20
|
+
* diff 이미지를 남겨 나중에 사람이 눈으로 확인할 수 있어야 한다.
|
|
21
|
+
*/
|
|
22
|
+
export type LoopVerify = 'ledger' | 'tests' | 'visual' | 'none';
|
|
9
23
|
export type LoopIsolation = 'worktree' | 'none';
|
|
10
24
|
/**
|
|
11
25
|
* 한 번의 호출에서 몇 바퀴를 도는가.
|
|
@@ -30,6 +44,8 @@ export interface ParsedLoopDefinition {
|
|
|
30
44
|
pipeline: string[];
|
|
31
45
|
verify: LoopVerify;
|
|
32
46
|
test_command?: string;
|
|
47
|
+
visual_command?: string;
|
|
48
|
+
artifact_dir?: string;
|
|
33
49
|
max_iterations: number;
|
|
34
50
|
isolation: LoopIsolation;
|
|
35
51
|
session: LoopSession;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validateLoopDefinition.d.ts","sourceRoot":"","sources":["../../../src/tools/loop/validateLoopDefinition.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC;AAC9D,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"validateLoopDefinition.d.ts","sourceRoot":"","sources":["../../../src/tools/loop/validateLoopDefinition.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC;AAC9D;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAChE,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,MAAM,CAAC;AAEhD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,eAAe,CAAC;AACzD,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE7C,gBAAgB;AAChB,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,UAAU,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,aAAa,CAAC;IACzB,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,mCAAmC;AACnC,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,oBAAoB,GAAG,IAAI,CAAC;CACzC;AA8ID;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,oBAAoB,CAgJ5E"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
// ─── Constants ───────────────────────────────────────────────────────
|
|
8
8
|
const TRIGGER_VALUES = new Set(['scheduled', 'manual', 'on-event']);
|
|
9
|
-
const VERIFY_VALUES = new Set(['ledger', 'tests', 'none']);
|
|
9
|
+
const VERIFY_VALUES = new Set(['ledger', 'tests', 'visual', 'none']);
|
|
10
10
|
const ISOLATION_VALUES = new Set(['worktree', 'none']);
|
|
11
11
|
const SESSION_VALUES = new Set(['continuous', 'per-iteration']);
|
|
12
12
|
const STATUS_VALUES = new Set(['active', 'paused']);
|
|
@@ -19,6 +19,27 @@ const MAX_ITERATIONS_MAX = 50;
|
|
|
19
19
|
* YAML-like frontmatter 파싱 (scope-from-spec.js#readFrontmatter 의미론 준수).
|
|
20
20
|
* 스칼라 값과 인라인 배열([a, b, c]), 블록 시퀀스(- item)를 처리한다.
|
|
21
21
|
*/
|
|
22
|
+
/**
|
|
23
|
+
* YAML 스칼라의 감싼 따옴표를 벗긴다.
|
|
24
|
+
*
|
|
25
|
+
* WHY: 이 파서는 `out[key] = raw` 로 원문을 그대로 담고 있었다. YAML 에서
|
|
26
|
+
* `key: "value"` 는 문자열 `value` 를 뜻하는데, 따옴표째 저장되면 그 값을 쓰는
|
|
27
|
+
* 쪽에서 깨진다 — 그리고 vibe 가 배송하는 템플릿이 **따옴표를 쓰라고 가르친다**:
|
|
28
|
+
*
|
|
29
|
+
* schedule: "0 2 * * *" → `"0 2 * * *"` 가 crontab 에 들어가 cron 필드 5개를 깬다
|
|
30
|
+
* test_command: "npm test" → sh 가 `npm test` 라는 이름의 파일을 찾는다 (not found)
|
|
31
|
+
*
|
|
32
|
+
* 짝이 맞는 감싼 따옴표만 벗긴다 — 값 안의 따옴표나 짝이 안 맞는 것은 건드리지
|
|
33
|
+
* 않는다. 그건 사용자가 의도한 리터럴일 수 있다.
|
|
34
|
+
*/
|
|
35
|
+
function unquote(raw) {
|
|
36
|
+
if (raw.length < 2)
|
|
37
|
+
return raw;
|
|
38
|
+
const q = raw[0];
|
|
39
|
+
if ((q === '"' || q === "'") && raw.endsWith(q))
|
|
40
|
+
return raw.slice(1, -1);
|
|
41
|
+
return raw;
|
|
42
|
+
}
|
|
22
43
|
function parseFrontmatter(content) {
|
|
23
44
|
if (!content.startsWith('---'))
|
|
24
45
|
return {};
|
|
@@ -64,7 +85,7 @@ function parseFrontmatter(content) {
|
|
|
64
85
|
out[key] = raw
|
|
65
86
|
.slice(1, -1)
|
|
66
87
|
.split(',')
|
|
67
|
-
.map((s) => s.trim())
|
|
88
|
+
.map((s) => unquote(s.trim()))
|
|
68
89
|
.filter((s) => s.length > 0);
|
|
69
90
|
}
|
|
70
91
|
else if (raw === '') {
|
|
@@ -74,7 +95,7 @@ function parseFrontmatter(content) {
|
|
|
74
95
|
blockLines = [];
|
|
75
96
|
}
|
|
76
97
|
else {
|
|
77
|
-
out[key] = raw;
|
|
98
|
+
out[key] = unquote(raw);
|
|
78
99
|
}
|
|
79
100
|
}
|
|
80
101
|
flushBlock();
|
|
@@ -133,6 +154,8 @@ export function validateLoopDefinition(content) {
|
|
|
133
154
|
const discover = typeof fm['discover'] === 'string' ? fm['discover'].trim() : '';
|
|
134
155
|
const verify = typeof fm['verify'] === 'string' ? fm['verify'].trim() : '';
|
|
135
156
|
const test_command = typeof fm['test_command'] === 'string' ? fm['test_command'].trim() : undefined;
|
|
157
|
+
const visual_command = typeof fm['visual_command'] === 'string' ? fm['visual_command'].trim() : undefined;
|
|
158
|
+
const artifact_dir = typeof fm['artifact_dir'] === 'string' ? fm['artifact_dir'].trim() : undefined;
|
|
136
159
|
const maxIterRaw = fm['max_iterations'];
|
|
137
160
|
const isolation = typeof fm['isolation'] === 'string' ? fm['isolation'].trim() : 'none';
|
|
138
161
|
const session = typeof fm['session'] === 'string' ? fm['session'].trim() : 'continuous';
|
|
@@ -192,6 +215,25 @@ export function validateLoopDefinition(content) {
|
|
|
192
215
|
else if (test_command !== undefined) {
|
|
193
216
|
errors.push('test_command: verify=tests 일 때만 허용됩니다');
|
|
194
217
|
}
|
|
218
|
+
// 조건부 필드: visual_command iff verify === 'visual'
|
|
219
|
+
if (verify === 'visual') {
|
|
220
|
+
if (!visual_command) {
|
|
221
|
+
errors.push('visual_command: verify=visual 일 때 필수 필드입니다');
|
|
222
|
+
}
|
|
223
|
+
// 증거가 남지 않으면 `tests` 와 다를 것이 없다 — 나중에 사람이 볼 것이 있어야 한다
|
|
224
|
+
if (!artifact_dir) {
|
|
225
|
+
errors.push('artifact_dir: verify=visual 일 때 필수 필드입니다 — 스크린샷·diff 를 남길 위치. '
|
|
226
|
+
+ '증거가 남지 않으면 verify=tests 와 다를 것이 없습니다.');
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
if (visual_command !== undefined) {
|
|
231
|
+
errors.push('visual_command: verify=visual 일 때만 허용됩니다');
|
|
232
|
+
}
|
|
233
|
+
if (artifact_dir !== undefined) {
|
|
234
|
+
errors.push('artifact_dir: verify=visual 일 때만 허용됩니다');
|
|
235
|
+
}
|
|
236
|
+
}
|
|
195
237
|
// max_iterations 범위 검사
|
|
196
238
|
const maxIter = Number(maxIterRaw);
|
|
197
239
|
if (maxIterRaw !== undefined && maxIterRaw !== null && maxIterRaw !== '') {
|
|
@@ -227,6 +269,8 @@ export function validateLoopDefinition(content) {
|
|
|
227
269
|
pipeline,
|
|
228
270
|
verify: verify,
|
|
229
271
|
...(test_command !== undefined ? { test_command } : {}),
|
|
272
|
+
...(visual_command !== undefined ? { visual_command } : {}),
|
|
273
|
+
...(artifact_dir !== undefined ? { artifact_dir } : {}),
|
|
230
274
|
max_iterations: maxIter,
|
|
231
275
|
session: session,
|
|
232
276
|
isolation: isolation,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validateLoopDefinition.js","sourceRoot":"","sources":["../../../src/tools/loop/validateLoopDefinition.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"validateLoopDefinition.js","sourceRoot":"","sources":["../../../src/tools/loop/validateLoopDefinition.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -46,7 +46,8 @@ HISTORY=".vibe/metrics/loop-history.jsonl"
|
|
|
46
46
|
- **목표(goal)**: 루프가 0으로 만들려는 것 (예: "open 회귀 0건", "P1 lint 0건")
|
|
47
47
|
- **트리거**: `scheduled`(cron) / `manual` / `on-event`
|
|
48
48
|
- **발견(discover)**: 일거리를 어떻게 찾는가 — 명령 또는 지시
|
|
49
|
-
- **검증(verify)**: `ledger`(vibe.verify 경유, 기본) / `tests`(테스트 명령 exit code) /
|
|
49
|
+
- **검증(verify)**: `ledger`(vibe.verify 경유, 기본) / `tests`(테스트 명령 exit code) /
|
|
50
|
+
`visual`(렌더 결과 검사 exit code + `artifact_dir` 에 증거) / `none`(보고만)
|
|
50
51
|
- **격리(isolation)**: 병렬 항목이 파일을 수정하면 `worktree`, 아니면 `none`
|
|
51
52
|
- **세션(session)**: `continuous`(기본, 한 호출에서 여러 바퀴) / `per-iteration`
|
|
52
53
|
(한 바퀴만 — 반복은 스케줄러가 만든다, `max_iterations: 1` 필수)
|
|
@@ -90,6 +91,12 @@ node -e "import('{{VIBE_PATH_URL}}/node_modules/@su-record/vibe/dist/tools/loop/
|
|
|
90
91
|
6. VERIFY 완료 판정 — verify 모드별 결정론 기준:
|
|
91
92
|
· ledger: cat .vibe/metrics/run-ledger.json → verifyPassed === true 만 성공
|
|
92
93
|
· tests: 정의의 test_command 실행 → exit 0 만 성공
|
|
94
|
+
· visual: 정의의 visual_command 실행 → **exit 0 만 성공**.
|
|
95
|
+
산출물(스크린샷·diff)을 artifact_dir 에 남기고 그 경로를
|
|
96
|
+
종료 기록·인박스에 적는다 — 나중에 사람이 눈으로 확인할 것.
|
|
97
|
+
⛔ 모델이 스크린샷을 보고 "괜찮아 보인다"고 판정하는 것은
|
|
98
|
+
금지다. 그건 자기보고이고 게이트가 아니다. 판정은 exit code,
|
|
99
|
+
이미지는 증거 — 둘의 역할을 섞지 않는다.
|
|
93
100
|
· none: 판정 생략(보고만). "코드를 보니 잘 된 것 같다"는 판정이 아니다.
|
|
94
101
|
6-b. 회전 기록 node "$HOOKS_DIR/loop-ledger.js" iteration <name> <verified|unverified>
|
|
95
102
|
VERIFY 결과를 그대로 넣는다. 이어서 예산을 확인한다:
|
|
@@ -195,6 +195,22 @@ JUDGE는 이번 feature의 **신규 생성 파일** 기준으로 검증 코드
|
|
|
195
195
|
| `ralplan` | 같은 계약을 계획 단계에 적용 |
|
|
196
196
|
| `ultrawork` / `ulw` | `automationLevel: autonomous` + 병렬 ACT — 루프 시맨틱이 아니라 자율성·병렬성 축. **병렬 항목이 파일을 수정하면 항목별 worktree 격리 필수** (`vibe.loop` 의 `isolation` 축과 같은 규칙) |
|
|
197
197
|
|
|
198
|
+
### 시각 검증 (`verify: visual`)
|
|
199
|
+
코드가 도는 것과 화면이 맞는 것은 다르다. `tests` 만으로 도는 UI 루프는 **초록불을 켜면서 화면을 망가뜨릴 수 있다.** 그래서 렌더 결과를 완료 기준으로 삼는 모드를 둔다.
|
|
200
|
+
|
|
201
|
+
| 필드 | 역할 |
|
|
202
|
+
|---|---|
|
|
203
|
+
| `visual_command` | **게이트** — exit 0 만 성공 |
|
|
204
|
+
| `artifact_dir` | **증거** — 스크린샷·diff 를 남길 위치 (필수) |
|
|
205
|
+
|
|
206
|
+
⛔ **모델이 스크린샷을 보고 판정하는 것이 아니다.** 그건 자기보고이고, 이 문서가 처음부터 배제하는 바로 그것이다. 판정은 명령의 exit code 이고, 이미지는 나중에 사람이 확인할 증거다. 둘의 역할을 섞으면 게이트가 아니라 분위기가 된다.
|
|
207
|
+
|
|
208
|
+
`visual_command` 는 **임계값으로 떨어지는 검사**여야 한다 — 베이스라인 픽셀 diff(임계 %), 접근성 감사(axe/WCAG), DESIGN.md 토큰 드리프트(`vibe.design verify`). "잘 나왔는지 본다" 는 명령이 될 수 없다.
|
|
209
|
+
|
|
210
|
+
`artifact_dir` 을 필수로 둔 이유: 증거가 남지 않으면 `tests` 와 기능적으로 같아진다. 이 모드가 존재할 이유가 증거이므로, 없으면 정의를 거부한다.
|
|
211
|
+
|
|
212
|
+
**비용을 감수하는 선택이다.** 렌더·캡처·비교는 단위 테스트보다 느리고, 검증이 비쌀수록 세션당 도는 루프가 줄어든다(위 사다리 참조). UI 결과물이 완료의 정의인 루프에만 쓴다.
|
|
213
|
+
|
|
198
214
|
### 세션 축 — 한 호출에서 몇 바퀴를 도는가
|
|
199
215
|
| 값 | 동작 | 얻는 것 | 치르는 것 |
|
|
200
216
|
|---|---|---|---|
|
|
@@ -11,6 +11,10 @@ pipeline:
|
|
|
11
11
|
- vibe.spec
|
|
12
12
|
- vibe.run
|
|
13
13
|
- vibe.verify
|
|
14
|
+
# ledger(기본) | tests | visual | none
|
|
15
|
+
# visual: 렌더 결과를 완료 기준으로 삼는다. visual_command(게이트, exit 0)와
|
|
16
|
+
# artifact_dir(증거, 스크린샷·diff)이 함께 필요하다.
|
|
17
|
+
# 모델이 화면을 보고 판정하는 것이 아니다 — 판정은 exit code 다.
|
|
14
18
|
verify: ledger
|
|
15
19
|
max_iterations: 10
|
|
16
20
|
isolation: none
|