The maintainer's two test-speaker MACs (A81B6A536A98 / A81B6A849D99,
plus colon-separated forms) appeared throughout documentation, runbooks,
and example READMEs. Public repo — same hygiene argument as the LAN-IP
sweep in 787c4fa.
Mapping:
A81B6A536A98 → AABBCCDDEEFF
A81B6A849D99 → AABBCCDDEE01
A8:1B:6A:53:6A:98 → AA:BB:CC:DD:EE:FF
A8:1B:6A:84:9D:99 → AA:BB:CC:DD:EE:01
The placeholders use the IANA-reserved AA:BB:CC:DD:EE:FF address that's
clearly synthetic, matching the convention the earlier anonymisation
pass had already adopted. 13 .md files touched; no tests, no code.
ANONYMIZATION-SUMMARY.md left for a dedicated rewrite commit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
storePreset on the speaker was failing with "AddPreset - failed due to
invalid SourceID" because the watchdog priming path only pushed ZeroConf
credentials and never registered a SPOTIFY ConfiguredSource in marge.
PrimeDeviceWithSpotify now:
- resolves the device's paired account via live :8090/info
(margeAccountUUID), falling back to ServiceDeviceInfo.AccountID — same
order as setup.populateDeviceInfo;
- writes a SPOTIFY ConfiguredSource under that account (providerID=15,
BoseSecret as credential), mirroring bridgeSpotifyToMarge;
- POSTs `<updates><sourcesUpdated/></updates>` so the speaker re-fetches
its on-device Sources.xml from marge.
Also introduce zeroconf.ErrAddUserNoOp for the narrow firmware quirk
(404 + empty body on ?action=addUser when activeUser already matches).
Recognised only on that exact pattern; real 4xx/5xx still surface loudly
with full response details. Same treatment applied to Amazon priming.
Docs:
- new docs/concepts/spotify-overview.md anchors the topic (mental model,
streamingoauth.bose.com DNS gotcha, token lifecycle, clientId notes,
troubleshooting table);
- spotify-oauth.md drops the removed install-primer endpoint and the
on-device boot-primer install sections, adds /mgmt/spotify/prime;
- spotify-priming-strategy.md and MUSIC-SERVICES.md link to the
overview.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Attempting to request amazon_music:access with a standard application
client ID (amzn1.application-oa2-client.*) returns HTTP 400
lwa-invalid-parameter-bad-scope from the LWA authorization endpoint.
The scope is gated to Amazon Music partner device client IDs.
Revert scope to "profile" (working state) and document the confirmed
blocker with the exact error. Path forward: Amazon Music partner
registration for a device client ID; one-line change to AmazonScopes
when available.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Amazon bridge: fall back to sync/legacy on any error from
SetMusicServiceOAuthAccount (not only error 1029); timeouts from
unresponsive speakers no longer silently skip the fallback chain
- Amazon bridge: reduce speaker client timeout from 30s to 5s for
faster failure on local network calls
- marge: resolveSourceName now prefers SourceName/DisplayName over
SourceKeyAccount, so Amazon (and Spotify) sources show the account
holder's name instead of the raw account ID
- docs: update amazon-music-oauth.md with real-world test results;
music-api.amazon.com returns 401 because standard LWA apps lack
music::* partner scopes — infrastructure is complete but streaming
is blocked pending Amazon partner access
- docs: add SELF-HOSTING.md and MUSIC-SERVICES.md user guides; link
both in SUMMARY.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Mark status as Implemented
- Add "Trying It Out" section: LWA app setup, service flags, OAuth flow,
account verification, speaker priming, DNS requirement, site_id open question
- Fix stale endpoint table entry (no longer a stub)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Mark ZeroConf Spotify priming and 404 handler as addressed in both docs
- Remove stale "Remaining gaps" and "Already adopted" tracking tables from
community-tools.md; detail now lives in PARITY-SOUNDCORK.md
- Update PARITY-SOUNDCORK.md summary to reflect Groups and ZeroConf as done;
add cross-reference to community-tools.md
- Rename remaining "gesellix" project references to "AfterTouch" throughout
community-tools.md (URLs and author attribution unchanged)
- Add soundcork-stockholm-app (entry 7) to community projects list
- Correct DNS priority entry: built-in DNS server requires no external tools
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the simplified tokenType=accesstoken push with the full Spotify
Connect ZeroConf protocol: GET getInfo to fetch the speaker's 768-bit DH
public key, derive AES-128-CTR + HMAC-SHA1 keys from the shared secret,
and POST an encrypted LoginCredentials protobuf blob. Speakers that
receive a proper blob can self-refresh their Spotify session
independently, eliminating the need for periodic re-priming on token
expiry. Falls back to the raw token approach automatically when getInfo
fails, preserving compatibility with older firmware.
SHA1 is mandated by the Spotify Connect ZeroConf protocol spec for DH key derivation. This cannot be changed without breaking protocol compatibility.
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>