carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

Census proposal: install-console --upgrade

Status: 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.

What changed

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.

  • 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.
  • runInstallConsole (changed, no read site): the identity, published-identity, build and platform checks are unchanged. A non-empty from calls upgradeProtectedConsole instead of installProtectedConsole.
  • 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).
  • 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: - 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. - console holding the target: Already, nothing changes. - console holding --from: upgrade. - console absent and console.prev holding --from: a run cut off between its two renames; this run completes it. - Anything else refuses and changes nothing.

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.

  • writeConsoleTemp (new): the exclusive no-follow create of console.next, chmod 0755, root:root and one link on the descriptor, fsync.

Root-read census (TestPlan14RootReadCensus)

Overlay 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.

| Unit | Executing identity | Class / tasks | Basis | |---|---|---|---| | activation_command_linux.go:runSystemClaims (changed) | operator CLI, uid 0 | authority G,J4 (fix1's) | the two flags, admitted only together for install-console | | activation_artifacts_linux.go:consoleSlotHolds (@remove) | | | its read moved into consoleSlotSHA | | 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 | | activation_artifacts_linux.go:upgradeProtectedConsole (new) | box installer, uid 0 (claims install-console --upgrade) | authority G,J4 (caller's) | as above | | 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 |

The internal/host source envelope is re-pinned. No other envelope moves.

No box agent, update, recovery or edge path reaches a new or changed unit. guard-exec, hostfloor.CheckComponent and installProtectedConsole are unchanged.

Record-write census (TestPlan9B8RecordWriteCensus)

Unchanged and passing. The upgrade writes local files only and adds no bucket writer.

Round 2 (Astra's review of da0a33b7, MERGE: block)

Same overlay and marker (rev3=PROPOSED-install-console-upgrade). platform-d8 accepted da0a33b7; this delta needs a new ruling.

  • 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).
  • 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.
  • 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.

Rows: 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.