---
name: bug
effort: medium
description: >
  Structured bug investigation and resolution workflow (framework-agnostic; project-specific entry points are loaded from `.baldart/overlays/bug.md`).
  Use when: the user says /bug, 'debug', 'c e un bug', 'non funziona', 'errore', 'broken',
  'investigate', or reports unexpected behavior. Accepts optional bug description as argument.
  Enforces a disciplined 5-phase debugging protocol that prevents blind guessing:
  (1) Reproduce & observe, (2) Enhanced logging if stuck, (3) Data-driven analysis,
  (4) Hypothesis & minimal fix, (5) Verify. Leverages Playwright MCP for browser capture,
  codebase-architect for code path tracing, `rg` over docs for known patterns, git bisect for regressions.
---

# /bug — Structured Bug Investigation

Argument: optional bug description (e.g., `/bug feature X is not saving`).

## Project Context

**Reads from `baldart.config.yml`:** `paths.design_system`, `paths.references_dir`, `paths.wiki_dir` (Phase 0 `rg` lookup target), `features.has_toolchain` + `toolchain.commands.{lint,typecheck,test}` (the PHASE 5 regression gates run those verbatim when the flag is on).
**Gated by features:** `features.has_design_system` (when `true`, Phase 4's design-system reads become BLOCKING for UI-touching bugs).
**Overlay:** loads `.baldart/overlays/bug.md` if present — project-specific debug entry points (e.g. SWR debug switches, env summary helpers, error-code modules). The base skill stays generic; project-specific code paths live in the overlay.
**On missing/empty keys:** ask the user; do not assume defaults. See `framework/agents/project-context.md` § 3.

## Effort

**Baseline:** `effort: medium` (frontmatter). **Inline override:** pass
`effort=<low|medium|high|xhigh|max>` anywhere in the invocation to scale
reasoning depth for this run — detect it once at kickoff and strip the token
before consuming user input. Level→behavior mapping, parsing contract, and
precedence caveats: `framework/agents/effort-protocol.md`.


## MCP dependencies

See [framework/docs/MCP-INTEGRATION.md](../../../docs/MCP-INTEGRATION.md) for the BALDART MCP integration contract and the rationale behind this section.

**Required** (skill cannot complete its task without these MCPs for the relevant bug class):
- `mcp__playwright__browser_*` (`browser_navigate`, `browser_take_screenshot`, `browser_console_messages`, `browser_network_requests`, `browser_evaluate`) — Phase 1 reproduction for **UI/Client** bugs. Without it the skill cannot capture deterministic state and Phase 1 degrades to "ask the user to reproduce manually and paste console logs". Phase 2's client-side `window.fetch` interception is impossible without `browser_evaluate`.

**Optional** (the skill benefits if present, has a documented fallback):
- `mcp__plugin_firebase_firebase__firestore_*` (or the project's DB MCP, when `stack.database.primary` is set) — Phase 1 inspection of runtime data state for **Data** bugs. Fallback: ask the user for a document export, or read the relevant code path and infer.
- `codebase-architect` agent (always available, listed for completeness) — Phase 0 code-path mapping. Not an MCP per se but is treated as a required dependency by this skill.

## ANTI-PATTERNS (NEVER DO)

- NEVER change code before reproducing the bug
- NEVER guess the root cause — form hypotheses from evidence only
- NEVER skip logging escalation when first pass finds nothing
- NEVER fix symptoms — trace to root cause
- NEVER remove temporary debug code without grep verification

## PHASE 0: TRIAGE (< 2 min)

1. Parse the bug description from args (or ask user if missing)
2. Classify the bug domain:
   - **UI/Client** → Playwright MCP is primary tool
   - **API/Server** → dev server logs + route handler analysis
   - **Data/Datastore** → the project's datastore inspection tooling per `stack.database` (e.g. the Firebase MCP for `firestore`, a SQL client for `postgres`/`supabase`, the Mongo shell for `mongodb`) + transaction tracing
   - **Auth** → the project's auth middleware/guard + auth error codes (per `stack.auth_provider`)
   - **Build/Deploy** → the deploy platform's logs + build output (per `stack.deployment`, e.g. Vercel)
3. Launch `codebase-architect` agent to map the affected code paths — do NOT start debugging blind.
   When `features.has_lsp_layer: true` and the symptom names a concrete symbol
   (function/type/handler), `codebase-architect` will use LSP find-references /
   go-to-definition to locate the exact callsites instead of grepping. See
   `framework/agents/code-search-protocol.md`. When `features.has_code_graph: true`,
   it can also trace blast-radius with `graphify affected "<symbol>"` (what breaks
   if this changes) — see `framework/agents/code-graph-protocol.md`.
4. Search for related patterns: `rg` over the project's error-code module (path
   listed in `.baldart/overlays/bug.md`) and `${paths.wiki_dir}/` with bug keywords.
   Verify any doc hit against repo docs/code before fixing.
5. Check git history for recent changes in affected area:
   ```
   git log --oneline -20 --all -- <affected-files>
   git log --oneline -10 --grep="<related-keyword>"
   ```

## PHASE 1: REPRODUCE & OBSERVE (mandatory before any code change)

Goal: get a reliable reproduction that you can re-run after fixing.

**For UI bugs:**
1. Navigate with Playwright MCP: `browser_navigate` to the affected page
2. Capture baseline: `browser_take_screenshot`
3. Capture console state: `browser_console_messages`
4. Capture network: `browser_network_requests`
5. Reproduce the bug step-by-step, capturing after each action
6. Record the exact sequence that triggers the bug

**For API bugs:**
1. Identify the route handler file from the URL pattern
2. Read the handler code — understand the full flow before anything else
3. Check the error propagation pattern: look for `throw new Error(JSON.stringify({code, status, message}))` — this is the domain error contract
4. Test the endpoint directly if possible (curl or Playwright network capture)

**For data bugs** (use the inspection tooling matching `stack.database`; the example below is for `firestore` via the Firebase MCP — for SQL stores use a SQL client / `SELECT`, for Mongo use the Mongo shell):
1. Inspect the record state — e.g. `mcp__plugin_firebase_firebase__firestore_get_document` (Firestore)
2. Check field/column values, timestamps, missing fields
3. If a collection/table query is involved: re-run the query against the store (e.g. `firestore_query_collection` for Firestore) to verify results

**Outcome:** a clear, repeatable reproduction OR evidence that the bug is intermittent (in which case, skip to Phase 2 immediately).

## PHASE 2: ENHANCED LOGGING (escalate if Phase 1 didn't reveal root cause)

**This is the critical phase.** If you don't see the root cause within 5 minutes of Phase 1, escalate to enhanced logging IMMEDIATELY. Do NOT keep reading code hoping to find it.

### Server-side logging injection

Add temporary debug logs to suspected route handlers. ALL temporary logs MUST:
- Use prefix `[DEBUG:<module>]` for easy grep
- End the line with comment `// DEBUG:` marker
- Include timestamps: `new Date().toISOString()`

```typescript
console.log(`[DEBUG:reservations] PATCH entry`, { // DEBUG:
  id: params.id,
  body: JSON.stringify(body).slice(0, 500),
  user: req.user?.uid,
  ts: new Date().toISOString(),
}); // DEBUG:
```

For datastore operations, wrap reads/writes to time them (Firestore shown as the example — use your store's client when `stack.database` differs):
```typescript
const t0 = Date.now(); // DEBUG:
const snap = await firestore.collection('X').doc(id).get();
console.log(`[DEBUG:fs] READ ${snap.ref.path} ${Date.now()-t0}ms exists=${snap.exists}`, snap.exists ? Object.keys(snap.data()!) : 'N/A'); // DEBUG:
```

For transactions, log attempt count:
```typescript
let attempt = 0; // DEBUG:
await firestore.runTransaction(async (tx) => {
  attempt++; // DEBUG:
  console.log(`[DEBUG:tx] attempt=${attempt}`); // DEBUG:
  // ... existing code
});
console.log(`[DEBUG:tx] done in ${attempt} attempts`); // DEBUG:
```

### Client-side logging (via Playwright MCP — zero code changes)

Use `browser_evaluate` to inject runtime instrumentation:
```javascript
// Intercept all fetch calls
const origFetch = window.fetch;
window.fetch = async (...args) => {
  const url = typeof args[0] === 'string' ? args[0] : args[0]?.url;
  console.log('[DEBUG:fetch]', args[1]?.method || 'GET', url);
  try {
    const res = await origFetch(...args);
    if (!res.ok) {
      const clone = res.clone();
      const text = await clone.text().catch(() => '');
      console.error('[DEBUG:fetch] error', res.status, url, text.slice(0, 500));
    }
    return res;
  } catch(e) {
    console.error('[DEBUG:fetch] network error', url, e.message);
    throw e;
  }
};
```
Then capture everything: `browser_console_messages` after reproducing.

### Cache/data-fetch debug mode

If the bug involves stale data and the project ships a cache provider with a debug switch (see `.baldart/overlays/bug.md` for the project-specific entry point — e.g. SWR/React Query/Apollo provider, env summary helper), enable it temporarily. Mark every temporary line with `// DEBUG:` so it can be grepped and reverted in Phase 5.

### Environment check

If the project exposes an env-summary helper (listed in `.baldart/overlays/bug.md`), call it to confirm env state. Otherwise, manually inspect the relevant `process.env` keys for the failing flow.

## PHASE 3: DATA-DRIVEN ANALYSIS

1. Reproduce the bug AGAIN with enhanced logging active
2. Collect ALL output:
   - Server terminal (grep for `[DEBUG:`)
   - `browser_console_messages` from Playwright
   - `browser_network_requests` from Playwright
   - Screenshots before/after
3. Analyze:
   - **Timeline**: what happened in what order?
   - **Divergence**: where does expected flow differ from actual?
   - **Error codes**: match against the project's error-code module (listed in `.baldart/overlays/bug.md`).
   - **Database state**: correct data returned? Transaction retries? (Storage tech depends on project.)
   - **Network**: status codes? Request bodies?
4. If regression, use git bisect:
   ```
   git bisect start HEAD <last-known-good> --
   git bisect run sh -c "npx tsc --noEmit 2>/dev/null || exit 125; <test-command>"
   ```
5. Form a specific hypothesis: "The bug occurs because X at line Y in file Z causes W"

## PHASE 4: HYPOTHESIS & FIX

1. State hypothesis explicitly
2. Verify consistency with ALL collected evidence
3. **Design System SSOT (MANDATORY for UI/styling bugs, when `features.has_design_system: true`)**: if the bug is visual (layout, spacing, color, motion, theming, overlay z-index) or the fix touches a UI component, you MUST read `${paths.design_system}/INDEX.md` and the relevant `${paths.design_system}/components/<Name>.md` BEFORE proposing the fix. This prevents patching symptoms with hardcoded hex/shadow values while the real fix is a token or component prop. Theming bugs (when `features.multi_tenant_theming: true`) → read the project's theming pattern doc; motion/animation bugs → read the project's motion pattern doc (both listed in `.baldart/overlays/bug.md` and `.baldart/overlays/ui-design.md`).
4. Implement MINIMAL fix — fewest lines possible
5. Do NOT refactor, add features, or "improve" surrounding code

## PHASE 5: VERIFY & CLEAN UP

> **Toolchain:** when `features.has_toolchain: true` in `baldart.config.yml`, run `toolchain.commands.{typecheck,lint,test}` **verbatim** instead of the defaults below — per `framework/agents/toolchain-protocol.md`. Empty/absent key (or flag off) → the default. A configured command that exits non-zero is a real FAIL (do not fall back).

1. Reproduce original scenario — confirm fix
2. Check regressions: `npx tsc --noEmit` + `npx eslint --max-warnings=0 <changed-files>`
3. If tests exist: `npm run test`
4. **REMOVE ALL DEBUG LOGGING:**
   ```bash
   grep -rn '// DEBUG:' src/ --include='*.ts' --include='*.tsx'
   ```
   Remove every line found. Run grep again to confirm zero results.
5. Revert any temporary cache/data-fetch debug switches enabled in Phase 2
6. Final Playwright screenshot to confirm visually

## TOOLS QUICK REFERENCE

| Tool | When | Purpose |
|------|------|---------|
| `codebase-architect` agent | Phase 0 | Map affected code paths |
| `rg` over docs / error-code module | Phase 0 | Search known patterns/errors |
| `mcp__playwright__browser_*` | Phase 1-5 | Navigate, screenshot, console, network |
| Project DB MCP (if available) | Phase 1 | Inspect storage state (e.g. firestore/postgres tools) |
| `git log/blame/bisect` | Phase 0, 3 | Find regression commits |
| Project-specific entry points | various | Listed in `.baldart/overlays/bug.md` — error-code module, env-summary helper, cache debug switch |

For detailed logging patterns, env vars, and storage debugging: see [references/logging-patterns.md](references/logging-patterns.md).
