From dbd98aff32e3e68f4976dcc38e76a007a2c4a08a Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Sat, 21 Mar 2026 16:55:47 -0700 Subject: [PATCH 1/2] feat: harden /office-hours diagnostic rigor (v0.9.9.0) (#307) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: harden /office-hours diagnostic rigor — anti-sycophancy + pushback patterns Address user feedback that gstack compromises toward founder input while dbs-diagnosis maintains strict self-consistency. Five changes: 1. Hardened Response Posture — "direct to discomfort" replaces "not cruel" 2. Anti-Sycophancy Rules — banned phrases + evidence-based position-taking 3. Pushback Patterns — 5 worked BAD/GOOD examples for common founder evasions 4. Post-Q1 Framing Check — challenges language precision and hidden assumptions 5. Gated Escape Hatch — 2 more questions before skip, double-refusal respected Co-Authored-By: Claude Opus 4.6 (1M context) * chore: bump version and changelog (v0.9.9.0) Co-Authored-By: Claude Opus 4.6 (1M context) --------- Co-authored-by: Claude Opus 4.6 (1M context) --- .agents/skills/gstack-office-hours/SKILL.md | 60 +++++++++++++++++++-- CHANGELOG.md | 6 +++ VERSION | 2 +- office-hours/SKILL.md | 60 +++++++++++++++++++-- office-hours/SKILL.md.tmpl | 60 +++++++++++++++++++-- 5 files changed, 178 insertions(+), 10 deletions(-) diff --git a/.agents/skills/gstack-office-hours/SKILL.md b/.agents/skills/gstack-office-hours/SKILL.md index c464c88c..955f4400 100644 --- a/.agents/skills/gstack-office-hours/SKILL.md +++ b/.agents/skills/gstack-office-hours/SKILL.md @@ -330,12 +330,54 @@ These are non-negotiable. They shape every response in this mode. ### Response Posture -- **Be direct, not cruel.** The goal is clarity, not demolition. But don't soften a hard truth into uselessness. "That's a red flag" is more useful than "that's something to think about." +- **Be direct to the point of discomfort.** Comfort means you haven't pushed hard enough. Your job is diagnosis, not encouragement. Save warmth for the closing — during the diagnostic, take a position on every answer and state what evidence would change your mind. - **Push once, then push again.** The first answer to any of these questions is usually the polished version. The real answer comes after the second or third push. "You said 'enterprises in healthcare.' Can you name one specific person at one specific company?" -- **Praise specificity when it shows up.** When a founder gives a genuinely specific, evidence-based answer, acknowledge it. That's hard to do and it matters. +- **Calibrated acknowledgment, not praise.** When a founder gives a specific, evidence-based answer, name what was good and pivot to a harder question: "That's the most specific demand evidence in this session — a customer calling you when it broke. Let's see if your wedge is equally sharp." Don't linger. The best reward for a good answer is a harder follow-up. - **Name common failure patterns.** If you recognize a common failure mode — "solution in search of a problem," "hypothetical users," "waiting to launch until it's perfect," "assuming interest equals demand" — name it directly. - **End with the assignment.** Every session should produce one concrete thing the founder should do next. Not a strategy — an action. +### Anti-Sycophancy Rules + +**Never say these during the diagnostic (Phases 2-5):** +- "That's an interesting approach" — take a position instead +- "There are many ways to think about this" — pick one and state what evidence would change your mind +- "You might want to consider..." — say "This is wrong because..." or "This works because..." +- "That could work" — say whether it WILL work based on the evidence you have, and what evidence is missing +- "I can see why you'd think that" — if they're wrong, say they're wrong and why + +**Always do:** +- Take a position on every answer. State your position AND what evidence would change it. This is rigor — not hedging, not fake certainty. +- Challenge the strongest version of the founder's claim, not a strawman. + +### Pushback Patterns — How to Push + +These examples show the difference between soft exploration and rigorous diagnosis: + +**Pattern 1: Vague market → force specificity** +- Founder: "I'm building an AI tool for developers" +- BAD: "That's a big market! Let's explore what kind of tool." +- GOOD: "There are 10,000 AI developer tools right now. What specific task does a specific developer currently waste 2+ hours on per week that your tool eliminates? Name the person." + +**Pattern 2: Social proof → demand test** +- Founder: "Everyone I've talked to loves the idea" +- BAD: "That's encouraging! Who specifically have you talked to?" +- GOOD: "Loving an idea is free. Has anyone offered to pay? Has anyone asked when it ships? Has anyone gotten angry when your prototype broke? Love is not demand." + +**Pattern 3: Platform vision → wedge challenge** +- Founder: "We need to build the full platform before anyone can really use it" +- BAD: "What would a stripped-down version look like?" +- GOOD: "That's a red flag. If no one can get value from a smaller version, it usually means the value proposition isn't clear yet — not that the product needs to be bigger. What's the one thing a user would pay for this week?" + +**Pattern 4: Growth stats → vision test** +- Founder: "The market is growing 20% year over year" +- BAD: "That's a strong tailwind. How do you plan to capture that growth?" +- GOOD: "Growth rate is not a vision. Every competitor in your space can cite the same stat. What's YOUR thesis about how this market changes in a way that makes YOUR product more essential?" + +**Pattern 5: Undefined terms → precision demand** +- Founder: "We want to make onboarding more seamless" +- BAD: "What does your current onboarding flow look like?" +- GOOD: "'Seamless' is not a product feature — it's a feeling. What specific step in onboarding causes users to drop off? What's the drop-off rate? Have you watched someone go through it?" + ### The Six Forcing Questions Ask these questions **ONE AT A TIME** via AskUserQuestion. Push on each one until the answer is specific, evidence-based, and uncomfortable. Comfort means the founder hasn't gone deep enough. @@ -356,6 +398,13 @@ Ask these questions **ONE AT A TIME** via AskUserQuestion. Push on each one unti **Red flags:** "People say it's interesting." "We got 500 waitlist signups." "VCs are excited about the space." None of these are demand. +**After the founder's first answer to Q1**, check their framing before continuing: +1. **Language precision:** Are the key terms in their answer defined? If they said "AI space," "seamless experience," "better platform" — challenge: "What do you mean by [term]? Can you define it so I could measure it?" +2. **Hidden assumptions:** What does their framing take for granted? "I need to raise money" assumes capital is required. "The market needs this" assumes verified pull. Name one assumption and ask if it's verified. +3. **Real vs. hypothetical:** Is there evidence of actual pain, or is this a thought experiment? "I think developers would want..." is hypothetical. "Three developers at my last company spent 10 hours a week on this" is real. + +If the framing is imprecise, **reframe constructively** — don't dissolve the question. Say: "Let me try restating what I think you're actually building: [reframe]. Does that capture it better?" Then proceed with the corrected framing. This takes 60 seconds, not 10 minutes. + #### Q2: Status Quo **Ask:** "What are your users doing right now to solve this problem — even badly? What does that workaround cost them?" @@ -406,7 +455,12 @@ Ask these questions **ONE AT A TIME** via AskUserQuestion. Push on each one unti **STOP** after each question. Wait for the response before asking the next. -**Escape hatch:** If the user says "just do it," expresses impatience, or provides a fully formed plan → fast-track to Phase 4 (Alternatives Generation). If user provides a fully formed plan, skip Phase 2 entirely but still run Phase 3 and Phase 4. +**Escape hatch:** If the user expresses impatience ("just do it," "skip the questions"): +- Say: "I hear you. But the hard questions are the value — skipping them is like skipping the exam and going straight to the prescription. Let me ask two more, then we'll move." +- Consult the smart routing table for the founder's product stage. Ask the 2 most critical remaining questions from that stage's list, then proceed to Phase 3. +- If the user pushes back a second time, respect it — proceed to Phase 3 immediately. Don't ask a third time. +- If only 1 question remains, ask it. If 0 remain, proceed directly. +- Only allow a FULL skip (no additional questions) if the user provides a fully formed plan with real evidence — existing users, revenue numbers, specific customer names. Even then, still run Phase 3 (Premise Challenge) and Phase 4 (Alternatives). --- diff --git a/CHANGELOG.md b/CHANGELOG.md index 31c1fbf1..1d88f8d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [0.9.9.0] - 2026-03-21 — Harder Office Hours + +### Changed + +- **`/office-hours` now pushes back harder.** The diagnostic questions no longer soften toward confident founders. Five changes: hardened response posture ("direct to the point of discomfort"), anti-sycophancy rules (banned phrases like "that's an interesting approach"), 5 worked pushback patterns showing BAD vs GOOD responses, a post-Q1 framing check that challenges undefined terms and hidden assumptions, and a gated escape hatch that asks 2 more questions before letting founders skip. Inspired by user feedback comparing gstack with dontbesilent's diagnostic skill. + ## [0.9.8.0] - 2026-03-21 — Deploy Pipeline + E2E Performance ### Added diff --git a/VERSION b/VERSION index 68f4aad3..94688c2a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.9.8.0 +0.9.9.0 diff --git a/office-hours/SKILL.md b/office-hours/SKILL.md index 218fe133..37c772c1 100644 --- a/office-hours/SKILL.md +++ b/office-hours/SKILL.md @@ -340,12 +340,54 @@ These are non-negotiable. They shape every response in this mode. ### Response Posture -- **Be direct, not cruel.** The goal is clarity, not demolition. But don't soften a hard truth into uselessness. "That's a red flag" is more useful than "that's something to think about." +- **Be direct to the point of discomfort.** Comfort means you haven't pushed hard enough. Your job is diagnosis, not encouragement. Save warmth for the closing — during the diagnostic, take a position on every answer and state what evidence would change your mind. - **Push once, then push again.** The first answer to any of these questions is usually the polished version. The real answer comes after the second or third push. "You said 'enterprises in healthcare.' Can you name one specific person at one specific company?" -- **Praise specificity when it shows up.** When a founder gives a genuinely specific, evidence-based answer, acknowledge it. That's hard to do and it matters. +- **Calibrated acknowledgment, not praise.** When a founder gives a specific, evidence-based answer, name what was good and pivot to a harder question: "That's the most specific demand evidence in this session — a customer calling you when it broke. Let's see if your wedge is equally sharp." Don't linger. The best reward for a good answer is a harder follow-up. - **Name common failure patterns.** If you recognize a common failure mode — "solution in search of a problem," "hypothetical users," "waiting to launch until it's perfect," "assuming interest equals demand" — name it directly. - **End with the assignment.** Every session should produce one concrete thing the founder should do next. Not a strategy — an action. +### Anti-Sycophancy Rules + +**Never say these during the diagnostic (Phases 2-5):** +- "That's an interesting approach" — take a position instead +- "There are many ways to think about this" — pick one and state what evidence would change your mind +- "You might want to consider..." — say "This is wrong because..." or "This works because..." +- "That could work" — say whether it WILL work based on the evidence you have, and what evidence is missing +- "I can see why you'd think that" — if they're wrong, say they're wrong and why + +**Always do:** +- Take a position on every answer. State your position AND what evidence would change it. This is rigor — not hedging, not fake certainty. +- Challenge the strongest version of the founder's claim, not a strawman. + +### Pushback Patterns — How to Push + +These examples show the difference between soft exploration and rigorous diagnosis: + +**Pattern 1: Vague market → force specificity** +- Founder: "I'm building an AI tool for developers" +- BAD: "That's a big market! Let's explore what kind of tool." +- GOOD: "There are 10,000 AI developer tools right now. What specific task does a specific developer currently waste 2+ hours on per week that your tool eliminates? Name the person." + +**Pattern 2: Social proof → demand test** +- Founder: "Everyone I've talked to loves the idea" +- BAD: "That's encouraging! Who specifically have you talked to?" +- GOOD: "Loving an idea is free. Has anyone offered to pay? Has anyone asked when it ships? Has anyone gotten angry when your prototype broke? Love is not demand." + +**Pattern 3: Platform vision → wedge challenge** +- Founder: "We need to build the full platform before anyone can really use it" +- BAD: "What would a stripped-down version look like?" +- GOOD: "That's a red flag. If no one can get value from a smaller version, it usually means the value proposition isn't clear yet — not that the product needs to be bigger. What's the one thing a user would pay for this week?" + +**Pattern 4: Growth stats → vision test** +- Founder: "The market is growing 20% year over year" +- BAD: "That's a strong tailwind. How do you plan to capture that growth?" +- GOOD: "Growth rate is not a vision. Every competitor in your space can cite the same stat. What's YOUR thesis about how this market changes in a way that makes YOUR product more essential?" + +**Pattern 5: Undefined terms → precision demand** +- Founder: "We want to make onboarding more seamless" +- BAD: "What does your current onboarding flow look like?" +- GOOD: "'Seamless' is not a product feature — it's a feeling. What specific step in onboarding causes users to drop off? What's the drop-off rate? Have you watched someone go through it?" + ### The Six Forcing Questions Ask these questions **ONE AT A TIME** via AskUserQuestion. Push on each one until the answer is specific, evidence-based, and uncomfortable. Comfort means the founder hasn't gone deep enough. @@ -366,6 +408,13 @@ Ask these questions **ONE AT A TIME** via AskUserQuestion. Push on each one unti **Red flags:** "People say it's interesting." "We got 500 waitlist signups." "VCs are excited about the space." None of these are demand. +**After the founder's first answer to Q1**, check their framing before continuing: +1. **Language precision:** Are the key terms in their answer defined? If they said "AI space," "seamless experience," "better platform" — challenge: "What do you mean by [term]? Can you define it so I could measure it?" +2. **Hidden assumptions:** What does their framing take for granted? "I need to raise money" assumes capital is required. "The market needs this" assumes verified pull. Name one assumption and ask if it's verified. +3. **Real vs. hypothetical:** Is there evidence of actual pain, or is this a thought experiment? "I think developers would want..." is hypothetical. "Three developers at my last company spent 10 hours a week on this" is real. + +If the framing is imprecise, **reframe constructively** — don't dissolve the question. Say: "Let me try restating what I think you're actually building: [reframe]. Does that capture it better?" Then proceed with the corrected framing. This takes 60 seconds, not 10 minutes. + #### Q2: Status Quo **Ask:** "What are your users doing right now to solve this problem — even badly? What does that workaround cost them?" @@ -416,7 +465,12 @@ Ask these questions **ONE AT A TIME** via AskUserQuestion. Push on each one unti **STOP** after each question. Wait for the response before asking the next. -**Escape hatch:** If the user says "just do it," expresses impatience, or provides a fully formed plan → fast-track to Phase 4 (Alternatives Generation). If user provides a fully formed plan, skip Phase 2 entirely but still run Phase 3 and Phase 4. +**Escape hatch:** If the user expresses impatience ("just do it," "skip the questions"): +- Say: "I hear you. But the hard questions are the value — skipping them is like skipping the exam and going straight to the prescription. Let me ask two more, then we'll move." +- Consult the smart routing table for the founder's product stage. Ask the 2 most critical remaining questions from that stage's list, then proceed to Phase 3. +- If the user pushes back a second time, respect it — proceed to Phase 3 immediately. Don't ask a third time. +- If only 1 question remains, ask it. If 0 remain, proceed directly. +- Only allow a FULL skip (no additional questions) if the user provides a fully formed plan with real evidence — existing users, revenue numbers, specific customer names. Even then, still run Phase 3 (Premise Challenge) and Phase 4 (Alternatives). --- diff --git a/office-hours/SKILL.md.tmpl b/office-hours/SKILL.md.tmpl index 7dbc6d32..33d673c1 100644 --- a/office-hours/SKILL.md.tmpl +++ b/office-hours/SKILL.md.tmpl @@ -99,12 +99,54 @@ These are non-negotiable. They shape every response in this mode. ### Response Posture -- **Be direct, not cruel.** The goal is clarity, not demolition. But don't soften a hard truth into uselessness. "That's a red flag" is more useful than "that's something to think about." +- **Be direct to the point of discomfort.** Comfort means you haven't pushed hard enough. Your job is diagnosis, not encouragement. Save warmth for the closing — during the diagnostic, take a position on every answer and state what evidence would change your mind. - **Push once, then push again.** The first answer to any of these questions is usually the polished version. The real answer comes after the second or third push. "You said 'enterprises in healthcare.' Can you name one specific person at one specific company?" -- **Praise specificity when it shows up.** When a founder gives a genuinely specific, evidence-based answer, acknowledge it. That's hard to do and it matters. +- **Calibrated acknowledgment, not praise.** When a founder gives a specific, evidence-based answer, name what was good and pivot to a harder question: "That's the most specific demand evidence in this session — a customer calling you when it broke. Let's see if your wedge is equally sharp." Don't linger. The best reward for a good answer is a harder follow-up. - **Name common failure patterns.** If you recognize a common failure mode — "solution in search of a problem," "hypothetical users," "waiting to launch until it's perfect," "assuming interest equals demand" — name it directly. - **End with the assignment.** Every session should produce one concrete thing the founder should do next. Not a strategy — an action. +### Anti-Sycophancy Rules + +**Never say these during the diagnostic (Phases 2-5):** +- "That's an interesting approach" — take a position instead +- "There are many ways to think about this" — pick one and state what evidence would change your mind +- "You might want to consider..." — say "This is wrong because..." or "This works because..." +- "That could work" — say whether it WILL work based on the evidence you have, and what evidence is missing +- "I can see why you'd think that" — if they're wrong, say they're wrong and why + +**Always do:** +- Take a position on every answer. State your position AND what evidence would change it. This is rigor — not hedging, not fake certainty. +- Challenge the strongest version of the founder's claim, not a strawman. + +### Pushback Patterns — How to Push + +These examples show the difference between soft exploration and rigorous diagnosis: + +**Pattern 1: Vague market → force specificity** +- Founder: "I'm building an AI tool for developers" +- BAD: "That's a big market! Let's explore what kind of tool." +- GOOD: "There are 10,000 AI developer tools right now. What specific task does a specific developer currently waste 2+ hours on per week that your tool eliminates? Name the person." + +**Pattern 2: Social proof → demand test** +- Founder: "Everyone I've talked to loves the idea" +- BAD: "That's encouraging! Who specifically have you talked to?" +- GOOD: "Loving an idea is free. Has anyone offered to pay? Has anyone asked when it ships? Has anyone gotten angry when your prototype broke? Love is not demand." + +**Pattern 3: Platform vision → wedge challenge** +- Founder: "We need to build the full platform before anyone can really use it" +- BAD: "What would a stripped-down version look like?" +- GOOD: "That's a red flag. If no one can get value from a smaller version, it usually means the value proposition isn't clear yet — not that the product needs to be bigger. What's the one thing a user would pay for this week?" + +**Pattern 4: Growth stats → vision test** +- Founder: "The market is growing 20% year over year" +- BAD: "That's a strong tailwind. How do you plan to capture that growth?" +- GOOD: "Growth rate is not a vision. Every competitor in your space can cite the same stat. What's YOUR thesis about how this market changes in a way that makes YOUR product more essential?" + +**Pattern 5: Undefined terms → precision demand** +- Founder: "We want to make onboarding more seamless" +- BAD: "What does your current onboarding flow look like?" +- GOOD: "'Seamless' is not a product feature — it's a feeling. What specific step in onboarding causes users to drop off? What's the drop-off rate? Have you watched someone go through it?" + ### The Six Forcing Questions Ask these questions **ONE AT A TIME** via AskUserQuestion. Push on each one until the answer is specific, evidence-based, and uncomfortable. Comfort means the founder hasn't gone deep enough. @@ -125,6 +167,13 @@ Ask these questions **ONE AT A TIME** via AskUserQuestion. Push on each one unti **Red flags:** "People say it's interesting." "We got 500 waitlist signups." "VCs are excited about the space." None of these are demand. +**After the founder's first answer to Q1**, check their framing before continuing: +1. **Language precision:** Are the key terms in their answer defined? If they said "AI space," "seamless experience," "better platform" — challenge: "What do you mean by [term]? Can you define it so I could measure it?" +2. **Hidden assumptions:** What does their framing take for granted? "I need to raise money" assumes capital is required. "The market needs this" assumes verified pull. Name one assumption and ask if it's verified. +3. **Real vs. hypothetical:** Is there evidence of actual pain, or is this a thought experiment? "I think developers would want..." is hypothetical. "Three developers at my last company spent 10 hours a week on this" is real. + +If the framing is imprecise, **reframe constructively** — don't dissolve the question. Say: "Let me try restating what I think you're actually building: [reframe]. Does that capture it better?" Then proceed with the corrected framing. This takes 60 seconds, not 10 minutes. + #### Q2: Status Quo **Ask:** "What are your users doing right now to solve this problem — even badly? What does that workaround cost them?" @@ -175,7 +224,12 @@ Ask these questions **ONE AT A TIME** via AskUserQuestion. Push on each one unti **STOP** after each question. Wait for the response before asking the next. -**Escape hatch:** If the user says "just do it," expresses impatience, or provides a fully formed plan → fast-track to Phase 4 (Alternatives Generation). If user provides a fully formed plan, skip Phase 2 entirely but still run Phase 3 and Phase 4. +**Escape hatch:** If the user expresses impatience ("just do it," "skip the questions"): +- Say: "I hear you. But the hard questions are the value — skipping them is like skipping the exam and going straight to the prescription. Let me ask two more, then we'll move." +- Consult the smart routing table for the founder's product stage. Ask the 2 most critical remaining questions from that stage's list, then proceed to Phase 3. +- If the user pushes back a second time, respect it — proceed to Phase 3 immediately. Don't ask a third time. +- If only 1 question remains, ask it. If 0 remain, proceed directly. +- Only allow a FULL skip (no additional questions) if the user provides a fully formed plan with real evidence — existing users, revenue numbers, specific customer names. Even then, still run Phase 3 (Premise Challenge) and Phase 4 (Alternatives). --- From 407b15692073dfd8aaff13e755d99a6022ff8ae5 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Sun, 22 Mar 2026 10:21:52 -0700 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20/autoplan=20=E2=80=94=20auto-review?= =?UTF-8?q?=20pipeline=20(v0.10.0.0)=20(#327)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: /autoplan skill — auto-review pipeline with decision audit trail Thin orchestrator that reads CEO, design, and eng review skills from disk and runs them at full depth with auto-decisions using 6 encoded principles. Surfaces taste decisions at a final approval gate. * chore: wire /autoplan into routing, touchfiles, and validation tests * chore: bump version and changelog (v0.10.0.0) Co-Authored-By: Claude Opus 4.6 --------- Co-authored-by: Claude Opus 4.6 --- .agents/skills/gstack-autoplan/SKILL.md | 535 +++++++++++++++++++++++ .agents/skills/gstack/SKILL.md | 1 + CHANGELOG.md | 6 + SKILL.md | 1 + SKILL.md.tmpl | 1 + VERSION | 2 +- autoplan/SKILL.md | 546 ++++++++++++++++++++++++ autoplan/SKILL.md.tmpl | 288 +++++++++++++ test/helpers/touchfiles.ts | 3 + test/skill-validation.test.ts | 14 + test/touchfiles.test.ts | 5 +- 11 files changed, 1399 insertions(+), 3 deletions(-) create mode 100644 .agents/skills/gstack-autoplan/SKILL.md create mode 100644 autoplan/SKILL.md create mode 100644 autoplan/SKILL.md.tmpl diff --git a/.agents/skills/gstack-autoplan/SKILL.md b/.agents/skills/gstack-autoplan/SKILL.md new file mode 100644 index 00000000..6c2535e7 --- /dev/null +++ b/.agents/skills/gstack-autoplan/SKILL.md @@ -0,0 +1,535 @@ +--- +name: autoplan +description: | + Auto-review pipeline — reads the full CEO, design, and eng review skills from disk + and runs them sequentially with auto-decisions using 6 decision principles. Surfaces + taste decisions (close approaches, borderline scope, codex disagreements) at a final + approval gate. One command, fully reviewed plan out. + Use when asked to "auto review", "autoplan", "run all reviews", "review this plan + automatically", or "make the decisions for me". + Proactively suggest when the user has a plan file and wants to run the full review + gauntlet without answering 15-30 intermediate questions. +--- + + + +## Preamble (run first) + +```bash +_UPD=$(~/.codex/skills/gstack/bin/gstack-update-check 2>/dev/null || .agents/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=$(~/.codex/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.codex/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") +echo "BRANCH: $_BRANCH" +echo "PROACTIVE: $_PROACTIVE" +_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") +echo "LAKE_INTRO: $_LAKE_SEEN" +_TEL=$(~/.codex/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") +_TEL_START=$(date +%s) +_SESSION_ID="$$-$(date +%s)" +echo "TELEMETRY: ${_TEL:-off}" +echo "TEL_PROMPTED: $_TEL_PROMPTED" +mkdir -p ~/.gstack/analytics +echo '{"skill":"autoplan","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.codex/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +``` + +If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke +them when the user explicitly asks. The user opted out of proactive suggestions. + +If output shows `UPGRADE_AVAILABLE `: read `~/.codex/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 `: 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. + +If `TEL_PROMPTED` is `no` AND `LAKE_INTRO` is `yes`: After the lake intro is handled, +ask the user about telemetry. Use AskUserQuestion: + +> Help gstack get better! Community mode shares usage data (which skills you use, how long +> they take, crash info) with a stable device ID so we can track trends and fix bugs faster. +> No code, file paths, or repo names are ever sent. +> Change anytime with `gstack-config set telemetry off`. + +Options: +- A) Help gstack get better! (recommended) +- B) No thanks + +If A: run `~/.codex/skills/gstack/bin/gstack-config set telemetry community` + +If B: ask a follow-up AskUserQuestion: + +> How about anonymous mode? We just learn that *someone* used gstack — no unique ID, +> no way to connect sessions. Just a counter that helps us know if anyone's out there. + +Options: +- A) Sure, anonymous is fine +- B) No thanks, fully off + +If B→A: run `~/.codex/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.codex/skills/gstack/bin/gstack-config set telemetry off` + +Always run: +```bash +touch ~/.gstack/.telemetry-prompted +``` + +This only happens once. If `TEL_PROMPTED` is `yes`, skip this entirely. + +## 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.") + +## Search Before Building + +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.codex/skills/gstack/ETHOS.md` for the full philosophy. + +**Three layers of knowledge:** +- **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. +- **Layer 2** (new and popular — search for these). But scrutinize: humans are subject to mania. Search results are inputs to your thinking, not answers. +- **Layer 3** (first principles — prize these above all). Original observations derived from reasoning about the specific problem. The most valuable of all. + +**Eureka moment:** When first-principles reasoning reveals conventional wisdom is wrong, name it: +"EUREKA: Everyone does X because [assumption]. But [evidence] shows this is wrong. Y is better because [reasoning]." + +Log eureka moments: +```bash +jq -n --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg branch "$(git branch --show-current 2>/dev/null)" --arg insight "ONE_LINE_SUMMARY" '{ts:$ts,skill:$skill,branch:$branch,insight:$insight}' >> ~/.gstack/analytics/eureka.jsonl 2>/dev/null || true +``` +Replace SKILL_NAME and ONE_LINE_SUMMARY. Runs inline — don't stop the workflow. + +**WebSearch fallback:** If WebSearch is unavailable, skip the search step and note: "Search unavailable — proceeding with in-distribution knowledge only." + +## 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}" + +## Completion Status Protocol + +When completing a skill workflow, report status using one of: +- **DONE** — All steps completed successfully. Evidence provided for each claim. +- **DONE_WITH_CONCERNS** — Completed, but with issues the user should know about. List each concern. +- **BLOCKED** — Cannot proceed. State what is blocking and what was tried. +- **NEEDS_CONTEXT** — Missing information required to continue. State exactly what you need. + +### Escalation + +It is always OK to stop and say "this is too hard for me" or "I'm not confident in this result." + +Bad work is worse than no work. You will not be penalized for escalating. +- If you have attempted a task 3 times without success, STOP and escalate. +- If you are uncertain about a security-sensitive change, STOP and escalate. +- If the scope of work exceeds what you can verify, STOP and escalate. + +Escalation format: +``` +STATUS: BLOCKED | NEEDS_CONTEXT +REASON: [1-2 sentences] +ATTEMPTED: [what you tried] +RECOMMENDATION: [what the user should do next] +``` + +## Telemetry (run last) + +After the skill workflow completes (success, error, or abort), log the telemetry event. +Determine the skill name from the `name:` field in this file's YAML frontmatter. +Determine the outcome from the workflow result (success if completed normally, error +if it failed, abort if the user interrupted). + +**PLAN MODE EXCEPTION — ALWAYS RUN:** This command writes telemetry to +`~/.gstack/analytics/` (user config directory, not project files). The skill +preamble already writes to the same directory — this is the same pattern. +Skipping this command loses session duration and outcome data. + +Run this bash: + +```bash +_TEL_END=$(date +%s) +_TEL_DUR=$(( _TEL_END - _TEL_START )) +rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true +~/.codex/skills/gstack/bin/gstack-telemetry-log \ + --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ + --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & +``` + +Replace `SKILL_NAME` with the actual skill name from frontmatter, `OUTCOME` with +success/error/abort, and `USED_BROWSE` with true/false based on whether `$B` was used. +If you cannot determine the outcome, use "unknown". This runs in the background and +never blocks the user. + +## Step 0: Detect base branch + +Determine which branch this PR targets. Use the result as "the base branch" in all subsequent steps. + +1. Check if a PR already exists for this branch: + `gh pr view --json baseRefName -q .baseRefName` + If this succeeds, use the printed branch name as the base branch. + +2. If no PR exists (command fails), detect the repo's default branch: + `gh repo view --json defaultBranchRef -q .defaultBranchRef.name` + +3. If both commands fail, fall back to `main`. + +Print the detected base branch name. In every subsequent `git diff`, `git log`, +`git fetch`, `git merge`, and `gh pr create` command, substitute the detected +branch name wherever the instructions say "the base branch." + +--- + +## Prerequisite Skill Offer + +When the design doc check above prints "No design doc found," offer the prerequisite +skill before proceeding. + +Say to the user via AskUserQuestion: + +> "No design doc found for this branch. `/office-hours` produces a structured problem +> statement, premise challenge, and explored alternatives — it gives this review much +> sharper input to work with. Takes about 10 minutes. The design doc is per-feature, +> not per-product — it captures the thinking behind this specific change." + +Options: +- A) Run /office-hours first (in another window, then come back) +- B) Skip — proceed with standard review + +If they skip: "No worries — standard review. If you ever want sharper input, try +/office-hours first next time." Then proceed normally. Do not re-offer later in the session. + +# /autoplan — Auto-Review Pipeline + +One command. Rough plan in, fully reviewed plan out. + +/autoplan reads the full CEO, design, and eng review skill files from disk and follows +them at full depth — same rigor, same sections, same methodology as running each skill +manually. The only difference: intermediate AskUserQuestion calls are auto-decided using +the 6 principles below. Taste decisions (where reasonable people could disagree) are +surfaced at a final approval gate. + +--- + +## The 6 Decision Principles + +These rules auto-answer every intermediate question: + +1. **Choose completeness** — Ship the whole thing. Pick the approach that covers more edge cases. +2. **Boil lakes** — Fix everything in the blast radius (files modified by this plan + direct importers). Auto-approve expansions that are in blast radius AND < 1 day CC effort (< 5 files, no new infra). +3. **Pragmatic** — If two options fix the same thing, pick the cleaner one. 5 seconds choosing, not 5 minutes. +4. **DRY** — Duplicates existing functionality? Reject. Reuse what exists. +5. **Explicit over clever** — 10-line obvious fix > 200-line abstraction. Pick what a new contributor reads in 30 seconds. +6. **Bias toward action** — Merge > review cycles > stale deliberation. Flag concerns but don't block. + +**Conflict resolution (context-dependent tiebreakers):** +- **CEO phase:** P1 (completeness) + P2 (boil lakes) dominate. +- **Eng phase:** P5 (explicit) + P3 (pragmatic) dominate. +- **Design phase:** P5 (explicit) + P1 (completeness) dominate. + +--- + +## Decision Classification + +Every auto-decision is classified: + +**Mechanical** — one clearly right answer. Auto-decide silently. +Examples: run codex (always yes), run evals (always yes), reduce scope on a complete plan (always no). + +**Taste** — reasonable people could disagree. Auto-decide with recommendation, but surface at the final gate. Three natural sources: +1. **Close approaches** — top two are both viable with different tradeoffs. +2. **Borderline scope** — in blast radius but 3-5 files, or ambiguous radius. +3. **Codex disagreements** — codex recommends differently and has a valid point. + +--- + +## Phase 0: Intake + Restore Point + +### Step 1: Capture restore point + +Before doing anything, save the plan file's current state to an external file: + +```bash +source <(~/.codex/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG +BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-') +DATETIME=$(date +%Y%m%d-%H%M%S) +echo "RESTORE_PATH=$HOME/.gstack/projects/$SLUG/${BRANCH}-autoplan-restore-${DATETIME}.md" +``` + +Write the plan file's full contents to the restore path with this header: +``` +# /autoplan Restore Point +Captured: [timestamp] | Branch: [branch] | Commit: [short hash] + +## Re-run Instructions +1. Copy "Original Plan State" below back to your plan file +2. Invoke /autoplan + +## Original Plan State +[verbatim plan file contents] +``` + +Then prepend a one-line HTML comment to the plan file: +`` + +### Step 2: Read context + +- Read CLAUDE.md, TODOS.md, git log -30, git diff against the base branch --stat +- Discover design docs: `ls -t ~/.gstack/projects/$SLUG/*-design-*.md 2>/dev/null | head -1` +- Detect UI scope: grep the plan for view/rendering terms (component, screen, form, + button, modal, layout, dashboard, sidebar, nav, dialog). Require 2+ matches. Exclude + false positives ("page" alone, "UI" in acronyms). + +### Step 3: Load skill files from disk + +Read each file using the Read tool: +- `~/.codex/skills/gstack/plan-ceo-review/SKILL.md` +- `~/.codex/skills/gstack/plan-design-review/SKILL.md` (only if UI scope detected) +- `~/.codex/skills/gstack/plan-eng-review/SKILL.md` + +**Section skip list — when following a loaded skill file, SKIP these sections +(they are already handled by /autoplan):** +- Preamble (run first) +- AskUserQuestion Format +- Completeness Principle — Boil the Lake +- Search Before Building +- Contributor Mode +- Completion Status Protocol +- Telemetry (run last) +- Step 0: Detect base branch +- Review Readiness Dashboard +- Plan File Review Report +- Prerequisite Skill Offer (BENEFITS_FROM) + +Follow ONLY the review-specific methodology, sections, and required outputs. + +Output: "Here's what I'm working with: [plan summary]. UI scope: [yes/no]. +Loaded review skills from disk. Starting full review pipeline with auto-decisions." + +--- + +## Phase 1: CEO Review (Strategy & Scope) + +Follow plan-ceo-review/SKILL.md — all sections, full depth. +Override: every AskUserQuestion → auto-decide using the 6 principles. + +**Override rules:** +- Mode selection: SELECTIVE EXPANSION +- Premises: accept reasonable ones (P6), challenge only clearly wrong ones +- **GATE: Present premises to user for confirmation** — this is the ONE AskUserQuestion + that is NOT auto-decided. Premises require human judgment. +- Alternatives: pick highest completeness (P1). If tied, pick simplest (P5). + If top 2 are close → mark TASTE DECISION. +- Scope expansion: in blast radius + <1d CC → approve (P2). Outside → defer to TODOS.md (P3). + Duplicates → reject (P4). Borderline (3-5 files) → mark TASTE DECISION. +- All 10 review sections: run fully, auto-decide each issue, log every decision. + +--- + +## Phase 2: Design Review (conditional — skip if no UI scope) + +Follow plan-design-review/SKILL.md — all 7 dimensions, full depth. +Override: every AskUserQuestion → auto-decide using the 6 principles. + +**Override rules:** +- Focus areas: all relevant dimensions (P1) +- Structural issues (missing states, broken hierarchy): auto-fix (P5) +- Aesthetic/taste issues: mark TASTE DECISION +- Design system alignment: auto-fix if DESIGN.md exists and fix is obvious + +--- + +## Phase 3: Eng Review + Codex + +Follow plan-eng-review/SKILL.md — all sections, full depth. +Override: every AskUserQuestion → auto-decide using the 6 principles. + +**Override rules:** +- Scope challenge: never reduce (P2) +- Codex review: always run if available (P6) + Command: `codex exec "Review this plan for architectural issues, missing edge cases, and hidden complexity. Be adversarial. File: " -s read-only --enable web_search_cached` + Timeout: 10 minutes, then proceed with "Codex timed out — single-reviewer mode" +- Architecture choices: explicit over clever (P5). If codex disagrees with valid reason → TASTE DECISION. +- Evals: always include all relevant suites (P1) +- Test plan: generate artifact at `~/.gstack/projects/$SLUG/{user}-{branch}-test-plan-{datetime}.md` +- TODOS.md: collect all deferred scope expansions from Phase 1, auto-write + +--- + +## Decision Audit Trail + +After each auto-decision, append a row to the plan file using Edit: + +```markdown + +## Decision Audit Trail + +| # | Phase | Decision | Principle | Rationale | Rejected | +|---|-------|----------|-----------|-----------|----------| +``` + +Write one row per decision incrementally (via Edit). This keeps the audit on disk, +not accumulated in conversation context. + +--- + +## Phase 4: Final Approval Gate + +**STOP here and present the final state to the user.** + +Present as a message, then use AskUserQuestion: + +``` +## /autoplan Review Complete + +### Plan Summary +[1-3 sentence summary] + +### Decisions Made: [N] total ([M] auto-decided, [K] choices for you) + +### Your Choices (taste decisions) +[For each taste decision:] +**Choice [N]: [title]** (from [phase]) +I recommend [X] — [principle]. But [Y] is also viable: + [1-sentence downstream impact if you pick Y] + +### Auto-Decided: [M] decisions [see Decision Audit Trail in plan file] + +### Review Scores +- CEO: [summary] +- Design: [summary or "skipped, no UI scope"] +- Eng: [summary] +- Codex: [summary or "unavailable"] + +### Deferred to TODOS.md +[Items auto-deferred with reasons] +``` + +**Cognitive load management:** +- 0 taste decisions: skip "Your Choices" section +- 1-7 taste decisions: flat list +- 8+: group by phase. Add warning: "This plan had unusually high ambiguity ([N] taste decisions). Review carefully." + +AskUserQuestion options: +- A) Approve as-is (accept all recommendations) +- B) Approve with overrides (specify which taste decisions to change) +- C) Interrogate (ask about any specific decision) +- D) Revise (the plan itself needs changes) +- E) Reject (start over) + +**Option handling:** +- A: mark APPROVED, write review logs, suggest /ship +- B: ask which overrides, apply, re-present gate +- C: answer freeform, re-present gate +- D: make changes, re-run affected phases (scope→1B, design→2, test plan→3, arch→3). Max 3 cycles. +- E: start over + +--- + +## Completion: Write Review Logs + +On approval, write 3 separate review log entries so /ship's dashboard recognizes them: + +```bash +COMMIT=$(git rev-parse --short HEAD 2>/dev/null) +TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ) + +~/.codex/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"mode":"SELECTIVE_EXPANSION","via":"autoplan","commit":"'"$COMMIT"'"}' + +~/.codex/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"issues_found":0,"mode":"FULL_REVIEW","via":"autoplan","commit":"'"$COMMIT"'"}' +``` + +If Phase 2 ran (UI scope): +```bash +~/.codex/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"via":"autoplan","commit":"'"$COMMIT"'"}' +``` + +Replace field values with actual counts from the review. + +Suggest next step: `/ship` when ready to create the PR. + +--- + +## Important Rules + +- **Never abort.** The user chose /autoplan. Respect that choice. Surface all taste decisions, never redirect to interactive review. +- **Premises are the one gate.** The only non-auto-decided AskUserQuestion is the premise confirmation in Phase 1. +- **Log every decision.** No silent auto-decisions. Every choice gets a row in the audit trail. +- **Full depth.** Do not compress or skip sections from the loaded skill files (except the skip list in Phase 0). +- **Sequential order.** CEO → Design → Eng. Each phase builds on the last. diff --git a/.agents/skills/gstack/SKILL.md b/.agents/skills/gstack/SKILL.md index 93128866..e7c19582 100644 --- a/.agents/skills/gstack/SKILL.md +++ b/.agents/skills/gstack/SKILL.md @@ -13,6 +13,7 @@ description: | - Reviewing a plan (strategy) → suggest /plan-ceo-review - Reviewing a plan (architecture) → suggest /plan-eng-review - Reviewing a plan (design) → suggest /plan-design-review + - Auto-reviewing a plan (all reviews at once) → suggest /autoplan - Creating a design system → suggest /design-consultation - Debugging errors → suggest /investigate - Testing the app → suggest /qa diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d88f8d8..7eea57d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [0.10.0.0] - 2026-03-22 — Autoplan + +### Added + +- **`/autoplan` — one command, fully reviewed plan.** Hand it a rough plan and it runs the full CEO → design → eng review pipeline automatically. Reads the actual review skill files from disk (same depth, same rigor as running each review manually) and makes intermediate decisions using 6 encoded principles: completeness, boil lakes, pragmatic, DRY, explicit over clever, bias toward action. Taste decisions (close approaches, borderline scope, codex disagreements) surface at a final approval gate. You approve, override, interrogate, or revise. Saves a restore point so you can re-run from scratch. Writes review logs compatible with `/ship`'s dashboard. + ## [0.9.9.0] - 2026-03-21 — Harder Office Hours ### Changed diff --git a/SKILL.md b/SKILL.md index d8e51bd1..ee84d736 100644 --- a/SKILL.md +++ b/SKILL.md @@ -14,6 +14,7 @@ description: | - Reviewing a plan (strategy) → suggest /plan-ceo-review - Reviewing a plan (architecture) → suggest /plan-eng-review - Reviewing a plan (design) → suggest /plan-design-review + - Auto-reviewing a plan (all reviews at once) → suggest /autoplan - Creating a design system → suggest /design-consultation - Debugging errors → suggest /investigate - Testing the app → suggest /qa diff --git a/SKILL.md.tmpl b/SKILL.md.tmpl index 0c985965..0c7105fb 100644 --- a/SKILL.md.tmpl +++ b/SKILL.md.tmpl @@ -14,6 +14,7 @@ description: | - Reviewing a plan (strategy) → suggest /plan-ceo-review - Reviewing a plan (architecture) → suggest /plan-eng-review - Reviewing a plan (design) → suggest /plan-design-review + - Auto-reviewing a plan (all reviews at once) → suggest /autoplan - Creating a design system → suggest /design-consultation - Debugging errors → suggest /investigate - Testing the app → suggest /qa diff --git a/VERSION b/VERSION index 94688c2a..b8d6a6d7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.9.9.0 +0.10.0.0 diff --git a/autoplan/SKILL.md b/autoplan/SKILL.md new file mode 100644 index 00000000..a2c74061 --- /dev/null +++ b/autoplan/SKILL.md @@ -0,0 +1,546 @@ +--- +name: autoplan +version: 1.0.0 +description: | + Auto-review pipeline — reads the full CEO, design, and eng review skills from disk + and runs them sequentially with auto-decisions using 6 decision principles. Surfaces + taste decisions (close approaches, borderline scope, codex disagreements) at a final + approval gate. One command, fully reviewed plan out. + Use when asked to "auto review", "autoplan", "run all reviews", "review this plan + automatically", or "make the decisions for me". + Proactively suggest when the user has a plan file and wants to run the full review + gauntlet without answering 15-30 intermediate questions. +benefits-from: [office-hours] +allowed-tools: + - Bash + - Read + - Write + - Edit + - Glob + - Grep + - WebSearch + - AskUserQuestion +--- + + + +## Preamble (run first) + +```bash +_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) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") +echo "BRANCH: $_BRANCH" +echo "PROACTIVE: $_PROACTIVE" +_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") +echo "LAKE_INTRO: $_LAKE_SEEN" +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") +_TEL_START=$(date +%s) +_SESSION_ID="$$-$(date +%s)" +echo "TELEMETRY: ${_TEL:-off}" +echo "TEL_PROMPTED: $_TEL_PROMPTED" +mkdir -p ~/.gstack/analytics +echo '{"skill":"autoplan","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +``` + +If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke +them when the user explicitly asks. The user opted out of proactive suggestions. + +If output shows `UPGRADE_AVAILABLE `: 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 `: 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. + +If `TEL_PROMPTED` is `no` AND `LAKE_INTRO` is `yes`: After the lake intro is handled, +ask the user about telemetry. Use AskUserQuestion: + +> Help gstack get better! Community mode shares usage data (which skills you use, how long +> they take, crash info) with a stable device ID so we can track trends and fix bugs faster. +> No code, file paths, or repo names are ever sent. +> Change anytime with `gstack-config set telemetry off`. + +Options: +- A) Help gstack get better! (recommended) +- B) No thanks + +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` + +If B: ask a follow-up AskUserQuestion: + +> How about anonymous mode? We just learn that *someone* used gstack — no unique ID, +> no way to connect sessions. Just a counter that helps us know if anyone's out there. + +Options: +- A) Sure, anonymous is fine +- B) No thanks, fully off + +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` + +Always run: +```bash +touch ~/.gstack/.telemetry-prompted +``` + +This only happens once. If `TEL_PROMPTED` is `yes`, skip this entirely. + +## 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.") + +## Search Before Building + +Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — **search first.** Read `~/.claude/skills/gstack/ETHOS.md` for the full philosophy. + +**Three layers of knowledge:** +- **Layer 1** (tried and true — in distribution). Don't reinvent the wheel. But the cost of checking is near-zero, and once in a while, questioning the tried-and-true is where brilliance occurs. +- **Layer 2** (new and popular — search for these). But scrutinize: humans are subject to mania. Search results are inputs to your thinking, not answers. +- **Layer 3** (first principles — prize these above all). Original observations derived from reasoning about the specific problem. The most valuable of all. + +**Eureka moment:** When first-principles reasoning reveals conventional wisdom is wrong, name it: +"EUREKA: Everyone does X because [assumption]. But [evidence] shows this is wrong. Y is better because [reasoning]." + +Log eureka moments: +```bash +jq -n --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg branch "$(git branch --show-current 2>/dev/null)" --arg insight "ONE_LINE_SUMMARY" '{ts:$ts,skill:$skill,branch:$branch,insight:$insight}' >> ~/.gstack/analytics/eureka.jsonl 2>/dev/null || true +``` +Replace SKILL_NAME and ONE_LINE_SUMMARY. Runs inline — don't stop the workflow. + +**WebSearch fallback:** If WebSearch is unavailable, skip the search step and note: "Search unavailable — proceeding with in-distribution knowledge only." + +## 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}" + +## Completion Status Protocol + +When completing a skill workflow, report status using one of: +- **DONE** — All steps completed successfully. Evidence provided for each claim. +- **DONE_WITH_CONCERNS** — Completed, but with issues the user should know about. List each concern. +- **BLOCKED** — Cannot proceed. State what is blocking and what was tried. +- **NEEDS_CONTEXT** — Missing information required to continue. State exactly what you need. + +### Escalation + +It is always OK to stop and say "this is too hard for me" or "I'm not confident in this result." + +Bad work is worse than no work. You will not be penalized for escalating. +- If you have attempted a task 3 times without success, STOP and escalate. +- If you are uncertain about a security-sensitive change, STOP and escalate. +- If the scope of work exceeds what you can verify, STOP and escalate. + +Escalation format: +``` +STATUS: BLOCKED | NEEDS_CONTEXT +REASON: [1-2 sentences] +ATTEMPTED: [what you tried] +RECOMMENDATION: [what the user should do next] +``` + +## Telemetry (run last) + +After the skill workflow completes (success, error, or abort), log the telemetry event. +Determine the skill name from the `name:` field in this file's YAML frontmatter. +Determine the outcome from the workflow result (success if completed normally, error +if it failed, abort if the user interrupted). + +**PLAN MODE EXCEPTION — ALWAYS RUN:** This command writes telemetry to +`~/.gstack/analytics/` (user config directory, not project files). The skill +preamble already writes to the same directory — this is the same pattern. +Skipping this command loses session duration and outcome data. + +Run this bash: + +```bash +_TEL_END=$(date +%s) +_TEL_DUR=$(( _TEL_END - _TEL_START )) +rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true +~/.claude/skills/gstack/bin/gstack-telemetry-log \ + --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ + --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & +``` + +Replace `SKILL_NAME` with the actual skill name from frontmatter, `OUTCOME` with +success/error/abort, and `USED_BROWSE` with true/false based on whether `$B` was used. +If you cannot determine the outcome, use "unknown". This runs in the background and +never blocks the user. + +## Step 0: Detect base branch + +Determine which branch this PR targets. Use the result as "the base branch" in all subsequent steps. + +1. Check if a PR already exists for this branch: + `gh pr view --json baseRefName -q .baseRefName` + If this succeeds, use the printed branch name as the base branch. + +2. If no PR exists (command fails), detect the repo's default branch: + `gh repo view --json defaultBranchRef -q .defaultBranchRef.name` + +3. If both commands fail, fall back to `main`. + +Print the detected base branch name. In every subsequent `git diff`, `git log`, +`git fetch`, `git merge`, and `gh pr create` command, substitute the detected +branch name wherever the instructions say "the base branch." + +--- + +## Prerequisite Skill Offer + +When the design doc check above prints "No design doc found," offer the prerequisite +skill before proceeding. + +Say to the user via AskUserQuestion: + +> "No design doc found for this branch. `/office-hours` produces a structured problem +> statement, premise challenge, and explored alternatives — it gives this review much +> sharper input to work with. Takes about 10 minutes. The design doc is per-feature, +> not per-product — it captures the thinking behind this specific change." + +Options: +- A) Run /office-hours first (in another window, then come back) +- B) Skip — proceed with standard review + +If they skip: "No worries — standard review. If you ever want sharper input, try +/office-hours first next time." Then proceed normally. Do not re-offer later in the session. + +# /autoplan — Auto-Review Pipeline + +One command. Rough plan in, fully reviewed plan out. + +/autoplan reads the full CEO, design, and eng review skill files from disk and follows +them at full depth — same rigor, same sections, same methodology as running each skill +manually. The only difference: intermediate AskUserQuestion calls are auto-decided using +the 6 principles below. Taste decisions (where reasonable people could disagree) are +surfaced at a final approval gate. + +--- + +## The 6 Decision Principles + +These rules auto-answer every intermediate question: + +1. **Choose completeness** — Ship the whole thing. Pick the approach that covers more edge cases. +2. **Boil lakes** — Fix everything in the blast radius (files modified by this plan + direct importers). Auto-approve expansions that are in blast radius AND < 1 day CC effort (< 5 files, no new infra). +3. **Pragmatic** — If two options fix the same thing, pick the cleaner one. 5 seconds choosing, not 5 minutes. +4. **DRY** — Duplicates existing functionality? Reject. Reuse what exists. +5. **Explicit over clever** — 10-line obvious fix > 200-line abstraction. Pick what a new contributor reads in 30 seconds. +6. **Bias toward action** — Merge > review cycles > stale deliberation. Flag concerns but don't block. + +**Conflict resolution (context-dependent tiebreakers):** +- **CEO phase:** P1 (completeness) + P2 (boil lakes) dominate. +- **Eng phase:** P5 (explicit) + P3 (pragmatic) dominate. +- **Design phase:** P5 (explicit) + P1 (completeness) dominate. + +--- + +## Decision Classification + +Every auto-decision is classified: + +**Mechanical** — one clearly right answer. Auto-decide silently. +Examples: run codex (always yes), run evals (always yes), reduce scope on a complete plan (always no). + +**Taste** — reasonable people could disagree. Auto-decide with recommendation, but surface at the final gate. Three natural sources: +1. **Close approaches** — top two are both viable with different tradeoffs. +2. **Borderline scope** — in blast radius but 3-5 files, or ambiguous radius. +3. **Codex disagreements** — codex recommends differently and has a valid point. + +--- + +## Phase 0: Intake + Restore Point + +### Step 1: Capture restore point + +Before doing anything, save the plan file's current state to an external file: + +```bash +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG +BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-') +DATETIME=$(date +%Y%m%d-%H%M%S) +echo "RESTORE_PATH=$HOME/.gstack/projects/$SLUG/${BRANCH}-autoplan-restore-${DATETIME}.md" +``` + +Write the plan file's full contents to the restore path with this header: +``` +# /autoplan Restore Point +Captured: [timestamp] | Branch: [branch] | Commit: [short hash] + +## Re-run Instructions +1. Copy "Original Plan State" below back to your plan file +2. Invoke /autoplan + +## Original Plan State +[verbatim plan file contents] +``` + +Then prepend a one-line HTML comment to the plan file: +`` + +### Step 2: Read context + +- Read CLAUDE.md, TODOS.md, git log -30, git diff against the base branch --stat +- Discover design docs: `ls -t ~/.gstack/projects/$SLUG/*-design-*.md 2>/dev/null | head -1` +- Detect UI scope: grep the plan for view/rendering terms (component, screen, form, + button, modal, layout, dashboard, sidebar, nav, dialog). Require 2+ matches. Exclude + false positives ("page" alone, "UI" in acronyms). + +### Step 3: Load skill files from disk + +Read each file using the Read tool: +- `~/.claude/skills/gstack/plan-ceo-review/SKILL.md` +- `~/.claude/skills/gstack/plan-design-review/SKILL.md` (only if UI scope detected) +- `~/.claude/skills/gstack/plan-eng-review/SKILL.md` + +**Section skip list — when following a loaded skill file, SKIP these sections +(they are already handled by /autoplan):** +- Preamble (run first) +- AskUserQuestion Format +- Completeness Principle — Boil the Lake +- Search Before Building +- Contributor Mode +- Completion Status Protocol +- Telemetry (run last) +- Step 0: Detect base branch +- Review Readiness Dashboard +- Plan File Review Report +- Prerequisite Skill Offer (BENEFITS_FROM) + +Follow ONLY the review-specific methodology, sections, and required outputs. + +Output: "Here's what I'm working with: [plan summary]. UI scope: [yes/no]. +Loaded review skills from disk. Starting full review pipeline with auto-decisions." + +--- + +## Phase 1: CEO Review (Strategy & Scope) + +Follow plan-ceo-review/SKILL.md — all sections, full depth. +Override: every AskUserQuestion → auto-decide using the 6 principles. + +**Override rules:** +- Mode selection: SELECTIVE EXPANSION +- Premises: accept reasonable ones (P6), challenge only clearly wrong ones +- **GATE: Present premises to user for confirmation** — this is the ONE AskUserQuestion + that is NOT auto-decided. Premises require human judgment. +- Alternatives: pick highest completeness (P1). If tied, pick simplest (P5). + If top 2 are close → mark TASTE DECISION. +- Scope expansion: in blast radius + <1d CC → approve (P2). Outside → defer to TODOS.md (P3). + Duplicates → reject (P4). Borderline (3-5 files) → mark TASTE DECISION. +- All 10 review sections: run fully, auto-decide each issue, log every decision. + +--- + +## Phase 2: Design Review (conditional — skip if no UI scope) + +Follow plan-design-review/SKILL.md — all 7 dimensions, full depth. +Override: every AskUserQuestion → auto-decide using the 6 principles. + +**Override rules:** +- Focus areas: all relevant dimensions (P1) +- Structural issues (missing states, broken hierarchy): auto-fix (P5) +- Aesthetic/taste issues: mark TASTE DECISION +- Design system alignment: auto-fix if DESIGN.md exists and fix is obvious + +--- + +## Phase 3: Eng Review + Codex + +Follow plan-eng-review/SKILL.md — all sections, full depth. +Override: every AskUserQuestion → auto-decide using the 6 principles. + +**Override rules:** +- Scope challenge: never reduce (P2) +- Codex review: always run if available (P6) + Command: `codex exec "Review this plan for architectural issues, missing edge cases, and hidden complexity. Be adversarial. File: " -s read-only --enable web_search_cached` + Timeout: 10 minutes, then proceed with "Codex timed out — single-reviewer mode" +- Architecture choices: explicit over clever (P5). If codex disagrees with valid reason → TASTE DECISION. +- Evals: always include all relevant suites (P1) +- Test plan: generate artifact at `~/.gstack/projects/$SLUG/{user}-{branch}-test-plan-{datetime}.md` +- TODOS.md: collect all deferred scope expansions from Phase 1, auto-write + +--- + +## Decision Audit Trail + +After each auto-decision, append a row to the plan file using Edit: + +```markdown + +## Decision Audit Trail + +| # | Phase | Decision | Principle | Rationale | Rejected | +|---|-------|----------|-----------|-----------|----------| +``` + +Write one row per decision incrementally (via Edit). This keeps the audit on disk, +not accumulated in conversation context. + +--- + +## Phase 4: Final Approval Gate + +**STOP here and present the final state to the user.** + +Present as a message, then use AskUserQuestion: + +``` +## /autoplan Review Complete + +### Plan Summary +[1-3 sentence summary] + +### Decisions Made: [N] total ([M] auto-decided, [K] choices for you) + +### Your Choices (taste decisions) +[For each taste decision:] +**Choice [N]: [title]** (from [phase]) +I recommend [X] — [principle]. But [Y] is also viable: + [1-sentence downstream impact if you pick Y] + +### Auto-Decided: [M] decisions [see Decision Audit Trail in plan file] + +### Review Scores +- CEO: [summary] +- Design: [summary or "skipped, no UI scope"] +- Eng: [summary] +- Codex: [summary or "unavailable"] + +### Deferred to TODOS.md +[Items auto-deferred with reasons] +``` + +**Cognitive load management:** +- 0 taste decisions: skip "Your Choices" section +- 1-7 taste decisions: flat list +- 8+: group by phase. Add warning: "This plan had unusually high ambiguity ([N] taste decisions). Review carefully." + +AskUserQuestion options: +- A) Approve as-is (accept all recommendations) +- B) Approve with overrides (specify which taste decisions to change) +- C) Interrogate (ask about any specific decision) +- D) Revise (the plan itself needs changes) +- E) Reject (start over) + +**Option handling:** +- A: mark APPROVED, write review logs, suggest /ship +- B: ask which overrides, apply, re-present gate +- C: answer freeform, re-present gate +- D: make changes, re-run affected phases (scope→1B, design→2, test plan→3, arch→3). Max 3 cycles. +- E: start over + +--- + +## Completion: Write Review Logs + +On approval, write 3 separate review log entries so /ship's dashboard recognizes them: + +```bash +COMMIT=$(git rev-parse --short HEAD 2>/dev/null) +TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ) + +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"mode":"SELECTIVE_EXPANSION","via":"autoplan","commit":"'"$COMMIT"'"}' + +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"issues_found":0,"mode":"FULL_REVIEW","via":"autoplan","commit":"'"$COMMIT"'"}' +``` + +If Phase 2 ran (UI scope): +```bash +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"via":"autoplan","commit":"'"$COMMIT"'"}' +``` + +Replace field values with actual counts from the review. + +Suggest next step: `/ship` when ready to create the PR. + +--- + +## Important Rules + +- **Never abort.** The user chose /autoplan. Respect that choice. Surface all taste decisions, never redirect to interactive review. +- **Premises are the one gate.** The only non-auto-decided AskUserQuestion is the premise confirmation in Phase 1. +- **Log every decision.** No silent auto-decisions. Every choice gets a row in the audit trail. +- **Full depth.** Do not compress or skip sections from the loaded skill files (except the skip list in Phase 0). +- **Sequential order.** CEO → Design → Eng. Each phase builds on the last. diff --git a/autoplan/SKILL.md.tmpl b/autoplan/SKILL.md.tmpl new file mode 100644 index 00000000..0e467a9e --- /dev/null +++ b/autoplan/SKILL.md.tmpl @@ -0,0 +1,288 @@ +--- +name: autoplan +version: 1.0.0 +description: | + Auto-review pipeline — reads the full CEO, design, and eng review skills from disk + and runs them sequentially with auto-decisions using 6 decision principles. Surfaces + taste decisions (close approaches, borderline scope, codex disagreements) at a final + approval gate. One command, fully reviewed plan out. + Use when asked to "auto review", "autoplan", "run all reviews", "review this plan + automatically", or "make the decisions for me". + Proactively suggest when the user has a plan file and wants to run the full review + gauntlet without answering 15-30 intermediate questions. +benefits-from: [office-hours] +allowed-tools: + - Bash + - Read + - Write + - Edit + - Glob + - Grep + - WebSearch + - AskUserQuestion +--- + +{{PREAMBLE}} + +{{BASE_BRANCH_DETECT}} + +{{BENEFITS_FROM}} + +# /autoplan — Auto-Review Pipeline + +One command. Rough plan in, fully reviewed plan out. + +/autoplan reads the full CEO, design, and eng review skill files from disk and follows +them at full depth — same rigor, same sections, same methodology as running each skill +manually. The only difference: intermediate AskUserQuestion calls are auto-decided using +the 6 principles below. Taste decisions (where reasonable people could disagree) are +surfaced at a final approval gate. + +--- + +## The 6 Decision Principles + +These rules auto-answer every intermediate question: + +1. **Choose completeness** — Ship the whole thing. Pick the approach that covers more edge cases. +2. **Boil lakes** — Fix everything in the blast radius (files modified by this plan + direct importers). Auto-approve expansions that are in blast radius AND < 1 day CC effort (< 5 files, no new infra). +3. **Pragmatic** — If two options fix the same thing, pick the cleaner one. 5 seconds choosing, not 5 minutes. +4. **DRY** — Duplicates existing functionality? Reject. Reuse what exists. +5. **Explicit over clever** — 10-line obvious fix > 200-line abstraction. Pick what a new contributor reads in 30 seconds. +6. **Bias toward action** — Merge > review cycles > stale deliberation. Flag concerns but don't block. + +**Conflict resolution (context-dependent tiebreakers):** +- **CEO phase:** P1 (completeness) + P2 (boil lakes) dominate. +- **Eng phase:** P5 (explicit) + P3 (pragmatic) dominate. +- **Design phase:** P5 (explicit) + P1 (completeness) dominate. + +--- + +## Decision Classification + +Every auto-decision is classified: + +**Mechanical** — one clearly right answer. Auto-decide silently. +Examples: run codex (always yes), run evals (always yes), reduce scope on a complete plan (always no). + +**Taste** — reasonable people could disagree. Auto-decide with recommendation, but surface at the final gate. Three natural sources: +1. **Close approaches** — top two are both viable with different tradeoffs. +2. **Borderline scope** — in blast radius but 3-5 files, or ambiguous radius. +3. **Codex disagreements** — codex recommends differently and has a valid point. + +--- + +## Phase 0: Intake + Restore Point + +### Step 1: Capture restore point + +Before doing anything, save the plan file's current state to an external file: + +```bash +source <(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null) && mkdir -p ~/.gstack/projects/$SLUG +BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-') +DATETIME=$(date +%Y%m%d-%H%M%S) +echo "RESTORE_PATH=$HOME/.gstack/projects/$SLUG/${BRANCH}-autoplan-restore-${DATETIME}.md" +``` + +Write the plan file's full contents to the restore path with this header: +``` +# /autoplan Restore Point +Captured: [timestamp] | Branch: [branch] | Commit: [short hash] + +## Re-run Instructions +1. Copy "Original Plan State" below back to your plan file +2. Invoke /autoplan + +## Original Plan State +[verbatim plan file contents] +``` + +Then prepend a one-line HTML comment to the plan file: +`` + +### Step 2: Read context + +- Read CLAUDE.md, TODOS.md, git log -30, git diff against the base branch --stat +- Discover design docs: `ls -t ~/.gstack/projects/$SLUG/*-design-*.md 2>/dev/null | head -1` +- Detect UI scope: grep the plan for view/rendering terms (component, screen, form, + button, modal, layout, dashboard, sidebar, nav, dialog). Require 2+ matches. Exclude + false positives ("page" alone, "UI" in acronyms). + +### Step 3: Load skill files from disk + +Read each file using the Read tool: +- `~/.claude/skills/gstack/plan-ceo-review/SKILL.md` +- `~/.claude/skills/gstack/plan-design-review/SKILL.md` (only if UI scope detected) +- `~/.claude/skills/gstack/plan-eng-review/SKILL.md` + +**Section skip list — when following a loaded skill file, SKIP these sections +(they are already handled by /autoplan):** +- Preamble (run first) +- AskUserQuestion Format +- Completeness Principle — Boil the Lake +- Search Before Building +- Contributor Mode +- Completion Status Protocol +- Telemetry (run last) +- Step 0: Detect base branch +- Review Readiness Dashboard +- Plan File Review Report +- Prerequisite Skill Offer (BENEFITS_FROM) + +Follow ONLY the review-specific methodology, sections, and required outputs. + +Output: "Here's what I'm working with: [plan summary]. UI scope: [yes/no]. +Loaded review skills from disk. Starting full review pipeline with auto-decisions." + +--- + +## Phase 1: CEO Review (Strategy & Scope) + +Follow plan-ceo-review/SKILL.md — all sections, full depth. +Override: every AskUserQuestion → auto-decide using the 6 principles. + +**Override rules:** +- Mode selection: SELECTIVE EXPANSION +- Premises: accept reasonable ones (P6), challenge only clearly wrong ones +- **GATE: Present premises to user for confirmation** — this is the ONE AskUserQuestion + that is NOT auto-decided. Premises require human judgment. +- Alternatives: pick highest completeness (P1). If tied, pick simplest (P5). + If top 2 are close → mark TASTE DECISION. +- Scope expansion: in blast radius + <1d CC → approve (P2). Outside → defer to TODOS.md (P3). + Duplicates → reject (P4). Borderline (3-5 files) → mark TASTE DECISION. +- All 10 review sections: run fully, auto-decide each issue, log every decision. + +--- + +## Phase 2: Design Review (conditional — skip if no UI scope) + +Follow plan-design-review/SKILL.md — all 7 dimensions, full depth. +Override: every AskUserQuestion → auto-decide using the 6 principles. + +**Override rules:** +- Focus areas: all relevant dimensions (P1) +- Structural issues (missing states, broken hierarchy): auto-fix (P5) +- Aesthetic/taste issues: mark TASTE DECISION +- Design system alignment: auto-fix if DESIGN.md exists and fix is obvious + +--- + +## Phase 3: Eng Review + Codex + +Follow plan-eng-review/SKILL.md — all sections, full depth. +Override: every AskUserQuestion → auto-decide using the 6 principles. + +**Override rules:** +- Scope challenge: never reduce (P2) +- Codex review: always run if available (P6) + Command: `codex exec "Review this plan for architectural issues, missing edge cases, and hidden complexity. Be adversarial. File: " -s read-only --enable web_search_cached` + Timeout: 10 minutes, then proceed with "Codex timed out — single-reviewer mode" +- Architecture choices: explicit over clever (P5). If codex disagrees with valid reason → TASTE DECISION. +- Evals: always include all relevant suites (P1) +- Test plan: generate artifact at `~/.gstack/projects/$SLUG/{user}-{branch}-test-plan-{datetime}.md` +- TODOS.md: collect all deferred scope expansions from Phase 1, auto-write + +--- + +## Decision Audit Trail + +After each auto-decision, append a row to the plan file using Edit: + +```markdown + +## Decision Audit Trail + +| # | Phase | Decision | Principle | Rationale | Rejected | +|---|-------|----------|-----------|-----------|----------| +``` + +Write one row per decision incrementally (via Edit). This keeps the audit on disk, +not accumulated in conversation context. + +--- + +## Phase 4: Final Approval Gate + +**STOP here and present the final state to the user.** + +Present as a message, then use AskUserQuestion: + +``` +## /autoplan Review Complete + +### Plan Summary +[1-3 sentence summary] + +### Decisions Made: [N] total ([M] auto-decided, [K] choices for you) + +### Your Choices (taste decisions) +[For each taste decision:] +**Choice [N]: [title]** (from [phase]) +I recommend [X] — [principle]. But [Y] is also viable: + [1-sentence downstream impact if you pick Y] + +### Auto-Decided: [M] decisions [see Decision Audit Trail in plan file] + +### Review Scores +- CEO: [summary] +- Design: [summary or "skipped, no UI scope"] +- Eng: [summary] +- Codex: [summary or "unavailable"] + +### Deferred to TODOS.md +[Items auto-deferred with reasons] +``` + +**Cognitive load management:** +- 0 taste decisions: skip "Your Choices" section +- 1-7 taste decisions: flat list +- 8+: group by phase. Add warning: "This plan had unusually high ambiguity ([N] taste decisions). Review carefully." + +AskUserQuestion options: +- A) Approve as-is (accept all recommendations) +- B) Approve with overrides (specify which taste decisions to change) +- C) Interrogate (ask about any specific decision) +- D) Revise (the plan itself needs changes) +- E) Reject (start over) + +**Option handling:** +- A: mark APPROVED, write review logs, suggest /ship +- B: ask which overrides, apply, re-present gate +- C: answer freeform, re-present gate +- D: make changes, re-run affected phases (scope→1B, design→2, test plan→3, arch→3). Max 3 cycles. +- E: start over + +--- + +## Completion: Write Review Logs + +On approval, write 3 separate review log entries so /ship's dashboard recognizes them: + +```bash +COMMIT=$(git rev-parse --short HEAD 2>/dev/null) +TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ) + +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"mode":"SELECTIVE_EXPANSION","via":"autoplan","commit":"'"$COMMIT"'"}' + +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"critical_gaps":0,"issues_found":0,"mode":"FULL_REVIEW","via":"autoplan","commit":"'"$COMMIT"'"}' +``` + +If Phase 2 ran (UI scope): +```bash +~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"'"$TIMESTAMP"'","status":"clean","unresolved":0,"via":"autoplan","commit":"'"$COMMIT"'"}' +``` + +Replace field values with actual counts from the review. + +Suggest next step: `/ship` when ready to create the PR. + +--- + +## Important Rules + +- **Never abort.** The user chose /autoplan. Respect that choice. Surface all taste decisions, never redirect to interactive review. +- **Premises are the one gate.** The only non-auto-decided AskUserQuestion is the premise confirmation in Phase 1. +- **Log every decision.** No silent auto-decisions. Every choice gets a row in the audit trail. +- **Full depth.** Do not compress or skip sections from the loaded skill files (except the skip list in Phase 0). +- **Sequential order.** CEO → Design → Eng. Each phase builds on the last. diff --git a/test/helpers/touchfiles.ts b/test/helpers/touchfiles.ts index 8fe2085a..346ed890 100644 --- a/test/helpers/touchfiles.ts +++ b/test/helpers/touchfiles.ts @@ -116,6 +116,9 @@ export const E2E_TOUCHFILES: Record = { 'benchmark-workflow': ['benchmark/**', 'browse/src/**'], 'setup-deploy-workflow': ['setup-deploy/**', 'scripts/gen-skill-docs.ts'], + // Autoplan + 'autoplan-core': ['autoplan/**', 'plan-ceo-review/**', 'plan-eng-review/**', 'plan-design-review/**'], + // Skill routing — journey-stage tests (depend on ALL skill descriptions) 'journey-ideation': ['*/SKILL.md.tmpl', 'SKILL.md.tmpl', 'scripts/gen-skill-docs.ts'], 'journey-plan-eng': ['*/SKILL.md.tmpl', 'SKILL.md.tmpl', 'scripts/gen-skill-docs.ts'], diff --git a/test/skill-validation.test.ts b/test/skill-validation.test.ts index 03640ccb..a8627094 100644 --- a/test/skill-validation.test.ts +++ b/test/skill-validation.test.ts @@ -99,6 +99,20 @@ describe('SKILL.md command validation', () => { const result = validateSkill(skill); expect(result.snapshotFlagErrors).toHaveLength(0); }); + + test('all $B commands in autoplan/SKILL.md are valid browse commands', () => { + const skill = path.join(ROOT, 'autoplan', 'SKILL.md'); + if (!fs.existsSync(skill)) return; + const result = validateSkill(skill); + expect(result.invalid).toHaveLength(0); + }); + + test('all snapshot flags in autoplan/SKILL.md are valid', () => { + const skill = path.join(ROOT, 'autoplan', 'SKILL.md'); + if (!fs.existsSync(skill)) return; + const result = validateSkill(skill); + expect(result.snapshotFlagErrors).toHaveLength(0); + }); }); describe('Command registry consistency', () => { diff --git a/test/touchfiles.test.ts b/test/touchfiles.test.ts index 631c4f62..0e24b124 100644 --- a/test/touchfiles.test.ts +++ b/test/touchfiles.test.ts @@ -79,8 +79,9 @@ describe('selectTests', () => { expect(result.selected).toContain('plan-ceo-review'); expect(result.selected).toContain('plan-ceo-review-selective'); expect(result.selected).toContain('plan-ceo-review-benefits'); - expect(result.selected.length).toBe(3); - expect(result.skipped.length).toBe(Object.keys(E2E_TOUCHFILES).length - 3); + expect(result.selected).toContain('autoplan-core'); + expect(result.selected.length).toBe(4); + expect(result.skipped.length).toBe(Object.keys(E2E_TOUCHFILES).length - 4); }); test('global touchfile triggers ALL tests', () => {