swe-workflow-skills 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 +144 -0
- package/VERSION +1 -0
- package/bin/cli.mjs +44 -0
- package/catalog.json +225 -0
- package/commands/role.md +34 -0
- package/hooks/session-start.mjs +118 -0
- package/install.mjs +318 -0
- package/package.json +47 -0
- package/roles.json +194 -0
- package/scripts/resolve.mjs +296 -0
- package/skills/accessibility-design/SKILL.md +128 -0
- package/skills/accessibility-design/evals/evals.json +51 -0
- package/skills/accessibility-design/references/accessibility-patterns.md +321 -0
- package/skills/api-design/SKILL.md +144 -0
- package/skills/api-design/evals/evals.json +48 -0
- package/skills/api-design/references/rest-conventions.md +147 -0
- package/skills/api-design/templates/api-spec.md +156 -0
- package/skills/architecture-design/SKILL.md +86 -0
- package/skills/architecture-design/evals/evals.json +44 -0
- package/skills/architecture-design/references/clean-architecture.md +147 -0
- package/skills/architecture-design/references/component-principles.md +129 -0
- package/skills/architecture-design/references/principles.md +81 -0
- package/skills/architecture-design/references/solid-principles.md +106 -0
- package/skills/architecture-design/templates/adr.md +63 -0
- package/skills/architecture-documentation/SKILL.md +126 -0
- package/skills/architecture-documentation/evals/evals.json +44 -0
- package/skills/architecture-documentation/references/abstraction-levels.md +91 -0
- package/skills/architecture-documentation/references/diagram-tooling.md +141 -0
- package/skills/architecture-documentation/templates/architecture-doc.md +171 -0
- package/skills/bug-investigating/SKILL.md +133 -0
- package/skills/bug-investigating/evals/evals.json +56 -0
- package/skills/bug-investigating/references/common-bugs.md +62 -0
- package/skills/bug-investigating/references/debugging-patterns.md +94 -0
- package/skills/cicd-pipeline/SKILL.md +87 -0
- package/skills/cicd-pipeline/evals/evals.json +34 -0
- package/skills/cicd-pipeline/references/pipeline-patterns.md +206 -0
- package/skills/cicd-pipeline/templates/github-actions.md +206 -0
- package/skills/code-reviewing/SKILL.md +92 -0
- package/skills/code-reviewing/evals/evals.json +62 -0
- package/skills/code-reviewing/references/error-handling.md +108 -0
- package/skills/code-reviewing/references/review-checklist.md +144 -0
- package/skills/configuration-strategy/SKILL.md +109 -0
- package/skills/configuration-strategy/evals/evals.json +41 -0
- package/skills/configuration-strategy/references/config-patterns.md +161 -0
- package/skills/containerization/SKILL.md +90 -0
- package/skills/containerization/evals/evals.json +36 -0
- package/skills/containerization/references/dockerfile-patterns.md +168 -0
- package/skills/containerization/templates/dockerfile.md +154 -0
- package/skills/data-modeling/SKILL.md +83 -0
- package/skills/data-modeling/evals/evals.json +43 -0
- package/skills/data-modeling/references/conventions.md +57 -0
- package/skills/data-modeling/templates/schema.md +120 -0
- package/skills/dependency-impact-analysis/SKILL.md +113 -0
- package/skills/dependency-impact-analysis/evals/evals.json +41 -0
- package/skills/dependency-impact-analysis/references/impact-patterns.md +150 -0
- package/skills/dependency-management/SKILL.md +161 -0
- package/skills/dependency-management/evals/evals.json +48 -0
- package/skills/dependency-management/references/evaluation-checklist.md +127 -0
- package/skills/deployment-checklist/SKILL.md +132 -0
- package/skills/deployment-checklist/evals/evals.json +58 -0
- package/skills/deployment-checklist/references/pre-deploy-gates.md +91 -0
- package/skills/deployment-repo/SKILL.md +190 -0
- package/skills/deployment-repo/evals/evals.json +44 -0
- package/skills/deployment-repo/references/deployment-repo-patterns.md +258 -0
- package/skills/deployment-repo/references/version-compatibility.md +227 -0
- package/skills/deployment-repo/templates/deployment-repo-structure.md +226 -0
- package/skills/effort-estimation/SKILL.md +95 -0
- package/skills/effort-estimation/evals/evals.json +32 -0
- package/skills/effort-estimation/references/estimation-methods.md +154 -0
- package/skills/feature-planning/SKILL.md +84 -0
- package/skills/feature-planning/evals/evals.json +44 -0
- package/skills/feature-planning/templates/plan.md +55 -0
- package/skills/feature-planning/templates/task.md +26 -0
- package/skills/frontend-architecture/SKILL.md +154 -0
- package/skills/frontend-architecture/evals/evals.json +34 -0
- package/skills/frontend-architecture/references/component-patterns.md +264 -0
- package/skills/frontend-architecture/templates/folder-structure.md +203 -0
- package/skills/git-workflow/SKILL.md +127 -0
- package/skills/git-workflow/evals/evals.json +44 -0
- package/skills/git-workflow/references/conventions.md +142 -0
- package/skills/git-workflow/templates/pull-request.md +57 -0
- package/skills/gitops-delivery/SKILL.md +319 -0
- package/skills/gitops-delivery/evals/evals.json +44 -0
- package/skills/gitops-delivery/references/gitops-patterns.md +478 -0
- package/skills/gitops-delivery/templates/gitops-config.md +196 -0
- package/skills/incident-response/SKILL.md +130 -0
- package/skills/incident-response/evals/evals.json +55 -0
- package/skills/incident-response/references/communication-templates.md +134 -0
- package/skills/incident-response/references/severity-levels.md +77 -0
- package/skills/incident-response/templates/incident-timeline.md +57 -0
- package/skills/infrastructure-as-code/SKILL.md +86 -0
- package/skills/infrastructure-as-code/evals/evals.json +33 -0
- package/skills/infrastructure-as-code/references/iac-patterns.md +179 -0
- package/skills/infrastructure-as-code/templates/terraform-module.md +158 -0
- package/skills/metrics-and-okrs/SKILL.md +113 -0
- package/skills/metrics-and-okrs/evals/evals.json +33 -0
- package/skills/metrics-and-okrs/references/metric-catalog.md +90 -0
- package/skills/metrics-and-okrs/templates/okr-document.md +61 -0
- package/skills/ml-experiment-tracking/SKILL.md +96 -0
- package/skills/ml-experiment-tracking/evals/evals.json +32 -0
- package/skills/ml-experiment-tracking/references/tracking-tools.md +127 -0
- package/skills/ml-model-deployment/SKILL.md +106 -0
- package/skills/ml-model-deployment/evals/evals.json +34 -0
- package/skills/ml-model-deployment/references/serving-patterns.md +162 -0
- package/skills/ml-pipeline-design/SKILL.md +162 -0
- package/skills/ml-pipeline-design/evals/evals.json +34 -0
- package/skills/ml-pipeline-design/references/pipeline-components.md +174 -0
- package/skills/observability-design/SKILL.md +162 -0
- package/skills/observability-design/evals/evals.json +52 -0
- package/skills/observability-design/references/logging-patterns.md +229 -0
- package/skills/observability-design/references/slo-framework.md +151 -0
- package/skills/observability-design/templates/slo-document.md +80 -0
- package/skills/performance-optimization/SKILL.md +83 -0
- package/skills/performance-optimization/evals/evals.json +47 -0
- package/skills/performance-optimization/references/bottleneck-patterns.md +256 -0
- package/skills/performance-optimization/references/concurrency.md +101 -0
- package/skills/prd-writing/SKILL.md +109 -0
- package/skills/prd-writing/evals/evals.json +33 -0
- package/skills/prd-writing/references/prd-examples.md +132 -0
- package/skills/prd-writing/templates/prd.md +71 -0
- package/skills/prd-writing/templates/rfc.md +79 -0
- package/skills/project-documentation/SKILL.md +104 -0
- package/skills/project-documentation/evals/evals.json +48 -0
- package/skills/project-documentation/references/contributing-guide.md +100 -0
- package/skills/project-documentation/templates/changelog.md +59 -0
- package/skills/project-documentation/templates/readme.md +121 -0
- package/skills/project-proposal/SKILL.md +90 -0
- package/skills/project-proposal/evals/evals.json +31 -0
- package/skills/project-proposal/references/proposal-examples.md +140 -0
- package/skills/project-proposal/templates/proposal.md +76 -0
- package/skills/project-review/SKILL.md +111 -0
- package/skills/project-review/evals/evals.json +42 -0
- package/skills/refactoring/SKILL.md +90 -0
- package/skills/refactoring/evals/evals.json +44 -0
- package/skills/refactoring/references/transformations.md +132 -0
- package/skills/retrospective/SKILL.md +157 -0
- package/skills/retrospective/evals/evals.json +34 -0
- package/skills/retrospective/references/facilitation-guide.md +130 -0
- package/skills/retrospective/templates/post-mortem.md +121 -0
- package/skills/rollback-strategy/SKILL.md +116 -0
- package/skills/rollback-strategy/evals/evals.json +55 -0
- package/skills/rollback-strategy/references/rollback-patterns.md +125 -0
- package/skills/rollback-strategy/templates/rollback-plan.md +69 -0
- package/skills/security-audit/SKILL.md +146 -0
- package/skills/security-audit/evals/evals.json +66 -0
- package/skills/security-audit/references/owasp-top-10.md +167 -0
- package/skills/security-audit/templates/security-report.md +79 -0
- package/skills/skill-router/SKILL.md +171 -0
- package/skills/skill-router/evals/evals.json +39 -0
- package/skills/strategic-review/SKILL.md +106 -0
- package/skills/strategic-review/evals/evals.json +42 -0
- package/skills/strategic-review/templates/full-review-prompt.md +84 -0
- package/skills/tdd-workflow/SKILL.md +147 -0
- package/skills/tdd-workflow/evals/evals.json +58 -0
- package/skills/tdd-workflow/references/test-quality.md +71 -0
- package/skills/technical-debt-review/SKILL.md +113 -0
- package/skills/technical-debt-review/evals/evals.json +41 -0
- package/skills/technical-debt-review/references/debt-taxonomy.md +124 -0
- package/skills/technical-debt-review/templates/debt-audit.md +85 -0
- package/skills/test-data-strategy/SKILL.md +129 -0
- package/skills/test-data-strategy/evals/evals.json +49 -0
- package/skills/test-data-strategy/references/data-generation-patterns.md +341 -0
- package/skills/test-suite-design/SKILL.md +137 -0
- package/skills/test-suite-design/evals/evals.json +69 -0
- package/skills/test-suite-design/references/test-infrastructure.md +175 -0
- package/skills/test-suite-design/references/testing-pyramid.md +140 -0
- package/skills/ui-ux-design/SKILL.md +117 -0
- package/skills/ui-ux-design/evals/evals.json +35 -0
- package/skills/ui-ux-design/references/interaction-patterns.md +145 -0
- package/skills/ui-ux-design/templates/screen-spec.md +97 -0
- package/skills/verification-before-completion/SKILL.md +85 -0
- package/skills/verification-before-completion/evals/evals.json +53 -0
- package/skills/writing-skills/SKILL.md +87 -0
- package/skills/writing-skills/evals/evals.json +41 -0
- package/skills/writing-skills/references/pressure-testing.md +69 -0
- package/uninstall.mjs +182 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Full pre-public / pre-milestone project review — prompt template
|
|
2
|
+
|
|
3
|
+
A generalized, reusable version of a founder-grade "should we go public?" review.
|
|
4
|
+
It orchestrates both review lenses — `strategic-review` (vision, positioning,
|
|
5
|
+
market) and `project-review` (scope, roadmap, implementation, evidence) — into a
|
|
6
|
+
single interactive decision instrument.
|
|
7
|
+
|
|
8
|
+
**How to use:** fill the placeholders below and paste as the task prompt, or hand
|
|
9
|
+
the filled brief to the skill router. Delete any section that doesn't apply to the
|
|
10
|
+
project (e.g. a solo library has no separate validation harness — fold "evidence"
|
|
11
|
+
into tests/coverage/changelog).
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Parameters
|
|
16
|
+
|
|
17
|
+
| Placeholder | Meaning | Example |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| `{{project_name}}` | What's under review | "Acme Toolkit" |
|
|
20
|
+
| `{{repos}}` | Repos/dirs in scope (strategy + implementation + validation) | `../core`, `../spec`, `../validation` |
|
|
21
|
+
| `{{strategy_docs}}` | Where vision/scope/roadmap/ADRs live | `docs/vision.md`, `ROADMAP.md` |
|
|
22
|
+
| `{{evidence_sources}}` | Tests, coverage, validation results, benchmarks, changelog | `validation/reports/`, `CHANGELOG.md` |
|
|
23
|
+
| `{{market_bands}}` | Known competitor bands to refresh + where to hunt for new entrants | "LLMOps, platform-native, prompt vaults" |
|
|
24
|
+
| `{{decision_question}}` | The actual decision this informs | "Go public now, later, or repositioned?" |
|
|
25
|
+
| `{{deliverable_path}}` | Gitignored output location | `.local/{{project_name}}-review-<date>.html` |
|
|
26
|
+
| `{{stance}}` | `options+recommendation` (default) \| `options-only` \| `go/no-go` | `options+recommendation` |
|
|
27
|
+
| `{{as_of_date}}` | Date stamp for market findings | `2026-06-20` |
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## The prompt
|
|
32
|
+
|
|
33
|
+
> Review the current state of **{{project_name}}** ahead of this decision:
|
|
34
|
+
> **{{decision_question}}**. The repos in scope are {{repos}}; the strategy/vision
|
|
35
|
+
> material is in {{strategy_docs}}; the evidence it works is in {{evidence_sources}}.
|
|
36
|
+
>
|
|
37
|
+
> Produce a single, blunt, maximally honest decision instrument. Foreground the most
|
|
38
|
+
> uncomfortable finding rather than burying it. Do the following:
|
|
39
|
+
>
|
|
40
|
+
> 1. **Vision, scope, positioning** (`strategic-review`) — state the thesis in one
|
|
41
|
+
> sentence and name its load-bearing assumption; critique the value proposition and
|
|
42
|
+
> scope; assess where positioning is strong vs. where it leans on unproven assumptions.
|
|
43
|
+
> 2. **Implementation vs. roadmap / execution plan** (`project-review`) — map
|
|
44
|
+
> implementation maturity (production-ready vs stub/deferred, by named path);
|
|
45
|
+
> reconcile against the roadmap; surface scope drift and the gap between "built"
|
|
46
|
+
> and "validated".
|
|
47
|
+
> 3. **Evidence / validation review** (`project-review`) — read the *actual* numbers
|
|
48
|
+
> in {{evidence_sources}}; report negative or inconclusive results honestly; state
|
|
49
|
+
> the built-vs-validated gap and what evidence would close it.
|
|
50
|
+
> 4. **Market research, live, as of {{as_of_date}}** (`strategic-review` →
|
|
51
|
+
> `deep-research`) — refresh {{market_bands}} and hunt for new entrants and adjacent
|
|
52
|
+
> standards; assess platform-absorption / wedge-closure risk; tag each comparable
|
|
53
|
+
> as competitor / complement / integration target. Date-bound every finding and
|
|
54
|
+
> label confirmed vs. inferred.
|
|
55
|
+
> 5. **Synthesis** — potential; ranked weak points (lead with the assumption most
|
|
56
|
+
> likely to be false); prioritized, severity-tagged suggestions; and **strategic
|
|
57
|
+
> forks with trade-offs**. Decision stance: **{{stance}}**.
|
|
58
|
+
>
|
|
59
|
+
> **Deliverable:** one self-contained interactive HTML file at `{{deliverable_path}}`
|
|
60
|
+
> (render via `artifact-design`): inline CSS/JS, no external runtime (opens offline),
|
|
61
|
+
> sticky section nav, collapsible subsections, a sortable/filterable findings table,
|
|
62
|
+
> severity tags, and a strategic-forks comparison panel. Dark, dense, dashboard-style
|
|
63
|
+
> — an analyst tool, not marketing. **No git changes** — write only to the gitignored
|
|
64
|
+
> path. Every claim cites its source (file path, command output, or dated URL).
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Non-negotiables (what the original brief left implicit — bake these in)
|
|
69
|
+
|
|
70
|
+
- **Cite or label.** Every claim is confirmed (with a source) or inferred (say so).
|
|
71
|
+
- **Date-bound the market.** Tag findings "as of {{as_of_date}}"; the landscape moves.
|
|
72
|
+
- **Negative evidence is the headline, not a footnote.** If validation is weak,
|
|
73
|
+
lead with it.
|
|
74
|
+
- **No verdict creep.** Honor `{{stance}}`. Default presents forks *and* a
|
|
75
|
+
recommendation; never silently collapse to a single forced verdict unless asked.
|
|
76
|
+
- **Stay out of git.** Gitignored output only; confirm with `git status` / `git
|
|
77
|
+
check-ignore` after writing.
|
|
78
|
+
|
|
79
|
+
## Verification checklist
|
|
80
|
+
|
|
81
|
+
1. File exists at `{{deliverable_path}}` and is git-ignored (`git check-ignore` returns it; `git status` is clean).
|
|
82
|
+
2. Opens offline — no external fetches; nav, collapsibles, and the findings table all work; no console errors.
|
|
83
|
+
3. Spot-check 3–4 cited numbers against their source files.
|
|
84
|
+
4. Synthesis honors `{{stance}}` (e.g. forks-with-recommendation, not a smuggled go/no-go).
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tdd-workflow
|
|
3
|
+
description: "Guide test-driven development with red-green-refactor. Triggers: use tdd, test first, write the tests, red green refactor, test-driven, what should I test, write tests before code, failing test, implement using TDD. For NEW code via test-first — use test-suite-design for adding tests to existing code."
|
|
4
|
+
model: sonnet
|
|
5
|
+
allowed-tools: Read, Grep, Glob, Write, Edit, Bash
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# TDD Workflow
|
|
9
|
+
|
|
10
|
+
Guide implementation through the red-green-refactor cycle. TDD produces code that is testable by design, has a living specification, and tends toward simpler solutions because you only write what's needed to pass the next test.
|
|
11
|
+
|
|
12
|
+
## ⛔ The Iron Law
|
|
13
|
+
|
|
14
|
+
**No production code without a failing test you have watched fail.**
|
|
15
|
+
|
|
16
|
+
If you wrote code before the test, delete it and restart from the test — don't keep it "as reference" or "adapt it" while writing the test. A test you didn't watch fail proves nothing: you don't know whether it tests the right thing. This is the one rule that the rest of the workflow protects.
|
|
17
|
+
|
|
18
|
+
## The Cycle
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
┌──────────────────────────────────┐
|
|
22
|
+
│ RED │
|
|
23
|
+
│ Write a failing test that │
|
|
24
|
+
│ describes the next behavior │
|
|
25
|
+
├──────────────────────────────────┤
|
|
26
|
+
│ GREEN │
|
|
27
|
+
│ Write the minimum code to │
|
|
28
|
+
│ make the test pass │
|
|
29
|
+
├──────────────────────────────────┤
|
|
30
|
+
│ REFACTOR │
|
|
31
|
+
│ Improve the code while │
|
|
32
|
+
│ keeping all tests green │
|
|
33
|
+
└──────────────────────────────────┘
|
|
34
|
+
↑ │
|
|
35
|
+
└────────────────────┘
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Workflow
|
|
39
|
+
|
|
40
|
+
### Step 0: Plan the Test List
|
|
41
|
+
|
|
42
|
+
Before writing any test, create a list of behaviors to test. Derive this from acceptance criteria or the task description. Order from simplest to most complex:
|
|
43
|
+
|
|
44
|
+
1. **Happy path** — the simplest valid scenario
|
|
45
|
+
2. **Edge cases** — boundary values, empty inputs, single items
|
|
46
|
+
3. **Error cases** — invalid input, missing resources, permission failures
|
|
47
|
+
4. **Integration points** — interactions with other components
|
|
48
|
+
|
|
49
|
+
Present the test list to the user. This is the roadmap — each item becomes one red-green-refactor cycle.
|
|
50
|
+
|
|
51
|
+
### Step 1: RED — Write a Failing Test
|
|
52
|
+
|
|
53
|
+
Write exactly one test that describes the next behavior. The test should:
|
|
54
|
+
|
|
55
|
+
- Have a descriptive name that reads like a specification: `test_user_cannot_login_with_expired_password`
|
|
56
|
+
- Follow the Arrange-Act-Assert pattern (or Given-When-Then)
|
|
57
|
+
- Test behavior, not implementation (assert on outputs, not internal state)
|
|
58
|
+
- Fail for the right reason (missing function, wrong return value — not syntax error)
|
|
59
|
+
|
|
60
|
+
Run the test and confirm it fails. Show the failure output to the user. If the test passes immediately, either the behavior already exists or the test is wrong.
|
|
61
|
+
|
|
62
|
+
### Step 2: GREEN — Make It Pass
|
|
63
|
+
|
|
64
|
+
Write the **minimum code** to make the failing test pass. This is critical — resist the urge to write the "right" solution. Minimum means:
|
|
65
|
+
|
|
66
|
+
- Hard-code a return value if that's enough
|
|
67
|
+
- Use the simplest possible data structure
|
|
68
|
+
- Skip error handling if no test requires it yet
|
|
69
|
+
- Ignore performance, elegance, or future needs
|
|
70
|
+
|
|
71
|
+
Run all tests (not just the new one). Everything must be green.
|
|
72
|
+
|
|
73
|
+
### Step 3: REFACTOR — Improve Under Green
|
|
74
|
+
|
|
75
|
+
Now improve the code while all tests stay green. Look for:
|
|
76
|
+
|
|
77
|
+
- **Duplication** → Extract methods, constants, or shared setup
|
|
78
|
+
- **Naming** → Rename to reveal intent
|
|
79
|
+
- **Complexity** → Simplify conditionals, flatten nesting
|
|
80
|
+
- **Responsibility** → Extract classes/modules if a function does too much
|
|
81
|
+
|
|
82
|
+
Also refactor the tests:
|
|
83
|
+
- Remove duplication in test setup (use fixtures/helpers)
|
|
84
|
+
- Improve test names if the behavior is clearer now
|
|
85
|
+
- Ensure tests are independent (no shared mutable state)
|
|
86
|
+
|
|
87
|
+
Run all tests after each refactoring step. If anything breaks, undo the last change immediately.
|
|
88
|
+
|
|
89
|
+
### Step 4: Repeat
|
|
90
|
+
|
|
91
|
+
Pick the next item from the test list. Return to Step 1.
|
|
92
|
+
|
|
93
|
+
After completing all items, do a final review — see [references/test-quality.md](references/test-quality.md).
|
|
94
|
+
|
|
95
|
+
## Adapting TDD to Different Contexts
|
|
96
|
+
|
|
97
|
+
**Unit tests** (default): Test a single function or class in isolation. Mock external dependencies. Fast feedback loop (milliseconds).
|
|
98
|
+
|
|
99
|
+
**Integration tests**: Test how components work together. Use for database queries, API endpoints, message handling. Slower but catch wiring bugs.
|
|
100
|
+
|
|
101
|
+
**Outside-in TDD**: Start with an acceptance test (failing), then drive the implementation with unit tests. Useful when you know the desired API or user interaction.
|
|
102
|
+
|
|
103
|
+
**Inside-out TDD**: Start with the core domain logic, build outward. Useful when the domain is complex and the interface is flexible.
|
|
104
|
+
|
|
105
|
+
Suggest the appropriate approach based on the task. Default to unit tests unless the task is primarily about integration.
|
|
106
|
+
|
|
107
|
+
## What NOT to TDD
|
|
108
|
+
|
|
109
|
+
TDD is a design tool, not a coverage tool. Don't TDD:
|
|
110
|
+
- Trivial getters/setters
|
|
111
|
+
- Framework configuration
|
|
112
|
+
- Third-party libraries themselves — test *your code's use* of them at the integration level; don't re-assert what the library's own tests already cover (its compression, its persistence, its parsing)
|
|
113
|
+
- UI layout (visual regression tools are better here)
|
|
114
|
+
|
|
115
|
+
## Principles Applied
|
|
116
|
+
|
|
117
|
+
- **YAGNI**: The test list prevents building more than needed. If there's no test for it, don't build it.
|
|
118
|
+
- **KISS**: Minimum code to pass forces simplicity.
|
|
119
|
+
- **Functional Independence**: Tests that mock dependencies encourage decoupled design.
|
|
120
|
+
- **DRY**: Refactoring phase explicitly targets duplication.
|
|
121
|
+
- **FIRST**: Tests should be Fast, Independent, Repeatable, Self-validating, and Timely — see [references/test-quality.md](references/test-quality.md) for the full checklist and test smell detection.
|
|
122
|
+
|
|
123
|
+
## Rationalizations to reject
|
|
124
|
+
|
|
125
|
+
These are the excuses that lead to skipping the test. None of them hold up.
|
|
126
|
+
|
|
127
|
+
| Excuse | Reality |
|
|
128
|
+
|--------|---------|
|
|
129
|
+
| "It's too simple to test" | Simple code still breaks. The test costs 30 seconds; the regression costs an afternoon. |
|
|
130
|
+
| "I'll add the tests after" | Tests written after the code pass immediately — they prove the code does what it does, not what it should. |
|
|
131
|
+
| "I already tested it manually" | Manual checks aren't repeatable and don't guard against the next regression. |
|
|
132
|
+
| "Deleting working code is wasteful" | Sunk cost. Unverified code is debt, not progress. |
|
|
133
|
+
| "Tests-after achieve the same thing" | Tests-first ask "what should this do?"; tests-after ask "what does this do?" — different specs. |
|
|
134
|
+
| "TDD will slow me down" | Debugging untested code is slower than writing the test first. |
|
|
135
|
+
|
|
136
|
+
## Red flags — stop and correct course
|
|
137
|
+
|
|
138
|
+
- You're writing implementation and will "get to the test next."
|
|
139
|
+
- A new test passes the first time you run it (you never saw RED).
|
|
140
|
+
- You can't explain why the test failed in the RED phase.
|
|
141
|
+
- You're glancing at not-yet-deleted draft code while writing the "test-first" version.
|
|
142
|
+
|
|
143
|
+
## Cross-Skill References
|
|
144
|
+
|
|
145
|
+
- `test-suite-design` — adding tests to existing code (this skill is for new code, test-first)
|
|
146
|
+
- `bug-investigating` — write a regression test for a found bug using this cycle
|
|
147
|
+
- `verification-before-completion` — the GREEN step is this gate: watch the test pass for real
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "tdd-workflow",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "I need to implement a password strength validator in Python. Requirements: minimum 8 characters, at least one uppercase, one lowercase, one digit, and one special character. Let's do this TDD style.",
|
|
7
|
+
"expected_output": "Should create a test list first, then implement one test at a time following red-green-refactor. Should NOT write all tests at once or write the implementation first.",
|
|
8
|
+
"assertions": [
|
|
9
|
+
"Creates a test list before writing any test",
|
|
10
|
+
"Starts with the simplest test case (e.g., rejects empty string or too-short password)",
|
|
11
|
+
"Writes exactly one failing test at a time",
|
|
12
|
+
"Writes minimum code to pass each test",
|
|
13
|
+
"Refactors after each green phase",
|
|
14
|
+
"Test names describe behavior, not implementation",
|
|
15
|
+
"Follows Arrange-Act-Assert pattern"
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": 2,
|
|
20
|
+
"prompt": "I want to add a shopping cart feature to my Express.js app. A user can add items, remove items, and calculate the total with discounts. Use TDD to build this. I use Jest for testing.",
|
|
21
|
+
"expected_output": "Should discuss inside-out vs outside-in approach, create a test list ordered by complexity, and implement iteratively.",
|
|
22
|
+
"assertions": [
|
|
23
|
+
"Discusses TDD approach (inside-out for domain logic)",
|
|
24
|
+
"Creates an ordered test list from simple to complex",
|
|
25
|
+
"Happy path tests come before error cases",
|
|
26
|
+
"Discount logic tests come after basic cart operations",
|
|
27
|
+
"Does not write implementation before tests",
|
|
28
|
+
"Uses Jest syntax correctly"
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"id": 3,
|
|
33
|
+
"prompt": "I have a function that calls an external payment API. How should I TDD this? I'm worried about testing external calls.",
|
|
34
|
+
"expected_output": "Should explain test doubles strategy — wrap the external API, stub/mock the wrapper, test the business logic around it. Should distinguish between unit and integration testing here.",
|
|
35
|
+
"assertions": [
|
|
36
|
+
"Recommends wrapping the external API (don't mock what you don't own)",
|
|
37
|
+
"Explains stub vs mock distinction for this case",
|
|
38
|
+
"Suggests unit tests with stubs for business logic",
|
|
39
|
+
"Suggests integration test for actual API communication",
|
|
40
|
+
"Does not suggest mocking the HTTP library directly"
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"pressure_tests": [
|
|
45
|
+
{
|
|
46
|
+
"id": 1,
|
|
47
|
+
"prompt": "We demo in 30 minutes and I already wrote the whole discount_calculator function — it worked when I tried it by hand. Just add a couple of tests after so we're covered, then we ship.",
|
|
48
|
+
"pressure": ["time", "sunk_cost"],
|
|
49
|
+
"expected_behavior": "Holds the Iron Law. Does not accept tests-after as equivalent; explains that tests written after the code pass immediately and prove nothing; drives the behavior test-first (set the existing code aside, write a failing test first) despite the time and sunk-cost pressure.",
|
|
50
|
+
"assertions": [
|
|
51
|
+
"Does NOT just write tests against the existing code and call it covered",
|
|
52
|
+
"Names why tests-after prove nothing (they pass on the first run)",
|
|
53
|
+
"Insists on a failing test first (or setting the draft aside) despite the deadline",
|
|
54
|
+
"Does not capitulate to the 'we'll be covered' framing"
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Test Quality Checklist
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
- FIRST principles for tests
|
|
5
|
+
- Test naming patterns
|
|
6
|
+
- Common test smells
|
|
7
|
+
- Coverage guidance
|
|
8
|
+
- Test doubles guidance
|
|
9
|
+
|
|
10
|
+
## FIRST Principles
|
|
11
|
+
|
|
12
|
+
Good tests are:
|
|
13
|
+
|
|
14
|
+
- **Fast**: Unit tests run in milliseconds. If a test needs a database, it's an integration test.
|
|
15
|
+
- **Independent**: Each test sets up its own state and cleans up after itself. No test depends on another test's side effects or execution order.
|
|
16
|
+
- **Repeatable**: Same result every time. No reliance on system clock, random values, or external services without deterministic control.
|
|
17
|
+
- **Self-validating**: Tests have a boolean outcome (pass/fail). No manual inspection of output needed.
|
|
18
|
+
- **Timely**: Written before or alongside the code they test, not as an afterthought.
|
|
19
|
+
|
|
20
|
+
## Test Naming
|
|
21
|
+
|
|
22
|
+
Tests are specifications. Their names should be readable by someone who hasn't seen the code.
|
|
23
|
+
|
|
24
|
+
Pattern: `test_{unit}_{scenario}_{expected_result}`
|
|
25
|
+
|
|
26
|
+
Examples:
|
|
27
|
+
- `test_password_validator_rejects_passwords_shorter_than_8_chars`
|
|
28
|
+
- `test_order_total_includes_tax_when_region_is_taxable`
|
|
29
|
+
- `test_login_returns_401_when_credentials_are_invalid`
|
|
30
|
+
|
|
31
|
+
Avoid:
|
|
32
|
+
- `test_password_1`, `test_password_2` (meaningless)
|
|
33
|
+
- `test_it_works` (what works?)
|
|
34
|
+
- `test_function_name` (tests behavior, not functions)
|
|
35
|
+
|
|
36
|
+
## Common Test Smells
|
|
37
|
+
|
|
38
|
+
**Test knows too much about implementation**: If changing internal structure (without changing behavior) breaks tests, the tests are coupled to implementation. Assert on outputs and observable side effects, not internal state.
|
|
39
|
+
|
|
40
|
+
**Fragile tests**: Tests that break when unrelated code changes. Usually caused by over-mocking or testing through too many layers.
|
|
41
|
+
|
|
42
|
+
**Slow tests**: A single test taking >100ms is suspicious for a unit test. Check for hidden I/O (file system, network, database).
|
|
43
|
+
|
|
44
|
+
**Test duplication**: Multiple tests asserting the same thing in slightly different ways. Consolidate or parameterize.
|
|
45
|
+
|
|
46
|
+
**Missing assertion**: A test that does work but never asserts anything. Passes vacuously.
|
|
47
|
+
|
|
48
|
+
**Logic in tests**: Tests with if/else, loops, or complex setup. Keep tests linear (arrange-act-assert) with no branching.
|
|
49
|
+
|
|
50
|
+
## Coverage Guidance
|
|
51
|
+
|
|
52
|
+
- Aim for high **behavior coverage**, not line coverage percentages
|
|
53
|
+
- 100% line coverage with shallow assertions is worse than 80% with meaningful tests
|
|
54
|
+
- Focus coverage on: business logic, validation, state transitions, error handling
|
|
55
|
+
- Acceptable to skip: boilerplate, framework glue, trivial delegation
|
|
56
|
+
- Track coverage trends, not absolute numbers — declining coverage is a signal
|
|
57
|
+
|
|
58
|
+
## Test Doubles
|
|
59
|
+
|
|
60
|
+
| Type | Purpose | When to Use |
|
|
61
|
+
|------|---------|-------------|
|
|
62
|
+
| **Stub** | Returns canned answers | When you need to control indirect inputs |
|
|
63
|
+
| **Mock** | Verifies interactions | When the side effect IS the behavior (sending email) |
|
|
64
|
+
| **Fake** | Working but simplified implementation | In-memory database, fake file system |
|
|
65
|
+
| **Spy** | Records calls for later assertion | When you need to verify call patterns |
|
|
66
|
+
|
|
67
|
+
Rules of thumb:
|
|
68
|
+
- Prefer stubs over mocks (test state, not interactions)
|
|
69
|
+
- If you need more than 3 mocks in a test, the code under test has too many dependencies
|
|
70
|
+
- Never mock what you don't own (wrap third-party code and mock the wrapper)
|
|
71
|
+
- Fakes are underused — an in-memory repository is often better than 20 mocked queries
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: technical-debt-review
|
|
3
|
+
description: "Strategic codebase health assessment — identify hotspots, categorize debt, produce remediation roadmap. Triggers: technical debt, tech debt, debt review, codebase health, hotspots, debt assessment, remediation plan, what should we fix first, debt roadmap, code rot, legacy code audit."
|
|
4
|
+
model: opus
|
|
5
|
+
allowed-tools: Read, Grep, Glob, Write, Edit
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Technical Debt Review
|
|
9
|
+
|
|
10
|
+
Produce a strategic picture of where the codebase is accumulating debt and what to do about it. The goal is a prioritized roadmap, not an exhaustive list of every imperfection.
|
|
11
|
+
|
|
12
|
+
## Step 1: Identify Hotspots
|
|
13
|
+
|
|
14
|
+
Don't try to review everything. Focus on where pain is concentrated.
|
|
15
|
+
|
|
16
|
+
**Code complexity signals:**
|
|
17
|
+
- Files or functions with high cyclomatic complexity (many branches, deep nesting)
|
|
18
|
+
- Functions over ~50 lines — usually doing too much (SRP violation)
|
|
19
|
+
- Classes over ~300 lines — usually a God class or multiple responsibilities
|
|
20
|
+
- High number of parameters (> 5 usually indicates missing abstraction)
|
|
21
|
+
|
|
22
|
+
**Change frequency signals (most valuable):**
|
|
23
|
+
- Files changed in almost every PR — high churn indicates poor separation of concerns or missing abstractions
|
|
24
|
+
- Files that always require changes together — tight coupling that should be decoupled
|
|
25
|
+
- Files with frequent bug fixes — instability indicates unclear ownership or poor test coverage
|
|
26
|
+
|
|
27
|
+
**Structural signals:**
|
|
28
|
+
- Circular dependencies between modules
|
|
29
|
+
- Modules that import from many other modules — likely a coordination layer doing too much
|
|
30
|
+
- Dead code (functions/classes with no callers)
|
|
31
|
+
|
|
32
|
+
**Test coverage signals:**
|
|
33
|
+
- Untested code paths in critical or high-churn files
|
|
34
|
+
- Tests that only test happy paths (no edge cases, no error cases)
|
|
35
|
+
- Test files significantly longer than the code they test (over-specified tests that break on refactoring)
|
|
36
|
+
|
|
37
|
+
Ask the user: Where do engineers slow down? What parts of the codebase do people avoid touching? Where do bugs keep appearing?
|
|
38
|
+
|
|
39
|
+
## Step 2: Categorize by Debt Type and Severity
|
|
40
|
+
|
|
41
|
+
For each hotspot, classify the debt:
|
|
42
|
+
|
|
43
|
+
**Debt types:**
|
|
44
|
+
| Type | Description | Typical fix |
|
|
45
|
+
|------|-------------|-------------|
|
|
46
|
+
| **Complexity debt** | Functions/classes doing too much | Extract, decompose, simplify |
|
|
47
|
+
| **Duplication debt** | Same logic in multiple places | Extract shared abstraction |
|
|
48
|
+
| **Test debt** | Missing or low-quality tests | Add tests before refactoring anything else |
|
|
49
|
+
| **Documentation debt** | Undocumented non-obvious behavior | Add comments, docstrings, decision records |
|
|
50
|
+
| **Architecture debt** | Wrong abstraction at system level | Restructure, introduce proper boundaries |
|
|
51
|
+
| **Dependency debt** | Outdated, vulnerable, or abandoned libraries | Upgrade or replace |
|
|
52
|
+
| **Observability debt** | No logging, metrics, or traceability | Add instrumentation |
|
|
53
|
+
|
|
54
|
+
**Severity:**
|
|
55
|
+
- **Critical**: Causing active bugs or security risks. Address immediately.
|
|
56
|
+
- **High**: Slowing down every sprint. Blocking new features. Schedule for next quarter.
|
|
57
|
+
- **Medium**: Painful but workable. Schedule when capacity allows.
|
|
58
|
+
- **Low**: Noticeable but not impeding. Do it opportunistically when touching related code.
|
|
59
|
+
|
|
60
|
+
## Step 3: Estimate Effort and Risk
|
|
61
|
+
|
|
62
|
+
For each hotspot, estimate:
|
|
63
|
+
|
|
64
|
+
**Effort**: hours/days/weeks of engineering work to address
|
|
65
|
+
**Risk**: probability that addressing this introduces new bugs (higher for untested, complex code)
|
|
66
|
+
**Prerequisite**: does this require tests before it can be safely changed? (almost always yes for High/Critical)
|
|
67
|
+
|
|
68
|
+
High-risk + no tests = address the tests first, before the underlying debt.
|
|
69
|
+
|
|
70
|
+
## Step 4: Prioritize by Value-to-Cost Ratio
|
|
71
|
+
|
|
72
|
+
Score each item: `(Severity × Impact on team velocity) / (Effort × Risk)`
|
|
73
|
+
|
|
74
|
+
Prioritize in this order:
|
|
75
|
+
1. **Quick wins**: Low effort, meaningful impact (inconsistent naming conventions, easy extractions)
|
|
76
|
+
2. **High pain, medium effort**: The things that slow every sprint down — worth dedicated sprint time
|
|
77
|
+
3. **Strategic investments**: High effort but unlocks future capability — needs executive buy-in and planned downtime from feature work
|
|
78
|
+
4. **Low impact**: Log them, don't schedule them — address opportunistically
|
|
79
|
+
|
|
80
|
+
Avoid the "big rewrite" trap. Long rewrites stall feature work, introduce new bugs, and often fail to ship. Prefer incremental improvement over big-bang rewrites.
|
|
81
|
+
|
|
82
|
+
## Step 5: Produce the Remediation Roadmap
|
|
83
|
+
|
|
84
|
+
Output a prioritized action plan:
|
|
85
|
+
|
|
86
|
+
**Immediate (this sprint):**
|
|
87
|
+
- [Quick win 1]: estimated [X hours], owner [Name]
|
|
88
|
+
- [Critical fix 1]: estimated [Y days], owner [Name]
|
|
89
|
+
|
|
90
|
+
**Next quarter:**
|
|
91
|
+
- [High-priority debt 1]: estimated [X weeks], requires [tests/migration/team availability]
|
|
92
|
+
- [High-priority debt 2]: ...
|
|
93
|
+
|
|
94
|
+
**Backlog (do when touching related code):**
|
|
95
|
+
- [Medium items to address opportunistically]
|
|
96
|
+
|
|
97
|
+
**Accepted debt (won't address):**
|
|
98
|
+
- [Items acknowledged but explicitly not worth fixing] — revisit if severity changes
|
|
99
|
+
|
|
100
|
+
Use [templates/debt-audit.md](templates/debt-audit.md) for the full audit format.
|
|
101
|
+
|
|
102
|
+
## Principles Applied
|
|
103
|
+
|
|
104
|
+
- **KISS**: Simplify complexity first — complex code is the root cause of most other debt
|
|
105
|
+
- **DRY**: Eliminate duplication — find the patterns, create the abstraction
|
|
106
|
+
- **SRP**: Split God classes and functions doing multiple jobs into focused units
|
|
107
|
+
- **Tests before refactoring**: Never refactor untested code without adding tests first — you won't know if the refactor is correct
|
|
108
|
+
|
|
109
|
+
## Cross-Skill References
|
|
110
|
+
|
|
111
|
+
- `refactoring` — use for the actual small-scale, test-protected code improvements identified in this review
|
|
112
|
+
- `architecture-design` — use when debt is architectural (wrong boundaries, wrong abstractions at system level)
|
|
113
|
+
- `performance-optimization` — use when debt is causing measurable performance problems, not just code cleanliness
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "technical-debt-review",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "We're planning our Q2 priorities and I want to do a technical debt review of our payments service. It's been growing for 3 years and is getting painful to work with. Where should I start?",
|
|
7
|
+
"expected_output": "Structured technical debt review starting with hotspot identification (not a comprehensive file-by-file scan), categorizing by type and severity, and producing a prioritized roadmap for Q2",
|
|
8
|
+
"assertions": [
|
|
9
|
+
"Starts by gathering information about where pain is concentrated (asks about churn, where bugs appear, what engineers avoid)",
|
|
10
|
+
"Focuses on hotspots rather than reviewing every file",
|
|
11
|
+
"Categorizes debt by type (complexity, test, architecture, etc.) and severity",
|
|
12
|
+
"Produces a prioritized roadmap with effort estimates",
|
|
13
|
+
"Distinguishes between quick wins, quarterly investments, and strategic changes",
|
|
14
|
+
"Does not recommend a full rewrite without strong justification"
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"id": 2,
|
|
19
|
+
"prompt": "Every file in our repo has some technical debt. How do I decide where to start when everything needs work?",
|
|
20
|
+
"expected_output": "Provides the prioritization framework: focus on high-churn + untested areas first, use value-to-cost ratio, and recommend starting with test coverage before any refactoring",
|
|
21
|
+
"assertions": [
|
|
22
|
+
"Recommends focusing on churn (frequently-changed files) rather than trying to address all debt",
|
|
23
|
+
"Emphasizes that test debt must be addressed before structural debt",
|
|
24
|
+
"Provides a concrete prioritization heuristic (not just 'prioritize by impact')",
|
|
25
|
+
"Acknowledges that low-impact debt can be accepted / deferred",
|
|
26
|
+
"Does not recommend addressing everything at once"
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"id": 3,
|
|
31
|
+
"prompt": "I found a function that's 20 lines with a bug in it. Can you help me refactor it?",
|
|
32
|
+
"expected_output": "Recognizes this is a small, targeted refactoring task — redirects to refactoring skill rather than performing a strategic debt review",
|
|
33
|
+
"assertions": [
|
|
34
|
+
"Recognizes this is a small-scale refactoring task, not a strategic debt review",
|
|
35
|
+
"Does not launch into a full technical debt audit workflow",
|
|
36
|
+
"May suggest using the refactoring skill for this specific task",
|
|
37
|
+
"Can still help fix the bug/refactor, but scopes appropriately to the small task"
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Technical Debt Taxonomy
|
|
2
|
+
|
|
3
|
+
## Types of Technical Debt
|
|
4
|
+
|
|
5
|
+
### Deliberate vs. Inadvertent Debt
|
|
6
|
+
|
|
7
|
+
**Deliberate debt** is incurred consciously: "We know this is not the right approach, but we're taking a shortcut to hit the deadline and will fix it later." This is often acceptable when the trade-off is explicit and the payback is scheduled.
|
|
8
|
+
|
|
9
|
+
**Inadvertent debt** accumulates without anyone deciding to incur it: the codebase gradually becomes harder to understand and change, and no single moment caused it. This is the most common form and the hardest to address because there's no "wrong decision" to point to.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Debt Patterns by Category
|
|
14
|
+
|
|
15
|
+
### Complexity Debt
|
|
16
|
+
|
|
17
|
+
**Symptoms:**
|
|
18
|
+
- Functions > 50 lines
|
|
19
|
+
- Cyclomatic complexity > 10 (more than 10 independent paths through the function)
|
|
20
|
+
- Nested conditionals 3+ levels deep
|
|
21
|
+
- Boolean parameters (signals the function does two things)
|
|
22
|
+
- Long parameter lists (> 4-5 parameters)
|
|
23
|
+
- Comments that explain *what* code does instead of *why* (code should be self-explanatory)
|
|
24
|
+
|
|
25
|
+
**Why it accumulates:** Features get added to existing functions because it's faster than designing a new abstraction. Over time, every function does a little more.
|
|
26
|
+
|
|
27
|
+
**Remediation:** Extract method, extract class, replace conditional with polymorphism, introduce parameter objects. Use the `refactoring` skill.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
### Duplication Debt
|
|
32
|
+
|
|
33
|
+
**Symptoms:**
|
|
34
|
+
- Near-identical blocks of code in different files
|
|
35
|
+
- Copy-pasted logic with slight variations
|
|
36
|
+
- The same concept (e.g., "active user") defined differently in multiple places
|
|
37
|
+
- Changes must be applied in 3+ places to take effect
|
|
38
|
+
|
|
39
|
+
**Why it accumulates:** It's faster to copy than to find the existing function and understand it. "I'll come back and consolidate this" never happens.
|
|
40
|
+
|
|
41
|
+
**Remediation:** Extract shared function/class/module. Be careful: not all duplication is bad. Three similar-looking but conceptually distinct things that happen to share implementation details should not be merged — DRY applies to concepts, not to textual similarity.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
### Test Debt
|
|
46
|
+
|
|
47
|
+
**Symptoms:**
|
|
48
|
+
- Low test coverage in high-churn files
|
|
49
|
+
- Tests only cover the happy path
|
|
50
|
+
- Tests that pass even when you break the code (false confidence)
|
|
51
|
+
- Integration tests that are slow and flaky (never run locally)
|
|
52
|
+
- No tests at all for error paths, edge cases, or boundary conditions
|
|
53
|
+
|
|
54
|
+
**Why it accumulates:** Tests are skipped under deadline pressure. "We'll add tests later" is a very reliable source of future debt.
|
|
55
|
+
|
|
56
|
+
**Impact:** Untested code cannot be safely refactored. Test debt blocks all other debt reduction — you must address test debt first.
|
|
57
|
+
|
|
58
|
+
**Remediation:** Add characterization tests (tests that document existing behavior) before any refactoring. Use the `tdd-workflow` and `test-suite-design` skills.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
### Architecture Debt
|
|
63
|
+
|
|
64
|
+
**Symptoms:**
|
|
65
|
+
- Circular dependencies between modules
|
|
66
|
+
- Business logic in presentation layer (or database layer)
|
|
67
|
+
- A single class/module that everyone imports
|
|
68
|
+
- Inability to test a module without standing up the entire application
|
|
69
|
+
- Features that "should be simple" require changes in 5+ files
|
|
70
|
+
|
|
71
|
+
**Why it accumulates:** Architectural decisions made for an earlier, smaller system don't scale as the system grows. Short-term pragmatic choices ("just put it in the utils file") create long-term coupling.
|
|
72
|
+
|
|
73
|
+
**Remediation:** This is the highest-effort, highest-risk debt to address. Requires architecture-design level thinking, not just refactoring. Consider the strangler fig pattern: build the new architecture alongside the old, migrate incrementally, delete the old.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
### Dependency Debt
|
|
78
|
+
|
|
79
|
+
**Symptoms:**
|
|
80
|
+
- Libraries multiple major versions behind current
|
|
81
|
+
- Libraries with known CVEs that haven't been patched
|
|
82
|
+
- Libraries that are unmaintained or deprecated
|
|
83
|
+
- Libraries with no clear reason for inclusion (what does it do?)
|
|
84
|
+
- Multiple libraries doing the same thing
|
|
85
|
+
|
|
86
|
+
**Why it accumulates:** Dependency updates feel risky and don't provide user-visible value, so they're deprioritized.
|
|
87
|
+
|
|
88
|
+
**Impact:** Outdated dependencies are a security risk and make future updates harder (upgrading 5 major versions at once is much harder than upgrading 1).
|
|
89
|
+
|
|
90
|
+
**Remediation:** Use the `dependency-management` skill. Update regularly — one major version at a time is much safer than multi-version jumps.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
### Observability Debt
|
|
95
|
+
|
|
96
|
+
**Symptoms:**
|
|
97
|
+
- Production errors discovered by users, not monitoring
|
|
98
|
+
- "We can't tell what's wrong" during incidents
|
|
99
|
+
- No structured logging — logs are free-text strings
|
|
100
|
+
- No way to trace a user request across services
|
|
101
|
+
- Metrics exist but no one looks at them
|
|
102
|
+
|
|
103
|
+
**Why it accumulates:** Observability isn't visible to users and doesn't affect development-time behavior. It gets skipped until the first production incident makes it painful.
|
|
104
|
+
|
|
105
|
+
**Remediation:** Use the `observability-design` skill. Add structured logging first (highest immediate value), then metrics, then distributed tracing.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## The "Rewrite vs. Refactor" Decision
|
|
110
|
+
|
|
111
|
+
When debt is severe, teams consider a full rewrite. Rewrites are almost always the wrong choice:
|
|
112
|
+
|
|
113
|
+
**Against rewrites:**
|
|
114
|
+
- The old system embodies years of learned behavior (edge cases, business rules) that are not documented
|
|
115
|
+
- Rewrites stall feature development for 6-18 months
|
|
116
|
+
- The rewrite accumulates the same debt as the original over time, just starting from a cleaner baseline
|
|
117
|
+
- "We'll do it right this time" rarely survives the same time and resource pressures that created the original mess
|
|
118
|
+
|
|
119
|
+
**When rewrite may be justified:**
|
|
120
|
+
- Technology platform is no longer supported (language or framework end-of-life)
|
|
121
|
+
- The domain model is fundamentally wrong and cannot be corrected incrementally
|
|
122
|
+
- The team is genuinely unable to make progress on the existing codebase (not just unwilling)
|
|
123
|
+
|
|
124
|
+
**The alternative:** Strangler fig pattern — build the new system incrementally alongside the old, migrate feature by feature, delete the old pieces as they're replaced. Delivers value continuously, reduces risk, and produces a better result.
|