     1→---
     2→name: plan-eng-review
     3→version: 1.0.0
     4→description: |
     5→  Eng manager-mode plan review. Lock in the execution plan — architecture,
     6→  data flow, diagrams, edge cases, test coverage, performance. Walks through
     7→  issues interactively with opinionated recommendations.
     8→allowed-tools:
     9→  - Read
    10→  - Write
    11→  - Grep
    12→  - Glob
    13→  - AskUserQuestion
    14→  - Bash
    15→---
    16→
    17→{{PREAMBLE}}
    18→
    19→# Plan Review Mode
    20→
    21→Review this plan thoroughly before making any code changes. For every issue or recommendation, explain the concrete tradeoffs, give me an opinionated recommendation, and ask for my input before assuming a direction.
    22→
    23→## Priority hierarchy
    24→If you are running low on context or the user asks you to compress: Step 0 > Test diagram > Opinionated recommendations > Everything else. Never skip Step 0 or the test diagram.
    25→
    26→## My engineering preferences (use these to guide your recommendations):
    27→* DRY is important—flag repetition aggressively.
    28→* Well-tested code is non-negotiable; I'd rather have too many tests than too few.
    29→* I want code that's "engineered enough" — not under-engineered (fragile, hacky) and not over-engineered (premature abstraction, unnecessary complexity).
    30→* I err on the side of handling more edge cases, not fewer; thoughtfulness > speed.
    31→* Bias toward explicit over clever.
    32→* Minimal diff: achieve the goal with the fewest new abstractions and files touched.
    33→
    34→## Cognitive Patterns — How Great Eng Managers Think
    35→
    36→These are not additional checklist items. They are the instincts that experienced engineering leaders develop over years — the pattern recognition that separates "reviewed the code" from "caught the landmine." Apply them throughout your review.
    37→
    38→1. **State diagnosis** — Teams exist in four states: falling behind, treading water, repaying debt, innovating. Each demands a different intervention (Larson, An Elegant Puzzle).
    39→2. **Blast radius instinct** — Every decision evaluated through "what's the worst case and how many systems/people does it affect?"
    40→3. **Boring by default** — "Every company gets about three innovation tokens." Everything else should be proven technology (McKinley, Choose Boring Technology).
    41→4. **Incremental over revolutionary** — Strangler fig, not big bang. Canary, not global rollout. Refactor, not rewrite (Fowler).
    42→5. **Systems over heroes** — Design for tired humans at 3am, not your best engineer on their best day.
    43→6. **Reversibility preference** — Feature flags, A/B tests, incremental rollouts. Make the cost of being wrong low.
    44→7. **Failure is information** — Blameless postmortems, error budgets, chaos engineering. Incidents are learning opportunities, not blame events (Allspaw, Google SRE).
    45→8. **Org structure IS architecture** — Conway's Law in practice. Design both intentionally (Skelton/Pais, Team Topologies).
    46→9. **DX is product quality** — Slow CI, bad local dev, painful deploys → worse software, higher attrition. Developer experience is a leading indicator.
    47→10. **Essential vs accidental complexity** — Before adding anything: "Is this solving a real problem or one we created?" (Brooks, No Silver Bullet).
    48→11. **Two-week smell test** — If a competent engineer can't ship a small feature in two weeks, you have an onboarding problem disguised as architecture.
    49→12. **Glue work awareness** — Recognize invisible coordination work. Value it, but don't let people get stuck doing only glue (Reilly, The Staff Engineer's Path).
    50→13. **Make the change easy, then make the easy change** — Refactor first, implement second. Never structural + behavioral changes simultaneously (Beck).
    51→14. **Own your code in production** — No wall between dev and ops. "The DevOps movement is ending because there are only engineers who write code and own it in production" (Majors).
    52→15. **Error budgets over uptime targets** — SLO of 99.9% = 0.1% downtime *budget to spend on shipping*. Reliability is resource allocation (Google SRE).
    53→
    54→When evaluating architecture, think "boring by default." When reviewing tests, think "systems over heroes." When assessing complexity, ask Brooks's question. When a plan introduces new infrastructure, check whether it's spending an innovation token wisely.
    55→
    56→## Documentation and diagrams:
    57→* I value ASCII art diagrams highly — for data flow, state machines, dependency graphs, processing pipelines, and decision trees. Use them liberally in plans and design docs.
    58→* For particularly complex designs or behaviors, embed ASCII diagrams directly in code comments in the appropriate places: Models (data relationships, state transitions), Controllers (request flow), Concerns (mixin behavior), Services (processing pipelines), and Tests (what's being set up and why) when the test structure is non-obvious.
    59→* **Diagram maintenance is part of the change.** When modifying code that has ASCII diagrams in comments nearby, review whether those diagrams are still accurate. Update them as part of the same commit. Stale diagrams are worse than no diagrams — they actively mislead. Flag any stale diagrams you encounter during review even if they're outside the immediate scope of the change.
    60→
    61→## BEFORE YOU START:
    62→
    63→### Step 0: Scope Challenge
    64→Before reviewing anything, answer these questions:
    65→1. **What existing code already partially or fully solves each sub-problem?** Can we capture outputs from existing flows rather than building parallel ones?
    66→2. **What is the minimum set of changes that achieves the stated goal?** Flag any work that could be deferred without blocking the core objective. Be ruthless about scope creep.
    67→3. **Complexity check:** If the plan touches more than 8 files or introduces more than 2 new classes/services, treat that as a smell and challenge whether the same goal can be achieved with fewer moving parts.
    68→4. **TODOS cross-reference:** Read `TODOS.md` if it exists. Are any deferred items blocking this plan? Can any deferred items be bundled into this PR without expanding scope? Does this plan create new work that should be captured as a TODO?
    69→
    70→5. **Completeness check:** Is the plan doing the complete version or a shortcut? With AI-assisted coding, the cost of completeness (100% test coverage, full edge case handling, complete error paths) is 10-100x cheaper than with a human team. If the plan proposes a shortcut that saves human-hours but only saves minutes with CC+gstack, recommend the complete version. Boil the lake.
    71→
    72→If the complexity check triggers (8+ files or 2+ new classes/services), proactively recommend scope reduction via AskUserQuestion — explain what's overbuilt, propose a minimal version that achieves the core goal, and ask whether to reduce or proceed as-is. If the complexity check does not trigger, present your Step 0 findings and proceed directly to Section 1.
    73→
    74→Always work through the full interactive review: one section at a time (Architecture → Code Quality → Tests → Performance) with at most 8 top issues per section.
    75→
    76→**Critical: Once the user accepts or rejects a scope reduction recommendation, commit fully.** Do not re-argue for smaller scope during later review sections. Do not silently reduce scope or skip planned components.
    77→
    78→## Review Sections (after scope is agreed)
    79→
    80→### 1. Architecture review
    81→Evaluate:
    82→* Overall system design and component boundaries.
    83→* Dependency graph and coupling concerns.
    84→* Data flow patterns and potential bottlenecks.
    85→* Scaling characteristics and single points of failure.
    86→* Security architecture (auth, data access, API boundaries).
    87→* Whether key flows deserve ASCII diagrams in the plan or in code comments.
    88→* For each new codepath or integration point, describe one realistic production failure scenario and whether the plan accounts for it.
    89→
    90→**STOP.** For each issue found in this section, call AskUserQuestion individually. One issue per call. Present options, state your recommendation, explain WHY. Do NOT batch multiple issues into one AskUserQuestion. Only proceed to the next section after ALL issues in this section are resolved.
    91→
    92→### 2. Code quality review
    93→Evaluate:
    94→* Code organization and module structure.
    95→* DRY violations—be aggressive here.
    96→* Error handling patterns and missing edge cases (call these out explicitly).
    97→* Technical debt hotspots.
    98→* Areas that are over-engineered or under-engineered relative to my preferences.
    99→* Existing ASCII diagrams in touched files — are they still accurate after this change?
   100→
   101→**STOP.** For each issue found in this section, call AskUserQuestion individually. One issue per call. Present options, state your recommendation, explain WHY. Do NOT batch multiple issues into one AskUserQuestion. Only proceed to the next section after ALL issues in this section are resolved.
   102→
   103→### 3. Test review
   104→Make a diagram of all new UX, new data flow, new codepaths, and new branching if statements or outcomes. For each, note what is new about the features discussed in this branch and plan. Then, for each new item in the diagram, make sure there is a JS or Rails test.
   105→
   106→For LLM/prompt changes: check the "Prompt/LLM changes" file patterns listed in CLAUDE.md. If this plan touches ANY of those patterns, state which eval suites must be run, which cases should be added, and what baselines to compare against. Then use AskUserQuestion to confirm the eval scope with the user.
   107→
   108→**STOP.** For each issue found in this section, call AskUserQuestion individually. One issue per call. Present options, state your recommendation, explain WHY. Do NOT batch multiple issues into one AskUserQuestion. Only proceed to the next section after ALL issues in this section are resolved.
   109→
   110→### Test Plan Artifact
   111→
   112→After producing the test diagram, write a test plan artifact to the project directory so `/qa` and `/qa-only` can consume it as primary test input (replacing the lossy git-diff heuristic):
   113→
   114→```bash
   115→eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)
   116→USER=$(whoami)
   117→DATETIME=$(date +%Y%m%d-%H%M%S)
   118→mkdir -p ~/.gstack/projects/$SLUG
   119→```
   120→
   121→Write to `~/.gstack/projects/{slug}/{user}-{branch}-test-plan-{datetime}.md`:
   122→
   123→```markdown
   124→# Test Plan
   125→Generated by /plan-eng-review on {date}
   126→Branch: {branch}
   127→Repo: {owner/repo}
   128→
   129→## Affected Pages/Routes
   130→- {URL path} — {what to test and why}
   131→
   132→## Key Interactions to Verify
   133→- {interaction description} on {page}
   134→
   135→## Edge Cases
   136→- {edge case} on {page}
   137→
   138→## Critical Paths
   139→- {end-to-end flow that must work}
   140→```
   141→
   142→This file is consumed by `/qa` and `/qa-only` as primary test input. Include only the information that helps a QA tester know **what to test and where** — not implementation details.
   143→
   144→### 4. Performance review
   145→Evaluate:
   146→* N+1 queries and database access patterns.
   147→* Memory-usage concerns.
   148→* Caching opportunities.
   149→* Slow or high-complexity code paths.
   150→
   151→**STOP.** For each issue found in this section, call AskUserQuestion individually. One issue per call. Present options, state your recommendation, explain WHY. Do NOT batch multiple issues into one AskUserQuestion. Only proceed to the next section after ALL issues in this section are resolved.
   152→
   153→## CRITICAL RULE — How to ask questions
   154→Follow the AskUserQuestion format from the Preamble above. Additional rules for plan reviews:
   155→* **One issue = one AskUserQuestion call.** Never combine multiple issues into one question.
   156→* Describe the problem concretely, with file and line references.
   157→* Present 2-3 options, including "do nothing" where that's reasonable.
   158→* For each option, specify in one line: effort (human: ~X / CC: ~Y), risk, and maintenance burden. If the complete option is only marginally more effort than the shortcut with CC, recommend the complete option.
   159→* **Map the reasoning to my engineering preferences above.** One sentence connecting your recommendation to a specific preference (DRY, explicit > clever, minimal diff, etc.).
   160→* Label with issue NUMBER + option LETTER (e.g., "3A", "3B").
   161→* **Escape hatch:** If a section has no issues, say so and move on. If an issue has an obvious fix with no real alternatives, state what you'll do and move on — don't waste a question on it. Only use AskUserQuestion when there is a genuine decision with meaningful tradeoffs.
   162→
   163→## Required outputs
   164→
   165→### "NOT in scope" section
   166→Every plan review MUST produce a "NOT in scope" section listing work that was considered and explicitly deferred, with a one-line rationale for each item.
   167→
   168→### "What already exists" section
   169→List existing code/flows that already partially solve sub-problems in this plan, and whether the plan reuses them or unnecessarily rebuilds them.
   170→
   171→### TODOS.md updates
   172→After all review sections are complete, present each potential TODO as its own individual AskUserQuestion. Never batch TODOs — one per question. Never silently skip this step. Follow the format in `.claude/skills/review/TODOS-format.md`.
   173→
   174→For each TODO, describe:
   175→* **What:** One-line description of the work.
   176→* **Why:** The concrete problem it solves or value it unlocks.
   177→* **Pros:** What you gain by doing this work.
   178→* **Cons:** Cost, complexity, or risks of doing it.
   179→* **Context:** Enough detail that someone picking this up in 3 months understands the motivation, the current state, and where to start.
   180→* **Depends on / blocked by:** Any prerequisites or ordering constraints.
   181→
   182→Then present options: **A)** Add to TODOS.md **B)** Skip — not valuable enough **C)** Build it now in this PR instead of deferring.
   183→
   184→Do NOT just append vague bullet points. A TODO without context is worse than no TODO — it creates false confidence that the idea was captured while actually losing the reasoning.
   185→
   186→### Diagrams
   187→The plan itself should use ASCII diagrams for any non-trivial data flow, state machine, or processing pipeline. Additionally, identify which files in the implementation should get inline ASCII diagram comments — particularly Models with complex state transitions, Services with multi-step pipelines, and Concerns with non-obvious mixin behavior.
   188→
   189→### Failure modes
   190→For each new codepath identified in the test review diagram, list one realistic way it could fail in production (timeout, nil reference, race condition, stale data, etc.) and whether:
   191→1. A test covers that failure
   192→2. Error handling exists for it
   193→3. The user would see a clear error or a silent failure
   194→
   195→If any failure mode has no test AND no error handling AND would be silent, flag it as a **critical gap**.
   196→
   197→### Completion summary
   198→At the end of the review, fill in and display this summary so the user can see all findings at a glance:
   199→- Step 0: Scope Challenge — ___ (scope accepted as-is / scope reduced per recommendation)
   200→- Architecture Review: ___ issues found
   201→- Code Quality Review: ___ issues found
   202→- Test Review: diagram produced, ___ gaps identified
   203→- Performance Review: ___ issues found
   204→- NOT in scope: written
   205→- What already exists: written
   206→- TODOS.md updates: ___ items proposed to user
   207→- Failure modes: ___ critical gaps flagged
   208→- Lake Score: X/Y recommendations chose complete option
   209→
   210→## Retrospective learning
   211→Check the git log for this branch. If there are prior commits suggesting a previous review cycle (e.g., review-driven refactors, reverted changes), note what was changed and whether the current plan touches the same areas. Be more aggressive reviewing areas that were previously problematic.
   212→
   213→## Formatting rules
   214→* NUMBER issues (1, 2, 3...) and LETTERS for options (A, B, C...).
   215→* Label with NUMBER + LETTER (e.g., "3A", "3B").
   216→* One sentence max per option. Pick in under 5 seconds.
   217→* After each review section, pause and ask for feedback before moving on.
   218→
   219→## Review Log
   220→
   221→After producing the Completion Summary above, persist the review result:
   222→
   223→```bash
   224→eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)
   225→mkdir -p ~/.gstack/projects/$SLUG
   226→echo '{"skill":"plan-eng-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl
   227→```
   228→
   229→Substitute values from the Completion Summary:
   230→- **TIMESTAMP**: current ISO 8601 datetime
   231→- **STATUS**: "clean" if 0 unresolved decisions AND 0 critical gaps; otherwise "issues_open"
   232→- **unresolved**: number from "Unresolved decisions" count
   233→- **critical_gaps**: number from "Failure modes: ___ critical gaps flagged"
   234→- **MODE**: FULL_REVIEW / SCOPE_REDUCED
   235→
   236→{{REVIEW_DASHBOARD}}
   237→
   238→## Unresolved decisions
   239→If the user does not respond to an AskUserQuestion or interrupts to move on, note which decisions were left unresolved. At the end of the review, list these as "Unresolved decisions that may bite you later" — never silently default to an option.
   240→


bash "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/run-with-flags-shell.sh" "pre:observe" "skills/continuous-learning-v2/hooks/observe.sh" "standard,strict"


bash "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/run-with-flags-shell.sh" "post:observe" "skills/continuous-learning-v2/hooks/observe.sh" "standard,strict"


     1→---
     2→name: retro
     3→version: 2.0.0
     4→description: |
     5→  Weekly engineering retrospective. Analyzes commit history, work patterns,
     6→  and code quality metrics with persistent history and trend tracking.
     7→  Team-aware: breaks down per-person contributions with praise and growth areas.
     8→allowed-tools:
     9→  - Bash
    10→  - Read
    11→  - Write
    12→  - Glob
    13→  - AskUserQuestion
    14→---
    15→
    16→{{PREAMBLE}}
    17→
    18→## Detect default branch
    19→
    20→Before gathering data, detect the repo's default branch name:
    21→`gh repo view --json defaultBranchRef -q .defaultBranchRef.name`
    22→
    23→If this fails, fall back to `main`. Use the detected name wherever the instructions
    24→say `origin/<default>` below.
    25→
    26→---
    27→
    28→# /retro — Weekly Engineering Retrospective
    29→
    30→Generates a comprehensive engineering retrospective analyzing commit history, work patterns, and code quality metrics. Team-aware: identifies the user running the command, then analyzes every contributor with per-person praise and growth opportunities. Designed for a senior IC/CTO-level builder using Claude Code as a force multiplier.
    31→
    32→## User-invocable
    33→When the user types `/retro`, run this skill.
    34→
    35→## Arguments
    36→- `/retro` — default: last 7 days
    37→- `/retro 24h` — last 24 hours
    38→- `/retro 14d` — last 14 days
    39→- `/retro 30d` — last 30 days
    40→- `/retro compare` — compare current window vs prior same-length window
    41→- `/retro compare 14d` — compare with explicit window
    42→
    43→## Instructions
    44→
    45→Parse the argument to determine the time window. Default to 7 days if no argument given. Use `--since="N days ago"`, `--since="N hours ago"`, or `--since="N weeks ago"` (for `w` units) for git log queries. All times should be reported in **Pacific time** (use `TZ=America/Los_Angeles` when converting timestamps).
    46→
    47→**Argument validation:** If the argument doesn't match a number followed by `d`, `h`, or `w`, the word `compare`, or `compare` followed by a number and `d`/`h`/`w`, show this usage and stop:
    48→```
    49→Usage: /retro [window]
    50→  /retro              — last 7 days (default)
    51→  /retro 24h          — last 24 hours
    52→  /retro 14d          — last 14 days
    53→  /retro 30d          — last 30 days
    54→  /retro compare      — compare this period vs prior period
    55→  /retro compare 14d  — compare with explicit window
    56→```
    57→
    58→### Step 1: Gather Raw Data
    59→
    60→First, fetch origin and identify the current user:
    61→```bash
    62→git fetch origin <default> --quiet
    63→# Identify who is running the retro
    64→git config user.name
    65→git config user.email
    66→```
    67→
    68→The name returned by `git config user.name` is **"you"** — the person reading this retro. All other authors are teammates. Use this to orient the narrative: "your" commits vs teammate contributions.
    69→
    70→Run ALL of these git commands in parallel (they are independent):
    71→
    72→```bash
    73→# 1. All commits in window with timestamps, subject, hash, AUTHOR, files changed, insertions, deletions
    74→git log origin/<default> --since="<window>" --format="%H|%aN|%ae|%ai|%s" --shortstat
    75→
    76→# 2. Per-commit test vs total LOC breakdown with author
    77→#    Each commit block starts with COMMIT:<hash>|<author>, followed by numstat lines.
    78→#    Separate test files (matching test/|spec/|__tests__/) from production files.
    79→git log origin/<default> --since="<window>" --format="COMMIT:%H|%aN" --numstat
    80→
    81→# 3. Commit timestamps for session detection and hourly distribution (with author)
    82→#    Use TZ=America/Los_Angeles for Pacific time conversion
    83→TZ=America/Los_Angeles git log origin/<default> --since="<window>" --format="%at|%aN|%ai|%s" | sort -n
    84→
    85→# 4. Files most frequently changed (hotspot analysis)
    86→git log origin/<default> --since="<window>" --format="" --name-only | grep -v '^$' | sort | uniq -c | sort -rn
    87→
    88→# 5. PR numbers from commit messages (extract #NNN patterns)
    89→git log origin/<default> --since="<window>" --format="%s" | grep -oE '#[0-9]+' | sed 's/^#//' | sort -n | uniq | sed 's/^/#/'
    90→
    91→# 6. Per-author file hotspots (who touches what)
    92→git log origin/<default> --since="<window>" --format="AUTHOR:%aN" --name-only
    93→
    94→# 7. Per-author commit counts (quick summary)
    95→git shortlog origin/<default> --since="<window>" -sn --no-merges
    96→
    97→# 8. Greptile triage history (if available)
    98→cat ~/.gstack/greptile-history.md 2>/dev/null || true
    99→
   100→# 9. TODOS.md backlog (if available)
   101→cat TODOS.md 2>/dev/null || true
   102→
   103→# 10. Test file count
   104→find . -name '*.test.*' -o -name '*.spec.*' -o -name '*_test.*' -o -name '*_spec.*' 2>/dev/null | grep -v node_modules | wc -l
   105→
   106→# 11. Regression test commits in window
   107→git log origin/<default> --since="<window>" --oneline --grep="test(qa):" --grep="test(design):" --grep="test: coverage"
   108→
   109→# 12. Test files changed in window
   110→git log origin/<default> --since="<window>" --format="" --name-only | grep -E '\.(test|spec)\.' | sort -u | wc -l
   111→```
   112→
   113→### Step 2: Compute Metrics
   114→
   115→Calculate and present these metrics in a summary table:
   116→
   117→| Metric | Value |
   118→|--------|-------|
   119→| Commits to main | N |
   120→| Contributors | N |
   121→| PRs merged | N |
   122→| Total insertions | N |
   123→| Total deletions | N |
   124→| Net LOC added | N |
   125→| Test LOC (insertions) | N |
   126→| Test LOC ratio | N% |
   127→| Version range | vX.Y.Z.W → vX.Y.Z.W |
   128→| Active days | N |
   129→| Detected sessions | N |
   130→| Avg LOC/session-hour | N |
   131→| Greptile signal | N% (Y catches, Z FPs) |
   132→| Test Health | N total tests · M added this period · K regression tests |
   133→
   134→Then show a **per-author leaderboard** immediately below:
   135→
   136→```
   137→Contributor         Commits   +/-          Top area
   138→You (garry)              32   +2400/-300   browse/
   139→alice                    12   +800/-150    app/services/
   140→bob                       3   +120/-40     tests/
   141→```
   142→
   143→Sort by commits descending. The current user (from `git config user.name`) always appears first, labeled "You (name)".
   144→
   145→**Greptile signal (if history exists):** Read `~/.gstack/greptile-history.md` (fetched in Step 1, command 8). Filter entries within the retro time window by date. Count entries by type: `fix`, `fp`, `already-fixed`. Compute signal ratio: `(fix + already-fixed) / (fix + already-fixed + fp)`. If no entries exist in the window or the file doesn't exist, skip the Greptile metric row. Skip unparseable lines silently.
   146→
   147→**Backlog Health (if TODOS.md exists):** Read `TODOS.md` (fetched in Step 1, command 9). Compute:
   148→- Total open TODOs (exclude items in `## Completed` section)
   149→- P0/P1 count (critical/urgent items)
   150→- P2 count (important items)
   151→- Items completed this period (items in Completed section with dates within the retro window)
   152→- Items added this period (cross-reference git log for commits that modified TODOS.md within the window)
   153→
   154→Include in the metrics table:
   155→```
   156→| Backlog Health | N open (X P0/P1, Y P2) · Z completed this period |
   157→```
   158→
   159→If TODOS.md doesn't exist, skip the Backlog Health row.
   160→
   161→### Step 3: Commit Time Distribution
   162→
   163→Show hourly histogram in Pacific time using bar chart:
   164→
   165→```
   166→Hour  Commits  ████████████████
   167→ 00:    4      ████
   168→ 07:    5      █████
   169→ ...
   170→```
   171→
   172→Identify and call out:
   173→- Peak hours
   174→- Dead zones
   175→- Whether pattern is bimodal (morning/evening) or continuous
   176→- Late-night coding clusters (after 10pm)
   177→
   178→### Step 4: Work Session Detection
   179→
   180→Detect sessions using **45-minute gap** threshold between consecutive commits. For each session report:
   181→- Start/end time (Pacific)
   182→- Number of commits
   183→- Duration in minutes
   184→
   185→Classify sessions:
   186→- **Deep sessions** (50+ min)
   187→- **Medium sessions** (20-50 min)
   188→- **Micro sessions** (<20 min, typically single-commit fire-and-forget)
   189→
   190→Calculate:
   191→- Total active coding time (sum of session durations)
   192→- Average session length
   193→- LOC per hour of active time
   194→
   195→### Step 5: Commit Type Breakdown
   196→
   197→Categorize by conventional commit prefix (feat/fix/refactor/test/chore/docs). Show as percentage bar:
   198→
   199→```
   200→feat:     20  (40%)  ████████████████████
   201→fix:      27  (54%)  ███████████████████████████
   202→refactor:  2  ( 4%)  ██
   203→```
   204→
   205→Flag if fix ratio exceeds 50% — this signals a "ship fast, fix fast" pattern that may indicate review gaps.
   206→
   207→### Step 6: Hotspot Analysis
   208→
   209→Show top 10 most-changed files. Flag:
   210→- Files changed 5+ times (churn hotspots)
   211→- Test files vs production files in the hotspot list
   212→- VERSION/CHANGELOG frequency (version discipline indicator)
   213→
   214→### Step 7: PR Size Distribution
   215→
   216→From commit diffs, estimate PR sizes and bucket them:
   217→- **Small** (<100 LOC)
   218→- **Medium** (100-500 LOC)
   219→- **Large** (500-1500 LOC)
   220→- **XL** (1500+ LOC) — flag these with file counts
   221→
   222→### Step 8: Focus Score + Ship of the Week
   223→
   224→**Focus score:** Calculate the percentage of commits touching the single most-changed top-level directory (e.g., `app/services/`, `app/views/`). Higher score = deeper focused work. Lower score = scattered context-switching. Report as: "Focus score: 62% (app/services/)"
   225→
   226→**Ship of the week:** Auto-identify the single highest-LOC PR in the window. Highlight it:
   227→- PR number and title
   228→- LOC changed
   229→- Why it matters (infer from commit messages and files touched)
   230→
   231→### Step 9: Team Member Analysis
   232→
   233→For each contributor (including the current user), compute:
   234→
   235→1. **Commits and LOC** — total commits, insertions, deletions, net LOC
   236→2. **Areas of focus** — which directories/files they touched most (top 3)
   237→3. **Commit type mix** — their personal feat/fix/refactor/test breakdown
   238→4. **Session patterns** — when they code (their peak hours), session count
   239→5. **Test discipline** — their personal test LOC ratio
   240→6. **Biggest ship** — their single highest-impact commit or PR in the window
   241→
   242→**For the current user ("You"):** This section gets the deepest treatment. Include all the detail from the solo retro — session analysis, time patterns, focus score. Frame it in first person: "Your peak hours...", "Your biggest ship..."
   243→
   244→**For each teammate:** Write 2-3 sentences covering what they worked on and their pattern. Then:
   245→
   246→- **Praise** (1-2 specific things): Anchor in actual commits. Not "great work" — say exactly what was good. Examples: "Shipped the entire auth middleware rewrite in 3 focused sessions with 45% test coverage", "Every PR under 200 LOC — disciplined decomposition."
   247→- **Opportunity for growth** (1 specific thing): Frame as a leveling-up suggestion, not criticism. Anchor in actual data. Examples: "Test ratio was 12% this week — adding test coverage to the payment module before it gets more complex would pay off", "5 fix commits on the same file suggest the original PR could have used a review pass."
   248→
   249→**If only one contributor (solo repo):** Skip the team breakdown and proceed as before — the retro is personal.
   250→
   251→**If there are Co-Authored-By trailers:** Parse `Co-Authored-By:` lines in commit messages. Credit those authors for the commit alongside the primary author. Note AI co-authors (e.g., `noreply@anthropic.com`) but do not include them as team members — instead, track "AI-assisted commits" as a separate metric.
   252→
   253→### Step 10: Week-over-Week Trends (if window >= 14d)
   254→
   255→If the time window is 14 days or more, split into weekly buckets and show trends:
   256→- Commits per week (total and per-author)
   257→- LOC per week
   258→- Test ratio per week
   259→- Fix ratio per week
   260→- Session count per week
   261→
   262→### Step 11: Streak Tracking
   263→
   264→Count consecutive days with at least 1 commit to origin/<default>, going back from today. Track both team streak and personal streak:
   265→
   266→```bash
   267→# Team streak: all unique commit dates (Pacific time) — no hard cutoff
   268→TZ=America/Los_Angeles git log origin/<default> --format="%ad" --date=format:"%Y-%m-%d" | sort -u
   269→
   270→# Personal streak: only the current user's commits
   271→TZ=America/Los_Angeles git log origin/<default> --author="<user_name>" --format="%ad" --date=format:"%Y-%m-%d" | sort -u
   272→```
   273→
   274→Count backward from today — how many consecutive days have at least one commit? This queries the full history so streaks of any length are reported accurately. Display both:
   275→- "Team shipping streak: 47 consecutive days"
   276→- "Your shipping streak: 32 consecutive days"
   277→
   278→### Step 12: Load History & Compare
   279→
   280→Before saving the new snapshot, check for prior retro history:
   281→
   282→```bash
   283→ls -t .context/retros/*.json 2>/dev/null
   284→```
   285→
   286→**If prior retros exist:** Load the most recent one using the Read tool. Calculate deltas for key metrics and include a **Trends vs Last Retro** section:
   287→```
   288→                    Last        Now         Delta
   289→Test ratio:         22%    →    41%         ↑19pp
   290→Sessions:           10     →    14          ↑4
   291→LOC/hour:           200    →    350         ↑75%
   292→Fix ratio:          54%    →    30%         ↓24pp (improving)
   293→Commits:            32     →    47          ↑47%
   294→Deep sessions:      3      →    5           ↑2
   295→```
   296→
   297→**If no prior retros exist:** Skip the comparison section and append: "First retro recorded — run again next week to see trends."
   298→
   299→### Step 13: Save Retro History
   300→
   301→After computing all metrics (including streak) and loading any prior history for comparison, save a JSON snapshot:
   302→
   303→```bash
   304→mkdir -p .context/retros
   305→```
   306→
   307→Determine the next sequence number for today (substitute the actual date for `$(date +%Y-%m-%d)`):
   308→```bash
   309→# Count existing retros for today to get next sequence number
   310→today=$(TZ=America/Los_Angeles date +%Y-%m-%d)
   311→existing=$(ls .context/retros/${today}-*.json 2>/dev/null | wc -l | tr -d ' ')
   312→next=$((existing + 1))
   313→# Save as .context/retros/${today}-${next}.json
   314→```
   315→
   316→Use the Write tool to save the JSON file with this schema:
   317→```json
   318→{
   319→  "date": "2026-03-08",
   320→  "window": "7d",
   321→  "metrics": {
   322→    "commits": 47,
   323→    "contributors": 3,
   324→    "prs_merged": 12,
   325→    "insertions": 3200,
   326→    "deletions": 800,
   327→    "net_loc": 2400,
   328→    "test_loc": 1300,
   329→    "test_ratio": 0.41,
   330→    "active_days": 6,
   331→    "sessions": 14,
   332→    "deep_sessions": 5,
   333→    "avg_session_minutes": 42,
   334→    "loc_per_session_hour": 350,
   335→    "feat_pct": 0.40,
   336→    "fix_pct": 0.30,
   337→    "peak_hour": 22,
   338→    "ai_assisted_commits": 32
   339→  },
   340→  "authors": {
   341→    "Garry Tan": { "commits": 32, "insertions": 2400, "deletions": 300, "test_ratio": 0.41, "top_area": "browse/" },
   342→    "Alice": { "commits": 12, "insertions": 800, "deletions": 150, "test_ratio": 0.35, "top_area": "app/services/" }
   343→  },
   344→  "version_range": ["1.16.0.0", "1.16.1.0"],
   345→  "streak_days": 47,
   346→  "tweetable": "Week of Mar 1: 47 commits (3 contributors), 3.2k LOC, 38% tests, 12 PRs, peak: 10pm",
   347→  "greptile": {
   348→    "fixes": 3,
   349→    "fps": 1,
   350→    "already_fixed": 2,
   351→    "signal_pct": 83
   352→  }
   353→}
   354→```
   355→
   356→**Note:** Only include the `greptile` field if `~/.gstack/greptile-history.md` exists and has entries within the time window. Only include the `backlog` field if `TODOS.md` exists. Only include the `test_health` field if test files were found (command 10 returns > 0). If any has no data, omit the field entirely.
   357→
   358→Include test health data in the JSON when test files exist:
   359→```json
   360→  "test_health": {
   361→    "total_test_files": 47,
   362→    "tests_added_this_period": 5,
   363→    "regression_test_commits": 3,
   364→    "test_files_changed": 8
   365→  }
   366→```
   367→
   368→Include backlog data in the JSON when TODOS.md exists:
   369→```json
   370→  "backlog": {
   371→    "total_open": 28,
   372→    "p0_p1": 2,
   373→    "p2": 8,
   374→    "completed_this_period": 3,
   375→    "added_this_period": 1
   376→  }
   377→```
   378→
   379→### Step 14: Write the Narrative
   380→
   381→Structure the output as:
   382→
   383→---
   384→
   385→**Tweetable summary** (first line, before everything else):
   386→```
   387→Week of Mar 1: 47 commits (3 contributors), 3.2k LOC, 38% tests, 12 PRs, peak: 10pm | Streak: 47d
   388→```
   389→
   390→## Engineering Retro: [date range]
   391→
   392→### Summary Table
   393→(from Step 2)
   394→
   395→### Trends vs Last Retro
   396→(from Step 11, loaded before save — skip if first retro)
   397→
   398→### Time & Session Patterns
   399→(from Steps 3-4)
   400→
   401→Narrative interpreting what the team-wide patterns mean:
   402→- When the most productive hours are and what drives them
   403→- Whether sessions are getting longer or shorter over time
   404→- Estimated hours per day of active coding (team aggregate)
   405→- Notable patterns: do team members code at the same time or in shifts?
   406→
   407→### Shipping Velocity
   408→(from Steps 5-7)
   409→
   410→Narrative covering:
   411→- Commit type mix and what it reveals
   412→- PR size discipline (are PRs staying small?)
   413→- Fix-chain detection (sequences of fix commits on the same subsystem)
   414→- Version bump discipline
   415→
   416→### Code Quality Signals
   417→- Test LOC ratio trend
   418→- Hotspot analysis (are the same files churning?)
   419→- Any XL PRs that should have been split
   420→- Greptile signal ratio and trend (if history exists): "Greptile: X% signal (Y valid catches, Z false positives)"
   421→
   422→### Test Health
   423→- Total test files: N (from command 10)
   424→- Tests added this period: M (from command 12 — test files changed)
   425→- Regression test commits: list `test(qa):` and `test(design):` and `test: coverage` commits from command 11
   426→- If prior retro exists and has `test_health`: show delta "Test count: {last} → {now} (+{delta})"
   427→- If test ratio < 20%: flag as growth area — "100% test coverage is the goal. Tests make vibe coding safe."
   428→
   429→### Focus & Highlights
   430→(from Step 8)
   431→- Focus score with interpretation
   432→- Ship of the week callout
   433→
   434→### Your Week (personal deep-dive)
   435→(from Step 9, for the current user only)
   436→
   437→This is the section the user cares most about. Include:
   438→- Their personal commit count, LOC, test ratio
   439→- Their session patterns and peak hours
   440→- Their focus areas
   441→- Their biggest ship
   442→- **What you did well** (2-3 specific things anchored in commits)
   443→- **Where to level up** (1-2 specific, actionable suggestions)
   444→
   445→### Team Breakdown
   446→(from Step 9, for each teammate — skip if solo repo)
   447→
   448→For each teammate (sorted by commits descending), write a section:
   449→
   450→#### [Name]
   451→- **What they shipped**: 2-3 sentences on their contributions, areas of focus, and commit patterns
   452→- **Praise**: 1-2 specific things they did well, anchored in actual commits. Be genuine — what would you actually say in a 1:1? Examples:
   453→  - "Cleaned up the entire auth module in 3 small, reviewable PRs — textbook decomposition"
   454→  - "Added integration tests for every new endpoint, not just happy paths"
   455→  - "Fixed the N+1 query that was causing 2s load times on the dashboard"
   456→- **Opportunity for growth**: 1 specific, constructive suggestion. Frame as investment, not criticism. Examples:
   457→  - "Test coverage on the payment module is at 8% — worth investing in before the next feature lands on top of it"
   458→  - "3 of the 5 PRs were 800+ LOC — breaking these up would catch issues earlier and make review easier"
   459→  - "All commits land between 1-4am — sustainable pace matters for code quality long-term"
   460→
   461→**AI collaboration note:** If many commits have `Co-Authored-By` AI trailers (e.g., Claude, Copilot), note the AI-assisted commit percentage as a team metric. Frame it neutrally — "N% of commits were AI-assisted" — without judgment.
   462→
   463→### Top 3 Team Wins
   464→Identify the 3 highest-impact things shipped in the window across the whole team. For each:
   465→- What it was
   466→- Who shipped it
   467→- Why it matters (product/architecture impact)
   468→
   469→### 3 Things to Improve
   470→Specific, actionable, anchored in actual commits. Mix personal and team-level suggestions. Phrase as "to get even better, the team could..."
   471→
   472→### 3 Habits for Next Week
   473→Small, practical, realistic. Each must be something that takes <5 minutes to adopt. At least one should be team-oriented (e.g., "review each other's PRs same-day").
   474→
   475→### Week-over-Week Trends
   476→(if applicable, from Step 10)
   477→
   478→---
   479→
   480→## Compare Mode
   481→
   482→When the user runs `/retro compare` (or `/retro compare 14d`):
   483→
   484→1. Compute metrics for the current window (default 7d) using `--since="7 days ago"`
   485→2. Compute metrics for the immediately prior same-length window using both `--since` and `--until` to avoid overlap (e.g., `--since="14 days ago" --until="7 days ago"` for a 7d window)
   486→3. Show a side-by-side comparison table with deltas and arrows
   487→4. Write a brief narrative highlighting the biggest improvements and regressions
   488→5. Save only the current-window snapshot to `.context/retros/` (same as a normal retro run); do **not** persist the prior-window metrics.
   489→
   490→## Tone
   491→
   492→- Encouraging but candid, no coddling
   493→- Specific and concrete — always anchor in actual commits/code
   494→- Skip generic praise ("great job!") — say exactly what was good and why
   495→- Frame improvements as leveling up, not criticism
   496→- **Praise should feel like something you'd actually say in a 1:1** — specific, earned, genuine
   497→- **Growth suggestions should feel like investment advice** — "this is worth your time because..." not "you failed at..."
   498→- Never compare teammates against each other negatively. Each person's section stands on its own.
   499→- Keep total output around 3000-4500 words (slightly longer to accommodate team sections)
   500→- Use markdown tables and code blocks for data, prose for narrative
   501→- Output directly to the conversation — do NOT write to filesystem (except the `.context/retros/` JSON snapshot)
   502→
   503→## Important Rules
   504→
   505→- ALL narrative output goes directly to the user in the conversation. The ONLY file written is the `.context/retros/` JSON snapshot.
   506→- Use `origin/<default>` for all git queries (not local main which may be stale)
   507→- Convert all timestamps to Pacific time for display (use `TZ=America/Los_Angeles`)
   508→- If the window has zero commits, say so and suggest a different window
   509→- Round LOC/hour to nearest 50
   510→- Treat merge commits as PR boundaries
   511→- Do not read CLAUDE.md or other docs — this skill is self-contained
   512→- On first run (no prior retros), skip comparison sections gracefully
   513→


     1→---
     2→name: document-release
     3→version: 1.0.0
     4→description: |
     5→  Post-ship documentation update. Reads all project docs, cross-references the
     6→  diff, updates README/ARCHITECTURE/CONTRIBUTING/CLAUDE.md to match what shipped,
     7→  polishes CHANGELOG voice, cleans up TODOS, and optionally bumps VERSION.
     8→allowed-tools:
     9→  - Bash
    10→  - Read
    11→  - Write
    12→  - Edit
    13→  - Grep
    14→  - Glob
    15→  - AskUserQuestion
    16→---
    17→
    18→{{PREAMBLE}}
    19→
    20→{{BASE_BRANCH_DETECT}}
    21→
    22→# Document Release: Post-Ship Documentation Update
    23→
    24→You are running the `/document-release` workflow. This runs **after `/ship`** (code committed, PR
    25→exists or about to exist) but **before the PR merges**. Your job: ensure every documentation file
    26→in the project is accurate, up to date, and written in a friendly, user-forward voice.
    27→
    28→You are mostly automated. Make obvious factual updates directly. Stop and ask only for risky or
    29→subjective decisions.
    30→
    31→**Only stop for:**
    32→- Risky/questionable doc changes (narrative, philosophy, security, removals, large rewrites)
    33→- VERSION bump decision (if not already bumped)
    34→- New TODOS items to add
    35→- Cross-doc contradictions that are narrative (not factual)
    36→
    37→**Never stop for:**
    38→- Factual corrections clearly from the diff
    39→- Adding items to tables/lists
    40→- Updating paths, counts, version numbers
    41→- Fixing stale cross-references
    42→- CHANGELOG voice polish (minor wording adjustments)
    43→- Marking TODOS complete
    44→- Cross-doc factual inconsistencies (e.g., version number mismatch)
    45→
    46→**NEVER do:**
    47→- Overwrite, replace, or regenerate CHANGELOG entries — polish wording only, preserve all content
    48→- Bump VERSION without asking — always use AskUserQuestion for version changes
    49→- Use `Write` tool on CHANGELOG.md — always use `Edit` with exact `old_string` matches
    50→
    51→---
    52→
    53→## Step 1: Pre-flight & Diff Analysis
    54→
    55→1. Check the current branch. If on the base branch, **abort**: "You're on the base branch. Run from a feature branch."
    56→
    57→2. Gather context about what changed:
    58→
    59→```bash
    60→git diff <base>...HEAD --stat
    61→```
    62→
    63→```bash
    64→git log <base>..HEAD --oneline
    65→```
    66→
    67→```bash
    68→git diff <base>...HEAD --name-only
    69→```
    70→
    71→3. Discover all documentation files in the repo:
    72→
    73→```bash
    74→find . -maxdepth 2 -name "*.md" -not -path "./.git/*" -not -path "./node_modules/*" -not -path "./.gstack/*" -not -path "./.context/*" | sort
    75→```
    76→
    77→4. Classify the changes into categories relevant to documentation:
    78→   - **New features** — new files, new commands, new skills, new capabilities
    79→   - **Changed behavior** — modified services, updated APIs, config changes
    80→   - **Removed functionality** — deleted files, removed commands
    81→   - **Infrastructure** — build system, test infrastructure, CI
    82→
    83→5. Output a brief summary: "Analyzing N files changed across M commits. Found K documentation files to review."
    84→
    85→---
    86→
    87→## Step 2: Per-File Documentation Audit
    88→
    89→Read each documentation file and cross-reference it against the diff. Use these generic heuristics
    90→(adapt to whatever project you're in — these are not gstack-specific):
    91→
    92→**README.md:**
    93→- Does it describe all features and capabilities visible in the diff?
    94→- Are install/setup instructions consistent with the changes?
    95→- Are examples, demos, and usage descriptions still valid?
    96→- Are troubleshooting steps still accurate?
    97→
    98→**ARCHITECTURE.md:**
    99→- Do ASCII diagrams and component descriptions match the current code?
   100→- Are design decisions and "why" explanations still accurate?
   101→- Be conservative — only update things clearly contradicted by the diff. Architecture docs
   102→  describe things unlikely to change frequently.
   103→
   104→**CONTRIBUTING.md — New contributor smoke test:**
   105→- Walk through the setup instructions as if you are a brand new contributor.
   106→- Are the listed commands accurate? Would each step succeed?
   107→- Do test tier descriptions match the current test infrastructure?
   108→- Are workflow descriptions (dev setup, contributor mode, etc.) current?
   109→- Flag anything that would fail or confuse a first-time contributor.
   110→
   111→**CLAUDE.md / project instructions:**
   112→- Does the project structure section match the actual file tree?
   113→- Are listed commands and scripts accurate?
   114→- Do build/test instructions match what's in package.json (or equivalent)?
   115→
   116→**Any other .md files:**
   117→- Read the file, determine its purpose and audience.
   118→- Cross-reference against the diff to check if it contradicts anything the file says.
   119→
   120→For each file, classify needed updates as:
   121→
   122→- **Auto-update** — Factual corrections clearly warranted by the diff: adding an item to a
   123→  table, updating a file path, fixing a count, updating a project structure tree.
   124→- **Ask user** — Narrative changes, section removal, security model changes, large rewrites
   125→  (more than ~10 lines in one section), ambiguous relevance, adding entirely new sections.
   126→
   127→---
   128→
   129→## Step 3: Apply Auto-Updates
   130→
   131→Make all clear, factual updates directly using the Edit tool.
   132→
   133→For each file modified, output a one-line summary describing **what specifically changed** — not
   134→just "Updated README.md" but "README.md: added /new-skill to skills table, updated skill count
   135→from 9 to 10."
   136→
   137→**Never auto-update:**
   138→- README introduction or project positioning
   139→- ARCHITECTURE philosophy or design rationale
   140→- Security model descriptions
   141→- Do not remove entire sections from any document
   142→
   143→---
   144→
   145→## Step 4: Ask About Risky/Questionable Changes
   146→
   147→For each risky or questionable update identified in Step 2, use AskUserQuestion with:
   148→- Context: project name, branch, which doc file, what we're reviewing
   149→- The specific documentation decision
   150→- `RECOMMENDATION: Choose [X] because [one-line reason]`
   151→- Options including C) Skip — leave as-is
   152→
   153→Apply approved changes immediately after each answer.
   154→
   155→---
   156→
   157→## Step 5: CHANGELOG Voice Polish
   158→
   159→**CRITICAL — NEVER CLOBBER CHANGELOG ENTRIES.**
   160→
   161→This step polishes voice. It does NOT rewrite, replace, or regenerate CHANGELOG content.
   162→
   163→A real incident occurred where an agent replaced existing CHANGELOG entries when it should have
   164→preserved them. This skill must NEVER do that.
   165→
   166→**Rules:**
   167→1. Read the entire CHANGELOG.md first. Understand what is already there.
   168→2. Only modify wording within existing entries. Never delete, reorder, or replace entries.
   169→3. Never regenerate a CHANGELOG entry from scratch. The entry was written by `/ship` from the
   170→   actual diff and commit history. It is the source of truth. You are polishing prose, not
   171→   rewriting history.
   172→4. If an entry looks wrong or incomplete, use AskUserQuestion — do NOT silently fix it.
   173→5. Use Edit tool with exact `old_string` matches — never use Write to overwrite CHANGELOG.md.
   174→
   175→**If CHANGELOG was not modified in this branch:** skip this step.
   176→
   177→**If CHANGELOG was modified in this branch**, review the entry for voice:
   178→
   179→- **Sell test:** Would a user reading each bullet think "oh nice, I want to try that"? If not,
   180→  rewrite the wording (not the content).
   181→- Lead with what the user can now **do** — not implementation details.
   182→- "You can now..." not "Refactored the..."
   183→- Flag and rewrite any entry that reads like a commit message.
   184→- Internal/contributor changes belong in a separate "### For contributors" subsection.
   185→- Auto-fix minor voice adjustments. Use AskUserQuestion if a rewrite would alter meaning.
   186→
   187→---
   188→
   189→## Step 6: Cross-Doc Consistency & Discoverability Check
   190→
   191→After auditing each file individually, do a cross-doc consistency pass:
   192→
   193→1. Does the README's feature/capability list match what CLAUDE.md (or project instructions) describes?
   194→2. Does ARCHITECTURE's component list match CONTRIBUTING's project structure description?
   195→3. Does CHANGELOG's latest version match the VERSION file?
   196→4. **Discoverability:** Is every documentation file reachable from README.md or CLAUDE.md? If
   197→   ARCHITECTURE.md exists but neither README nor CLAUDE.md links to it, flag it. Every doc
   198→   should be discoverable from one of the two entry-point files.
   199→5. Flag any contradictions between documents. Auto-fix clear factual inconsistencies (e.g., a
   200→   version mismatch). Use AskUserQuestion for narrative contradictions.
   201→
   202→---
   203→
   204→## Step 7: TODOS.md Cleanup
   205→
   206→This is a second pass that complements `/ship`'s Step 5.5. Read `review/TODOS-format.md` (if
   207→available) for the canonical TODO item format.
   208→
   209→If TODOS.md does not exist, skip this step.
   210→
   211→1. **Completed items not yet marked:** Cross-reference the diff against open TODO items. If a
   212→   TODO is clearly completed by the changes in this branch, move it to the Completed section
   213→   with `**Completed:** vX.Y.Z.W (YYYY-MM-DD)`. Be conservative — only mark items with clear
   214→   evidence in the diff.
   215→
   216→2. **Items needing description updates:** If a TODO references files or components that were
   217→   significantly changed, its description may be stale. Use AskUserQuestion to confirm whether
   218→   the TODO should be updated, completed, or left as-is.
   219→
   220→3. **New deferred work:** Check the diff for `TODO`, `FIXME`, `HACK`, and `XXX` comments. For
   221→   each one that represents meaningful deferred work (not a trivial inline note), use
   222→   AskUserQuestion to ask whether it should be captured in TODOS.md.
   223→
   224→---
   225→
   226→## Step 8: VERSION Bump Question
   227→
   228→**CRITICAL — NEVER BUMP VERSION WITHOUT ASKING.**
   229→
   230→1. **If VERSION does not exist:** Skip silently.
   231→
   232→2. Check if VERSION was already modified on this branch:
   233→
   234→```bash
   235→git diff <base>...HEAD -- VERSION
   236→```
   237→
   238→3. **If VERSION was NOT bumped:** Use AskUserQuestion:
   239→   - RECOMMENDATION: Choose C (Skip) because docs-only changes rarely warrant a version bump
   240→   - A) Bump PATCH (X.Y.Z+1) — if doc changes ship alongside code changes
   241→   - B) Bump MINOR (X.Y+1.0) — if this is a significant standalone release
   242→   - C) Skip — no version bump needed
   243→
   244→4. **If VERSION was already bumped:** Do NOT skip silently. Instead, check whether the bump
   245→   still covers the full scope of changes on this branch:
   246→
   247→   a. Read the CHANGELOG entry for the current VERSION. What features does it describe?
   248→   b. Read the full diff (`git diff <base>...HEAD --stat` and `git diff <base>...HEAD --name-only`).
   249→      Are there significant changes (new features, new skills, new commands, major refactors)
   250→      that are NOT mentioned in the CHANGELOG entry for the current version?
   251→   c. **If the CHANGELOG entry covers everything:** Skip — output "VERSION: Already bumped to
   252→      vX.Y.Z, covers all changes."
   253→   d. **If there are significant uncovered changes:** Use AskUserQuestion explaining what the
   254→      current version covers vs what's new, and ask:
   255→      - RECOMMENDATION: Choose A because the new changes warrant their own version
   256→      - A) Bump to next patch (X.Y.Z+1) — give the new changes their own version
   257→      - B) Keep current version — add new changes to the existing CHANGELOG entry
   258→      - C) Skip — leave version as-is, handle later
   259→
   260→   The key insight: a VERSION bump set for "feature A" should not silently absorb "feature B"
   261→   if feature B is substantial enough to deserve its own version entry.
   262→
   263→---
   264→
   265→## Step 9: Commit & Output
   266→
   267→**Empty check first:** Run `git status` (never use `-uall`). If no documentation files were
   268→modified by any previous step, output "All documentation is up to date." and exit without
   269→committing.
   270→
   271→**Commit:**
   272→
   273→1. Stage modified documentation files by name (never `git add -A` or `git add .`).
   274→2. Create a single commit:
   275→
   276→```bash
   277→git commit -m "$(cat <<'EOF'
   278→docs: update project documentation for vX.Y.Z.W
   279→
   280→Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
   281→EOF
   282→)"
   283→```
   284→
   285→3. Push to the current branch:
   286→
   287→```bash
   288→git push
   289→```
   290→
   291→**PR body update (idempotent, race-safe):**
   292→
   293→1. Read the existing PR body into a PID-unique tempfile:
   294→
   295→```bash
   296→gh pr view --json body -q .body > /tmp/gstack-pr-body-$$.md
   297→```
   298→
   299→2. If the tempfile already contains a `## Documentation` section, replace that section with the
   300→   updated content. If it does not contain one, append a `## Documentation` section at the end.
   301→
   302→3. The Documentation section should include a **doc diff preview** — for each file modified,
   303→   describe what specifically changed (e.g., "README.md: added /document-release to skills
   304→   table, updated skill count from 9 to 10").
   305→
   306→4. Write the updated body back:
   307→
   308→```bash
   309→gh pr edit --body-file /tmp/gstack-pr-body-$$.md
   310→```
   311→
   312→5. Clean up the tempfile:
   313→
   314→```bash
   315→rm -f /tmp/gstack-pr-body-$$.md
   316→```
   317→
   318→6. If `gh pr view` fails (no PR exists): skip with message "No PR found — skipping body update."
   319→7. If `gh pr edit` fails: warn "Could not update PR body — documentation changes are in the
   320→   commit." and continue.
   321→
   322→**Structured doc health summary (final output):**
   323→
   324→Output a scannable summary showing every documentation file's status:
   325→
   326→```
   327→Documentation health:
   328→  README.md       [status] ([details])
   329→  ARCHITECTURE.md [status] ([details])
   330→  CONTRIBUTING.md [status] ([details])
   331→  CHANGELOG.md    [status] ([details])
   332→  TODOS.md        [status] ([details])
   333→  VERSION         [status] ([details])
   334→```
   335→
   336→Where status is one of:
   337→- Updated — with description of what changed
   338→- Current — no changes needed
   339→- Voice polished — wording adjusted
   340→- Not bumped — user chose to skip
   341→- Already bumped — version was set by /ship
   342→- Skipped — file does not exist
   343→
   344→---
   345→
   346→## Important Rules
   347→
   348→- **Read before editing.** Always read the full content of a file before modifying it.
   349→- **Never clobber CHANGELOG.** Polish wording only. Never delete, replace, or regenerate entries.
   350→- **Never bump VERSION silently.** Always ask. Even if already bumped, check whether it covers the full scope of changes.
   351→- **Be explicit about what changed.** Every edit gets a one-line summary.
   352→- **Generic heuristics, not project-specific.** The audit checks work on any repo.
   353→- **Discoverability matters.** Every doc file should be reachable from README or CLAUDE.md.
   354→- **Voice: friendly, user-forward, not obscure.** Write like you're explaining to a smart person
   355→  who hasn't seen the code.
   356→


     1→---
     2→name: qa
     3→version: 2.0.0
     4→description: |
     5→  Systematically QA test a web application and fix bugs found. Runs QA testing,
     6→  then iteratively fixes bugs in source code, committing each fix atomically and
     7→  re-verifying. Use when asked to "qa", "QA", "test this site", "find bugs",
     8→  "test and fix", or "fix what's broken". Three tiers: Quick (critical/high only),
     9→  Standard (+ medium), Exhaustive (+ cosmetic). Produces before/after health scores,
    10→  fix evidence, and a ship-readiness summary. For report-only mode, use /qa-only.
    11→allowed-tools:
    12→  - Bash
    13→  - Read
    14→  - Write
    15→  - Edit
    16→  - Glob
    17→  - Grep
    18→  - AskUserQuestion
    19→  - WebSearch
    20→---
    21→
    22→{{PREAMBLE}}
    23→
    24→{{BASE_BRANCH_DETECT}}
    25→
    26→# /qa: Test → Fix → Verify
    27→
    28→You are a QA engineer AND a bug-fix engineer. Test web applications like a real user — click everything, fill every form, check every state. When you find bugs, fix them in source code with atomic commits, then re-verify. Produce a structured report with before/after evidence.
    29→
    30→## Setup
    31→
    32→**Parse the user's request for these parameters:**
    33→
    34→| Parameter | Default | Override example |
    35→|-----------|---------|-----------------:|
    36→| Target URL | (auto-detect or required) | `https://myapp.com`, `http://localhost:3000` |
    37→| Tier | Standard | `--quick`, `--exhaustive` |
    38→| Mode | full | `--regression .gstack/qa-reports/baseline.json` |
    39→| Output dir | `.gstack/qa-reports/` | `Output to /tmp/qa` |
    40→| Scope | Full app (or diff-scoped) | `Focus on the billing page` |
    41→| Auth | None | `Sign in to user@example.com`, `Import cookies from cookies.json` |
    42→
    43→**Tiers determine which issues get fixed:**
    44→- **Quick:** Fix critical + high severity only
    45→- **Standard:** + medium severity (default)
    46→- **Exhaustive:** + low/cosmetic severity
    47→
    48→**If no URL is given and you're on a feature branch:** Automatically enter **diff-aware mode** (see Modes below). This is the most common case — the user just shipped code on a branch and wants to verify it works.
    49→
    50→**Require clean working tree before starting:**
    51→```bash
    52→if [ -n "$(git status --porcelain)" ]; then
    53→  echo "ERROR: Working tree is dirty. Commit or stash changes before running /qa."
    54→  exit 1
    55→fi
    56→```
    57→
    58→**Find the browse binary:**
    59→
    60→{{BROWSE_SETUP}}
    61→
    62→**Check test framework (bootstrap if needed):**
    63→
    64→{{TEST_BOOTSTRAP}}
    65→
    66→**Create output directories:**
    67→
    68→```bash
    69→mkdir -p .gstack/qa-reports/screenshots
    70→```
    71→
    72→---
    73→
    74→## Test Plan Context
    75→
    76→Before falling back to git diff heuristics, check for richer test plan sources:
    77→
    78→1. **Project-scoped test plans:** Check `~/.gstack/projects/` for recent `*-test-plan-*.md` files for this repo
    79→   ```bash
    80→   eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)
    81→   ls -t ~/.gstack/projects/$SLUG/*-test-plan-*.md 2>/dev/null | head -1
    82→   ```
    83→2. **Conversation context:** Check if a prior `/plan-eng-review` or `/plan-ceo-review` produced test plan output in this conversation
    84→3. **Use whichever source is richer.** Fall back to git diff analysis only if neither is available.
    85→
    86→---
    87→
    88→## Phases 1-6: QA Baseline
    89→
    90→{{QA_METHODOLOGY}}
    91→
    92→Record baseline health score at end of Phase 6.
    93→
    94→---
    95→
    96→## Output Structure
    97→
    98→```
    99→.gstack/qa-reports/
   100→├── qa-report-{domain}-{YYYY-MM-DD}.md    # Structured report
   101→├── screenshots/
   102→│   ├── initial.png                        # Landing page annotated screenshot
   103→│   ├── issue-001-step-1.png               # Per-issue evidence
   104→│   ├── issue-001-result.png
   105→│   ├── issue-001-before.png               # Before fix (if fixed)
   106→│   ├── issue-001-after.png                # After fix (if fixed)
   107→│   └── ...
   108→└── baseline.json                          # For regression mode
   109→```
   110→
   111→Report filenames use the domain and date: `qa-report-myapp-com-2026-03-12.md`
   112→
   113→---
   114→
   115→## Phase 7: Triage
   116→
   117→Sort all discovered issues by severity, then decide which to fix based on the selected tier:
   118→
   119→- **Quick:** Fix critical + high only. Mark medium/low as "deferred."
   120→- **Standard:** Fix critical + high + medium. Mark low as "deferred."
   121→- **Exhaustive:** Fix all, including cosmetic/low severity.
   122→
   123→Mark issues that cannot be fixed from source code (e.g., third-party widget bugs, infrastructure issues) as "deferred" regardless of tier.
   124→
   125→---
   126→
   127→## Phase 8: Fix Loop
   128→
   129→For each fixable issue, in severity order:
   130→
   131→### 8a. Locate source
   132→
   133→```bash
   134→# Grep for error messages, component names, route definitions
   135→# Glob for file patterns matching the affected page
   136→```
   137→
   138→- Find the source file(s) responsible for the bug
   139→- ONLY modify files directly related to the issue
   140→
   141→### 8b. Fix
   142→
   143→- Read the source code, understand the context
   144→- Make the **minimal fix** — smallest change that resolves the issue
   145→- Do NOT refactor surrounding code, add features, or "improve" unrelated things
   146→
   147→### 8c. Commit
   148→
   149→```bash
   150→git add <only-changed-files>
   151→git commit -m "fix(qa): ISSUE-NNN — short description"
   152→```
   153→
   154→- One commit per fix. Never bundle multiple fixes.
   155→- Message format: `fix(qa): ISSUE-NNN — short description`
   156→
   157→### 8d. Re-test
   158→
   159→- Navigate back to the affected page
   160→- Take **before/after screenshot pair**
   161→- Check console for errors
   162→- Use `snapshot -D` to verify the change had the expected effect
   163→
   164→```bash
   165→$B goto <affected-url>
   166→$B screenshot "$REPORT_DIR/screenshots/issue-NNN-after.png"
   167→$B console --errors
   168→$B snapshot -D
   169→```
   170→
   171→### 8e. Classify
   172→
   173→- **verified**: re-test confirms the fix works, no new errors introduced
   174→- **best-effort**: fix applied but couldn't fully verify (e.g., needs auth state, external service)
   175→- **reverted**: regression detected → `git revert HEAD` → mark issue as "deferred"
   176→
   177→### 8e.5. Regression Test
   178→
   179→Skip if: classification is not "verified", OR the fix is purely visual/CSS with no JS behavior, OR no test framework was detected AND user declined bootstrap.
   180→
   181→**1. Study the project's existing test patterns:**
   182→
   183→Read 2-3 test files closest to the fix (same directory, same code type). Match exactly:
   184→- File naming, imports, assertion style, describe/it nesting, setup/teardown patterns
   185→The regression test must look like it was written by the same developer.
   186→
   187→**2. Trace the bug's codepath, then write a regression test:**
   188→
   189→Before writing the test, trace the data flow through the code you just fixed:
   190→- What input/state triggered the bug? (the exact precondition)
   191→- What codepath did it follow? (which branches, which function calls)
   192→- Where did it break? (the exact line/condition that failed)
   193→- What other inputs could hit the same codepath? (edge cases around the fix)
   194→
   195→The test MUST:
   196→- Set up the precondition that triggered the bug (the exact state that made it break)
   197→- Perform the action that exposed the bug
   198→- Assert the correct behavior (NOT "it renders" or "it doesn't throw")
   199→- If you found adjacent edge cases while tracing, test those too (e.g., null input, empty array, boundary value)
   200→- Include full attribution comment:
   201→  ```
   202→  // Regression: ISSUE-NNN — {what broke}
   203→  // Found by /qa on {YYYY-MM-DD}
   204→  // Report: .gstack/qa-reports/qa-report-{domain}-{date}.md
   205→  ```
   206→
   207→Test type decision:
   208→- Console error / JS exception / logic bug → unit or integration test
   209→- Broken form / API failure / data flow bug → integration test with request/response
   210→- Visual bug with JS behavior (broken dropdown, animation) → component test
   211→- Pure CSS → skip (caught by QA reruns)
   212→
   213→Generate unit tests. Mock all external dependencies (DB, API, Redis, file system).
   214→
   215→Use auto-incrementing names to avoid collisions: check existing `{name}.regression-*.test.{ext}` files, take max number + 1.
   216→
   217→**3. Run only the new test file:**
   218→
   219→```bash
   220→{detected test command} {new-test-file}
   221→```
   222→
   223→**4. Evaluate:**
   224→- Passes → commit: `git commit -m "test(qa): regression test for ISSUE-NNN — {desc}"`
   225→- Fails → fix test once. Still failing → delete test, defer.
   226→- Taking >2 min exploration → skip and defer.
   227→
   228→**5. WTF-likelihood exclusion:** Test commits don't count toward the heuristic.
   229→
   230→### 8f. Self-Regulation (STOP AND EVALUATE)
   231→
   232→Every 5 fixes (or after any revert), compute the WTF-likelihood:
   233→
   234→```
   235→WTF-LIKELIHOOD:
   236→  Start at 0%
   237→  Each revert:                +15%
   238→  Each fix touching >3 files: +5%
   239→  After fix 15:               +1% per additional fix
   240→  All remaining Low severity: +10%
   241→  Touching unrelated files:   +20%
   242→```
   243→
   244→**If WTF > 20%:** STOP immediately. Show the user what you've done so far. Ask whether to continue.
   245→
   246→**Hard cap: 50 fixes.** After 50 fixes, stop regardless of remaining issues.
   247→
   248→---
   249→
   250→## Phase 9: Final QA
   251→
   252→After all fixes are applied:
   253→
   254→1. Re-run QA on all affected pages
   255→2. Compute final health score
   256→3. **If final score is WORSE than baseline:** WARN prominently — something regressed
   257→
   258→---
   259→
   260→## Phase 10: Report
   261→
   262→Write the report to both local and project-scoped locations:
   263→
   264→**Local:** `.gstack/qa-reports/qa-report-{domain}-{YYYY-MM-DD}.md`
   265→
   266→**Project-scoped:** Write test outcome artifact for cross-session context:
   267→```bash
   268→eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)
   269→mkdir -p ~/.gstack/projects/$SLUG
   270→```
   271→Write to `~/.gstack/projects/{slug}/{user}-{branch}-test-outcome-{datetime}.md`
   272→
   273→**Per-issue additions** (beyond standard report template):
   274→- Fix Status: verified / best-effort / reverted / deferred
   275→- Commit SHA (if fixed)
   276→- Files Changed (if fixed)
   277→- Before/After screenshots (if fixed)
   278→
   279→**Summary section:**
   280→- Total issues found
   281→- Fixes applied (verified: X, best-effort: Y, reverted: Z)
   282→- Deferred issues
   283→- Health score delta: baseline → final
   284→
   285→**PR Summary:** Include a one-line summary suitable for PR descriptions:
   286→> "QA found N issues, fixed M, health score X → Y."
   287→
   288→---
   289→
   290→## Phase 11: TODOS.md Update
   291→
   292→If the repo has a `TODOS.md`:
   293→
   294→1. **New deferred bugs** → add as TODOs with severity, category, and repro steps
   295→2. **Fixed bugs that were in TODOS.md** → annotate with "Fixed by /qa on {branch}, {date}"
   296→
   297→---
   298→
   299→## Additional Rules (qa-specific)
   300→
   301→11. **Clean working tree required.** Refuse to start if `git status --porcelain` is non-empty.
   302→12. **One commit per fix.** Never bundle multiple fixes into one commit.
   303→13. **Only modify tests when generating regression tests in Phase 8e.5.** Never modify CI configuration. Never modify existing tests — only create new test files.
   304→14. **Revert on regression.** If a fix makes things worse, `git revert HEAD` immediately.
   305→15. **Self-regulate.** Follow the WTF-likelihood heuristic. When in doubt, stop and ask.
   306→


Now let me read a few more remaining files and check for template variables and preamble:


Bash

head -200 /root/projects/gits/gstack/scripts/gen-skill-docs.ts | tail -100


node "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/run-with-flags.js" "pre:bash:tmux-reminder" "scripts/hooks/pre-bash-tmux-reminder.js" "strict"


node "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/run-with-flags.js" "pre:bash:git-push-reminder" "scripts/hooks/pre-bash-git-push-reminder.js" "strict"


node "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/run-with-flags.js" "pre:insaits-security" "scripts/hooks/insaits-security-wrapper.js" "standard,strict"


grep -n "{{" /root/projects/gits/gstack/scripts/gen-skill-docs.ts | head -20


node "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/run-with-flags.js" "post:bash:pr-created" "scripts/hooks/post-bash-pr-created.js" "standard,strict"


node "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/run-with-flags.js" "post:bash:build-complete" "scripts/hooks/post-bash-build-complete.js" "standard,strict"


_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"
_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no")
echo "LAKE_INTRO: $_LAKE_SEEN"
\`\`\`

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.

If \`LAKE_INTRO\` is \`no\`: Before continuing, introduce the Completeness Principle.
Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete
thing when AI makes the marginal cost near-zero. Read more: https://garryslist.org/posts/boil-the-ocean"
Then offer to open the essay in their default browser:

\`\`\`bash
open https://garryslist.org/posts/boil-the-ocean
touch ~/.gstack/.completeness-intro-seen
\`\`\`

Only run \`open\` if the user says yes. Always run \`touch\` to mark as seen. This only happens once.

## AskUserQuestion Format

**ALWAYS follow this structure for every AskUserQuestion call:**
1. **Re-ground:** State the project, the current branch (use the \`_BRANCH\` value printed by the preamble — NOT any branch from conversation history or gitStatus), and the current plan/task. (1-2 sentences)
2. **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.
3. **Recommend:** \`RECOMMENDATION: Choose [X] because [one-line reason]\` — always prefer the complete option over shortcuts (see Completeness Principle). Include \`Completeness: X/10\` for each option. Calibration: 10 = complete implementation (all edge cases, full coverage), 7 = covers happy path but skips some edges, 3 = shortcut that defers significant work. If both options are 8+, pick the higher; if one is ≤5, flag it.
4. **Options:** Lettered options: \`A) ... B) ... C) ...\` — when an option involves effort, show both scales: \`(human: ~X / CC: ~Y)\`

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.

## Completeness Principle — Boil the Lake

AI-assisted coding makes the marginal cost of completeness near-zero. When you present options:

- If Option A is the complete implementation (full parity, all edge cases, 100% coverage) and Option B is a shortcut that saves modest effort — **always recommend A**. The delta between 80 lines and 150 lines is meaningless with CC+gstack. "Good enough" is the wrong instinct when "complete" costs minutes more.
- **Lake vs. ocean:** A "lake" is boilable — 100% test coverage for a module, full feature implementation, handling all edge cases, complete error paths. An "ocean" is not — rewriting an entire system from scratch, adding features to dependencies you don't control, multi-quarter platform migrations. Recommend boiling lakes. Flag oceans as out of scope.
- **When estimating effort**, always show both scales: human team time and CC+gstack time. The compression ratio varies by task type — use this reference:

| Task type | Human team | CC+gstack | Compression |
|-----------|-----------|-----------|-------------|
| Boilerplate / scaffolding | 2 days | 15 min | ~100x |
| Test writing | 1 day | 15 min | ~50x |
| Feature implementation | 1 week | 30 min | ~30x |
| Bug fix + regression test | 4 hours | 15 min | ~20x |
| Architecture / design | 2 days | 4 hours | ~5x |
| Research / exploration | 1 day | 3 hours | ~3x |

- This principle applies to test coverage, error handling, documentation, edge cases, and feature completeness. Don't skip the last 10% to "save time" — with AI, that 10% costs seconds.

**Anti-patterns — DON'T do this:**
- BAD: "Choose B — it covers 90% of the value with less code." (If A is only 70 lines more, choose A.)
- BAD: "We can skip edge case handling to save time." (Edge case handling costs minutes with CC.)
- BAD: "Let's defer test coverage to a follow-up PR." (Tests are the cheapest lake to boil.)
- BAD: Quoting only human-team effort: "This would take 2 weeks." (Say: "2 weeks human / ~1 hour CC.")

## 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}"`;


6: *   read .tmpl → find {{PLACEHOLDERS}} → resolve from source → format → write .md
1105:const GENERATED_HEADER = `<!-- AUTO-GENERATED from {{SOURCE}} — do not edit directly -->\n<!-- Regenerate: bun run gen:skill-docs -->\n`;
1115:    if (!resolver) throw new Error(`Unknown placeholder {{${name}}} in ${relTmplPath}`);
1126:  const header = GENERATED_HEADER.replace('{{SOURCE}}', path.basename(tmplPath));


total 20
drwxr-xr-x  2 root root   43 Mar 18 15:58 .
drwxr-xr-x 22 root root 4096 Mar 18 15:58 ..
-rw-r--r--  1 root root 7962 Mar 18 15:58 SKILL.md
-rw-r--r--  1 root root 7850 Mar 18 15:58 SKILL.md.tmpl


total 20
drwxr-xr-x  2 root root   43 Mar 18 15:58 .
drwxr-xr-x 22 root root 4096 Mar 18 15:58 ..
-rw-r--r--  1 root root 9699 Mar 18 15:58 SKILL.md
-rw-r--r--  1 root root 2067 Mar 18 15:58 SKILL.md.tmpl


total 52
drwxr-xr-x  2 root root    43 Mar 18 15:58 .
drwxr-xr-x 22 root root  4096 Mar 18 15:58 ..
-rw-r--r--  1 root root 26030 Mar 18 15:58 SKILL.md
-rw-r--r--  1 root root 18398 Mar 18 15:58 SKILL.md.tmpl


Let me read the remaining template files and look for the shared template variables:


     1→---
     2→name: gstack-upgrade
     3→version: 1.1.0
     4→description: |
     5→  Upgrade gstack to the latest version. Detects global vs vendored install,
     6→  runs the upgrade, and shows what's new.
     7→allowed-tools:
     8→  - Bash
     9→  - Read
    10→  - Write
    11→  - AskUserQuestion
    12→---
    13→
    14→# /gstack-upgrade
    15→
    16→Upgrade gstack to the latest version and show what's new.
    17→
    18→## Inline upgrade flow
    19→
    20→This section is referenced by all skill preambles when they detect `UPGRADE_AVAILABLE`.
    21→
    22→### Step 1: Ask the user (or auto-upgrade)
    23→
    24→First, check if auto-upgrade is enabled:
    25→```bash
    26→_AUTO=""
    27→[ "${GSTACK_AUTO_UPGRADE:-}" = "1" ] && _AUTO="true"
    28→[ -z "$_AUTO" ] && _AUTO=$(~/.claude/skills/gstack/bin/gstack-config get auto_upgrade 2>/dev/null || true)
    29→echo "AUTO_UPGRADE=$_AUTO"
    30→```
    31→
    32→**If `AUTO_UPGRADE=true` or `AUTO_UPGRADE=1`:** Skip AskUserQuestion. Log "Auto-upgrading gstack v{old} → v{new}..." and proceed directly to Step 2. If `./setup` fails during auto-upgrade, restore from backup (`.bak` directory) and warn the user: "Auto-upgrade failed — restored previous version. Run `/gstack-upgrade` manually to retry."
    33→
    34→**Otherwise**, use AskUserQuestion:
    35→- Question: "gstack **v{new}** is available (you're on v{old}). Upgrade now?"
    36→- Options: ["Yes, upgrade now", "Always keep me up to date", "Not now", "Never ask again"]
    37→
    38→**If "Yes, upgrade now":** Proceed to Step 2.
    39→
    40→**If "Always keep me up to date":**
    41→```bash
    42→~/.claude/skills/gstack/bin/gstack-config set auto_upgrade true
    43→```
    44→Tell user: "Auto-upgrade enabled. Future updates will install automatically." Then proceed to Step 2.
    45→
    46→**If "Not now":** Write snooze state with escalating backoff (first snooze = 24h, second = 48h, third+ = 1 week), then continue with the current skill. Do not mention the upgrade again.
    47→```bash
    48→_SNOOZE_FILE=~/.gstack/update-snoozed
    49→_REMOTE_VER="{new}"
    50→_CUR_LEVEL=0
    51→if [ -f "$_SNOOZE_FILE" ]; then
    52→  _SNOOZED_VER=$(awk '{print $1}' "$_SNOOZE_FILE")
    53→  if [ "$_SNOOZED_VER" = "$_REMOTE_VER" ]; then
    54→    _CUR_LEVEL=$(awk '{print $2}' "$_SNOOZE_FILE")
    55→    case "$_CUR_LEVEL" in *[!0-9]*) _CUR_LEVEL=0 ;; esac
    56→  fi
    57→fi
    58→_NEW_LEVEL=$((_CUR_LEVEL + 1))
    59→[ "$_NEW_LEVEL" -gt 3 ] && _NEW_LEVEL=3
    60→echo "$_REMOTE_VER $_NEW_LEVEL $(date +%s)" > "$_SNOOZE_FILE"
    61→```
    62→Note: `{new}` is the remote version from the `UPGRADE_AVAILABLE` output — substitute it from the update check result.
    63→
    64→Tell user the snooze duration: "Next reminder in 24h" (or 48h or 1 week, depending on level). Tip: "Set `auto_upgrade: true` in `~/.gstack/config.yaml` for automatic upgrades."
    65→
    66→**If "Never ask again":**
    67→```bash
    68→~/.claude/skills/gstack/bin/gstack-config set update_check false
    69→```
    70→Tell user: "Update checks disabled. Run `~/.claude/skills/gstack/bin/gstack-config set update_check true` to re-enable."
    71→Continue with the current skill.
    72→
    73→### Step 2: Detect install type
    74→
    75→```bash
    76→if [ -d "$HOME/.claude/skills/gstack/.git" ]; then
    77→  INSTALL_TYPE="global-git"
    78→  INSTALL_DIR="$HOME/.claude/skills/gstack"
    79→elif [ -d ".claude/skills/gstack/.git" ]; then
    80→  INSTALL_TYPE="local-git"
    81→  INSTALL_DIR=".claude/skills/gstack"
    82→elif [ -d ".claude/skills/gstack" ]; then
    83→  INSTALL_TYPE="vendored"
    84→  INSTALL_DIR=".claude/skills/gstack"
    85→elif [ -d "$HOME/.claude/skills/gstack" ]; then
    86→  INSTALL_TYPE="vendored-global"
    87→  INSTALL_DIR="$HOME/.claude/skills/gstack"
    88→else
    89→  echo "ERROR: gstack not found"
    90→  exit 1
    91→fi
    92→echo "Install type: $INSTALL_TYPE at $INSTALL_DIR"
    93→```
    94→
    95→The install type and directory path printed above will be used in all subsequent steps.
    96→
    97→### Step 3: Save old version
    98→
    99→Use the install directory from Step 2's output below:
   100→
   101→```bash
   102→OLD_VERSION=$(cat "$INSTALL_DIR/VERSION" 2>/dev/null || echo "unknown")
   103→```
   104→
   105→### Step 4: Upgrade
   106→
   107→Use the install type and directory detected in Step 2:
   108→
   109→**For git installs** (global-git, local-git):
   110→```bash
   111→cd "$INSTALL_DIR"
   112→STASH_OUTPUT=$(git stash 2>&1)
   113→git fetch origin
   114→git reset --hard origin/main
   115→./setup
   116→```
   117→If `$STASH_OUTPUT` contains "Saved working directory", warn the user: "Note: local changes were stashed. Run `git stash pop` in the skill directory to restore them."
   118→
   119→**For vendored installs** (vendored, vendored-global):
   120→```bash
   121→PARENT=$(dirname "$INSTALL_DIR")
   122→TMP_DIR=$(mktemp -d)
   123→git clone --depth 1 https://github.com/garrytan/gstack.git "$TMP_DIR/gstack"
   124→mv "$INSTALL_DIR" "$INSTALL_DIR.bak"
   125→mv "$TMP_DIR/gstack" "$INSTALL_DIR"
   126→cd "$INSTALL_DIR" && ./setup
   127→rm -rf "$INSTALL_DIR.bak" "$TMP_DIR"
   128→```
   129→
   130→### Step 4.5: Sync local vendored copy
   131→
   132→Use the install directory from Step 2. Check if there's also a local vendored copy that needs updating:
   133→
   134→```bash
   135→_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
   136→LOCAL_GSTACK=""
   137→if [ -n "$_ROOT" ] && [ -d "$_ROOT/.claude/skills/gstack" ]; then
   138→  _RESOLVED_LOCAL=$(cd "$_ROOT/.claude/skills/gstack" && pwd -P)
   139→  _RESOLVED_PRIMARY=$(cd "$INSTALL_DIR" && pwd -P)
   140→  if [ "$_RESOLVED_LOCAL" != "$_RESOLVED_PRIMARY" ]; then
   141→    LOCAL_GSTACK="$_ROOT/.claude/skills/gstack"
   142→  fi
   143→fi
   144→echo "LOCAL_GSTACK=$LOCAL_GSTACK"
   145→```
   146→
   147→If `LOCAL_GSTACK` is non-empty, update it by copying from the freshly-upgraded primary install (same approach as README vendored install):
   148→```bash
   149→mv "$LOCAL_GSTACK" "$LOCAL_GSTACK.bak"
   150→cp -Rf "$INSTALL_DIR" "$LOCAL_GSTACK"
   151→rm -rf "$LOCAL_GSTACK/.git"
   152→cd "$LOCAL_GSTACK" && ./setup
   153→rm -rf "$LOCAL_GSTACK.bak"
   154→```
   155→Tell user: "Also updated vendored copy at `$LOCAL_GSTACK` — commit `.claude/skills/gstack/` when you're ready."
   156→
   157→If `./setup` fails, restore from backup and warn the user:
   158→```bash
   159→rm -rf "$LOCAL_GSTACK"
   160→mv "$LOCAL_GSTACK.bak" "$LOCAL_GSTACK"
   161→```
   162→Tell user: "Sync failed — restored previous version at `$LOCAL_GSTACK`. Run `/gstack-upgrade` manually to retry."
   163→
   164→### Step 5: Write marker + clear cache
   165→
   166→```bash
   167→mkdir -p ~/.gstack
   168→echo "$OLD_VERSION" > ~/.gstack/just-upgraded-from
   169→rm -f ~/.gstack/last-update-check
   170→rm -f ~/.gstack/update-snoozed
   171→```
   172→
   173→### Step 6: Show What's New
   174→
   175→Read `$INSTALL_DIR/CHANGELOG.md`. Find all version entries between the old version and the new version. Summarize as 5-7 bullets grouped by theme. Don't overwhelm — focus on user-facing changes. Skip internal refactors unless they're significant.
   176→
   177→Format:
   178→```
   179→gstack v{new} — upgraded from v{old}!
   180→
   181→What's new:
   182→- [bullet 1]
   183→- [bullet 2]
   184→- ...
   185→
   186→Happy shipping!
   187→```
   188→
   189→### Step 7: Continue
   190→
   191→After showing What's New, continue with whatever skill the user originally invoked. The upgrade is done — no further action needed.
   192→
   193→---
   194→
   195→## Standalone usage
   196→
   197→When invoked directly as `/gstack-upgrade` (not from a preamble):
   198→
   199→1. Force a fresh update check (bypass cache):
   200→```bash
   201→~/.claude/skills/gstack/bin/gstack-update-check --force 2>/dev/null || \
   202→.claude/skills/gstack/bin/gstack-update-check --force 2>/dev/null || true
   203→```
   204→Use the output to determine if an upgrade is available.
   205→
   206→2. If `UPGRADE_AVAILABLE <old> <new>`: follow Steps 2-6 above.
   207→
   208→3. If no output (primary is up to date): check for a stale local vendored copy.
   209→
   210→Run the Step 2 bash block above to detect the primary install type and directory (`INSTALL_TYPE` and `INSTALL_DIR`). Then run the Step 4.5 detection bash block above to check for a local vendored copy (`LOCAL_GSTACK`).
   211→
   212→**If `LOCAL_GSTACK` is empty** (no local vendored copy): tell the user "You're already on the latest version (v{version})."
   213→
   214→**If `LOCAL_GSTACK` is non-empty**, compare versions:
   215→```bash
   216→PRIMARY_VER=$(cat "$INSTALL_DIR/VERSION" 2>/dev/null || echo "unknown")
   217→LOCAL_VER=$(cat "$LOCAL_GSTACK/VERSION" 2>/dev/null || echo "unknown")
   218→echo "PRIMARY=$PRIMARY_VER LOCAL=$LOCAL_VER"
   219→```
   220→
   221→**If versions differ:** follow the Step 4.5 sync bash block above to update the local copy from the primary. Tell user: "Global v{PRIMARY_VER} is up to date. Updated local vendored copy from v{LOCAL_VER} → v{PRIMARY_VER}. Commit `.claude/skills/gstack/` when you're ready."
   222→
   223→**If versions match:** tell the user "You're on the latest version (v{PRIMARY_VER}). Global and local vendored copy are both up to date."
   224→


     1→---
     2→name: setup-browser-cookies
     3→version: 1.0.0
     4→description: |
     5→  Import cookies from your real browser (Comet, Chrome, Arc, Brave, Edge) into the
     6→  headless browse session. Opens an interactive picker UI where you select which
     7→  cookie domains to import. Use before QA testing authenticated pages.
     8→allowed-tools:
     9→  - Bash
    10→  - Read
    11→  - AskUserQuestion
    12→---
    13→
    14→{{PREAMBLE}}
    15→
    16→# Setup Browser Cookies
    17→
    18→Import logged-in sessions from your real Chromium browser into the headless browse session.
    19→
    20→## How it works
    21→
    22→1. Find the browse binary
    23→2. Run `cookie-import-browser` to detect installed browsers and open the picker UI
    24→3. User selects which cookie domains to import in their browser
    25→4. Cookies are decrypted and loaded into the Playwright session
    26→
    27→## Steps
    28→
    29→### 1. Find the browse binary
    30→
    31→{{BROWSE_SETUP}}
    32→
    33→### 2. Open the cookie picker
    34→
    35→```bash
    36→$B cookie-import-browser
    37→```
    38→
    39→This auto-detects installed Chromium browsers (Comet, Chrome, Arc, Brave, Edge) and opens
    40→an interactive picker UI in your default browser where you can:
    41→- Switch between installed browsers
    42→- Search domains
    43→- Click "+" to import a domain's cookies
    44→- Click trash to remove imported cookies
    45→
    46→Tell the user: **"Cookie picker opened — select the domains you want to import in your browser, then tell me when you're done."**
    47→
    48→### 3. Direct import (alternative)
    49→
    50→If the user specifies a domain directly (e.g., `/setup-browser-cookies github.com`), skip the UI:
    51→
    52→```bash
    53→$B cookie-import-browser comet --domain github.com
    54→```
    55→
    56→Replace `comet` with the appropriate browser if specified.
    57→
    58→### 4. Verify
    59→
    60→After the user confirms they're done:
    61→
    62→```bash
    63→$B cookies
    64→```
    65→
    66→Show the user a summary of imported cookies (domain counts).
    67→
    68→## Notes
    69→
    70→- First import per browser may trigger a macOS Keychain dialog — click "Allow" / "Always Allow"
    71→- Cookie picker is served on the same port as the browse server (no extra process)
    72→- Only domain names and cookie counts are shown in the UI — no cookie values are exposed
    73→- The browse session persists cookies between commands, so imported cookies work immediately
    74→