@su-record/vibe 3.2.60 → 3.2.62
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/CLAUDE.md +12 -4
- package/README.en.md +1 -1
- package/README.md +1 -1
- package/dist/cli/commands/codex-proxy.d.ts.map +1 -1
- package/dist/cli/commands/codex-proxy.js +8 -7
- package/dist/cli/commands/codex-proxy.js.map +1 -1
- package/dist/cli/commands/config.d.ts.map +1 -1
- package/dist/cli/commands/config.js +19 -18
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/evolution.d.ts.map +1 -1
- package/dist/cli/commands/evolution.js +35 -34
- package/dist/cli/commands/evolution.js.map +1 -1
- package/dist/cli/commands/figma.d.ts.map +1 -1
- package/dist/cli/commands/figma.js +21 -20
- package/dist/cli/commands/figma.js.map +1 -1
- package/dist/cli/commands/info.js +4 -4
- package/dist/cli/commands/info.js.map +1 -1
- package/dist/cli/commands/llm.d.ts.map +1 -1
- package/dist/cli/commands/llm.js +11 -10
- package/dist/cli/commands/llm.js.map +1 -1
- package/dist/cli/commands/remove.js +13 -13
- package/dist/cli/commands/remove.js.map +1 -1
- package/dist/cli/commands/sentinel.d.ts +10 -1
- package/dist/cli/commands/sentinel.d.ts.map +1 -1
- package/dist/cli/commands/sentinel.js +51 -49
- package/dist/cli/commands/sentinel.js.map +1 -1
- package/dist/cli/commands/skills.js +3 -3
- package/dist/cli/commands/skills.js.map +1 -1
- package/dist/cli/commands/slack.d.ts.map +1 -1
- package/dist/cli/commands/slack.js +16 -15
- package/dist/cli/commands/slack.js.map +1 -1
- package/dist/cli/commands/stats.d.ts.map +1 -1
- package/dist/cli/commands/stats.js +30 -29
- package/dist/cli/commands/stats.js.map +1 -1
- package/dist/cli/commands/telegram.d.ts.map +1 -1
- package/dist/cli/commands/telegram.js +26 -25
- package/dist/cli/commands/telegram.js.map +1 -1
- package/dist/cli/postinstall/main.d.ts +11 -0
- package/dist/cli/postinstall/main.d.ts.map +1 -1
- package/dist/cli/postinstall/main.js +29 -0
- package/dist/cli/postinstall/main.js.map +1 -1
- package/dist/infra/lib/browser/launch.d.ts.map +1 -1
- package/dist/infra/lib/browser/launch.js +0 -1
- package/dist/infra/lib/browser/launch.js.map +1 -1
- package/dist/tools/docs/agentsMd.d.ts +45 -0
- package/dist/tools/docs/agentsMd.d.ts.map +1 -0
- package/dist/tools/docs/agentsMd.js +51 -0
- package/dist/tools/docs/agentsMd.js.map +1 -0
- package/dist/tools/docs/cacheSurface.d.ts +37 -0
- package/dist/tools/docs/cacheSurface.d.ts.map +1 -0
- package/dist/tools/docs/cacheSurface.js +98 -0
- package/dist/tools/docs/cacheSurface.js.map +1 -0
- package/dist/tools/memory/getMemoryGraph.d.ts.map +1 -1
- package/dist/tools/memory/getMemoryGraph.js.map +1 -1
- package/dist/tools/spec/index.d.ts +2 -0
- package/dist/tools/spec/index.d.ts.map +1 -1
- package/dist/tools/spec/index.js +2 -0
- package/dist/tools/spec/index.js.map +1 -1
- package/dist/tools/spec/specGenerator.js +3 -5
- package/dist/tools/spec/specGenerator.js.map +1 -1
- package/dist/tools/spec/specLifecycle.d.ts +40 -0
- package/dist/tools/spec/specLifecycle.d.ts.map +1 -0
- package/dist/tools/spec/specLifecycle.js +147 -0
- package/dist/tools/spec/specLifecycle.js.map +1 -0
- package/dist/tools/spec/validateSpecDocument.d.ts.map +1 -1
- package/dist/tools/spec/validateSpecDocument.js +13 -0
- package/dist/tools/spec/validateSpecDocument.js.map +1 -1
- package/hooks/scripts/figma-extract.js +6 -2
- package/hooks/scripts/figma-to-scss.js +10 -3
- package/hooks/scripts/llm-orchestrate.js +2 -2
- package/hooks/scripts/session-start.js +30 -23
- package/hooks/scripts/utils.js +4 -5
- package/package.json +19 -9
- package/skills/vibe.docs/references/agent.md +4 -0
- package/vibe/rules/prefix-cache-surface.md +98 -0
- package/vibe/templates/spec-template.md +16 -1
|
@@ -96,19 +96,11 @@ async function main() {
|
|
|
96
96
|
getLatestVersionCached(),
|
|
97
97
|
]);
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const iterMod = await import(`${LIB_BASE_P}IterationTracker.js`);
|
|
105
|
-
const progressLine = iterMod.getProgressSummary(PROJECT_DIR);
|
|
106
|
-
if (progressLine) {
|
|
107
|
-
console.log(`\n📋 ${progressLine} — resume full context: /vibe.continue`);
|
|
108
|
-
}
|
|
109
|
-
} catch { /* progress index is best-effort */ }
|
|
110
|
-
|
|
111
|
-
console.log('\n[Memory Index — bodies on demand via recall_memory]');
|
|
99
|
+
// ─── 안정 블록 먼저 ────────────────────────────────────────────────
|
|
100
|
+
// 세션마다 값이 달라지는 것(현재 시각·진행 카운터·버전 체크)은 아래 휘발 블록으로
|
|
101
|
+
// 모아 뒤에 붙인다. 세션 컨텍스트의 앞부분을 가능한 한 세션 간 동일하게 유지하려는
|
|
102
|
+
// 배치다 — 휘발 데이터를 앞에 두면 어떤 합성 방식에서도 이득이 없다.
|
|
103
|
+
console.log('[Memory Index — bodies on demand via recall_memory]');
|
|
112
104
|
console.log(memories.content[0].text);
|
|
113
105
|
|
|
114
106
|
// Phase 3 — Recipes + anti-patterns 인덱스 (post-task curation)
|
|
@@ -130,15 +122,6 @@ async function main() {
|
|
|
130
122
|
}
|
|
131
123
|
} catch { /* curation is best-effort */ }
|
|
132
124
|
|
|
133
|
-
// Version check
|
|
134
|
-
if (latestVersion) {
|
|
135
|
-
const currentVersion = getCurrentVersion();
|
|
136
|
-
if (currentVersion && compareVersions(latestVersion, currentVersion) > 0) {
|
|
137
|
-
console.log(`\n⬆️ Harness update available: v${currentVersion} → v${latestVersion}`);
|
|
138
|
-
console.log(' Run: vibe upgrade');
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
125
|
// Scope sync — 기본 OFF (opt-in: scopeGuard.enabled=true). SSOT: scope-from-spec.js.
|
|
143
126
|
try {
|
|
144
127
|
const { syncScopeFile, isScopeGuardEnabled } = await import('./lib/scope-from-spec.js');
|
|
@@ -214,8 +197,32 @@ async function main() {
|
|
|
214
197
|
|
|
215
198
|
// Evolution 상태 요약은 제거 — evolution 은 동결(opt-in) 상태이며
|
|
216
199
|
// 사용자는 `vibe evolution` CLI 로 명시적으로 조회한다 (P3-3).
|
|
200
|
+
|
|
201
|
+
// ─── 휘발 블록 마지막 ──────────────────────────────────────────────
|
|
202
|
+
// 현재 시각·진행 카운터·버전 체크는 세션마다 값이 달라진다. 위의 안정 블록을
|
|
203
|
+
// 앞에 두기 위해 여기로 모았다. 내용은 이전과 동일하고 순서만 바뀐다.
|
|
204
|
+
console.log(`\n${time.content[0].text}`);
|
|
205
|
+
|
|
206
|
+
try {
|
|
207
|
+
const LIB_BASE_P = (await import('./utils.js')).getLibBaseUrl();
|
|
208
|
+
const iterMod = await import(`${LIB_BASE_P}IterationTracker.js`);
|
|
209
|
+
const progressLine = iterMod.getProgressSummary(PROJECT_DIR);
|
|
210
|
+
if (progressLine) {
|
|
211
|
+
console.log(`📋 ${progressLine} — resume full context: /vibe.continue`);
|
|
212
|
+
}
|
|
213
|
+
} catch { /* progress index is best-effort */ }
|
|
214
|
+
|
|
215
|
+
if (latestVersion) {
|
|
216
|
+
const currentVersion = getCurrentVersion();
|
|
217
|
+
if (currentVersion && compareVersions(latestVersion, currentVersion) > 0) {
|
|
218
|
+
console.log(`\n⬆️ Harness update available: v${currentVersion} → v${latestVersion}`);
|
|
219
|
+
console.log(' Run: vibe upgrade');
|
|
220
|
+
}
|
|
221
|
+
}
|
|
217
222
|
} catch (e) {
|
|
218
|
-
|
|
223
|
+
// 훅 실패를 stdout 으로 보내면 "실패 신호" 가 아니라 모델에게 주입되는
|
|
224
|
+
// 컨텍스트 문자열이 된다 — 가드의 생사가 관측 불가능해진다.
|
|
225
|
+
console.error('[Session] Error:', e.message);
|
|
219
226
|
}
|
|
220
227
|
}
|
|
221
228
|
|
package/hooks/scripts/utils.js
CHANGED
|
@@ -372,12 +372,11 @@ const DEFAULT_COST = { input: 0.003, output: 0.010 };
|
|
|
372
372
|
*
|
|
373
373
|
* @param {string} provider - 프로바이더 (gpt, antigravity)
|
|
374
374
|
* @param {string} model - 모델명
|
|
375
|
-
* @param {
|
|
376
|
-
*
|
|
377
|
-
* @param {number} durationMs - 호출 소요 시간
|
|
378
|
-
* @param {boolean} cached - 캐시 히트 여부
|
|
375
|
+
* @param {{ inputLen: number, outputLen: number, durationMs: number, cached: boolean }} call
|
|
376
|
+
* inputLen/outputLen 은 문자 수, durationMs 는 호출 소요 시간, cached 는 캐시 히트 여부
|
|
379
377
|
*/
|
|
380
|
-
export function logLlmCost(provider, model,
|
|
378
|
+
export function logLlmCost(provider, model, call) {
|
|
379
|
+
const { inputLen, outputLen, durationMs, cached } = call;
|
|
381
380
|
try {
|
|
382
381
|
if (fs.existsSync(LLM_COST_PATH)) {
|
|
383
382
|
const stat = fs.statSync(LLM_COST_PATH);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@su-record/vibe",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.62",
|
|
4
4
|
"description": "AI Coding Framework for Claude Code — 7+ agents, 52 skills, multi-LLM orchestration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/cli/index.js",
|
|
@@ -23,12 +23,15 @@
|
|
|
23
23
|
"scripts": {
|
|
24
24
|
"build": "tsc -p tsconfig.build.json && chmod +x dist/cli/index.js",
|
|
25
25
|
"dev": "tsc --watch",
|
|
26
|
-
"gen:skill-docs": "
|
|
27
|
-
"gen:skill-docs:check": "
|
|
28
|
-
"sync:agent-models": "
|
|
29
|
-
"sync:agent-models:check": "
|
|
30
|
-
"validate:skill-invocation": "
|
|
31
|
-
"validate:counts": "
|
|
26
|
+
"gen:skill-docs": "tsx scripts/gen-skill-docs.ts",
|
|
27
|
+
"gen:skill-docs:check": "tsx scripts/gen-skill-docs.ts --check",
|
|
28
|
+
"sync:agent-models": "tsx scripts/sync-agent-models.ts",
|
|
29
|
+
"sync:agent-models:check": "tsx scripts/sync-agent-models.ts --check",
|
|
30
|
+
"validate:skill-invocation": "tsx scripts/validate-skill-invocation.ts",
|
|
31
|
+
"validate:counts": "tsx scripts/validate-counts.ts",
|
|
32
|
+
"lint": "oxlint",
|
|
33
|
+
"lint:ratchet": "tsx scripts/lint-ratchet.ts",
|
|
34
|
+
"verify:all": "pnpm lint && pnpm lint:ratchet && pnpm gen:skill-docs:check && pnpm sync:agent-models:check && pnpm validate:skill-invocation && pnpm validate:counts && pnpm gen:agents-md:check && pnpm validate:spec-lifecycle && pnpm validate:cache-surface",
|
|
32
35
|
"test": "vitest run",
|
|
33
36
|
"test:watch": "vitest",
|
|
34
37
|
"test:coverage": "vitest run --coverage",
|
|
@@ -41,7 +44,11 @@
|
|
|
41
44
|
"gen:plugin-hooks": "npx tsx scripts/gen-plugin-hooks.ts",
|
|
42
45
|
"gen:plugin-hooks:check": "npx tsx scripts/gen-plugin-hooks.ts --check",
|
|
43
46
|
"validate:plugin-tree": "npx tsx scripts/build-plugin.ts && git diff --exit-code --stat HEAD -- plugins/",
|
|
44
|
-
"validate:mermaid": "npx tsx scripts/validate-mermaid.ts"
|
|
47
|
+
"validate:mermaid": "npx tsx scripts/validate-mermaid.ts",
|
|
48
|
+
"validate:spec-lifecycle": "npx tsx scripts/validate-spec-lifecycle.ts",
|
|
49
|
+
"validate:cache-surface": "npx tsx scripts/validate-cache-surface.ts",
|
|
50
|
+
"gen:agents-md": "npx tsx scripts/gen-agents-md.ts",
|
|
51
|
+
"gen:agents-md:check": "npx tsx scripts/gen-agents-md.ts --check"
|
|
45
52
|
},
|
|
46
53
|
"keywords": [
|
|
47
54
|
"ai",
|
|
@@ -100,6 +107,8 @@
|
|
|
100
107
|
"ajv": "^8.17.1",
|
|
101
108
|
"jsdom": "^25.0.1",
|
|
102
109
|
"mermaid": "^11.17.2",
|
|
110
|
+
"oxlint": "^1.76.0",
|
|
111
|
+
"tsx": "^4.23.5",
|
|
103
112
|
"typescript": "^5.9.3",
|
|
104
113
|
"vitest": "^4.1.10"
|
|
105
114
|
},
|
|
@@ -121,7 +130,8 @@
|
|
|
121
130
|
],
|
|
122
131
|
"pnpm": {
|
|
123
132
|
"onlyBuiltDependencies": [
|
|
124
|
-
"better-sqlite3"
|
|
133
|
+
"better-sqlite3",
|
|
134
|
+
"esbuild"
|
|
125
135
|
]
|
|
126
136
|
}
|
|
127
137
|
}
|
|
@@ -17,6 +17,10 @@ Cursor is not supported — do not generate or check Cursor-specific context fil
|
|
|
17
17
|
**Source of truth:**
|
|
18
18
|
- **`CLAUDE.md` is the content SSOT.** Always edit it first; `AGENTS.md` is a regenerated derivative.
|
|
19
19
|
- Behavioral block: `skills/vibe.docs/templates/behavioral-principles.md` (4 Karpathy principles, wrapped in `<!-- VIBE-BEHAVIORAL:START/END -->` markers).
|
|
20
|
+
- **번역 규칙이 파일로 존재하면 그 파일이 SSOT다.** 프로젝트 루트에 `scripts/agents-md-rules.json` 이 있으면
|
|
21
|
+
아래 4·5번 손 치환 목록을 쓰지 않고 `npm run gen:agents-md` 로 생성한다 — 규칙을 두 곳에 적으면
|
|
22
|
+
그 순간 두 벌이 되고, 어느 쪽이 맞는지 판정할 수단이 사라진다. 검증은 `npm run gen:agents-md:check`.
|
|
23
|
+
(vibe 저장소 자신이 이 경로다. 규칙 파일이 없는 프로젝트는 4·5번을 그대로 적용한다.)
|
|
20
24
|
|
|
21
25
|
**Procedure (applies to both creation and modification):**
|
|
22
26
|
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# 프리픽스 캐시 표면
|
|
2
|
+
|
|
3
|
+
> 매 요청의 **앞부분에 항상 실리는 자산**이 무엇이고, 그것을 건드리면 무엇이 깨지는지.
|
|
4
|
+
> 검증: `npm run validate:cache-surface` (CI `test` job).
|
|
5
|
+
|
|
6
|
+
## 왜 이 문서가 있는가
|
|
7
|
+
|
|
8
|
+
컨텍스트 정책(85% 룰, `/new` 가 KV 프리픽스 캐시를 전량 폐기한다)은 `CLAUDE.md` 에 한 줄로
|
|
9
|
+
적혀 있었다. 그 한 줄은 **어떤 파일을 고치면 캐시가 깨지는지**를 말해주지 않는다 — 그래서
|
|
10
|
+
"상시 로드 자산에 문단 하나 추가" 같은 변경이 리뷰에서 그냥 통과한다. 비용은 그 PR 이
|
|
11
|
+
아니라 이후 모든 세션의 첫 토큰에서 나온다.
|
|
12
|
+
|
|
13
|
+
여기서 고정하는 것은 두 가지다: **모델이 이 자산을 어떻게 경험하는가**(Model Experience)와
|
|
14
|
+
**이 자산을 바꾸면 캐시가 어떻게 되는가**(KV Cache effect). 자산이 늘거나 사라지면 게이트가 막는다.
|
|
15
|
+
|
|
16
|
+
## 무효화의 규칙 (모든 표면 공통)
|
|
17
|
+
|
|
18
|
+
프리픽스 캐시는 **접두사 일치**로 재사용된다 — 앞에서 한 바이트가 달라지면 그 뒤는 전부
|
|
19
|
+
다시 계산된다. 따라서 비용은 "얼마나 고쳤나" 가 아니라 **"얼마나 앞에서 고쳤나"** 로 정해진다.
|
|
20
|
+
표면을 아래 순서대로 읽는다: 위쪽일수록 한 글자의 대가가 크다.
|
|
21
|
+
|
|
22
|
+
<!-- surface: always-loaded-docs -->
|
|
23
|
+
## 표면 1 — 루트 지침 문서 (`CLAUDE.md` · `AGENTS.md`)
|
|
24
|
+
|
|
25
|
+
- **Model Experience**: 세션 시작 시 **전문이** 시스템 프롬프트에 들어간다. 모델은 이 문서를
|
|
26
|
+
"검색해서 찾는 문서" 가 아니라 **이미 알고 있는 규칙**으로 경험한다 — 그래서 여기 적힌 것은
|
|
27
|
+
탐색 없이 즉시 적용되고, 여기 없는 것은 존재를 모른다.
|
|
28
|
+
- **KV Cache effect**: 프리픽스의 가장 앞쪽에 가깝다. **한 줄만 고쳐도 그 아래 전체가 무효화**되고,
|
|
29
|
+
이후 모든 세션이 첫 요청에서 전문을 다시 계산한다. 문단 추가는 상시 비용이므로, 상세는
|
|
30
|
+
`vibe/rules/**` 로 내리고 루트에는 **포인터만** 남긴다.
|
|
31
|
+
|
|
32
|
+
| 자산 | 비고 |
|
|
33
|
+
|---|---|
|
|
34
|
+
| `CLAUDE.md` | content SSOT |
|
|
35
|
+
| `AGENTS.md` | `CLAUDE.md` 에서 생성 (`npm run gen:agents-md`) |
|
|
36
|
+
|
|
37
|
+
<!-- surface: prefix-hooks -->
|
|
38
|
+
## 표면 2 — 프리픽스에 stdout 을 얹는 훅
|
|
39
|
+
|
|
40
|
+
훅 전체가 아니라 **턴 앞단에서 도는 두 이벤트**만 해당한다. `PreToolUse`/`PostToolUse`/`Stop` 은
|
|
41
|
+
턴 중간에 끼어들어 이미 만들어진 프리픽스를 바꾸지 않는다.
|
|
42
|
+
|
|
43
|
+
- **Model Experience**: 이 훅의 stdout 은 모델에게 **사용자가 말하지 않은 지시문**으로 보인다.
|
|
44
|
+
출처 표시가 없으면 사용자 발화와 구분되지 않으므로, 출력은 짧고 라벨이 붙어야 한다.
|
|
45
|
+
- **KV Cache effect**: `SessionStart` 출력은 세션 프리픽스에 **한 번** 박힌다 — 길이가 그대로
|
|
46
|
+
상시 비용이다. `UserPromptSubmit` 출력은 **매 턴** 프리픽스 끝에 붙는다. 출력이 턴마다
|
|
47
|
+
달라지면(시각·카운터·랜덤 순서) 그 지점부터 재사용이 끊기므로, **불변 텍스트를 앞에, 가변
|
|
48
|
+
텍스트를 뒤에** 둔다.
|
|
49
|
+
|
|
50
|
+
| 이벤트 | 스크립트 |
|
|
51
|
+
|---|---|
|
|
52
|
+
| SessionStart | `hooks/scripts/session-start.js` |
|
|
53
|
+
| UserPromptSubmit | `hooks/scripts/prompt-dispatcher.js` |
|
|
54
|
+
|
|
55
|
+
<!-- surface: agents -->
|
|
56
|
+
## 표면 3 — 에이전트 frontmatter `description`
|
|
57
|
+
|
|
58
|
+
- **Model Experience**: 에이전트 **본문은 로드되지 않는다.** 모델이 항상 보는 것은 이름과
|
|
59
|
+
`description` 한 줄뿐이고, 위임 여부는 전적으로 그 한 줄로 결정된다. description 이 비면
|
|
60
|
+
에이전트는 설치돼 있어도 **없는 것과 같다** (실측: frontmatter 가 YAML 파싱에 실패해 통째로
|
|
61
|
+
버려진 설치본이 11개 중 4개였다 — `CLAUDE.md` Gotchas).
|
|
62
|
+
- **KV Cache effect**: 에이전트 목록 전체가 프리픽스에 실린다. 에이전트를 **추가·삭제**하면
|
|
63
|
+
목록이 바뀌어 그 뒤가 무효화되고, description 을 한 글자 고쳐도 같다. 본문을 아무리 늘려도
|
|
64
|
+
프리픽스는 커지지 않는다 — **길이는 본문으로, 신호는 description 으로**.
|
|
65
|
+
|
|
66
|
+
| 에이전트 |
|
|
67
|
+
|---|
|
|
68
|
+
| `agents/architect.md` |
|
|
69
|
+
| `agents/build-error-resolver.md` |
|
|
70
|
+
| `agents/code-reviewer.md` |
|
|
71
|
+
| `agents/e2e-tester.md` |
|
|
72
|
+
| `agents/implementer.md` |
|
|
73
|
+
| `agents/security-reviewer.md` |
|
|
74
|
+
| `agents/tester.md` |
|
|
75
|
+
| `agents/event/event-ops.md` |
|
|
76
|
+
| `agents/event/event-planner.md` |
|
|
77
|
+
| `agents/ui/design-reviewer.md` |
|
|
78
|
+
| `agents/ui/design-system-gen.md` |
|
|
79
|
+
|
|
80
|
+
<!-- surface: skills -->
|
|
81
|
+
## 표면 4 — 스킬 frontmatter `description` (집계)
|
|
82
|
+
|
|
83
|
+
- **Model Experience**: 에이전트와 같다 — **본문은 호출될 때만** 로드되고, 상시 실리는 것은
|
|
84
|
+
`name` + `description` 이다. 따라서 스킬 본문의 길이는 라우팅 정확도에 기여하지 않는다.
|
|
85
|
+
라우팅은 description 이 한다.
|
|
86
|
+
- **KV Cache effect**: 스킬 **개수**가 프리픽스 길이를 좌우한다. 스킬을 하나 추가하면 목록이
|
|
87
|
+
길어져 그 뒤가 무효화된다. 그래서 스택·capability 로 갈라 설치하는 것이다 — 아무 프로젝트에나
|
|
88
|
+
실릴 이유가 없는 스킬은 내려둔다 (`GLOBAL_SKILLS_*` / `STACK_TO_SKILLS` / `CAPABILITY_SKILLS`).
|
|
89
|
+
- **개수 검증은 여기서 하지 않는다** — `npm run validate:counts` 가 이미 그 사실의 집이다.
|
|
90
|
+
같은 사실을 두 곳에서 세면 그 순간 두 벌이 된다.
|
|
91
|
+
|
|
92
|
+
## 새 표면을 추가할 때
|
|
93
|
+
|
|
94
|
+
1. 위 형식으로 절을 만든다 — `<!-- surface: {id} -->` 마커 + `Model Experience` + `KV Cache effect`.
|
|
95
|
+
2. 자산을 나열한다면 표의 백틱 경로가 실물과 **정확히 일치**해야 한다. 게이트가 양방향으로 본다:
|
|
96
|
+
문서에 없는 실물도, 실물이 없는 문서 항목도 실패다.
|
|
97
|
+
3. 집계로 충분하면 나열하지 않는다. 나열은 그 자체가 유지보수 비용이고, 다른 게이트가 이미
|
|
98
|
+
세고 있다면 여기서 또 세지 않는다.
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# SPEC: {Feature Name}
|
|
2
2
|
|
|
3
3
|
- **Created**: {YYYY-MM-DD}
|
|
4
|
-
- **Status**: DRAFT | APPROVED
|
|
4
|
+
- **Status**: DRAFT | APPROVED | VERIFIED | SUPERSEDED | REJECTED (닫힌 집합 — `npm run validate:spec-lifecycle`)
|
|
5
|
+
- **Class**: feature | bug-fix | simplification | architecture | process | testing
|
|
5
6
|
- **Stakes**: demo | prototype | production — {판정 근거 1구} (SSOT: vibe/rules/loop-contract.md)
|
|
6
7
|
- **Tech Stack**: {Project tech stack summary}
|
|
7
8
|
|
|
@@ -153,3 +154,17 @@ Response: 201 {...}
|
|
|
153
154
|
- Verification writes `.vibe/runs/{run-id}/evidence.json`; only deterministic Judge results can complete the loop.
|
|
154
155
|
- Model Judge findings are advisory-only. Human Taste is release-only.
|
|
155
156
|
- Gate = all Done Criteria pass (exit codes / observed behavior) — loop continues until gates pass, stuck, or max iterations.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Anchors
|
|
161
|
+
|
|
162
|
+
> **Class 가 feature · bug-fix · architecture 이고 Status 를 VERIFIED 로 올릴 때 필수.**
|
|
163
|
+
> 그 외에는 이 절을 통째로 지운다 — 고정할 코드 경로가 없는 SPEC 에 억지로 요구하면 통과 의식이 된다.
|
|
164
|
+
|
|
165
|
+
이 SPEC 이 안착한 경로를 나열한다. 여기 적힌 경로가 사라지면 `npm run validate:spec-lifecycle`
|
|
166
|
+
이 실패한다 — 그것이 "코드가 움직였는데 SPEC 이 따라오지 않았다" 를 잡는 유일한 신호다.
|
|
167
|
+
lifecycle 표기만으로는 못 잡는다: 문서는 Status 를 바꾸지 않은 채 늙기 때문이다.
|
|
168
|
+
|
|
169
|
+
- `{src/auth/session.ts}`
|
|
170
|
+
- `{src/auth/session.test.ts}`
|