Reviewed `8e59f598` against the clean worktree after reading AGENTS.md. R1–R7 remain settled.

| Round-1 finding | Status | Why |
|---|---|---|
| 1. Picker bypasses pool exclusion | Resolved | Pooled manifests now produce no candidates or guess. |
| 2. Browser adoption changes the default | Resolved | `@auto` remains distinct from an explicit choice; inference happens after adoption detection. |
| 3. Unnamed home prevents override | Resolved | Writing non-home app defaults requires a named home, which provides an explicit override. |
| 4. Mixed versions and rollback unspecified | Resolved | Read-first rollout, the switch, and the binary floor are specified; R7 accepts operational enforcement. |
| 5. Existing-canary `--region` undefined | Resolved | A different region refuses before writes or upload; an equal region proceeds. |
| 6. Manifest absence versus failure unspecified | Resolved | Absent, known, and unreadable policies have distinct behavior; legacy topology remains available. |
| 7. Absent-region explanation disappears | Resolved | `app_default` represents absent regions independently; C8 no longer depends on alternative-region count. |
| 8. Query hints reflected by redirects | Resolved | Hints travel in POST bodies, with redirect, error, logging, and audit assertions. |

The following findings are new.

1. **P1 — Arming per-host steering can break DNS for existing, unsteered siblings.**  
   **Spec:** §13.2–§13.4, §13.6, §17 Phase L.

   The documented deployment uses one `*.<apps-domain>` record ([README.md:442](/home/paulca/amadan.net/carlos/platform-nearest-region/README.md:442)). The converger writes individual steered names and `edge.<apps-domain>`, without account-level fallback records ([steering.go:369](/home/paulca/amadan.net/carlos/platform-nearest-region/internal/steering/steering.go:369)).

   Suppose `old.bap.apps.example` currently resolves through the root wildcard. Publishing a latency record for `new.bap.apps.example` creates the intermediate DNS node `bap.apps.example`. Queries for `old.bap.apps.example` then seek `*.bap.apps.example`, which does not exist; they cannot fall back to `*.apps.example`. Existing instances can therefore become unreachable when another instance is steered. This follows the closest-encloser rule in [RFC 4592 §3.3.1](https://www.rfc-editor.org/rfc/rfc4592.html#section-3.3.1).

   **Fix:** Specify how fallback DNS remains available beneath every ancestor introduced by steering. Include unstamped siblings, nested canaries, opt-out, and deletion in authoritative-DNS tests. Install and verify that coverage before Phase L writes per-host records. Checking only exact-name conflicts does not protect these names.

2. **P1 — “One latency record per edge” is invalid when two edges share an AWS region.**  
   **Spec:** §13.1, §13.3, §16, §17.

   `desiredState` emits one record per box ([steering.go:386](/home/paulca/amadan.net/carlos/platform-nearest-region/internal/steering/steering.go:386)); `desiredRRSet` uses the box as `SetIdentifier` and its AWS region as `Region` ([route53.go:597](/home/paulca/amadan.net/carlos/platform-nearest-region/internal/steering/route53.go:597)). Route53 allows only one latency record per AWS region within a name/type group. Distinct identifiers do not remove that restriction. [AWS latency-record requirements](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-values-latency.html#resource-record-sets-values-latency-region)

   With two London boxes, the desired set contains two `eu-west-2` records for each hostname, including the synthetic steering hostname. Route53 rejects the affected change batch; retries reproduce it. The spec explicitly accommodates multiple placement codes in one AWS region but does not constrain steering topology.

   **Fix:** Define a valid regional aggregation strategy, such as one latency alias per region targeting a separately health-checked regional routing group. Alternatively, explicitly constrain and validate the supported topology before arming. Add this AWS restriction to the Route53 fake and test duplicate-region edges.

3. **P1 — The prescribed pool-publication test would advertise a box that cannot provision shared instances.**  
   **Spec:** §6.1, §16 “Edges file and eligibility.”

   §16 says `CARLOS_POOLS=,tito` includes the shared pool. The actual parser discards empty elements, producing only `["tito"]` ([agent.go:2033](/home/paulca/amadan.net/carlos/platform-nearest-region/internal/host/agent.go:2033)). `poolServed(["tito"], "")` is false ([reconcile.go:1339](/home/paulca/amadan.net/carlos/platform-nearest-region/internal/provision/reconcile.go:1339)).

   A publisher implemented to satisfy that test would report shared eligibility while reconciliation rejects the resulting ordinary instances. This is a new inconsistency in the proposed fix for R2-1.

   **Fix:** Derive publication from the same parsed configuration and predicate reconciliation uses. Under current semantics, `,tito` must publish false. Supporting shared-plus-named pools through that spelling requires an explicit parser change and corresponding tenancy tests, beyond adding publication fields.

4. **P2 — Home fallback is not consistently constrained by the manifest allow-list.**  
   **Spec:** §6.1, §6.3–§6.4, §16.

   Candidate filtering is correct, but §6.4 separately says that missing home coordinates produce home “whatever the inputs”; §6.1 also substitutes home after a listing failure. The null rule covers an excluded home only when “no nearest exists.”

   For a manifest allowing only `uk`, a mapped, eligible UK candidate, and an unmapped home, these instructions conflict: UK has a nearest point, yet the unconditional fallback says home. A literal implementation can return a suggestion the create door rejects. Home normalization produces `""` ([apiinstancemove.go:136](/home/paulca/amadan.net/carlos/platform-nearest-region/internal/console/apiinstancemove.go:136)), and the allow-list compares that exact value ([apiinstances.go:1797](/home/paulca/amadan.net/carlos/platform-nearest-region/internal/console/apiinstances.go:1797)).

   **Fix:** State one final invariant: every non-null guess, including every home fallback, must pass the normalized policy predicate. If a fallback selects an excluded home, return null. Test missing home coordinates, unmappable hints, and edges-read failure against a non-home-only allow-list. The door still prevents a residency bypass; the defect is an unusable suggestion.

5. **P2 — Large DNS withdrawals are refused indefinitely, not spread over passes.**  
   **Spec:** §13.4, §16.

   §13.4 says the shrink limit may spread a mass deletion over passes. In fact, exceeding the limit returns before **any** changes ([route53.go:207](/home/paulca/amadan.net/carlos/platform-nearest-region/internal/steering/route53.go:207)). The existing loop documentation explicitly says this repeats forever without intervention ([steering_loop.go:154](/home/paulca/amadan.net/carlos/platform-nearest-region/internal/host/steering_loop.go:154)).

   For example, removing three of four steered hosts with three edges withdraws nine of fifteen records, counting the synthetic hostname. The limit is seven. Every pass refuses; old DNS remains, and unrelated additions in that pass also stop.

   **Fix:** Replace the automatic-progress claim with a defined recovery procedure, or design an explicit authorized withdrawal mechanism. Preserve the protection against incomplete reads. Add repeated-pass tests and require verification of actual DNS removal after bulk deletion or opt-out.

6. **P3 — §4 reverses which requests require positive eligibility.**  
   **Spec:** §4 versus §7.

   §4 says a **“non-app-derived”** value additionally needs positive eligibility. §7 specifies the opposite: app-derived values require it; explicit requests retain legacy dormancy, implemented at [apiinstances.go:848](/home/paulca/amadan.net/carlos/platform-nearest-region/internal/console/apiinstances.go:848).

   **Fix:** Change “non-app-derived” to “app-derived.” Otherwise a builder following the summary could tighten explicit requests while leaving automatic defaults insufficiently checked.

The other requested checks support the design. The fill preserves fleet precedence and the pool, replica, static, and address-backed exclusions; sidecars retain their separate door. The migration correctly covers both the ALTER-before-rebuild order and the fixed rebuild columns ([store.go:402](/home/paulca/amadan.net/carlos/platform-nearest-region/internal/console/store.go:402), [store.go:487](/home/paulca/amadan.net/carlos/platform-nearest-region/internal/console/store.go:487)). Old JSON clients remain compatible through permissive decoding and unmarshalling.

Migrated apps retain `""`, so the new positive-eligibility refusal does not newly strand their creates. Non-home apps can require capacity or policy repair if every allowed region becomes unavailable; an explicit override cannot override the manifest. I found no additional IP or coordinate retention requirement in the revised interfaces.

Your section references match an earlier revision: rev 3 has rollout in §17, no open questions in §18, and dispositions in §21. For the former rev-2 questions:

| Former question | Recommendation under the settled rulings |
|---|---|
| Q1 — titogo completion | Apply R5: existing-app relief comes from moves. Keep titogo adoption separate from acceptance of the new-app default. |
| Q2 — latency | Implement R6, including the DNS corrections above. Retain the separate, approved Phase L rollout and before/after measurements. |
| Q3 — rollback floor | Apply R7’s runbook floor. Name the exact version before activation and preserve region-aware reads when disabling new assignments. |

All code citations supporting these findings were checked in this worktree. No files changed, no tests ran, and production configuration was not inspected.

**Verdict: not ready for planning.** The earlier findings are addressed, but wildcard DNS continuity, duplicate-region latency records, and the pool-publication mismatch need concrete corrections. None requires reopening R1–R7.