v0.127.0: a mount Felhom itself made is not 'something else' (R-220)
gates / gates (push) Successful in 8s
gates / gates (push) Successful in 8s
After a rebuild the customer's own drives could not be re-attached: candidates returned initialize:[] attach:[] while both drives sat there, and the deploy refused with 'choose an attached drive from the list' — a list that was empty. Measured live three times. Mechanism: enrolment mounts a drive TWICE, at /mnt/felhom-drives/<name> and at the raw /mnt/<name> it creates on the host. The host survives a guest rebuild; the controller's registry does not. So classifyClaim saw a mount outside the managed prefix and concluded 'claimed by something else' — about our own mount. The fix is CORROBORATED, not a widened prefix: a non-managed mountpoint is forgiven only when the SAME device is also mounted under the managed path, a pairing only our enrolment produces. A disk another system uses — /srv/data, /media/x, even /mnt/someone-elses-disk — has no counterpart and is STILL refused, with its own test and a red-proof showing an over-wide fix offering it for formatting. Read from /proc/mounts deliberately: the lsblk invocation is pinned verbatim in configs/felhom-agent.sudoers, so using the plural MOUNTPOINTS would have coupled this to a sudoers rollout. /proc/mounts is world-readable — no sudo, no new allowlisted command, no config change. Fail-safe: an unreadable mount table corroborates NOTHING, so the device classifies exactly as before. 'Could not corroborate' must never read as 'ours'. 29 packages ok, vet clean, agent gates OK.
This commit is contained in:
@@ -1,3 +1,36 @@
|
||||
## v0.127.0 — a mount Felhom itself made is not "something else" (2026-08-06, R-220)
|
||||
|
||||
**After a rebuild the customer's own drives could not be re-attached, and the refusal named an action
|
||||
they could not perform.** `GET /api/disks/candidates` returned `initialize: [], attach: []` while both
|
||||
drives sat there, and the deploy refused with *"choose an attached drive from the list"* — a list that
|
||||
was empty. Measured live **three times**: CAMPAIGN-11 Phase 1, and twice on the R-201 re-walk.
|
||||
|
||||
**The mechanism.** Enrolment mounts a drive **twice** — at the managed `/mnt/felhom-drives/<name>` and
|
||||
at the raw `/mnt/<name>` it creates on the host. **The host survives a guest rebuild; the controller's
|
||||
registry does not.** So `classifyClaim` saw a mount outside the managed prefix and correctly concluded
|
||||
"claimed by something else" — about Felhom's own mount.
|
||||
|
||||
**The fix is CORROBORATED, not a widened prefix.** A mountpoint outside `/mnt/felhom-drives` is
|
||||
forgiven **only when the same device is ALSO mounted under the managed path** — a pairing that only
|
||||
Felhom's own enrolment produces. A disk another system is using, at `/srv/data` or `/media/x` or even
|
||||
`/mnt/someone-elses-disk`, has no such counterpart and **is still refused**. That fence has its own
|
||||
test, and its red-proof shows an over-wide fix offering `/mnt/someone-elses-disk` for formatting.
|
||||
|
||||
**Read from `/proc/mounts`, deliberately.** The lsblk invocation is pinned **verbatim** in
|
||||
`configs/felhom-agent.sudoers` (`lsblk -J -o NAME,FSTYPE,PTTYPE,MOUNTPOINT /dev/*`), so switching it to
|
||||
the plural `MOUNTPOINTS` would have meant shipping a sudoers change with the binary — a far larger
|
||||
blast radius than this finding warrants. `/proc/mounts` is world-readable: **no sudo, no new allowlisted
|
||||
command, no config change.**
|
||||
|
||||
**Fail-safe:** an unreadable mount table corroborates **nothing**, so the device classifies exactly as
|
||||
it did before this change — refused. "We could not corroborate" must never read as "it is ours".
|
||||
|
||||
Tests: `claim_r220_test.go` — the own-drive case, the foreign-mount fence over four paths, and the
|
||||
corroboration itself (both mounts required; a lone raw mount vouches for nothing; another device's
|
||||
managed mount does not vouch for this one; an unreadable table corroborates nothing).
|
||||
**Red-proofs:** removing the exemption refuses the customer's own drive again
|
||||
(*"device is mounted at /mnt/adatok (sdb)"*); over-widening it to any `/mnt/*` path breaks the fence.
|
||||
|
||||
## docs — CLAUDE.md becomes a core plus path-scoped rules (2026-08-06, R-229 leg (b)) — no version bump
|
||||
|
||||
**Documentation only. No Go changed, nothing built, nothing deployed.** `go build`/`vet`/`test` green
|
||||
|
||||
Reference in New Issue
Block a user