skills: deduplicate single-agent SKILL.md files (debug, fieldtest)

The four-phase debug process and the five-phase fieldtest process
each lived twice — once in SKILL.md (orchestrator-facing) and once
in the dispatched agent's file (subagent-facing). The orchestrator
does not execute these phases; the subagent does. Duplicating them
in SKILL.md just bloated the orchestrator's main context with bytes
that only the subagent ever needs.

SKILL.md now carries only what the orchestrator must consult at
dispatch time: trigger gating, Iron Law as headline, the carrier
contract, the produced handoff, and cross-references. Iron Law in
operational form, full process, Common Rationalisations, Red Flags,
and (for fieldtest) the spec template now live solely in the agent
file. Net −160 LOC across the skills tree.

CLAUDE.md pointer for 'Bug fixes — TDD, always' updated to reflect
that the substantive discipline lives in the agent file, not the
skill file.
This commit is contained in:
2026-05-10 10:53:53 +02:00
parent bb6b52e7c3
commit 64b0841c5a
5 changed files with 97 additions and 254 deletions
+22 -87
View File
@@ -15,6 +15,13 @@ skill then drives the fix to GREEN. Skipping the RED stage — even for
"trivial" bugs — produces fixes that don't stick and tests that don't
exist to catch the next regression.
The substantive process — root cause investigation → pattern analysis
→ RED test → handoff, plus the Phase 4.5 architecture-question trigger
after three failed hypotheses — lives in
`agents/ailang-debugger.md`. That file is the single source of truth
for the discipline; this skill file only governs trigger, dispatch,
and handoff.
## When to Use / Skipping
Trigger this skill on:
@@ -40,74 +47,24 @@ Both clauses are non-negotiable. The second was formerly the
CLAUDE.md "Bug fixes — TDD, always" section before the
2026-05-09 skill-system migration.
## The Process — four phases
## Dispatch
Each phase must complete before the next starts.
Dispatch `ailang-debugger` with:
### Phase 1 — Root Cause Investigation
| Carrier field | Content |
|---------------|---------|
| `symptom` | Exact error message, stack trace, wrong output, or repro command |
| `repro_known` | One-line repro if known, otherwise the agent finds one |
| `recent_iter` | Iteration that last touched the suspected area (often `git log` tail) |
1. Read the error message in full. Stack traces, line numbers, exit
codes — none of them get skimmed.
2. Reproduce with the shortest possible command. If you can't repro
reliably, gather more data — do NOT guess.
3. Check recent changes: `git log --oneline -20`,
`git diff <previous-iter-commit>..HEAD`.
4. For multi-component issues (compiler → emitter → linker; or
runtime → C glue → binary), instrument every boundary. Find the
layer where the data goes wrong before deciding which layer to
fix.
5. Trace data flow backward from symptom to source. Fix at source,
not at symptom.
### Phase 2 — Pattern Analysis
1. Find a similar working example in the codebase. What's different?
2. If the bug is in a pattern (e.g. ADT match lowering, RC drop
emission), read the reference implementation completely. No
skimming.
3. List every difference between working and broken — however small.
### Phase 3 — Hypothesis and Test
1. State the hypothesis as a single falsifiable claim:
*"X is the root cause because Y."*
2. **Write the failing test FIRST**, before any fix attempt:
- smallest possible reproducer (E2E in `crates/ail/tests/e2e.rs`,
or unit test in the affected crate)
- automated, deterministic — same input always same output
- doc comment names the property the test protects, not just
what it does
3. Run it to confirm it fails on the current code, with the symptom
the bug-report described.
4. Commit the failing test as a separate commit:
`git commit -m "test: red for <symptom>"`.
### Phase 4 — Hand off to `implement`
The fix itself is `implement`'s job, run in mini-mode. Hand it:
- path to the RED-test file
- 1-2 sentence cause summary from Phase 1
- hard constraint: *"minimal fix, no surrounding cleanup,
no opportunistic refactor"*
`implement` runs the GREEN side and commits `fix: <symptom>`.
### Phase 4.5 — 3+ failures = architecture question
If the third hypothesis fails:
```
STOP. Do not attempt Fix #4.
```
Three failed fixes in a row indicate the architecture is wrong, not
that the latest hypothesis is wrong. Each fix likely revealed new
shared state or coupling in a different place. Surface the
architecture question to the user; do not guess again.
The agent commits the RED test as `test: red for <symptom>` and reports
the handoff carrier for `implement` mini-mode. The agent does NOT write
the fix — splitting RED (this skill) and GREEN (`implement` mini-mode)
across two dispatches keeps the diagnosis honest.
## Handoff Contract
The carrier `debug` hands to `implement`:
`debug` produces, for `implement` mini-mode:
| Field | Content |
|-------|---------|
@@ -118,34 +75,12 @@ The carrier `debug` hands to `implement`:
Anything else (broader refactor, doc rewrite, new feature) is OUT of
scope for the bug-fix iteration and gets queued for a separate one.
## Common Rationalisations
| Excuse | Reality |
|--------|---------|
| "The implementer says it's obviously the new tag-extract emit" | Confident guesses paper over real causes. Repro, isolate, RED test, then fix. |
| "Trivial bug, existing tests will catch it if we break something" | The existing tests already passed while this bug shipped — by definition they don't cover it. |
| "30 seconds to repro, 30 seconds to fix, skip the test" | 30 seconds to repro is also 30 seconds to capture as a regression fixture. Don't trade durable coverage for nothing. |
| "I'll write the test after the fix works" | Test-after proves nothing about whether the test would have caught the bug pre-fix. |
| "Two fixes failed; the third hypothesis is the right one" | Two failures means the hypothesis space is wrong. STOP, dispatch the debugger agent, do not guess again. |
| "End-of-day, just push the fix and write the test tomorrow" | End-of-day pressure is exactly when shotgun fixes corrupt the tree. Clean tree + open bug > three speculative half-fixes merged. |
| "Architecture question is for next milestone, fix-and-revisit" | Phase 4.5 fires NOW or never. Carrying the wrong shape forward compounds. |
## Red Flags — STOP and follow process
- "Quick fix for now, investigate later"
- "Just try changing X and see if it works"
- "I see the symptom, let me fix it"
- "The test is redundant, I manually verified"
- "Pattern says X but I'll adapt it differently"
- *"One more fix attempt"* (when ≥ 2 already failed)
All of these mean: **return to Phase 1**.
## Cross-references
- **Agent dispatched:** `skills/debug/agents/ailang-debugger.md`
carries the actual diagnostic work (read CLAUDE.md / DESIGN.md /
JOURNAL, reproduce, write RED test, propose minimal fix).
carries the four-phase process, the Phase 4.5 escalation rule, the
Common Rationalisations table, and the Red Flags list. The
orchestrator does not execute these phases directly.
- **Hand-off target:** `skills/implement/SKILL.md` — runs the GREEN
side after the RED test is committed.
- **Project source:** former CLAUDE.md "Bug fixes — TDD, always"
+3 -1
View File
@@ -26,7 +26,9 @@ genuinely captures the symptom, not the post-fix code path.
2. `docs/DESIGN.md` — invariants the bug may have crossed.
3. `docs/JOURNAL.md` — most recent entries; the last iteration may have
introduced the bug.
4. `skills/debug/SKILL.md` — the four-phase process you follow.
The four-phase process below is the single source of truth — the
dispatching skill file does not duplicate it.
## Carrier contract — what the controller hands you