@kamilmarzynski/scifi 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +232 -0
  3. package/dist/skills/sf-bug/manifest.d.ts +2 -0
  4. package/dist/skills/sf-bug/manifest.js +6 -0
  5. package/dist/skills/sf-bug/manifest.js.map +1 -0
  6. package/dist/skills/sf-change/manifest.d.ts +2 -0
  7. package/dist/skills/sf-change/manifest.js +6 -0
  8. package/dist/skills/sf-change/manifest.js.map +1 -0
  9. package/dist/skills/sf-code-review/manifest.d.ts +2 -0
  10. package/dist/skills/sf-code-review/manifest.js +5 -0
  11. package/dist/skills/sf-code-review/manifest.js.map +1 -0
  12. package/dist/skills/sf-continue/manifest.d.ts +2 -0
  13. package/dist/skills/sf-continue/manifest.js +6 -0
  14. package/dist/skills/sf-continue/manifest.js.map +1 -0
  15. package/dist/skills/sf-feature/manifest.d.ts +2 -0
  16. package/dist/skills/sf-feature/manifest.js +6 -0
  17. package/dist/skills/sf-feature/manifest.js.map +1 -0
  18. package/dist/skills/sf-fix/manifest.d.ts +2 -0
  19. package/dist/skills/sf-fix/manifest.js +6 -0
  20. package/dist/skills/sf-fix/manifest.js.map +1 -0
  21. package/dist/skills/sf-handover/manifest.d.ts +2 -0
  22. package/dist/skills/sf-handover/manifest.js +5 -0
  23. package/dist/skills/sf-handover/manifest.js.map +1 -0
  24. package/dist/skills/sf-implement/manifest.d.ts +2 -0
  25. package/dist/skills/sf-implement/manifest.js +6 -0
  26. package/dist/skills/sf-implement/manifest.js.map +1 -0
  27. package/dist/skills/sf-plan/manifest.d.ts +2 -0
  28. package/dist/skills/sf-plan/manifest.js +6 -0
  29. package/dist/skills/sf-plan/manifest.js.map +1 -0
  30. package/dist/skills/sf-plan-review/manifest.d.ts +2 -0
  31. package/dist/skills/sf-plan-review/manifest.js +5 -0
  32. package/dist/skills/sf-plan-review/manifest.js.map +1 -0
  33. package/dist/skills/sf-receiving-review/manifest.d.ts +2 -0
  34. package/dist/skills/sf-receiving-review/manifest.js +5 -0
  35. package/dist/skills/sf-receiving-review/manifest.js.map +1 -0
  36. package/dist/skills/sf-spec-review/manifest.d.ts +2 -0
  37. package/dist/skills/sf-spec-review/manifest.js +5 -0
  38. package/dist/skills/sf-spec-review/manifest.js.map +1 -0
  39. package/dist/skills/sf-tdd/manifest.d.ts +2 -0
  40. package/dist/skills/sf-tdd/manifest.js +5 -0
  41. package/dist/skills/sf-tdd/manifest.js.map +1 -0
  42. package/dist/skills/sf-verification/manifest.d.ts +2 -0
  43. package/dist/skills/sf-verification/manifest.js +5 -0
  44. package/dist/skills/sf-verification/manifest.js.map +1 -0
  45. package/dist/src/cli/commands/bug.d.ts +2 -0
  46. package/dist/src/cli/commands/bug.js +58 -0
  47. package/dist/src/cli/commands/bug.js.map +1 -0
  48. package/dist/src/cli/commands/finish.d.ts +2 -0
  49. package/dist/src/cli/commands/finish.js +43 -0
  50. package/dist/src/cli/commands/finish.js.map +1 -0
  51. package/dist/src/cli/commands/fix.d.ts +2 -0
  52. package/dist/src/cli/commands/fix.js +60 -0
  53. package/dist/src/cli/commands/fix.js.map +1 -0
  54. package/dist/src/cli/commands/init.d.ts +2 -0
  55. package/dist/src/cli/commands/init.js +92 -0
  56. package/dist/src/cli/commands/init.js.map +1 -0
  57. package/dist/src/cli/commands/list.d.ts +2 -0
  58. package/dist/src/cli/commands/list.js +52 -0
  59. package/dist/src/cli/commands/list.js.map +1 -0
  60. package/dist/src/cli/commands/plan-ready.d.ts +2 -0
  61. package/dist/src/cli/commands/plan-ready.js +27 -0
  62. package/dist/src/cli/commands/plan-ready.js.map +1 -0
  63. package/dist/src/cli/commands/plan.d.ts +2 -0
  64. package/dist/src/cli/commands/plan.js +43 -0
  65. package/dist/src/cli/commands/plan.js.map +1 -0
  66. package/dist/src/cli/commands/spec-ready.d.ts +2 -0
  67. package/dist/src/cli/commands/spec-ready.js +27 -0
  68. package/dist/src/cli/commands/spec-ready.js.map +1 -0
  69. package/dist/src/cli/commands/spec.d.ts +2 -0
  70. package/dist/src/cli/commands/spec.js +46 -0
  71. package/dist/src/cli/commands/spec.js.map +1 -0
  72. package/dist/src/cli/commands/start.d.ts +2 -0
  73. package/dist/src/cli/commands/start.js +27 -0
  74. package/dist/src/cli/commands/start.js.map +1 -0
  75. package/dist/src/cli/commands/status.d.ts +2 -0
  76. package/dist/src/cli/commands/status.js +62 -0
  77. package/dist/src/cli/commands/status.js.map +1 -0
  78. package/dist/src/cli/commands/task.d.ts +2 -0
  79. package/dist/src/cli/commands/task.js +64 -0
  80. package/dist/src/cli/commands/task.js.map +1 -0
  81. package/dist/src/cli/commands/worktree.d.ts +2 -0
  82. package/dist/src/cli/commands/worktree.js +33 -0
  83. package/dist/src/cli/commands/worktree.js.map +1 -0
  84. package/dist/src/cli/index.d.ts +3 -0
  85. package/dist/src/cli/index.js +106 -0
  86. package/dist/src/cli/index.js.map +1 -0
  87. package/dist/src/core/bugs/create.d.ts +13 -0
  88. package/dist/src/core/bugs/create.js +28 -0
  89. package/dist/src/core/bugs/create.js.map +1 -0
  90. package/dist/src/core/bugs/frontmatter.d.ts +7 -0
  91. package/dist/src/core/bugs/frontmatter.js +65 -0
  92. package/dist/src/core/bugs/frontmatter.js.map +1 -0
  93. package/dist/src/core/bugs/id.d.ts +1 -0
  94. package/dist/src/core/bugs/id.js +4 -0
  95. package/dist/src/core/bugs/id.js.map +1 -0
  96. package/dist/src/core/bugs/paths.d.ts +2 -0
  97. package/dist/src/core/bugs/paths.js +8 -0
  98. package/dist/src/core/bugs/paths.js.map +1 -0
  99. package/dist/src/core/bugs/types.d.ts +12 -0
  100. package/dist/src/core/bugs/types.js +3 -0
  101. package/dist/src/core/bugs/types.js.map +1 -0
  102. package/dist/src/core/fixes/create.d.ts +11 -0
  103. package/dist/src/core/fixes/create.js +43 -0
  104. package/dist/src/core/fixes/create.js.map +1 -0
  105. package/dist/src/core/fixes/frontmatter.d.ts +7 -0
  106. package/dist/src/core/fixes/frontmatter.js +50 -0
  107. package/dist/src/core/fixes/frontmatter.js.map +1 -0
  108. package/dist/src/core/fixes/id.d.ts +1 -0
  109. package/dist/src/core/fixes/id.js +4 -0
  110. package/dist/src/core/fixes/id.js.map +1 -0
  111. package/dist/src/core/fixes/list.d.ts +8 -0
  112. package/dist/src/core/fixes/list.js +43 -0
  113. package/dist/src/core/fixes/list.js.map +1 -0
  114. package/dist/src/core/fixes/paths.d.ts +2 -0
  115. package/dist/src/core/fixes/paths.js +9 -0
  116. package/dist/src/core/fixes/paths.js.map +1 -0
  117. package/dist/src/core/fixes/transition.d.ts +9 -0
  118. package/dist/src/core/fixes/transition.js +26 -0
  119. package/dist/src/core/fixes/transition.js.map +1 -0
  120. package/dist/src/core/fixes/types.d.ts +9 -0
  121. package/dist/src/core/fixes/types.js +2 -0
  122. package/dist/src/core/fixes/types.js.map +1 -0
  123. package/dist/src/core/init/config.d.ts +6 -0
  124. package/dist/src/core/init/config.js +18 -0
  125. package/dist/src/core/init/config.js.map +1 -0
  126. package/dist/src/core/init/install-skills.d.ts +8 -0
  127. package/dist/src/core/init/install-skills.js +14 -0
  128. package/dist/src/core/init/install-skills.js.map +1 -0
  129. package/dist/src/core/init/prompt-harness.d.ts +8 -0
  130. package/dist/src/core/init/prompt-harness.js +19 -0
  131. package/dist/src/core/init/prompt-harness.js.map +1 -0
  132. package/dist/src/core/init/scaffold.d.ts +5 -0
  133. package/dist/src/core/init/scaffold.js +91 -0
  134. package/dist/src/core/init/scaffold.js.map +1 -0
  135. package/dist/src/core/init/types.d.ts +5 -0
  136. package/dist/src/core/init/types.js +2 -0
  137. package/dist/src/core/init/types.js.map +1 -0
  138. package/dist/src/core/output/emit.d.ts +8 -0
  139. package/dist/src/core/output/emit.js +50 -0
  140. package/dist/src/core/output/emit.js.map +1 -0
  141. package/dist/src/core/output/errors.d.ts +14 -0
  142. package/dist/src/core/output/errors.js +36 -0
  143. package/dist/src/core/output/errors.js.map +1 -0
  144. package/dist/src/core/output/index.d.ts +4 -0
  145. package/dist/src/core/output/index.js +4 -0
  146. package/dist/src/core/output/index.js.map +1 -0
  147. package/dist/src/core/output/tty.d.ts +1 -0
  148. package/dist/src/core/output/tty.js +4 -0
  149. package/dist/src/core/output/tty.js.map +1 -0
  150. package/dist/src/core/package-root.d.ts +1 -0
  151. package/dist/src/core/package-root.js +18 -0
  152. package/dist/src/core/package-root.js.map +1 -0
  153. package/dist/src/core/skills/catalog.d.ts +6 -0
  154. package/dist/src/core/skills/catalog.js +69 -0
  155. package/dist/src/core/skills/catalog.js.map +1 -0
  156. package/dist/src/core/skills/harness/adapter.d.ts +15 -0
  157. package/dist/src/core/skills/harness/adapter.js +31 -0
  158. package/dist/src/core/skills/harness/adapter.js.map +1 -0
  159. package/dist/src/core/skills/harness/claude-code.d.ts +2 -0
  160. package/dist/src/core/skills/harness/claude-code.js +37 -0
  161. package/dist/src/core/skills/harness/claude-code.js.map +1 -0
  162. package/dist/src/core/skills/harness/register-defaults.d.ts +1 -0
  163. package/dist/src/core/skills/harness/register-defaults.js +4 -0
  164. package/dist/src/core/skills/harness/register-defaults.js.map +1 -0
  165. package/dist/src/core/skills/harness/registry.d.ts +3 -0
  166. package/dist/src/core/skills/harness/registry.js +22 -0
  167. package/dist/src/core/skills/harness/registry.js.map +1 -0
  168. package/dist/src/core/skills/types.d.ts +18 -0
  169. package/dist/src/core/skills/types.js +9 -0
  170. package/dist/src/core/skills/types.js.map +1 -0
  171. package/dist/src/core/slugify.d.ts +2 -0
  172. package/dist/src/core/slugify.js +13 -0
  173. package/dist/src/core/slugify.js.map +1 -0
  174. package/dist/src/core/specs/create.d.ts +11 -0
  175. package/dist/src/core/specs/create.js +35 -0
  176. package/dist/src/core/specs/create.js.map +1 -0
  177. package/dist/src/core/specs/id.d.ts +1 -0
  178. package/dist/src/core/specs/id.js +4 -0
  179. package/dist/src/core/specs/id.js.map +1 -0
  180. package/dist/src/core/specs/lifecycle.d.ts +17 -0
  181. package/dist/src/core/specs/lifecycle.js +97 -0
  182. package/dist/src/core/specs/lifecycle.js.map +1 -0
  183. package/dist/src/core/specs/list.d.ts +6 -0
  184. package/dist/src/core/specs/list.js +43 -0
  185. package/dist/src/core/specs/list.js.map +1 -0
  186. package/dist/src/core/specs/metadata.d.ts +3 -0
  187. package/dist/src/core/specs/metadata.js +13 -0
  188. package/dist/src/core/specs/metadata.js.map +1 -0
  189. package/dist/src/core/specs/paths.d.ts +3 -0
  190. package/dist/src/core/specs/paths.js +13 -0
  191. package/dist/src/core/specs/paths.js.map +1 -0
  192. package/dist/src/core/specs/plan-session.d.ts +18 -0
  193. package/dist/src/core/specs/plan-session.js +24 -0
  194. package/dist/src/core/specs/plan-session.js.map +1 -0
  195. package/dist/src/core/specs/transition.d.ts +8 -0
  196. package/dist/src/core/specs/transition.js +33 -0
  197. package/dist/src/core/specs/transition.js.map +1 -0
  198. package/dist/src/core/specs/types.d.ts +17 -0
  199. package/dist/src/core/specs/types.js +8 -0
  200. package/dist/src/core/specs/types.js.map +1 -0
  201. package/dist/src/core/specs/worktree.d.ts +10 -0
  202. package/dist/src/core/specs/worktree.js +32 -0
  203. package/dist/src/core/specs/worktree.js.map +1 -0
  204. package/dist/src/core/tasks/frontmatter.d.ts +7 -0
  205. package/dist/src/core/tasks/frontmatter.js +53 -0
  206. package/dist/src/core/tasks/frontmatter.js.map +1 -0
  207. package/dist/src/core/tasks/list.d.ts +2 -0
  208. package/dist/src/core/tasks/list.js +18 -0
  209. package/dist/src/core/tasks/list.js.map +1 -0
  210. package/dist/src/core/tasks/paths.d.ts +2 -0
  211. package/dist/src/core/tasks/paths.js +11 -0
  212. package/dist/src/core/tasks/paths.js.map +1 -0
  213. package/dist/src/core/tasks/transition.d.ts +8 -0
  214. package/dist/src/core/tasks/transition.js +30 -0
  215. package/dist/src/core/tasks/transition.js.map +1 -0
  216. package/dist/src/core/tasks/types.d.ts +8 -0
  217. package/dist/src/core/tasks/types.js +2 -0
  218. package/dist/src/core/tasks/types.js.map +1 -0
  219. package/package.json +67 -0
  220. package/skills/sf-bug/DISPATCH-CODE-REVIEW.md +22 -0
  221. package/skills/sf-bug/body.md +117 -0
  222. package/skills/sf-bug/manifest.ts +8 -0
  223. package/skills/sf-change/body.md +178 -0
  224. package/skills/sf-change/manifest.ts +8 -0
  225. package/skills/sf-code-review/body.md +155 -0
  226. package/skills/sf-code-review/manifest.ts +7 -0
  227. package/skills/sf-continue/body.md +90 -0
  228. package/skills/sf-continue/manifest.ts +8 -0
  229. package/skills/sf-feature/ADR-TEMPLATE.md +16 -0
  230. package/skills/sf-feature/DISPATCH-SPEC-REVIEW.md +16 -0
  231. package/skills/sf-feature/SPEC-TEMPLATE.md +37 -0
  232. package/skills/sf-feature/body.md +145 -0
  233. package/skills/sf-feature/manifest.ts +8 -0
  234. package/skills/sf-fix/DISPATCH-CODE-REVIEW.md +25 -0
  235. package/skills/sf-fix/body.md +174 -0
  236. package/skills/sf-fix/manifest.ts +8 -0
  237. package/skills/sf-handover/body.md +67 -0
  238. package/skills/sf-handover/manifest.ts +7 -0
  239. package/skills/sf-implement/DISPATCH-CODE-REVIEW.md +19 -0
  240. package/skills/sf-implement/DISPATCH-HANDOVER.md +19 -0
  241. package/skills/sf-implement/DISPATCH-IMPLEMENTER.md +36 -0
  242. package/skills/sf-implement/body.md +147 -0
  243. package/skills/sf-implement/manifest.ts +8 -0
  244. package/skills/sf-plan/ADR-TEMPLATE.md +16 -0
  245. package/skills/sf-plan/DESIGN-TEMPLATE.md +54 -0
  246. package/skills/sf-plan/DISPATCH-PLAN-REVIEW.md +17 -0
  247. package/skills/sf-plan/TASK-TEMPLATE.md +30 -0
  248. package/skills/sf-plan/body.md +162 -0
  249. package/skills/sf-plan/manifest.ts +8 -0
  250. package/skills/sf-plan-review/body.md +90 -0
  251. package/skills/sf-plan-review/manifest.ts +7 -0
  252. package/skills/sf-receiving-review/body.md +73 -0
  253. package/skills/sf-receiving-review/manifest.ts +7 -0
  254. package/skills/sf-spec-review/body.md +83 -0
  255. package/skills/sf-spec-review/manifest.ts +7 -0
  256. package/skills/sf-tdd/body.md +120 -0
  257. package/skills/sf-tdd/manifest.ts +7 -0
@@ -0,0 +1,83 @@
1
+ # sf-spec-review
2
+
3
+ You are a critic. You were dispatched to review ONE feature spec before it is
4
+ marked spec-ready. You do not write the spec and you do not implement anything.
5
+ You read, you judge, you report back to the agent that dispatched you.
6
+
7
+ ## Inputs
8
+
9
+ The dispatching agent gives you the path to the spec (e.g.
10
+ `docs/scifi/specs/<slug>/spec.md`). If it is missing, say so and stop.
11
+
12
+ ## What to read
13
+
14
+ - The spec at the given path.
15
+ - `docs/scifi/CONTEXT.md` — the project's ubiquitous language (canonical
16
+ glossary of domain terms).
17
+
18
+ Read both before judging. Never invent project facts; if something is
19
+ unknowable from these files, flag it as a question instead of assuming.
20
+
21
+ ## What to check
22
+
23
+ Go section by section. Look for:
24
+
25
+ - **Ambiguity** — any requirement that two engineers would read two ways. Quote
26
+ it and say what is unclear.
27
+ - **Acceptance criteria** — present, testable, and actually covering the
28
+ in-scope items? A criterion that cannot be verified as done/not-done is a
29
+ defect. Missing criteria for an in-scope behavior is a defect.
30
+ - **Scope coherence** — is "out of scope" explicit, and does "in scope" match
31
+ the problem statement? Flag scope creep and silent gaps.
32
+ - **Structure impact** — if the spec touches structure, does it say so in
33
+ "Architecture & Context impact"? A silent structural change is a defect.
34
+ (Judge against the spec's own section, not an external architecture doc.)
35
+ - **Naming / glossary** — domain terms used but not in `CONTEXT.md` (ubiquitous
36
+ language) and not proposed for it. This is a naming-consistency check, not a
37
+ structural one.
38
+ - **Edge cases** — obvious error states, boundaries, or failure modes the spec
39
+ ignores.
40
+ - **Placeholders** — any `TBD` / `TODO` / empty section. Open questions are
41
+ allowed only under the "Open questions" heading, never as a stand-in for a
42
+ decision that should have been made.
43
+
44
+ ## How to report
45
+
46
+ Open with a header that names what this is, so the receiving agent applies the
47
+ right lens: **`Spec review of <path>`**. Then use this exact shape:
48
+
49
+ ```
50
+ # Spec review of <path>
51
+
52
+ ### Strengths
53
+ - <what the spec gets right — be specific; accurate praise earns trust>
54
+
55
+ ### Issues
56
+
57
+ #### Critical (must fix)
58
+ - Where: <section / quoted line>
59
+ Problem: <what is wrong>
60
+ Fix: <concrete change, or the exact question to ask the user>
61
+
62
+ #### Important (should fix)
63
+ - ...
64
+
65
+ #### Minor (nice to have)
66
+ - ...
67
+
68
+ ### Verdict: Pass | Fail | With fixes
69
+ <one-line technical reason>
70
+ ```
71
+
72
+ Calibration:
73
+
74
+ - **Pass** — unambiguous, criteria testable and complete, no silent structural changes, no
75
+ placeholders. No Critical or Important issues.
76
+ - **With fixes** — only Minor issues remain; the spec is sound enough to
77
+ proceed once they are addressed.
78
+ - **Fail** — any Critical or Important issue. A placeholder, a missing
79
+ acceptance criterion is always at least Important.
80
+
81
+ Be specific — quote the line, name the section. The receiving agent acts on
82
+ your list directly, so vague feedback wastes a round trip. Do not mark nitpicks
83
+ as Critical. Do not edit any file yourself.
@@ -0,0 +1,7 @@
1
+ import type { SkillManifest } from "scifi/skill-types";
2
+
3
+ export const manifest: SkillManifest = {
4
+ id: "sf-spec-review",
5
+ description:
6
+ "Critic pass on a spec.md. Surfaces ambiguity, missing AC, CONTEXT.md gaps.",
7
+ };
@@ -0,0 +1,120 @@
1
+ # sf-tdd
2
+
3
+ You are implementing ONE task test-first. This skill is the discipline you hold
4
+ while you do it. It is rigid: follow it exactly. Violating the letter of these
5
+ rules violates their spirit.
6
+
7
+ You were almost certainly dispatched by `sf-implement` with a single task to
8
+ build. Your task file's **Tests first** section is your starting list of
9
+ behaviors. Build them one at a time.
10
+
11
+ ## The Iron Law
12
+
13
+ ```
14
+ NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST
15
+ ```
16
+
17
+ If you wrote implementation before its test, delete it. Not "keep as reference",
18
+ not "adapt it while writing the test" — delete, then re-derive it from the test.
19
+ If you never watched a test fail, you do not know that it tests anything.
20
+
21
+ ## Vertical slices, never horizontal
22
+
23
+ Do **not** write all the tests, then all the code. That "horizontal" split
24
+ produces tests of *imagined* behavior — they check the shape of things and stay
25
+ green when behavior actually breaks.
26
+
27
+ Work in **vertical** slices instead: one test → make it pass → next test. Each
28
+ test responds to what the previous cycle taught you.
29
+
30
+ ```
31
+ WRONG (horizontal): test1 test2 test3 → impl1 impl2 impl3
32
+ RIGHT (vertical): test1 → impl1 → test2 → impl2 → test3 → impl3
33
+ ```
34
+
35
+ ## The loop: red → green → refactor
36
+
37
+ For each behavior in the task:
38
+
39
+ 1. **RED — write one failing test.**
40
+ - One behavior. A name that reads like a spec ("rejects empty email"), not
41
+ "test1" and not "validates email and domain and whitespace" (the "and"
42
+ means split it).
43
+ - Test observable behavior through the public interface. Real code paths, no
44
+ mocks of your own modules.
45
+
46
+ 2. **Verify RED — watch it fail. MANDATORY, never skip.**
47
+ - Run the test. Confirm it *fails*, not *errors*, and fails for the right
48
+ reason: the behavior is missing, not a typo or bad import.
49
+ - Passes already? It tests existing behavior — rewrite it.
50
+ - Errors? Fix the error and re-run until it fails cleanly.
51
+
52
+ 3. **GREEN — minimal code to pass.**
53
+ - The simplest thing that makes this one test pass. No speculative options,
54
+ no config knobs nothing calls yet (YAGNI). Don't improve unrelated code.
55
+
56
+ 4. **Verify GREEN — watch it pass.**
57
+ - This test passes, and every other test still passes, with pristine output
58
+ (no stray errors or warnings). Other tests broke? Fix them now.
59
+
60
+ 5. **REFACTOR — only while green.**
61
+ - Remove duplication, improve names, deepen modules (push complexity behind a
62
+ narrow interface). Re-run tests after each step; stay green throughout.
63
+ - **Never refactor while red.** Get to green first.
64
+
65
+ Then repeat for the next behavior.
66
+
67
+ ## Depth while you refactor
68
+
69
+ Same lens `sf-plan` used to design these modules — hold it as you clean up:
70
+
71
+ - A **deep** module hides a lot of behavior behind a small interface. Prefer it.
72
+ - Distrust the shallow: a "utils" grab bag, a class that only forwards calls, a
73
+ function extracted solely so a test can reach it.
74
+ - Deletion test: would removing this unit *concentrate* complexity (keep it) or
75
+ just *scatter* it (inline it)?
76
+
77
+ If the design module you were handed turns out shallow, say so in your report —
78
+ do not silently redesign across task boundaries.
79
+
80
+ ## Mock only at the boundary
81
+
82
+ Mock external APIs, the clock, randomness, sometimes the database or filesystem.
83
+ Do **not** mock your own modules or internal collaborators — that couples the
84
+ test to implementation and it breaks on every refactor. If something is hard to
85
+ test without mocking internals, the design is too coupled: inject the dependency
86
+ or narrow the seam, don't reach for a mock.
87
+
88
+ A test that verifies "the system saved a user" should read the user back through
89
+ the public interface, not query the database directly.
90
+
91
+ ## When you are stuck
92
+
93
+ | Problem | Move |
94
+ | --- | --- |
95
+ | Don't know how to test it | Write the wished-for call and assertion first. |
96
+ | Test is complicated | The design is complicated. Simplify the interface. |
97
+ | Must mock everything | Too coupled. Inject dependencies. |
98
+ | Test setup is huge | Extract helpers; if still huge, simplify the design. |
99
+
100
+ ## Done
101
+
102
+ The task is done (from your side) when:
103
+
104
+ - every behavior in **Tests first** has a test that you watched fail then pass,
105
+ - the full suite is green with pristine output,
106
+ - the task's **Validation** step passes,
107
+ - you committed the work.
108
+
109
+ Hand back to `sf-implement` with your status (`DONE`, `DONE_WITH_CONCERNS`,
110
+ `NEEDS_CONTEXT`, or `BLOCKED`) and a one-line summary. The orchestrator runs the
111
+ code review — you do not mark the task done yourself.
112
+
113
+ ## Red flags — stop and start over
114
+
115
+ - Production code with no failing test behind it.
116
+ - A test that passed the first time you ran it.
117
+ - You cannot say why a test failed.
118
+ - "I'll add tests after." / "Too simple to test." / "Just this once."
119
+
120
+ Each of these means: delete the untested code, return to RED.
@@ -0,0 +1,7 @@
1
+ import type { SkillManifest } from "scifi/skill-types";
2
+
3
+ export const manifest: SkillManifest = {
4
+ id: "sf-tdd",
5
+ description:
6
+ "Tests-first implementation discipline for a single task. Red-green-refactor in vertical slices; no production code without a failing test first.",
7
+ };