feat(qa): record an agent walking a web or iOS app, then open it
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, iOSrecord-session.ts, QArecording.md+/recordingalias,demos/bookedfixture + 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.shis 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


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|openusing CDPPage.startScreencast(JPEG frames), encodes viaffmpegwhen present (HTML player fallback), opens via the platform handler, and flushes in‑progress recordings on server shutdown. -
Introduces
browse/src/screencast.tsandbrowse/src/screencast-encode.ts; validates output paths; caps frames and duration; keepsrecordread‑scoped and off the tunnel allowlist. -
Adds
ios-qa/scripts/record-session.tsto poll the daemon’s/screenshotfor PNG frames, then encode/open; independent of the web runtime. -
Routes
/recordingto$qa --mode Report --module recording; the specialist starts capture, then runs webqa-onlyor deviceios-qa, and finally opens the artifact. -
Demo:
demos/bookedplusrecord-mac.shserves 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]. Ifffmpegis missing, an HTML player is written and opened instead. - iOS:
bun ios-qa/scripts/record-session.ts start --daemon <URL> [--fps N]thenstop --open. No migration required.
- Web: