feat(bootstrap): staging role — host archetype for box-minted staging VMs #23
No reviewers
Labels
No labels
attention
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-ruling
needs-triage
offsite
post-merge
ready
release
scope:bootstrap
scope:coolify
scope:db
scope:docs
scope:drill
scope:installer
scope:labels
scope:platform
scope:runner
scope:users
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/rig#23
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/staging-role"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
stagingbootstrap role — the host archetype for box-minted staging VMsAdds a fourth bootstrap role,
staging, alongsidecontrol-plane/workload/runner: the machine whose job is to host staging boxes — Incus VMs minted by theboxCLI (companion: heavy-duty/box#68), each later converged from inside withrig bootstrap workloadand registered in the control plane as its own server.Role semantics:
staging(convention: default = role name).tag:local; the role refusestag:serverinverify_effective_tag, exit 1, exactly where and how therunnerrefusal lives. A staging host is never managed by the control plane — its guest VMs are — and the fleet has already been bitten by a host wrongly carryingtag:server./dev/kvmabsence is an advisory warning in the execution path (the role is rehearsed in containers), never a failure; arg validation stays pure and root-free.box setup-hostto prepare Incus, thenbox new --template staging. rig deliberately installs no Incus and no box — box'ssetup-hostis the single owner of Incus config; two tools converging one daemon is drift by construction.The first commit is the implementation plan (
docs/plans/2026-07-17-staging-role.md), per repo convention; implementation follows on this branch.Note for review: issue #22 was written before #20 merged, so its acceptance criterion names the now-removed
--ts-tagflag. The plan's addendum reconciles this — thetag:serverrefusal lands on the effective tag (the strictly stronger, post-#20 layer). While addingstagingto the dispatcher's role list, thebin/rigbootstrap usage line also drops the stale[--ts-tag <tag>]/ "defaults to tag:ci" text that #20 left behind.Out of scope, deliberately: no
devrole yet, no VM provisioning, no Coolify API.Closes #22
🤖 Generated with Claude Code
Verification
Implementation is complete on this branch (plan →
feat(bootstrap)→docs). Results, all as non-root on Debian:bash test/cli.sh—74 passed, 0 failed, exit 0. New checks:stagingparses and reaches the root check (exit 1,must run as root);staging --ts-tag tag:serverdies at arg validation (exit 2, points at the key — validation still precedes the root check); the staging effective-tag refusal message is present in the shipped script (grep guard, same rationale as the runner-install repo-guard grep); unknown roles still exit 2.ci.ymlruns it (shopt -s globstar; files=(bin/* **/*.sh); shellcheck -x "${files[@]}") — clean, zero findings.bash -noncommands/bootstrap.sh,bin/rig,test/cli.sh— clean.rig --helplists the four roles;rig bootstrap staging(non-root,TS_AUTHKEY=x) → exit 1must run as root;rig bootstrap staging --ts-tag tag:server→ exit 2 with the removed-flag message.Not exercised here (needs root + a real tailnet, per the repo's rehearsal convention): the full converge on a pristine box, the post-join
tag:serverrefusal firing live, and the/dev/kvmwarning on real hardware. The plan's Test Plan section spells out that rehearsal.🤖 Generated with Claude Code