@ikon85/agent-workflow-kit 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. package/.agents/skills/ask-matt/SKILL.md +139 -0
  2. package/.agents/skills/ask-matt/THIRD-PARTY-NOTICES.md +29 -0
  3. package/.agents/skills/audit-skills/SKILL.md +145 -0
  4. package/.agents/skills/board-to-waves/SKILL.md +135 -0
  5. package/.agents/skills/code-review/SKILL.md +64 -0
  6. package/.agents/skills/codebase-design/DEEPENING.md +37 -0
  7. package/.agents/skills/codebase-design/DESIGN-IT-TWICE.md +44 -0
  8. package/.agents/skills/codebase-design/SKILL.md +114 -0
  9. package/.agents/skills/codebase-design/THIRD-PARTY-NOTICES.md +29 -0
  10. package/.agents/skills/codex-adapter-sync/SKILL.md +151 -0
  11. package/.agents/skills/decision-gate/SKILL.md +67 -0
  12. package/.agents/skills/diagnose/SKILL.md +136 -0
  13. package/.agents/skills/diagnose/THIRD-PARTY-NOTICES.md +29 -0
  14. package/.agents/skills/diagnose/scripts/hitl-loop.template.sh +41 -0
  15. package/.agents/skills/domain-modeling/ADR-FORMAT.md +47 -0
  16. package/.agents/skills/domain-modeling/CONTEXT-FORMAT.md +60 -0
  17. package/.agents/skills/domain-modeling/SKILL.md +76 -0
  18. package/.agents/skills/domain-modeling/THIRD-PARTY-NOTICES.md +29 -0
  19. package/.agents/skills/git-worktree-recover/SKILL.md +176 -0
  20. package/.agents/skills/grill-me/SKILL.md +54 -0
  21. package/.agents/skills/grill-me/THIRD-PARTY-NOTICES.md +29 -0
  22. package/.agents/skills/grill-with-docs/ADR-FORMAT.md +47 -0
  23. package/.agents/skills/grill-with-docs/CONTEXT-FORMAT.md +60 -0
  24. package/.agents/skills/grill-with-docs/SKILL.md +137 -0
  25. package/.agents/skills/grill-with-docs/THIRD-PARTY-NOTICES.md +29 -0
  26. package/.agents/skills/implement/SKILL.md +15 -0
  27. package/.agents/skills/implement/THIRD-PARTY-NOTICES.md +29 -0
  28. package/.agents/skills/improve-codebase-architecture/ADR-FORMAT.md +47 -0
  29. package/.agents/skills/improve-codebase-architecture/CONTEXT-FORMAT.md +60 -0
  30. package/.agents/skills/improve-codebase-architecture/DEEPENING.md +37 -0
  31. package/.agents/skills/improve-codebase-architecture/HTML-REPORT.md +123 -0
  32. package/.agents/skills/improve-codebase-architecture/INTERFACE-DESIGN.md +46 -0
  33. package/.agents/skills/improve-codebase-architecture/LANGUAGE.md +53 -0
  34. package/.agents/skills/improve-codebase-architecture/SKILL.md +88 -0
  35. package/.agents/skills/improve-codebase-architecture/THIRD-PARTY-NOTICES.md +29 -0
  36. package/.agents/skills/kit-release/SKILL.md +56 -0
  37. package/.agents/skills/local-ci/SKILL.md +94 -0
  38. package/.agents/skills/orchestrate-wave/SKILL.md +261 -0
  39. package/.agents/skills/orchestrate-wave/references/builder-contract.md +67 -0
  40. package/.agents/skills/prototype/LOGIC.md +79 -0
  41. package/.agents/skills/prototype/SKILL.md +30 -0
  42. package/.agents/skills/prototype/THIRD-PARTY-NOTICES.md +29 -0
  43. package/.agents/skills/prototype/UI.md +112 -0
  44. package/.agents/skills/research/SKILL.md +12 -0
  45. package/.agents/skills/research/THIRD-PARTY-NOTICES.md +29 -0
  46. package/.agents/skills/resolving-merge-conflicts/SKILL.md +14 -0
  47. package/.agents/skills/resolving-merge-conflicts/THIRD-PARTY-NOTICES.md +29 -0
  48. package/.agents/skills/retro/SKILL.md +209 -0
  49. package/.agents/skills/scale-check/SKILL.md +141 -0
  50. package/.agents/skills/security-audit/SKILL.md +67 -0
  51. package/.agents/skills/setup-workflow/SKILL.md +187 -0
  52. package/.agents/skills/setup-workflow/THIRD-PARTY-NOTICES.md +29 -0
  53. package/.agents/skills/setup-workflow/board-sync.md +111 -0
  54. package/.agents/skills/setup-workflow/code-review.md +26 -0
  55. package/.agents/skills/setup-workflow/domain.md +51 -0
  56. package/.agents/skills/setup-workflow/issue-tracker-github.md +35 -0
  57. package/.agents/skills/setup-workflow/issue-tracker-gitlab.md +34 -0
  58. package/.agents/skills/setup-workflow/issue-tracker-local.md +30 -0
  59. package/.agents/skills/setup-workflow/orchestrate-wave-seed.md +44 -0
  60. package/.agents/skills/setup-workflow/spec-completeness-seed.md +44 -0
  61. package/.agents/skills/setup-workflow/spec-self-critique-seed.md +43 -0
  62. package/.agents/skills/setup-workflow/triage-labels.md +18 -0
  63. package/.agents/skills/setup-workflow/workflow-overview.md +33 -0
  64. package/.agents/skills/spec-self-critique/SKILL.md +152 -0
  65. package/.agents/skills/spec-self-critique/scenarios.md +82 -0
  66. package/.agents/skills/tdd/SKILL.md +120 -0
  67. package/.agents/skills/tdd/THIRD-PARTY-NOTICES.md +29 -0
  68. package/.agents/skills/tdd/deep-modules.md +33 -0
  69. package/.agents/skills/tdd/interface-design.md +31 -0
  70. package/.agents/skills/tdd/mocking.md +59 -0
  71. package/.agents/skills/tdd/refactoring.md +10 -0
  72. package/.agents/skills/tdd/tests.md +61 -0
  73. package/.agents/skills/to-issues/SKILL.md +325 -0
  74. package/.agents/skills/to-issues/THIRD-PARTY-NOTICES.md +29 -0
  75. package/.agents/skills/to-prd/PROGRAM-PRD-FORMAT.md +162 -0
  76. package/.agents/skills/to-prd/SKILL.md +180 -0
  77. package/.agents/skills/to-prd/THIRD-PARTY-NOTICES.md +29 -0
  78. package/.agents/skills/to-waves/SKILL.md +260 -0
  79. package/.agents/skills/to-waves/SLICE-METADATA-FORMAT.md +74 -0
  80. package/.agents/skills/triage/AGENT-BRIEF.md +168 -0
  81. package/.agents/skills/triage/OUT-OF-SCOPE.md +101 -0
  82. package/.agents/skills/triage/SKILL.md +122 -0
  83. package/.agents/skills/triage/THIRD-PARTY-NOTICES.md +29 -0
  84. package/.agents/skills/verify-spike/SKILL.md +39 -0
  85. package/.agents/skills/wayfinder/SKILL.md +127 -0
  86. package/.agents/skills/wayfinder/THIRD-PARTY-NOTICES.md +29 -0
  87. package/.agents/skills/wrapup/SKILL.md +71 -0
  88. package/.agents/skills/wrapup/SOURCES.txt +6 -0
  89. package/.agents/skills/zoom-out/SKILL.md +7 -0
  90. package/.agents/skills/zoom-out/THIRD-PARTY-NOTICES.md +29 -0
  91. package/.claude/hooks/_hook_utils.py +184 -0
  92. package/.claude/hooks/drift-guard.py +176 -0
  93. package/.claude/hooks/skill-drift-hint.py +122 -0
  94. package/.claude/hooks/sync-board-status.py +191 -0
  95. package/.claude/skills/ask-matt/SKILL.md +139 -0
  96. package/.claude/skills/ask-matt/THIRD-PARTY-NOTICES.md +29 -0
  97. package/.claude/skills/audit-skills/SKILL.md +145 -0
  98. package/.claude/skills/board-to-waves/SKILL.md +148 -0
  99. package/.claude/skills/code-review/SKILL.md +64 -0
  100. package/.claude/skills/codebase-design/DEEPENING.md +37 -0
  101. package/.claude/skills/codebase-design/DESIGN-IT-TWICE.md +44 -0
  102. package/.claude/skills/codebase-design/SKILL.md +114 -0
  103. package/.claude/skills/codebase-design/THIRD-PARTY-NOTICES.md +29 -0
  104. package/.claude/skills/codex-build/SKILL.md +126 -0
  105. package/.claude/skills/codex-build/THIRD-PARTY-NOTICES.md +35 -0
  106. package/.claude/skills/codex-review/SKILL.md +145 -0
  107. package/.claude/skills/codex-review/THIRD-PARTY-NOTICES.md +31 -0
  108. package/.claude/skills/decision-gate/SKILL.md +67 -0
  109. package/.claude/skills/diagnose/SKILL.md +136 -0
  110. package/.claude/skills/diagnose/THIRD-PARTY-NOTICES.md +29 -0
  111. package/.claude/skills/diagnose/scripts/hitl-loop.template.sh +41 -0
  112. package/.claude/skills/domain-modeling/ADR-FORMAT.md +47 -0
  113. package/.claude/skills/domain-modeling/CONTEXT-FORMAT.md +60 -0
  114. package/.claude/skills/domain-modeling/SKILL.md +76 -0
  115. package/.claude/skills/domain-modeling/THIRD-PARTY-NOTICES.md +29 -0
  116. package/.claude/skills/git-guardrails-claude-code/SKILL.md +96 -0
  117. package/.claude/skills/git-guardrails-claude-code/THIRD-PARTY-NOTICES.md +29 -0
  118. package/.claude/skills/git-guardrails-claude-code/scripts/block-dangerous-git.sh +28 -0
  119. package/.claude/skills/git-worktree-recover/SKILL.md +182 -0
  120. package/.claude/skills/grill-me/SKILL.md +54 -0
  121. package/.claude/skills/grill-me/THIRD-PARTY-NOTICES.md +29 -0
  122. package/.claude/skills/grill-me-codex/SKILL.md +158 -0
  123. package/.claude/skills/grill-me-codex/THIRD-PARTY-NOTICES.md +32 -0
  124. package/.claude/skills/grill-with-docs/ADR-FORMAT.md +47 -0
  125. package/.claude/skills/grill-with-docs/CONTEXT-FORMAT.md +60 -0
  126. package/.claude/skills/grill-with-docs/SKILL.md +137 -0
  127. package/.claude/skills/grill-with-docs/THIRD-PARTY-NOTICES.md +29 -0
  128. package/.claude/skills/grill-with-docs-codex/ADR-FORMAT.md +47 -0
  129. package/.claude/skills/grill-with-docs-codex/CONTEXT-FORMAT.md +60 -0
  130. package/.claude/skills/grill-with-docs-codex/SKILL.md +233 -0
  131. package/.claude/skills/grill-with-docs-codex/THIRD-PARTY-NOTICES.md +33 -0
  132. package/.claude/skills/implement/SKILL.md +15 -0
  133. package/.claude/skills/implement/THIRD-PARTY-NOTICES.md +29 -0
  134. package/.claude/skills/improve-codebase-architecture/ADR-FORMAT.md +47 -0
  135. package/.claude/skills/improve-codebase-architecture/CONTEXT-FORMAT.md +60 -0
  136. package/.claude/skills/improve-codebase-architecture/DEEPENING.md +37 -0
  137. package/.claude/skills/improve-codebase-architecture/HTML-REPORT.md +123 -0
  138. package/.claude/skills/improve-codebase-architecture/INTERFACE-DESIGN.md +46 -0
  139. package/.claude/skills/improve-codebase-architecture/LANGUAGE.md +53 -0
  140. package/.claude/skills/improve-codebase-architecture/SKILL.md +88 -0
  141. package/.claude/skills/improve-codebase-architecture/THIRD-PARTY-NOTICES.md +29 -0
  142. package/.claude/skills/kit-release/SKILL.md +56 -0
  143. package/.claude/skills/local-ci/SKILL.md +94 -0
  144. package/.claude/skills/orchestrate-wave/SKILL.md +269 -0
  145. package/.claude/skills/orchestrate-wave/references/builder-contract.md +67 -0
  146. package/.claude/skills/prototype/LOGIC.md +79 -0
  147. package/.claude/skills/prototype/SKILL.md +30 -0
  148. package/.claude/skills/prototype/THIRD-PARTY-NOTICES.md +29 -0
  149. package/.claude/skills/prototype/UI.md +112 -0
  150. package/.claude/skills/research/SKILL.md +12 -0
  151. package/.claude/skills/research/THIRD-PARTY-NOTICES.md +29 -0
  152. package/.claude/skills/resolving-merge-conflicts/SKILL.md +14 -0
  153. package/.claude/skills/resolving-merge-conflicts/THIRD-PARTY-NOTICES.md +29 -0
  154. package/.claude/skills/retro/SKILL.md +209 -0
  155. package/.claude/skills/scale-check/SKILL.md +141 -0
  156. package/.claude/skills/security-audit/SKILL.md +67 -0
  157. package/.claude/skills/setup-pre-commit/SKILL.md +104 -0
  158. package/.claude/skills/setup-pre-commit/scripts/pre-commit.template.sh +35 -0
  159. package/.claude/skills/setup-workflow/SKILL.md +187 -0
  160. package/.claude/skills/setup-workflow/THIRD-PARTY-NOTICES.md +29 -0
  161. package/.claude/skills/setup-workflow/board-sync.md +111 -0
  162. package/.claude/skills/setup-workflow/code-review.md +26 -0
  163. package/.claude/skills/setup-workflow/domain.md +51 -0
  164. package/.claude/skills/setup-workflow/issue-tracker-github.md +35 -0
  165. package/.claude/skills/setup-workflow/issue-tracker-gitlab.md +34 -0
  166. package/.claude/skills/setup-workflow/issue-tracker-local.md +30 -0
  167. package/.claude/skills/setup-workflow/orchestrate-wave-seed.md +44 -0
  168. package/.claude/skills/setup-workflow/spec-completeness-seed.md +44 -0
  169. package/.claude/skills/setup-workflow/spec-self-critique-seed.md +43 -0
  170. package/.claude/skills/setup-workflow/triage-labels.md +18 -0
  171. package/.claude/skills/setup-workflow/workflow-overview.md +33 -0
  172. package/.claude/skills/skill-manifest.json +389 -0
  173. package/.claude/skills/spec-self-critique/SKILL.md +152 -0
  174. package/.claude/skills/spec-self-critique/scenarios.md +82 -0
  175. package/.claude/skills/tdd/SKILL.md +120 -0
  176. package/.claude/skills/tdd/THIRD-PARTY-NOTICES.md +29 -0
  177. package/.claude/skills/tdd/deep-modules.md +33 -0
  178. package/.claude/skills/tdd/interface-design.md +31 -0
  179. package/.claude/skills/tdd/mocking.md +59 -0
  180. package/.claude/skills/tdd/refactoring.md +10 -0
  181. package/.claude/skills/tdd/tests.md +61 -0
  182. package/.claude/skills/to-issues/SKILL.md +325 -0
  183. package/.claude/skills/to-issues/THIRD-PARTY-NOTICES.md +29 -0
  184. package/.claude/skills/to-prd/PROGRAM-PRD-FORMAT.md +162 -0
  185. package/.claude/skills/to-prd/SKILL.md +180 -0
  186. package/.claude/skills/to-prd/THIRD-PARTY-NOTICES.md +29 -0
  187. package/.claude/skills/to-waves/SKILL.md +260 -0
  188. package/.claude/skills/to-waves/SLICE-METADATA-FORMAT.md +74 -0
  189. package/.claude/skills/triage/AGENT-BRIEF.md +168 -0
  190. package/.claude/skills/triage/OUT-OF-SCOPE.md +101 -0
  191. package/.claude/skills/triage/SKILL.md +122 -0
  192. package/.claude/skills/triage/THIRD-PARTY-NOTICES.md +29 -0
  193. package/.claude/skills/verify-spike/SKILL.md +39 -0
  194. package/.claude/skills/wayfinder/SKILL.md +127 -0
  195. package/.claude/skills/wayfinder/THIRD-PARTY-NOTICES.md +29 -0
  196. package/.claude/skills/wrapup/SKILL.md +81 -0
  197. package/.claude/skills/wrapup/SOURCES.txt +6 -0
  198. package/.claude/skills/write-a-skill/GLOSSARY.md +201 -0
  199. package/.claude/skills/write-a-skill/SKILL.md +88 -0
  200. package/.claude/skills/write-a-skill/THIRD-PARTY-NOTICES.md +29 -0
  201. package/.claude/skills/zoom-out/SKILL.md +7 -0
  202. package/.claude/skills/zoom-out/THIRD-PARTY-NOTICES.md +29 -0
  203. package/LICENSE +28 -0
  204. package/PROVENANCE.md +39 -0
  205. package/README.md +619 -0
  206. package/agent-workflow-kit.package.json +1939 -0
  207. package/docs/agents/board-sync.md +71 -0
  208. package/docs/agents/code-review.md +14 -0
  209. package/docs/agents/domain.md +7 -0
  210. package/docs/agents/issue-tracker.md +12 -0
  211. package/docs/agents/security-audit-runbook-template.md +205 -0
  212. package/docs/agents/skills/orchestrate-wave.md +13 -0
  213. package/docs/agents/skills/spec-self-critique.md +18 -0
  214. package/docs/agents/triage-labels.md +10 -0
  215. package/docs/agents/wave-anchor-template.md +88 -0
  216. package/docs/conventions/spec-completeness.md +23 -0
  217. package/docs/index.html +56 -0
  218. package/docs/methodology.html +488 -0
  219. package/docs/methodology.svg +93 -0
  220. package/docs/workflow.png +0 -0
  221. package/package.json +40 -0
  222. package/scripts/anchor_table.py +343 -0
  223. package/scripts/board-sync.py +1232 -0
  224. package/scripts/board_config.py +147 -0
  225. package/scripts/board_fields.py +192 -0
  226. package/scripts/build-kit.mjs +116 -0
  227. package/scripts/build-kit.test.mjs +59 -0
  228. package/scripts/check-kit-staleness.mjs +45 -0
  229. package/scripts/check-kit-staleness.test.mjs +19 -0
  230. package/scripts/execute-ready-check.py +516 -0
  231. package/scripts/issue_deps.py +79 -0
  232. package/scripts/kit-release.mjs +100 -0
  233. package/scripts/kit-release.test.mjs +67 -0
  234. package/scripts/lib/audit-refs.mjs +146 -0
  235. package/scripts/lib/scrub.mjs +113 -0
  236. package/scripts/lib/scrub.test.mjs +187 -0
  237. package/scripts/loc_offender_core.py +196 -0
  238. package/scripts/loc_offender_gate.py +182 -0
  239. package/scripts/node_kind.py +68 -0
  240. package/scripts/portability_profile_scan.py +53 -0
  241. package/scripts/pr-body-check.py +263 -0
  242. package/scripts/program_graph.py +125 -0
  243. package/scripts/program_graph_parse.py +275 -0
  244. package/scripts/program_graph_validate.py +256 -0
  245. package/scripts/program_sync.py +160 -0
  246. package/scripts/release-delta-guard.mjs +96 -0
  247. package/scripts/release-delta-guard.test.mjs +53 -0
  248. package/scripts/test_board_sync_create_idempotency.py +104 -0
  249. package/scripts/test_dist_kit_smoke.py +199 -0
  250. package/scripts/test_kit_docs_language_census.py +178 -0
  251. package/scripts/test_skill_code_review_seed.py +89 -0
  252. package/scripts/test_skill_frontmatter_lint.py +226 -0
  253. package/scripts/test_skill_gh_lint.py +124 -0
  254. package/scripts/test_skill_language_census.py +254 -0
  255. package/scripts/test_skill_portability_lint.py +773 -0
  256. package/scripts/test_skill_publish_audit.py +300 -0
  257. package/scripts/test_skill_selfcontainment_lint.py +255 -0
  258. package/scripts/test_skill_setup_workflow_seeds.py +200 -0
  259. package/scripts/test_skill_stale_name_lint.py +126 -0
  260. package/scripts/test_skill_surface_refs.py +300 -0
  261. package/scripts/test_skill_trailing_artifact_lint.py +71 -0
  262. package/scripts/wrapup-land.py +573 -0
  263. package/src/cli.mjs +70 -0
  264. package/src/commands/diff.mjs +6 -0
  265. package/src/commands/init.mjs +59 -0
  266. package/src/commands/uninstall.mjs +43 -0
  267. package/src/commands/update.mjs +95 -0
  268. package/src/lib/atomicWrite.mjs +49 -0
  269. package/src/lib/bundle.mjs +133 -0
  270. package/src/lib/hash.mjs +13 -0
  271. package/src/lib/manifest.mjs +58 -0
  272. package/src/lib/sentinel.mjs +20 -0
  273. package/src/lib/settings.mjs +23 -0
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: local-ci
3
+ description: Run the repo's local CI gate before opening a PR — the stand-in for GitHub required status checks when your plan or repo visibility can't enforce them (a Free-plan private repo has no branch protection). Use before every PR, when a guard/test red is suspected on a branch, or when wiring/repairing the pre-push guard backstop. Triggers — "local ci", "run local ci", "pre-PR check", "why is main red", "did a guard land red".
4
+ ---
5
+
6
+ # Local CI
7
+
8
+ A guard only protects if it runs on a **gate**. When your host can't enforce a
9
+ required status check at merge — **GitHub Free + Private has no branch protection
10
+ and no rulesets** ([GitHub Docs: protected
11
+ branches](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches))
12
+ — the gate has to be **local**. This skill is that gate.
13
+
14
+ > Fault class: *Detection without Enforcement.* A guard that runs only in a
15
+ > manual, opt-in step is not a gate — the drift it catches still merges. Fix the
16
+ > gate class, not the one field that slipped through.
17
+
18
+ The exact commands, guard names, hook wiring and the project's own incident lore
19
+ live in the **project layer** for this skill (its `docs/agents/skills/local-ci.md`,
20
+ seeded as an empty stub by `/setup-workflow` and filled per project). This
21
+ skeleton names the two profiles generically; run the two your project layer names.
22
+
23
+ ## When
24
+
25
+ - **Before opening ANY PR** → run the full local gate. Red → fix it, or defer a
26
+ *single* failure ONLY with an explicit written reason in the PR body (never
27
+ silently — a skipped gate framed as done is a fake quality gate).
28
+ - A guard/test red is suspected on a branch ("why is main red").
29
+ - Wiring or repairing the pre-push backstop / adding a new guard.
30
+
31
+ ## The two profiles
32
+
33
+ Two commands, one fast and one full — your project layer names the exact
34
+ invocations:
35
+
36
+ - **Fast static guards** — no DB, ~seconds. Run automatically at **pre-push** so a
37
+ red drift guard cannot leave the machine.
38
+ - **Full gate** — typecheck + lint + the test suites a CI job would run, ~a minute.
39
+ Too slow for a hook → the **agent's named pre-PR step**, explicit not automatic.
40
+
41
+ ## Enforcement model
42
+
43
+ - **pre-push** runs the fast guards automatically → a red drift guard cannot be
44
+ pushed. Keep any emergency escape hatch explicit and logged — never a silent one.
45
+ - **pre-commit** gates typecheck + lint, and should block a committed focused-test
46
+ marker (`.only` / `fit` / `fdescribe`) so a focused test can't silently gut a
47
+ file's coverage (green-but-empty).
48
+ - The **full gate** is the agent's named pre-PR step: the full suite is too slow
49
+ for a hook, so it is explicit, not automatic. Run it; report the result honestly.
50
+
51
+ ## Contention — stop the dev server before the full gate
52
+
53
+ The full gate runs several test runners at once. A dev server running in parallel
54
+ oversubscribes the cores → **boot-contention false reds**: hook/boot timeouts in
55
+ *unrelated* tests that are green in isolation. Symptom = "Hook timed out" in tests
56
+ that pass on their own.
57
+
58
+ - Stop the dev server before the full gate. Verify a suspicious red as a false red
59
+ by running that one test in isolation — green in isolation = contention, not a
60
+ real red.
61
+ - Kill the dev server by **PID-via-port, not a process-name match**. A name match
62
+ (`vite`) also hits the test runner (`vitest`), and matching your own command line
63
+ kills the running command. Resolve the PID from the listening port instead.
64
+
65
+ ## On a red
66
+
67
+ 1. Read the failing test's message — a good guard prints the exact drift
68
+ (`file:line`, the offending token, the missing allowlist key).
69
+ 2. Fix the source. If a guard legitimately can't be satisfied yet, add its
70
+ **documented allowlist entry with a reason** — never widen a guard silently
71
+ (that re-opens the blind spot the guard exists to close).
72
+ 3. Iterate on the single file, then the full gate for sign-off.
73
+
74
+ ## Adding a new guard
75
+
76
+ Prefer a **glob-discovered** guard config so a new fast static guard joins the
77
+ pre-push set automatically — no hand-maintained list. Name it to match the include
78
+ glob and keep it **DB-free** (pre-push must stay ~seconds); DB-bound tests belong
79
+ to the full gate, not the fast pre-push set.
80
+
81
+ ## Baseline-green first
82
+
83
+ If your success criterion is "gate green" and you do NOT know the base's green
84
+ status — you are **hardening the gate itself**, or building against a `main` that a
85
+ rename/schema cascade is landing on piecemeal — run the relevant gate part ONCE on
86
+ the **unmodified base** before your first edit. It separates pre-existing breakage
87
+ from your work; otherwise foreign reds surface one at a time as you build (an abort
88
+ + scope question each).
89
+
90
+ ## When the host CAN enforce
91
+
92
+ If the repo moves to a plan/visibility with required checks: add a CI workflow
93
+ running the full gate on PR and make it a **required status check** — then the gate
94
+ is machine-enforced at merge, not just local. Until then, local is the gate.
@@ -0,0 +1,269 @@
1
+ ---
2
+ name: orchestrate-wave
3
+ description: >-
4
+ Use when the user hands you a whole WAVE / cluster of pre-planned, file-disjoint
5
+ slices and wants you to ORCHESTRATE building, verifying AND landing it end-to-end —
6
+ often AFK / "ultracode". Triggers: "orchestriere Welle #N" (or any wording that
7
+ delegates wave-landing responsibility to you), "ultracode diese Welle / diesen
8
+ Cluster", or a wave-anchor issue (a cluster/umbrella issue with file-disjoint
9
+ sub-issues whose specs are already locked) handed over to land. NOT for a single
10
+ slice (just `tdd` it), NOT for finding/clustering a wave (that's `board-to-waves`),
11
+ NOT for planning specs (that's `grill-with-docs`/`to-issues`).
12
+ ---
13
+
14
+ # Orchestrate Wave
15
+
16
+ You are the orchestrator. The user gives you a wave anchor (a cluster/umbrella
17
+ issue with file-disjoint sub-issues whose specs/decisions are already locked) and
18
+ says "land it". You decide inline-vs-delegate; you are responsible for it landing
19
+ correctly, AFK. Subagents BUILD; **you** integrate + verify + land.
20
+
21
+ The anchor, its sub-issues and the locked plan doc contain the verbatim contracts
22
+ you must NOT paraphrase.
23
+
24
+ > **Phase 0 probes a project layer.** Concrete tooling — exact test/verify
25
+ > commands, a DB/tunnel setup, a headless login recipe, brand checks, deploy
26
+ > lockstep — is project-specific and lives in a **project layer** this skill reads
27
+ > at runtime, not in this skeleton. The skeleton names the layer's sections
28
+ > (`§Setup`, `§Builder Commands`, `§Builder Hard Rules`, `§Integration Suites`,
29
+ > `§Verify Recipe`, `§Headless Login`, `§Landing`) and falls back to generic
30
+ > instructions when the layer is absent. See **Phase 0**.
31
+
32
+ ## Standing rules (all phases)
33
+
34
+ - **AFK heartbeat.** A wave run may take time but must never look stuck: during any
35
+ long-running gate (dispatch wait, integration suite, full verify, browser/E2E,
36
+ migration) send a short status update at least every ~30 s and on every phase
37
+ change — current gate, last green milestone, next step, visible blocker/risk. A
38
+ still-running tool session is stated as such; never wait silently for the final
39
+ result.
40
+ - **Degrade by subtraction, never by improvisation.** The defined failure paths:
41
+ - **Slice stays red after escalation** (2-strikes rule, see Routing): pull the
42
+ slice — do not merge it (or revert its merge), pull every dependent that
43
+ consumes its artifacts (Phase-1 graph), land the remaining green subset, create
44
+ a tracking issue, leave its anchor row open, report the pull prominently.
45
+ - **Schema wave degraded:** if a pulled slice owns a migration/schema that a
46
+ remaining slice reads, the ONE-lockstep-window premise no longer holds → STOP,
47
+ land nothing schema-dependent, report.
48
+ - **Plan-level error** (integration/verify reveals a wrong LOCKED decision, not a
49
+ slice bug): STOP the wave. No improvised redesign AFK — keep worktrees intact,
50
+ report findings + options.
51
+ - **Routing = one axis: how expensive is a wrong result to catch?** Mechanically
52
+ caught (test/screenshot/lint) → default tier at medium/low effort; plausible-but-
53
+ wrong / subtle logic / architecture → top tier at high effort + main-thread
54
+ re-verify; review/verify verdicts never below high. Concrete tier→model mapping
55
+ lives in your dispatch/model doctrine, if present — no model names here.
56
+ Escalate a repeatedly-failing slice one tier/effort up on the 2-strikes rule (2×
57
+ same problem despite concrete feedback, or structurally wrong approach — NOT the
58
+ first red test). The same axis sets how hard you re-verify. Borderline → default
59
+ tier + re-verify beats blanket top tier.
60
+
61
+ ## Phase 0 — Setup
62
+
63
+ 1. **Read everything**: the anchor body, every sub-issue body (each has a Handoff
64
+ block: scope, blast-radius, live-verify, PR line), and the locked plan /
65
+ plan-review doc in the planning worktree (file-exact).
66
+ 2. **Probe the project layer.** Read the project layer doc for this skill (the
67
+ consumer's `docs/agents/skills/orchestrate-wave.md` or the path your project
68
+ uses). If its `§`-sections carry **filled** content, follow the project recipe
69
+ wherever a phase below points at a `§`-section. If the file is only a
70
+ `setup-workflow` sentinel stub (empty headings, no real content) or absent,
71
+ treat the layer as **ABSENT** → use the generic fallback in each phase and warn
72
+ **once** that `/setup-workflow` plus project maintenance fill the layer (the
73
+ commands/tunnel/login can't be guessed). Never treat an empty heading as a
74
+ verify recipe.
75
+ 3. **Wave worktree**: reuse the planning worktree (never re-create; the handoff
76
+ points there). Bring its branch to current `main`:
77
+ `git -C <wave> merge --ff-only origin/main` (if your repo guards destructive
78
+ git, ff-merge is the safe path — not `reset --hard`). Install dependencies with
79
+ your package manager after (the lockfile may have moved). A gitignored plan doc
80
+ survives the merge.
81
+ 4. **Run project setup steps (`§Setup`)** the later verify needs — e.g. a DB
82
+ tunnel or service the live-verify depends on. Absent layer → start whatever your
83
+ live-verify environment requires before Phase 4.
84
+
85
+ **Done when:** anchor + every sub-issue + plan read · project layer probed
86
+ (filled → project recipe; stub/absent → generic + one-time warning) · wave branch
87
+ ff'd to `origin/main` + deps installed · project setup steps running.
88
+
89
+ ## Phase 1 — Disjointness recon (the load-bearing step)
90
+
91
+ Zero merge conflicts later depends entirely on getting this right.
92
+
93
+ - Delegate to a read-only investigator agent: for EACH slice the exact file path of
94
+ every named component + resolve ambiguous targets, then a **FILE → SLICES** table
95
+ listing every file that appears in ≥2 slices.
96
+ - Build the **overlap graph**. Identify the **conflict hub** (the slice whose new
97
+ artifacts other slices reuse). **Build the hub first**, merge it, THEN the
98
+ dependents stop conflicting.
99
+ - Cut into **waves of fully file-disjoint slices**. Edited-by-≥2 = serialize across
100
+ waves; only-shared-via-import = safe. A new primitive edited by one slice but
101
+ *consumed* by others is NOT a conflict.
102
+ - **Native blocking edges are the frontier authority.** Read the anchor's
103
+ buildable frontier from the tracker's native issue dependencies:
104
+ `python3 scripts/board-sync.py frontier <anchor#>` → `FREI` / `BLOCKED by #…` /
105
+ `done` per sub-issue. A body `## Blocked by` section is only the machine-written
106
+ MIRROR of those edges (on conflict the API wins) — never derive build order from
107
+ body text or table order alone. The frontier must AGREE with your Phase-1
108
+ dependency order; a contradiction is a plan finding to reconcile before dispatch,
109
+ not a detail.
110
+ - **Reconcile contradictory sub-issue ACs against the plan BEFORE dispatch — the
111
+ plan is authority.** `to-issues` cuts slices independently, so a shared
112
+ append-only file (a query-key registry, a barrel, a shared types module) is often
113
+ claimed by *every* slice, with duplicate/clashing adds. **The hub slice OWNS the
114
+ shared-mutable file: it pre-adds ALL the wave's keys/types/helpers; dependents
115
+ CONSUME only and never touch it.** Embed verbatim in each dependent's contract:
116
+ "X already exists in `<file>` — do NOT add it, consume only." (Real case: all 14
117
+ sub-issues claimed the same registry adds + 4 contradictions — hub expanded to
118
+ own all 20 keys, batch merged conflict-free.)
119
+
120
+ **Done when:** FILE→SLICES table exists · every ≥2-slice file has exactly ONE
121
+ owning slice · disjoint waves cut in dependency order · every dependent contract
122
+ carries its verbatim consume-only lines.
123
+
124
+ ## Phase 2 — Dispatch one wave in parallel (isolated worktree per implementer)
125
+
126
+ Phase 2+3 repeat **per disjoint wave** from Phase 1 — the conflict-hub wave first.
127
+ Within ONE wave, all slices dispatch at once. **Dispatch only `FREI` slices** —
128
+ re-read the native frontier (`frontier <anchor#>`) before each wave; a
129
+ gate-before-build edge clears only when its blocker actually lands (never
130
+ "unblock" by editing body text — remove the edge via `dep-remove` if the plan
131
+ genuinely changed). Two per-slice calls first: **(a)
132
+ inline vs delegate** — a tiny mechanical bit (a rename, a 1-2-line tweak) you do
133
+ yourself — and **(b) tier + effort** (Standing rules → Routing). For each
134
+ delegated slice:
135
+
136
+ - **One worktree per agent** off the wave-branch HEAD, own index so parallel agents
137
+ never share a git index. Use your project's worktree-setup command (`§Setup`),
138
+ else plain `git worktree add <path> -b feat/<anchor>-<slug>`.
139
+ - **Build the prompt from [`references/builder-contract.md`](references/builder-contract.md)**
140
+ — fill the slots with the slice's VERBATIM What+AC, plan decision, recon
141
+ file:line map and consume-only lines; never paraphrase (paraphrase drift has
142
+ produced real contract errors). The template is the SSOT for the builder's hard
143
+ rules, test/typecheck commands, workflow order and report format.
144
+ - **Capture reusable names** from the hub agent's report (the new component/helper
145
+ paths) and embed them into the dependent slices' contracts.
146
+
147
+ **Done when:** every dispatched slice reported back with commit SHA + green
148
+ package tests + green fast gate (`§Builder Commands`) — or a STOP item you resolved
149
+ (answered / re-dispatched) before integration.
150
+
151
+ ## Phase 3 — Serial integration
152
+
153
+ In the wave worktree: `git merge --no-ff <slice-branch>` per slice (disjoint →
154
+ conflict-free). After EACH wave, on the integrated branch:
155
+
156
+ - Typecheck both packages + the **FULL suite** — catches sibling/consumer test
157
+ breaks the agent ownership didn't cover (hardcoded count/tab asserts). Exact
158
+ commands = `§Integration Suites` (absent layer → your project's full test +
159
+ typecheck for every package the wave touched).
160
+ - **Run EVERY test framework the wave's files belong to**, not just the primary
161
+ one: a kit/tooling/scripts wave may also have a separate unit-test runner and a
162
+ separate script-test runner the main suite does NOT cover (real case: a
163
+ second-framework red rode 3 integrations before surfacing). `§Integration Suites`
164
+ names each framework for this project.
165
+
166
+ **Done when:** every framework green on the integrated branch — before dispatching
167
+ the next wave.
168
+
169
+ ## Phase 4 — Central verify (YOURS, serial — the user explicitly wants this)
170
+
171
+ Live-verify asserts USER OUTCOME (a DB-/UI value compared), not a tech metric.
172
+ A single browser + single dev DB ⇒ verify is serial and yours. **A subagent's
173
+ "PASS" is a hypothesis, not a gate** — implementers repeatedly mis-report green
174
+ (real case: "gate PASS" while a size gate was red; files declared missing that
175
+ existed). Never merge on the subagent's word.
176
+
177
+ - **Re-run your project's full CI/verify gate CENTRALLY yourself** (`§Verify
178
+ Recipe`). On an integrated verify/coordinator branch (no per-slice issue number)
179
+ a branch-name-derived guard can BLOCK with no matching baseline — a branch-naming
180
+ artifact, not a coverage gap (each slice branch carried its own); `§Verify
181
+ Recipe` names the skip/override for that. Absent layer → run your project's
182
+ verification command or a project-provided verification skill (e.g. the kit's
183
+ **`/local-ci`** gate), if one exists; if the project has neither, run its full
184
+ test + typecheck and assert each slice's AC as a user-visible outcome by hand.
185
+ - **Schema-/reader-changing waves** additionally run the COMBINED integration suite
186
+ against the refreshed snapshot before merge (`§Verify Recipe`) — per-slice-
187
+ isolated runs miss cross-slice seed/reader breaks.
188
+ - **ONE dev server / one shared dev DB only.** ⚠ A second backend against a shared
189
+ dev DB can reaper-kill a live job (`§Verify Recipe` names the project's gotcha).
190
+ Stop the first dev server before starting another worktree's, or verify in the
191
+ same worktree.
192
+ - **Headless login into the session-MCP profile** (AFK, no password in the
193
+ transcript). First navigate the MCP browser to the app root: no `/login`
194
+ redirect = already authenticated → skip the login (an authed profile makes a
195
+ login script time out on the e-mail field — looks like a selector bug, is not).
196
+ Otherwise: full recipe, profile-resolution lore + script = `§Headless Login`.
197
+ - **Per surface**: browser snapshot + screenshot; assert each slice's AC visibly
198
+ gone/fixed + no regression. Run the project's design/brand checks (tokens, no
199
+ hardcoded values, formatters, chart-axis rules — `§Verify Recipe`) +
200
+ cross-surface consistency.
201
+ - **Standardisation wave → CROSS-CONSUMER uniformity assert, NOT just per-slice
202
+ ACs.** If the wave unifies a shared pattern across ≥2 consumers, per-slice-green
203
+ is NOT enough — measure the standardised property on ALL N consumers and assert
204
+ they are EQUAL (e.g. `table.left - card.left` identical across every table;
205
+ export column-set identical), not just "present on each". Divergence only shows
206
+ in the cross-consumer diff. The shared component must OWN the standardised
207
+ property; this verify proves it actually does.
208
+ - **DB-compare** the outcome value against the SQL source of truth. Watch
209
+ type-coercion traps your project layer flags (`§Verify Recipe`) — e.g. a `date`
210
+ column that shifts a day through a naive ISO round-trip.
211
+ - **Console-clean** where required: read the browser console at warning level → 0
212
+ errors / 0 warnings.
213
+ - **Gap the agents missed?** 1-file mechanical → fix inline; else **freshly
214
+ re-dispatch** a new agent into the existing slice worktree/branch with the prior
215
+ findings embedded — a continuation is NOT available in the parallel-wave flow;
216
+ stopped/background agents are re-dispatched, not resumed.
217
+
218
+ **Done when — count it, don't remember it:** own central gate green (+ combined
219
+ integration where schema/reader) · **N/N slice ACs** visually asserted with
220
+ screenshot · cross-consumer equality measured (standardisation wave) · brand/design
221
+ checks pass · console 0/0 · DB outcome value compared.
222
+
223
+ ## Phase 5 — Land
224
+
225
+ - **One PR** for the whole wave (one merge for the user) OR per-slice — your call;
226
+ one PR with per-slice commits is usually kindest AFK.
227
+ - **Schema-/migration waves: land as ONE combined PR — NOT incremental
228
+ auto-merge.** If merges to the main branch auto-deploy, per-slice merges race a
229
+ manually-gated prod migration → prod errors ×N slices. One combined PR = ONE
230
+ deploy = ONE prod-migration lockstep window. Incremental merge only for
231
+ byte-neutral waves (no new schema the deployed code reads). Project specifics
232
+ (deploy trigger, migration command, done-signal) = `§Landing`.
233
+ - **`Closes #N` needs the keyword before EACH issue, one per line** — `Closes #a,
234
+ #b` only closes the first. Anchor → `Part of #<anchor>`, never `closes`
235
+ (premature close).
236
+ - **Anchor tracker: `python3 scripts/board-sync.py anchor-sync <anchor#>`** — first
237
+ `--dry-run`, review the diff, then write; gate symbol + stable cells of freshly
238
+ appended rows by hand. Mandatory at EVERY slice event: PR-create AND merge.
239
+ - **Stacked follow-up PRs** that build on the unmerged wave: base on the **wave
240
+ branch** (not main) — the platform auto-retargets them when the wave PR merges.
241
+ Note the merge order in the body.
242
+ - New issues via `scripts/board-sync.py` (never bare `gh issue create`); write
243
+ multi-paragraph PR/issue bodies via `--body-file` (an inline body with backticks
244
+ can crash the shell).
245
+
246
+ **Done when:** PR(s) open with correct `Closes`/`Part of` lines · anchor-sync
247
+ written · merge order documented.
248
+
249
+ ## Phase 6 — Cleanup + close
250
+
251
+ - Stop the dev server(s) you started, by port (`lsof -ti:<port> | xargs kill` —
252
+ your own processes, targeted by the worktree's assigned ports, never blind).
253
+ Remove temp verify scripts (a login helper, DB-check scripts).
254
+ - **Before removing any slice worktree, read its `ANNAHMEN.md`** (an assumptions
255
+ log, gitignored at worktree-root) and propagate each build-time assumption marker
256
+ to the sibling issue it carries. A hand-driven multi-PR / migration landing does
257
+ NOT run `wrapup`'s assumption-propagation step — this is the only place it
258
+ happens; `worktree remove` deletes the log.
259
+ - **Post-merge:** run `anchor-sync` again; verify every leaf issue actually closed
260
+ (the same checks `wrapup` runs, by hand when landing outside `wrapup`). The
261
+ anchor closes manually — a parent is not auto-closed on sub-issue completion.
262
+ - A skill edited during the wave → run `codex-adapter-sync` (lives in
263
+ `.agents/skills/`) in the SAME PR — the mirror-presence-parity lint is a
264
+ pre-PR gate and blocks a dual-surface skill PR without its mirror.
265
+ - Leave slice worktrees for the user to inspect, or note they're
266
+ post-merge-removable.
267
+
268
+ **Done when:** no orphan process · ANNAHMEN propagated · anchor reconciled + leaf
269
+ closes verified · final report lists landed/pulled slices as **X of Y**.
@@ -0,0 +1,67 @@
1
+ # Builder Contract — template (fill slots, embed VERBATIM)
2
+
3
+ SSOT for every delegated slice prompt in `orchestrate-wave` Phase 2. The
4
+ orchestrator copies the block below and fills the `{{SLOTS}}` with verbatim
5
+ material from the locked plan/issue — never paraphrased (paraphrase drift has
6
+ produced real contract errors). Tier + effort per SKILL.md §Standing rules →
7
+ Routing.
8
+
9
+ The **Hard rules** and **Commands** sections below carry generic defaults so the
10
+ template is never shipped with an unresolved project slot. When a project layer
11
+ is present (`orchestrate-wave` Phase 0 probe → `§Builder Hard Rules` /
12
+ `§Builder Commands`), the orchestrator REPLACES the generic lines with the
13
+ project's exact rules and commands before dispatch — the builder must see exact
14
+ commands, not "your project's tests".
15
+
16
+ ```text
17
+ You are the implementer for slice #{{ISSUE}} of wave #{{ANCHOR}}.
18
+ Worktree: {{WORKTREE_PATH}} (branch {{BRANCH}}) — work ONLY here.
19
+
20
+ ## Scope (verbatim from issue/plan — do not reinterpret)
21
+ {{WHAT_AND_AC_VERBATIM}}
22
+
23
+ ## Plan decisions that bind you
24
+ {{PLAN_DECISIONS_VERBATIM}}
25
+
26
+ ## File map (recon)
27
+ {{FILE_LINE_MAP}}
28
+ {{CONSUME_ONLY_LINES}}
29
+
30
+ ## Hard rules
31
+ - Follow this project's UI/content conventions (from the project layer
32
+ §Builder Hard Rules — e.g. UI-text language, design tokens, formatters).
33
+ Absent a project layer: match the surrounding code's conventions exactly.
34
+ - Size gates (recommended default): no new file >300 lines, no function >50
35
+ lines — unless the project sets its own limit.
36
+ - If your slice adds a guard/helper/auth-check: WIRE it into its consumer + add a
37
+ negative test — an unwired helper is dead code.
38
+ - STOP + report on any contract ambiguity — do NOT guess (this discipline has
39
+ caught real contract errors).
40
+ - Do NOT run a browser/E2E or a dev server — the orchestrator verifies centrally.
41
+
42
+ ## Commands (exact — deviations produce false reds)
43
+ Run, for EVERY package you edit: your package's unit tests for the files you
44
+ touched, a typecheck, and the project's fast pre-PR gate. State the EXACT
45
+ commands here from the project layer §Builder Commands. Absent a project layer,
46
+ use: run your package tests + typecheck + fast gate, and name the exact
47
+ invocation for each in this prompt so the builder cannot guess a wrong one.
48
+
49
+ ## Workflow order (non-negotiable)
50
+ 1. Implement (red→green test-first where the slice has logic).
51
+ 2. Commit your ONE commit on the slice branch FIRST — before any longer verify
52
+ (verify-then-forget-to-commit leaves the orchestrator hand-committing your
53
+ worktree). Do NOT push. Do NOT `--no-verify` (pre-commit hooks must pass).
54
+ 3. Run the commands above. Never end your turn with a background command still
55
+ running.
56
+
57
+ ## Report back (concise)
58
+ Files touched · decisions taken · test results (exact output) · commit SHA ·
59
+ STOP items · what the orchestrator should visually verify.
60
+ ```
61
+
62
+ Orchestrator notes:
63
+
64
+ - `{{CONSUME_ONLY_LINES}}` come from the Phase-1 reconciliation, e.g.
65
+ "X already exists in `<file>` — do NOT add it, consume only."
66
+ - For dependent slices, fill hub artifact paths from the hub agent's report
67
+ (Phase 2 "capture reusable names"), not from the plan's guesses.
@@ -0,0 +1,79 @@
1
+ # Logic Prototype
2
+
3
+ A tiny interactive terminal app that lets the user drive a state model by hand. Use this when the question is about **business logic, state transitions, or data shape** — the kind of thing that looks reasonable on paper but only feels wrong once you push it through real cases.
4
+
5
+ ## When this is the right shape
6
+
7
+ - "I'm not sure if this state machine handles the edge case where X then Y."
8
+ - "Does this data model actually let me represent the case where..."
9
+ - "I want to feel out what the API should look like before writing it."
10
+ - Anything where the user wants to **press buttons and watch state change**.
11
+
12
+ If the question is "what should this look like" — wrong branch. Use [UI.md](UI.md).
13
+
14
+ ## Process
15
+
16
+ ### 1. State the question
17
+
18
+ Before writing code, write down what state model and what question you're prototyping. One paragraph, in the prototype's README or a comment at the top of the file. A logic prototype that answers the wrong question is pure waste — make the question explicit so it can be checked later, whether the user is watching now or returning to it AFK.
19
+
20
+ ### 2. Pick the language
21
+
22
+ Use whatever the host project uses. If the project has no obvious runtime (e.g. a docs repo), ask.
23
+
24
+ Match the project's existing conventions for tooling — don't add a new package manager or runtime just for the prototype.
25
+
26
+ ### 3. Isolate the logic in a portable module
27
+
28
+ Put the actual logic — the bit that's answering the question — behind a small, pure interface that could be lifted out and dropped into the real codebase later. The TUI around it is throwaway; the logic module shouldn't be.
29
+
30
+ The right shape depends on the question:
31
+
32
+ - **A pure reducer** — `(state, action) => state`. Good when actions are discrete events and state is a single value.
33
+ - **A state machine** — explicit states and transitions. Good when "which actions are even legal right now" is part of the question.
34
+ - **A small set of pure functions** over a plain data type. Good when there's no implicit current state — just transformations.
35
+ - **A class or module with a clear method surface** when the logic genuinely owns ongoing internal state.
36
+
37
+ Pick whichever shape best fits the question being asked, *not* whichever is easiest to wire to a TUI. Keep it pure: no I/O, no terminal code, no `console.log` for control flow. The TUI imports it and calls into it; nothing flows the other direction.
38
+
39
+ This is what makes the prototype useful past its own lifetime. When the question's been answered, the validated reducer / machine / function set can be lifted into the real module — the TUI shell gets deleted.
40
+
41
+ ### 4. Build the smallest TUI that exposes the state
42
+
43
+ Build it as a **lightweight TUI** — on every tick, clear the screen (`console.clear()` / `print("\033[2J\033[H")` / equivalent) and re-render the whole frame. The user should always see one stable view, not an ever-growing scrollback.
44
+
45
+ Each frame has two parts, in this order:
46
+
47
+ 1. **Current state**, pretty-printed and diff-friendly (one field per line, or formatted JSON). Use **bold** for field names or section headers and **dim** for less important context (timestamps, IDs, derived values). Native ANSI escape codes are fine — `\x1b[1m` bold, `\x1b[2m` dim, `\x1b[0m` reset. No need to pull in a styling library unless one is already in the project.
48
+ 2. **Keyboard shortcuts**, listed at the bottom: `[a] add user [d] delete user [t] tick clock [q] quit`. Bold the key, dim the description, or vice-versa — whatever reads cleanly.
49
+
50
+ Behaviour:
51
+
52
+ 1. **Initialise state** — a single in-memory object/struct. Render the first frame on start.
53
+ 2. **Read one keystroke (or one line)** at a time, dispatch to a handler that mutates state.
54
+ 3. **Re-render** the full frame after every action — don't append, replace.
55
+ 4. **Loop until quit.**
56
+
57
+ The whole frame should fit on one screen.
58
+
59
+ ### 5. Make it runnable in one command
60
+
61
+ Add a script to the project's existing task runner (`package.json` scripts, `Makefile`, `justfile`, `pyproject.toml`). The user should run `pnpm run <prototype-name>` or equivalent — never need to remember a path.
62
+
63
+ If the host project has no task runner, just put the command at the top of the prototype's README.
64
+
65
+ ### 6. Hand it over
66
+
67
+ Give the user the run command. They'll drive it themselves; the interesting moments are when they say "wait, that shouldn't be possible" or "huh, I assumed X would be different" — those are the bugs in the _idea_, which is the whole point. If they want new actions added, add them. Prototypes evolve.
68
+
69
+ ### 7. Capture the answer
70
+
71
+ When the prototype has done its job, the answer to the question is the only thing worth keeping. If the user is around, ask what it taught them. If not, leave a `NOTES.md` next to the prototype so the answer can be filled in (or filled in by you, if you've watched the session) before the prototype gets deleted.
72
+
73
+ ## Anti-patterns
74
+
75
+ - **Don't add tests.** A prototype that needs tests is no longer a prototype.
76
+ - **Don't wire it to the real database.** Use an in-memory store unless the question is specifically about persistence.
77
+ - **Don't generalise.** No "what if we wanted to support X later." The prototype answers one question.
78
+ - **Don't blur the logic and the TUI together.** If the reducer / state machine references `console.log`, prompts, or terminal escape codes, it's no longer portable. Keep the TUI as a thin shell over a pure module.
79
+ - **Don't ship the TUI shell into production.** The shell is optimised for being driven by hand from a terminal. The logic module behind it is the bit worth keeping.
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: prototype
3
+ description: Build a throwaway prototype to flesh out a design before committing to it. Routes between two branches — a runnable terminal app for state/business-logic questions, or several radically different UI variations toggleable from one route. Use when the user wants to prototype, sanity-check a data model or state machine, mock up a UI, explore design options, or says "prototype this", "let me play with it", "try a few designs".
4
+ ---
5
+
6
+ # Prototype
7
+
8
+ A prototype is **throwaway code that answers a question**. The question decides the shape.
9
+
10
+ ## Pick a branch
11
+
12
+ Identify which question is being answered — from the user's prompt, the surrounding code, or by asking if the user is around:
13
+
14
+ - **"Does this logic / state model feel right?"** → [LOGIC.md](LOGIC.md). Build a tiny interactive terminal app that pushes the state machine through cases that are hard to reason about on paper.
15
+ - **"What should this look like?"** → [UI.md](UI.md). Generate several radically different UI variations on a single route, switchable via a URL search param and a floating bottom bar.
16
+
17
+ The two branches produce very different artifacts — getting this wrong wastes the whole prototype. If the question is genuinely ambiguous and the user isn't reachable, default to whichever branch better matches the surrounding code (a backend module → logic; a page or component → UI) and state the assumption at the top of the prototype.
18
+
19
+ ## Rules that apply to both
20
+
21
+ 1. **Throwaway from day one, and clearly marked as such.** Locate the prototype code close to where it will actually be used (next to the module or page it's prototyping for) so context is obvious — but name it so a casual reader can see it's a prototype, not production. For throwaway UI routes, obey whatever routing convention the project already uses; don't invent a new top-level structure.
22
+ 2. **One command to run.** Whatever the project's existing task runner supports — `pnpm <name>`, `python <path>`, `bun <path>`, etc. The user must be able to start it without thinking.
23
+ 3. **No persistence by default.** State lives in memory. Persistence is the thing the prototype is _checking_, not something it should depend on. If the question explicitly involves a database, hit a scratch DB or a local file with a clear "PROTOTYPE — wipe me" name.
24
+ 4. **Skip the polish.** No tests, no error handling beyond what makes the prototype _runnable_, no abstractions. The point is to learn something fast and then delete it.
25
+ 5. **Surface the state.** After every action (logic) or on every variant switch (UI), print or render the full relevant state so the user can see what changed.
26
+ 6. **Delete or absorb when done.** When the prototype has answered its question, either delete it or fold the validated decision into the real code — don't leave it rotting in the repo.
27
+
28
+ ## When done
29
+
30
+ The _answer_ is the only thing worth keeping from a prototype. Capture it somewhere durable (commit message, ADR, issue, or a `NOTES.md` next to the prototype) along with the question it was answering. If the user is around, that capture is a quick conversation; if not, leave the placeholder so they (or you, on the next pass) can fill in the verdict before deleting the prototype.
@@ -0,0 +1,29 @@
1
+ # Third-Party Notices
2
+
3
+ This skill is adapted from **Matt Pocock's skills**
4
+ (https://github.com/mattpocock/skills), `skills/engineering/prototype` @ d574778, Copyright (c) 2026 Matt Pocock,
5
+ used under the MIT License. Locally adapted (fork-and-own); see PROVENANCE.md.
6
+
7
+ ```
8
+ MIT License
9
+
10
+ Copyright (c) 2026 Matt Pocock
11
+
12
+ Permission is hereby granted, free of charge, to any person obtaining a copy
13
+ of this software and associated documentation files (the "Software"), to deal
14
+ in the Software without restriction, including without limitation the rights
15
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
+ copies of the Software, and to permit persons to whom the Software is
17
+ furnished to do so, subject to the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be included in all
20
+ copies or substantial portions of the Software.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
+ SOFTWARE.
29
+ ```