gstack-investigate skill
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)
Is the gstack-investigate skill safe?
Clean: nothing in its files matched our rules. We read 1 file in the folder on 2026-11-06.
No findings.
Install the gstack-investigate skill
A skill is a folder. Copy it into your agent's skills folder and the agent loads it when the task matches its description.
git clone --depth 1 https://github.com/garrytan/gstack.git /tmp/gstack mkdir -p ~/.claude/skills cp -r /tmp/gstack/qm/sandbox/skills/gstack-investigate ~/.claude/skills/gstack-investigate
In the Claude apps, zip the folder and upload it from the Skills settings. The folder on GitHub
The instructions your agent would load
SKILL.md as published, without the frontmatter. Read it on GitHub
<!-- Generated by scripts/gen-qm-edition.ts from hosts/qm.ts and investigate/SKILL.md.tmpl, investigate/sections/race.md.tmpl. Do not edit. -->
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.
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.
- Timing probes. Log a monotonic timestamp (performance.now()) and the
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.
- Forced interleaving. Inject an await or sleep at the suspected point
invariant, not the absence of an error:
- Concurrent-writer template. Drive N writers at once and assert the
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 recordedRun with N ≥ 8 under the forced interleaving; the template becomes the regression test with the interleaving still injected.
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.
- Fix shape. An atomic primitive: create with wx, compare-and-swap,
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
- DONEWITHCONCERNS — fixed but cannot fully verify (e.g., intermittent bug, requires staging)
- BLOCKED — root cause unclear after investigation, escalated
More skills from garrytan/gstack
- AalphaFixture dispatcher with a mode table and forced-read references.
- AautoplanAuto-review pipeline — runs the CEO, design, eng (architecture, edge cases, failure modes, tests) and DX reviews (lean run: one reviewer), auto-deciding. (gstack)
- AbenchmarkWeb performance regression detection. (gstack)
- Abenchmark-modelsCross-model benchmark for gstack skills. (gstack)
- AbetaClean fixture tool skill with no forced reads and no mode table.
- FbrowseDrive a real browser through Aside: open a page, read it, click through a flow, take screenshots, check console errors. (gstack)
- AcanaryPost-deploy canary monitoring. (gstack)
- AcaptainRun a crew of coding agents from one controller (also /crew): lanes send READY blocks and never merge; the controller merges through trains, keeps the digest, relays approvals, fixes flakes daily. (gstack)
- FcarefulSafety guardrails for destructive commands. (gstack)
- AcodexOpenAI Codex CLI wrapper — three modes. (gstack)
- Acontext-restoreRestore working context saved earlier by /context-save. (gstack)
- Acontext-saveSave working context. (gstack)