diff --git a/docs/plans/2026-09-07-campaign-vt-slice7-tabs.md b/docs/plans/2026-09-07-campaign-vt-slice7-tabs.md index 315af5b8..07e6c661 100644 --- a/docs/plans/2026-09-07-campaign-vt-slice7-tabs.md +++ b/docs/plans/2026-09-07-campaign-vt-slice7-tabs.md @@ -150,3 +150,6 @@ re-review, merge to the campaign branch, then the owner's visual gate. - 2026-09-07 20:50 round F landed on the panel worktree (`279de7c2d` merge of the campaign branch; `ad3f4df57` Advanced Options bottom block gone, popup 392×300 resizable; `9e23f0acb` `tString` hidden; `179e6f339` Items tab VTank-only (`RefillWornMana*` stay catalog settings); `6ef6eb751` recall combo 120 wide with VTank's 27 terse captions; `bae34aaa8` Monsters filler column; `837610593` Buffs strip / Loot Editor Back removed / Route count column 30 px; `13a304a92` ledger; MossTank suite 722 → 726, App filter 258 → 262). Deviation: the Buffs extras strip is centred at the 856 floor, not at the 984 default (a fixed strip can be centred at one width only; accepted under "polish later"). Final combined re-check (both lenses, E+F) dispatched; then merge + gate build. - 2026-09-07 round E (architecture re-check of round D) landed on the same worktree, six commits, base `2b79ca325`: `3178d9202` (D-4 — an .af "rcl" node whose spell name fails to resolve leaves RecallSpellId at 0 and Recall at its default ordinal, PrimaryPortalRecall; SubmitRecall's own Recall-based fallback used to cast spell 48 for it regardless, since MetafSerializer.ReadNavNode never touches the enum on that path — TickRecall now refuses and skips instead, naming the unresolved spell in the status notice; the dead fallback branch is removed). `a9d1d0a82` (D-1 — the pre-cutover RouteRecallKind was {Lifestone=0, Marketplace=1, PrimaryPortal=2, SecondaryPortal=3}, completely different kinds at the SAME ordinals as the round-D enum, and Enum.IsDefined never caught the silent remap since 0..3 are all still valid new members; LegacyWaypointDocument.Recall is now a bare int translated through an explicit MapLegacyRecall table that also derives RecallSpellId/RecallSpellName). `3fe304359` (D-2 — RouteRecallNames/SelectedRouteRecall showed Enum.GetNames/ToString()'s bare C# identifiers; both now route through RouteWaypoint.RecallDisplayName like RouteInsertModeNames/RouteModeNames already do, SelectRouteRecall parses the same display string back, and the combo widened 120->300 to fit VTank's own full metaf-sourced names, e.g. "Paradox-touched Olthoi Infested Area Recall" — VTank's real combo is also 120 wide only because ITS captions are hand-abbreviated). `64b62fea3` (D-3 — mosstank.xml's own top comment already claimed the Advanced Options popup got resizable+anchored treatment; the popup file itself still carried the dead resize="none", never actually resizable; now resizable="true" minw/minh floored at the pre-fix authored 392x450, lOptionList grows WIDTH ONLY since the value field/description/notice sit directly below with zero vertical slack and none of them anchor to shift down, lFilterList tracks the growing right edge in lockstep so the widening list never walks into it; AdvancedOptionDescription is declared anchor="left top right" for consistency but documented as a real no-op — UiLabel.OnDraw always overwrites Width/Height to the measured text extent every draw, so nothing a label's anchor computes is ever visible). `1a0b0e014` (D-5 — RefreshAdvancedOptions' own doc comment lists every mutation site that must call it, but ShowAdvancedOptions itself was missing one, so a setting changed via /vt opt set or an Options-tab checkbox while the popup was closed stayed stale until some in-popup interaction refreshed it; ShowAdvancedOptions now calls RefreshAdvancedOptions). `7badbee88` (D-6 — a new whole-tree resolved-geometry pin at the main panel's minw/minh floor (856x236) and one enlarged size (1100x320), adapting AssertNoSiblingOverlap/AssertWithinParent's rectangle-overlap algorithm from the authored XElement tree to the resolved UiElement tree for each of the nine tabs in turn; building the test surfaced and fixed two real test-methodology bugs along the way — reusing one built tree across tabs let an earlier tab's resize corrupt a later tab's anchor-capture baseline, and walking into an invisible tab group's never-anchored-for-this-size descendants misreported stale geometry as broken — plus one genuine test-harness false positive (UiLabel's font-dependent measured box, excluded from the size checks for the same reason D-3's own commit documents). Every new/changed test shown to fail first via a targeted revert-then-reapply (git checkout + saved patch) or a deliberate markup mutation (D-6's Monsters-anchor removal), each restored green afterward. MossTank suite 715 (pre-round-E baseline, matching round D's close) -> 716 (D-4) -> 720 (D-1) -> 721 (D-2) -> 721 (D-3, App-side only) -> 722 (D-5); App markup/plugin filter 243 -> 243 (D-2 widened menu, no new pin) -> 244 (D-3) -> 246 (D-6, two theory cases). Full solution builds clean in Release throughout. Carried, accepted deviations unchanged from round D: #491 (buff-list wiring) and (now closed by D-1) the former pre-cutover-JSON RouteRecallKind-ordinal migration risk. Scrollbar snap-back fixed App-side and merged (`b4fe18007`: the list re-centred on its selected row every frame). Round F dispatched (merges the campaign branch; the owner's second-look items 1/3/4 + VTank's terse recall captions at 120 wide + Monsters filler column + Buffs/Loot Editor/Route nits). After F: one combined final re-check, merge, gate build. - 2026-09-07 round F landed on the panel worktree, six commits, base `279de7c2d` (merge of `claude/latest-main-sync-497549` — `7b7e5e579` no selection band by default on plugin lists, `3d7065ebc` geometry-hash window revision, `b4fe18007` scrollbar snap-back fix; resolved the UiMarkupList/plugin-ui-markup/ledger conflicts keeping both sides' intent, including retiring the now-dead opt-in `` doc section in favor of "menus always scroll"). Item 1 (`ad3f4df57`): the whole Advanced Options bottom block — the "Editing X." notice and the "MossTank Extras" section (Checkpoint/Jump/Remove/Set Follow Target/Follow Corners/Open Doors/Nav Priority/Follow-Nav min distance) — is gone; popup back to VTank's 392x300. Every removed control had a real path already: Checkpoint/Jump via `/mt addnavcheckpoint`/`/mt addnavjump`, Remove via the Route tab's own click-to-delete grid (DeleteRouteWaypointAt — identical logic to the removed RemoveRouteWaypointCore), Set Follow Target via re-selecting "Follow" in the Route tab's own nav-mode menu (already calls CaptureFollowTarget), and the four toggles/stepper via their own real VtankOptionCatalog entries (FollowAroundCorners/OpenDoors/NavPriorityBoost/NavCloseStopRange), still listed in THIS SAME shrunk popup. Item 2 (`9e23f0acb`): `FilteredAdvancedOptionNames` now excludes every `tString` row (BuffProfile-Prots/-Banes, BlacklistedSpellComps) — VTank's own Advanced Options list has no case for tString at all (KB 01, db.cs:132-166/:201-203) — closing the owner's "duplicated" BuffProfile report; the enum counterparts stay listed. Item 3 (`179e6f339`): Items tab's right-of-list MossTank block (Weapon/Offhand readout, Refill Worn Mana toggle/slider/status, the notice hint) is gone; RefillWornMana/RefillWornMana-Item-ManaPercent remain real catalog settings, editable in Advanced Options. The pre-campaign "Remove" button (traced to the plugin's very first commit, `4e6e9bc9d`) stays as the accepted slice-1 exception. Item 4 (`6ef6eb751`): the recall combo shows VTank's own terse cmbRecallType captions (RecallShortCaption, transcribed from the KB's mainView.xml citation since this worktree has no refs/vtank/ checkout) instead of round E's full spell names, back at VTank's real 120px width; the full name still lands on the waypoint/grid row/.af via RecallDisplayName, untouched. Item 5 (`bae34aaa8`): a 24th, genuinely-handled trailing filler column after Monsters' MoveDownIcons so it is no longer the grid's LAST column (docs/plugin-ui-markup.md's "last column always auto" rule) and keeps its declared 23px pitch — the arrows now stay a fixed ~23px apart at both 984 and 1100 wide, proven wrong first (89.5px/147.5px gaps against the unmodified file). Item 6 (`837610593`, three nits): Loot Editor's leftover "Back" button is gone (the title bar closes it, matching every other popup since round D); Route's count column narrows the text column 337->324 AND adds a trailing filler so 324+30 exactly matches the scrollbar-reduced 354px width (a filler alone was proved insufficient by mutation — still clamped to 17px); Buffs' Coverage label moved from the group's anchored bottom edge (a 55px hole) to sit right under the Buff button row. Buffs' "136px gap" turned out geometrically unclosable at the 984 default without breaking the D-6 floor-safety invariant (Extra Buff Spells never moves, Blacklisted Buff Families anchors to the growing right edge, a 128px swing) — discovered by writing x=397 first and watching the existing whole-tree overlap pin catch it; the strip is now centered at the panel's own tested FLOOR instead (x=333, ~1px from where fix round B item 2 already had it), with the residual 984-default asymmetry accepted as the same "dead margin, polish later" trade already applied to six other tabs. Every new/changed pin shown to fail against a targeted mutation first (temporarily re-adding removed markup, or reverting a property to its pre-fix form, then restoring). MossTank suite 722 (round F start, matching round E's close) -> 722 (item 1, existing pins updated in place, no new Fact) -> 723 (item 2, +1) -> 724 (item 3, +1) -> 724 (item 4, one Fact replaced/renamed not added) -> 724 (item 5, the 23->24 column-count update lives in an EXISTING Fact — item 5's own new pin is App-side) -> 726 (item 6, +2: LootEditorHasNoLeftoverBackButton, BuffsExtrasStripIsCenteredAtThePanelsFloorAndCoverageSitsUnderTheButtonRow). App markup/plugin filter 258 (round F start — already ahead of the other worktree's last-recorded 254 by the time this branch merged the sync branch) -> 258 (items 1-4, no App-side pin) -> 260 (item 5's two-width Theory) -> 262 (item 6, +2: RouteShapedGrid_CountColumnStaysThirtyPxWhenTheListScrolls, BuffsExtrasStripStaysCenteredAndNonOverlappingAtTheFloor). Full solution builds clean in Release throughout. Deviations carried forward, none new this round. Next: one combined final re-check, merge, gate build. + +## Closeout +- 2026-09-07 21:10 final combined re-check (E+F, both lenses): all twelve items CLOSED with failable tests, no per-frame allocation regression, the three recall tables agree pairwise, plugin references BCL + Abstractions only — MERGE-READY. **Merged into the campaign branch at `4a825c23c`.** Owner's second-look items all closed (Advanced Options bottom block gone; string settings hidden; Items tab VTank-only). Accepted, documented deviations: the Buffs extras strip centres at the 856 floor only (anchors have no "centre"); the recall combo lists "Marketplace" in place of VTank's duplicated "Fac. Hub"; dead margins on six tabs at the 984 default. Carried polish (owner: "we do that later"): strip the retired `scroll="true"` from five markup sites and make its test failable or document that unknown attributes are ignored; delete the ~20 bindings round F orphaned; cache the two Buffs row sources like every other column; two comment corrections; Meta's delete cell as an icon. Open issues from this slice: #490 part 1 (host: `StartVisible=false` + `ShowInSidePanel=false` unshowable), #491 (buff lists not consumed by `BuffPlan.Build`), #492 (Vulkan device-loss crash + shutdown re-throw), #493 (in-game meta/loot rule editors, deferred). Owner's visual gate: the merged build launched from the gate worktree for the final look.