carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

Findings on the media roadmap, revision 3

Reviewed by GPT-6 (Codex), 2026-09-07, third pass, against revision 3 at 3f800f6, with Paul's rulings treated as fixed. Unedited apart from this note. Revision 4 records which findings were accepted and how.

| Revision-2 finding | Disposition | One-line reason | |---|---|---| | R2-1 — Visibility transitions | Partial | Deletion is now required, but stale public serving and the incomplete publication fence still weaken retirement. | | R2-2 — Relay compromise boundary | Partial | Exposure is stated correctly; the incarnation is missing from the described verification mechanism. | | R2-3 — Orthogonal read-only links | Closed | Secret and private doors now address the same object in protected/. | | R2-4 — Private-check transport | Closed | Backend-specific transport, home-edge serving and cache bypass are explicit requirements. | | R2-5 — Secret-response expiry | Closed | Per-request headers include bounded freshness and must-revalidate, overriding object directives. | | R2-6 — Purge serving gate | Partial | Catch-up and per-box reporting are specified, but public responses escape the stale-state bound. | | R2-7 — Publication enforcement | Partial | Attempt keys and committed manifests are defined; their conditional write still does not enforce lease expiry. | | R2-8 — Remote completion | Closed | Version one uses polling; callbacks explicitly require a later durable outbox. | | R2-9 — Worker and residency eligibility | Closed | Submission checks bucket region, allowed regions and worker availability; media DNS respects the allowed set. | | R2-10 — Media hostname ownership | Partial | Reservation is decided, but the proposed reuse of app-name validation breaks length and compatibility cases. | | R2-11 — Dependencies | Partial | The graph and shared prerequisites are corrected; §9 still imposes a contradictory sequential gate. | | R2-12 — Artefact disclosure | Closed | The interim exception now includes recordings and exports. | | R2-13 — Placement claims | Closed | Existing placement controls are distinguished from the missing runtime transport-capability contract. | | R2-14 — Browser-cookie claim | Closed | The universal claim is replaced with a cross-browser reliability statement. |

Reviewed commit 3f800f6df80441df32ca03c806184c43840e1c77. Paul’s eleven rulings are treated as fixed. No files were changed.

Severity: P1 breaks a trust guarantee or makes a stage unbuildable as written; P2 is a contract or claim defect to fix before the stage spec; P3 is advisory. “Closed” means resolved at roadmap level, not implementation-proven.

R3-1 — P1 — §2 and stage 1: public cache hits bypass retirement indefinitely

Problem and evidence: The serving gate closes secret and private doors after fifteen minutes without fresh authority, but explicitly lets public cached responses continue.

An edge can cache public/x, lose control-plane connectivity while remaining reachable by clients, and continue serving it after another box moves the source to protected/, disables media, removes that region, or records an infected verdict. Deleting the bucket object and removing its read grant do not invalidate those local bytes. Catch-up-before-serving only helps when the edge reconnects.

This also leaves inconsistent completion rules: the visibility lifecycle waits for every allowed region, whereas stage 1 correctly reports every box. One current box in a region cannot establish that another reachable, disconnected box has retired its copy.

Correction: Apply a bounded freshness requirement for purge and serving authority to public cache hits too. Public requests need no viewer authorization, but still need current authority to serve that object in that region. Define retirement completion over every box that could retain a copy, including removed regions: each must acknowledge retirement or become unable to serve under an expired serving lease. Use that same condition for visibility moves, disable and infected verdicts.

R3-2 — P2 — Stages 1–3: manifest conditional writes still do not enforce lease expiry

Problem and evidence: The publication fence specifies a conditional write to a per-source manifest containing source ETag, purge generation and app incarnation. It then claims an expired worker’s commit is refused.

Consider a worker that reads manifest ETag M, takes a lease, and stalls. Its lease expires without another worker changing the manifest. Its eventual If-Match: M still succeeds. Merely passing time changes neither the manifest nor its ETag. Likewise, changing a generation in a separate record does not invalidate the manifest condition unless an authoritative operation ties them together. S3 compares the addressed object’s ETag; it does not evaluate an external lease or application fields. AWS conditional-write contract.

Attempt-specific output and manifest-only serving close part of R2-7, but do not supply the missing rejection mechanism.

Correction: Name the component that authorizes and serializes publication. It must enforce the current attempt/lease, source generation and app incarnation against purge, cancellation and deletion. Workers should upload attempts without independent authority to publish them. If conditional manifests remain the mechanism, specify how those competing transitions invalidate the exact condition used by commits, and how expiry is enforced. Test an expired worker with no successor, as well as a worker racing lease takeover.

R3-3 — P2 — Stage 4a: the relay cannot derive the specified key from the specified username

Problem and evidence: Credential derivation now includes (account, app, incarnation), but the username remains expiry:account:app. The relay is said to derive the key from that username and its regional master. The incarnation is unavailable from those inputs.

A locally converged incarnation record would resolve this, but none is specified. Including the incarnation in the username alone would also be insufficient: accepting whichever incarnation the caller supplies would continue accepting old credentials after disable and re-enable.

Correction: Define locally converged relay authority containing the enabled state and current incarnation. Either obtain the incarnation from that record or include it in the authenticated username and compare it with the record. Define stale-state refusal, durable incarnation retention across deletion/name reuse, and allocation termination on disable. This implements ruling 8 without changing its key-delivery decision.

R3-4 — P2 — Stage 1 and §11: hostname reservation is assigned to an incompatible validator

Problem and evidence: Stage 1 claims media-<app> through the existing app-name gate. That gate calls release.ValidApp, whose grammar permits at most 32 characters. A valid app name of 27–32 characters therefore produces an invalid synthetic claim of 33–38 characters.

Separately, §11 targets that shared grammar for reserving media-. Changing ValidApp to reject the prefix would also reject existing apps’ release manifests and channel pointers. That contradicts the promise to preserve existing media-<x> apps.

The current claim operation also creates an ordinary app row; it is not a separate hostname reservation abstraction.

Correction: Reserve the prefix at new-name acquisition, including rename, while preserving historical name parsing. Define a media-host claim owned by the source app, with validation that accepts the generated hostname for every valid source name. Make collision handling atomic and connect claim retirement to media disable. Do not implement the reservation by narrowing the shared release grammar.

R3-5 — P2 — Stage 4b and §8: stock LiveKit does not use Meet’s SSE/POST signalling

Problem and evidence: After selecting hosted LiveKit, the roadmap still says offers, answers and candidates stay on the app’s HTTP path, pointing to §8’s SSE/POST recommendation.

LiveKit clients instead establish a WebSocket connection to /rtc and exchange LiveKit signalling messages there. Port 7880 serves both its API and WebSocket endpoint. LiveKit client protocol, ports reference.

Consequently, hosting the server behind a platform API does not preserve the existing signalling contract. Routing that WebSocket through a tunnel-backed app would encounter the acknowledged upgrade refusal.

Correction: Scope SSE/POST to Meet’s peer-to-peer mode and app-level room coordination. Specify a platform SFU hostname with TLS and WebSocket proxying to LiveKit, reached directly by the client even when the app backend is tunnel-backed. State the client SDK/protocol integration required for 4b. This preserves ruling 9.

R3-6 — P2 — Stage 4b: the shared SFU has no tenant-authority or revocation contract

Problem and evidence: Stage 4b specifies the server, box, ports and recording destination, but “fronted by the platform’s own API” leaves room ownership, participant admission and management authority undefined.

LiveKit tokens authorize a participant for named rooms and permissions. Its self-hosted server also does not invalidate an existing token merely because a participant is removed; that participant can rejoin while the token remains usable. Token expiry alone does not terminate an established session. LiveKit tokens and lifecycle.

Thus neither tenant separation nor removal from an app’s room follows automatically from hosting LiveKit. Reusing the private-media check does not solve this: that check governs individual object requests, not a long-lived SFU session.

Correction: Require platform-derived account/app/incarnation room identities, app-authorized participant admission, scoped management operations, and platform custody of unrestricted LiveKit signing credentials. Define removal and reconnect behavior, including how old tokens are prevented from restoring revoked access. Add cross-app room-access and remove-then-rejoin tests to the 4b gate.

R3-7 — P2 — §2 and ruling 1: the future positive authorization cache contradicts the fixed ruling

Problem and evidence: Section 2 retains a later per-app positive authorization cache for tenants outside the suite. Ruling 1 fixes private delivery as ask-the-app per request, never cached, without that exception.

With the knob enabled, a warm authorization result admits a request after the app has revoked the grant. Being disabled by default does not preserve the ruling when enabled.

Correction: Remove the exception from the roadmap’s authorized scope. Any future proposal to cache private authorization must explicitly return for a changed ruling; it cannot be presented as an already-permitted implementation option.

R3-8 — P3 — Stage 4b: deferred recording needs additional infrastructure

Problem and evidence: The recording paragraph names separate services but omits their Redis dependency and gives a two-vCPU composite-recording estimate without a capacity gate.

LiveKit Egress uses Redis to communicate with the server. Its deployment guidance recommends at least four CPUs and 4 GB per Egress instance and identifies additional Chrome sandbox requirements. The bare single-node SFU’s no-Redis configuration therefore does not extend unchanged to recording. LiveKit Egress deployment.

Correction: Record Redis, recording-worker provisioning and measured admission limits as prerequisites of the deferred recording extension. Keep them deferred under ruling 9; do not imply that the launch SFU box or stage-3 ffmpeg worker supplies them automatically.

R3-9 — P3 — §9: the heading still contradicts ruling 11

Problem and evidence: Section 9 remains “What each stage must prove before the next starts.” That imposes the sequential condition R2-11 requested removing, despite the corrected graph and the fixed independent starts for stages 1 and 4a.

Correction: Describe these as acceptance gates for each stage, with downstream prerequisites determined by §4’s graph. This is the remaining editorial portion of R2-11, not a request to change the order Paul ruled.

Verdict: request changes. Revision 3 resolves the shared protected-object model, private transport selection, secret HTTP-cache expiry, submission eligibility and several staging defects. The remaining corrections fit within Paul’s rulings: bound public serving during control-plane outages, make publication rejection enforceable, supply the relay’s incarnation authority, preserve existing app names, and define LiveKit’s signalling and tenant-access boundary. Those mechanisms need correction before the affected stage specifications can rely on the roadmap’s guarantees.