R-280: attach list from mounted-but-unregistered filesystems; two-clicks promise made conditional
gates / gates (push) Successful in 17s

After a reinstall the data drive could not be re-attached through any dashboard
route: both candidate lists came from the agent's unclaimed-disk scan, and the
rebuilt box's drives are claimed. The restore page said it was two clicks while
pointing at an empty picker.

The attach list now also carries the controller's own mounted-but-unregistered
filesystems. initialize is untouched, so the format wizard's system/backup
protection is unchanged. The 'two clicks' sentence is conditional on the picker
being non-empty, and says something true and actionable when it is not.
This commit is contained in:
2026-08-10 13:41:32 +02:00
parent c732fe1283
commit b762a37097
9 changed files with 600 additions and 12 deletions
+37
View File
@@ -1,3 +1,40 @@
## v0.211.0 — the wall a rebuilt box could not get past (2026-08-10, R-280) — MinAgent 0.127.0
**R-280 — after a reinstall the data drive can be re-attached, and the page stops promising a click
that does not exist.** Measured on the rebuilt demo-hp 2026-08-09: the restore page diagnosed the
situation perfectly, said *„Ez két kattintás"*, and pointed at a picker holding nothing. It was zero
clicks; getting past it needed an internal path no customer could produce.
**Why the obvious fix would not have worked, kept here because it cost the session an hour.** The
agent builds BOTH `initialize` and `attach` from its unclaimed-DISK scan, and widening that scan is
the fix the finding proposed. But the filesystem a rebuilt box must re-register is an **in-guest**
one — on demo-hp `/mnt/sys_drive`, the guest's own 70 GB data volume, which is what the escape hatch
actually registered. The agent enumerates HOST block devices and would have offered the 1 TB NVMe
(the `felhom-backup` target): the wrong drive, non-destructively attached, customer data still
unreachable. **So this ships in the controller and the agent is unchanged** — MinAgent stays 0.127.0.
- **`attach` now also carries the controller's own mounted-but-unregistered filesystems**
(`internal/web/attach_sources.go`), read from its own mount table — the controller runs in-guest
with `/mnt` bind-mounted in, so what it can see is what it can register. `initialize` is passed
through **untouched**: the format wizard's system/backup protection lives in the agent's scan and
is not widened by a single line here (pinned by `TestMergeAttachCandidates_InitializeIsUntouched`,
whose red-proof put the customer's data volume in the FORMAT list).
- **A union, not a replacement.** The agent's entries serve the case this wizard was built for — a
fresh external drive carrying a filesystem, not yet mounted — which a mount table cannot report
precisely because it is not mounted. Dropping them would fix the reinstall and break the USB.
- **These candidates are REGISTERED in place, never mounted** (`POST /api/storage/register-mounted`).
The posted path is re-derived server-side and refused if it is not currently offered, so the route
cannot register an arbitrary directory.
- **The „két kattintás" sentence is now conditional on the picker being non-empty**, and the false
branch says what is true and names a route. Both branches are render-tested.
- **Exclusions, each with a reason in the code:** the guest rootfs at `/mnt`, the intermediary-model
parent `/mnt/felhom-drives`, tmpfs/overlay, anything outside `/mnt/`, non-ext4/xfs, already-
registered paths — and **any bind alias of the rootfs, excluded by DEVICE**, because a bind
republishes a filesystem under a second path and registering that one would put app data on the
box's own root. That last guard was found by trying to build the live reproduction, not by review.
- **Fail-safe:** an unreadable mount table yields an EMPTY list, never a permissive one — and because
the page gates its promise on that list, "we could not look" renders as "we cannot offer this".
## v0.210.0 — two pictures that were not true (2026-08-08, R-259 / R-258) — MinAgent 0.127.0
Both are the same shape: something the box already knows, drawn as its opposite.