`rig bootstrap` already knew everything else about what a box is — class,
host, join, hostname — and wrote /etc/rig/role to say so. The users file was
the last piece of that answer it did not take, so bring-up was two commands
and the second one was the forgettable one.
--users <path> now runs the `users apply` convergence as bootstrap's final
phase: after the traits, after the verified tailnet join, after the role
marker (apply reads that marker), and after the host=yes box install (so
box-role users find the incus group box's own setup-host built). One
command, and the box has its people on it.
BREAKING: --users is required on every machine role, with --no-users as the
explicit opt-out. Omitting both is a usage error naming both flags; passing
both is a usage error too. class=server is required as well: a machine
nobody logs into routinely is exactly where shared-root access rots, and
per-human accounts keep attribution intact for the times someone does go in.
The file is never persisted — passed per invocation, read once through
apply, copied nowhere. `--users -` is refused: bootstrap's stdin belongs to
the pre-auth key prompt. The box TENANT roles take neither flag; a guest is
minted non-interactively, never joins the tailnet, and has no SSH door of
its own.
rig still never installs Incus and never calls `box setup-host` itself. The
host=yes box-role precondition refuses early only where the outcome is
already proven (RIG_SKIP_BOX_INSTALL=1); every other way that step can fail
lands in `users apply`'s existing refusal, unchanged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>