feat(qa): record an agent walking a web or iOS app, then open it

TI
2mo ago
+1786-11

Why (in your own words)

If you have a web app or a physical iOS app, you should be able to ask for a screen recording of an agent actually using it, plus a full QA pass, and have that recording open when it is done. Today QA can screenshot and write a report, but there is no walkthrough capture and nothing opens a video at the end. This is that affordance: a QA specialist (recording.md), not a sixth public skill. /recording is an opt-in alias for $qa --mode Report --module recording. Web capture is $B record; iOS capture polls the existing DebugBridge screenshot endpoint. Mutation stays report-only unless the user explicitly asked to fix.

demos/booked is a calm SFO-origin flight booker (published 2026 schedules, simulated card-on-file payment) plus record-mac.sh so the walkthrough can be run on a local Mac. A cloud agent cannot open a headed browser on the user's machine; $B record is also blocked on pair-agent tunnel tokens.

Live evidence

$B record start → stop writes a RECORDING: artifact. On the cloud VM (Linux Chromium, not the user's Mac) a Booked walkthrough produced:

RECORDING: /workspace/.gstack/qa-reports/recordings/booked-sfo-jfk.mp4
kind=mp4 frames=94 elapsed=10.9s ffmpeg=true

Delta DL 405 SFO→JFK Wed Aug 19 2026, $357, confirmation BKVBFEKH. Viewer open failed on the headless/cloud host (expected).

Browse unit tests:

bun test browse/test/screencast.test.ts
 10 pass
 0 fail

bun test test/compat-alias-routes.test.ts
(pass) /recording routes to a dispatcher and module that exist

bun test test/gstack2-skills.test.ts
 3 pass
 0 fail

Scope

  • Changed: $B record start|stop|status|open, iOS record-session.ts, QA recording.md + /recording alias, demos/booked fixture + Mac runner.
  • Verified live by: cloud-VM Playwright/Chromium start/stop + Booked booking walkthrough.
  • Did NOT test: the user's local Mac (this agent has no access to that display). record-mac.sh is the path for that.

Liveness proof (required)

This PR is from a cloud agent. There is no human desktop here to type GSTACK PR into a live UI.

Checklist

  • Liveness screenshot attached — cloud agent cannot satisfy this
  • Commits are signed off (git commit -s) — DCO
  • This is not a generated-file-only diff
  • No ETHOS.md edits
  • New public command / external service / host adapter — N/A (not a sixth public skill; no cloud browser)
  • Linked issue or reproduction: #

How to use it

/recording
# or on a Mac, from this branch:
cd demos/booked && ./record-mac.sh
Open in Web Open in Cursor 

Summary by cubic

Record agent walkthroughs for web and physical iOS QA and open the result when finished. Previously QA produced screenshots and a report only; now $B record (web) and an iOS poller capture sessions to mp4 or an HTML player, and stop --open launches it; recording remains blocked over the pair‑agent tunnel.

  • Adds $B record start|stop|status|open using CDP Page.startScreencast (JPEG frames), encodes via ffmpeg when present (HTML player fallback), opens via the platform handler, and flushes in‑progress recordings on server shutdown.

  • Introduces browse/src/screencast.ts and browse/src/screencast-encode.ts; validates output paths; caps frames and duration; keeps record read‑scoped and off the tunnel allowlist.

  • Adds ios-qa/scripts/record-session.ts to poll the daemon’s /screenshot for PNG frames, then encode/open; independent of the web runtime.

  • Routes /recording to $qa --mode Report --module recording; the specialist starts capture, then runs web qa-only or device ios-qa, and finally opens the artifact.

  • Demo: demos/booked plus record-mac.sh serves a local app on a Mac, walks a booking in a headed browser, records, and opens the file (cloud hosts cannot open a viewer on the user’s machine).

  • Tests cover encode fallback (JPEG/PNG), command validation and gating, and a live Chromium start/stop producing a RECORDING: artifact.

  • Usage:

    • Web: $B record start [path] [--fps N] [--quality Q] then $B record stop [--open]. If ffmpeg is missing, an HTML player is written and opened instead.
    • iOS: bun ios-qa/scripts/record-session.ts start --daemon <URL> [--fps N] then stop --open. No migration required.