Merge remote-tracking branch 'origin/main' into garrytan/colombo-v3

Resolves VERSION conflict (kept 1.43.0.0 — already ahead of main's
1.42.2.0 browse launch hardening wave). Picks up main's
browser-manager + server hardening cleanly (no conflicts there).

Also strips "device farm" / "DIY device farm" framing from the iOS
docs per Garry's direction. This isn't a device farm — it's full iOS
app QA, with agents able to control real iOS apps either locally over
USB or remotely over Tailscale.

Files touched in the farm sweep:
- CHANGELOG.md (1.43.0.0 entry headline + AGENTS subsection title)
- README.md (ios-qa row + gstack-ios-qa-daemon row)
- AGENTS.md (section header reframed to "iOS QA — drive real iPhones
  over USB or Tailscale")
- ios-qa/SKILL.md.tmpl + regenerated SKILL.md (description)
- ios-qa/docs/tailscale-acl-example.md (intro + sample ACL host name)
- docs/howto-ios-testing-with-gstack.md (intro + closing)
- docs/skills.md (section header + body)
- test/helpers/touchfiles.ts (touchfile comment)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-05-21 08:33:04 -07:00
12 changed files with 388 additions and 56 deletions
+3 -3
View File
@@ -1,6 +1,6 @@
# How to test iOS apps with GStack iOS
This is the end-to-end walkthrough for the iOS device-farm capability that ships with gstack: install the canonical Swift templates into your app, connect a real iPhone over USB, and drive it from any agent (Claude Code locally, or any HTTP-capable agent over Tailscale). No simulators, no XCTest harness, no WebDriverAgent.
This is the end-to-end walkthrough for the iOS QA capability that ships with gstack: install the canonical Swift templates into your app, connect a real iPhone over USB, and drive it from any agent (Claude Code locally, or any HTTP-capable agent over Tailscale). No simulators, no XCTest harness, no WebDriverAgent.
Everything below has been verified end-to-end on a real iPhone 17 Pro Max running iOS 26.5. The same flow works on any iOS 16+ device.
@@ -175,6 +175,6 @@ Before you ship to TestFlight or the App Store, run `/ios-clean`. It removes the
## What this gets you
You can write an agent loop in any language that speaks HTTP. Take a screenshot, ask a model what to do, send a tap. Capture state snapshots before and after to record deterministic fixtures for `/ios-fix` regression tests. Add a colleague to the allowlist and they drive your device farm from their laptop without ever touching the hardware. Plug the same daemon into CI by minting a `tag:ci` session token with mutate-tier capability and a 24-hour TTL.
You can write an agent loop in any language that speaks HTTP. Take a screenshot, ask a model what to do, send a tap. Capture state snapshots before and after to record deterministic fixtures for `/ios-fix` regression tests. Add a colleague to the allowlist and they drive your iPhone from their laptop over Tailscale without ever touching the hardware. Plug the same daemon into CI by minting a `tag:ci` session token with mutate-tier capability and a 24-hour TTL.
The whole stack is a Mac you already own, an iPhone you already own, a free Apple developer account, and gstack. No paid device-farm subscription. No simulator drift. The thing the user sees is what the agent drives.
The whole stack is a Mac you already own, an iPhone you already own, a free Apple developer account, and gstack. No paid testing service. No simulator drift. The thing the user sees is what the agent drives.
+2 -2
View File
@@ -1214,9 +1214,9 @@ The agent reads your Swift source, finds `@Observable` classes with `@Snapshotab
The iOS app's `StateServer` binds loopback only (`::1` + `127.0.0.1`). The Mac daemon owns tailnet identity validation, capability tiers, and the audit trail. Remote agents NEVER see the boot token — only short-lived session tokens (1h default, 24h hard cap) minted via Tailscale identity gating.
### The unlock: USB-tethered + Tailscale = DIY device farm
### The unlock: USB-tethered + Tailscale = remote iOS QA from any agent
A $500 Mac mini + an old iPhone + Tailscale free tier replaces what most teams pay BrowserStack/Sauce Labs for. Tailscale ACLs scope which identities can reach which devices at which capability tier.
A Mac plus an iPhone you already own plus the Tailscale free tier replaces what most teams pay BrowserStack/Sauce Labs for. Any HTTP-capable agent on your tailnet can drive the iOS app once you've minted them a session token. Tailscale ACLs scope which identities can reach the Mac at which capability tier.
See `ios-qa/docs/tailscale-acl-example.md` for the runnable setup.