rig/commands/manifest.sh
dan-claude-bot 5c40e906a1 feat: /etc/rig/manifest — which rig converged this machine, and when
A rig-managed machine recorded nothing about its own provenance. The entire
durable output of a bootstrap run was one line in /etc/rig/role, and that line
says what the box IS, never what built it. VERSION was read in exactly one
place (bin/rig:9, for --version) and reports the currently INSTALLED tree, not
the one that ran; there was no timestamp anywhere in the codebase.

bootstrap now stamps a second file beside the marker: schema=1, a birth pair
(bootstrapped_by/_at, pinned forever) and a latest pair (converged_by/_at).
key=value, one per line, 0644 — the one file that must stay readable on the
most broken machine in the fleet, where there is no YAML parser and no jq.
`rig manifest [<key>]` reads it back.

Only DECIDED facts go in, which is what keeps bootstrap.sh:3's convergence
contract intact: bootstrapped_* is first-write-wins, and converged_* updates
only when the version actually differs — it is the time the converging version
last changed, not the time of the last run. The renderer is pure, so a re-run
by the same rig is byte-identical no matter where the clock is, and the
cmp-guard stays silent. OBSERVED facts (cores, RAM, disk, kernel) stay out:
they go stale on their own and belong to `rig platform` (#64).

/etc/rig/role is untouched.

Closes #61

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 12:48:39 +00:00

88 lines
3.1 KiB
Bash
Executable file

#!/usr/bin/env bash
# rig manifest — print this machine's provenance record, /etc/rig/manifest
# (#61). Reads only: this command NEVER writes the file. `rig bootstrap` is its
# single writer, and it stamps it as its own last durable act.
set -euo pipefail
HERE="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)"
# shellcheck source=SCRIPTDIR/lib/manifest.sh
. "$HERE/lib/manifest.sh" # manifest_path / manifest_value
die() { printf 'rig-manifest: ERROR: %s\n' "$1" >&2; exit "${2:-1}"; }
usage() {
cat <<'EOF'
usage: rig manifest [<key>]
Print /etc/rig/manifest — which rig converged this machine, and when. With a
key, print that key's value alone, unquoted and newline-terminated, so a shell
caller does not re-parse the file:
rig manifest schema=1
bootstrapped_by=0.2.0
bootstrapped_at=2026-07-19T14:24:51Z
converged_by=0.4.0
converged_at=2026-08-02T09:11:03Z
rig manifest converged_by 0.4.0
Both pairs are provenance, both immutable in the sense that matters: BIRTH —
the rig that first converged this machine, pinned forever — and LATEST — the
newest rig to have converged it. On a fresh machine the two are equal. Ask the
second pair "is this machine converged by something ancient?"; ask the first
"what built it".
The version recorded is the one that RAN. `rig --version` reports the tree
installed NOW, which after an upgrade is a different question — a machine
outlives the rig that built it.
Reads only. Needs no root (the file is 0644), no network, and works on a
machine whose rig has since been upgraded or removed. Specs — cores, RAM,
disk, kernel — are NOT here: they are observed rather than decided, so they go
stale on their own and belong to `rig platform`, which computes them fresh and
stores nothing.
Exit 1 when there is no manifest — a machine converged before rig wrote one,
or never converged at all.
RIG_MANIFEST override the path (default /etc/rig/manifest)
EOF
}
KEY=""
for a in "$@"; do
case "$a" in
-h|--help) usage; exit 0 ;;
-*)
printf 'rig-manifest: unknown option: %s\n' "$a" >&2
usage >&2
exit 2
;;
*)
if [ -n "$KEY" ]; then
printf 'rig-manifest: manifest takes at most one key\n' >&2
usage >&2
exit 2
fi
KEY="$a"
;;
esac
done
MPATH="$(manifest_path)"
[ -r "$MPATH" ] || die "no manifest at $MPATH — this machine has not been converged by a rig that writes one (rig bootstrap writes it)"
if [ -z "$KEY" ]; then
cat "$MPATH"
exit 0
fi
# A key that is absent and a key whose value is empty are different answers to
# a shell caller, and $(...) collapses both to "". So the ABSENCE is the exit
# code, and only a present key ever prints — a caller reading `rig manifest
# converged_by` into a variable can trust that an empty result it accepted was
# a real empty value, not a missing key.
manifest_has "$MPATH" "$KEY" \
|| die "no such key: $KEY (keys present: $(cut -d= -f1 "$MPATH" | tr '\n' ' '))"
manifest_value "$MPATH" "$KEY"
echo