docs: README's users-apply section matches the new gate (#60 review)

#58 inverted the section's central claim — the host= trait now decides in
both directions and the incus group never overrides it — but README still
read "when the `incus` group is absent, the `host=` trait decides". That
qualifier is precisely the bypass the change removes, so the operator
reference asserted the bug as the contract.

It also omitted the behavior an operator most needs to know before running
apply on a repurposed box: on a host=no box carrying a stray incus group,
apply warns about the marker/reality mismatch and STRIPS box-role users out
of the group. Discovering that from a diff of your own fleet is the wrong
way to learn it.

Rewritten so the trait gates the role, the group only distinguishes
ready-vs-die once the trait already said yes, and the mismatch names both
its hazard and `rig bootstrap --host yes` as the repair. Pinned in both
directions — current sentences present, superseded one absent — following
the same grep-the-prose-stays-honest discipline the file already uses.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
dan-claude-bot 2026-07-19 17:50:24 +00:00
parent b8e8e79b87
commit 49471bde4f
2 changed files with 35 additions and 8 deletions

View file

@ -761,14 +761,27 @@ silently root-equivalent through the very tool it scopes. Direct root — a
bring-up shell, before any admin exists — proceeds. bring-up shell, before any admin exists — proceeds.
`box` binds where VMs live, and a users file is fleet-wide — its box grants `box` binds where VMs live, and a users file is fleet-wide — its box grants
are not. rig never installs Incus — box's `setup-host` owns the daemon — so are not. **The `host=` trait decides whether the box role applies here, and
when the `incus` group is absent, the `host=` trait decides: on `host=yes` the `incus` group never overrides it.** On `host=no` — or a marker that names
apply dies pointing at `box setup-host` (a VM host missing Incus is a real no `host=` at all, or no marker — the role is **skipped with a warning** and
problem) rather than conjure a group the (nonexistent) daemon would never everything else, admins included, still converges: one box-role user
consult; on `host=no` the box role is **skipped with a warning** and somewhere in the fleet must not stop apply everywhere VMs don't live. The
everything else — admins included — still converges, because one box-role verdict is the same whether or not the group happens to exist.
user somewhere in the fleet must not stop apply everywhere VMs don't live.
`incus-admin` is deliberately **not** a role: that group is That last part is the point. rig never installs Incus — box's `setup-host`
owns the daemon — so a `host=no` box can still carry a leftover `incus`
group from a previous life. Adding someone to it there would hand out the
socket with no tier behind it, and incus-user would lazily build them an
**unhardened** project on first contact: `incusbr-<uid>`, NAT on v4 *and*
v6, no ACL, no `dns.mode=none`, no port isolation. So on that mismatch apply
warns — naming the contradiction and `rig bootstrap --host yes` as the
repair — and **strips** box-role users out of `incus`, because an inherited
half-grant is the same defect as a fresh one.
The group's presence matters only once the trait already said yes: on
`host=yes` an absent `incus` group means the daemon was never set up, so
apply dies pointing at `box setup-host` rather than conjure a group nothing
would consult. `incus-admin` is deliberately **not** a role: that group is
host-root-equivalent, break-glass by hand only. host-root-equivalent, break-glass by hand only.
**All passwords stay locked, always** — created or found. The SSH key at the **All passwords stay locked, always** — created or found. The SSH key at the

View file

@ -177,6 +177,20 @@ check "README: no stale heavy-duty/claudebox links" 1 "" \
grep -n "heavy-duty/claudebox" "$ROOT/README.md" grep -n "heavy-duty/claudebox" "$ROOT/README.md"
check "README: points at heavy-duty/box" 0 "" \ check "README: points at heavy-duty/box" 0 "" \
grep -q "github.com/heavy-duty/box" "$ROOT/README.md" grep -q "github.com/heavy-duty/box" "$ROOT/README.md"
# The users-apply section is the operator's reference for what the box role
# does, and #58 inverted its central claim: the trait decides in BOTH
# directions now, and the group's presence never overrides it. A reference
# that still says "when the incus group is absent, the host= trait decides"
# asserts the very bypass that was the bug. Pinned in both directions — the
# current sentence present, the superseded one gone — so the prose cannot
# drift back to describing a semantics the code no longer has.
check "README: the trait gates the box role regardless of the group" 0 "" \
grep -q "the \`incus\` group never overrides it" "$ROOT/README.md"
check "README: documents the mismatch strip on host=no" 0 "" \
grep -q "half-grant is the same defect as a fresh one" "$ROOT/README.md"
check "README: no stale 'group absent decides' semantics" 1 "" \
grep -n "when the \`incus\` group is absent, the \`host=\` trait decides" "$ROOT/README.md"
if [ "$(id -u)" -ne 0 ]; then if [ "$(id -u)" -ne 0 ]; then
check "bootstrap: refuses non-root" 1 "must run as root" env TS_AUTHKEY=x "$ROOT/commands/bootstrap.sh" workload check "bootstrap: refuses non-root" 1 "must run as root" env TS_AUTHKEY=x "$ROOT/commands/bootstrap.sh" workload
check "bootstrap: runner role parses, refuses non-root" 1 "must run as root" env TS_AUTHKEY=x "$ROOT/commands/bootstrap.sh" runner check "bootstrap: runner role parses, refuses non-root" 1 "must run as root" env TS_AUTHKEY=x "$ROOT/commands/bootstrap.sh" runner