@mohammadhprp/system-prompt 0.11.1 → 0.11.2

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 (95) hide show
  1. package/framework/agents/backend-architect.md +1 -1
  2. package/framework/mcps/figma-mcp-go/README.md +0 -1
  3. package/framework/mcps/gitlab-mcp/README.md +0 -1
  4. package/framework/mcps/jira-mcp/README.md +0 -1
  5. package/framework/mcps/laravel-boost/README.md +0 -1
  6. package/framework/mcps/notion-mcp/README.md +0 -1
  7. package/framework/mcps/supabase-mcp/README.md +0 -1
  8. package/framework/plugins/opencode-goal-plugin/README.md +0 -1
  9. package/framework/references/standards/api.md +0 -1
  10. package/framework/references/standards/architecture.md +0 -1
  11. package/framework/references/standards/database.md +0 -1
  12. package/framework/references/standards/debugging.md +0 -1
  13. package/framework/references/standards/documentation.md +0 -2
  14. package/framework/references/standards/logging.md +0 -1
  15. package/framework/references/standards/naming.md +0 -1
  16. package/framework/references/standards/observability.md +0 -1
  17. package/framework/references/standards/performance.md +0 -1
  18. package/framework/references/standards/pull-requests.md +0 -1
  19. package/framework/references/standards/security.md +0 -1
  20. package/framework/references/standards/testing.md +0 -1
  21. package/framework/skills/README.md +15 -3
  22. package/framework/skills/codenavi/SKILL.md +306 -0
  23. package/framework/skills/codenavi/examples.md +33 -0
  24. package/framework/skills/codenavi/references/coding-principles.md +143 -0
  25. package/framework/skills/codenavi/references/notebook-spec.md +171 -0
  26. package/framework/skills/create-adr/SKILL.md +429 -0
  27. package/framework/skills/create-adr/examples.md +35 -0
  28. package/framework/skills/docs-writer/SKILL.md +39 -0
  29. package/framework/skills/docs-writer/examples.md +34 -0
  30. package/framework/skills/docs-writer/references/style-guide.md +72 -0
  31. package/framework/skills/frontend-design/SKILL.md +55 -0
  32. package/framework/skills/frontend-design/examples.md +45 -0
  33. package/framework/skills/humanizer/SKILL.md +412 -0
  34. package/framework/skills/humanizer/examples.md +46 -0
  35. package/framework/skills/learning-opportunities/SKILL.md +140 -0
  36. package/framework/skills/learning-opportunities/examples.md +34 -0
  37. package/framework/skills/learning-opportunities/references/PRINCIPLES.md +42 -0
  38. package/framework/skills/perf-web-optimization/SKILL.md +163 -0
  39. package/framework/skills/perf-web-optimization/examples.md +35 -0
  40. package/framework/skills/perf-web-optimization/references/bundle-optimization.md +180 -0
  41. package/framework/skills/perf-web-optimization/references/core-web-vitals.md +154 -0
  42. package/framework/skills/perf-web-optimization/references/image-optimization.md +170 -0
  43. package/framework/skills/security-best-practices/LICENSE.txt +201 -0
  44. package/framework/skills/security-best-practices/SKILL.md +89 -0
  45. package/framework/skills/security-best-practices/examples.md +35 -0
  46. package/framework/skills/security-best-practices/references/golang-general-backend-security.md +988 -0
  47. package/framework/skills/security-best-practices/references/javascript-express-web-server-security.md +1151 -0
  48. package/framework/skills/security-best-practices/references/javascript-general-web-frontend-security.md +725 -0
  49. package/framework/skills/security-best-practices/references/javascript-jquery-web-frontend-security.md +672 -0
  50. package/framework/skills/security-best-practices/references/javascript-typescript-nextjs-web-server-security.md +1138 -0
  51. package/framework/skills/security-best-practices/references/javascript-typescript-react-web-frontend-security.md +975 -0
  52. package/framework/skills/security-best-practices/references/javascript-typescript-vue-web-frontend-security.md +789 -0
  53. package/framework/skills/security-best-practices/references/python-django-web-server-security.md +880 -0
  54. package/framework/skills/security-best-practices/references/python-fastapi-web-server-security.md +1030 -0
  55. package/framework/skills/security-best-practices/references/python-flask-web-server-security.md +835 -0
  56. package/framework/skills/sentry/SKILL.md +127 -0
  57. package/framework/skills/sentry/examples.md +34 -0
  58. package/framework/skills/sentry/scripts/sentry_api.py +238 -0
  59. package/framework/skills/show-me/SKILL.md +127 -0
  60. package/framework/skills/show-me/examples.md +78 -0
  61. package/framework/skills/spec-driven-eval/SKILL.md +341 -0
  62. package/framework/skills/spec-driven-eval/examples.md +35 -0
  63. package/framework/skills/spec-driven-eval/references/quickstart.md +118 -0
  64. package/framework/skills/spec-driven-eval/references/reference.md +295 -0
  65. package/framework/skills/technical-design-doc-creator/README.md +411 -0
  66. package/framework/skills/technical-design-doc-creator/SKILL.md +1484 -0
  67. package/framework/skills/technical-design-doc-creator/examples.md +35 -0
  68. package/framework/skills/tlc-spec-driven/SKILL.md +184 -0
  69. package/framework/skills/tlc-spec-driven/examples.md +34 -0
  70. package/framework/skills/tlc-spec-driven/references/code-analysis.md +98 -0
  71. package/framework/skills/tlc-spec-driven/references/coding-principles.md +72 -0
  72. package/framework/skills/tlc-spec-driven/references/context-limits.md +31 -0
  73. package/framework/skills/tlc-spec-driven/references/design.md +199 -0
  74. package/framework/skills/tlc-spec-driven/references/discuss.md +159 -0
  75. package/framework/skills/tlc-spec-driven/references/implement.md +436 -0
  76. package/framework/skills/tlc-spec-driven/references/lessons.md +115 -0
  77. package/framework/skills/tlc-spec-driven/references/memory.md +144 -0
  78. package/framework/skills/tlc-spec-driven/references/specify.md +228 -0
  79. package/framework/skills/tlc-spec-driven/references/sub-agents.md +147 -0
  80. package/framework/skills/tlc-spec-driven/references/tasks.md +451 -0
  81. package/framework/skills/tlc-spec-driven/references/validate.md +355 -0
  82. package/framework/skills/tlc-spec-driven/scripts/check_commit.py +115 -0
  83. package/framework/skills/tlc-spec-driven/scripts/lessons.py +412 -0
  84. package/framework/skills/tlc-spec-driven/scripts/validate_spec.py +260 -0
  85. package/framework/skills/tlc-spec-driven/scripts/validate_state.py +162 -0
  86. package/framework/skills/tlc-spec-driven/scripts/validate_tasks.py +251 -0
  87. package/framework/skills/web-design-guidelines/SKILL.md +65 -0
  88. package/framework/skills/web-design-guidelines/examples.md +32 -0
  89. package/framework/skills/web-design-guidelines/references/guideline.md +174 -0
  90. package/package.json +1 -1
  91. package/src/catalog.js +15 -3
  92. package/framework/skills/backend-engineer/SKILL.md +0 -76
  93. package/framework/skills/backend-engineer/examples.md +0 -31
  94. package/framework/skills/documentation/SKILL.md +0 -74
  95. package/framework/skills/documentation/examples.md +0 -31
@@ -0,0 +1,355 @@
1
+ # Execute: Validate & Verify
2
+
3
+ **Goal**: Verify implementation meets spec AND coding principles. This is NOT a separate phase - verification is part of every task's completion within Execute.
4
+
5
+ **Three levels of verification:**
6
+
7
+ 1. **Per-task verification (always, author self-check):** After implementing each task, verify its "Done when" criteria before committing. This is mandatory and automatic. The implementer runs it.
8
+
9
+ 2. **Feature-level validation (independent Verifier sub-agent, always-on, never prompted):** After all tasks for a feature (or priority group) are done, validation runs automatically - the orchestrator dispatches a **fresh Verifier sub-agent** (see [sub-agents.md](sub-agents.md)). Do NOT ask the user whether to run it; it is the safety net, not an opt-in. User interaction is limited to interactive UAT (for user-facing features) and acting on a FAIL verdict ("fix these gaps now?"). The Verifier:
10
+ - Runs **read-only** over the real implementation and tests - mutations run in a scratch/throwaway state only (see Discrimination Sensor section)
11
+ - Scopes coverage to the feature's **git diff surface** (not the full repository)
12
+ - Re-derives coverage independently using **evidence-or-zero**: every AC must be traced to a `file:line` + assertion expression; a criterion with no `file:line` citation counts as NOT covered
13
+ - Runs the **spec-anchored outcome check** and the **discrimination sensor** (both described below)
14
+ - Writes `.specs/features/[feature]/validation.md` with the full evidence report
15
+ - Returns a compact verdict + ranked gap list to the orchestrator in chat
16
+ - Gaps become **fix tasks** routed back to an implementer; re-verification follows with a maximum of **3 fix→re-verify iterations** before escalating to the user
17
+
18
+ 3. **Interactive UAT (for user-facing features only):** The feature has complex user-facing behavior where human judgment matters (UI flows, interaction patterns, visual design). For backend-only or infrastructure work, automated checks are sufficient.
19
+
20
+ **Trigger for explicit validation:** "Validate", "verify work", "UAT", "test with me", "walk me through it"
21
+
22
+ ---
23
+
24
+ ## Process
25
+
26
+ ### 1. Check Completed Tasks
27
+
28
+ Go through tasks.md:
29
+
30
+ - [ ] All tasks marked done?
31
+ - [ ] Any blocked or partial?
32
+
33
+ ### 2. Spec-Anchored Acceptance Criteria Check
34
+
35
+ For each acceptance criterion in `spec.md`, the Verifier re-derives the **spec-defined expected outcome** and confirms the test's actual assertion matches it:
36
+
37
+ ```markdown
38
+ ### P1: [Story Title]
39
+
40
+ **Acceptance Criteria**:
41
+
42
+ | Criterion (WHEN X THEN Y) | Spec-defined outcome | `file:line` + assertion expression | Result |
43
+ | ------------------------- | -------------------- | ---------------------------------- | ------ |
44
+ | WHEN [X] THEN [Y] | [precise value/state from spec] | `path/to/test.ts:42` - `expect(result.field).toBe(expected)` | ✅ PASS / ❌ GAP / ⚠️ Spec-precision gap |
45
+ ```
46
+
47
+ **Rules:**
48
+
49
+ - Where the spec defines a precise outcome (specific status code, field value, error message, state), the test assertion MUST target that exact outcome - not just that an assertion exists.
50
+ - Where the spec does NOT define a precise outcome, mark as **⚠️ Spec-precision gap** and flag it in the report. Do NOT silently pass a vague assertion.
51
+ - Evidence-or-zero: a criterion with no `file:line` citation counts as NOT covered.
52
+
53
+ ### 3. Check Edge Cases
54
+
55
+ From spec.md edge cases:
56
+
57
+ - [ ] [Edge case 1] handled correctly
58
+ - [ ] [Edge case 2] handled correctly
59
+
60
+ ### 4. Run Build-Level Gate Check (MANDATORY)
61
+
62
+ Run the Build-level gate check from the **Gate Check Commands** section in tasks.md. This is NOT optional.
63
+
64
+ 1. Run: `[Build gate command from the Gate Check Commands section in tasks.md]`
65
+ 2. Non-zero exit code = STOP. Do not proceed to Code Quality Check.
66
+ 3. Record results:
67
+ - Total test count: [N]
68
+ - Passed: [N]
69
+ - Failed: [list]
70
+ - Skipped: [list - each skip must be justified]
71
+
72
+ **Test Integrity Check:**
73
+
74
+ - Compare current test count against the count before this feature was implemented
75
+ - If test count DECREASED: investigate why. Tests should only be deleted with explicit justification.
76
+ - If assertions were weakened (less specific than before): flag as potential regression
77
+
78
+ ### 5. Discrimination Sensor (MANDATORY - always runs after gate check passes)
79
+
80
+ The sensor provides the empirical guarantee that the tests can actually detect regressions. It runs in a scratch/throwaway state - the real working tree is never modified.
81
+
82
+ **How it works:**
83
+
84
+ 1. **Prepare an isolated scratch.** Never mutate the real worktree. Choose one:
85
+ - Preferred: a temporary git worktree (`git worktree add <scratch-path> HEAD`), mutate and run tests there, then `git worktree remove --force <scratch-path>`.
86
+ - Fallback (no git / worktree unavailable): copy only the affected file(s) to a temp directory, mutate the copies, point the test runner at those copies (or restore originals from the copies' backups), then delete the temp directory.
87
+ - **Forbidden:** `git stash` / `git stash pop`. A stash records state *before* the mutation; popping it does not reverse a mutation applied afterward, and on a clean tree `git stash` creates no entry at all - so the fault is left in the real worktree.
88
+ 2. **Capture a baseline.** Record `git status --porcelain` (or equivalent) of the real worktree *before* any sensor work. It must be unchanged after cleanup.
89
+ 3. **Inject a behavior-level fault** into the scratch copy of the new code introduced by this feature. Choose a mutation proportional to the code's risk:
90
+ - Flip a boolean condition (`if (x)` → `if (!x)`, `>` → `>=`)
91
+ - Change a return value (return a wrong status code, wrong field, zero instead of a computed value)
92
+ - Off-by-one (shift a loop bound, change a slice index)
93
+ - Remove a required side effect (delete a method call that the spec requires)
94
+ 4. **Run the tests** that cover the mutated code (against the scratch). Use the Quick or Full gate command from tasks.md.
95
+ 5. **Confirm the mutant is killed** (tests FAIL). Discard the scratch (remove worktree or delete temp copies).
96
+ 6. **Verify isolation.** Re-run `git status --porcelain` on the real worktree and confirm it matches the baseline from step 2. If it differs, STOP - restore the real tree before continuing, and treat the sensor run as invalid.
97
+ 7. **If a mutant survives** (tests still pass after the fault), the tests are not discriminating for that behavior - add a fix task to strengthen the assertion.
98
+
99
+ **Tiering (proportional, not optional):**
100
+
101
+ | Context | Sensor depth |
102
+ | ------- | ------------ |
103
+ | Default (all features) | Lightweight fault-injection: 1-3 targeted behavior-level mutations per feature, focused on the highest-risk new code |
104
+ | P0 / critical paths (payment, auth, data integrity) | Full mutation run: use language-appropriate mutation tooling if available (e.g., Stryker, mutmut, cargo-mutants, pitest); otherwise increase the number of manual fault-injection mutations to ≥5 covering all branches |
105
+
106
+ **Stack-agnostic:** The sensor targets behavior-level semantics (what the code does), not a specific tool. Any language, any framework.
107
+
108
+ **Report:** Record killed/survived for each mutation attempt. Surviving mutants → create fix tasks before marking the feature done.
109
+
110
+ ### 6. Code Quality Check (MANDATORY)
111
+
112
+ For each changed file, verify against [coding-principles.md](coding-principles.md):
113
+
114
+ | Check | Pass? |
115
+ | ------------------------------------ | ----- |
116
+ | No features beyond what was asked | |
117
+ | No abstractions for single-use code | |
118
+ | No unnecessary "flexibility" added | |
119
+ | Only touched files required for task | |
120
+ | Didn't "improve" unrelated code | |
121
+ | Matches existing patterns/style | |
122
+ | Would senior engineer approve? | |
123
+ | Tests map to acceptance criteria and are non-shallow (spot-check one story) | |
124
+ | Spec-anchored outcome check: each test's asserted value matches the spec-defined outcome (or gap flagged) | |
125
+ | Per-layer Coverage Expectation met: domain logic has 1:1 AC mapping; routes/e2e cover happy + edge + error paths for every route in scope | |
126
+ | Every test in scope maps to a spec AC, listed edge case, or Done-when criterion (no unclaimed tests) | |
127
+ | Documented project quality/testing guidelines followed (cite guideline file, or "none - strong defaults applied") | |
128
+
129
+ ❌ Any "No"? → Fix before marking complete.
130
+
131
+ ### 7. Interactive UAT (if user-facing feature)
132
+
133
+ For each testable deliverable, present one test at a time:
134
+
135
+ ```
136
+ Test [N]: [Test Name]
137
+
138
+ Expected: [What should happen - specific and observable]
139
+
140
+ → Does this work? Describe what you see.
141
+ ```
142
+
143
+ Wait for user response:
144
+
145
+ | User says | Interpret as |
146
+ | ------------------------------ | ----------------------- |
147
+ | "yes", "pass", "works", "next" | ✅ Pass |
148
+ | "skip", "can't test", "n/a" | ⏭️ Skip |
149
+ | Anything else | ❌ Issue - log verbatim |
150
+
151
+ **Severity inference (never ask the user for severity):**
152
+
153
+ | User description contains | Inferred severity |
154
+ | --------------------------------------- | ----------------- |
155
+ | crash, error, exception, fails, broken | Blocker |
156
+ | doesn't work, wrong, missing, can't | Major |
157
+ | slow, weird, off, minor, small | Minor |
158
+ | color, font, spacing, alignment, visual | Cosmetic |
159
+ | (unclear) | Major (default) |
160
+
161
+ ### 8. Generate Fix Plans (if issues found)
162
+
163
+ For each issue found during UAT or from the Verifier:
164
+
165
+ 1. **Diagnose** - Analyze the codebase to find root cause
166
+ 2. **Create fix task** - Write a task definition with:
167
+ - What: The specific fix
168
+ - Where: File paths
169
+ - Verify: How to prove the fix works
170
+ - Done when: Acceptance criteria for the fix
171
+ 3. **Present fix plan** - Show all fix tasks to user for approval
172
+
173
+ Fix tasks follow the same format as regular tasks and can be executed with the implement phase.
174
+
175
+ **Guardrail:** Maximum 3 diagnostic iterations per issue. If root cause isn't found after 3 attempts, flag for human investigation. The same 3-iteration bound applies to the Verifier's fix→re-verify cycle: if gaps persist after 3 rounds, escalate to the user rather than continuing to loop.
176
+
177
+ ### 9. Write Validation Report File + Return Chat Summary (MANDATORY)
178
+
179
+ After all checks complete, the Verifier MUST:
180
+
181
+ 1. **Write the persisted report** to `.specs/features/[feature]/validation.md` (see template below). This file is the evidence artifact - it survives the session and can be referenced by CI, reviewers, or future agents.
182
+ 2. **Return a compact summary in chat** to the orchestrator (see Compact Chat Summary section below). The orchestrator surfaces it to the user and routes any ranked gaps to fix tasks.
183
+
184
+ **Deterministic backing (run it, do not eyeball it).** After writing the report, run `python3 <skill-dir>/scripts/validate_state.py <feature>`. It confirms the report is real - present, verdict filled to PASS, and backed by at least one `file:line` evidence citation - so a missing, hollow, placeholder, or FAIL report cannot slip through as done. A non-zero exit means the feature is NOT done: repair the report or route the FAIL gaps to fix tasks, then re-run. This is the closing gate of Execute and runs automatically, the same way the lessons layer runs at distillation; it is never a manual step. If no code-execution tool is available, confirm the same by reading `validation.md`.
185
+
186
+ ### 10. Distill Lessons (MANDATORY when validation.md has signal)
187
+
188
+ This is the closing action of validation - not a separate phase. Immediately after the report is written, turn its grounded failures into reusable, project-local guidance by following [lessons.md](lessons.md). In short: for each surviving mutant, spec-precision gap, failed/uncovered AC, or `// SPEC_DEVIATION`, record one terse general lesson via `python3 <skill-dir>/scripts/lessons.py add` (the script enforces grounding and owns all bookkeeping). A clean PASS with no signal → record nothing. Run the self-check: if there was signal but no lesson was recorded, say so in chat. See [lessons.md](lessons.md) for the exact commands, phrasing rules, scope discipline, and the no-script fallback.
189
+
190
+ ---
191
+
192
+ ## Compact Chat Summary (returned in chat after validation)
193
+
194
+ The Verifier returns this block to the orchestrator after completing all checks:
195
+
196
+ ```markdown
197
+ ## Validation: [Feature] - [PASS ✅ | FAIL ❌]
198
+
199
+ **Spec-anchored check**: [N/N ACs matched spec outcome | M spec-precision gaps flagged]
200
+ **Gate**: [X passed, 0 failed]
201
+ **Sensor**: [N mutations injected, N killed, N survived]
202
+ **Report**: `.specs/features/[feature]/validation.md`
203
+
204
+ **Ranked gaps** (if FAIL):
205
+ 1. [Gap description] - [AC or criterion] - [file:line or "no evidence"]
206
+ 2. ...
207
+ ```
208
+
209
+ ---
210
+
211
+ ## Validation Report Template (`.specs/features/[feature]/validation.md`)
212
+
213
+ ```markdown
214
+ # [Feature] Validation
215
+
216
+ **Date**: [YYYY-MM-DD]
217
+ **Spec**: `.specs/features/[feature]/spec.md`
218
+ **Diff range**: [commit range or branch..HEAD]
219
+ **Verifier**: independent sub-agent (author ≠ verifier)
220
+
221
+ ---
222
+
223
+ ## Task Completion
224
+
225
+ | Task | Status | Notes |
226
+ | ---- | ---------- | ------- |
227
+ | T1 | ✅ Done | - |
228
+ | T2 | ✅ Done | - |
229
+ | T3 | ⚠️ Partial | [Issue] |
230
+
231
+ ---
232
+
233
+ ## Spec-Anchored Acceptance Criteria
234
+
235
+ | Criterion (WHEN X THEN Y) | Spec-defined outcome | `file:line` + assertion | Result |
236
+ | ------------------------- | -------------------- | ----------------------- | ------ |
237
+ | WHEN X THEN Y | [precise value/state from spec] | `path/to/test.ts:42` - `expect(result.field).toBe(expected)` | ✅ PASS |
238
+ | WHEN A THEN B | [expected value] | `path/to/test.ts:88` - `expect(res.status).toBe(400)` | ✅ PASS |
239
+ | WHEN C THEN D | not precisely defined in spec | - | ⚠️ Spec-precision gap |
240
+
241
+ **Status**: ✅ All ACs covered / ❌ Gaps present / ⚠️ Spec-precision gaps flagged
242
+
243
+ ---
244
+
245
+ ## Discrimination Sensor
246
+
247
+ | Mutation | File:line | Description | Killed? |
248
+ | -------- | --------- | ----------- | ------- |
249
+ | 1 | `src/service.ts:42` | Flipped condition `x > 0` → `x >= 0` | ✅ Killed |
250
+ | 2 | `src/service.ts:88` | Changed return value `status: 'active'` → `status: 'inactive'` | ✅ Killed |
251
+ | 3 | `src/handler.ts:15` | Removed side-effect call to `notify()` | ❌ Survived → fix task created |
252
+
253
+ **Sensor depth**: [lightweight / P0-full]
254
+ **Result**: [N/N killed] - [PASS ✅ | FAIL ❌]
255
+
256
+ ---
257
+
258
+ ## Interactive UAT Results (if performed)
259
+
260
+ | # | Test | Result | Details |
261
+ | --- | ----------- | -------- | ----------------------------------------------- |
262
+ | 1 | [Test name] | ✅ Pass | - |
263
+ | 2 | [Test name] | ❌ Issue | [Verbatim user response] - Severity: [inferred] |
264
+ | 3 | [Test name] | ⏭️ Skip | [Reason] |
265
+
266
+ ---
267
+
268
+ ## Code Quality
269
+
270
+ | Principle | Status |
271
+ | ---------------- | ------ |
272
+ | Minimum code | ✅ |
273
+ | Surgical changes | ✅ |
274
+ | No scope creep | ✅ |
275
+ | Matches patterns | ✅ |
276
+ | Spec-anchored outcome check (asserted values match spec) | ✅ |
277
+ | Per-layer Coverage Expectation met (domain 1:1 ACs; routes happy+edge+error) | ✅ |
278
+ | Every test maps to a spec requirement - no unclaimed tests | ✅ |
279
+ | Documented guidelines followed: [file(s) or "none - strong defaults applied"] | ✅ |
280
+
281
+ ---
282
+
283
+ ## Edge Cases
284
+
285
+ - [x] Edge case 1: Handled correctly
286
+ - [ ] Edge case 2: NOT handled - needs fix
287
+
288
+ ---
289
+
290
+ ## Gate Check
291
+
292
+ - **Gate command**: [Build gate command from the Gate Check Commands section in tasks.md]
293
+ - **Result**: [X] passed, [Y] failed, [Z] skipped
294
+ - **Test count before feature**: [N]
295
+ - **Test count after feature**: [M]
296
+ - **Delta**: [+(M - N) new tests]
297
+ - **Skipped tests**: [list with justification for each]
298
+ - **Failures**: [list with details]
299
+
300
+ ---
301
+
302
+ ## Fix Plans (if issues found)
303
+
304
+ ### Fix 1: [Issue description]
305
+
306
+ - **Root cause**: [What's actually wrong]
307
+ - **Fix task**: [Task definition]
308
+ - **Priority**: [Blocker/Major/Minor/Cosmetic]
309
+
310
+ ---
311
+
312
+ ## Requirement Traceability Update
313
+
314
+ Update spec.md requirement statuses:
315
+
316
+ | Requirement | Previous Status | New Status |
317
+ | ----------- | --------------- | ------------ |
318
+ | [FEAT]-01 | Implementing | ✅ Verified |
319
+ | [FEAT]-02 | Implementing | ❌ Needs Fix |
320
+
321
+ ---
322
+
323
+ ## Summary
324
+
325
+ **Overall**: ✅ Ready | ⚠️ Issues | ❌ Not Ready
326
+
327
+ **Spec-anchored check**: [N/N ACs matched spec outcome | M spec-precision gaps]
328
+ **Sensor**: [N/N mutations killed]
329
+ **Gate**: [X passed]
330
+
331
+ **What works**: [List]
332
+
333
+ **Issues found**: [Issue 1: How to fix]
334
+
335
+ **Next steps**: [Action]
336
+ ```
337
+
338
+ ---
339
+
340
+ ## Tips
341
+
342
+ - **Validation is never prompted** - it always runs after the last task; do not ask the user whether to run it
343
+ - **Spec-anchored, not just covered** - "there is an assertion" is not enough; the assertion must target the spec-defined outcome
344
+ - **Sensor in scratch only** - never mutate the real tree; use a temp worktree or file copies (never `git stash`), run, discard, then confirm porcelain matches the pre-sensor baseline
345
+ - **Surviving mutants are fix tasks** - do not mark the feature done if the sensor found weak tests
346
+ - **P1 first** - MVP must work before P2/P3
347
+ - **WHEN/THEN = Test** - Each criterion is a test case
348
+ - **Be specific** - "Doesn't work" isn't helpful
349
+ - **Recommend fixes** - Don't just report problems, create fix tasks
350
+ - **Quality check is mandatory** - Not optional
351
+ - **Infer severity** - Never ask the user "how bad is this?"
352
+ - **Max 3 diagnostic iterations** - Prevents infinite investigation loops
353
+ - **Update traceability** - Every verified requirement updates spec.md status
354
+ - **Always write the report file** - `.specs/features/[feature]/validation.md` is the persisted evidence artifact
355
+ - **Distill after writing** - turn grounded failures into lessons via `scripts/lessons.py` ([lessons.md](lessons.md)); clean PASS → no lesson
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ check_commit.py - deterministic Conventional Commits validation.
4
+
5
+ The per-task atomic-commit rule mandates Conventional Commits 1.0.0. This makes
6
+ that rule checkable instead of trusting the model to remember the format. Pure
7
+ standard library, zero dependencies, agent-agnostic.
8
+
9
+ It reads the message from (in priority order): a positional file path, --message,
10
+ or stdin. The file-path form matches how git passes the message file to a
11
+ `commit-msg` hook, so this doubles as an optional git-level guard WITHOUT
12
+ coupling the skill to any AI agent:
13
+
14
+ ln -s <skill-dir>/scripts/check_commit.py .git/hooks/commit-msg && chmod +x .git/hooks/commit-msg
15
+
16
+ What it checks:
17
+ ERROR - header does not match type(scope)!: description
18
+ ERROR - type is not one of the allowed Conventional Commits types
19
+ ERROR - description is empty, starts uppercase, or ends with a period
20
+ ERROR - `!` breaking marker present but no `BREAKING CHANGE:` footer
21
+ WARN - header longer than 72 characters
22
+
23
+ Usage:
24
+ python3 <skill-dir>/scripts/check_commit.py [msgfile]
25
+ python3 <skill-dir>/scripts/check_commit.py --message "feat(auth): add email validation"
26
+ echo "fix(cart): prevent negative quantity" | python3 <skill-dir>/scripts/check_commit.py
27
+
28
+ Exit codes: 0 pass, 1 violation, 2 usage error.
29
+ """
30
+
31
+ import argparse
32
+ import re
33
+ import sys
34
+
35
+ TYPES = ["feat", "fix", "refactor", "docs", "test", "style", "perf", "build", "ci", "chore"]
36
+ HEADER_RE = re.compile(r"^(?P<type>\w+)(?:\((?P<scope>[^)]+)\))?(?P<bang>!)?: (?P<desc>.+)$")
37
+
38
+
39
+ def read_message(args):
40
+ if args.message is not None:
41
+ return args.message
42
+ if args.msgfile:
43
+ with open(args.msgfile, "r", encoding="utf-8") as f:
44
+ return f.read()
45
+ if not sys.stdin.isatty():
46
+ return sys.stdin.read()
47
+ return ""
48
+
49
+
50
+ def check(message):
51
+ errors, warnings = [], []
52
+ # Ignore comment lines (git puts '#' comments in the message file).
53
+ lines = [ln for ln in message.splitlines() if not ln.lstrip().startswith("#")]
54
+ # Trim leading blank lines.
55
+ while lines and not lines[0].strip():
56
+ lines.pop(0)
57
+ if not lines:
58
+ return (["empty commit message"], warnings)
59
+
60
+ header = lines[0].rstrip()
61
+ if len(header) > 72:
62
+ warnings.append(f"header is {len(header)} chars (>72): {header[:60]}...")
63
+
64
+ m = HEADER_RE.match(header)
65
+ if not m:
66
+ errors.append(f"header does not match 'type(scope): description': {header!r}")
67
+ return (errors, warnings)
68
+
69
+ ctype = m.group("type")
70
+ desc = m.group("desc")
71
+ bang = m.group("bang")
72
+
73
+ if ctype not in TYPES:
74
+ errors.append(f"type '{ctype}' is not one of: {', '.join(TYPES)}")
75
+ if not desc.strip():
76
+ errors.append("description is empty")
77
+ else:
78
+ if desc[:1].isupper():
79
+ errors.append(f"description should start lowercase: '{desc[:30]}'")
80
+ if desc.rstrip().endswith("."):
81
+ errors.append("description should not end with a period")
82
+
83
+ body = "\n".join(lines[1:])
84
+ breaking_footer = bool(re.search(r"^BREAKING CHANGE:", body, re.MULTILINE))
85
+ if bang and not breaking_footer:
86
+ errors.append("'!' breaking marker present but no 'BREAKING CHANGE:' footer")
87
+
88
+ return (errors, warnings)
89
+
90
+
91
+ def main(argv=None):
92
+ p = argparse.ArgumentParser(prog="check_commit.py", description="Validate a Conventional Commits message.")
93
+ p.add_argument("msgfile", nargs="?", default=None, help="path to a commit message file (as git passes to commit-msg)")
94
+ p.add_argument("--message", default=None, help="the commit message as a string")
95
+ args = p.parse_args(argv)
96
+
97
+ message = read_message(args)
98
+ if not message.strip():
99
+ print("check_commit: no message provided (pass a file, --message, or pipe via stdin).", file=sys.stderr)
100
+ return 2
101
+
102
+ errors, warnings = check(message)
103
+ for w in warnings:
104
+ print(f" WARN {w}")
105
+ for e in errors:
106
+ print(f" ERROR {e}")
107
+ if errors:
108
+ print("\ncheck_commit: FAIL - see https://www.conventionalcommits.org/en/v1.0.0/")
109
+ return 1
110
+ print("check_commit: OK")
111
+ return 0
112
+
113
+
114
+ if __name__ == "__main__":
115
+ raise SystemExit(main())