@su-record/vibe 2.12.5 → 2.13.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.
Files changed (110) hide show
  1. package/CLAUDE.md +8 -2
  2. package/README.en.md +11 -11
  3. package/README.md +7 -7
  4. package/dist/cli/postinstall/fs-utils.d.ts +23 -0
  5. package/dist/cli/postinstall/fs-utils.d.ts.map +1 -1
  6. package/dist/cli/postinstall/fs-utils.js +71 -0
  7. package/dist/cli/postinstall/fs-utils.js.map +1 -1
  8. package/dist/cli/postinstall/fs-utils.test.js +69 -1
  9. package/dist/cli/postinstall/fs-utils.test.js.map +1 -1
  10. package/dist/cli/postinstall/main.d.ts.map +1 -1
  11. package/dist/cli/postinstall/main.js +12 -2
  12. package/dist/cli/postinstall/main.js.map +1 -1
  13. package/dist/cli/setup/CodexHooks.test.js +27 -0
  14. package/dist/cli/setup/CodexHooks.test.js.map +1 -1
  15. package/dist/cli/setup/ProjectSetup.js +2 -2
  16. package/dist/cli/setup/ProjectSetup.js.map +1 -1
  17. package/dist/infra/lib/DecisionTracer.d.ts +4 -0
  18. package/dist/infra/lib/DecisionTracer.d.ts.map +1 -1
  19. package/dist/infra/lib/DecisionTracer.js +4 -0
  20. package/dist/infra/lib/DecisionTracer.js.map +1 -1
  21. package/dist/infra/lib/LoopBreaker.d.ts +4 -0
  22. package/dist/infra/lib/LoopBreaker.d.ts.map +1 -1
  23. package/dist/infra/lib/LoopBreaker.js +4 -0
  24. package/dist/infra/lib/LoopBreaker.js.map +1 -1
  25. package/dist/infra/lib/ReviewRace.d.ts +4 -0
  26. package/dist/infra/lib/ReviewRace.d.ts.map +1 -1
  27. package/dist/infra/lib/ReviewRace.js +4 -0
  28. package/dist/infra/lib/ReviewRace.js.map +1 -1
  29. package/dist/infra/lib/SkillQualityGate.d.ts +4 -0
  30. package/dist/infra/lib/SkillQualityGate.d.ts.map +1 -1
  31. package/dist/infra/lib/SkillQualityGate.js +4 -0
  32. package/dist/infra/lib/SkillQualityGate.js.map +1 -1
  33. package/dist/infra/lib/UltraQA.d.ts +4 -0
  34. package/dist/infra/lib/UltraQA.d.ts.map +1 -1
  35. package/dist/infra/lib/UltraQA.js +4 -0
  36. package/dist/infra/lib/UltraQA.js.map +1 -1
  37. package/dist/infra/lib/VerificationLoop.d.ts +4 -0
  38. package/dist/infra/lib/VerificationLoop.d.ts.map +1 -1
  39. package/dist/infra/lib/VerificationLoop.js +4 -0
  40. package/dist/infra/lib/VerificationLoop.js.map +1 -1
  41. package/dist/infra/orchestrator/index.d.ts.map +1 -1
  42. package/dist/infra/orchestrator/index.js +1 -3
  43. package/dist/infra/orchestrator/index.js.map +1 -1
  44. package/dist/infra/orchestrator/parallelResearch.d.ts.map +1 -1
  45. package/dist/infra/orchestrator/parallelResearch.js +1 -4
  46. package/dist/infra/orchestrator/parallelResearch.js.map +1 -1
  47. package/dist/tools/convention/validateCodeQuality.d.ts.map +1 -1
  48. package/dist/tools/convention/validateCodeQuality.js +5 -4
  49. package/dist/tools/convention/validateCodeQuality.js.map +1 -1
  50. package/dist/tools/spec/traceabilityMatrix.d.ts +2 -0
  51. package/dist/tools/spec/traceabilityMatrix.d.ts.map +1 -1
  52. package/dist/tools/spec/traceabilityMatrix.js +50 -1
  53. package/dist/tools/spec/traceabilityMatrix.js.map +1 -1
  54. package/dist/tools/spec/traceabilityMatrix.path-resolution.test.d.ts +10 -0
  55. package/dist/tools/spec/traceabilityMatrix.path-resolution.test.d.ts.map +1 -0
  56. package/dist/tools/spec/traceabilityMatrix.path-resolution.test.js +89 -0
  57. package/dist/tools/spec/traceabilityMatrix.path-resolution.test.js.map +1 -0
  58. package/dist/tools/spec/traceabilityMatrix.test.js +19 -0
  59. package/dist/tools/spec/traceabilityMatrix.test.js.map +1 -1
  60. package/hooks/hooks.json +1 -0
  61. package/hooks/scripts/__tests__/.vibe/command-log.txt +39 -0
  62. package/hooks/scripts/__tests__/.vibe/memories/memories.db +0 -0
  63. package/hooks/scripts/__tests__/.vibe/memories/memories.db-shm +0 -0
  64. package/hooks/scripts/__tests__/.vibe/memories/memories.db-wal +0 -0
  65. package/hooks/scripts/__tests__/auto-test-debounce.test.js +145 -0
  66. package/hooks/scripts/__tests__/code-check-detectors.test.js +155 -0
  67. package/hooks/scripts/__tests__/dispatcher-inprocess.test.js +99 -0
  68. package/hooks/scripts/__tests__/post-edit-dispatcher.test.js +139 -0
  69. package/hooks/scripts/__tests__/pre-tool-guard.test.js +115 -1
  70. package/hooks/scripts/__tests__/run-ledger-verify-required.test.js +146 -0
  71. package/hooks/scripts/__tests__/run-ledger.test.js +330 -0
  72. package/hooks/scripts/__tests__/scope-from-spec.test.js +215 -0
  73. package/hooks/scripts/__tests__/sentinel-guard.test.js +79 -24
  74. package/hooks/scripts/__tests__/step-counter.test.js +95 -15
  75. package/hooks/scripts/__tests__/utils-npm-root.test.js +98 -0
  76. package/hooks/scripts/auto-commit.js +27 -1
  77. package/hooks/scripts/auto-format.js +85 -20
  78. package/hooks/scripts/auto-test.js +187 -37
  79. package/hooks/scripts/code-check.js +286 -90
  80. package/hooks/scripts/codex-hook-adapter.js +12 -1
  81. package/hooks/scripts/command-log.js +26 -16
  82. package/hooks/scripts/lib/dispatcher.js +38 -0
  83. package/hooks/scripts/lib/hook-context.js +101 -0
  84. package/hooks/scripts/lib/pr-gate-runner.js +62 -0
  85. package/hooks/scripts/lib/run-ledger.js +169 -0
  86. package/hooks/scripts/lib/scope-from-spec.js +40 -7
  87. package/hooks/scripts/post-edit-dispatcher.js +93 -20
  88. package/hooks/scripts/post-edit.js +40 -19
  89. package/hooks/scripts/pr-test-gate.js +8 -37
  90. package/hooks/scripts/pre-tool-dispatcher.js +18 -16
  91. package/hooks/scripts/pre-tool-guard.js +55 -52
  92. package/hooks/scripts/prompt-dispatcher.js +10 -0
  93. package/hooks/scripts/scope-guard.js +40 -39
  94. package/hooks/scripts/sentinel-guard.js +41 -41
  95. package/hooks/scripts/session-start.js +13 -1
  96. package/hooks/scripts/step-counter.js +100 -7
  97. package/hooks/scripts/stop-dispatcher.js +26 -0
  98. package/hooks/scripts/utils.js +63 -21
  99. package/hooks/scripts/verify-ledger.js +22 -0
  100. package/package.json +2 -2
  101. package/skills/spec/references/templates.md +11 -6
  102. package/skills/vibe.run/SKILL.md +144 -1681
  103. package/skills/vibe.run/references/brand-assets.md +59 -0
  104. package/skills/vibe.run/references/parallel-agents.md +326 -0
  105. package/skills/vibe.run/references/race-review.md +272 -0
  106. package/skills/vibe.run/references/ralph-loop.md +172 -0
  107. package/skills/vibe.run/references/ultrawork-mode.md +148 -0
  108. package/skills/vibe.trace/SKILL.md +25 -38
  109. package/skills/vibe.verify/SKILL.md +15 -0
  110. package/hooks/scripts/figma-guard.js +0 -219
@@ -0,0 +1,172 @@
1
+ # Ralph Loop — Full Reference
2
+
3
+ > Loaded by vibe.run SKILL.md when Ralph Loop or ULTRAWORK is active (coverage verification).
4
+
5
+ ## Ralph Loop (Completion Verification)
6
+
7
+ > **Inspired by [ghuntley.com/ralph](https://ghuntley.com/ralph)**: "Deterministically bad in an undeterministic world" — Keep iterating until TRULY complete.
8
+
9
+ **Problem**: AI often claims "complete" when implementation is partial.
10
+
11
+ **Solution**: RTM-based automated coverage verification with iteration tracking.
12
+
13
+ ```
14
+ ┌─────────────────────────────────────────────────────────────────┐
15
+ │ RALPH LOOP (Mandatory) │
16
+ │ │
17
+ │ After ALL phases complete: │
18
+ │ │
19
+ │ ┌──────────────────────────────────────────────────────────┐ │
20
+ │ │ RTM COVERAGE VERIFICATION [Iteration {{ITER}}/{{MAX}}] │ │
21
+ │ │ │ │
22
+ │ │ Generate RTM via core tools: │ │
23
+ │ │ → generateTraceabilityMatrix("{feature-name}") │ │
24
+ │ │ │ │
25
+ │ │ Coverage Metrics (automated): │ │
26
+ │ │ □ Requirements coverage: {coveragePercent}% │ │
27
+ │ │ □ SPEC → Feature mapping: {featureCovered}/{total} │ │
28
+ │ │ □ Feature → Test mapping: {testCovered}/{total} │ │
29
+ │ │ □ Build successful? │ │
30
+ │ │ □ Tests passing? │ │
31
+ │ │ │ │
32
+ │ │ UNCOVERED: {uncoveredRequirements[]} │ │
33
+ │ └──────────────────────────────────────────────────────────┘ │
34
+ │ │ │
35
+ │ ┌──────────┴──────────┐ │
36
+ │ │ Coverage == 100%? │ │
37
+ │ └──────────┬──────────┘ │
38
+ │ │ │ │
39
+ │ NO YES │
40
+ │ │ │ │
41
+ │ ↓ ↓ │
42
+ │ ┌────────────────┐ ┌────────────────┐ │
43
+ │ │ IMPLEMENT │ │ TRULY DONE │ │
44
+ │ │ UNCOVERED │ │ │ │
45
+ │ │ REQUIREMENTS │ │ Report final │ │
46
+ │ │ (auto-extract) │ │ RTM coverage │ │
47
+ │ └───────┬────────┘ └────────────────┘ │
48
+ │ │ │
49
+ │ └──────────→ [Re-generate RTM] │
50
+ │ │
51
+ │ │ │
52
+ │ ↓ │
53
+ │ Stuck? (coverage unchanged from prev iteration) │
54
+ │ │ │
55
+ │ ├─ Interactive: Ask user │
56
+ │ │ 1. Provide resolution → retry │
57
+ │ │ 2. "proceed" → TODO + done │
58
+ │ │ 3. "abort" → stop │
59
+ │ └─ ultrawork: TODO + done │
60
+ │ │
61
+ │ NO iteration cap — loop until 100% OR stuck │
62
+ │ ZERO TOLERANCE for silent scope reduction │
63
+ └─────────────────────────────────────────────────────────────────┘
64
+ ```
65
+
66
+ ## RTM Invocation
67
+
68
+ ```bash
69
+ # Generate RTM for coverage verification (generateTraceabilityMatrix is synchronous — no .then())
70
+ node -e "import('{{VIBE_PATH_URL}}/node_modules/@su-record/vibe/dist/tools/index.js').then(t => { const r = t.generateTraceabilityMatrix('{feature-name}', {projectPath: process.cwd()}); console.log(JSON.stringify(r, null, 2)); })"
71
+ ```
72
+
73
+ > **Note:** Default SPEC path is `.vibe/specs/<feature>.md` (falls back to `.claude/vibe/specs/` then `.claude/specs/` for legacy projects).
74
+ > `status === 'empty'` means the gate MUST be treated as failed/not-applicable, never as 100% pass.
75
+
76
+ ## RTM Metrics
77
+
78
+ | Metric | Description |
79
+ |--------|-------------|
80
+ | `totalRequirements` | Total REQ-* items in SPEC |
81
+ | `specCovered` | Requirements with SPEC mapping |
82
+ | `featureCovered` | Requirements with Feature scenarios |
83
+ | `testCovered` | Requirements with test files |
84
+ | `coveragePercent` | Overall coverage percentage |
85
+ | `uncoveredRequirements` | List of missing REQ-* IDs |
86
+
87
+ ## Ralph Loop Rules
88
+
89
+ | Rule | Description |
90
+ |------|-------------|
91
+ | **No Scope Reduction** | Never say "simplified" or "basic version" — implement FULL request |
92
+ | **Iteration Tracking** | Display `[{{ITER}}]` to show progress (no max — loop until done) |
93
+ | **RTM-Based Gap List** | Use `uncoveredRequirements` array — no manual comparison |
94
+ | **Coverage Threshold** | Must reach 100% coverage to complete |
95
+ | **No Iteration Cap** | Loop until 100% coverage OR stuck (convergence detected) |
96
+ | **Stuck Handling** | If coverage % unchanged between iterations → ask user (proceed/abort/fix), or ultrawork → TODO + done |
97
+ | **Diminishing Returns** | Iteration 3+ → focus on core requirements (REQ-*-001~003) first; P2/P3 continue but lower priority |
98
+
99
+ ## Ralph Loop Output Format
100
+
101
+ ```
102
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
103
+ RALPH VERIFICATION [Iteration 1]
104
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
105
+
106
+ RTM Coverage Report: login
107
+
108
+ Requirements Traceability:
109
+ Total Requirements: 9
110
+ SPEC Covered: 9/9 (100%)
111
+ Feature Covered: 5/9 (55%)
112
+ Test Covered: 4/9 (44%)
113
+
114
+ REQ-login-001: Login form UI → Scenario 1 → login.test.ts
115
+ REQ-login-002: Email validation → Scenario 2 → validation.test.ts
116
+ REQ-login-003: Password validation → Scenario 2 → validation.test.ts
117
+ REQ-login-004: Remember me checkbox → NOT IMPLEMENTED
118
+ REQ-login-005: Forgot password link → NOT IMPLEMENTED
119
+ REQ-login-006: API integration → Scenario 3 → api.test.ts
120
+ REQ-login-007: Loading state → NOT IMPLEMENTED
121
+ REQ-login-008: Error toast → NOT IMPLEMENTED
122
+ REQ-login-009: Session storage → Scenario 4 → (no test)
123
+
124
+ Overall Coverage: 55% BELOW 100% TARGET
125
+
126
+ UNCOVERED REQUIREMENTS (auto-extracted from RTM):
127
+ 1. REQ-login-004: Remember me checkbox
128
+ 2. REQ-login-005: Forgot password link
129
+ 3. REQ-login-007: Loading state
130
+ 4. REQ-login-008: Error toast notifications
131
+
132
+ NOT COMPLETE — Implementing uncovered requirements...
133
+
134
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
135
+ RALPH VERIFICATION [Iteration 2]
136
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
137
+
138
+ RTM Coverage Report: login
139
+
140
+ Requirements Traceability:
141
+ Total Requirements: 9
142
+ SPEC Covered: 9/9 (100%)
143
+ Feature Covered: 9/9 (100%)
144
+ Test Covered: 9/9 (100%)
145
+
146
+ Overall Coverage: 100% TARGET REACHED
147
+
148
+ Build: Passed
149
+ Tests: 12/12 Passed
150
+ Type Check: No errors
151
+
152
+ RALPH VERIFIED COMPLETE!
153
+
154
+ RTM saved: .vibe/rtm/login-rtm.md
155
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
156
+ ```
157
+
158
+ ## When to Trigger Ralph Loop
159
+
160
+ 1. After all phases complete
161
+ 2. Before final quality report
162
+ 3. Whenever user says "ultrawork" or "ralph"
163
+
164
+ ## Forbidden Responses (VIOLATIONS)
165
+
166
+ | NEVER Say | Instead |
167
+ |-----------|---------|
168
+ | "I've implemented a basic version" | Implement the FULL version |
169
+ | "This is a simplified approach" | Implement as specified |
170
+ | "You can add X later" | Add X now |
171
+ | "For demonstration purposes" | Implement production-ready |
172
+ | "The core functionality is done" | ALL functionality must be done |
@@ -0,0 +1,148 @@
1
+ # ULTRAWORK Mode — Full Reference
2
+
3
+ > Loaded by vibe.run SKILL.md when user includes `ultrawork` or `ulw` keyword.
4
+
5
+ ## What ULTRAWORK Enables
6
+
7
+ When you include `ultrawork` (or `ulw`), ALL of these activate automatically:
8
+
9
+ | Feature | Description |
10
+ |---------|-------------|
11
+ | **Parallel Exploration** | 3+ Task(haiku) agents run simultaneously |
12
+ | **Boulder Loop** | Auto-continues until ALL phases complete |
13
+ | **Context Compression** | Aggressive auto-save at 70%+ context |
14
+ | **No Pause** | Doesn't wait for confirmation between phases |
15
+ | **External LLMs** | Auto-consults GPT/Antigravity if enabled |
16
+ | **Error Recovery** | Loops until 100% or stuck; on stuck auto-records TODO and proceeds (no user prompt) |
17
+ | **Race Review (v2.6.9)** | Multi-LLM review (GPT+Antigravity) with cross-validation |
18
+
19
+ ## Boulder Loop (Inspired by Sisyphus)
20
+
21
+ Like Sisyphus rolling the boulder, ULTRAWORK **keeps going until done**:
22
+
23
+ ```
24
+ ┌─────────────────────────────────────────────────────────────────┐
25
+ │ BOULDER LOOP (ultrawork) │
26
+ │ │
27
+ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
28
+ │ │ Phase 1 │───→│ Phase 2 │───→│ Phase 3 │───→│ Phase N │ │
29
+ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
30
+ │ │ │ │ │ │
31
+ │ ↓ ↓ ↓ ↓ │
32
+ │ [Parallel] [Parallel] [Parallel] [Parallel] │
33
+ │ [Implement] [Implement] [Implement] [Implement] │
34
+ │ [Test] [Test] [Test] [Test] │
35
+ │ │ │ │ │ │
36
+ │ └───────────────┴───────────────┴───────────────┘ │
37
+ │ │ │
38
+ │ ↓ │
39
+ │ ┌──────────────┐ │
40
+ │ │ ALL DONE? │ │
41
+ │ └──────────────┘ │
42
+ │ │ │ │
43
+ │ NO YES │
44
+ │ │ │ │
45
+ │ ↓ ↓ │
46
+ │ [Continue] [Complete!] │
47
+ │ │
48
+ │ NO STOPPING until acceptance criteria met or error limit hit │
49
+ └─────────────────────────────────────────────────────────────────┘
50
+ ```
51
+
52
+ ## ULTRAWORK Example Session
53
+
54
+ ```
55
+ User: /vibe.run "brick-game" ultrawork
56
+
57
+ Claude:
58
+ ULTRAWORK MODE ACTIVATED
59
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
60
+
61
+ SPEC: .vibe/specs/brick-game.md
62
+ 4 Phases detected
63
+ Boulder Loop: ENABLED (will continue until all phases complete)
64
+ Auto-retry: ON (loop until 100% or stuck → auto-TODO)
65
+ Context compression: AGGRESSIVE
66
+
67
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
68
+ BOULDER ROLLING... Phase 1/4
69
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
70
+
71
+ [PARALLEL] Launching 3 exploration agents...
72
+ Exploration complete (7.2s)
73
+ Implementing...
74
+ Phase 1 complete
75
+
76
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
77
+ BOULDER ROLLING... Phase 2/4
78
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
79
+
80
+ [PARALLEL] Launching 3 exploration agents...
81
+ Exploration complete (6.8s)
82
+ Implementing...
83
+ Test failed: collision detection
84
+ Auto-retry [iteration 1]...
85
+ Fixing...
86
+ Phase 2 complete
87
+
88
+ [...continues automatically...]
89
+
90
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
91
+ BOULDER REACHED THE TOP!
92
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
93
+
94
+ All 4 phases complete
95
+ All acceptance criteria passed
96
+ Build succeeded
97
+ Tests passed
98
+
99
+ Total: 8m 24s
100
+ Retries: 2
101
+ Context saved: 3 checkpoints
102
+ ```
103
+
104
+ ## Normal vs ULTRAWORK Comparison
105
+
106
+ | Aspect | Normal | ULTRAWORK |
107
+ |--------|--------|-----------|
108
+ | Phase transition | May pause | Auto-continues |
109
+ | On error | Reports and stops | Auto-retries (3x) |
110
+ | Context 70%+ | Warning only | Auto-compress + save |
111
+ | Exploration | Sequential possible | FORCED parallel |
112
+ | Completion | Phase-by-phase | Until ALL done |
113
+
114
+ ## Automation Level System
115
+
116
+ Magic keywords in the user input automatically set the **AutomationLevel**, which controls how much the AI self-advances vs. pausing for confirmation.
117
+
118
+ ### Level Definitions
119
+
120
+ | Level | Name | Keyword(s) | Auto-advance | Auto-retry | Stuck Behavior | Parallel Agents | Checkpoints |
121
+ |-------|------|------------|--------------|------------|----------------|-----------------|-------------|
122
+ | L0 | Manual | `manual` | No | No | Ask user every step | No | All |
123
+ | L1 | Guided | `guided`, `verify` | No | No | Ask user on stuck | No | All |
124
+ | L2 | Semi-auto | `quick` (default) | Yes | Yes (low cap: 2) | Ask user after 2 retries | No | Key points |
125
+ | L3 | Auto | `ultrawork`, `ulw` | Yes | Yes (no cap) | Auto-TODO + proceed | Yes | Checkpoint-only |
126
+ | L4 | Full-auto | `ralph`, `ralplan` | Yes | Yes (no cap) | Auto-TODO + proceed | Yes | None |
127
+
128
+ ### Detection Rule
129
+
130
+ ```
131
+ /vibe.run "login" → L2 Semi-auto (default)
132
+ /vibe.run "login" ultrawork → L3 Auto
133
+ /vibe.run "login" ralph → L4 Full-auto
134
+ /vibe.run "login" verify → L1 Guided
135
+ ```
136
+
137
+ ### Confirmation Matrix
138
+
139
+ | Action | L0 | L1 | L2 | L3 | L4 |
140
+ |--------|----|----|----|----|-----|
141
+ | `destructive` | confirm | confirm | confirm | confirm | auto |
142
+ | `architecture_choice` | confirm | confirm | confirm | auto | auto |
143
+ | `implementation_scope` | confirm | confirm | confirm | auto | auto |
144
+ | `phase_advance` | confirm | confirm | auto | auto | auto |
145
+ | `fix_strategy` | confirm | confirm | auto | auto | auto |
146
+ | `retry` | confirm | auto | auto | auto | auto |
147
+
148
+ **Rule**: When confirmation is required, pause and display a checkpoint before proceeding.
@@ -187,63 +187,50 @@ Loading files:
187
187
  The RTM generation uses core tools:
188
188
 
189
189
  ```bash
190
- # Generate RTM
191
- node -e "import('{{VIBE_PATH_URL}}/node_modules/@su-record/vibe/dist/tools/index.js').then(t => t.generateTraceabilityMatrix('login').then(m => console.log(t.formatMatrixAsMarkdown(m))))"
190
+ # Generate RTM (generateTraceabilityMatrix is synchronous — no .then())
191
+ node -e "import('{{VIBE_PATH_URL}}/node_modules/@su-record/vibe/dist/tools/index.js').then(t => { const m = t.generateTraceabilityMatrix('login', {projectPath: process.cwd()}); console.log(t.formatMatrixAsMarkdown(m)); })"
192
192
 
193
193
  # Generate HTML
194
- node -e "import('{{VIBE_PATH_URL}}/node_modules/@su-record/vibe/dist/tools/index.js').then(t => t.generateTraceabilityMatrix('login').then(m => console.log(t.formatMatrixAsHtml(m))))"
194
+ node -e "import('{{VIBE_PATH_URL}}/node_modules/@su-record/vibe/dist/tools/index.js').then(t => { const m = t.generateTraceabilityMatrix('login', {projectPath: process.cwd()}); console.log(t.formatMatrixAsHtml(m)); })"
195
195
  ```
196
196
 
197
- ## VerificationLoop Integration
197
+ > **Note:** Default SPEC path is `.vibe/specs/<feature>.md` (falls back to `.claude/vibe/specs/` then `.claude/specs/` for legacy projects).
198
+ > `status === 'empty'` means the gate MUST be treated as failed/not-applicable, never as 100% pass.
198
199
 
199
- `/vibe.trace` results feed directly into the **VerificationLoop** module, which quantifies achievement rate and drives automatic re-iteration.
200
+ ## Post-Trace Gates
200
201
 
201
- ### Key Functions
202
+ After `/vibe.trace` completes and the RTM is displayed, two downstream mechanisms consume the result.
202
203
 
203
- | Function | Purpose |
204
- |----------|---------|
205
- | `createLoop(feature, config?)` | Initialize a new verification loop for a feature |
206
- | `recordVerification(state, requirements)` | Record RTM results and determine next action |
207
- | `formatVerificationResult(result, config)` | Format a single iteration result for display |
208
- | `formatLoopSummary(state)` | Format the full loop history as readable text |
209
- | `getUnmetRequirements(result)` | Extract failed/partial requirements for targeted fixing |
210
- | `isImproving(state)` | Detect whether achievement rate is increasing across iterations |
204
+ ### Empty-result gate
211
205
 
212
- ### Loop Configuration
206
+ `generateTraceabilityMatrix` returns `status: 'empty'` when no `REQ-<feature>-NNN` IDs are found in the SPEC. This state **must be treated as a gate failure**, not as 100% coverage. When the matrix status is `empty`, report it explicitly and do not proceed as if the feature is verified.
213
207
 
214
208
  ```
215
- threshold: 90 — Minimum achievement rate (%) to pass (default)
216
- maxIterations: 3 — Max re-verification attempts before stopping
217
- autoRetry: false Whether to auto-trigger re-implementation
209
+ RTM status === 'empty'
210
+ Coverage gate: FAILED (no requirements to trace)
211
+ → Action: run /vibe.spec to add REQ-IDs before re-running /vibe.trace
218
212
  ```
219
213
 
220
- ### Action Types
214
+ ### Run-ledger flow
221
215
 
222
- After each `recordVerification` call, the loop returns one of:
216
+ `/vibe.verify` records its outcome via `hooks/scripts/verify-ledger.js pass|fail`. This writes `verifyPassed` and `verifyAt` into `.vibe/metrics/run-ledger.json`. Downstream gates consume this record:
223
217
 
224
- | Action | Condition | Meaning |
225
- |--------|-----------|---------|
226
- | `passed` | rate >= threshold | All requirements met done |
227
- | `retry` | rate < threshold AND iterations remaining | Fix unmet requirements and re-run |
228
- | `max_iterations` | rate < threshold AND no iterations left | Report remaining gaps as TODO |
218
+ | Gate | Behavior |
219
+ |------|----------|
220
+ | `auto-commit` | Commits only when `verifyPassed === true` AND `verifyAt > runStarted` |
221
+ | Stop hook | Warns when `runStarted && !verifyPassed`; blocks once if `verifyGate.mode === 'block'` |
229
222
 
230
- ### Convergence Detection
231
-
232
- If the achievement rate does not improve between iterations (`isImproving` returns false), the loop stops early to avoid wasted cycles.
233
-
234
- ### Example Flow
223
+ **To register a passing trace as verified**, run `/vibe.verify` after `/vibe.trace` reports acceptable coverage. The verify skill calls `verify-ledger.js pass` internally — you do not invoke it manually.
235
224
 
236
225
  ```
237
- /vibe.trace "login"
238
- RTM generated: 7/9 requirements covered (78%)
239
- createLoop("login", { threshold: 90, maxIterations: 3 })
240
- recordVerification(...)action: retry (iteration 1, 3 unmet)
241
- → [fix unmet requirements]
242
- → /vibe.trace "login"
243
- → recordVerification(...) → action: passed (rate: 100%)
244
- → formatVerificationResult → display final report
226
+ /vibe.trace "login" → RTM: 9/9 (100%)
227
+ /vibe.verify "login" runs checks calls verify-ledger.js pass
228
+ .vibe/metrics/run-ledger.json updated
229
+ auto-commit / Stop gate verifyPassed=true, gate clears
245
230
  ```
246
231
 
232
+ If `/vibe.verify` is skipped, `auto-commit` will log the skip reason and abort the commit.
233
+
247
234
  ## Options
248
235
 
249
236
  | Option | Description |
@@ -465,6 +465,21 @@ Load skill `contract` with: check "{feature-name}"
465
465
  - **P1 drift** → demote verify to fail; auto-call `/vibe.regress register --from-contract`
466
466
  - P2 / P3 drift → warning only; verify still passes
467
467
 
468
+ ## Ledger Update (MANDATORY final step)
469
+
470
+ After producing the verification report, record the result to the run ledger:
471
+
472
+ ```bash
473
+ # pass 또는 fail — 시나리오 전체 통과 여부에 따라 선택
474
+ HOOKS_DIR="${VIBE_PATH:-$(npm root -g 2>/dev/null)/@su-record/vibe}/hooks/scripts"
475
+ if [ -f "$HOOKS_DIR/verify-ledger.js" ]; then
476
+ node "$HOOKS_DIR/verify-ledger.js" pass # 전체 통과 시
477
+ # node "$HOOKS_DIR/verify-ledger.js" fail # 실패 시
478
+ fi
479
+ ```
480
+
481
+ Replace `pass` with `fail` when any scenario fails. This step enables the Stop-hook verify-skip gate and auto-commit verify gate.
482
+
468
483
  ## Next Step
469
484
 
470
485
  On verification pass:
@@ -1,219 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Figma Guard — vibe.figma 작업 시 스킬 우회 차단
4
- *
5
- * 차단 대상:
6
- * 1. /tmp/{feature}/ 하위에 자체 정제/생성 스크립트(.mjs/.js) 작성
7
- * → figma-refine.js / figma-to-scss.js 호출하라고 차단
8
- * 2. SCSS 파일을 직접 작성 (figma-to-scss.js 호출 흔적 없이)
9
- * 3. Vue/React <style> 블록에 figma 관련 SCSS 클래스 직접 작성
10
- *
11
- * 작동 조건:
12
- * - tool: Write 또는 Edit
13
- * - file_path가 figma 작업 컨텍스트에 해당
14
- *
15
- * Exit codes:
16
- * 0 — 통과
17
- * 2 — 차단
18
- */
19
-
20
- import fs from 'fs';
21
- import path from 'path';
22
- import os from 'os';
23
-
24
- // ─── stdin 읽기 ─────────────────────────────────────────────────────
25
-
26
- function readStdinSync() {
27
- try {
28
- if (process.stdin.isTTY) return null;
29
- // fd 0을 직접 사용 (Windows는 '/dev/stdin'이 없음)
30
- const buf = Buffer.alloc(1024 * 1024); // 1MB
31
- const bytesRead = fs.readSync(0, buf, 0, buf.length, null);
32
- if (bytesRead > 0) {
33
- return JSON.parse(buf.toString('utf-8', 0, bytesRead));
34
- }
35
- } catch { /* fallback */ }
36
- return null;
37
- }
38
-
39
- // ─── 검사 1: /tmp/{feature}/ 자체 작성 스크립트 ─────────────────────
40
-
41
- const FORBIDDEN_TMP_SCRIPT_PATTERNS = [
42
- /\/tmp\/[^/]+\/refine[\w-]*\.(mjs|js)$/i,
43
- /\/tmp\/[^/]+\/.*sections.*\.(mjs|js)$/i,
44
- /\/tmp\/[^/]+\/.*to-scss.*\.(mjs|js)$/i,
45
- /\/tmp\/[^/]+\/.*generate-scss.*\.(mjs|js)$/i,
46
- /\/tmp\/[^/]+\/analyze-tree\.(mjs|js)$/i,
47
- /\/tmp\/[^/]+\/analyze-section\.(mjs|js)$/i,
48
- ];
49
-
50
- function checkForbiddenTmpScript(filePath) {
51
- if (!filePath) return null;
52
- for (const pattern of FORBIDDEN_TMP_SCRIPT_PATTERNS) {
53
- if (pattern.test(filePath)) {
54
- return {
55
- block: true,
56
- reason: `자체 작성 figma 스크립트 금지: ${path.basename(filePath)}`,
57
- suggestion: 'figma-refine.js / figma-to-scss.js / figma-validate.js 사용. ' +
58
- '결과가 마음에 안 들면 ~/.vibe/hooks/scripts/figma-*.js 자체를 수정하세요.'
59
- };
60
- }
61
- }
62
- return null;
63
- }
64
-
65
- // ─── 검사 2: SCSS 직접 작성 ─────────────────────────────────────────
66
-
67
- /**
68
- * Figma 작업 컨텍스트인지 판단:
69
- * - 현재 작업 디렉토리 또는 file_path에 figma 관련 흔적이 있어야 함
70
- * - /tmp/ 하위에 sections.json이 존재 → 활성 figma 작업으로 판단
71
- */
72
- function isFigmaContext() {
73
- try {
74
- const tmpDirs = fs.readdirSync('/tmp', { withFileTypes: true });
75
- for (const entry of tmpDirs) {
76
- if (!entry.isDirectory()) continue;
77
- const moSections = path.join('/tmp', entry.name, 'mo-main', 'sections.json');
78
- const pcSections = path.join('/tmp', entry.name, 'pc-main', 'sections.json');
79
- if (fs.existsSync(moSections) || fs.existsSync(pcSections)) {
80
- return { active: true, feature: entry.name };
81
- }
82
- }
83
- } catch { /* ignore */ }
84
- return { active: false };
85
- }
86
-
87
- /**
88
- * SCSS 파일 작성 시도 검사
89
- */
90
- function checkScssWrite(filePath, content) {
91
- if (!filePath) return null;
92
- if (!filePath.endsWith('.scss')) return null;
93
-
94
- // figma 컨텍스트가 아니면 통과
95
- const ctx = isFigmaContext();
96
- if (!ctx.active) return null;
97
-
98
- // 자동 생성 표시 코멘트 있으면 통과
99
- if (typeof content === 'string' && content.includes('Auto-generated from sections.json')) {
100
- return null;
101
- }
102
-
103
- // 빈 파일 또는 @import만 있는 경우 통과
104
- if (typeof content === 'string') {
105
- const meaningfulLines = content
106
- .split('\n')
107
- .map(l => l.trim())
108
- .filter(l => l && !l.startsWith('//') && !l.startsWith('/*'));
109
- const hasOnlyImports = meaningfulLines.every(l =>
110
- l.startsWith('@import') || l.startsWith('@use') || l.startsWith('@forward')
111
- );
112
- if (hasOnlyImports) return null;
113
- }
114
-
115
- return {
116
- block: true,
117
- reason: `SCSS 직접 작성 금지: ${filePath}`,
118
- suggestion: `figma-to-scss.js로 생성하세요:\n` +
119
- ` node ~/.vibe/hooks/scripts/figma-to-scss.js \\\n` +
120
- ` /tmp/${ctx.feature}/{bp}-main/sections.json \\\n` +
121
- ` --out=$(dirname ${filePath})`
122
- };
123
- }
124
-
125
- // ─── 검사 3: Vue/React <style> 블록에 CSS 값 작성 ───────────────────
126
-
127
- function checkVueStyleBlock(filePath, content) {
128
- if (!filePath) return null;
129
- if (!/\.(vue|jsx|tsx)$/.test(filePath)) return null;
130
-
131
- const ctx = isFigmaContext();
132
- if (!ctx.active) return null;
133
-
134
- // 파일 경로에 feature 이름이 있는지 확인
135
- if (!filePath.includes(ctx.feature)) return null;
136
-
137
- if (typeof content !== 'string') return null;
138
-
139
- // <style ...> ... </style> 블록 추출
140
- const styleBlocks = content.match(/<style[^>]*>([\s\S]*?)<\/style>/g);
141
- if (!styleBlocks || styleBlocks.length === 0) return null;
142
-
143
- for (const block of styleBlocks) {
144
- const inner = block.replace(/<style[^>]*>/, '').replace(/<\/style>/, '');
145
- const meaningfulLines = inner
146
- .split('\n')
147
- .map(l => l.trim())
148
- .filter(l => l && !l.startsWith('//') && !l.startsWith('/*'));
149
-
150
- // @import / @use 만 있으면 통과
151
- const hasOnlyImports = meaningfulLines.every(l =>
152
- l.startsWith('@import') || l.startsWith('@use') || l.startsWith('@forward')
153
- );
154
- if (hasOnlyImports) continue;
155
-
156
- // CSS 값으로 보이는 라인 검출 (px, rem, color, flex 등)
157
- const hasCssValue = meaningfulLines.some(l =>
158
- /:\s*[^;]*(?:px|rem|em|%|vh|vw|#[0-9a-fA-F]|rgba?\(|flex|grid|absolute|relative|inherit)/.test(l)
159
- );
160
- if (hasCssValue) {
161
- return {
162
- block: true,
163
- reason: `Vue/React <style> 블록에 CSS 직접 작성 금지: ${path.basename(filePath)}`,
164
- suggestion: `<style> 블록은 @import만 허용:\n` +
165
- ` <style lang="scss" scoped>\n` +
166
- ` @import '~/assets/scss/${ctx.feature}/index.scss';\n` +
167
- ` </style>`
168
- };
169
- }
170
- }
171
-
172
- return null;
173
- }
174
-
175
- // ─── 메인 ───────────────────────────────────────────────────────────
176
-
177
- const stdinPayload = readStdinSync();
178
- if (!stdinPayload) {
179
- process.exit(0);
180
- }
181
-
182
- const toolName = stdinPayload.tool_name || '';
183
- const toolInput = stdinPayload.tool_input || {};
184
-
185
- // Write 또는 Edit만 검사
186
- if (toolName !== 'Write' && toolName !== 'Edit') {
187
- process.exit(0);
188
- }
189
-
190
- const filePath = toolInput.file_path || '';
191
- const content = toolInput.content || toolInput.new_string || '';
192
-
193
- // 3단계 검사
194
- const checks = [
195
- checkForbiddenTmpScript(filePath),
196
- checkScssWrite(filePath, content),
197
- checkVueStyleBlock(filePath, content),
198
- ];
199
-
200
- const violations = checks.filter(c => c !== null);
201
-
202
- if (violations.length === 0) {
203
- process.exit(0);
204
- }
205
-
206
- // 차단
207
- const messages = ['🚫 FIGMA GUARD: 스킬 규칙 위반'];
208
- for (const v of violations) {
209
- messages.push('');
210
- messages.push(` ${v.reason}`);
211
- messages.push(` 💡 ${v.suggestion}`);
212
- }
213
- messages.push('');
214
- messages.push('⛔ vibe.figma 작업 중에는 스크립트 파이프라인을 우회하지 마세요.');
215
- messages.push(' ~/.vibe/hooks/scripts/figma-{refine,to-scss,validate}.js만 사용.');
216
-
217
- // PreToolUse hook은 stderr 출력 + exit 2로 차단
218
- console.error(messages.join('\n'));
219
- process.exit(2);