Skip to content

docs(roadmap): the login the catalogue asks for, and an order to read the lines by - #204

Merged
wine-fall merged 3 commits into
mainfrom
zachg-0904--roadmap-auth-catalogue
Sep 4, 2026
Merged

docs(roadmap): the login the catalogue asks for, and an order to read the lines by#204
wine-fall merged 3 commits into
mainfrom
zachg-0904--roadmap-auth-catalogue

Conversation

@wine-fall

@wine-fall wine-fall commented Sep 4, 2026

Copy link
Copy Markdown
Owner

What this is

ROADMAP.md gains a sixth line and a priority column, and its
Tracked-as cells catch up with what has landed since it was written.

The new line 5 — an opt-in login for an auth-gated catalogue (P1)

Not a new want: specs/DESIGN.md §5 already excluded both sources by name and
said why — NetEase Cloud Music has the best Chinese catalogue but only
unofficial APIs, needs a login cookie, and gates its good tracks behind VIP;
Spotify has no clean no-app-no-membership path, and headless librespot needs
Premium
. specs/spec03/03-01-brain-harness.md deferred it as a single work
item and named cliamp as the credential
reference — the auth flow only, never its user-picks interaction model.

What is new is the lazy road in: yt-dlp — already murmur's only provider —
ships netease:song / playlist / singer / djradio extractors and takes
--cookies FILE / --cookies-from-browser
(checked against yt-dlp
2026.08.19). So the NetEase half is not a second provider; it is a credential
reaching the provider murmur already runs, plus URL-shaped candidate sources
beside the open-ended search. MusicProvider (src/contracts.ts:175) is
search + resolve with no notion of a source that can fail on auth, and
src/app.ts:248 constructs YtDlpMusicProvider directly — so an expired cookie
would surface today as one more dead stream probe, which is the exact confusion
line 3 exists to remove. Spotify gets the seam and an honest refusal.

Opt-in, never a shipped default (DESIGN §3.7's personal-experiment tier): the
default install stays login-free yt-dlp.

The P column

The row numbers were the order, and the order has moved. P0 = line 0, because
every by-ear judgement above it is worthless while the listener's first typed
line disappears. P1 = lines 1, 2 and 5 — the ones that change what murmur is.
P2 = line 3 (reliability). P3 = line 4 (distribution and not rotting), with a
note that its eval half (#98) becomes P2 the moment lines 1/2 land, since both
are entirely stochastic behaviour.

Line 0 gets a status check

Recorded rather than left for the next session to re-derive: no fix has
landed
for the dropped first line — the settled guard in lineReader
predates the 2026-08-25 repro (it came in on 08-18/08-19) and LineQueue has
not changed since. A stub plain-mode run with a pre-seeded persona echoed and
acted on the first typed line, but that path runs with no harness, so neither
the crash-report offer nor the setup conversation opens a pre-broadcast reader
— it therefore neither reproduces the bug nor clears it. The suspected seam
also reads clean today (every read() is awaited; settled is set in the
race's own finally), so the suspected cause is marked unconfirmed and the
next attempt should start from the repro conditions, not from that seam.

One test fix rides along

CI came back red on a docs-only branch: test/memory-fold.test.ts:312 reopened
PersistentMemoryStore with the real clock while the rows under it were
written on a frozen 2026-09-01, so the 48h recent window in load() dropped
them for age. It passed the day it landed (#196) and went red on 2026-09-04
with nothing changed — a calendar failure, not a regression, and it blocks
every PR until it is fixed. The reopen now reads the same clock as the writes,
which is what that assertion was ever about: the row survived forget, not the
window.

Verification

Docs, plus that one test line. pre-commit run --files ROADMAP.md → source-language gate passed;
tsc / oxlint / path-governance had no files to check. Every factual claim in
the new text was checked against the tree: yt-dlp --list-extractors and
yt-dlp --help on 2026.08.19 for the extractors and cookie flags, git blame

  • git log for the settled guard's date and LineQueue's history, and the
    two code references (src/contracts.ts:175, src/app.ts:248) read directly.

Full local gate after the test fix: npx vitest run --dir test 1366 passed / 0
failed, tsc --noEmit clean, oxlint clean.

Peer review (codex gpt-5.6-sol): 6 findings, 6 applied, 0 dismissed
verdict was request changes, all six on claims the document overstated, and
all six now corrected in a follow-up commit:

It also confirmed independently that yt-dlp 2026.08.19 lists the cited NetEase
extractors and accepts both cookie options, and that the two code references
match.

AI coding brief

Original request. The user asked what is on the roadmap and what is done —
which surfaced that ROADMAP.md had gone stale (line 2 built and unmerged,
line 1 half-landed). They then asked to add the NetEase/Spotify login they
remembered from the original specs, mark it P1, and assign priorities to the
existing lines. The why: the roadmap is the document the README points at, and
an order that only lives in a conversation is not an order.

Manual interventions. The user set line 5's priority (P1) themselves and
left the rest of the priorities to analysis. They also pushed back on line 0 —
"I thought that was fixed" — which turned into the status-check paragraph after
git blame showed the guard predates the repro and a stub run turned out to
prove nothing either way.

Retro. The roadmap and the issue tracker had already drifted apart in four
days; reading gh issue list + gh pr list before answering "what is done"
was what caught it, and doing that first would have made the first answer
correct rather than the second. Verifying the yt-dlp extractor claim before
writing it into the doc (one --list-extractors call) is what turned line 5
from "build an auth provider" into "pass a cookie to the provider we run" —
worth the 20 seconds, since it changes the size of the work.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Sx3J45TyoScFDneRF7qX14

wine-fall and others added 3 commits September 4, 2026 11:07
… the lines by

Adds a sixth line and a priority column.

The new line 5 — an opt-in, guided login for an auth-gated source — is not a
new want: DESIGN.md §5 excluded NetEase (login cookie, VIP) and Spotify (no
no-app-no-membership path; librespot needs Premium) with reasons, and spec
03-01 deferred it as one work item naming cliamp as the credential reference.
What is new is that yt-dlp, already murmur's only provider, ships the
netease:* extractors and takes --cookies / --cookies-from-browser, so the
NetEase half is a credential reaching the provider we run, not a second
provider. Spotify gets the seam and an honest refusal.

The P column gives the lines an order the row numbers no longer carry: line 0
blocks every by-ear judgement above it, lines 1/2/5 change what murmur is,
line 3 is reliability, line 4 is distribution. The Tracked-as cells catch up
with what has landed since the file was written (the lead-in half of line 1,
line 2 built and unmerged).

Line 0 also records a status check: no fix has landed for the dropped first
line, the settled guard predates the repro, and a stub run neither reproduces
nor clears it — the suspected seam is unconfirmed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sx3J45TyoScFDneRF7qX14
`PersistentMemoryStore.forget`'s reload assertion reopened the store with the
real clock while the rows under it were written on a frozen 2026-09-01, so the
48h recent window in `load()` dropped them for age. It passed on the day it
landed and went red on 2026-09-04 with nothing changed — a calendar failure,
not a regression. The reopen now reads the same clock as the writes, which is
what the assertion was ever about: the row survived `forget`, not the window.

Found on CI for the roadmap PR, which touches no code.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sx3J45TyoScFDneRF7qX14
Six factual corrections from the codex review, all of them places where the
document overstated what it knew:

- Line 1: speaking over a ducked track is not the missing piece — the lead-in
  (#199) and the coda (#200) both do it today. What is left in #163 is the
  autonomous mid-track beat, so the line and its table cell say that instead.
- Line 5: a yt-dlp auth failure comes back through `provider.resolve` and is
  caught by `submit_pick` as "pick another" — it never reaches the stream
  probe, so an expired cookie is a silent stream of rejected candidates, not
  "one more dead probe".
- Line 5: a free Spotify account does have a stream (the desktop app, ads and
  on-demand limits — DESIGN §5); the refusal is that murmur cannot conduct it,
  the external-player duck path being out of scope in spec 03-02.
- Line 5: says outright that it does not reopen DESIGN §8's v1 exclusion.
- Line 0: the crash-report offer landed 08-31, after the 08-25 repro, so it
  cannot have eaten that line; the repro conditions are the August boot state,
  and the offer is a separate new reader worth its own check.
- Line 0: #187 did touch `LineQueue` (hasReader + the IpcHost echo flow), so
  the claim narrows to the take/peek semantics the plain path uses.

Peer review (codex gpt-5.6-sol): 6 findings, 6 applied, 0 dismissed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sx3J45TyoScFDneRF7qX14
@wine-fall
wine-fall merged commit 37fdac2 into main Sep 4, 2026
4 checks passed
@wine-fall
wine-fall deleted the zachg-0904--roadmap-auth-catalogue branch September 4, 2026 05:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant