| 1 | # Census proposal: claim-prev-rehearsal |
| 2 | |
| 3 | Status: RULED. platform-1e accepted every row as proposed on 2026-10-18 (census-ruling-claim-prev-rehearsal). Overlay `internal/provision/testdata/plan14-root-reads-claim-prev-rehearsal.tsv`, loaded last (after `claim-step6-artifacts-fix2`), every row `rev3=census-ruling-claim-prev-rehearsal`. |
| 4 | |
| 5 | ## What changed |
| 6 | |
| 7 | `carlos system install-channel` takes `--policy FILE` (controller ruling R1, with platform-00's binding additions). FILE is exactly what `carlos system claims run` sign-policy writes. With it: |
| 8 | |
| 9 | - the policy's floor, verified as guard-arm verifies it (the root-signed moves-protocol authorization, for this deployment's bucket, under `CARLOS_RELEASE_PUBKEY`), stands in for the published floor while none is published; |
| 10 | - a published floor, or either half of one, must be the policy's bytes, or the run is refused; |
| 11 | - one updated box is admitted: `applied.json` names the channel release, `carlos` hashes to its signed artifact, and the guard is not armed. Its `carlos.prev` is refreshed from `carlos` by the updater's own `notePrev`, and the identity is kept beside the slots. |
| 12 | |
| 13 | Without `--policy` nothing changes (ruling 6). |
| 14 | |
| 15 | ## Units |
| 16 | |
| 17 | | Unit | Change | Class | Executing identity | |
| 18 | |---|---|---|---| |
| 19 | | `internal/host/installchannel.go` `readChannelPolicy` | new; read site `file:ReadFile` | authority F,J4 | uid 0 at the box's attended root shell, running `carlos system install-channel --policy`. Reads the operator-staged policy file once, before the apply lock or any store read. | |
| 20 | | `internal/host/installchannel.go` `channelInstall.refreshPrev` | new; read site `file:Lstat` | authority F,J4 | the same uid 0 root shell, under root's apply lock. Lstats `carlos.prev` to refuse a symlink or a non-regular file. | |
| 21 | | `internal/host/installchannel.go` `channelInstall.run` | unchanged digest | F,J4 (region-ha-2b) | unchanged | |
| 22 | | `internal/host/installchannel_linux.go` `slotState`, `var openat2`, `removeBeneath` | unchanged digests | F,J4 (region-ha-2b) | unchanged; 2b's rows stand and are not restated | |
| 23 | | `channelInstall.install`, `channelInstall.checkFloor`, `policyFloorPublished`, `channelPolicy`, `RunSystemInstallChannel` | changed or new, no read site of their own | envelope | the same root shell | |
| 24 | |
| 25 | The `internal/host` envelope is re-pinned. The seal stands: no accepted-legacy row. No box agent, update, recovery or edge path reaches either new unit. |
| 26 | |
| 27 | ## 9B8 |
| 28 | |
| 29 | No new bucket writer. install-channel writes only local files (`carlos.prev`, its version sidecar through `notePrev`, and `channel-identity.json`). No 9B8 entry is proposed. |
| 30 | |
| 31 | ## Test files |
| 32 | |
| 33 | The rewritten root-runner witness (`activation_console_rootrunner_linux_test.go`) and the new `installchannel_policy_test.go` are tests and are outside the census. |
| 34 | |
| 35 | ## Fix round 1 (RULED) |
| 36 | |
| 37 | Status: RULED. platform-1e accepted every row as proposed on 2026-10-18 (census-ruling-claim-prev-rehearsal-fix1). Overlay `internal/provision/testdata/plan14-root-reads-claim-prev-rehearsal-fix1.tsv`, loaded after the ruled overlay, every row `rev3=census-ruling-claim-prev-rehearsal-fix1`. Everything is in the `--policy` path; without `--policy` nothing changes. |
| 38 | |
| 39 | What changed: |
| 40 | |
| 41 | - carlos.prev's version record is mandatory in the `--policy` path (Astra). `completePrev` runs under the prev lock: it removes the old verdicts and record, copies carlos when refreshing, then writes the record and reads it back. Every failure is fatal, then the floor's judgement follows through `notePrev` without a replace. The `--policy` "already installed" answer requires the record, and completes it when it is missing or stale. |
| 42 | - An open update journal, or an update-begun marker beside the guard, refuses through `guardArmIdle` (I1). |
| 43 | - The `--policy` applier reads the root participation census (`rootMovesFloorIdentity`), as the update's does, so a census box takes the root moves floor branch (I2). |
| 44 | - The policy file is opened with O_NOFOLLOW and O_NONBLOCK, checked with fstat to be a regular file, and capped at 64 KiB (M3). |
| 45 | |
| 46 | | Unit | Change | Class | Executing identity | |
| 47 | |---|---|---|---| |
| 48 | | `internal/host/installchannel.go` `channelInstall.run` | digest unchanged; basis corrected (M5): it now also runs with `--policy` at an updated box's root shell | F,J4, kept exactly | unchanged | |
| 49 | | `internal/host/installchannel.go` `channelInstall.refreshPrev` | re-pinned; basis now says it reaches `notePrev`, and through it `judgePrevWith`/`judgeSeedsPrev` (or the root moves floor judge on a census box), which can open the registry as root when a legacy local floor exists | F,J4 | uid 0 at the box's attended root shell | |
| 50 | | `internal/host/installchannel_linux.go` `openChannelPolicy` | new; read sites `file:Open`, `file:Stat`, `file:ReadAll` | F,J4 | uid 0 at the box's attended root shell | |
| 51 | | `internal/host/installchannel.go` `readChannelPolicy` | `@remove`: its read moved into `openChannelPolicy` | | | |
| 52 | | `completePrev`, `prevRecorded`, `newChannelInstall`, `install` | no read site of their own | envelope | the same root shell | |
| 53 | |
| 54 | The internal/host envelope is re-pinned. The seal stands. No 9B8 entry: no new bucket writer. (On a census box, verifyPointer remembers the channel identity in root's guarded identities, as the update already does; that is a local root-state write, not a bucket write.) |
| 55 | |
| 56 | ## Fix round 2 (RULED) |
| 57 | |
| 58 | Status: RULED. platform-1e accepted it as proposed on 2026-10-18 (census-ruling-claim-prev-rehearsal-fix2). |
| 59 | |
| 60 | Overlay `internal/provision/testdata/plan14-root-reads-claim-prev-rehearsal-fix2.tsv`, loaded after fix1. Envelope only: the internal/host envelope is re-pinned, and no root-read unit's digest or read sites change. |
| 61 | |
| 62 | What changed, all in the `--policy` path: |
| 63 | |
| 64 | - "Already installed" always runs carlos.prev's judgement again: `channelPrevJudge`, which is `notePrev` without a replace. It fails on the judgement's error, so a judgement that was cut off or failed is finished or reported, never answered over. `completePrev` ends with the same judgement, after the version record. |
| 65 | - The unfinished-update refusal's reason drops guard-arm's floor prefix. |
| 66 | - `installChannelUsage` is now one literal, of the same value, so the re-approved RHB-C19 can be pinned whole. |
| 67 | |
| 68 | The seal stands. No 9B8 entry. |
| 69 | |