← LeaderboardThe Skill Leaderboard

gstack-investigate

Use when a test fails, code errors or output is wrong: find and prove the root cause before any fix, then fix it with a regression test. (gstack)

Published by garrytan ↗garrytan/gstack

Try your first task

A source-grounded starter task has not been verified for this skill yet.

SKILL.md

name: gstack-investigatedescription: "Use when a test fails, code errors or output is wrong: find and prove the root cause before any fix, then fix it with a regression test. (gstack)"

Investigate: root cause before any fix

Start here, before reading code. In the repository (cd into it first: the shell starts in the workspace root), run with execute, adding the failing file or directory if you know it:

git status --short
git log --oneline -20 -- <path>

Then reproduce the symptom with the project's own test or run command, and write down what you saw, before you form a hypothesis.

Iron Law

NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST.

Fixing symptoms creates whack-a-mole debugging. Every fix that doesn't address root cause makes the next bug harder to find. Find the root cause, then fix it.

How to work

Find the root cause, fix it with the smallest change, prove the fix, and finish with the DEBUG REPORT below. The order, tools and depth are yours. Three lessons that cost real time before:

  • Before calling two queries, helpers or code paths duplicates, read their call sites: what looks identical usually differs in a caller's guard, transaction or scope, and the "duplicate" is the one that is right.
  • Before timing anything that spawns git in a benchmark or bisect worktree, run git update-index --refresh there: a stale index makes the first git status/git diff pay a full refresh and the measurement lies.
  • Two fixes that shared one premise failed the same gate — write the premise down in one sentence and test it before a third fix. The evidence already points away from it.

Three guards:

  • 3-strike rule: if 3 hypotheses fail, STOP and ask the user: A) continue with a new hypothesis (describe it), B) escalate for human review, C) add logging and wait.
  • Blast radius: if the fix touches more than 5 files, ask the user: A) proceed, the root cause spans these files, B) split, fixing the critical path now, C) rethink for a more targeted approach.
  • Web searches: search the generic error class, library and version, never the raw error text, hostnames, IPs, file paths, SQL, customer data or secrets.

Race recipe

A race is two actors touching shared state with an ordering nobody enforces. Make it deterministic before fixing it.

  1. Timing probes. Log a monotonic timestamp (performance.now()) and the actor id at every read and write of the shared state (file, row, map, lock). A race shows as interleaved writes or a read between another actor's check and its write. Keep the probe output as evidence.
  2. Forced interleaving. Inject an await or sleep at the suspected point in one actor (behind a test-only hook or env var) so the other actor runs in the window. The bug must now appear every time; if it does not, the window is elsewhere.
  3. Concurrent-writer template. Drive N writers at once and assert the invariant, not the absence of an error:
    const results = await Promise.allSettled(Array.from({ length: N }, (_, i) => writer(i)));
    // exactly one winner | all N applied | file or row intact | lock released and owner recorded
    
    Run with N ≥ 8 under the forced interleaving; the template becomes the regression test with the interleaving still injected.
  4. Fix shape. An atomic primitive: create with wx, compare-and-swap, UPDATE … WHERE old_value = ?, a lock with an owner token and a stale-owner rule. A check-then-act with a smaller window is not a fix. Rerun step 3 after the change and paste both outputs.

Report

Output a structured debug report:

DEBUG REPORT
════════════════════════════════════════
Symptom:         [what the user observed]
Root cause:      [what was actually wrong]
Fix:             [what was changed, with file:line references]
Evidence:        [test output, reproduction attempt showing fix works]
Regression test: [file:line of the new test]
Related:         [TODOS.md items, prior bugs in same area, architectural notes]
Status:          DONE | DONE_WITH_CONCERNS | BLOCKED
════════════════════════════════════════

Important Rules

  • 3+ failed fix attempts → STOP and question the architecture. Wrong architecture, not failed hypothesis.
  • Never apply a fix you cannot verify. If you can't reproduce and confirm, don't ship it.
  • Never say "this should fix it." Verify and prove it. Run the tests.
  • If fix touches >5 files → ask the user about blast radius before proceeding.
  • Completion status:
    • DONE — root cause found, fix applied, regression test written, all tests pass
    • DONE_WITH_CONCERNS — fixed but cannot fully verify (e.g., intermittent bug, requires staging)
    • BLOCKED — root cause unclear after investigation, escalated