<!--
  scaffold: investigate-root-causes.md
  bucket: engineering-discipline (Bucket 5)
  what belongs here: investigate root causes; don't bypass safety checks.
    - When a hook fails, understand why before proposing a workaround.
    - When tests fail, understand why before adding an ignore.
    - When a lint fails, understand why before disabling.
    - Patch vs fix — the patch shortcut is what makes a codebase decay.
-->

# Investigate root causes

## The rule

When something fails — a hook, a test, a lint, a deploy — investigate the root cause BEFORE proposing a bypass. The bypass is often what someone in the future has to unwind at 10x the cost.

## Common shortcut failures

- **`--no-verify` to bypass a pre-commit hook.** The hook exists for a reason. Fix the underlying issue.
- **`skip: true` on a failing test.** The test caught a real issue. Fix the code the test is asserting about.
- **`// eslint-disable-next-line` on every failing lint.** The rule was enabled for a reason. Either follow it or (with reasoning) disable it project-wide.
- **`try { ... } catch { /* ignore */ }`.** The error was raised for a reason. Handle it or let it propagate.
- **Bumping a dep to work around a bug.** The bug was in your code, not the dep — the bump masked it.

## When bypass is warranted

- **The check itself is wrong.** Rare, but real. If the pre-commit hook has a bug and the fix will land in the next commit, bypassing THIS commit is defensible — but propose the bypass to the operator, don't do it silently.
- **Time-sensitive fix under partial constraint.** A prod outage where a hook fires on unrelated files — bypass the hook, land the fix, come back and address the hook's over-broad match.

In both cases the bypass is temporary and the underlying issue is captured. If the bypass becomes durable, the check is de facto disabled and should be either removed or fixed.

## Investigation shape

- Reproduce the failure locally.
- Read the check's actual output. Not the summary — the actual output.
- Read the code the check is asserting about.
- Formulate a hypothesis about what's wrong.
- Confirm the hypothesis before fixing.

## Don't accept "flaky test" as an explanation

Tests are either deterministic or they're broken. "Flaky" means "there's a real race / timing / state-leakage issue and no-one has time to fix it." The right response is to fix the flakiness (isolate the state, fix the race, add the retry-with-known-fix pattern), not to add `retry: 3` and hope.

## Related

- CLAUDE.md.template Bucket 5 rule 4.
- `blast-radius-and-safety.md` — the safety context this rule lives in.
- `verify-runtime-behaviour.md` — verification is how you confirm the root cause was actually fixed.
