Gate·Isolate·Prove — debug to truth, no trial-and-error
The procedure that lands the ACCURATE fix by making every conclusion a measured fact, never a source-read guess. Composes two laws: instrument the boundary, don't reason from source + validate in isolation.
Standing order: a fix that can't reduce to an observation you can point to is a guess. Plausible-but-wrong is the enemy — each plausible theory costs a full fix cycle. One measurement ends the search.
G1 — Gate the surface
Reproduce, then bound where the bug can live. Which route / tab / component / query / layer? Rule out the false sources first (framework? DB? proxy/CDN? hydration? network? your own logic?) so you don't fix the wrong layer. State facts / unknowns / assumptions, labelled. Don't dig until the surface is narrowed.
G2 — Instrument the boundary
Hook the exact seam where your code meets the opaque layer and read what crosses it. Pick the probe by symptom:
- Server crash / 500 / opaque error → the runtime logs (Vercel, Supabase, app). Grep the thrown message. HTML where you expected JSON = a proxy/CF challenge.
- Blank / broken / partial render → CDP attached to the real browser (not a fresh incognito):
Runtime.exceptionThrown, Runtime.consoleAPICalled errors, Network.responseReceived status, and a DOM read of the ACTUAL panel node's textContent (not body.innerText, which collapses to chrome).
- Slow query →
EXPLAIN (ANALYZE, BUFFERS) on the RPC's inner query (the outer function-scan hides the cost). Read Seq-Scan vs Index-Scan, "Rows Removed by Filter", temp/disk spill, row counts.
- Slow interaction / "not snappy" → CDP network timing on the click: one RSC fetch or many? how long? serial waterfall or parallel? Compare to the DB time — if DB≈0 the cost is RTT × serialization, not SQL.
Reason from the source tree ONLY after the boundary names which file to open.
G3 — Isolate a faithful env
Reproduce in a controlled copy that mirrors production, not a mock:
- Web: a prod build (
build + start), NOT dev — dev hides error-stripping, minification, streaming, the digest path. Run it on a separate port — never kill or reuse the user's running dev server.
- Mirror the prod config that triggers the bug (same proxied domain, same env shape). A green
dev server or a passing typecheck is not proof.
- DB:
EXPLAIN/timing against the real table, or a branch — reproducible from migrations/config, not hand-built.
G4 — Prove cause, then prove fix
State the root cause with the measurement that shows it. Apply the fix. Re-run the same boundary hook — the fix can create the symptom it was meant to kill; a green diff proves nothing. Report before/after numbers from the same probe.
G5 — Distrust the harness
Your tooling has its own artifacts — separate them from the app:
- browser-extension console errors (
runtime.lastError), CF challenges that fire only because localhost routes through the proxy, secure cookies that vanish on http, a count:'exact' slow in a script but instant in prod, a DOM read that landed mid-transition.
- When server-truth and browser-truth disagree, trust neither until reconciled — the disagreement is the clue. Read more than once; take the settled/largest sample.
Discipline
- No fix without a measured before/after at the boundary you diagnosed at (not an easier one).
- Prefer the cheapest probe that yields a fact: one log grep / one
EXPLAIN / one CDP read beats three source hypotheses.
- Skip the ceremony for a typo or a bug in your own visible logic — a breakpoint is faster there. This is for the opaque layer and the "it might be…" that has produced more than one theory.
- Capture the win: on close, the root cause + before/after go to the repo's gotchas doc (symptom → cause → fix), and anything reusable to wherever you keep cross-project notes.
Reply BLUF: the boundary you hooked, the measured cause, the before/after. No narration of rejected theories unless asked.
1---2name: gate-isolate3description: Debug-to-truth loop for any non-trivial bug (crash, blank render, slow load, laggy UX). Gate the surface → instrument the boundary → isolate a faithful env → prove cause AND fix with the same probe. Use for "/gate-isolate", "find the real cause", "why is X slow/crashing/blank", or any bug where the fix isn't obvious from one log line and you must not waste hours on plausible-but-wrong guesses.4---56# Gate·Isolate·Prove — debug to truth, no trial-and-error78The procedure that lands the ACCURATE fix by making every conclusion a measured fact, never a source-read guess. Composes two laws: **instrument the boundary, don't reason from source** + **validate in isolation**.910> Standing order: a fix that can't reduce to an observation you can point to is a guess. Plausible-but-wrong is the enemy — each plausible theory costs a full fix cycle. One measurement ends the search.1112## G1 — Gate the surface13Reproduce, then bound where the bug can live. Which route / tab / component / query / layer? **Rule out the false sources first** (framework? DB? proxy/CDN? hydration? network? your own logic?) so you don't fix the wrong layer. State facts / unknowns / assumptions, labelled. Don't dig until the surface is narrowed.1415## G2 — Instrument the boundary16Hook the exact seam where your code meets the opaque layer and read what crosses it. Pick the probe by symptom:17- **Server crash / 500 / opaque error** → the runtime **logs** (Vercel, Supabase, app). Grep the thrown message. HTML where you expected JSON = a proxy/CF challenge.18- **Blank / broken / partial render** → **CDP** attached to the *real* browser (not a fresh incognito): `Runtime.exceptionThrown`, `Runtime.consoleAPICalled` errors, `Network.responseReceived` status, and a DOM read of the ACTUAL panel node's `textContent` (not `body.innerText`, which collapses to chrome).19- **Slow query** → **`EXPLAIN (ANALYZE, BUFFERS)`** on the RPC's **inner** query (the outer function-scan hides the cost). Read Seq-Scan vs Index-Scan, "Rows Removed by Filter", temp/disk spill, row counts.20- **Slow interaction / "not snappy"** → **CDP network timing** on the click: one RSC fetch or many? how long? serial waterfall or parallel? Compare to the DB time — if DB≈0 the cost is RTT × serialization, not SQL.2122Reason from the source tree ONLY after the boundary names which file to open.2324## G3 — Isolate a faithful env25Reproduce in a controlled copy that mirrors production, not a mock:26- Web: a **prod build** (`build` + `start`), NOT `dev` — dev hides error-stripping, minification, streaming, the digest path. Run it on a **separate port** — never kill or reuse the user's running dev server.27- Mirror the prod config that triggers the bug (same proxied domain, same env shape). A green `dev` server or a passing typecheck is **not proof**.28- DB: `EXPLAIN`/timing against the real table, or a branch — reproducible from migrations/config, not hand-built.2930## G4 — Prove cause, then prove fix31State the root cause with the measurement that shows it. Apply the fix. **Re-run the same boundary hook** — the fix can create the symptom it was meant to kill; a green diff proves nothing. Report before/after numbers from the same probe.3233## G5 — Distrust the harness34Your tooling has its own artifacts — separate them from the app:35- browser-extension console errors (`runtime.lastError`), CF challenges that fire only because *localhost* routes through the proxy, `secure` cookies that vanish on http, a `count:'exact'` slow in a script but instant in prod, a DOM read that landed mid-transition.36- When **server-truth and browser-truth disagree**, trust neither until reconciled — the disagreement is the clue. Read more than once; take the settled/largest sample.3738## Discipline39- No fix without a measured before/after at the boundary you diagnosed at (not an easier one).40- Prefer the cheapest probe that yields a fact: one log grep / one `EXPLAIN` / one CDP read beats three source hypotheses.41- Skip the ceremony for a typo or a bug in your own visible logic — a breakpoint is faster there. This is for the opaque layer and the "it might be…" that has produced more than one theory.42- Capture the win: on close, the root cause + before/after go to the repo's gotchas doc (symptom → cause → fix), and anything reusable to wherever you keep cross-project notes.4344Reply BLUF: the boundary you hooked, the measured cause, the before/after. No narration of rejected theories unless asked.