# gstack: every skill, every command, and who should use it

URL: https://www.thedeepfeed.ai/posts/2026-05-23-gstack-garry-tan-claude-code-developer-guide/
Category: Tools
Published: 2026-05-24
Updated: 2026-05-25
Author: the-deep-feed
Tags: gstack, garry-tan, claude-code, ai-coding, developer-tools, y-combinator
Kind: deep

> Garry Tan's gstack passed 101,020 GitHub stars in ten weeks. Inside the repo: 33 slash commands, 7 standalone CLIs, 4 OpenClaw skills. Here is the full reference, every skill with three concrete examples, and the LOC controversy decoded.

## TL;DR

- **gstack** is **Garry Tan's** open-source Claude Code skill pack: **33 slash commands, 7 standalone CLIs, 4 OpenClaw native skills**, MIT-licensed. It hit **101,020 GitHub stars in ten weeks** with **15,047 forks** and (per Garry's April 18 disclosure) **305,309 skill invocations and ~7,000 weekly active users**.
- The skills run as a sprint, **Think → Plan → Build → Review → Test → Ship → Reflect**, with state passing forward. `/office-hours` writes a design doc that `/plan-ceo-review` reads. `/qa` picks up a test plan from `/plan-eng-review`. **`/autoplan`** collapses the four review skills into one auto-decided run surfacing only taste calls.
- Below: **every skill, three concrete examples each**, drawn from real founder, staff-engineer, DX-lead, designer, SRE, and consultant workflows. ~45 entries, full coverage of v0.19+.
- The **LOC controversy** is the central public fight. Garry's [v1.0 release post](https://x.com/garrytan/status/2045399029560033551) pivoted from raw LOC to *logical SLOC* and reported **14 lines/day (2013)** vs **11,417 lines/day (2026)** = **~810×**. The single most-viewed critique is [Gregorein's gslop audit](https://x.com/Gregorein/status/2038953944475472316) at **2.78M views and 7,693 likes**, an empirical takedown of garryslist.org.
- gstack is **for** founders, technical CEOs, staff engineers running parallel sprints, first-time Claude Code users, and tech leads wanting rigorous review/QA/release automation. **Not for** developers who already hand-rolled their own skill pack and prefer it (per [Mo Bitar](https://www.youtube.com/watch?v=Q6nem-F8AG8), *"every developer who's used Claude Code for more than a week has a version of this"*).

On **March 12, 2026**, [Garry Tan](https://x.com/garrytan), President and CEO of **Y Combinator**, pushed a public commit to a brand-new repo called [gstack](https://github.com/garrytan/gstack) and posted a tweet saying he wanted readers to have his *exact* Claude Code setup. Ten weeks later the repo sits at **101,020 stars and 15,047 forks**, a growth curve that puts it inside the top 50 fastest-starred GitHub projects of all time. The skill pack is MIT-licensed, free, and has no waitlist. Anyone can install it in 30 seconds.

What's inside, at the literal level, is **33 slash-command skills, 7 standalone CLIs, 4 OpenClaw-native conversational skills, and a parallel iOS device-farm subsystem**, all wired through `~/.claude/skills/gstack/` and addressable from Claude Code with a `/`. What's inside, at the editorial level, is a complete sprint methodology, *Think → Plan → Build → Review → Test → Ship → Reflect*, encoded as Markdown files that the model reads on demand. Each skill plays a role on a virtual team: CEO, eng manager, designer, staff engineer, QA lead, SRE, security officer, release engineer, technical writer. The pitch is that one founder can run that whole team.

The pitch is also the controversy. Garry has spent two months getting publicly dunked on for the LOC numbers attached to gstack, the design quality of his demo site, and the *register* in which he writes about all of it. The fight is so loud it has crowded out the simpler question: *what is actually in the repo, and who should use it?* This piece answers that. It is the full developer reference for gstack, every skill, three examples each, the controversy decoded, written so a reader who has never heard of gstack can decide in one sitting whether to install it.

# 1. What gstack is, in 200 words

gstack turns Claude Code (Anthropic's terminal-native coding agent) into an opinionated workflow rather than a blank prompt. You install it once with a 30-second `git clone` into `~/.claude/skills/gstack/`. Every slash command thereafter is a Markdown file that gives the model a specific role, `/office-hours` plays a YC partner, `/plan-ceo-review` plays a founder, `/review` plays a paranoid staff engineer, `/cso` plays a security officer, `/ship` plays a release engineer.

The skills know about each other. `/office-hours` writes a design doc to `~/.gstack/projects/<slug>/`. `/plan-ceo-review` reads it. `/plan-eng-review` adds architecture and a test plan. `/qa` picks up the test plan and exercises the live site in a real Chromium browser. `/review` finds the bugs that pass CI. `/ship` runs tests, opens a PR, and verifies coverage. `/land-and-deploy` merges, waits for CI, watches production. `/retro` summarizes the week and feeds growth opportunities back into next week's `/office-hours`.

The state survives sessions. The output of every skill is durable. That is what makes gstack a sprint rather than a chat.

![A horizontal flow diagram in cream and red of seven labeled gear-stages, Think, Plan, Build, Review, Test, Ship, Reflect, connected left-to-right, with a small red feedback arrow looping from Reflect back to Think, illustrating the gstack sprint cycle](/post-images/2026-05-23-gstack-garry-tan-claude-code-developer-guide/01-sprint-loop.jpg)

# 2. Why gstack exploded

Three things made the launch trajectory possible.

**First, the credentials.** Garry runs Y Combinator. He cofounded Posterous (acquired by Twitter), was one of the first eng/PM/designers at Palantir, built Bookface (YC's internal social network) himself in 2013, and now writes the Y Combinator partner posts on AI. When a YC president personally publishes the exact skill pack he uses to ship code, three constituencies pay attention in the same week: YC founders, prospective YC founders, and the much larger group of developers who follow YC content.

**Second, the timing.** Anthropic's Claude Code shipped in early 2025 and crossed inflection in Q4 2025–Q1 2026 as Skills (Markdown files in `.claude/agents/skill.md`) became the canonical packaging unit for AI coding knowledge. By March 2026, the format was a year old and every viral how-to was telling you to write your own skill pack. gstack arrived as a *complete* skill pack from a name brand, free, MIT-licensed.

**Third, the framing.** Garry's launch tweet did not say "I made some markdown files." It said: *\"I've been having such an amazing time with Claude Code, I wanted you to be able to have my exact skill setup.\"* The implicit promise, *this is what the YC president uses to ship YC's own products*, does a lot of marketing work that 33 Markdown files would not do unaided.

The combination produced the curve below. Twenty thousand stars in days. Seventy-five thousand stars in five weeks. One hundred one thousand stars in ten. Forks at 15,047, meaning more than fifteen thousand developers have copied the repo to modify for themselves.

# 3. The launch in numbers

Per Garry's [April 18, 2026 disclosure](https://x.com/garrytan/status/2045404377226285538), quoted verbatim below, gstack's adoption metrics at the v1.0 release mark:

> gstack is not a hypothetical. It's a product with real users:
> 75,000+ GitHub stars in 5 weeks
> 14,965 unique installations (opt-in telemetry, so real number is at least 2x higher)
> 305,309 skill invocations recorded since January 2026
> ~7,000 weekly active users at peak
>
> — [@garrytan](https://x.com/garrytan/status/2045404377226285538), April 18, 2026

| Metric | At v1.0 (Apr 18) | Today (May 23) |
|---|---:|---:|
| GitHub stars | 75,000+ | **101,020** |
| Forks | n/d | **15,047** |
| Watchers (subscribers) | n/d | 614 |
| Open issues | n/d | 563 |
| Unique installations (telemetry, opt-in floor) | 14,965 | n/d publicly |
| Skill invocations | 305,309 | n/d publicly |
| Peak weekly active users | ~7,000 | n/d publicly |

🟡 The growth rate (4,200+ stars per week net through May) is consistent with continued strong adoption. Garry's telemetry is opt-in only, so the public installation count is a floor, the actual number is at least 2x by his own caveat.

That 305,309-invocation number is the load-bearing fact. **It is the only AI-coding skill pack of this scale with verifiable usage data attached.** Most viral "Claude Code skills" repos publish a `README.md` and a star count and stop there. gstack publishes the operational data through `gstack-analytics`, an opt-in telemetry pipeline routed through Supabase row-level-security policies that block direct access, anyone can [audit the schema in `supabase/migrations/`](https://github.com/garrytan/gstack/blob/main/supabase/migrations/004_attack_telemetry.sql) and verify what's collected.

# 4. The sprint, end to end

The reading sequence that follows treats the skills in the order a sprint actually runs them. If you install gstack and want to use it correctly, you run them this way:

| Phase | Skills | What you produce |
|---|---|---|
| **Think** | `/office-hours` | A design doc anchored in real user pain |
| **Plan** | `/plan-ceo-review`, `/plan-eng-review`, `/plan-design-review`, `/plan-devex-review`, `/design-consultation`, `/autoplan` | An architecture-locked, design-system-aligned, test-planned doc |
| **Build** | `/design-shotgun`, `/design-html`, in-session implementation | Working code + production-grade HTML/CSS |
| **Review** | `/review`, `/investigate`, `/design-review`, `/devex-review`, `/codex` | Caught bugs + verified fixes + slop-scrubbed design |
| **Test** | `/qa`, `/qa-only`, `/browse`, `/open-gstack-browser`, `/pair-agent`, `/benchmark`, `/canary`, `/setup-browser-cookies` | Real-browser-tested flows with regression coverage |
| **Ship** | `/ship`, `/land-and-deploy`, `/setup-deploy` | Merged PR, deployed code, verified production health |
| **Secure / Doc / Reflect** | `/cso`, `/document-release`, `/document-generate`, `/retro`, `/learn` | OWASP+STRIDE audit, fresh docs, weekly retro, persistent memory |

🟢 The point of running them in order is that *state passes forward*. Skipping `/office-hours` and going straight to `/plan-eng-review` means the eng review has no product framing to challenge. Skipping `/plan-eng-review` and going straight to `/ship` means the test plan was never written, and `/qa` has nothing to pick up. The skills are scored on the assumption that the ones upstream of them ran.

What follows is the complete reference, phase by phase, every skill with three usage examples drawn from real founder, staff-engineer, DX-lead, designer, SRE, and consultant workflows.

![Six rounded geometric blobs arranged across cream paper, each containing a cluster of charcoal-ink dots labeled by sprint phase (Think, Plan, Build, Review, Test, Ship), with two dots in the Review cluster highlighted in red to mark the cross-model review pair (/review and /codex)](/post-images/2026-05-23-gstack-garry-tan-claude-code-developer-guide/03-skill-clusters.jpg)

# 5. Phase 1, Think and Plan

![A small round meeting table drawn in charcoal ink on cream paper, with five empty geometric chairs arranged around it, each chair tagged with a folded paper place-card labeled CEO, Eng, Designer, Sec, PM; in the center sits a single sheet of paper representing the design doc, and a single editorial red ink ring marks the CEO place-card](/post-images/2026-05-23-gstack-garry-tan-claude-code-developer-guide/07-think-plan-roundtable.jpg)

## /office-hours

This is the **YC Office Hours specialist**, where every new project should start. Before you plan, before you write code, you sit down with a YC-style partner who asks about *pain*, not feature requests, and then pushes back on your framing. Two modes: **Startup mode** runs six forcing questions (demand reality, status quo, desperate specificity, narrowest wedge, observation, future-fit); **Builder mode** is generative for hackathons and side projects. Output is a design doc written to `~/.gstack/projects/<slug>/` that every downstream skill reads.

**Three examples:**

1. You're a founder who says: \"I want to build a daily briefing app for my multi-Google-Calendar mess.\" You type `/office-hours`. The skill asks for specific pain. You describe stale event info, AI-slop prep docs, wrong locations. It comes back: *\"I'm going to push back on the framing. You said 'daily briefing app.' What you actually described is a personal chief of staff AI.\"* It extracts five capabilities, presents four falsifiable premises, and recommends shipping Approach A. The design doc lands at `~/.gstack/projects/chief-of-staff-ai/`.

2. You're a staff engineer prototyping an internal \"code search\" tool for your platform team. You run `/office-hours` in Builder mode. Instead of interrogation, you get an enthusiastic collaborator: \"What would make a teammate say *whoa*?\" It proposes embedding-based semantic search + a one-key keyboard shortcut + Slack share-as-permalink. The design doc lands in `~/.gstack/projects/codesearch/` and `/autoplan` picks it up automatically when you switch to building.

3. You're a designer-founder considering a Notion competitor. You type `/office-hours` and answer \"the pain is sluggish multi-cursor editing on 50-page docs.\" The skill challenges premise #3, \"narrowest wedge is a daily-active product, not a doc tool\", and presents three implementation paths with effort estimates (M / L / XL in both human-weeks and CC-days). You disagree with premise 3 in writing; it adjusts the doc and recommends Approach A anyway, with your dissent recorded.

🔴 **Don't use** for clearly scoped infrastructure fixes (\"upgrade Postgres 14→16\"); there is no product reframing to do.

## /plan-ceo-review

This is **Brian Chesky / founder mode**. After `/office-hours` writes the design doc, `/plan-ceo-review` re-reads the problem from the user's point of view and asks: *what is the 10-star product hiding inside this request?* It runs in four modes: **SCOPE EXPANSION** (dream big, recommend enthusiastically), **SELECTIVE EXPANSION** (current scope as baseline, surface opportunities with neutral recommendations), **HOLD SCOPE** (keep what's there, polish only), and **REDUCTION** (cut). Every expansion is justified or explicitly cut. Output: a revised plan + a decisions log.

**Three examples:**

1. You're a founder reviewing your `/office-hours` plan for a \"saved searches\" feature. You run `/plan-ceo-review` in SELECTIVE EXPANSION. It surfaces five candidate opportunities one at a time, shareable searches, scheduled re-runs, slack notifications, search-as-RSS, search-as-API. You accept the first three with one-line rationales, reject the API, defer RSS. The plan is now scoped, with five line-item decisions in the log.

2. You're a tech-lead shipping pre-IPO compliance work. You run `/plan-ceo-review` in HOLD SCOPE. It refuses to add anything; instead it sharpens the existing items, *audit log* becomes *audit log with append-only Postgres `INSERT ON CONFLICT DO NOTHING` and a per-row HMAC*. Same surface area, twice the rigor.

3. You're a CTO doing a quarterly product review. You point `/plan-ceo-review` at your roadmap in REDUCTION mode. It cuts three items that compete with each other for the same persona, marks two as \"keep but downsize,\" and lands a sharper one-line product mission. You bring the diff to the next leadership meeting.

## /plan-eng-review

This is the **Eng Manager** specialist. It locks architecture before code. ASCII diagrams for data flow, state machines, error paths. A test matrix. Failure modes. Security concerns. The skill forces hidden assumptions into the open: *\"You said 'idempotent.' By idempotent do you mean (a) same-request-same-response, or (b) safe-to-retry-on-network-failure?\"* Either acceptable; ambiguity is not. Output: a doc that engineers can implement without re-asking the founder.

**Three examples:**

1. You wrote a `/office-hours` doc for a checkout flow. You run `/plan-eng-review`. It produces a state machine (cart → reserve → charge → fulfill → notify) with three error paths each, identifies the idempotency boundary at `reserve`, requests a 3-table data model, surfaces a *time-of-check / time-of-use* race in the inventory step, and writes a 14-row test matrix covering it. The plan is now implementable.

2. You're a junior engineer planning an OAuth integration. You run `/plan-eng-review`. It draws the OAuth handshake as a four-actor sequence diagram, names every secret that touches disk, flags the missing PKCE flow, and prescribes a refresh-token rotation policy. Three architectural decisions made before you write a single line.

3. You're refactoring a queue worker. `/plan-eng-review` traces the data flow, identifies that the current implementation depends on at-most-once semantics but the new requirement needs exactly-once, and prescribes a database-backed dedupe key. It writes the migration as part of the plan.

## /plan-design-review

The **senior designer** for plan-stage design work. Rates each design dimension 0-10, explains what a 10 looks like, then edits the plan to get there. Six passes, IA, interaction states, visual hierarchy, AI slop, design-system alignment, accessibility. **AI Slop detection** flags the top patterns (3-column icon grid, gradient hero, uniform 12px radius, centered body, generic \"Get Started\" buttons). Interactive, one `AskUserQuestion` per design choice, so taste decisions stay with the human.

**Three examples:**

1. You're a designer who just wrote a 4-screen dashboard plan. You run `/plan-design-review`. Initial rating: 4/10. Pass 2 (Interaction States) scores 2/10, \"4 features × 5 states = 20 states; you specified 0.\" Pass 4 (AI Slop) scores 4/10, \"*clean modern UI with cards and icons* and *hero with gradient* are the top two AI-tell patterns.\" The skill adds an interaction-state table, rewrites the hero spec as \"single 96px headline in Instrument Serif, no gradient, asymmetric image right.\" Final: 8/10.

2. You're a backend engineer writing a plan for a billing settings page. You don't know what \"good\" looks like. `/plan-design-review` rates IA at 3/10 and writes the primary/secondary/tertiary content hierarchy itself: subscription state on top, plan switcher in the middle, payment method + invoices below. It asks one AskUserQuestion: \"Pause vs Cancel, same row or separate sections?\" You pick separate. Plan moves to 7/10 with one taste decision recorded.

3. You're a PM iterating on a doc you've already revised. You re-run `/plan-design-review`. Pass 1 (IA) is already at 9/10, quick pass, no edits. Pass 5 (Design-System Alignment) drops to 6 because you added a new \"warning toast\" pattern that isn't in `DESIGN.md`. The skill asks: \"Add `toast` to the design system or use existing `banner`?\" You pick banner. Three-second decision, plan stays aligned.

## /plan-devex-review

The **Developer Experience Lead** for plan-stage DX work. Interactive review for any developer-facing surface, an API or CLI or SDK or library or platform or docs site. Three modes: **DX EXPANSION** (build a competitive advantage), **DX POLISH** (bulletproof every touchpoint), **DX TRIAGE** (only critical gaps). Asks 20–45 forcing questions: who are the developer personas, what's competitors' **TTHW** (time-to-hello-world), what's *your* magical moment, where does each persona hit friction in the first five minutes.

**Three examples:**

1. You're the DX lead at a YC API startup planning v2 of your auth SDK. You run `/plan-devex-review` in EXPANSION mode. It benchmarks against Clerk, Auth0, and WorkOS, pulls their actual TTHW numbers via WebSearch, and finds yours at 12 minutes vs competitors' 4. It traces the friction: `npm install` → 3 env vars → 2 callback handlers → 1 webhook setup. It rewrites the plan to ship a single `npx @yourco/auth init` that scaffolds all four steps. New target: 90 seconds.

2. You're an open-source maintainer about to ship a 1.0 of a CLI. `/plan-devex-review` in POLISH mode asks: \"On `--help`, what's the first thing a developer sees?\" You don't know. It mocks two options, a tour-style ASCII GIF vs a curated 5-command quick-start, and lets you pick. Then it audits error messages: \"your current error `ERR_INVALID_CONFIG` has no remediation. A 10/10 message has *what failed*, *why*, and *the next command to run*.\"

3. You're a staff engineer adding GraphQL to an existing REST API. You run `/plan-devex-review` in TRIAGE mode, you only have 2 hours. It returns three critical gaps: no introspection examples in docs, no playground link in the readme, no error-mapping table. It edits the plan to add all three and exits. No 45-question interrogation.

🔴 **Don't use** for internal-only tooling with one user (yourself). The persona analysis won't earn its keep.

## /design-consultation

The **design partner** for greenfield projects. While `/plan-design-review` audits an existing design, `/design-consultation` is for when you have *nothing yet*, no `DESIGN.md`, no font choices, no color palette. Conversational. It asks about your product, users, and what you want to communicate (trust, speed, craft, warmth), then builds a coherent design system from zero, aesthetic direction, typography (3+ fonts with specific roles), color palette with hex values, spacing scale, layout approach, motion strategy. The load-bearing move: it proposes **safe choices AND deliberate creative risks**, and labels each. After approval it generates an interactive HTML preview with realistic mockups, then writes `DESIGN.md` and updates `CLAUDE.md`.

**Three examples:**

1. You're a solo founder starting an analytics dashboard for engineering teams. You type `/design-consultation`. It asks to research the landscape and browses the four reference apps you name (Linear, Vercel, Datadog, Posthog). Report: \"they all converge on clean sans-serifs and muted blue-grays.\" It proposes Geist + Instrument Serif + JetBrains Mono, slate neutrals, a single teal accent (#0D9488), 4px spacing base. It flags Instrument Serif as a *risk* (\"nobody in dev tools uses a serif\"). You take the risk. It generates a preview dashboard at `/tmp/design-consultation-preview-*.html` and writes DESIGN.md.

2. You're a designer onboarding to a B2B SaaS rebrand. You run `/design-consultation` and say \"make it feel like Stripe, but for healthcare.\" It proposes a restrained palette of off-whites + a desaturated forest green, Söhne for UI, Tiempos for editorial, and pushes back on your \"make it feel like Stripe\" request: \"Stripe's restraint signals *finance trust*. For healthcare you want *competence + warmth*. Söhne is too cold; consider GT America.\" You accept the swap.

3. You're an indie hacker shipping a writing app for novelists. `/design-consultation` proposes Lyon Display + Söhne Buch + a single sepia accent, asymmetric layouts, motion only on save-confirmation. It generates the preview as a fake novel-writing surface (sidebar with chapters, center text in 18px Lyon at 680px max-width). You approve. DESIGN.md commits with `risks: asymmetric layouts in a category that defaults to symmetry`.

## /autoplan

The **review pipeline autopilot**. Running CEO + design + eng + DX reviews individually means answering 15–30 intermediate questions. `/autoplan` reads all four review skills from disk and runs them sequentially with auto-decisions, using six encoded principles: prefer completeness, match existing patterns, choose reversible options, prefer the option you chose for similar past decisions, defer ambiguous items, escalate security. Taste decisions (close approaches, borderline scope expansions, cross-model disagreements with `/codex`) get saved and presented at a final approval gate. One command, fully reviewed plan out.

**Three examples:**

1. You're shipping ten parallel sprints in Conductor. You hate stopping every two minutes. You run `/autoplan` on a plan for a new \"saved searches\" feature. It runs CEO → Design → Eng (DX skipped, no developer surface), auto-resolves 9 decisions (3 scope, 3 design, 3 eng), and surfaces 2 taste decisions: \"Codex suggested adding shared-team-searches, borderline expansion. Add?\" and \"Two empty-state copy options scored within 1 point.\" You answer both in 30 seconds. Plan complete.

2. You're a founder who keeps over-thinking. You point `/autoplan` at a plan for a chat feature. It auto-defers 4 items as ambiguous (model choice, rate-limit cap, retention period, abuse policy) and escalates 1 security item to you (PII handling in logs). The plan ships with explicit `DEFERRED: 4 items, see ~/.gstack/projects/$SLUG/deferred.md`.

3. You're a tech lead reviewing a junior engineer's plan. You run `/autoplan` instead of doing it yourself. The principles bias toward \"match existing patterns\" so when the junior proposed a brand-new ORM, the pipeline pushes back: \"Repo uses Drizzle; the codebase has 47 query files. Switching adds 3-week cost for unclear benefit. Recommendation: stay on Drizzle.\" Junior sees the reasoning, learns something.

🔴 **Don't use** when you actually want to think through decisions interactively. `/autoplan` is for when you trust the principles.

# 6. Phase 2, Build and Design

![A vertical cascade of three abstract device frames on cream paper, drawn as simple charcoal-ink rectangles in descending widths from desktop to tablet to mobile, with thin ink arrows between them showing the same content reflowing downward, and a single short ink line shaded solid editorial red in the mobile frame at the bottom](/post-images/2026-05-23-gstack-garry-tan-claude-code-developer-guide/08-build-design-cascade.jpg)

## /design-shotgun

The **design explorer**. You have a feature, page, or landing screen, and you're not sure what it should look like. One AI answer is one perspective; design is a taste game and you need to *see* options. `/design-shotgun` generates 3–6 visual design variants via the GPT Image API, opens a side-by-side comparison board in your browser, and waits for feedback. You approve, request changes, or ask for a fresh round. Reads `DESIGN.md` for brand constraints. **Taste memory** persists across sessions, the system learns from your approvals (decays 5%/week via `gstack-taste-update`). Output `approved.json` feeds `/design-html` directly.

**Three examples:**

1. You're a founder stuck on the hero section for a dev-tools landing page. You type `/design-shotgun, hero section for developer tools landing`. It generates: A) bold typography + dark + code-snippet hero, B) split layout with product screenshot, C) minimal centered headline with gradient accent. The comparison board opens at `localhost:PORT`. You click \"Approve\" on A. The file lands at `~/.gstack/projects/myapp/designs/`. Next: `/design-html`.

2. You're a designer iterating on a paywall screen. First shotgun returns 4 variants. None feel right. You leave feedback: \"more whitespace, lose the gradient, headline should feel like a manifesto not a sales pitch.\" Second round biases toward editorial layouts (taste memory kicking in). Third round nails it. Approved variant ships with `taste-profile.json` updated: `layout=editorial +1, gradient=rejected`.

3. You're a PM exploring an empty-state for a \"no projects yet\" screen. You run `/design-shotgun` and ask for 6 variants. Half look like Linear, half look like Notion. You approve a Notion-style with a single illustrated character. Three weeks later when you run `/design-shotgun` on a different empty-state, the system biases toward illustrated characters because your taste profile remembers.

## /design-html

The **design-to-code engineer**. Every other AI codegen tool produces static CSS, hardcoded heights, text that overflows at every viewport that isn't the one it was generated at. `/design-html` generates HTML using [Pretext](https://github.com/chenglou/pretext) (Cheng Lou's 15KB layout-without-DOM-measurement library). Text reflows, heights adjust to content, cards size themselves. Layout-aware API routing per design type: simple layouts use `prepare()+layout()`, chat UIs use `walkLineRanges()`, editorial uses `layoutNextLine()`. Inputs: `/design-shotgun` approved mockup, CEO plan, design-review context, raw PNG, or just a description. Framework detection (React/Svelte/Vue) outputs proper components. Refinement loop: live-reload server + 3-viewport screenshots, then surgical edits via the Edit tool.

**Three examples:**

1. You approved a hero variant via `/design-shotgun`. You type `/design-html`. It reads `approved.json`, picks `prepare()+layout()` (simple layout type), generates a self-contained HTML with Pretext inlined (15KB, zero network deps), opens live-reload at `localhost:3456`, and screenshots at 375/768/1440. Text reflows perfectly. You ask: \"make the headline bigger and add more spacing below the CTA.\" It edits two CSS values. Done.

2. You're a React engineer. You point `/design-html` at a Figma screenshot of a chat UI. It detects `package.json` → React, picks `walkLineRanges()` for chat-bubble tight-fit, generates a `<ChatMessage>` component, runs `npm install @chenglou/pretext`, screenshots at 3 viewports. Chat bubbles shrinkwrap perfectly. No wasted padding even on one-character messages.

3. You don't have a mockup, just a CEO plan that says \"build a settings page with profile, billing, and team sections.\" You run `/design-html`. It uses the plan as the spec, picks card-grid pattern, and generates a self-sizing layout where the team-members card grows tall when there are 12 members and shrinks when there are 2. No `min-height` hack.

# 7. Phase 3, Review and Debug

![A large charcoal-ink magnifying glass tilted at an angle on cream paper, with several short hash-marks of code visible through its lens and one of them shaded solid editorial red marking the bug; to the left, four small geometric reviewer silhouettes tagged Claude, Codex, Gemini, Auto, representing the cross-model review pair](/post-images/2026-05-23-gstack-garry-tan-claude-code-developer-guide/09-review-magnifier.jpg)

## /review

The **paranoid staff engineer**. Passing tests do not mean the branch is safe. `/review` exists for the class of bugs that survive CI and blow up in production: N+1 queries, stale reads, race conditions, bad trust boundaries, missing indexes, escaping bugs, broken invariants, bad retry logic, tests that pass while missing the real failure mode, and **forgotten enum handlers** (add a new status constant, it traces every switch and allowlist in the codebase). Fix-First philosophy: obvious mechanical fixes are auto-applied (`[AUTO-FIXED] file:line`); ambiguous issues are surfaced. Flags completeness gaps where the 100% solution is < 30 minutes of CC time away. Greptile-aware.

**Three examples:**

1. You just merged `feat: smart listing flow` locally and run `/review`. The skill flags: an N+1 in `renderListingPhotos`, client-trusted file metadata, a missing advisory lock around `setHeroImage` allowing two-tab races, orphaned-files-on-failure-upload, and a *prompt injection* path because draft text pulls from scraped web pages. It auto-fixes the N+1 and the dead code; asks you about the race-condition strategy (advisory lock vs select-for-update).

2. You added a new `OrderStatus.RETURN_INITIATED` enum value. You run `/review`. It greps for every `switch (status)` and every allowlist in your repo, finds 11 of 13 handlers got updated and 2 didn't (`email-templates.ts:88` and `analytics-events.ts:124` will silently no-op for the new status). It applies the missing branches automatically and commits with attribution.

3. You're shipping a payment endpoint. `/review` reads Greptile comments off the PR, classifies them, and shows: 1 VALID (race condition, concurrent charges can double-debit), 1 ALREADY-FIXED (handled in commit `abc1234`, auto-replied to Greptile), 1 FALSE POSITIVE (you already use `ActiveSupport::SecurityUtils.secure_compare`). You approve the auto-reply and apply the race-condition fix.

## /investigate

The **systematic debugger**. When something is broken and you don't know why, `/investigate` follows the **Iron Law: no fixes without root cause investigation first**. It traces data flow, matches against known bug patterns, tests hypotheses one at a time. After three failed fix attempts, it stops thrashing and questions the architecture instead. Auto-activates `/freeze` on the directory being investigated so it cannot accidentally \"fix\" unrelated code. Prevents the \"let me try one more thing\" spiral that wastes hours.

**Three examples:**

1. Production billing is double-charging some users. You type `/investigate src/billing` and paste a Sentry stack trace. It auto-freezes edits to `src/billing/`, traces the data flow from `POST /charge` through the queue to Stripe, hypothesizes (a) idempotency-key not set, (b) retry without dedupe, (c) clock skew. Tests (a) first by replaying the production payload, confirmed. Writes the fix as `idempotency_key = \"charge:#{order.id}:#{order.updated_at.to_i}\"`.

2. A user reports \"the dashboard chart is empty on Tuesdays.\" You run `/investigate`. The skill resists the urge to add a default-empty-state. It greps for \"Tuesday\", nothing. It greps for `getDay()`, finds a bug where `getDay() === 0` (Sunday) was treated as \"today\" but the function fed into Tuesday's aggregation. Root cause first, fix second.

3. CI started flaking on `auth.test.ts:142`. You run `/investigate`. It runs the test 50× locally, finds a race between the JWT clock-skew tolerance (5s) and a hardcoded `setTimeout(4900)` in the fixture. After 3 fix attempts fail, it stops and asks: \"the test fixture timing is fundamentally fragile, should we replace the timing test with a deterministic clock mock?\" You approve. No fourth flaky retry.

🔴 **Don't use** when you already know the root cause and just need to ship the fix.

## /design-review

The **designer who codes**. `/plan-design-review` audits the plan; `/design-review` audits and fixes the **live site**. 80-item visual audit on the URL you point it at, then a fix loop: each finding → locate source file → minimal CSS/style change → `git commit -m \"style(design): FINDING-NNN ...\"` → reload and verify → before/after screenshots. One commit per fix, fully bisectable. Self-regulation: CSS-only edits are free; JSX/TSX edits count against the risk budget. Hard cap of 30 fixes per run; stops at 20% risk score and asks.

**Three examples:**

1. You're a designer auditing your own staging site. You type `/design-review https://staging.myapp.com`. It scores **Design: C, AI Slop: D**, finds 12 issues. It applies 9 atomic commits in order, replacing the 3-column icon grid with asymmetric, adding a heading scale 48/32/24/18/16, killing the gradient hero, varying border-radius by element role. Final scores: **Design B+, AI Slop A**. Report and 9 before/after screenshots saved to `.gstack/design-reports/`.

2. You're a frontend lead enforcing design-system compliance pre-launch. `/design-review` on production catches a `border-radius: 12px` on a button that's supposed to be `8px` per DESIGN.md, a `font-size: 17px` that drifted from the 16/18 scale, and a missing `prefers-reduced-motion` block. All three commit as separate findings; you cherry-pick what to ship.

3. You're shipping a marketing site and the AI-slop score is a personal red line. You run `/design-review https://launch.myapp.com`. The skill finds five AI-tell patterns: hero gradient, uniform 12px radius, centered body text, \"Get Started for Free\" button, identical card columns. It rewrites all five and the AI-slop score moves D → A. You ship knowing it doesn't look like every other Vercel template.

## /devex-review

The **live developer experience auditor**. Where `/plan-devex-review` reviews the plan, `/devex-review` walks the **actual onboarding flow** like a new developer would: walks docs, runs the getting-started commands, times TTHW, screenshots every error message, audits the first 5 minutes. Generates a scorecard with evidence. The \"boomerang\" feature: if `/plan-devex-review` ran earlier and predicted 3-minute hello-world, `/devex-review` shows whether reality matched. Use after shipping any developer-facing surface.

**Three examples:**

1. You shipped a v2 SDK last week. You run `/devex-review https://docs.yourco.com/quickstart`. The skill installs the SDK in a clean directory, follows the quickstart literally, times TTHW at 7 minutes (vs the planned 3), and surfaces the gap: \"step 4 says `set MYAPP_API_KEY` but the actual env var is `MYAPPAPI_KEY`. One missing `_`.\" Trivial fix; massive friction removed.

3. You're a DX engineer auditing a competitor. `/devex-review https://competitor.com/start` produces a public scorecard you'd never have written manually. It captures that their `init` command needs `sudo`, their first error message has no remediation, and their getting-started has no copy button. You ship a comparison post.

3. You're at v0.4 and the docs are sparse. `/devex-review` runs the quickstart, fails at step 2 (a missing dependency the docs didn't list), and writes a Diataxis-shaped how-to that fills the gap. The skill chains directly to `/document-generate` to ship the doc.

## /codex

The **second-opinion AI**. Reads the same branch `/review` reads but runs OpenAI Codex CLI instead of Claude. Three modes: **review** (pass/fail gate with concrete findings), **adversarial challenge** (actively tries to break your code), and **open consultation** (free-form). When both `/review` (Claude) and `/codex` (OpenAI) have reviewed the same branch, gstack produces a cross-model analysis showing which findings overlap and which are unique to each model. Catches the \"both models agreed on a wrong assumption\" failure mode.

**Three examples:**

1. You just ran `/review` and it passed. You're shipping payments. Risk threshold: cross-model approval. You run `/codex`. Codex finds an additional issue Claude missed, a timing side-channel in a string-compare on auth tokens. You apply the fix; ship with both reviewers green.

2. You're a contractor reviewing a YC company's pre-acquisition code. You run `/codex` in adversarial mode on the auth module. It tries injection payloads, malformed JWTs, replay attacks. Finds two real bugs, writes them up. You hand the report to the acquirer.

3. You're stuck on a design decision and want a second model's take without writing a long prompt. `/codex` in open consultation mode preserves session continuity across follow-ups. You converse with Codex about an architectural tradeoff; the final recommendation goes into your design doc.

🟡 **Note:** Requires OpenAI Codex CLI authenticated. The `gstack-model-benchmark` standalone (Section 12) also covers cross-model runs, but `/codex` is for a single branch review.

# 8. Phase 4, Test

![A central charcoal-ink browser window outline on cream paper, surrounded by five smaller geometric viewport rectangles of varying sizes arranged in a loose orbit, each connected to the browser by a thin ink hairline, with one of the small viewports containing a single editorial red dot at its center marking the bug found by QA](/post-images/2026-05-23-gstack-garry-tan-claude-code-developer-guide/10-test-qa-viewports.jpg)

## /qa

The **QA Lead** specialist. Test your app, find bugs, fix them with atomic commits, re-verify. Auto-generates regression tests for every fix so the bug never returns silently. Runs in a real Chromium browser via the `/browse` daemon (Section below), real clicks, real screenshots, real network. Reads any test plan from `/plan-eng-review` if present. Outputs a structured bug report + per-bug commits + a regression test file.

**Three examples:**

1. You shipped a checkout feature to staging. You run `/qa https://staging.myapp.com`. The skill clicks through the cart → checkout → payment flow, finds three bugs (a JS console error on the address page, a misaligned summary row at 375px, and a 500 on submit-without-CVV). It fixes all three with atomic commits, generates regression tests at `tests/regression/checkout-{1,2,3}.spec.ts`, re-runs the flow clean.

2. You're shipping a new sign-up flow on production behind a feature flag. `/qa https://app.com?ff=newsignup` exercises the new flow with cookies imported via `/setup-browser-cookies`. It finds an off-by-one in the email-verification step and an a11y violation in the password strength meter; ships both fixes.

3. You're a tech lead enforcing a \"every PR runs `/qa`\" policy. The skill picks up the PR branch automatically via `git status`, finds two issues, opens a draft PR comment with the screenshots and proposed fixes, asks the author to accept.

## /qa-only

Same methodology as `/qa` but **report only**. No code changes, no commits, no fixes. Use when you want a pure bug report, for stakeholders, contractors, security audits, or when the codebase isn't yours to modify.

**Three examples:**

1. You're a contractor auditing a client's app pre-acquisition. You run `/qa-only https://client.com`. Returns a 23-bug PDF-shaped report. You attach it to the acquisition memo; no client code touched.

2. You're a PM filing a bug report to your eng team. `/qa-only` documents the repro steps, captures screenshots, and writes it Jira-shaped. Your engineers triage from the report instead of you describing it in Slack.

3. You're testing a competitor's site for a benchmarking post. `/qa-only https://competitor.com/signup` produces a public-shareable bug catalog. You publish it as part of a Twitter thread.

## /browse

**Real Chromium browser eyes for the agent.** `~100ms per command` headless daemon. Real clicks, real screenshots, real network. The `$B` alias gives the agent every primitive: `nav`, `click`, `screenshot`, `fill`, `scroll`, `wait-for-selector`, `eval`, `intercept-requests`. Anti-bot stealth defaults on (sites like Google work without captchas). Daemon survives between skills so context (cookies, viewport, tabs) persists. Foundation primitive that `/qa`, `/canary`, `/benchmark`, `/design-review` all sit on top of.

**Three examples:**

1. You're scraping a one-off page that doesn't justify a full `/scrape` codification yet. You ask Claude to use `$B` directly: `$B nav https://news.ycombinator.com; $B screenshot; $B eval 'document.querySelectorAll(\".storylink\").length'`. ~300ms total. Result lands in chat.

2. You're debugging why your e-commerce site loads slowly. You ask Claude to walk the page with `$B` and report timings. It captures network waterfall, screenshots the LCP, identifies a 2.4MB hero image, and proposes a fix.

3. You're shipping a feature with a flaky UI behavior. You use `$B` interactively across a five-minute session to reproduce the bug, click, screenshot, click, screenshot. The agent uses the sequence to identify the race.

## /open-gstack-browser

**GStack Browser**, an AI-controlled Chromium with anti-bot stealth, custom branding, and a sidebar extension baked in. The menu bar says \"GStack Browser\" instead of \"Chrome for Testing.\" Sidebar agent (Sonnet for fast actions, Opus for analysis, auto-routed) takes natural-language instructions in a Chrome side panel, *\"open the settings page and screenshot it\"*, *\"fill the form with test data\"*, *\"extract the prices from this list.\"* Each task gets up to 5 minutes. Isolated session, separate from your main Claude Code agent.

**Three examples:**

1. You're testing a feature that requires a real-browser session. You type `/open-gstack-browser`. Chromium opens. You log into your staging site once. The session persists. You drop back to Claude Code, type `/qa`, and the QA agent uses the same authenticated browser without re-logging-in.

2. You're doing personal automation. From the sidebar: *\"Browse my kid's school parent portal and add all the other parents' names, phone numbers, and photos to my Google Contacts.\"* Sidebar agent walks the directory, extracts the data, creates the contacts. Anti-bot stealth keeps the school portal from blocking.

3. You hit a CAPTCHA mid-task. The sidebar agent automatically suggests `$B handoff`, opens a visible Chrome at the same page with all your cookies and tabs intact. You solve the CAPTCHA, type `$B resume`. The agent picks up exactly where it left off.

## /pair-agent

**Multi-agent browser coordinator.** You're in Claude Code. You also have OpenClaw or Hermes or Codex running. You want them both looking at the same website. `/pair-agent` opens a GStack Browser window, prints a setup block, and exchanges a one-time setup key for a session token. Paste the block into the other agent's chat. Each agent gets its own tab. You see both agents working in the same browser, attributed by tab color and activity log. Scoped tokens, tab isolation, rate limiting.

**Three examples:**

1. You're debugging a flaky test that only one model reproduces. You `/pair-agent` and ask both Claude (in Claude Code) and Codex (separately) to repro the same flow. Codex hits the flake; Claude doesn't. You inspect the activity log to find the divergence, Codex clicked faster than the form's debounce.

2. You're benchmarking two AI agents on the same web-research task. Both share a GStack Browser instance. You watch them split, Claude opens five tabs of academic papers; Codex stays on Google Scholar three tabs deep. Different research strategies, same starting URL.

3. You're a tech lead training a junior engineer who's using a different AI. `/pair-agent` lets you watch their agent work. You intervene in your own tab when they hit a dead end. The pairing produces a shared activity log you can post-mortem together.

## /benchmark

The **performance engineer**. Baseline page load times, Core Web Vitals (LCP, INP, CLS), and resource sizes. Compare before/after on every PR. Track trends over time. Stores baselines in `.gstack/benchmark/` per-page. Re-runs after every deploy. Flags regressions exceeding configurable thresholds (default: 10% LCP, 100ms INP, 0.05 CLS).

**Three examples:**

1. You're about to ship a refactor that touches the home page. You run `/benchmark` before and after. Before: LCP 1.8s, INP 90ms. After: LCP 2.3s, INP 240ms. Regression flagged. You investigate the INP spike, turns out a new effect runs on every scroll. You debounce it. Re-benchmark: INP 80ms.

2. You're a perf engineer auditing a CRM dashboard. `/benchmark` baselines the 6 most-visited pages, captures Core Web Vitals + 3 custom metrics (TTFB, total bundle size, # of fonts). Six baselines stored. Every weekly deploy compares against them. Trend graph emitted to `.gstack/benchmark/trends.html`.

3. You're shipping a marketing site. `/benchmark` flags that the hero image is 2.4MB. You optimize to 220KB. Re-benchmark: LCP 1.2s → 0.6s. The before/after PNG diff goes in the PR description.

## /canary

The **SRE**. Post-deploy monitoring loop. Watches your production site for console errors, network failures, performance regressions, and page failures for a configurable window (default: 30 minutes after deploy). Uses the `/browse` daemon. Pings your `#deploys` Slack channel if anything regresses. Stops after the window unless you re-arm it.

**Three examples:**

1. You just ran `/land-and-deploy`. Your CI is green; production is live. `/canary` auto-starts a 30-min watch on your top 5 routes. 12 minutes in, it detects a JS error on `/dashboard` (a third-party script timing out). It pings Slack with the stack trace and the diff that introduced the dependency.

2. You're rolling out a feature flag to 10% of traffic. You run `/canary --routes /checkout --window 60m`. For an hour it watches checkout, finds no regressions, exits clean. You bump the flag to 25%.

3. You're on call and a deploy went out 90 minutes ago. You re-run `/canary --window 60m` retroactively against logs. It identifies that the deploy regressed `/profile/edit` (a 500 error rate spike from 0.01% → 1.2%), correlates to the commit, opens an incident.

## /setup-browser-cookies

The **session manager**. Imports cookies from your real browser (Chrome, Arc, Brave, Edge) into the gstack headless session so you can test authenticated pages. Picks the cookies for one specific domain so you don't leak everything. Handles browser-specific encrypted-storage formats. One-time setup per domain.

**Three examples:**

1. You're testing a feature behind your staging auth. `/setup-browser-cookies staging.myapp.com chrome`. The skill copies your staging session cookies into the headless browser; next `/qa` run is authenticated.

2. You're auditing a competitor's authenticated dashboard for a comparison post. `/setup-browser-cookies competitor.com arc`. Headless browser opens the dashboard as you. `/qa-only` produces an authenticated bug report.

3. You're a multi-product engineer. `/setup-browser-cookies prod.app1.com chrome` and `/setup-browser-cookies prod.app2.com brave`. Two different domains, two different source browsers; both authenticated in the gstack session.

# 9. Phase 5, Ship and Deploy

![A horizontal pipeline drawn as a thick charcoal-ink tube running across cream paper, with three labeled stations along its length, a circle for PR open, a square for CI checks, a triangle for deploy, and a small editorial red dot at the triangle marking the live release; three faint ink check-marks float above the pipeline](/post-images/2026-05-23-gstack-garry-tan-claude-code-developer-guide/11-ship-pipeline.jpg)

## /ship

The **release engineer**. Sync `main`, run tests, audit coverage, push, open PR. Bootstraps test frameworks if you don't have one, detects language, picks Vitest / Jest / pytest / RSpec, scaffolds. One command. Filter-squashes any `WIP:` commits from continuous-checkpoint mode before opening the PR so `git bisect` stays clean. Generates the PR description from the diff + the project's design doc context.

**Three examples:**

1. You finished a feature branch. You type `/ship`. The skill `git fetch`s main, finds 3 commits behind, rebases, runs `bun test`, finds 1 new failing test, asks for permission to fix it. You approve. Tests green. It opens a PR with a structured description (problem, change, test plan, screenshots from `/qa`), assigns reviewers.

2. You're shipping to a repo with no tests. `/ship` notices `package.json` has no test runner. Bootstraps Vitest, writes three regression tests from the diff (each covering one changed function), runs them, ships. Repo goes from 0 → 3 tests on the first PR.

3. You're closing out a sprint with 8 small features. `/ship` opens 8 PRs in sequence (one per branch), each with a tested-and-reviewed description. Your morning code review queue is the team's, not yours.

## /land-and-deploy

The **end-to-end deploy**. Merge the PR, wait for CI and deploy, verify production health. One command from \"approved\" to \"verified in production.\" Configured once via `/setup-deploy`. Knows your platform (any of Vercel / Fly / Cloudflare / Render / AWS), the production URL, and the post-deploy health-check endpoint. If health-check fails, opens an incident.

**Three examples:**

1. The PR you opened with `/ship` got two approvals. You type `/land-and-deploy`. The skill squash-merges to main, waits for GitHub Actions (deploys to Fly), polls the `/_health` endpoint until it returns 200, then runs a 5-min `/canary`. Reports: ✅ deployed, ✅ health check, ✅ canary clean.

2. You're a solo founder pushing 10x a day. `/land-and-deploy` runs every PR. Average time-from-approval-to-production-verified: 6 minutes. No manual ceremony.

3. CI breaks on a deploy. `/land-and-deploy` detects the failed GitHub Action, surfaces the log, asks: \"build failed at step `deploy:fly` with `exit 1`. Open the log? Investigate? Roll back?\" You pick investigate. The skill chains to `/investigate` with the failure context preloaded.

## /setup-deploy

The **deploy configurator**. One-time setup for `/land-and-deploy`. Detects your platform from your repo (`fly.toml` → Fly, `vercel.json` → Vercel, `wrangler.toml` → Cloudflare, etc.), asks for the production URL, the deploy command (default: `git push origin main`), and the health-check endpoint. Writes the config to `.gstack/deploy.yaml` so `/land-and-deploy` works out of the box for the rest of the project's life.

**Three examples:**

1. You just initialized a Fly app. You run `/setup-deploy`. Skill reads `fly.toml`, identifies the app name, asks if `https://app-name.fly.dev/_health` is the right health check. You confirm. `.gstack/deploy.yaml` written. Done in 30 seconds.

2. You have a custom multi-step deploy (CDN purge + lambda update + slack post). You run `/setup-deploy --custom`. The skill walks you through writing the deploy script and the health check as YAML steps. Saves a more complex `deploy.yaml`. `/land-and-deploy` now runs the multi-step.

3. You moved from Vercel to Cloudflare. You re-run `/setup-deploy`. It detects `wrangler.toml`, rewrites `deploy.yaml`, and asks if you want to keep the old health check or replace it. You replace.

# 10. Phase 6, Secure, Document, Reflect

![Three small charcoal-ink icons arranged horizontally on cream paper, a shield on the left for security with a single editorial red dot at its center, a stack of pages in the middle for documentation, and a small open notebook on the right for retro, with a single charcoal curved arrow looping from the notebook back to the shield to suggest the closing of the sprint loop](/post-images/2026-05-23-gstack-garry-tan-claude-code-developer-guide/12-secure-document-reflect.jpg)

## /cso

The **Chief Security Officer**. OWASP Top 10 + STRIDE threat model. Scans for injection, auth, crypto, access control, secrets exposure, dependency vulns, and prompt injection paths. Zero-noise: 17 false-positive exclusions, 8/10+ confidence gate, independent finding verification. Each finding includes a **concrete exploit scenario**, not \"SQL injection possible in user input\" but \"send `'); DROP TABLE users; --` to the `/api/search?q=...` endpoint via the homepage search bar\".

**Three examples:**

1. You're shipping a SaaS app pre-launch. You run `/cso`. It finds: (1) a JWT signing key in `.env.production` checked into git, (2) a path traversal on `/api/download?file=...`, (3) a missing CSP header that allows inline scripts. Each comes with the exploit payload. You rotate the key, fix the traversal, add the CSP header.

2. You're a YC startup applying for SOC2. `/cso` generates a Markdown audit report covering 47 controls. You attach it to your security questionnaire. The audit takes 4 minutes instead of 4 hours.

3. You're handing a contract to a freelancer. You run `/cso` weekly to catch any regressions. Week 3, it flags a new `eval()` call in user-handler code. You ask the freelancer to refactor.

## /document-release

The **technical writer**. Updates all project docs to match what you just shipped. Catches stale READMEs automatically. Builds a **Diataxis coverage map** (reference / how-to / tutorial / explanation) so doc gaps are visible in the PR body. Runs after `/ship`. Surgical: only edits files where the diff actually changed something documented.

**Three examples:**

1. You just shipped a new `/login` endpoint. You run `/document-release`. The skill finds 4 docs referencing the auth API, updates the request/response shape in 3 of them, and leaves the 4th (a high-level overview) alone because the shape change doesn't affect it. PR description now includes \"docs updated: 3 files.\"

2. You renamed a feature. `/document-release` greps for the old name across `docs/`, `README.md`, and `CHANGELOG.md`, finds 11 references, edits 9 with the new name and leaves 2 historic-context mentions. Diataxis map shows \"reference: 0 gaps; how-to: 1 gap (no how-to for the renamed feature yet).\"

3. You shipped a behavior change to existing code. `/document-release` finds the README example that demonstrated the old behavior, updates the expected output, and re-runs the example to verify the new output. Doc and code stay synchronized.

## /document-generate

The **documentation author**. When `/document-release` finds a Diataxis gap (e.g., \"no how-to for feature X\"), `/document-generate` writes it. Researches the codebase first, reads the source, traces the call sites, captures the error paths, then writes reference / how-to / tutorial / explanation docs that match the code. Invokable standalone or chained from `/document-release`.

**Three examples:**

1. Your `/document-release` flagged a missing how-to for the new `/login` endpoint. `/document-generate` writes it: step-by-step request, expected response, error cases, code samples in JS / Python / curl. Lands at `docs/how-to-authenticate.md`.

2. You inherited an OSS project with sparse docs. You run `/document-generate --feature billing`. The skill reads `src/billing/`, identifies 4 doc-worthy capabilities (charge, refund, subscribe, cancel), and writes a reference page for each, with code snippets pulled from your tests.

3. You're publishing a tutorial post. `/document-generate --tutorial \"build a webhook receiver in 10 minutes\"` writes a beginner-grade walkthrough, starting from `npm init`, ending at a working receiver, using your library's actual API. Lands ready for the blog.

## /retro

The **eng manager** doing the weekly retro. Team-aware: per-person breakdowns, shipping streaks, test health trends, growth opportunities. `/retro` for current project; `/retro global` runs across all your projects and AI tools (Claude Code, Codex, Gemini). Reads commit metadata, gstack analytics, test coverage trends, and produces a structured Markdown retro you can paste into Slack.

**Three examples:**

1. Friday afternoon. You run `/retro` for the current project. Output: 47 commits, 38% tests, peak hours 9–11am, 5-day shipping streak. Praises shipping rhythm. Notes that the `app/components/` directory has 12 files at 0% coverage and asks if you'd like a coverage sprint next week.

2. You're an eng manager doing a team retro. `/retro` produces per-person breakdowns with specific praise (Alice: 18 disciplined sub-200-LOC PRs) and specific growth areas (Bob: test ratio at 12%, time to invest). You bring this into Monday's 1:1s.

3. You're a YC founder running 8 parallel projects. `/retro global` aggregates across all of them: 312 commits, 4 production deploys, 28 features shipped, top friction is repeated regressions in the auth module. You decide the auth module needs a `/investigate` + `/cso` pass before next week.

## /learn

The **memory manager**. Manage what gstack learned across sessions, patterns, pitfalls, project-specific preferences. Search, review, prune, export. Learnings persist in `~/.gstack/projects/$SLUG/learnings.jsonl`. Compounds across sessions so gstack gets smarter on your codebase. Pairs with `/sync-gbrain` for cross-project memory.

**Three examples:**

1. You taught Claude last week that this repo's auth tokens are stored in `localStorage` under the key `__app_auth`. You run `/learn` to see all stored learnings. It surfaces 14 patterns including that one. You pin three (auth token location, the `ENV=staging` constant, the test database URL pattern) so they always appear in CLAUDE.md.

2. You realize a learning is wrong, gstack thinks you use Drizzle when you switched to Kysely. You run `/learn search Drizzle`, find the stale entry, `/learn prune <id>`. Future sessions don't get the wrong context.

3. You're starting a new project that's similar to an old one. `/learn export --project=oldapp > /tmp/learnings.jsonl` and `/learn import < /tmp/learnings.jsonl` ports the useful patterns over.

# 11. Safety and power tools

## /careful

The **safety guardrails** on demand. Warns before destructive commands, `rm -rf`, `DROP TABLE`, `git push --force`, `git reset --hard`, `truncate`. Say *\"be careful\"* in chat to activate. Override any warning explicitly. Off by default to avoid friction in low-stakes contexts.

**Three examples:**

1. You're working on a production database. You say \"be careful.\" Five minutes later you absent-mindedly ask Claude to run `DROP INDEX old_idx`. The skill warns: \"This will require a 4-minute lock on a 220M-row table during peak hours. Proceed?\" You realize and pick a different approach.

2. You're cleaning a node_modules directory. You ask Claude to `rm -rf node_modules`. With `/careful` on, the skill confirms once. You approve. With `/careful` off, no prompt. You decide the friction is worth it for prod work.

3. You're force-pushing to a personal branch. Even on a personal branch the skill warns: \"force-push will rewrite 14 commits in the last hour. Proceed?\" You confirm. The warning is cheap; the mistake-prevention is expensive when it matters.

## /freeze

The **edit lock**. Restrict file edits to one directory. Prevents accidental changes outside scope while debugging. `/freeze src/billing/` means any tool call to edit a file outside that directory fails fast with `FROZEN: cannot edit src/api/users.ts (outside billing/)`. Released with `/unfreeze`.

**Three examples:**

1. You're debugging a billing bug. You `/freeze src/billing/`. Claude tries to \"helpfully\" refactor a related auth file. The freeze blocks it. The bug fix stays scoped.

2. You're a contractor on a sensitive PR. The contract limits you to one module. You `/freeze` that module on day one. You forget about it; gstack never lets you bleed scope.

3. You're pairing with a junior who's prone to scope creep. You `/freeze` the directory. Their edits stay in bounds. When they want to expand, they have to ask you to `/unfreeze`, a useful conversation forcing function.

## /guard

`/careful` + `/freeze` in one command. Maximum safety for prod work. Use when you're touching production code under time pressure and want every guardrail on.

**Three examples:**

1. Saturday 3am incident. You `/guard src/payments/`. Every edit is scoped; every destructive command warns. Your tired self can't accidentally drop a table.

2. You're a junior engineer on your first prod hotfix. The senior engineer types `/guard` into your session before handing it back. You ship the fix without learning the hard way.

3. You're recording a coding live-stream and don't want to publicly nuke a database. `/guard` runs the whole stream. Viewers see the warnings as part of the workflow.

## /unfreeze

Removes the `/freeze` boundary. Single-purpose command.

**Three examples:**

1. You finished the billing bug. `/unfreeze`. Now you can refactor across the codebase.

2. You realize you actually need to edit one file outside the frozen directory. `/unfreeze`, edit, `/freeze src/billing/` again. Two seconds.

3. You're handing the session to a teammate. `/unfreeze` so they don't start with your scope restrictions.

## /gstack-upgrade

The **self-updater**. Upgrade gstack to latest. Detects global install vs vendored project install, syncs both, shows what changed. Resists stale GitHub raw CDN responses. Semver-order guard.

**Three examples:**

1. You're at v1.40.x and want to try the new iOS QA features in v1.43. `/gstack-upgrade`. Skill fetches, diffs, lists 4 new skills (`/ios-qa`, `/ios-fix`, `/ios-design-review`, `/ios-clean`, `/ios-sync`), updates symlinks, prints \"upgraded to v1.43.3.0.\"

2. You're a team admin who set `auto_upgrade: true` in `~/.gstack/config.yaml`. `/gstack-upgrade` runs silently every Claude Code session start, once per hour, network-failure-safe.

3. Your project has gstack vendored (set up via team mode). `/gstack-upgrade` updates both the global install at `~/.claude/skills/gstack/` *and* the project's `.claude/skills/gstack/` symlink/copy. One command, two locations in sync.

# 12. Data, scrape, and skill codification

## /scrape

The **browser data extractor**. Pull data from a web page. First call prototypes via `$B` (Section 8 above); subsequent calls on a matching intent run a codified browser-skill in ~200ms. Use for one-off and recurring data pulls. Caches successful extractions per-domain for replay.

**Three examples:**

1. You want yesterday's HN front page in JSON. `/scrape news.ycombinator.com, titles, points, comment counts, urls`. First run prototypes with `$B`, takes 2 seconds. Second run executes the codified skill in 180ms.

2. You're maintaining a competitive intelligence sheet that pulls pricing from 12 SaaS sites weekly. `/scrape` codifies one per site. The Monday morning script runs all 12 in under 5 seconds total.

3. You need a one-off pull from your AWS dashboard. `/scrape console.aws.amazon.com/billing` (cookies imported via `/setup-browser-cookies`) gets the current month's costs as JSON.

## /skillify

The **skill codifier**. Walks back through your conversation, finds the last `/scrape` prototype that worked, synthesizes a script + test + fixture, runs the test, asks before committing. Turns one-off browser actions into reusable skills.

**Three examples:**

1. You just did a one-off `/scrape` of LinkedIn that worked. You type `/skillify`. The skill reads the conversation, generates `~/.claude/skills/linkedin-scrape/SKILL.md` + a test that mocks the page DOM, runs the test (green), and asks: \"Commit?\" You say yes. Future LinkedIn pulls take 200ms.

2. You spent 20 minutes debugging a flaky CMS scrape. `/skillify` captures the working configuration (correct wait-for-selector, the right scroll-before-extract sequence) so you never lose the knowledge to a new chat session.

3. You're building a library of personal automations. Every successful `$B` session ends with `/skillify`. Six weeks in, you have 14 codified skills running ~200ms each. Personal data pipelines from the gstack browser.

# 13. iOS suite, real device QA

![A row of three identical iPhone-shaped charcoal-ink rectangles on cream paper, drawn as upright geometric devices with rounded corners and small notches at the top; above each phone a thin charcoal hairline rises into a small branching tree shape representing the accessibility tree, and the middle phone has a single editorial red dot on its screen marking the visual bug found by /ios-qa](/post-images/2026-05-23-gstack-garry-tan-claude-code-developer-guide/13-ios-device-farm.jpg)

## /ios-qa

The **iOS Live-Device QA** (v1.43.0+). Drive a real iPhone over USB CoreDevice via an embedded `StateServer` in the app. Reads Swift source, codegens typed `@Observable` accessors, runs the agent loop on the connected device. Optional `--tailnet` flag exposes the device to OpenClaw or any HTTP-capable agent on your Tailscale tailnet, remote agents can run iOS QA without ever touching the hardware. **Capability-tier allowlist** (observe / interact / mutate / restore), per-device session lock, audit log.

**Three examples:**

1. You plug your iPhone into your Mac. You type `/ios-qa` in Claude Code. Daemon starts, accessors generated. Claude opens the Settings screen, opens Notifications, takes a screenshot, finds the toggle visually misaligned at the bottom, reports it.

2. You're an indie iOS dev shipping a TestFlight build. `/ios-qa --observe` walks every screen, captures screenshots, generates a 14-screen \"first-launch experience\" PDF. You attach it to the TestFlight description.

3. You're outsourcing QA to a contractor. You grant their tailnet identity at `interact` tier via `gstack-ios-qa-mint`. They run `/ios-qa --tailnet` from their machine; the daemon validates their identity and lets them drive your physical iPhone remotely. Audit log captures every action.

## /ios-fix

The **iOS bug-fix loop**. Same iron-law-of-investigation as `/investigate` but on iOS state. Reads the live observable state of the running app, traces the bug, fixes the Swift source, rebuilds, re-tests. Stops after 3 failed fix attempts.

**Three examples:**

1. `/ios-qa` found a layout glitch. You hand off to `/ios-fix` with the screenshot. The skill identifies the SwiftUI view, traces the spacing modifier chain, fixes the constraint, rebuilds, verifies.

2. A user reports \"tap-to-zoom breaks after pinching.\" You manually trigger the bug in the running app, then run `/ios-fix`. Snapshot captured at the moment of breakage. The skill traces the gesture state machine, finds a stale `scale` ivar, fixes, rebuilds, verifies. Three minutes total.

3. You're 4 fixes deep on a flaky test. The skill stops after the 3rd failed `/ios-fix` attempt and follows the Iron Law: \"fix attempts exhausted. Re-investigate.\" It hands back to you with the failed-attempt summary so you can change strategy.

## /ios-design-review

The **iOS designer's eye** on real hardware. Connects to the same `/ios-qa` daemon in observe-tier mode and screenshots every screen. Scores **10 dimensions 0-10**: typography hierarchy, spacing rhythm, color hierarchy, touch targets (44pt rule), loading/empty/error states, accessibility (Dynamic Type, VoiceOver), animation discipline, iOS-idiom alignment (HIG), information density, AI-slop check.

**Three examples:**

1. You shipped a new iOS settings screen. `/ios-design-review` screenshots all 12 sub-screens. Touch targets score 5/10, three toggle rows are 36pt tall, below the 44pt HIG minimum. The skill asks: \"Bump row height to 44pt or use a vertical-padding approach?\" You pick padded. It writes the recommended change to `Settings.swift`.

2. You're a designer auditing your own app pre-App-Store-submission. `/ios-design-review` scores Animation Discipline 4/10, \"8 animations use the default `withAnimation` curve; HIG recommends `spring(response:0.3,dampingFraction:0.7)` for natural motion.\" You apply the suggested spring everywhere.

3. AI-slop check scores 6/10: \"App uses 3-column icon grid + gradient header, the two most recognizable AI-tells.\" Even on iOS the slop patterns are common. Skill recommends asymmetric layout + a flat header. You take the recommendation; ship.

## /ios-clean

The **iOS bridge cleanup**. Strips the DebugBridge SPM package and all `#if DEBUG` wiring before App Store submission. The *structural* Release-build guard lives in `Package.swift` (`.when(configuration: .debug)`) plus a CI invariant test. `/ios-clean` is the guided removal flow.

**Three examples:**

1. You're submitting to TestFlight and want extra paranoia. You run `/ios-clean`. The skill walks through every `#if DEBUG` block referencing DebugBridge, asks \"remove this block?\" for each, offers to delete the SPM dependency. You confirm. Your Release build is now bridge-free regardless of `Package.swift` conditional.

2. You inherited an iOS app from a contractor who manually added DebugBridge without using `/ios-qa`. `/ios-clean` finds 14 wiring points across 6 files, removes them in one pass.

3. You're switching from gstack iOS to a different test harness. `/ios-clean` wipes the entire DebugBridge surface area so the new harness can install cleanly.

## /ios-sync

The **iOS bridge resync**. Regenerate accessors against the latest upstream gstack. Run after you upgrade gstack or add new `@Observable` classes / properties. Detects what's installed, regenerates accessors against latest templates, verifies the app rebuilds. Cache-key invalidation handles Swift version changes and source changes.

**Three examples:**

1. You added a new `@Observable class PaymentStore { var balance: Decimal }` last night. Today `/ios-qa` can't see the new property. You run `/ios-sync`. The skill regenerates accessors, includes `balance`, rebuilds. `/ios-qa` now reads `GET /state/PaymentStore/balance` and gets the live value.

2. You just upgraded gstack 0.8.2 → 0.9.0. The Swift templates moved. `/ios-sync` detects the version change, regenerates every accessor, verifies the build, runs the CI invariant test (`swift build -c release` still excludes DebugBridge).

3. You upgraded Swift 5.9 → 6.0. Cache-key invalidation kicks in. `/ios-sync` regenerates everything from scratch, catches a deprecated API in one accessor, falls back to the upstream template for that file.

# 14. GBrain, persistent memory

## /setup-gbrain

The **memory setup**. One command from zero to a live persistent knowledge base for your AI agents. Four paths: **Supabase existing URL** (paste a Session Pooler URL, share data across machines), **Supabase auto-provision** (paste a Personal Access Token, skill creates a project, polls to healthy, fetches the pooler URL, hands it to `gbrain init`, ~90 seconds end-to-end), **PGLite local** (zero accounts, zero network, ~30 seconds, isolated brain on this Mac), **Remote gbrain MCP** (your brain runs on another machine via Tailscale/ngrok/LAN; paste an MCP URL and bearer). After init it offers to register gbrain as a Claude Code MCP server so `gbrain search`, `gbrain put`, etc. show up as typed tools.

**Three examples:**

1. You're trying gbrain for the first time, don't want to make any cloud commitments. You type `/setup-gbrain`, pick **PGLite local**. 30 seconds later you have an isolated brain. You can `/setup-gbrain --switch` to Supabase later when it earns its keep.

2. You're a YC founder who codes on a laptop and a desktop. You type `/setup-gbrain` on the laptop, pick **Supabase auto-provision**, paste a Supabase PAT. 90 seconds later you have a hosted brain. On the desktop you `/setup-gbrain` again, pick **Supabase existing URL**, paste the same pooler URL. Both machines share data.

3. You're a multi-client consultant. You run a single gbrain MCP server on a Tailscale-connected box at home. In each client's repo you `/setup-gbrain`, pick **Remote gbrain MCP**, paste the URL + token. The skill sets the repo's per-remote trust tier to `read-only` for client A, search the shared brain, never write client A patterns into it.

## /sync-gbrain

The **keep-brain-current** skill. Refresh gbrain against this repo's code so `gbrain search` and `code-def` stay accurate, and write a `## GBrain Search Guidance` block to CLAUDE.md so future Claude sessions prefer `gbrain` over `Grep` for symbol lookups. Idempotent. Registers the cwd as a federated source via `gbrain sources add`, runs `gbrain sync --strategy code`, and prints a verdict block. Removes stale guidance automatically if the capability check fails.

**Three examples:**

1. Friday afternoon, your repo grew 40% this week. You type `/sync-gbrain`. Incremental sync, only changed files, 22 seconds. CLAUDE.md gets a fresh \"prefer `gbrain search`/`code-def`/`code-refs` over Grep\" block. Next session, when you ask \"where is `processPayment` called,\" Claude uses `gbrain code-refs` (200ms) instead of grepping the whole repo.

2. You renamed a major subsystem. You run `/sync-gbrain --full`. Full reindex, 4 minutes for a 200k-LOC repo. The brain catches up with the rename and stale aliases disappear from search.

3. You're a consultant in Client B's repo. You run `/sync-gbrain --dry-run` first to preview what would be indexed. The preview shows 14 file types, 8k symbols. You confirm with the actual sync. The `read-only` trust policy ensures Client B's code doesn't pollute Client A's brain.

# 15. Standalone CLIs

These don't run as slash commands inside Claude Code, they're shell binaries on your PATH that pair with the workflow.

## gstack-model-benchmark

The **cross-model benchmark CLI**. Run the same prompt across Claude, GPT (via Codex CLI), and Gemini. Compare latency, tokens, cost, tool-call count, and optionally an LLM-judge quality score. Auth detected per provider; unavailable providers skip cleanly. Output as table / JSON / markdown. `--dry-run` validates flags + auth without spending API calls.

**Three examples:**

1. You're picking a model for your sprint. You run `gstack-model-benchmark --prompt \"Refactor this React component to use TanStack Query\" --models claude,gpt,gemini --judge`. Output table shows Claude latency 4.2s / $0.012 / quality 9.1, GPT 6.1s / $0.018 / quality 8.7, Gemini 3.8s / $0.004 / quality 7.9. You pick Claude for quality, Gemini for cheap iteration.

2. You're a DX lead writing a benchmark blog post. `gstack-model-benchmark ./prompts/sql-injection-detection.txt --models claude,gpt,gemini --output markdown` produces a copy-pasteable comparison table for the post.

3. You added a new prompt to a CI matrix. `gstack-model-benchmark --prompt \"hi\" --models claude,gpt,gemini --dry-run` validates auth without spending money. You see Gemini auth failed (`GOOGLE_GENERATIVE_AI_API_KEY` missing) and fix it before the real run.

## gstack-taste-update

The **design taste learning CLI**. Writes approvals/rejections from `/design-shotgun` into a persistent per-project taste profile at `~/.gstack/projects/$SLUG/taste-profile.json`. Schema v1 tracks dimensions: fonts, colors, layouts, aesthetics. Each has approved + rejected arrays. Last 50 sessions kept. Profile decays 5%/week so old preferences fade.

**Three examples:**

1. You approved 8 minimal layouts and rejected 4 busy ones over two weeks. You run `gstack-taste-update show`. Output: \"layouts: approved×8 (minimal), rejected×4 (busy). aesthetics: approved×6 (editorial), rejected×3 (dashboard-style).\" Next `/design-shotgun` round biases toward minimal-editorial.

2. You just rejected variant C in `/design-shotgun`. You run `gstack-taste-update rejected ~/.gstack/.../variant-C.png --reason \"gradient hero feels AI-slop\"`. The reason is stored alongside the rejection so future generations can avoid the whole *category* you flagged, not only the one pattern.

3. You imported an old `/design-shotgun` project that predates the v1 schema. You run `gstack-taste-update migrate`. Legacy `approved.json` files get upgraded to v1 taste-profile.json with sessions reconstructed from timestamps.

## gstack-ios-qa-daemon

The **iOS QA daemon**. Mac-side broker between an agent and a connected iPhone over USB CoreDevice. Loopback by default; `--tailnet` opens a Tailscale-facing listener with identity-gated capability tiers. Single-instance via `flock` on `~/.gstack/ios-qa-daemon.pid`. Exits cleanly when no active loopback clients are connected and no remote session tokens are outstanding.

**Three examples:**

1. You plug your iPhone into your Mac and run `gstack-ios-qa-daemon`. Loopback-only listener binds to port 9099. `/ios-qa` from a Claude Code session in another terminal connects locally. No remote exposure.

2. You're enabling remote iOS QA. You run `gstack-ios-qa-daemon --tailnet`. The daemon binds both loopback (9099) and a tailnet listener. From a remote agent (`/ios-qa --tailnet`), the daemon validates the Tailscale identity, mints a session token, and proxies HTTP to the iPhone's `StateServer`.

3. The daemon is hung from yesterday's session. You try to start a new one; the flock blocks. You `kill $(cat ~/.gstack/ios-qa-daemon.pid)` and restart. Single-instance behavior prevents two daemons fighting over the USB tunnel.

## gstack-ios-qa-mint

The **iOS allowlist manager**. Owner-grant CLI for the tailnet allowlist. `grant`/`revoke`/`list` against `~/.gstack/ios-qa-allowlist.json` (mode 0600). Remote agents never auto-allowlist themselves; this is the explicit-intent path.

**Three examples:**

1. Your teammate is on your tailnet and needs iOS QA access. You run `gstack-ios-qa-mint grant teammate@tailnet --tier interact --expires 8h`. They can now self-mint short-lived session tokens for the next 8 hours and drive your physical iPhone at `interact` tier.

2. You finished an outsourced QA pass. You run `gstack-ios-qa-mint revoke contractor@tailnet`. Their next mint attempt returns `403 Forbidden`.

3. You're auditing access. `gstack-ios-qa-mint list` prints every identity, tier, and expiry. You spot a stale grant from two months ago, revoke it.

## gstack-analytics

The **personal usage dashboard** from local JSONL. No remote data needed. `gstack-analytics` (default 7d), `gstack-analytics 30d`, `gstack-analytics all`. Reads `~/.gstack/analytics/skill-usage.jsonl` and renders a terminal dashboard: top skills, total invocations, time saved (estimated), trend lines.

**Three examples:**

1. End of month. You run `gstack-analytics 30d`. Top: `/qa` (47 runs), `/review` (38), `/ship` (22), `/design-shotgun` (8). You realize you've shipped 22 PRs but only run `/cso` once, flag for next month.

2. You're writing an internal post on how gstack changed your workflow. `gstack-analytics all` over 6 months shows `/office-hours` is at 14 runs (only on new projects) but `/review` is at 312. Concrete numbers for the post.

3. You're tracking whether `/autoplan` adoption stuck. `gstack-analytics 7d` last week showed 6 runs of `/autoplan`; this week 0. You ask yourself why and notice you went back to running the reviews individually for the last set of refactors.

## gstack-brain-init

The **gstack memory sync** to a private repo. Optionally pushes your gstack state (learnings, CEO plans, design docs, retros, developer profile) to a private 1-person repo so your AI memory follows you between machines. One-time setup with a privacy prompt: **everything allowlisted** / **artifacts only** / **off**. Every skill run syncs the queue at start and end. Secret-shaped content (AWS keys, GitHub tokens, PEM blocks, JWTs, bearer tokens) is blocked from sync before it leaves your machine.

**Three examples:**

1. You're setting up a new MacBook. You run `gstack-brain-init`. Pick \"artifacts only.\" 60 seconds later your last 14 days of CEO plans, design docs, retros, and learnings are pulled from your private repo. Your new Mac knows what your old Mac knew.

2. You're paranoid about behavioral telemetry leaving your machine. You run `gstack-brain-init`, pick \"off.\" gstack still works locally; no sync happens. You can later flip to \"artifacts only\" via the same command.

3. You travel between two laptops weekly. `gstack-brain-restore` on a new machine pulls yesterday's learnings. Today's gstack session benefits from yesterday's discoveries.

## gstack-uninstall

The **clean uninstall CLI**. Removes gstack skills, symlinks, global state (`~/.gstack/`), project-local state, browse daemons, and temp files. `--keep-state` preserves config and analytics; `--force` skips confirmation. Stops running browse daemons via SIGTERM before cleanup.

**Three examples:**

1. You're done evaluating gstack. You run `~/.claude/skills/gstack/bin/gstack-uninstall`. Interactive prompts confirm each removal scope. 30 seconds later your `~/.claude/skills/`, `~/.gstack/`, project-local `.gstack/`, and any active browse daemons are gone.

2. You want to keep your analytics history but uninstall the skills. `gstack-uninstall --keep-state` removes skills but preserves `~/.gstack/` so you keep your usage history and learnings for a future reinstall.

3. You're scripting a CI runner that needs a fresh install. `gstack-uninstall --force` skips prompts; the next line clones gstack and runs `./setup` for a clean baseline.

# 16. OpenClaw native skills

Four conversational skills that run **directly inside an OpenClaw agent** (no Claude Code session required). Installed via `clawhub install gstack-openclaw-*`.

## gstack-openclaw-office-hours

The **conversational `/office-hours`** for OpenClaw. Same six forcing questions, but the OpenClaw agent runs the interrogation in chat, no Claude Code spin-up. Use when you're already in OpenClaw and don't want to context-switch.

**Three examples:**

1. You're chatting with your OpenClaw agent while on the train. You say *\"let's run office hours on my newsletter idea.\"* The skill activates and starts the six-question sequence in chat. No Claude Code, no laptop required.

2. You're a YC founder doing a brainstorm with a teammate over Slack. OpenClaw is in the channel. You ping it: \"office hours: what should we build next?\" The skill produces a structured design doc that lives in the channel for the team to react to.

3. You're a hackathon team prototyping at 11pm. OpenClaw on the laptop runs Builder mode. Six questions later, a design doc is ready and you're picking an implementation path before midnight.

## gstack-openclaw-ceo-review

The **conversational `/plan-ceo-review`** for OpenClaw. Strategic challenge with the same four scope modes. Particularly useful for high-level strategic questions where you want the founder lens without a coding session.

**Three examples:**

1. You're a CTO weighing whether to expand a feature set. You ask OpenClaw to run a CEO review on the spec. Five minutes of conversational back-and-forth, you land on SELECTIVE EXPANSION with two added items and one trimmed.

2. A teammate proposes a new product line. You run `gstack-openclaw-ceo-review` on their pitch deck. The skill challenges three premises, identifies the implicit assumption that the existing audience converts to the new line (which it probably doesn't), and recommends a smaller wedge test.

3. You're an investor doing diligence. The skill stress-tests the founder's pitch against the four-mode framework and surfaces what would have to be true for each mode to be the right answer.

## gstack-openclaw-investigate

The **conversational debugger** for OpenClaw. Same iron law, no fixes without root cause investigation first, but in chat. Useful when the bug is in a non-code context (your spreadsheet, your CRM, your billing data) where a coding session isn't the right venue.

**Three examples:**

1. Your monthly revenue numbers don't match in two systems. You ask OpenClaw: \"investigate why MRR in Stripe doesn't match MRR in our dashboard.\" The skill asks for the reproduction, the data flow upstream of the calculation, the last-good month. Identifies the regression in 4 messages, root cause first, then proposes the fix.

2. You're on call. A user emails \"checkout is broken.\" No stack trace. The skill conversationally rebuilds the user's exact path, asks about timing/region/payment method. You realize it's only broken for Stripe Apple Pay. Root cause: a feature flag rollout.

3. You debug a \"weird behavior\" without a stack trace. The skill resists the urge to suggest fixes. After 3 wrong hypotheses it explicitly says: \"Stopping. The architecture itself may be wrong. What's the simplest thing this code is supposed to do?\"

## gstack-openclaw-retro

The **conversational weekly retro** for OpenClaw. Same data-driven retrospective methodology as `/retro`. Particularly useful for voice-driven retros on mobile via OpenClaw.

**Three examples:**

1. Friday afternoon. You ask your OpenClaw agent for a weekly retro. It pulls `git log` for the past 7 days, runs the methodology, and walks you through the numbers conversationally: 47 commits, 38% tests, peak hours, shipping streak.

2. You're a founder doing a personal retro on the bus home. Voice-driven via OpenClaw on mobile. The skill computes your week's stats, calls out the biggest ship, asks \"what did you learn that you want to keep doing?\" Your spoken answer gets logged.

3. You're an eng manager reviewing the team. The skill produces per-person breakdowns with specific praise (Alice: disciplined sub-200-LOC PRs) and specific growth areas (Bob: test ratio at 12%, time to invest). You bring this into Monday's 1:1s.

# 17. The architecture, end-to-end, how the four surfaces compose

The sixteen prior sections inventoried the parts. This section reads gstack as one system. The number that matters here is not 33 slash commands or 57 SKILL.md files; it is the number of *surfaces*. There are four. The slash-command skills under `~/.claude/skills/gstack/` are the surface the user types into. The standalone CLIs in `bin/` are the surface the operating system runs against. The OpenClaw native skills under `openclaw/skills/` are the surface a different host agent invokes. The persistent state layer under `~/.gstack/projects/<slug>/` and the in-repo `.gstack/` directory is the surface every other surface reads and writes. The fourth surface is the one that ties the other three together, and it is the most boring of the four because it is just a tree of flat files.

![A large editorial system-architecture diagram in charcoal ink on cream paper drawn as a vintage engineering schematic, with four horizontal bands stacked vertically labelled SLASH COMMAND SKILLS, STANDALONE CLIs, OPENCLAW NATIVE SKILLS, and PERSISTENT STATE LAYER, each band containing small hand-lettered tiles for the skills and CLIs that live in that band, with a single editorial red ribbon labelled ANALYTICS PIPELINE 305K INVOCATIONS wrapped diagonally across all four bands as an observability overlay, thin charcoal arrows connecting the bands top to bottom, and a hand-lettered legend in the lower right reading "state flows down through the filesystem"](/post-images/2026-05-23-gstack-garry-tan-claude-code-developer-guide/16-architecture-four-surfaces.jpg)

🔴 **The load-bearing thesis: state passes between skills via flat files, not via a process, a daemon, or a database.** This is the architectural choice that makes gstack a *sprint* rather than a chat. Every other property follows from it. The walkthrough in the next section reads as a continuous narrative because the *artefacts* read as a continuous narrative; each skill leaves a Markdown or JSONL trace at a known path, and the next skill picks that trace up by name. There is no in-memory session object, no orchestrator process, no graph runtime. There is `~/.gstack/projects/<slug>/`, and there is `cat`.

**Surface 1, the slash-command skills.** These are 57 SKILL.md files under `~/.claude/skills/gstack/<skill>/SKILL.md`. The Claude Code host scans the directory at startup, reads the frontmatter of each `SKILL.md` (name, description, allowed-tools, triggers), and exposes the name as a slash command. When the user types `/review`, Claude Code reads the full body of `review/SKILL.md` into its prompt and follows the body's instructions. The body is plain Markdown plus inline bash blocks. There is no plugin runtime; the model is the runtime. The surface is the directory.

**Surface 2, the standalone CLIs.** These are 62 compiled binaries and TypeScript executables under `~/.claude/skills/gstack/bin/`. The slash-command skills shell out to them. `gstack-analytics` reads `~/.gstack/analytics/skill-usage.jsonl` and prints a terminal dashboard. `gstack-model-benchmark` runs the same prompt across Claude, GPT-via-Codex, and Gemini and tabulates latency, cost, and tool-call counts. `gstack-browse` is the Bun-compiled CLI that talks to the long-lived Chromium daemon over localhost HTTP. `gstack-ios-qa-daemon` is the Mac-side broker that proxies an agent's HTTP requests into the iPhone's CoreDevice tunnel. These exist because some primitives need a long-lived process (a browser, a USB tunnel, a metrics scraper); Markdown cannot host a process, so the CLI does. The skill calls the CLI; the CLI does the I/O; the skill reads the CLI's output as text.

**Surface 3, the OpenClaw native skills.** These are four conversational skills under `openclaw/skills/gstack-openclaw-*/SKILL.md` that run inside an OpenClaw agent rather than Claude Code. `gstack-openclaw-ceo-review`, `gstack-openclaw-investigate`, `gstack-openclaw-office-hours`, `gstack-openclaw-retro`. They share the rhetoric and the role of their Claude-Code cousins, but their host is a different terminal-native coding agent. The architectural property they prove is that the skill is portable across hosts; any agent that can read a SKILL.md, follow its instructions, and write to a known path can participate. The state layer does not care which host produced the state.

**Surface 4, the persistent state layer.** This is the surface the other three depend on. It has three roots. The user-global root at `~/.gstack/` holds `projects/<slug>/`, `analytics/`, `sessions/`, and the configuration files. The per-repo root at `.gstack/` (inside the git repo) holds the artefacts that should travel with the code. The `~/.claude/skills/gstack/` install itself is the third root, but it is a read-only mirror of the upstream repo. Within `~/.gstack/projects/<slug>/`, the conventions are codified by the skills themselves: `<user>-<branch>-design-<datetime>.md` for `/office-hours` output, `plan.md` for `/autoplan`, `learnings.jsonl` as the append-only learning log written by every skill that completes, `taste-profile.json` for `/design-shotgun`'s persistent preferences, `health-history.jsonl` for `/health`, `retros/` for weekly retrospectives. The format is JSONL or Markdown. The access pattern is `cat`, `grep`, `tail -n 50`. Any human can audit the entire institutional memory of a project by reading flat files; any skill can do the same because the skill is a model and the model can read files.

The **observability plane** sits *above* the four surfaces, not between them. The opt-in analytics pipeline writes one line of JSONL to `~/.gstack/analytics/skill-usage.jsonl` every time a skill completes. The schema captures the skill name, the timestamp, the project slug, and a synthetic time-saved estimate. The `gstack-analytics` CLI reads the file and renders the dashboard. Garry's [April 18 public disclosure](https://x.com/garrytan/status/2045404377226285538) reports **305,309 invocations** and roughly **7,000 weekly active users** drawn from this pipeline; the number is verifiable because the pipeline is open source and the user can run `gstack-analytics --export` against their own machine to see the raw inputs. The pipeline does not change behaviour; it observes it. That is what makes it the observability plane rather than a control plane.

The **request lifecycle** for a realistic single invocation makes the file-based composition concrete. The user is on the `feat/payments-refactor` branch of a repo they have used before, with `~/.gstack/projects/payments/` already populated. They have just finished implementing the refactor. They type `/review`.

![A horizontal lifecycle diagram in charcoal ink on cream paper drawn as a vintage railway timetable, tracing a single /review request from left to right across eight numbered stations connected by a thin charcoal line, labelled TERMINAL, CLAUDE CODE, PREAMBLE, READ STATE, ANALYZE DIFF, SPECIALISTS, WRITE STATE, NEXT SKILL, with a single editorial red arrow looping from station 7 back to station 4 hand-lettered "state passes via flat files anyone can cat"](/post-images/2026-05-23-gstack-garry-tan-claude-code-developer-guide/17-request-lifecycle-review.jpg)

Claude Code reads `~/.claude/skills/gstack/review/SKILL.md`. The first block in the body is the **preamble**: a bash sequence that runs `gstack-update-check` (a remote-version probe with a 100ms timeout), `gstack-slug` (computes the canonical project slug from the git remote and `cwd`), and `gstack-repo-mode` (reads `~/.gstack/.repo-mode/<slug>` to determine whether this repo is a full-trust personal repo, a client repo with `read-only` policy, or a tracked OSS repo). The preamble exports `$SLUG`, `$BRANCH`, `$REPO_MODE`, and `$LEARN_FILE=${GSTACK_HOME:-$HOME/.gstack}/projects/$SLUG/learnings.jsonl` for the rest of the skill body to use.

The skill body then reads upstream state. It opens `~/.gstack/projects/payments/plan.md` (written by an earlier `/autoplan` run that morning), the last `*-design-*.md` for this branch (written by an earlier `/office-hours`), and the trailing 200 lines of `learnings.jsonl`. The model now has, in its prompt context, the design intent, the architecture decisions, and the prior patterns this project has accumulated. None of that came from chat memory; it all came from the filesystem.

The skill body runs the analysis. It calls `git diff main...feat/payments-refactor`, parses the diff against the `review/checklist.md` rubric (SQL safety, LLM trust-boundary violations, conditional side effects, drive-by edits), and uses the `Agent` tool to spawn three sub-reviewers in parallel, one per specialist area. The sub-reviewers return findings. The parent skill aggregates them into a structured report.

The skill body writes downstream state. It appends one or more JSONL lines to `learnings.jsonl` capturing the patterns it caught, writes a structured review report to `.gstack/review-log/<timestamp>.md` in the repo, and (per the `/review` ↔ `/codex` cross-model pair) optionally writes a `pending-codex-review.json` ready for `/codex` to pick up. If the user runs `/codex` next, that skill reads the same diff and the `pending-codex-review.json`, runs the same checklist through GPT-via-Codex-CLI, and writes its own report alongside the Claude one. The two reports get diffed in `.gstack/cross-model-review.md`; disagreement is surfaced to the user as a taste decision rather than silently resolved. That is the quality gate. It works because both runs read and write the same flat files, and the comparison logic is a `diff` against two files.

The **gbrain integration** plugs in as a tool extension rather than a separate runtime. `/setup-gbrain` installs the [gbrain](https://github.com/garrytan/gbrain) CLI, initialises a per-machine knowledge base (PGLite local, Supabase auto-provisioned, Supabase existing pooler URL, or remote MCP), registers gbrain as a Claude Code MCP server, and writes a per-remote trust policy at `~/.gstack/.gbrain-trust/<remote>.json` (one of `read-write`, `read-only`, `deny`). `/sync-gbrain` keeps the per-repo index fresh and writes a `## GBrain Search Guidance` block into the repo's `CLAUDE.md` so future Claude sessions prefer `gbrain search` over `Grep` for symbol lookups. The architecture lesson: gbrain is mounted into the skill surface through MCP, not through bespoke wiring. Any skill can call `gbrain search "processPayment"` the same way it calls `git log`. The cross-machine memory problem reduces to the cross-machine database problem, and the database is Postgres.

The **iOS device farm** composes through the standalone-CLI surface and the persistent state surface together. `gstack-ios-qa-daemon` runs on the Mac connected to the iPhone over USB CoreDevice; it binds loopback on port 9099 by default, and binds a Tailscale-facing listener when started with `--tailnet`. `gstack-ios-qa-mint grant teammate@tailnet --tier interact --expires 8h` writes a row to `~/.gstack/ios-qa-allowlist.json` (mode `0600`) that the daemon reads on every connection attempt. The remote agent's `/ios-qa --tailnet` invocation triggers a Tailscale identity check at the daemon, validates against the allowlist, mints a session token, and proxies the agent's HTTP requests into the iPhone's StateServer. Three capability tiers (`view`, `interact`, `admin`) gate what the remote agent can do, audit logs land in `~/.gstack/security/attempts.jsonl`, and the daemon exits cleanly when no loopback clients and no outstanding remote sessions remain. The device farm is not a separate platform; it is one daemon, one allowlist file, one Tailscale identity check, one log file. The persistence is in the file, the gating is in the daemon, the policy is in the JSON.

The composition pattern that recurs through every example above is the same: **declarative on the left, persistent on the right.** SKILL.md frontmatter declares the role (name, allowed-tools, triggers); the body declares the procedure (the bash preamble, the read-upstream-state block, the analyse-diff block, the write-downstream-state block); the persistent state layer holds the procedure's input and output. The thing the skill *does* lives in the body; the thing the skill *knows* lives on disk. The thing the next skill *reads* is the previous skill's *what it knew at the end*. That is the entire orchestration model.

That model has obvious limitations and one non-obvious strength. The obvious limitations: no transactions across files, no live multi-user concurrency, no distributed consistency, no streaming progress reporting, no built-in retry on partial failures. A sprint that takes two hours can crash halfway through and leave the state directory partially written; the recovery model is a human reading `learnings.jsonl` and re-running the affected skill. The non-obvious strength: every state transition is auditable by `cat`. There is no SDK, no schema migration, no version-skew problem between a control plane and a data plane. Anyone who can read Markdown can audit the system. The category's competitors (Manus, Replit Agent, Devin, OpenAI Codex) bury their state inside vendor-controlled session stores; gstack puts it in `~/.gstack/projects/`. That is what the sprint promise actually delivers, and that is the answer to *what does "skills that compose" mean*.

# 18. End to end: build a product in one Saturday with gstack

Reading the skill reference in isolation is useful but partial. The skills are designed to compose, and the real argument for gstack is what happens when you string them together. Below is a complete sprint walkthrough, one Saturday from idea to live deploy, every command in order, what each one returns, where the state lives, and how the next skill picks it up.

The product: **standuply**, a small web app that takes a few Slack channel IDs and a time of day, and at 9am each weekday posts a one-paragraph synthesis of yesterday's channel activity to a designated channel. One developer, one Saturday, one repo. The skill flow uses 14 of the 33 gstack slash commands. Every intermediate artifact (the design doc, the architecture, the test plan, the screenshots, the atomic commits, the retro) persists in `~/.gstack/projects/standuply/` and `.gstack/` inside the repo, so a Monday-morning re-read costs nothing.

![A winding charcoal-ink path running across cream paper from upper-left to lower-right, with ten small geometric stations labeled idea, office-hours, autoplan, build, review, qa, ship, deploy, canary, retro; above the start sits a small ink clock showing 8am, and at the end a single editorial red dot marks the live deployed product](/post-images/2026-05-23-gstack-garry-tan-claude-code-developer-guide/15-end-to-end-journey.jpg)

## 8:00am — `/office-hours`: pin down the actual product

```text
You: /office-hours
You: I want to build a Slack standup-summary bot. We have too many channels and nobody reads them.
```

The skill enters **Startup mode** and runs the six forcing questions. Within five exchanges it has pushed back twice on your framing. Illustrative skill output (composite, drawn from the actual `/office-hours` rhetoric in the repo's `SKILL.md`):

```text
/office-hours [pushback]
I'm going to push back. You said "standup-summary bot." Standups
happen at 9am, but the pain you described — "nobody reads channels" —
is an end-of-day problem. What you actually want is a yesterday-digest,
not a standup tool. Different naming, different default schedule,
different acceptance test.
```

It then poses four falsifiable premises (one user job, narrowest wedge, future fit, demand reality), captures your one-line answers, and writes a design doc to `~/.gstack/projects/standuply/design.md`. Output: a 1.5-page doc with a sharpened product name (**\"yesterday-digest, posted at 9am\"**), one primary capability (synthesize last 24h of channel messages into one paragraph), and three deferred capabilities (custom prompts, thread-level summaries, per-person attribution).

🟢 **Elapsed: ~7 minutes. State written: `~/.gstack/projects/standuply/design.md`.**

## 8:10am — `/autoplan`: collapse CEO + design + eng + DX reviews into one pass

```text
You: /autoplan
```

`/autoplan` reads `design.md` and runs the four review skills sequentially, applying its six encoded principles. The output stream is concise: it shows what each review found, what it auto-resolved, and what it's escalating to you.

- **CEO review:** SELECTIVE EXPANSION. Surfaces three opportunities. Auto-accepts \"per-channel scheduling\" (matches existing pattern, low cost), defers \"AI-generated channel tags\" (ambiguous PII), escalates \"per-team billing\" (security gate triggered).
- **Eng review:** Locks the architecture as **Cloudflare Worker + Durable Object cron + Slack OAuth + KV for last-summary timestamps**. Writes a 7-row data flow ASCII diagram and a 9-row test matrix including the time-zone edge case (DST transitions) you would have missed.
- **Design review:** N/A — no UI surface beyond a Slack OAuth install page. Auto-skipped.
- **DX review:** N/A — internal-only. Auto-skipped.

`/autoplan` surfaces **two taste decisions** at the end. Illustrative escalation block (composite):

```text
/autoplan [escalation]
(1) Empty-state copy for the install page:
    "Connect your Slack workspace"
      vs
    "Get yesterday-digest in your standup channel"
    Codex preferred the second; Claude preferred the first.
(2) Per-team billing was escalated to you (security gate).
```

You answer the first in seconds (pick Codex's framing — it leads with the value), and resolve the second (\"no billing for v1, security gate cleared\"). Plan is locked.

🟢 **Elapsed: ~12 minutes. State: `~/.gstack/projects/standuply/plan.md` + `architecture.md` + `tests.md`.**

## 8:25am — Implementation: 2,400 lines across 11 files

```text
You: Approve plan. Exit plan mode. Implement.
```

This is the only step where you stop typing slash commands and let Claude run. The locked plan acts as the contract. Claude writes the Worker, the OAuth flow, the Durable Object cron, the KV state, the Slack message formatter, the OpenAI summarization prompt, the wrangler.toml, and the migration that creates the `installations` table in D1.

🟡 **Elapsed: ~22 minutes. State: 11 files, 2,400 LOC, ~700 logical SLOC per the gstack methodology.**

## 8:47am — `/review`: catch the bugs that pass CI

```text
You: /review
```

`/review` runs against the diff and produces a structured report. It auto-fixes three mechanical issues with `[AUTO-FIXED]` tags:

1. An N+1 query in `listInstallations()`, auto-fixed with `IN ($1, $2, ...)`.
2. A `try/catch` swallowing a Slack rate-limit error, auto-fixed to re-throw on 429.
3. A missing `await` on the KV write inside the cron handler, auto-fixed.

It flags one issue for your decision. Illustrative finding (composite):

```text
/review [HIGH] prompt-injection vector in summarize.ts
The summarization prompt pulls text from arbitrary Slack messages.
A hostile message in a channel can hijack the summary.
Recommended fix: wrap untrusted message bodies in an <UNTRUSTED>
envelope and instruct the model to treat envelope content as data.
Apply? [y/n]
```

You approve. `/review` writes the fix as a one-liner in `summarize.ts` and adds a regression test that asserts a hostile message containing \"ignore previous instructions\" does not influence the summary. The regression test passes.

🟢 **Elapsed: ~6 minutes. State: 4 commits, 1 regression test, the prompt-injection envelope as a per-project learning written to `~/.gstack/projects/standuply/learnings.jsonl`.**

## 8:53am — `/cso`: OWASP + STRIDE pass

```text
You: /cso
```

The Chief Security Officer skill scans the diff. It returns three findings, each with a concrete exploit scenario:

| # | Finding | Exploit |
|---|---|---|
| 1 | OAuth state token uses `Math.random()` | Predictable state allows CSRF on install |
| 2 | Bot token stored in D1 without encryption | DB read leak exposes all customer tokens |
| 3 | No rate limit on the `/install` endpoint | DoS via install storms |

🔴 Each is rated at confidence ≥8/10. You apply all three: swap to `crypto.randomUUID()` for state, wrap the token column in `AES-GCM` with a Workers secret, add a 10-req-per-IP-per-minute rate limit via Workers Rate Limiting. Total fix time: 8 minutes.

🟢 **Elapsed: ~14 minutes. State: 3 commits, OWASP-clean.**

## 9:07am — `/qa`: real-browser test against staging

```text
You: deploy to staging, then /qa https://standuply-staging.workers.dev
```

You push to a staging branch, Cloudflare deploys in 30 seconds. `/qa` opens a real Chromium browser via the gstack browse daemon, walks the Slack OAuth install flow, screenshots every step, and exercises the cron path by manually invoking the Durable Object alarm via the staging admin endpoint.

It finds two bugs:

1. The Slack OAuth callback returns a 500 if the user denies the scope. Reproduces in screenshot. Atomic commit: `fix(oauth): handle user-denial path with friendly redirect`. Regression test added.
2. The summary message renders with no markdown when posted to a channel that has Slack's WYSIWYG composer disabled. Atomic commit: `fix(slack): use mrkdwn=true on message payload`. Regression test added.

Re-runs both bugs through the same flow. Both green.

🟢 **Elapsed: ~18 minutes. State: 2 commits, 2 new regression tests at `tests/regression/qa-{1,2}.spec.ts`, 4 screenshots in `.gstack/qa-reports/`.**

## 9:25am — `/ship`: open the PR

```text
You: /ship
```

`/ship` syncs main (already in sync), runs `bun test` (all green, 14 tests, 9 new from this sprint), pushes the branch, and opens a PR. The PR description is auto-generated from the diff plus the design doc, structured as: **Problem → Change → Test plan → Screenshots from `/qa` → Security notes from `/cso`**. Reviewers assigned per `CODEOWNERS`.

🟢 **Elapsed: ~3 minutes. State: PR #1 open at github.com/you/standuply/pull/1.**

## 9:28am — Self-review pause

This is the only step where gstack pauses for you. You read your own diff. You approve. (For a real team, two human reviewers would sign off here. For a solo Saturday build, your one approval is the gate.)

🟢 **Elapsed: ~5 minutes.**

## 9:33am — `/land-and-deploy`: from approved to live in production

```text
You: /land-and-deploy
```

Configured once by `/setup-deploy` an hour earlier when you scaffolded the repo. `/land-and-deploy` squash-merges to main, waits for the Cloudflare Workers GitHub Action (4 minutes), polls `https://standuply.workers.dev/_health` until it returns 200, then chains automatically into `/canary` for a 30-minute watch.

🟢 **Elapsed: ~4 minutes. State: production deploy + canary armed.**

## 9:37am — `/canary`: 30-minute post-deploy watch

```text
[/canary auto-started by /land-and-deploy]
```

Runs in the background. You make coffee. Twelve minutes in, `/canary` pings your `#deploys` Slack channel with a yellow flag: \"INP regressed on `/install` from 90ms baseline to 220ms.\" You glance at the screenshot, see it's the new rate-limiter middleware running on cold-start, and decide to accept it (the path is rare and the regression is below your threshold). The canary clears at 10:07am with one acknowledged regression.

🟢 **Elapsed: 30 minutes (background). One acknowledged warning, no rollback.**

## 10:10am — `/document-release`: keep the docs honest

```text
You: /document-release
```

Reads the diff, walks the docs tree, finds the `README.md` doesn't yet mention the install URL or the env-var requirements. Writes both. Generates a **Diataxis coverage map** in the PR-follow-up note: \"reference: 0 gaps; how-to: 0 gaps; tutorial: 1 gap — no 'first-Slack-install' tutorial yet.\" You decide the tutorial gap is fine for v0; it'll get written when the second customer asks for it.

🟢 **Elapsed: ~4 minutes. State: README.md updated, coverage map saved.**

## 10:14am — `/retro`: capture the learning

```text
You: /retro
```

`/retro` reads the morning's git log + gstack analytics and produces a one-page Markdown retro. The headline numbers: **11 files, 2,400 LOC, 14 tests (5 from `/review`, 4 from `/qa`, 5 from initial impl), 4 deploys, 1 live release, 2 hours 14 minutes total**. Top friction: the Slack OAuth user-denial path that `/qa` caught — flagged as \"missing from initial plan, would have been caught earlier by a more rigorous `/plan-eng-review`.\" `/retro` writes that learning back to `~/.gstack/projects/standuply/learnings.jsonl` so the next time you build something with OAuth, the plan-stage review will check for it.

🟢 **Elapsed: ~3 minutes. State: `retros/2026-05-23.md` + 1 new learning.**

## Total

| Phase | Skill | Elapsed | Cumulative |
|---|---|---:|---:|
| Think | `/office-hours` | 7m | 7m |
| Plan | `/autoplan` | 12m | 19m |
| Build | (impl) | 22m | 41m |
| Review | `/review` | 6m | 47m |
| Secure | `/cso` | 14m | 1h 1m |
| Test | `/qa` | 18m | 1h 19m |
| Ship | `/ship` | 3m | 1h 22m |
| (pause) | self-review | 5m | 1h 27m |
| Deploy | `/land-and-deploy` | 4m | 1h 31m |
| Watch | `/canary` (bg) | 30m | 2h 1m |
| Doc | `/document-release` | 4m | 2h 5m |
| Reflect | `/retro` | 3m | 2h 8m |
| **Active time** | | | **~1h 38m** |
| **Wall-clock** | | | **~2h 14m** |

🟢 **One Saturday morning. 14 of the 33 skills used. Idea to live, fully tested, security-audited, documented, retroactively learning-captured.** The skills you did *not* use, `/design-shotgun`, `/design-html`, `/design-review`, `/plan-design-review`, `/devex-review`, the `/ios-*` suite, would have come in for a UI-heavy or developer-facing or iOS product. They were not needed here because standuply has no UI beyond an OAuth-install page.

## What this walkthrough does not show

🟡 **Three honest caveats.** First, you would have a worse experience on a repo without `/setup-deploy` already configured — add 5 minutes for that. Second, the Cloudflare Workers deploy is unusually fast (~30 seconds); on Fly Machines or AWS ECS it would have been 3–5 minutes per deploy, and there were four of them. Third, the prompt-injection finding from `/review` is the kind of issue most solo developers would not have spotted unaided. That single catch is, by itself, a stronger argument for gstack than the productivity numbers anywhere else in the discourse.

🟢 **The walkthrough's load-bearing claim:** every step here was either a skill invocation or an explicit human decision. There were exactly **four** taste-level decisions you made during the sprint, the four `/autoplan` surfaced and the one self-review pause. Everything else, the architecture, the tests, the security fixes, the documentation, the canary watch, was mechanical execution by skills with state passed through the file system. That's the difference between a copilot and a sprint.

# 19. The LOC controversy, decoded

No piece on gstack is complete without addressing the public fight that defines its outside reputation. Here is what actually happened.

**On March 15, 2026**, three days after the gstack launch, Garry tweeted:

> I'm going to rile up the trolls with this right now but I am working on 3 different big projects simultaneously across 15 @conductor_build sessions all the time. In the last 7 days I'm averaging 17k lines of code per day, 35% tests, all thanks to gstack.
>
> — [@garrytan](https://x.com/garrytan/status/2033306615966060734), March 15, 2026

**654 likes, 27 reposts, 139,000 views, 111 replies.** The replies arrived fast. Two of the most-cited:

> this many LoC is not a good thing. why are we glorifying this? 'I did 100k lines of code with an llm' is not a flex. im all for the use of LLMs, but filling repos with thousands of lines of slop is bad. how about you use 'features added' or 'bugs fixed' instead of 'lines of slop'.
>
> — [@JackBra74966037](https://x.com/garrytan/status/2033306615966060734), reply, March 16, 2026

> Volume is not precision. Precision is what moves fast.
>
> — [@fred_pope](https://x.com/garrytan/status/2033306615966060734), reply, March 16, 2026

The dunking compounded for two weeks. The single most-viewed piece of public criticism was developer **Gregorein's** April 1 audit of `garryslist.org`, Garry's personal newsletter site, ostensibly built with gstack:

> So… I audited Garry's website after he bragged about 37K LOC/day and a 72-day shipping streak. Here's what 78,400 lines of AI slop code actually looks like in production. A single homepage load of https://garryslist.org/ downloads 6.42 MB across 169 requests. For a newsletter-blog-thingy.
>
> — [@Gregorein](https://x.com/Gregorein/status/2038953944475472316), April 1, 2026

**7,693 likes, 628 reposts, 2.78 million views.** That single thread has more views than every other piece of gstack criticism combined. The findings: 28 test files shipped to prod, duplicate/unused JS controllers, uncompressed PNGs, an empty 0-byte AVIF in production, a rich-text editor on a read-only page.

Gregorein's closing line is the one most-quoted in the discourse:

> AI amplifies whatever process you feed it — including no process at all. Garry's site is what happens when you replace code review with a shipping streak counter. A Duolingo streak for `git push` 🔥
>
> — [@Gregorein](https://x.com/Gregorein/status/2038953944475472316), closing of the same thread, April 1, 2026

[TechCrunch](https://techcrunch.com/2026/03/17/why-garry-tans-claude-code-setup-has-gotten-so-much-love-and-hate/) had already framed the fight as *\"love and hate\"* on March 17, quoting an anonymous founder reply that captures the strongest version of the dunk:

> (1) Garry should be embarrassed for tweeting this. (2) If it's true, that CTO should be fired immediately.
>
> — anonymous founder, [quoted in TechCrunch](https://techcrunch.com/2026/03/17/why-garry-tans-claude-code-setup-has-gotten-so-much-love-and-hate/), March 17, 2026

🔴 **Then, on April 18, five weeks after the original tweet, Garry pivoted.** He shipped v1.0.0 of gstack with [a Markdown defense file](https://github.com/garrytan/gstack/blob/main/docs/ON_THE_LOC_CONTROVERSY.md) inside the repo and a tweet:

> GStack is now v1.0.0. And yes, I swapped using LOC for logical SLOC, and the wild thing is the functional increase in productivity per day didn't go down from my stats from 2013 to this year. They went up.
>
> — [@garrytan](https://x.com/garrytan/status/2045399029560033551), April 18, 2026

The defense file's core argument is a three-branch deconstruction of the critic position, the kind of essay you write when you've actually read every reply:

> **Branch 1: LOC doesn't measure quality.** True. Always has been.
>
> **Branch 2: AI inflates LOC.** True. LLMs generate verbose code by default.
>
> **Branch 3: Therefore bragging about LOC is embarrassing.** This is where the argument jumps the track. Branch 2 is the interesting one. If raw LOC is inflated by some factor, the honest thing is to compute the deflation and report the deflated number. That's what this post does.
>
> — Garry Tan, [`ON_THE_LOC_CONTROVERSY.md`](https://github.com/garrytan/gstack/blob/main/docs/ON_THE_LOC_CONTROVERSY.md), April 18, 2026

The math, after running `scripts/garry-output-comparison.ts` across 41 `garrytan/*` repos (excluding one demo repo `tax-app`):

| | 2013 (full year, Bookface era) | 2026 (108 days, gstack era) | Multiple |
|---|---:|---:|---:|
| Logical SLOC | 5,143 | 1,233,062 | **240×** |
| Logical SLOC/day | 14 | 11,417 | **810×** |
| Commits | 71 | 351 | 4.9× |
| Files touched | 290 | 13,629 | 47× |
| Active repos | 4 | 15 | 3.75× |

The script (logical SLOC = lines minus blanks minus comments) is open source, runnable by anyone with `git clone` and a few `garrytan/*` repos worth of cloned data.

![A two-column comparison on cream paper: the left column labeled 2013 contains a single short charcoal-ink block representing 14 lines per day, the right column labeled 2026 contains a tall stack of fourteen blocks representing 11,417 lines per day, with the topmost block in the right stack shaded solid red](/post-images/2026-05-23-gstack-garry-tan-claude-code-developer-guide/05-loc-comparison.jpg)

🟢 **The structure of the disagreement, read end-to-end:** the critics and Garry mostly agree on Branches 1 and 2. Both sides accept raw LOC is a bad metric and that AI inflates LOC. The fight is **entirely on Branch 3**, is *publishing* a productivity number, after you've deflated for AI bloat, useful self-tracking or unbecoming founder theatre? The strongest version of each position:

- **Critics:** the act of publishing the number is the problem. \"Tell me you aren't an engineer.\" The frame (\"810×\"!) overwhelms whatever methodology sits behind it. From HN's most-cited dunk: *\"To the best of my knowledge Linus Torvalds isn't posting walls of text to Github breathlessly announcing he's 810x-ed his 'logical lines of code/day' compared to what he was doing in 2013\"* ([toraway, May 1, 2026](https://news.ycombinator.com/item?id=47981349)).

- **Garry:** the honest move is to actually do the math, publish the script, and let the number stand. He never re-litigates the CTO \"god mode\" anecdote, never re-publishes a raw LOC number, and never re-engages the loudest dunkers by name.

🟡 What Garry does *not* address publicly: whether `garryslist.org` (the 78,400-line site Gregorein audited) is in the corpus the 810× math is computed on, the error rates / revert counts / DAUs the original replies asked for, and the CTO \"god mode\" anecdote. The Gregorein audit short-circuits the entire methodology debate by attacking the **artifact** rather than the math. No methodology dispute survives a screenshot of an empty 0-byte AVIF in production.

🔴 **The editorial read:** the LOC fight has become a proxy for a question about founder discourse norms in the AI era, not about LOC. *\"Should a CEO publish self-tracking metrics from AI-augmented work at all?\"* The fight is so good (and so high-engagement) that it has crowded out the much simpler question this piece tried to answer: *what's in the repo, and is it useful?*

![A sparse vertical timeline in cream and red, with five labeled milestones, March 12 launch, March 15 17k-LOC tweet, April 1 Gregorein audit, April 18 v1.0 logical-SLOC pivot, May 23 101K stars, drawn as ink dots on a thin charcoal line, the April 18 dot circled in red as the inflection point](/post-images/2026-05-23-gstack-garry-tan-claude-code-developer-guide/02-loc-timeline.jpg)

# 20. What outside reviewers actually found when they used it

![Three concentric ink rings on cream paper, the innermost small and sparse with a few dots (actual users), the middle with more dots (press and influencers), the outermost dense with dots (the dunk economy), and a single red dot sitting at the boundary between the outer ring and the middle ring marking the Gregorein audit as the breakthrough piece](/post-images/2026-05-23-gstack-garry-tan-claude-code-developer-guide/04-discourse-rings.jpg)

Outside the dunk economy, three substantive reviews stand out.

The **single sharpest endorsement-by-mechanism** comes from [Utkarsha Bakshi on Agile Insider](https://medium.com/agileinsider/i-tried-gstack-by-garry-tan-heres-my-honest-take-6550ac9e8db8). After running gstack on her own tech spec:

> Over the weekend, my X feed was full of gstack posts. People either loved it or were writing it off as hype. I was in the middle of refining a tech spec for a side project, so I decided to stop reading takes and just try it. At the end of Eng Review, gstack pulled together every decision and open question into a structured epic with task breakdowns. AI that asks uncomfortable questions beats AI that writes code.
>
> — Utkarsha Bakshi, [Medium / Agile Insider](https://medium.com/agileinsider/i-tried-gstack-by-garry-tan-heres-my-honest-take-6550ac9e8db8), April 2026

That last sentence is the most quotable in the entire user-side corpus. It captures what gstack's defenders actually like: the **interrogation pattern**, not the codegen. `/office-hours` and `/plan-eng-review` are pulled-on more than `/ship` and `/qa` per Garry's own [analytics](https://x.com/garrytan/status/2045404377226285538).

The **most balanced long-form take on Hacker News** is [MaxLeiter / Madrox](https://news.ycombinator.com/item?id=47418781), 5 days post-launch:

> I've been using gstack for the last few days, and will probably keep it in my skill toolkit. There's a lot of things I like. It maps closely to skills I've made for myself. First, I appreciate how he implemented auto-update. Not sure if that pattern is original, but I've been solving it in a different-but-worse way for a similar project. NOT a fan of how it's being used to present articles on Garry's List. I like the site, but that's a totally different lane. The skills are great for upleveling plans. Claude in particular has a way of generating plans with huge blind spots. The plan skills do a fair job at helping catch gaps so I don't have to ralph-wiggum later. I don't find the CEO skill terribly effective, but I do like the role it plays at finding delighters for features.
>
> — MaxLeiter, [Hacker News](https://news.ycombinator.com/item?id=47418781), March 17, 2026

And the **most-cited dismissal**, from Mo Bitar's [\"AI is making CEOs delusional\"](https://www.youtube.com/watch?v=Q6nem-F8AG8) YouTube, which TechCrunch and the Substack synthesis both link to:

> One of them says, 'Act like a staff engineer.' That's the product. That's G stack. Everyone has this. Every developer who's used Claude Code for more than a week has a version of this.
>
> — Mo Bitar, [YouTube](https://www.youtube.com/watch?v=Q6nem-F8AG8), March 2026

🟡 The Bitar critique is the right one, in a narrow sense. The literal contents of gstack are Markdown files with role descriptions and decision principles. Anyone who's spent two weeks on Claude Code has scribbled some version of *\"act like a staff engineer\"* into their CLAUDE.md. What Bitar's framing misses is the *integration*: the 33 skills share state, feed each other, persist memory, and run as a sprint. The difference between \"a skill\" and \"a skill pack\" is the difference between a prompt and an operating system. Critics treat the skill pack as the prompt; users treat it as the OS.

# 21. Karpathy's four failure modes, addressed

![A vertical checklist illustration on cream paper, four checkbox rows stacked vertically, each with a small charcoal-ink square checkbox already filled with a charcoal check-mark and a short hand-drawn label line to its right; to the right of the four rows a single small editorial red ink star marks the entire checklist as a callout](/post-images/2026-05-23-gstack-garry-tan-claude-code-developer-guide/14-karpathy-failure-modes.jpg)

A separate strand of the discourse compares gstack against [Andrej Karpathy's AI coding rules](https://github.com/forrestchang/andrej-karpathy-skills) (17,000 GitHub stars), which name **four canonical failure modes** of AI-augmented coding:

| Karpathy failure mode | What gstack does about it |
|---|---|
| **Wrong assumptions** | `/office-hours` forces assumptions into the open before code is written. The Confusion Protocol prevents Claude from guessing on architectural decisions. |
| **Overcomplexity** | `/review` catches unnecessary complexity. `/plan-ceo-review` REDUCTION mode cuts scope. |
| **Orthogonal edits** | `/freeze` locks edits to one directory. `/review` flags drive-by edits. `/investigate` auto-freezes. |
| **Imperative over declarative** | `/ship` transforms tasks into verifiable goals. Test-first execution. |

🟢 The architectural argument the gstack README makes: *if you use Karpathy-style CLAUDE.md rules, gstack is the workflow enforcement layer that makes them stick across entire sprints, not just single prompts.* That's the strongest framing of how gstack relates to its predecessors. Karpathy's pack tells the model what *not* to do per-prompt. gstack stitches the *not-doing* into multi-step sprints.

# 22. Who this is for, and who it isn't

The README states the three audiences explicitly:

1. **Founders and CEOs**, especially technical ones who still want to ship
2. **First-time Claude Code users**, structured roles instead of a blank prompt
3. **Tech leads and staff engineers**, rigorous review, QA, and release automation on every PR

🟢 Read against the reactions corpus, that targeting is accurate. The endorsements come from these three groups. The dunks come from somewhere else, developers who have spent a year on Claude Code, written their own skills, and react to gstack as if it's *replacing* their craft. Mo Bitar's *\"every developer has a version of this\"* is the cleanest expression of that disposition.

🔴 **gstack is for the people who don't have a version of this.** It is the skill pack you give to a YC founder who needs to ship before they have time to develop their own taste. It is the skill pack you install on day one of a new repo so the team's reviews run consistently rather than depending on whichever senior engineer happens to look. It is the skill pack you point a contractor at when you can't supervise their PRs end-to-end.

🟡 **gstack is also for tooling researchers**, which is its second, quieter audience. The repo is the largest open-source corpus of Claude Code skill design patterns in existence. Anyone building competing skill packs (or new AI-coding tools entirely) has a reference implementation to study. The frontmatter conventions, the cross-skill state passing, the analytics schema, the security boundaries on `/browse` and `/ios-qa`, all of it is reusable IP under MIT.

🔴 **gstack is not for:** developers who already wrote and tuned their own skill pack and prefer it; engineers in regulated environments that can't run an arbitrary `~/.claude/skills/gstack/` install; users who want every skill loaded inline rather than autoloaded per-task; and, per the [Conductor note in the README](https://github.com/garrytan/gstack/blob/main/USING_GBRAIN_WITH_GSTACK.md#conductor--gstack_-env-vars), users running gstack inside Conductor without setting `GSTACK_ANTHROPIC_API_KEY` / `GSTACK_OPENAI_API_KEY` (which strips the default env vars).

# 23. A view from inside the skill pack

A note on method. Every prior section in this piece reads gstack from the outside: tweets, repo URLs, screenshot citations, third-party reviews, the README and the docs. This section reads it from the inside. The artefacts below are produced by `git clone https://github.com/garrytan/gstack` into a sandbox and then walking the resulting directory with `ls`, `find`, `cat`, and `wc`. The point is not to be exhaustive; the point is to show that the 101,020-star artefact is, at the literal level, a tree of Markdown files plus a handful of TypeScript and shell binaries. Anyone with `git` can reproduce the read.

The clone takes four seconds on a warm connection. The repository, on the canonical `main` branch as of the date of this piece, presents this top level when listed with `ls`:

```text
ARCHITECTURE.md    benchmark-models/    docs/             pair-agent/
CHANGELOG.md       bin/                 document-generate/ plan-ceo-review/
CLAUDE.md          browse/              document-release/  plan-design-review/
CONTRIBUTING.md    browser-skills/      extension/         plan-devex-review/
DESIGN.md          canary/              freeze/            plan-tune/
ETHOS.md           careful/             gstack/            qa/
LICENSE            claude/              gstack-upgrade/    qa-only/
README.md          codex/               guard/             retro/
SKILL.md           connect-chrome/      health/            review/
SKILL.md.tmpl      context-restore/     hosts/             scrape/
TODOS.md           context-save/        ios-clean/         scripts/
USING_GBRAIN_WITH_GSTACK.md             ios-design-review/ ship/
VERSION            cso/                 ios-fix/           skillify/
agents/            design/              ios-qa/            supabase/
autoplan/          design-consultation/ ios-sync/          sync-gbrain/
benchmark/         design-html/         land-and-deploy/   test/
                   design-review/       landing-report/    unfreeze/
                   design-shotgun/      learn/
                   devex-review/        make-pdf/
                                        office-hours/
                                        open-gstack-browser/
                                        openclaw/
```

Sixty-eight top-level directories plus the documentation files. Each directory whose name corresponds to a slash command holds the SKILL.md plus its supporting files. A `find . -name SKILL.md` count returns 57, of which one is at the repository root (the umbrella `gstack` skill), 52 are skill directories one level deep, and four are the OpenClaw native skills under `openclaw/skills/`. A `ls bin/` count returns 62 standalone CLIs, including the `gstack-analytics`, `gstack-model-benchmark`, `gstack-ios-qa-daemon`, and `gstack-ios-qa-mint` binaries the previous sections refer to. A `find . -name "*.ts" -not -path "*/node_modules/*"` count returns 524 TypeScript files, almost all under `design/`, `browse/`, `scripts/`, and the `extension/` subtree. The rest is Markdown.

![An editorial illustration in charcoal ink on cream paper of a hand-drawn directory tree, vintage typewritten outline style, with a root labelled gstack at the top, several flat documentation files beneath it drawn as small page icons, three thicker branches labelled 57 SKILL DIRECTORIES, bin/ 62 CLIs, and openclaw/ 4 NATIVE SKILLS, with a slim charcoal-ink column on the right listing the file totals and a single editorial red ink hand-lettered band marking 101,020 GITHUB STARS](/post-images/2026-05-23-gstack-garry-tan-claude-code-developer-guide/18-directory-tree.jpg)

The shape of a single skill is the next layer to inspect. `ls review/` returns six entries: `SKILL.md`, `SKILL.md.tmpl`, `TODOS-format.md`, `checklist.md`, `design-checklist.md`, and a `specialists/` subdirectory holding the per-area sub-reviewer instructions. `head -25 review/SKILL.md` produces the frontmatter:

```yaml
---
name: review
preamble-tier: 4
version: 1.0.0
description: |
  Pre-landing PR review. Analyzes diff against the base branch for SQL safety, LLM trust
  boundary violations, conditional side effects, and other structural issues. Use when
  asked to "review this PR", "code review", "pre-landing review", or "check my diff".
  Proactively suggest when the user is about to merge or land code changes. (gstack)
allowed-tools:
  - Bash
  - Read
  - Edit
  - Write
  - Grep
  - Glob
  - Agent
  - AskUserQuestion
  - WebSearch
triggers:
  - review this pr
  - code review
  - check my diff
  - pre-landing review
---
```

Six fields. The `name` matches the directory name (the Agent Skills spec enforces this). The `preamble-tier` field is a gstack convention; higher tiers run a longer system audit. The `version` field tracks per-skill semver. The `description` is what Claude Code's skill index surfaces to the host model when deciding which skill to invoke. The `allowed-tools` array names the exact tool subset this skill is permitted to call, an explicit allowlist rather than the host's default. The `triggers` array names the user phrases that should auto-suggest this skill proactively. None of this is novel; it is the Anthropic Agent Skills frontmatter spec applied consistently across 57 skills.

The body of `review/SKILL.md` begins with the bash preamble shown in the architecture section and runs to roughly 2,400 lines. The preamble exports the project slug, the branch, the repo mode, and the path to `learnings.jsonl`. The body then specifies, in plain English plus inline bash, the read-upstream-state procedure, the diff-analysis procedure, the sub-reviewer spawning procedure, and the write-downstream-state procedure. The `specialists/` subdirectory holds the per-area instructions that the `Agent` tool invokes as sub-reviewers; each specialist is itself a small Markdown file with its own checklist. The composition pattern is consistent: a parent SKILL.md orchestrates, the specialist children are read-as-prompts.

![An editorial side-by-side diagram in charcoal ink on cream paper, two halves separated by a thin vertical charcoal rule, the left half labelled SKILL.md FRONTMATTER drawn as a small hand-typed YAML block, the right half labelled PERSISTENT STATE drawn as a charcoal-ink filing cabinet with four open drawers labelled gstack-projects, dot-gstack, learnings.jsonl, retros, with a single editorial red ribbon arcing from the YAML block to the filing cabinet hand-lettered "declarative on the left, persistent on the right"](/post-images/2026-05-23-gstack-garry-tan-claude-code-developer-guide/19-frontmatter-state.jpg)

The state layer is observable from a clean clone too, even before any skill has run. `grep -rn "~/.gstack/projects" --include="*.md"` against the repository returns more than thirty hits across `office-hours/SKILL.md`, `learn/SKILL.md`, `health/SKILL.md`, `context-save/SKILL.md`, `retro/SKILL.md`, and others. Every one of those hits is a literal path string telling the skill body where to write a state artefact. One representative pair, from `office-hours/SKILL.md`:

```bash
_LEARN_FILE="${GSTACK_HOME:-$HOME/.gstack}/projects/${SLUG:-unknown}/learnings.jsonl"
```

```text
Write to `~/.gstack/projects/{slug}/{user}-{branch}-design-{datetime}.md`.
```

The first line is the bash that exports the path. The second is the Markdown that tells the model where to put the design doc. The skill body composes the path from `$GSTACK_HOME`, the slug, the user, the branch, and the timestamp. The convention is hardcoded in the skill body; the directory does not have to exist until the skill creates it. Multiple skills writing to the same `<slug>/` directory is the entire mechanism of cross-skill state passing.

The `ARCHITECTURE.md` file at the repo root names the operational layer that the slash-command skills run *above*. It opens with: *"gstack gives Claude Code a persistent browser and a set of opinionated workflow skills. The browser is the hard part, everything else is Markdown."* The browser pieces are the Bun-compiled CLI under `browse/src/`, the long-lived Chromium daemon, the localhost HTTP server, and the tunnel-vs-loopback access matrix the architecture doc lays out across roughly sixty rate-limited endpoints. The `bin/gstack-browse` binary is what every skill that needs a browser calls; `connect-chrome/`, `setup-browser-cookies/`, and `open-gstack-browser/` are skills that compose the daemon for specific user-facing workflows.

The OpenClaw surface lives in a parallel directory. `ls openclaw/` returns `agents-gstack-section.md`, three CLAUDE.md variants (full, lite, plan), and `skills/` with four subdirectories: `gstack-openclaw-ceo-review`, `gstack-openclaw-investigate`, `gstack-openclaw-office-hours`, `gstack-openclaw-retro`. Each contains a SKILL.md whose frontmatter is shorter than the Claude Code ones (no `preamble-tier`, no `allowed-tools`, no `triggers`) because OpenClaw's host runtime uses a thinner contract. The body of `gstack-openclaw-ceo-review/SKILL.md` opens with: *"You are not here to rubber-stamp this plan. You are here to make it extraordinary, catch every landmine before it explodes, and ensure that when this ships, it ships at the highest possible standard."* The same rhetoric and the same four-mode framework (SCOPE EXPANSION, SELECTIVE EXPANSION, HOLD SCOPE, SCOPE REDUCTION) appear in the Claude Code `plan-ceo-review/SKILL.md`. The skill content is the asset; the host is the runtime.

The infrastructure under `scripts/`, `setup`, `bin/`, and `test/` is the part most readers never inspect. The `setup` script is a 46,444-byte single-file installer that links the skills into `~/.claude/skills/gstack/`, writes the per-platform configuration, and runs the smoke tests. The `test/` directory holds the harness that exercises the skill pack end-to-end against fixtures. The `scripts/` directory holds the operational utilities (slug computation, telemetry sync, learnings search, security dashboard generation) that the slash-command skills shell out to through the `bin/` wrappers. The `extension/` directory holds the GStack Browser companion extension, the source for the small UI sidebar the `/browse` daemon exposes at `http://localhost:<port>/welcome`.

The total surface, counted directly from the clone:

| Artefact | Count | Notes |
|---|---:|---|
| Top-level directories | 68 | Mix of skills, infrastructure, vendored deps |
| `SKILL.md` files | 57 | 52 Claude Code skills + 4 OpenClaw + 1 umbrella |
| `bin/` CLIs | 62 | TypeScript-compiled and shell scripts |
| TypeScript files | 524 | Browser, design, scripts, extension |
| Root docs | ~12 | README, ARCHITECTURE, ETHOS, USING_GBRAIN, etc |

That is the entire engineering surface. Almost no compiled state, almost no opaque binaries, no proprietary protocols. The argument that anybody with a week on Claude Code has "a version of this" is partially true: the role descriptions are not technically hard. The argument that the integration is not technically hard is the part that does not survive a walk through the clone. The integration is in the path conventions, the frontmatter conventions, the sub-reviewer spawning patterns, the cross-skill state schema, the per-remote trust policies, the tunnel-vs-loopback security matrix, and the analytics pipeline. Those are written down. They are in this directory. The directory is the documentation of the architecture, and it is `git clone`-able by anyone.

# 24. The argument the LOC fight has buried

![An empty exoskeleton or mech suit drawn as flat charcoal-ink geometric shapes on cream paper, articulated with hinges and ribbed sections, standing upright in the center, with a single small editorial red badge over the chest plate, evoking Garry Tan's mech-warrior-suit framing of gstack as a transferable exoskeleton anyone can put on](/post-images/2026-05-23-gstack-garry-tan-claude-code-developer-guide/06-mech-suit.jpg)

There is a final, structural fact about gstack that the public fight has hidden. It is the only Claude Code skill pack that has shipped:

1. A complete sprint methodology with state passing forward between skills.
2. A real Chromium browser primitive (`/browse`, GStack Browser, `/pair-agent`) that other agents can co-drive.
3. A persistent memory layer (`/setup-gbrain`, `/sync-gbrain`) with per-repo trust policies (read-write / read-only / deny) that solve the multi-client-consultant problem natively.
4. A live iOS device farm (v1.43.0+) with capability-tier allowlists, audit logs, and remote agent access via Tailscale.
5. A cross-model benchmark (`gstack-model-benchmark`, `/codex`) that lets two models review the same branch.
6. An opt-in analytics pipeline that produces verifiable adoption data (the 305,309-invocation number), a thing no other skill pack ships.

That is a substantial engineering surface for a free, MIT-licensed, eleven-week-old project shipped by one person part-time while running YC. Whether you agree with Garry's LOC math, his SXSW \"cyber psychosis\" framing, or the design of `garryslist.org` is independent of whether the six items above are useful to you.

🟢 **The clean recommendation:** install gstack with the README's 30-second command. Run `/office-hours` on something. Run `/plan-ceo-review` and `/plan-eng-review` on the output. Skip directly to `/qa` on your existing staging environment. Stop there. The README's own quick-start says the same: *\"Stop there. You'll know if this is for you.\"* Most of the productive disagreement about gstack happens *after* this five-minute test, not before it.

The dunk economy will keep dunking. The 7,000 weekly active users will keep shipping. The two populations don't overlap much. The skill pack, measured by what it does in a sprint, not what its author tweets, is the most complete open-source Claude Code workflow that exists today. The question is whether you need a sprint, or whether you already have one. The five-minute test will tell you which.

## Sources

- [garrytan/gstack — repository (101,020 stars, 15,047 forks, MIT)](https://github.com/garrytan/gstack)
- [garrytan/gstack — README](https://github.com/garrytan/gstack/blob/main/README.md)
- [gstack — canonical skills reference (docs/skills.md, 1,260 lines)](https://github.com/garrytan/gstack/blob/main/docs/skills.md)
- [gstack — ON_THE_LOC_CONTROVERSY.md (Garry's three-branch defense)](https://github.com/garrytan/gstack/blob/main/docs/ON_THE_LOC_CONTROVERSY.md)
- [gstack — ETHOS.md (Boil the Lake, Search Before Building)](https://github.com/garrytan/gstack/blob/main/ETHOS.md)
- [gstack — ARCHITECTURE.md](https://github.com/garrytan/gstack/blob/main/ARCHITECTURE.md)
- [gstack — USING_GBRAIN_WITH_GSTACK.md](https://github.com/garrytan/gstack/blob/main/USING_GBRAIN_WITH_GSTACK.md)
- [gstack — BROWSER.md](https://github.com/garrytan/gstack/blob/main/BROWSER.md)
- [gstack — CHANGELOG.md](https://github.com/garrytan/gstack/blob/main/CHANGELOG.md)
- [Garry Tan — original 17k-lines/day post (March 15, 2026, 654 likes, 139K views)](https://x.com/garrytan/status/2033306615966060734)
- [Garry Tan — v1.0.0 release / logical SLOC pivot (April 18, 2026)](https://x.com/garrytan/status/2045399029560033551)
- [Garry Tan — real-users metrics post (April 18, 2026)](https://x.com/garrytan/status/2045404377226285538)
- [Garry Tan — Bookface 2,400-line PR post (March 24, 2026)](https://x.com/garrytan/status/2036330296308802012)
- [Garry Tan — GStack v1.28 browser update (May 8, 2026)](https://x.com/garrytan/status/2052588548126364028)
- [Garry Tan — iOS QA launch (May 21, 2026)](https://x.com/garrytan/status/2057599962465309113)
- [Gregorein — the gslop audit thread (April 1, 2026, 7,693 likes, 2.78M views)](https://x.com/Gregorein/status/2038953944475472316)
- [TechCrunch — Why Garry Tan's Claude Code setup has gotten so much love, and hate (Julie Bort, March 17, 2026)](https://techcrunch.com/2026/03/17/why-garry-tans-claude-code-setup-has-gotten-so-much-love-and-hate/)
- [Mo Bitar — AI is making CEOs delusional (YouTube)](https://www.youtube.com/watch?v=Q6nem-F8AG8)
- [handyai.substack.com — Your CEO is suffering from AI psychosis (Jake Handy, April 15, 2026)](https://handyai.substack.com/p/your-ceo-is-suffering-from-ai-psychosis)
- [Hacker News — primary gstack submission (March 12, 2026)](https://news.ycombinator.com/item?id=47355173)
- [Hacker News — toraway, the mania read on Garry's 810x claim (May 1, 2026)](https://news.ycombinator.com/item?id=47981349)
- [Hacker News — Madrox/MaxLeiter long-form gstack review (March 17, 2026)](https://news.ycombinator.com/item?id=47418781)
- [Medium / Agile Insider — Utkarsha Bakshi, gstack review (April 2026)](https://medium.com/agileinsider/i-tried-gstack-by-garry-tan-heres-my-honest-take-6550ac9e8db8)
- [Reddit — r/ClaudeAI gstack megathread (March 30, 2026)](https://www.reddit.com/r/ClaudeAI/comments/1s7jdof/)
- [Andrej Karpathy — original Claude Code skill pack (17K GitHub stars)](https://github.com/forrestchang/andrej-karpathy-skills)
- [Anthropic — Claude Code documentation](https://docs.anthropic.com/en/docs/claude-code)
- [Conductor — parallel Claude Code workspace tool](https://conductor.build)
- [Bun — JavaScript runtime (gstack dependency)](https://bun.sh/)
- [Pretext (Cheng Lou) — 15KB layout-without-DOM-measurement library used by /design-html](https://github.com/chenglou/pretext)
- [GBrain — persistent memory for AI agents (Garry Tan)](https://github.com/garrytan/gbrain)
- [Greptile — code review platform integrated by /review](https://greptile.com)

---

Canonical: https://www.thedeepfeed.ai/posts/2026-05-23-gstack-garry-tan-claude-code-developer-guide/
Site: https://www.thedeepfeed.ai
Full corpus: https://www.thedeepfeed.ai/llms-full.txt