The pre-0.7.0 migration manufactures a version entry nobody installed, and never mentions it #117

Closed
opened 2026-07-19 23:12:54 +00:00 by dan-claude-bot · 0 comments
dan-claude-bot commented 2026-07-19 23:12:54 +00:00 (Migrated from github.com)

Found during the 0.8.0 release drill. Distinct from #115, which is about setup-host being skipped by the same migration — this one is about the tree the migration leaves behind.

What happens

Installing 0.7.0+ over a pre-0.7.0 flat /opt/box converts that flat tree into the versioned layout, creating /opt/box/versions/<old-version>/. On the drill host, a flat 0.6.0 install became versions/0.6.0, and after installing 0.8.0 the machine had:

$ box versions
VERSIONS  (/opt/box)
  0.6.0
  0.8.0 (current) (running)

0.6.0 is now a first-class entry in box versions — a version the operator never installed into that layout, has no reason to keep, and was never told about. Nothing reaps it, nothing mentions it, and it stays there indefinitely.

Why it is a defect and not just untidiness

The install output never names it. The migration is silent. An operator who ran sudo bash install.sh to get 0.8.0 has no way to learn a second tree now exists short of running box versions and noticing an entry they did not put there.

It is indistinguishable from a deliberate rollback target. box versions is also how an operator sees versions they intentionally kept for box use. A migration-manufactured entry looks identical to one they chose, so the natural reading of that list is wrong.

It quietly contradicts uninstall's own contract. box uninstall --all promises "everything: every version, the current and PATH symlinks" — and it does remove the orphan, correctly. But the asymmetry is that install created a version entry the operator never asked for, so the install/uninstall pair is not symmetric even though each half behaves as documented.

Not a removal bug — verified

To be precise about severity: the tree is removable through the normal path, and it worked first try on the drill host:

$ sudo box uninstall 0.6.0
box: removed version 0.6.0 (the default stays 0.8.0)

So this is a discoverability and lifecycle problem, not an unremovable-garbage problem. Filing it because nothing surfaces the orphan, not because anything is stuck.

Scope

Same population as #115: hosts upgrading from a pre-0.7.0 flat /opt/box. Hosts already on the versioned layout never trigger the migration and are unaffected.

Suggested fix

Cheapest honest option: say so. Have the migration print what it did and what it left — "migrated the existing flat 0.6.0 install to versions/0.6.0; remove it with box uninstall 0.6.0 if you do not need a rollback target." That turns an invisible artifact into a decision, costs nothing, and preserves the rollback option for anyone who wants it.

Deleting it automatically is the wrong default: the pre-existing install is the only thing to roll back to if the new version misbehaves, and this runs at exactly the moment that matters.

Worth considering alongside #115, since both come from the same migration block and a single pass could address the reporting for both.

Refs

Found during the release: 0.8.0 drill (#114). Closely related: #115 (the same migration skipping setup-host, which is the more serious half). Context: #71 (the global-install requirement making /opt/box operative).

Found during the 0.8.0 release drill. Distinct from #115, which is about `setup-host` being skipped by the same migration — this one is about the tree the migration leaves behind. ## What happens Installing 0.7.0+ over a **pre-0.7.0 flat `/opt/box`** converts that flat tree into the versioned layout, creating `/opt/box/versions/<old-version>/`. On the drill host, a flat 0.6.0 install became `versions/0.6.0`, and after installing 0.8.0 the machine had: ``` $ box versions VERSIONS (/opt/box) 0.6.0 0.8.0 (current) (running) ``` `0.6.0` is now a first-class entry in `box versions` — a version the operator never installed into that layout, has no reason to keep, and was never told about. Nothing reaps it, nothing mentions it, and it stays there indefinitely. ## Why it is a defect and not just untidiness **The install output never names it.** The migration is silent. An operator who ran `sudo bash install.sh` to get 0.8.0 has no way to learn a second tree now exists short of running `box versions` and noticing an entry they did not put there. **It is indistinguishable from a deliberate rollback target.** `box versions` is also how an operator sees versions they intentionally kept for `box use`. A migration-manufactured entry looks identical to one they chose, so the natural reading of that list is wrong. **It quietly contradicts uninstall's own contract.** `box uninstall --all` promises "everything: every version, the current and PATH symlinks" — and it does remove the orphan, correctly. But the asymmetry is that install *created* a version entry the operator never asked for, so the install/uninstall pair is not symmetric even though each half behaves as documented. ## Not a removal bug — verified To be precise about severity: the tree **is** removable through the normal path, and it worked first try on the drill host: ``` $ sudo box uninstall 0.6.0 box: removed version 0.6.0 (the default stays 0.8.0) ``` So this is a **discoverability and lifecycle** problem, not an unremovable-garbage problem. Filing it because nothing surfaces the orphan, not because anything is stuck. ## Scope Same population as #115: hosts upgrading from a pre-0.7.0 flat `/opt/box`. Hosts already on the versioned layout never trigger the migration and are unaffected. ## Suggested fix Cheapest honest option: **say so**. Have the migration print what it did and what it left — "migrated the existing flat 0.6.0 install to versions/0.6.0; remove it with `box uninstall 0.6.0` if you do not need a rollback target." That turns an invisible artifact into a decision, costs nothing, and preserves the rollback option for anyone who wants it. Deleting it automatically is the wrong default: the pre-existing install is the only thing to roll back to if the new version misbehaves, and this runs at exactly the moment that matters. Worth considering alongside #115, since both come from the same migration block and a single pass could address the reporting for both. ## Refs Found during the `release: 0.8.0` drill (#114). Closely related: #115 (the same migration skipping `setup-host`, which is the more serious half). Context: #71 (the global-install requirement making `/opt/box` operative).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: heavy-duty/box#117
No description provided.