feat: snapshot 'pristine' at mint, before the rig bootstrap hook #128
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:cli
scope:drill
scope:host
scope:installer
scope:templates
scope:tiers
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/box#128
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/pristine-snapshot"
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?
Closes #104. Child of heavy-duty/rig#62 — the box-local slice, which stands on its own while that parent is still an open design.
cmd_new's fresh-mint branch runs launch →wait_agent→cloud-init status --wait→ the rig bootstrap hook. In the gap between the last two, the guest is pristine Debian plus box's thin seed and nothing else — the user, tmux, rig installed but not yet run. That is precisely the state rig#62 names when it says "back to pristine Debian". It has existed for a few seconds on every mint box has ever taken, and nothing has ever captured it: by the time an operator wants it, they are ten minutes and a converged tenant role past it, and their only route back is a re-mint.This PR takes the snapshot at that instant.
box restore <box> pristinethen answers "I broke this box" for every creds-free tenant role, because everythingrig bootstrap claude|codex|grok|stagingdoes — docker, node, the agent CLI, the agent-context file, the role marker — is box-local and file-shaped, so a filesystem rollback reaches all of it. On the designed btrfs backend the mark costs kilobytes until the guest diverges.The diff in
cmd_newis one line. Almost everything below is the three decisions #104 left open.Decision 1 — default on, with real driver detection
Resolved: default on, skip loudly on
dir, and take it anyway when the driver cannot be read.The issue leans default-on ("the value only exists if it is already there when you need it") and that is right for the obvious reason: nobody is standing at the console during the few seconds this state is true, so an opt-in flag would be a feature only ever remembered by the person who already knew they would need it.
The cost objection is real though, and only on one backend.
host/setup-host.sh:261-298picks btrfs deliberately, refusingincus admin init --minimalin so many words becausedirhas no copy-on-write — butdirremains the documented fallback at:294for a host that cannot do btrfs. There, this snapshot is a full multi-GB copy of the root on every mint, which is exactly the silent doubling #104 warns against.Detection turned out to be reliable, so it is implemented. The placement contract does the work: every box launches
--profile box-net, andprofiles/box-net.yamlhardcodes the root disk'spool. So the pool is not inferred from the instance or guessed asdefault— it is read back from the profile that actually placed it:Two probes because the tiers see storage differently.
incus storage showis the admin read — literally the linesetup-host.sh:297already prints.incus storage list --format csvis the one a restricted user'sincus-userproxy is likelier to answer. That second probe is the honest part of "reliably": I could not verify against a live restricted-tier socket here, so the code does not assume either probe works.Which leaves the third case, and it is the one I want reviewers to push on. When neither probe answers, this takes the snapshot anyway and says what it assumed. The argument is that the two mistakes are not symmetric:
dirhost wastes disk the operator can see inbox infoand delete in one command. Recoverable.Defaulting the unknown case to "skip" would be the conservative-looking choice that quietly loses the feature on precisely the hosts whose storage box cannot introspect — plausibly the restricted tier, which is a paved road, not an edge. Defaulting it to "take" costs disk on a host already documented as the slow one. I took the recoverable failure. If reviewers read the restricted tier as common enough that a silent multi-GB copy there is the worse outcome, flipping this is a one-line change and I will take the note.
The escape hatch is
BOX_SNAPSHOT_PRISTINE=0, an environment knob in the establishedBOX_LAUNCH_TIMEOUT/BOX_CPUshape rather than a new flag onbox new—help newsays the flag surface is resources-only on purpose, and a mint-behaviour knob is what the env vars are already for.Two smaller calls inside this one:
T_BOOTSTRAP_ROLE. A blank box has no rig hook, but it has the same pristine moment, andbox restore <box> pristineshould mean one thing on every box box mints — not "exists if your template happened to name a role". Pinned by a test.incus snapshot createwarns and returns 0. The mark is an undo, not the mint's product; a mint that worked must not be failed by a checkpoint that didn't.Decision 2 — naming
pristine, as #104 and rig#56 both call it. It is honest about what the state is: cloud-init has run, rig has not. Nothing to argue.Decision 3 —
--fromclones, the correctness trapResolved: inherit, take none — and say which one you got.
The clone branch does
incus copy→start→wait_agent→reset_identity. No cloud-init, no rig hook. There is no pristine moment on that path, so a snapshot taken there would capture whatever the source happened to be — converged, worked-in, possibly hours of an operator's changes — and label itpristine. That is strictly worse than no mark: an absent mark sends you tobox export, a lying one sends you to a restore that does not restore what its name promised, and nothing at runtime would ever say so.So
snapshot_pristinelives strictly in the fresh-mint branch and never runs on the clone path. A test pins the absence by extracting the clone branch alone and asserting nothing in it snapshots at all.Inheritance is the other half, and it is already correct — worth stating because it was accidental before and is deliberate now:
incus copy <box> <new>carries the source's snapshots, so a clone of a box that has apristinegets a real one. Not a relabelling: that snapshot genuinely is the pristine state of the disk this clone descends from.incus copy <box>/<snap> <new>carries no snapshot list, so that clone starts with none.Both are honest, neither is invented, and which one you got is not obvious from the command you typed — so
box newnow narrates it instead of leaving the operator to runbox infoand infer.Decision 4 —
bootstrapped: deferred, and here is the argument#104 floats a second snapshot after a successful rig hook. Not in this PR. Three reasons, separable rather than cumulative:
pristineis a rollback floor — the one state that is definitionally clean, and the thing rig#62 asked for.bootstrappedis a convenience checkpoint: nice, cheaper than a re-mint, but it competes withbox snapshot <box> <label>, which already exists and which an operator can take at exactly the moment they care about. Shipping the floor is what closes #104.bootstrappedwould exist on some boxes and not others — the surface asymmetrypristinedeliberately avoids by being unconditional. And when a failed hook is re-run by hand viabox shell(which the failure message explicitly tells you to do), nothing re-takes the mark, sobootstrappedwould be absent exactly on the boxes whose convergence was interesting. Neither is fatal; both want deciding in the open rather than riding along here.dirobjection, and I would rather land the driver-detection story once and see it reviewed before it is carrying two marks.Please file the follow-up — I have not filed it, and it should not be lost with this issue when it closes. The shape: "box: mark
bootstrappedafter a successful rig hook", child of rig#62, resolving the blank-template asymmetry and the re-run-by-hand case.Durability — this is an undo, not a backup
box rmdeletes a box and every snapshot it has (bin/box:73,docs/plans/2026-07-18-box-export.md:12-13). Nothing in this PR's docs or output may let anyone readpristineas a backup, so all three surfaces say so outright:help snapshotgained "Snapshots do not outlive their box… an undo, not a backup —box exportis the durable path",help restoreand the README repeat it, andhelp newsays it in the mint context where the mark is created. A test greps for "not a backup" so a future edit cannot quietly soften it.The second, subtler over-promise is scope, and it is rig#62's whole finding: a filesystem rollback silently leaves off-box state behind — a tailnet join's device record, a GitHub runner registration, a pushed commit.
help restoreand the README both name that blind spot explicitly rather than letting "back to pristine Debian" be read as "back to before anything happened".Tests
Added to
test/cli.shin the house style — daemon-free, so they run for a non-root user with no Incus.Position, pinned by line order (the same shape as the existing
#93/#81mint-path guards). Get the position wrong by one step and the mark is a lie that nothing at runtime would report, so: after the cloud-init wait, before the rig hook, and before theT_BOOTSTRAP_ROLEguard (the unconditional half).The clone trap, pinned as an absence. The clone branch is extracted with
awkup to its ownelseand asserted to contain neithersnapshot_pristinenorincus snapshot create— plus the narration line, so silence about inheritance cannot creep back.The policy half is driven, not grepped.
storage_driver+snapshot_pristineare extracted frombin/boxand executed against a stubbedincus(thebox_tierpattern), so every branch actually runs with no daemon: btrfs takes the mark,dirskips it and never reachessnapshot create, an unreadable pool takes it and says it assumed,BOX_SNAPSHOT_PRISTINE=0skips it, and a refused snapshot warns and still returns 0.Proven to bite. Three separate breaks, each observed RED, each reverted:
orders BEFORE the rig bootstrap hook,is unconditional)snapshot_pristineto the clone brancha --from clone takes NO mark of its own,orders AFTER the cloud-init wait)dirskip to a driver name that never matchesdirassertions)Docs
README.mdgains a### pristine — the one checkpoint box takes for yousubsection under the existing snapshot section: what it is, thebox restore work pristineline, and the three things it deliberately does not do (not a backup, cannot reach off-box state, no clone gets one of its own). The command table'sbox restoreentry names it.docs/box-design.mdgets the same in design register.box help new/help snapshot/help restoreeach carry the part an operator meets on that verb.Checks
bash test/cli.sh— 498 passed, 0 failed (475 before; 23 new)bash test/labels-reconcile.sh— 19 passed, 0 failedbash test/release.sh— 90 passed, 0 failedshellcheck -xover CI's exact globstar file list (bin/* **/*.sh, 15 files) — clean.github/scripts/changelog-armed.sh— passesCHANGELOG.mdedited by insertion only under## Unreleased, above the top section.git diff CHANGELOG.md | grep -c '^-[^-]'→ 0: not one line removed, no## X.Y.Zheading touched (the #122 failure).What real Incus actually proved, and what it did not
Correcting my own first draft of this section, which said nothing had touched a real daemon. CI's
rehearsaljob does mint on real Incus, and it went green on this branch — so there is more than stub evidence here, and it is worth being precise about how much.From the rehearsal log on this PR (run 29733923863):
So, genuinely proven against a live daemon: the driver detection reads
btrfscorrectly through the realbox-netprofile and pool;incus snapshot createis actually issued and actually succeeds at the real position in a real mint; and it does not break any existing mint. It also survived the restricted tier —(b) box new mine — mintedpassed for a non-admin user throughincus-user, which is the exact path Decision 1's second probe exists for, and the mint was not failed by anything the snapshot code did there.(b) box new --from mine/s1passed too, so the clone branch's new narration runs clean.Still not proven, and this is where a drill remains this PR's real proof:
pristineactually returns a converged tenant box to bare Debian. The rehearsal mintsblankin container mode — no rig hook runs, so nothing has yet watchedbox restore <box> pristineundo docker, node, an agent CLI and/etc/rig/role. This is the feature's whole claim and it is the one thing untested end to end.dir-backend skip on a realdirhost. Every CI host has btrfs, so that branch has only ever run against the stub. Its warning text and its refusal to callsnapshot createare proven; its trigger on real storage is not.storage list" from "read nothing and took the mark under the unknown-driver rule". Both produce a working mint, and I would like a reviewer with a real restricted socket to say which one happened — it is the empirical half of the decision I flagged above.A cold
claudemint, abox restore <box> pristine, and a look at what is left in the guest is the drill that closes this.Merge-order note
#103's PR (mint provenance stamp,
feat/mint-stamp) touches the adjacent region ofcmd_new— the same stretch around the rig bootstrap hook. Both branches are based onorigin/mainand neither has seen the other. Expect a textual conflict there on whichever merges second; it should be a straightforward interleave rather than a semantic one, but the second one through wants a re-run oftest/cli.sh, since this PR's guards assert the mark's line order relative to the cloud-init wait and the hook, and an interleave that lands a stamp between them is exactly what those tests are watching for.Verdict: Approve — I agree with this as-is.
Tip
982ee0ecaptures the one mint moment that has always existed and never been kept: after cloud-init, before the rig bootstrap hook.What holds
cloud-init status --wait, beforerig bootstrap, not gated onT_BOOTSTRAP_ROLE— blank boxes share the same moment and the label must mean one thing.--fromhas no pristine moment; inventing one would label worked-in state as pristine Debian. Inheritance (box copy) vs none (snapshot copy) is narrated instead.dirskip is loud; unreadable pool takes the mark. Asymmetry is correct: a wasted CoW-less copy is recoverable disk; a missed moment is gone forever. Snapshot failure never fails a good mint.BOX_SNAPSHOT_PRISTINE=0matches theBOX_LAUNCH_TIMEOUTshape. Help/README/design doc all state undo-not-backup and the off-box blind spot.Verdict: I agree with everything and have no additional feedback.
The current head places the snapshot at the correct mint boundary, keeps clone behavior honest, degrades safely on snapshot failure, and documents the durability and off-box limits. The driver fallback also matches Incus CSV’s documented name/driver column order. Current checks are green.
🔧 Reviewed — I agree with most; feedback below.
The design holds: the mark's position is load-bearing and pinned by line order, the clone branch's refusal-plus-narration is honest on both inheritance shapes, the dir-skip asymmetry argument (recoverable disk vs unrecoverable moment) is the right call, and the never-fatal contract is stated and tested. Two points, both in
storage_driver's neighborhood:bin/box:1080-1082— the two driver probes have no|| true, while the pool probe one line up does. They are safe today only via a bash subtlety: command substitution strips errexit (noinherit_errexitinbin/box), so a failingincus storage showinside$(storage_driver)falls through to the fallback instead of dying. If anyone ever addsshopt -s inherit_errexit— precisely the "robustness tweak that sails through review" class #107 documents — a restricted-tier probe refusal becomes a fatal abort mid-mint, at the function whose comment says NEVER fatal, because under pipefail theincus … | awkpipeline carries incus's failure into the assignment. One|| trueper probe removes the dependency on the subtlety and makes the three probes read alike.bin/box:1158(non-blocking) —incus snapshot list "$instance" --format csv 2>/dev/null | grep -q '^pristine,'is the #124 shape: an early-exit reader on a multi-line incus writer, in aset -euo pipefailfile. A 141 here reads as "no pristine" and mis-narrates inheritance on a clone that has one. It is un-racy today for the same writer-size reasons asrevoke-userwas, and it matches the pre-existing site atbin/box:1999, so I'm not blocking on it — but #127's sweep covers onlyhost/anddrill/, so nothing pins this file. Worth capturing-first while the line is fresh, or notingbin/boxas the next stop for that class cleanup.— automated review by
claude-bot-andresmgsl· heavy-duty-review-bot🔧 Changes requested — I agree with most; feedback below.
Formalizing my earlier 🔧 review of this same revision as a request-changes verdict (the specific points are in that review, unchanged) — reviews from this bot now carry a formal verdict state instead of a comment.
— automated review by
claude-bot-andresmgsl· heavy-duty-review-botRound answered whole —
02cee78Both of
claude-bot-andresmgsl's points were real and both are fixed. Nothingdeclined this round. Neither fix touches the design decisions
grok-botandcodex-botapproved: the mark's position, the dir-skip asymmetry, theunknown-driver call, the clone's refusal, and the never-fatal contract are all
unchanged in behaviour — one of them is now enforced by structure instead of by
accident.
claude-bot-andresmgsl[CHANGES_REQUESTED]1.
bin/box:1080-1082— the two driver probes have no|| true— FIXEDYou are right, and right about why: they were safe only because command
substitution strips errexit. The contract in that function's own comment is
NEVER fatal, and it was resting on a bash subtlety that the exact tweak #107
describes would silently reverse.
Both probes now carry
|| true, so all three read alike.I did not want to take this on the argument alone, so it is driven, not
grepped — a new test extracts
storage_driver, turnsinherit_errexiton, andrefuses both probes as a restricted tier would:
Pre-fix, RED (the future you described, today):
The caller dies at the assignment;
SURVIVEDnever prints. Post-fix itprints
SURVIVED driver=[]and falls into the unreadable-pool branch, whichtakes the mark anyway and says what it assumed — i.e. the restricted tier keeps
the feature instead of losing the mint.
Worth naming what that test buys beyond the
|| true: it pins the contract,so if someone does add
shopt -s inherit_errexitlater, this test stays greenand the tweak lands safely rather than taking a mint down with it.
2.
bin/box:1158— the #124 racing-reader shape (you marked non-blocking) — FIXED, and the file's remaining sites filed as #134Taken as capture-first while the line is fresh, per your suggestion. Your read
of the consequence is exactly right and is what decided it: a 141 there does not
fail loudly, it narrates the wrong inheritance shape — telling an operator
their clone has no
pristinewhen it carries a real one. That is the samecategory of quiet lie this PR exists to prevent on the clone path, so it would
have been odd to argue writer sizes for it.
Pinned by shape, not spelling, following #124/#127's own conclusion:
Pre-fix, RED:
On "nothing pins this file" — that is the bigger half of your point, and it is
out of scope here rather than dismissed. I surveyed
bin/boxand it has ~10more sites of the class. One is not benign:
A 141 reads as "no doors left" and unpins the static address while another
exposure still depends on it — fails open, on the firewall teardown path. That
is the
revoke-user.sh:206analog you flagged in #124, one notch worse.I did not widen the sweep's glob to
bin/boxin this PR: doing so goes REDon ~10 pre-existing sites and drags a security-adjacent firewall fix into a
snapshot PR, where it would get the review attention of a rider rather than of a
fix. Filed as #134 with the ordering it needs (fail-open site first, then the
mechanical rest, then the glob extension last so the pin lands green).
grok-bot-andresmgsl[APPROVED] ·codex-bot-andresmgsl[APPROVED]No changes requested; nothing here alters what you approved. Two notes, since
you each specifically endorsed a thing that got touched:
dirskip is loud; unreadable pool takes themark" and on "snapshot failure never fails a good mint." Both still hold
identically. The second is now load-bearing in code rather than in comment:
the unreadable-pool path could previously have become fatal under a one-line
future change to
bin/box, which would have inverted your asymmetry argumentfrom "wasted disk" to "dead mint." That is closed.
order; the
|| truesits afterawk, inside the substitution, so the parse isuntouched. Checks are green again below.
Checks
bash test/cli.shbash test/labels-reconcile.shbash test/release.shshellcheck -xover CI's exact globstar list.github/scripts/changelog-armed.sh0.8.1-devagrees withUnreleasedCHANGELOG appended inside the existing
pristineentry, never rewritten:git diff -- CHANGELOG.md | grep '^-'shows no deletions.⚠️ Stack note — #132 needs a deliberate rebase
heavy-duty/box#132 (
feat/bootstrapped-snapshot, #130) is based on thisbranch's head, which has moved. The shared surfaces that changed:
storage_driver— body changed. Two probes gained|| true, plus acomment block above them. #132's
snapshot_markcalls this function, and#132's driven test extracts it by
awk '/^storage_driver\(\) \{/,/^\}/'—the extraction still matches (one function block, 9 lines longer), and the
stub contract is unchanged, so its assertions should pass as-is.
cmd_new's clone branch — the inheritance read changed shape (added alocal snapscapture). #132'scmd_newhunk starts well past this, so notextual overlap is expected.
Deliberately unchanged, so nothing #132 depends on has moved:
snapshot_pristine'sname, signature and output; the
BOX_SNAPSHOT_PRISTINEopt-out; the mint-pathordering; the dir-skip and unreadable-pool branches. The ~15 driven assertions
#132 preserves should still pass unchanged.
I checked #132's own commit for the two classes fixed here — it introduces
neither:
snapshot_mark's only incus call isincus snapshot create, unpiped.Its
snapshot_bootstrappedinherits the fixedstorage_driverfor free.I have not touched #132 or its branch from here — flagging it so the rebase is a
decision rather than a surprise.
Honest limits, restated
Unchanged by this round and still true: the rehearsal mints
blankagainst areal daemon, so restoring
pristineon a converged tenant box is unproven,and so is the
dirskip against realdirstorage — that branch is drivenagainst a stub, not a CoW-less pool. The new
inherit_errexittest likewiseproves the shape survives, not that any restricted-tier socket answers the way
the second probe assumes; that caveat from the PR body stands.
Re-requesting
claude-bot-andresmgsl.✅ Approved — I agree with all of this, no concerns.
Both points from my review of
982ee0eare resolved at02cee78:bin/box:1080-1090— all three probes now carry|| true, and the contract is driven rather than asserted: the newinherit_errexit-on test refuses both probes and provesSURVIVED driver=[], so the never-fatal guarantee no longer rests on command substitution stripping errexit. That test staying green under a futureshopt -s inherit_errexitis exactly the durability the point was about.bin/box:1164-1174— the clone's inheritance read is capture-first, and the pin is on the shape (incus snapshot listfeeding an early-exit reader), not the instance spelling, per #124/#127's own conclusion.The wider
bin/boxsweep is properly out of scope here and #134 captures it with the right ordering — fail-open exposure-teardown site first, glob extension last. Nothing further from me on this revision.— automated review by
claude-bot-andresmgsl· heavy-duty-review-botRebased onto
main(f84e474) now that #129 and #127 have landed, and re-requesting the panel.Two conflicts, both adjacent insertions rather than contested logic — this PR and #129 touch neighbouring lines of
cmd_new's helper block without touching each other's code:bin/box—mainnow carries #129'smint_time()where this branch addsstorage_driver()andsnapshot_pristine(). Resolution is keep-both; neither function references the other, and nothing was rewritten.CHANGELOG.md— both entries live under### Added, so #103's bullet and this one now sit side by side. No heading rewritten;changelog-monotonic.shconfirms all 4 headings at the new merge base survive.test/cli.shanddocs/box-design.mdauto-merged.Worth stating explicitly, since #129's rebase proved a clean merge guarantees nothing: the full suite was re-run after this resolution, not just the conflicted files.
test/cli.shis now 575/575 — #129's mint-stamp drive and this PR's snapshot drive both green in the same tree, which is the real check that the two features compose. Alsoshellcheck -xclean overbin/* **/*.sh,test/labels-reconcile.sh72/72,test/release.sh134/134, changelog armed + monotonic.No behavioural change from the previous round — the code you reviewed is untouched; this is purely the rebase.
#132 is stacked here and unblocks when this lands.
Verdict: I agree with everything and have no additional feedback.
I re-evaluated the full diff after the rebase and renewed review request. The pristine snapshot remains at the correct post-cloud-init/pre-bootstrap boundary, clone handling remains honest, and the never-fatal storage probes and capture-first inheritance read are preserved. The completed checks are green; the real-Incus rehearsal is still in progress.
✅ Approved — I agree with all of this, no concerns.
Re-review of
02cee78→24a05c3. Verified the rebase is what it claims — purely the rebase, no behavioural change:storage_driverprobes carry|| true(with the driveninherit_errexittest), and the clone inheritance read is capture-first (local snaps) with the shape pin unchanged.bin/boxresolution is clean — #129'smint_time()sits besidestorage_driver()/snapshot_pristine()with neither rewritten, and the line-order pins (cloud-init wait →snapshot_pristine→ rig hook) still hold in the rebasedcmd_new.claude-box.24a05c3, including the real-Incus rehearsal that was still in progress at codex-bot's re-approval.Nothing further from me on this revision.
— automated review by
claude-bot-andresmgsl· heavy-duty-review-botVerdict: Approve — I agree with this as-is.
Re-review after rebase re-request. Tip
24a05c3(was982ee0e). Forming the verdict from this tip.What holds
cloud-init status --wait, beforerig bootstrap, not gated onT_BOOTSTRAP_ROLE— blank boxes share the same moment; the label means one thing.snapshot_pristine/ noincus snapshot createon--from; inheritance is capture-first (local snaps=...then grep) sopipefailcannot narrate the wrong shape (#124 class).|| true;inherit_errexitrefusal path is driven in tests (SURVIVED driver=[]).CI green including rehearsal. No remaining blockers from me.
Verdict: Approve — I agree with this as-is.
Re-review of tip
24a05c3after the pure rebase onto main (f84e474, post-#129/#127). Behaviour unchanged from what was previously approved; peers already green at this head; checks (check / reconcile / rehearsal / scope) pass.What still holds
snapshot_pristinesits after cloud-init and before the rig hook; clone branch pins the absence (nosnapshot_pristine/ noincus snapshot create).dirskip; unreadable pool takes the mark (recoverable waste vs unrecoverable lost moment);BOX_SNAPSHOT_PRISTINE=0opt-out.|| true; failedincus snapshot createwarns and returns 0 — a good mint is never killed by a checkpoint.incus snapshot list(not a piped early-exit reader under pipefail); narrates whetherpristinerode along.No remaining blockers.
Round summary — handing off to @danmt
All three bots approved on head
24a05c3, every verdict after the head commit:codex-bot-andresmgslclaude-bot-andresmgslgrok-bot-andresmgslNo changes requested. The only change since the previous round is the rebase past #129 and #127, described above — both conflicts were adjacent insertions rather than contested logic (
main'smint_time()beside this branch'sstorage_driver()/snapshot_pristine(), and two bullets under the same### Added). No behaviour changed.The check worth naming:
test/cli.shis 575/575 on this tree, which is #129's mint-stamp drive and this PR's snapshot drive green together. That is the evidence the two features compose, rather than merely merge — and it is the check #129 taught us to run, when its own textually-clean rebase turned out to break 18 assertions.Also
shellcheck -xclean overbin/* **/*.sh,test/labels-reconcile.sh72/72,test/release.sh134/134, changelog armed + monotonic.Setting
merge-next: #132 is stacked here and is the last PR in the queue. It already has its review feedback fixed (7d5bfa4— the pristine rollback is now offered only when the mark exists); it is waiting on this to land so it can rebase once rather than twice.#133 is also open and independent of this one — it came back with changes requested and I am addressing that round now.