| simulator-audio.md |
rationale |
Simulator audio capture (iOS/Android) — design, whole-sim dynamic tap, sim-volume, rejected approaches |
| legacy-browser-fallback-ios-only.md |
rationale |
Why the JPEG legacy-browser (~5%) fallback exists only on iOS — historical, not a bug |
| monorepo-project-references.md |
rationale |
Why library packages use TS project references — the exports.types→src bug (#345), rejected alternatives |
| android-sdk-bootstrap.md |
rationale |
Why setup android bootstraps a self-contained SDK — Android Studio ≠ SDK, the three fragility causes |
| runtime-platform-registration.md |
rationale |
Why platforms self-register at runtime (AgentRegistry.register) instead of a literal Platform union — the OCP payoff |
| codec-negotiation.md |
rationale |
Why the browser negotiates H.264 capability before the agent streams — the ~95%/5% floor, black-screen prevention |
| android-rotation.md |
rationale |
Why rotation uses wm user-rotation + pinned scrcpy 3.3 — legacy command ignored on API 35+ |
| ios-device-recovery.md |
rationale |
Why tapflow start does not pre-boot iOS, and where zombie-simulator recovery lives |
| agent-keep-awake.md |
rationale |
Why the agent holds a caffeinate assertion during a session — idle throttle drops the emulator to ~4-5 fps |
| relay-heartbeat.md |
rationale |
Why the relay runs a ping/pong heartbeat — dead sockets otherwise linger to the TCP timeout |
| relay-resource-rejection.md |
rationale |
Why the relay rejects new sessions above a CPU/RAM threshold, evaluated relay-side |
| relay-backpressure-frame-drop.md |
rationale |
Why the relay silently drops frames on bufferedAmount backpressure — bounds memory |
| build-status-deletion-decoupling.md |
rationale |
Why a build's Done status is decoupled from its delete_after deletion lifetime |
| relay-tunnel-access.md |
rationale |
Why the relay stays inside the agent's network and tunneling is an opt-in plugin |
| relay-agent-auth.md |
rationale |
Why remote agents authenticate with an agent-scope PAT instead of an IP check |
| relay-secret-loading.md |
rationale |
Why the relay loads .env before evaluating its module-singleton config |
| simkit-internals.md |
reference |
SimulatorKit reverse-engineering notes — binary layout, symbols, touch/button injection |
| measurement.md |
reference |
Every performance metric emitter — how to enable it, its output, what it means |
| downscale-tuning.md |
reference |
Encode-resolution downscale lever — QA fidelity vs decode/bandwidth, recommended default |
| frame-envelope.md |
reference |
Frame envelope wire format (TFFE v1) — 22-byte per-frame timestamp header, magic-byte backward compat |
| sustainability-carbon-math.md |
reference |
Carbon arithmetic behind the Sustainability page — measured session increment, Apple PER inputs, sensitivity, and the comparisons we dropped |
| streaming-latency-log.md |
log |
Append-only glass-to-glass latency log — pipeline analysis, attempts, decisions |
| android-video-streaming-diagnosis.md |
diagnosis |
Android emulator streaming issues traced to root cause, one section per issue |
| awdl-wifi-latency-diagnosis.md |
diagnosis |
Periodic Wi-Fi stream hitch traced to AWDL via ICMP ping — method and evidence |
| workshop-lab-fork-observations.md |
reference |
Third-party workshop-lab fork: independent iOS-sim capacity data (~4 seats/32GB) + where our extension seams stop |
| adversarial-review.md |
rules |
How to run the pre-PR review and the cross-cutting design pass — channel design, prompt skeleton, why a cleared list ages with the diff, why a fix falsifies the prose beside it, why the same review costs 4 minutes or 106 |
| test-and-guard-coverage.md |
rules |
What a test or a static check must execute to hold its claim — absence assertions verified only by the mutation that creates the absence, four ways a guard gets bypassed, why the success path gets the first mutation |
| security-bumps.md |
rules |
Why a security bump is pnpm update before pnpm.overrides — fourteen inert entries measured, why the override key comes from the GHSA advisory and not the Dependabot alert, why the key and its replacement are both capped to one major |