5-phase-workflow 1.6.0 → 1.7.1

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 CHANGED
@@ -10,7 +10,7 @@ The **5-Phase Workflow** is a structured approach to feature development that br
10
10
  2. **Implementation Planning** - Map requirements to technical components
11
11
  3. **Orchestrated Implementation** - Execute with state tracking and parallel processing
12
12
  4. **Verify Implementation** - Automated verification of completeness and correctness
13
- 5. **Code Review** - AI-powered review and quality improvements
13
+ 5. **Code Review** - AI-powered review, findings annotation, and fix application
14
14
 
15
15
  ## Why Use It?
16
16
 
@@ -79,6 +79,9 @@ After configuration is complete, start your first feature:
79
79
 
80
80
  # Phase 5: Review code
81
81
  /5:review-code
82
+
83
+ # Phase 5b: Apply review findings (optional — if you chose "Fix later")
84
+ /5:address-review-findings
82
85
  ```
83
86
 
84
87
  **Tip:** Running `/clear` between phases resets context and keeps conversations focused. Each phase reads necessary artifacts from previous phases, so no context is lost.
@@ -124,7 +127,8 @@ All commands are available under the `/5:` namespace:
124
127
  | `/5:plan-implementation` | 2 | Map feature to technical components |
125
128
  | `/5:implement-feature` | 3 | Execute implementation with agents |
126
129
  | `/5:verify-implementation` | 4 | Verify completeness and correctness |
127
- | `/5:review-code` | 5 | AI-powered code review (CodeRabbit) |
130
+ | `/5:review-code` | 5 | AI-powered code review (Claude or CodeRabbit) |
131
+ | `/5:address-review-findings` | 5 | Apply annotated findings and address PR comments |
128
132
  | `/5:quick-implement` | Fast | Streamlined workflow for small tasks |
129
133
  | `/5:unlock` | Utility | Remove planning guard lock |
130
134
 
@@ -223,12 +227,21 @@ Results are saved to a verification report.
223
227
 
224
228
  ### Phase 5: Code Review
225
229
 
226
- Automated review using CodeRabbit (if installed):
230
+ Two commands work together to handle the review workflow:
231
+
232
+ **`/5:review-code`** — runs the automated review and presents findings:
233
+ - Supports Claude (built-in, no setup) or CodeRabbit CLI
234
+ - Reviews staged changes, unstaged changes, or branch diff
235
+ - Categorizes findings as Fixable, Questions, or Manual
236
+ - Lets you fix immediately or save findings for later
227
237
 
228
- - Finds code smells and potential issues
229
- - Suggests improvements
230
- - Applies approved fixes
231
- - Re-verifies after changes
238
+ **`/5:address-review-findings`** applies annotated findings from a saved file:
239
+ - Reads the `review-findings-*.md` file generated by `/5:review-code`
240
+ - Applies `[FIX]` items, skips `[SKIP]` items, and follows `[MANUAL]` instructions
241
+ - Optionally fetches and addresses GitHub PR review comments
242
+ - Posts threaded replies to processed PR comments
243
+ - Runs build, tests, and lint after applying fixes
244
+ - Saves a summary report
232
245
 
233
246
  ## Project Structure
234
247
 
@@ -247,6 +260,7 @@ After installation, your `.claude/` directory will contain:
247
260
  │ ├── implement-feature.md
248
261
  │ ├── verify-implementation.md
249
262
  │ ├── review-code.md
263
+ │ ├── address-review-findings.md
250
264
  │ ├── discuss-feature.md
251
265
  │ ├── quick-implement.md
252
266
  │ ├── configure.md
package/bin/install.js CHANGED
@@ -41,7 +41,7 @@ function getInstalledVersion(isGlobal) {
41
41
 
42
42
  try {
43
43
  const data = JSON.parse(fs.readFileSync(versionFile, 'utf8'));
44
- return data.installedVersion;
44
+ return data.packageVersion;
45
45
  } catch (e) {
46
46
  return null; // Corrupted file, treat as missing
47
47
  }
@@ -386,6 +386,20 @@ function selectiveUpdate(targetPath, sourcePath) {
386
386
  log.success('Updated templates/ (workflow files only)');
387
387
  }
388
388
 
389
+ // Ensure .5/.gitignore exists and contains .update-cache.json
390
+ function ensureDotFiveGitignore(dataDir) {
391
+ const gitignorePath = path.join(dataDir, '.gitignore');
392
+ const entry = '.update-cache.json';
393
+ if (fs.existsSync(gitignorePath)) {
394
+ const content = fs.readFileSync(gitignorePath, 'utf8');
395
+ if (!content.includes(entry)) {
396
+ fs.appendFileSync(gitignorePath, '\n' + entry + '\n');
397
+ }
398
+ } else {
399
+ fs.writeFileSync(gitignorePath, entry + '\n');
400
+ }
401
+ }
402
+
389
403
  // Initialize version.json after successful install
390
404
  function initializeVersionJson(isGlobal) {
391
405
  const dataDir = getDataPath(isGlobal);
@@ -400,13 +414,13 @@ function initializeVersionJson(isGlobal) {
400
414
 
401
415
  const versionData = {
402
416
  packageVersion: version,
403
- installedVersion: version,
404
417
  installedAt: now,
405
418
  lastUpdated: now,
406
419
  installationType: isGlobal ? 'global' : 'local'
407
420
  };
408
421
 
409
422
  fs.writeFileSync(versionFile, JSON.stringify(versionData, null, 2));
423
+ ensureDotFiveGitignore(dataDir);
410
424
  log.success('Initialized version tracking');
411
425
  }
412
426
 
@@ -486,14 +500,15 @@ function checkExistingInstallation(targetPath) {
486
500
  // Helper to show commands
487
501
  function showCommandsHelp(isGlobal) {
488
502
  log.info('Available commands:');
489
- log.info(' /5:plan-feature - Start feature planning (Phase 1)');
490
- log.info(' /5:plan-implementation - Create implementation plan (Phase 2)');
491
- log.info(' /5:implement-feature - Execute implementation (Phase 3)');
492
- log.info(' /5:verify-implementation - Verify implementation (Phase 4)');
493
- log.info(' /5:review-code - Code review (Phase 5)');
494
- log.info(' /5:configure - Interactive project setup');
495
- log.info(' /5:reconfigure - Refresh docs/skills (no Q&A)');
496
- log.info(' /5:unlock - Remove planning guard lock');
503
+ log.info(' /5:plan-feature - Start feature planning (Phase 1)');
504
+ log.info(' /5:plan-implementation - Create implementation plan (Phase 2)');
505
+ log.info(' /5:implement-feature - Execute implementation (Phase 3)');
506
+ log.info(' /5:verify-implementation - Verify implementation (Phase 4)');
507
+ log.info(' /5:review-code - Code review (Phase 5)');
508
+ log.info(' /5:address-review-findings - Apply review findings & PR comments');
509
+ log.info(' /5:configure - Interactive project setup');
510
+ log.info(' /5:reconfigure - Refresh docs/skills (no Q&A)');
511
+ log.info(' /5:unlock - Remove planning guard lock');
497
512
  log.info('');
498
513
  log.info(`Config file: ${path.join(getDataPath(isGlobal), 'config.json')}`);
499
514
  }
@@ -553,26 +568,23 @@ function performUpdate(targetPath, sourcePath, isGlobal, versionInfo) {
553
568
  // Update version.json
554
569
  const dataDir = getDataPath(isGlobal);
555
570
  const versionFile = path.join(dataDir, 'version.json');
571
+ const now = new Date().toISOString();
556
572
 
557
- let versionData;
558
- if (fs.existsSync(versionFile)) {
559
- versionData = JSON.parse(fs.readFileSync(versionFile, 'utf8'));
560
- } else {
561
- // Legacy install, create version.json
562
- versionData = {
563
- installedAt: new Date().toISOString(),
564
- installationType: isGlobal ? 'global' : 'local'
565
- };
566
- }
567
-
568
- versionData.packageVersion = versionInfo.available;
569
- versionData.installedVersion = versionInfo.available;
570
- versionData.lastUpdated = new Date().toISOString();
573
+ const existing = fs.existsSync(versionFile)
574
+ ? JSON.parse(fs.readFileSync(versionFile, 'utf8'))
575
+ : {};
576
+ const versionData = {
577
+ packageVersion: versionInfo.available,
578
+ installedAt: existing.installedAt || now,
579
+ lastUpdated: now,
580
+ installationType: existing.installationType || (isGlobal ? 'global' : 'local')
581
+ };
571
582
 
572
583
  if (!fs.existsSync(dataDir)) {
573
584
  fs.mkdirSync(dataDir, { recursive: true });
574
585
  }
575
586
  fs.writeFileSync(versionFile, JSON.stringify(versionData, null, 2));
587
+ ensureDotFiveGitignore(dataDir);
576
588
 
577
589
  // Create features directory if it doesn't exist
578
590
  const featuresDir = path.join(dataDir, 'features');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "5-phase-workflow",
3
- "version": "1.6.0",
3
+ "version": "1.7.1",
4
4
  "description": "A 5-phase feature development workflow for Claude Code",
5
5
  "bin": {
6
6
  "5-phase-workflow": "bin/install.js"
@@ -21,6 +21,7 @@ HARD CONSTRAINTS — violations waste tokens and get blocked by plan-guard:
21
21
  - Each component in the table gets: name, action, file path, one-sentence description, complexity
22
22
  - Implementation Notes reference EXISTING pattern files, not new code
23
23
  - If a component needs more than one sentence to describe, split it into multiple components
24
+ - Every component with action "create" that contains logic (services, controllers, repositories, hooks, utilities, helpers) MUST have a corresponding test component in the plan. Declarative components (types, interfaces, models without logic, route registrations, config files) are exempt. When uncertain, include the test.
24
25
  </constraints>
25
26
 
26
27
  <write-rules>
@@ -59,6 +60,7 @@ After writing plan.md, read it back and verify:
59
60
  3. **Scope:** Every component traces back to a requirement in feature.md — if not, remove it
60
61
  4. **Completeness:** Every functional requirement from feature.md has at least one component
61
62
  5. **Description length:** Each Description cell is one sentence. If longer, split the component.
63
+ 6. **Test coverage:** Every "create" component with logic has a corresponding test component. Declarative-only components (types, interfaces, route wiring) are exempt. If a testable component lacks a test, add one.
62
64
 
63
65
  Output the verification result before the completion message.
64
66
  </self-check>
@@ -0,0 +1,364 @@
1
+ ---
2
+ name: 5:address-review-findings
3
+ description: Applies annotated review findings and/or addresses GitHub PR review comments. Use --github to process PR comments only.
4
+ allowed-tools: Bash, Read, Edit, Write, Glob, Grep, AskUserQuestion, Task, Skill, mcp__jetbrains__*
5
+ model: sonnet
6
+ context: fork
7
+ user-invocable: true
8
+ disable-model-invocation: true
9
+ ---
10
+
11
+ <role>
12
+ You are a Fix Applicator. You read annotated review findings and apply approved fixes.
13
+ You do NOT review code. You do NOT implement new features. You do NOT refactor beyond what findings specify.
14
+ You apply fixes exactly as described in the findings file and confirmed by the user.
15
+ You follow the exact step sequence below. Do not skip or reorder steps.
16
+ </role>
17
+
18
+ # Address Review Findings (Phase 5b)
19
+
20
+ This command reads a `review-findings-*.md` file produced by `/5:review-code`, applies all `[FIX]` items, and optionally fetches and addresses GitHub PR review comments.
21
+
22
+ ## Options
23
+
24
+ - **`--github`** — Skip local findings entirely. Only fetch and process GitHub PR review comments for the current branch.
25
+
26
+ ## Process
27
+
28
+ ### Step 1: Determine Mode and Feature Context
29
+
30
+ Check if the command was invoked with `--github`.
31
+
32
+ - **`--github` mode:** Skip Steps 2 and 3. Proceed directly to Step 4 (GitHub PR Integration), which is now mandatory — do not ask the user whether to include PR comments.
33
+ - **Normal mode:** Follow all steps in order.
34
+
35
+ ---
36
+
37
+ Regardless of mode, read `.5/features/*/state.json` using Glob to find all state files. Select the one with the most recent `startedAt` (or `lastUpdated` if present).
38
+
39
+ Read `.5/features/*/state.json` using Glob to find all state files. Select the one with the most recent `startedAt` (or `lastUpdated` if present).
40
+
41
+ Extract:
42
+ - `feature` — feature directory name
43
+ - `ticket` — ticket ID
44
+ - Feature directory path: `.5/features/{feature}/`
45
+
46
+ Also read `.5/config.json` if present. Extract `git.branch` if set.
47
+
48
+ If no state.json files found, ask user via AskUserQuestion: "Which feature are you working on?" — prompt them to enter the feature name manually.
49
+
50
+ ### Step 2: Locate Review Findings File *(skipped in --github mode)*
51
+
52
+ Use Glob to find `review-findings-*.md` in the feature directory:
53
+ ```
54
+ .5/features/{feature}/review-findings-*.md
55
+ ```
56
+
57
+ - **Multiple files found:** Use the one with the most recent timestamp in the filename (format `YYYYMMDD-HHmmss`).
58
+ - **One file found:** Use it.
59
+ - **No file found:** Ask via AskUserQuestion:
60
+ - "No review-findings file found. How would you like to proceed?"
61
+ - Options: "Proceed with GitHub PR comments only" / "Stop — I'll run /5:review-code first"
62
+ - If "Stop", exit with: `Run /5:review-code to generate a findings file first.`
63
+ - If "GitHub PR only", skip to Step 4.
64
+
65
+ #### Parse Findings
66
+
67
+ Read the findings file. For each finding block, extract:
68
+ - File path
69
+ - Line number
70
+ - Category and severity
71
+ - Description
72
+ - Suggested fix
73
+ - Custom instructions (if MANUAL)
74
+ - **Action:** `[FIX]` / `[SKIP]` / `[MANUAL]`
75
+
76
+ Collect three lists:
77
+ - `to_fix` — all `[FIX]` items
78
+ - `to_skip` — all `[SKIP]` items
79
+ - `to_manual` — all `[MANUAL]` items
80
+
81
+ ### Step 3: Present Findings Summary *(skipped in --github mode)*
82
+
83
+ Display a summary to the user:
84
+
85
+ ```
86
+ Review Findings Summary:
87
+ - To fix (automatic): {N}
88
+ - To skip: {N}
89
+ - Manual (custom fix): {N}
90
+
91
+ Fixes to apply:
92
+ {#} {file}:{line} — {description}
93
+
94
+ Manual items:
95
+ {#} {file}:{line} — {description}
96
+ Instructions: {custom instructions}
97
+
98
+ Skipped items:
99
+ {#} {file}:{line} — {description}
100
+ ```
101
+
102
+ ### Step 4: GitHub PR Integration
103
+
104
+ Check if a PR exists for the current branch:
105
+ ```bash
106
+ gh pr list --head "$(git branch --show-current)" --json number,url,title --limit 1
107
+ ```
108
+
109
+ If the `gh` command is not available or returns an error:
110
+ - In `--github` mode: report the error and STOP — PR comments are the only goal.
111
+ - In normal mode: skip this step silently.
112
+
113
+ **If no PR is found:**
114
+ - In `--github` mode: report "No open PR found for the current branch." and STOP.
115
+ - In normal mode: skip this step.
116
+
117
+ **If a PR is found in normal mode:** Ask via AskUserQuestion:
118
+ - "A PR was found: {title} ({url}). Include PR review comments?"
119
+ - Options: "Yes, include PR comments" / "No, local findings only"
120
+ - If "No": skip the rest of this step.
121
+
122
+ **If a PR is found in `--github` mode:** proceed immediately without asking.
123
+
124
+ **Fetch PR comments:**
125
+
126
+ Fetch review comments (inline code comments):
127
+ ```bash
128
+ gh api repos/{owner}/{repo}/pulls/{number}/comments --paginate
129
+ ```
130
+
131
+ Fetch issue comments (general PR comments):
132
+ ```bash
133
+ gh api repos/{owner}/{repo}/issues/{number}/comments --paginate
134
+ ```
135
+
136
+ To get `{owner}` and `{repo}`, run:
137
+ ```bash
138
+ gh repo view --json owner,name
139
+ ```
140
+
141
+ Spawn a sonnet agent to analyze PR comments:
142
+
143
+ ```
144
+ Task tool call:
145
+ subagent_type: general-purpose
146
+ model: sonnet
147
+ description: "Analyze PR review comments"
148
+ prompt: |
149
+ Analyze these GitHub PR review comments and categorize each one.
150
+
151
+ ## Local Findings (already being addressed)
152
+ {list of file:line:description from to_fix + to_skip + to_manual — or "none" in --github mode}
153
+
154
+ ## PR Review Comments
155
+ {raw JSON of review comments}
156
+
157
+ ## PR Issue Comments
158
+ {raw JSON of issue comments}
159
+
160
+ ## Instructions
161
+ For each PR comment, categorize it as:
162
+ - **actionable_fix**: Clear code change needed, not already covered by local findings
163
+ - **duplicate**: Same file + similar issue already in local findings
164
+ - **manual**: Requires judgment or discussion, not a simple code fix
165
+ - **skip**: Automated, bot-generated, resolved, or not actionable
166
+
167
+ For duplicates, note which local finding covers it.
168
+
169
+ ## Output Format
170
+ Return a structured list:
171
+
172
+ ---PR-COMMENTS---
173
+ {id} | {file}:{line} | {category} | {description} | {duplicate_of or "none"}
174
+ ---END-PR-COMMENTS---
175
+
176
+ Rules:
177
+ - DO NOT apply fixes
178
+ - DO NOT interact with user
179
+ - Include every comment in the output
180
+ ```
181
+
182
+ Parse the `---PR-COMMENTS---` block. Collect:
183
+ - `pr_to_fix` — actionable_fix items
184
+ - `pr_duplicates` — duplicate items
185
+ - `pr_manual` — manual items
186
+
187
+ **Present PR comment summary to user:**
188
+ ```
189
+ PR Review Comments:
190
+ - Actionable (new): {N}
191
+ - Duplicates (covered by local findings): {N}
192
+ - Manual/Discussion: {N}
193
+ - Skipped (bot/resolved): {N}
194
+
195
+ Actionable PR comments:
196
+ {#} {file}:{line} — {description}
197
+
198
+ Manual PR comments:
199
+ {#} {file}:{line} — {description}
200
+ ```
201
+
202
+ Ask via AskUserQuestion for each actionable PR comment batch:
203
+ - "Apply actionable PR fixes?" Options: "All" / "None" / "Let me choose"
204
+ - If "Let me choose": present each one and ask Fix / Skip per item.
205
+
206
+ Collect final `pr_approved_fixes` list.
207
+
208
+ ### Step 5: Apply Fixes
209
+
210
+ Apply fixes in this order: local `[FIX]` items first, then local `[MANUAL]` items, then approved PR fixes.
211
+
212
+ #### Grouping Strategy
213
+
214
+ Group fixes by target file. For each file:
215
+ - **1–3 fixes:** Apply directly using Read + Edit tools (bottom-to-top by line number to preserve positions)
216
+ - **4+ fixes or complex logic:** Spawn a haiku or sonnet agent per file
217
+
218
+ #### Direct Application (1–3 fixes per file)
219
+
220
+ For each fix:
221
+ 1. Read the file
222
+ 2. Apply the change using Edit tool
223
+ 3. Track result: APPLIED or FAILED
224
+
225
+ Apply from highest line number to lowest within each file to avoid line offset shifts.
226
+
227
+ #### Agent Application (4+ fixes per file)
228
+
229
+ ```
230
+ Task tool call:
231
+ subagent_type: general-purpose
232
+ model: {haiku for simple | sonnet for complex}
233
+ description: "Apply fixes to {file-path}"
234
+ prompt: |
235
+ Apply these fixes to the file below. Apply all fixes.
236
+ Work from the highest line number to the lowest to avoid line offset issues.
237
+
238
+ ## File
239
+ {file-path}
240
+
241
+ ## Fixes to Apply
242
+ {#1} Line {N}: {description}
243
+ Fix: {suggested fix or custom instructions}
244
+
245
+ {#2} Line {N}: {description}
246
+ Fix: {suggested fix or custom instructions}
247
+
248
+ ## Instructions
249
+ 1. Read the file first
250
+ 2. Apply each fix using Edit tool
251
+ 3. Apply from highest line to lowest
252
+ 4. Do NOT introduce unrelated changes
253
+ 5. Report each fix as APPLIED or FAILED with reason
254
+
255
+ ## Output Format
256
+ {#} APPLIED | {description}
257
+ {#} FAILED | {description} | {reason}
258
+ ```
259
+
260
+ Collect all APPLIED/FAILED results.
261
+
262
+ #### Apply [MANUAL] Items
263
+
264
+ For each `[MANUAL]` item with custom instructions:
265
+ - Read the file
266
+ - Apply the custom instructions using Edit tool
267
+ - If instructions are ambiguous, spawn a sonnet agent with the full context
268
+
269
+ ### Step 6: Reply to GitHub PR Comments
270
+
271
+ For each PR comment that was processed (from `pr_approved_fixes`, `pr_duplicates`, and `pr_manual`):
272
+
273
+ Post a reply using the GitHub API:
274
+
275
+ **For review comments (inline):**
276
+ ```bash
277
+ gh api repos/{owner}/{repo}/pulls/{number}/comments/{comment_id}/replies \
278
+ --method POST \
279
+ --field body="{reply text}"
280
+ ```
281
+
282
+ **For issue comments (general):**
283
+ ```bash
284
+ gh api repos/{owner}/{repo}/issues/{number}/comments \
285
+ --method POST \
286
+ --field body="{reply text}"
287
+ ```
288
+
289
+ Reply templates:
290
+ - **Fixed:** `Applied fix: {description}. Will be included in the next push.`
291
+ - **Skipped:** `Reviewed — not addressing: {reason if known, else "will handle separately"}`
292
+ - **Duplicate (applied):** `Covered by local review findings — fix applied.`
293
+ - **Duplicate (skipped):** `Covered by local review findings — marked as skip.`
294
+ - **Manual/Discussion:** `Noted. This requires manual review: {description}`
295
+
296
+ If `gh api` is unavailable or fails, log the failure and continue. Do NOT abort for reply failures.
297
+
298
+ ### Step 7: Verification
299
+
300
+ After all fixes are applied:
301
+
302
+ 1. **Build:** Use the `/build-project` skill: `Skill tool: skill="build-project", args="target=compile"`
303
+ 2. **Test:** Use the `/run-tests` skill: `Skill tool: skill="run-tests", args="target=all"`
304
+ 3. **Lint:** Check for any lint warnings and errors
305
+
306
+ If build fails:
307
+ - Report which file(s) were modified and likely caused the failure
308
+ - Ask via AskUserQuestion: "Build failed after applying fixes. What would you like to do?"
309
+ - Options: "Show me the error and I'll fix manually" / "Revert the last fix and retry"
310
+ - If revert: re-read the original file content (from git: `git show HEAD:{file}`) and restore it, then re-run build
311
+
312
+ ### Step 8: Save Summary Report
313
+
314
+ Write `.5/features/{feature}/review-summary-{YYYYMMDD-HHmmss}.md`.
315
+
316
+ Use the template structure from `.claude/templates/workflow/REVIEW-SUMMARY.md`. Include:
317
+
318
+ ```markdown
319
+ # Code Review Summary
320
+
321
+ **Reviewed:** {feature} — findings from {findings-filename}
322
+ **Timestamp:** {ISO-timestamp}
323
+ **User Decisions:** Applied {N} fixes, skipped {N}, {N} manual
324
+
325
+ ## Summary
326
+
327
+ - **Local Fixes Applied:** {N}
328
+ - **Local Fixes Skipped:** {N}
329
+ - **Manual Items Applied:** {N}
330
+ - **PR Comments Fixed:** {N}
331
+ - **PR Comments Skipped:** {N}
332
+ - **Build:** {passed/failed}
333
+ - **Tests:** {passed/failed}
334
+
335
+ ## Applied Fixes
336
+ ...
337
+
338
+ ## Skipped Items
339
+ ...
340
+
341
+ ## Manual Items
342
+ ...
343
+
344
+ ## PR Comment Replies
345
+ ...
346
+ ```
347
+
348
+ ### Step 9: Final Output
349
+
350
+ Output exactly:
351
+
352
+ ```
353
+ Review findings addressed.
354
+
355
+ Local findings: {N fixed / N skipped / N manual — or "skipped (--github mode)"}
356
+ PR comments: {N fixed / N skipped / N replied — or "none"}
357
+
358
+ Build: {passed/failed/skipped}
359
+ Tests: {passed/failed/skipped}
360
+
361
+ Summary saved at .5/features/{feature}/review-summary-{timestamp}.md
362
+ ```
363
+
364
+ STOP. Do not implement new features. Your job is done.
@@ -4,6 +4,7 @@ description: Configures the project. Analyzes project, gathers preferences, writ
4
4
  allowed-tools: Read, Write, Bash, Glob, Grep, AskUserQuestion
5
5
  context: inherit
6
6
  user-invocable: true
7
+ disable-model-invocation: true
7
8
  ---
8
9
 
9
10
  # Configure (Phase 1 - Plan Feature for Project Configuration)
@@ -4,6 +4,7 @@ description: Discusses and refines an existing feature specification through ite
4
4
  allowed-tools: Read, Write, Glob, Grep, Task, AskUserQuestion
5
5
  context: inherit
6
6
  user-invocable: true
7
+ disable-model-invocation: true
7
8
  ---
8
9
 
9
10
  # Discuss Feature Specification (Phase 1 - Optional Iteration)
@@ -4,6 +4,7 @@ description: Executes an implementation plan by delegating to agents. Phase 3 of
4
4
  allowed-tools: Task, Read, Write, Glob, Grep, Bash, TaskCreate, TaskUpdate, TaskList
5
5
  context: fork
6
6
  user-invocable: true
7
+ disable-model-invocation: true
7
8
  ---
8
9
 
9
10
  # Implement Feature (Phase 3)
@@ -236,6 +237,16 @@ Update `verificationResults` in state.json:
236
237
  ```
237
238
  Also update `lastUpdated`.
238
239
 
240
+ **4b. Check test file creation**
241
+
242
+ For each component in the plan that appears to be a test file (filename contains `.test.`, `.spec.`, `test_`, or lives in a `__tests__`/`tests` directory):
243
+ - Verify the file was actually created using Glob
244
+ - If a planned test file was NOT created, record it as a verification warning
245
+
246
+ For each non-test component with action "create" that contains logic:
247
+ - Check if its corresponding test component exists in the plan
248
+ - If a test was planned but is in `failedAttempts`, flag it prominently
249
+
239
250
  **MANDATORY VERIFICATION:** Read state.json back and confirm `verificationResults.builtAt` is set.
240
251
 
241
252
  If build or tests fail:
@@ -267,6 +278,8 @@ Implementation complete!
267
278
  - {M} components skipped (failures that exhausted retries)
268
279
  - Build: {status}
269
280
  - Tests: {status}
281
+ - Test files created: {N}/{M} planned test files exist
282
+ {If any planned test files missing: "⚠ Missing test files: {list}"}
270
283
  {If git.autoCommit was true: "- Commits: {N} atomic commits created"}
271
284
 
272
285
  {If any failures: list them with errors}
@@ -5,6 +5,7 @@ agent: feature-planner
5
5
  allowed-tools: Read, Write, Task, AskUserQuestion, TaskCreate, TaskUpdate, TaskList, TaskGet
6
6
  context: fork
7
7
  user-invocable: true
8
+ disable-model-invocation: true
8
9
  ---
9
10
 
10
11
  # Plan Feature (Phase 1)
@@ -5,6 +5,7 @@ agent: implementation-planner
5
5
  allowed-tools: Read, Write, Task, AskUserQuestion
6
6
  context: fork
7
7
  user-invocable: true
8
+ disable-model-invocation: true
8
9
  ---
9
10
 
10
11
  # Plan Implementation (Phase 2)
@@ -43,6 +44,7 @@ Add emergency schedule tracking to products with date validation.
43
44
  | 3 | Schedule controller | create | src/controllers/ScheduleController.ts | REST endpoints: GET/POST/DELETE /api/schedules | moderate |
44
45
  | 3 | Register routes | modify | src/routes/index.ts | Add schedule routes to router | simple |
45
46
  | 4 | Schedule service tests | create | src/services/__tests__/ScheduleService.test.ts | Test validation and CRUD | moderate |
47
+ | 4 | Schedule controller tests | create | src/controllers/__tests__/ScheduleController.test.ts | Test REST endpoints and error handling | moderate |
46
48
 
47
49
  ## Implementation Notes
48
50
 
@@ -96,12 +98,14 @@ Quick codebase scan for implementation planning.
96
98
  2. Identify where similar components live (models, services, controllers, tests)
97
99
  3. Note naming conventions from existing files
98
100
  4. Find example files that can serve as patterns for new components
101
+ 5. Identify the project's test framework, test file conventions, and test directory structure (e.g., __tests__/, tests/, *.test.ts, *.spec.ts, test_*.py)
99
102
 
100
103
  **Report Format:**
101
104
  - Project structure (key directories)
102
105
  - Naming conventions observed
103
106
  - Pattern files for each component type
104
107
  - Where new files should be placed
108
+ - Test setup: framework, file naming pattern, test directory location (or "no test setup detected")
105
109
 
106
110
  **IMPORTANT:** Quick scan, not deep analysis. Focus on structure and patterns.
107
111
  **READ-ONLY:** Only use Read, Glob, and Grep tools.
@@ -141,9 +145,13 @@ Group into steps:
141
145
  - **Step 1**: Foundation (models, types, interfaces)
142
146
  - **Step 2**: Logic (services, business rules)
143
147
  - **Step 3**: Integration (controllers, routes, wiring)
144
- - **Step 4**: Tests (if not alongside components)
148
+ - **Final step**: Tests for all logic-bearing components
145
149
 
146
- Not every feature needs all steps. Use what makes sense.
150
+ **Test requirement:** Every component with action "create" that contains logic (services, controllers, repositories, hooks, utilities, helpers) MUST have a corresponding test component. Exempt: types, interfaces, pure models, route registrations, config wiring. When uncertain, include the test.
151
+
152
+ If the explore agent reported "no test setup detected," still include test components but add an Implementation Note: "Project has no test framework detected — test components may need framework setup first or may be skipped during implementation."
153
+
154
+ Not every feature needs all non-test steps. Use what makes sense. But testable components always need tests.
147
155
 
148
156
  **Parallel execution:** Components in the same step run in parallel. Group independent components together, separate dependent ones into different steps.
149
157
 
@@ -173,6 +181,7 @@ Plan self-check:
173
181
  - Scope: pass/fail
174
182
  - Completeness: pass/fail
175
183
  - Description length: pass/fail
184
+ - Test coverage: pass/fail
176
185
  ```
177
186
 
178
187
  If any check fails, fix plan.md before proceeding to the completion output.
@@ -4,6 +4,7 @@ description: Execute small, focused implementations quickly with state tracking
4
4
  allowed-tools: Read, Write, Edit, Glob, Grep, Bash, Task, AskUserQuestion, Skill, TaskCreate, TaskUpdate, TaskList, mcp__jetbrains__*
5
5
  context: fork
6
6
  user-invocable: true
7
+ disable-model-invocation: true
7
8
  ---
8
9
 
9
10
  # Quick Implement
@@ -4,6 +4,7 @@ description: Lightweight refresh of project documentation and skills without ful
4
4
  allowed-tools: Read, Write, Bash, Glob, Grep, Task, AskUserQuestion
5
5
  context: fork
6
6
  user-invocable: true
7
+ disable-model-invocation: true
7
8
  ---
8
9
 
9
10
  # Reconfigure (Lightweight Refresh)
@@ -1,19 +1,19 @@
1
1
  ---
2
2
  name: 5:review-code
3
- description: Reviews code changes using Claude (built-in) or CodeRabbit CLI. Handles user interaction and fix application in main context.
4
- allowed-tools: Bash, Read, Edit, Write, Glob, Grep, AskUserQuestion, Task, mcp__jetbrains__*
3
+ description: Reviews code changes using Claude (built-in) or CodeRabbit CLI. Categorizes findings and saves them for /5:address-review-findings.
4
+ allowed-tools: Bash, Read, Glob, Grep, AskUserQuestion, Task, mcp__jetbrains__*
5
5
  model: sonnet
6
6
  context: fork
7
7
  user-invocable: true
8
+ disable-model-invocation: true
8
9
  ---
9
10
 
10
11
  <role>
11
- You are a Code Reviewer. You review code and apply user-approved fixes.
12
- You do NOT implement new features. You do NOT refactor beyond review findings.
13
- You ALWAYS get user consent before applying ANY fix.
14
- You ALWAYS verify changes after applying fixes (build + test).
12
+ You are a Code Reviewer. Your job is to review code, categorize findings, and save them to a findings file.
13
+ You do NOT apply fixes. You do NOT implement new features. You do NOT refactor code.
14
+ Fix application is handled by /5:address-review-findings.
15
15
  You follow the exact step sequence below. Do not skip or reorder steps.
16
- After saving the review report, you are DONE.
16
+ After saving the findings file, you are DONE.
17
17
  </role>
18
18
 
19
19
  # Review Code (Phase 5)
@@ -44,35 +44,23 @@ If not installed or not authenticated, ask user via AskUserQuestion:
44
44
  - "Switch to Claude for this review? (Recommended)" / "I'll install CodeRabbit first"
45
45
  - If they choose CodeRabbit setup, provide install instructions and STOP
46
46
 
47
- ### Step 2: Check for Apply Mode
48
-
49
- If user invoked with `apply` argument (`/5:review-code apply`):
50
- - Skip to Step 10 (Apply Annotated Findings)
51
- - Do NOT run a new review
52
-
53
- Otherwise, continue with new review.
54
-
55
- ### Step 3: Determine What to Review
47
+ ### Step 2: Determine What to Review
56
48
 
57
49
  Ask the user via AskUserQuestion:
58
50
 
59
- **Question 1: What to review?**
51
+ **Question: What to review?**
60
52
  1. Staged changes (`git diff --cached`) — default
61
53
  2. Unstaged changes (`git diff`)
62
54
  3. All changes (`git diff HEAD`)
63
55
  4. Current branch vs main/master (`git diff main...HEAD`)
64
56
 
65
- **Question 2: How to present results?**
66
- 1. Interactive (show findings, apply fixes immediately) — default
67
- 2. Save to file (for later annotation with `[FIX]`/`[SKIP]`/`[MANUAL]`)
68
-
69
- ### Step 4: Spawn Review Agent
57
+ ### Step 3: Spawn Review Agent
70
58
 
71
59
  Spawn a single agent to execute the review. Do NOT run the review yourself.
72
60
 
73
- **Architecture:** You (main agent) handle user interaction and fix application. The spawned agent runs the review and categorizes findings.
61
+ **Architecture:** You (main agent) handle user interaction. The spawned agent runs the review and categorizes findings.
74
62
 
75
- #### 4A: CodeRabbit Review Agent
63
+ #### 3A: CodeRabbit Review Agent
76
64
 
77
65
  ```
78
66
  Task tool call:
@@ -83,7 +71,7 @@ Task tool call:
83
71
  Run CodeRabbit CLI and categorize findings.
84
72
 
85
73
  ## Review Scope
86
- Scope: {scope from Step 3}
74
+ Scope: {scope from Step 2}
87
75
  Base Branch: {branch-name if scope is "branch"}
88
76
 
89
77
  ## Process
@@ -115,7 +103,7 @@ Task tool call:
115
103
  - Include ALL findings
116
104
  ```
117
105
 
118
- #### 4B: Claude Review Agent
106
+ #### 3B: Claude Review Agent
119
107
 
120
108
  ```
121
109
  Task tool call:
@@ -127,7 +115,7 @@ Task tool call:
127
115
  Review this code blind, purely on its merits.
128
116
 
129
117
  ## Review Scope
130
- Scope: {scope from Step 3}
118
+ Scope: {scope from Step 2}
131
119
  Base Branch: {branch-name if scope is "branch"}
132
120
 
133
121
  ## Process
@@ -169,17 +157,13 @@ Task tool call:
169
157
  - Be thorough but practical — focus on real issues, not style nitpicks
170
158
  ```
171
159
 
172
- ### Step 5: Process Agent Results
160
+ ### Step 4: Process Agent Results
173
161
 
174
162
  Receive structured results from the agent. If agent returned failure, report error and STOP.
175
163
 
176
- **If user selected "Save to file":** Skip to Step 9.
164
+ ### Step 5: Present Findings
177
165
 
178
- **If user selected "Interactive":** Continue to Step 6.
179
-
180
- ### Step 6: Present Overview and Ask User
181
-
182
- Present ALL findings to the user first. Do NOT apply anything yet.
166
+ Present ALL findings to the user.
183
167
 
184
168
  ```
185
169
  Code Review Results:
@@ -200,87 +184,31 @@ Manual Review Needed:
200
184
  - {file}:{line} - {description}
201
185
  ```
202
186
 
203
- Ask via AskUserQuestion: "Which fixable issues should be applied?"
204
- - Options: All / Selected / None
205
-
206
- ### Step 7: Apply User-Approved Fixes
207
-
208
- **ONLY apply fixes the user has agreed to.**
209
-
210
- - If "All": Apply all fixable issues
211
- - If "Selected": Ask which specific fixes, then apply only those
212
- - If "None": Skip to Step 8
213
-
214
- For each fix:
215
- 1. Read the file
216
- 2. Apply the fix using Edit tool
217
- 3. Track applied fixes
218
-
219
- ### Step 8: Handle Questions
220
-
221
- If there are questions from the reviewer, ask via AskUserQuestion:
222
- - "Ask me each question" / "Skip all questions"
223
-
224
- If "Ask me each": Present each question individually via AskUserQuestion. If the answer requires a code change, apply it.
225
-
226
- ### Step 9: Save Findings to File (File-Based Mode)
227
-
228
- For "Save to file" mode only.
187
+ ### Step 6: Save Findings to File
229
188
 
230
189
  Determine feature name from `.5/features/*/state.json` (most recent by `startedAt` field) or ask user.
231
190
 
232
- Write to `.5/features/{feature-name}/review-{YYYYMMDD-HHmmss}-findings.md`.
233
-
234
- Use the template structure from `.claude/templates/workflow/REVIEW-FINDINGS.md`. Include all findings with `[FIX]`/`[SKIP]`/`[MANUAL]` action markers.
235
-
236
- Tell user: "Findings saved. Edit the file to mark actions, then run `/5:review-code apply`"
237
-
238
- Skip to REVIEW COMPLETE.
239
-
240
- ### Step 10: Apply Annotated Findings (Apply Mode)
241
-
242
- When invoked with `apply`:
243
-
244
- 1. Determine feature name from `.5/features/*/state.json` (most recent by `startedAt` field) or ask user
245
- 2. Find most recent `review-*-findings.md` in the feature folder
246
- 3. If none found, tell user to run `/5:review-code` first and STOP
247
- 4. Parse each finding and its action marker: `[FIX]`, `[SKIP]`, `[MANUAL]`
248
- 5. Apply `[FIX]` findings using Edit tool
249
- 6. Apply `[MANUAL]` findings using custom instructions from the file
250
- 7. Skip `[SKIP]` findings
251
- 8. Continue to Step 11
191
+ Write to `.5/features/{feature-name}/review-findings-{YYYYMMDD-HHmmss}.md`.
252
192
 
253
- ### Step 11: Verify Changes
254
-
255
- After applying any fixes (interactive or file-based):
256
-
257
- 1. **Build:** Use the `/build-project` skill: `Skill tool: skill="build-project", args="target=compile"`
258
- 2. **Test:** Use the `/run-tests` skill: `Skill tool: skill="run-tests", args="target=all"`
259
- 3. If build fails: report which fixes caused issues
260
- 4. If tests fail: report which tests failed
261
-
262
- ### Step 12: Save Review Report
263
-
264
- **Interactive mode:** Save summary to `.5/features/{feature-name}/review-{YYYYMMDD-HHmmss}.md`
265
-
266
- Use the template structure from `.claude/templates/workflow/REVIEW-SUMMARY.md`.
267
-
268
- **Apply mode:** Append application results to the findings file with: fixes applied count, custom fixes count, skipped count, build/test status.
193
+ Use the template structure from `.claude/templates/workflow/REVIEW-FINDINGS.md`. All findings get their default action markers:
194
+ - Fixable items → `[FIX]`
195
+ - Manual items `[MANUAL]`
196
+ - Questions → `[FIX]` (with the question as the suggested fix instruction)
269
197
 
270
198
  ## REVIEW COMPLETE
271
199
 
272
- After saving the report, output exactly:
200
+ Output exactly:
273
201
 
274
202
  ```
275
203
  Review complete.
276
204
 
277
- - Fixes applied: {N}
278
- - Questions resolved: {N}
205
+ - Fixable: {N}
206
+ - Questions: {N}
279
207
  - Manual review needed: {N}
280
- - Build: {passed/failed}
281
- - Tests: {passed/failed}
282
208
 
283
- Report saved at `.5/features/{feature-name}/review-{timestamp}.md`
209
+ Findings saved at `.5/features/{feature-name}/review-findings-{timestamp}.md`
210
+
211
+ Edit the file to adjust actions ([FIX] / [SKIP] / [MANUAL]), then run `/5:address-review-findings {feature-name}` to apply fixes and optionally address GitHub PR comments.
284
212
  ```
285
213
 
286
214
  STOP. You are a reviewer. Your job is done. Do not implement new features.
@@ -4,6 +4,7 @@ description: Remove the planning guard lock to allow edits outside the workflow
4
4
  allowed-tools: Bash
5
5
  context: inherit
6
6
  user-invocable: true
7
+ disable-model-invocation: true
7
8
  ---
8
9
 
9
10
  # Unlock Planning Guard
@@ -4,6 +4,7 @@ description: Update the 5-Phase Workflow to the latest version
4
4
  allowed-tools: Bash, Read, AskUserQuestion
5
5
  context: inherit
6
6
  user-invocable: true
7
+ disable-model-invocation: true
7
8
  ---
8
9
 
9
10
  # Update 5-Phase Workflow
@@ -4,6 +4,7 @@ description: Verifies a feature implementation is complete and working with mult
4
4
  allowed-tools: Read, Glob, Grep, Bash, Write, Task, AskUserQuestion
5
5
  context: fork
6
6
  user-invocable: true
7
+ disable-model-invocation: true
7
8
  ---
8
9
 
9
10
  # Verify Implementation (Phase 4)
@@ -154,6 +155,12 @@ For each component with action `create` in the plan:
154
155
 
155
156
  This is a lightweight check — it only verifies test files exist for new code, not test quality.
156
157
 
158
+ **Test requirement enforcement:**
159
+ - Components with logic (services, controllers, repositories, hooks, utilities, helpers) without tests → MISSING_REQUIRED_TEST (error-level)
160
+ - Declarative components (types, interfaces, models without logic) without tests → MISSING_OPTIONAL_TEST (info-level, not counted as issues)
161
+
162
+ If no test framework detected (no test runner in config, no existing test files found via Glob for `**/*.test.*`, `**/*.spec.*`, `**/test_*.*`), downgrade all MISSING_REQUIRED_TEST to warnings with note: "No test framework detected."
163
+
157
164
  ### Step 5: Determine Status
158
165
 
159
166
  Evaluate all three layers:
@@ -168,10 +175,11 @@ Evaluate all three layers:
168
175
 
169
176
  **PARTIAL** — infrastructure OK but gaps exist:
170
177
  - All files exist AND build succeeds AND tests pass
171
- - BUT: some acceptance criteria not satisfied, OR some requirements not implemented, OR some components partial, OR some new files lack tests
178
+ - BUT: some acceptance criteria not satisfied, OR some requirements not implemented, OR some components partial, OR logic-bearing components lack tests but project has no test framework
172
179
 
173
180
  **FAILED** — infrastructure problems:
174
181
  - Any files missing, OR build fails, OR tests fail
182
+ - Any logic-bearing components lack test files (MISSING_REQUIRED_TEST) AND project has a test framework
175
183
 
176
184
  ### Step 6: Generate Verification Report
177
185
 
@@ -223,7 +231,8 @@ Build fix entries from verification results:
223
231
  - Partial components → fix: describe what's missing from the component
224
232
 
225
233
  **From Layer 3 (Quality):**
226
- - Missing test files → fix: create test file for the component
234
+ - Missing required test files (logic-bearing components) → fix: create test file for the component (priority: high)
235
+ - Missing optional test files (declarative components) → note in report, no fix entry
227
236
 
228
237
  Each fix entry follows the same table format as `plan.md`:
229
238
 
@@ -40,7 +40,7 @@ async function checkForUpdates(workspaceDir) {
40
40
  }
41
41
 
42
42
  // Compare versions
43
- const installed = versionData.installedVersion;
43
+ const installed = versionData.packageVersion;
44
44
  const latestVersion = await getLatestVersion();
45
45
 
46
46
  let newLatest = null;
@@ -48,16 +48,16 @@ async function checkForUpdates(workspaceDir) {
48
48
  newLatest = latestVersion;
49
49
  }
50
50
 
51
- // Only write if latestAvailableVersion actually changed
52
- const oldLatest = versionData.latestAvailableVersion || null;
51
+ // Read/write latestAvailableVersion from .update-cache.json (gitignored)
52
+ const cacheFile = path.join(path.dirname(versionFile), '.update-cache.json');
53
+ let cacheData = {};
54
+ if (fs.existsSync(cacheFile)) {
55
+ try { cacheData = JSON.parse(fs.readFileSync(cacheFile, 'utf8')); } catch(e) {}
56
+ }
57
+ const oldLatest = cacheData.latestAvailableVersion || null;
53
58
  if (newLatest !== oldLatest) {
54
- versionData.latestAvailableVersion = newLatest;
55
-
56
- // Clean up legacy throttling fields
57
- delete versionData.updateCheckLastRun;
58
- delete versionData.updateCheckFrequency;
59
-
60
- fs.writeFileSync(versionFile, JSON.stringify(versionData, null, 2));
59
+ cacheData.latestAvailableVersion = newLatest;
60
+ fs.writeFileSync(cacheFile, JSON.stringify(cacheData, null, 2));
61
61
  }
62
62
 
63
63
  process.exit(0);
@@ -50,9 +50,16 @@ process.stdin.on('end', () => {
50
50
  const versionFile = path.join(dir, '.5', 'version.json');
51
51
  const versionData = JSON.parse(fs.readFileSync(versionFile, 'utf8'));
52
52
 
53
- // Update check
54
- const latest = versionData.latestAvailableVersion;
55
- const installed = versionData.installedVersion;
53
+ // Update check — read latestAvailableVersion from cache file (gitignored)
54
+ const cacheFile = path.join(dir, '.5', '.update-cache.json');
55
+ let latest = null;
56
+ if (fs.existsSync(cacheFile)) {
57
+ try {
58
+ const cache = JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
59
+ latest = cache.latestAvailableVersion || null;
60
+ } catch(e) {}
61
+ }
62
+ const installed = versionData.packageVersion;
56
63
  if (latest && installed && compareVersions(installed, latest) < 0) {
57
64
  updateIndicator = ` | \x1b[33m↑${latest} → /5:update\x1b[0m`;
58
65
  }
@@ -9,6 +9,8 @@ created: {ISO-timestamp}
9
9
  - Description column: one action-oriented sentence per component
10
10
  - Implementation Notes: reference existing files as patterns, no code snippets
11
11
  - Components table must cover all functional requirements from feature.md
12
+ - Every "create" component with logic (services, controllers, repositories, utilities) must have a corresponding test component
13
+ - Declarative-only components (types, interfaces, route wiring) are exempt from test requirements
12
14
  -->
13
15
 
14
16
  # Implementation Plan: {TICKET-ID}
@@ -24,6 +26,7 @@ created: {ISO-timestamp}
24
26
  | 2 | {name} | create | {path} | {what it does} | moderate |
25
27
  | 2 | {name} | modify | {path} | {what to change} | moderate |
26
28
  | 3 | {name} | create | {path} | {what it does} | complex |
29
+ | 4 | {name} tests | create | {test-path} | Test {what it tests} | moderate |
27
30
 
28
31
  ## Implementation Notes
29
32
 
@@ -14,9 +14,9 @@
14
14
  - `[SKIP]` - Don't apply this fix (change FIX to SKIP)
15
15
  - `[MANUAL]` - Custom instructions (change FIX to MANUAL and add instructions)
16
16
  3. Save this file
17
- 4. Run: `/review-code apply`
17
+ 4. Run: `/5:address-review-findings`
18
18
 
19
- The apply command will read your annotations and apply marked fixes.
19
+ The command will read your annotations and apply marked fixes.
20
20
 
21
21
  ---
22
22
 
@@ -55,4 +55,4 @@ The apply command will read your annotations and apply marked fixes.
55
55
 
56
56
  **Next Steps:**
57
57
  1. Edit this file to mark which findings to fix
58
- 2. Run: `/review-code apply`
58
+ 2. Run: `/5:address-review-findings`
@@ -73,14 +73,22 @@
73
73
 
74
74
  ### Test Coverage for New Files
75
75
 
76
+ **Required Tests (logic-bearing components):**
77
+
78
+ | New File | Test File | Status |
79
+ |----------|-----------|--------|
80
+ | {src/path/Service.ts} | {src/path/Service.test.ts} | HAS TEST |
81
+ | {src/path/Controller.ts} | — | MISSING REQUIRED TEST |
82
+
83
+ **Optional Tests (declarative components):**
84
+
76
85
  | New File | Test File | Status |
77
86
  |----------|-----------|--------|
78
- | {src/path/File.ts} | {src/path/File.test.ts} | HAS TEST |
79
- | {src/path/Other.ts} | — | NO TEST |
87
+ | {src/path/types.ts} | | NO TEST (exempt) |
80
88
 
81
- **Result:** {N}/{M} new files have tests
89
+ **Result:** {N}/{M} required test files exist
82
90
 
83
- **Layer 3 Result:** PASSED | PARTIAL
91
+ **Layer 3 Result:** PASSED | FAILED | PARTIAL
84
92
 
85
93
  ---
86
94