# Review brief: stage 4a relay spec

You are GPT-6 reviewing a stage design spec independently of its author.
Your output is a findings report, not an edit. Do not modify any file.

## What to read

1. The spec under review:
   `docs/superpowers/specs/2026-09-07-relay-stun-turn-design.md`.
2. Its parent, which it must honour: the media roadmap
   `docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md`,
   especially §1, §3, stage 4a, §7 rulings 8, 10 and 11, and §9's stage
   4a gate. Rulings are fixed; report a mechanism that fails one, do not
   re-argue one.
3. The code it fits into, in this worktree: `internal/host/bootstrap.go`
   and `internal/host/units/carlos-edge.service` (units, hardening,
   `enabledUnits`); `internal/host/agent.go` (IMDS reads near line 1761,
   fast-converge loop near 1304, config generation loop near 985);
   `internal/host/edgesfile.go`; `internal/host/metrics_loop.go`;
   `internal/objstore/walk.go` (`writeEnv` near 554) and
   `internal/appconfig/` (Apply, generation, sync); `store.go`,
   `internal/console/apistore.go`, `internal/console/apicli.go`
   (`apiAccountApp`); `internal/release/serial.go`;
   `infra/modules/region-host/main.tf`; `go.mod`; `AGENTS.md`.
4. pion/turn v4's API as documented at pkg.go.dev
   (`ServerConfig`, `AuthHandler`, `PermissionHandler`, `QuotaHandler`,
   `EventHandler`, `RelayAddressGeneratorPortRange`, `GenerateAuthKey`).
   Check the spec's claims about when pion calls the auth handler and
   what it does with the returned key.
5. The suite doctrine ruling 6 and §8 at
   `/home/paulca/amadan.net/oficina/suite/docs/superpowers/specs/2026-09-05-suite-sharing-doctrine.md`.

## What matters most

- **The app-facing contract in §2** is what the Meet app will code
  against today. Is it complete, unambiguous and implementable from the
  text alone? Does the test vector follow from §4 exactly? Is anything
  the app needs missing?
- **Verification in §4.** Look for a way to obtain a TURN allocation
  without a key an enabled app was given, to use one app's credential
  for another, to keep using a credential after disable, or to make the
  relay accept something the authority record does not cover. Check the
  interaction with pion's long-term credential mechanism.
- **Key custody in §4 and §5.** Masters in `host.env` and as console
  secrets, two hand-staged copies. Is the exposure stated honestly and
  consistently with roadmap §1's statement that sealed config is
  decryptable on every host? Does rotation as written ever leave a
  window where a credential stops working or an old master is accepted
  too long?
- **The unit in §3.** Hardening, ports, the allocation range, the EIP
  as relay address, the certificate for 5349, the authority record and
  its fifteen-minute lease. Is anything unbuildable as written on a
  `t4g.small` sharing the box with the edge?
- **Limits and metering.** Can one app starve another, exhaust the port
  range, or relay to somewhere it should not? Can the meters be
  attributed wrongly?
- **Claims about the code.** Every `file:line` and every "already
  exists" claim: check it. Report each one that is wrong.
- **Operability.** Can a member, with no box access, enable, see status
  and disable? Can an operator rotate a master without a call dropping?

## How to report

Number findings R1-1 onward. For each: severity (P1 breaks a trust
guarantee or makes the stage unbuildable; P2 a contract or claim defect
to fix before the plan; P3 advisory), the section, the problem, the
evidence with citations, a proposed correction. End with a verdict:
accept, accept with corrections, or request changes. Do not soften, do
not pad, do not restate the spec.
