spec: media roadmap revision 6, codex round 5 accepts
Round 5 found no P1 or P2. Two wording fixes: media-<app> can be, not is, a valid app name; RemoveParticipant is what ends an active LiveKit media session, the proxy closes signalling and refuses readmission.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2 files changed,
+50
−10
docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md+14 −10docs/superpowers/specs/CODEX-FINDINGS-MEDIA-R5.md+36 −0
CI passed — run details
diff --git a/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md b/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md| index db02fea45..50950e42c 100644 |
| --- a/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md |
| +++ b/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md |
| @@ -1,6 +1,6 @@ |
| # Media on CARLOS: a staged roadmap |
| -**Date:** 2026-09-07, revision 5 |
| +**Date:** 2026-09-07, revision 6 |
| **Status:** rulings taken. Paul ruled on all eleven decisions in §7 on |
| 2026-09-07; each is marked **(ruling)**. Everything not so marked is a |
| **(decision)** that a stage spec may overturn cheaply. |
| @@ -11,9 +11,12 @@ by GPT-6 via Codex, independently of the author: revision 1's 27 |
| findings are in `CODEX-FINDINGS-MEDIA.md`, revision 2's 14 in |
| `CODEX-FINDINGS-MEDIA-R2.md`, revision 3's 9 in |
| `CODEX-FINDINGS-MEDIA-R3.md`, revision 4's 8 in |
| -`CODEX-FINDINGS-MEDIA-R4.md`, all unedited. Each place a finding changed |
| -the text is marked **(codex N)**, **(codex R2-N)**, **(codex R3-N)** or |
| -**(codex R4-N)**. §10 names the two parts declined. |
| +`CODEX-FINDINGS-MEDIA-R4.md`, and revision 5's 2 in |
| +`CODEX-FINDINGS-MEDIA-R5.md`, all unedited. **Round 5 returned accept: |
| +no P1 or P2 remained, and its two wording corrections are in this |
| +revision.** Each place a finding changed the text is marked |
| +**(codex N)**, **(codex R2-N)**, **(codex R3-N)** or **(codex R4-N)**. |
| +§10 names the two parts declined. |
| This is a roadmap, not an implementation spec. Each stage below gets its |
| own design and plan when it is picked up. The roadmap exists so the first |
| @@ -316,8 +319,8 @@ its open questions answered. **(codex R4-8)** |
| **What an app sees.** `carlos media enable` writes an additive `media` |
| block into `store.json` (prefix, allowed regions, key ids, hostname) |
| and mints `media-<app>.<sqid>.<apps domain>`, one label so the account |
| -wildcard already covers it. **(codex 24)** Because `media-<app>` is |
| -also a valid app name, the hostname is a **media-host claim** of its |
| +wildcard already covers it. **(codex 24)** Because `media-<app>` can |
| +also be a valid app name, the hostname is a **media-host claim** of its |
| own, owned by the source app and recorded in the account, not an app |
| row. It is one entry in the account's hostname namespace, and every |
| door that acquires a hostname there consults it: new app names, |
| @@ -707,9 +710,10 @@ about sixty room-hours a month, since both are dominated by bandwidth. |
| refresh for connected clients does not matter, because admission is |
| keyed on identity and room against platform state, not on a token |
| being unexpired. Removal is an app-to-platform door that records the |
| - revocation, calls LiveKit's remove-participant, and has the proxy drop |
| - that participant's signalling connection, which ends the session |
| - without waiting for anything the client does. Webhooks are for |
| + revocation, calls LiveKit's remove-participant, which is what ends the |
| + active media session, and has the proxy close that participant's |
| + signalling connection and refuse its next admission, none of it |
| + waiting for anything the client does. Webhooks are for |
| observation and reconciliation, never enforcement. Management |
| operations are the door's, scoped to the app's rooms. **(codex R3-6, |
| R4-1, R4-2)** |
| @@ -952,7 +956,7 @@ failing, then playback working. **(codex 27, R3-9)** |
| tenant reports a 443-only network, because it changes the fleet's |
| networking for every box to serve a case nobody has hit yet. |
| -Every revision-2, revision-3 and revision-4 finding was accepted. |
| +Every finding from revisions 2 to 5 was accepted. |
| ## 11. Amendments to existing specs |
diff --git a/docs/superpowers/specs/CODEX-FINDINGS-MEDIA-R5.md b/docs/superpowers/specs/CODEX-FINDINGS-MEDIA-R5.md| new file mode 100644 |
| index 000000000..9cdb8f36c |
| --- /dev/null |
| +++ b/docs/superpowers/specs/CODEX-FINDINGS-MEDIA-R5.md |
| @@ -0,0 +1,36 @@ |
| +# Findings on the media roadmap, revision 5 |
| + |
| +Reviewed by **GPT-6 (Codex), 2026-09-07**, fifth pass, against revision 5 at `1255d28`, with Paul's rulings treated as fixed. Unedited apart from this note. Verdict: accept. Revision 6 applies the two wording corrections. |
| + |
| +| Revision-4 finding | Disposition | One-line reason | |
| +|---|---|---| |
| +| R4-1 — Rejoin admission | Closed | An unavoidable proxy checks revocation before upstream admission, serialized against removal. | |
| +| R4-2 — Established-session removal | Closed | An explicit backend removal operation calls `RemoveParticipant`, independently of client refresh; §9 bounds termination to one second. | |
| +| R4-3 — Synchronous publication bypass | Closed | The initiating request receives transformed bytes only after successful console publication. | |
| +| R4-4 — Instance-host collisions | Closed | All hostname-acquisition doors share the claim; enable checks existing app, route and instance ownership. | |
| +| R4-5 — Invalid generated hostnames | Partial | Trailing-hyphen refusal and length handling are sound; one blanket app-name assertion remains false. | |
| +| R4-6 — Existing relay allocations | Closed | Authority expiry now terminates established allocations as well as refusing new ones. | |
| +| R4-7 — External STUN defaults | Closed | Stage 4b explicitly requires platform-only discovery and client ICE configuration, with no external fallback. | |
| +| R4-8 — Existing-code descriptions | Closed | Scanning enforcement is qualified, and media is correctly described as the fourth app-mintable kind. | |
| + |
| +Reviewed commit `1255d28529a1db3def775c46618df5e98e5eac21`, with Paul’s eleven rulings fixed. “Closed” means complete at roadmap level, not implementation-proven. No files were changed. |
| + |
| +**Severity:** P1 breaks a trust guarantee or makes a stage unbuildable; P2 requires correction before the stage spec; P3 is advisory. |
| + |
| +## R5-1 — P3 — Stage 1: the blanket app-name assertion remains false |
| + |
| +**Problem and evidence:** [Lines 319–320](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md:319) still say that `media-<app>` “is also a valid app name.” [`release.ValidApp`](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/internal/release/release.go:242) permits at most 32 characters. Prefixing a valid 27–32-character app name produces a 33–38-character label. |
| + |
| +The surrounding mechanism correctly accepts these as hostname claims without using the app-name validator, and §1 already states the 26-character qualification. Only the explanatory sentence remains wrong. |
| + |
| +**Correction:** Say that `media-<app>` **can also be a valid app name**, which creates the collision the separate claim prevents. |
| + |
| +## R5-2 — P3 — Stage 4b: attribute media termination to `RemoveParticipant` |
| + |
| +**Problem and evidence:** [Lines 709–712](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md:709) describe dropping the participant’s signalling connection as ending the session. LiveKit’s `HandleSignalSourceClose` closes the participant only when ICE has **not** connected; an established media connection can survive signalling loss. [LiveKit implementation](https://github.com/livekit/livekit/blob/master/pkg/rtc/participant.go#L977). |
| + |
| +The same paragraph already names the appropriate server operation, `RemoveParticipant`, and the admission gate prevents revoked identities from reconnecting. This closes the earlier architectural defect; the remaining issue is the explanation of which operation terminates media. [LiveKit removal API](https://docs.livekit.io/reference/other/roomservice-api/#removeparticipant). |
| + |
| +**Correction:** State that `RemoveParticipant` terminates the active media session, while the proxy closes signalling and refuses subsequent admission. Preserve §9’s one-second termination gate. |
| + |
| +**Verdict: accept.** No P1 or P2 problems remain. The two P3 corrections concern explanatory wording; the mechanisms are named, bounded and assigned to stages, and no remaining mechanism-level conflict with Paul’s fixed rulings was found. |
| \ No newline at end of file |