release: 0.2.0 #137
Labels
No labels
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-triage
ready
release
scope:apply
scope:capture
scope:coolify-api
scope:fleet
scope:manifest
scope:secrets
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/cast#137
Loading…
Reference in a new issue
No description provided.
Delete branch "release/0.2.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.2.0. Per CONTRIBUTING.md "Releasing".
The stamp
package.json:0.1.2-dev→0.2.0, withpackage-lock.jsonkept in stepvia
npm install --package-lock-only(both now read0.2.0).CHANGELOG.md:## Unreleasedrewritten to## 0.2.0 — 2026-07-21, with afresh empty
## Unreleasedput back above it. The empty top section isthe deliberately-tolerated case in
test/release.test.ts: what must extractnon-empty is the section that SHIPS, not the top one.
Why 0.2.0 and not 0.1.2
Two
### Added— declarative HTTP basic auth (#76) andcast github-app create/register(#7) — and a### Removed:scripts/register-github-app.shis gone, replaced bycast github-app register.Deleting a script operators were told to run is breaking, so a patch number
would understate it.
Verification on this tree
npm testnpm run check(biome,--error-on-warnings)npm run build(tsc)test/release.test.tschangelog-monotonic.sh origin/mainrelease-notes.sh 0.2.0The 767 is the thing the stacked fix PR buys:
maintoday is 766/1 —tmp-guardcatching three files from #124/#125 on rawmkdtempSync. A releasePR on a red main is red on arrival, which is why that fix is its own PR
underneath this one.
Merge-door interlock
release.ymlfires on the merged,release-labeled PR and asserts, eachfail-loud and creating nothing: the merged version is non-
-dev(0.2.0✓);the version changed in this PR (
0.1.2-dev→0.2.0✓ — the-devtransitionis the interlock that fails a mislabeled ordinary PR); that version's changelog
section extracts non-empty (✓, 35 lines); and no tag or release exists for it
yet (✓ — tags are 0.1.1 and 0.1.0). Then, in the same job, it tags the merge
commit bare
0.2.0, builds once (npm ci && npm run build && npm prune --omit=dev) and attaches the runnable tree ascast-0.2.0.tgz— the asset theinstaller's release channels download, built in CI and never on an operator's
machine.
Do not merge on my account — merging IS the ship decision.
Verdict: I have feedback.
The release stamp and version choice are sound. The current
scopecheck is reported as failed because that job was canceled, and the PR still carriesblocker:ci-red; please rerun or otherwise clear that check before merge. I do not see a source defect requiring changes.✅ Approved — I agree with all of this, no concerns.
First review of this PR (head
35197a0). Verified against the live tree:package.jsonandpackage-lock.jsonboth0.1.2-dev→0.2.0(lockfile in step at both positions), andCHANGELOG.md:10inserts## 0.2.0 — 2026-07-21beneath a re-armed empty## Unreleased.main.scripts/register-github-app.shin favor ofcast github-app registeris breaking for operators told to run it.releaselabel set; no0.2.0tag or release exists (remote tags: 0.1.1, 0.1.0).blocker:ci-redlabel traces to run 29841350333, whosescopejob was cancelled by concurrency ("higher priority waiting request for labels-scope-137 exists"); the parallel run 29841350558 passed and every check on the head commit is green. Worth clearing the label before merge so the door isn't misread.— automated review by
claude-bot-andresmgsl· heavy-duty-review-botVerdict: Approve — I agree with this as-is.
First review (head
35197a0). Pure release ceremony on main after #135/#136:package.json+package-lock.jsonboth0.1.2-dev→0.2.0(lockfile root +packages[""]in step).## Unreleasedre-armed above## 0.2.0 — 2026-07-21; shipping section has non-empty Added/Changed/Removed/Fixed (incl. BREAKING drop ofscripts/register-github-app.sh).### Addedfeatures land in the same cut.releaselabel set; no0.2.0tag/release yet (remote: 0.1.1, 0.1.0); version is non--devand changed in this PR.cigreen (build+install). Labelsscopeshows fail only because run 29841350333 was cancelled by concurrency — not a source defect. Staleblocker:ci-redis a label artifact only (optional clear before merge).Agree with peer approvals on tip.
🛑 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.⚠️ Do not merge on the strength of these green checks — they are stale.
The drill gate has now merged to
main. This PR has not re-run CI since, so the checks shown above were computed against amainthat had no gate. They say nothing about whether this release has a drill record. It does not.If this merged right now,
release.ymlwould tag and publish an undrilled release, and the gate would only go red afterwards, onmain. The green is a stale artifact, not a verdict.I am deliberately not rebasing this branch yet — agents are actively writing in that checkout, and two writers in one checkout is how rebases get corrupted. As soon as they finish I will rebase onto
main, at which point this PR will correctly go red ondrill-recordedand stay that way until the drill is run and recorded.Until then the
blocker:drill-pendinglabel and this comment are what is holding the door. @danmt — please treat this PR as blocked regardless of what the checks say.📝 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
b2ccce05(prior approval was the stamp at9fa5c3d7). The delta isdrills/0.2.0.md, the documented-waiver form of the drill gate, and it is the strongest of the three family records because it is the most specific about what goes unproven: the A→B promotion path against live instances, the basic-auth write that is deliberately never read back, the App Manifestredirect_urlthat #7 itself documents as unvalidated and load-bearing, and the removedregister-github-app.shpath being exercised only by unit tests. That is exactly the level of precision that makes a waiver worth reading later.The debt is tracked in #142 — verified open. On the waiver naming @danmt while being relayed by
dan-claude-bot: closed by construction, since merging is the release and the file naming the maintainer is in the diff only they can merge.Stamp unchanged from my prior approval:
package.json/package-lock.jsonin step at0.2.0, changelog re-armed, 0.2.0 over 0.1.2 justified by the### Removedbreaking change.— automated review by
claude-bot-andresmgsl· heavy-duty-review-botVerdict: Approve — I agree with this as-is at
b2ccce0.Re-reviewed tip after head moved past prior APPROVE (ceremony-only stamp → stamp + drill waiver).
What this tip is
package.json/package-lock.json0.1.2-dev→ bare0.2.0;CHANGELOG.mdre-arms empty## Unreleasedabove## 0.2.0 — 2026-07-21.drills/0.2.0.mdis an explicit WAIVED record (maintainer decision, date, why cast has no trustworthy harness path, precise unproven surface, what CI did prove, next-release commitment + #142). Matches the gate design: a record, not silence.Checks
build,install,reconcile,scopegreen on this head. Sequencing note in-thread (olddrill/RUNS.mdgate vs newdrills/path until the refactor lands) is process, not a content defect in this diff.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
b2ccce0. Three head-current approvals, zero changes requested. Merging this publishes 0.2.0.The ceremony, four files
package.json0.1.2-dev→0.2.0package-lock.jsonnpm install --package-lock-onlyCHANGELOG.md## Unreleasedstamped to## 0.2.0 — 2026-07-21, empty## Unreleasedre-armed above itdrills/0.2.0.mdWhy 0.2.0 and not 0.1.2
Two
### Added— declarative HTTP basic auth (#76) andcast github-app create/register(#7) — and a### Removed:scripts/register-github-app.shis gone. Deleting a script operators were told to run is breaking.What the waiver says — and cast's gap is the one I would read most carefully
cast has no drill harness, and its legs are the heaviest to stand up: two live Coolify instances, credentials, an age store, a registered GitHub App. In the July drill, instance B had to be built from a hand-written compose file.
The record names what 0.2.0 therefore does not prove, and two of them are this release's headline features:
cast github-app create(#7) runs GitHub's App Manifest flow, whoseredirect_urlon127.0.0.1is documented in that PR as unvalidated and load-bearing. No automated test covers it, and this release does not either.### Removedbreaking change is exercised only by unit tests.team,apply, idempotent re-diff,smoke,inventory,emit-draft,fleet --all,destroybehind its typed gate, the read-only guard.That is a real gap and the waiver states it plainly rather than gesturing at it.
Verification on
b2ccce0— checked against the shipping treedrill-recorded.shdrills/0.2.0.md carries a drill record for 0.2.0 (62 line(s))changelog-monotonic.shrelease-notes.sh 0.2.0npm testnpm run check(biome,--error-on-warnings)npm run build(tsc)shellcheck-all.shWhat merging does
release.ymlasserts, creating nothing until all pass: merged version non--dev✓; changed in this PR ✓; changelog section extracts non-empty ✓; no0.2.0tag or release exists ✓. Then it tags bare0.2.0, builds once (npm ci && npm run build && npm prune --omit=dev), and attaches the runnable tree ascast-0.2.0.tgz— the asset the installer's release channels download, built in CI and never on an operator's machine.Irreversible. The waiver ships with it.
The debt
#142 — the next release must carry a real drill record, not a waiver.