carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1# Census proposal: install-console --upgrade
2
3Status: RULED (platform-d8, 2026-10-20): census-ruling-install-console-upgrade, accepted as proposed (U1 to U4 at da0a33b7; U5 to U7 for the delta to b913bb65). Astra approved b913bb65. Branch `install-console-upgrade`, cut from main at 54ae7fb9.
4
5## What changed
6
7`claims install-console` was a first install only: an occupied slot holding another build refused, so a guard-armed box's protected console could never be replaced. platform-d8's harness found this rolling dev's console to v0.28.5. This branch adds `--upgrade --from <sha256>`. Without `--upgrade`, install-console and its output are unchanged.
8
9- **`runSystemClaims`** (changed): two new flags, `--upgrade` and `--from`. `upgradeFlagsRefused` (new, no read site) admits them only together and only for install-console. Anywhere else they refuse with errActivation, as unknown flags did before. The upgrade output adds `upgraded`, `from` and `previous_sha`.
10- **`runInstallConsole`** (changed, no read site): the identity, published-identity, build and platform checks are unchanged. A non-empty `from` calls `upgradeProtectedConsole` instead of `installProtectedConsole`.
11- **`consoleSlotSHA`** (new): `consoleSlotHolds`'s read moved here. The shape check is the same and is now applied to the opened descriptor as well (same device and inode). It returns the slot's sha256, or "" when absent. `consoleSlotHolds` keeps its behaviour and now has no read site (`@remove`).
12- **`upgradeProtectedConsole`** (new): the source is verified against the identity's console sha256 before anything is opened. The directory is checked as `consoleDir` does but never created. Under the directory's exclusive flock:
13 - `console` and `console.prev` must each be absent or a root:root 0755 regular file with one link. `console.prev`'s bytes are not checked.
14 - `console` holding the target: Already, nothing changes.
15 - `console` holding `--from`: upgrade.
16 - `console` absent and `console.prev` holding `--from`: a run cut off between its two renames; this run completes it.
17 - Anything else refuses and changes nothing.
18
19 The upgrade writes `console.next` (exclusive, 0755, fsync), renames `console` to `console.prev`, renames `console.next` to `console`, fsyncs the directory, and reads both slots back through `hostfloor.OpenProtected`. A leftover `console.next` that is a regular file is removed first; anything else at that name refuses.
20- **`writeConsoleTemp`** (new): the exclusive no-follow create of `console.next`, chmod 0755, root:root and one link on the descriptor, fsync.
21
22## Root-read census (TestPlan14RootReadCensus)
23
24Overlay `internal/provision/testdata/plan14-root-reads-install-console-upgrade.tsv`, loaded last, after `plan14-root-reads-armed-box-updates.tsv`. No accepted-legacy row, so the seal stands.
25
26| Unit | Executing identity | Class / tasks | Basis |
27|---|---|---|---|
28| `activation_command_linux.go:runSystemClaims` (changed) | operator CLI, uid 0 | authority G,J4 (fix1's) | the two flags, admitted only together for install-console |
29| `activation_artifacts_linux.go:consoleSlotHolds` (`@remove`) | | | its read moved into consoleSlotSHA |
30| `activation_artifacts_linux.go:consoleSlotSHA` (new) | box installer, uid 0 | authority G,J4 (consoleSlotHolds's) | absent, or root:root 0755 one-link regular file, checked on the entry and the descriptor, hashed bounded |
31| `activation_artifacts_linux.go:upgradeProtectedConsole` (new) | box installer, uid 0 (`claims install-console --upgrade`) | authority G,J4 (caller's) | as above |
32| `activation_artifacts_linux.go:writeConsoleTemp` (new) | box installer, uid 0 | authority G,J4 (caller's) | exclusive create of one fixed name in the locked directory |
33
34The `internal/host` source envelope is re-pinned. No other envelope moves.
35
36No box agent, update, recovery or edge path reaches a new or changed unit. guard-exec, `hostfloor.CheckComponent` and `installProtectedConsole` are unchanged.
37
38## Record-write census (TestPlan9B8RecordWriteCensus)
39
40Unchanged and passing. The upgrade writes local files only and adds no bucket writer.
41
42## Round 2 (Astra's review of da0a33b7, MERGE: block)
43
44Same overlay and marker (`rev3=PROPOSED-install-console-upgrade`). platform-d8 accepted da0a33b7; this delta needs a new ruling.
45
46- **F1, source aliasing (MEDIUM).** An upgrade refuses a `--source` inside the console directory by path, before reading anything. Under the lock, it also refuses a source whose opened descriptor has the device and inode of `console`, `console.prev` or `console.next`, which catches a bind mount or any other path to the same file. To return that descriptor's stat, `readConsoleSource`'s read moved unchanged into `readConsoleSourceFile` (new). `readConsoleSource` wraps it for the first install and now has no read site (`@remove`).
47- **F2, Already skipped the directory fsync (MEDIUM).** A non-dry Already now fsyncs the held directory and returns any failure. A run cut off after its second rename, before its fsync, is therefore made durable by the rerun. The fsync goes through `consoleUpgradeSync`, a package variable with no read site that tests replace.
48- **F3, prefix digest (LOW).** `consoleDigest` (new) hashes a held slot through EOF. It refuses a slot over 512 MiB by fstat size and by the bytes read (`consoleCounter.Read`, new), and never hashes a prefix. `consoleSlotSHA` and the upgrade's readback use it. The first install's slot checks go through `consoleSlotSHA`, so they get the same refusal. The first install's own readback is unchanged.
49
50Rows: `consoleSlotSHA` and `upgradeProtectedConsole` are re-pinned. `readConsoleSourceFile`, `consoleDigest` and `consoleCounter.Read` are new. `readConsoleSource` gets `@remove`. All are authority G,J4, the class of the rows they come from or their caller's. The `internal/host` envelope is re-pinned. There is no legacy row, so the seal stands, and 9B8 is unchanged.
51