plan: region HA 1a, what the build changed and what plan 1b picks up
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 file changed,
+19
−0
docs/superpowers/plans/2026-10-05-region-ha-1a-foundations.md+19 −0
CI passed — run details
diff --git a/docs/superpowers/plans/2026-10-05-region-ha-1a-foundations.md b/docs/superpowers/plans/2026-10-05-region-ha-1a-foundations.md| index 1496539f1..f374bea37 100644 |
| --- a/docs/superpowers/plans/2026-10-05-region-ha-1a-foundations.md |
| +++ b/docs/superpowers/plans/2026-10-05-region-ha-1a-foundations.md |
| @@ -6720,3 +6720,22 @@ Findings are in `CODEX-PLAN-REGION-HA-1A-R4.md`. Round 4 marked every outstandin |
| | # | Finding | Disposition | |
| |---|---|---| |
| | 1 | P2 Task 8: wake state named by the manifest but missing its object read as "no wake state" | fixed: `LoadWake` reports absence only when the manifest has no wake entry; any failure to read a named entry is an error; `TestLoadWakeWithItsObjectMissingIsAnError` | |
| + |
| +## After the build (2026-10-06) |
| + |
| +The plan was built task by task with a review after each, then a whole-branch review and one fix wave. Where the code now differs from the text above, the code is right: |
| + |
| +- **`box_id` is the box's label on every box** (final review, I2). `edgesFileBoxID` and the instance-id read at loop arm were removed. Spec §2 keeps labels for boxes that predate region HA; plan 1b adds instance ids for Auto Scaling boxes from a positive signal, and must write box records under the label. |
| +- **Headroom is published only when `CARLOS_REGION_HA` is on** (`headroomFor`), so a one-box region never rewrites its edges file for headroom alone. `parseMemAvailableMiB` lives once, in `headroom.go`. |
| +- **`Publisher.Commit` remembers every failed attempt since the last success** and adopts whichever one storage holds, so a lost response is never a false `ErrSuperseded`, even with stages in between or two failures in a row. |
| +- **`Restore`** masks modes to permission bits, resolves an entry that is both a live path and the ancestor of another by keeping the higher seq (`RestoreStats.Superseded`), and refuses any entry whose object key, hash or size is not one this package could have written. |
| +- **`descend`** refuses `""`, `.` and `..` components. The run loop retries repair and failing scans at most once per poll and logs only transitions; zero `Options` take the defaults. |
| +- **`ImportWake`** checks the route exists before it writes. |
| + |
| +**Add to "What plan 1b picks up":** |
| + |
| +11. One inotify instance per agent rather than per host, and no re-hash of a file whose size, mtime and inode match what was last staged (final review, I4). As built, a box with many continuous hosts exhausts `max_user_instances` and falls back to polling full scans. |
| +12. A `MaxFileBytes` cap in `StagePlatform`, matching `Restore`'s refusal; a rate limit on `Commit` during a manifest outage. |
| +13. The box-record writer (`boxid.Publish` at agent start) and `carlos ops box bind`, keyed by label. |
| +14. Box ids must not contain `.` (`Key("x.bind") == BindKey("x")`); the termination queue is one per box (per `region-host` instance), not one per region. |
| +15. Before the first apply of the deployment-buckets module: check each deployment bucket for an existing bucket policy (`aws s3api get-bucket-policy`) and the consuming root for another `aws_s3_bucket_policy`. A bucket holds one policy, and this resource replaces it whole. |