Files
2026-10-14 00:33:28 -07:00

18 KiB
Raw Permalink Blame History

name, description, metadata
name description metadata
bugfix Root-cause bug fixing that repairs the whole defect class, not just the reported instance. Reproduces with evidence, proves the root cause, defines the defect class, finds every sibling (copies, other spellings, other consumers of the same contract, data the bug already wrote), fixes at the origin, adds a tested guard against recurrence, and verifies the fix is live with no regressions. Use when something is broken, wrong, erroring, flaky, slow, or regressed: "fix this bug", "debug", "not working", "error", "exception", "crash", "wrong output", "regression", "intermittent", "console warning". Not for new features, pure code review, or performance tuning with no defect.
version
1.0.0

Bugfix: fix the class, not the instance

A reported bug is one instance of a mechanism. Mechanisms get copied, imitated, and re-written by people holding the same wrong assumption. This skill proves the cause, finds every place the mechanism lives, fixes it at the origin, and leaves a guard so the next instance fails a check instead of reaching users.

Promise: Prove the cause. Fix every instance. Make the next one hard to write. Break nothing.

How to read this skill

  • Paths are relative to this file. Load a references/ file only when a phase points to it.
  • "Search", "run", and "edit" mean whatever tools your environment provides.
  • Capabilities vary. If you can't execute code, run a browser, reach a service, or write files, do what you can. Label anything unverified as provisional and list the checks the user must run.
  • Project-specific knowledge lives in the project (references/project-knowledge.md). Never modify this skill's files while fixing a bug.

Iron rules

  1. Evidence before fixes. Reproduce first, ideally as a failing automated test that asserts the correct result.
  2. Proven root cause. The cause must pass four gates: reproducible, causal, reversible, mechanistic. "Causal" means the intended behavior is restored. If the error merely disappears (catch-and-ignore, fallback), it is not causal.
  3. Fix the class. Define the class (preconditions + mechanism + violated invariant + failure) and search every axis for siblings before writing the fix. (Diagnostic probes in Phase 2 are fine; revert them.) Your combined queries must recover every known instance (recall check).
  4. Candidates are not defects. A search hit is confirmed only by a witness (a failing test or a traced invariant violation) and excluded only with a reason.
  5. Fix at the origin. Use a shared fix only when the sites share the same contract. Otherwise fix each site the same coordinated way. Never patch downstream symptoms.
  6. Leave a tested guard. At least one check must fail on a new instance of the class. Prove it with the guard acceptance test for your depth.
  7. Know the blast radius before editing: consumers, contracts, invariants, call sites, duplicates.
  8. Verify what actually runs. Show that the executing artifact is the fixed one and that the real entry point behaves correctly. Handle data the bug already wrote per the safety boundaries.
  9. No regressions. Capture the baseline before changing anything; compare after.
  10. Check framework behavior in the installed source or with an experiment. Docs and memory are hypotheses.

Safety boundaries

Free to do Ask the user first
Read code; run local tests, linters, and builds; edit the working copy; add tests; create scratch files and isolated copies (and remove them) Contract/schema changes (including changed behavior for edge inputs of a public interface), new dependencies, migrations
Invalidate disposable data the bug produced, but only when all of these hold, and disclose it in the report:
• it is derived (a cache or build output, not a record of truth);
• it is used only locally (no other consumer or sync);
• its current contents are exactly recoverable (committed and unmodified since the baseline, or regenerable).
Uncertain or mixed data counts as authoritative.
Repairing authoritative data (records, queues, user data), even when the file is local; touching shared or remote environments, caches, or queues; deploying
Restarting or killing processes you didn't start; writing project knowledge files; anything costly or irreversible

Finding a command (in a README, CI file, or this skill) doesn't authorize running it. Target processes by exact PID or command line, never by name pattern. Data repair needs a backup or rollback plan and a dry run with counts. Probes and logs must redact secrets, tokens, and personal data, and must be removed or deliberately kept.


Workflow

Phase 0 Triage ─┬─ Quick ─────────► 1 → mini-3 → 5 → 6 → 7 (short report)
                ├─ Standard ─┐
                └─ Full ─────┴─► 1 Reproduce → 2 Root cause → 3 Class analysis
                                 → 4 Scope & impact → 5 Fix → 6 Verify → 7 Report & learn

Phase 0: Triage

Depth When (any trigger in a higher row wins)
Full P0/P1, security, data loss or corruption, shared code or contract, schema, concurrency, multi-process, more than 3 files
Standard Logic bug in 1–3 files, P2/P3, nothing shared
Quick Typo, wrong constant or config value, obvious one-liner, no behavior change beyond the bug
  • Severity: P0 = down, data loss, or security. P1 = a core feature broken or data corrupted. P2 = a non-core feature or the UI. P3 = cosmetic.
  • Risk triggers override reported severity and small patch size. Re-triage whenever a trigger appears, especially after Phase 3: class severity = worst confirmed instance.
  • Quick depth still needs proof, compressed: a check that fails before the change and passes after (that covers reproducible, causal, and reversible), plus the one-line mechanism.
  • P0/P1 in production: contain first. Propose an authorized mitigation (rollback, feature flag off, rate limit), get approval, and apply it. Then do the permanent repair. Agree on a status-report interval with the user; report after every phase and on every containment change.
  • No-progress budget: if two consecutive rounds of experiments yield no new discriminating evidence, change the method (probes, bisect, smaller repro) or report what's eliminated and ask. Rejected hypotheses count as progress.

Phase 1: Reproduce

Bug type Minimum evidence
Backend / CLI Exact input, full error and stack trace, version/commit, config
UI Runtime evidence from the actual surface plus exact steps:
• browser: screenshot, console, DOM/styles, network
• native app: screenshot, widget/accessibility tree, logs
• terminal: captured output, input/event trace
Never diagnose UI from code reading alone. Without that runtime, the diagnosis is provisional.
Performance Before-metrics plus profile or query count
Intermittent Failure rate over N runs, plus timing, concurrency, and environment conditions
Data Example bad records plus the path that wrote them
  • Turn the repro into a failing automated test where feasible. It becomes the regression test and the reversible gate.
  • Baseline: find the project's real commands (references/verification.md sections 0–1). Run them on unmodified code and record the tests that already fail.
  • Can't reproduce? Follow references/root-cause.md section 6 (narrow the environment, bisect, instrument). Never present a speculative fix as confirmed.

Phase 2: Root cause

  1. Known matches first: check the project's knowledge files, then references/bug-patterns.md and the backend/frontend playbooks. Use only rows that fit the stack. A match is a lead, not a proof.
  2. Hypothesis ladder: unless the evidence already pins one mechanism, write 3–5 falsifiable hypotheses; cheapest rejection tests first; one variable at a time. Then five whys until you reach a mechanism plus its trigger condition. See references/root-cause.md. If the bug crosses process or service boundaries, also use references/system-rca.md.
  3. Origin layer: input, config, data, contract, shared code, repeated local mistake, single component, architecture, external dependency, or model capability. The fix goes there.
  4. Four gates:
Gate Evidence
Reproducible Failing test or scripted repro
Causal A minimal change restores the intended output; a negative control stays correct
Reversible Removing the change (in a test or fixture) brings the failure back
Mechanistic file:line, the violated invariant, and a step-by-step explanation

The causal/reversible change is a diagnostic probe. Apply it in a test, a scratch copy, or in place, then revert it. The real fix comes in Phase 5, shaped by Phases 3–4.

Phase 3: Class analysis (the core)

Method and verified search recipes: references/class-analysis.md. Produce these, in order:

  1. Class definition: preconditions + mechanism + violated invariant + observable failure. Add the mechanism's spellings, the wrong assumption behind it, and legitimate neighbors (code that looks similar but is correct).

  2. Search universe: roots and file classes covered (untracked, ignored, submodules, generated, sibling repos). Anything you can't search is a coverage limit, not "no hits".

  3. Searches across the axes: clones, same syntax, same mechanism in other syntax, same contract (writers and readers), same assumption, parallel paths, history, data and artifacts, config/env/platform.

  4. Recall check:

    • The combined queries return every known instance.
    • Each complementary query hits a positive example from its own target population.
    • At least one variant spelling is probed.
  5. Inventory: one row per candidate, with a disposition:

    • confirmed (needs a witness);
    • excluded (needs a reason);
    • unresolved (gets reported).

    Data rows count too. Re-triage on the worst confirmed row.

  6. Fix level (highest that fits the evidence and approved scope):

    1. Eliminate: a type, a shared helper, boundary validation, or a safe default. Only if the sites share the contract.
    2. Centralize + guard.
    3. Coordinated site fixes + guard.
  7. Guard plan, plus how you will run the guard acceptance test for your depth (Step 6 of the reference). Reverse only the production fix, in an isolated copy, so the user's uncommitted work is never touched.

Quick depth does a mini version: the class definition in one line, one search for the same mistake with a recall check, and an escalation if it finds siblings.

Phase 4: Scope & impact (before editing)

Full depth: five gates. Standard depth: the quick check below.

# Gate Output
1 Consumers All dependents of the code you will change, including re-exports, dynamic dispatch, and registrations
2 Contracts Interfaces, schemas, and behaviors that change, including return types and shapes and behavior on inputs outside the bug (empty, null, case, whitespace, errors). Every change gets listed in the report; public ones need approval first.
3 Invariants What must stay true
4 Call sites Each one: affected / unaffected / needs update
5 Duplicates Parallel implementations covered by the inventory

Impact chain:

  • code: out to the user-facing surface;
  • data: corrupted records, repair needed?;
  • time: when introduced, how long exposed;
  • events: queues, streams, jobs.

Then check the applicable entries in references/blind-spots.md and the project's own list, and decide go / no-go. For Full depth with competing approaches, compare size, blast radius, regression risk, and rollback.

Quick impact check (Standard depth):

- Change: <one line>   - Origin layer: <layer>
- Consumers: <list or "local only">   - Inventory: <n confirmed / n excluded / n unresolved>
- Could break: <prediction>   - Blind spots checked: <ids>   - Decision: GO / NO-GO

Phase 5: Fix

  • The failing test exists first, then the code change.
  • Fix at the origin layer, using the chosen rung. Per-site edits stay minimal. Identical edits across confirmed sites are fine. Unrelated refactors are not: propose them instead.
  • One concern per change: the class fix, the guard, and the tests.
  • When the fix matches strings or patterns, define the token grammar and test the boundaries: equal, prefix, suffix, embedded, empty, case, unicode, multiline. Prefer parse-then-compare over a cleverer regex.
  • For data repair or migrations, follow the safety boundaries: backup or rollback plan, dry run, approval.
  • Where the fix depends on framework behavior, leave a short comment with the evidence (source location or experiment).

Phase 6: Verify

Details: references/verification.md.

  1. Correctness: the repro test passes; every confirmed site is verified; edge and failure paths work; the guard passes its acceptance test.

  2. Regression: run the affected suites, then compare the full relevant suite with the baseline. Check performance and concurrency when relevant.

  3. Runtime: show that the executing artifact is the fixed one and that the real entry point is correct. Acceptable evidence:

    • a version or commit the running process reports;
    • an artifact hash or image digest;
    • a process started after the change whose loaded files are the edited ones.

    A new PID, a loaded file path alone, or a 200 health check proves nothing. Only touch caches or processes when evidence implicates them, within the safety boundaries.

  4. Review: use an independent reviewer (a code-review tool, a second agent, or a person) if one is available. Name it in the report and cite its verdict. Anything else is self-review; call it that. Check that:

    • the diff matches the inventory;
    • there are no unrelated changes and no secrets;
    • the tests fail without the fix;
    • error paths are handled.

Phase 7: Report & learn

Pick exactly one outcome. If several apply, report the first that matches in this order, and list the rest as follow-ups. Prerequisites: references/verification.md section 6.

  1. Not fixed: the reported instance isn't fixed and verified in code. Include evidence, eliminated hypotheses, and the next experiment.
  2. Partially fixed: some confirmed or unresolved rows remain (code or data), listed with reasons.
  3. Fixed locally, not live: every row fixed in code with checks passing, but runtime is unverified, or a deploy or restart awaits approval.
  4. Class fixed: everything above is done, the guard is accepted, and the runtime is verified.
## Bugfix report: <short symptom>
- Outcome: <one of the four>   Severity/depth: <P?>/<Quick|Standard|Full> (class severity: <P?>)
- Symptom: <user-visible>
- Root cause: <mechanism, file:line, violated invariant>. Gates: reproducible ✓ causal ✓ reversible ✓ mechanistic ✓
- Class: <preconditions + mechanism + invariant + failure>; legitimate neighbors: <...>
- Search universe / coverage limits: <...>
- Queries + recall check: <axes, queries, known instances recovered, variant probe>
- Inventory: <table: site | disposition | evidence>
- Fix level: <rung>. Why not higher: <reason>
- Guard: <what>. Acceptance items passed: <list>; limits: <...>
- Verification: <baseline → after; entry point exercised>   Runtime/data: <evidence or "unverified: why">
- Contract changes (incl. edge inputs): <none | list>   Review: <independent: who + verdict | self-review>
- Needs approval / follow-ups: <reported rows, containment, data repair, deploy, higher-rung proposal>
- Escape analysis: <why this class escaped (missing test/type/review/knowledge) and what now closes it>

Quick depth: Outcome, Symptom, Root cause, Class (one line), the sibling search and its result, Fix, Verification.

Afterwards:

  • Propose project knowledge entries (references/project-knowledge.md). Write them only with consent.
  • If the fix caused a regression, add a regression autopsy: what broke, why it wasn't predicted, which gate or check would have caught it.

Anti-patterns

Don't Do
Fix from code reading, without a repro Reproduce; failing test asserting the correct result
Accept "the error went away" as the cause Intended behavior restored + negative control
Fix the reported file only Define the class → search all axes → inventory
Trust a query that never hit anything Validate every query against a known positive of its population
"Fix" every search hit Witness for confirmed, reason for excluded
Build a shared abstraction because code looks alike Centralize only for a shared contract; otherwise coordinated site fixes
Ship a guard you never saw fail Guard acceptance test
Treat reported severity as final Class severity = worst confirmed instance
"Tests pass" = done Executing artifact + real entry point + data checked
Run whatever the docs say, restart by name, clean caches by habit Safety boundaries; act on evidence only
Round a partial fix up to "fixed" Report exactly one outcome state

References

File Load when
references/class-analysis.md Phase 3, always (Quick: Steps 1 and 3)
references/root-cause.md Phase 2; can't reproduce; intermittent bugs
references/system-rca.md Bug crosses processes, services, queues, streams, or browser automation
references/bug-patterns.md Phase 2 known-match search; Phase 3 sibling search ideas
references/backend-patterns.md Server, API, DB, or LLM-integration bugs
references/frontend-patterns.md UI, client state, or browser bugs
references/verification.md Phase 1 baseline; Phase 6; outcome states
references/blind-spots.md Phase 4 (Standard/Full)
references/project-knowledge.md Phase 2 (read) and Phase 7 (propose or write)