| 1 | 1. **P1 — Shared types are introduced after tasks that require them.** Plan 1 Task 8 defines `assetPolicy.For` returning `edge.HostAssets`, but Task 9 first introduces that type and `LocalAssets` ([plan 1:262](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-1-declare-publish.md:262), [plan 1:290](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-1-declare-publish.md:290)). Likewise, Plan 2 Task 1 defines `Config.FS FS`, while Task 2 introduces `FS` ([plan 2:65](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-2-disk-store.md:65), [plan 2:82](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-2-disk-store.md:82)). Neither earlier task can reach its required passing build. **Smallest fix:** move the shared type declarations before their first consumers; leave their implementations in the later tasks. |
| 2 | |
| 3 | 2. **P1 — Plan 3 Task 5 calls a method on the wrong interface.** `fillFromApp` takes `a HostAssets` and asks “`a`’s `Declared`” ([plan 3:157](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-3-serve.md:157)). `HostAssets` is a data struct; `Declared` belongs to `LocalAssets` ([plan 1:290](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-1-declare-publish.md:290)). **Smallest fix:** specify `e.assets.local.Declared(host, answeringBuild, path)`, using the request hostname. |
| 4 | |
| 5 | 3. **P1 — The census instructions prescribe invalid dispositions.** Plan 1 Task 11’s inventory calls for an `@legacy` row retaining class `authority`, and a new authority row owned solely by `J1` ([plan 1:45](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-1-declare-publish.md:45)). Plan 3 Task 10 prescribes class `cache` ([plan 3:37](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-3-serve.md:37)). The loader requires `@legacy` rows to have class `legacy`, has no `cache` class, and does not accept `J1` alone as an authority owner ([census:420](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/provision/plan14_root_reads_test.go:420), [census:480](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/provision/plan14_root_reads_test.go:480), [census:507](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/provision/plan14_root_reads_test.go:507)). **Smallest fix:** preserve existing authority rows as ordinary authority entries, assign valid kept-family ownership, and explicitly use the existing legacy format for applicable cache reads. |
| 6 | |
| 7 | 4. **P1 — Plan 3 Task 10’s provider test necessarily fails on existing code.** It asserts that `go list -deps` for `internal/edge` contains no AWS packages, claiming the package already imports none ([plan 3:252](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-3-serve.md:252)). `route53dns.go` directly imports four AWS packages ([route53dns.go:25](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/edge/route53dns.go:25)). **Smallest fix:** retain the dependency check for the new `assetcache` package and check the new asset implementation files for AWS imports; retain the credential-free `DirStore` integration test. |
| 8 | |
| 9 | 5. **P1 — Plan 1 Task 7’s proposed write-failure fixtures cannot exercise the named branches.** The plan keeps a concrete `*registry.Registry` parameter but proposes an `aliasRegFailing` wrapper or closing the registry ([plan 1:240](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-1-declare-publish.md:240)). A wrapper cannot satisfy that concrete parameter. Closing the handle makes `ListAliases` fail before the write branches, so the pass returns an error instead of the required nil-with-incomplete result ([aliases.go:245](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/domains/aliases.go:245), [registry.go:2755](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/registry/registry.go:2755)). **Smallest fix:** prescribe selective SQLite write-failure triggers on the test database, or introduce a narrow registry interface. |
| 10 | |
| 11 | 6. **P2 — Plan 3 Tasks 2, 5 and 6 omit the `Set-Cookie` trailer veto.** Admission checks headers, and the fill instructions commit after a successful body without a trailer check ([plan 3:102](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-3-serve.md:102), [plan 3:157](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-3-serve.md:157)). The spec explicitly prohibits `Set-Cookie` trailers ([spec:491](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/specs/2026-10-24-edge-asset-cache-design.md:491)); the existing shared cache already checks them ([edge.go:1875](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/edge/edge.go:1875)). **Smallest fix:** require a final trailer veto before committing on both edges, preserving the information through backhaul; test announced and unannounced cookie trailers. |
| 12 | |
| 13 | 7. **P2 — Plan 1 Task 6 can confirm records that were never applied.** Its completeness predicate checks successful reads and successful attempted writes ([plan 1:225](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-1-declare-publish.md:225)). However, an unreadable trash marker sets `declineMint`, and the record loop skips the record before `convergeOwned`, without a failing route write ([reconcile.go:1137](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/provision/reconcile.go:1137), [reconcile.go:1174](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/provision/reconcile.go:1174)). A newly purged generation can therefore remain unapplied while authority time advances. **Smallest fix:** require positive application or verified equality for every relevant existing route; mark skipped application incomplete and test this case with a changed generation. |
| 14 | |
| 15 | 8. **P2 — Plan 2 Tasks 3 and 4 do not bound metadata writes.** Reservations allocate 64 KiB for metadata, but the specified write limits cover only identity and gzip bodies; `Commit` serializes arbitrary `Meta.Header` and key contents ([plan 2:103](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-2-disk-store.md:103), [plan 2:126](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-2-disk-store.md:126)). This does not implement the spec’s prohibition on writes past the reservation ([spec:643](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/specs/2026-10-24-edge-asset-cache-design.md:643)). **Smallest fix:** bound the encoded metadata before writing it, include its bytes in accounting, and test oversized headers and queries. |
| 16 | |
| 17 | 9. **P2 — Plan 2 Task 4’s replacement sequence is not crash-safe.** `Commit` replaces `.body`, then `.gz`, then `.meta`, including for an existing key ([plan 2:126](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-2-disk-store.md:126)). A crash after replacing the body leaves the previous valid metadata, so `Open` indexes new bytes with old headers, sizes or expiry. The proposed missing-meta crash test does not catch this. **Smallest fix:** invalidate the old metadata before replacing its files, with coordinated readers, or publish versioned body files through the metadata commit. Add a replacement-crash test. |
| 18 | |
| 19 | 10. **P2 — Plan 3 Task 5 does not apply conditional or range semantics to the initiating miss.** It strips those request headers upstream and tees the resulting body directly to the client ([plan 3:157](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-3-serve.md:157)). Task 3 tests those semantics only against an existing entry. The spec requires the edge to answer them itself ([spec:400](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/specs/2026-10-24-edge-asset-cache-design.md:400)). **Smallest fix:** specify how an admitted cold fill answers its initiating conditional/range request through `serveAssetEntry`, and add cold local and far tests. |
| 20 | |
| 21 | 11. **P2 — Plan 3 Tasks 1 and 5 leave acknowledgement key selection undefined during rotation.** `verifyAssetFill` accepts either key but returns only a boolean; `verifyAssetAck` accepts only the key the far edge used ([plan 3:83](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-3-serve.md:83)). The existing `signingKey` prefers `.next` immediately ([mesh.go:167](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/edge/mesh.go:167)). If the home has `.next` and the far edge still signs with current, signing the acknowledgement with the home’s preferred key makes both edges skip billing. **Smallest fix:** return the matched verification key and sign the acknowledgement with it; test asymmetric key availability. |
| 22 | |
| 23 | 12. **P2 — Plan 3 Task 6 catches upgrade requests.** Its far-edge predicate accepts any matching canonical GET or HEAD, with no upgrade exclusion ([plan 3:187](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-3-serve.md:187)). Unlike the local hook, this executes before the existing upgrade branch. A WebSocket GET under an asset prefix can receive a cached body or lose its upgrade headers during filling, contrary to [spec:385](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/specs/2026-10-24-edge-asset-cache-design.md:385). **Smallest fix:** explicitly reject `isUpgradeRequest(r)` before far-cache lookup and test intact backhaul of the upgrade. |
| 24 | |
| 25 | 13. **P2 — Plan 1 Task 8 lacks a publication trigger for serving-generation changes.** It adds the serving build to the path union and a trigger for authority-time advances, but no trigger for a serving build changing while registry fields stay unchanged ([plan 1:264](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-1-declare-publish.md:264)). The current loop skips the writer until the registry fingerprint changes or its timer expires ([edgesfile.go:888](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/internal/host/edgesfile.go:888)). Thus a retiring build’s prefixes can remain published until the five-minute refresh, contrary to [spec:255](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/specs/2026-10-24-edge-asset-cache-design.md:255). **Smallest fix:** include serving-build changes in the scheduling signal and test a generation switch with an unchanged registry fingerprint. |
| 26 | |
| 27 | 14. **P2 — No task implements the fallback ETag.** Plan 2 Task 4 stores supplied headers, while Plan 3 Task 3 only preserves or weakens an existing ETag ([plan 2:126](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-2-disk-store.md:126), [plan 3:119](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-3-serve.md:119)). The spec requires a strong body-SHA256 ETag when the app supplies none ([spec:560](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/specs/2026-10-24-edge-asset-cache-design.md:560)). **Smallest fix:** assign hashing and fallback-header creation to the fill/commit task, with tests for identical home/far validators and conditional hits. |
| 28 | |
| 29 | 15. **P2 — Plan 3’s acceptance tasks omit required production-wired attacks.** Tasks 5 and 6 explicitly use fake `LocalAssets` and a fake home; Task 9’s real two-edge tests cover only five scenarios ([plan 3:161](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-3-serve.md:161), [plan 3:189](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-3-serve.md:189), [plan 3:239](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-3-serve.md:239)). The spec requires production wiring for the attack matrix, including credential stripping, refused fills, coalescing, deadlines and answering-generation checks ([spec:717](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/specs/2026-10-24-edge-asset-cache-design.md:717)). **Smallest fix:** assign those cases explicitly to the real two-edge suite, including the warm/sleep/restart generation lifecycle. |
| 30 | |
| 31 | 16. **P2 — Plan 1’s fixed copy inventory omits newly required refusals.** Task 0 pins exactly EAC-1 through EAC-19 ([plan 1:104](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-1-declare-publish.md:104)), but Task 3 requires a new error for combining `--assets` and `--no-assets`, and Task 2 requires echo and changed-assets reship refusals, without corresponding rows ([plan 1:138](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-1-declare-publish.md:138), [plan 1:161](/home/paulca/amadan.net/carlos/platform-edge-asset-cache/docs/superpowers/plans/2026-10-24-edge-asset-cache-plan-1-declare-publish.md:161)). **Smallest fix:** inventory these strings before Task 0’s review, update the exact-ID gate, and explicitly identify any existing approved wording reused. |
| 32 | |
| 33 | reject |