| 1 | Reviewed `521f78ee1569e1fcbaadd9647660198832290838` read-only. No builds or tests run; working tree unchanged. |
| 2 | |
| 3 | | Open round-2 item | Status | Assessment | |
| 4 | |---|---|---| |
| 5 | | Ownership after failed install handoff | **Closed** | [`cacheDir`](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-2b/docs/superpowers/plans/2026-10-17-region-ha-2b-joining.md:2083) reconciles every required parent on every invocation. The retry test covers the previous failure. | |
| 6 | | Permanent reference collisions | **Closed** | Group references replace the 1,600-label namespace for identity and enrolment. Console derivation and rollout gating are specified. The status fallback has a separate defect below. | |
| 7 | | Membership freshness at the write | **Closed** | [`writeBound`](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-2b/docs/superpowers/plans/2026-10-17-region-ha-2b-joining.md:2982) covers the downstream reads and final `Put` of both writers. Slow-read tests now exercise the original gap. | |
| 8 | | Seeding permissions | **Closed** | Seam 4 and RHB-C61 include the SSM read and scoped `kms:Decrypt`. | |
| 9 | | Stop/start versus reboot verification | **Partly** | Explicitly gated before activation; the required dev observation remains outstanding. This does not itself block implementation. | |
| 10 | |
| 11 | New findings: |
| 12 | |
| 13 | 1. **P2 — An unresolved group reference can overwrite a legacy box’s status indefinitely.** |
| 14 | [Task 6’s `statusLoop` patch](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-2b/docs/superpowers/plans/2026-10-17-region-ha-2b-joining.md:5541) accepts `("", true)` from `groupStatusLabel`. [`statusTick`](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-2b/internal/host/agent.go:3763) interprets the empty override as “use `status.Label(machineID)`.” [`WriteBox`](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-2b/internal/status/snapshot.go:1111) reads that key’s current ETag and replaces its contents; CAS does **not** establish ownership. |
| 15 | |
| 16 | **Reachability matters:** with both claim mode and HA enabled, `productionModeFacts` obtains and caches a nonempty group reference before hosting starts. An IMDS outage at that startup therefore waits; it does **not** reach this fallback. However, [`decideAgentMode`](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-2b/docs/superpowers/plans/2026-10-17-region-ha-2b-joining.md:6660) bypasses that check when either flag is off, while the group marker still controls status naming. |
| 17 | |
| 18 | On that path, a colliding legacy label lets the group box replace another box’s report. Its own derived-key report stops refreshing, and the victim’s metrics become incorrect or fail enrolment/instance validation. Correctly keyed group reports are unaffected. Recovery of IMDS does not repair this loop: `fleetLabel` was captured once. |
| 19 | |
| 20 | **Publish nothing until the group reference resolves, then retry.** Preserve existing non-group behaviour. Add coverage through the actual status publication path, including an existing victim report; the current helper test explicitly accepts the empty reference without testing its consequence. |
| 21 | |
| 22 | 2. **P2 — Automatic replacement eventually exceeds the status reader’s lifetime-object limit.** |
| 23 | Every replacement now publishes a distinct status object, but [`loadBoxesReport`](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-2b/internal/status/fleet.go:244) truncates the entire prefix to 200 keys **before** considering freshness. The [bucket lifecycle configuration](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-2b/infra/modules/deployment-buckets/main.tf:28) does not expire these reports, and this plan adds no retirement cleanup. |
| 24 | |
| 25 | Once historical and current reports exceed 200, current boxes can disappear from status results and completeness remains false. That disables automatic non-home region eligibility through [`regionCandidates`](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-2b/internal/console/regioncandidates.go:166), and blocks report-dependent retention. Two concurrent boxes do not prevent this lifetime accumulation. |
| 26 | |
| 27 | The reader limit predates this change, but automatic replacement makes it an operational lifecycle requirement. Specify safe retirement/expiry or bounded discovery of current reports, and test more than 200 historical reports alongside live boxes. |
| 28 | |
| 29 | **The two redundant pre-checks:** I recommend removing both—the `enroll` freshness callback and the check immediately before `Invite`. Retain `checkConfirmed`’s freshness check after the describe and retain the mandatory bound store/context. The extra checks cannot protect against intervening I/O, and the callback unnecessarily changes generic enrolment plumbing. Their surviving individual mutation tests are expected redundancy, not a safety failure. |
| 30 | |
| 31 | --- |
| 32 | |
| 33 | **FIRST PROMPT:** |
| 34 | Round 3 review of region HA 2b at 521f78ee, including status fallback and redundant pre-checks. |
| 35 | |
| 36 | **WHAT:** |
| 37 | Reviewed the revised plan against round 2 and its supporting code paths. |
| 38 | |
| 39 | **STATUS:** |
| 40 | Four prior defects closed at plan level; two new P2 findings. Activation verification remains pending. |
| 41 | |
| 42 | **NEEDED:** |
| 43 | Nothing for this review. |
| 44 | |
| 45 | **RECOMMENDED:** |
| 46 | Fix unresolved-reference publication and specify status-report retirement; remove the redundant pre-checks. |
| 47 | |
| 48 | **SESSION:** |
| 49 | Safe to close. No files changed or processes started. |
| 50 | |
| 51 | **Verdict: not ready to build.** |