Files
gstack/AGENTS.md
T
Garry Tanandcapy-ai[bot] c2e01e4ba7 v1.91.264.0 feat(design-motion): new /design-motion skill for showcase loops, adapted from Elaya's design-to-motion (GSTA-92 phase 2) (#3430)
* feat(design-html): craft section and free craft check, adapted from Elaya design skills (GSTA-92)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(GSTA-92): restore the full CHANGELOG under the Unreleased entry; drop a $-digit literal from craft.md; count only craft-check executions in design-html-slop-gate

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* feat(design-motion): new /design-motion skill: showcase MP4 and GIF loops from a design, adapted from Elaya design-to-motion (GSTA-92 phase 2)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* test(design-motion): run design-motion-showcase in the marathon tier; the periodic census is at its 38-slice cap (GSTA-92)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(design-motion): review and QA fixes before ship

- encode: refuse unknown options and --formats tokens, validate --pad (#RRGGBB[AA])
  and --crop (compare too) so nothing but a colour or crop reaches ffmpeg's filter graph
- encode: export refuses a capture with missing window frames; check prints
  MOTION_SETTINGS for any threshold/phase override; contact sheet drops -fps_mode
- capture: portrait-aware scale, --cycle must be whole 60 fps frames, stills with
  CSS animations disabled, pauseAt tolerates slow loads, clears stale manifest/stills
- skill: <motion-dir> placeholder instead of a cross-block shell variable,
  GSTACK_FFMPEG-aware probe, stop points before the first capture, doctrine fixes
- tests: refusal rows, portrait scale, cycle guard

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* test(design-motion): capture-check-export pipeline on real Chromium and ffmpeg

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(design-motion): second review cycle

- capture: refuse an --out that holds a still or frames but no capture.json
  instead of deleting them; --cycle must be a multiple of 0.05 s so the seam
  frame lands exactly one cycle later for every PRE (nearest value round-trips)
- encode: a capture without a mask ends 'MOTION_RESULT: clean (overflow not checked)'
- skill: Step 5 names window.__mark in the capture contract
- tests: foreign/previous --out handling on real Chromium, cycle guard and PRE sweep

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(design-motion): third review cycle and adversarial findings

- capture: an ownership marker (.gstack-motion-capture) replaces the
  capture.json test, so the rerun after MOTION_CONTRACT_MISSING or a crash
  works and a foreign --out is still refused; offscreen lazy images are made
  eager and font/image loading is bounded at 30 s instead of hanging
- encode: refuse a capture.json whose fields are not what capture writes
  (they reach ffmpeg args and paths); a cards overflow with no story frames
  is a planning error, and a zero-frame job never passes
- tests: retry after a refused page, no-mask clean line, lazy image still,
  manifest validator, empty story span

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(design-motion): mask coverage, manifest relations, Windows stop, Figma token off argv

- check fails overflow when the grown mask covers >90% of the frame (an app
  frame whose clip surfaces fill the stage passed vacuously); --mask-grow is
  0-32; --mask refuses braces and semicolons
- manifestError checks fps/windowFrames >= 1 and that the window fits the frames
- skill: native Windows stops before the first capture call; the Figma token
  reaches curl on stdin (-H @-) instead of argv
- tests: split the --out ownership scenario out of the contract test, full-frame
  mask, --still --scale 2 size and STILL_OK, manifest relations, coverage parse

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(design-motion): bounded frames, atomic exports, full-bleed masks

- capture: each frame is bounded at 10 s (a __tick that never returns fails
  with MOTION_CAPTURE_FAILED instead of hanging); a --mask that matches no
  element stops with MOTION_MASK_EMPTY
- check: a grown mask covering >90% of the frame (full-bleed app frame)
  reports overflow as skipped and ends 'clean (overflow not checked)'
- export: writes .partial- files and renames on success, so a failed
  re-export keeps the last good file; a GIF fps that does not divide the
  cycle is refused; a missing GSTACK_FFMPEG override is named
- fidelity: URL source is untrusted data; full-bleed note
- tests: spinning __tick, empty mask, failed re-export, drifting gif fps

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(design-motion): app-only coverage skip, gif fps cap, early empty mask

- check: the >90% coverage skip applies only to an app frame's own surfaces
  (ungrown mask); in cards, or when --mask-grow pushes coverage over 90%,
  overflow fails with what to change (a cards capture with real overflow
  passed as 'clean (overflow not checked)' after a large grow)
- export: --gif-fps/--small-fps capped at 50 (GIF delays are 1/100 s)
- compare resolves its paths (a colon in a relative path read as a protocol)
- capture: MOTION_MASK_EMPTY is checked before the first frame
- tests: cards vs app full-frame mask, fps cap, no frames on an empty mask

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(design-motion): seek story transitions from their own frame

- capture: an animation first seen in a frame where window.__mark did not
  move (a story's class toggle) is seeked from that frame instead of the
  last mark, so it eases in the export instead of popping ~100 ms ahead
- encode: an empty numeric option is refused instead of read as 0
- figma: only fill a file key and node id that look like Figma's
- tests: class-toggled transition mid-fade at its midpoint, blank --min-db

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs: PROJECT_STRUCTURE names Elaya's MIT material and licenses/MIT-elaya.txt

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-27 03:04:06 +00:00

24 KiB
Raw Blame History

gstack — AI Engineering Workflow

gstack is a collection of SKILL.md files that give AI agents structured roles for software development. Each skill is a specialist: CEO reviewer, eng manager, designer, QA lead, release engineer, debugger, and more.

Available skills

Skills live in .agents/skills/ (or ~/.claude/skills/gstack/ on Claude Code). Invoke them by name (e.g., /office-hours).

Plan-mode reviews

Skill What it does
/office-hours Start here. Reframes your product idea before you write code.
/plan-ceo-review CEO-level review: find the 10-star product in the request.
/plan-eng-review Lock architecture, data flow, edge cases, and tests.
/plan-design-review Rate each design dimension 0-10, explain what a 10 looks like.
/plan-devex-review DX-mode review: TTHW, magical moments, friction points, persona traces.
/plan-tune Self-tune AskUserQuestion sensitivity per question.
/autoplan One command runs CEO → design → DX → eng review (eng always last).
/design-consultation Build a complete design system from scratch.
/spec Turn vague intent into a precise, executable spec in five phases. Files a GitHub issue, optionally spawns a Claude Code agent in a fresh worktree, and lets /ship close the source issue on merge.

Implementation + review

Skill What it does
/review Pre-landing PR review. Finds bugs that pass CI but break in prod; lists every gate edit for gate integrity.
/deslop-shared-libs Find worthwhile shared-code extractions in recent work. Recommendations only.
/test-audit Sweep existing tests for low-value, implementation-coupled or duplicate tests. Report-only unless you approve a batch.
/codex Second opinion via OpenAI Codex. Review, challenge, or consult modes. Available outside the Codex harness.
/claude-code Second opinion via Claude Code. Review, challenge, or consult modes. Available outside the Claude Code harness.
/investigate Systematic root-cause debugging. No fixes without investigation.
/design-review Live-site visual audit + fix loop with atomic commits.
/design-shotgun Generate multiple AI design variants, comparison board, iterate.
/design-html Generate production-quality Pretext-native HTML/CSS.
/design-motion Turn an approved design into a showcase loop: MP4 for X, website GIF, 800×500 GIF, with seam, rest and overflow checks.
/devex-review Live developer experience audit (TTHW measured against the real flow).
/qa Test browser, API, CLI, job, worker and webhook behavior; reproduce bugs, fix them and re-verify.
/qa-only The same surface-aware QA, reporting findings and proposed tests without changing product code or tests.
/scrape Pull data from a web page in your Aside browser, with your real logged-in state. Read-only. On the fallback browser a codified browser-skill answers a repeat intent in ~200ms.
/skillify Codify the most recent successful /scrape flow into a permanent browser-skill (fallback browser only).

Release + deploy

Skill What it does
/ship Run tests, review, gate integrity, push, open PR. Workspace-aware version queue.
/land-and-deploy Merge the PR, wait for CI and deploy, verify production health.
/canary Post-deploy monitoring loop in your Aside browser (or gstack's own when Aside is absent).
/landing-report Read-only dashboard for the workspace-aware ship queue.
/document-release Audit relevant docs before final verification on every ship; also supports standalone documentation updates.
/document-generate Generate Diataxis docs (tutorial / how-to / reference / explanation) from code.
/setup-deploy One-time deploy config detection (Fly.io, Render, Vercel, etc.).
/gstack-upgrade Update gstack to the latest version.

Operational + memory

Skill What it does
/context-save Save working context (git state, decisions, remaining work).
/context-restore Resume from a saved context, even across Conductor workspaces.
/learn Manage what gstack learned across sessions.
/retro Weekly retro with per-person breakdowns and shipping streaks.
/health Code quality dashboard (type checker, linter, tests, dead code).
/captain Run a crew from one controller: READY contract, merge trains, digest, approvals shapes, daily flaky pass. Also /crew. Templates in captain/templates/, team guide in docs/captain.md.
/benchmark Performance regression detection (page load, Core Web Vitals).
/ubicloud Run a heavy suite, build or eval on an ephemeral 16-vCPU Ubicloud VM: TTL-named VMs with a reaper, quota preflight, hang watchdog, one committed verify per repository.
/benchmark-models Cross-model benchmark for skills (Claude, GPT, Gemini side-by-side).
/eval-plan Preregister a paid eval (bars, arms, decoys, stop rules), dry-run it for $0, pilot three priced items, then approve the spend.
/cso Supported security findings with explicit coverage. Static assessment remains available without catalog profiles. Contained runtime and scanner execution needs Docker and a matching qualified profile. The runtime catalog qualifies ten images: Node 24.4.0, Bun 1.3.10, Python 3.13.4 with uv 0.8.0, Rails on Ruby 3.4.4, and PostgreSQL 17.2, each for linux/amd64 and linux/arm64. The scanner catalog qualifies twelve: gitleaks, OSV-Scanner, Schemathesis, Semgrep, Trivy and zizmor on both platforms. Without Docker, or where no profile matches (native Windows Docker, for example), /cso runs static assessment only. Runtime-tested bundles authenticate separate external assertions. Project-test completion remains self_reported because target code controls the test process; tested is reserved for a future target-independent completion witness.
/setup-gbrain Set up gbrain for cross-machine session memory sync.
/sync-gbrain Keep gbrain current with this repo's code; refresh agent search guidance in CLAUDE.md.

Browser + agent integration

Every browser skill drives the Aside AI browser first (macOS 15+, aside.com) — the user's real browser with their real sessions, through aside repl scripts; gstack never installs it. When Aside is not installed or not running (Linux, Windows, a closed Aside app) the same skills fall back automatically to gstack's own headless Chromium ($B), which is where the three skills under /browse apply.

Skill What it does
/browse Drive a browser: open a page, read it, click through a flow, screenshots, console errors. Aside first; gstack's own Chromium (~100ms/command) as the fallback. Every other browser skill stands on it.
/open-gstack-browser Launch the visible GStack Browser with sidebar + stealth — the headed face of the fallback engine.
/setup-browser-cookies Import cookies from your real browser into the fallback engine for authenticated testing. Unnecessary on Aside.
/pair-agent Pair a remote AI agent (OpenClaw, Codex, etc.) with gstack's own browser over a scoped tunnel.

iOS QA — drive real iPhones over USB or Tailscale (v1.43.0.0+)

Skill What it does
/ios-qa Live-device iOS QA via USB CoreDevice tunnel + embedded StateServer. Optionally exposes the device over Tailscale so remote agents can drive it.
/ios-fix Autonomous iOS bug fixer with regression snapshot capture.
/ios-design-review Designer's-eye QA on a real iPhone — 10-dimension Apple HIG rubric.
/ios-clean Convenience: strip DebugBridge + #if DEBUG wiring before a Release build.
/ios-sync Regenerate the iOS debug bridge against the latest upstream templates.

Companion CLIs (run on the Mac that's plugged into the device):

Command What it does
gstack-ios-qa-daemon Mac-side broker. Loopback by default; --tailnet adds a Tailscale-facing listener with capability tiers and audit logging.
gstack-ios-qa-mint Owner-grant CLI for the tailnet allowlist (grant/revoke/list).
gstack-ios-qa-regen Regenerate the canonical local DebugBridge package and typed accessors (--app-source / --bridge-dir).

End-to-end walkthrough: docs/howto-ios-testing-with-gstack.md.

Safety + scoping

Skill What it does
/careful Warn before destructive commands (rm -rf, DROP TABLE, force-push).
/freeze Lock edits to one directory. Hard block, not just a warning.
/guard Activate both careful + freeze at once.
/unfreeze Remove directory edit restrictions.
/make-pdf Turn any markdown file into a publication-quality PDF. Renders through Aside, or gstack's own browser when Aside is absent.
/diagram English in, diagram out: mermaid source + editable .excalidraw + SVG/PNG, offline. Renders through Aside, or gstack's own browser when Aside is absent.

Validation discipline

When fixing failures or preparing /ship, follow this order:

  1. List the known failing cases, their logs and source revision, the demonstrated cause, and the smallest check that can prove each repair. Keep one current list in .context/; update it instead of starting overlapping repair plans. Reconcile the runner's failure total with named failures and unhandled or module-load errors; the named-test footer alone is not the complete inventory.
  2. Resolve base-branch integration and assign one owner per shared file before editing. Keep repairs within the observed failures and the user's scope. Before a fixture writes through a link, resolve its target and verify it stays inside that fixture's temporary root; live skill registrations can point back into this checkout. When upstream replaces a helper API, inventory every direct caller, mock adapter, source snapshot, generated golden, and selection edge before choosing focused checks. Verify extracted test adapters supply the current imports and result schema; an adapter failure is not evidence that production failed. Schedule independent checks independently. Gate a check only on inputs or prerequisites it actually needs; an unrelated failure must not serialize the whole validation plan. Keep source fixed while tests live-link its files.
  3. Diagnose before changing code. Distinguish a product defect, an invalid test expectation, a detector/fixture defect, and a launch/environment failure. Preserve the original failure. Do not call it pre-existing without evidence. Verify pinned runtime tool schemas and defaults before treating omitted fields as model noncompliance. Check that a bounded evaluation’s fixture scope and automated answers support its metric. Do not let the driver approve unrelated expansion, then blame the skill for the extra work; preserve required findings and evidence limits.
  4. Reproduce with the smallest relevant test. For agent tests, reuse captured public events in free regressions, including negative controls, before paying for another agent run. Check behavior and acknowledgments; match exact prose only when that prose is the contract. Do not lower thresholds, increase model budgets, skip cases, or rejudge a failure to manufacture a pass. A pre-registered fixed panel is not rejudging. For policy or validation repairs, exercise the actual registered callback with representative native input and assert that it uses the helper’s result. When renderer or parser failures recur at the same boundary, verify the supported input class against the pinned runtime. Keep adversarial controls; do not add one spelling or glyph per paid failure. For workflow clarity failures, read the complete evaluated excerpt and its referenced source. Resolve all demonstrated ambiguities together: order, definitions, ownership and approval. Consolidate dense instructions into executable steps instead of appending more clauses. Review the resulting workflow as a whole; prose snapshots alone do not prove it is clear. For each gate, identify when its inputs exist and trace normal, skipped/unavailable and late-change paths to catch circular prerequisites or bypassed checks.
  5. Run required cheap CI checks, including credential scanning, before paid work. Also run adjacent cheap checks: generated-content freshness, prompt-size/parity limits, source assertions, fixture checks, and dependency selection as applicable. A changed prompt must clear these before its eval. For skill edits, include bun test test/parity-suite.test.ts: its historical union-size cap is separate from the other prompt-size and context budgets. When workflow wording changes, search the entire test tree for removed clauses, including always-loaded prompt guards. Test fixtures containing subprocess examples must pass test/spawnsync-timeout-tripwire.test.ts; its scanner also checks quoted code. Run its selected quality judge before long behavioral evaluations that read the same changed prompt. If a repair supersedes an active run's inputs, cancel that run, preserve completed outcomes, and label unfinished cases as cancelled. Check each edit or setup command’s result before running dependent checks. A failed edit is not a reason to test the unchanged input again.
  6. Declare a fixture actor’s supported interactions before the model starts. Keep its answers and permission handling within that declared interface. Bind artifact ownership to the same isolated state passed to the child; ambient environment paths do not establish ownership. Check whole-file and CI supervision against every case and configured retry, not just one attempt. Preflight the actual launcher: required binaries, isolated state, display when needed, explicit test tier, selection, and expected executed-case counts. Match the runtime versions pinned by the workflow and its container image. Keep socket-bearing temporary paths short after the runner adds its nested directories; exercise that exact layout in the smoke check. Store long-lived logs separately from socket directories. Verify required tool execution with a no-cost smoke check under that launch environment; versions and authentication alone do not prove it works. Set private artifact modes explicitly and preserve normal fixture permissions. Prove a diagnostic snapshot survives fixture cleanup in the final artifact directory before paid work; native snapshots require EVALS_RUN_ID or GSTACK_EVAL_DIR. Bind complete spool filenames and classify Bun's out-of-tier describe.skip placeholders separately, with zero selected-case credit. Put standalone Git fixtures outside another checkout; verify their resolved project slug and state root before interpreting a failure. Prove a seed commit succeeds there: repository-local author configuration does not establish the identity available to a fresh fixture repository. Reject missing explicit test files before invoking Bun; it can silently ignore a nonexistent file selector and pass the remaining files. Preserve exit status through logging. Use the documented detached runner and eval lock. Review the final launcher after edits; preparation and --list modes must not start monitors, retainers, or test processes. Verify this with a before/after process check. During long runs, inspect the last public tool result and pending permission state; diagnose a blocked actor before waiting through its deadline. Preserve cancellation separately from a test verdict. Skipped or unstarted cases do not satisfy coverage; preserve every attempt. Paid evals never retry, with one exception: the gate reruns a red rule, behavior or judge case verdict once at the same head (Garry, 2026-10-19: "you can just run the failed test again and note that it is flaky"); a pass is green with a flaky annotation and a flake record, a second failure is a real red, and harness, INFRA, INCOMPLETE or unattributed reds never rerun (docs/TESTING_INTERNALS.md#flaky-reruns). Each case's kind (E2E_KINDS) fixes its trials before the run: rule one trial; behavior a panel of 3 independent trials, PASS at >= 2 with no contract violation; judge 3 samples on one output, each dimension gated on its median (at least 2 of 3 samples) against the unchanged threshold. Never add trials, samples or dispatches after seeing a result, never change a kind to change a verdict without pass-rate evidence, and report every trial. Quarantine follows CASE_QUARANTINE's entry and exit rules only (EVAL_POLICY, docs/TESTING_INTERNALS.md). A census whose every red is machine-classified INFRA or INCOMPLETE may be re-dispatched once as a new run; report both runs.
  7. Prove all known repairs with focused tests, including affected paid cases. Rerun a failed case only after a concrete repair or a demonstrated launch correction. Run the remaining required selected evaluations on the integrated code. Do not use the full free suite to discover predictable adjacent failures. Reuse a passing check when its consumed inputs and relevant environment are unchanged. For model judges, compare the expanded prompt, rubric, parameters and dependencies; a different commit alone does not invalidate the result. Do not resample an unchanged passing judge to simplify launcher configuration. Preserve its original source and label the result as reused evidence. Use actual prompt builders and compare complete bytes when proving model-input identity; preserve literal text in excerpts and record the consumed inputs.
  8. Finish review fixes, generation, release metadata, and build before final acceptance. Freeze the code, then run bun run test once at the end. During repair, focused checks replace a full-suite run before every commit. If final acceptance unexpectedly fails, retain the failure, diagnose it narrowly, and report the changed validation plan before another full run; never retry it blindly or claim a pass from an older revision.
  9. Publish only with passing required checks, unless the user explicitly grants an exception for identified failures. Report revision, actual pass/fail/skip counts, and incomplete coverage. A passing subset is not release acceptance.

Build commands

bun install              # install dependencies
bun run typecheck        # strict tsc over product code; must report zero errors
bun run typecheck:test   # test-code type-debt ratchet (new diagnostics fail; --write-baseline locks in fixes)
bun run format:cso       # format lib/cso/*.ts (format:cso:check is the CI gate)
bun run test:quick       # fast measured free subset for edit feedback (not acceptance)
bun run test             # complete free suite via the strict shard runner (no API spend)
bun run eval:bg:pr       # changed live probes + selected judges; dispatches CI when HEAD is clean and pushed, else runs locally
bun run eval:bg:release  # fresh complete gate + periodic live coverage (same backend choice)
bun run test:health      # audit success metrics and weekly health from CI history (free; needs gh)
bun run build            # generate docs + compile binaries
bun run gen:skill-docs   # regenerate SKILL.md files from templates
bun run skill:check      # health dashboard for all skills

Every other test and eval command (Ubicloud, the Windows subset, one paid tier or case, branch validation in CI, pass rates, plan previews), with its cost and prerequisites, is in Which command do I run?. Agents poll eval:bg:* logs for the ### gstack-detach EXIT=<code> ### sentinel (CLAUDE.md).

Platform support

  • macOS + Linux: full test suite supported.
  • Windows: the curated Windows-safe subset runs in the windows-free-tests CI workflow across six windows-latest jobs, packed by Windows-measured durations. Setup script (./setup) requires Git Bash or MSYS today; native PowerShell support is a future expansion. The bin/gstack-paths helper resolves state roots through CLAUDE_PLUGIN_DATA / GSTACK_HOME so plugin installs work on every platform.
  • CSO native helper: /cso additionally needs Bun's four --no-compile-autoload-* flags and a native toolchain (static-capable C on Linux, Xcode command-line tools on macOS, or VS 2022 C++ Build Tools on Windows). Setup installs everything else and leaves /cso explicitly unavailable when that optional toolchain is absent.
  • Browser and renderer: the browser skills, /make-pdf, and /diagram drive the Aside browser first, which is macOS 15+ only. On Linux and Windows (or a Mac with Aside closed) the readiness check says so once and the same skills use gstack's own bundled browser, built by ./setup.

Key conventions

  • SKILL.md files are generated from .tmpl templates. Edit the template, not the output.
  • Run bun run gen:skill-docs --host codex to regenerate Codex-specific output.
  • Browser steps in skills are aside repl scripts per scripts/resolvers/aside.ts (Aside first), each with a $B equivalent for the fallback engine — $B <command> is the browse binary and is a legitimate tool when the Aside probe does not print READY. Local HTML renders through bin/gstack-render.ts, which picks the same way.
  • Safety skills (careful, freeze, guard) use inline advisory prose — always confirm before destructive operations.
  • State paths resolve through one chain owned by lib/state-root.ts and its sourced bash twin bin/gstack-state-root.sh (GSTACK_STATE_ROOT → GSTACK_HOME → GSTACK_STATE_DIR → gstack's CLAUDE_PLUGIN_DATA → ~/.gstack; see docs/state-root.md). Skill prose uses GSTACK_STATE_ROOT=$(bin/gstack-paths --get GSTACK_STATE_ROOT) with its ${GSTACK_STATE_ROOT:?…} guard (worktree-isolated Claude Code sessions refuse eval); test/state-root-ratchet.test.ts rejects hand-rolled chains.
  • Browse daemon HTTP routes are entries in browse/src/routes/table.ts (its header shows how to add one); never dispatch on url.pathname in server.ts.
  • Both test lanes run shards through scripts/lib/shard-engine.ts; the free and paid runners hold lane policy only. PTY harness code lives in test/helpers/pty/* behind the claude-pty-runner.ts barrel.
  • Outside-voice failure prose (auth, timeout, empty, fallback) comes only from outsideVoiceFailurePolicy() in scripts/resolvers/outside-voice.ts.
  • Every env-var-host fence starts with the shared prelude from scripts/resolvers/runtime-root.ts (inserted by its post-render pass); never resolve gstack's root by hand in a template.
  • Every Codex run's verdict goes through lib/outside-review-result.ts; its reason codes live in lib/gate-outcomes.ts, each with a docs/troubleshooting.md anchor.
  • test/module-size-ratchet.test.ts keeps refactored owner modules at or under 800 lines (150 per function) and residual files from growing.
  • The claude CLI binary resolves via lib/claude-bin.ts (re-exported from browse/src/claude-bin.ts for browse internals; Bun.which() + GSTACK_CLAUDE_BIN override). Set GSTACK_CLAUDE_BIN=wsl plus GSTACK_CLAUDE_BIN_ARGS='["claude"]' to run Claude through WSL on Windows.
  • Every Bun gstack starts ignores the working directory's .env files and bunfig.toml: bun shebangs are #!/usr/bin/env -S bun --no-env-file --config=/dev/null, skill prose passes bun --no-env-file --config=/dev/null, shipped shell files define GSTACK_BUN_CONFIG with the line in test/bun-entry-isolation.test.ts (NUL when OSTYPE is msys or cygwin and cygpath is on PATH, where native Bun cannot open /dev/null, #3415) and pass bun --no-env-file --config="${GSTACK_BUN_CONFIG:-/dev/null}", TypeScript spawns use bunIsolationArgs() from lib/bun-isolation.ts, and bun build --compile adds --no-compile-autoload-dotenv --no-compile-autoload-bunfig. test/bun-entry-isolation.test.ts enforces all four.