@hegemonart/get-design-done 1.59.3 → 1.59.5

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 (155) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +61 -0
  4. package/SKILL.md +2 -0
  5. package/figma-plugin/README.md +61 -0
  6. package/figma-plugin/code.ts +36 -0
  7. package/figma-plugin/manifest.json +12 -0
  8. package/figma-plugin/package-lock.json +35 -0
  9. package/figma-plugin/package.json +12 -0
  10. package/figma-plugin/src/export-variables.ts +144 -0
  11. package/figma-plugin/src/payload-schema.ts +250 -0
  12. package/figma-plugin/tsconfig.json +16 -0
  13. package/figma-plugin/ui.html +44 -0
  14. package/hooks/budget-enforcer.ts +134 -7
  15. package/hooks/gdd-intel-trigger.js +3 -3
  16. package/package.json +6 -1
  17. package/reference/DEPRECATIONS.md +3 -3
  18. package/reference/live-mode-integration.md +1 -1
  19. package/reference/registry.json +1 -1
  20. package/reference/runtime-models.md +15 -15
  21. package/reference/schemas/generated.d.ts +4 -0
  22. package/reference/schemas/runtime-models.schema.json +5 -0
  23. package/reference/skill-metadata.md +4 -4
  24. package/reference/skill-placeholders.md +2 -2
  25. package/scripts/build-skills.cjs +146 -0
  26. package/scripts/generate-skill-frontmatter.cjs +243 -0
  27. package/scripts/lib/bandit-router/integration.cjs +38 -0
  28. package/scripts/lib/install/installer.cjs +133 -1
  29. package/scripts/lib/manifest/scaffolder.cjs +1 -1
  30. package/scripts/lib/manifest/schemas/skills.schema.json +1 -1
  31. package/scripts/lib/manifest/skills.json +1 -1
  32. package/scripts/lib/new-addendum.cjs +1 -1
  33. package/scripts/skill-templates/README.md +90 -0
  34. package/scripts/skill-templates/add-backlog/SKILL.md +48 -0
  35. package/scripts/skill-templates/analyze-dependencies/SKILL.md +95 -0
  36. package/scripts/skill-templates/apply-reflections/SKILL.md +109 -0
  37. package/scripts/skill-templates/apply-reflections/apply-reflections-procedure.md +170 -0
  38. package/scripts/skill-templates/audit/SKILL.md +79 -0
  39. package/scripts/skill-templates/bandit-reset/SKILL.md +91 -0
  40. package/scripts/skill-templates/bandit-status/SKILL.md +94 -0
  41. package/scripts/skill-templates/benchmark/SKILL.md +65 -0
  42. package/scripts/skill-templates/bootstrap-ds/SKILL.md +43 -0
  43. package/scripts/skill-templates/brief/SKILL.md +145 -0
  44. package/scripts/skill-templates/budget/SKILL.md +45 -0
  45. package/scripts/skill-templates/cache-manager/SKILL.md +66 -0
  46. package/scripts/skill-templates/cache-manager/cache-policy.md +126 -0
  47. package/scripts/skill-templates/check-update/SKILL.md +98 -0
  48. package/scripts/skill-templates/compare/SKILL.md +82 -0
  49. package/scripts/skill-templates/compare/compare-rubric.md +171 -0
  50. package/scripts/skill-templates/complete-cycle/SKILL.md +81 -0
  51. package/scripts/skill-templates/connections/SKILL.md +71 -0
  52. package/scripts/skill-templates/connections/connections-onboarding.md +608 -0
  53. package/scripts/skill-templates/context/SKILL.md +137 -0
  54. package/scripts/skill-templates/continue/SKILL.md +24 -0
  55. package/scripts/skill-templates/darkmode/SKILL.md +76 -0
  56. package/scripts/skill-templates/darkmode/darkmode-audit-procedure.md +258 -0
  57. package/scripts/skill-templates/debug/SKILL.md +41 -0
  58. package/scripts/skill-templates/debug/debug-feedback-loops.md +119 -0
  59. package/scripts/skill-templates/design/SKILL.md +118 -0
  60. package/scripts/skill-templates/design/design-procedure.md +304 -0
  61. package/scripts/skill-templates/discuss/SKILL.md +96 -0
  62. package/scripts/skill-templates/do/SKILL.md +45 -0
  63. package/scripts/skill-templates/explore/SKILL.md +118 -0
  64. package/scripts/skill-templates/explore/explore-procedure.md +267 -0
  65. package/scripts/skill-templates/export/SKILL.md +30 -0
  66. package/scripts/skill-templates/extract-learnings/SKILL.md +114 -0
  67. package/scripts/skill-templates/fast/SKILL.md +91 -0
  68. package/scripts/skill-templates/figma-extract/SKILL.md +64 -0
  69. package/scripts/skill-templates/figma-write/SKILL.md +50 -0
  70. package/scripts/skill-templates/graphify/SKILL.md +49 -0
  71. package/scripts/skill-templates/health/SKILL.md +99 -0
  72. package/scripts/skill-templates/health/health-mcp-detection.md +44 -0
  73. package/scripts/skill-templates/health/health-skill-length-report.md +69 -0
  74. package/scripts/skill-templates/help/SKILL.md +60 -0
  75. package/scripts/skill-templates/instinct/SKILL.md +111 -0
  76. package/scripts/skill-templates/list-assumptions/SKILL.md +61 -0
  77. package/scripts/skill-templates/list-pins/SKILL.md +27 -0
  78. package/scripts/skill-templates/live/SKILL.md +98 -0
  79. package/scripts/skill-templates/locale/SKILL.md +51 -0
  80. package/scripts/skill-templates/map/SKILL.md +89 -0
  81. package/scripts/skill-templates/migrate/SKILL.md +70 -0
  82. package/scripts/skill-templates/migrate-context/SKILL.md +123 -0
  83. package/scripts/skill-templates/new-addendum/SKILL.md +81 -0
  84. package/scripts/skill-templates/new-cycle/SKILL.md +37 -0
  85. package/scripts/skill-templates/new-project/SKILL.md +53 -0
  86. package/scripts/skill-templates/new-skill/SKILL.md +90 -0
  87. package/scripts/skill-templates/next/SKILL.md +68 -0
  88. package/scripts/skill-templates/note/SKILL.md +48 -0
  89. package/scripts/skill-templates/openrouter-status/SKILL.md +86 -0
  90. package/scripts/skill-templates/optimize/SKILL.md +97 -0
  91. package/scripts/skill-templates/override/SKILL.md +86 -0
  92. package/scripts/skill-templates/paper-write/SKILL.md +54 -0
  93. package/scripts/skill-templates/pause/SKILL.md +77 -0
  94. package/scripts/skill-templates/peer-cli-add/SKILL.md +88 -0
  95. package/scripts/skill-templates/peer-cli-add/peer-cli-protocol.md +161 -0
  96. package/scripts/skill-templates/peer-cli-customize/SKILL.md +89 -0
  97. package/scripts/skill-templates/peers/SKILL.md +96 -0
  98. package/scripts/skill-templates/pencil-write/SKILL.md +54 -0
  99. package/scripts/skill-templates/pin/SKILL.md +37 -0
  100. package/scripts/skill-templates/plan/SKILL.md +105 -0
  101. package/scripts/skill-templates/plan/plan-procedure.md +278 -0
  102. package/scripts/skill-templates/plant-seed/SKILL.md +48 -0
  103. package/scripts/skill-templates/pr-branch/SKILL.md +32 -0
  104. package/scripts/skill-templates/progress/SKILL.md +107 -0
  105. package/scripts/skill-templates/quality-gate/SKILL.md +90 -0
  106. package/scripts/skill-templates/quality-gate/threat-modeling.md +101 -0
  107. package/scripts/skill-templates/quick/SKILL.md +44 -0
  108. package/scripts/skill-templates/reapply-patches/SKILL.md +32 -0
  109. package/scripts/skill-templates/recall/SKILL.md +75 -0
  110. package/scripts/skill-templates/reflect/SKILL.md +85 -0
  111. package/scripts/skill-templates/reflect/procedures/capability-gap-scan.md +119 -0
  112. package/scripts/skill-templates/report-issue/SKILL.md +53 -0
  113. package/scripts/skill-templates/report-issue/report-issue-procedure.md +119 -0
  114. package/scripts/skill-templates/resume/SKILL.md +93 -0
  115. package/scripts/skill-templates/review-backlog/SKILL.md +46 -0
  116. package/scripts/skill-templates/review-decisions/SKILL.md +42 -0
  117. package/scripts/skill-templates/roi/SKILL.md +54 -0
  118. package/scripts/skill-templates/rollout-status/SKILL.md +35 -0
  119. package/scripts/skill-templates/router/SKILL.md +89 -0
  120. package/scripts/skill-templates/router/capability-gap-emitter.md +65 -0
  121. package/scripts/skill-templates/router/router-pick-emitter.md +78 -0
  122. package/scripts/skill-templates/router/router-rules.md +84 -0
  123. package/scripts/skill-templates/settings/SKILL.md +87 -0
  124. package/scripts/skill-templates/ship/SKILL.md +48 -0
  125. package/scripts/skill-templates/sketch/SKILL.md +78 -0
  126. package/scripts/skill-templates/sketch-wrap-up/SKILL.md +92 -0
  127. package/scripts/skill-templates/skill-manifest/SKILL.md +79 -0
  128. package/scripts/skill-templates/spike/SKILL.md +67 -0
  129. package/scripts/skill-templates/spike-wrap-up/SKILL.md +86 -0
  130. package/scripts/skill-templates/start/SKILL.md +67 -0
  131. package/scripts/skill-templates/start/start-procedure.md +115 -0
  132. package/scripts/skill-templates/state/SKILL.md +106 -0
  133. package/scripts/skill-templates/stats/SKILL.md +51 -0
  134. package/scripts/skill-templates/style/SKILL.md +71 -0
  135. package/scripts/skill-templates/style/style-doc-procedure.md +150 -0
  136. package/scripts/skill-templates/synthesize/SKILL.md +94 -0
  137. package/scripts/skill-templates/timeline/SKILL.md +66 -0
  138. package/scripts/skill-templates/todo/SKILL.md +64 -0
  139. package/scripts/skill-templates/turn-closeout/SKILL.md +95 -0
  140. package/scripts/skill-templates/undo/SKILL.md +31 -0
  141. package/scripts/skill-templates/unlock-decision/SKILL.md +54 -0
  142. package/scripts/skill-templates/unpin/SKILL.md +31 -0
  143. package/scripts/skill-templates/update/SKILL.md +56 -0
  144. package/scripts/skill-templates/using-gdd/SKILL.md +78 -0
  145. package/scripts/skill-templates/verify/SKILL.md +113 -0
  146. package/scripts/skill-templates/verify/verify-procedure.md +511 -0
  147. package/scripts/skill-templates/warm-cache/SKILL.md +81 -0
  148. package/scripts/skill-templates/watch-authorities/SKILL.md +82 -0
  149. package/scripts/skill-templates/zoom-out/SKILL.md +26 -0
  150. package/sdk/cli/commands/build.ts +2 -2
  151. package/sdk/cli/index.js +2 -2
  152. package/sdk/cli/index.ts +1 -1
  153. package/skills/README.md +22 -14
  154. package/skills/help/SKILL.md +28 -55
  155. package/skills/new-skill/SKILL.md +5 -5
@@ -0,0 +1,137 @@
1
+ ---
2
+ name: gdd-context
3
+ description: "Queries the typed DesignContext graph at .design/context-graph.json - the design-semantic map of tokens, components, variants, states, motion, a11y patterns, screens, layers, and design patterns plus the edges between them. Lists and filters nodes and edges, traces a path between two nodes, finds the consumers of a node, and reports unreachable nodes, dependency cycles, and coverage. Use when the user wants to inspect the design graph, find what depends on a token or component, trace how one node reaches another, or check graph health. Activates for requests involving the design context graph, design dependencies, token consumers, component composition, unreachable design nodes, design cycles, or design coverage."
4
+ argument-hint: "[nodes --type X | edges --type Z | path <a> <b> | consumers-of <id> | unreachable | cycles | coverage]"
5
+ tools: Read, Bash
6
+ user-invocable: true
7
+ ---
8
+
9
+ # {{command_prefix}}context
10
+
11
+ **Role:** Read-only front end for the typed DesignContext graph. The graph is a design-semantic map: nodes are tokens, components, variants, states, motion fragments, a11y patterns, screens, layers, and design patterns; edges connect them (uses-token, composes, extends, transitions-to, depends-on, mirrors, conflicts-with, referenced-by, tested-by, documented-by, consumes-context, provides-context). This skill queries that graph. It never writes to it. The graph is authored by the mapper agents plus the design-research-synthesizer; this skill only reads.
12
+
13
+ The query engine ships at `scripts/lib/design-context-query.cjs` (authored elsewhere; this skill only calls it). It is pure and dep-free, exposing `load`, `nodes`, `edges`, `path`, `consumersOf`, `unreachable`, `cycles`, and `coverage`. The merged graph lives at `.design/context-graph.json` with the shape `{ schema_version, generated_at, nodes[], edges[] }`.
14
+
15
+ If `.design/context-graph.json` is absent, print: `No DesignContext graph yet. Run the design research pipeline (mappers plus {{command_prefix}}synthesize) to generate .design/context-graph.json.` Then STOP. Do not invent a graph.
16
+
17
+ The engine exposes a module API rather than a CLI, so drive it from a short `node -e` script, the same way other skills call a `scripts/lib` helper:
18
+
19
+ ```bash
20
+ node -e "const q=require('${CLAUDE_PLUGIN_ROOT}/scripts/lib/design-context-query.cjs'); \
21
+ const g=q.load('.design/context-graph.json'); \
22
+ console.log(JSON.stringify(q.nodes(g, { type: process.env.NODE_TYPE || undefined, tag: process.env.TAG || undefined })));"
23
+ ```
24
+
25
+ ## Invocation Modes
26
+
27
+ | Command | Behavior |
28
+ |---|---|
29
+ | `{{command_prefix}}context nodes` | List graph nodes, optionally filtered by `--type` and `--tag` (default mode). |
30
+ | `{{command_prefix}}context edges` | List graph edges, optionally filtered by `--type`. |
31
+ | `{{command_prefix}}context path <a> <b>` | Trace a path from node `<a>` to node `<b>`. |
32
+ | `{{command_prefix}}context consumers-of <id>` | List the nodes that consume node `<id>`. |
33
+ | `{{command_prefix}}context unreachable` | List nodes no edge reaches. |
34
+ | `{{command_prefix}}context cycles` | List dependency cycles in the graph. |
35
+ | `{{command_prefix}}context coverage` | Report graph coverage (typed and tagged ratios). |
36
+
37
+ Output discipline: emit JSON when a tool or another skill is the caller; render a compact table when a person is at the terminal.
38
+
39
+ ## nodes
40
+
41
+ List nodes. `--type <t>` filters by node type (token, component, variant, state, motion-fragment, a11y-pattern, screen, layer, pattern, anti-pattern). `--tag <tag>` filters by a controlled tag. Call `nodes(graph, { type, tag })`:
42
+
43
+ ```bash
44
+ node -e "const q=require('${CLAUDE_PLUGIN_ROOT}/scripts/lib/design-context-query.cjs'); \
45
+ const g=q.load('.design/context-graph.json'); \
46
+ console.log(JSON.stringify(q.nodes(g, { type: process.env.NODE_TYPE || undefined, tag: process.env.TAG || undefined })));"
47
+ ```
48
+
49
+ Render one row per node. Keep it scannable:
50
+
51
+ ```
52
+ ID TYPE COMPLEXITY NAME
53
+ token:color/brand token simple Brand primary
54
+ component:Button component moderate Button
55
+ ```
56
+
57
+ If no nodes match, say so plainly and suggest a broader filter.
58
+
59
+ ## edges
60
+
61
+ List edges. `--type <t>` filters by edge type (uses-token, composes, extends, transitions-to, depends-on, mirrors, conflicts-with, referenced-by, tested-by, documented-by, consumes-context, provides-context). Call `edges(graph, { type })`:
62
+
63
+ ```bash
64
+ node -e "const q=require('${CLAUDE_PLUGIN_ROOT}/scripts/lib/design-context-query.cjs'); \
65
+ const g=q.load('.design/context-graph.json'); \
66
+ console.log(JSON.stringify(q.edges(g, { type: process.env.EDGE_TYPE || undefined })));"
67
+ ```
68
+
69
+ Render `source -> target (type, weight)` per row. If none match, report it and suggest dropping the filter.
70
+
71
+ ## path
72
+
73
+ Trace a path between two node ids. Call `path(graph, from, to)`:
74
+
75
+ ```bash
76
+ node -e "const q=require('${CLAUDE_PLUGIN_ROOT}/scripts/lib/design-context-query.cjs'); \
77
+ const g=q.load('.design/context-graph.json'); \
78
+ console.log(JSON.stringify(q.path(g, process.env.FROM, process.env.TO)));"
79
+ ```
80
+
81
+ Print the ordered node ids joined by arrows. If no path exists, print `No path from <a> to <b>.` Do not fabricate intermediate nodes.
82
+
83
+ ## consumers-of
84
+
85
+ List the nodes that consume a given node (the inbound side). Call `consumersOf(graph, id)`:
86
+
87
+ ```bash
88
+ node -e "const q=require('${CLAUDE_PLUGIN_ROOT}/scripts/lib/design-context-query.cjs'); \
89
+ const g=q.load('.design/context-graph.json'); \
90
+ console.log(JSON.stringify(q.consumersOf(g, process.env.ID)));"
91
+ ```
92
+
93
+ Render the consumer ids one per row. If the id is unknown, print `No node <id> in the graph.` and suggest `{{command_prefix}}context nodes`.
94
+
95
+ ## unreachable
96
+
97
+ List nodes that no edge reaches (orphans). Call `unreachable(graph)`:
98
+
99
+ ```bash
100
+ node -e "const q=require('${CLAUDE_PLUGIN_ROOT}/scripts/lib/design-context-query.cjs'); \
101
+ const g=q.load('.design/context-graph.json'); \
102
+ console.log(JSON.stringify(q.unreachable(g)));"
103
+ ```
104
+
105
+ If the list is empty, print `Every node is reachable.`
106
+
107
+ ## cycles
108
+
109
+ List dependency cycles. Call `cycles(graph)`:
110
+
111
+ ```bash
112
+ node -e "const q=require('${CLAUDE_PLUGIN_ROOT}/scripts/lib/design-context-query.cjs'); \
113
+ const g=q.load('.design/context-graph.json'); \
114
+ console.log(JSON.stringify(q.cycles(g)));"
115
+ ```
116
+
117
+ Print each cycle as its ordered node ids. If there are none, print `No cycles detected.`
118
+
119
+ ## coverage
120
+
121
+ Report graph coverage. Call `coverage(graph)`:
122
+
123
+ ```bash
124
+ node -e "const q=require('${CLAUDE_PLUGIN_ROOT}/scripts/lib/design-context-query.cjs'); \
125
+ const g=q.load('.design/context-graph.json'); \
126
+ console.log(JSON.stringify(q.coverage(g)));"
127
+ ```
128
+
129
+ Surface the returned ratios (for example typed and tagged coverage and node and edge counts) as a short summary.
130
+
131
+ ## Do Not
132
+
133
+ - Do not edit `.design/context-graph.json` or the fragments under `.design/fragments/`. All writes go through the mapper agents and the synthesizer.
134
+ - Do not invent nodes, edges, or paths. If a query returns nothing, report it plainly.
135
+ - Do not modify `scripts/lib/design-context-query.cjs` or the DesignContext schema.
136
+
137
+ ## CONTEXT COMPLETE
@@ -0,0 +1,24 @@
1
+ ---
2
+ name: gdd-continue
3
+ description: "Alias for {{command_prefix}}resume - restore session context from the most recent checkpoint."
4
+ argument-hint: "[<checkpoint-N>]"
5
+ tools: Read, Write, Bash, Glob
6
+ disable-model-invocation: true
7
+ ---
8
+
9
+ @reference/retrieval-contract.md
10
+
11
+ # {{command_prefix}}continue
12
+
13
+ Alias for `{{command_prefix}}resume`. Delegates immediately to the resume skill with the same argument.
14
+
15
+ This alias exists for discoverability - users familiar with `git continue` or similar conventions find `{{command_prefix}}continue` more intuitive than `{{command_prefix}}resume` after a pause.
16
+
17
+ ## Steps
18
+
19
+ 1. Forward the argument (if any) to the `{{command_prefix}}resume` skill logic.
20
+ 2. Execute all `{{command_prefix}}resume` steps exactly as documented in `skills/resume/SKILL.md`.
21
+
22
+ The two commands are functionally identical. `{{command_prefix}}resume` is the canonical form; `{{command_prefix}}continue` is the convenience alias.
23
+
24
+ ## CONTINUE COMPLETE
@@ -0,0 +1,76 @@
1
+ ---
2
+ name: gdd-darkmode
3
+ description: "Audit a project's dark mode implementation - detects architecture (CSS custom props, Tailwind `dark:` prefix, or JS class toggle), runs architecture-specific contrast / token-override / anti-pattern / meta-property checks, and writes a prioritized fix list to `.design/DARKMODE-AUDIT.md`. Use when the user wants to verify dark mode quality without re-running the full design pipeline. Read-only - no score writeback to `DESIGN.md`. Activates for requests involving auditing dark mode, checking dark-theme contrast, or dark-mode anti-patterns."
4
+ argument-hint: ""
5
+ user-invocable: true
6
+ ---
7
+
8
+ # gdd-darkmode - Dark Mode Audit
9
+
10
+ Standalone dark mode audit. Detects the project's dark mode architecture, runs architecture-specific checks across contrast, token completeness, anti-patterns, and meta properties, then writes a prioritized fix list to `.design/DARKMODE-AUDIT.md`.
11
+
12
+ For the full step-by-step methodology (architecture-detection greps, WCAG contrast formula, anti-pattern grep snippets, meta-property checks, screenshot capture, and `DARKMODE-AUDIT.md` template), see `./darkmode-audit-procedure.md`. For the perceptual-contrast layer (APCA / WCAG 3 draft) sitting on top of WCAG 2.1 ratios, see `../../reference/contrast-advanced.md`. For OKLCH-based dark token-pair generation, see `../../reference/color-theory.md` §OKLCH. For the cross-skill output discipline + connection-probe pattern, see `../../reference/shared-preamble.md#output-contract-reminders` and `../../reference/shared-preamble.md#connection-handshake-summary`.
13
+
14
+ ---
15
+
16
+ ## Scope
17
+
18
+ This command is a **standalone audit** - not a pipeline stage:
19
+
20
+ - Does NOT update `DESIGN.md` scores (V2-05 deferred - two-sources-of-truth risk).
21
+ - Does NOT invoke `design-auditor` (Pitfall 4 - darkmode runs its own inline audit, separate from the `DESIGN-AUDIT.md` pipeline).
22
+ - Does NOT write to `.design/STATE.md`, `DESIGN-CONTEXT.md`, `DESIGN-PLAN.md`, `DESIGN-SUMMARY.md`, or `DESIGN-VERIFICATION.md`.
23
+ - Writes exactly ONE artifact: `.design/DARKMODE-AUDIT.md`.
24
+ - Does NOT execute fixes - audit-only per V2-07 deferral (fixes belong in the design pipeline's color task).
25
+
26
+ Output artifact prefix `DARKMODE-AUDIT` is distinct from the pipeline namespace (`DESIGN-*.md`). No naming conflict.
27
+
28
+ ---
29
+
30
+ ## Pre-Flight
31
+
32
+ Confirm source root exists. Try in order: `src/` (preferred), `app/` (Next.js App Router), `lib/` (libraries), `pages/` (Next.js Pages Router). Set `SRC_ROOT` to the first that exists. If none exist, abort: `"No source directory detected. Run /get-design-done scan first."`
33
+
34
+ Confirm `.design/` exists (create if absent: `mkdir -p .design/`).
35
+
36
+ Probe `preview` connection per `../../reference/shared-preamble.md#connection-handshake-summary` (ToolSearch → `mcp__Claude_Preview__preview_list` → STATE.md write). Result drives Step 5B (visual dark mode rendering).
37
+
38
+ ---
39
+
40
+ ## Workflow
41
+
42
+ 1. **Architecture Detection (DARK-02)** - run three greps (CSS custom props / Tailwind `dark:` / JS class toggle), classify primary architecture or `Hybrid` or `None`. If `None`, abort. Detail: `./darkmode-audit-procedure.md#step-1-architecture-detection-dark-02`.
43
+ 2. **Contrast Audit (DARK-03)** - extract dark-context token pairs for the detected architecture, compute WCAG 2.1 ratios, flag failures at 4.5:1 (body) / 3:1 (large text + UI boundaries). Cross-check with APCA from `../../reference/contrast-advanced.md` for thin / large / colored text. Detail: `./darkmode-audit-procedure.md#step-2-contrast-audit-dark-03`.
44
+ 3. **Token Override Completeness (DARK-04)** - every light-mode color token must have a dark-mode override. Flag missing overrides → P1. Detail: `./darkmode-audit-procedure.md#step-3-token-override-completeness-dark-04`.
45
+ 4. **Dark-Specific Anti-Patterns (DARK-05)** - Images/SVGs without dark variant (P2), pure-black backgrounds in dark context = BAN-05 (P1), missing `@media (forced-colors)` (P2). Detail: `./darkmode-audit-procedure.md#step-4-dark-specific-anti-patterns-dark-05`.
46
+ 5. **Meta Property Check (DARK-06)** - `color-scheme` property + `prefers-color-scheme` query. Each absent → P2. Detail: `./darkmode-audit-procedure.md#step-5-meta-property-check-dark-06`.
47
+ 6. **Visual Rendering (preview: available only)** - capture light/dark screenshot pair to `.design/screenshots/darkmode/{light,dark}.png`. Detail: `./darkmode-audit-procedure.md#step-5b-dark-mode-rendering-screenshots-when-preview-available`.
48
+ 7. **Write `.design/DARKMODE-AUDIT.md`** - group flagged issues by priority (P0 → P1 → P2 → P3). Full template at `./darkmode-audit-procedure.md#step-6-darkmode-auditmd-template`.
49
+
50
+ ---
51
+
52
+ ## Constraints
53
+
54
+ This command MUST NOT (per `../../reference/shared-preamble.md#output-contract-reminders`):
55
+
56
+ - Write to `DESIGN.md`, `DESIGN-SUMMARY.md`, `DESIGN-VERIFICATION.md`, `DESIGN-CONTEXT.md`, or `.design/STATE.md`.
57
+ - Invoke `design-auditor` (Pitfall 4 - this is a separate audit with its own inline checks).
58
+ - Execute any fixes - audit-only (V2-07 deferred).
59
+ - Write scores back to `DESIGN.md` (V2-05 deferred - two-sources-of-truth risk).
60
+ - Add rows to `DESIGN.md` or append to pipeline-owned artifacts.
61
+
62
+ MUST write exactly one output file: `.design/DARKMODE-AUDIT.md`.
63
+
64
+ ---
65
+
66
+ ## Completion
67
+
68
+ After writing the audit, print:
69
+
70
+ ```
71
+ Dark mode audit complete. Architecture: <X>. Fixes: P0=<N>, P1=<M>, P2=<K>, P3=<J>. See .design/DARKMODE-AUDIT.md.
72
+ ```
73
+
74
+ Do not summarize individual issues in the completion message - the file contains the full detail.
75
+
76
+ ## DARKMODE AUDIT COMPLETE
@@ -0,0 +1,258 @@
1
+ ---
2
+ name: darkmode-audit-procedure
3
+ type: meta-rules
4
+ version: 1.0.0
5
+ phase: 28.5
6
+ tags: [darkmode, dark-mode, contrast, audit, procedure, extracted]
7
+ last_updated: 2026-05-18
8
+ ---
9
+
10
+ Source: extracted from `skills/darkmode/SKILL.md` (Phase 28.5 rework - D-10 extract-then-link).
11
+ The skill's essential routing + decision tree stays in `../skills/darkmode/SKILL.md`; this
12
+ file holds the architecture-detection greps, contrast computation, anti-pattern grep
13
+ snippets, and the `DARKMODE-AUDIT.md` report template.
14
+
15
+ # Dark Mode Audit Procedure
16
+
17
+ Detailed procedure for the `gdd-darkmode` standalone audit - companion to
18
+ `../skills/darkmode/SKILL.md`. Read this file when executing a specific audit step
19
+ (architecture detection, contrast computation, anti-pattern grep, report layout). The
20
+ SKILL.md keeps the essential pre-flight + step routing; this file holds the deep
21
+ methodology.
22
+
23
+ For the perceptual layer (APCA / WCAG 3 draft) sitting on top of the WCAG 2.1 ratios used
24
+ in Step 2, see `./contrast-advanced.md`. For modern OKLCH-based dark token-pair generation,
25
+ see `./color-theory.md` §OKLCH. For the cross-skill output discipline + connection-probe
26
+ pattern, see `./shared-preamble.md#output-contract-reminders` and
27
+ `./shared-preamble.md#connection-handshake-summary`.
28
+
29
+ ---
30
+
31
+ ## Step 1: Architecture Detection (DARK-02)
32
+
33
+ Run all three architecture greps against `$SRC_ROOT`. Use `2>/dev/null` on each to suppress missing-directory errors.
34
+
35
+ ```bash
36
+ # Architecture 1: CSS custom properties with dark media query
37
+ arch1_count=$(grep -rEn "prefers-color-scheme.*dark|\.dark[[:space:]]*\{" "$SRC_ROOT" \
38
+ --include="*.css" --include="*.scss" 2>/dev/null | wc -l)
39
+
40
+ # Architecture 2: Tailwind dark: prefix
41
+ arch2_count=$(grep -rEn "dark:[a-z]" "$SRC_ROOT" \
42
+ --include="*.tsx" --include="*.jsx" --include="*.html" 2>/dev/null | wc -l)
43
+
44
+ # Architecture 3: JS class toggle on <html> / <body>
45
+ arch3_count=$(grep -rEn "classList.*dark|setAttribute.*dark|document\.documentElement" "$SRC_ROOT" \
46
+ --include="*.ts" --include="*.tsx" --include="*.js" 2>/dev/null | wc -l)
47
+ ```
48
+
49
+ **Classification rules:**
50
+
51
+ | Condition | Classification |
52
+ |-----------|---------------|
53
+ | All three counts < 3 | No dark mode - abort: "No dark mode implementation detected - nothing to audit." |
54
+ | Exactly one count ≥ 3 | Primary architecture = that one |
55
+ | Two or more counts ≥ 5 | Hybrid (list all detected architectures) |
56
+ | One count ≥ 3, others < 5 | Primary = highest count |
57
+
58
+ Record `ARCH_DETECTED` as one of: `Architecture 1 (CSS custom props)`, `Architecture 2 (Tailwind dark:)`, `Architecture 3 (JS class toggle)`, or `Hybrid`.
59
+
60
+ ---
61
+
62
+ ## Step 2: Contrast Audit (DARK-03)
63
+
64
+ For the detected architecture, enumerate color token + background token pairs used in dark context, then compute WCAG contrast ratios.
65
+
66
+ **Token extraction by architecture:**
67
+
68
+ **Architecture 1 (CSS custom props):**
69
+ ```bash
70
+ grep -rEn "\.dark[[:space:]]*\{|prefers-color-scheme.*dark" "$SRC_ROOT" \
71
+ --include="*.css" --include="*.scss" -A 30 2>/dev/null \
72
+ | grep -E "^\s*--[a-z].*:\s*#[0-9a-fA-F]{3,8}|^\s*--[a-z].*:\s*rgb"
73
+ ```
74
+
75
+ **Architecture 2 (Tailwind dark:):**
76
+ ```bash
77
+ grep -rEhon "dark:(bg|text)-[a-z0-9-]+" "$SRC_ROOT" \
78
+ --include="*.tsx" --include="*.jsx" --include="*.html" 2>/dev/null | sort -u
79
+ ```
80
+
81
+ **Architecture 3 (JS class toggle):**
82
+ ```bash
83
+ grep -rEn "\.dark[[:space:]]*\{" "$SRC_ROOT" \
84
+ --include="*.css" --include="*.scss" -A 30 2>/dev/null \
85
+ | grep -E "color|background"
86
+ ```
87
+
88
+ **WCAG contrast computation:**
89
+
90
+ Use the linearized-sRGB formula from `agents/design-executor.md` Type: accessibility (pre-calibrated - do not re-derive):
91
+
92
+ 1. Convert each hex channel to linear light: `c_lin = (c/255 ≤ 0.04045) ? c/255/12.92 : ((c/255 + 0.055)/1.055)^2.4`
93
+ 2. Relative luminance: `L = 0.2126 * R_lin + 0.7152 * G_lin + 0.0722 * B_lin`
94
+ 3. Contrast ratio: `(L_lighter + 0.05) / (L_darker + 0.05)`
95
+
96
+ **Thresholds:**
97
+
98
+ | Text type | Min ratio | Fail severity |
99
+ |-----------|-----------|---------------|
100
+ | Body text (< 18pt or < 14pt bold) | 4.5:1 | P0 (critical) |
101
+ | Large text (≥ 18pt or ≥ 14pt bold) | 3:1 | P1 (major) |
102
+ | UI component boundaries | 3:1 | P1 (major) |
103
+
104
+ Flag every pair that fails its threshold. Include token names, hex values, computed ratio, and required ratio in the fix description.
105
+
106
+ For pairs that pass WCAG 2.1 but feel wrong perceptually (thin mid-gray text, large saturated text, saturated-on-saturated), cross-check with the APCA Lc thresholds in `./contrast-advanced.md` and annotate `[APCA-mismatch]` in the fix description.
107
+
108
+ ---
109
+
110
+ ## Step 3: Token Override Completeness (DARK-04)
111
+
112
+ Check that every light-mode color token has a corresponding dark-mode override.
113
+
114
+ **Enumerate light-mode tokens:**
115
+ ```bash
116
+ grep -rEhon "var\(--color-[a-z0-9-]+\)" "$SRC_ROOT" \
117
+ --include="*.css" --include="*.scss" --include="*.tsx" --include="*.jsx" 2>/dev/null \
118
+ | grep -oE "\-\-color-[a-z0-9-]+" | sort -u
119
+
120
+ grep -rEhon "(bg|text|border|ring)-[a-z]+-[0-9]+" "$SRC_ROOT" \
121
+ --include="*.tsx" --include="*.jsx" 2>/dev/null | sort -u
122
+ ```
123
+
124
+ **Check dark overrides (architecture-specific):**
125
+ - Arch 1: Token appears in `.dark { --color-* }` block or `@media (prefers-color-scheme: dark) { --color-* }`
126
+ - Arch 2: A `dark:` prefixed variant of the Tailwind class exists in the same file or a shared layout
127
+ - Arch 3: Token appears in the dark CSS block activated by JS class toggle
128
+
129
+ **Flag:** Any light-mode color token with no dark override → P1 (major). For OKLCH-based pair generation guidance, see `./color-theory.md` §OKLCH.
130
+
131
+ ---
132
+
133
+ ## Step 4: Dark-Specific Anti-Patterns (DARK-05)
134
+
135
+ **Anti-pattern A: Images and SVGs without dark variant**
136
+
137
+ ```bash
138
+ grep -rEn "<img[^>]+src=|<svg" "$SRC_ROOT" \
139
+ --include="*.tsx" --include="*.jsx" --include="*.html" --include="*.vue" 2>/dev/null \
140
+ | grep -v "dark\."
141
+ ```
142
+
143
+ For each image/SVG found, check whether any of the following exist:
144
+ - A sibling file with pattern `[name]-dark.{png,svg,webp}`
145
+ - A `dark:hidden` / `dark:block` swap class pairing in the same component
146
+ - A `<picture>` element with a `prefers-color-scheme: dark` source
147
+
148
+ Flag images/SVGs with none of the above → P2 (minor).
149
+
150
+ **Anti-pattern B: Pure-black backgrounds (BAN-05)**
151
+
152
+ ```bash
153
+ grep -rEn "#000000|#000\b|rgb\([[:space:]]*0[[:space:]]*,[[:space:]]*0[[:space:]]*,[[:space:]]*0[[:space:]]*\)|background[^:]*:[[:space:]]*black" \
154
+ "$SRC_ROOT" --include="*.css" --include="*.scss" 2>/dev/null
155
+ ```
156
+
157
+ Any match within a `.dark {}` block or `@media (prefers-color-scheme: dark)` context → P1 (major). Pure black (`#000000`) in dark mode causes visual harshness and fails accessibility in high-contrast conditions. Use near-black (`#0a0a0a` – `#1a1a1a`) instead.
158
+
159
+ **Anti-pattern C: Missing forced-colors media query**
160
+
161
+ ```bash
162
+ forced_count=$(grep -rEn "@media.*forced-colors" "$SRC_ROOT" \
163
+ --include="*.css" --include="*.scss" 2>/dev/null | wc -l)
164
+ ```
165
+
166
+ If `forced_count` equals 0 → P2 (minor). The `forced-colors` media query ensures the design respects Windows High Contrast mode and similar OS accessibility overrides.
167
+
168
+ ---
169
+
170
+ ## Step 5: Meta Property Check (DARK-06)
171
+
172
+ **color-scheme property:**
173
+ ```bash
174
+ cs_count=$(grep -rEn "color-scheme" "$SRC_ROOT" public/ \
175
+ --include="*.html" --include="*.tsx" --include="*.css" 2>/dev/null | wc -l)
176
+ ```
177
+ If `cs_count` equals 0 → P2 (minor).
178
+
179
+ **prefers-color-scheme media query:**
180
+ ```bash
181
+ pcs_count=$(grep -rEn "prefers-color-scheme" "$SRC_ROOT" public/ \
182
+ --include="*.html" --include="*.tsx" --include="*.css" 2>/dev/null | wc -l)
183
+ ```
184
+ If `pcs_count` equals 0 → P2 (minor). Absence means the site ignores the OS-level dark mode preference.
185
+
186
+ ---
187
+
188
+ ## Step 5B: Dark Mode Rendering Screenshots (when preview: available)
189
+
190
+ Check `preview` status from `.design/STATE.md <connections>` (per `./shared-preamble.md#connection-handshake-summary`).
191
+
192
+ **If `preview: available`:**
193
+
194
+ 1. `preview_navigate` to the primary route (e.g., `http://localhost:3000/`).
195
+ 2. Capture light-mode: `preview_screenshot` → `.design/screenshots/darkmode/light.png`.
196
+ 3. Inject dark mode using the project's toggle mechanism (check `DESIGN-CONTEXT.md` D-XX decisions):
197
+ - Tailwind dark: `preview_eval("document.documentElement.classList.add('dark')")`
198
+ - data-theme: `preview_eval("document.documentElement.setAttribute('data-theme','dark')")`
199
+ - Custom class: `preview_eval("document.documentElement.classList.add('theme-dark')")`
200
+ - If mechanism is unknown: attempt Tailwind default first; note in `DARKMODE-AUDIT.md` which method was used.
201
+ 4. `preview_screenshot` → `.design/screenshots/darkmode/dark.png`.
202
+ 5. Record both paths (NOT base64) for embedding in `## Dark Mode Rendering` section.
203
+
204
+ **If `preview: unavailable` or `preview: not_configured`:** omit `## Dark Mode Rendering` section entirely. Emit `Visual dark mode check skipped — preview not configured.` in Notes.
205
+
206
+ ---
207
+
208
+ ## Step 6: DARKMODE-AUDIT.md Template
209
+
210
+ Output path: `.design/DARKMODE-AUDIT.md`.
211
+
212
+ ```markdown
213
+ # Dark Mode Audit
214
+
215
+ **Generated:** <ISO date>
216
+ **Architecture detected:** <Architecture 1 (CSS custom props) | Architecture 2 (Tailwind dark:) | Architecture 3 (JS class toggle) | Hybrid | None>
217
+ **Source scanned:** <SRC_ROOT>
218
+
219
+ ## Summary
220
+
221
+ | Category | Status | Issues |
222
+ |----------|--------|--------|
223
+ | Contrast (DARK-03) | <pass / fail> | <count> |
224
+ | Token Overrides (DARK-04) | <pass / fail> | <count> |
225
+ | Anti-Patterns (DARK-05) | <pass / fail> | <count> |
226
+ | Meta Properties (DARK-06) | <pass / fail> | <count> |
227
+
228
+ ## P0 Fixes (Critical — contrast failure on body text)
229
+ - [CONTRAST] <token-pair>: ratio <X:1> — required 4.5:1. File: <path>
230
+
231
+ ## P1 Fixes (Major — large-text contrast / missing dark overrides / pure-black)
232
+ - [CONTRAST-LARGE] <token-pair>: ratio <X:1> — required 3:1. File: <path>
233
+ - [TOKEN-OVERRIDE] Missing dark override for <--token-name>. Light value: <hex>. File: <path>
234
+ - [BAN-05] Pure-black background detected in dark context. File: <path>:line
235
+
236
+ ## P2 Fixes (Minor — missing SVG variants / forced-colors / meta props)
237
+ - [SVG-DARK] <image.svg> has no dark variant. File: <path>
238
+ - [FORCED-COLORS] No @media (forced-colors) block detected in any CSS file.
239
+ - [COLOR-SCHEME] No color-scheme property or meta tag detected.
240
+ - [PREFERS-COLOR-SCHEME] No prefers-color-scheme query detected.
241
+
242
+ ## P3 Fixes (Cosmetic)
243
+ - <cosmetic issues, if any>
244
+
245
+ ## Dark Mode Rendering
246
+ <Either side-by-side screenshot references, or "Visual dark mode check skipped — preview not configured.">
247
+
248
+ ## Notes
249
+ This audit is read-only. It does NOT write scores back to DESIGN.md.
250
+ To apply fixes, run the design pipeline and include dark mode decisions in DESIGN-CONTEXT.md.
251
+ Score writeback (V2-05) is deferred.
252
+ ```
253
+
254
+ If a priority bucket has no issues, omit that section or write "None."
255
+
256
+ ---
257
+
258
+ *Imported by: `../skills/darkmode/SKILL.md`. Maintained as part of Phase 28.5 (Bucket 2 rework - D-10).*
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: gdd-debug
3
+ description: "Symptom-driven design debugger with persistent state. Phase 1 builds a feedback loop; Phase 2 hypothesizes. Writes findings to .design/DEBUG.md. Use when a symptom needs systematic, one-variable-at-a-time tracking."
4
+ argument-hint: "[<symptom description>]"
5
+ tools: Read, Write, Grep, Glob, AskUserQuestion, Task
6
+ ---
7
+
8
+ # {{command_prefix}}debug
9
+
10
+ Systematic, checkpoint-driven design debugger. Loads framing from `./../reference/debugger-philosophy.md` (five principles) and the feedback-loop construction catalog from `./debug-feedback-loops.md` (10 priority-ordered loop paths). Phase 1 builds the loop; Phase 2 generates hypotheses. Writes every step to `.design/DEBUG.md` so killed sessions can resume.
11
+
12
+ ## Steps
13
+
14
+ 1. **Load philosophy + feedback-loop catalog**: Read `reference/debugger-philosophy.md` (five principles) and `./debug-feedback-loops.md` (10 construction paths; iterate-on-loop discipline). Keep both in mind for the entire session.
15
+ 2. **Symptom**: If no symptom argument was passed, ask (AskUserQuestion): "What design symptom are you investigating? (observable only - 'cards look crowded', not 'padding is wrong')"
16
+ 3. **Resume check**: Read `.design/DEBUG.md` if it exists. If there is an open session with no `### Fix Proposal` block, ask: "Resume existing session '<symptom>' or start a new one?"
17
+ 4. **Ground truth load**: Read `.design/DESIGN-PLAN.md` (goals), `.design/STATE.md` `<decisions>` block (D-XX items), and any source files pointed at by the symptom.
18
+ 5. **Phase 1 - Build a feedback loop**: Before ANY hypothesizing, build a deterministic, fast, agent-runnable pass/fail signal that reproduces the symptom. See `./debug-feedback-loops.md` for the 10 construction paths in priority order (failing test > curl > CLI fixture > headless browser > trace replay > throwaway harness > fuzz > bisect > differential > HITL bash). Iterate on the loop itself (cache setup, narrow scope, pin time, seed RNG, isolate filesystem, freeze network) before iterating on the bug. For non-deterministic bugs: raise reproduction rate to at least 30%, not clean repro. **Do not proceed to Phase 2 (hypothesis generation) until you have a loop you believe in.**
19
+ 6. **Optional rendered-output check**: Use ToolSearch to see if Playwright/Preview MCP tools are available. If yes, capture rendered state. If no, fall back to code-only analysis.
20
+ 7. **Phase 2 - Investigation loop** (one hypothesis at a time) - for each step:
21
+ - Form one hypothesis (one variable).
22
+ - Investigate (read files, grep, measure). Re-run the Phase 1 feedback loop to confirm the hypothesis pinpoints the symptom.
23
+ - Append to `.design/DEBUG.md`:
24
+
25
+ ```markdown
26
+ ## <symptom> — <date>
27
+ ### Hypothesis <N>
28
+ ### Investigation
29
+ ### Finding
30
+ ```
31
+
32
+ - Ask (AskUserQuestion): "Continue investigating? (yes / found it / dead end)"
33
+ 8. **When found**: Write `### Fix Proposal` block with a concrete patch description. Re-run the Phase 1 loop to confirm the fix flips it from fail to pass. Ask: "Create a todo with `{{command_prefix}}todo add`, or execute the fix now?"
34
+
35
+ ## Do Not
36
+
37
+ - Do not change multiple variables at once.
38
+ - Do not modify global tokens to fix a single component without explicit user approval.
39
+ - Do not close the DEBUG.md session without a finding (mark as "dead end" if abandoned).
40
+
41
+ ## DEBUG COMPLETE
@@ -0,0 +1,119 @@
1
+ ---
2
+ name: debug-feedback-loops
3
+ type: heuristic
4
+ version: 1.0.0
5
+ phase: 28.5
6
+ tags: [debug, feedback-loop, deterministic-signal, iterate-on-loop, mit-port, mattpocock]
7
+ last_updated: 2026-05-18
8
+ ---
9
+
10
+ Source: mattpocock/skills (MIT) - engineering/diagnose Phase 1 - adapted with permission. See `../NOTICE` for the full attribution block.
11
+
12
+ # Debug Feedback Loops
13
+
14
+ Build a feedback loop before any hypothesizing. A feedback loop is a deterministic, fast, agent-runnable pass/fail signal that tells you whether the bug is reproduced right now, every time, in well under a minute. Without it, debugging degenerates to speculation.
15
+
16
+ **Do not proceed to Phase 2 (hypothesis generation) until you have a loop you believe in.**
17
+
18
+ ## The 10 construction paths
19
+
20
+ Listed in priority order - try the cheaper, faster paths first. Each entry: when to reach for it, the shape of the loop, and the verification snippet.
21
+
22
+ ### 1. Failing test
23
+
24
+ The strongest signal. Write the failing test in the project's native test framework (pytest, jest, vitest, go test, cargo test, junit, rspec). Assert the buggy behavior; run with watch mode if available. When the test goes green, the bug is fixed. Best case: reproduces in under 2 seconds, runnable by a fresh agent with one command.
25
+
26
+ When to reach: the project already has a test runner the agent can invoke; the bug is in a unit/integration-testable code path; the symptom is expressible as a deterministic assertion.
27
+
28
+ ### 2. `curl` against a running endpoint
29
+
30
+ For HTTP endpoints, a `curl` against the staging or local server with assertion on body/status. Pipe to `jq` for structured assertions. Cheap, reliable, framework-free. Wrap in a 3-line bash script so the loop is one command.
31
+
32
+ When to reach: the bug is in an HTTP endpoint; the server is already runnable locally; the symptom shows up in response body/status/headers.
33
+
34
+ ### 3. CLI fixture
35
+
36
+ For CLI tools, a small shell script that invokes the binary with fixture inputs and `grep`s for the symptom in stdout/stderr. Bash one-liner is enough; no test framework. Capture exit code, stdout, and stderr separately.
37
+
38
+ When to reach: the bug is in a CLI tool; the symptom shows up in stdout/stderr/exit-code; the failure mode is reproducible from a fixed input.
39
+
40
+ ### 4. Headless browser
41
+
42
+ For UI bugs, a Playwright or Puppeteer script that opens the page, performs the trigger action, and screenshots the symptom region. Compare against a known-good fixture or assert on a DOM selector's text/attribute. Use a deterministic seed for any randomness (animations, IDs, dates).
43
+
44
+ When to reach: the bug is visible only in a rendered browser context; DOM-level inspection isn't enough; the symptom involves layout, paint, or interaction timing.
45
+
46
+ ### 5. Trace replay
47
+
48
+ For bugs reproducible from a captured execution trace, replay the trace deterministically. `rr` on Linux for native binaries, record-and-replay plugins for some browsers, Chrome DevTools recording for web, or a captured production trace for distributed systems. Replays are bit-for-bit reproducible - the gold standard for non-deterministic bugs that have been captured once.
49
+
50
+ When to reach: the bug is hard to reproduce live but you have a captured trace; the trace runtime is available; bit-identical replay is achievable.
51
+
52
+ ### 6. Throwaway harness
53
+
54
+ Write a minimal `main()` that calls the buggy function with known inputs and prints the output. ~10 lines. Side-step framework startup costs entirely. Throw away when fixed. Useful when the test framework's setup is too heavy to iterate quickly.
55
+
56
+ When to reach: the bug is in a single function with a clear input/output contract; framework setup dominates iteration time; you'd rather iterate on a 10-line script than wait for the framework to boot.
57
+
58
+ ### 7. Fuzz
59
+
60
+ When the bug surfaces unpredictably, use property-based testing (Hypothesis, fast-check, jqwik) or AFL/libfuzzer for native code. The fuzzer narrows on the failing input across runs. Combine with a "minimize" pass to shrink the failing input to its smallest form.
61
+
62
+ When to reach: the input space is exotic (parsers, serializers, network protocols); the bug isn't tied to a specific input you can name; you suspect a class of inputs but can't enumerate it.
63
+
64
+ ### 8. Bisect
65
+
66
+ When you know "it worked on commit X, fails on commit Y," `git bisect` is the loop. Each iteration runs the test/curl/CLI from a higher path. Reproduces in O(log N) commits. Combine with `git bisect run <script>` to fully automate.
67
+
68
+ When to reach: the bug regressed between two known commits; you have a binary pass/fail script from one of the earlier paths; you don't yet know which commit introduced the regression.
69
+
70
+ ### 9. Differential
71
+
72
+ When you have two systems and one's correct, write a differential harness: feed the same input to both, assert outputs match. Cheap for migration bugs (old → new implementation) and protocol bugs (your client vs reference client). The harness becomes the regression test once the bug is fixed.
73
+
74
+ When to reach: a known-good reference implementation exists; the buggy code is supposed to match the reference; input space is enumerable enough to drive both implementations side by side.
75
+
76
+ ### 10. HITL bash (Human In The Loop)
77
+
78
+ Last resort. A documented sequence of bash commands a human runs that produces a pass/fail signal. Slower (human in the path), but better than no loop. The agent reads stdout/stderr; the human reads the screen and reports. Use only when no automatable signal is available - physical hardware, vendor portals, manual eyeball checks.
79
+
80
+ When to reach: every other path is blocked by an unautomatable surface; the human cost is acceptable for the duration of the investigation; the loop will be retired or upgraded the moment any earlier path becomes possible.
81
+
82
+ ## Iterate on the loop itself
83
+
84
+ The loop is a first-class artifact. Iterate on it before iterating on hypotheses. A 5-minute loop run 20 times costs 100 minutes; a 5-second loop run 20 times costs 100 seconds. Spending 30 minutes tightening the loop pays back inside the same session.
85
+
86
+ - **Cache setup**: hoist expensive setup (DB seed, fixture load, container start) out of the loop body. Run the loop only on the fast inner part. Use `--no-rebuild`, persistent containers, or test-runner watch modes.
87
+ - **Narrow scope**: if the loop runs the full test suite to verify one bug, narrow to just the failing test/group. Fewer side-effects, faster iterations. `pytest -k`, `jest -t`, `vitest --testNamePattern`, `go test -run` are your friends.
88
+ - **Pin time**: when the bug is time-dependent, freeze the clock (`sinon.useFakeTimers`, `jest.useFakeTimers`, `freezegun`, `time-machine`). Removes wallclock as a variable.
89
+ - **Seed RNG**: every random source gets a fixed seed in the loop. `Math.random`, `crypto.randomBytes`, `random.seed(...)`, `rand::SeedableRng`. Determinism over coverage - the loop must be bit-identical given the same code state.
90
+ - **Isolate filesystem**: run in a `tmpdir`; reset between iterations. Avoids "fixed on my machine" via stale state. Bind-mount or copy fixtures into the tmpdir per iteration.
91
+ - **Freeze network**: mock or record/replay all outbound calls (`nock`, `vcr`, `polly.js`, `mitmproxy --replay`). Real-network loops are non-deterministic by definition.
92
+
93
+ The discipline: every iteration of the loop should be bit-identical given the same code state. If two iterations differ without a code change, the loop has a hidden input - find it and pin it before continuing.
94
+
95
+ ## Non-deterministic bugs
96
+
97
+ Some bugs surface only sometimes. The goal is NOT a clean repro - the goal is to raise the reproduction rate to debuggable.
98
+
99
+ - **Measure baseline rate**: run the loop N=20 times. Note pass/fail count. Record the rate so you can tell whether later changes helped.
100
+ - **Raise stressors**: add concurrency, contention, memory pressure, network jitter (use `tc qdisc add dev lo root netem delay 100ms 50ms` on Linux, `Network Link Conditioner` on macOS). Re-measure.
101
+ - **Target the suspect axis**: if you suspect a race, add a deterministic sleep at the suspect point and measure. If reproduction jumps to 100% with sleep, the race is in that region. If it stays at baseline, the race is elsewhere.
102
+ - **A 30% reproduction rate is debuggable.** A 5% rate isn't - keep raising stressors until you cross 30%. At 30% you can iterate; at 5% you're guessing whether your fix helped or you got lucky.
103
+
104
+ ## When the loop is good enough
105
+
106
+ The loop is good enough when:
107
+
108
+ - It runs in under a minute (preferably under 10 seconds).
109
+ - It's deterministic (or, for non-determinism, reproduces at least 30% of the time).
110
+ - It's automatable - no human in the inner loop except by explicit choice (Path 10).
111
+ - A fresh agent could pick up the loop and run it without context.
112
+
113
+ Only after the loop is good enough should you proceed to hypothesizing the fix. The hypothesis cycle is governed by `./debugger-philosophy.md` (one variable at a time, do not stop at first plausible cause, the bug is where you didn't look).
114
+
115
+ ## Cross-references
116
+
117
+ - `./debugger-philosophy.md` - companion framing; the hypothesis-cycle discipline that runs in Phase 2 once the loop is in place.
118
+ - `../skills/debug/SKILL.md` - Phase 1 of the debug skill mandates this catalog before any hypothesis generation.
119
+ - `../NOTICE` - full mattpocock/skills MIT attribution.