SQ6 over-capture FIXED for classified apps: the userdata root tar is exclude-scoped (keeps only
ancestors/descendants of a SELECTED bind relpath — R1-C, the tier2Reconcile keep-rule); no selected
userdata bind → no root tar (radarr state-only). New appbackup.ComputeFabBuckets (shared
resolveGuardCollapse pipeline; class buckets; guards over ALL classes; no cross-bucket containment).
appexport/fabplan.go: computeFabPlan + tarDirectoryExcluding + fabEstimateSplit. ExportRequest gains
DeselectOptional/OptInExcluded (both start handlers — two-call-site); mandatory is a server-side
floor. Manifest v1 + import UNTOUCHED; legacy apps byte-identical to v0.130.0. Estimate additive
class split; export UI: locked-mandatory/optional-checkboxes/excluded-opt-in + two-number warning.
All 6 §10 red-proofs verified. 6D Accept #1 now runs against this shape.
executeExport no longer either/or gates user data on needs_hdd — a needs_hdd
app bundles BOTH its HDD mounts and its named volumes (sonarr_config = the
whole app DB was silently dropped pre-fix). exportHDDData returns error and
fails LOUDLY on a basename collision between mounts (the manifest keys tars by
basename; the old code silently overwrote the first tar). EstimateExport made
additive to match, so the fits-on-dest gate counts both. Round-trip placement
test proves a userdata tar restores to <HDD_PATH>/userdata through the
untouched import mapping. Red-proofs recorded: either/or revert fails
scenario A; collision-check removal fails the collision test.