ca-debug · diff

git:20260724.a3a2df2 to git:20260925.b075a61

100 added, 27 removed. Audit A to A.

---
name: ca-debug
- description: Investigate-then-decide root-cause analysis for a defect whose cause is unknown. No code changes — exits to /ca-fix, /ca-adr, or a no-action close.
+ description: "Investigate an unexplained defect or unexpected behavior without changing application code. Use for root-cause diagnosis and an evidence-backed handoff. A no-action close records a board note. Not for implementing a known fix, new features, or explanation-only questions."
argument-hint: "<observed symptom>"
---
- # /ca-debug — root-cause investigation
+ # debug
- Investigates a defect, anomaly, or unexpected behavior whose cause is not yet known. Separates investigation from implementation: no code is modified while debugging. Describe the symptom with enough fidelity that another operator could reproduce it — observed behavior, reproduction steps (or intermittent-trigger profile), and environment. Vague descriptions ("it's flaky") are rejected; the orchestrator asks for clarification before routing.
+ Select this owning procedure for a root-cause investigation, whether requested in
+ plain language or through `/debug`. The command spelling is not a prerequisite.
+ Investigation and implementation remain separate: this procedure never changes code.
+ It closes the reproduce, evidence, and regression-test handoff loop through `/fix`.
- If the cause is already known and a regression test is already named, invoke `/ca-fix` directly.
+ ## Entry boundaries
- ## Routes to
+ - A known bug with a named regression test belongs to `/fix` directly.
+ - A design discussion without failing behavior belongs to `/adr`; attribution is
+ still required before authoring an ADR. New behavior belongs to `/feature`.
+ - An explanation-only question stays in the non-mutating question-answer path;
+ it does not require a debug invocation or a command spelled by the user.
+ - Do not re-enter from an active `/fix` or `/adr` invocation. Complete that
+ invocation before a separate investigation; do not create a routing cycle.
+ - The phase gates below own symptom precision, evidence, and the one named exit.
+ A no-action close uses the board helper in Phase 5, never a direct file append.
- The `debug` skill (`<plugin-root>/routines/debug/SKILL.md`) — five gated phases: symptom
- capture, hypothesis generation, evidence gathering, root-cause decision, handoff. Phase 4 forces one
- named exit:
+ ## Pre-flight
- - **(a) Confirmed bug → `/ca-fix`**, carrying the confirmed bug statement, cited evidence, and a named
- regression test obligation tied to the minimal repro.
- - **(b) Behavior/design ambiguity → `/ca-adr`**, with the ambiguity statement and evidence ledger,
- authored only with explicit user attribution.
- - **(c) No-action close** — symptom and rationale appended to
- `<project-root>/.codearbiter/open-tasks.md`.
+ Read these, or STOP and surface the gap — never guess a log path, trace tool, or test runner:
- A real finding that is out of scope for those exits is marked inline `[NEEDS-TRIAGE]` and the
- investigation continues.
+ - `<project-root>/.codearbiter/tech-stack.md` — log paths, trace tooling, test runner conventions. The evidence sources.
+ - `<project-root>/.codearbiter/CONTEXT.md` — domain vocabulary, system structure, and the `stage:` frontmatter (the maturity value; higher demands more rigorous evidence before exit).
+ - `<project-root>/.codearbiter/security-controls.md` — only when the symptom touches a security boundary (auth, crypto, secrets). Optional; absent on most defects.
- ## When NOT to use
+ The user MUST supply at least a one-sentence symptom. If absent, ask for one — do not guess the symptom.
- - Known bug with a named regression test → `/ca-fix` directly.
- - Design discussion with no failing behavior → `/ca-adr`.
- - New feature → `/ca-feature`.
- - A general "why does it behave this way" question with no defect → `/ca-btw`.
- - Re-entry from inside `/ca-fix` or `/ca-adr` → exit that command first (routing-cycle prevention).
+ ## Phase 1 — Symptom capture · gate: BLOCK
- ## Hard gate
+ Record the symptom with enough fidelity that another operator reproduces it without further questions:
- MUST NOT modify any code during Phases 1–5 — code changes belong to `/ca-fix`. MUST exit Phase 4 with
- exactly one of (a)/(b)/(c). Exit (a) MUST carry a regression test obligation. Exit (b) MUST obtain
- user attribution before any `/ca-adr`. MUST NOT promote INCONCLUSIVE evidence to CONFIRMED without a
- cited source.
+ - **Observed** — one sentence: what the system did. Not the suspected cause; causes belong to Phase 2.
+ - **Expected** — one sentence. If the user cannot state expected behavior, that itself may be a design/behavior ambiguity — flag it for Phase 4.
+ - **Minimal repro** — exact command/request/action, required input and state, environment (local/staging/prod/test) and maturity value, frequency (every time / intermittent / one-time).
+ - **Evidence in hand** — error messages, stack traces, log excerpts; cite the source of each (log path + timestamp, request ID).
+
+ If no minimal repro exists, derive one with the user before continuing. An intermittent issue still has a trigger condition (an input pattern, a load condition, a timing window) — capture that.
+
+ Gate: a minimal repro, or a documented intermittent-trigger profile. A symptom without one cannot be debugged, only speculated about. Every piece of evidence MUST cite its source.
+
+ ## Phase 2 — Hypothesis generation · gate: BLOCK
+
+ Produce at least three distinct candidate causes, ranked by likelihood, before gathering any evidence against them. Distinct means different subsystems, mechanisms, or failure modes — not three rewordings of one suspicion.
+
+ For each candidate write: a one-sentence hypothesis, the subsystem/boundary involved, and the mechanism by which it produces the observed symptom. Number them H1, H2, H3… for Phase 3.
+
+ Rank by recency of relevant changes (recent commits to the suspect subsystem raise rank), symptom specificity (a symptom pointing narrowly at one mechanism raises it), and historical pattern.
+
+ Include at least one **boring** hypothesis — environmental drift, dependency version change, config mismatch, stale cache, operator error. List it even if ranked last. Confirmation bias toward exotic causes is the recurring debug failure mode.
+
+ Gate: three or more distinct hypotheses, one of them boring. Single-hypothesis lock-in is the single most common cause of misdiagnosis — the gate forces breadth before depth.
+
+ ## Phase 3 — Evidence gathering · gate: BLOCK
+
+ For each hypothesis, identify what would confirm or refute it, then gather that evidence by reading existing artifacts only. No code is modified in this phase.
+
+ For each H1…HN write the CONFIRM signal, the REFUTE signal, and the source where each lives (log file, trace tool, commit range, metric dashboard). Then read:
+
+ - Application logs and traces at the paths/tools in `tech-stack.md`.
+ - Recent commits (`git log`, `git diff`) on suspect paths.
+ - Configuration, environment variables, feature flags (read-only).
+
+ Annotate each hypothesis CONFIRMED, REFUTED, or INCONCLUSIVE, with a cited source. Do not collapse INCONCLUSIVE to CONFIRMED or REFUTED by inference — state what additional evidence is needed and where it lives. New hypotheses that emerge are added and gathered against; Phase 2 is a floor, not a ceiling.
+
+ Gate: no code change of any kind — no edit, no refactor, no "try a fix." A hypothesis testable only by changing code becomes a Phase 4 finding (exit (a), with a regression test obligation), not a change here. No INCONCLUSIVE evidence promoted to CONFIRMED without a cited source.
+
+ ## Phase 4 — Root-cause decision · gate: BLOCK
+
+ Walk the evidence ledger and pick exactly one exit. "We'll figure it out later" is not an exit.
+
+ - **(a) Confirmed bug → `/fix`.** One hypothesis is CONFIRMED by cited evidence and the disposition is a code change. Carry: the hypothesis ID and statement, the cited confirming evidence, and a named **regression test obligation** — a one-sentence description of the test `/fix` MUST write (and watch fail) before any fix code. It MUST encode the Phase 1 minimal repro, so the exact condition that reproduced the defect becomes the test that proves it fixed — this is what closes the reproduce→fix→verify loop. `/fix` refuses to proceed without it.
+ - **(b) Behavior/design ambiguity → `/adr`.** The system behaves as currently specified, but the specification itself is in question. Carry: the hypothesis ID and statement, a one-sentence statement of the ambiguity, and the symptom record plus evidence ledger as context. An ADR is authored only via `/adr` with explicit user attribution — surface the question to the user and obtain attribution; never author the ADR autonomously as the disposition of a debug session.
+ - **(c) No-action close.** The symptom is non-reproducible, was a one-time environmental event, or was already resolved by an unrelated commit. Carry: a one-sentence rationale, the cited evidence supporting "no action," and a note appended to the symptom record.
+
+ If a finding is real but out of scope for any of the three exits, mark it inline with `[NEEDS-TRIAGE]` and continue — do not stall on it.
+
+ If no exit can be chosen — all hypotheses INCONCLUSIVE — loop back to Phase 3 for more evidence, or take exit (b) and surface the open question. "No decision" is not a valid exit.
+
+ Gate: exactly one of (a) / (b) / (c) is named. Exit (a) carries a regression test obligation. Exit (b) carries the ambiguity statement and user attribution before any `/adr`. No exit closes on "more investigation needed" without either looping to Phase 3 or selecting (b).
+
+ ## Phase 5 — Handoff · gate: BLOCK
+
+ Emit a summary downstream skills can consume without re-reading the session, then route:
+
+ - **Summary block:** symptom (one sentence), reproduction profile, hypotheses considered (count + one-line list), evidence ledger summary (CONFIRMED / REFUTED / INCONCLUSIVE per hypothesis), the Phase 4 exit and rationale, and the handoff target.
+ - **Exit (a):** route to `/fix` with the confirmed bug statement, cited evidence, and named regression test obligation. The orchestrator routes `/fix` to the `tdd` skill in bug-fix variant, where that test becomes the Phase 1 obligation that must fail before fix code. `debug` does not pre-write the test.
+ - **Exit (b):** surface the chosen `/adr` with the ambiguity statement, symptom record, and evidence ledger attached as context, with user attribution.
+ - **Exit (c):** record a queued entry **through the board helper, never by appending to the file** — `python3 "<plugin-root>/hooks/taskwrite.py" add "<symptom>" --desc "<no-action rationale>"` (add `--id debug.note` to mint a dotted ID; optional for a debug note). The helper owns the schema the SessionStart hook parses, so a note recorded this way cannot drift from it, and it is the only writer that `.codearbiter/open-tasks.md`'s protected-state class admits. This keeps the note in the in-flight count as an open item to revisit rather than a bare bullet. No further handoff.
+
+ Surface the summary and the handoff to the user before the skill exits.
+
+ Gate: the handoff is routed. Exit (a) carries an explicit regression test obligation. Exit (c) is recorded before close.
+
+ ## Hard rules
+
+ - MUST NOT modify, refactor, or "try a fix" on any code during Phases 1–5. Code changes belong to `/fix`.
+ - MUST NOT proceed past Phase 1 without a minimal repro or a documented intermittent-trigger profile.
+ - MUST NOT proceed past Phase 2 with fewer than three distinct hypotheses, or with three rewordings of one suspicion.
+ - MUST include at least one boring environmental / configuration / dependency hypothesis in Phase 2.
+ - MUST NOT promote INCONCLUSIVE evidence to CONFIRMED or REFUTED without a cited source.
+ - MUST cite the source of every piece of evidence — log path + timestamp, commit SHA, trace ID.
+ - MUST exit Phase 4 with exactly one of (a) confirmed bug → `/fix`, (b) ambiguity → `/adr`, or (c) no-action close.
+ - MUST NOT route to `/fix` for a bug not yet confirmed by cited evidence — `/fix` is for known bugs.
+ - MUST NOT exit (a) without a named regression test obligation for `/fix` to carry into its TDD Phase 1.
+ - MUST tie the exit-(a) regression test obligation to the Phase 1 minimal repro — the repro is the test that closes the loop.
+ - MUST NOT author an ADR autonomously as the disposition of a debug session — exit (b) obtains user attribution and routes through `/adr`.
+ - MUST NOT guess a log path, trace tool, or test command — read `tech-stack.md` or STOP.