proposals/2026-07-30-session-home-regardless-of-view.md
Rama master · réplica de lectura del repositorio original.
# The play token goes to one elected host, whatever view a device is in
**Goal** - two of a person's devices paired to the same libraries always put their play token on
the SAME host, so the cross-scope arbitration shipped in #283 actually applies instead of applying
by luck.
**Tier** - T1. No schema change, no new methods, no wire change. What moves is WHICH host a session
row is written to.
## Why
#283 made a claim in one session scope take the other scope's token, so a blended device and a
focused one can no longer both be "the active player". That fix only bites when both devices'
session rows live on the SAME host - and they often do not:
```
sessionTarget() // src/bare.js, before this change
merged -> sessionHomeLib() = electHome(connected) : the smallest connected hostKey
single -> defaultLibraryId : whichever host you focused
```
With one paired library those always coincide, which is why every hardware test so far passed.
With two, they coincide only if the library you happen to be focused on is also the elected one -
about a coin flip. The rig that proved #283 passed because the focused phone was pointed at the
elected host; pointing it at the other one would have reproduced the bug with the fix in place.
So #283 is correct but narrower than its own PR text implied, and that is recorded as a correction
rather than quietly fixed here.
## Scope
`sessionTarget()` returns the elected home in BOTH modes. `merged` stays exactly what it was - the
SCOPE, i.e. which row (`session:` or `session:merged:`) - and only the HOST changes:
```
sessionTarget() // after
lib -> sessionHomeLib() ?? defaultLibraryId : the same host on every device
merged -> mergedMode() : unchanged, still selects the row
```
`sessionReady()` follows: it must ensure the ELECTED host is connected, not merely the focused one,
so it uses the same all-hosts path in both modes when more than one library is paired.
One consequence to state: a focused device's queue is written to the elected host rather than the
one it is focused on. That is already what the merged row does - a session queue is opaque to the
host, which never dereferences a trackId - so no host-side change is needed.
**Also fixed here, because it falls out of the move:** `sessionTakeover`'s resume fallback used the
SESSION client to look up a track's position when not merged. With the token on a different host
than the track, that would ask the wrong host and quietly get 0. It now routes by the track's
owning library, as merged mode already did, falling back to the default client.
**Not in scope.** Devices with DIFFERENT pairing sets still elect different hosts and remain
unarbitrated, as do devices that can reach different subsets. That is the cross-host problem, which
needs a person identity spanning hosts - `personId` is minted per host and means nothing elsewhere -
and stays logged in TODO.md as a decision not yet taken.
## Compat
- ONE paired library: `electHome` returns that library, which is also `defaultLibraryId`. Byte for
byte the same behavior. This is the overwhelming majority of installs.
- Host side unchanged - no new fields, no new methods. An old host is claimed against exactly as
before, just possibly a different one of the person's hosts.
- A device that upgrades mid-session may move its row from host A to host B, leaving a stale row on
A. It is inert: nothing reads a session row except a device targeting that host, which will now
target B, and the row is overwritten on the next claim there.
## Verify
- Unit on the pure part: with two hosts, a focused device and a blended device resolve the SAME
target host, and the `merged` flag still differs so they still take different rows.
- Unit: with one host, the target is unchanged from `defaultLibraryId`.
- On hardware, the case that fails today: TCL blended, Pixel focused on the NON-elected library,
both playing. Before this change both keep playing despite #283; after, one stops.
## Rollback
Revert. The token goes back to following the focused library, and #283 goes back to applying only
when the two happen to coincide.
## Open questions
- `electHome` elects among CONNECTED libraries, so two devices that can reach different subsets
still diverge. Electing among ALL PAIRED would be stable but could send the token at a host that
is offline, which is worse. Left as is deliberately.