# Final whole-branch review: region HA plan 2b (built)

You are Astra, giving the final review of plan 2b's BUILT code before merge. Read-only. Run nothing heavy: no whole `internal/host` or `internal/console` suite; focused `go test -run` only if a specific doubt needs it (GOFLAGS=-buildvcs=false, nice -n 19).

- Branch `region-ha-2b-build`, HEAD `ac45a709`, merged with main `26065378` (merge-base). The branch diff is `git diff 26065378 ac45a709` (72 files, mostly internal/hostenv, internal/host, internal/hostactors, internal/console, internal/status, system.go, docs, the census overlay and the copy gate).
- Plan: `docs/superpowers/plans/2026-10-17-region-ha-2b-joining.md` (reviewed by you in six rounds; your rounds are CODEX-REVIEW-REGION-HA-2B-1..6.md). Spec: `docs/superpowers/specs/2026-10-15-region-ha-two-box-regions-design.md` rev 20. Copy record: `docs/superpowers/plans/2026-10-17-region-ha-2b-copy.md` (all rows approved by Paul).
- Build ledger with every ruling made during the build and every deferred minor: `/home/paulca/amadan.net/carlos/platform/.claude/worktrees/region-ha-2b-build/.superpowers/sdd/2026-10-17-region-ha-2b-joining/deferred-and-rulings.md`. Triage the deferred minors: say which must be fixed before merge.

Build-time departures from the plan (all reviewed per task):
1. Task 2: CARLOS_DNSIMPLE_TOKEN removed from the host.env allowlist (tokens are excluded by the plan's own rule).
2. Task 3: install-channel refuses a box that already runs a release (applied.json not Already) and a slot holding a foreign binary (O_NOFOLLOW fd hash vs the signed artifact sha, new copy row RHB-C69); cache removal is descriptor-anchored openat2 RESOLVE_BENEATH|RESOLVE_NO_SYMLINKS with no path fallback; cleanup registered only after cacheDir succeeds.
3. Task 4: request ids kept on failed/partial reads (NoRequestID constant); request-id checks before group/state; deadlineStore holds its store in a named field.
4. Task 5: the invite path binds the deadline to checkConfirmed's own confirmation; the invited path reads the invitation read-only (enrollmentNonce), never via get-or-create Invite; exported CheckConfirmed removed; refused/unknown log classification.
5. Task 6: a group box with an empty CARLOS_REGION is held.
6. Task 7: joinBoxLabel refuses with IMDS's reason (new copy rows RHB-C70/C71).
7. Task 8: RunAgent resolves a group box's reference before the gate and before any loop, whatever the switches; the joining run re-touches the join marker each minute while invited and unarmed.
8. Merge: runSystem/systemVerb rows carry main's activation-tools class (B,C,D,F,G,J4) with 2b's digest.

Binding conditions (claim owner platform-1e), all expected to hold: no box writes/approves/mints membership; the console's own describes are the only membership evidence; no exported path builds a confirmation from caller data; every invite and enrolling write is issued before 60 s from describe start with a 15 s per-call cut-off, a late success is unknown, unknown keeps the attempt with no backoff growth; roster writes are ETag CAS, invitations create-only; group refs are g- + 20 hex of sha256("carlos-box-ref-v1|"+account+"|"+instance); a group box publishes no status until its reference resolves; non-group boxes byte-for-byte unchanged; dormant with CARLOS_HOST_CLAIM or CARLOS_REGION_HA off.

Output: findings with severity (P1/P2/P3), file:line, failure scenario, and fix; then the deferred-minor triage; then "Verdict: ready to merge" or "not ready to merge". End with the usual FIRST PROMPT / WHAT / STATUS / NEEDED / RECOMMENDED / SESSION block.
