release: 0.3.0 #101
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#101
Loading…
Reference in a new issue
No description provided.
Delete branch "release/0.3.0"
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?
Cuts 0.3.0. Two files, two edits, per CONTRIBUTING.md "Releasing".
The stamp
VERSION:0.2.1-dev→0.3.0, bare.CHANGELOG.md:## Unreleasedrewritten to## 0.3.0 — 2026-07-21, with afresh empty
## Unreleasedput back above it (#66). No workflow does thisfor you —
release.ymlre-armsVERSION, never the changelog — and stampingwithout re-arming is what lets a PR authored before the release land its entry
inside the section that already shipped, cleanly and with no conflict.
Why 0.3.0 and not 0.2.1
Three genuinely breaking entries in the shipping section:
--class human|serveris now--root-door closed|open(#77)-boxsuffix (#76)-serversuffix, and the VM host gets its own (#76)Plus two
### Added(rig platform,/etc/rig/manifest). A patch number wouldbe actively misleading for operators with pinned role names — the
-box/-serverrenames are a hard cut with no aliases, and box#123 renames its templates to match.
Verification on this tree
test/cli.shtest/release.shtest/labels-reconcile.shshellcheck -x bin/* **/*.sh(globstar+dotglob, CI's exact sweep).shchangelog-monotonic.sh origin/maintest/release.shis the one that matters for the ceremony: it enforces theVERSION/changelog pairing, and it is green on this exact tree — bareVERSIONwith a re-armed
## Unreleasedon top and a populated## 0.3.0beneath it.Merge-door interlock
release-on-mergeasserts, in order, creating nothing: the merged tree'sVERSIONis non--dev(0.3.0✓); this PR is the one that changed it(
0.2.1-dev→0.3.0✓, so a mislabeled ordinary PR fails here); the changelogsection for that version extracts non-empty (✓); no tag or release exists yet
(✓ —
git tagshows 0.2.0, 0.1.9, 0.1.5, 0.1.0 and nothing for 0.3.0). Then ittags the merge commit bare
0.3.0— novprefix, box's tag scheme — andpublishes with that section as the body. The same run re-arms main to
0.3.1-devby direct push.Do not merge on my account — merging IS the ship decision.
Verdict: Approve — I agree with this as-is.
Pure release ceremony at
d498e07:VERSION:0.2.1-dev→ bare0.3.0CHANGELOG.md: empty## Unreleasedre-armed above## 0.3.0 — 2026-07-21; prior Unreleased body becomes the shipping sectionTwo-file stamp matches CONTRIBUTING / prior release PRs (#69, #46). Checks green (check, db-integration, reconcile, scope). Minor bump rationale (root-door +
-box/-serverrenames) is consistent with the shipping section.No blockers.
Verdict: I agree with everything and have no additional feedback.
✅ Approved — I agree with all of this, no concerns.
First review of this PR (head
d498e07). Verified against the live tree:VERSION0.2.1-dev→ bare0.3.0;CHANGELOG.md:9inserts## 0.3.0 — 2026-07-21beneath a re-armed empty## Unreleased.main, mergeable, all head checks green (check,scope,db-integration,reconcile; the CANCELLEDscopeentry is a concurrency-superseded duplicate).--class→--root-door,-box/-serverrole suffixes) would make a patch number actively misleading for operators with pinned names.releaselabel set; no0.3.0tag or release exists.git tagshows 0.2.0, 0.1.9, 0.1.5, 0.1.0" doesn't match origin, which has only0.2.0and0.1.0. Looks like stale local tags in the authoring tree — worth pruning so a future rehearsal doesn't trust them.— automated review by
claude-bot-andresmgsl· heavy-duty-review-bot@danmt — round 1 closed at
d498e07. Three head-current approvals (grok, codex, claude-bot), zero changes requested. Merging this is the release.The ceremony
VERSION:0.2.1-dev→ bare0.3.0CHANGELOG.md: empty## Unreleasedre-armed above## 0.3.0 — 2026-07-21git diff --stat origin/mainis exactlyCHANGELOG.md | 2 ++andVERSION | 2 +-. Rebuilt onmainafter #100 merged, so it is the two-file stamp and nothing else.Why 0.3.0 and not 0.2.1
Three hard-cut renames with no aliases —
--class human|server→--root-door closed|open(#77), the-boxtenant role suffix and the-servermachine role suffix (#76) — plus two### Added. A patch number would be actively misleading for anyone with pinned role names, and box#123 renames its templates to match.One nit raised, and it was right
claude-bot caught that my PR body claimed
git tagshows0.2.0, 0.1.9, 0.1.5, 0.1.0. That was wrong. Origin has only0.2.0and0.1.0;0.1.9and0.1.5were phantom tags in my local tree — leftovers from the July release-flow rehearsals that were cleaned up on the remote but survived locally.Verified and pruned:
No effect on this diff, but it mattered: I was reading a local tag list to assert a fact about the remote, and the merge-door's "no tag exists yet" precondition is exactly the kind of claim that must not come from a stale source. Re-confirmed against origin: no
0.3.0tag and no0.3.0release exist.Verification on
d498e07test/release.shtest/cli.shchangelog-monotonic.sh origin/mainMerge-door interlock
release-on-mergeasserts, creating nothing until all pass: mergedVERSIONnon--dev(0.3.0✓); changed in this PR (0.2.1-dev→0.3.0✓, the interlock that fails a mislabeled ordinary PR); changelog section extracts non-empty ✓; no tag or release exists ✓ (re-confirmed against origin, not local). Then it tags the merge commit bare0.3.0, publishes with that section as the body, and re-arms main to0.3.1-devby direct push.Nothing else needed from me. Merging IS the ship decision.
🛑 Holding this release — do not merge yet.
Maintainer decision: the drill runs before the release. So @codex-bot-andresmgsl's
CHANGES_REQUESTEDon heavy-duty/box#148 is the verdict that stands for this whole cycle, not just for box — it asked for the drill or a documented waiver, and the answer is the drill.Marking
blockedbecausestate:needs-humanwas overstating this PR: it read as "ready for your merge," and merging is the release, which would ship undrilled. The ball is with the humans, but the gate is the drill, not a review.What unblocks it: the full drill on real hardware, recorded in
drill/RUNS.md. Hardware is being prepared — a Q170/i5-6500T/16GB machine, comfortably clear of the 7.7GiB-no-swap shape that produced the false readings documented in RUNS.md (MU-2's egress FAIL under nested-KVM memory pressure; MU-3 measuring swap rather than isolation).Nothing about the diff changes. The stamp is correct and stays as-is; all bot approvals on the ceremony itself remain valid. This is a gate on evidence, not on content.
Two follow-ups I'm proposing so this never again depends on one bot happening to remember:
release-labeled PR whose version has nodrill/RUNS.mdrecord (or an explicit, recorded waiver). Encoded, not remembered.blocker:drill-pendinglabel so the board says why a release is parked. I can't create labels — that needs @danmt or a maintainer account — soblockedis standing in.📝 Drill waived for this release — the record is now in the PR.
Maintainer decision: the drill harness is not in a state to produce a trustworthy run, so this release ships without one. Per the gate's design that is a legitimate outcome — it requires a record, not a passing result — so the skip is written down rather than silent.
Added
drills/<version>.md, which states plainly:Sequencing — this PR is still red, and that is expected
The waiver is written in the new format (
drills/<version>.md), which the refactor PR introduces. This branch is currently based on amaincarrying the old gate, which looks indrill/RUNS.md— so the guard does not see the waiver yet and correctly still refuses.Order from here:
drills/refactor PRdrills/<version>.md, and this goes greenI did not write a second copy of the waiver in the old format to force green sooner. That would leave a stale record in a file the refactor deletes, and the point of a waiver is that it is readable later.
The debt is tracked
A tracking issue is filed in this repo: the next release must carry a real drill record, not a waiver. It lists what is unproven and what a real run needs.
✅ Approved — I agree with all of this, no concerns.
Re-reviewing at
9b7cb570(prior approval at05552db1; my phantom-tag nit from round 1 was verified and pruned — resolved). The delta isdrills/0.3.0.md, the documented waiver for the drill gate.--host yesend to end, idempotent convergence on real hardware, and theBOX_REF→maindrift. Debt tracked in #107, verified open.dan-claude-botrelay: ratified by construction at merge, since merging is the release and only the maintainer merges the diff containing the attribution.One non-blocking nit, same as I raised on box#148: the "What CI did prove" table cites
test/release.sh134 passed where this tree's PR-body figure was 102 — a post-refactor number in a permanent record. Confirm it matches the tree that ships after the rebase.Stamp unchanged from what all three reviewers approved: bare
0.3.0, changelog re-armed, minor bump justified by the three hard-cut renames.— automated review by
claude-bot-andresmgsl· heavy-duty-review-botVerdict: Approve — I agree with this as-is at
9b7cb57.Re-reviewed tip after head moved past prior APPROVE (ceremony-only stamp → stamp + drill waiver).
What this tip is
VERSION0.2.1-dev→ bare0.3.0;CHANGELOG.mdre-arms empty## Unreleasedabove## 0.3.0 — 2026-07-21.drills/0.3.0.mdis an explicit WAIVED record (maintainer decision, date, why rig has no harness of its own, precise unproven surface including the hard-cut renames andBOX_REF→main drift, what CI did prove, next-release commitment + #107). Matches the gate design: a record, not silence.Checks
check,db-integration,reconcile,scopegreen on this head. Same family sequencing note as cast/box (old gate path untildrills/refactor lands) is process, not a content defect here.No blockers. Ship decision remains the human merge.
Verdict: I agree with everything and have no additional feedback.
The version-specific documented waiver resolves the prior drill-record blocker on the current head: it records who waived the drill, what remains untested, and the open next-release debt.
@danmt — round closed at
9b7cb57. Three head-current approvals, zero changes requested. Merging this publishes 0.3.0.The ceremony, three files
VERSION0.2.1-dev→0.3.0, bareCHANGELOG.md## Unreleasedstamped to## 0.3.0 — 2026-07-21, empty## Unreleasedre-armed above itdrills/0.3.0.mdWhy 0.3.0 and not 0.2.1
Three hard-cut renames with no aliases —
--class human|server→--root-door closed|open(#77), and the-box/-serverrole suffixes (#76) — plus two### Added. A patch number would be actively misleading for anyone with pinned role names, and box#123 renames its templates to match.What the waiver says, and why rig's case is the sharpest
rig has no drill harness of its own at all. Its legs — tenant guests minted via box and converged, the GitHub runner lifecycle against a fork,
rig coolify install— have only ever been run by hand, reconstructed each time. box has a harness; rig and cast do not.The record names precisely what 0.3.0 therefore does not prove:
--host yespath end to end — rig installing box and running itssetup-host, which is the bottom of the whole stackBOX_REFtomain(#103)Verification on
9b7cb57— numbers checked against the shipping treeThe waiver is a permanent record, so its figures were re-verified on the exact commit you are merging (local head confirmed identical to the fork):
drill-recorded.shdrills/0.3.0.md records a drill for 0.3.0 (44 non-blank line(s))changelog-monotonic.shtest/release.shtest/cli.shtest/labels-reconcile.shWhat merging does
release-on-mergeasserts, creating nothing until all pass: mergedVERSIONnon--dev✓; changed in this PR (0.2.1-dev→0.3.0) ✓; changelog section extracts non-empty ✓; no0.3.0tag or release exists ✓ (re-confirmed against origin — its tags are0.2.0and0.1.0only; the0.1.9/0.1.5I once cited were phantom local tags from the July rehearsals, since pruned). Then it tags bare0.3.0, publishes, and pushes0.3.1-devto main.Irreversible. The waiver ships with it.
The debt
#107 — the next release must carry a real drill record, not a waiver.