review
Preamble (run first)
_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true)
[ -n "$_UPD" ] && echo "$_UPD" || true
mkdir -p ~/.gstack/sessions
touch ~/.gstack/sessions/"$PPID"
_SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ')
find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true
_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true)
_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
echo "BRANCH: $_BRANCH"
If output shows UPGRADE_AVAILABLE <old> <new>: read ~/.claude/skills/gstack/gstack-upgrade/SKILL.md and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If JUST_UPGRADED <from> <to>: tell user "Running gstack v{to} (just updated!)" and continue.
AskUserQuestion Format
ALWAYS follow this structure for every AskUserQuestion call:
- Re-ground: State the project, the current branch (use the
_BRANCHvalue printed by the preamble — NOT any branch from conversation history or gitStatus), and the current plan/task. (1-2 sentences) - Simplify: Explain the problem in plain English a smart 16-year-old could follow. No raw function names, no internal jargon, no implementation details. Use concrete examples and analogies. Say what it DOES, not what it's called.
- Recommend:
RECOMMENDATION: Choose [X] because [one-line reason] - Options: Lettered options:
A) ... B) ... C) ...
Assume the user hasn't looked at this window in 20 minutes and doesn't have the code open. If you'd need to read the source to understand your own explanation, it's too complex.
Per-skill instructions may add additional formatting rules on top of this baseline.
Contributor Mode
If _CONTRIB is true: you are in contributor mode. You're a gstack user who also helps make it better.
At the end of each major workflow step (not after every single command), reflect on the gstack tooling you used. Rate your experience 0 to 10. If it wasn't a 10, think about why. If there is an obvious, actionable bug OR an insightful, interesting thing that could have been done better by gstack code or skill markdown — file a field report. Maybe our contributor will help make us better!
Calibration — this is the bar: For example, $B js "await fetch(...)" used to fail with SyntaxError: await is only valid in async functions because gstack didn't wrap expressions in async context. Small, but the input was reasonable and gstack should have handled it — that's the kind of thing worth filing. Things less consequential than this, ignore.
NOT worth filing: user's app bugs, network errors to user's URL, auth failures on user's site, user's own JS logic bugs.
To file: write ~/.gstack/contributor-logs/{slug}.md with all sections below (do not truncate — include every section through the Date/Version footer):
# {Title}
Hey gstack team — ran into this while using /{skill-name}:
**What I was trying to do:** {what the user/agent was attempting}
**What happened instead:** {what actually happened}
**My rating:** {0-10} — {one sentence on why it wasn't a 10}
## Steps to reproduce
1. {step}
## Raw output
{paste the actual error or unexpected output here}
## What would make this a 10
{one sentence: what gstack should have done differently}
**Date:** {YYYY-MM-DD} | **Version:** {gstack version} | **Skill:** /{skill}
Slug: lowercase, hyphens, max 60 chars (e.g. browse-js-no-await). Skip if file already exists. Max 3 reports per session. File inline and continue — don't stop the workflow. Tell user: "Filed gstack field report: {title}"
Step 0: Detect base branch
Determine which branch this PR targets. Use the result as "the base branch" in all subsequent steps.
-
Check if a PR already exists for this branch:
gh pr view --json baseRefName -q .baseRefNameIf this succeeds, use the printed branch name as the base branch. -
If no PR exists (command fails), detect the repo's default branch:
gh repo view --json defaultBranchRef -q .defaultBranchRef.name -
If both commands fail, fall back to
main.
Print the detected base branch name. In every subsequent git diff, git log,
git fetch, git merge, and gh pr create command, substitute the detected
branch name wherever the instructions say "the base branch."
Pre-Landing PR Review
You are running the /review workflow. Analyze the current branch's diff against the base branch for structural issues that tests don't catch.
Step 1: Check branch
- Run
git branch --show-currentto get the current branch. - If on the base branch, output: "Nothing to review — you're on the base branch or have no changes against it." and stop.
- Run
git fetch origin <base> --quiet && git diff origin/<base> --statto check if there's a diff. If no diff, output the same message and stop.
Step 2: Read the checklist
Read .claude/skills/review/checklist.md.
If the file cannot be read, STOP and report the error. Do not proceed without the checklist.
Step 2.5: Check for Greptile review comments
Read .claude/skills/review/greptile-triage.md and follow the fetch, filter, classify, and escalation detection steps.
If no PR exists, gh fails, API returns an error, or there are zero Greptile comments: Skip this step silently. Greptile integration is additive — the review works without it.
If Greptile comments are found: Store the classifications (VALID & ACTIONABLE, VALID BUT ALREADY FIXED, FALSE POSITIVE, SUPPRESSED) — you will need them in Step 5.
Step 3: Get the diff
Fetch the latest base branch to avoid false positives from stale local state:
git fetch origin <base> --quiet
Run git diff origin/<base> to get the full diff. This includes both committed and uncommitted changes against the latest base branch.
Step 4: Two-pass review
Apply the checklist against the diff in two passes:
- Pass 1 (CRITICAL): SQL & Data Safety, Race Conditions & Concurrency, LLM Output Trust Boundary, Enum & Value Completeness
- Pass 2 (INFORMATIONAL): Conditional Side Effects, Magic Numbers & String Coupling, Dead Code & Consistency, LLM Prompt Issues, Test Gaps, View/Frontend
Enum & Value Completeness requires reading code OUTSIDE the diff. When the diff introduces a new enum value, status, tier, or type constant, use Grep to find all files that reference sibling values, then Read those files to check if the new value is handled. This is the one category where within-diff review is insufficient.
Follow the output format specified in the checklist. Respect the suppressions — do NOT flag items listed in the "DO NOT flag" section.
Step 5: Output findings
Always output ALL findings — both critical and informational. The user must see every issue.
- If CRITICAL issues found: output all findings, then for EACH critical issue use a separate AskUserQuestion with the problem, then
RECOMMENDATION: Choose A because [one-line reason], then options (A: Fix it now, B: Acknowledge, C: False positive — skip). After all critical questions are answered, output a summary of what the user chose for each issue. If the user chose A (fix) on any issue, apply the recommended fixes. If only B/C were chosen, no action needed. - If only non-critical issues found: output findings. No further action needed.
- If no issues found: output
Pre-Landing Review: No issues found.
Greptile comment resolution
After outputting your own findings, if Greptile comments were classified in Step 2.5:
Include a Greptile summary in your output header: + N Greptile comments (X valid, Y fixed, Z FP)
Before replying to any comment, run the Escalation Detection algorithm from greptile-triage.md to determine whether to use Tier 1 (friendly) or Tier 2 (firm) reply templates.
-
VALID & ACTIONABLE comments: These are already included in your CRITICAL findings — they follow the same AskUserQuestion flow (A: Fix it now, B: Acknowledge, C: False positive). If the user chooses A (fix), reply using the Fix reply template from greptile-triage.md (include inline diff + explanation). If the user chooses C (false positive), reply using the False Positive reply template (include evidence + suggested re-rank), save to both per-project and global greptile-history.
-
FALSE POSITIVE comments: Present each one via AskUserQuestion:
- Show the Greptile comment: file:line (or [top-level]) + body summary + permalink URL
- Explain concisely why it's a false positive
- Options:
- A) Reply to Greptile explaining why this is incorrect (recommended if clearly wrong)
- B) Fix it anyway (if low-effort and harmless)
- C) Ignore — don't reply, don't fix
If the user chooses A, reply using the False Positive reply template from greptile-triage.md (include evidence + suggested re-rank), save to both per-project and global greptile-history.
-
VALID BUT ALREADY FIXED comments: Reply using the Already Fixed reply template from greptile-triage.md — no AskUserQuestion needed:
- Include what was done and the fixing commit SHA
- Save to both per-project and global greptile-history
-
SUPPRESSED comments: Skip silently — these are known false positives from previous triage.
Step 5.5: TODOS cross-reference
Read TODOS.md in the repository root (if it exists). Cross-reference the PR against open TODOs:
- Does this PR close any open TODOs? If yes, note which items in your output: "This PR addresses TODO: "
- Does this PR create work that should become a TODO? If yes, flag it as an informational finding.
- Are there related TODOs that provide context for this review? If yes, reference them when discussing related findings.
If TODOS.md doesn't exist, skip this step silently.
Step 5.6: Documentation staleness check
Cross-reference the diff against documentation files. For each .md file in the repo root (README.md, ARCHITECTURE.md, CONTRIBUTING.md, CLAUDE.md, etc.):
- Check if code changes in the diff affect features, components, or workflows described in that doc file.
- If the doc file was NOT updated in this branch but the code it describes WAS changed, flag it as an INFORMATIONAL finding:
"Documentation may be stale: [file] describes [feature/component] but code changed in this branch. Consider running
/document-release."
This is informational only — never critical. The fix action is /document-release.
If no documentation files exist, skip this step silently.
Important Rules
- Read the FULL diff before commenting. Do not flag issues already addressed in the diff.
- Read-only by default. Only modify files if the user explicitly chooses "Fix it now" on a critical issue. Never commit, push, or create PRs.
- Be terse. One line problem, one line fix. No preamble.
- Only flag real problems. Skip anything that's fine.
- Use Greptile reply templates from greptile-triage.md. Every reply includes evidence. Never post vague replies.