@drafthq/draft 3.5.3 → 3.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.
Files changed (143) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.cursor-plugin/plugin.json +1 -1
  4. package/README.md +28 -49
  5. package/bin/README.md +47 -1
  6. package/cli/src/hosts/cursor.js +3 -0
  7. package/cli/src/installer.js +8 -4
  8. package/cli/src/lib/cursor-registry.js +10 -0
  9. package/cli/src/lib/fsx.js +3 -0
  10. package/cli/src/lib/marker.js +8 -3
  11. package/core/agents/architect.md +21 -9
  12. package/core/agents/debugger.md +5 -0
  13. package/core/agents/ops.md +7 -2
  14. package/core/agents/planner.md +7 -0
  15. package/core/agents/rca.md +14 -3
  16. package/core/agents/reviewer.md +1 -0
  17. package/core/agents/writer.md +6 -0
  18. package/core/knowledge-base.md +22 -3
  19. package/core/methodology.md +30 -5
  20. package/core/shared/condensation.md +28 -18
  21. package/core/shared/context-verify.md +3 -1
  22. package/core/shared/cross-skill-dispatch.md +7 -3
  23. package/core/shared/draft-context-loading.md +3 -0
  24. package/core/shared/git-report-metadata.md +2 -1
  25. package/core/shared/graph-query.md +24 -26
  26. package/core/shared/graph-usage-report.md +1 -1
  27. package/core/shared/jira-sync.md +10 -6
  28. package/core/shared/okf-retrieval.md +1 -1
  29. package/core/shared/parallel-analysis.md +14 -7
  30. package/core/shared/pattern-learning.md +2 -0
  31. package/core/shared/template-contract.md +1 -1
  32. package/core/shared/tool-resolver.md +20 -15
  33. package/core/shared/vcs-commands.md +5 -2
  34. package/core/templates/ai-context.md +3 -2
  35. package/core/templates/ai-profile.md +7 -0
  36. package/core/templates/architecture.md +6 -2
  37. package/core/templates/discovery.md +1 -1
  38. package/core/templates/guardrails.md +9 -0
  39. package/core/templates/hld.md +5 -4
  40. package/core/templates/intake-questions.md +45 -0
  41. package/core/templates/jira.md +11 -2
  42. package/core/templates/lld.md +8 -5
  43. package/core/templates/okf/concept.md +0 -1
  44. package/core/templates/plan.md +1 -1
  45. package/core/templates/product.md +11 -2
  46. package/core/templates/rca.md +6 -0
  47. package/core/templates/service-index.md +1 -0
  48. package/core/templates/spec.md +15 -0
  49. package/core/templates/tech-stack.md +12 -0
  50. package/core/templates/workflow.md +20 -0
  51. package/integrations/agents/AGENTS.md +1449 -817
  52. package/integrations/copilot/.github/copilot-instructions.md +1449 -817
  53. package/package.json +1 -1
  54. package/scripts/fetch-memory-engine.sh +25 -7
  55. package/scripts/lib.sh +90 -6
  56. package/scripts/tools/_graph_queries.sh +22 -8
  57. package/scripts/tools/_lib.sh +81 -11
  58. package/scripts/tools/adr-index.sh +1 -1
  59. package/scripts/tools/check-repo-size.sh +125 -0
  60. package/scripts/tools/check-skill-line-caps.sh +3 -4
  61. package/scripts/tools/check-template-noop.sh +0 -1
  62. package/scripts/tools/check-track-hygiene.sh +41 -21
  63. package/scripts/tools/classify-files.sh +3 -3
  64. package/scripts/tools/cycle-detect.sh +18 -17
  65. package/scripts/tools/detect-test-framework.sh +1 -1
  66. package/scripts/tools/emit-skill-metrics.sh +7 -2
  67. package/scripts/tools/fix-whitespace.sh +3 -0
  68. package/scripts/tools/freshness-check.sh +2 -2
  69. package/scripts/tools/git-metadata.sh +12 -6
  70. package/scripts/tools/graph-arch.sh +5 -11
  71. package/scripts/tools/graph-callers.sh +10 -15
  72. package/scripts/tools/graph-deps.sh +3 -10
  73. package/scripts/tools/graph-errors.sh +4 -11
  74. package/scripts/tools/graph-hierarchy.sh +4 -11
  75. package/scripts/tools/graph-impact.sh +21 -19
  76. package/scripts/tools/graph-init.sh +13 -9
  77. package/scripts/tools/graph-preflight.sh +4 -1
  78. package/scripts/tools/graph-query.sh +74 -18
  79. package/scripts/tools/graph-risk.sh +3 -10
  80. package/scripts/tools/graph-search.sh +4 -11
  81. package/scripts/tools/graph-snapshot.sh +38 -9
  82. package/scripts/tools/graph-snippet.sh +3 -10
  83. package/scripts/tools/graph-tests.sh +3 -10
  84. package/scripts/tools/graph-traces.sh +3 -10
  85. package/scripts/tools/hotspot-rank.sh +6 -12
  86. package/scripts/tools/install-smoke-test.sh +223 -0
  87. package/scripts/tools/mermaid-from-graph.sh +5 -11
  88. package/scripts/tools/migrate-track-frontmatter.sh +11 -10
  89. package/scripts/tools/okf-coverage-check.sh +8 -7
  90. package/scripts/tools/okf-emit-catalog.sh +256 -0
  91. package/scripts/tools/okf-fix-links.sh +251 -0
  92. package/scripts/tools/okf-plan-concepts.sh +242 -14
  93. package/scripts/tools/okf-render-views.sh +63 -21
  94. package/scripts/tools/okf-validate-all.sh +20 -9
  95. package/scripts/tools/okf-validate-quality.sh +15 -10
  96. package/scripts/tools/okf-validate.sh +20 -6
  97. package/scripts/tools/parse-git-log.sh +23 -5
  98. package/scripts/tools/parse-reports.sh +1 -1
  99. package/scripts/tools/render-track.sh +1 -1
  100. package/scripts/tools/resolve-tools.sh +24 -8
  101. package/scripts/tools/run-coverage.sh +1 -1
  102. package/scripts/tools/scan-markers.sh +4 -4
  103. package/scripts/tools/validate-frontmatter.sh +2 -2
  104. package/scripts/tools/verify-citations.sh +3 -4
  105. package/scripts/tools/verify-doc-anchors.sh +14 -34
  106. package/scripts/tools/verify-graph-binary.sh +15 -5
  107. package/skills/GRAPH.md +21 -10
  108. package/skills/adr/SKILL.md +25 -7
  109. package/skills/assist-review/SKILL.md +2 -1
  110. package/skills/bughunt/SKILL.md +55 -12
  111. package/skills/bughunt/references/regression-tests.md +14 -4
  112. package/skills/change/SKILL.md +19 -9
  113. package/skills/coverage/SKILL.md +28 -12
  114. package/skills/debug/SKILL.md +13 -3
  115. package/skills/decompose/SKILL.md +42 -12
  116. package/skills/deep-review/SKILL.md +19 -6
  117. package/skills/deploy-checklist/SKILL.md +10 -3
  118. package/skills/documentation/SKILL.md +12 -1
  119. package/skills/draft/SKILL.md +40 -29
  120. package/skills/draft/context-files.md +8 -1
  121. package/skills/draft/quality-guide.md +10 -2
  122. package/skills/graph/SKILL.md +2 -2
  123. package/skills/impact/SKILL.md +4 -2
  124. package/skills/implement/SKILL.md +62 -20
  125. package/skills/incident-response/SKILL.md +5 -2
  126. package/skills/init/SKILL.md +112 -30
  127. package/skills/init/references/architecture-spec.md +32 -8
  128. package/skills/init/references/okf-emitter.md +42 -78
  129. package/skills/jira/SKILL.md +33 -13
  130. package/skills/jira/references/review.md +61 -19
  131. package/skills/learn/SKILL.md +30 -7
  132. package/skills/new-track/SKILL.md +73 -18
  133. package/skills/quick-review/SKILL.md +8 -3
  134. package/skills/revert/SKILL.md +11 -5
  135. package/skills/review/SKILL.md +126 -27
  136. package/skills/review/references/zero-setup-mode.md +117 -0
  137. package/skills/standup/SKILL.md +10 -2
  138. package/skills/status/SKILL.md +7 -7
  139. package/skills/tech-debt/SKILL.md +9 -3
  140. package/skills/testing-strategy/SKILL.md +10 -2
  141. package/skills/tour/SKILL.md +2 -1
  142. package/skills/upload/SKILL.md +4 -3
  143. package/core/templates/track-architecture.md +0 -311
@@ -11,7 +11,7 @@ Qualify any Jira ticket — Epic, Story, Bug, or Sub-task — by running a manda
11
11
 
12
12
  **Invoked via:** `/draft:jira review <JIRA_ID>`. The router in [SKILL.md](SKILL.md) dispatches here.
13
13
 
14
- ## Red Flags — STOP if you're:
14
+ ## Red Flags — STOP if you're
15
15
 
16
16
  - Skipping Phase 0 prerequisites — MCP servers and `draft/` context are **required**.
17
17
  - Treating `context.md` as the final report — it's intermediate input for quality analysis.
@@ -42,7 +42,7 @@ Throughout the rest of this document, "story" means "child story (epic mode) OR
42
42
 
43
43
  ## Pipeline Overview
44
44
 
45
- ```
45
+ ```text
46
46
  Phase 0: Prerequisites & MCP Discovery ← fail-fast, verify ALL MCPs, branch on issuetype
47
47
  Phase 1: Issue & Story Collection (Jira MCP) — fan-out for Epic, self-only otherwise
48
48
  Phase 2: Document Collection & Synthesis (WebFetch / configured MCPs)
@@ -80,10 +80,13 @@ previous_run: "{path to previous qualification-report.md or null}"
80
80
  Git state (branch, commit, dirty, synced_to_commit) is read from `draft/metadata.json` — include a human-readable summary table in the report body but do not embed git fields in frontmatter.
81
81
 
82
82
  Gather git metadata at pipeline start from `draft/metadata.json`:
83
+
83
84
  ```bash
84
85
  python3 -c "import json; d=json.load(open('draft/metadata.json')); print(d['git']['branch'], d['git']['commit_short'], d['synced_to_commit'])"
85
86
  ```
87
+
86
88
  Fallback if `draft/metadata.json` absent:
89
+
87
90
  ```bash
88
91
  git branch --show-current
89
92
  git rev-parse HEAD
@@ -99,6 +102,7 @@ git status --porcelain | head -1
99
102
  ### 0.1 Validate Input
100
103
 
101
104
  Parse `$ARGUMENTS` as a Jira issue key:
105
+
102
106
  - If matches `<PROJECT>-<NUMBER>` (e.g., `ENG-446236`, `PROJ-1234`): use as-is.
103
107
  - If numeric-only (e.g., `446236`): prompt user for project prefix — do NOT assume.
104
108
  - If invalid format: **STOP** with usage example.
@@ -128,7 +132,7 @@ Record the detected Code Review MCP type — Phase 3 adapts its calls accordingl
128
132
 
129
133
  The working directory **must** have Draft context. `draft:deep-review`, `draft:bughunt`, and `draft:coverage` depend on it.
130
134
 
131
- ```
135
+ ```text
132
136
  IF draft/.ai-context.md AND draft/architecture.md exist:
133
137
  → Use existing context
134
138
  → Read synced_to_commit from draft/metadata.json (fallback: draft/.ai-context.md YAML frontmatter for pre-migration installs)
@@ -144,12 +148,13 @@ ELSE:
144
148
 
145
149
  After validating input and verifying MCPs, fetch the issue's type:
146
150
 
147
- ```
151
+ ```text
148
152
  get_issue(key=<JIRA_ID>, prune_mode="minimal")
149
153
  → record issue_type, parent (for sub-tasks)
150
154
  ```
151
155
 
152
156
  Branch based on `issue_type`:
157
+
153
158
  - **Epic** → enable Phase 1.3 fan-out (collect child stories).
154
159
  - **Story / Bug** → skip Phase 1.3 fan-out; treat self as the only story record.
155
160
  - **Sub-task** → skip Phase 1.3 fan-out; treat self as the only story record; fetch parent for context.
@@ -164,6 +169,7 @@ ls draft/jira-review/<JIRA_ID>/qualification-report.md 2>/dev/null
164
169
  ```
165
170
 
166
171
  If a previous run exists:
172
+
167
173
  - Note its `generated_at` timestamp for delta comparison in Phase 7.
168
174
  - Do NOT delete — the new run overwrites.
169
175
 
@@ -181,7 +187,7 @@ Announce: "Starting Jira Review Pipeline for `<JIRA_ID>`"
181
187
 
182
188
  ### 1.1 Issue Metadata
183
189
 
184
- ```
190
+ ```text
185
191
  get_issue(key=<JIRA_ID>, prune_mode="full")
186
192
  get_issue_description(issue_key=<JIRA_ID>)
187
193
  get_issue_comments(issue_key=<JIRA_ID>, prune_mode="default")
@@ -190,9 +196,11 @@ get_issue_comments(issue_key=<JIRA_ID>, prune_mode="default")
190
196
  From the full issue, extract and store: key, summary, status, assignee, priority, type, created, updated, labels, components, fix versions.
191
197
 
192
198
  For **Sub-task** type, also fetch the parent:
193
- ```
199
+
200
+ ```text
194
201
  get_issue(key=<PARENT_KEY>, prune_mode="minimal")
195
202
  ```
203
+
196
204
  Record parent key and summary — included in the report for context, not qualified itself.
197
205
 
198
206
  ### 1.2 Extract Artifact Links
@@ -206,6 +214,7 @@ Scan issue description, custom fields, and comments for:
206
214
  | TestRail Results | TestRail URLs, embedded pass/fail data | "TestRail: Results", "Test Results", "QA Results" |
207
215
 
208
216
  Also check:
217
+
209
218
  - `get_linked_issues(issue_key=<JIRA_ID>)` for documentation-type tickets.
210
219
  - Jira attachments (design docs uploaded directly to the issue).
211
220
 
@@ -217,13 +226,14 @@ For each artifact: record URL, type, and hold for Phase 2.
217
226
 
218
227
  For **Epic**:
219
228
 
220
- ```
229
+ ```text
221
230
  get_issues(jql="\"Epic Link\" = <JIRA_ID>", max_results=100, prune_mode="default")
222
231
  ```
223
232
 
224
233
  **Pagination:** If `truncated: true`, increase `max_results` or make follow-up calls. Do not silently drop stories.
225
234
 
226
235
  **Fallbacks** (try in order, stop when results found):
236
+
227
237
  1. `get_issues(jql="parent = <JIRA_ID>", max_results=100)` — Jira Cloud uses `parent` instead of `Epic Link`.
228
238
  2. `get_linked_issues(issue_key=<JIRA_ID>, relationship_type="epic child")`.
229
239
  3. `get_linked_issues(issue_key=<JIRA_ID>)` — all links, filter child/subtask types.
@@ -233,7 +243,8 @@ If all return zero: flag "no stories found", produce minimal report.
233
243
  ### 1.4 Story Enrichment
234
244
 
235
245
  Per story (or per the single self-record for non-Epic):
236
- ```
246
+
247
+ ```text
237
248
  get_issue(key=<STORY_ID>, prune_mode="default")
238
249
  get_issue_comments(issue_key=<STORY_ID>, prune_mode="default")
239
250
  ```
@@ -246,13 +257,15 @@ Extract from fields: "TestRail: Results" if present.
246
257
  ### 1.5 Sub-Task Collection
247
258
 
248
259
  Per story, check for sub-tasks:
249
- ```
260
+
261
+ ```text
250
262
  get_linked_issues(issue_key=<STORY_ID>, relationship_type="subtask")
251
263
  ```
252
264
 
253
265
  Or parse the `subtasks` field from `get_issue(key=<STORY_ID>, prune_mode="full")`.
254
266
 
255
267
  For each sub-task:
268
+
256
269
  - Collect its code-review links from comments (same extraction as stories).
257
270
  - Roll up sub-task code changes into the parent story's change set.
258
271
  - Do NOT treat sub-tasks as independent stories for gap analysis.
@@ -277,6 +290,7 @@ Check each code-deliverable story status:
277
290
  | Blocked | Blocked, Impediment | "BLOCKED — escalation needed" |
278
291
 
279
292
  Additional flags:
293
+
280
294
  - No description or acceptance criteria → "INCOMPLETE SPEC — gap".
281
295
  - Code-deliverable + no code-review links in comments → "NO CODE CHANGES — verify in Phase 3".
282
296
 
@@ -296,6 +310,7 @@ Additional flags:
296
310
  6. All fail → record URL + "could not access" + flag as process gap.
297
311
 
298
312
  **If content retrieved from local Draft artifacts**, synthesis pulls directly:
313
+
299
314
  - §Background → Goals and scope.
300
315
  - §High Level Design (Architecture, Key Design Decisions, Alternatives Considered) → Architecture / design decisions, key trade-offs.
301
316
  - §Detailed Design → API changes.
@@ -304,6 +319,7 @@ Additional flags:
304
319
  - §Approvals signed/unsigned → process compliance signal.
305
320
 
306
321
  **If content retrieved from external doc**, synthesize and write to `draft/jira-review/<JIRA_ID>/design-doc-synthesis.md` (with metadata header):
322
+
307
323
  - Goals and scope.
308
324
  - Architecture / design decisions.
309
325
  - API changes, data model changes.
@@ -311,6 +327,7 @@ Additional flags:
311
327
  - Non-functional requirements (performance, security, scalability).
312
328
 
313
329
  **Process gap signals** to flag:
330
+
314
331
  - Track exists in `draft/tracks/` but no `hld.md` AND no external design doc — qualification gap.
315
332
  - HLD exists but Approvals table fully unsigned — review-process gap (track was implemented without sign-off).
316
333
  - HLD `synced_to_commit` is older than the latest merged code change for the track — drift gap (design and code diverged).
@@ -320,15 +337,18 @@ Additional flags:
320
337
  **Test Plan document** — same access strategy as 2.1. Synthesize test strategy and coverage goals.
321
338
 
322
339
  **TestRail integration** (if TestRail MCP available):
340
+
323
341
  - Extract test suite/run IDs from: Test Plan URL path segments, Jira "TestRail: Results" field, or story-level TestRail references.
324
342
  - Fetch: test case ID, title, status (passed/failed/blocked/untested), mapped story.
325
343
  - Fetch: test run results, pass rate summary.
326
344
 
327
345
  **If TestRail MCP not available:**
346
+
328
347
  - WebFetch on TestRail URLs.
329
348
  - Parse "TestRail: Results" Jira field for embedded data (pass/fail counts, test case references).
330
349
 
331
350
  **Write to** `draft/jira-review/<JIRA_ID>/test-data-synthesis.md` (with metadata header):
351
+
332
352
  - Total test cases with pass/fail/blocked/untested counts.
333
353
  - Test cases mapped to specific stories.
334
354
  - Stories without test cases (test gaps).
@@ -372,7 +392,7 @@ Group result: `{STORY_ID: [change_id_1, change_id_2, ...]}`. Include sub-task ch
372
392
 
373
393
  For each change ID (Gerrit example shown; adapt calls for GitHub/GitLab):
374
394
 
375
- ```
395
+ ```text
376
396
  get_change_details(change_id, options=["ALL_REVISIONS", "MESSAGES", "REVIEWERS"])
377
397
  → status (NEW/MERGED/ABANDONED), owner, reviewers, labels, branch,
378
398
  insertions/deletions, patchset count (_number from revisions)
@@ -436,6 +456,7 @@ Extract code-review links from **issue-level comments** (Phase 1.1). These are c
436
456
  ### 3.6 No Changes for Code Story
437
457
 
438
458
  If a code-deliverable story has **no code changes** (including sub-tasks):
459
+
439
460
  - Check issue-level changes for commit messages mentioning the story ID.
440
461
  - If still none: flag "implementation gap — no code changes found".
441
462
 
@@ -529,12 +550,15 @@ Generate `draft/jira-review/<JIRA_ID>/context.md` (with metadata header) combini
529
550
  ### Where — Codebase Impact
530
551
  (Files grouped by module from consolidated change set:)
531
552
  ```
553
+
532
554
  module_a/ (N files)
555
+
533
556
  - file1.cc (MODIFIED)
534
557
  - file2.h (ADDED)
535
558
  module_b/ (N files)
536
559
  - file3.py (MODIFIED)
537
- ```
560
+
561
+ ```text
538
562
 
539
563
  ### How — Technical Approach
540
564
  (Per-module: 2-3 sentences summarizing what the code changes do. Derived from commit
@@ -598,6 +622,7 @@ For each story, include under `## Per-Story Detail`:
598
622
  ### Learnings Narrative Per Story
599
623
 
600
624
  For **bug-fix stories** (5 sections):
625
+
601
626
  1. **What was the issue** — symptoms, scope, observables, impact. Generalize using patterns rather than raw ticket IDs.
602
627
  2. **RCA** — primary cause, contributing factors. Incorporate code-review insights from `list_change_comments` if relevant.
603
628
  3. **Resolution** — fix type, change ID, branch, merge status, who reviewed. Reference patchset count.
@@ -605,6 +630,7 @@ For **bug-fix stories** (5 sections):
605
630
  5. **Learnings** — technical, operational, process takeaways. Test gaps.
606
631
 
607
632
  For **feature stories** (5 sections):
633
+
608
634
  1. **What was the requirement** — goal, user need, scope, acceptance criteria. Cross-reference design doc synthesis.
609
635
  2. **Technical approach** — design decisions, patterns, integration points.
610
636
  3. **Implementation** — key files from `list_change_files`, change scope (insertions/deletions).
@@ -697,11 +723,12 @@ All three commands use the `draft/` context established in Phase 0.
697
723
  ### 5.1 /draft:deep-review
698
724
 
699
725
  Run per changed module. Module selection follows deep-review's own priority:
726
+
700
727
  1. Check `draft/.ai-context.md` for `## Modules` or `## Module Catalog` — match against modules from the consolidated change set.
701
728
  2. If no module catalog: use top-level directories from the consolidated file list.
702
729
  3. Run once per affected module:
703
730
 
704
- ```
731
+ ```text
705
732
  draft:deep-review <module-name-or-directory>
706
733
  ```
707
734
 
@@ -716,11 +743,12 @@ Produces per-module: ACID compliance, resilience, observability, configuration a
716
743
  Run scoped to specific file paths from the consolidated change set.
717
744
 
718
745
  **Invocation protocol:** bughunt prompts for scope type when invoked. Pre-answer the prompt:
746
+
719
747
  1. Select **"Specific paths"** when bughunt asks for scope.
720
748
  2. Supply the consolidated file list from Phase 3.4 as the target paths.
721
749
  3. If bughunt asks for track context, respond: "No track — running as part of /draft:jira review pipeline".
722
750
 
723
- ```
751
+ ```text
724
752
  /draft:bughunt
725
753
  → (scope prompt) → "Specific paths"
726
754
  → (paths prompt) → <consolidated file list from Phase 3.4>
@@ -736,13 +764,14 @@ Produces: severity-ranked bug list (Critical/High/Medium/Low) with code evidence
736
764
 
737
765
  Run with explicit path argument per changed module:
738
766
 
739
- ```
767
+ ```text
740
768
  /draft:coverage <module-directory>
741
769
  ```
742
770
 
743
771
  Coverage reads `coverage_target` from `draft/workflow.md` (default: **95%** if absent).
744
772
 
745
773
  **Track requirement workaround:** `/draft:coverage` expects an active track and writes to `draft/tracks/<id>/coverage-report.md`. Since `jira review` does not create a track:
774
+
746
775
  1. Coverage will look for an active track from `draft/tracks.md` — if none exists, it will warn.
747
776
  2. Capture coverage output directly from the tool's console/response text.
748
777
  3. Record the coverage percentages, gap analysis, and uncovered files in the review context document (Phase 4).
@@ -753,6 +782,7 @@ Coverage reads `coverage_target` from `draft/workflow.md` (default: **95%** if a
753
782
  ### 5.4 Partial Completion Handling
754
783
 
755
784
  If any Phase 5 command fails:
785
+
756
786
  - Record which commands completed and which failed.
757
787
  - Continue with remaining commands — do NOT abort the pipeline.
758
788
  - In Phase 7, note failed analyses: "draft:coverage — FAILED: no test framework detected" etc.
@@ -801,6 +831,7 @@ From Phase 3.4 test file classification:
801
831
  | Story ships only test files | Test-only change (backfill, refactor) — positive signal |
802
832
 
803
833
  Per story, assign a **Test Shipping Status**:
834
+
804
835
  - **TESTED**: code changes include test files covering the production changes.
805
836
  - **PARTIALLY TESTED**: some production files have companion tests (unchanged or in different changes).
806
837
  - **UNTESTED**: no test files shipped, no companion tests in codebase.
@@ -809,6 +840,7 @@ Per story, assign a **Test Shipping Status**:
809
840
  ### 6.3 Acceptance Criteria → Test Mapping
810
841
 
811
842
  Per code-deliverable story:
843
+
812
844
  1. Extract acceptance criteria (from Phase 1.4).
813
845
  2. Map to **codebase tests** discovered in 6.1 (test function names that exercise the criterion).
814
846
  3. Map to **TestRail test cases** (from Phase 2.2, if available) — if TestRail unavailable, leave column blank and weight codebase tests + coverage higher.
@@ -857,7 +889,7 @@ Generate **framework-specific, copy-pasteable test suggestions** for every ident
857
889
 
858
890
  For each production file/function without adequate test coverage:
859
891
 
860
- ```
892
+ ```yaml
861
893
  Test: <descriptive_test_function_name>
862
894
  Type: Unit
863
895
  Priority: Critical / High / Medium
@@ -873,7 +905,8 @@ Sketch:
873
905
  <include setup/teardown if needed>
874
906
  <test the specific changed function with meaningful assertions>
875
907
  ```
876
- ```
908
+
909
+ ```text
877
910
 
878
911
  **Focus areas** (in priority order):
879
912
  1. Changed functions with zero test coverage.
@@ -887,6 +920,7 @@ Sketch:
887
920
  For each Critical/High bughunt finding (from 6.5):
888
921
 
889
922
  ```
923
+
890
924
  Test: regression_<bug_description>
891
925
  Type: Regression
892
926
  Priority: Critical (matches bughunt severity)
@@ -897,18 +931,21 @@ Tests: <reproduces the exact bug scenario>
897
931
  Why: Prevents regression of <bughunt finding>
898
932
 
899
933
  Sketch:
934
+
900
935
  ```<language>
901
936
  <test that sets up the vulnerable state>
902
937
  <triggers the code path that had the bug>
903
938
  <asserts correct behavior — the bug does NOT manifest>
904
939
  ```
905
- ```
940
+
941
+ ```text
906
942
 
907
943
  #### Integration Tests — for cross-module changes
908
944
 
909
945
  When code changes span multiple modules (from Phase 3.4 consolidated change set):
910
946
 
911
947
  ```
948
+
912
949
  Test: integration_<module_a>_<module_b>_<scenario>
913
950
  Type: Integration
914
951
  Priority: High
@@ -918,12 +955,14 @@ Tests: <interaction between modules — data flow, API contract, event handli
918
955
  Why: Cross-module changes risk breaking integration points
919
956
 
920
957
  Sketch:
958
+
921
959
  ```<language>
922
960
  <set up both modules with test fixtures>
923
961
  <exercise the integration point changed by the issue>
924
962
  <assert end-to-end behavior across module boundary>
925
963
  ```
926
- ```
964
+
965
+ ```text
927
966
 
928
967
  **Trigger conditions** for integration test suggestions:
929
968
  - Stories whose code changes touch files in 2+ modules.
@@ -1222,10 +1261,13 @@ Total: <N> changes across <M> stories
1222
1261
  ## All Files Changed
1223
1262
  (Deduplicated, grouped by module:)
1224
1263
  ```
1264
+
1225
1265
  module_a/ (N files)
1266
+
1226
1267
  - file1.cc (MODIFIED, stories: ENG-111, ENG-222)
1227
1268
  - file2.h (ADDED, stories: ENG-111)
1228
- ```
1269
+
1270
+ ```yaml
1229
1271
  Total: <N> files across <M> modules
1230
1272
  ```
1231
1273
 
@@ -14,7 +14,7 @@ First resolve the bundled helpers:
14
14
  ```bash
15
15
  # Locate Draft's bundled helpers (cwd is the user's project; ${CLAUDE_PLUGIN_ROOT}
16
16
  # is not exported into skill Bash). See core/shared/tool-resolver.md.
17
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
17
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
18
18
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
19
19
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
20
20
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -28,11 +28,12 @@ When `draft/graph/schema.yaml` exists, this skill **must** follow the graph-firs
28
28
 
29
29
  Filesystem `find` for source discovery (Step 2.1) is permitted **as a complement** to the graph for languages not covered by indexes (e.g. Ruby, Java without ctags). Record the rationale in the Graph Usage Report.
30
30
 
31
- ## Red Flags - STOP if you're:
31
+ ## Red Flags - STOP if you're
32
32
 
33
33
  See [shared red flags](../../core/shared/red-flags.md) — applies to all code-touching skills.
34
34
 
35
35
  Skill-specific:
36
+
36
37
  - Writing to guardrails.md without reading the codebase first
37
38
  - Learning a pattern from fewer than 3 occurrences
38
39
  - Auto-promoting patterns to Hard Guardrails (requires human approval)
@@ -72,6 +73,7 @@ ls draft/guardrails.md 2>/dev/null
72
73
  ```
73
74
 
74
75
  If it exists, read it and internalize:
76
+
75
77
  - Current Hard Guardrails (checked items)
76
78
  - Current Learned Conventions (existing entries)
77
79
  - Current Learned Anti-Patterns (existing entries)
@@ -93,6 +95,7 @@ If `draft/guardrails.md` does NOT exist:
93
95
  3. Create `draft/guardrails.md` using template from `core/templates/guardrails.md`
94
96
  4. Copy checked guardrail items from `workflow.md ## Guardrails` into the Hard Guardrails section
95
97
  5. Add a comment in `workflow.md` where `## Guardrails` was:
98
+
96
99
  ```markdown
97
100
  ## Guardrails
98
101
 
@@ -104,6 +107,7 @@ If `migrate` argument was given, stop here after migration. Otherwise, continue
104
107
  ### 1.3: Load Supporting Context
105
108
 
106
109
  Read and follow `core/shared/draft-context-loading.md` for full Draft context. Key files:
110
+
107
111
  - `draft/.ai-context.md` — Module boundaries, invariants, concurrency model
108
112
  - `draft/tech-stack.md` — Frameworks, accepted patterns (do not learn patterns that duplicate these)
109
113
  - `draft/product.md` — Product requirements
@@ -133,41 +137,48 @@ If scope argument provided, filter to that path.
133
137
  Scan the codebase across these dimensions, looking for **recurring patterns** (3+ occurrences):
134
138
 
135
139
  #### Error Handling Conventions
140
+
136
141
  - How errors are caught, logged, and propagated
137
142
  - Custom error classes or error codes
138
143
  - Try/catch patterns, error boundaries
139
144
  - Retry and fallback strategies
140
145
 
141
146
  #### Naming Conventions
147
+
142
148
  - Variable, function, class naming styles beyond language defaults
143
149
  - File naming patterns (kebab-case, PascalCase, etc.)
144
150
  - Module/directory organization conventions
145
151
 
146
152
  #### Architecture Patterns
153
+
147
154
  - Import/dependency patterns (barrel exports, lazy loading)
148
155
  - State management approaches
149
156
  - API call patterns (centralized client, interceptors)
150
157
  - Component composition patterns
151
158
 
152
159
  #### Concurrency Patterns
160
+
153
161
  - Async/await usage conventions
154
162
  - Locking and synchronization approaches
155
163
  - Queue and worker patterns
156
164
  - Cancellation and timeout handling
157
165
 
158
166
  #### Data Flow Patterns
167
+
159
168
  - Validation placement (boundary vs deep)
160
169
  - Serialization/deserialization conventions
161
170
  - Caching strategies
162
171
  - Data transformation pipelines
163
172
 
164
173
  #### Testing Conventions
174
+
165
175
  - Test file placement and naming
166
176
  - Test structure (arrange/act/assert, given/when/then)
167
177
  - Mock/stub conventions
168
178
  - Fixture and factory patterns
169
179
 
170
180
  #### Configuration Patterns
181
+
171
182
  - Environment variable access patterns
172
183
  - Feature flag patterns
173
184
  - Config file conventions
@@ -181,9 +192,11 @@ Detect patterns that are being phased out by the team:
181
192
  - **New files** (last modified <6 months ago): low or zero occurrence of the pattern
182
193
  - If occurrence ratio old:new is >3:1, flag as a declining pattern
183
194
  2. **Mark declining patterns** — When writing to guardrails.md, add `declining: true` to the entry metadata:
195
+
184
196
  ```markdown
185
197
  - **Declining:** yes — found in 8 old files (avg age 18mo), 1 new file (avg age 2mo). Being replaced by [newer pattern].
186
198
  ```
199
+
187
200
  3. **Do NOT propagate declining patterns** — Quality commands should not flag absence of a declining pattern as inconsistency
188
201
  4. **Example:** Old error handling style `try/catch with manual logging` found in files last modified >1 year ago, newer files use structured error middleware — the old style is declining, not a convention to enforce
189
202
 
@@ -198,12 +211,14 @@ When in a monorepo (detected by `draft/service-index.md` existing OR multiple `d
198
211
  - Does Service A use a different approach than Service B for the same concern?
199
212
  - Example: Service A uses `Result<T, E>` for error handling, Service B uses exceptions
200
213
  3. **Flag inconsistencies** — Report cross-service divergences:
201
- ```
214
+
215
+ ```text
202
216
  Cross-service inconsistency: Error Handling
203
217
  services/auth/ → uses custom Result type (5 files)
204
218
  services/billing/ → uses thrown exceptions (8 files)
205
219
  Suggestion: standardize on one approach
206
220
  ```
221
+
207
222
  4. **Respect intentional differences** — Do NOT flag inconsistencies when:
208
223
  - Services use different languages or frameworks
209
224
  - The pattern difference is documented in `tech-stack.md` or `.ai-context.md`
@@ -237,9 +252,10 @@ Scan the output for recurring message patterns (3+ occurrences of the same type)
237
252
  | `fix: don't X` / `fix: never X` | Team keeps violating X → anti-pattern candidate |
238
253
  | `refactor: replace X with Y` | X is declining, Y is the replacement → mark X as `declining: true` |
239
254
  | `chore: enforce X` / `chore: add X check` | X is being formalized → convention candidate |
240
- | `revert: ` followed by same topic 3+ times | That topic is consistently problematic → anti-pattern candidate |
255
+ | `revert:` followed by same topic 3+ times | That topic is consistently problematic → anti-pattern candidate |
241
256
 
242
257
  **Rules:**
258
+
243
259
  - Do NOT add git-only signals as standalone entries. Use them only to adjust confidence of patterns already found in Step 2.2.
244
260
  - If a pattern appears in both commit history AND code (3+ occurrences): increase confidence by one level.
245
261
  - If a pattern appears only in commit history but not in current code: note as `historically_recurring: true` — do not add as active anti-pattern.
@@ -260,6 +276,7 @@ git log --follow --oneline -1 -- {file_containing_pattern}
260
276
  If `draft/graph/schema.yaml` exists (engine live), derive objective severity for all anti-pattern candidates based on the fanIn of files where the pattern was found via `"$DRAFT_TOOLS/hotspot-rank.sh" --repo .`.
261
277
 
262
278
  For each anti-pattern candidate from Step 2.2:
279
+
263
280
  1. Check if any evidence files appear in the hotspot output from `"$DRAFT_TOOLS/hotspot-rank.sh" --repo .`
264
281
  2. Take the highest fanIn value across all evidence files:
265
282
  - fanIn ≥ 10 → `graph_severity: critical` (breakage propagates to many callers)
@@ -303,9 +320,11 @@ Before saving any new pattern, check for conflicts with existing entries:
303
320
  3. **Check against Hard Guardrails** — Does the new pattern violate a hard guardrail?
304
321
 
305
322
  **If conflict found:**
323
+
306
324
  - Do NOT silently save the new pattern
307
325
  - Alert the user with both patterns side by side:
308
- ```
326
+
327
+ ```text
309
328
  CONFLICT DETECTED:
310
329
 
311
330
  Existing convention: "Use async/await for all async operations"
@@ -320,6 +339,7 @@ Before saving any new pattern, check for conflicts with existing entries:
320
339
  [2] Replace existing with new (pattern has evolved)
321
340
  [3] Discard new (existing is correct)
322
341
  ```
342
+
323
343
  - Wait for user input before proceeding
324
344
 
325
345
  **Reference:** Google Code Health — conflicting patterns create confusion and should be resolved explicitly.
@@ -340,6 +360,7 @@ After discovering patterns, optionally compare project conventions against commu
340
360
  | **C/C++** | Google C++ Style Guide, C++ Core Guidelines |
341
361
 
342
362
  For each project convention that **deviates** from its language's community standard:
363
+
343
364
  1. Note the deviation in the summary report (not as an anti-pattern — deviations may be intentional)
344
365
  2. If the deviation is undocumented, suggest adding it to `tech-stack.md ## Accepted Patterns` with a rationale
345
366
  3. Example: project uses `snake_case` for TypeScript functions (deviates from `camelCase` convention) — flag for documentation, not correction
@@ -400,7 +421,7 @@ Follow the write procedure in `core/shared/pattern-learning.md`:
400
421
 
401
422
  Review all learned patterns with `confidence: high` and present promotion candidates:
402
423
 
403
- ```
424
+ ```text
404
425
  Pattern promotion candidates:
405
426
 
406
427
  1. [Convention] "Centralized API client pattern" (high confidence, 12 files)
@@ -414,6 +435,7 @@ Pattern promotion candidates:
414
435
  ```
415
436
 
416
437
  For each promoted pattern:
438
+
417
439
  - **Convention → Accepted Pattern**: Append to `draft/tech-stack.md ## Accepted Patterns` and remove from guardrails.md Learned Conventions
418
440
  - **Convention → Hard Guardrail**: Move from Learned Conventions to Hard Guardrails section (as checked `[x]` item)
419
441
  - **Anti-Pattern → Hard Guardrail**: Move from Learned Anti-Patterns to Hard Guardrails section (as checked `[x]` item)
@@ -424,7 +446,7 @@ For each promoted pattern:
424
446
 
425
447
  Display results to the user:
426
448
 
427
- ```
449
+ ```text
428
450
  /draft:learn complete
429
451
 
430
452
  Scanned: N source files across M directories
@@ -457,6 +479,7 @@ After `/draft:learn` populates guardrails.md, all quality commands automatically
457
479
  | **Unchecked Hard Guardrails** | Ignore (not enforced) |
458
480
 
459
481
  This creates a **continuous improvement loop**:
482
+
460
483
  1. Quality command runs → discovers patterns → updates guardrails.md
461
484
  2. Next quality command run → reads updated guardrails.md → fewer false positives, catches known-bad patterns
462
485
  3. `/draft:learn promote` → graduates stable patterns to permanent status