Files
Bose-SoundTouch/pkg
Lukáš LipinskýandClaude Opus 5 5ea96d0cfa Harden player source selection reconciliation
Use a single POST command with bounded delayed readback, revision-order
REST and WebSocket state, and explicit pending, confirmed, unverified, or
failed outcomes. Mark stale source inventories unusable until a successful
refresh and preserve legacy API error handling outside this command path.

Rebased onto main. One conflict could not be resolved by picking a side:
this change introduced its own per-field fencing (fieldRevision,
deviceStatusFieldRevisions, MergeNowPlaying/MergeVolume/MergePresets/
MergeSources/MergeBass/MergeIsConnected) over the same six fields that
main's StatusField mechanism (BeginFieldPoll/CompleteFieldPoll/
ApplyFieldEvent, added by the #654/#668 stack) already orders. Landing
both would leave two independent generation counters guarding the same
state, which is the divergent-fencing bug class that stack already had to
fix three times. Resolved in favour of main's mechanism:

  - the Merge* methods and their counters are dropped; the WebSocket
    handlers and updateDeviceStatus use main's calls;
  - NowPlayingRevision is derived from the existing FieldNowPlaying
    generation via recordFieldRevision, not a second counter;
  - SetStatus derives Revision from the stored status and supersedes all
    field generations, so a replacement cannot reset the revision a
    browser is ordering on;
  - updateSourcesCache records a failed /sources read through
    CompleteFieldPoll, keeping the newer-failure-fences-older-success
    property the original had via MergeSourcesFailure;
  - the three tests that called the dropped API were ported to it.

Everything else in this change is unmodified.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-05 20:36:58 +02:00
..