plan rev 2.1: platform-1e's narrowing of the claim refusals (guard mode not read; placement-scoped capability; done plans allowed)
1 file changed,
+12
−0
docs/superpowers/plans/2026-10-20-offline-operator-move.md+12 −0
diff --git a/docs/superpowers/plans/2026-10-20-offline-operator-move.md b/docs/superpowers/plans/2026-10-20-offline-operator-move.md| index 12de34774..ca3fb620c 100644 |
| --- a/docs/superpowers/plans/2026-10-20-offline-operator-move.md |
| +++ b/docs/superpowers/plans/2026-10-20-offline-operator-move.md |
| @@ -163,6 +163,18 @@ The `docs/site/cli.md` paragraph under `### carlos move` (Task 7) is copy too. T |
| ## Global Constraints |
| +- **Ruling 2026-10-20, from platform-1e as claim owner. It supersedes the claim and guard wording below where they conflict.** |
| + 1. **Instance claim state.** The start door refuses (MV-O29) on any of: |
| + - `control/hosts/<host>.json`; |
| + - a domains claim carrying `acq`; |
| + - a record carrying `acquisition`; |
| + - an `apps/<account>/<app>/admission.json`. |
| + |
| + It refuses (MV-O20) on a `control/hosts-backfill.json` whose phase is `collecting` or `adopting`. A plan at `done` is allowed, with any number of hosts. |
| + 2. **A console on the claim path refuses (MV-O20).** This is unchanged. |
| + 3. **The region-wide capability check narrows.** The start door refuses (MV-O21) when the target box lacks `offline-move-1`, or when any box that publishes the source placement lacks it. Those are the boxes whose pools match the record's placement, the ones that could serve or wake the host. It also refuses when the record's placement matches the pools of any box that runs claims-on. Boxes in the region that cannot hold the host are not consulted. This point may be confirmed or tightened later. |
| + 4. **An armed or enforced guard is NOT a refusal.** The capability depends only on hibernation being configured and `CARLOS_HOST_CLAIM` and `CARLOS_MOVES_PHASE1` being unset. The guard mode is not read for the capability. The target's build stages through ordinary adoption, so root's existing floor check applies on a guarded target box, and the move adds no other stage, adopt or restart path. |
| + |
| - **Switches stay off, and claims are refused from evidence.** Every offline door refuses with MV-O20 when the console runs with `HostClaim` or `MovesEnabled`. A box publishes the `offline-move-1` capability, and runs any offline step, only when hibernation is configured, `CARLOS_HOST_CLAIM` and `CARLOS_MOVES_PHASE1` are unset, and the guard policy (`/opt/carlos/system/guard/policy.json`, `internal/hostfloor/floor.go:33`, `:141`) is absent or its `Mode` is neither `armed` nor `enforced`; otherwise it logs one notice per host and does nothing. The start door refuses (MV-O21) when any box in the source or target region lacks the capability, refuses MV-O29 when `control/hosts/<host>.json` exists, and refuses MV-O20 when `control/hosts-backfill.json` (`hostops.BackfillKey`) exists or the console is on the claim path at all (`HostClaim`, which includes the `claimMoveUnsupportedMsg` case, `apiinstancemove.go:575-578`). Nothing here reads `CONSOLE_APP_REGIONS`, `CARLOS_SWAP` or `CARLOS_REGION_HA`, and nothing takes the operator's word for any of it. |
| - **No activator change, no root change.** The target is never started before `open`. Root's stage pass is used only as it already is for any ready row. |
| - **The hold is a function of the record.** `Hold(rec)` reads only `rec` and the box's placement (through `park.PlacementMatches`, as `movesNamesBox` does at `movespass.go:169-185`). The view's snapshot is for `KeepParticipant` only, refreshed at agent startup before the reconcile loops, fail-closed only when that listing failed. |