Multi-instancing migration (Step 8 — forcing function): delete the static BattleRecoveryInfo fallback the earlier .ambient-recoveryinfo patch added as a coexistence shim. BattleRecoveryInfo is now strictly per-session ambient. Supersedes the intermediate .ambient-recoveryinfo patch (kept for the audit trail). Semantics: - BattleRecoveryInfo (getter) : Current?.RecoveryInfo — soft (null when no scope). The MulliganMgrBase.StartDeal call site reads this with a null-tolerant pattern, so a null degrade is the historical fallback. Inside a scope, returns the per-session RecoveryInfo (SessionBattleEngine pre-seeds an uninitialized BattleRecoveryInfo on its ctx field initializer). - BattleRecoveryInfo (setter) : BattleAmbient.Require().RecoveryInfo = value — strict (writes must land on the per-session ctx; forcing function). Related (SVSim.BattleNode/Sessions/Engine/EngineGlobalInit.cs): the dead `Data.BattleRecoveryInfo = ...` write inside the `_done` lock block is also deleted (flagged by Task 7 reviewer). The per-session ctx pre-seeds RecoveryInfo, so the process-global write was dead the moment the ambient seam landed. In-file edits: - line ~179 declaration `private static BattleRecoveryInfo _battleRecoveryInfoFallback;` DELETED - lines ~180-189 the ambient+fallback get/set body REPLACED with strict semantics --- Engine/Wizard/Data.cs (~lines 179-189) - private static BattleRecoveryInfo _battleRecoveryInfoFallback; public static BattleRecoveryInfo BattleRecoveryInfo { - get => SVSim.BattleEngine.Ambient.BattleAmbient.Current?.RecoveryInfo ?? _battleRecoveryInfoFallback; - set - { - var c = SVSim.BattleEngine.Ambient.BattleAmbient.Current; - if (c != null) c.RecoveryInfo = value; - else _battleRecoveryInfoFallback = value; - } + // Soft read: returns null when no scope is active. The MulliganMgrBase.StartDeal call site + // reads this with a null-tolerant ??=-style pattern, so a null degrade is the historical + // fallback. Inside a scope, returns the per-session RecoveryInfo (SessionBattleEngine + // pre-seeds an uninitialized BattleRecoveryInfo on its ctx field initializer). + get => SVSim.BattleEngine.Ambient.BattleAmbient.Current?.RecoveryInfo; + // Strict setter: writes must land on the per-session ctx. No historical production caller + // writes this outside a scope; an unwrapped write now fails fast (forcing function). + set => SVSim.BattleEngine.Ambient.BattleAmbient.Require().RecoveryInfo = value; }