fix(settings): OP9 review residuals — restore SaveAudio live-apply pin, delete dead residues

Closes the OP9 combined review's findings (docs/research/2026-08-11-op9-review.md,
APPROVE-WITH-FIXES):

- MUST-FIX 1: SaveAudio -> ApplyAudio (OP6's Config-tab live-apply) lost
  its ONLY assertion when the retired SettingsVM save-order test was
  deleted. Restored directly on the now-public seam:
  SaveAudioPersistsThenPushesLiveApplyAudioWithTheSavedSnapshot pins
  persist-then-push order + the pushed snapshot;
  SaveAudioSkipsTheLivePushWhenPersistenceFails pins the failure ordering
  (a failed persist pushes nothing and commits nothing). Also closes
  SF-5: the OP6 effective-volume comment's 'target-audio assertion above'
  reference is real again and now names the restored test.
- SF-3: dead residues deleted — RuntimeSettingsController's private
  SaveCharacter (zero callers post-371197a3), ISettingsStorage.SaveCharacter
  + its JsonRuntimeSettingsStorage/FakeStorage implementations (the deleted
  private method was the only caller), and IngressShutdownRoots.Settings
  (zero readers since the view-model shutdown stage died). SettingsStore's
  PUBLIC SaveCharacter stays: it is the tested storage-API seam, and
  per-toon entries in existing settings.json files still load through the
  live LoadCharacter path.
- SF-2: code-structure.md's presentation-seam list no longer routes the
  settings preview through 'optional SettingsVM'.
- NIT 6: AP-196's retirement note now attributes LockUI (/lockui +
  PlayerDescription SetUiLocked convergence) and UseMouseTurning
  (Gameplay-tab macro + Config-tab row) to their real channels instead of
  folding all 13 members into the Character tab.

Full Release suite: 13,077 passed / 4 skipped / 0 failed (13,075 + the two
restored tests). One unnamed App-assembly failure appeared on the first
post-fix full run and did not reproduce on the isolated assembly rerun nor
a second full run — consistent with the known #250-class parallel-load
flake, recorded here for honesty rather than silently rerun.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-08-11 13:42:39 +02:00
parent 289bf5bc6e
commit 07f2b3f72e
6 changed files with 57 additions and 47 deletions

View file

@ -1667,7 +1667,6 @@ public sealed class GameWindow :
_retailUiLease,
_uiHost,
_runtime,
_runtimeSettings,
_movementInput,
_cameraInput,
_windowCallbacks),

View file

@ -72,7 +72,6 @@ internal sealed record IngressShutdownRoots(
// Keeps failed physical UI bindings alive through native-window release.
UiHost? RetainedUiHost,
GameRuntime Runtime,
RuntimeSettingsController Settings,
DispatcherMovementInputSource MovementInput,
DispatcherCameraInputSource CameraInput,
SilkWindowCallbackBinding? WindowCallbacks);

View file

@ -28,8 +28,6 @@ internal interface IRuntimeSettingsStorage
void SaveChat(ChatSettings chat);
void SaveCharacter(string toonKey, CharacterSettings character);
void SaveCameraTurning(CameraTurningSettings cameraTurning);
}
@ -65,9 +63,6 @@ internal sealed class JsonRuntimeSettingsStorage : IRuntimeSettingsStorage
public void SaveChat(ChatSettings chat) => _store.SaveChat(chat);
public void SaveCharacter(string toonKey, CharacterSettings character) =>
_store.SaveCharacter(toonKey, character);
public void SaveCameraTurning(CameraTurningSettings cameraTurning) =>
_store.SaveCameraTurning(cameraTurning);
}
@ -544,27 +539,6 @@ internal sealed class RuntimeSettingsController :
/// <inheritdoc cref="ServerOptionsSeeded"/>
public void NotifyServerOptionsSeeded() => ServerOptionsSeeded?.Invoke();
private void SaveCharacter(CharacterSettings character)
{
try
{
_storage.SaveCharacter(ActiveToonKey, character);
Character = character;
if (string.Equals(
ActiveToonKey,
DefaultToonKey,
StringComparison.OrdinalIgnoreCase))
{
_defaultCharacter = character;
}
_log($"settings: character[{ActiveToonKey}] saved to {_storage.Location}");
}
catch (Exception ex)
{
_log($"settings: character save failed: {ex.Message}");
}
}
private static QualitySettings ResolveQuality(QualityPreset preset) =>
QualitySettings.WithEnvOverrides(QualitySettings.From(preset));
}