/build-fix
What
The kit's autonomous iteration-loop skill. It drives a broken dotnet build
(or failing dotnet test) to green by looping: run, parse failures,
categorize by root cause, apply targeted fixes, re-run. It repeats until
green or a guard fires — the same way an experienced developer works through
a wall of red, but with hard limits that stop it from thrashing.
This is not a single-pass fix. It handles cascading errors where fixing one
issue reveals the next.
When
- The build is broken and there are multiple compiler errors
- Tests are failing after code changes or a build-fix pass
- After a major refactor that touched type names, namespaces, or signatures
- After updating NuGet packages (especially major version bumps)
- After merging a branch with conflicts resolved but not compiled
- After scaffolding or code generation that needs manual adjustments
- User says: "fix the build", "make it compile", "make the tests pass",
"keep going until it works", "keep fixing"
How
Loop Discipline (applies to every loop)
- Bounded iteration, always — Default max 5 iterations, hard cap 10
(user "keep going" extends by 3, never past 10). If 5 iterations cannot
solve it, the problem needs human judgment, not a 6th identical attempt.
- Progress or exit — Each iteration must reduce the error/failure count.
Same errors after a fix attempt = STUCK: stop, report, and re-plan with a
different approach. Never retry the same fix that already failed.
- Categorize before fixing — Group errors by root cause and fix the
highest-leverage first (one missing
using can erase a dozen downstream
errors).
- Transparency per iteration — Report what changed and why:
Iteration 3/5: fixed CS0246 by adding using System.Text.Json, 2 remain.
Never modify files silently.
- Atomicity — Each iteration leaves the codebase no worse than before.
If iteration 3 fails, the code stays in iteration 2's state.
Primary Flow: Build-Fix Loop (max 5 iterations)
Build — Run dotnet build, capture full error output
Parse — Extract every error CS#### with file, line, and message
Categorize — Group by root cause:
| Category |
Codes |
Fix strategy |
| Missing using/reference |
CS0246, CS0234 |
Add using, package, or project ref |
| Type mismatch |
CS0029, CS1503 |
Check expected type, cast or convert |
| API change |
CS0117, CS7036 |
Check new signature, update call sites |
| Nullability |
CS8600–CS8604 |
Add null check, ?. or ?? |
| Ambiguity / duplicate |
CS0104, CS0121, CS0111 |
Qualify namespace, remove dupe |
| Missing member |
CS1061 |
Check spelling, verify member exists |
| Missing implementation |
CS0535 |
Implement interface/abstract members |
| Obsolete API |
CS0618 |
Replace with recommended alternative |
Fix — Apply targeted fixes, root-cause/highest-leverage errors first
Rebuild — Run dotnet build again, compare error count
Evaluate — Zero errors: run dotnet test as a sanity check, report
success. Fewer errors: continue. Same errors: STUCK — exit and re-plan.
More errors: revert the iteration, report REGRESSION.
Variant: Test-Fix Loop (max 5; 3 if it follows a build-fix pass)
Same loop, same guards, with dotnet test --no-build as the runner and one
critical extra step — diagnose before fixing:
- Read the test — understand the assertion and setup
- Read the production code — understand the actual behavior
- Decide where the bug lives: wrong expectation → fix the test; production
bug → fix the code; incomplete setup → fix the setup; contract changed →
update the test to match
- Never weaken an assertion to make a test pass.
BAD:
Assert.Equal(expected, actual) → Assert.NotNull(actual).
GOOD: fix the production code so the original assertion passes.
Fail-Safe Guards (immediate exit)
- STUCK — same errors/failures after a fix, or count oscillates
(3 → 2 → 3): report what could not be fixed and what a human should check
- REGRESSION — an iteration introduced more errors than it fixed: revert
its changes, report
- Cascading failures — fixing one error spawns 3+ new ones twice in a
row: the approach is wrong, stop
- Critical error — wrong SDK, missing project file, corrupted solution,
or the test runner itself fails: human intervention needed, stop
- User interruption — finish the current iteration, report progress, ask
how to proceed
Other Loops
The same discipline — bounded iterations, progress detection, fail-safe
guards — governs refactor passes (/de-sloppify: verify build + tests after
each target, revert on failure) and scaffolding (/scaffold: generate, then
run nested build-fix and test-fix loops). Nested loops get a smaller budget
(parent 5 → nested 3), max nesting depth 2, total budget 15.
Invokes
| Type |
Name |
Purpose |
| Skill |
instinct-system |
Capture fix patterns in MEMORY.md |
| Agent |
dotnet-architect |
Consulted for architectural error patterns |
MCP Tools Used
get_diagnostics — Compiler errors/warnings scoped to file or project
find_symbol — Locate moved or renamed types
find_references — Assess blast radius of a broken API change
get_project_graph — Dependency order for fixing reference errors
Example
User: /build-fix
Claude: Running dotnet build...
Found 12 errors across 4 files.
Iteration 1/5:
- 6 errors: Missing namespace (CS0246) — adding using directives
- 3 errors: Type mismatch (CS1503) — updating method signatures
- 3 errors: Interface not implemented (CS0738) — package API changed
Rebuilding... 3 errors remaining.
Iteration 2/5:
- 3 errors: CS0738 after xunit.v3 upgrade
- IAsyncLifetime.InitializeAsync now returns ValueTask (was Task in v2),
and DisposeAsync comes from IAsyncDisposable
- Updating 3 test fixtures to the ValueTask signatures
Rebuilding... 0 errors. Build is green.
Running dotnet test... All 47 tests passed.
Added to Memory > Packages: "xunit.v3 IAsyncLifetime uses ValueTask signatures"
Related
/verify — Full verification pass (build + test + format + diagnostics)
/tdd — Red-green-refactor when building new features test-first
/de-sloppify — Clean up code quality issues after the build is green
1---
2name: build-fix
3description: >
4 Autonomous iteration loops for .NET: drive a broken build or failing test
5 suite to green with bounded iterations, progress detection, and fail-safe
6 guards that prevent infinite retries and wasted tokens. The build-fix loop
7 (dotnet build, parse, categorize, fix, rebuild) is the primary flow; the
8 test-fix loop is a first-class variant. Invoke when the build is broken,
9 after a major refactor or dependency update, or when the user says "fix the
10 build", "build is broken", "make it compile", "make the tests pass", "fix
11 failing tests", "keep going until it works", "autonomous", "loop",
12 "auto-fix", or "keep fixing".
13---
14
15# /build-fix
16
17## What
18
19The kit's autonomous iteration-loop skill. It drives a broken `dotnet build`
20(or failing `dotnet test`) to green by looping: run, parse failures,
21categorize by root cause, apply targeted fixes, re-run. It repeats until
22green or a guard fires — the same way an experienced developer works through
23a wall of red, but with hard limits that stop it from thrashing.
24
25This is not a single-pass fix. It handles cascading errors where fixing one
26issue reveals the next.
27
28## When
29
30- The build is broken and there are multiple compiler errors
31- Tests are failing after code changes or a build-fix pass
32- After a major refactor that touched type names, namespaces, or signatures
33- After updating NuGet packages (especially major version bumps)
34- After merging a branch with conflicts resolved but not compiled
35- After scaffolding or code generation that needs manual adjustments
36- User says: "fix the build", "make it compile", "make the tests pass",
37 "keep going until it works", "keep fixing"
38
39## How
40
41### Loop Discipline (applies to every loop)
42
431. **Bounded iteration, always** — Default max 5 iterations, hard cap 10
44 (user "keep going" extends by 3, never past 10). If 5 iterations cannot
45 solve it, the problem needs human judgment, not a 6th identical attempt.
462. **Progress or exit** — Each iteration must reduce the error/failure count.
47 Same errors after a fix attempt = STUCK: stop, report, and re-plan with a
48 different approach. Never retry the same fix that already failed.
493. **Categorize before fixing** — Group errors by root cause and fix the
50 highest-leverage first (one missing `using` can erase a dozen downstream
51 errors).
524. **Transparency per iteration** — Report what changed and why:
53 `Iteration 3/5: fixed CS0246 by adding using System.Text.Json, 2 remain`.
54 Never modify files silently.
555. **Atomicity** — Each iteration leaves the codebase no worse than before.
56 If iteration 3 fails, the code stays in iteration 2's state.
57
58### Primary Flow: Build-Fix Loop (max 5 iterations)
59
601. **Build** — Run `dotnet build`, capture full error output
612. **Parse** — Extract every `error CS####` with file, line, and message
623. **Categorize** — Group by root cause:
63
64 | Category | Codes | Fix strategy |
65 |---|---|---|
66 | Missing using/reference | CS0246, CS0234 | Add using, package, or project ref |
67 | Type mismatch | CS0029, CS1503 | Check expected type, cast or convert |
68 | API change | CS0117, CS7036 | Check new signature, update call sites |
69 | Nullability | CS8600–CS8604 | Add null check, `?.` or `??` |
70 | Ambiguity / duplicate | CS0104, CS0121, CS0111 | Qualify namespace, remove dupe |
71 | Missing member | CS1061 | Check spelling, verify member exists |
72 | Missing implementation | CS0535 | Implement interface/abstract members |
73 | Obsolete API | CS0618 | Replace with recommended alternative |
74
754. **Fix** — Apply targeted fixes, root-cause/highest-leverage errors first
765. **Rebuild** — Run `dotnet build` again, compare error count
776. **Evaluate** — Zero errors: run `dotnet test` as a sanity check, report
78 success. Fewer errors: continue. Same errors: STUCK — exit and re-plan.
79 More errors: revert the iteration, report REGRESSION.
80
81### Variant: Test-Fix Loop (max 5; 3 if it follows a build-fix pass)
82
83Same loop, same guards, with `dotnet test --no-build` as the runner and one
84critical extra step — **diagnose before fixing**:
85
861. Read the test — understand the assertion and setup
872. Read the production code — understand the actual behavior
883. Decide where the bug lives: wrong expectation → fix the test; production
89 bug → fix the code; incomplete setup → fix the setup; contract changed →
90 update the test to match
914. **Never weaken an assertion to make a test pass.**
92 BAD: `Assert.Equal(expected, actual)` → `Assert.NotNull(actual)`.
93 GOOD: fix the production code so the original assertion passes.
94
95### Fail-Safe Guards (immediate exit)
96
97- **STUCK** — same errors/failures after a fix, or count oscillates
98 (3 → 2 → 3): report what could not be fixed and what a human should check
99- **REGRESSION** — an iteration introduced more errors than it fixed: revert
100 its changes, report
101- **Cascading failures** — fixing one error spawns 3+ new ones twice in a
102 row: the approach is wrong, stop
103- **Critical error** — wrong SDK, missing project file, corrupted solution,
104 or the test runner itself fails: human intervention needed, stop
105- **User interruption** — finish the current iteration, report progress, ask
106 how to proceed
107
108### Other Loops
109
110The same discipline — bounded iterations, progress detection, fail-safe
111guards — governs refactor passes (`/de-sloppify`: verify build + tests after
112each target, revert on failure) and scaffolding (`/scaffold`: generate, then
113run nested build-fix and test-fix loops). Nested loops get a smaller budget
114(parent 5 → nested 3), max nesting depth 2, total budget 15.
115
116## Invokes
117
118| Type | Name | Purpose |
119|-------|------------------------|--------------------------------------------|
120| Skill | `instinct-system` | Capture fix patterns in MEMORY.md |
121| Agent | `dotnet-architect` | Consulted for architectural error patterns |
122
123### MCP Tools Used
124
125- `get_diagnostics` — Compiler errors/warnings scoped to file or project
126- `find_symbol` — Locate moved or renamed types
127- `find_references` — Assess blast radius of a broken API change
128- `get_project_graph` — Dependency order for fixing reference errors
129
130## Example
131
132```
133User: /build-fix
134
135Claude: Running dotnet build...
136 Found 12 errors across 4 files.
137
138 Iteration 1/5:
139 - 6 errors: Missing namespace (CS0246) — adding using directives
140 - 3 errors: Type mismatch (CS1503) — updating method signatures
141 - 3 errors: Interface not implemented (CS0738) — package API changed
142
143 Rebuilding... 3 errors remaining.
144
145 Iteration 2/5:
146 - 3 errors: CS0738 after xunit.v3 upgrade
147 - IAsyncLifetime.InitializeAsync now returns ValueTask (was Task in v2),
148 and DisposeAsync comes from IAsyncDisposable
149 - Updating 3 test fixtures to the ValueTask signatures
150
151 Rebuilding... 0 errors. Build is green.
152
153 Running dotnet test... All 47 tests passed.
154 Added to Memory > Packages: "xunit.v3 IAsyncLifetime uses ValueTask signatures"
155```
156
157## Related
158
159- `/verify` — Full verification pass (build + test + format + diagnostics)
160- `/tdd` — Red-green-refactor when building new features test-first
161- `/de-sloppify` — Clean up code quality issues after the build is green