From 91a8905a7145dc2fbe17b35d8598bba60e12e694 Mon Sep 17 00:00:00 2001 From: dan-claude-bot Date: Mon, 20 Jul 2026 00:22:01 +0000 Subject: [PATCH] fix: platform reads #61's actual manifest schema, not invented keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The reader asked for `version` and `bootstrapped`. #61 specifies `schema`, `bootstrapped_by`/`bootstrapped_at` and `converged_by`/`converged_at` — so no writer would ever have produced the keys being read, and the day #61 landed this command would have rendered 'unknown' with the timestamp omitted, forever, with nothing to say why. Keyed to #61's spelling, with fixtures carrying that schema verbatim so the contract is pinned rather than assumed. Birth and latest are reported separately and neither is inferred from the other: under #61 rule 2 converged_* is written only when the version differs, so its absence is a legitimate state on a freshly bootstrapped box, printed 'not recorded' rather than backfilled from birth. A manifest whose schema this rig does not know is named as such instead of being half-read in silence. Found in review of #74. Refs #64 --- CHANGELOG.md | 7 +++++-- README.md | 22 ++++++++++++++++------ commands/platform.sh | 25 ++++++++++++++++++++++--- test/cli.sh | 32 +++++++++++++++++++++++++++----- 4 files changed, 70 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6923726..a7a2106 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,8 +29,11 @@ on the way to cutting its first release, and this file starts there. the harness can RUN for real instead of grepping: the tests assert the actual answer describes the actual test machine. Provenance is read, never written, and degrades per-file — `/etc/rig/manifest` is #61 and does not - exist yet, so that line reads `not bootstrapped` on every machine today and - nothing else depends on it. Named `platform` and not `status` on purpose: + exist yet, so those lines read `not bootstrapped` on every machine today and + nothing else depends on it. The reader is keyed to #61's documented schema + (`schema`, `bootstrapped_by`/`_at`, `converged_by`/`_at`) and fixtures pin + that exact spelling, so the integration cannot land silently broken; birth + and latest stay separate rather than one being inferred from the other. Named `platform` and not `status` on purpose: `users status` and `runner status` cross-check recorded against live state and print `DRIFT`, and a command that records nothing cannot drift — which also leaves `rig status` free for the machine-wide roll-up. Known diff --git a/README.md b/README.md index 9743bda..0910a55 100644 --- a/README.md +++ b/README.md @@ -738,7 +738,8 @@ DISK 456Gi total, 201Gi free on / VIRT kvm PROVENANCE -RIG 0.4.0, bootstrapped 2026-07-19T14:24:51Z +CONVERGED 0.6.0, 2026-08-02T09:11:03Z +BOOTSTRAP 0.4.0, 2026-07-19T14:24:51Z ROLE dev (class=human host=yes join=authkey) ``` @@ -763,11 +764,20 @@ needs no root, makes no network call, and writes nothing, ever. The `PROVENANCE` block is the complementary half — which rig, and when, which is *decided* rather than observed, so it is stored. It is **read, never -written**: `RIG` comes from `/etc/rig/manifest` and `ROLE` from -`/etc/rig/role`. Neither file is required — a machine missing one reads `not -bootstrapped` for that line, which is itself the useful answer. The manifest -is #61 and is not implemented yet, so today that line reads `not bootstrapped` -on every machine; nothing else in the command depends on it. +written**: `CONVERGED`/`BOOTSTRAP` come from `/etc/rig/manifest` and `ROLE` +from `/etc/rig/role`. Neither file is required — a machine missing one reads +`not bootstrapped` for that line, which is itself the useful answer. The +manifest is #61 and is not implemented yet, so today those lines read `not +bootstrapped` on every machine; nothing else in the command depends on it. + +**The two dates are deliberately separate**, matching #61's schema: `BOOTSTRAP` +is birth (`bootstrapped_by`/`bootstrapped_at`, first-write-wins, pinned +forever) and `CONVERGED` is latest (`converged_by`/`converged_at`, updated only +when the converging version actually differs). That distinction is what answers +"is this machine still converged by a rig that predates the fix?" — so +`CONVERGED` reads `not recorded` rather than being backfilled from birth on a +box that has only ever been bootstrapped once. A manifest whose `schema=` this +rig does not know is named as such instead of being half-read in silence. **Known limitation — `CPU` and `MEMORY` inside a container-style guest are unverified.** `CPU` and `MEMORY` are read straight from `/proc/cpuinfo` and diff --git a/commands/platform.sh b/commands/platform.sh index 2bdb999..65c446d 100755 --- a/commands/platform.sh +++ b/commands/platform.sh @@ -155,10 +155,29 @@ manifest_field() { # $1 = key — empty when absent, unreadable or unset } printf '%s\n' "PROVENANCE" +# Keys are #61's documented schema verbatim — schema/bootstrapped_by/ +# bootstrapped_at/converged_by/converged_at — NOT invented ones. #61 keeps +# birth and latest deliberately separate ("is this machine converged by a rig +# that predates the fix?"), so both are reported and neither is inferred from +# the other: CONVERGED answers currency, BOOTSTRAPPED answers provenance. +# Every field degrades independently, so a partial manifest from a future +# schema still renders what it does carry. if [ -r "$MANIFEST" ]; then - RIG_VER="$(manifest_field version)" - RIG_WHEN="$(manifest_field bootstrapped)" - field RIG "${RIG_VER:-unknown}${RIG_WHEN:+, bootstrapped $RIG_WHEN}" + M_SCHEMA="$(manifest_field schema)" + B_BY="$(manifest_field bootstrapped_by)"; B_AT="$(manifest_field bootstrapped_at)" + C_BY="$(manifest_field converged_by)"; C_AT="$(manifest_field converged_at)" + # A manifest with no schema= line is pre-#61; say so rather than render blanks. + if [ -z "$M_SCHEMA$B_BY$B_AT$C_BY$C_AT" ]; then + field RIG "manifest present but carries no recognised fields ($MANIFEST)" + else + # 'not recorded' rather than 'unknown': under #61's rule 2 converged_* is + # written only when the version actually differs, so its absence is a + # legitimate state on a freshly bootstrapped box, not a lost value. + field CONVERGED "${C_BY:-not recorded}${C_AT:+, $C_AT}" + field BOOTSTRAP "${B_BY:-not recorded}${B_AT:+, $B_AT}" + [ -n "$M_SCHEMA" ] && [ "$M_SCHEMA" != "1" ] && \ + field NOTE "manifest schema=$M_SCHEMA is newer than this rig reads (expects 1)" + fi else field RIG "not bootstrapped (no $MANIFEST)" fi diff --git a/test/cli.sh b/test/cli.sh index 8e93a88..f9941a5 100644 --- a/test/cli.sh +++ b/test/cli.sh @@ -1006,23 +1006,45 @@ check "platform: MEMORY carries real numbers" 0 "total," "$ROOT/bin/rig" platfor # not exist yet, so 'not bootstrapped' is the state of the world today and the # command must ship complete without it. Both paths driven against fixtures. PLATWORK="$(mktemp -d)" -printf 'version=9.9.9\nbootstrapped=2026-07-19T14:24:51Z\n' > "$PLATWORK/manifest" +# THE INTEGRATION CONTRACT (#61, found in #74 review): these fixtures carry +# #61's documented schema VERBATIM — schema/bootstrapped_by/bootstrapped_at/ +# converged_by/converged_at. An earlier draft of this reader invented `version` +# and `bootstrapped`, which no writer would ever have produced: the command +# would have rendered 'unknown' forever the day #61 landed, and nothing here +# would have said so. Keep these keys in step with #61; that is the point. +printf 'schema=1\nbootstrapped_by=0.4.0\nbootstrapped_at=2026-07-19T14:24:51Z\nconverged_by=0.6.0\nconverged_at=2026-08-02T09:11:03Z\n' > "$PLATWORK/manifest" check "platform: no manifest reads 'not bootstrapped'" 0 "RIG not bootstrapped" \ env RIG_MANIFEST="$PLATWORK/absent" RIG_ROLE_MARKER="$PLATWORK/absent" "$ROOT/bin/rig" platform check "platform: no role marker reads 'not bootstrapped'" 0 "ROLE not bootstrapped" \ env RIG_MANIFEST="$PLATWORK/absent" RIG_ROLE_MARKER="$PLATWORK/absent" "$ROOT/bin/rig" platform # A manifest that DOES exist is read, never written — the forward-compatible # half, so #61 landing needs no change here. -check "platform: reads the manifest version" 0 "9.9.9" \ +check "platform: reads #61's converged_by/at" 0 "CONVERGED 0.6.0, 2026-08-02T09:11:03Z" \ env RIG_MANIFEST="$PLATWORK/manifest" RIG_ROLE_MARKER="$PLATWORK/absent" "$ROOT/bin/rig" platform -check "platform: reads the manifest timestamp" 0 "bootstrapped 2026-07-19T14:24:51Z" \ +check "platform: reads #61's bootstrapped_by/at" 0 "BOOTSTRAP 0.4.0, 2026-07-19T14:24:51Z" \ env RIG_MANIFEST="$PLATWORK/manifest" RIG_ROLE_MARKER="$PLATWORK/absent" "$ROOT/bin/rig" platform +# Birth and latest stay SEPARATE: #61 rule 2 writes converged_* only when the +# version actually differs, so its absence on a freshly bootstrapped box is a +# legitimate state — it must not be silently backfilled from bootstrapped_*. +printf 'schema=1\nbootstrapped_by=0.4.0\nbootstrapped_at=2026-07-19T14:24:51Z\n' > "$PLATWORK/manifest-birth" +check "platform: unconverged box says so, never infers from birth" 0 "CONVERGED not recorded" \ + env RIG_MANIFEST="$PLATWORK/manifest-birth" RIG_ROLE_MARKER="$PLATWORK/absent" "$ROOT/bin/rig" platform +# A newer schema renders what it recognises and says the rest is unreadable, +# rather than pretending a partial read is the whole truth. +printf 'schema=2\nbootstrapped_by=9.9.9\nbootstrapped_at=2027-01-01T00:00:00Z\n' > "$PLATWORK/manifest-v2" +check "platform: a newer schema is named, not silently half-read" 0 "schema=2 is newer" \ + env RIG_MANIFEST="$PLATWORK/manifest-v2" RIG_ROLE_MARKER="$PLATWORK/absent" "$ROOT/bin/rig" platform +# A manifest carrying none of #61's keys is reported as such — the pre-#61 or +# corrupt case, distinct from both 'absent' and 'read fine'. +printf 'somethingelse=1\n' > "$PLATWORK/manifest-alien" +check "platform: an unrecognised manifest is not read as empty" 0 "no recognised fields" \ + env RIG_MANIFEST="$PLATWORK/manifest-alien" RIG_ROLE_MARKER="$PLATWORK/absent" "$ROOT/bin/rig" platform # ...including one whose last line has no trailing newline: `read` returns 1 at # EOF even having filled the variables, so an unguarded loop drops that line # silently — the timestamp would vanish while the version still rendered. #61's # writer must not have to know this reader's tolerances (found in #74 review). -printf 'version=9.9.9\nbootstrapped=2026-07-19T14:24:51Z' > "$PLATWORK/manifest-nonl" -check "platform: reads a manifest with no trailing newline" 0 "bootstrapped 2026-07-19T14:24:51Z" \ +printf 'schema=1\nbootstrapped_by=0.4.0\nbootstrapped_at=2026-07-19T14:24:51Z' > "$PLATWORK/manifest-nonl" +check "platform: reads a manifest with no trailing newline" 0 "BOOTSTRAP 0.4.0, 2026-07-19T14:24:51Z" \ env RIG_MANIFEST="$PLATWORK/manifest-nonl" RIG_ROLE_MARKER="$PLATWORK/absent" "$ROOT/bin/rig" platform printf 'role=dev class=human host=yes join=authkey\n' > "$PLATWORK/role" check "platform: renders the role marker's traits" 0 "dev (class=human host=yes join=authkey)" \