@phuc1403/musketeer 0.9.0 → 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 (163) hide show
  1. package/INSTALLATION.md +52 -52
  2. package/bin/musketeer.js +168 -168
  3. package/package.json +48 -48
  4. package/src/dotnet-scaffold-copier.js +79 -79
  5. package/src/provisioner/detect.js +93 -93
  6. package/src/self-update.js +77 -77
  7. package/template/.claude/agents/git-manager.md +18 -18
  8. package/template/.claude/agents/hallmark-auditor.md +78 -78
  9. package/template/.claude/agents/researcher.md +33 -33
  10. package/template/.claude/hooks/block-unsafe-adr-title.cjs +85 -85
  11. package/template/.claude/hooks/init-adr-dir.cjs +173 -173
  12. package/template/.claude/hooks/inject-adr-flags.cjs +94 -94
  13. package/template/.claude/hooks/lib/adr/command-scan.cjs +115 -115
  14. package/template/.claude/hooks/lib/characteristics/checker.cjs +357 -357
  15. package/template/.claude/hooks/lib/git-info-cache.cjs +191 -191
  16. package/template/.claude/hooks/sync-adr-toc.cjs +146 -146
  17. package/template/.claude/hooks/usage-quota-cache-refresh.cjs +166 -166
  18. package/template/.claude/hooks/validate-characteristics-hook.cjs +66 -66
  19. package/template/.claude/hooks/validate-cml-hook.js +145 -145
  20. package/template/.claude/skills/adr-writer/SKILL.md +48 -48
  21. package/template/.claude/skills/adr-writer/references/adr-example.md +35 -35
  22. package/template/.claude/skills/architecture-characteristic-writer/SKILL.md +215 -215
  23. package/template/.claude/skills/architecture-characteristic-writer/assets/worksheet-template.md +29 -29
  24. package/template/.claude/skills/architecture-characteristic-writer/references/characteristics-catalog.md +40 -40
  25. package/template/.claude/skills/architecture-characteristic-writer/scripts/ranking-table.cjs +171 -171
  26. package/template/.claude/skills/context-map/SKILL.md +80 -80
  27. package/template/.claude/skills/context-map/example.cml +106 -106
  28. package/template/.claude/skills/context-map/reference/Bounded Context/Bounded Context.md +40 -40
  29. package/template/.claude/skills/context-map/reference/Bounded Context/businessModel.md +5 -5
  30. package/template/.claude/skills/context-map/reference/Bounded Context/domainVisionStatement.md +2 -2
  31. package/template/.claude/skills/context-map/reference/Bounded Context/evolution.md +5 -5
  32. package/template/.claude/skills/context-map/reference/Bounded Context/implementationTechnology.md +1 -1
  33. package/template/.claude/skills/context-map/reference/Bounded Context/implements.md +1 -1
  34. package/template/.claude/skills/context-map/reference/Bounded Context/knowledgeLevel.md +4 -4
  35. package/template/.claude/skills/context-map/reference/Bounded Context/realizes.md +9 -9
  36. package/template/.claude/skills/context-map/reference/Bounded Context/refines.md +10 -10
  37. package/template/.claude/skills/context-map/reference/Bounded Context/responsibilities.md +26 -26
  38. package/template/.claude/skills/context-map/reference/Bounded Context/type.md +23 -23
  39. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Anticorruption Layer.md +5 -5
  40. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Bounded Context Relationship.md +12 -12
  41. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Conformist.md +5 -5
  42. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Customer-Supplier (C-S).md +22 -22
  43. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Open Host Service.md +4 -4
  44. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Partnership (P).md +13 -13
  45. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Published Language.md +4 -4
  46. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Shared Kernel (SK).md +12 -12
  47. package/template/.claude/skills/context-map/reference/Context Map.md +62 -62
  48. package/template/.claude/skills/context-map/reference/Domain/Domain.md +30 -30
  49. package/template/.claude/skills/context-map/reference/Domain/supports.md +33 -33
  50. package/template/.claude/skills/context-map/reference/Domain/type.md +3 -3
  51. package/template/.claude/skills/context-map/reference/Semantic Rules.md +32 -32
  52. package/template/.claude/skills/hallmark/SKILL.md +552 -552
  53. package/template/.claude/skills/hallmark/references/anti-patterns.md +412 -412
  54. package/template/.claude/skills/hallmark/references/assets.md +406 -406
  55. package/template/.claude/skills/hallmark/references/color.md +95 -95
  56. package/template/.claude/skills/hallmark/references/component-cookbook.md +256 -256
  57. package/template/.claude/skills/hallmark/references/components/c1-outlined-chip.md +12 -12
  58. package/template/.claude/skills/hallmark/references/components/c2-inline-form-as-cta.md +16 -16
  59. package/template/.claude/skills/hallmark/references/components/c3-typographic-link.md +8 -8
  60. package/template/.claude/skills/hallmark/references/components/c4-sticky-bottom-bar.md +16 -16
  61. package/template/.claude/skills/hallmark/references/components/f1-bento-grid.md +20 -20
  62. package/template/.claude/skills/hallmark/references/components/f2-sticky-scroll-stack.md +20 -20
  63. package/template/.claude/skills/hallmark/references/components/f3-tabular-spec-sheet.md +11 -11
  64. package/template/.claude/skills/hallmark/references/components/f4-step-sequence.md +11 -11
  65. package/template/.claude/skills/hallmark/references/components/f5-annotated-screenshot.md +11 -11
  66. package/template/.claude/skills/hallmark/references/components/f6-product-card-grid.md +41 -41
  67. package/template/.claude/skills/hallmark/references/components/ft1-mast-headed.md +13 -13
  68. package/template/.claude/skills/hallmark/references/components/ft2-inline-rule-single-line.md +10 -10
  69. package/template/.claude/skills/hallmark/references/components/ft3-index-style-category-list.md +12 -12
  70. package/template/.claude/skills/hallmark/references/components/ft4-dense-typographic.md +10 -10
  71. package/template/.claude/skills/hallmark/references/components/ft5-statement.md +21 -21
  72. package/template/.claude/skills/hallmark/references/components/ft6-letter-close.md +19 -19
  73. package/template/.claude/skills/hallmark/references/components/ft7-newsletter-first.md +27 -27
  74. package/template/.claude/skills/hallmark/references/components/ft8-marquee-scroll.md +25 -25
  75. package/template/.claude/skills/hallmark/references/components/h1-marquee.md +15 -15
  76. package/template/.claude/skills/hallmark/references/components/h2-split-diptych.md +15 -15
  77. package/template/.claude/skills/hallmark/references/components/h3-quote-led.md +11 -11
  78. package/template/.claude/skills/hallmark/references/components/h4-stat-led.md +14 -14
  79. package/template/.claude/skills/hallmark/references/components/h5-letter-hero.md +11 -11
  80. package/template/.claude/skills/hallmark/references/components/h6-photographic-fold.md +16 -16
  81. package/template/.claude/skills/hallmark/references/components/h7-demo-video-clipped-by-viewport-edge.md +27 -27
  82. package/template/.claude/skills/hallmark/references/components/h8-mockup-split-browser-framed.md +23 -23
  83. package/template/.claude/skills/hallmark/references/components/h9-custom-illustration-centerpiece.md +27 -27
  84. package/template/.claude/skills/hallmark/references/components/n1-wordmark-2-links.md +12 -12
  85. package/template/.claude/skills/hallmark/references/components/n10-floating-on-scroll-morph.md +19 -19
  86. package/template/.claude/skills/hallmark/references/components/n2-floating-chip.md +14 -14
  87. package/template/.claude/skills/hallmark/references/components/n3-side-rail.md +14 -14
  88. package/template/.claude/skills/hallmark/references/components/n4-hidden-behind-k.md +9 -9
  89. package/template/.claude/skills/hallmark/references/components/n5-floating-pill.md +28 -28
  90. package/template/.claude/skills/hallmark/references/components/n6-newspaper-masthead.md +24 -24
  91. package/template/.claude/skills/hallmark/references/components/n7-brutal-slab.md +22 -22
  92. package/template/.claude/skills/hallmark/references/components/n8-terminal-command.md +21 -21
  93. package/template/.claude/skills/hallmark/references/components/n9-edge-aligned-minimal.md +17 -17
  94. package/template/.claude/skills/hallmark/references/components/s1-left-margin-numbered.md +15 -15
  95. package/template/.claude/skills/hallmark/references/components/s2-hanging.md +13 -13
  96. package/template/.claude/skills/hallmark/references/components/s3-sticky-pinned.md +19 -19
  97. package/template/.claude/skills/hallmark/references/components/s4-inline-no-break.md +11 -11
  98. package/template/.claude/skills/hallmark/references/components/s5-bottom-anchored.md +13 -13
  99. package/template/.claude/skills/hallmark/references/components/t1-pull-quote-with-marginalia.md +12 -12
  100. package/template/.claude/skills/hallmark/references/components/t2-logo-wall-hairline.md +19 -19
  101. package/template/.claude/skills/hallmark/references/components/t3-single-huge-quote.md +11 -11
  102. package/template/.claude/skills/hallmark/references/components/t4-numbered-stat-strip.md +14 -14
  103. package/template/.claude/skills/hallmark/references/contract.md +24 -24
  104. package/template/.claude/skills/hallmark/references/copy.md +182 -182
  105. package/template/.claude/skills/hallmark/references/custom-craft.md +626 -626
  106. package/template/.claude/skills/hallmark/references/custom-theme.md +329 -329
  107. package/template/.claude/skills/hallmark/references/design-md.md +116 -116
  108. package/template/.claude/skills/hallmark/references/export-formats.md +328 -328
  109. package/template/.claude/skills/hallmark/references/floating-nav.md +89 -89
  110. package/template/.claude/skills/hallmark/references/genres/atmospheric.md +65 -65
  111. package/template/.claude/skills/hallmark/references/genres/editorial.md +70 -70
  112. package/template/.claude/skills/hallmark/references/genres/modern-minimal.md +67 -67
  113. package/template/.claude/skills/hallmark/references/genres/playful.md +65 -65
  114. package/template/.claude/skills/hallmark/references/hero-enrichment.md +474 -474
  115. package/template/.claude/skills/hallmark/references/imagery-kit.md +170 -170
  116. package/template/.claude/skills/hallmark/references/interaction-and-states.md +207 -207
  117. package/template/.claude/skills/hallmark/references/layout-and-space.md +111 -111
  118. package/template/.claude/skills/hallmark/references/macrostructures/01-bento-grid.md +35 -35
  119. package/template/.claude/skills/hallmark/references/macrostructures/02-long-document.md +34 -34
  120. package/template/.claude/skills/hallmark/references/macrostructures/03-marquee-hero.md +31 -31
  121. package/template/.claude/skills/hallmark/references/macrostructures/04-stat-led.md +32 -32
  122. package/template/.claude/skills/hallmark/references/macrostructures/05-workbench.md +32 -32
  123. package/template/.claude/skills/hallmark/references/macrostructures/06-conversational-faq.md +33 -33
  124. package/template/.claude/skills/hallmark/references/macrostructures/07-manifesto.md +32 -32
  125. package/template/.claude/skills/hallmark/references/macrostructures/08-photographic.md +34 -34
  126. package/template/.claude/skills/hallmark/references/macrostructures/09-quote-led.md +32 -32
  127. package/template/.claude/skills/hallmark/references/macrostructures/10-specimen.md +32 -32
  128. package/template/.claude/skills/hallmark/references/macrostructures/11-catalogue.md +23 -23
  129. package/template/.claude/skills/hallmark/references/macrostructures/12-letter.md +23 -23
  130. package/template/.claude/skills/hallmark/references/macrostructures/13-index-first.md +23 -23
  131. package/template/.claude/skills/hallmark/references/macrostructures/14-narrative-workflow.md +23 -23
  132. package/template/.claude/skills/hallmark/references/macrostructures/15-split-studio.md +23 -23
  133. package/template/.claude/skills/hallmark/references/macrostructures/16-feature-stack.md +23 -23
  134. package/template/.claude/skills/hallmark/references/macrostructures/17-type-specimen.md +23 -23
  135. package/template/.claude/skills/hallmark/references/macrostructures/18-portfolio-grid.md +23 -23
  136. package/template/.claude/skills/hallmark/references/macrostructures/19-map-diagram.md +23 -23
  137. package/template/.claude/skills/hallmark/references/macrostructures/20-ecosystem-index.md +23 -23
  138. package/template/.claude/skills/hallmark/references/macrostructures/21-component-playground.md +23 -23
  139. package/template/.claude/skills/hallmark/references/macrostructures.md +89 -89
  140. package/template/.claude/skills/hallmark/references/microinteractions.md +260 -260
  141. package/template/.claude/skills/hallmark/references/motion.md +109 -109
  142. package/template/.claude/skills/hallmark/references/preview-examples.md +49 -49
  143. package/template/.claude/skills/hallmark/references/responsive.md +138 -138
  144. package/template/.claude/skills/hallmark/references/slop-test.md +205 -205
  145. package/template/.claude/skills/hallmark/references/structure.md +164 -164
  146. package/template/.claude/skills/hallmark/references/study.md +511 -511
  147. package/template/.claude/skills/hallmark/references/typography.md +243 -243
  148. package/template/.claude/skills/hallmark/references/verbs/audit.md +25 -25
  149. package/template/.claude/skills/hallmark/references/verbs/redesign.md +269 -269
  150. package/template/.claude/skills/hallmark-loop/SKILL.md +105 -105
  151. package/template/.claude/skills/hallmark-loop/references/auditor-call.md +60 -60
  152. package/template/.claude/skills/hallmark-loop/references/capture.md +78 -78
  153. package/template/.claude/skills/hallmark-loop/references/loop-control.md +79 -79
  154. package/template/.claude/skills/handoff/SKILL.md +15 -15
  155. package/template/.claude/skills/knowledge-crunching/SKILL.md +94 -94
  156. package/template/.claude/skills/research/SKILL.md +69 -69
  157. package/template/.claude/skills/tdd/SKILL.md +142 -142
  158. package/template/.claude/skills/tdd/deep-modules.md +15 -15
  159. package/template/.claude/skills/tdd/interface-design.md +31 -31
  160. package/template/.claude/skills/tdd/mocking.md +59 -59
  161. package/template/.claude/skills/tdd/refactoring.md +10 -10
  162. package/template/.claude/skills/tdd/tests.md +61 -61
  163. package/template/.claude/statusline.cjs +100 -37
@@ -1,142 +1,142 @@
1
- ---
2
- name: tdd
3
- description: Test-driven development with red-green-refactor loop. Use when user wants to build features or fix bugs using TDD, mentions "red-green-refactor", wants integration tests, or asks for test-first development.
4
- ---
5
-
6
- # Test-Driven Development
7
-
8
- ## Philosophy
9
-
10
- **Core principle**: Tests should verify behavior through public interfaces, not implementation details. Code can change entirely; tests shouldn't.
11
-
12
- **Good tests** are integration-style: they exercise real code paths through public APIs. They describe _what_ the system does, not _how_ it does it. A good test reads like a specification - "user can checkout with valid cart" tells you exactly what capability exists. These tests survive refactors because they don't care about internal structure.
13
-
14
- **Bad tests** are coupled to implementation. They mock internal collaborators, test private methods, or verify through external means (like querying a database directly instead of using the interface). The warning sign: your test breaks when you refactor, but behavior hasn't changed. If you rename an internal function and tests fail, those tests were testing implementation, not behavior.
15
-
16
- Note: "integration-_style_" here means _through the public surface_ — it is **not** the same as an out-of-process "integration test" (real HTTP + real DB). Which layer uses which is settled in [Build inside-out, and match the test to the layer](#build-inside-out-and-match-the-test-to-the-layer) below.
17
-
18
- See [tests.md](tests.md) for examples and [mocking.md](mocking.md) for mocking guidelines.
19
-
20
- ## Anti-Pattern: Horizontal Slices
21
-
22
- **DO NOT write all tests first, then all implementation.** This is "horizontal slicing" - treating RED as "write all tests" and GREEN as "write all code."
23
-
24
- This produces **crap tests**:
25
-
26
- - Tests written in bulk test _imagined_ behavior, not _actual_ behavior
27
- - You end up testing the _shape_ of things (data structures, function signatures) rather than user-facing behavior
28
- - Tests become insensitive to real changes - they pass when behavior breaks, fail when behavior is fine
29
- - You outrun your headlights, committing to test structure before understanding the implementation
30
-
31
- **Correct approach**: Vertical slices via tracer bullets. One test → one implementation → repeat. Each test responds to what you learned from the previous cycle. Because you just wrote the code, you know exactly what behavior matters and how to verify it.
32
-
33
- ```
34
- WRONG (horizontal):
35
- RED: test1, test2, test3, test4, test5
36
- GREEN: impl1, impl2, impl3, impl4, impl5
37
-
38
- RIGHT (vertical):
39
- RED→GREEN: test1→impl1
40
- RED→GREEN: test2→impl2
41
- RED→GREEN: test3→impl3
42
- ...
43
- ```
44
-
45
- ## Build inside-out, and match the test to the layer
46
-
47
- Grow a feature from the **domain core outward** — never build the whole stack and test at the end.
48
- Test-drive each layer as you reach it; the _kind_ of first test follows the layer:
49
-
50
- | Layer | First test | Project |
51
- |---|---|---|
52
- | Domain | **unit** | `*.Domain.UnitTests` |
53
- | Application (handlers) | **unit**, mocking only boundaries (repository, clock, LLM) | `*.Application.UnitTests` |
54
- | Contracts | **unit** only if they carry logic | — |
55
- | Infrastructure + API (outer edge) | **integration** — one suite, real HTTP + real DB | `*.IntegrationTests` |
56
-
57
- Order: **domain → application → outer edge.** The integration suite boots the _composed app_, so the
58
- real EF mapping/repository only runs through it — there is no separate infra test before the API.
59
-
60
- "Integration-_style_" (Philosophy: through the public surface) ≠ "integration _test_" (out-of-process,
61
- real HTTP + DB). Don't conflate them.
62
-
63
- See [test-per-layer.md](test-per-layer.md): why "first" is per-layer and red-green-refactor stays
64
- intact; why integration tests are few-but-load-bearing, not cosmetic; and how many ACs to
65
- integration-test.
66
-
67
- ## Build configuration (strict gates)
68
-
69
- Treat the build as a quality gate, not just "it compiled". The solution should enforce
70
- warnings-as-errors, code-style, and full security analysis via a root `Directory.Build.props`
71
- (`TreatWarningsAsErrors`, `EnforceCodeStyleInBuild`, `AnalysisLevel=latest-recommended`,
72
- `AnalysisModeSecurity=All`). Ensure these are present — see
73
- [dotnet-build-config.md](dotnet-build-config.md) (reference: [assets/Directory.Build.props](assets/Directory.Build.props)).
74
-
75
- ## Workflow
76
-
77
- ### 1. Planning
78
-
79
- When exploring the codebase, use the project's domain glossary so that test names and interface vocabulary match the project's language, and respect ADRs in the area you're touching.
80
-
81
- **Default to the full flow. Do not ask the user to approve the plan or choose scope — decide and build.** When the task names a behavior (e.g. a story/AC set), implement the entire vertical slice for it: domain → application → outer edge, every layer that the behavior touches, inside-out (see the layer table). "Backend only" / "frontend only" scopes the stack, not the depth — go all the way down the named side. Pick the sensible default for any open decision, state it in one line, and proceed. Only stop to ask if a choice is genuinely irreversible or the requirements truly contradict each other — not merely because more than one option exists.
82
-
83
- Before writing any code, work this out for yourself (no approval gate):
84
-
85
- - [ ] Decide what interface changes are needed
86
- - [ ] List the behaviors to test, ordered (not implementation steps) — cover every AC of the named work
87
- - [ ] Identify opportunities for [deep modules](deep-modules.md) (small interface, deep implementation)
88
- - [ ] Design interfaces for [testability](interface-design.md)
89
- - [ ] Identify the layer(s) you're touching and the matching first-test type (see the layer table)
90
-
91
- State the plan in one short message, then immediately start the tracer-bullet loop in the same turn.
92
-
93
- **You can't test everything**, but the named behavior's ACs are all in scope. Focus extra effort on critical paths and complex logic; don't burn cycles on every theoretical edge case beyond the spec.
94
-
95
- ### 2. Tracer Bullet
96
-
97
- Write ONE test that confirms ONE thing about the system:
98
-
99
- ```
100
- RED: Write test for first behavior → test fails
101
- GREEN: Write minimal code to pass → test passes
102
- ```
103
-
104
- This is your tracer bullet - proves the path works end-to-end.
105
-
106
- ### 3. Incremental Loop
107
-
108
- For each remaining behavior:
109
-
110
- ```
111
- RED: Write next test → fails
112
- GREEN: Minimal code to pass → passes
113
- ```
114
-
115
- Rules:
116
-
117
- - One test at a time
118
- - Only enough code to pass current test
119
- - Don't anticipate future tests
120
- - Keep tests focused on observable behavior
121
-
122
- ### 4. Refactor
123
-
124
- After all tests pass, look for [refactor candidates](refactoring.md):
125
-
126
- - [ ] Extract duplication
127
- - [ ] Deepen modules (move complexity behind simple interfaces)
128
- - [ ] Apply SOLID principles where natural
129
- - [ ] Consider what new code reveals about existing code
130
- - [ ] Run tests after each refactor step
131
-
132
- **Never refactor while RED.** Get to GREEN first.
133
-
134
- ## Checklist Per Cycle
135
-
136
- ```
137
- [ ] Test describes behavior, not implementation
138
- [ ] Test uses public interface only
139
- [ ] Test would survive internal refactor
140
- [ ] Code is minimal for this test
141
- [ ] No speculative features added
142
- ```
1
+ ---
2
+ name: tdd
3
+ description: Test-driven development with red-green-refactor loop. Use when user wants to build features or fix bugs using TDD, mentions "red-green-refactor", wants integration tests, or asks for test-first development.
4
+ ---
5
+
6
+ # Test-Driven Development
7
+
8
+ ## Philosophy
9
+
10
+ **Core principle**: Tests should verify behavior through public interfaces, not implementation details. Code can change entirely; tests shouldn't.
11
+
12
+ **Good tests** are integration-style: they exercise real code paths through public APIs. They describe _what_ the system does, not _how_ it does it. A good test reads like a specification - "user can checkout with valid cart" tells you exactly what capability exists. These tests survive refactors because they don't care about internal structure.
13
+
14
+ **Bad tests** are coupled to implementation. They mock internal collaborators, test private methods, or verify through external means (like querying a database directly instead of using the interface). The warning sign: your test breaks when you refactor, but behavior hasn't changed. If you rename an internal function and tests fail, those tests were testing implementation, not behavior.
15
+
16
+ Note: "integration-_style_" here means _through the public surface_ — it is **not** the same as an out-of-process "integration test" (real HTTP + real DB). Which layer uses which is settled in [Build inside-out, and match the test to the layer](#build-inside-out-and-match-the-test-to-the-layer) below.
17
+
18
+ See [tests.md](tests.md) for examples and [mocking.md](mocking.md) for mocking guidelines.
19
+
20
+ ## Anti-Pattern: Horizontal Slices
21
+
22
+ **DO NOT write all tests first, then all implementation.** This is "horizontal slicing" - treating RED as "write all tests" and GREEN as "write all code."
23
+
24
+ This produces **crap tests**:
25
+
26
+ - Tests written in bulk test _imagined_ behavior, not _actual_ behavior
27
+ - You end up testing the _shape_ of things (data structures, function signatures) rather than user-facing behavior
28
+ - Tests become insensitive to real changes - they pass when behavior breaks, fail when behavior is fine
29
+ - You outrun your headlights, committing to test structure before understanding the implementation
30
+
31
+ **Correct approach**: Vertical slices via tracer bullets. One test → one implementation → repeat. Each test responds to what you learned from the previous cycle. Because you just wrote the code, you know exactly what behavior matters and how to verify it.
32
+
33
+ ```
34
+ WRONG (horizontal):
35
+ RED: test1, test2, test3, test4, test5
36
+ GREEN: impl1, impl2, impl3, impl4, impl5
37
+
38
+ RIGHT (vertical):
39
+ RED→GREEN: test1→impl1
40
+ RED→GREEN: test2→impl2
41
+ RED→GREEN: test3→impl3
42
+ ...
43
+ ```
44
+
45
+ ## Build inside-out, and match the test to the layer
46
+
47
+ Grow a feature from the **domain core outward** — never build the whole stack and test at the end.
48
+ Test-drive each layer as you reach it; the _kind_ of first test follows the layer:
49
+
50
+ | Layer | First test | Project |
51
+ |---|---|---|
52
+ | Domain | **unit** | `*.Domain.UnitTests` |
53
+ | Application (handlers) | **unit**, mocking only boundaries (repository, clock, LLM) | `*.Application.UnitTests` |
54
+ | Contracts | **unit** only if they carry logic | — |
55
+ | Infrastructure + API (outer edge) | **integration** — one suite, real HTTP + real DB | `*.IntegrationTests` |
56
+
57
+ Order: **domain → application → outer edge.** The integration suite boots the _composed app_, so the
58
+ real EF mapping/repository only runs through it — there is no separate infra test before the API.
59
+
60
+ "Integration-_style_" (Philosophy: through the public surface) ≠ "integration _test_" (out-of-process,
61
+ real HTTP + DB). Don't conflate them.
62
+
63
+ See [test-per-layer.md](test-per-layer.md): why "first" is per-layer and red-green-refactor stays
64
+ intact; why integration tests are few-but-load-bearing, not cosmetic; and how many ACs to
65
+ integration-test.
66
+
67
+ ## Build configuration (strict gates)
68
+
69
+ Treat the build as a quality gate, not just "it compiled". The solution should enforce
70
+ warnings-as-errors, code-style, and full security analysis via a root `Directory.Build.props`
71
+ (`TreatWarningsAsErrors`, `EnforceCodeStyleInBuild`, `AnalysisLevel=latest-recommended`,
72
+ `AnalysisModeSecurity=All`). Ensure these are present — see
73
+ [dotnet-build-config.md](dotnet-build-config.md) (reference: [assets/Directory.Build.props](assets/Directory.Build.props)).
74
+
75
+ ## Workflow
76
+
77
+ ### 1. Planning
78
+
79
+ When exploring the codebase, use the project's domain glossary so that test names and interface vocabulary match the project's language, and respect ADRs in the area you're touching.
80
+
81
+ **Default to the full flow. Do not ask the user to approve the plan or choose scope — decide and build.** When the task names a behavior (e.g. a story/AC set), implement the entire vertical slice for it: domain → application → outer edge, every layer that the behavior touches, inside-out (see the layer table). "Backend only" / "frontend only" scopes the stack, not the depth — go all the way down the named side. Pick the sensible default for any open decision, state it in one line, and proceed. Only stop to ask if a choice is genuinely irreversible or the requirements truly contradict each other — not merely because more than one option exists.
82
+
83
+ Before writing any code, work this out for yourself (no approval gate):
84
+
85
+ - [ ] Decide what interface changes are needed
86
+ - [ ] List the behaviors to test, ordered (not implementation steps) — cover every AC of the named work
87
+ - [ ] Identify opportunities for [deep modules](deep-modules.md) (small interface, deep implementation)
88
+ - [ ] Design interfaces for [testability](interface-design.md)
89
+ - [ ] Identify the layer(s) you're touching and the matching first-test type (see the layer table)
90
+
91
+ State the plan in one short message, then immediately start the tracer-bullet loop in the same turn.
92
+
93
+ **You can't test everything**, but the named behavior's ACs are all in scope. Focus extra effort on critical paths and complex logic; don't burn cycles on every theoretical edge case beyond the spec.
94
+
95
+ ### 2. Tracer Bullet
96
+
97
+ Write ONE test that confirms ONE thing about the system:
98
+
99
+ ```
100
+ RED: Write test for first behavior → test fails
101
+ GREEN: Write minimal code to pass → test passes
102
+ ```
103
+
104
+ This is your tracer bullet - proves the path works end-to-end.
105
+
106
+ ### 3. Incremental Loop
107
+
108
+ For each remaining behavior:
109
+
110
+ ```
111
+ RED: Write next test → fails
112
+ GREEN: Minimal code to pass → passes
113
+ ```
114
+
115
+ Rules:
116
+
117
+ - One test at a time
118
+ - Only enough code to pass current test
119
+ - Don't anticipate future tests
120
+ - Keep tests focused on observable behavior
121
+
122
+ ### 4. Refactor
123
+
124
+ After all tests pass, look for [refactor candidates](refactoring.md):
125
+
126
+ - [ ] Extract duplication
127
+ - [ ] Deepen modules (move complexity behind simple interfaces)
128
+ - [ ] Apply SOLID principles where natural
129
+ - [ ] Consider what new code reveals about existing code
130
+ - [ ] Run tests after each refactor step
131
+
132
+ **Never refactor while RED.** Get to GREEN first.
133
+
134
+ ## Checklist Per Cycle
135
+
136
+ ```
137
+ [ ] Test describes behavior, not implementation
138
+ [ ] Test uses public interface only
139
+ [ ] Test would survive internal refactor
140
+ [ ] Code is minimal for this test
141
+ [ ] No speculative features added
142
+ ```
@@ -1,15 +1,15 @@
1
- # Deep Modules Summary
2
-
3
- The concept of deep modules comes from "A Philosophy of Software Design" and contrasts two design approaches:
4
-
5
- **Deep modules** feature a "small interface + lots of implementation." They expose minimal methods and parameters while concealing substantial internal complexity. This design reduces cognitive load for users of the module.
6
-
7
- **Shallow modules** present the opposite problem: they expose many methods with complex parameters but provide little substantive logic—essentially acting as thin wrappers.
8
-
9
- When designing module interfaces, the guidance is to consider three key questions:
10
-
11
- - Can the number of exposed methods be reduced?
12
- - Can parameter signatures be simplified?
13
- - Can additional complexity be internalized rather than exposed?
14
-
15
- The deep module approach represents superior software design because it maximizes the value delivered relative to the interface burden imposed on developers using that code.
1
+ # Deep Modules Summary
2
+
3
+ The concept of deep modules comes from "A Philosophy of Software Design" and contrasts two design approaches:
4
+
5
+ **Deep modules** feature a "small interface + lots of implementation." They expose minimal methods and parameters while concealing substantial internal complexity. This design reduces cognitive load for users of the module.
6
+
7
+ **Shallow modules** present the opposite problem: they expose many methods with complex parameters but provide little substantive logic—essentially acting as thin wrappers.
8
+
9
+ When designing module interfaces, the guidance is to consider three key questions:
10
+
11
+ - Can the number of exposed methods be reduced?
12
+ - Can parameter signatures be simplified?
13
+ - Can additional complexity be internalized rather than exposed?
14
+
15
+ The deep module approach represents superior software design because it maximizes the value delivered relative to the interface burden imposed on developers using that code.
@@ -1,31 +1,31 @@
1
- # Interface Design for Testability
2
-
3
- Good interfaces make testing natural:
4
-
5
- 1. **Accept dependencies, don't create them**
6
-
7
- ```typescript
8
- // Testable
9
- function processOrder(order, paymentGateway) {}
10
-
11
- // Hard to test
12
- function processOrder(order) {
13
- const gateway = new StripeGateway();
14
- }
15
- ```
16
-
17
- 2. **Return results, don't produce side effects**
18
-
19
- ```typescript
20
- // Testable
21
- function calculateDiscount(cart): Discount {}
22
-
23
- // Hard to test
24
- function applyDiscount(cart): void {
25
- cart.total -= discount;
26
- }
27
- ```
28
-
29
- 3. **Small surface area**
30
- - Fewer methods = fewer tests needed
31
- - Fewer params = simpler test setup
1
+ # Interface Design for Testability
2
+
3
+ Good interfaces make testing natural:
4
+
5
+ 1. **Accept dependencies, don't create them**
6
+
7
+ ```typescript
8
+ // Testable
9
+ function processOrder(order, paymentGateway) {}
10
+
11
+ // Hard to test
12
+ function processOrder(order) {
13
+ const gateway = new StripeGateway();
14
+ }
15
+ ```
16
+
17
+ 2. **Return results, don't produce side effects**
18
+
19
+ ```typescript
20
+ // Testable
21
+ function calculateDiscount(cart): Discount {}
22
+
23
+ // Hard to test
24
+ function applyDiscount(cart): void {
25
+ cart.total -= discount;
26
+ }
27
+ ```
28
+
29
+ 3. **Small surface area**
30
+ - Fewer methods = fewer tests needed
31
+ - Fewer params = simpler test setup
@@ -1,59 +1,59 @@
1
- # When to Mock
2
-
3
- Mock at **system boundaries** only:
4
-
5
- - External APIs (payment, email, etc.)
6
- - Databases (sometimes - prefer test DB)
7
- - Time/randomness
8
- - File system (sometimes)
9
-
10
- Don't mock:
11
-
12
- - Your own classes/modules
13
- - Internal collaborators
14
- - Anything you control
15
-
16
- ## Designing for Mockability
17
-
18
- At system boundaries, design interfaces that are easy to mock:
19
-
20
- **1. Use dependency injection**
21
-
22
- Pass external dependencies in rather than creating them internally:
23
-
24
- ```typescript
25
- // Easy to mock
26
- function processPayment(order, paymentClient) {
27
- return paymentClient.charge(order.total);
28
- }
29
-
30
- // Hard to mock
31
- function processPayment(order) {
32
- const client = new StripeClient(process.env.STRIPE_KEY);
33
- return client.charge(order.total);
34
- }
35
- ```
36
-
37
- **2. Prefer SDK-style interfaces over generic fetchers**
38
-
39
- Create specific functions for each external operation instead of one generic function with conditional logic:
40
-
41
- ```typescript
42
- // GOOD: Each function is independently mockable
43
- const api = {
44
- getUser: (id) => fetch(`/users/${id}`),
45
- getOrders: (userId) => fetch(`/users/${userId}/orders`),
46
- createOrder: (data) => fetch('/orders', { method: 'POST', body: data }),
47
- };
48
-
49
- // BAD: Mocking requires conditional logic inside the mock
50
- const api = {
51
- fetch: (endpoint, options) => fetch(endpoint, options),
52
- };
53
- ```
54
-
55
- The SDK approach means:
56
- - Each mock returns one specific shape
57
- - No conditional logic in test setup
58
- - Easier to see which endpoints a test exercises
59
- - Type safety per endpoint
1
+ # When to Mock
2
+
3
+ Mock at **system boundaries** only:
4
+
5
+ - External APIs (payment, email, etc.)
6
+ - Databases (sometimes - prefer test DB)
7
+ - Time/randomness
8
+ - File system (sometimes)
9
+
10
+ Don't mock:
11
+
12
+ - Your own classes/modules
13
+ - Internal collaborators
14
+ - Anything you control
15
+
16
+ ## Designing for Mockability
17
+
18
+ At system boundaries, design interfaces that are easy to mock:
19
+
20
+ **1. Use dependency injection**
21
+
22
+ Pass external dependencies in rather than creating them internally:
23
+
24
+ ```typescript
25
+ // Easy to mock
26
+ function processPayment(order, paymentClient) {
27
+ return paymentClient.charge(order.total);
28
+ }
29
+
30
+ // Hard to mock
31
+ function processPayment(order) {
32
+ const client = new StripeClient(process.env.STRIPE_KEY);
33
+ return client.charge(order.total);
34
+ }
35
+ ```
36
+
37
+ **2. Prefer SDK-style interfaces over generic fetchers**
38
+
39
+ Create specific functions for each external operation instead of one generic function with conditional logic:
40
+
41
+ ```typescript
42
+ // GOOD: Each function is independently mockable
43
+ const api = {
44
+ getUser: (id) => fetch(`/users/${id}`),
45
+ getOrders: (userId) => fetch(`/users/${userId}/orders`),
46
+ createOrder: (data) => fetch('/orders', { method: 'POST', body: data }),
47
+ };
48
+
49
+ // BAD: Mocking requires conditional logic inside the mock
50
+ const api = {
51
+ fetch: (endpoint, options) => fetch(endpoint, options),
52
+ };
53
+ ```
54
+
55
+ The SDK approach means:
56
+ - Each mock returns one specific shape
57
+ - No conditional logic in test setup
58
+ - Easier to see which endpoints a test exercises
59
+ - Type safety per endpoint
@@ -1,10 +1,10 @@
1
- # Refactor Candidates
2
-
3
- After TDD cycle, look for:
4
-
5
- - **Duplication** → Extract function/class
6
- - **Long methods** → Break into private helpers (keep tests on public interface)
7
- - **Shallow modules** → Combine or deepen
8
- - **Feature envy** → Move logic to where data lives
9
- - **Primitive obsession** → Introduce value objects
10
- - **Existing code** the new code reveals as problematic
1
+ # Refactor Candidates
2
+
3
+ After TDD cycle, look for:
4
+
5
+ - **Duplication** → Extract function/class
6
+ - **Long methods** → Break into private helpers (keep tests on public interface)
7
+ - **Shallow modules** → Combine or deepen
8
+ - **Feature envy** → Move logic to where data lives
9
+ - **Primitive obsession** → Introduce value objects
10
+ - **Existing code** the new code reveals as problematic
@@ -1,61 +1,61 @@
1
- # Good and Bad Tests
2
-
3
- ## Good Tests
4
-
5
- **Integration-style**: Test through real interfaces, not mocks of internal parts.
6
-
7
- ```typescript
8
- // GOOD: Tests observable behavior
9
- test("user can checkout with valid cart", async () => {
10
- const cart = createCart();
11
- cart.add(product);
12
- const result = await checkout(cart, paymentMethod);
13
- expect(result.status).toBe("confirmed");
14
- });
15
- ```
16
-
17
- Characteristics:
18
-
19
- - Tests behavior users/callers care about
20
- - Uses public API only
21
- - Survives internal refactors
22
- - Describes WHAT, not HOW
23
- - One logical assertion per test
24
-
25
- ## Bad Tests
26
-
27
- **Implementation-detail tests**: Coupled to internal structure.
28
-
29
- ```typescript
30
- // BAD: Tests implementation details
31
- test("checkout calls paymentService.process", async () => {
32
- const mockPayment = jest.mock(paymentService);
33
- await checkout(cart, payment);
34
- expect(mockPayment.process).toHaveBeenCalledWith(cart.total);
35
- });
36
- ```
37
-
38
- Red flags:
39
-
40
- - Mocking internal collaborators
41
- - Testing private methods
42
- - Asserting on call counts/order
43
- - Test breaks when refactoring without behavior change
44
- - Test name describes HOW not WHAT
45
- - Verifying through external means instead of interface
46
-
47
- ```typescript
48
- // BAD: Bypasses interface to verify
49
- test("createUser saves to database", async () => {
50
- await createUser({ name: "Alice" });
51
- const row = await db.query("SELECT * FROM users WHERE name = ?", ["Alice"]);
52
- expect(row).toBeDefined();
53
- });
54
-
55
- // GOOD: Verifies through interface
56
- test("createUser makes user retrievable", async () => {
57
- const user = await createUser({ name: "Alice" });
58
- const retrieved = await getUser(user.id);
59
- expect(retrieved.name).toBe("Alice");
60
- });
61
- ```
1
+ # Good and Bad Tests
2
+
3
+ ## Good Tests
4
+
5
+ **Integration-style**: Test through real interfaces, not mocks of internal parts.
6
+
7
+ ```typescript
8
+ // GOOD: Tests observable behavior
9
+ test("user can checkout with valid cart", async () => {
10
+ const cart = createCart();
11
+ cart.add(product);
12
+ const result = await checkout(cart, paymentMethod);
13
+ expect(result.status).toBe("confirmed");
14
+ });
15
+ ```
16
+
17
+ Characteristics:
18
+
19
+ - Tests behavior users/callers care about
20
+ - Uses public API only
21
+ - Survives internal refactors
22
+ - Describes WHAT, not HOW
23
+ - One logical assertion per test
24
+
25
+ ## Bad Tests
26
+
27
+ **Implementation-detail tests**: Coupled to internal structure.
28
+
29
+ ```typescript
30
+ // BAD: Tests implementation details
31
+ test("checkout calls paymentService.process", async () => {
32
+ const mockPayment = jest.mock(paymentService);
33
+ await checkout(cart, payment);
34
+ expect(mockPayment.process).toHaveBeenCalledWith(cart.total);
35
+ });
36
+ ```
37
+
38
+ Red flags:
39
+
40
+ - Mocking internal collaborators
41
+ - Testing private methods
42
+ - Asserting on call counts/order
43
+ - Test breaks when refactoring without behavior change
44
+ - Test name describes HOW not WHAT
45
+ - Verifying through external means instead of interface
46
+
47
+ ```typescript
48
+ // BAD: Bypasses interface to verify
49
+ test("createUser saves to database", async () => {
50
+ await createUser({ name: "Alice" });
51
+ const row = await db.query("SELECT * FROM users WHERE name = ?", ["Alice"]);
52
+ expect(row).toBeDefined();
53
+ });
54
+
55
+ // GOOD: Verifies through interface
56
+ test("createUser makes user retrievable", async () => {
57
+ const user = await createUser({ name: "Alice" });
58
+ const retrieved = await getUser(user.id);
59
+ expect(retrieved.name).toBe("Alice");
60
+ });
61
+ ```