Skill Tracer
Skills › gstack › plan-design-review › review-sections.md

review-sections.md

722 lines · plan-design-review/sections/review-sections.md at 3f79d81

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1<!-- AUTO-GENERATED from review-sections.md.tmpl — do not edit directly -->
2<!-- Regenerate: bun run gen:skill-docs -->

<!-- AUTO-GENERATED from review-sections.md.tmpl — do not edit directly --> <!-- Regenerate: bun run gen:skill-docs -->

Raw lines 1 to 2
3## Review Sections (7 passes, after scope is agreed)
4
5**Anti-skip rule:** Never condense, abbreviate, or skip any review pass (1-7) regardless of plan type (strategy, spec, code, infra). Every pass in this skill exists for a reason. "This is a strategy doc so design passes don't apply" is always wrong — design gaps are where implementation breaks down. If a pass genuinely has zero findings, say "No issues found" and move on — but you must evaluate it.
6
7**Context:** This section continues `plan-design-review/SKILL.md`. If its setup
8is no longer in context, Read `~/.claude/skills/gstack/plan-design-review/SKILL.md`
9for the System Audit, Design Philosophy, Step 0, Step 0.5 mockup setup (`$D`),
10and Section self-check. Use their existing results; do not restart the review.
12**Anti-shortcut clause:** Complete one decision cycle per unresolved finding:
13explain the gap, recommend options, obtain its individual decision, then apply
14the selected fix. Scope, focus, setup, and next-step choices approve no remedies.
15Never use the final next-step AskUserQuestion to satisfy the issue-approval loop.
16With no unresolved findings, no issue question is required.
18**Carry decisions across passes.** An issue is one unresolved design requirement
19or tradeoff, even when it appears in several plan locations. Before each pass,
20compare the plan, DESIGN.md, and the decisions already made:
22| Situation | Required action |
23|-----------|-----------------|
24| The exact fix already has an individual user decision or a preamble-authorized per-issue auto-decision. | Reuse that decision. Apply it to all affected references and matching tokens; do not ask again. |
25| An accepted requirement needs to be copied unchanged into a required artifact, such as the journey storyboard. | Create the artifact without a separate format question. This records the requirement; it approves no new remedy. |
26| The plan violates DESIGN.md or has a gap, and no individual decision has approved its fix. | Ask about that issue and wait before fixing it, even if the input names the gap or DESIGN.md prescribes the exact token. Keep the proposed remedy pending meanwhile. |
27| New evidence introduces a missing requirement, a conflict, or a new tradeoff. | Name the new issue, offer alternatives, and obtain its individual decision before changing the plan. |
29Writing a report, mapping a token, creating a mockup, or listing a task does not
30approve a remedy. If findings exist but only navigation was answered, the review
31is still waiting for its first issue decision.

Review Sections (7 passes, after scope is agreed)

Anti-skip rule: Never condense, abbreviate, or skip any review pass (1-7) regardless of plan type (strategy, spec, code, infra). Every pass in this skill exists for a reason. "This is a strategy doc so design passes don't apply" is always wrong — design gaps are where implementation breaks down. If a pass genuinely has zero findings, say "No issues found" and move on — but you must evaluate it.

Context: This section continues plan-design-review/SKILL.md. If its setup is no longer in context, Read ~/.claude/skills/gstack/plan-design-review/SKILL.md for the System Audit, Design Philosophy, Step 0, Step 0.5 mockup setup ($D), and Section self-check. Use their existing results; do not restart the review.

Anti-shortcut clause: Complete one decision cycle per unresolved finding: explain the gap, recommend options, obtain its individual decision, then apply the selected fix. Scope, focus, setup, and next-step choices approve no remedies. Never use the final next-step AskUserQuestion to satisfy the issue-approval loop. With no unresolved findings, no issue question is required.

Carry decisions across passes. An issue is one unresolved design requirement or tradeoff, even when it appears in several plan locations. Before each pass, compare the plan, DESIGN.md, and the decisions already made:

SituationRequired action
The exact fix already has an individual user decision or a preamble-authorized per-issue auto-decision.Reuse that decision. Apply it to all affected references and matching tokens; do not ask again.
An accepted requirement needs to be copied unchanged into a required artifact, such as the journey storyboard.Create the artifact without a separate format question. This records the requirement; it approves no new remedy.
The plan violates DESIGN.md or has a gap, and no individual decision has approved its fix.Ask about that issue and wait before fixing it, even if the input names the gap or DESIGN.md prescribes the exact token. Keep the proposed remedy pending meanwhile.
New evidence introduces a missing requirement, a conflict, or a new tradeoff.Name the new issue, offer alternatives, and obtain its individual decision before changing the plan.

Writing a report, mapping a token, creating a mockup, or listing a task does not approve a remedy. If findings exist but only navigation was answered, the review is still waiting for its first issue decision.

Raw lines 3 to 32
Involves a person AskUserQuestion :15
Involves a person and wait :26
33## Prior Learnings
35Search for relevant learnings from previous sessions:
37```bash
38_CROSS_PROJ=$(~/.claude/skills/gstack/bin/gstack-config get cross_project_learnings 2>/dev/null || echo "unset")
39echo "CROSS_PROJECT: $_CROSS_PROJ"
40if [ "$_CROSS_PROJ" = "true" ]; then
41 { _LE=$(~/.claude/skills/gstack/bin/gstack-learnings-search --limit 10 --cross-project 2>&1 >&3 3>&-); _LR=$?; } 3>&1
42else
43 { _LE=$(~/.claude/skills/gstack/bin/gstack-learnings-search --limit 10 2>&1 >&3 3>&-); _LR=$?; } 3>&1
44fi
45[ "$_LR" = 0 ] || { _LE=${_LE%%$'\n'*}; echo "LEARNINGS: unavailable (${_LE:-exit $_LR})"; }
46```
48If `CROSS_PROJECT` is `unset` (first time): Use AskUserQuestion:
50> gstack can search learnings from your other projects on this machine to find
51> patterns that might apply here. This stays local (no data leaves your machine).
52> Recommended for solo developers. Skip if you work on multiple client codebases
53> where cross-contamination would be a concern.
55Options:
56- A) Enable cross-project learnings (recommended)
57- B) Keep learnings project-scoped only
59If A: run `~/.claude/skills/gstack/bin/gstack-config set cross_project_learnings true`
60If B: run `~/.claude/skills/gstack/bin/gstack-config set cross_project_learnings false`
62Then re-run the search with the appropriate flag.
64If learnings are found, incorporate them into your analysis. When a review finding
65matches a past learning, display:
67**"Prior learning applied: [key] (confidence N/10, from [date])"**
69This makes the compounding visible. The user should see that gstack is getting
70smarter on their codebase over time.
72Evaluate every pass using the plan and referenced existing contracts. An explicitly excluded artifact is not a missing requirement: assess the same dimension with permitted evidence. Reopen that exclusion only for a concrete design gap, and ask before changing it.
74**Pass protocol (1-6):** Record the initial 0-10 score. Every `FIX TO 10` below is a proposal: ask about each issue, wait for approval, then edit the plan and re-rate that pass with the reason for the score change. Never edit first and ask afterward.
76A declined fix remains documented: the unresolved gap keeps the rating below 10. Carry each pass's before/after scores and remaining gaps into the Completion Summary below. Compute the overall score as specified in the Completion Summary; do not treat litmus answers or Pass 7's decision counts as numeric ratings. Pass 7 is the unscored decision register, not a seventh rating.
78A faithful restatement of an existing or already approved contract, such as a wireframe of the unchanged layout, is review evidence rather than a new design choice. Record it directly; ask if producing it would introduce or change a design decision. Finish with the Required Outputs and terminal Plan File Review Report below, including any unanswered decisions.

Prior Learnings

Search for relevant learnings from previous sessions:

_CROSS_PROJ=$(~/.claude/skills/gstack/bin/gstack-config get cross_project_learnings 2>/dev/null || echo "unset")
echo "CROSS_PROJECT: $_CROSS_PROJ"
if [ "$_CROSS_PROJ" = "true" ]; then
  { _LE=$(~/.claude/skills/gstack/bin/gstack-learnings-search --limit 10 --cross-project 2>&1 >&3 3>&-); _LR=$?; } 3>&1
else
  { _LE=$(~/.claude/skills/gstack/bin/gstack-learnings-search --limit 10 2>&1 >&3 3>&-); _LR=$?; } 3>&1
fi
[ "$_LR" = 0 ] || { _LE=${_LE%%$'\n'*}; echo "LEARNINGS: unavailable (${_LE:-exit $_LR})"; }

If CROSS_PROJECT is unset (first time): Use AskUserQuestion:

gstack can search learnings from your other projects on this machine to find patterns that might apply here. This stays local (no data leaves your machine). Recommended for solo developers. Skip if you work on multiple client codebases where cross-contamination would be a concern.

Options:

  • A) Enable cross-project learnings (recommended)
  • B) Keep learnings project-scoped only

If A: run ~/.claude/skills/gstack/bin/gstack-config set cross_project_learnings true If B: run ~/.claude/skills/gstack/bin/gstack-config set cross_project_learnings false

Then re-run the search with the appropriate flag.

If learnings are found, incorporate them into your analysis. When a review finding matches a past learning, display:

"Prior learning applied: [key] (confidence N/10, from [date])"

This makes the compounding visible. The user should see that gstack is getting smarter on their codebase over time.

Evaluate every pass using the plan and referenced existing contracts. An explicitly excluded artifact is not a missing requirement: assess the same dimension with permitted evidence. Reopen that exclusion only for a concrete design gap, and ask before changing it.

Pass protocol (1-6): Record the initial 0-10 score. Every FIX TO 10 below is a proposal: ask about each issue, wait for approval, then edit the plan and re-rate that pass with the reason for the score change. Never edit first and ask afterward.

A declined fix remains documented: the unresolved gap keeps the rating below 10. Carry each pass's before/after scores and remaining gaps into the Completion Summary below. Compute the overall score as specified in the Completion Summary; do not treat litmus answers or Pass 7's decision counts as numeric ratings. Pass 7 is the unscored decision register, not a seventh rating.

A faithful restatement of an existing or already approved contract, such as a wireframe of the unchanged layout, is review evidence rather than a new design choice. Record it directly; ask if producing it would introduce or change a design decision. Finish with the Required Outputs and terminal Plan File Review Report below, including any unanswered decisions.

Raw lines 33 to 79
Runs code bin/gstack-config :38
Runs code bin/gstack-learnings-search :41
Involves a person AskUserQuestion :48
Involves a person wait for approval :74
80### Pass 1: Information Architecture
81Rate 0-10: Does the plan define what the user sees first, second, third?
82FIX TO 10: Add information hierarchy to the plan. Include ASCII diagram of screen/page structure and navigation flow. Apply "constraint worship" — if you can only show 3 things, which 3?
83**Persuade plan** (a landing, marketing, pricing, waitlist, campaign or comparison page; the Pass 4 classifier): the plan settles each check below, or the gap is a Pass 1 finding. Ask the user for missing proof and risk terms; never invent them.
841. **One primary action**, named; nothing competes with it above the fold, and the closing CTA repeats it.
852. **Named objections**: the visitor's top objections, each answered where it arises (FAQ of real questions, comparison, guarantee).
863. **Proof beside each claim**: a supplied customer, quote or figure next to the claim it supports, never a metric row; an unsupported claim is cut or marked `[Needs proof: …]`.
874. **A risk reversal** the business really offers (free plan, trial, no card, cancel anytime, refund); never an invented one.
885. **An index/noindex decision**: an ad-only or time-bound page is `noindex`; an indexed one has a real title and description, and its FAQ ships as FAQPage JSON-LD.
89**STOP.** AskUserQuestion once per issue. Do NOT batch. Recommend + WHY. If no issues, say so and move on. Do NOT proceed until user responds.

Pass 1: Information Architecture

Rate 0-10: Does the plan define what the user sees first, second, third? FIX TO 10: Add information hierarchy to the plan. Include ASCII diagram of screen/page structure and navigation flow. Apply "constraint worship" — if you can only show 3 things, which 3? Persuade plan (a landing, marketing, pricing, waitlist, campaign or comparison page; the Pass 4 classifier): the plan settles each check below, or the gap is a Pass 1 finding. Ask the user for missing proof and risk terms; never invent them.

  1. One primary action, named; nothing competes with it above the fold, and the closing CTA repeats it.
  2. Named objections: the visitor's top objections, each answered where it arises (FAQ of real questions, comparison, guarantee).
  3. Proof beside each claim: a supplied customer, quote or figure next to the claim it supports, never a metric row; an unsupported claim is cut or marked [Needs proof: …].
  4. A risk reversal the business really offers (free plan, trial, no card, cancel anytime, refund); never an invented one.
  5. An index/noindex decision: an ad-only or time-bound page is noindex; an indexed one has a real title and description, and its FAQ ships as FAQPage JSON-LD.

STOP. AskUserQuestion once per issue. Do NOT batch. Recommend + WHY. If no issues, say so and move on. Do NOT proceed until user responds.

Raw lines 80 to 90
Involves a person Ask the user :83
Involves a person AskUserQuestion :89
91### Pass 2: Interaction State Coverage
92Rate 0-10: Does the plan specify loading, empty, error, success, partial states?
93FIX TO 10: Add interaction state table to the plan:
94```
95 FEATURE | LOADING | EMPTY | ERROR | SUCCESS | PARTIAL
96 ---------------------|---------|-------|-------|---------|--------
97 [each UI feature] | [spec] | [spec]| [spec]| [spec] | [spec]
98```
99For each state: describe what the user SEES, not backend behavior.
100Empty states are features — specify warmth, primary action, context.
101**STOP.** AskUserQuestion once per issue. Do NOT batch. Recommend + WHY.

Pass 2: Interaction State Coverage

Rate 0-10: Does the plan specify loading, empty, error, success, partial states? FIX TO 10: Add interaction state table to the plan:

  FEATURE              | LOADING | EMPTY | ERROR | SUCCESS | PARTIAL
  ---------------------|---------|-------|-------|---------|--------
  [each UI feature]    | [spec]  | [spec]| [spec]| [spec]  | [spec]

For each state: describe what the user SEES, not backend behavior. Empty states are features — specify warmth, primary action, context. STOP. AskUserQuestion once per issue. Do NOT batch. Recommend + WHY.

Raw lines 91 to 102
Involves a person AskUserQuestion :101
103### Pass 3: User Journey & Emotional Arc
104Rate 0-10: Does the plan consider the user's emotional experience?
105FIX TO 10: Render the accepted journey as the required storyboard; do not ask whether to create it:
106```
107 STEP | USER DOES | USER FEELS | PLAN SPECIFIES?
108 -----|------------------|-----------------|----------------
109 1 | Lands on page | [what emotion?] | [what supports it?]
110 ...
111```
112Apply time-horizon design: 5-sec visceral, 5-min behavioral, 5-year reflective.
113**STOP.** AskUserQuestion once per issue. Do NOT batch. Recommend + WHY.

Pass 3: User Journey & Emotional Arc

Rate 0-10: Does the plan consider the user's emotional experience? FIX TO 10: Render the accepted journey as the required storyboard; do not ask whether to create it:

  STEP | USER DOES        | USER FEELS      | PLAN SPECIFIES?
  -----|------------------|-----------------|----------------
  1    | Lands on page    | [what emotion?] | [what supports it?]
  ...

Apply time-horizon design: 5-sec visceral, 5-min behavioral, 5-year reflective. STOP. AskUserQuestion once per issue. Do NOT batch. Recommend + WHY.

Raw lines 103 to 114
Involves a person AskUserQuestion :113
115### Pass 4: AI Slop Risk
117**Pass 4 evaluation:** Rate 0-10: Does the plan describe specific, intentional UI, or generic patterns? Record each hard-rejection hit and litmus YES/NO with evidence. An unresolved hard rejection caps this pass below 8 (not design-complete); it does not automatically set the score to 0. Litmus answers support findings, not a separate numeric score.
118Use plan text and any available mockups as evidence for the rules below.
120#### Design Hard Rules
122Review these as UI requirements in the plan, approved mockups, and referenced existing contracts. Inspect pixels or computed values when a rendered surface is available; otherwise assess what the plan specifies and identify concrete gaps.
124**Classifier: name the mode before you apply the rules.** The mode is what the visitor's win looks like on THIS surface, not what the product is. A dev tool's landing page is Persuade. A fashion house's docs are Read.
125- **PERSUADE** (MARKETING/LANDING PAGE: hero-driven, brand-forward, pricing, campaigns) → they decide and act. Design IS the product. Apply Landing Page Rules.
126- **OPERATE** (APP UI: dashboards, admin, settings, editors, tools) → they finish a task. Scanability and native expectations beat expression; the brand lives in the details. Apply App UI Rules.
127- **READ** (docs, articles, guides, changelogs) → they understand something. Structure for comprehension, then make staying worth it. Apply Read Rules.
128- **EXPERIENCE** (portfolios, galleries, showcases) → they are inside the work. The artifact owns the first viewport; the interface gets out of the way. Apply Experience Rules.
129- **HYBRID** (marketing shell with app-like sections) → classify per section, not per page.
131**Hard rejection criteria** (instant-fail patterns — flag if ANY apply):
1321. Generic SaaS card grid as first impression
1332. Beautiful image with weak brand
1343. Strong headline with no clear action
1354. Busy imagery behind text
1365. Sections repeating same mood statement
1376. Carousel with no narrative purpose
1387. App UI made of stacked cards instead of layout
140**Litmus checks** (answer YES/NO for each with evidence; compare with the outside-voice litmus scorecard when available. These support findings, not an additional numeric score):
1411. Brand/product unmistakable in first screen?
1422. One strong visual anchor present?
1433. Page understandable by scanning headlines only?
1444. Each section has one job?
1455. Are cards actually necessary?
1466. Does motion improve hierarchy or atmosphere?
1477. Would design feel premium with all decorative shadows removed?
149**Landing page rules** (apply when classifier = PERSUADE / MARKETING/LANDING):
150- First viewport reads as one composition, not a dashboard
151- Brand-first hierarchy: brand > headline > body > CTA
152- Typography: expressive, purposeful — no default stacks (Inter, Roboto, Arial, system)
153- No flat single-color backgrounds by default: texture from the brand or a real asset, never a halo, spotlight, stripe, or grid-paper gradient (see the AI Slop blacklist and detector rule ids below)
154- Hero: full-bleed, edge-to-edge, no inset/tiled/rounded variants
155- Hero budget: brand, one headline, one supporting sentence, one CTA group, one image
156- No cards in hero. Cards only when card IS the interaction
157- One job per section: one purpose, one headline, one short supporting sentence
158- Motion: one authored moment on the first viewport (an entrance or a scroll-linked reveal), ease-out from a visible default; hover states only where they carry information
159- Color: define CSS variables, avoid purple-on-white defaults, one accent color default
160- Copy: product language not design commentary. "If deleting 30% improves it, keep deleting"
161- Beautiful defaults: composition-first, brand as loudest text, two text faces max (plus a mono for data and code), cardless by default, first viewport as one composition, not a document (poster in stance, not in type size: display stays under 6rem)
163**App UI rules** (apply when classifier = OPERATE / APP UI):
164- Calm surface hierarchy, strong typography, few colors
165- Dense but readable, minimal chrome
166- Organize: primary workspace, navigation, secondary context, one accent
167- Avoid: dashboard-card mosaics, thick borders, decorative gradients, ornamental icons
168- Copy: utility language — orientation, status, action. Not mood/brand/aspiration
169- Cards only when card IS the interaction
170- Section headings state what area is or what user can do ("Selected KPIs", "Plan status")
172**Read rules** (apply when classifier = READ):
173- Measure 65-75ch, one reading column, headings closer to what follows than to what precedes
174- Wayfinding is a feature: where am I, what is next, where do I search
175- A docs index is Read, not Persuade: no hero, no CTA theater
177**Experience rules** (apply when classifier = EXPERIENCE):
178- The work fills the first viewport; chrome earns every pixel
179- One authored transition, not a scroll-jacked tour
180- Never crop the artifact to fit a template
182**Universal rules** (apply to ALL types):
183- Define CSS variables for color system
184- No default font stacks as the display voice (Inter, Roboto, Arial, system); DM Sans, Instrument Sans, IBM Plex Sans are allowed for body/UI on an Operate or Read surface when the proposal explicitly assigns that role
185- One job per section
186- "If deleting 30% of the copy improves it, keep deleting"
187- Cards earn their existence — no decorative card grids
188- NEVER use small, low-contrast type (body text < 16px or contrast ratio < 4.5:1 on body text)
189- NEVER put labels inside form fields as the only label (placeholder-as-label pattern — labels must be visible when the field has content)
190- ALWAYS preserve visited vs unvisited link distinction (visited links must have a different color)
191- NEVER float headings between paragraphs (heading must be visually closer to the section it introduces than to the preceding section)
193**Reflexes no detector catches** (check by hand, every time):
194- **Browser surfaces carry the design.** Selection color, caret, scrollbars, focus rings, underline offset, tabular numerals all ship with browser defaults that belong to no design system. Theme them from the palette. Cheapest tell that a page was designed rather than assembled, and the one models skip most.
195- **One authored motion moment.** Not the same entrance on every section, not a hover effect on everything. Exponential ease-out from an already-visible default. Content never hides behind animation timing.
196- **Depth has an offset.** Shadows are offset plus soft blur. A zero-offset colored halo is decoration, not depth.
197- **Secondary text on a colored surface is tinted from that hue.** Never gray.
198- **More space above a heading than below it.** Read the computed values.
199- **Light or dark comes from the use scene.** Who, where, under what light: one sentence. Never from the category.
201**Calibration: the three looks.** AI-built interfaces land in one of three looks no matter what the product is: (1) cream ground, high-contrast serif display, terracotta or signal-red accent; (2) near-black, one neon accent, glowing edges; (3) broadsheet hairlines, italic display serif, tiny tracked mono labels. Each is fine when the brief asks for it. If the brief left the look open and you landed in one anyway, you stopped looking. The test: could someone guess your look from the category alone? From "the category, but avoiding the obvious"? Either way, start over. "It's about books, so cream and a serif" fails this test. Book cloth and jackets come in every saturated color there is.
203**AI Slop blacklist** (the 11 patterns that scream "AI-generated"):
2041. Purple/violet/indigo gradient backgrounds or blue-to-purple color schemes
2052. **The 3-column feature grid:** icon-in-colored-circle + bold title + 2-line description, repeated 3x symmetrically. THE most recognizable AI layout.
2063. Icons in colored circles as section decoration (SaaS starter template look)
2074. Centered everything (`text-align: center` on all headings, descriptions, cards)
2085. Uniform bubbly border-radius on every element (same large radius on everything)
2096. Decorative blobs, floating circles, wavy SVG dividers (if a section feels empty, it needs better content, not decoration)
2107. Emoji as design elements (rockets in headings, emoji as bullet points)
2118. Colored left-border on cards (`border-left: 3px solid <accent>`)
2129. Generic hero copy ("Welcome to [X]", "Unlock the power of...", "Your all-in-one solution for...")
21310. Cookie-cutter section rhythm (hero → 3 features → testimonials → pricing → CTA, every section same height)
21411. system-ui or `-apple-system` as the PRIMARY display/body font — the "I gave up on typography" signal. Pick a real typeface.
216Detector rule ids for the rest of the catalog (a `[rule-id]` in a finding is one of these): border-accent-on-rounded: Border accent on a rounded card; overused-font: Overused display font; flat-type-hierarchy: Flat type hierarchy; gradient-text: Gradient text; cream-palette: Cream default palette; nested-cards: Nested cards; monotonous-spacing: Monotonous spacing; bounce-easing: Bounce easing; pulsing-dot: Pulsing status dot; blinking-cursor: Blinking cursor effect; shape-assembled-illustration: Shape-assembled illustration; dark-glow: Dark-mode glow; radial-halo: Radial halo; radial-spotlight-glow: Radial spotlight glow; marquee: Logo marquee; icon-tile-stack: Icon tile above every heading; italic-serif-display: Italic serif display; hero-eyebrow-chip: Hero eyebrow chip; kicker-above-heading: Kicker above heading; numbered-section-labels: Numbered section labels; em-dash-overuse: Em-dash overuse; marketing-buzzword: Marketing buzzwords; aphoristic-cadence: Aphoristic cadence; oversized-h1: Oversized h1; extreme-negative-tracking: Extreme negative tracking; gpt-thin-border-wide-shadow: Thin border plus wide shadow; repeating-stripes-gradient: Repeating stripes gradient; codex-grid-background: Grid-paper background; theater-slop-phrase: Theater phrases; image-hover-transform: Image hover zoom.
217Judgment tells with no detector rule: gradient cta button, stock-photo hero, cards as the default component, generic testimonial section, left-text right-image hero, generic cta labels, hero metric template, identical card grids, glassmorphism, hand-drawn svg illustration, modal by default, monospace as costume, content stand-ins, mode picked by category, unthemed browser surfaces, missing states.
219Source: [OpenAI "Designing Delightful Frontends with GPT-5.4"](https://developers.openai.com/blog/designing-delightful-frontends-with-gpt-5-4) (Mar 2026) + gstack design methodology.
221FIX TO 10: Rewrite vague UI descriptions with specific alternatives:
222- "Cards with icons" → what differentiates these from every SaaS template?
223- "Hero section" → what makes this hero feel like THIS product?
224- "Clean, modern UI" → meaningless. Replace with actual design decisions.
225- "Dashboard with widgets" → what makes this NOT every other dashboard?
226- "Trusted by thousands", "99.9% uptime" → on a Persuade plan, supplied proof beside the claim (Pass 1, check 3), or no claim.
227If visual mockups were generated in Step 0.5, evaluate them against the AI slop blacklist above. Read each mockup image using the Read tool. Does the mockup fall into generic patterns (3-column grid, centered hero, stock-photo feel)? If so, flag it and offer to regenerate with more specific direction via `$D iterate --feedback "$(cat "$FEEDBACK_FILE")"` (the feedback in a private file, never inline); use its printed `outputPath` for any later view, check or board.
228**STOP.** AskUserQuestion once per issue. Do NOT batch. Recommend + WHY.

Pass 4: AI Slop Risk

Pass 4 evaluation: Rate 0-10: Does the plan describe specific, intentional UI, or generic patterns? Record each hard-rejection hit and litmus YES/NO with evidence. An unresolved hard rejection caps this pass below 8 (not design-complete); it does not automatically set the score to 0. Litmus answers support findings, not a separate numeric score. Use plan text and any available mockups as evidence for the rules below.

Design Hard Rules

Review these as UI requirements in the plan, approved mockups, and referenced existing contracts. Inspect pixels or computed values when a rendered surface is available; otherwise assess what the plan specifies and identify concrete gaps.

Classifier: name the mode before you apply the rules. The mode is what the visitor's win looks like on THIS surface, not what the product is. A dev tool's landing page is Persuade. A fashion house's docs are Read.

  • PERSUADE (MARKETING/LANDING PAGE: hero-driven, brand-forward, pricing, campaigns) → they decide and act. Design IS the product. Apply Landing Page Rules.
  • OPERATE (APP UI: dashboards, admin, settings, editors, tools) → they finish a task. Scanability and native expectations beat expression; the brand lives in the details. Apply App UI Rules.
  • READ (docs, articles, guides, changelogs) → they understand something. Structure for comprehension, then make staying worth it. Apply Read Rules.
  • EXPERIENCE (portfolios, galleries, showcases) → they are inside the work. The artifact owns the first viewport; the interface gets out of the way. Apply Experience Rules.
  • HYBRID (marketing shell with app-like sections) → classify per section, not per page.

Hard rejection criteria (instant-fail patterns — flag if ANY apply):

  1. Generic SaaS card grid as first impression
  2. Beautiful image with weak brand
  3. Strong headline with no clear action
  4. Busy imagery behind text
  5. Sections repeating same mood statement
  6. Carousel with no narrative purpose
  7. App UI made of stacked cards instead of layout

Litmus checks (answer YES/NO for each with evidence; compare with the outside-voice litmus scorecard when available. These support findings, not an additional numeric score):

  1. Brand/product unmistakable in first screen?
  2. One strong visual anchor present?
  3. Page understandable by scanning headlines only?
  4. Each section has one job?
  5. Are cards actually necessary?
  6. Does motion improve hierarchy or atmosphere?
  7. Would design feel premium with all decorative shadows removed?

Landing page rules (apply when classifier = PERSUADE / MARKETING/LANDING):

  • First viewport reads as one composition, not a dashboard
  • Brand-first hierarchy: brand > headline > body > CTA
  • Typography: expressive, purposeful — no default stacks (Inter, Roboto, Arial, system)
  • No flat single-color backgrounds by default: texture from the brand or a real asset, never a halo, spotlight, stripe, or grid-paper gradient (see the AI Slop blacklist and detector rule ids below)
  • Hero: full-bleed, edge-to-edge, no inset/tiled/rounded variants
  • Hero budget: brand, one headline, one supporting sentence, one CTA group, one image
  • No cards in hero. Cards only when card IS the interaction
  • One job per section: one purpose, one headline, one short supporting sentence
  • Motion: one authored moment on the first viewport (an entrance or a scroll-linked reveal), ease-out from a visible default; hover states only where they carry information
  • Color: define CSS variables, avoid purple-on-white defaults, one accent color default
  • Copy: product language not design commentary. "If deleting 30% improves it, keep deleting"
  • Beautiful defaults: composition-first, brand as loudest text, two text faces max (plus a mono for data and code), cardless by default, first viewport as one composition, not a document (poster in stance, not in type size: display stays under 6rem)

App UI rules (apply when classifier = OPERATE / APP UI):

  • Calm surface hierarchy, strong typography, few colors
  • Dense but readable, minimal chrome
  • Organize: primary workspace, navigation, secondary context, one accent
  • Avoid: dashboard-card mosaics, thick borders, decorative gradients, ornamental icons
  • Copy: utility language — orientation, status, action. Not mood/brand/aspiration
  • Cards only when card IS the interaction
  • Section headings state what area is or what user can do ("Selected KPIs", "Plan status")

Read rules (apply when classifier = READ):

  • Measure 65-75ch, one reading column, headings closer to what follows than to what precedes
  • Wayfinding is a feature: where am I, what is next, where do I search
  • A docs index is Read, not Persuade: no hero, no CTA theater

Experience rules (apply when classifier = EXPERIENCE):

  • The work fills the first viewport; chrome earns every pixel
  • One authored transition, not a scroll-jacked tour
  • Never crop the artifact to fit a template

Universal rules (apply to ALL types):

  • Define CSS variables for color system
  • No default font stacks as the display voice (Inter, Roboto, Arial, system); DM Sans, Instrument Sans, IBM Plex Sans are allowed for body/UI on an Operate or Read surface when the proposal explicitly assigns that role
  • One job per section
  • "If deleting 30% of the copy improves it, keep deleting"
  • Cards earn their existence — no decorative card grids
  • NEVER use small, low-contrast type (body text < 16px or contrast ratio < 4.5:1 on body text)
  • NEVER put labels inside form fields as the only label (placeholder-as-label pattern — labels must be visible when the field has content)
  • ALWAYS preserve visited vs unvisited link distinction (visited links must have a different color)
  • NEVER float headings between paragraphs (heading must be visually closer to the section it introduces than to the preceding section)

Reflexes no detector catches (check by hand, every time):

  • Browser surfaces carry the design. Selection color, caret, scrollbars, focus rings, underline offset, tabular numerals all ship with browser defaults that belong to no design system. Theme them from the palette. Cheapest tell that a page was designed rather than assembled, and the one models skip most.
  • One authored motion moment. Not the same entrance on every section, not a hover effect on everything. Exponential ease-out from an already-visible default. Content never hides behind animation timing.
  • Depth has an offset. Shadows are offset plus soft blur. A zero-offset colored halo is decoration, not depth.
  • Secondary text on a colored surface is tinted from that hue. Never gray.
  • More space above a heading than below it. Read the computed values.
  • Light or dark comes from the use scene. Who, where, under what light: one sentence. Never from the category.

Calibration: the three looks. AI-built interfaces land in one of three looks no matter what the product is: (1) cream ground, high-contrast serif display, terracotta or signal-red accent; (2) near-black, one neon accent, glowing edges; (3) broadsheet hairlines, italic display serif, tiny tracked mono labels. Each is fine when the brief asks for it. If the brief left the look open and you landed in one anyway, you stopped looking. The test: could someone guess your look from the category alone? From "the category, but avoiding the obvious"? Either way, start over. "It's about books, so cream and a serif" fails this test. Book cloth and jackets come in every saturated color there is.

AI Slop blacklist (the 11 patterns that scream "AI-generated"):

  1. Purple/violet/indigo gradient backgrounds or blue-to-purple color schemes
  2. The 3-column feature grid: icon-in-colored-circle + bold title + 2-line description, repeated 3x symmetrically. THE most recognizable AI layout.
  3. Icons in colored circles as section decoration (SaaS starter template look)
  4. Centered everything (text-align: center on all headings, descriptions, cards)
  5. Uniform bubbly border-radius on every element (same large radius on everything)
  6. Decorative blobs, floating circles, wavy SVG dividers (if a section feels empty, it needs better content, not decoration)
  7. Emoji as design elements (rockets in headings, emoji as bullet points)
  8. Colored left-border on cards (border-left: 3px solid <accent>)
  9. Generic hero copy ("Welcome to [X]", "Unlock the power of...", "Your all-in-one solution for...")
  10. Cookie-cutter section rhythm (hero → 3 features → testimonials → pricing → CTA, every section same height)
  11. system-ui or -apple-system as the PRIMARY display/body font — the "I gave up on typography" signal. Pick a real typeface.

Detector rule ids for the rest of the catalog (a [rule-id] in a finding is one of these): border-accent-on-rounded: Border accent on a rounded card; overused-font: Overused display font; flat-type-hierarchy: Flat type hierarchy; gradient-text: Gradient text; cream-palette: Cream default palette; nested-cards: Nested cards; monotonous-spacing: Monotonous spacing; bounce-easing: Bounce easing; pulsing-dot: Pulsing status dot; blinking-cursor: Blinking cursor effect; shape-assembled-illustration: Shape-assembled illustration; dark-glow: Dark-mode glow; radial-halo: Radial halo; radial-spotlight-glow: Radial spotlight glow; marquee: Logo marquee; icon-tile-stack: Icon tile above every heading; italic-serif-display: Italic serif display; hero-eyebrow-chip: Hero eyebrow chip; kicker-above-heading: Kicker above heading; numbered-section-labels: Numbered section labels; em-dash-overuse: Em-dash overuse; marketing-buzzword: Marketing buzzwords; aphoristic-cadence: Aphoristic cadence; oversized-h1: Oversized h1; extreme-negative-tracking: Extreme negative tracking; gpt-thin-border-wide-shadow: Thin border plus wide shadow; repeating-stripes-gradient: Repeating stripes gradient; codex-grid-background: Grid-paper background; theater-slop-phrase: Theater phrases; image-hover-transform: Image hover zoom. Judgment tells with no detector rule: gradient cta button, stock-photo hero, cards as the default component, generic testimonial section, left-text right-image hero, generic cta labels, hero metric template, identical card grids, glassmorphism, hand-drawn svg illustration, modal by default, monospace as costume, content stand-ins, mode picked by category, unthemed browser surfaces, missing states.

Source: OpenAI "Designing Delightful Frontends with GPT-5.4" (Mar 2026) + gstack design methodology.

FIX TO 10: Rewrite vague UI descriptions with specific alternatives:

  • "Cards with icons" → what differentiates these from every SaaS template?
  • "Hero section" → what makes this hero feel like THIS product?
  • "Clean, modern UI" → meaningless. Replace with actual design decisions.
  • "Dashboard with widgets" → what makes this NOT every other dashboard?
  • "Trusted by thousands", "99.9% uptime" → on a Persuade plan, supplied proof beside the claim (Pass 1, check 3), or no claim.

If visual mockups were generated in Step 0.5, evaluate them against the AI slop blacklist above. Read each mockup image using the Read tool. Does the mockup fall into generic patterns (3-column grid, centered hero, stock-photo feel)? If so, flag it and offer to regenerate with more specific direction via $D iterate --feedback "$(cat "$FEEDBACK_FILE")" (the feedback in a private file, never inline); use its printed outputPath for any later view, check or board. STOP. AskUserQuestion once per issue. Do NOT batch. Recommend + WHY.

Raw lines 115 to 229
Involves a person AskUserQuestion :228
230### Pass 5: Design System Alignment
231Rate 0-10: Does the plan align with DESIGN.md?
232If DESIGN.md is absent, rate the plan's explicit token and component specifications. Missing specifications remain findings; do not skip the score or assume alignment.
233FIX TO 10: If DESIGN.md exists, annotate with specific tokens/components; when it has YAML front matter (the open DESIGN.md format), cite tokens by path (`{colors.primary}`, `{rounded.md}`) so the plan and the file share one vocabulary. If no DESIGN.md, flag the gap and recommend `/design-consultation`.
234Flag any new component — does it fit the existing vocabulary?
235Before offering a token-alignment fix, check whether an earlier pass already approved that outcome. If so, apply the established tokens and update every stale gap/reference under that decision; changing the plan location or spelling out the same fix is not a new issue. Ask again only if new evidence exposes an unresolved requirement or tradeoff, and name it. An unapproved violation still needs its first individual decision.
236**STOP.** AskUserQuestion once per issue. Do NOT batch. Recommend + WHY.

Pass 5: Design System Alignment

Rate 0-10: Does the plan align with DESIGN.md? If DESIGN.md is absent, rate the plan's explicit token and component specifications. Missing specifications remain findings; do not skip the score or assume alignment. FIX TO 10: If DESIGN.md exists, annotate with specific tokens/components; when it has YAML front matter (the open DESIGN.md format), cite tokens by path ({colors.primary}, {rounded.md}) so the plan and the file share one vocabulary. If no DESIGN.md, flag the gap and recommend /design-consultation. Flag any new component — does it fit the existing vocabulary? Before offering a token-alignment fix, check whether an earlier pass already approved that outcome. If so, apply the established tokens and update every stale gap/reference under that decision; changing the plan location or spelling out the same fix is not a new issue. Ask again only if new evidence exposes an unresolved requirement or tradeoff, and name it. An unapproved violation still needs its first individual decision. STOP. AskUserQuestion once per issue. Do NOT batch. Recommend + WHY.

Raw lines 230 to 237
Names a skill design-consultation :233
Involves a person AskUserQuestion :236
238### Pass 6: Responsive & Accessibility
239Rate 0-10: Does the plan specify mobile/tablet, keyboard nav, screen readers?
240FIX TO 10: Add responsive specs per viewport — not "stacked on mobile" but intentional layout changes. Add a11y: keyboard nav patterns, ARIA landmarks, touch target sizes (44px min), color contrast requirements.
241**STOP.** AskUserQuestion once per issue. Do NOT batch. Recommend + WHY.

Pass 6: Responsive & Accessibility

Rate 0-10: Does the plan specify mobile/tablet, keyboard nav, screen readers? FIX TO 10: Add responsive specs per viewport — not "stacked on mobile" but intentional layout changes. Add a11y: keyboard nav patterns, ARIA landmarks, touch target sizes (44px min), color contrast requirements. STOP. AskUserQuestion once per issue. Do NOT batch. Recommend + WHY.

Raw lines 238 to 242
Involves a person AskUserQuestion :241
243### Pass 7: Unresolved Design Decisions
244Start from unresolved choices recorded in earlier passes. For each new item, cite an actual in-scope element and the missing decision in the plan, source, DESIGN.md, or approved mockup. Page/section names and outside-review suggestions do not establish that a control exists. Check the available artifacts first; if its existence is unknown, keep the item conditional and state what must be verified. Do not invent controls or reopen accepted treatments for a hypothetical element. Surface real missing decisions and concrete conflicts; approval of one treatment does not settle a different known element.
246Preserve accepted user-facing outcomes. Choosing implementation mechanics does not
247reopen them; ask only if a concrete constraint exposes a new design requirement
248or tradeoff. Surface the remaining ambiguities that will haunt implementation:
249```
250 DECISION NEEDED | IF DEFERRED, WHAT HAPPENS
251 -----------------------------|---------------------------
252 What does empty state look like? | Engineer ships "No items found."
253 Mobile nav pattern? | Desktop nav hides behind hamburger
254 ...
255```
256If visual mockups were generated in Step 0.5, reference them as evidence when surfacing unresolved decisions. A mockup makes decisions concrete — e.g., "Your approved mockup shows a sidebar nav, but the plan doesn't specify mobile behavior. What happens to this sidebar on 375px?"
257Each decision = one AskUserQuestion with recommendation + WHY + alternatives. Edit the plan with each decision as it's made.
258**STOP.** Wait for each answer before editing or advancing. Record unanswered decisions as unresolved.

Pass 7: Unresolved Design Decisions

Start from unresolved choices recorded in earlier passes. For each new item, cite an actual in-scope element and the missing decision in the plan, source, DESIGN.md, or approved mockup. Page/section names and outside-review suggestions do not establish that a control exists. Check the available artifacts first; if its existence is unknown, keep the item conditional and state what must be verified. Do not invent controls or reopen accepted treatments for a hypothetical element. Surface real missing decisions and concrete conflicts; approval of one treatment does not settle a different known element.

Preserve accepted user-facing outcomes. Choosing implementation mechanics does not reopen them; ask only if a concrete constraint exposes a new design requirement or tradeoff. Surface the remaining ambiguities that will haunt implementation:

  DECISION NEEDED              | IF DEFERRED, WHAT HAPPENS
  -----------------------------|---------------------------
  What does empty state look like? | Engineer ships "No items found."
  Mobile nav pattern?          | Desktop nav hides behind hamburger
  ...

If visual mockups were generated in Step 0.5, reference them as evidence when surfacing unresolved decisions. A mockup makes decisions concrete — e.g., "Your approved mockup shows a sidebar nav, but the plan doesn't specify mobile behavior. What happens to this sidebar on 375px?" Each decision = one AskUserQuestion with recommendation + WHY + alternatives. Edit the plan with each decision as it's made. STOP. Wait for each answer before editing or advancing. Record unanswered decisions as unresolved.

Raw lines 243 to 259
Involves a person AskUserQuestion :257
260### Post-Pass: Update Mockups (if generated)
262After Pass 7: offer the mockup update below when applicable, resolve deferred TODO proposals, reconcile approvals, then synthesize tasks and the Completion Summary.
264If mockups were generated in Step 0.5 and review passes changed significant design decisions (information architecture restructure, new states, layout changes), offer to regenerate (one-shot, not a loop):
266AskUserQuestion: "The review passes changed [list major design changes]. Want me to regenerate mockups to reflect the updated plan? This ensures the visual reference matches what we're actually building."
268If yes, use `$D iterate` with feedback summarizing the changes, or `$D variants` with an updated brief; either text goes in a brief or feedback file, never inline. Save to the same `$_DESIGN_DIR` directory; nothing is overwritten, so do round accounting and carry the printed paths into any new board (rebuild it with the board block, which rewrites `board-images.json`) or check.

Post-Pass: Update Mockups (if generated)

After Pass 7: offer the mockup update below when applicable, resolve deferred TODO proposals, reconcile approvals, then synthesize tasks and the Completion Summary.

If mockups were generated in Step 0.5 and review passes changed significant design decisions (information architecture restructure, new states, layout changes), offer to regenerate (one-shot, not a loop):

AskUserQuestion: "The review passes changed [list major design changes]. Want me to regenerate mockups to reflect the updated plan? This ensures the visual reference matches what we're actually building."

If yes, use $D iterate with feedback summarizing the changes, or $D variants with an updated brief; either text goes in a brief or feedback file, never inline. Save to the same $_DESIGN_DIR directory; nothing is overwritten, so do round accounting and carry the printed paths into any new board (rebuild it with the board block, which rewrites board-images.json) or check.

Raw lines 260 to 269
Involves a person AskUserQuestion :266
270## How to ask questions
271Follow the AskUserQuestion format from the Preamble above. Additional rules for plan design reviews:
272* **One issue = one AskUserQuestion call.** Never combine multiple issues into one question. Each call contains exactly one question; multiple question tabs in one call are also batching. If a user could choose either remedy without choosing the other, ask separately, even when both affect the same component or token file. Shared implementation work does not make independent design choices inseparable.
273* Describe the design gap concretely — what's missing, what the user will experience if it's not specified.
274* Present 2-3 options. For each: effort to specify now, risk if deferred.
275* **Map to Design Principles above.** One sentence connecting your recommendation to a specific principle.
276* A gap with an "obvious fix" still needs the user's approval before it lands in the plan.
277* **Never use AskUserQuestion to ask which variant the user prefers.** The comparison board (`$D compare --serve`) is the chooser; AskUserQuestion only says the board is open and waits.

How to ask questions

Follow the AskUserQuestion format from the Preamble above. Additional rules for plan design reviews:

  • One issue = one AskUserQuestion call. Never combine multiple issues into one question. Each call contains exactly one question; multiple question tabs in one call are also batching. If a user could choose either remedy without choosing the other, ask separately, even when both affect the same component or token file. Shared implementation work does not make independent design choices inseparable.
  • Describe the design gap concretely — what's missing, what the user will experience if it's not specified.
  • Present 2-3 options. For each: effort to specify now, risk if deferred.
  • Map to Design Principles above. One sentence connecting your recommendation to a specific principle.
  • A gap with an "obvious fix" still needs the user's approval before it lands in the plan.
  • Never use AskUserQuestion to ask which variant the user prefers. The comparison board ($D compare --serve) is the chooser; AskUserQuestion only says the board is open and waits.
Raw lines 270 to 278
Involves a person AskUserQuestion :271
279## Required Outputs

Required Outputs

Raw lines 279 to 280
281### "NOT in scope" section
282Design decisions considered and explicitly deferred, with one-line rationale each.

"NOT in scope" section

Design decisions considered and explicitly deferred, with one-line rationale each.

Raw lines 281 to 283
284### "What already exists" section
285Existing DESIGN.md, UI patterns, and components that the plan should reuse.

"What already exists" section

Existing DESIGN.md, UI patterns, and components that the plan should reuse.

Raw lines 284 to 286
287### TODOS.md updates
288Put implementation and verification of approved fixes in the plan tasks. Do not
289make in-scope verification an optional follow-up. Reserve deferred TODO proposals
290for unresolved/out-of-scope debt or a new scope decision or tradeoff. After the
291passes, ask about each such TODO individually; never batch. Honor explicit user
292deferrals. If none remain, say so.
294For design debt (missing a11y, unresolved responsive behavior, deferred empty states), each TODO gets What, Why, Pros, Cons, Context (enough for someone in 3 months) and Depends on.
296Then present options: **A)** Add to TODOS.md **B)** Skip — not valuable enough **C)** Build it now in this PR instead of deferring.
298Before synthesizing tasks or the completion summary, perform the approval
299reconciliation from the Section self-check in `~/.claude/skills/gstack/plan-design-review/SKILL.md` (Read it if no longer in context). Export only agreed implementation work; retain unapproved remedies as pending findings.
300Count only individually approved new decisions in "Decisions made" and the
301review log; a proposed remedy or next-step answer contributes zero.

TODOS.md updates

Put implementation and verification of approved fixes in the plan tasks. Do not make in-scope verification an optional follow-up. Reserve deferred TODO proposals for unresolved/out-of-scope debt or a new scope decision or tradeoff. After the passes, ask about each such TODO individually; never batch. Honor explicit user deferrals. If none remain, say so.

For design debt (missing a11y, unresolved responsive behavior, deferred empty states), each TODO gets What, Why, Pros, Cons, Context (enough for someone in 3 months) and Depends on.

Then present options: A) Add to TODOS.md B) Skip — not valuable enough C) Build it now in this PR instead of deferring.

Before synthesizing tasks or the completion summary, perform the approval reconciliation from the Section self-check in ~/.claude/skills/gstack/plan-design-review/SKILL.md (Read it if no longer in context). Export only agreed implementation work; retain unapproved remedies as pending findings. Count only individually approved new decisions in "Decisions made" and the review log; a proposed remedy or next-step answer contributes zero.

Raw lines 287 to 302
303## Implementation Tasks
305Before closing this review, synthesize the findings above into a flat list of
306build-actionable tasks. Each task derives from a specific finding — no padding.
307Emit the markdown section AND write a JSONL artifact that `/autoplan` can
308aggregate across phases.

Implementation Tasks

Before closing this review, synthesize the findings above into a flat list of build-actionable tasks. Each task derives from a specific finding — no padding. Emit the markdown section AND write a JSONL artifact that /autoplan can aggregate across phases.

Raw lines 303 to 309
Names a skill autoplan :307
310### Markdown section (always emit)
312```markdown
313## Implementation Tasks
314Synthesized from this review's findings. Each task derives from a specific
315finding above. Run with Claude Code or Codex; checkbox as you ship.
317- [ ] **T1 (P1, human: ~2h / CC: ~15min)** — <component> — <imperative title>
318 - Surfaced by: <section name> — <specific finding text or line reference>
319 - Files: <paths to touch>
320 - Verify: <test command or manual check>
321- [ ] **T2 (P2, human: ~30min / CC: ~5min)** — ...
322```
324Rules:
325- P1 blocks ship; P2 should land same branch; P3 is a follow-up TODO.
326- If a finding produced no actionable task, do not invent one.
327- If a section had zero findings, emit `_No new tasks from <section>._`
328- Show human-team and CC+gstack effort estimates. Default task-type ratios (human ÷ CC time): scaffolding ~100x, tests ~50x, features ~30x, bug fix with regression ~20x, architecture ~5x, research ~3x. Adjust to the actual work and state the assumption.

Markdown section (always emit)

## Implementation Tasks
Synthesized from this review's findings. Each task derives from a specific
finding above. Run with Claude Code or Codex; checkbox as you ship.

- [ ] **T1 (P1, human: ~2h / CC: ~15min)** — <component> — <imperative title>
  - Surfaced by: <section name> — <specific finding text or line reference>
  - Files: <paths to touch>
  - Verify: <test command or manual check>
- [ ] **T2 (P2, human: ~30min / CC: ~5min)** — ...

Rules:

  • P1 blocks ship; P2 should land same branch; P3 is a follow-up TODO.
  • If a finding produced no actionable task, do not invent one.
  • If a section had zero findings, emit _No new tasks from <section>._
  • Show human-team and CC+gstack effort estimates. Default task-type ratios (human ÷ CC time): scaffolding ~100x, tests ~50x, features ~30x, bug fix with regression ~20x, architecture ~5x, research ~3x. Adjust to the actual work and state the assumption.
Raw lines 310 to 329
330### JSONL artifact (always write, even if zero tasks)
332`/autoplan` reads this file to aggregate across phases. Build each line with
333`jq -nc` so titles and source findings containing quotes, newlines, or
334backslashes serialize cleanly — never use hand-rolled `echo` / `printf`.
336```bash
337GSTACK_STATE_ROOT=$(~/.claude/skills/gstack/bin/gstack-paths --get GSTACK_STATE_ROOT); : "${GSTACK_STATE_ROOT:?gstack-paths failed; reinstall with ./setup or /gstack-upgrade}"
338SLUG=$(~/.claude/skills/gstack/bin/gstack-slug --get SLUG 2>/dev/null)
339TASKS_DIR="$GSTACK_STATE_ROOT/projects/${SLUG:-unknown}"
340mkdir -p "$TASKS_DIR"
341TASKS_FILE="$TASKS_DIR/tasks-design-review-$(date +%Y%m%d-%H%M%S).jsonl"
342COMMIT=$(git rev-parse HEAD 2>/dev/null || echo unknown)
343# The task record keeps the raw git branch; artifact filenames keep gstack-slug's sanitized BRANCH.
344GIT_BRANCH=$(git branch --show-current 2>/dev/null || echo unknown)
345RUN_ID="$(date -u +%Y%m%dT%H%M%SZ)-$$"
347# Repeat ONE jq invocation per task identified during this review.
348# Substitute the placeholders inline with shell variables you set per task:
349# TASK_ID (T1, T2, ...), PRIORITY (P1/P2/P3), COMPONENT, TITLE,
350# SOURCE_FINDING, EFFORT_HUMAN, EFFORT_CC, FILES_JSON (a JSON array literal
351# like '["browse/src/sanitize.ts","browse/src/server.ts"]').
352jq -nc \
353 --arg phase 'design-review' \
354 --arg run_id "$RUN_ID" \
355 --arg branch "$GIT_BRANCH" \
356 --arg commit "$COMMIT" \
357 --arg id "$TASK_ID" \
358 --arg priority "$PRIORITY" \
359 --arg component "$COMPONENT" \
360 --arg effort_human "$EFFORT_HUMAN" \
361 --arg effort_cc "$EFFORT_CC" \
362 --arg title "$TITLE" \
363 --arg source_finding "$SOURCE_FINDING" \
364 --argjson files "$FILES_JSON" \
365 '{phase:$phase, run_id:$run_id, branch:$branch, commit:$commit, id:$id, priority:$priority, component:$component, files:$files, effort_human:$effort_human, effort_cc:$effort_cc, title:$title, source_finding:$source_finding}' \
366 >> "$TASKS_FILE"
367```
369If `jq` is not installed, fall back to skipping the JSONL write and warn
370the user to install jq for autoplan aggregation. Never hand-roll JSONL.
372If zero tasks were identified in this review, still touch the JSONL file
373(`: > "$TASKS_FILE"`) so the aggregator sees that the phase produced output
374this run (an empty file means "ran, no findings" — distinct from "didn't run").

JSONL artifact (always write, even if zero tasks)

/autoplan reads this file to aggregate across phases. Build each line with jq -nc so titles and source findings containing quotes, newlines, or backslashes serialize cleanly — never use hand-rolled echo / printf.

GSTACK_STATE_ROOT=$(~/.claude/skills/gstack/bin/gstack-paths --get GSTACK_STATE_ROOT); : "${GSTACK_STATE_ROOT:?gstack-paths failed; reinstall with ./setup or /gstack-upgrade}"
SLUG=$(~/.claude/skills/gstack/bin/gstack-slug --get SLUG 2>/dev/null)
TASKS_DIR="$GSTACK_STATE_ROOT/projects/${SLUG:-unknown}"
mkdir -p "$TASKS_DIR"
TASKS_FILE="$TASKS_DIR/tasks-design-review-$(date +%Y%m%d-%H%M%S).jsonl"
COMMIT=$(git rev-parse HEAD 2>/dev/null || echo unknown)
# The task record keeps the raw git branch; artifact filenames keep gstack-slug's sanitized BRANCH.
GIT_BRANCH=$(git branch --show-current 2>/dev/null || echo unknown)
RUN_ID="$(date -u +%Y%m%dT%H%M%SZ)-$$"

# Repeat ONE jq invocation per task identified during this review.
# Substitute the placeholders inline with shell variables you set per task:
#   TASK_ID (T1, T2, ...), PRIORITY (P1/P2/P3), COMPONENT, TITLE,
#   SOURCE_FINDING, EFFORT_HUMAN, EFFORT_CC, FILES_JSON (a JSON array literal
#   like '["browse/src/sanitize.ts","browse/src/server.ts"]').
jq -nc \
  --arg phase 'design-review' \
  --arg run_id "$RUN_ID" \
  --arg branch "$GIT_BRANCH" \
  --arg commit "$COMMIT" \
  --arg id "$TASK_ID" \
  --arg priority "$PRIORITY" \
  --arg component "$COMPONENT" \
  --arg effort_human "$EFFORT_HUMAN" \
  --arg effort_cc "$EFFORT_CC" \
  --arg title "$TITLE" \
  --arg source_finding "$SOURCE_FINDING" \
  --argjson files "$FILES_JSON" \
  '{phase:$phase, run_id:$run_id, branch:$branch, commit:$commit, id:$id, priority:$priority, component:$component, files:$files, effort_human:$effort_human, effort_cc:$effort_cc, title:$title, source_finding:$source_finding}' \
  >> "$TASKS_FILE"

If jq is not installed, fall back to skipping the JSONL write and warn the user to install jq for autoplan aggregation. Never hand-roll JSONL.

If zero tasks were identified in this review, still touch the JSONL file (: > "$TASKS_FILE") so the aggregator sees that the phase produced output this run (an empty file means "ran, no findings" — distinct from "didn't run").

Raw lines 330 to 376
Names a skill autoplan :332
Runs code bin/gstack-paths :337
Runs code bin/gstack-slug :338
377### Completion Summary
378Prepare this for the saved review; announce completion after the Read-back gate below.
379In the plan file, write it as its own `## Design Review Completion Summary` section
380(the box, the deferred list and the Unresolved Decisions below) above the terminal
381`## GSTACK REVIEW REPORT`, replacing this review's earlier one. Never write it inside
382the report: the next plan review deletes and regenerates everything under that heading.
384**Overall design score:** use the lowest of the six rated pass scores (1-6),
385separately before and after approved fixes. Pass 7 is unscored. Keep Step 0's
386initial impression in its own row. An overall 8+ therefore means every rated
387pass is 8+; unresolved findings still prevent a clean review log.
389```
390 +====================================================================+
391 | DESIGN PLAN REVIEW — COMPLETION SUMMARY |
392 +====================================================================+
393 | System Audit | [DESIGN.md status, UI scope] |
394 | Step 0 | [initial rating, focus areas] |
395 | Pass 1 (Info Arch) | ___/10 → ___/10 after fixes |
396 | Pass 2 (States) | ___/10 → ___/10 after fixes |
397 | Pass 3 (Journey) | ___/10 → ___/10 after fixes |
398 | Pass 4 (AI Slop) | ___/10 → ___/10 after fixes |
399 | Pass 5 (Design Sys) | ___/10 → ___/10 after fixes |
400 | Pass 6 (Responsive) | ___/10 → ___/10 after fixes |
401 | Pass 7 (Decisions) | ___ resolved, ___ deferred |
402 +--------------------------------------------------------------------+
403 | NOT in scope | written (___ items) |
404 | What already exists | written |
405 | TODOS.md updates | ___ items proposed |
406 | Approved Mockups | ___ generated, ___ approved |
407 | Decisions made | ___ added to plan |
408 | Decisions deferred | ___ (listed below) |
409 | Overall design score | ___/10 → ___/10 |
410 +====================================================================+
411```
413After Read-back, if all passes 8+: "Plan is design-complete. Run /design-review after implementation for visual QA."
414If any below 8: note what's unresolved and why (user chose to defer).

Completion Summary

Prepare this for the saved review; announce completion after the Read-back gate below. In the plan file, write it as its own ## Design Review Completion Summary section (the box, the deferred list and the Unresolved Decisions below) above the terminal ## GSTACK REVIEW REPORT, replacing this review's earlier one. Never write it inside the report: the next plan review deletes and regenerates everything under that heading.

Overall design score: use the lowest of the six rated pass scores (1-6), separately before and after approved fixes. Pass 7 is unscored. Keep Step 0's initial impression in its own row. An overall 8+ therefore means every rated pass is 8+; unresolved findings still prevent a clean review log.

  +====================================================================+
  |         DESIGN PLAN REVIEW — COMPLETION SUMMARY                    |
  +====================================================================+
  | System Audit         | [DESIGN.md status, UI scope]                |
  | Step 0               | [initial rating, focus areas]               |
  | Pass 1  (Info Arch)  | ___/10 → ___/10 after fixes                |
  | Pass 2  (States)     | ___/10 → ___/10 after fixes                |
  | Pass 3  (Journey)    | ___/10 → ___/10 after fixes                |
  | Pass 4  (AI Slop)    | ___/10 → ___/10 after fixes                |
  | Pass 5  (Design Sys) | ___/10 → ___/10 after fixes                |
  | Pass 6  (Responsive) | ___/10 → ___/10 after fixes                |
  | Pass 7  (Decisions)  | ___ resolved, ___ deferred                 |
  +--------------------------------------------------------------------+
  | NOT in scope         | written (___ items)                         |
  | What already exists  | written                                     |
  | TODOS.md updates     | ___ items proposed                          |
  | Approved Mockups     | ___ generated, ___ approved                  |
  | Decisions made       | ___ added to plan                           |
  | Decisions deferred   | ___ (listed below)                          |
  | Overall design score | ___/10 → ___/10                             |
  +====================================================================+

After Read-back, if all passes 8+: "Plan is design-complete. Run /design-review after implementation for visual QA." If any below 8: note what's unresolved and why (user chose to defer).

Raw lines 377 to 415
Names a skill design-review :413
416### Unresolved Decisions
417List every unresolved finding here, including a finding not yet asked or an unanswered AskUserQuestion. Never silently default to an option.

Unresolved Decisions

List every unresolved finding here, including a finding not yet asked or an unanswered AskUserQuestion. Never silently default to an option.

Raw lines 416 to 418
Involves a person AskUserQuestion :417
419### Approved Mockups
421If visual mockups were generated during this review, add to the plan file:
423```
424## Approved Mockups
426| Screen/Section | Mockup Path | Direction | Notes |
427|----------------|-------------|-----------|-------|
428| [screen name] | [absolute $_DESIGN_DIR]/[filename].png | [brief description] | [constraints from review] |
429```
431Use the full path of each chosen variant. Omit this section when no mockups were generated.

Approved Mockups

If visual mockups were generated during this review, add to the plan file:

## Approved Mockups

| Screen/Section | Mockup Path | Direction | Notes |
|----------------|-------------|-----------|-------|
| [screen name]  | [absolute $_DESIGN_DIR]/[filename].png | [brief description] | [constraints from review] |

Use the full path of each chosen variant. Omit this section when no mockups were generated.

Raw lines 419 to 432
433## Plan File Review Report
435Save the accepted plan changes and full review output, including the report below, before logging or announcing completion.

Plan File Review Report

Save the accepted plan changes and full review output, including the report below, before logging or announcing completion.

Raw lines 433 to 436
437### Detect the plan file
439Use an explicitly requested output/report file first. Otherwise use the reviewed plan named by the user, then the host active plan. If no file is in scope, skip this section; ordinary no-file review logging still applies.

Detect the plan file

Use an explicitly requested output/report file first. Otherwise use the reviewed plan named by the user, then the host active plan. If no file is in scope, skip this section; ordinary no-file review logging still applies.

Raw lines 437 to 440
441### Generate the report
443Run `~/.claude/skills/gstack/bin/gstack-review-read` for prior review entries.
444Use the current Completion Summary or DX Scorecard for this review's status and findings;
445apply the Review Log field rules below and add exactly one to its prior run count.
446Do not pre-log this run to populate the report.
447Use prior entries for other reviews, retaining their status, attribution and freshness.
449Parse each JSONL entry using recorded provenance. Historical source "claude" is a native Claude subagent; "claude-code" is the external CLI. Keep historical codex identifiers and never relabel old records from the current harness. Unknown model identity remains unknown. For new records, show host, outside_provider, outside_status, and phase. Only completed external records establish outside coverage; native fallbacks do not.
451Each skill logs different fields:
453- **plan-ceo-review**: \`status\`, \`unresolved\`, \`critical_gaps\`, \`mode\`, \`scope_proposed\`, \`scope_accepted\`, \`scope_deferred\`, \`commit\`
454 → Findings: "{scope_proposed} proposals, {scope_accepted} accepted, {scope_deferred} deferred"
455 → If scope fields are 0 or missing (HOLD/REDUCTION mode): "mode: {mode}, {critical_gaps} critical gaps"
456- **plan-eng-review**: \`status\`, \`unresolved\`, \`critical_gaps\`, \`issues_found\`, \`mode\`, \`commit\`
457 → Findings: "{issues_found} issues, {critical_gaps} critical gaps"
458- **plan-design-review**: \`status\`, \`initial_score\`, \`overall_score\`, \`unresolved\`, \`decisions_made\`, \`commit\`
459 → Findings: "score: {initial_score}/10 → {overall_score}/10, {decisions_made} decisions"
460- **plan-devex-review**: \`status\`, \`initial_score\`, \`overall_score\`, \`product_type\`, \`tthw_current\`, \`tthw_target\`, \`mode\`, \`persona\`, \`competitive_tier\`, \`unresolved\`, \`commit\`
461 → Findings: "score: {initial_score}/10 → {overall_score}/10, TTHW: {tthw_current} → {tthw_target}"
462- **devex-review**: \`status\`, \`overall_score\`, \`product_type\`, \`tthw_measured\`, \`dimensions_tested\`, \`dimensions_inferred\`, \`boomerang\`, \`commit\`
463 → Findings: "score: {overall_score}/10, TTHW: {tthw_measured}, {dimensions_tested} tested/{dimensions_inferred} inferred"
464- **codex-review**: \`status\`, \`gate\`, \`findings\`, \`findings_fixed\`
465 → Findings: "{findings} findings, {findings_fixed}/{findings} fixed"
467The current row and its later log must describe the same saved review.
469Produce this markdown table:
471\`\`\`markdown

Generate the report

Run ~/.claude/skills/gstack/bin/gstack-review-read for prior review entries. Use the current Completion Summary or DX Scorecard for this review's status and findings; apply the Review Log field rules below and add exactly one to its prior run count. Do not pre-log this run to populate the report. Use prior entries for other reviews, retaining their status, attribution and freshness.

Parse each JSONL entry using recorded provenance. Historical source "claude" is a native Claude subagent; "claude-code" is the external CLI. Keep historical codex identifiers and never relabel old records from the current harness. Unknown model identity remains unknown. For new records, show host, outside_provider, outside_status, and phase. Only completed external records establish outside coverage; native fallbacks do not.

Each skill logs different fields:

  • plan-ceo-review: \status\, \unresolved\, \critical_gaps\, \mode\, \scope_proposed\, \scope_accepted\, \scope_deferred\, \commit\ → Findings: "{scope_proposed} proposals, {scope_accepted} accepted, {scope_deferred} deferred" → If scope fields are 0 or missing (HOLD/REDUCTION mode): "mode: {mode}, {critical_gaps} critical gaps"
  • plan-eng-review: \status\, \unresolved\, \critical_gaps\, \issues_found\, \mode\, \commit\ → Findings: "{issues_found} issues, {critical_gaps} critical gaps"
  • plan-design-review: \status\, \initial_score\, \overall_score\, \unresolved\, \decisions_made\, \commit\ → Findings: "score: {initial_score}/10 → {overall_score}/10, {decisions_made} decisions"
  • plan-devex-review: \status\, \initial_score\, \overall_score\, \product_type\, \tthw_current\, \tthw_target\, \mode\, \persona\, \competitive_tier\, \unresolved\, \commit\ → Findings: "score: {initial_score}/10 → {overall_score}/10, TTHW: {tthw_current} → {tthw_target}"
  • devex-review: \status\, \overall_score\, \product_type\, \tthw_measured\, \dimensions_tested\, \dimensions_inferred\, \boomerang\, \commit\ → Findings: "score: {overall_score}/10, TTHW: {tthw_measured}, {dimensions_tested} tested/{dimensions_inferred} inferred"
  • codex-review: \status\, \gate\, \findings\, \findings_fixed\ → Findings: "{findings} findings, {findings_fixed}/{findings} fixed"

The current row and its later log must describe the same saved review.

Produce this markdown table:

\\\`markdown

Raw lines 441 to 471
Runs code bin/gstack-review-read :443
Starts an agent subagent :449
Names a skill devex-review :462
472## GSTACK REVIEW REPORT
474| Review | Trigger | Why | Runs | Status | Findings |
475|--------|---------|-----|------|--------|----------|
476| CEO Review | \`/plan-ceo-review\` | Scope & strategy | {runs} | {status} | {findings} |
477| Outside Review | {recorded provider and trigger} | Independent 2nd opinion | {runs} | {outside_status} | {findings} |
478| Eng Review | \`/plan-eng-review\` | Architecture & tests (required) | {runs} | {status} | {findings} |
479| Design Review | \`/plan-design-review\` | UI/UX gaps | {runs} | {status} | {findings} |
480| DX Review | \`/plan-devex-review\` | Developer experience gaps | {runs} | {status} | {findings} |
481\`\`\`
483Below the table, add these lines. **OUTSIDE COVERAGE** and **CROSS-MODEL** are conditional:
484include them when the phase ran, was disabled/skipped/unavailable, or has findings;
485omit them only when no such phase applies. **VERDICT** is always present:
487- **OUTSIDE COVERAGE:** provider, phase, completion state, and findings. Include unavailable, disabled, and skipped phases; never infer completion from another phase.
488- **CROSS-MODEL:** only when native and completed external reviews exist — overlap analysis with recorded providers and known model identity. Do not infer distinct model families from harness names.
489- **VERDICT:** list reviews that are CLEAR (e.g., "CEO + ENG CLEARED — ready to implement").
490 If Eng Review is not CLEAR and not skipped globally, append "eng review required".
492**Unresolved-decisions status (MANDATORY — never omitted; the report's final non-whitespace
493line).** After VERDICT, end the report (content under the \`## GSTACK REVIEW REPORT\`
494heading — a bold label, never a new \`## \` heading; exempt from the "omit when empty"
495rule) with exactly one: the exact unbolded line \`NO UNRESOLVED DECISIONS\` (a bolded one
496does NOT count), OR a \`**UNRESOLVED DECISIONS:**\` header + one bullet per open item
497(last bullet = final line; add \`+ N unresolved from prior reviews\` only when N > 0).
498This avoids double-counting: list THIS review's open items from context; for prior reviews
499sum \`unresolved\` over the latest fresh row per skill (dashboard 7-day window) after you
500DROP the current skill's row; emit the sentinel only when both are zero.

GSTACK REVIEW REPORT

ReviewTriggerWhyRunsStatusFindings
CEO Review\/plan-ceo-review\Scope & strategy{runs}{status}{findings}
Outside Review{recorded provider and trigger}Independent 2nd opinion{runs}{outside_status}{findings}
Eng Review\/plan-eng-review\Architecture & tests (required){runs}{status}{findings}
Design Review\/plan-design-review\UI/UX gaps{runs}{status}{findings}
DX Review\/plan-devex-review\Developer experience gaps{runs}{status}{findings}

\\\`

Below the table, add these lines. OUTSIDE COVERAGE and CROSS-MODEL are conditional: include them when the phase ran, was disabled/skipped/unavailable, or has findings; omit them only when no such phase applies. VERDICT is always present:

  • OUTSIDE COVERAGE: provider, phase, completion state, and findings. Include unavailable, disabled, and skipped phases; never infer completion from another phase.
  • CROSS-MODEL: only when native and completed external reviews exist — overlap analysis with recorded providers and known model identity. Do not infer distinct model families from harness names.
  • VERDICT: list reviews that are CLEAR (e.g., "CEO + ENG CLEARED — ready to implement"). If Eng Review is not CLEAR and not skipped globally, append "eng review required".

Unresolved-decisions status (MANDATORY — never omitted; the report's final non-whitespace line). After VERDICT, end the report (content under the \## GSTACK REVIEW REPORT\ heading — a bold label, never a new \## \ heading; exempt from the "omit when empty" rule) with exactly one: the exact unbolded line \NO UNRESOLVED DECISIONS\ (a bolded one does NOT count), OR a \**UNRESOLVED DECISIONS:**\ header + one bullet per open item (last bullet = final line; add \+ N unresolved from prior reviews\ only when N > 0). This avoids double-counting: list THIS review's open items from context; for prior reviews sum \unresolved\ over the latest fresh row per skill (dashboard 7-day window) after you DROP the current skill's row; emit the sentinel only when both are zero.

Raw lines 472 to 501
Names a skill plan-devex-review :480
502### Write to the plan file
504**PLAN MODE EXCEPTION — ALWAYS RUN:** Save the complete reviewed plan/report with only accepted changes applied; keep unresolved choices pending.
506The report must always be the LAST section of the plan file — never mid-file.
507Use a single delete-then-append flow:
5091. Read the existing plan/report, if present. Preserve its content and apply only
510 accepted changes; include the full review output. Locate any existing
511 `## GSTACK REVIEW REPORT` section.
5122. If found, use the Edit tool to DELETE the entire existing section. Match from
513 \`## GSTACK REVIEW REPORT\` through either the next \`## \` heading or end of
514 file, whichever comes first. Replace with the empty string. This applies
515 regardless of where the section currently lives — mid-file deletion is
516 intentional, not a special case. If the Edit fails (e.g., concurrent edit
517 changed the content), re-read the plan file and retry once.
5183. If a report was deleted, Read the updated file. Append the new
519 \`## GSTACK REVIEW REPORT\` at EOF. Use Edit to match the suffix
520 confirmed by the latest Read, or Write the full file with the report last. Append whether or not a prior report existed.
521 "Unresolved Decisions" is not an EOF anchor when other sections follow it.
5224. **Read-back gate:** Read the saved file. Verify the accepted changes, full review
523 output, current review row, verdict and final unresolved-decisions status, with
524 `## GSTACK REVIEW REPORT` as the last section. If writing or verification fails,
525 report the error and stop before Review Log or decision logging.
527Do NOT replace the section in place; delete it and append the new report at EOF,
528so the review report is always the plan's last section.

Write to the plan file

PLAN MODE EXCEPTION — ALWAYS RUN: Save the complete reviewed plan/report with only accepted changes applied; keep unresolved choices pending.

The report must always be the LAST section of the plan file — never mid-file. Use a single delete-then-append flow:

  1. Read the existing plan/report, if present. Preserve its content and apply only accepted changes; include the full review output. Locate any existing ## GSTACK REVIEW REPORT section.
  2. If found, use the Edit tool to DELETE the entire existing section. Match from \## GSTACK REVIEW REPORT\ through either the next \## \ heading or end of file, whichever comes first. Replace with the empty string. This applies regardless of where the section currently lives — mid-file deletion is intentional, not a special case. If the Edit fails (e.g., concurrent edit changed the content), re-read the plan file and retry once.
  3. If a report was deleted, Read the updated file. Append the new \## GSTACK REVIEW REPORT\ at EOF. Use Edit to match the suffix confirmed by the latest Read, or Write the full file with the report last. Append whether or not a prior report existed. "Unresolved Decisions" is not an EOF anchor when other sections follow it.
  4. Read-back gate: Read the saved file. Verify the accepted changes, full review output, current review row, verdict and final unresolved-decisions status, with ## GSTACK REVIEW REPORT as the last section. If writing or verification fails, report the error and stop before Review Log or decision logging.

Do NOT replace the section in place; delete it and append the new report at EOF, so the review report is always the plan's last section.

Raw lines 502 to 529
530## Review Log
532When a plan/report file is in scope, persist only after its successful write and Read-back
533above. On failure, report the error and stop; do not log completion or an accepted decision.
534**PLAN MODE EXCEPTION — ALWAYS RUN after verification:** these commands write review
535metadata to `~/.gstack/`; the following dashboard reads the saved result.
537```bash
538~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"TIMESTAMP","status":"STATUS","initial_score":N,"overall_score":N,"unresolved":N,"decisions_made":N,"commit":"COMMIT"}'
539```
541Substitute values from the Completion Summary:
542- **TIMESTAMP**: current ISO 8601 datetime
543- **STATUS**: "clean" if overall score 8+ AND 0 unresolved; otherwise "issues_open"
544- **initial_score**: initial overall design score before fixes (0-10)
545- **overall_score**: final overall design score after fixes (0-10)
546- **unresolved**: number of unresolved design decisions
547- **decisions_made**: number of design decisions added to the plan
548- **COMMIT**: output of `git rev-parse --short HEAD`

Review Log

When a plan/report file is in scope, persist only after its successful write and Read-back above. On failure, report the error and stop; do not log completion or an accepted decision. PLAN MODE EXCEPTION — ALWAYS RUN after verification: these commands write review metadata to ~/.gstack/; the following dashboard reads the saved result.

~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-design-review","timestamp":"TIMESTAMP","status":"STATUS","initial_score":N,"overall_score":N,"unresolved":N,"decisions_made":N,"commit":"COMMIT"}'

Substitute values from the Completion Summary:

  • TIMESTAMP: current ISO 8601 datetime
  • STATUS: "clean" if overall score 8+ AND 0 unresolved; otherwise "issues_open"
  • initial_score: initial overall design score before fixes (0-10)
  • overall_score: final overall design score after fixes (0-10)
  • unresolved: number of unresolved design decisions
  • decisions_made: number of design decisions added to the plan
  • COMMIT: output of git rev-parse --short HEAD
Raw lines 530 to 549
Runs code bin/gstack-review-log :538
550## Review Readiness Dashboard
552After completing the review, read the review log and config to display the dashboard.
554```bash
555~/.claude/skills/gstack/bin/gstack-review-read
556```
558**1. Choose the records to display.** Use the latest record for each row below.
559Do not use a record older than 7 days to clear a row, and never substitute an older
560success for a newer failure. Ship metrics are not review records.
562| Row | Choose the latest of | Status suffix |
563|---|---|---|
564| Eng Review | `review` or `plan-eng-review` | (DIFF) or (PLAN) |
565| CEO Review | `plan-ceo-review` | — |
566| Design Review | `plan-design-review` or `design-review-lite` | (FULL) or (LITE) |
567| Adversarial | `adversarial-review` or legacy `codex-review` | — |
568| Outside Voice | `codex-plan-review` from CEO or Eng review | — |
570Keep each record's host, source, outside_provider, outside_status and phase.
571Historical source "claude" is a native subagent; "claude-code" is the external CLI.
572Do not infer old providers or unknown models from today's harness. A native result
573does not fill missing, disabled or skipped outside coverage.
575**Source attribution:** Append a recorded `via` to the suffix ("CLEAR (PLAN via
576/autoplan)"); without one, keep "CLEAR (PLAN)" or "CLEAR (DIFF)". Below the dashboard, group `autoplan-voices`
577and `design-outside-voices` by workflow run and phase. Show each phase's provider
578and outside_status; retain partial coverage. These details do not clear Eng Review.
580**2. Check freshness before choosing a verdict.**
582- **Content-first rule:** For `review`, `adversarial-review`, `codex-review`,
583 ship-stage reviews and `design-review-lite`, use `review_freshness.status`
584 and show its `reason`. CURRENT means a completed clean review whose start and
585 end content fingerprints equal the current `---WTREE---` fingerprint.
586 STALE or UNVERIFIED cannot clear Eng Review. Missing `review_freshness`,
587 including legacy log-only records, means UNVERIFIED. Never fall back to HEAD
588 equality or commit distance for diff evidence, even at zero commits.
589 Show recorded cycles, completed/converged fields and missing source/phase
590 coverage. Unknown coverage is not a pass.
591- **Plan records** (plan-ceo-review, plan-eng-review, plan-design-review and
592 codex-plan-review) use the 7-day window, not the working-tree fingerprint.
593 If `plan_sha256` is present, you may compare the plan file and report a mismatch.
594 Compare the recorded commit with `---HEAD---`; if different, run
595 `git rev-list --count STORED_COMMIT..HEAD` and report
596 "Note: {skill} review from {date} may be stale — {N} commits since review".
597 A failed command means UNKNOWN, treated as stale; without commit tracking,
598 suggest a re-run. Omit notes when all reviews are current.
600**3. Choose the historical verdict.** CLEARED requires the selected Eng Review
601to be `clean`, within 7 days and fresh under step 2. Otherwise report NOT CLEARED
602and its missing, stale or open-issue reason. If `skip_eng_review` is true, show
603"SKIPPED (global)" for Eng Review and CLEARED for this dashboard.
604Eng Review is required by default; `gstack-config set skip_eng_review true` disables that requirement.
606Other rows provide context, not a substitute for Eng Review:
607- Recommend CEO Review for product/business or scope decisions, not routine fixes or cleanup.
608- Recommend Design Review for UI/UX work, not backend, infrastructure or prompt-only work.
609- Adversarial review always includes a native pass. Available, enabled outside
610 challenges supplement it; diffs of 200+ lines also get the structured P1 gate.
611- Outside Voice is the default-on plan review after CEO/Eng review. `codex_reviews`
612 disables that extra step. Provider failure uses native fallback and records
613 missing outside coverage; this dashboard row never gates shipping.
615**4. Display the dashboard.** Show missing, stale, disabled or unavailable results
616explicitly, never as CLEAR. Display a fresh `clean` result as CLEAR and
617`issues_open` as ISSUES OPEN without changing the stored status.
619```
620+====================================================================+
621| REVIEW READINESS DASHBOARD |
622+====================================================================+
623| Review | Runs | Last Run | Status | Required |
624|-----------------|------|---------------------|-----------|----------|
625| Eng Review | 1 | 2026-03-16 15:00 | CLEAR | YES |
626| CEO Review | 0 | — | — | no |
627| Design Review | 0 | — | — | no |
628| Adversarial | 0 | — | — | no |
629| Outside Voice | 0 | — | — | no |
630+--------------------------------------------------------------------+
631| VERDICT: CLEARED — Eng Review passed |
632+====================================================================+
633```

Review Readiness Dashboard

After completing the review, read the review log and config to display the dashboard.

~/.claude/skills/gstack/bin/gstack-review-read

1. Choose the records to display. Use the latest record for each row below. Do not use a record older than 7 days to clear a row, and never substitute an older success for a newer failure. Ship metrics are not review records.

RowChoose the latest ofStatus suffix
Eng Reviewreview or plan-eng-review(DIFF) or (PLAN)
CEO Reviewplan-ceo-review—
Design Reviewplan-design-review or design-review-lite(FULL) or (LITE)
Adversarialadversarial-review or legacy codex-review—
Outside Voicecodex-plan-review from CEO or Eng review—

Keep each record's host, source, outside_provider, outside_status and phase. Historical source "claude" is a native subagent; "claude-code" is the external CLI. Do not infer old providers or unknown models from today's harness. A native result does not fill missing, disabled or skipped outside coverage.

Source attribution: Append a recorded via to the suffix ("CLEAR (PLAN via /autoplan)"); without one, keep "CLEAR (PLAN)" or "CLEAR (DIFF)". Below the dashboard, group autoplan-voices and design-outside-voices by workflow run and phase. Show each phase's provider and outside_status; retain partial coverage. These details do not clear Eng Review.

2. Check freshness before choosing a verdict.

  • Content-first rule: For review, adversarial-review, codex-review, ship-stage reviews and design-review-lite, use review_freshness.status and show its reason. CURRENT means a completed clean review whose start and end content fingerprints equal the current ---WTREE--- fingerprint. STALE or UNVERIFIED cannot clear Eng Review. Missing review_freshness, including legacy log-only records, means UNVERIFIED. Never fall back to HEAD equality or commit distance for diff evidence, even at zero commits. Show recorded cycles, completed/converged fields and missing source/phase coverage. Unknown coverage is not a pass.
  • Plan records (plan-ceo-review, plan-eng-review, plan-design-review and codex-plan-review) use the 7-day window, not the working-tree fingerprint. If plan_sha256 is present, you may compare the plan file and report a mismatch. Compare the recorded commit with ---HEAD---; if different, run git rev-list --count STORED_COMMIT..HEAD and report "Note: {skill} review from {date} may be stale — {N} commits since review". A failed command means UNKNOWN, treated as stale; without commit tracking, suggest a re-run. Omit notes when all reviews are current.

3. Choose the historical verdict. CLEARED requires the selected Eng Review to be clean, within 7 days and fresh under step 2. Otherwise report NOT CLEARED and its missing, stale or open-issue reason. If skip_eng_review is true, show "SKIPPED (global)" for Eng Review and CLEARED for this dashboard. Eng Review is required by default; gstack-config set skip_eng_review true disables that requirement.

Other rows provide context, not a substitute for Eng Review:

  • Recommend CEO Review for product/business or scope decisions, not routine fixes or cleanup.
  • Recommend Design Review for UI/UX work, not backend, infrastructure or prompt-only work.
  • Adversarial review always includes a native pass. Available, enabled outside challenges supplement it; diffs of 200+ lines also get the structured P1 gate.
  • Outside Voice is the default-on plan review after CEO/Eng review. codex_reviews disables that extra step. Provider failure uses native fallback and records missing outside coverage; this dashboard row never gates shipping.

4. Display the dashboard. Show missing, stale, disabled or unavailable results explicitly, never as CLEAR. Display a fresh clean result as CLEAR and issues_open as ISSUES OPEN without changing the stored status.

+====================================================================+
|                    REVIEW READINESS DASHBOARD                       |
+====================================================================+
| Review          | Runs | Last Run            | Status    | Required |
|-----------------|------|---------------------|-----------|----------|
| Eng Review      |  1   | 2026-03-16 15:00    | CLEAR     | YES      |
| CEO Review      |  0   | —                   | —         | no       |
| Design Review   |  0   | —                   | —         | no       |
| Adversarial     |  0   | —                   | —         | no       |
| Outside Voice   |  0   | —                   | —         | no       |
+--------------------------------------------------------------------+
| VERDICT: CLEARED — Eng Review passed                                |
+====================================================================+
Raw lines 550 to 634
Runs code bin/gstack-review-read :555
Names a skill review :564
Names a skill plan-eng-review :564
Names a skill plan-ceo-review :565
Starts an agent subagent :571
635## Capture Learnings
637If you discovered a non-obvious pattern, pitfall, or architectural insight during
638this session, log it for future sessions:
640```bash
641~/.claude/skills/gstack/bin/gstack-learnings-log '{"skill":"plan-design-review","type":"TYPE","key":"SHORT_KEY","insight":"DESCRIPTION","confidence":N,"source":"SOURCE","files":["path/to/relevant/file"]}'
642```
644**Types:** `pattern` (reusable approach), `pitfall` (what NOT to do), `preference`
645(user stated), `architecture` (structural decision), `tool` (library/framework insight),
646`operational` (project environment/CLI/workflow knowledge).
648**Sources:** `observed` (you found this in the code), `user-stated` (user told you),
649`inferred` (AI deduction), `cross-model` (both Claude and Codex agree).
651**Confidence:** 1-10. Be honest. An observed pattern you verified in the code is 8-9.
652An inference you're not sure about is 4-5. A user preference they explicitly stated is 10.
654**files:** Include the specific file paths this learning references. This enables
655staleness detection: if those files are later deleted, the learning can be flagged.
657**Only log genuine discoveries.** Don't log obvious things. Don't log things the user
658already knows. A good test: would this insight save time in a future session? If yes, log it.

Capture Learnings

If you discovered a non-obvious pattern, pitfall, or architectural insight during this session, log it for future sessions:

~/.claude/skills/gstack/bin/gstack-learnings-log '{"skill":"plan-design-review","type":"TYPE","key":"SHORT_KEY","insight":"DESCRIPTION","confidence":N,"source":"SOURCE","files":["path/to/relevant/file"]}'

Types: pattern (reusable approach), pitfall (what NOT to do), preference (user stated), architecture (structural decision), tool (library/framework insight), operational (project environment/CLI/workflow knowledge).

Sources: observed (you found this in the code), user-stated (user told you), inferred (AI deduction), cross-model (both Claude and Codex agree).

Confidence: 1-10. Be honest. An observed pattern you verified in the code is 8-9. An inference you're not sure about is 4-5. A user preference they explicitly stated is 10.

files: Include the specific file paths this learning references. This enables staleness detection: if those files are later deleted, the learning can be flagged.

Only log genuine discoveries. Don't log obvious things. Don't log things the user already knows. A good test: would this insight save time in a future session? If yes, log it.

Raw lines 635 to 661
Runs code bin/gstack-learnings-log :641
662## Brain Calibration Write-Back (gated)
664Skip unless `BRAIN_CALIBRATION_WRITEBACK` is set and the preamble/brain-health
665output or gstack config shows `brain_trust_policy@<endpoint-hash>=personal`.
666If unknown, skip. If both gates pass, record one durable
667typed prediction with `mcp__gbrain__takes_add`; if unavailable, use
668`mcp__gbrain__put_page` with a gstack:takes fence block.
670Take frontmatter:
671```yaml
672kind: bet
673holder: <user identity from whoami>
674claim: <one-line prediction the skill is making>
675weight: 0.5
676since_date: <today's date>
677expected_resolution: <date in 1-3 months depending on skill>
678source_skill: plan-design-review
679```
681After write, invalidate affected digests:
683```bash
684SLUG=$(~/.claude/skills/gstack/bin/gstack-slug --get SLUG 2>/dev/null) || true
685 ~/.claude/skills/gstack/bin/gstack-brain-cache invalidate brand --project "$SLUG" 2>/dev/null || true
686```

Brain Calibration Write-Back (gated)

Skip unless BRAIN_CALIBRATION_WRITEBACK is set and the preamble/brain-health output or gstack config shows brain_trust_policy@<endpoint-hash>=personal. If unknown, skip. If both gates pass, record one durable typed prediction with mcp__gbrain__takes_add; if unavailable, use mcp__gbrain__put_page with a gstack:takes fence block.

Take frontmatter:

kind: bet
holder: <user identity from whoami>
claim: <one-line prediction the skill is making>
weight: 0.5
since_date: <today's date>
expected_resolution: <date in 1-3 months depending on skill>
source_skill: plan-design-review

After write, invalidate affected digests:

SLUG=$(~/.claude/skills/gstack/bin/gstack-slug --get SLUG 2>/dev/null) || true
  ~/.claude/skills/gstack/bin/gstack-brain-cache invalidate brand --project "$SLUG" 2>/dev/null || true
Raw lines 662 to 687
Uses an outside tool mcp__gbrain__takes_add :667
Uses an outside tool mcp__gbrain__put_page :668
Runs code bin/gstack-slug :684
Runs code bin/gstack-brain-cache :685
688## Brain Cache Background Refresh
690After the skill's work completes (and telemetry has logged), kick a
691background refresh of any cache digest that's getting close to its TTL.
692This is non-blocking — the user doesn't wait. Next invocation benefits
693from the warm cache.
695```bash
696SLUG=$(~/.claude/skills/gstack/bin/gstack-slug --get SLUG 2>/dev/null) || true
697(~/.claude/skills/gstack/bin/gstack-brain-cache refresh --project "$SLUG" 2>/dev/null &) || true
698```

Brain Cache Background Refresh

After the skill's work completes (and telemetry has logged), kick a background refresh of any cache digest that's getting close to its TTL. This is non-blocking — the user doesn't wait. Next invocation benefits from the warm cache.

SLUG=$(~/.claude/skills/gstack/bin/gstack-slug --get SLUG 2>/dev/null) || true
(~/.claude/skills/gstack/bin/gstack-brain-cache refresh --project "$SLUG" 2>/dev/null &) || true
Raw lines 688 to 700
Runs code bin/gstack-slug :696
Runs code bin/gstack-brain-cache :697
701## Next Steps — Review Chaining
703From the dashboard output, recommend the next review(s):
705- **/plan-eng-review** unless `skip_eng_review` is `true`: it is the required shipping gate. Stress it when this review added flows or changed the information architecture; an eng review whose commit predates this review is stale and should be re-run.
706- **/plan-ceo-review** only for fundamental product gaps (initial score below 4/10, major IA problems, or doubt about the problem itself) and no CEO review exists. Most design reviews should not trigger it. If both apply, eng review first.
707- **/design-shotgun** for visual issues worth exploring; **/design-html** when approved mockups need HTML. Both produce design artifacts, so they fit plan mode.
709Use AskUserQuestion to present the next step. Always include the manual/stop
710option E; offer only applicable follow-on skills. If the user chooses manual,
711finish without starting another skill:
712- **A)** Run /plan-eng-review next (required gate)
713- **B)** Run /plan-ceo-review (only if fundamental product gaps found)
714- **C)** Run /design-shotgun — explore visual design variants for issues found
715- **D)** Run /design-html — generate Pretext-native HTML from approved mockups
716- **E)** Skip — I'll handle next steps manually

Next Steps — Review Chaining

From the dashboard output, recommend the next review(s):

  • /plan-eng-review unless skip_eng_review is true: it is the required shipping gate. Stress it when this review added flows or changed the information architecture; an eng review whose commit predates this review is stale and should be re-run.
  • /plan-ceo-review only for fundamental product gaps (initial score below 4/10, major IA problems, or doubt about the problem itself) and no CEO review exists. Most design reviews should not trigger it. If both apply, eng review first.
  • /design-shotgun for visual issues worth exploring; /design-html when approved mockups need HTML. Both produce design artifacts, so they fit plan mode.

Use AskUserQuestion to present the next step. Always include the manual/stop option E; offer only applicable follow-on skills. If the user chooses manual, finish without starting another skill:

  • A) Run /plan-eng-review next (required gate)
  • B) Run /plan-ceo-review (only if fundamental product gaps found)
  • C) Run /design-shotgun — explore visual design variants for issues found
  • D) Run /design-html — generate Pretext-native HTML from approved mockups
  • E) Skip — I'll handle next steps manually
Raw lines 701 to 717
Names a skill plan-eng-review :705
Names a skill plan-ceo-review :706
Names a skill design-shotgun :707
Names a skill design-html :707
Involves a person AskUserQuestion :709
718## Formatting Rules
719* Number issues and letter options; label each option NUMBER + LETTER ("3A", "3B").
720* One sentence max per option.
721* Pause for each unresolved issue. If a pass has none, say so and continue; do not manufacture a question.
722* Rate before and after each pass for scannability.

Formatting Rules

  • Number issues and letter options; label each option NUMBER + LETTER ("3A", "3B").
  • One sentence max per option.
  • Pause for each unresolved issue. If a pass has none, say so and continue; do not manufacture a question.
  • Rate before and after each pass for scannability.
Raw lines 718 to 722