@tplog/hasapi 0.1.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.
- package/LICENSE +21 -0
- package/README.md +54 -0
- package/bin/hasapi.mjs +292 -0
- package/hasapi-skills/README.md +56 -0
- package/hasapi-skills/_shared/common.md +240 -0
- package/hasapi-skills/_shared/custom-risks-guide.md +48 -0
- package/hasapi-skills/_shared/decay-risks.md +294 -0
- package/hasapi-skills/_shared/remedy-guide.md +37 -0
- package/hasapi-skills/_shared/source-coverage.md +248 -0
- package/hasapi-skills/_shared/test-decay-risks.md +246 -0
- package/hasapi-skills/hasapi-audit/SKILL.md +42 -0
- package/hasapi-skills/hasapi-audit/architecture-guide.md +195 -0
- package/hasapi-skills/hasapi-audit/onboarding-guide.md +89 -0
- package/hasapi-skills/hasapi-debt/SKILL.md +35 -0
- package/hasapi-skills/hasapi-debt/debt-guide.md +125 -0
- package/hasapi-skills/hasapi-diagnosing-bugs/SKILL.md +134 -0
- package/hasapi-skills/hasapi-diagnosing-bugs/scripts/hitl-loop.template.sh +41 -0
- package/hasapi-skills/hasapi-grilling/SKILL.md +10 -0
- package/hasapi-skills/hasapi-handoff/SKILL.md +16 -0
- package/hasapi-skills/hasapi-health/SKILL.md +37 -0
- package/hasapi-skills/hasapi-health/health-guide.md +89 -0
- package/hasapi-skills/hasapi-implement/SKILL.md +15 -0
- package/hasapi-skills/hasapi-resolving-merge-conflicts/SKILL.md +14 -0
- package/hasapi-skills/hasapi-review/SKILL.md +37 -0
- package/hasapi-skills/hasapi-review/pr-review-guide.md +163 -0
- package/hasapi-skills/hasapi-setup/SKILL.md +121 -0
- package/hasapi-skills/hasapi-setup/domain.md +51 -0
- package/hasapi-skills/hasapi-setup/issue-tracker-github.md +22 -0
- package/hasapi-skills/hasapi-setup/issue-tracker-gitlab.md +23 -0
- package/hasapi-skills/hasapi-setup/issue-tracker-local.md +19 -0
- package/hasapi-skills/hasapi-setup/triage-labels.md +15 -0
- package/hasapi-skills/hasapi-sweep/SKILL.md +38 -0
- package/hasapi-skills/hasapi-sweep/sweep-guide.md +264 -0
- package/hasapi-skills/hasapi-tdd/SKILL.md +108 -0
- package/hasapi-skills/hasapi-tdd/mocking.md +59 -0
- package/hasapi-skills/hasapi-tdd/refactoring.md +10 -0
- package/hasapi-skills/hasapi-tdd/tests.md +61 -0
- package/hasapi-skills/hasapi-test/SKILL.md +36 -0
- package/hasapi-skills/hasapi-test/test-guide.md +147 -0
- package/hasapi-skills/hasapi-to-issues/SKILL.md +84 -0
- package/hasapi-skills/hasapi-to-prd/SKILL.md +75 -0
- package/package.json +39 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# Test Decay Risk Reference
|
|
2
|
+
|
|
3
|
+
Six patterns that cause test suites to degrade. Apply the Iron Law to each finding.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Risk T1: Test Obscurity
|
|
8
|
+
|
|
9
|
+
**Diagnostic question:** How much effort does it take to understand what this test verifies?
|
|
10
|
+
|
|
11
|
+
Unclear test intent breeds distrust, missed failures, and duplicates — one step from an abandoned suite.
|
|
12
|
+
|
|
13
|
+
### Symptoms
|
|
14
|
+
|
|
15
|
+
- Assertion Roulette: multiple assertions with no message string — when one fails, it is
|
|
16
|
+
impossible to determine which behavior broke without reading every assertion
|
|
17
|
+
- Mystery Guest: test depends on external state (files, database rows, shared fixtures)
|
|
18
|
+
that is not visible in the test body
|
|
19
|
+
- Test names that do not express the scenario and expected outcome
|
|
20
|
+
(e.g., `test1`, `shouldWork`, `testLogin`, `testUserService`)
|
|
21
|
+
- General Fixture: an oversized setUp or beforeEach shared by unrelated tests, making
|
|
22
|
+
each test's preconditions invisible
|
|
23
|
+
- Test body requires reading production code to understand what is being verified
|
|
24
|
+
|
|
25
|
+
### Sources
|
|
26
|
+
|
|
27
|
+
| Symptom | Book | Principle / Smell |
|
|
28
|
+
|---------|------|-------------------|
|
|
29
|
+
| Assertion Roulette | Meszaros — xUnit Test Patterns | Assertion Roulette (p.224) |
|
|
30
|
+
| Mystery Guest | Meszaros — xUnit Test Patterns | Mystery Guest (p.411) |
|
|
31
|
+
| General Fixture | Meszaros — xUnit Test Patterns | General Fixture (p.316) |
|
|
32
|
+
| Test naming | Osherove — The Art of Unit Testing | method_scenario_expected naming convention |
|
|
33
|
+
|
|
34
|
+
### Severity Guide
|
|
35
|
+
|
|
36
|
+
- 🔴 Critical: no test name in the file describes the behavior being tested; all assertions lack messages
|
|
37
|
+
- 🟡 Warning: multiple Mystery Guests; several ambiguous test names
|
|
38
|
+
- 🟢 Suggestion: minor naming issues; isolated General Fixture
|
|
39
|
+
|
|
40
|
+
### What Not to Flag
|
|
41
|
+
|
|
42
|
+
- Multiple assertions are acceptable when they describe one coherent behavior and fail with a clear story
|
|
43
|
+
- Shared setup is fine when every initialized value is relevant to nearly every test
|
|
44
|
+
- Concise test names are acceptable if scenario and expected outcome are still obvious
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Risk T2: Test Brittleness
|
|
49
|
+
|
|
50
|
+
**Diagnostic question:** Do tests break when you refactor without changing behavior?
|
|
51
|
+
|
|
52
|
+
Brittle tests punish refactoring — eventually developers stop refactoring and the codebase stagnates to protect the suite.
|
|
53
|
+
|
|
54
|
+
### Symptoms
|
|
55
|
+
|
|
56
|
+
- Tests assert on private method results, internal state, or implementation details
|
|
57
|
+
rather than observable behavior
|
|
58
|
+
- Eager Test: one test method verifies multiple unrelated behaviors; any single change
|
|
59
|
+
causes it to fail regardless of which behavior was touched
|
|
60
|
+
- Over-specified: assertions enforce mock call order or exact parameter values that are
|
|
61
|
+
irrelevant to the behavior being tested
|
|
62
|
+
- Renaming or extracting a method causes 5 or more tests to fail even though no behavior changed
|
|
63
|
+
- Erratic Test: a test produces different results across runs without any change to
|
|
64
|
+
production code — caused by race conditions, time-dependent logic, random data, or
|
|
65
|
+
shared mutable state between tests
|
|
66
|
+
|
|
67
|
+
### Sources
|
|
68
|
+
|
|
69
|
+
| Symptom | Book | Principle / Smell |
|
|
70
|
+
|---------|------|-------------------|
|
|
71
|
+
| Eager Test | Meszaros — xUnit Test Patterns | Eager Test (p.228) |
|
|
72
|
+
| Erratic Test | Meszaros — xUnit Test Patterns | Erratic Test |
|
|
73
|
+
| Implementation coupling | Osherove — The Art of Unit Testing | Test isolation principle |
|
|
74
|
+
| Orthogonality violation | Hunt & Thomas — The Pragmatic Programmer | Ch. 2: Orthogonality |
|
|
75
|
+
|
|
76
|
+
### Severity Guide
|
|
77
|
+
|
|
78
|
+
- 🔴 Critical: refactoring with no behavior change causes test failures; > 5 tests coupled to a single implementation detail
|
|
79
|
+
- 🟡 Warning: Eager Tests common across the suite; moderate implementation-detail assertions
|
|
80
|
+
- 🟢 Suggestion: isolated over-specification in non-critical tests
|
|
81
|
+
|
|
82
|
+
### What Not to Flag
|
|
83
|
+
|
|
84
|
+
- Verifying an externally observable event or emitted command is not implementation coupling
|
|
85
|
+
- One test with several assertions is acceptable when all assertions support one behavior claim
|
|
86
|
+
- A fake or in-memory adapter is not brittleness if the test still asserts behavior, not wiring
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Risk T3: Test Duplication
|
|
91
|
+
|
|
92
|
+
**Diagnostic question:** Is the same test scenario expressed in more than one place?
|
|
93
|
+
|
|
94
|
+
Duplicated tests must change in multiple places and create false confidence without testing distinct behavior.
|
|
95
|
+
|
|
96
|
+
### Symptoms
|
|
97
|
+
|
|
98
|
+
- Test Code Duplication: same setup or assertion logic copy-pasted across multiple tests
|
|
99
|
+
without extraction into a shared helper
|
|
100
|
+
- Lazy Test: multiple tests verifying identical behavior with no differentiation in input,
|
|
101
|
+
state, or expected output
|
|
102
|
+
- Same boundary condition tested identically at unit, integration, and E2E level —
|
|
103
|
+
three copies with no layer differentiation
|
|
104
|
+
- Test helper functions or fixtures duplicated across test files instead of shared
|
|
105
|
+
|
|
106
|
+
### Sources
|
|
107
|
+
|
|
108
|
+
| Symptom | Book | Principle / Smell |
|
|
109
|
+
|---------|------|-------------------|
|
|
110
|
+
| Test Code Duplication | Meszaros — xUnit Test Patterns | Test Code Duplication (p.213) |
|
|
111
|
+
| Lazy Test | Meszaros — xUnit Test Patterns | Lazy Test (p.232) |
|
|
112
|
+
| DRY violation in tests | Hunt & Thomas — The Pragmatic Programmer | DRY: Don't Repeat Yourself |
|
|
113
|
+
|
|
114
|
+
### Severity Guide
|
|
115
|
+
|
|
116
|
+
- 🔴 Critical: core business scenario fully duplicated across all three test layers with no differentiation
|
|
117
|
+
- 🟡 Warning: common scenario setup repeated in 5 or more tests without extraction
|
|
118
|
+
- 🟢 Suggestion: minor helper duplication; isolated Lazy Tests
|
|
119
|
+
|
|
120
|
+
### What Not to Flag
|
|
121
|
+
|
|
122
|
+
- The same scenario may appear at unit and integration level when each layer verifies a distinct risk
|
|
123
|
+
- Small local setup duplication can be clearer than an over-abstracted fixture maze
|
|
124
|
+
- Similar assertions against different domain rules are not Lazy Tests if the business intent differs
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Risk T4: Mock Abuse
|
|
129
|
+
|
|
130
|
+
**Diagnostic question:** Is the test more complex than the behavior it tests?
|
|
131
|
+
|
|
132
|
+
Mock abuse produces tests that pass while verifying nothing — production code can be fully broken as long as the mocks are wired up.
|
|
133
|
+
|
|
134
|
+
### Symptoms
|
|
135
|
+
|
|
136
|
+
- Mock setup code is longer than the test logic itself
|
|
137
|
+
- Primary assertion is `expect(mock).toHaveBeenCalledWith(...)` — the test verifies
|
|
138
|
+
that a mock was called, not that any real behavior occurred
|
|
139
|
+
- Test-only methods added to production classes for lifecycle management in tests
|
|
140
|
+
- Single unit test uses more than 3 mocks
|
|
141
|
+
- Incomplete Mock: mock object missing fields that downstream code will access,
|
|
142
|
+
causing silent failures only visible in integration
|
|
143
|
+
- Hard-Coded Test Data: test data has no resemblance to real data shapes or constraints
|
|
144
|
+
|
|
145
|
+
### Sources
|
|
146
|
+
|
|
147
|
+
| Symptom | Book | Principle / Smell |
|
|
148
|
+
|---------|------|-------------------|
|
|
149
|
+
| Mock count > 3 | Osherove — The Art of Unit Testing | Mock usage guidelines |
|
|
150
|
+
| Testing mock behavior | Meszaros — xUnit Test Patterns | Behavior Verification (p.544) |
|
|
151
|
+
| Test-only production methods | Feathers — Working Effectively with Legacy Code | Ch. 3: Sensing and Separation |
|
|
152
|
+
| Hard-Coded Test Data | Meszaros — xUnit Test Patterns | Hard-Coded Test Data (p.534) |
|
|
153
|
+
| Incomplete Mock | Osherove — The Art of Unit Testing | Mock completeness requirement |
|
|
154
|
+
|
|
155
|
+
### Severity Guide
|
|
156
|
+
|
|
157
|
+
- 🔴 Critical: mock setup > 50% of test code; production class has methods only called from tests
|
|
158
|
+
- 🟡 Warning: mocks consistently > 3 per test; primary assertions are mock call verifications
|
|
159
|
+
- 🟢 Suggestion: isolated Incomplete Mocks; minor Hard-Coded Test Data
|
|
160
|
+
|
|
161
|
+
### What Not to Flag
|
|
162
|
+
|
|
163
|
+
- A small number of mocks around nondeterministic dependencies is acceptable when assertions still verify behavior
|
|
164
|
+
- Fakes and spies used to observe state transitions are not mock abuse by default
|
|
165
|
+
- One interaction assertion may be appropriate when the interaction itself is the behavior under test
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Risk T5: Coverage Illusion
|
|
170
|
+
|
|
171
|
+
**Diagnostic question:** Does the test suite actually protect against the failures that matter?
|
|
172
|
+
|
|
173
|
+
Coverage measures execution, not verification. 90% line coverage can still miss every critical failure mode — teams stop looking because the number says "covered."
|
|
174
|
+
|
|
175
|
+
### Symptoms
|
|
176
|
+
|
|
177
|
+
- High line coverage but error-handling branches, boundary conditions, and exception paths
|
|
178
|
+
have no corresponding tests
|
|
179
|
+
- Happy-path only: no sad paths, no null/empty/zero inputs, no concurrency edge cases
|
|
180
|
+
- Legacy code areas are being actively modified with no tests present
|
|
181
|
+
(Feathers: "legacy code is code without tests")
|
|
182
|
+
- Coverage percentage treated as a sign-off criterion; critical change paths remain untested
|
|
183
|
+
- Tests assert on return values but not on important side effects such as database writes,
|
|
184
|
+
event publications, or state transitions
|
|
185
|
+
|
|
186
|
+
### Sources
|
|
187
|
+
|
|
188
|
+
| Symptom | Book | Principle / Smell |
|
|
189
|
+
|---------|------|-------------------|
|
|
190
|
+
| Legacy code = no tests | Feathers — Working Effectively with Legacy Code | Ch. 1: "Legacy code is code without tests" |
|
|
191
|
+
| Change coverage vs line coverage | Google — How Google Tests Software | Ch. 11: Testing at Google Scale |
|
|
192
|
+
| Happy-path only | Osherove — The Art of Unit Testing | Test completeness principle |
|
|
193
|
+
|
|
194
|
+
### Severity Guide
|
|
195
|
+
|
|
196
|
+
- 🔴 Critical: legacy code area actively being modified with no tests; error-handling paths entirely absent
|
|
197
|
+
- 🟡 Warning: coverage > 80% but edge and exception paths are systematically absent
|
|
198
|
+
- 🟢 Suggestion: a few non-critical paths missing sad-path tests
|
|
199
|
+
|
|
200
|
+
### What Not to Flag
|
|
201
|
+
|
|
202
|
+
- High line coverage is useful when paired with branch, boundary, and change-path coverage
|
|
203
|
+
- A new module may have limited coverage early if it is still private and low-risk
|
|
204
|
+
- Side-effect assertions may live in integration tests rather than unit tests without implying a gap
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Risk T6: Architecture Mismatch
|
|
209
|
+
|
|
210
|
+
**Diagnostic question:** Does the test suite structure reflect the system's actual risk profile?
|
|
211
|
+
|
|
212
|
+
Wrong suite shape is slow and expensive — not from bad tests, but from using the wrong type at the wrong layer.
|
|
213
|
+
|
|
214
|
+
### Symptoms
|
|
215
|
+
|
|
216
|
+
- Inverted test pyramid: E2E or integration test count exceeds unit test count,
|
|
217
|
+
causing a slow and fragile suite
|
|
218
|
+
- Legacy code with no seam points: no interfaces, dependency injection, or seams exist,
|
|
219
|
+
making it impossible to test in isolation without modifying production code
|
|
220
|
+
- Legacy areas being modified have no Characterization Tests to capture current behavior
|
|
221
|
+
before changes are made
|
|
222
|
+
- Full suite execution time exceeds 10 minutes (indicates architectural problem,
|
|
223
|
+
not a performance problem — too many slow tests)
|
|
224
|
+
- High-risk and low-risk paths are tested at identical density;
|
|
225
|
+
no risk-based prioritization in test distribution
|
|
226
|
+
|
|
227
|
+
### Sources
|
|
228
|
+
|
|
229
|
+
| Symptom | Book | Principle / Smell |
|
|
230
|
+
|---------|------|-------------------|
|
|
231
|
+
| Inverted pyramid | Google — How Google Tests Software | 70:20:10 unit:integration:E2E ratio |
|
|
232
|
+
| No seam points | Feathers — Working Effectively with Legacy Code | Ch. 4: Seam Model |
|
|
233
|
+
| Missing Characterization Tests | Feathers — Working Effectively with Legacy Code | Ch. 13: Characterization Tests |
|
|
234
|
+
| Suite execution time | Meszaros — xUnit Test Patterns | Slow Tests (p. 253) |
|
|
235
|
+
|
|
236
|
+
### Severity Guide
|
|
237
|
+
|
|
238
|
+
- 🔴 Critical: legacy code being modified has no seams and no characterization tests; pyramid fully inverted
|
|
239
|
+
- 🟡 Warning: suite execution > 10 minutes; integration/E2E count exceeds unit tests
|
|
240
|
+
- 🟢 Suggestion: localized pyramid ratio deviation; a few legacy areas missing characterization tests
|
|
241
|
+
|
|
242
|
+
### What Not to Flag
|
|
243
|
+
|
|
244
|
+
- Deviating from 70:20:10 can be justified by platform constraints or product risk
|
|
245
|
+
- A suite heavy on integration tests can still be healthy if feedback is fast and purposefully layered
|
|
246
|
+
- A small number of critical-path E2E tests is desirable, not a smell
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hasapi-audit
|
|
3
|
+
description: >
|
|
4
|
+
Architecture audit that maps module dependencies, checks layering integrity, and
|
|
5
|
+
flags structural decay across a codebase, drawing on twelve classic engineering books.
|
|
6
|
+
Triggers when: user asks to audit architecture, review folder/module structure,
|
|
7
|
+
check for circular imports, understand how the codebase is organized, or asks
|
|
8
|
+
"does this follow clean architecture?", "why does everything depend on everything?",
|
|
9
|
+
"are our layers correct?", "where should this code live?".
|
|
10
|
+
Also triggers for onboarding requests: "explain this codebase to a new developer"
|
|
11
|
+
or "give me a codebase tour" (use onboarding mode).
|
|
12
|
+
Do NOT trigger for: PR-level code review (use brooks-review) or line-level refactoring
|
|
13
|
+
questions — this skill analyzes structural/module-level concerns, not individual functions.
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Brooks-Lint — Architecture Audit
|
|
17
|
+
|
|
18
|
+
## Setup
|
|
19
|
+
|
|
20
|
+
1. Read `../_shared/common.md` for the Iron Law, Project Config, Report Template, and Health Score rules
|
|
21
|
+
2. Read `../_shared/source-coverage.md` for book-level coverage, exceptions, and tradeoffs
|
|
22
|
+
3. Read `../_shared/decay-risks.md` for symptom definitions and source attributions
|
|
23
|
+
4. Read `architecture-guide.md` in this directory for the audit framework
|
|
24
|
+
|
|
25
|
+
## Process
|
|
26
|
+
|
|
27
|
+
**Onboarding mode:** If the user asks for an onboarding report, codebase tour, or
|
|
28
|
+
"explain this codebase to a new developer", read `onboarding-guide.md` from this
|
|
29
|
+
directory and follow it instead of `architecture-guide.md`. This mode explains rather
|
|
30
|
+
than diagnoses — no Health Score, no Iron Law findings.
|
|
31
|
+
|
|
32
|
+
**If the user has not specified files or a directory to audit:** apply Auto Scope
|
|
33
|
+
Detection from `../_shared/common.md` to determine the audit scope before proceeding.
|
|
34
|
+
|
|
35
|
+
1. Gather codebase context and draw the module dependency graph as Mermaid (Steps 0–1 of the guide)
|
|
36
|
+
2. Scan for each decay risk in the order specified (Steps 2–4 of the guide)
|
|
37
|
+
3. Assign node colors in the Mermaid diagram based on findings (red/yellow/green) — after Step 4
|
|
38
|
+
4. Run the Testability Seam Assessment (Step 5 of the guide)
|
|
39
|
+
5. Run the Conway's Law check (Step 6 of the guide)
|
|
40
|
+
6. Output using the Report Template from common.md — Mermaid graph FIRST, then Findings
|
|
41
|
+
|
|
42
|
+
**Mode line in report:** `Architecture Audit`
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# Architecture Audit Guide — Mode 2
|
|
2
|
+
|
|
3
|
+
**Purpose:** Analyze the module and dependency structure of a system for decay risks that
|
|
4
|
+
operate at the architectural level. Every finding must follow the Iron Law:
|
|
5
|
+
Symptom → Source → Consequence → Remedy.
|
|
6
|
+
|
|
7
|
+
**Monorepo note:** Treat each deployable service or library as a top-level module. Draw
|
|
8
|
+
dependencies between services, not between their internal packages. Apply the Conway's Law
|
|
9
|
+
check at the service ownership level. Within a single service, apply standard module-level analysis.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Analysis Process
|
|
14
|
+
|
|
15
|
+
Work through these six steps in order.
|
|
16
|
+
|
|
17
|
+
### Step 0: Gather Codebase Context
|
|
18
|
+
|
|
19
|
+
Before drawing anything, establish what you can see.
|
|
20
|
+
|
|
21
|
+
**If the user provided a full directory tree or pasted relevant file contents:** skip the
|
|
22
|
+
proactive reading below and proceed to Step 1.
|
|
23
|
+
|
|
24
|
+
**Otherwise, proactively read the project using these tools:**
|
|
25
|
+
|
|
26
|
+
1. **Top-level structure** — glob top two levels to identify module boundaries:
|
|
27
|
+
```
|
|
28
|
+
Glob: **/*(depth 2, directories only)
|
|
29
|
+
```
|
|
30
|
+
2. **Entry points** — read the package manifest or main config file (e.g., `package.json`,
|
|
31
|
+
`go.mod`, `pom.xml`, `Cargo.toml`, `pyproject.toml`) to confirm language, framework,
|
|
32
|
+
and declared dependencies.
|
|
33
|
+
3. **Dependency edges** — grep import statements to discover inter-module calls. Run once
|
|
34
|
+
per language present; limit to the first 200 matches to avoid token overrun:
|
|
35
|
+
```
|
|
36
|
+
Grep: "^\s*(import|from|require\(|use )" across *.ts|*.py|*.go|*.rs|*.java
|
|
37
|
+
```
|
|
38
|
+
4. **Large modules** — for any top-level directory with > 10 files, read the file matching
|
|
39
|
+
`index.*`, `main.*`, or `__init__.*` to understand its stated responsibility.
|
|
40
|
+
|
|
41
|
+
**Stop when you can answer all three:**
|
|
42
|
+
- What are the top-level modules (names and count)?
|
|
43
|
+
- Which modules import from which other modules?
|
|
44
|
+
- Which module has the highest fan-in or fan-out?
|
|
45
|
+
|
|
46
|
+
If the project has > 100 top-level files or > 4 levels of nesting, note which areas were
|
|
47
|
+
sampled vs. inferred, and flag this in the report scope line.
|
|
48
|
+
|
|
49
|
+
### Step 1: Draw the Module Dependency Graph (Mermaid)
|
|
50
|
+
|
|
51
|
+
Before evaluating any risk, map the dependencies as a Mermaid diagram. Use this format:
|
|
52
|
+
|
|
53
|
+
````mermaid
|
|
54
|
+
graph TD
|
|
55
|
+
subgraph UI
|
|
56
|
+
WebApp
|
|
57
|
+
MobileApp
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
subgraph Domain
|
|
61
|
+
AuthService
|
|
62
|
+
OrderService
|
|
63
|
+
PaymentService
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
subgraph Infrastructure
|
|
67
|
+
Database
|
|
68
|
+
MessageQueue
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
WebApp --> AuthService
|
|
72
|
+
WebApp --> OrderService
|
|
73
|
+
MobileApp --> AuthService
|
|
74
|
+
MobileApp --> OrderService
|
|
75
|
+
OrderService --> PaymentService
|
|
76
|
+
OrderService --> Database
|
|
77
|
+
OrderService --> MessageQueue
|
|
78
|
+
PaymentService --> Database
|
|
79
|
+
AuthService -.->|circular| OrderService
|
|
80
|
+
|
|
81
|
+
classDef critical fill:#ff6b6b,stroke:#c92a2a,color:#fff
|
|
82
|
+
classDef warning fill:#ffd43b,stroke:#e67700
|
|
83
|
+
classDef clean fill:#51cf66,stroke:#2b8a3e,color:#fff
|
|
84
|
+
|
|
85
|
+
class PaymentService critical
|
|
86
|
+
class OrderService warning
|
|
87
|
+
class Database,MessageQueue,AuthService,WebApp,MobileApp clean
|
|
88
|
+
````
|
|
89
|
+
|
|
90
|
+
Draw the graph structure first — nodes, subgraphs, and edges — without any `classDef` or
|
|
91
|
+
`class` lines. You cannot assign colors until you have completed the risk scan in Steps 2–4.
|
|
92
|
+
|
|
93
|
+
**After completing Step 4**, return to this graph and add the `classDef` and `class` lines
|
|
94
|
+
based on findings. The example above shows the final colored output.
|
|
95
|
+
|
|
96
|
+
Rules:
|
|
97
|
+
1. **Nodes** — Use top-level directories or services as nodes, not individual files
|
|
98
|
+
2. **Grouping** — One `subgraph` per architectural layer or top-level directory (e.g., UI, Domain, Infrastructure)
|
|
99
|
+
3. **Edges** — Solid arrows (`-->`) point FROM the depending module TO the dependency; use dotted arrows with label (`-.->|circular|`) for circular dependencies. If no circular dependencies exist, use only solid arrows
|
|
100
|
+
4. **Node limit** — Keep the graph to ~50 nodes maximum; collapse low-risk leaf modules into their parent if needed
|
|
101
|
+
5. **Fan-out** — For any node with fan-out > 5, use a descriptive label: `HighFanOutModule["ModuleName (fan-out: 7)"]`
|
|
102
|
+
6. **Colors** — Apply `classDef` colors AFTER completing Steps 2-4: `critical` (red `#ff6b6b`) for nodes with Critical findings, `warning` (yellow `#ffd43b`) for Warning findings, `clean` (green `#51cf66`) for nodes with no findings or only Suggestions. If no findings at all, classify all nodes as `clean`
|
|
103
|
+
7. **Direction** — Default to `graph TD` (top-down); use `graph LR` only if the architecture is clearly a left-to-right pipeline
|
|
104
|
+
|
|
105
|
+
### Step 2: Scan for Dependency Disorder
|
|
106
|
+
|
|
107
|
+
*The most architecturally consequential risk — scan this first.*
|
|
108
|
+
|
|
109
|
+
Look for:
|
|
110
|
+
- Circular dependencies (any `-.->|circular|` edge in the map above)
|
|
111
|
+
- Arrows flowing upward (high-level domain depending on low-level infrastructure)
|
|
112
|
+
- Stable, widely-depended-on modules that import from frequently-changing modules
|
|
113
|
+
- Modules with fan-out > 5
|
|
114
|
+
- Absence of a clear layering rule (no consistent answer to "what depends on what?")
|
|
115
|
+
|
|
116
|
+
### Step 3: Scan for Domain Model Distortion
|
|
117
|
+
|
|
118
|
+
Look for:
|
|
119
|
+
- Do module names match the business domain vocabulary?
|
|
120
|
+
- Is there a layer called "services" that contains all the business logic while domain objects
|
|
121
|
+
are pure data structures?
|
|
122
|
+
- Are there modules that cross bounded context boundaries (e.g., billing logic in the user module)?
|
|
123
|
+
- Is there an anti-corruption layer where external systems interface with the domain?
|
|
124
|
+
|
|
125
|
+
### Step 4: Scan for Remaining Four Risks
|
|
126
|
+
|
|
127
|
+
Check each in turn:
|
|
128
|
+
|
|
129
|
+
**Knowledge Duplication:**
|
|
130
|
+
- Are there multiple modules implementing the same concept independently?
|
|
131
|
+
- Does the same domain concept appear under different names in different modules?
|
|
132
|
+
|
|
133
|
+
**Accidental Complexity:**
|
|
134
|
+
- Are there entire layers in the architecture that do not add value?
|
|
135
|
+
- Are there modules whose responsibility cannot be stated in one sentence?
|
|
136
|
+
|
|
137
|
+
**Change Propagation:**
|
|
138
|
+
- Which modules are "blast radius hotspots"? (A change here requires changes in many other modules)
|
|
139
|
+
- Does the dependency map reveal why certain features are slow to develop?
|
|
140
|
+
|
|
141
|
+
**Cognitive Overload:**
|
|
142
|
+
- Can the module responsibility of each module be stated in one sentence from its name alone?
|
|
143
|
+
- Would a new developer know which module to add a new feature to?
|
|
144
|
+
|
|
145
|
+
### Step 5: Testability Seam Assessment
|
|
146
|
+
|
|
147
|
+
A *seam* is a place in the architecture where behavior can be altered without editing source
|
|
148
|
+
code — typically an interface, a configuration point, or a dependency injection boundary.
|
|
149
|
+
Seam density is a proxy for testability and evolvability.
|
|
150
|
+
|
|
151
|
+
Scan for:
|
|
152
|
+
- **No seam at the infrastructure boundary**: can you replace a real database, file system,
|
|
153
|
+
or HTTP client with a test double without editing the module under test? If not, the
|
|
154
|
+
architecture forces integration tests where unit tests would suffice.
|
|
155
|
+
- **Seam collapse**: a module that was once testable in isolation has had its seams removed
|
|
156
|
+
(e.g., direct constructor instantiation replaced a dependency injection point, or a global
|
|
157
|
+
singleton replaced an injected collaborator).
|
|
158
|
+
- **Missing seam in legacy areas**: modules without an obvious injection point or interface
|
|
159
|
+
boundary — any change requires touching the entire call stack to substitute behavior.
|
|
160
|
+
|
|
161
|
+
If all modules have clear seams at their infrastructure boundaries → no finding.
|
|
162
|
+
|
|
163
|
+
If seams are absent or collapsed: flag as 🟡 Warning with a Remedy pointing to the specific
|
|
164
|
+
module and the injection point that needs to be restored or introduced.
|
|
165
|
+
|
|
166
|
+
Source: Feathers — Working Effectively with Legacy Code, Ch. 4: The Seam Model
|
|
167
|
+
|
|
168
|
+
### Step 6: Conway's Law Check
|
|
169
|
+
|
|
170
|
+
After the six-risk scan, assess the relationship between architecture and team structure:
|
|
171
|
+
|
|
172
|
+
- Does the module/service structure reflect the team structure?
|
|
173
|
+
(Conway's Law: "Organizations design systems that mirror their communication structure")
|
|
174
|
+
- If yes: is this intentional design or accidental coupling?
|
|
175
|
+
- A mismatch that causes cross-team coordination overhead for every feature is 🔴 Critical.
|
|
176
|
+
- A mismatch that is theoretical but not yet causing pain is 🟡 Warning.
|
|
177
|
+
- If team structure is unknown, note this as context missing and skip the check.
|
|
178
|
+
|
|
179
|
+
**Calibration examples:**
|
|
180
|
+
- 🔴 Critical: the Payments module is owned by Team A but contains auth logic owned by Team B —
|
|
181
|
+
every Payments change requires a sync meeting with Team B
|
|
182
|
+
- 🟡 Warning: two separate teams own the `utils/` and `helpers/` directories which do the same
|
|
183
|
+
things — theoretically painful but not yet causing release coordination issues
|
|
184
|
+
- Not a finding: a single team owns a monorepo with multiple logical modules — Conway's Law
|
|
185
|
+
misalignment requires *separate teams* to be meaningful
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Output
|
|
190
|
+
|
|
191
|
+
Use the standard Report Template from `../_shared/common.md`. Mode: Architecture Audit.
|
|
192
|
+
|
|
193
|
+
Place the Mermaid dependency graph FIRST under "Module Dependency Graph". Reference
|
|
194
|
+
relevant node names in findings. Add `classDef` color assignments LAST, after all
|
|
195
|
+
findings are identified.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Codebase Onboarding Guide
|
|
2
|
+
|
|
3
|
+
**Purpose:** Produce a newcomer-friendly tour of the codebase. This is NOT a diagnostic
|
|
4
|
+
report — no Health Score, no Iron Law findings. Focus on explanation and orientation.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Process
|
|
9
|
+
|
|
10
|
+
### Step 1: Map the Territory
|
|
11
|
+
|
|
12
|
+
- Read top-level structure (same as architecture-guide Step 0)
|
|
13
|
+
- Output: a plain-language overview of what each top-level module does (one sentence each)
|
|
14
|
+
- Group into layers: "Things users interact with", "Business logic", "Infrastructure"
|
|
15
|
+
|
|
16
|
+
### Step 2: Draw the Dependency Map
|
|
17
|
+
|
|
18
|
+
Draw the same Mermaid dependency graph as architecture audit Step 1, but color nodes by
|
|
19
|
+
**recommended reading order** using a DISTINCT palette from the severity palette
|
|
20
|
+
(which uses red/yellow/green). This avoids confusing "red = danger" with "red = read last":
|
|
21
|
+
|
|
22
|
+
- 🔵 Blue (`#339af0`): start here — entry points, core domain
|
|
23
|
+
- 🟣 Purple (`#9775fa`): read next — supporting modules
|
|
24
|
+
- ⚪ Gray (`#ced4da`): read last — infrastructure, generated code, utilities
|
|
25
|
+
|
|
26
|
+
Add numbered labels: `CoreModule["1. CoreModule"]`
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
classDef start fill:#339af0,color:#fff
|
|
30
|
+
classDef next fill:#9775fa,color:#fff
|
|
31
|
+
classDef last fill:#ced4da
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Step 3: Highlight Key Conventions
|
|
35
|
+
|
|
36
|
+
Identify and document patterns the codebase follows:
|
|
37
|
+
- Naming conventions (file naming, class naming, variable naming)
|
|
38
|
+
- Directory organization pattern (feature-based? layer-based? hybrid?)
|
|
39
|
+
- Error handling pattern (exceptions? result types? error codes?)
|
|
40
|
+
- Testing convention (co-located? separate directory? naming pattern?)
|
|
41
|
+
- Dependency injection pattern (if any)
|
|
42
|
+
|
|
43
|
+
### Step 4: Mark Danger Zones
|
|
44
|
+
|
|
45
|
+
For each module with known complexity or coupling issues, add a brief warning:
|
|
46
|
+
- "OrderService: high complexity, only modify with full test suite running"
|
|
47
|
+
- "legacy/: no tests, use Characterization Tests before changing"
|
|
48
|
+
|
|
49
|
+
Do NOT use Iron Law format — use plain warnings. This is orientation, not diagnosis.
|
|
50
|
+
|
|
51
|
+
### Step 5: Build a Domain Glossary
|
|
52
|
+
|
|
53
|
+
Extract 10-15 key domain terms from code (class names, method names, constants) and map
|
|
54
|
+
them to plain-language definitions. This applies Evans's Ubiquitous Language as documentation.
|
|
55
|
+
|
|
56
|
+
### Step 6: Suggest First Tasks
|
|
57
|
+
|
|
58
|
+
Based on the dependency map, suggest 2-3 low-risk areas where a new developer could make
|
|
59
|
+
their first contribution: modules with good test coverage, clear boundaries, low coupling.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Output Template
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
# Codebase Tour: [Project Name]
|
|
67
|
+
|
|
68
|
+
## Overview
|
|
69
|
+
[2-3 sentence summary of what the project does and its tech stack]
|
|
70
|
+
|
|
71
|
+
## Module Map
|
|
72
|
+
[Mermaid graph with reading-order colors]
|
|
73
|
+
|
|
74
|
+
## Module Guide
|
|
75
|
+
[One paragraph per top-level module: what it does, what it depends on, key files to read]
|
|
76
|
+
|
|
77
|
+
## Conventions
|
|
78
|
+
[Bullet list of patterns this codebase follows]
|
|
79
|
+
|
|
80
|
+
## Danger Zones
|
|
81
|
+
[Bullet list of areas to be careful with, or "None identified" if the codebase is clean]
|
|
82
|
+
|
|
83
|
+
## Domain Glossary
|
|
84
|
+
| Term | Meaning |
|
|
85
|
+
|------|---------|
|
|
86
|
+
|
|
87
|
+
## Suggested First Tasks
|
|
88
|
+
[2-3 concrete suggestions for a new developer's first PR]
|
|
89
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hasapi-debt
|
|
3
|
+
description: >
|
|
4
|
+
Tech debt assessment that identifies, classifies, and prioritizes maintainability
|
|
5
|
+
problems — helping teams build a refactoring roadmap — drawing on twelve classic
|
|
6
|
+
engineering books.
|
|
7
|
+
Triggers when: user asks about tech debt, refactoring priorities, what to clean up
|
|
8
|
+
first, or asks "why is this so hard to change?", "where's the most painful part?",
|
|
9
|
+
"what should we fix first?", "how do I justify refactoring to management?",
|
|
10
|
+
"why is our velocity dropping?".
|
|
11
|
+
Do NOT trigger for: server health checks, HTTP /health endpoints, Kubernetes probes,
|
|
12
|
+
database health, or application uptime — "health" in those contexts is infrastructure,
|
|
13
|
+
not code quality. Also not for single-function refactoring questions.
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Brooks-Lint — Tech Debt Assessment
|
|
17
|
+
|
|
18
|
+
## Setup
|
|
19
|
+
|
|
20
|
+
1. Read `../_shared/common.md` for the Iron Law, Project Config, Report Template, and Health Score rules
|
|
21
|
+
2. Read `../_shared/source-coverage.md` for book-level coverage, exceptions, and tradeoffs
|
|
22
|
+
3. Read `../_shared/decay-risks.md` for symptom definitions and source attributions
|
|
23
|
+
4. Read `debt-guide.md` in this directory for the debt classification framework
|
|
24
|
+
|
|
25
|
+
## Process
|
|
26
|
+
|
|
27
|
+
**If the user has not described the codebase or pointed to specific areas:** apply Auto
|
|
28
|
+
Scope Detection from `../_shared/common.md` to determine the assessment scope before proceeding.
|
|
29
|
+
|
|
30
|
+
1. Scan for all six decay risks (Step 1 of the guide); list every finding before scoring
|
|
31
|
+
2. Apply the Pain × Spread priority formula and classify debt intent (Steps 2–3 of the guide)
|
|
32
|
+
3. Group findings by decay risk (Step 4 of the guide)
|
|
33
|
+
4. Output using the Report Template from common.md, plus the Debt Summary Table
|
|
34
|
+
|
|
35
|
+
**Mode line in report:** `Tech Debt Assessment`
|