From 00cefcafb1f4e6b3c931bb0798af19950eaaade9 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Thu, 19 Mar 2026 01:36:26 -0500 Subject: [PATCH 1/2] feat: review chaining + commit hash staleness tracking (v0.8.3) (#206) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: review chaining + commit hash staleness tracking Each plan review skill now suggests the next review via AskUserQuestion: - CEO review → eng review (required gate) + design review (if UI scope) - Design review → eng review + CEO review (if product gaps) - Eng review → design review (if UI changes) + CEO review (soft suggestion) Reviews now track HEAD commit hash in JSONL entries for deterministic staleness detection. Dashboard compares stored hash against current HEAD and reports drift. Respects skip_eng_review config in chaining logic. Also adds commit tracking to design-review-lite entries. * chore: regenerate SKILL.md files for review chaining * chore: bump version and changelog (v0.8.3) Co-Authored-By: Claude Opus 4.6 --------- Co-authored-by: Claude Opus 4.6 --- CHANGELOG.md | 9 ++++++ VERSION | 2 +- plan-ceo-review/SKILL.md | 26 +++++++++++++++++- plan-ceo-review/SKILL.md.tmpl | 18 +++++++++++- plan-design-review/SKILL.md | 26 +++++++++++++++++- plan-design-review/SKILL.md.tmpl | 18 +++++++++++- plan-eng-review/SKILL.md | 28 ++++++++++++++++++- plan-eng-review/SKILL.md.tmpl | 20 +++++++++++++- review/SKILL.md | 4 +-- scripts/gen-skill-docs.ts | 14 ++++++++-- ship/SKILL.md | 12 ++++++-- test/gen-skill-docs.test.ts | 47 ++++++++++++++++++++++++++++++++ 12 files changed, 210 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20735e5d..a43363d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## [0.8.3] - 2026-03-19 + +### Added + +- **Plan reviews now guide you to the next step.** After running `/plan-ceo-review`, `/plan-eng-review`, or `/plan-design-review`, you get a recommendation for what to run next — eng review is always suggested as the required shipping gate, design review is suggested when UI changes are detected, and CEO review is softly mentioned for big product changes. No more remembering the workflow yourself. +- **Reviews know when they're stale.** Each review now records the commit it was run at. The dashboard compares that against your current HEAD and tells you exactly how many commits have elapsed — "eng review may be stale — 13 commits since review" instead of guessing. +- **`skip_eng_review` respected everywhere.** If you've opted out of eng review globally, the chaining recommendations won't nag you about it. +- **Design review lite now tracks commits too.** The lightweight design check that runs inside `/review` and `/ship` gets the same staleness tracking as full reviews. + ## [0.8.2] - 2026-03-19 ### Added diff --git a/VERSION b/VERSION index 100435be..ee94dd83 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.8.2 +0.8.3 diff --git a/plan-ceo-review/SKILL.md b/plan-ceo-review/SKILL.md index 5101ea76..008a4e63 100644 --- a/plan-ceo-review/SKILL.md +++ b/plan-ceo-review/SKILL.md @@ -794,7 +794,7 @@ After producing the Completion Summary above, persist the review result: ```bash eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG -echo '{"skill":"plan-ceo-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl +echo '{"skill":"plan-ceo-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE","commit":"COMMIT"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl ``` Before running this command, substitute the placeholder values from the Completion Summary you just produced: @@ -803,6 +803,7 @@ Before running this command, substitute the placeholder values from the Completi - **unresolved**: number from "Unresolved decisions" in the summary - **critical_gaps**: number from "Failure modes: ___ CRITICAL GAPS" in the summary - **MODE**: the mode the user selected (SCOPE_EXPANSION / SELECTIVE_EXPANSION / HOLD_SCOPE / SCOPE_REDUCTION) +- **COMMIT**: output of `git rev-parse --short HEAD` ## Review Readiness Dashboard @@ -813,6 +814,8 @@ eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) cat ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl 2>/dev/null || echo "NO_REVIEWS" echo "---CONFIG---" ~/.claude/skills/gstack/bin/gstack-config get skip_eng_review 2>/dev/null || echo "false" +echo "---HEAD---" +git rev-parse --short HEAD 2>/dev/null || echo "unknown" ``` Parse the output. Find the most recent entry for each skill (plan-ceo-review, plan-eng-review, plan-design-review, design-review-lite, codex-review). Ignore entries with timestamps older than 7 days. For Design Review, show whichever is more recent between `plan-design-review` (full visual audit) and `design-review-lite` (code-level check). Append "(FULL)" or "(LITE)" to the status to distinguish. Display: @@ -844,6 +847,27 @@ Parse the output. Find the most recent entry for each skill (plan-ceo-review, pl - CEO, Design, and Codex reviews are shown for context but never block shipping - If \`skip_eng_review\` config is \`true\`, Eng Review shows "SKIPPED (global)" and verdict is CLEARED +**Staleness detection:** After displaying the dashboard, check if any existing reviews may be stale: +- Parse the \`---HEAD---\` section from the bash output to get the current HEAD commit hash +- For each review entry that has a \`commit\` field: compare it against the current HEAD. If different, count elapsed commits: \`git rev-list --count STORED_COMMIT..HEAD\`. Display: "Note: {skill} review from {date} may be stale — {N} commits since review" +- For entries without a \`commit\` field (legacy entries): display "Note: {skill} review from {date} has no commit tracking — consider re-running for accurate staleness detection" +- If all reviews match the current HEAD, do not display any staleness notes + +## Next Steps — Review Chaining + +After displaying the Review Readiness Dashboard, recommend the next review(s) based on what this CEO review discovered. Read the dashboard output to see which reviews have already been run and whether they are stale. + +**Recommend /plan-eng-review if eng review is not skipped globally** — check the dashboard output for `skip_eng_review`. If it is `true`, eng review is opted out — do not recommend it. Otherwise, eng review is the required shipping gate. If this CEO review expanded scope, changed architectural direction, or accepted scope expansions, emphasize that a fresh eng review is needed. If an eng review already exists in the dashboard but the commit hash shows it predates this CEO review, note that it may be stale and should be re-run. + +**Recommend /plan-design-review if UI scope was detected** — specifically if Section 11 (Design & UX Review) was NOT skipped, or if accepted scope expansions included UI-facing features. If an existing design review is stale (commit hash drift), note that. In SCOPE REDUCTION mode, skip this recommendation — design review is unlikely relevant for scope cuts. + +**If both are needed, recommend eng review first** (required gate), then design review. + +Use AskUserQuestion to present the next step. Include only applicable options: +- **A)** Run /plan-eng-review next (required gate) +- **B)** Run /plan-design-review next (only if UI scope detected) +- **C)** Skip — I'll handle reviews manually + ## docs/designs Promotion (EXPANSION and SELECTIVE EXPANSION only) At the end of the review, if the vision produced a compelling feature direction, offer to promote the CEO plan to the project repo. AskUserQuestion: diff --git a/plan-ceo-review/SKILL.md.tmpl b/plan-ceo-review/SKILL.md.tmpl index 09189af5..4f927880 100644 --- a/plan-ceo-review/SKILL.md.tmpl +++ b/plan-ceo-review/SKILL.md.tmpl @@ -641,7 +641,7 @@ After producing the Completion Summary above, persist the review result: ```bash eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG -echo '{"skill":"plan-ceo-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl +echo '{"skill":"plan-ceo-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE","commit":"COMMIT"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl ``` Before running this command, substitute the placeholder values from the Completion Summary you just produced: @@ -650,9 +650,25 @@ Before running this command, substitute the placeholder values from the Completi - **unresolved**: number from "Unresolved decisions" in the summary - **critical_gaps**: number from "Failure modes: ___ CRITICAL GAPS" in the summary - **MODE**: the mode the user selected (SCOPE_EXPANSION / SELECTIVE_EXPANSION / HOLD_SCOPE / SCOPE_REDUCTION) +- **COMMIT**: output of `git rev-parse --short HEAD` {{REVIEW_DASHBOARD}} +## Next Steps — Review Chaining + +After displaying the Review Readiness Dashboard, recommend the next review(s) based on what this CEO review discovered. Read the dashboard output to see which reviews have already been run and whether they are stale. + +**Recommend /plan-eng-review if eng review is not skipped globally** — check the dashboard output for `skip_eng_review`. If it is `true`, eng review is opted out — do not recommend it. Otherwise, eng review is the required shipping gate. If this CEO review expanded scope, changed architectural direction, or accepted scope expansions, emphasize that a fresh eng review is needed. If an eng review already exists in the dashboard but the commit hash shows it predates this CEO review, note that it may be stale and should be re-run. + +**Recommend /plan-design-review if UI scope was detected** — specifically if Section 11 (Design & UX Review) was NOT skipped, or if accepted scope expansions included UI-facing features. If an existing design review is stale (commit hash drift), note that. In SCOPE REDUCTION mode, skip this recommendation — design review is unlikely relevant for scope cuts. + +**If both are needed, recommend eng review first** (required gate), then design review. + +Use AskUserQuestion to present the next step. Include only applicable options: +- **A)** Run /plan-eng-review next (required gate) +- **B)** Run /plan-design-review next (only if UI scope detected) +- **C)** Skip — I'll handle reviews manually + ## docs/designs Promotion (EXPANSION and SELECTIVE EXPANSION only) At the end of the review, if the vision produced a compelling feature direction, offer to promote the CEO plan to the project repo. AskUserQuestion: diff --git a/plan-design-review/SKILL.md b/plan-design-review/SKILL.md index e0e3a839..8b85f2db 100644 --- a/plan-design-review/SKILL.md +++ b/plan-design-review/SKILL.md @@ -424,7 +424,7 @@ After producing the Completion Summary above, persist the review result: ```bash eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG -echo '{"skill":"plan-design-review","timestamp":"TIMESTAMP","status":"STATUS","overall_score":N,"unresolved":N,"decisions_made":N}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl +echo '{"skill":"plan-design-review","timestamp":"TIMESTAMP","status":"STATUS","overall_score":N,"unresolved":N,"decisions_made":N,"commit":"COMMIT"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl ``` Substitute values from the Completion Summary: @@ -433,6 +433,7 @@ Substitute values from the Completion Summary: - **overall_score**: final overall design score (0-10) - **unresolved**: number of unresolved design decisions - **decisions_made**: number of design decisions added to the plan +- **COMMIT**: output of `git rev-parse --short HEAD` ## Review Readiness Dashboard @@ -443,6 +444,8 @@ eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) cat ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl 2>/dev/null || echo "NO_REVIEWS" echo "---CONFIG---" ~/.claude/skills/gstack/bin/gstack-config get skip_eng_review 2>/dev/null || echo "false" +echo "---HEAD---" +git rev-parse --short HEAD 2>/dev/null || echo "unknown" ``` Parse the output. Find the most recent entry for each skill (plan-ceo-review, plan-eng-review, plan-design-review, design-review-lite, codex-review). Ignore entries with timestamps older than 7 days. For Design Review, show whichever is more recent between `plan-design-review` (full visual audit) and `design-review-lite` (code-level check). Append "(FULL)" or "(LITE)" to the status to distinguish. Display: @@ -474,6 +477,27 @@ Parse the output. Find the most recent entry for each skill (plan-ceo-review, pl - CEO, Design, and Codex reviews are shown for context but never block shipping - If \`skip_eng_review\` config is \`true\`, Eng Review shows "SKIPPED (global)" and verdict is CLEARED +**Staleness detection:** After displaying the dashboard, check if any existing reviews may be stale: +- Parse the \`---HEAD---\` section from the bash output to get the current HEAD commit hash +- For each review entry that has a \`commit\` field: compare it against the current HEAD. If different, count elapsed commits: \`git rev-list --count STORED_COMMIT..HEAD\`. Display: "Note: {skill} review from {date} may be stale — {N} commits since review" +- For entries without a \`commit\` field (legacy entries): display "Note: {skill} review from {date} has no commit tracking — consider re-running for accurate staleness detection" +- If all reviews match the current HEAD, do not display any staleness notes + +## Next Steps — Review Chaining + +After displaying the Review Readiness Dashboard, recommend the next review(s) based on what this design review discovered. Read the dashboard output to see which reviews have already been run and whether they are stale. + +**Recommend /plan-eng-review if eng review is not skipped globally** — check the dashboard output for `skip_eng_review`. If it is `true`, eng review is opted out — do not recommend it. Otherwise, eng review is the required shipping gate. If this design review added significant interaction specifications, new user flows, or changed the information architecture, emphasize that eng review needs to validate the architectural implications. If an eng review already exists but the commit hash shows it predates this design review, note that it may be stale and should be re-run. + +**Consider recommending /plan-ceo-review** — but only if this design review revealed fundamental product direction gaps. Specifically: if the overall design score started below 4/10, if the information architecture had major structural problems, or if the review surfaced questions about whether the right problem is being solved. AND no CEO review exists in the dashboard. This is a selective recommendation — most design reviews should NOT trigger a CEO review. + +**If both are needed, recommend eng review first** (required gate). + +Use AskUserQuestion to present the next step. Include only applicable options: +- **A)** Run /plan-eng-review next (required gate) +- **B)** Run /plan-ceo-review (only if fundamental product gaps found) +- **C)** Skip — I'll handle reviews manually + ## Formatting Rules * NUMBER issues (1, 2, 3...) and LETTERS for options (A, B, C...). * Label with NUMBER + LETTER (e.g., "3A", "3B"). diff --git a/plan-design-review/SKILL.md.tmpl b/plan-design-review/SKILL.md.tmpl index 73e383b6..25666628 100644 --- a/plan-design-review/SKILL.md.tmpl +++ b/plan-design-review/SKILL.md.tmpl @@ -271,7 +271,7 @@ After producing the Completion Summary above, persist the review result: ```bash eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG -echo '{"skill":"plan-design-review","timestamp":"TIMESTAMP","status":"STATUS","overall_score":N,"unresolved":N,"decisions_made":N}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl +echo '{"skill":"plan-design-review","timestamp":"TIMESTAMP","status":"STATUS","overall_score":N,"unresolved":N,"decisions_made":N,"commit":"COMMIT"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl ``` Substitute values from the Completion Summary: @@ -280,9 +280,25 @@ Substitute values from the Completion Summary: - **overall_score**: final overall design score (0-10) - **unresolved**: number of unresolved design decisions - **decisions_made**: number of design decisions added to the plan +- **COMMIT**: output of `git rev-parse --short HEAD` {{REVIEW_DASHBOARD}} +## Next Steps — Review Chaining + +After displaying the Review Readiness Dashboard, recommend the next review(s) based on what this design review discovered. Read the dashboard output to see which reviews have already been run and whether they are stale. + +**Recommend /plan-eng-review if eng review is not skipped globally** — check the dashboard output for `skip_eng_review`. If it is `true`, eng review is opted out — do not recommend it. Otherwise, eng review is the required shipping gate. If this design review added significant interaction specifications, new user flows, or changed the information architecture, emphasize that eng review needs to validate the architectural implications. If an eng review already exists but the commit hash shows it predates this design review, note that it may be stale and should be re-run. + +**Consider recommending /plan-ceo-review** — but only if this design review revealed fundamental product direction gaps. Specifically: if the overall design score started below 4/10, if the information architecture had major structural problems, or if the review surfaced questions about whether the right problem is being solved. AND no CEO review exists in the dashboard. This is a selective recommendation — most design reviews should NOT trigger a CEO review. + +**If both are needed, recommend eng review first** (required gate). + +Use AskUserQuestion to present the next step. Include only applicable options: +- **A)** Run /plan-eng-review next (required gate) +- **B)** Run /plan-ceo-review (only if fundamental product gaps found) +- **C)** Skip — I'll handle reviews manually + ## Formatting Rules * NUMBER issues (1, 2, 3...) and LETTERS for options (A, B, C...). * Label with NUMBER + LETTER (e.g., "3A", "3B"). diff --git a/plan-eng-review/SKILL.md b/plan-eng-review/SKILL.md index a98fa4f2..bbab36d1 100644 --- a/plan-eng-review/SKILL.md +++ b/plan-eng-review/SKILL.md @@ -395,7 +395,7 @@ After producing the Completion Summary above, persist the review result: ```bash eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG -echo '{"skill":"plan-eng-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl +echo '{"skill":"plan-eng-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE","commit":"COMMIT"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl ``` Substitute values from the Completion Summary: @@ -404,6 +404,7 @@ Substitute values from the Completion Summary: - **unresolved**: number from "Unresolved decisions" count - **critical_gaps**: number from "Failure modes: ___ critical gaps flagged" - **MODE**: FULL_REVIEW / SCOPE_REDUCED +- **COMMIT**: output of `git rev-parse --short HEAD` ## Review Readiness Dashboard @@ -414,6 +415,8 @@ eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) cat ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl 2>/dev/null || echo "NO_REVIEWS" echo "---CONFIG---" ~/.claude/skills/gstack/bin/gstack-config get skip_eng_review 2>/dev/null || echo "false" +echo "---HEAD---" +git rev-parse --short HEAD 2>/dev/null || echo "unknown" ``` Parse the output. Find the most recent entry for each skill (plan-ceo-review, plan-eng-review, plan-design-review, design-review-lite, codex-review). Ignore entries with timestamps older than 7 days. For Design Review, show whichever is more recent between `plan-design-review` (full visual audit) and `design-review-lite` (code-level check). Append "(FULL)" or "(LITE)" to the status to distinguish. Display: @@ -445,5 +448,28 @@ Parse the output. Find the most recent entry for each skill (plan-ceo-review, pl - CEO, Design, and Codex reviews are shown for context but never block shipping - If \`skip_eng_review\` config is \`true\`, Eng Review shows "SKIPPED (global)" and verdict is CLEARED +**Staleness detection:** After displaying the dashboard, check if any existing reviews may be stale: +- Parse the \`---HEAD---\` section from the bash output to get the current HEAD commit hash +- For each review entry that has a \`commit\` field: compare it against the current HEAD. If different, count elapsed commits: \`git rev-list --count STORED_COMMIT..HEAD\`. Display: "Note: {skill} review from {date} may be stale — {N} commits since review" +- For entries without a \`commit\` field (legacy entries): display "Note: {skill} review from {date} has no commit tracking — consider re-running for accurate staleness detection" +- If all reviews match the current HEAD, do not display any staleness notes + +## Next Steps — Review Chaining + +After displaying the Review Readiness Dashboard, check if additional reviews would be valuable. Read the dashboard output to see which reviews have already been run and whether they are stale. + +**Suggest /plan-design-review if UI changes exist and no design review has been run** — detect from the test diagram, architecture review, or any section that touched frontend components, CSS, views, or user-facing interaction flows. If an existing design review's commit hash shows it predates significant changes found in this eng review, note that it may be stale. + +**Mention /plan-ceo-review if this is a significant product change and no CEO review exists** — this is a soft suggestion, not a push. CEO review is optional. Only mention it if the plan introduces new user-facing features, changes product direction, or expands scope substantially. + +**Note staleness** of existing CEO or design reviews if this eng review found assumptions that contradict them, or if the commit hash shows significant drift. + +**If no additional reviews are needed** (or `skip_eng_review` is `true` in the dashboard config, meaning this eng review was optional): state "All relevant reviews complete. Run /ship when ready." + +Use AskUserQuestion with only the applicable options: +- **A)** Run /plan-design-review (only if UI scope detected and no design review exists) +- **B)** Run /plan-ceo-review (only if significant product change and no CEO review exists) +- **C)** Ready to implement — run /ship when done + ## Unresolved decisions 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. diff --git a/plan-eng-review/SKILL.md.tmpl b/plan-eng-review/SKILL.md.tmpl index e7120f60..a864324e 100644 --- a/plan-eng-review/SKILL.md.tmpl +++ b/plan-eng-review/SKILL.md.tmpl @@ -259,7 +259,7 @@ After producing the Completion Summary above, persist the review result: ```bash eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG -echo '{"skill":"plan-eng-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl +echo '{"skill":"plan-eng-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE","commit":"COMMIT"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl ``` Substitute values from the Completion Summary: @@ -268,8 +268,26 @@ Substitute values from the Completion Summary: - **unresolved**: number from "Unresolved decisions" count - **critical_gaps**: number from "Failure modes: ___ critical gaps flagged" - **MODE**: FULL_REVIEW / SCOPE_REDUCED +- **COMMIT**: output of `git rev-parse --short HEAD` {{REVIEW_DASHBOARD}} +## Next Steps — Review Chaining + +After displaying the Review Readiness Dashboard, check if additional reviews would be valuable. Read the dashboard output to see which reviews have already been run and whether they are stale. + +**Suggest /plan-design-review if UI changes exist and no design review has been run** — detect from the test diagram, architecture review, or any section that touched frontend components, CSS, views, or user-facing interaction flows. If an existing design review's commit hash shows it predates significant changes found in this eng review, note that it may be stale. + +**Mention /plan-ceo-review if this is a significant product change and no CEO review exists** — this is a soft suggestion, not a push. CEO review is optional. Only mention it if the plan introduces new user-facing features, changes product direction, or expands scope substantially. + +**Note staleness** of existing CEO or design reviews if this eng review found assumptions that contradict them, or if the commit hash shows significant drift. + +**If no additional reviews are needed** (or `skip_eng_review` is `true` in the dashboard config, meaning this eng review was optional): state "All relevant reviews complete. Run /ship when ready." + +Use AskUserQuestion with only the applicable options: +- **A)** Run /plan-design-review (only if UI scope detected and no design review exists) +- **B)** Run /plan-ceo-review (only if significant product change and no CEO review exists) +- **C)** Ready to implement — run /ship when done + ## Unresolved decisions 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. diff --git a/review/SKILL.md b/review/SKILL.md index 557259f1..b93ea79c 100644 --- a/review/SKILL.md +++ b/review/SKILL.md @@ -296,10 +296,10 @@ eval $(~/.claude/skills/gstack/bin/gstack-diff-scope 2>/dev/null) ```bash eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG -echo '{"skill":"design-review-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl +echo '{"skill":"design-review-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M,"commit":"COMMIT"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl ``` -Substitute: TIMESTAMP = ISO 8601 datetime, STATUS = "clean" if 0 findings or "issues_found", N = total findings, M = auto-fixed count. +Substitute: TIMESTAMP = ISO 8601 datetime, STATUS = "clean" if 0 findings or "issues_found", N = total findings, M = auto-fixed count, COMMIT = output of `git rev-parse --short HEAD`. Include any design findings alongside the findings from Step 4. They follow the same Fix-First flow in Step 5 — AUTO-FIX for mechanical CSS fixes, ASK for everything else. diff --git a/scripts/gen-skill-docs.ts b/scripts/gen-skill-docs.ts index 9f5460a3..08136b49 100644 --- a/scripts/gen-skill-docs.ts +++ b/scripts/gen-skill-docs.ts @@ -592,10 +592,10 @@ eval $(~/.claude/skills/gstack/bin/gstack-diff-scope 2>/dev/null) \`\`\`bash eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG -echo '{"skill":"design-review-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl +echo '{"skill":"design-review-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M,"commit":"COMMIT"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl \`\`\` -Substitute: TIMESTAMP = ISO 8601 datetime, STATUS = "clean" if 0 findings or "issues_found", N = total findings, M = auto-fixed count.`; +Substitute: TIMESTAMP = ISO 8601 datetime, STATUS = "clean" if 0 findings or "issues_found", N = total findings, M = auto-fixed count, COMMIT = output of \`git rev-parse --short HEAD\`.`; } // NOTE: design-checklist.md is a subset of this methodology for code-level detection. @@ -944,6 +944,8 @@ eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) cat ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl 2>/dev/null || echo "NO_REVIEWS" echo "---CONFIG---" ~/.claude/skills/gstack/bin/gstack-config get skip_eng_review 2>/dev/null || echo "false" +echo "---HEAD---" +git rev-parse --short HEAD 2>/dev/null || echo "unknown" \`\`\` Parse the output. Find the most recent entry for each skill (plan-ceo-review, plan-eng-review, plan-design-review, design-review-lite, codex-review). Ignore entries with timestamps older than 7 days. For Design Review, show whichever is more recent between \`plan-design-review\` (full visual audit) and \`design-review-lite\` (code-level check). Append "(FULL)" or "(LITE)" to the status to distinguish. Display: @@ -973,7 +975,13 @@ Parse the output. Find the most recent entry for each skill (plan-ceo-review, pl - **CLEARED**: Eng Review has >= 1 entry within 7 days with status "clean" (or \\\`skip_eng_review\\\` is \\\`true\\\`) - **NOT CLEARED**: Eng Review missing, stale (>7 days), or has open issues - CEO, Design, and Codex reviews are shown for context but never block shipping -- If \\\`skip_eng_review\\\` config is \\\`true\\\`, Eng Review shows "SKIPPED (global)" and verdict is CLEARED`; +- If \\\`skip_eng_review\\\` config is \\\`true\\\`, Eng Review shows "SKIPPED (global)" and verdict is CLEARED + +**Staleness detection:** After displaying the dashboard, check if any existing reviews may be stale: +- Parse the \\\`---HEAD---\\\` section from the bash output to get the current HEAD commit hash +- For each review entry that has a \\\`commit\\\` field: compare it against the current HEAD. If different, count elapsed commits: \\\`git rev-list --count STORED_COMMIT..HEAD\\\`. Display: "Note: {skill} review from {date} may be stale — {N} commits since review" +- For entries without a \\\`commit\\\` field (legacy entries): display "Note: {skill} review from {date} has no commit tracking — consider re-running for accurate staleness detection" +- If all reviews match the current HEAD, do not display any staleness notes`; } function generateTestBootstrap(_ctx: TemplateContext): string { diff --git a/ship/SKILL.md b/ship/SKILL.md index 97c8e79e..7bc9d758 100644 --- a/ship/SKILL.md +++ b/ship/SKILL.md @@ -217,6 +217,8 @@ eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) cat ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl 2>/dev/null || echo "NO_REVIEWS" echo "---CONFIG---" ~/.claude/skills/gstack/bin/gstack-config get skip_eng_review 2>/dev/null || echo "false" +echo "---HEAD---" +git rev-parse --short HEAD 2>/dev/null || echo "unknown" ``` Parse the output. Find the most recent entry for each skill (plan-ceo-review, plan-eng-review, plan-design-review, design-review-lite, codex-review). Ignore entries with timestamps older than 7 days. For Design Review, show whichever is more recent between `plan-design-review` (full visual audit) and `design-review-lite` (code-level check). Append "(FULL)" or "(LITE)" to the status to distinguish. Display: @@ -248,6 +250,12 @@ Parse the output. Find the most recent entry for each skill (plan-ceo-review, pl - CEO, Design, and Codex reviews are shown for context but never block shipping - If \`skip_eng_review\` config is \`true\`, Eng Review shows "SKIPPED (global)" and verdict is CLEARED +**Staleness detection:** After displaying the dashboard, check if any existing reviews may be stale: +- Parse the \`---HEAD---\` section from the bash output to get the current HEAD commit hash +- For each review entry that has a \`commit\` field: compare it against the current HEAD. If different, count elapsed commits: \`git rev-list --count STORED_COMMIT..HEAD\`. Display: "Note: {skill} review from {date} may be stale — {N} commits since review" +- For entries without a \`commit\` field (legacy entries): display "Note: {skill} review from {date} has no commit tracking — consider re-running for accurate staleness detection" +- If all reviews match the current HEAD, do not display any staleness notes + If the Eng Review is NOT "CLEAR": 1. **Check for a prior override on this branch:** @@ -708,10 +716,10 @@ eval $(~/.claude/skills/gstack/bin/gstack-diff-scope 2>/dev/null) ```bash eval $(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) mkdir -p ~/.gstack/projects/$SLUG -echo '{"skill":"design-review-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl +echo '{"skill":"design-review-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M,"commit":"COMMIT"}' >> ~/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl ``` -Substitute: TIMESTAMP = ISO 8601 datetime, STATUS = "clean" if 0 findings or "issues_found", N = total findings, M = auto-fixed count. +Substitute: TIMESTAMP = ISO 8601 datetime, STATUS = "clean" if 0 findings or "issues_found", N = total findings, M = auto-fixed count, COMMIT = output of `git rev-parse --short HEAD`. Include any design findings alongside the code review findings. They follow the same Fix-First flow below. diff --git a/test/gen-skill-docs.test.ts b/test/gen-skill-docs.test.ts index b53ebc17..7396933c 100644 --- a/test/gen-skill-docs.test.ts +++ b/test/gen-skill-docs.test.ts @@ -374,4 +374,51 @@ describe('REVIEW_DASHBOARD resolver', () => { expect(content).toContain('Design Review'); expect(content).toContain('skip_eng_review'); }); + + test('dashboard bash block includes git HEAD for staleness detection', () => { + const content = fs.readFileSync(path.join(ROOT, 'plan-ceo-review', 'SKILL.md'), 'utf-8'); + expect(content).toContain('git rev-parse --short HEAD'); + expect(content).toContain('---HEAD---'); + }); + + test('dashboard includes staleness detection prose', () => { + const content = fs.readFileSync(path.join(ROOT, 'plan-ceo-review', 'SKILL.md'), 'utf-8'); + expect(content).toContain('Staleness detection'); + expect(content).toContain('commit'); + }); + + for (const skill of REVIEW_SKILLS) { + test(`${skill} contains review chaining section`, () => { + const content = fs.readFileSync(path.join(ROOT, skill, 'SKILL.md'), 'utf-8'); + expect(content).toContain('Review Chaining'); + }); + + test(`${skill} Review Log includes commit field`, () => { + const content = fs.readFileSync(path.join(ROOT, skill, 'SKILL.md'), 'utf-8'); + expect(content).toContain('"commit"'); + }); + } + + test('plan-ceo-review chaining mentions eng and design reviews', () => { + const content = fs.readFileSync(path.join(ROOT, 'plan-ceo-review', 'SKILL.md'), 'utf-8'); + expect(content).toContain('/plan-eng-review'); + expect(content).toContain('/plan-design-review'); + }); + + test('plan-eng-review chaining mentions design and ceo reviews', () => { + const content = fs.readFileSync(path.join(ROOT, 'plan-eng-review', 'SKILL.md'), 'utf-8'); + expect(content).toContain('/plan-design-review'); + expect(content).toContain('/plan-ceo-review'); + }); + + test('plan-design-review chaining mentions eng and ceo reviews', () => { + const content = fs.readFileSync(path.join(ROOT, 'plan-design-review', 'SKILL.md'), 'utf-8'); + expect(content).toContain('/plan-eng-review'); + expect(content).toContain('/plan-ceo-review'); + }); + + test('ship does NOT contain review chaining', () => { + const content = fs.readFileSync(path.join(ROOT, 'ship', 'SKILL.md'), 'utf-8'); + expect(content).not.toContain('Review Chaining'); + }); }); From 3a315b338b61d7b7edfef2ec88591598eb5a5391 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Thu, 19 Mar 2026 01:38:54 -0500 Subject: [PATCH 2/2] docs: rewrite README + skills docs, auto-invoke /document-release (v0.8.4) (#207) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: add 6 missing skills to proactive suggestion list Add /codex, /careful, /freeze, /guard, /unfreeze, /gstack-upgrade to the root SKILL.md.tmpl proactive suggestion list so Claude suggests them at the appropriate workflow stages. Co-Authored-By: Claude Opus 4.6 (1M context) * docs: add 6 new skill entries + browse handoff to docs - docs/skills.md: add /codex, /careful, /freeze, /guard, /unfreeze, /gstack-upgrade to skill table with deep-dive sections. Group safety skills into one "Safety & Guardrails" section. Add browse handoff subsection to /browse deep-dive. - BROWSER.md: add handoff/resume to command reference table + section. Co-Authored-By: Claude Opus 4.6 (1M context) * docs: add power tools section + update skill lists in README - Update prose: "Fifteen specialists and six power tools" - Add power tools table after sprint specialists: /codex, /careful, /freeze, /guard, /unfreeze, /gstack-upgrade - Update all 4 skill list locations (install Step 1, Step 2, troubleshooting CLAUDE.md example) to include all 21 skills Co-Authored-By: Claude Opus 4.6 (1M context) * docs: add v0.7-v0.8.2 features to README "What's new" section Add paragraphs for browse handoff, /codex multi-AI review, safety guardrails (/careful, /freeze, /guard), proactive skill suggestions, and /ship auto-invoking /document-release. Co-Authored-By: Claude Opus 4.6 (1M context) * feat: auto-invoke /document-release after /ship PR creation Add Step 8.5 to /ship that automatically reads document-release/SKILL.md and executes the doc update workflow after creating the PR. This prevents documentation drift — /ship now keeps docs current without a separate command. Completes P1 TODO: "Auto-invoke /document-release from /ship" Co-Authored-By: Claude Opus 4.6 (1M context) * chore: bump version and changelog (v0.8.4) Co-Authored-By: Claude Opus 4.6 --------- Co-authored-by: Claude Opus 4.6 (1M context) --- BROWSER.md | 13 +++++ CHANGELOG.md | 9 +++ README.md | 32 ++++++++-- SKILL.md | 6 ++ SKILL.md.tmpl | 6 ++ TODOS.md | 12 +--- VERSION | 2 +- docs/skills.md | 143 +++++++++++++++++++++++++++++++++++++++++++++ ship/SKILL.md | 25 +++++++- ship/SKILL.md.tmpl | 25 +++++++- 10 files changed, 252 insertions(+), 21 deletions(-) diff --git a/BROWSER.md b/BROWSER.md index df4a6d1d..b024cdd4 100644 --- a/BROWSER.md +++ b/BROWSER.md @@ -17,6 +17,7 @@ This document covers the command reference and internals of gstack's headless br | Tabs | `tabs`, `tab`, `newtab`, `closetab` | Multi-page workflows | | Cookies | `cookie-import`, `cookie-import-browser` | Import cookies from file or real browser | | Multi-step | `chain` (JSON from stdin) | Batch commands in one call | +| Handoff | `handoff [reason]`, `resume` | Switch to visible Chrome for user takeover | All selector arguments accept CSS selectors, `@e` refs after `snapshot`, or `@c` refs after `snapshot -C`. 50+ commands total plus cookie import. @@ -123,6 +124,18 @@ The server hooks into Playwright's `page.on('console')`, `page.on('response')`, The `console`, `network`, and `dialog` commands read from the in-memory buffers, not disk. +### User handoff + +When the headless browser can't proceed (CAPTCHA, MFA, complex auth), `handoff` opens a visible Chrome window at the exact same page with all cookies, localStorage, and tabs preserved. The user solves the problem manually, then `resume` returns control to the agent with a fresh snapshot. + +```bash +$B handoff "Stuck on CAPTCHA at login page" # opens visible Chrome +# User solves CAPTCHA... +$B resume # returns to headless with fresh snapshot +``` + +The browser auto-suggests `handoff` after 3 consecutive failures. State is fully preserved across the switch — no re-login needed. + ### Dialog handling Dialogs (alert, confirm, prompt) are auto-accepted by default to prevent browser lockup. The `dialog-accept` and `dialog-dismiss` commands control this behavior. For prompts, `dialog-accept ` provides the response text. All dialogs are logged to the dialog buffer with type, message, and action taken. diff --git a/CHANGELOG.md b/CHANGELOG.md index a43363d7..87233991 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## [0.8.4] - 2026-03-19 + +### Added + +- **`/ship` now automatically syncs your docs.** After creating the PR, `/ship` runs `/document-release` as Step 8.5 — README, ARCHITECTURE, CONTRIBUTING, and CLAUDE.md all stay current without an extra command. No more stale docs after shipping. +- **Six new skills in the docs.** README, docs/skills.md, and BROWSER.md now cover `/codex` (multi-AI second opinion), `/careful` (destructive command warnings), `/freeze` (directory-scoped edit lock), `/guard` (full safety mode), `/unfreeze`, and `/gstack-upgrade`. The sprint skill table keeps its 15 specialists; a new "Power tools" section covers the rest. +- **Browse handoff documented everywhere.** BROWSER.md command table, docs/skills.md deep-dive, and README "What's new" all explain `$B handoff` and `$B resume` for CAPTCHA/MFA/auth walls. +- **Proactive suggestions know about all skills.** Root SKILL.md.tmpl now suggests `/codex`, `/careful`, `/freeze`, `/guard`, `/unfreeze`, and `/gstack-upgrade` at the right workflow stages. + ## [0.8.3] - 2026-03-19 ### Added diff --git a/README.md b/README.md index 86aeea66..d921e420 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ In the last 60 days I have written **over 600,000 lines of production code** — Same person. Different era. The difference is the tooling. -**gstack is how I do it.** It is my open source software factory. It turns Claude Code into a virtual engineering team you actually manage — a CEO who rethinks the product, an eng manager who locks the architecture, a designer who catches AI slop, a paranoid reviewer who finds production bugs, a QA lead who opens a real browser and clicks through your app, and a release engineer who ships the PR. Fifteen specialists, all as slash commands, all Markdown, **all free, MIT license, available right now.** +**gstack is how I do it.** It is my open source software factory. It turns Claude Code into a virtual engineering team you actually manage — a CEO who rethinks the product, an eng manager who locks the architecture, a designer who catches AI slop, a paranoid reviewer who finds production bugs, a QA lead who opens a real browser and clicks through your app, and a release engineer who ships the PR. Fifteen specialists and six power tools, all as slash commands, all Markdown, **all free, MIT license, available right now.** I am learning how to get to the edge of what agentic systems can do as of March 2026, and this is my live experiment. I am sharing it because I want the whole world on this journey with me. @@ -48,11 +48,11 @@ Expect first useful run in under 5 minutes on any repo with tests already set up Open Claude Code and paste this. Claude does the rest. -> Install gstack: run **`git clone https://github.com/garrytan/gstack.git ~/.claude/skills/gstack && cd ~/.claude/skills/gstack && ./setup`** then add a "gstack" section to CLAUDE.md that says to use the /browse skill from gstack for all web browsing, never use mcp\_\_claude-in-chrome\_\_\* tools, and lists the available skills: /office-hours, /plan-ceo-review, /plan-eng-review, /plan-design-review, /design-consultation, /review, /ship, /browse, /qa, /qa-only, /design-review, /setup-browser-cookies, /retro, /debug, /document-release. Then ask the user if they also want to add gstack to the current project so teammates get it. +> Install gstack: run **`git clone https://github.com/garrytan/gstack.git ~/.claude/skills/gstack && cd ~/.claude/skills/gstack && ./setup`** then add a "gstack" section to CLAUDE.md that says to use the /browse skill from gstack for all web browsing, never use mcp\_\_claude-in-chrome\_\_\* tools, and lists the available skills: /office-hours, /plan-ceo-review, /plan-eng-review, /plan-design-review, /design-consultation, /review, /ship, /browse, /qa, /qa-only, /design-review, /setup-browser-cookies, /retro, /debug, /document-release, /codex, /careful, /freeze, /guard, /unfreeze, /gstack-upgrade. Then ask the user if they also want to add gstack to the current project so teammates get it. ### Step 2: Add to your repo so teammates get it (optional) -> Add gstack to this project: run **`cp -Rf ~/.claude/skills/gstack .claude/skills/gstack && rm -rf .claude/skills/gstack/.git && cd .claude/skills/gstack && ./setup`** then add a "gstack" section to this project's CLAUDE.md that says to use the /browse skill from gstack for all web browsing, never use mcp\_\_claude-in-chrome\_\_\* tools, lists the available skills: /office-hours, /plan-ceo-review, /plan-eng-review, /plan-design-review, /design-consultation, /review, /ship, /browse, /qa, /qa-only, /design-review, /setup-browser-cookies, /retro, /debug, /document-release, and tells Claude that if gstack skills aren't working, run `cd .claude/skills/gstack && ./setup` to build the binary and register skills. +> Add gstack to this project: run **`cp -Rf ~/.claude/skills/gstack .claude/skills/gstack && rm -rf .claude/skills/gstack/.git && cd .claude/skills/gstack && ./setup`** then add a "gstack" section to this project's CLAUDE.md that says to use the /browse skill from gstack for all web browsing, never use mcp\_\_claude-in-chrome\_\_\* tools, lists the available skills: /office-hours, /plan-ceo-review, /plan-eng-review, /plan-design-review, /design-consultation, /review, /ship, /browse, /qa, /qa-only, /design-review, /setup-browser-cookies, /retro, /debug, /document-release, /codex, /careful, /freeze, /guard, /unfreeze, /gstack-upgrade, and tells Claude that if gstack skills aren't working, run `cd .claude/skills/gstack && ./setup` to build the binary and register skills. Real files get committed to your repo (not a submodule), so `git clone` just works. Everything lives inside `.claude/`. Nothing touches your PATH or runs in the background. @@ -127,6 +127,17 @@ One sprint, one person, one feature — that takes about 30 minutes with gstack. | `/browse` | **QA Engineer** | Give the agent eyes. Real Chromium browser, real clicks, real screenshots. ~100ms per command. | | `/setup-browser-cookies` | **Session Manager** | Import cookies from your real browser (Chrome, Arc, Brave, Edge) into the headless session. Test authenticated pages. | +### Power tools + +| Skill | What it does | +|-------|-------------| +| `/codex` | **Second Opinion** — independent code review from OpenAI Codex CLI. Three modes: review (pass/fail gate), adversarial challenge, and open consultation. Cross-model analysis when both `/review` and `/codex` have run. | +| `/careful` | **Safety Guardrails** — warns before destructive commands (rm -rf, DROP TABLE, force-push). Say "be careful" to activate. Override any warning. | +| `/freeze` | **Edit Lock** — restrict file edits to one directory. Prevents accidental changes outside scope while debugging. | +| `/guard` | **Full Safety** — `/careful` + `/freeze` in one command. Maximum safety for prod work. | +| `/unfreeze` | **Unlock** — remove the `/freeze` boundary. | +| `/gstack-upgrade` | **Self-Updater** — upgrade gstack to latest. Detects global vs vendored install, syncs both, shows what changed. | + **[Deep dives with examples and philosophy for every skill →](docs/skills.md)** ## What's new and why it matters @@ -141,7 +152,15 @@ One sprint, one person, one feature — that takes about 30 minutes with gstack. **Test everything.** `/ship` bootstraps test frameworks from scratch if your project doesn't have one. Every `/ship` run produces a coverage audit. Every `/qa` bug fix generates a regression test. 100% test coverage is the goal — tests make vibe coding safe instead of yolo coding. -**`/document-release` is the engineer you never had.** It reads every doc file in your project, cross-references the diff, and updates everything that drifted. README, ARCHITECTURE, CONTRIBUTING, CLAUDE.md, TODOS — all kept current automatically. +**`/document-release` is the engineer you never had.** It reads every doc file in your project, cross-references the diff, and updates everything that drifted. README, ARCHITECTURE, CONTRIBUTING, CLAUDE.md, TODOS — all kept current automatically. And now `/ship` auto-invokes it — docs stay current without an extra command. + +**Browser handoff when the AI gets stuck.** Hit a CAPTCHA, auth wall, or MFA prompt? `$B handoff` opens a visible Chrome at the exact same page with all your cookies and tabs intact. Solve the problem, tell Claude you're done, `$B resume` picks up right where it left off. The agent even suggests it automatically after 3 consecutive failures. + +**Multi-AI second opinion.** `/codex` gets an independent review from OpenAI's Codex CLI — a completely different AI looking at the same diff. Three modes: code review with a pass/fail gate, adversarial challenge that actively tries to break your code, and open consultation with session continuity. When both `/review` (Claude) and `/codex` (OpenAI) have reviewed the same branch, you get a cross-model analysis showing which findings overlap and which are unique to each. + +**Safety guardrails on demand.** Say "be careful" and `/careful` warns before any destructive command — rm -rf, DROP TABLE, force-push, git reset --hard. `/freeze` locks edits to one directory while debugging so Claude can't accidentally "fix" unrelated code. `/guard` activates both. `/debug` auto-freezes to the module being investigated. + +**Proactive skill suggestions.** gstack notices what stage you're in — brainstorming, reviewing, debugging, testing — and suggests the right skill. Don't like it? Say "stop suggesting" and it remembers across sessions. ## 10-15 parallel sprints @@ -163,7 +182,7 @@ Same tools, different outcome — because gstack gives you structured roles and The models are getting better fast. The people who figure out how to work with them now — really work with them, not just dabble — are going to have a massive advantage. This is that window. Let's go. -Fifteen specialists. All slash commands. All Markdown. All free. **[github.com/garrytan/gstack](https://github.com/garrytan/gstack)** — MIT License +Fifteen specialists and six power tools. All slash commands. All Markdown. All free. **[github.com/garrytan/gstack](https://github.com/garrytan/gstack)** — MIT License > **We're hiring.** Want to ship 10K+ LOC/day and help harden gstack? > Come work at YC — [ycombinator.com/software](https://ycombinator.com/software) @@ -194,7 +213,8 @@ Fifteen specialists. All slash commands. All Markdown. All free. **[github.com/g Use /browse from gstack for all web browsing. Never use mcp__claude-in-chrome__* tools. Available skills: /office-hours, /plan-ceo-review, /plan-eng-review, /plan-design-review, /design-consultation, /review, /ship, /browse, /qa, /qa-only, /design-review, -/setup-browser-cookies, /retro, /debug, /document-release. +/setup-browser-cookies, /retro, /debug, /document-release, /codex, /careful, +/freeze, /guard, /unfreeze, /gstack-upgrade. ``` ## License diff --git a/SKILL.md b/SKILL.md index afd90d1c..e6809b53 100644 --- a/SKILL.md +++ b/SKILL.md @@ -22,6 +22,12 @@ description: | - Ready to deploy / create PR → suggest /ship - Post-ship doc updates → suggest /document-release - Weekly retrospective → suggest /retro + - Wanting a second opinion or adversarial code review → suggest /codex + - Working with production or live systems → suggest /careful + - Want to scope edits to one module/directory → suggest /freeze + - Maximum safety mode (destructive warnings + edit restrictions) → suggest /guard + - Removing edit restrictions → suggest /unfreeze + - Upgrading gstack to latest version → suggest /gstack-upgrade If the user pushes back on skill suggestions ("stop suggesting things", "I don't need suggestions", "too aggressive"): diff --git a/SKILL.md.tmpl b/SKILL.md.tmpl index 68f18ce9..23f5973c 100644 --- a/SKILL.md.tmpl +++ b/SKILL.md.tmpl @@ -22,6 +22,12 @@ description: | - Ready to deploy / create PR → suggest /ship - Post-ship doc updates → suggest /document-release - Weekly retrospective → suggest /retro + - Wanting a second opinion or adversarial code review → suggest /codex + - Working with production or live systems → suggest /careful + - Want to scope edits to one module/directory → suggest /freeze + - Maximum safety mode (destructive warnings + edit restrictions) → suggest /guard + - Removing edit restrictions → suggest /unfreeze + - Upgrading gstack to latest version → suggest /gstack-upgrade If the user pushes back on skill suggestions ("stop suggesting things", "I don't need suggestions", "too aggressive"): diff --git a/TODOS.md b/TODOS.md index e77b8f47..472f202c 100644 --- a/TODOS.md +++ b/TODOS.md @@ -442,17 +442,9 @@ Shipped as v0.5.0 on main. Includes `/plan-design-review` (report-only design au ## Document-Release -### Auto-invoke /document-release from /ship +### Auto-invoke /document-release from /ship — SHIPPED -**What:** Add Step 8.5 to /ship that reads document-release/SKILL.md and executes the doc update workflow after creating the PR. - -**Why:** Zero-friction doc updates — user runs /ship and docs are automatically current. No extra command to remember. - -**Context:** /ship currently ends at Step 8 (PR URL output). Step 8.5 would continue into the document-release workflow. Same pattern as /ship calling /review's checklist in Step 3.5. - -**Effort:** S -**Priority:** P1 -**Depends on:** /document-release shipped +Shipped in v0.8.3. Step 8.5 added to `/ship` — after creating the PR, `/ship` automatically reads `document-release/SKILL.md` and executes the doc update workflow. Zero-friction doc updates. ### `{{DOC_VOICE}}` shared resolver diff --git a/VERSION b/VERSION index ee94dd83..b60d7196 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.8.3 +0.8.4 diff --git a/docs/skills.md b/docs/skills.md index a90f22d4..63ba1cfd 100644 --- a/docs/skills.md +++ b/docs/skills.md @@ -19,6 +19,16 @@ Detailed guides for every gstack skill — philosophy, workflow, and examples. | [`/retro`](#retro) | **Eng Manager** | Team-aware weekly retro. Per-person breakdowns, shipping streaks, test health trends, growth opportunities. | | [`/browse`](#browse) | **QA Engineer** | Give the agent eyes. Real Chromium browser, real clicks, real screenshots. ~100ms per command. | | [`/setup-browser-cookies`](#setup-browser-cookies) | **Session Manager** | Import cookies from your real browser (Chrome, Arc, Brave, Edge) into the headless session. Test authenticated pages. | +| | | | +| **Multi-AI** | | | +| [`/codex`](#codex) | **Second Opinion** | Independent review from OpenAI Codex CLI. Three modes: code review (pass/fail gate), adversarial challenge, and open consultation with session continuity. Cross-model analysis when both `/review` and `/codex` have run. | +| | | | +| **Safety & Utility** | | | +| [`/careful`](#safety--guardrails) | **Safety Guardrails** | Warns before destructive commands (rm -rf, DROP TABLE, force-push, git reset --hard). Override any warning. Common build cleanups whitelisted. | +| [`/freeze`](#safety--guardrails) | **Edit Lock** | Restrict all file edits to a single directory. Blocks Edit and Write outside the boundary. Accident prevention for debugging. | +| [`/guard`](#safety--guardrails) | **Full Safety** | Combines /careful + /freeze in one command. Maximum safety for prod work. | +| [`/unfreeze`](#safety--guardrails) | **Unlock** | Remove the /freeze boundary, allowing edits everywhere again. | +| [`/gstack-upgrade`](#gstack-upgrade) | **Self-Updater** | Upgrade gstack to the latest version. Detects global vs vendored install, syncs both, shows what changed. | --- @@ -616,6 +626,29 @@ Claude: [18 tool calls, ~60 seconds] 18 tool calls, about a minute. Full QA pass. No browser opened. +### Browser handoff + +When the headless browser gets stuck — CAPTCHA, MFA, complex auth — hand off to the user: + +``` +Claude: I'm stuck on a CAPTCHA at the login page. Opening a visible + Chrome so you can solve it. + + > browse handoff "Stuck on CAPTCHA at login page" + + Chrome opened at https://app.example.com/login with all your + cookies and tabs intact. Solve the CAPTCHA and tell me when + you're done. + +You: done + +Claude: > browse resume + + Got a fresh snapshot. Logged in successfully. Continuing QA. +``` + +The browser preserves all state (cookies, localStorage, tabs) across the handoff. After `resume`, the agent gets a fresh snapshot of wherever you left off. If the browse tool fails 3 times in a row, it automatically suggests using `handoff`. + **Security note:** `/browse` runs a persistent Chromium session. Cookies, localStorage, and session state carry over between commands. Do not use it against sensitive production environments unless you intend to — it is a real browser with real state. The session auto-shuts down after 30 minutes of idle time. For the full command reference, see [BROWSER.md](../BROWSER.md). @@ -653,6 +686,116 @@ Claude: Imported 12 cookies for github.com from Comet. --- +## `/codex` + +This is my **second opinion mode**. + +When `/review` catches bugs from Claude's perspective, `/codex` brings a completely different AI — OpenAI's Codex CLI — to review the same diff. Different training, different blind spots, different strengths. The overlap tells you what's definitely real. The unique findings from each are where you find the bugs neither would catch alone. + +### Three modes + +**Review** — run `codex review` against the current diff. Codex reads every changed file, classifies findings by severity (P1 critical, P2 high, P3 medium), and returns a PASS/FAIL verdict. Any P1 finding = FAIL. The review is fully independent — Codex doesn't see Claude's review. + +**Challenge** — adversarial mode. Codex actively tries to break your code. It looks for edge cases, race conditions, security holes, and assumptions that would fail under load. Uses maximum reasoning effort (`xhigh`). Think of it as a penetration test for your logic. + +**Consult** — open conversation with session continuity. Ask Codex anything about the codebase. Follow-up questions reuse the same session, so context carries over. Great for "am I thinking about this correctly?" moments. + +### Cross-model analysis + +When both `/review` (Claude) and `/codex` (OpenAI) have reviewed the same branch, you get a cross-model comparison: which findings overlap (high confidence), which are unique to Codex (different perspective), and which are unique to Claude. This is the "two doctors, same patient" approach to code review. + +``` +You: /codex review + +Claude: Running independent Codex review... + + CODEX REVIEW: PASS (3 findings) + [P2] Race condition in payment handler — concurrent charges + can double-debit without advisory lock + [P3] Missing null check on user.email before downcase + [P3] Token comparison not using constant-time compare + + Cross-model analysis (vs /review): + OVERLAP: Race condition in payment handler (both caught it) + UNIQUE TO CODEX: Token comparison timing attack + UNIQUE TO CLAUDE: N+1 query in listing photos +``` + +--- + +## Safety & Guardrails + +Four skills that add safety rails to any Claude Code session. They work via Claude Code's PreToolUse hooks — transparent, session-scoped, no configuration files. + +### `/careful` + +Say "be careful" or run `/careful` when you're working near production, running destructive commands, or just want a safety net. Every Bash command gets checked against known-dangerous patterns: + +- `rm -rf` / `rm -r` — recursive delete +- `DROP TABLE` / `DROP DATABASE` / `TRUNCATE` — data loss +- `git push --force` / `git push -f` — history rewrite +- `git reset --hard` — discard commits +- `git checkout .` / `git restore .` — discard uncommitted work +- `kubectl delete` — production resource deletion +- `docker rm -f` / `docker system prune` — container/image loss + +Common build artifact cleanups (`rm -rf node_modules`, `dist`, `.next`, `__pycache__`, `build`, `coverage`) are whitelisted — no false alarms on routine operations. + +You can override any warning. The guardrails are accident prevention, not access control. + +### `/freeze` + +Restrict all file edits to a single directory. When you're debugging a billing bug, you don't want Claude accidentally "fixing" unrelated code in `src/auth/`. `/freeze src/billing` blocks all Edit and Write operations outside that path. + +`/debug` activates this automatically — it detects the module being debugged and freezes edits to that directory. + +``` +You: /freeze src/billing + +Claude: Edits restricted to src/billing/. Run /unfreeze to remove. + + [Later, Claude tries to edit src/auth/middleware.ts] + +Claude: BLOCKED — Edit outside freeze boundary (src/billing/). + Skipping this change. +``` + +Note: this blocks Edit and Write tools only. Bash commands like `sed` can still modify files outside the boundary — it's accident prevention, not a security sandbox. + +### `/guard` + +Full safety mode — combines `/careful` + `/freeze` in one command. Destructive command warnings plus directory-scoped edits. Use when touching prod or debugging live systems. + +### `/unfreeze` + +Remove the `/freeze` boundary, allowing edits everywhere again. The hooks stay registered for the session — they just allow everything. Run `/freeze` again to set a new boundary. + +--- + +## `/gstack-upgrade` + +Keep gstack current with one command. It detects your install type (global at `~/.claude/skills/gstack` vs vendored in your project at `.claude/skills/gstack`), runs the upgrade, syncs both copies if you have dual installs, and shows you what changed. + +``` +You: /gstack-upgrade + +Claude: Current version: 0.7.4 + Latest version: 0.8.2 + + What's new: + - Browse handoff for CAPTCHAs and auth walls + - /codex multi-AI second opinion + - /qa always uses browser now + - Safety skills: /careful, /freeze, /guard + - Proactive skill suggestions + + Upgraded to 0.8.2. Both global and project installs synced. +``` + +Set `auto_upgrade: true` in `~/.gstack/config.yaml` to skip the prompt entirely — gstack upgrades silently at the start of each session when a new version is available. + +--- + ## Greptile integration [Greptile](https://greptile.com) is a YC company that reviews your PRs automatically. It catches real bugs — race conditions, security issues, things that pass CI and blow up in production. It has genuinely saved my ass more than once. I love these guys. diff --git a/ship/SKILL.md b/ship/SKILL.md index 7bc9d758..a6727a04 100644 --- a/ship/SKILL.md +++ b/ship/SKILL.md @@ -1036,7 +1036,28 @@ EOF )" ``` -**Output the PR URL** — this should be the final output the user sees. +**Output the PR URL** — then proceed to Step 8.5. + +--- + +## Step 8.5: Auto-invoke /document-release + +After the PR is created, automatically sync project documentation. Read the +`document-release/SKILL.md` skill file (adjacent to this skill's directory) and +execute its full workflow: + +1. Read the `/document-release` skill: `cat ${CLAUDE_SKILL_DIR}/../document-release/SKILL.md` +2. Follow its instructions — it reads all .md files in the project, cross-references + the diff, and updates anything that drifted (README, ARCHITECTURE, CONTRIBUTING, + CLAUDE.md, TODOS, etc.) +3. If any docs were updated, commit the changes and push to the same branch: + ```bash + git add -A && git commit -m "docs: sync documentation with shipped changes" && git push + ``` +4. If no docs needed updating, say "Documentation is current — no updates needed." + +This step is automatic. Do not ask the user for confirmation. The goal is zero-friction +doc updates — the user runs `/ship` and documentation stays current without a separate command. --- @@ -1053,4 +1074,4 @@ EOF - **Use Greptile reply templates from greptile-triage.md.** Every reply includes evidence (inline diff, code references, re-rank suggestion). Never post vague replies. - **Never push without fresh verification evidence.** If code changed after Step 3 tests, re-run before pushing. - **Step 3.4 generates coverage tests.** They must pass before committing. Never commit failing tests. -- **The goal is: user says `/ship`, next thing they see is the review + PR URL.** +- **The goal is: user says `/ship`, next thing they see is the review + PR URL + auto-synced docs.** diff --git a/ship/SKILL.md.tmpl b/ship/SKILL.md.tmpl index bbc03fa6..4274e9c8 100644 --- a/ship/SKILL.md.tmpl +++ b/ship/SKILL.md.tmpl @@ -653,7 +653,28 @@ EOF )" ``` -**Output the PR URL** — this should be the final output the user sees. +**Output the PR URL** — then proceed to Step 8.5. + +--- + +## Step 8.5: Auto-invoke /document-release + +After the PR is created, automatically sync project documentation. Read the +`document-release/SKILL.md` skill file (adjacent to this skill's directory) and +execute its full workflow: + +1. Read the `/document-release` skill: `cat ${CLAUDE_SKILL_DIR}/../document-release/SKILL.md` +2. Follow its instructions — it reads all .md files in the project, cross-references + the diff, and updates anything that drifted (README, ARCHITECTURE, CONTRIBUTING, + CLAUDE.md, TODOS, etc.) +3. If any docs were updated, commit the changes and push to the same branch: + ```bash + git add -A && git commit -m "docs: sync documentation with shipped changes" && git push + ``` +4. If no docs needed updating, say "Documentation is current — no updates needed." + +This step is automatic. Do not ask the user for confirmation. The goal is zero-friction +doc updates — the user runs `/ship` and documentation stays current without a separate command. --- @@ -670,4 +691,4 @@ EOF - **Use Greptile reply templates from greptile-triage.md.** Every reply includes evidence (inline diff, code references, re-rank suggestion). Never post vague replies. - **Never push without fresh verification evidence.** If code changed after Step 3 tests, re-run before pushing. - **Step 3.4 generates coverage tests.** They must pass before committing. Never commit failing tests. -- **The goal is: user says `/ship`, next thing they see is the review + PR URL.** +- **The goal is: user says `/ship`, next thing they see is the review + PR URL + auto-synced docs.**