| 1 | Reviewed `996b24c3`. **P** refers to the [implementation plan](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/region-ha-1b-next/docs/superpowers/plans/2026-10-07-region-ha-1b-next-relocation.md). Stage B dispositions assess contracts only. |
| 2 | |
| 3 | | Finding or partial carried by round 4 | Disposition | Assessment against rev 5 | |
| 4 | |---|---|---| |
| 5 | | R1-5 — immutable files pin | Resolved | P8271 preserves verification against the retained manifest. | |
| 6 | | R1-9 — release replay after restart | Resolved | P8269 requires `Region` initially and on recovery, plus `Recover` and a coordinator replay test. | |
| 7 | | R2-N4 — completed target remains held | Resolved | The policy permits clearing with HA enabled; P8274 retains the adapter’s completion test. | |
| 8 | | R2-N5 — retained controller lifetime | Resolved for the timeout | The entry survives an interrupted close. Cleanup safety remains incomplete below. | |
| 9 | | R3-N1 — adapter identifiers and fixture | Resolved at contract level | P8274 requires the real adapter and its integration tests; compilation awaits Stage B. | |
| 10 | | R3-N2 — premature controller removal | Resolved | P7616–7620 retains the entry when close or clear fails. | |
| 11 | | R3-N3 — production provider wiring | Resolved | R8 requires the verified actor before policy capture; P8275 names the assembly test. | |
| 12 | | R3-N4 — fenced source’s hold | Resolved | Task 9a provides the hold-only path with a fresh decision under `WithLocal`. | |
| 13 | | R3-N5 — exhausted target after installation | Resolved | `FenceExhaustedTarget` consumes the fence and reaches stuck pinning. | |
| 14 | | R3-N6 — replacement acknowledgement | Resolved | `PinAfterRelease` checks acknowledgements before leaving `releasing`. | |
| 15 | | R4-1 — fence observer deadlock | Resolved | P3568 reads without reacquiring the lock; Task 9a tests both paths with the real observer. | |
| 16 | | R4-2 — target probe authority | Resolved | Task 3 admits the separate `"probe"` action; R1 requires runtime dispatch through it. | |
| 17 | | R4-3 — missing restore directories | Resolved at contract level | P9014–9017 requires inventory and directory creation before restore, tested on a fresh spare. | |
| 18 | | R4-4 — privileged held staging | Resolved at contract level | R9 and P9019–9022 require relocation-aware root staging and verification. | |
| 19 | | R4-5 — durable controller cleanup | **Partly; P1 safety gap** | P7616–7619 relies on a successful `Close` before clearing. But [`Controller.Close`](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/region-ha-1b-next/internal/hostexec/controller.go:480) returns a cleanup failure once, sets `closed`, then returns nil on subsequent calls. The next sweep can therefore clear the record despite failed cleanup. Restart recovery at P7640 likewise clears from the binding without cleanup-success evidence. Persist that evidence or repeat authenticated cleanup before clearing; test failure followed by another sweep and restart. Also discover records left by a crash before the first `Finish`. Carry these obligations into P8270. | |
| 20 | | R4-6 — obsolete-hold clearance with HA disabled | Resolved | The bypass now requires `Policy.Relocation`; both settings are tested. | |
| 21 | |
| 22 | New findings, ranked: |
| 23 | |
| 24 | 1. **P1 — Task 1, Step 3; Task 2, Step 3; Task 5, Step 3: replacement can install on a box owing `park-local`.** |
| 25 | P2780–2786 excludes lost boxes but not boxes with outstanding local retirement. The worker’s exclusions at P5595–5605 omit those obligations too. During replacement, P2071–2073 calls `install` directly, bypassing `ToInstalling`’s `park-local` check. |
| 26 | |
| 27 | Start A→B while spare C owes an older local retirement, then terminate B during `installing` or `installed`. C can receive new installation authority despite that obligation. Spec §2 explicitly excludes C. |
| 28 | |
| 29 | **Fix:** exclude these boxes during selection and enforce the condition again inside the replacement CAS. Test refusal of C and selection of a clean spare. |
| 30 | |
| 31 | 2. **P2 — Task 1, Step 3: automatic fencing leaves regional chores assigned to the dead box.** |
| 32 | `fenceBox` at P1369–1411 handles local discharge and loss retention but never reassigns `park-generation` or `park-replica` obligations. A box-owned `park-generation` is permitted by `RelocationStartGuard`, so failover can leave it permanently assigned to the terminated source. |
| 33 | |
| 34 | L3 requires reassignment to `region:<r>`; [`lost.go:302`](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/region-ha-1b-next/internal/hostclaim/lost.go:302) already implements this for declared loss. |
| 35 | |
| 36 | **Fix:** apply equivalent reassignment in the automatic fence CAS, preserving obligation identities and scope. Test with both qualified and unqualified local discharge. |
| 37 | |
| 38 | 3. **P2 — Task 9a, Step 3: reconciliation changes behavior with HA disabled.** |
| 39 | P8163–8187 unconditionally replaces `Serving` with `RelocationRow`, accepting `RowHeld` even when both new callbacks are nil. A `moving` or `restoring` executor participant now passes the initial check. Dry runs succeed; real calls can activate the installation and record inventory before the later write-policy refusal. [`WorkSource.SelectAt`](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/region-ha-1b-next/internal/hostbox/work.go:94) does not evaluate that policy. |
| 40 | |
| 41 | **Fix:** preserve the original serving-only check when HA is disabled. Test non-serving executor claims with HA off, asserting refusal and unchanged guard/inventory state. |
| 42 | |
| 43 | 4. **P2 — Task 7, Step 4: an interrupted journal write hides all restart cleanup work.** |
| 44 | P7658–7672 writes `.json.tmp` before renaming. A crash can leave it truncated. `journaled` attempts to decode every directory entry at P7544–7551, so that temporary file makes the whole listing fail. `Retained` discards the error at P7570. |
| 45 | |
| 46 | After restart, even valid finishing entries for other hosts disappear from the sweep, leaving their controller records blocking updates indefinitely. |
| 47 | |
| 48 | **Fix:** exclude uncommitted temporary files, surface committed-record errors, and preserve unrelated recoverable entries. Test a restart with one valid journal and one truncated temporary file. |
| 49 | |
| 50 | 5. **P2 — Task 7, Step 4: release flushing preserves a deleted environment file.** |
| 51 | P7199 loads the existing manifest. When the environment file is absent, P7210–7218 does nothing, leaving the old `Platform[EnvItem]` intact. Flushing `KEY=v`, removing the file, and flushing again therefore still publishes `KEY=v` for restoration. This contradicts the final-state promise and §5.6’s requirement to flush deletions. |
| 52 | |
| 53 | **Fix:** represent platform-item deletion explicitly and stage it on `ENOENT`. Extend the flush test with a previously published environment file that is subsequently removed. |
| 54 | |
| 55 | I accept rulings 1–24 as scoped choices; ruling 20 remains incompletely implemented. Stage B covers the earlier integration obligations, but its cleanup contract needs the recovery requirements identified under R4-5. |
| 56 | |
| 57 | All **12 embedded patches pass `git apply --check`**. Compilation and tests were not reproduced in this read-only sandbox. No files changed. |
| 58 | |
| 59 | **Verdict: not ready.** |