| 1 | Reviewed `7ebc545e`. **The “no privilege over the public door” claim remains false:** `unknown` can make downstream address handling fall back to a caller-controlled header or loopback. |
| 2 | |
| 3 | | Round-3 finding | Disposition | |
| 4 | |---|---| |
| 5 | | R3-1: address trust grants application/gate authority | **Partly.** Rotating XFF no longer changes the local gate’s limiter key. Application authority remains possible through the new `unknown` representation; see finding 1. | |
| 6 | | R3-2: ownership residuals have no maximum lifetime | **Partly.** The bounds are now stated honestly, but classifying the residuals as harmless still depends on the disproved no-privilege claim. | |
| 7 | | R3-3: forwarded scheme differs by placement | **Closed.** Task 5 explicitly supplies `https` locally; the receiving TLS edge supplies it remotely. | |
| 8 | | R3-4: renewal/example contradictions | **Closed.** Publication advances only below the bucket revision ([plan:473](/home/paulca/amadan.net/carlos/platform-instance-moves-p7/docs/superpowers/plans/2026-09-28-instance-moves-p7-edge-door.md:473)); the option takes one argument ([plan:745](/home/paulca/amadan.net/carlos/platform-instance-moves-p7/docs/superpowers/plans/2026-09-28-instance-moves-p7-edge-door.md:745)). | |
| 9 | |
| 10 | The no-port `RemoteAddr` itself is handled safely: both [gate.go:230](/home/paulca/amadan.net/carlos/platform-instance-moves-p7/internal/gate/gate.go:230) and [analytics.go:86](/home/paulca/amadan.net/carlos/platform-instance-moves-p7/internal/edge/analytics.go:86) fall back to the raw string. Go’s `SetXForwarded` deletes XFF on that parse failure, after which Task 5 sets `unknown`. I found no reachable parser that panics on the synthetic address. The findings below come from source tracing, not execution of the unbuilt plan. |
| 11 | |
| 12 | 1. **P1 — `unknown` can restore caller-address authority or make the application see loopback.** |
| 13 | |
| 14 | Task 5 supplies `X-Forwarded-For: unknown` ([plan:652](/home/paulca/amadan.net/carlos/platform-instance-moves-p7/docs/superpowers/plans/2026-09-28-instance-moves-p7-edge-door.md:652)), while the scrubber leaves `Client-IP` untouched ([homemap.go:806](/home/paulca/amadan.net/carlos/platform-instance-moves-p7/internal/edge/homemap.go:806)). |
| 15 | |
| 16 | Rails 8.0.2 provides a concrete counterexample. Its address resolver discards non-IP XFF values. With `unknown`, its forwarded-address list becomes empty, disabling the comparison that normally rejects a conflicting `Client-IP`. It can therefore return an attacker-selected `Client-IP`. Without that header, it falls back to the backend peer address. [Rails RemoteIp implementation](https://raw.githubusercontent.com/rails/rails/v8.0.2/actionpack/lib/action_dispatch/middleware/remote_ip.rb). |
| 17 | |
| 18 | For an application behind CARLOS’s loopback TCP proxy ([edge.go:2182](/home/paulca/amadan.net/carlos/platform-instance-moves-p7/internal/edge/edge.go:2182)), that fallback is loopback. Rails then considers the request local when both peer and resolved addresses are loopback. [Rails `local?` implementation](https://raw.githubusercontent.com/rails/rails/v8.0.2/actionpack/lib/action_dispatch/http/request.rb). |
| 19 | |
| 20 | Thus an application authorizing by resolved IP or locality can admit a door request that its public counterpart rejects. This also restores the security consequence of stale cross-app ownership. |
| 21 | |
| 22 | **Required:** preserve Paul’s no-caller-address ruling, but specify downstream handling that cannot accept alternate address headers or fall back to privileged peers. Add real framework tests for local and backhauled requests, with and without `Client-IP`. Merely asserting the raw XFF value is insufficient. |
| 23 | |
| 24 | 2. **P2 — Cache variation sees different headers from the application.** |
| 25 | |
| 26 | The door removes inbound forwarding headers ([plan:711](/home/paulca/amadan.net/carlos/platform-instance-moves-p7/docs/superpowers/plans/2026-09-28-instance-moves-p7-edge-door.md:711)). Task 5 regenerates them only on `pr.Out`. Meanwhile, cache lookup uses the inbound request ([edge.go:1583](/home/paulca/amadan.net/carlos/platform-instance-moves-p7/internal/edge/edge.go:1583)), and storage computes `Vary` from that same inbound request ([edge.go:1702](/home/paulca/amadan.net/carlos/platform-instance-moves-p7/internal/edge/edge.go:1702)). |
| 27 | |
| 28 | Consider an application returning cacheable, address-dependent content with `Vary: X-Forwarded-For`. A local door response generated for `unknown` is stored under an **empty** XFF value. An ordinary public request without XFF matches it, even though its upstream address would be a real client IP. The reverse ordering also serves the wrong representation. Successful backhaul instead supplies inbound `unknown`, creating different behavior by placement. |
| 29 | |
| 30 | This exposes an existing inbound/outbound cache mismatch through the new door. |
| 31 | |
| 32 | **Required:** make cache selection reflect effective upstream forwarding values, or exclude responses varying on rewritten headers. Test public→door and door→public cache reuse, including backhaul. |
| 33 | |
| 34 | 3. **P2 — Failed hop verification breaks the promised address representation.** |
| 35 | |
| 36 | Task 5 explicitly leaves `acceptHop` unchanged ([plan:666](/home/paulca/amadan.net/carlos/platform-instance-moves-p7/docs/superpowers/plans/2026-09-28-instance-moves-p7-edge-door.md:666)). If the receiving edge cannot verify the sender’s mesh key, it strips forwarding headers and continues as an ordinary request ([homemap.go:793](/home/paulca/amadan.net/carlos/platform-instance-moves-p7/internal/edge/homemap.go:793)). |
| 37 | |
| 38 | The door context never crossed the connection. Consequently, the receiving proxy generates XFF from the sending edge’s network address instead of preserving `unknown`. Analytics also uses that peer address. The unconditional “no real address” and placement-equivalence promises therefore fail during verification failure. |
| 39 | |
| 40 | **Required:** define this failure outcome explicitly and add a two-edge mismatched-key test. If `unknown` is mandatory, delivery must refuse rather than silently substitute an infrastructure address. |
| 41 | |
| 42 | 4. **P3 — The stated gate and visitor aggregation contracts are inaccurate.** |
| 43 | |
| 44 | [Plan:14](/home/paulca/amadan.net/carlos/platform-instance-moves-p7/docs/superpowers/plans/2026-09-28-instance-moves-p7-edge-door.md:14) promises one guessing limit and one visitor per app per box. The gate actually includes the route host in its limiter key ([gate.go:151](/home/paulca/amadan.net/carlos/platform-instance-moves-p7/internal/gate/gate.go:151)). After backhaul, it keys on the sending edge’s address, not the app marker. |
| 45 | |
| 46 | Analytics hashes host and User-Agent alongside the address ([meter.go:178](/home/paulca/amadan.net/carlos/platform-instance-moves-p7/internal/analytics/meter.go:178)); successful backhaul supplies `unknown` instead of the local app marker. |
| 47 | |
| 48 | **Required:** document these actual partitions and test them, or specify the changes needed to deliver the promised aggregation. |
| 49 | |
| 50 | **The plan is not ready to build.** |