# Correction Loop & the diagnostic report

The how-to depth for the two outputs this skill produces: a root-caused *correction* (when a
symptom is wrong) and a *diagnostic report* (when a repo is audited). The four-layer triage
these route through is in [triage-model.md](triage-model.md).

## The Correction Loop — root-cause before you patch

Triggers whenever something — markup, plan, diagnostic, commit, response — is reported wrong,
or you notice it is wrong before the user does. **The instinct to fix the surface is the
failure mode**: a patch without a root cause re-emerges in another shape next turn. Five
phases, strict order, each gating the next.

```
1. CONTEXT     Re-anchor: what turn is this, what did I produce, what did the
               user actually say, what else is live (peer commits, working tree,
               stale memory)? Trust git log + filesystem over memory.
2. REFERENT    What are they pointing at — concretely? Name (a) the artifact,
               (b) the comparison anchor, (c) the failure mode, (d) any implicit
               reference. Any fuzzy → ask ONE targeted question; do not guess.
3. DECOMPOSE   Map the symptom to its layer of origin (triage-model.md).
               Run the zeroth question FIRST (Light DOM vs Shadow DOM) — before
               any getBoundingClientRect() probe.
4. ROOT-CAUSE  First-principles at that layer. Stop-condition: you can write
               "the wrong output happened because <Layer-N artifact> does <X>
               when it should do <Y> because of <first-principles reason>."
5. CLASSIFY    Route the fix — frequently MORE than one: immediate patch +
               upstream remediation + prevention gate.
```

If you cannot write the Phase-4 sentence, you do not have the root cause — return to Phase 3
and recheck the layer.

**The conversational shape (when you reply):** acknowledge without defending → restate the
referent (1 sentence) → walk the decomposition ("this came from layer N because <evidence>") →
name the root cause → propose the compound fix (immediate + upstream + prevention) → wait for
confirmation before executing, unless the immediate fix is trivial and obviously correct.
**Never silently swap in the right output** — it destroys the trail and trains the user to
distrust your reasoning.

## The bug-shape taxonomy (recognize the shape → narrow the layer)

| Shape | Symptom | Most common origin layer |
|---|---|---|
| **Tag swap** | wrong tag entirely (`<main>` for `<admin-content>`) | Skill (stale) or Codebase (predates ADR) |
| **Slot misdiagnosis** | looks like a missing `slot=`; the parent is Light DOM and the slot is inert | Skill (wrong substrate model) — **not a real slot bug** |
| **Attribute-shape misuse** | right tag/slot, wrong value type (string for an array prop) | Substrate (silent on bad shape) + Skill (missing shape contract) |
| **Composition violation** | right primitives, wrong nesting (`<button-ui>` in `<button-ui>`) | Spec (no nest rule) + Substrate (no nest-check warn) |
| **Token override** | right styling, wrong cascade source (`--a-fg` set in `:root`) | Codebase (global override) + Skill (missing scope note) |
| **Version-trailing** | right code, behaves like an older substrate | Codebase (range too loose) + Tooling (no version gate) |
| **Doc-stale** | right code matching an old spec since superseded | Spec (ADR/journal contradicts itself) |

For the lower four shapes, **expect a compound Codebase + Substrate-or-Spec fix.** A
single-layer patch leaves the next agent to hit the same silent trap.

## Worked example A — tag-swap ("shell uses `<main>` not `<admin-content>`")

Walk downward: intent is fine (user asked for an admin shell). Skill — did SKILL.md teach
`<main>`? grep it; if yes, origin found. Codebase — did the repo have `<main>` examples I
cargo-culted? grep the repo. Substrate — does `<admin-content>` exist?
`node_modules/@adia-ai/web-modules/shell/`. Spec — does an ADR mandate the swap? The first
layer where the symptom is *not yet caused* sits one above the origin.

## Worked example B — the Light-DOM trap (the misdiagnosis that shipped + reverted)

Symptom: "the admin shell renders but the topbar appears mispositioned." This is what tag-swap
looks like *after* the repo adopted the canonical vocabulary — right tag, suspected-wrong
attribute. **Run the zeroth question first.** `<admin-content>` / `<admin-sidebar>` are Light
DOM: a `slot="header"` on a child is inert, positioning is by tag + DOM order, so
adding/removing the slot is decorative. *Then* probe — but interpret against the right model: a
sidebar's topbar spanning only the 200px sidebar column (`0,0,200,48`) is **correct**, not
broken; a missing boundingClientRect points at DOM-construction or CSS-not-loaded, not slot
projection. A misdiagnosis that shipped is more instructive than a clean diagnosis: it exposes
the discipline gap (verify the rendering mechanism before the symptom probe) a clean case hides.

## Anti-compound-fix — land all three, or it comes back

A symptom that surfaces in markup (Codebase) often roots in the Skill **and** a missing
Substrate gate **and** a stale Spec. Route all that apply:

| Origin | Immediate fix | Upstream remediation | Prevention gate |
|---|---|---|---|
| Skill | patch the section, re-lint | re-audit the skill | its own eval / lint |
| Codebase | PR / commit | add convention to `AGENTS.md` | consumer-side `check:` script |
| Substrate | file upstream (feedback-discipline) | npm release + CHANGELOG | substrate `npm run check` |
| Spec | amend ADR, sweep surfaces | journal the change | the framework's own gate |

Ticket submission is **layer-routing, not effort-routing** — file because the origin is owned
by someone else or needs cross-version coordination, not because the fix is big.

## Sniff tests — before you commit to a root cause

1. **Could this occur in a clean repo, same skill, same substrate version?** Yes → origin is Skill/Substrate/Spec, not the Codebase. No → the Codebase carries triggering state.
2. **Did it exist before my (or a peer's) most recent change?** `git log -p <file>` — the commit that introduced it is usually the layer of origin.
3. **Does a gate exist that *should* have caught this?** Yes → the gate has a hole (a finding alongside the primary). No → propose one.
4. **Is this the same shape of bug I've seen this session?** Yes → the layer is probably one *up* (three wrong markups in a row = a wrong skill pattern, not three independent mistakes).
5. **Am I about to fix the symptom or the cause?** If the fix is one verb (`patch markup`, `rename attribute`), you're surface-patching. A cause-fix spans multiple steps across layers.

## The diagnostic report — the seven-section template

A **synthesis** of inventory + gaps + plan, not a recon dump. Sections 1–6 exhaustive; §7 the tl;dr.

1. **Repo identity** — tier, framework, rendering model, age, ownership (recon stop-questions).
2. **Version state** — the declared / installed / latest 3-tuple per `@adia-ai/*` package; lockstep status.
3. **Findings by gap class** — each as `{class, evidence:<file:line>, count, substrate_answer, remediation, leverage, risk}`; manifest-gap (class 0) sorts first.
4. **Ranked remediation sweeps** — leverage-ordered, each a single additive PATCH cut, each naming the gate that confirms it landed.
5. **Out-of-scope** — what you *considered and rejected*, with rationale. Load-bearing: it builds trust faster than any other section and shows the ranking was deliberate.
6. **Verification plan** — the gate per sweep; if none exists, propose one as part of the sweep.
7. **Overall posture** — one paragraph: *`<Repo>` is in `<strong/moderate/weak>` adoption — ~N% canonical, M gaps (X spec-drift, Y hygiene, Z deferred). Biggest leverage: `<Gap N>`. **Recommended next action:** `<Sweep K>` (`<effort>`), routed to `<app-migration / screen-composition / shell-selection>`. Defer the rest until `<trigger>`.*

**Discipline rules:** evidence is mandatory (every gap cites ≥1 `<file:line>` or grep line);
mechanism before remediation; leverage ranking explicit (un-ranked → §5 with its exclusion
rationale); PATCH-scoped sweeps only (additive, non-breaking; decompose a big sweep into N
ranked PATCH cuts); hand off, do not author (the report ends — authoring proceeds from a
*confirmed* plan handed to a builder skill, never an inferred one).

**Report anti-patterns:** dumping recon greps as "the report" (recon is raw inventory, the
report is synthesis) · ranking by personal interest instead of leverage · a remediation with
no verification gate · skipping §5 out-of-scope.
