docs: FA4 MF-3 REOPEN re-fix re-review -- CLOSED (04161def)
The re-fix moves the 0x00A6 re-declaration off the pre-world reset seam and onto the post-world EnteredWorld seam, and stops the widget latch from advancing on a dropped publish. Verified in the diff: - SetPageVisible advances _pageVisible ONLY on RuntimeCommandStatus.Accepted (the widget-level root of the REOPEN); a dropped Inactive publish leaves the latch clear so the in-world attempt is not deduplicated. - ResetSessionDeclaration (pre-world) now only clears the latch; RedeclareAfterWorldEntry (new) does the re-evaluation, wired through RetailUiRuntime.RedeclareSocialPanelAfterWorldEntry into LiveSessionRuntimeFactory's EnteredWorld RestoreLayout delegate. Seam ordering traced and confirmed inverse of the pre-world SessionDialogs stage: StartCore runs ResetHostBeforeStart (pre-world reset, latch clear) at :555, then ActivateCommands :639, _inWorld=true :642, and ApplyEnteredWorld :644 -> LiveSessionHost.ApplyEnteredWorld -> RestoreLayout delegate -> RedeclareAfterWorldEntry. So SetPanelOpen's requireWorld gate is Accepted and 0x00A6 publishes on the fresh server. Idempotent and load-bearing (the social panel isn't state-managed visibility, so RestoreLayout fires no OnShown edge). Tests model the world gate (fake returns Accepted only when in-world) and would fail against pre-fix behavior: the widget test's second attempt is deduplicated if the latch advances unconditionally; the reconnect test's DoesNotContain-after-reset fails if the pre-world declaration is reintroduced (the coordinator's RED-verification). Binary confirmed post-fix (new tests reference RedeclareAfterWorldEntry); 3/3 new + 58/58 touched classes green. 13,286/4/0 reconciles (+1, 0 deletions). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
04161defd8
commit
06dbf1cf8f
1 changed files with 100 additions and 0 deletions
|
|
@ -720,3 +720,103 @@ so `0x00A6` never reaches the reconnected server). Everything else CLOSED,
|
|||
with the dimming arithmetic audited correct at 34/16. Recommend a focused
|
||||
MUST-FIX-3-only re-fix (move the re-declaration to an in-world seam); no
|
||||
re-review of the other findings is owed.
|
||||
|
||||
---
|
||||
|
||||
## MF-3 REOPEN re-fix re-review — 2026-08-12 (commit `04161def`)
|
||||
|
||||
**Verdict: CLOSED.** The seam ordering the whole fix rests on holds — the
|
||||
`EnteredWorld` re-declaration is genuinely post-world, the inverse of the
|
||||
pre-world `ResetSessionState`/`SessionDialogs` stage the original fix used.
|
||||
The widget-level root I named is addressed, the tests model the world gate
|
||||
(not an unconditional fake), and the full suite reconciles.
|
||||
|
||||
### The two halves, verified in the diff
|
||||
1. **Widget-level (the root I named).**
|
||||
`SocialFellowshipPageController.SetPageVisible` now advances the latch
|
||||
ONLY on `Accepted`:
|
||||
`if (_bindings.SetPanelOpen(visible).Status == RuntimeCommandStatus.Accepted) _pageVisible = visible;`
|
||||
A dropped/Inactive publish (the pre-world reconnect state) leaves
|
||||
`_pageVisible` untouched, so the in-world attempt is not deduplicated
|
||||
away by the `if (_pageVisible == visible) return` guard. The normal
|
||||
in-world case is unchanged (Accepted → latch advances as before), and a
|
||||
persistently non-Accepted result retries at most once per generation
|
||||
(EnteredWorld fires once per generation) — no retry loop.
|
||||
2. **Lifecycle split.** `ResetSessionDeclaration` (pre-world) now ONLY
|
||||
clears the latch (`=> _fellowship?.ResetPageVisibleLatch();`) — it no
|
||||
longer calls `UpdateFellowshipPageVisibility`, so it makes no dropped
|
||||
pre-world declaration. The new `RedeclareAfterWorldEntry()`
|
||||
(`=> UpdateFellowshipPageVisibility();`) does the re-evaluation, exposed
|
||||
as `RetailUiRuntime.RedeclareSocialPanelAfterWorldEntry` and composed
|
||||
into `LiveSessionRuntimeFactory`'s `EnteredWorld.RestoreLayout` delegate
|
||||
(RestoreLayout first, then redeclare).
|
||||
|
||||
### Seam ordering — traced, and it holds (the load-bearing claim)
|
||||
The fix is correct only if `EnteredWorld` runs after `_inWorld = true` and
|
||||
after the command seam is active. It does. In `LiveSessionController.StartCore`:
|
||||
- `ResetHostBeforeStart` (`:555`) → `host.ResetSessionState` →
|
||||
`LiveSessionLifecycleHost.ResetSessionState` (`:47`) → `_bindings.Reset`
|
||||
→ the reset manifest's `SessionDialogs` stage → `ResetSessionTransientUi`
|
||||
→ `ResetSessionDeclaration` (clears the latch). **PRE-world** — `_inWorld`
|
||||
is still false here.
|
||||
- `binding.ActivateCommands()` (`:639`) — the deferred command seam binds
|
||||
for the new generation.
|
||||
- `_inWorld = true` (`:642`).
|
||||
- `host.ApplyEnteredWorld(selection)` (`:644`) →
|
||||
`LiveSessionLifecycleHost.ApplyEnteredWorld` (`:57`) → `_bindings.Entered`
|
||||
→ `LiveSessionHost.ApplyEnteredWorld` (`:212`) →
|
||||
`_enteredWorld.RestoreLayout()` (`:216`) → the re-fixed delegate →
|
||||
`RedeclareSocialPanelAfterWorldEntry` → `RedeclareAfterWorldEntry` →
|
||||
`UpdateFellowshipPageVisibility` → `SetPageVisible(true)`. **POST-world**
|
||||
— `_inWorld` is true and commands are active, so
|
||||
`SetPanelOpen`'s `Validate(requireWorld: true)` passes → **Accepted →
|
||||
`0x00A6` published** → latch advances. Fellow vitals resume on the fresh
|
||||
server.
|
||||
|
||||
This is the exact inverse of the pre-world `SessionDialogs` stage traced in
|
||||
the REOPEN, and it is idempotent: the social panel is not a
|
||||
state-managed-visibility window, so `RestoreLayout` does not re-show it and
|
||||
no `OnShown` edge fires — `RedeclareAfterWorldEntry` is therefore
|
||||
load-bearing (not redundant) in the reconnect-with-panel-open case, while
|
||||
still a safe no-op if some other path had already re-declared (latch
|
||||
already set).
|
||||
|
||||
### Tests genuinely exercise the world gate (and would fail against pre-fix)
|
||||
The fake `SetPanelOpen` now returns `AcceptedResult` when its
|
||||
`inWorld`/`PanelOpenInWorld` flag is true and `InactiveResult` when false —
|
||||
a real world-gate model, not an unconditional recorder.
|
||||
- `SetPageVisible_DoesNotLatch_WhenDeclarationDropped_SoItRetriesInWorld`:
|
||||
sets the flag false, `SetPageVisible(true)` records the dropped attempt;
|
||||
flips the flag true, `SetPageVisible(true)` AGAIN records a send. Against
|
||||
the pre-fix unconditional `_pageVisible = visible`, the second call would
|
||||
early-return (deduplicated) and record nothing — the `Assert.Contains`
|
||||
would fail. So this pins the widget-level root.
|
||||
- `Reconnect_ReDeclares0x00A6_AfterWorldEntry_NotDuringPreWorldReset`:
|
||||
after the in-world declare, sets in-world false, calls
|
||||
`ResetSessionDeclaration()` and asserts `DoesNotContain(...set-panel-open...)`
|
||||
— this is exactly the assertion that fails if the pre-world declaration is
|
||||
reintroduced (matching the coordinator's RED-verification); then sets
|
||||
in-world true, calls `RedeclareAfterWorldEntry()` and asserts the send
|
||||
lands.
|
||||
- `Reconnect_StaysSilent_WhenFellowshipPageIsNotActuallyOpen`: default tab
|
||||
Allegiance; after reset + post-world redeclare, the D4 conjunction is
|
||||
false, so no send — the counterpart holds.
|
||||
|
||||
### Build currency and totals
|
||||
The current App test binary is post-`04161def`: the three new tests
|
||||
reference `SocialPanelController.RedeclareAfterWorldEntry`, a method that
|
||||
exists only in the fixed source — the project would not compile against
|
||||
pre-fix source, so a resolving+passing run proves the binary reflects the
|
||||
fix. Ran on it: the three new tests 3/3, and the three touched classes
|
||||
(`SocialFellowshipPageControllerTests` / `SocialPanelControllerTests` /
|
||||
`GameplayConfirmationControllerTests`) 58/58. The **13,286/4/0** full-suite
|
||||
claim reconciles by direct count: net **+1** test from the prior 13,285
|
||||
(the one new widget `[Fact]`; the two panel tests were renamed in place,
|
||||
net 0), 0 deletions. Not re-run end-to-end here.
|
||||
|
||||
### Disposition
|
||||
MF-3 is CLOSED. All five MUST-FIX, all 9 SHOULD-FIX, all 4 NIT, and blast
|
||||
SF-1 are now correctly applied; the D6/D7/SF-8 dimming stands at the
|
||||
audited-correct 34/16. The FA4 fix round is fully resolved on the
|
||||
mechanism lens; only the user's connected gate (several steps
|
||||
`[TWO-CLIENT]`, deferrable to FA6) remains owed.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue