CodeVetter · Repo Unpack · Behavior traces
garrytan/gstack
Four flows were traced end-to-end. Install: ./setup checks bun, compiles binaries, regenerates host skill docs, and links skills into the host's skill dir. Browse command: CLI → state file → health probe → daemon spawn → authenticated POST → scope check → Playwright → sanitized untrusted-wrapped output. Local render: gstack-render → pickEngine → loopback static serve → aside repl single script (or daemon command sequence) → artifact copy-out. Paid-eval CI: planner emits a slice manifest from diff selection, six executors run shards, and a fail-closed reconcile job + token-isolated comment job close the lane.
- Install trace: ./setup (bash, set -e, umask 077) → short-circuit --help → require bun on PATH → resolve SOURCE_GSTACK_DIR + per-host skill dirs (CODEX_SKILLS, FACTORY_SKILLS, OPENCODE_SKILLS, CURSOR_SKILLS, KIRO_SKILLS) → scripts/build.sh compiles binaries → gen-skill-docs renders host output → _link_or_copy symlinks skills → prune retired renders (ownership-gated).
- Browse command trace (e.g. `$B snapshot -i`): cli.ts readState() reads .gstack/browse.json → isProcessAlive + isServerHealthy GET /health → on missing/dead daemon spawn server.ts detached (15s/30s-CI start budget via resolveStartTimeout, BROWSE_START_TIMEOUT override) → version-mismatch auto-restart → POST /command Bearer → server.ts buildFetchHandler → canonicalizeCommand → validateScopedToken/checkScope → handleSnapshot → wrap/sanitize → stdout.
- Snapshot→act trace: `snapshot` calls page.accessibility.snapshot(), assigns @e1..@eN refs stored as Map<string, RefEntry> of Playwright Locators on BrowserManager; a later `click @e3` resolves the ref with an async count() staleness check before locator.click(); navigation clears the map via framenavigated.
- Aside drive trace: a skill's BROWSER SETUP runs the generated probe (command -v aside + `aside repl 'console.log("ASIDE_READY " + pwd)'` with gtimeout/timeout/perl fallbacks) → READY | NEEDS_ASIDE | ASIDE_NOT_RUNNING → on READY the skill runs one self-contained `aside repl` script per flow ending in console.log("GSTACK_STEP_OK") and copies artifacts out of the printed ASIDE_DIR.
- Render trace: gstack-render.ts parses flags into RenderSpec → pickEngine/probeAside → Bun.serve binds 127.0.0.1 ephemeral port serving only the file's dir (per-render secret first path segment, realpath containment, no dir listing) → Aside path runs one repl script with goto+wait+pdf/screenshot/eval steps via raw CDP Page.printToPDF → copies artifacts from ASIDE_DIR → prints ENGINE= + OK lines; fallback runs the same spec as daemon calls newtab --json → goto → js-poll → pdf --from-file / screenshot → closetab in a finally.
- Paid-eval CI trace: evals.yml build-image (hash-keyed ghcr image) → plan-slices runs test-paid-shards.ts --emit-plan (EVALS_TIER=gate, 6 slices) → eval-slices matrix executes each slice inside the container with seeded claude config + registered skills → slices-report re-runs the runner with --report to reconcile artifacts vs manifest FAIL-CLOSED (PIPESTATUS pinned) → slices-comment posts the PR comment from a separate job holding the write token and zero repo code.
- Free-test trace: `bun run test` → scripts/test-free-shards.ts enumerates TEST_ROOTS (browse/test, test/, make-pdf/test, design/test) excluding paid files via isPaidTestFile → stable-hash shard assignment → N concurrent `bun test` children → BunTestOutputClassifier strict classification (a shard without bun's terminal summary FAILS; wall-timeout SIGKILL = distinct timed-out) → optional GSTACK_FREE_RETRY_FLAKY attribution-gated retry writing the flake ledger.
- pair-agent tunnel trace: POST /pair (root-only, local listener) mints a setup key → remote agent POSTs /connect on the tunnel listener (rate-limited, unauth) → exchangeSetupKey yields a scoped token (DEFAULT_PAIR_SCOPES = read+write+admin+meta) → tunnel listener serves only /connect + /command with a browser-driving command allowlist; root token on the tunnel = 403; denials are logged to ~/.gstack/security/attempts.jsonl.
- Ship trace: /ship template runs {{PREAMBLE}} (gstack-skill-start) → {{THIRD_PARTY_ACTIONS}} → {{BASE_BRANCH_DETECT}} → {{GBRAIN_CONTEXT_LOAD}} → enumerated gates (on-base-branch abort, conflict stop, test triage, review ASK items, MINOR/MAJOR bump asks) → auto-commit/push/PR.
- Skill invocation runtime trace: generated SKILL.md opens with {{PREAMBLE}} → bin/gstack-skill-start runs update check + session tracking (~/.gstack/sessions/<parent-pid>, 2h prune) → emits STATUS lines → skill executes → bin/gstack-skill-end records telemetry.
- iOS QA trace (inferred from layout): gstack-ios-qa-daemon (ios-qa/daemon/src/index.ts) brokers devicectl over a CoreDevice tunnel; auth-mint/session-tokens manage the tailnet allowlist; Swift templates under ios-qa/templates/ (DebugBridgeManager, StateServer, DebugBridgeTouch) are injected into the target app by gstack-ios-qa-regen. (inferred)