Make tool-managed lane splits visually transparent: collapse display + lazy-mint

Drive C_LANESCOLLAPSED=2 and hide lane buttons only on tracks the tool itself splits
(gated on the pre-write I_FREEMODE read, so user comp-lane display prefs are never
stomped). Lazy-mint managed lanes only for modes with own content, never an empty
reserved lane; confinement holds via C_LANEPLAYS on the lone lane.
This commit is contained in:
2026-07-24 05:44:19 -04:00
parent ff2c3ebce5
commit 314cd7bf36
4 changed files with 131 additions and 23 deletions
+60 -5
View File
@@ -1235,9 +1235,11 @@ static void testLaneMintingThreeModesAndOwnershipKeys() {
// The exact failing case. A folder {F} has descendant leaves in BOTH modes ({LD} Design,
// {LA} Arrange) and carries ONE OWN item ({own}) tagged Design. W3-A's own-item-span test
// alone would NOT split {F} (its own content is single-mode Design), so the item leaked
// into every mode the folder was derived-visible in. The visibility-aware decision now
// mints managed lanes on {F} and lanes {own} onto the Design lane — so it hides+silences
// whenever Arrange is active. This is the load-bearing fix; assert it hard.
// into every mode the folder was derived-visible in. The visibility-aware decision splits
// {F} and lanes {own} onto the Design lane — so it hides+silences whenever Arrange is
// active. LAZY-MINT: {F} mints ONLY the Design lane (holding the item), NOT an empty
// reserved Arrange lane — confinement holds via C_LANEPLAYS=0 on the lone Design lane when
// Arrange is active. This is the load-bearing fix; assert it hard.
static void testLaneMintingFolderDerivedVisibleSplitsOwnMedia() {
ViewModeModel vm;
vm.membership().tag("{LD}", kDesignModeId); // a Design leaf under the folder
@@ -1264,17 +1266,69 @@ static void testLaneMintingFolderDerivedVisibleSplitsOwnMedia() {
// {F} MUST split even though its own item is single-mode: it is visible in 2 modes.
CHECK(!plan.empty());
CHECK(splitLaneCount(plan, "{F}") == 2); // one lane per stance
// LAZY-MINT: ONE lane only — the Design lane that holds the item. No empty reserved
// Arrange lane is minted, even though {F} is derived-visible in Arrange. The Arrange
// lane appears on demand when an Arrange item first lands on {F}.
CHECK(splitLaneCount(plan, "{F}") == 1); // Design lane only — no reserved lane
CHECK(plan.mints.size() == 1);
CHECK(hasMint(plan, "{F}", kDesignModeId)); // Design lane (holds the item)
CHECK(hasMint(plan, "{F}", kArrangeModeId)); // Arrange lane (reserves the slot)
CHECK(!hasMint(plan, "{F}", kArrangeModeId)); // NO empty reserved Arrange lane
// The own item is confined to its tagged (Design) lane — the exact hide-in-Arrange fix.
// With only the Design lane present, toggling to Arrange sets its C_LANEPLAYS to 0, so
// the item hides+silences and the track reads as an empty normal track (no leak).
CHECK(plan.assigns.size() == 1);
CHECK(hasAssign(plan, "{own}", "{F}", kDesignModeId));
for (const auto& a : plan.assigns)
CHECK(!(a.itemGuid == "{own}" && a.laneKey == laneNameForMode(kArrangeModeId)));
}
// LAZY-MINT confinement proof. Same single-own-mode / dual-visibility folder, but instead
// of asserting the mint COUNT we prove the FUNCTIONAL confinement the lazy split preserves:
// apply the minted lane's ownership to a live model, then drive the toggle planner and show
// the lone Design lane SILENCES when Arrange is active (C_LANEPLAYS = 0). That is the whole
// point — a single managed lane still hides its item in every other mode, so removing the
// empty reserved Arrange lane costs nothing functionally. Fails if the split ever leaves the
// Design item audible in Arrange (the leak the D2 fix closed) or mints a spurious lane.
static void testLaneMintingLazySingleLaneStillConfines() {
ViewModeModel vm;
vm.membership().tag("{LD}", kDesignModeId); // Design leaf ⇒ folder visible in Design
// {LA} untagged ⇒ Arrange member ⇒ folder ALSO derived-visible in Arrange.
vm.membership().tag("{own}", kDesignModeId); // the folder's one own item (Design)
FolderTree tree;
tree.nodes.push_back(FolderNode{"{F}", "", /*isParent=*/true});
tree.nodes.push_back(FolderNode{"{LD}", "{F}", false});
tree.nodes.push_back(FolderNode{"{LA}", "{F}", false});
std::vector<LaneTrack> tracks{
LaneTrack{"{F}", {LaneItem{"{own}", kDesignModeId, false}}},
};
const LaneMintPlan plan = planLaneMinting(vm, tree, tracks);
// Exactly one lane minted (the Design lane) — no empty reserved Arrange lane.
CHECK(plan.mints.size() == 1);
CHECK(hasMint(plan, "{F}", kDesignModeId));
// Apply the mint's ownership exactly as the shell does, then drive the toggle planner.
for (const auto& m : plan.mints)
CHECK(vm.lanes().setManaged(m.trackGuid, m.laneKey, m.modeId));
CHECK(vm.lanes().size() == 1); // one managed lane on {F}, not two
const std::string designLane = laneNameForMode(kDesignModeId);
// Active = Design: the lone Design lane PLAYS (item visible+audible in its own mode).
const auto design = vm.planToggle(tree, kDesignModeId);
CHECK(lanePlaysFor(design, "{F}", designLane) == kLanePlaysExclusive);
// Active = Arrange: the lone Design lane SILENCES — with no lane playing, the track
// reads as an empty normal track and the Design item does NOT leak. This is the
// confinement guarantee that lets us drop the reserved Arrange lane.
const auto arrange = vm.planToggle(tree, kArrangeModeId);
CHECK(lanePlaysFor(arrange, "{F}", designLane) == kLaneSilent);
}
// A folder carrying its OWN items that already span both modes → still split (the two
// triggers OR: own-item span AND derived visibility both point the same way here). Both
// own items separate to their tagged lanes.
@@ -1470,6 +1524,7 @@ int main() {
testLaneMintingManualLaneExempt();
testLaneMintingThreeModesAndOwnershipKeys();
testLaneMintingFolderDerivedVisibleSplitsOwnMedia();
testLaneMintingLazySingleLaneStillConfines();
testLaneMintingFolderOwnItemsSpanBothModes();
testLaneMintingShowBothNotForceSplit();
testLaneMintingSingleModeLeafVisibleOnceNoSplit();