@su-record/vibe 2.9.20 → 2.9.22

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.
@@ -9,18 +9,18 @@ chain-next: []
9
9
 
10
10
  # vibe.contract — API Contract Drift Detection
11
11
 
12
- **Purpose**: SPEC에 적힌 외부 계약과 실제 구현이 어긋나면 즉시 잡는다. 테스트 통과계약 준수.
12
+ **Purpose**: catch divergence between the SPEC's external contract and the actual implementation. Passing tests contract preserved.
13
13
 
14
14
  ## Why this exists
15
15
 
16
- 바이브코딩의 숨은 약점: 구현이 자라면서 SPEC에 명시된 응답 shape에서 조용히 벗어난다. 시나리오 테스트는 통과해도 **외부 소비자는 깨진다**. 사람이 매번 SPEC 비교하기엔 마찰이 크므로 기계화.
16
+ Hidden vibe-coding weakness: as the implementation grows, response shapes drift away from what the SPEC documents. Scenario tests still pass — but **external consumers break**. Manual SPEC-vs-code review is high-friction, so mechanize it.
17
17
 
18
18
  ## Storage Contract
19
19
 
20
20
  ```
21
21
  .claude/vibe/contracts/
22
- <feature>.md # 계약 SSOT (SPEC에서 추출)
23
- <feature>.snapshot.md # 구현 스냅샷 (마지막 check 시점)
22
+ <feature>.md # contract SSOT (extracted from SPEC)
23
+ <feature>.snapshot.md # implementation snapshot (last check)
24
24
  ```
25
25
 
26
26
  ### Contract frontmatter schema
@@ -30,9 +30,9 @@ chain-next: []
30
30
  feature: string
31
31
  extracted-from: .claude/vibe/specs/<feature>.md
32
32
  extracted-at: ISO-8601
33
- source-spec-hash: sha256 # SPEC 변경 감지용
33
+ source-spec-hash: sha256 # for change detection
34
34
  endpoints:
35
- - id: unique-kebab-id # 예: get-user-by-id
35
+ - id: unique-kebab-id # e.g. get-user-by-id
36
36
  kind: http | graphql | event | function
37
37
  # http
38
38
  method: GET | POST | PUT | DELETE | PATCH
@@ -64,75 +64,75 @@ endpoints:
64
64
 
65
65
  ## Subcommands
66
66
 
67
- ### 1. `extract <feature>` — SPEC에서 계약 추출
67
+ ### 1. `extract <feature>` — pull contract out of the SPEC
68
68
 
69
- **단계**:
70
- 1. SPEC 파일 로드 (single file or split folder)
71
- 2. 다음 섹션을 순서대로 탐색:
69
+ **Steps**:
70
+ 1. Load SPEC file (single file or split folder)
71
+ 2. Search sections in this order:
72
72
  - `## API` / `## Endpoints` / `## Interface` / `## Contract`
73
- - Markdown 테이블 (method/path/request/response 헤더)
74
- - 코드 블록 안의 OpenAPI/JSON Schema 스니펫
75
- 3. 추출 실패(해당 섹션 없음) → **에러 없이 `no-contract` 상태 기록 종료**. 모든 feature가 API를 갖진 않음.
76
- 4. 추출 성공 → frontmatter 구조로 변환
77
- 5. `source-spec-hash`: SPEC 파일 내용의 sha256 (다음 extract 변경 감지)
78
- 6. `.claude/vibe/contracts/<feature>.md` 저장 (기존 파일이 있고 hash가 같으면 **no-op**)
79
-
80
- **주의**: 추출은 LLM 파싱. 신뢰도 낮은 필드는 `# unconfirmed` 주석 달아서 사용자가 검토 가능하게.
81
-
82
- ### 2. `check <feature>` — 계약 vs 구현 비교
83
-
84
- **단계**:
85
- 1. `.claude/vibe/contracts/<feature>.md` 로드. 없으면 **먼저 extract 제안**.
86
- 2. endpoint 대해 구현 탐색:
87
- - http: 프레임워크 감지 (Express, Fastify, Next.js API routes, Hono, ...)
88
- - graphql: resolver 파일 찾기
89
- - event: 프로듀서/컨슈머 코드
90
- - function: 모듈 export
91
- 3. 구현 시그니처/스키마를 추출계약과 비교
92
- 4. Drift 분류 (severity 표는 command file 참고)
93
- 5. 스냅샷 저장: `.claude/vibe/contracts/<feature>.snapshot.md` (현재 구현 상태)
94
-
95
- ### 3. `diff <feature>` — 이전 스냅샷 대비 변경만
96
-
97
- **단계**:
98
- 1. `.snapshot.md`가 없으면 " 실행" 안내 후 종료
99
- 2. 현재 구현 재추출 vs 기존 스냅샷 비교
100
- 3. **변경된 필드만** 출력 (ASCII diff 형식):
73
+ - Markdown tables (method/path/request/response headers)
74
+ - OpenAPI/JSON Schema snippets inside code blocks
75
+ 3. Extraction failure (no such section) → **exit cleanly with `no-contract` state**. Not every feature has an API.
76
+ 4. Successconvert to the frontmatter structure
77
+ 5. `source-spec-hash`: sha256 of SPEC content (for next extract to detect change)
78
+ 6. Save to `.claude/vibe/contracts/<feature>.md` (no-op if file exists with the same hash)
79
+
80
+ **Caveat**: extraction is LLM-driven. Mark low-confidence fields with `# unconfirmed` so the user can review.
81
+
82
+ ### 2. `check <feature>` — contract vs implementation
83
+
84
+ **Steps**:
85
+ 1. Load `.claude/vibe/contracts/<feature>.md`. If missing **suggest extract first**.
86
+ 2. For each endpoint, find implementation:
87
+ - http: detect framework (Express, Fastify, Next.js API routes, Hono, ...)
88
+ - graphql: locate resolver files
89
+ - event: producer/consumer code
90
+ - function: module export
91
+ 3. Extract implementation signature/schemacompare against contract
92
+ 4. Classify drift (severity table in command file)
93
+ 5. Persist snapshot at `.claude/vibe/contracts/<feature>.snapshot.md` (current implementation state)
94
+
95
+ ### 3. `diff <feature>` — changes since last snapshot
96
+
97
+ **Steps**:
98
+ 1. If `.snapshot.md` does not exist → say "first run" and exit
99
+ 2. Re-extract current implementation; compare to existing snapshot
100
+ 3. Output **only changed fields** in ASCII diff form:
101
101
  ```
102
102
  endpoints/get-user-by-id/response/200:
103
103
  - email: string
104
- + email: string | null ← nullability 추가 (P1 breaking)
105
- + phoneNumber: string ← 신규 필드 (P3 safe)
104
+ + email: string | null ← nullability added (P1 breaking)
105
+ + phoneNumber: string ← new field (P3 safe)
106
106
  ```
107
- 4. 드리프트 있으면 `/vibe.regress register --from-contract` 자동 호출
107
+ 4. On any drift, auto-call `/vibe.regress register --from-contract`
108
108
 
109
109
  ## Drift Severity Matrix
110
110
 
111
- (command file 표와 동일 변경 양쪽 갱신)
111
+ (matches command file keep both in sync on edits)
112
112
 
113
113
  ## Integration Points
114
114
 
115
115
  ### From /vibe.spec
116
116
 
117
- SPEC 작성 완료 직후 자동 호출:
117
+ Auto-invoke right after the SPEC is written:
118
118
  ```
119
119
  Load skill `vibe-contract` with: extract <feature>
120
120
  ```
121
- 실패해도 `/vibe.spec`은 계속 진행 (계약 추출은 옵션). 성공 `/vibe.run`이 계약을 참조.
121
+ Failure does not stop `/vibe.spec` (extraction is optional). On success, `/vibe.run` references this contract.
122
122
 
123
123
  ### From /vibe.verify
124
124
 
125
- 모든 scenario pass 후 자동 체인:
125
+ After all scenarios pass:
126
126
  ```
127
127
  Load skill `vibe-contract` with: check <feature>
128
128
  ```
129
- - drift 없음 → verify 통과 유지
130
- - P1 drift → verify 실패로 강등, regress 자동 등록
131
- - P2/P3 drift → 경고만, verify 통과 유지
129
+ - no drift → verify still passes
130
+ - P1 drift → demote verify to fail; auto-register
131
+ - P2 / P3 drift → warning only; verify still passes
132
132
 
133
133
  ### To /vibe.regress
134
134
 
135
- P1 drift 발견 시:
135
+ On P1 drift:
136
136
  ```
137
137
  Load skill `vibe-regress` with:
138
138
  subcommand: register --from-contract
@@ -143,15 +143,15 @@ Load skill `vibe-regress` with:
143
143
 
144
144
  ## Framework Detection Rules
145
145
 
146
- HTTP framework 감지 순서:
147
- 1. `package.json` dependencies에서: `next` → Next.js API routes
146
+ HTTP framework detection order:
147
+ 1. `package.json` dependencies: `next` → Next.js API routes
148
148
  2. `fastify` → Fastify
149
149
  3. `express` → Express
150
150
  4. `hono` → Hono
151
151
  5. `@nestjs/core` → NestJS
152
- 6. 감지 실패 → user에게 질문 manual mapping
152
+ 6. None detectedask user for manual mapping
153
153
 
154
- 감지 프레임워크의 **라우트 정의 패턴**을 Grep으로 찾아 endpoint 매핑:
154
+ After detection, grep for each framework's **route definition pattern** to map endpoints:
155
155
  - Next.js: `pages/api/**` or `app/api/**/route.ts`
156
156
  - Express: `app.get|post|put|delete|patch\(`
157
157
  - Fastify: `fastify.get|post|...` or route configuration
@@ -159,8 +159,8 @@ HTTP framework 감지 순서:
159
159
 
160
160
  ## Done Criteria
161
161
 
162
- - [ ] `extract`가 API 섹션 없는 SPEC에서 에러 내지 않음
163
- - [ ] `source-spec-hash` 기반 re-extract 스킵
164
- - [ ] `check`는 drift severity + 위치(file:line) 명시
165
- - [ ] P1 drift 100% `/vibe.regress` 자동 등록
166
- - [ ] 프레임워크 감지 실패 silently skip 금지반드시 user 질문
162
+ - [ ] `extract` does not error on SPEC without an API section
163
+ - [ ] `source-spec-hash`-based re-extract is a no-op when unchanged
164
+ - [ ] `check` reports each drift with severity + location (file:line)
165
+ - [ ] P1 drift always invokes `/vibe.regress`
166
+ - [ ] On framework detection failure, ask the userdo not silently skip
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: vibe-regress
3
3
  tier: core
4
- description: "Regression test auto-evolution. Registers bugs (auto from /vibe.verify failures or manual), generates preventive vitest/jest files from bug records, clusters repeated patterns (3+ same root-cause-tag) into shared tests, and imports historical `fix:` commits from git log. Storage: .claude/vibe/regressions/<slug>.md. Must use this skill when user runs /vibe.regress, when /vibe.verify produces a failure, or when the user says 'don't let this happen again' / '이 버그 다시는' / 'regression test' / '회귀 테스트'."
4
+ description: "Regression test auto-evolution. Registers bugs (auto from /vibe.verify failures or manual), generates preventive vitest/jest files from bug records, clusters repeated patterns (3+ same root-cause-tag) into shared tests, and imports historical `fix:` commits from git log. Storage: .claude/vibe/regressions/<slug>.md. Must use this skill when user runs /vibe.regress, when /vibe.verify produces a failure, or when the user says 'don't let this happen again' / 'regression test' / '회귀 테스트'."
5
5
  triggers: [regress, regression, "회귀", "다시는", "반복 버그", "fix commit"]
6
6
  priority: 70
7
7
  chain-next: []
@@ -9,92 +9,92 @@ chain-next: []
9
9
 
10
10
  # vibe.regress — Regression Auto-Evolution
11
11
 
12
- **Purpose**: 같은 버그를 잡지 않는다. 버그를 잡을 때마다 예방 테스트가 자라난다.
12
+ **Purpose**: never fix the same bug twice. Each fix grows a preventive test.
13
13
 
14
14
  ## Why this exists
15
15
 
16
- 바이브코딩의 고전적 약점: LLM이 같은 클래스의 버그를 매번 새로 만든다. 회귀 테스트는 이를 기계적으로 막는 유일한 장치. 단, 사람이 매번 회귀 테스트를 쓰면 건너뛰게 그래서 자동화.
16
+ A classic vibe-coding weakness: LLMs reintroduce bugs of the same class. Regression tests are the only mechanical defense. But if the human has to write the test every time, it gets skipped so automate.
17
17
 
18
18
  ## Storage Contract
19
19
 
20
20
  ```
21
21
  .claude/vibe/regressions/
22
- <bug-slug>.md # 하나의 버그 = 하나의 파일
23
- _cluster-<tag>.md # cluster 서브커맨드가 생성한 공통 테스트 설계
22
+ <bug-slug>.md # one file per bug
23
+ _cluster-<tag>.md # shared-test design produced by `cluster`
24
24
  ```
25
25
 
26
- ### Frontmatter schema (엄격)
26
+ ### Frontmatter schema (strict)
27
27
 
28
28
  ```yaml
29
- slug: string # kebab-case, 글로벌 유일
30
- symptom: string # 1줄, 사용자 관점
31
- root-cause-tag: enum # 아래 허용 태그만
32
- fix-commit: string # git hash (없으면 "pending")
33
- test-path: string # 생성된 테스트 파일 경로 (없으면 "pending")
29
+ slug: string # kebab-case, globally unique
30
+ symptom: string # one line, user-facing
31
+ root-cause-tag: enum # only the allowed tags below
32
+ fix-commit: string # git hash (or "pending")
33
+ test-path: string # generated test file path (or "pending")
34
34
  status: open | test-generated | resolved
35
35
  registered: YYYY-MM-DD
36
- feature: string # 연관 feature 이름 (SPEC과 매칭)
36
+ feature: string # related feature name (matches SPEC)
37
37
  ```
38
38
 
39
39
  ### Allowed `root-cause-tag` values
40
40
 
41
- 클러스터링의 기반이므로 **미리 정의된 집합만** 사용:
41
+ Clustering depends on this, so use **only the predefined set**:
42
42
 
43
- - `timezone` — 시간대/DST/off-by-one
44
- - `nullability` — null/undefined/empty 처리
45
- - `concurrency` — race condition, 동시성
46
- - `boundary` — off-by-one, edge value
47
- - `encoding` — charset, URL encoding, escape
48
- - `validation` — 입력 검증 누락
49
- - `auth` — 인증/권한 로직
50
- - `state-sync` — 클라이언트/서버 상태 불일치
51
- - `integration` — 외부 API 호출 실패
52
- - `type-narrow` — TypeScript 타입 좁히기 실수
53
- - `other` — 위에 맞을 (나중에 태그 추가)
43
+ - `timezone` — timezone / DST / off-by-one in time
44
+ - `nullability` — null / undefined / empty handling
45
+ - `concurrency` — race conditions
46
+ - `boundary` — off-by-one, edge values
47
+ - `encoding` — charset, URL encoding, escaping
48
+ - `validation` — missing input validation
49
+ - `auth` — authn/authz logic
50
+ - `state-sync` — client/server state mismatch
51
+ - `integration` — external API call failure
52
+ - `type-narrow` — TypeScript type narrowing mistake
53
+ - `other` — when nothing fits (add new tags later)
54
54
 
55
- **규칙**: 태그가 필요하면 기존 태그에 억지로 맞추지 말고 `other`로 등록한 뒤, `other`가 3 이상 쌓이면 사용자에게 태그 추가를 제안.
55
+ **Rule**: if a new tag is needed, do not force-fit into an existing one — register as `other`. Once `other` reaches 3 entries, propose adding a new tag.
56
56
 
57
57
  ## Subcommands
58
58
 
59
- ### 1. `register "<symptom>"` — 수동 등록
59
+ ### 1. `register "<symptom>"` — manual registration
60
60
 
61
- 대부분은 자동 호출되므로 수동 사용은 드뭅니다 (verify 실패 밖에서 발견된 버그, 또는 프로덕션 이슈용).
61
+ Most calls are automatic; manual use is rare (bugs found outside `/vibe.verify`, or production incidents).
62
62
 
63
- **단계**:
64
- 1. `getCurrentTime`으로 오늘 날짜 확보
65
- 2. `git log -1 --format=%H`으로 현재 커밋 해시 (fix-commit 후보)
66
- 3. Claude가 대화로 다음을 뽑아냄:
63
+ **Steps**:
64
+ 1. `getCurrentTime` for today's date
65
+ 2. `git log -1 --format=%H` for current commit hash (fix-commit candidate)
66
+ 3. Conversation extracts:
67
67
  - Reproduction steps (Given/When/Then)
68
- - Root cause 1문단
69
- - Fix 설명
70
- 4. `root-cause-tag`는 허용 집합에서 **자동 추론 사용자에게 확인**. 애매하면 `other`.
71
- 5. slug 생성: symptom에서 핵심어 kebab-case, 충돌 `-2` 접미사
72
- 6. `.claude/vibe/regressions/<slug>.md` 작성 (status: `open`)
73
-
74
- ### 2. `generate <slug>` — 예방 테스트 생성
75
-
76
- **단계**:
77
- 1. bug 파일 읽기
78
- 2. 테스트 스택 감지:
79
- - `package.json`의 `devDependencies`에서 `vitest` > `jest`
80
- - 없으면 **user에게 질문 후 중단**
81
- 3. 테스트 위치 결정:
82
- - feature의 구현 파일 옆 `__tests__/` 또는
83
- - 프로젝트의 기존 test dir (vitest config.test.include 확인)
84
- 4. 파일명: `<original-file>.regression.test.ts`
85
- 5. 내용: `templates/test-vitest.md` 또는 `templates/test-jest.md` 템플릿에서 치환
86
- 6. bug 파일 frontmatter 업데이트: `test-path`, `status: test-generated`
87
- 7. **생성 즉시 테스트 실행** 실패해야 정상 (아직 수정 됨이면) 또는 통과 (수정 완료됨이면). 결과를 frontmatter에 기록.
88
-
89
- ### 3. `list` — 미해결 목록
68
+ - Root-cause paragraph
69
+ - Fix description
70
+ 4. `root-cause-tag` is **inferred from the allowed set, then confirmed with the user**. If unclear → `other`.
71
+ 5. Generate slug: kebab-case keywords from the symptom; on collision append `-2`
72
+ 6. Write `.claude/vibe/regressions/<slug>.md` (status: `open`)
73
+
74
+ ### 2. `generate <slug>` — generate preventive test
75
+
76
+ **Steps**:
77
+ 1. Read bug file
78
+ 2. Detect test stack:
79
+ - From `package.json` `devDependencies`: prefer `vitest` over `jest`
80
+ - If neither **ask user, then stop**
81
+ 3. Decide test location:
82
+ - Sibling `__tests__/` next to the implementation file, OR
83
+ - The project's existing test dir (vitest config `test.include`)
84
+ 4. File name: `<original-file>.regression.test.ts`
85
+ 5. Body: render `templates/test-vitest.md` or `templates/test-jest.md`
86
+ 6. Update bug frontmatter: `test-path`, `status: test-generated`
87
+ 7. **Run the test immediately**should fail (if not yet fixed) or pass (if fixed). Record outcome in frontmatter.
88
+
89
+ ### 3. `list` — open items
90
90
 
91
91
  ```
92
- /vibe.regress list # status != resolved 전부
93
- /vibe.regress list --feature login # feature
94
- /vibe.regress list --tag timezone # tag
92
+ /vibe.regress list # status != resolved
93
+ /vibe.regress list --feature login # filter by feature
94
+ /vibe.regress list --tag timezone # filter by tag
95
95
  ```
96
96
 
97
- 터미널 표:
97
+ Terminal table:
98
98
 
99
99
  ```
100
100
  SLUG FEATURE TAG STATUS AGE
@@ -102,36 +102,36 @@ login-jwt-expiry-off-by-one login timezone test-generated 3d
102
102
  cart-stock-race-double-deduct cart concurrency open 1d
103
103
  ```
104
104
 
105
- ### 4. `import` — git log 역추적
105
+ ### 4. `import` — backfill from git log
106
106
 
107
- **단계**:
107
+ **Steps**:
108
108
  1. `git log --grep='^fix:' --format='%H|%s|%ci' --since=<last-import-date>`
109
- - `last-import-date`는 `.claude/vibe/regressions/.import-cursor` 파일에서 읽음 (없으면 90 )
110
- 2. 커밋에 대해:
111
- - 이미 같은 `fix-commit`을 가진 bug 파일이 있으면 **스킵**
112
- - 없으면 커밋 메시지/diff에서 symptom + root-cause-tag 추론 (LLM 호출)
113
- - 신규 bug.md 작성 (status: `resolved` — 이미 고쳐졌으므로)
114
- 3. 완료 `.import-cursor` 갱신
115
- 4. 새로 import된 항목에 대해 사용자에게 `generate` 제안
109
+ - `last-import-date` lives in `.claude/vibe/regressions/.import-cursor` (defaults to 90 days ago)
110
+ 2. For each commit:
111
+ - If a bug file with the same `fix-commit` already exists **skip**
112
+ - Otherwise infer symptom + root-cause-tag from message/diff (LLM call)
113
+ - Write a new bug file (status: `resolved` — already fixed)
114
+ 3. Update `.import-cursor`
115
+ 4. Suggest `generate` for newly imported entries
116
116
 
117
- **주의**: `fix:` 커밋이 아닌 일반 커밋은 **무시**. Conventional Commits 규약을 사용하지 않는 프로젝트는 `--grep-pattern` 옵션으로 오버라이드.
117
+ **Note**: only `fix:` commits are considered. Projects not using Conventional Commits can override with `--grep-pattern`.
118
118
 
119
- ### 5. `cluster` — 반복 패턴 승격
119
+ ### 5. `cluster` — promote recurring patterns
120
120
 
121
- **단계**:
122
- 1. 모든 bug 파일의 `root-cause-tag` 집계
123
- 2. **같은 태그가 3 이상**이면 cluster 후보
124
- 3. 후보에 대해:
125
- - 3 bug의 reproduction을 LLM에게 주고 "공통 원인과 공통 테스트 케이스"를 추출
126
- - `_cluster-<tag>.md` 파일 생성 (기존 bug 파일들의 slug를 링크)
127
- - 공통 테스트 skeleton `<project-test-dir>/_cluster-<tag>.regression.test.ts`로 제안 (사용자 승인 생성)
128
- 4. 클러스터 생성 원본 bug 파일은 **삭제하지 않음** 이력 보존
121
+ **Steps**:
122
+ 1. Aggregate `root-cause-tag` across all bug files
123
+ 2. **A tag with ≥3 entries** becomes a cluster candidate
124
+ 3. For each candidate:
125
+ - Feed the 3 reproductions to an LLM to extract the common cause and shared test cases
126
+ - Write `_cluster-<tag>.md` (links to the original bug slugs)
127
+ - Propose a shared test skeleton at `<project-test-dir>/_cluster-<tag>.regression.test.ts` (create only with user approval)
128
+ 4. Original bug files are **not deleted**history preserved
129
129
 
130
- **중요**: cluster 자동 실행 됨. 사용자가 명시적으로 호출해야 (과도한 추상화 방지).
130
+ **Important**: `cluster` is never automatic. Users invoke it explicitly to avoid premature abstraction.
131
131
 
132
132
  ## Integration with /vibe.verify
133
133
 
134
- `/vibe.verify` 실패 verify가 다음을 호출:
134
+ When `/vibe.verify` fails it calls:
135
135
 
136
136
  ```
137
137
  Load skill `vibe-regress` with: register --from-verify
@@ -141,34 +141,34 @@ Load skill `vibe-regress` with: register --from-verify
141
141
  <location>: {file:line}
142
142
  ```
143
143
 
144
- `--from-verify` 플래그 동작:
144
+ `--from-verify` behavior:
145
145
  - symptom = scenario name + error summary
146
- - feature = 전달된 feature name
147
- - root-cause-tag = error pattern에서 자동 추론 (애매하면 `other`)
146
+ - feature = forwarded feature name
147
+ - root-cause-tag = inferred from error pattern (default `other` if unclear)
148
148
  - status = `open`
149
- - **사용자 확인 없이 등록** (verify 실패 상황은 이미 주의 집중 중이라 마찰 최소화가 중요)
149
+ - **Skip user confirmation** the user is already attentive in a verify-failure context, and friction must be minimized
150
150
 
151
151
  ## Integration with /vibe.run
152
152
 
153
- `/vibe.run "<feature>"` 시작 시:
153
+ At the start of `/vibe.run "<feature>"`:
154
154
 
155
- 1. `ls .claude/vibe/regressions/*.md`에서 `feature: <feature-name>` + `status != resolved` 필터
156
- 2. 미해결 있으면 경고:
155
+ 1. Filter `.claude/vibe/regressions/*.md` for `feature: <feature-name>` + `status != resolved`
156
+ 2. If any open items:
157
157
  ```
158
158
  ⚠️ Open regressions for this feature:
159
159
  - login-jwt-expiry-off-by-one (timezone, 3d old)
160
160
  - login-session-leak (auth, 1w old)
161
-
161
+
162
162
  Fix these before adding new behavior? [y/N]
163
163
  ```
164
- 3. `y` → `/vibe.regress generate`로 체인 (미생성 항목)
165
- 4. `N` → 계속 진행 (ultrawork 모드는 자동 `N` + TODO 기록)
164
+ 3. `y` → chain to `/vibe.regress generate` for items not yet test-generated
165
+ 4. `N` → continue (ultrawork mode auto-`N`, records TODO)
166
166
 
167
167
  ## Done Criteria
168
168
 
169
- - [ ] 서브커맨드가 지정 없이 호출되면 usage 표시
170
- - [ ] frontmatter 스키마 엄격 준수 (누락 필드 있으면 거부)
171
- - [ ] `root-cause-tag`가 허용 집합 값이면 경고 + `other`로 강제
172
- - [ ] `generate` 테스트를 **실제로 실행**하여 결과 검증
173
- - [ ] `import`는 중복 스킵 (fix-commit 해시 기준)
174
- - [ ] `cluster`는 3개 미만이면 아무것도 (false positive 방지)
169
+ - [ ] Subcommand-less invocation prints usage
170
+ - [ ] Frontmatter schema strictly enforced (missing fields rejected)
171
+ - [ ] `root-cause-tag` outside the allowed set warn + force `other`
172
+ - [ ] After `generate`, the test is **actually run** to verify
173
+ - [ ] `import` deduplicates by `fix-commit` hash
174
+ - [ ] `cluster` does nothing under 3 entries (false-positive guard)
@@ -400,21 +400,21 @@ Read ~/.claude/vibe/languages/typescript-react.md
400
400
  Before spawning any research agents, check for a prior persisted dataset:
401
401
 
402
402
  ```bash
403
- # Slug = kebab-case of feature/topic, max 50 chars
403
+ # Slug = kebab-case of the feature/topic, max 50 chars
404
404
  ls .claude/vibe/research/<slug>/paper.md 2>/dev/null
405
405
  ```
406
406
 
407
407
  **If `paper.md` exists:**
408
408
  1. Read `.claude/vibe/research/<slug>/paper.md`
409
409
  2. Read `.claude/vibe/research/<slug>/awesome-list.md` (if present)
410
- 3. Inject the **Findings**, **Recommendation**, and **Security considerations** sections into SPEC Context verbatim, prefixed with `> Source: .claude/vibe/research/<slug>/paper.md (cached {{FILE_MTIME}})`
410
+ 3. Inject the **Findings**, **Recommendation**, and **Security considerations** sections verbatim into SPEC Context, prefixed with `> Source: .claude/vibe/research/<slug>/paper.md (cached {{FILE_MTIME}})`
411
411
  4. **Skip step 3** (parallel research) entirely — do not re-run GPT/Gemini/Claude agents
412
- 5. Show message: `✅ Research cache hit: <slug> (saved ~30s of LLM calls)`
412
+ 5. Print: `✅ Research cache hit: <slug> (saved ~30s of LLM calls)`
413
413
 
414
414
  **Cache invalidation:**
415
- - User passes `--refresh-research` → delete dir, run step 3 fresh
416
- - `paper.md` mtime older than 30 days → warn user, ask to refresh or reuse
417
- - Stack in `paper.md` header differs from current stack → auto-refresh
415
+ - User passes `--refresh-research` → delete dir, rerun step 3 from scratch
416
+ - `paper.md` mtime older than 30 days → warn the user, ask to refresh or reuse
417
+ - `stack` in `paper.md` frontmatter differs from current stack → auto-refresh
418
418
 
419
419
  **If `paper.md` does NOT exist:**
420
420
  Proceed to step 3. After step 3 completes, the synthesizer **must** write the 3 artifacts (see `parallel-research/orchestrator.md` Phase 5) so the next `/vibe.spec` run on this topic hits the cache.
@@ -565,19 +565,19 @@ Task(subagent_type="ui-layout-architect",
565
565
 
566
566
  ### 3.9 Persist Research Cache (AFTER research completes, BEFORE SPEC write)
567
567
 
568
- > The "no Write during research" rule (step 3) does **not** apply here — research is done, artifacts are safe to persist.
568
+ > The "no Write during research" rule from step 3 does **not** apply here — research is done; artifacts are safe to persist.
569
569
 
570
- After parallel research + UI/UX intelligence complete and before writing the SPEC, save the merged research into `.claude/vibe/research/<slug>/`:
570
+ After parallel research + UI/UX intelligence complete, before writing the SPEC, save the merged research to `.claude/vibe/research/<slug>/`:
571
571
 
572
572
  1. Compute slug: kebab-case of feature name, max 50 chars
573
573
  2. Write **three files** using templates from `parallel-research/templates/`:
574
574
  - `.claude/vibe/research/<slug>/synthesis.md` — raw merged findings (all agent outputs)
575
- - `.claude/vibe/research/<slug>/awesome-list.md` — curated links/repos/patterns (each entry needs a one-line "why"; drop entries without it)
575
+ - `.claude/vibe/research/<slug>/awesome-list.md` — curated links/repos/patterns (every entry needs a one-line "why"; drop entries without one)
576
576
  - `.claude/vibe/research/<slug>/paper.md` — structured survey (Abstract → Background → Method → Findings → Recommendation → Security → References)
577
- 3. Include a frontmatter header in `paper.md` with `stack:` field so step 2.9 can detect stack drift
578
- 4. If the directory already exists (user ran `--refresh-research`), overwrite
577
+ 3. Include a frontmatter header in `paper.md` with a `stack:` field so step 2.9 can detect stack drift
578
+ 4. If the directory already exists (user passed `--refresh-research`), overwrite
579
579
 
580
- This makes the next `/vibe.spec` or `/vibe.research` invocation on the same topic hit the cache at step 2.9.
580
+ This makes the next `/vibe.spec` (or future `/vibe.research`) invocation on the same topic hit the cache at step 2.9.
581
581
 
582
582
  ### 4. Write SPEC Document (PTCF Structure)
583
583