chore(plugin-ui): review cleanup — hermetic memo tests, shelf button anchors, outline pin, bounded miss cache; file #486/#487; correct #461

- Split the two hermetic RetailMarkupIconResolver memoization tests (and
  their counting fakes) out of the Lane=InstalledDat class into a new
  untagged RetailMarkupIconResolverMemoizationTests.cs so CI's portable
  filter (Lane!=InstalledDat) actually runs them.
- PluginSidePanel: move the entry button's Anchors = AnchorEdges.None from
  the Add() call site into PluginShelfButton's own constructor (same
  comment carried over) so a second construction path cannot miss it.
- UiRectOutlinePainterOrderTests: assert the back panel's border segment
  carries exactly 4 quads (24 vertices, FloatsPerVertex each) so a partial
  outline cannot pass the painter-order check.
- RetailMarkupIconResolver: document the type as UI-thread-only (every
  caller is a draw-time icon source) and bound the MISS cache to 256
  entries with FIFO eviction — HIT entries stay unbounded (bounded by the
  DAT's own surface count already). New test proves the 257th distinct
  miss evicts the first (re-probe count rises); verified failing first
  against the un-bounded code (Expected 258, Actual 257) before restoring
  the fix.
- docs/plugin-ui-markup.md: split the icon-binding row's failure mode into
  Build-time (missing property only — the binder never checks CLR type)
  vs. draw-time (a resolved value that cannot convert to a number throws
  from the draw, not from Build).
- docs/ISSUES.md: filed #486 (credits picture scroll frozen by the
  per-draw anchor pass) and #487 (radar compass tokens candidate, same
  mechanism, unconfirmed); corrected #461's causality — the graceful
  logout/reveal-cancel log lines are printed by LiveSessionController.Tick's
  catch -> StopAfterFailure -> StopCore AFTER the motion-update exception,
  then it rethrows, so the logout is a consequence of the crash, not its
  cause; real chain is the #462 stalled login-reveal materialization
  leaving PlayerMovementController in RuntimeOwnedDormant outside its
  SetPosition ground phase when an inbound 0xF74C arrives.
- Plan doc: recorded the three fix-round commits' verdicts (all PASS) and
  the Smoke-plugin cleanup commit SHA in the Review ledger, plus a pointer
  to the two newly filed issues.

Verified: dotnet build AcDream.slnx -c Release (0/0), targeted filter
85/0/0, full App suite 7364 passed / 97 skipped / 36 failed (36 pre-existing
InstalledDat/Manual/Linux-only failures, unchanged by name from baseline;
net +1 passed test from the new eviction test).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-09-06 17:09:46 +02:00
parent ece2104189
commit f2d7562c86
8 changed files with 416 additions and 158 deletions

View file

@ -303,3 +303,14 @@ all four places, list icon column aligned with rows.
same commit; see `chore(plugins): remove the Smoke gate plugin; MossTank
shelf icon 0x06002C41`. MossTank's own panels defaulting to
`StartVisible = true` remains open — same look, still out of scope here.
- **Fix-round commits + closing cleanup (2026-09-06):** `47eb2d575` (shelf
children must not anchor — PASS, connected gate confirmed the `<`/`>`
toggle survives collapse/reflow), `761a7519f` (retained-UI rect outlines
composite in painter order — PASS, connected gate confirmed the MossTank
border no longer draws over the inventory paperdoll), `ce05c4fb0` (Slice B
residuals — shelf icon sink without magenta, validated icon bindings,
negative ids, memoized DID resolves — PASS; its one SHOULD-FIX carryover,
the memoization tests sitting in a `Lane=InstalledDat` class where CI never
ran them, is this session's cleanup item 1), and the cleanup commit
`ece210418` (Smoke gate plugin removal, referenced by message above).
Latent anchor-pass owners filed by this cleanup pass: #486, #487.