1. **P1 — An old edge can turn a client-supplied fill marker into an authenticated fill.**  
   §5.3 trusts `X-Carlos-Asset-Fill: 1` whenever `acceptHop` succeeds. An old far edge forwards that unknown client header and adds legitimate hop authentication ([edge.go:3032](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/edge/edge.go:3032)). The signature covers only hostname and timestamp, not the fill marker ([mesh.go:179](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/edge/mesh.go:179)). Consequently, a client reaching an old edge can make an upgraded home suppress metering, while the old edge also records nothing. Stripping the marker on upgraded ingress edges does not close this mixed-fleet path.

   **Smallest fix:** Require a separate, authenticated fill assertion covering the request and fill identity, with a signature domain distinct from ordinary hop authentication. Add an old-far/new-home test carrying a forged marker and require ordinary billing.

2. **P1 — A purge can populate the new generation with the old generation’s bytes.**  
   The publisher reads the registry independently ([edgesfile.go:877](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/host/edgesfile.go:877)); the serving edge updates through its separate watcher ([edge.go:2332](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/edge/edge.go:2332)). Therefore: the registry reaches G2, the publisher advertises G2, a far edge reads G2, but the home still serves G1. The marker in [§5.3](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/specs/2026-10-24-edge-asset-cache-design.md:320) carries no expected generation. The home can return its G1 cache hit, which the far edge stores under G2 for the full lifetime. Subsequent convergence cannot invalidate that entry. The explicitly permitted disarmed-home fallback also admits responses from the shared LRU and restores double billing.

   **Smallest fix:** Bind fills to the expected account, app and asset generation. Require a home-generated acknowledgement of that identity and fill handling before far-edge admission. Mismatches and unarmed homes must not populate the asset cache. Test publication ahead of home reload, disarming, and ownership changes during fills.

3. **P1 — The freshness fix still allows stale authority to be renewed indefinitely.**  
   [§4.2](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/specs/2026-10-24-edge-asset-cache-design.md:243) renews `assets_at` at publication time, independently of successful instance convergence. The publisher builds from local registry rows ([edgesfile.go:420](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/host/edgesfile.go:420)). If instance reads fail while edges-file writes continue, it can repeatedly advertise an obsolete generation with a fresh timestamp. Far-edge hits then survive beyond the promised hour.

   There is another trap in the proposed local bound: `RecordView.Refresh` can return nil after individual scope reads fail; completeness is reported separately ([recordview.go:164](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/provision/recordview.go:164)).

   **Smallest fix:** Tie serving and publication expiry to successfully validated **and applied** authoritative state. Publication alone must never renew that expiry. Require the appropriate snapshot-completeness checks and fresh convergence after restart. Test failed instance reads with successful edges-file publication for longer than an hour.

4. **P1 — Cached responses lose security headers.**  
   The exhaustive stored-header list in [§5.4](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/specs/2026-10-24-edge-asset-cache-design.md:360) omits `Content-Security-Policy` and `Cross-Origin-Resource-Policy`. An otherwise admissible SVG can contain script that the origin deliberately disables through CSP. Opening the cached SVG would execute that script because the hit drops the policy. This changes security behavior between miss and hit. The existing cache preserves the response headers ([edge.go:1907](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/edge/edge.go:1907)) and replays them ([edge.go:2121](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/edge/edge.go:2121)).

   **Smallest fix:** Preserve security-relevant end-to-end response headers, or refuse admission when their semantics cannot be preserved. Add an SVG response with restrictive CSP and CORP to the miss/hit tests.

5. **P2 — “Union of live generations” removes catching when an instance hibernates.**  
   [§4.1](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/specs/2026-10-24-edge-asset-cache-design.md:211) derives declarations exclusively from currently live generations. Hibernation deletes the activator entry and republishes the generation inventory without that build ([activator.go:4393](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/activator/activator.go:4393)); `ServingGen` then returns false ([genservice.go:68](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/activator/genservice.go:68)). The union becomes empty, so warmed assets cease to be caught and the next request can wake the app. The existing cache explicitly retains `CacheGen` after sleep for this reason ([gensource.go:29](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/edge/gensource.go:29)).

   **Smallest fix:** Define declaration state that survives sleep, tied to the instance’s owner and asset generation and updated appropriately on deployment. Test a generation-managed instance through warm → sleep → home/far cache hit, including restart.

6. **P2 — A home-cache hit receives a new full lifetime at the far edge.**  
   [§5.3](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/specs/2026-10-24-edge-asset-cache-design.md:334) derives lifetime solely from `s-maxage` or `max-age`; §5.4 retains neither `Date` nor upstream age. Yet marked fills can return home-cache hits. With `max-age=3600`, a home response already 3,599 seconds old can receive another 3,600 seconds at the far edge. Emitting `Age` on later hits does not correct admission or expiry. Reusing the existing insertion pattern would produce exactly this reset ([edge.go:1907](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/edge/edge.go:1907)).

   **Smallest fix:** Specify age-aware admission and persist the original freshness deadline, accounting for incoming `Age`, `Date`, and transfer time. Test a nearly expired home entry filled through a far edge and require both copies to expire at the original deadline.

7. **P2 — The gzip serving rules omit representation correctness.**  
   [§§5.4–5.5](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/specs/2026-10-24-edge-asset-cache-design.md:360) retain one strong ETag while serving either identity or gzip, omit outgoing `Vary: Accept-Encoding`, and permit compression despite `Cache-Control: no-transform`. A downstream cache can consequently reuse gzip for a client that cannot decode it; the shared strong validator also makes byte-range validation unsafe. Existing compression code already handles these requirements: it respects `no-transform` ([compress.go:112](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/edge/compress.go:112)), adds `Vary`, and weakens the gzip ETag ([compress.go:237](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/edge/compress.go:237)).

   **Smallest fix:** Require equivalent behavior for precompressed entries: appropriate `Vary`, representation-specific or weakened validators, and no transformation when prohibited. Test identity/gzip conditional requests and `If-Range`.

8. **P2 — Checking free space only when a fill starts does not preserve the disk floor.**  
   [§7](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/specs/2026-10-24-edge-asset-cache-design.md:430) claims that refusing starts below 15% free prevents crossing 10%. On an 8 GiB filesystem at 15% free, sixteen simultaneous 32 MiB identity fills consume 512 MiB and leave only 8.75% free—even before gzip copies. Spread across four apps, these fills satisfy both concurrency limits and fit within the default total budget. The actual placement floor is 10% ([policy.go:20](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/boxchoice/policy.go:20)).

   **Smallest fix:** Reserve disk capacity atomically before admitting fills, accounting for concurrent temporary files, identity bodies, gzip copies and metadata. Bound writes against those reservations and release them on every exit. Test simultaneous maximum-size fills near the headroom threshold.

reject