Two defects the V2 boundary review confirmed:
1. The per-badge range table was never reclaimed. usb-storage receives exit
notifications (via the subscriber watch), but onNotification handled only
the timer and dropped child-exits, so a dead filesystem left its range
slot used forever. The medium-removal lifecycle churns filesystems, so
after maximum_ranges confine/die cycles define_range would return ENOSPC
and no volume could be confined again until reboot. onNotification now
frees the dead badge's slot, mirroring fat's open-node sweep.
2. define_range checked only that the CALLER was unconfined, never that it
owned the target badge — so any unconfined opener could install a range
for another live client and silently redirect its I/O. Confinement now has
a single controller: the first unconfined party to define a range (the
volume manager, which confines every filesystem before handing it a
channel). Only the controller may thereafter; the slot releases on its
death so a restarted manager re-takes it. This is the mechanism half; V3
adds the grant half (only the volume manager gets an unconfined channel).
Neutral: block-range (the fixture is the sole definer -> controller),
fat-mount, usb-report all green. End-to-end exercise of both lands in V3/V4
(the VM+filesystem relationship and the remount churn).