takt 0.1.6 → 0.2.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 (68) hide show
  1. package/README.md +136 -40
  2. package/dist/cli.js +11 -2
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/addTask.d.ts +15 -0
  5. package/dist/commands/addTask.d.ts.map +1 -0
  6. package/dist/commands/addTask.js +101 -0
  7. package/dist/commands/addTask.js.map +1 -0
  8. package/dist/commands/help.d.ts.map +1 -1
  9. package/dist/commands/help.js +16 -5
  10. package/dist/commands/help.js.map +1 -1
  11. package/dist/commands/index.d.ts +3 -0
  12. package/dist/commands/index.d.ts.map +1 -1
  13. package/dist/commands/index.js +3 -0
  14. package/dist/commands/index.js.map +1 -1
  15. package/dist/commands/refreshBuiltin.d.ts +11 -0
  16. package/dist/commands/refreshBuiltin.d.ts.map +1 -0
  17. package/dist/commands/refreshBuiltin.js +37 -0
  18. package/dist/commands/refreshBuiltin.js.map +1 -0
  19. package/dist/commands/taskExecution.d.ts +9 -0
  20. package/dist/commands/taskExecution.d.ts.map +1 -1
  21. package/dist/commands/taskExecution.js +30 -2
  22. package/dist/commands/taskExecution.js.map +1 -1
  23. package/dist/commands/watchTasks.d.ts +12 -0
  24. package/dist/commands/watchTasks.d.ts.map +1 -0
  25. package/dist/commands/watchTasks.js +98 -0
  26. package/dist/commands/watchTasks.js.map +1 -0
  27. package/dist/models/schemas.js +5 -5
  28. package/dist/models/schemas.js.map +1 -1
  29. package/dist/resources/index.d.ts +5 -0
  30. package/dist/resources/index.d.ts.map +1 -1
  31. package/dist/resources/index.js +33 -9
  32. package/dist/resources/index.js.map +1 -1
  33. package/dist/task/display.d.ts.map +1 -1
  34. package/dist/task/display.js +19 -1
  35. package/dist/task/display.js.map +1 -1
  36. package/dist/task/index.d.ts +4 -0
  37. package/dist/task/index.d.ts.map +1 -1
  38. package/dist/task/index.js +4 -0
  39. package/dist/task/index.js.map +1 -1
  40. package/dist/task/parser.d.ts +33 -0
  41. package/dist/task/parser.d.ts.map +1 -0
  42. package/dist/task/parser.js +86 -0
  43. package/dist/task/parser.js.map +1 -0
  44. package/dist/task/runner.d.ts +6 -0
  45. package/dist/task/runner.d.ts.map +1 -1
  46. package/dist/task/runner.js +33 -42
  47. package/dist/task/runner.js.map +1 -1
  48. package/dist/task/schema.d.ts +32 -0
  49. package/dist/task/schema.d.ts.map +1 -0
  50. package/dist/task/schema.js +31 -0
  51. package/dist/task/schema.js.map +1 -0
  52. package/dist/task/watcher.d.ts +33 -0
  53. package/dist/task/watcher.d.ts.map +1 -0
  54. package/dist/task/watcher.js +69 -0
  55. package/dist/task/watcher.js.map +1 -0
  56. package/dist/task/worktree.d.ts +31 -0
  57. package/dist/task/worktree.d.ts.map +1 -0
  58. package/dist/task/worktree.js +112 -0
  59. package/dist/task/worktree.js.map +1 -0
  60. package/dist/utils/slug.d.ts +12 -0
  61. package/dist/utils/slug.d.ts.map +1 -0
  62. package/dist/utils/slug.js +18 -0
  63. package/dist/utils/slug.js.map +1 -0
  64. package/package.json +3 -2
  65. package/resources/global/en/workflows/simple.yaml +594 -0
  66. package/resources/global/ja/agents/default/architect.md +120 -0
  67. package/resources/global/ja/workflows/default.yaml +12 -0
  68. package/resources/global/ja/workflows/simple.yaml +594 -0
@@ -0,0 +1,594 @@
1
+ # Simple TAKT Workflow
2
+ # Plan -> Coder -> Architect Review -> AI Review -> Supervisor Approval
3
+ # (Simplified version of default - removed improve, fix, ai_fix, security_review, security_fix)
4
+ #
5
+ # Template Variables:
6
+ # {iteration} - Workflow-wide turn count (total steps executed across all agents)
7
+ # {max_iterations} - Maximum iterations allowed for the workflow
8
+ # {step_iteration} - Per-step iteration count (how many times THIS step has been executed)
9
+ # {task} - Original user request
10
+ # {previous_response} - Output from the previous step
11
+ # {git_diff} - Current uncommitted changes (git diff)
12
+ # {user_inputs} - Accumulated user inputs during workflow
13
+ # {report_dir} - Report directory name (e.g., "20250126-143052-task-summary")
14
+
15
+ name: simple
16
+ description: Simplified development workflow (plan -> implement -> review -> ai_review -> supervise)
17
+
18
+ max_iterations: 20
19
+
20
+ initial_step: plan
21
+
22
+ steps:
23
+ - name: plan
24
+ agent: ~/.takt/agents/default/planner.md
25
+ allowed_tools:
26
+ - Read
27
+ - Glob
28
+ - Grep
29
+ - Bash
30
+ - WebSearch
31
+ - WebFetch
32
+ status_rules_prompt: |
33
+ # ⚠️ REQUIRED: Status Output Rules ⚠️
34
+
35
+ **Without this tag, the workflow will stop.**
36
+ Your final output MUST include a status tag following the rules below.
37
+
38
+ ## Judgment Criteria
39
+
40
+ | Situation | Judgment |
41
+ |-----------|----------|
42
+ | Requirements clear and implementable | DONE |
43
+ | Requirements unclear, insufficient info | BLOCKED |
44
+
45
+ ## Output Format
46
+
47
+ | Situation | Tag |
48
+ |-----------|-----|
49
+ | Analysis complete | `[PLANNER:DONE]` |
50
+ | Insufficient info | `[PLANNER:BLOCKED]` |
51
+
52
+ ### Output Examples
53
+
54
+ **DONE case:**
55
+ ```
56
+ [PLANNER:DONE]
57
+ ```
58
+
59
+ **BLOCKED case:**
60
+ ```
61
+ [PLANNER:BLOCKED]
62
+
63
+ Clarifications needed:
64
+ - {Question 1}
65
+ - {Question 2}
66
+ ```
67
+ instruction_template: |
68
+ ## Workflow Context
69
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
70
+ - Step Iteration: {step_iteration} (times this step has run)
71
+ - Step: plan (Task Analysis)
72
+ - Report Directory: .takt/reports/{report_dir}/
73
+ - Report File: .takt/reports/{report_dir}/00-plan.md
74
+
75
+ ## User Request
76
+ {task}
77
+
78
+ ## Previous Response (when returned from implement)
79
+ {previous_response}
80
+
81
+ ## Instructions
82
+ Analyze the task and create an implementation plan.
83
+
84
+ **Note:** If returned from implement step (Previous Response exists),
85
+ review and revise the plan based on that feedback (replan).
86
+
87
+ **Tasks:**
88
+ 1. Understand the requirements
89
+ 2. Identify impact scope
90
+ 3. Decide implementation approach
91
+
92
+ **Report output:** Output to the `Report File` specified above.
93
+ - If file does not exist: Create new file
94
+ - If file exists: Append with `## Iteration {step_iteration}` section
95
+
96
+ **Report format:**
97
+ ```markdown
98
+ # Task Plan
99
+
100
+ ## Original Request
101
+ {User's request as-is}
102
+
103
+ ## Analysis Results
104
+
105
+ ### Objective
106
+ {What needs to be achieved}
107
+
108
+ ### Scope
109
+ {Impact scope}
110
+
111
+ ### Implementation Approach
112
+ {How to proceed}
113
+
114
+ ## Clarifications Needed (if any)
115
+ - {Unclear points or items requiring confirmation}
116
+ ```
117
+ pass_previous_response: true
118
+ transitions:
119
+ - condition: done
120
+ next_step: implement
121
+ - condition: blocked
122
+ next_step: ABORT
123
+
124
+ - name: implement
125
+ agent: ~/.takt/agents/default/coder.md
126
+ allowed_tools:
127
+ - Read
128
+ - Glob
129
+ - Grep
130
+ - Edit
131
+ - Write
132
+ - Bash
133
+ - WebSearch
134
+ - WebFetch
135
+ status_rules_prompt: |
136
+ # ⚠️ REQUIRED: Status Output Rules ⚠️
137
+
138
+ **Without this tag, the workflow will stop.**
139
+ Your final output MUST include a status tag following the rules below.
140
+
141
+ ## Output Format
142
+
143
+ | Situation | Tag |
144
+ |-----------|-----|
145
+ | Implementation complete | `[CODER:DONE]` |
146
+ | Cannot decide/insufficient info | `[CODER:BLOCKED]` |
147
+
148
+ **Important**: When in doubt, `[BLOCKED]`. Don't decide on your own.
149
+
150
+ ### Output Examples
151
+
152
+ **DONE case:**
153
+ ```
154
+ Implementation complete.
155
+ - Created: `src/auth/service.ts`, `tests/auth.test.ts`
156
+ - Modified: `src/routes.ts`
157
+
158
+ [CODER:DONE]
159
+ ```
160
+
161
+ **BLOCKED case:**
162
+ ```
163
+ [CODER:BLOCKED]
164
+
165
+ Reason: DB schema is undefined, cannot implement
166
+ Required info: users table structure
167
+ ```
168
+ instruction_template: |
169
+ ## Workflow Context
170
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
171
+ - Step Iteration: {step_iteration} (times this step has run)
172
+ - Step: implement
173
+ - Report Directory: .takt/reports/{report_dir}/
174
+ - Report Files:
175
+ - Scope: .takt/reports/{report_dir}/01-coder-scope.md
176
+ - Decisions: .takt/reports/{report_dir}/02-coder-decisions.md
177
+
178
+ ## User Request
179
+ {task}
180
+
181
+ ## Additional User Inputs
182
+ {user_inputs}
183
+
184
+ ## Instructions
185
+ Follow the plan from the plan step and implement.
186
+ Refer to the plan report (00-plan.md) and proceed with implementation.
187
+
188
+ **Report output:** Output to the `Report Files` specified above.
189
+ - If file does not exist: Create new file
190
+ - If file exists: Append with `## Iteration {step_iteration}` section
191
+
192
+ **Scope report format (create at implementation start):**
193
+ ```markdown
194
+ # Change Scope Declaration
195
+
196
+ ## Task
197
+ {One-line task summary}
198
+
199
+ ## Planned Changes
200
+ | Type | File |
201
+ |------|------|
202
+ | Create | `src/example.ts` |
203
+ | Modify | `src/routes.ts` |
204
+
205
+ ## Estimated Size
206
+ Small / Medium / Large
207
+
208
+ ## Impact Scope
209
+ - {Affected modules or features}
210
+ ```
211
+
212
+ **Decisions report format (on completion, only if decisions were made):**
213
+ ```markdown
214
+ # Decision Log
215
+
216
+ ## 1. {Decision Content}
217
+ - **Background**: {Why the decision was needed}
218
+ - **Options Considered**: {List of options}
219
+ - **Reason**: {Why this option was chosen}
220
+ ```
221
+ transitions:
222
+ - condition: done
223
+ next_step: review
224
+ - condition: blocked
225
+ next_step: plan
226
+
227
+ - name: review
228
+ agent: ~/.takt/agents/default/architect.md
229
+ allowed_tools:
230
+ - Read
231
+ - Glob
232
+ - Grep
233
+ - WebSearch
234
+ - WebFetch
235
+ status_rules_prompt: |
236
+ # ⚠️ REQUIRED: Status Output Rules ⚠️
237
+
238
+ **Without this tag, the workflow will stop.**
239
+ Your final output MUST include a status tag following the rules below.
240
+
241
+ ## Judgment Criteria
242
+
243
+ | Situation | Judgment |
244
+ |-----------|----------|
245
+ | Structural issues | REJECT |
246
+ | Design principle violations | REJECT |
247
+ | Security issues | REJECT |
248
+ | Insufficient tests | REJECT |
249
+ | No issues | APPROVE |
250
+
251
+ **Note:** In simple workflow, IMPROVE is not used.
252
+ If there are minor suggestions, use APPROVE + comments.
253
+
254
+ ## Output Format
255
+
256
+ | Situation | Tag |
257
+ |-----------|-----|
258
+ | No issues | `[ARCHITECT:APPROVE]` |
259
+ | Structural changes required | `[ARCHITECT:REJECT]` |
260
+
261
+ ### Output Examples
262
+
263
+ **APPROVE case:**
264
+ ```
265
+ [ARCHITECT:APPROVE]
266
+
267
+ Positive points:
268
+ - Appropriate module organization
269
+ - Single responsibility maintained
270
+ ```
271
+
272
+ **REJECT case:**
273
+ ```
274
+ [ARCHITECT:REJECT]
275
+
276
+ Issues:
277
+ 1. File size exceeded
278
+ - Location: `src/services/user.ts` (523 lines)
279
+ - Fix: Split into 3 files
280
+ ```
281
+ instruction_template: |
282
+ ## Workflow Context
283
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
284
+ - Step Iteration: {step_iteration} (times this step has run)
285
+ - Step: review (Architecture Review)
286
+ - Report Directory: .takt/reports/{report_dir}/
287
+ - Report File: .takt/reports/{report_dir}/03-architect-review.md
288
+
289
+ ## Original User Request (Initial request from workflow start)
290
+ {task}
291
+
292
+ ## Git Diff
293
+ ```diff
294
+ {git_diff}
295
+ ```
296
+
297
+ ## Instructions
298
+ Focus on **architecture and design** review. Do NOT review AI-specific issues (that's the next step).
299
+
300
+ Review the changes and provide feedback.
301
+
302
+ **Note:** In simple workflow, IMPROVE judgment is not used.
303
+ If there are minor suggestions, use APPROVE + comments.
304
+
305
+ **Report output:** Output to the `Report File` specified above.
306
+ - If file does not exist: Create new file
307
+ - If file exists: Append with `## Iteration {step_iteration}` section
308
+
309
+ **Report format:**
310
+ ```markdown
311
+ # Architecture Review
312
+
313
+ ## Result: APPROVE / REJECT
314
+
315
+ ## Summary
316
+ {1-2 sentences summarizing result}
317
+
318
+ ## Reviewed Perspectives
319
+ - [x] Structure & Design
320
+ - [x] Code Quality
321
+ - [x] Change Scope
322
+
323
+ ## Issues (if REJECT)
324
+ | # | Location | Issue | Fix |
325
+ |---|----------|-------|-----|
326
+ | 1 | `src/file.ts:42` | Issue description | Fix method |
327
+
328
+ ## Improvement Suggestions (optional, non-blocking)
329
+ - {Future improvement suggestions}
330
+ ```
331
+
332
+ **Cognitive load reduction rules:**
333
+ - APPROVE + no issues → Summary only (5 lines or less)
334
+ - APPROVE + minor suggestions → Summary + suggestions (15 lines or less)
335
+ - REJECT → Issues in table format (30 lines or less)
336
+ transitions:
337
+ - condition: approved
338
+ next_step: ai_review
339
+ - condition: rejected
340
+ next_step: plan
341
+
342
+ - name: ai_review
343
+ agent: ~/.takt/agents/default/ai-reviewer.md
344
+ allowed_tools:
345
+ - Read
346
+ - Glob
347
+ - Grep
348
+ - WebSearch
349
+ - WebFetch
350
+ status_rules_prompt: |
351
+ # ⚠️ REQUIRED: Status Output Rules ⚠️
352
+
353
+ **Without this tag, the workflow will stop.**
354
+ Your final output MUST include a status tag following the rules below.
355
+
356
+ ## Judgment Criteria
357
+
358
+ | Situation | Judgment |
359
+ |-----------|----------|
360
+ | Incorrect assumptions (affecting behavior) | REJECT |
361
+ | Plausible-but-wrong code | REJECT |
362
+ | Significant context mismatch with codebase | REJECT |
363
+ | Scope creep | APPROVE (with warning noted) |
364
+ | Minor style deviations only | APPROVE |
365
+ | Code fits context and works | APPROVE |
366
+
367
+ **Note:** Scope creep is noted as a warning but doesn't warrant REJECT alone.
368
+
369
+ ## Output Format
370
+
371
+ | Situation | Tag |
372
+ |-----------|-----|
373
+ | No AI-specific issues | `[AI_REVIEW:APPROVE]` |
374
+ | Issues found | `[AI_REVIEW:REJECT]` |
375
+
376
+ ### Output Examples
377
+
378
+ **APPROVE case:**
379
+ ```
380
+ [AI_REVIEW:APPROVE]
381
+
382
+ Verification result: No issues
383
+ ```
384
+
385
+ **REJECT case:**
386
+ ```
387
+ [AI_REVIEW:REJECT]
388
+
389
+ Issues:
390
+ 1. Non-existent API used: `fetch.json()` → `response.json()`
391
+ ```
392
+ instruction_template: |
393
+ ## Workflow Context
394
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
395
+ - Step Iteration: {step_iteration} (times this step has run)
396
+ - Step: ai_review (AI-Generated Code Review)
397
+ - Report Directory: .takt/reports/{report_dir}/
398
+ - Report File: .takt/reports/{report_dir}/04-ai-review.md
399
+
400
+ ## Original User Request (Initial request from workflow start)
401
+ {task}
402
+
403
+ ## Git Diff
404
+ ```diff
405
+ {git_diff}
406
+ ```
407
+
408
+ ## Instructions
409
+ Review the code for AI-specific issues:
410
+ - Assumption validation
411
+ - Plausible but wrong patterns
412
+ - Context fit with existing codebase
413
+ - Scope creep detection
414
+
415
+ **Report output:** Output to the `Report File` specified above.
416
+ - If file does not exist: Create new file
417
+ - If file exists: Append with `## Iteration {step_iteration}` section
418
+
419
+ **Report format:**
420
+ ```markdown
421
+ # AI-Generated Code Review
422
+
423
+ ## Result: APPROVE / REJECT
424
+
425
+ ## Summary
426
+ {One sentence summarizing result}
427
+
428
+ ## Verified Items
429
+ | Aspect | Result | Notes |
430
+ |--------|--------|-------|
431
+ | Assumption validity | ✅ | - |
432
+ | API/Library existence | ✅ | - |
433
+ | Context fit | ✅ | - |
434
+ | Scope | ✅ | - |
435
+
436
+ ## Issues (if REJECT)
437
+ | # | Category | Location | Issue |
438
+ |---|----------|----------|-------|
439
+ | 1 | Hallucinated API | `src/file.ts:23` | Non-existent method |
440
+ ```
441
+
442
+ **Cognitive load reduction rules:**
443
+ - No issues → Summary 1 line + check table only (10 lines or less)
444
+ - Issues found → + Issues in table format (25 lines or less)
445
+ transitions:
446
+ - condition: approved
447
+ next_step: supervise
448
+ - condition: rejected
449
+ next_step: plan
450
+
451
+ - name: supervise
452
+ agent: ~/.takt/agents/default/supervisor.md
453
+ allowed_tools:
454
+ - Read
455
+ - Glob
456
+ - Grep
457
+ - Bash
458
+ - WebSearch
459
+ - WebFetch
460
+ status_rules_prompt: |
461
+ # ⚠️ REQUIRED: Status Output Rules ⚠️
462
+
463
+ **Without this tag, the workflow will stop.**
464
+ Your final output MUST include a status tag following the rules below.
465
+
466
+ ## Judgment Criteria
467
+
468
+ | Situation | Judgment |
469
+ |-----------|----------|
470
+ | Requirements not met | REJECT |
471
+ | Tests failing | REJECT |
472
+ | Build fails | REJECT |
473
+ | Workarounds remaining | REJECT |
474
+ | All OK | APPROVE |
475
+
476
+ **Principle**: When in doubt, REJECT. Don't give ambiguous approval.
477
+
478
+ ## Output Format
479
+
480
+ | Situation | Tag |
481
+ |-----------|-----|
482
+ | Final approval | `[SUPERVISOR:APPROVE]` |
483
+ | Return for fixes | `[SUPERVISOR:REJECT]` |
484
+
485
+ ### Output Examples
486
+
487
+ **APPROVE case:**
488
+ ```
489
+ [SUPERVISOR:APPROVE]
490
+
491
+ Verification results:
492
+ - Tests: ✅ All passed
493
+ - Build: ✅ Succeeded
494
+ - Requirements met: ✅
495
+ ```
496
+
497
+ **REJECT case:**
498
+ ```
499
+ [SUPERVISOR:REJECT]
500
+
501
+ Issues:
502
+ 1. Tests failing: `npm test` - 2 failures
503
+ 2. Requirements not met: Login feature not implemented
504
+ ```
505
+ instruction_template: |
506
+ ## Workflow Context
507
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
508
+ - Step Iteration: {step_iteration} (times this step has run)
509
+ - Step: supervise (final verification)
510
+ - Report Directory: .takt/reports/{report_dir}/
511
+ - Report Files:
512
+ - Validation: .takt/reports/{report_dir}/05-supervisor-validation.md
513
+ - Summary: .takt/reports/{report_dir}/summary.md
514
+
515
+ ## Original User Request
516
+ {task}
517
+
518
+ ## Git Diff
519
+ ```diff
520
+ {git_diff}
521
+ ```
522
+
523
+ ## Instructions
524
+ Run tests, verify the build, and perform final approval.
525
+
526
+ **Workflow Overall Review:**
527
+ 1. Does the implementation match the plan (00-plan.md)?
528
+ 2. Were all review step issues addressed?
529
+ 3. Was the original task objective achieved?
530
+
531
+ **Review Reports:** Read all reports in Report Directory and
532
+ check for any unaddressed improvement suggestions.
533
+
534
+ **Report output:** Output to the `Report Files` specified above.
535
+ - If file does not exist: Create new file
536
+ - If file exists: Append with `## Iteration {step_iteration}` section
537
+
538
+ **Validation report format:**
539
+ ```markdown
540
+ # Final Validation Results
541
+
542
+ ## Result: APPROVE / REJECT
543
+
544
+ ## Validation Summary
545
+ | Item | Status | Verification Method |
546
+ |------|--------|---------------------|
547
+ | Requirements met | ✅ | Matched against requirements list |
548
+ | Tests | ✅ | `npm test` (N passed) |
549
+ | Build | ✅ | `npm run build` succeeded |
550
+ | Functional check | ✅ | Main flows verified |
551
+
552
+ ## Deliverables
553
+ - Created: {Created files}
554
+ - Modified: {Modified files}
555
+
556
+ ## Incomplete Items (if REJECT)
557
+ | # | Item | Reason |
558
+ |---|------|--------|
559
+ | 1 | {Item} | {Reason} |
560
+ ```
561
+
562
+ **Summary report format (only if APPROVE):**
563
+ ```markdown
564
+ # Task Completion Summary
565
+
566
+ ## Task
567
+ {Original request in 1-2 sentences}
568
+
569
+ ## Result
570
+ ✅ Complete
571
+
572
+ ## Changes
573
+ | Type | File | Summary |
574
+ |------|------|---------|
575
+ | Create | `src/file.ts` | Summary description |
576
+
577
+ ## Review Results
578
+ | Review | Result |
579
+ |--------|--------|
580
+ | Architect | ✅ APPROVE |
581
+ | AI Review | ✅ APPROVE |
582
+ | Supervisor | ✅ APPROVE |
583
+
584
+ ## Verification Commands
585
+ ```bash
586
+ npm test
587
+ npm run build
588
+ ```
589
+ ```
590
+ transitions:
591
+ - condition: approved
592
+ next_step: COMPLETE
593
+ - condition: rejected
594
+ next_step: plan
@@ -264,6 +264,126 @@ function createUser(data: UserData) {
264
264
 
265
265
  **これらを見つけたら必ず指摘する。** 一時的な対応でも本番に残る。
266
266
 
267
+ ### 7.5. TODOコメントの厳格な禁止
268
+
269
+ **「将来やる」は決してやらない。今やらないことは永遠にやらない。**
270
+
271
+ **原則: TODOコメントは即REJECT**
272
+
273
+ ```kotlin
274
+ // ❌ REJECT - 将来を見越したTODO
275
+ // TODO: 施設IDによる認可チェックを追加
276
+ fun deleteCustomHoliday(@PathVariable id: String) {
277
+ deleteCustomHolidayInputPort.execute(input)
278
+ }
279
+
280
+ // ✅ APPROVE - 今実装する
281
+ fun deleteCustomHoliday(@PathVariable id: String) {
282
+ val currentUserFacilityId = getCurrentUserFacilityId()
283
+ val holiday = findHolidayById(id)
284
+ require(holiday.facilityId == currentUserFacilityId) {
285
+ "Cannot delete holiday from another facility"
286
+ }
287
+ deleteCustomHolidayInputPort.execute(input)
288
+ }
289
+ ```
290
+
291
+ **TODOが許容される唯一のケース:**
292
+
293
+ | 条件 | 例 | 判定 |
294
+ |------|-----|------|
295
+ | 外部依存で今は実装不可 + Issue化済み | `// TODO(#123): APIキー取得後に実装` | 許容 |
296
+ | 技術的制約で回避不可 + Issue化済み | `// TODO(#456): ライブラリバグ修正待ち` | 許容 |
297
+ | 「将来実装」「後で追加」 | `// TODO: バリデーション追加` | **REJECT** |
298
+ | 「時間がないので」 | `// TODO: リファクタリング` | **REJECT** |
299
+
300
+ **判断基準:**
301
+ 1. **今実装できるか?** → できるなら今やる。TODOは禁止
302
+ 2. **外部要因で不可能か?** → Issue化して番号をコメントに記載。それ以外は禁止
303
+ 3. **「後でやる」か?** → それは「やらない」と同義。今やるかコードから削除
304
+
305
+ **なぜTODOは悪か:**
306
+ - 時間が経つと文脈が失われる
307
+ - 誰も気づかなくなる
308
+ - セキュリティホールや技術的負債として残る
309
+ - Issue管理と二重管理になる
310
+
311
+ **正しい対処:**
312
+ - 今必要 → 今実装する
313
+ - 今不要 → コードを削除する
314
+ - 外部要因で不可 → Issue化してチケット番号をコメントに入れる
315
+
316
+ ### 7.6. DRY原則の即時適用
317
+
318
+ **「後でまとめる」は決して実現しない。重複は見つけた瞬間に抽出する。**
319
+
320
+ **原則: 3回以上の重複を見つけたら即REJECT**
321
+
322
+ ```typescript
323
+ // ❌ REJECT - 3箇所で同じバリデーション
324
+ function createOrder(data: OrderData) {
325
+ if (!data.customerId) throw new Error('Customer ID required')
326
+ if (!data.items || data.items.length === 0) throw new Error('Items required')
327
+ // ...
328
+ }
329
+
330
+ function updateOrder(id: string, data: OrderData) {
331
+ if (!data.customerId) throw new Error('Customer ID required')
332
+ if (!data.items || data.items.length === 0) throw new Error('Items required')
333
+ // ...
334
+ }
335
+
336
+ function validateOrder(data: OrderData) {
337
+ if (!data.customerId) throw new Error('Customer ID required')
338
+ if (!data.items || data.items.length === 0) throw new Error('Items required')
339
+ // ...
340
+ }
341
+
342
+ // ✅ APPROVE - 共通化
343
+ function validateOrderData(data: OrderData) {
344
+ if (!data.customerId) throw new Error('Customer ID required')
345
+ if (!data.items || data.items.length === 0) throw new Error('Items required')
346
+ }
347
+
348
+ function createOrder(data: OrderData) {
349
+ validateOrderData(data)
350
+ // ...
351
+ }
352
+ ```
353
+
354
+ **DRY違反の検出:**
355
+
356
+ | パターン | 判定 |
357
+ |---------|------|
358
+ | 同じロジックが3箇所以上 | **即REJECT** - 関数/メソッドに抽出 |
359
+ | 同じバリデーションが2箇所以上 | **即REJECT** - バリデーター関数に抽出 |
360
+ | 似たようなコンポーネントが3個以上 | **即REJECT** - 共通コンポーネント化 |
361
+ | コピペで派生したコード | **即REJECT** - パラメータ化または抽象化 |
362
+
363
+ **「後でまとめる」が実現しない理由:**
364
+ 1. **気づけない** - 新しいコードを書く人は既存の重複に気づかない
365
+ 2. **忘れる** - 「次のタスクでまとめよう」は忘れられる
366
+ 3. **コストが増す** - 後から抽出するより今抽出する方が簡単
367
+ 4. **バグが増殖** - 重複コードはバグ修正時に修正漏れを生む
368
+
369
+ **正しい対処:**
370
+ - 2回目の重複を書く時点で「3回目が来る」と予測し、抽出を検討
371
+ - 3回目の重複を見つけたら即座に抽出
372
+ - 「似ているが微妙に違う」場合はパラメータ化を検討
373
+
374
+ **例外: 抽象化が早すぎる場合**
375
+
376
+ | 状況 | 対応 |
377
+ |------|------|
378
+ | 2回しか使われていない | 様子見(3回目で抽出) |
379
+ | 偶然似ているだけ | 抽象化しない |
380
+ | ドメインが異なる | 別々に保つ(AHA原則) |
381
+
382
+ **AHA原則(Avoid Hasty Abstractions)とのバランス:**
383
+ - 2回の重複 → 様子見
384
+ - 3回の重複 → 即抽出
385
+ - ドメインが異なる重複 → 抽象化しない(例: 顧客用バリデーションと管理者用バリデーションは別物)
386
+
267
387
  ### 8. 品質特性
268
388
 
269
389
  | 特性 | 確認観点 |