# Findings on the media roadmap, revision 2

Reviewed by **GPT-6 (Codex), 2026-09-07**, second pass, against revision 2 at `6424a4f`, with its own revision-1 findings in hand. Unedited apart from this note. Revision 3 records which findings were accepted and how.

Reviewed commit `6424a4f320821fd72667625c1aa7dbb35baff0cc` against the review brief, the 27 original findings, the cited platform code and private specs, and the suite doctrine. No files were changed.

“Closed” means the roadmap now supplies the missing decision or requirement; implementation still needs to prove it. Severity remains: **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.

## Disposition of the original findings

| Original | Status | One-line reason |
|---|---|---|
| 1 — Visibility-door bypass | Closed | Disjoint storage namespaces prevent an unsigned URL rewrite from reaching the protected object. |
| 2 — Private browser identity | Closed | The app-origin path carries its session cookie, including on custom domains. |
| 3 — Authorization and downstream caching | Partial | Private checks and responses bypass caching, but secret `max-age` alone does not prohibit stale reuse. |
| 4 — Malware enforcement | Partial | The reader deny and derivative removal are specified; late derivative publication can still undo removal. |
| 5 — Signed authorization contract | Partial | Claims, normalization, presets and rotation are defined; stale-edge revocation behavior remains incomplete. |
| 6 — HLS capability transport | Closed | Relative child paths retain the capability segment in the stated playlist layout. |
| 7 — Range and conditional handling | Closed | Explicit HTTP handling, ETag-bound entries and complete-fill publication replace the claimed automatic reuse. |
| 8 — Cache isolation | Closed | Per-box budgets, fair eviction, account caps, bounded fills and reusable blocks address the original defects. |
| 9 — Distributed purge | Partial | The durable log and generations are explicit, but catch-up-before-serving and stale-state limits are not. |
| 10 — Residency | Partial | Grants and handlers enforce a region list; its interaction with bucket location and worker placement is unresolved. |
| 11 — Doctrine mapping | Partial | The terminology is corrected, but exclusive namespaces do not support an item’s orthogonal read-only link. |
| 12 — Third-party relay doctrine | Partial | Team-selected endpoints are removed; disclosure on produced artefacts is still omitted. |
| 13 — Relay minting authority | Partial | Keys are app- and region-derived, but their delivery contradicts the claimed regional compromise boundary. |
| 14 — Relay abuse controls | Closed | Peer restrictions and allocation, rate, bandwidth and lifetime limits are explicit. |
| 15 — Relay connectivity and placement | Closed | Public-address/range configuration and the 443-only limitation are stated; the ICE latency claim is removed. |
| 16 — Helper isolation | Closed | Every codec candidate runs separately with resource limits and authenticated update/rollback support. |
| 17 — Derivative identity | Partial | Versioned representations and fair admission are specified; identity alone does not fence publication after purge. |
| 18 — Job authority and recovery | Partial | Submission and leases are named, but publication enforcement and remote completion remain missing mechanisms. |
| 19 — Existing queue and deletion ownership | Closed | The roadmap acknowledges the scan queue and places media jobs under the app’s deletion prefix. |
| 20 — Worker capacity | Closed | Admission limits and sustained-load measurements replace the unsupported co-location guarantee. |
| 21 — Remux versus adaptive encoding | Closed | Single-rendition remux and ladder generation are separate products with input probing. |
| 22 — LL-HLS and network services | Closed | Live serving is a distinct extension, and network services are separated from codec helpers. |
| 23 — CORS | Closed | Media-response CORS and bucket-wide upload CORS ownership are specified separately. |
| 24 — Media hostname | Partial | Wildcard coverage is fixed, but the new name collides with an ordinary app’s hostname. |
| 25 — Enable/disable lifecycle | Partial | Reconciliation and backend refusals are explicit; stale readers and retirement completion still need a contract. |
| 26 — Original factual corrections | Closed | Scanner integration, infrastructure citations, STUN wording and relay meter distinctions were corrected. |
| 27 — Stage dependencies | Partial | Relay work is independent, but the graph still reverses an SFU dependency and hides a stage-2 prerequisite. |

## New and remaining findings

### R2-1 — P1 — §2: changing visibility leaves the old readable object behind

**Problem and evidence:** [Roadmap lines 128–135](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md:128) define a visibility change as a server-side copy and a purge. Copying `public/x` to `private/x` does not remove `public/x`. After its cache is purged, an anonymous request simply fetches the old public object again. Moving `secret/x` to `private/x` similarly leaves the old capability usable against the surviving secret copy.

This is a transition defect introduced by the namespace design, distinct from the original URL-substitution bypass.

**Correction:** Define a move as a coordinated lifecycle that removes or tombstones the old source namespace and its derivatives, fences concurrent publication, and reports completion after regional invalidation. State separately that copies already delivered to clients cannot be withdrawn. Test public-to-private and secret-to-private transitions against cold caches as well as warm ones.

### R2-2 — P1 — Stage 4a: sealed config defeats the claimed regional compromise boundary

**Problem and evidence:** [Roadmap lines 500–512](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md:500) deliver durable derived keys for every allowed region to each enabled instance, while claiming that compromising a box yields nothing durable about other regions.

At minimum, a compromised box can read its resident apps’ other-region minting keys. The existing delivery architecture permits a wider exposure: [the config spec’s crypto section](/home/paulca/github.com/carlosframework/platform-infrastructure/platform-design/superpowers/specs/2026-08-02-app-config-secrets-design.md:86) places the deployment’s decryption key on every host, and [the host policy](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/infra/modules/region-host/main.tf:121) permits reading deployment-bucket objects. Sealing therefore does not isolate those app keys from a compromised deployment host. [Materialization explicitly decrypts them into environment values](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/internal/appconfig/materialize.go:30).

The one-hour credential lifetime does not expire the stolen minting key. Separate regional masters prevent deriving another master; they do not prevent using another region’s already-distributed app keys.

**Correction:** Either withdraw the regional compromise guarantee and describe the actual exposure, or change delivery so a box cannot recover durable remote-region minting material. Short-lived issuance is one option; a genuinely compartmentalized key-delivery system is another.

Also include an app incarnation or revocation epoch in derivation. With only `(region master, account, app)`, disabling and re-enabling an app restores the same key until the regional master changes.

### R2-3 — P2 — §2: exclusive namespaces conflict with orthogonal read-only links

**Problem and evidence:** [The doctrine mapping and namespace rule](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md:125) require authenticated delivery from `private/`, link delivery from `secret/`, and an object written into exactly one namespace.

Consider a team-readable video whose owner enables a read-only link. Existing team viewers must continue using authenticated delivery while link holders use the capability. Neither door can reach the other namespace. Moving the object breaks one audience; duplicating it requires a second copy and a synchronization/revocation contract that the roadmap does not define.

[Doctrine §4.2](/home/paulca/amadan.net/oficina/suite/docs/superpowers/specs/2026-09-05-suite-sharing-doctrine.md:276) makes links an additional axis, not a replacement visibility.

**Correction:** Specify how both delivery mechanisms address one logical asset. For example, a verified capability could name a protected canonical source, with its namespace included in the signed claims, while the public door remains strictly confined to `public/`. Alternatively, explicitly design linked copies and their shared lifecycle. Do not leave this to each app’s URL builder.

### R2-4 — P2 — §2 and stage 1: the activator check only supplies a local-socket transport

**Problem and evidence:** [Roadmap lines 170–174](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md:170) select the scheduled-tick path for private authorization. That path expressly never leaves the box and [refuses routes without a Unix socket](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/internal/host/schedule_wiring.go:220).

The platform also serves TCP-backed and tunnel-backed routes. [Edge routing explicitly handles those separately](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/internal/edge/edge.go:457), and [remote app requests can be backhauled to their home edge](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/internal/edge/edge.go:1197).

The selected transport therefore does not establish private-media support for every app/backend or private byte serving at an allowed edge that does not host the app.

**Correction:** Define the supported topology. Either private requests travel to the app’s home edge and use its local media cache, or remote media edges gain an authenticated, cache-bypassing authorization transport. Specify TCP and tunnel support or refuse those backends explicitly. The reserved path must bypass shared-cache lookup before reaching any authorization or proxy branch.

### R2-5 — P2 — §2: secret `max-age` does not enforce capability expiry

**Problem and evidence:** [Roadmap lines 175–179](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md:175) cap freshness at the capability’s remaining life but do not prohibit stale responses.

A cache may serve stale content under permitted conditions, including disconnection. `max-age` determines freshness; it is not an unconditional prohibition on reuse after that age. [RFC 9111 §§4.2.4 and 5.2.2.2](https://www.rfc-editor.org/rfc/rfc9111.html#section-4.2.4) distinguish those properties.

**Correction:** Require `must-revalidate` alongside the bounded freshness lifetime, or use `no-store`. Override source-object directives that permit stale delivery. Generate expiry-dependent headers for the current capability on every response, including internal byte-cache hits. This governs HTTP cache reuse, not a recipient’s ability to retain downloaded bytes.

### R2-6 — P2 — Stage 1: purge catch-up and authorization-state freshness need a serving gate

**Problem and evidence:** [The purge design](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md:327) says an offline edge catches up on reconnect. It does not say that catch-up precedes serving its persistent disk cache. [Key revocation takes effect on the next sync](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md:277), with no maximum age for that state.

This matters because [the ingress spec explicitly permits continued serving from last-converged state during a control-bucket outage](/home/paulca/github.com/carlosframework/platform-infrastructure/platform-design/superpowers/specs/2026-08-20-multi-region-ingress-design.md:123). Removing bucket permission does not stop a disconnected edge serving cached bytes. A removed region, disabled media route or revoked key can remain usable under stale local state.

**Correction:** Define maximum stale-state windows and fail-closed behavior for media authority. Require a returning edge to reconcile route authority and its purge cursor before admitting persistent cache hits. Define recovery from missing log history, and report retirement against the relevant boxes, not merely one acknowledgement per region. Local purge fast paths must not count as distributed completion.

### R2-7 — P2 — Stages 2 and 3: identifiers and fencing tokens do not themselves prevent late publication

**Problem and evidence:** [Stage 2’s derivative identity](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md:377) is said to prevent publication after purge. [Stage 3 grants direct bucket writes and then promises atomic publication carrying a fencing token](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md:449).

Neither names the component that rejects an obsolete writer. A transform can finish after its derivative was removed by a scan-triggered purge. An expired worker can complete an already-started write after another worker takes the lease. Its bucket permission remains valid. Including an ETag in a filename or a token in metadata does not make that write fail.

S3 conditional writes compare the state of the addressed object; they do not automatically consult a separate job lease. See [AWS’s conditional-write contract](https://docs.aws.amazon.com/AmazonS3/latest/userguide/conditional-writes.html).

**Correction:** Name an enforced publication mechanism: immutable attempt-specific output plus a conditional commit record tied to the current job lease, source/purge generation and app incarnation, for example. The serving path must expose only committed output. Purge, infection, cancellation and deletion must invalidate that same publication authority. Apply the rule to synchronous image transforms as well as transcodes.

### R2-8 — P2 — Stage 3: the schedule runner does not provide the claimed remote completion door

**Problem and evidence:** [Roadmap lines 457–459](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md:457) claim the runner already delivers completion across hosts.

Existing once-timers are filed through [an instance-local control socket, bound to that host and its administrative token](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/internal/schedule/control.go:28). The runner processes its local registry. A worker on another box has no described door for filing the promised once-timer on the destination.

**Correction:** Add a durable completion outbox that the destination host converges into an idempotent local delivery, with destination selection, retries and deletion handling. Alternatively, make polling the initial completion contract and defer callbacks explicitly. Reusing local timer execution does not eliminate the cross-host handoff.

### R2-9 — P2 — Stages 1 and 3: allowed regions, bucket location and the Ireland-only launch can disagree

**Problem and evidence:** [Stage 1 defaults allowed regions to app-route placements](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md:339). Stage 3 requires workers to read buckets only in their own region, first describes one worker per relevant region, then [launches only on the Ireland medium](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md:436).

Store location is a separate fact: [the object-storage spec configures it through `CARLOS_STORE_REGION`](/home/paulca/github.com/carlosframework/platform-infrastructure/platform-design/superpowers/specs/2026-08-10-object-storage-primitive-design.md:197). An app placed outside its bucket’s region can therefore receive a default list that excludes the only worker permitted to process its source. A non-Ireland bucket has no version-one worker at all.

**Correction:** State launch eligibility and refuse unsupported jobs before enqueueing. Resolve processing region from both bucket location and the allowed list. Either launch regional workers or explicitly limit version one to eligible Ireland buckets. Also specify media DNS placement within the allowed set; a 421 response alone is not a routing plan.

### R2-10 — P2 — Stage 1: `media-<app>` occupies another valid app’s hostname

**Problem and evidence:** [The generated hostname](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md:255) fits the wildcard, but `media-docs` is also an ordinary valid app name under [the existing app-name grammar](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/internal/release/release.go:239).

In account `abc`, the media host for `docs` and the normal platform host for app `media-docs` are both `media-docs.abc.oncarlos.com`. Certificate coverage does not resolve ownership.

**Correction:** Define an atomic hostname claim and collision policy covering both media enable and ordinary app creation. Existing apps must not be displaced. Either reserve a namespace with a migration/refusal policy or choose another naming scheme with explicit certificate support.

### R2-11 — P2 — §4 and §9: the dependency graph contradicts the implementation dependencies

**Problem and evidence:** [The graph](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md:228) puts an arrow from stage 4b into stage 3, making SFU work a prerequisite for on-demand media. The prose instead has SFU recording submit stage-3 jobs.

Meanwhile, stage 3 depends on [the derivative-write policy “stage 2 adds”](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md:449), although decision 11 says the single-rendition product follows stage 1. Section 9 still describes each gate as preceding “the next” stage.

**Correction:** Make stage 3 independent of SFU work and make recording depend on stage 3. Extract derivative-write authority and publication into shared prerequisites available to whichever of stages 2 or 3 ships first. Express gates against those dependencies rather than a global next-stage sequence.

### R2-12 — P2 — §8: the external-relay exception still omits artefact disclosure

**Problem and evidence:** [The revised interim guidance for Meet](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md:673) requires the README’s first paragraph but omits disclosure on every produced artefact. [Doctrine §8 requires both](/home/paulca/amadan.net/oficina/suite/docs/superpowers/specs/2026-09-05-suite-sharing-doctrine.md:934).

Removing arbitrary team-selected endpoints closes the main original defect. It does not make the shortened exception complete.

**Correction:** Carry the entire disclosure condition into the recommendation. Where no artefact is produced, say so; recordings and other produced artefacts must retain the required disclosure.

### R2-13 — P2 — §1 and §8: the blanket claim that placement is invisible and unconstrainable is outdated

**Problem and evidence:** [Roadmap lines 681–683](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md:681) say no app-visible placement signal or constraint exists or is planned before extended CONNECT.

The current member-facing interfaces already include:

- [`carlos instances create --region`](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/instances_cli.go:182).
- [`carlos apps place`](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/apps.go:65).
- [Instance API placement information naming serving boxes and regions](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/internal/console/instancesplacement.go:21).

These do not establish a runtime “WebSocket transport supported” flag, but they contradict the broad absence claim.

**Correction:** Distinguish member-controlled placement, observable placement and a runtime transport-capability contract. Keep the tunnel upgrade limitation and SSE fallback recommendation; identify the missing runtime capability precisely.

### R2-14 — P3 — §2: the universal third-party-cookie claim is false

**Problem and evidence:** [Roadmap lines 160–165](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/media-roadmap-spec/docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md:160) claim every current browser blocks cross-site cookies regardless of `SameSite=None`. Chrome retains user choice rather than universal blocking; Google’s [published update](https://privacysandbox.google.com/blog/update-on-plans-for-privacy-sandbox-technologies) explicitly describes that approach.

**Correction:** Say third-party cookies cannot be relied on across supported browsers and privacy settings. The app-origin decision remains justified without the universal claim.

**Verdict: request changes.** Revision 2 closes the original unsigned visibility bypass, private-cookie transport problem, HLS query propagation failure, and most isolation and feasibility defects. Remaining changes are still architectural: visibility transitions must retire the old source, orthogonal links need a coherent object model, publication needs an enforced fence, and the relay’s regional compromise claim conflicts with existing secret delivery. Resolve those alongside stale-edge behavior, backend coverage and job placement before treating the roadmap as ready for stage specifications.