Answers #7 — the next item of the roadmap's (#73) Phase 1, unblocked by #16.
What was wrong
An album the user holds part of showed only the tracks on disk, with nothing to say the rest existed. The page could already draw the full release with the missing rows dimmed — it just could not be asked. The automatic rule fires on completeness.known, which needs either the files' per-disc total or the catalog's total_tracks.
Neither reaches most albums, and the second is worse than it looks.
Measured, while confirming Direction part 2
The shipped artifact does not carry total_tracks:
$ curl -sSI .../generic/yellowjacket-core-index/latest/core-index.db.zst
last-modified: Mon, 10 Aug 2026 04:38:16 GMT
$ sqlite3 core-index.db \
"SELECT COUNT(*) FROM pragma_table_info('explore_index') WHERE name='total_tracks';"
0
$ sqlite3 core-index.db "SELECT COUNT(*) FROM explore_index;"
1079667
The column landed on 2026-08-16; the artifact is from 08-10, and index-artifact.yml is a weekly cron rather than a push trigger. So completenessAnswer()'s catalog fallback answers 0 for every user today. artifactHasTotals() is doing precisely its job — which is why nothing is failing — but a probe that makes a column optional also makes its absence silent. Noted on #88, which is the publish that carries it, and in .planning/NOTES.md.
That is the argument for Direction part 1 being the real ask.
Commits
Commit
Issue
feat(explore): let the album page be asked for the whole tracklist
A "Show the whole album" switch above the tracklist, flipping the synthetic "Your Library" entry between the local files and the release — the same rendering the automatic rule produces, reached deliberately.
Three things that are load-bearing
showFullTracklist is a tri-state, null meaning "follow the automatic rule". The rule is right when it fires and the switch must agree with the page it sits on rather than starting out contradicting it; a plain boolean would need its default recomputed every time the completeness answer moved underneath it. The user outranks it in both directions.
fullReleaseCluster() falls back to the highest-scoring cluster.findLibraryCluster is a guess over the inLibrary flags and returns nothing when none are set — exactly the untagged library this exists for, so without the fallback the control would be absent precisely where it is needed.
It appears only where it can change what is on screen: against the library entry, with a release to switch to, and only when the two tracklists differ. A complete album's release has the same rows as its files, so the switch would redraw the same list and read as broken — the same test the version dropdown one section up already answers.
Verification actually run
make ui-test — 844 passed (74 files), up from 843.
frontend/test/components/album-full-tracklist.test.ts — 8 specs: the report's own case (2 local, 12 on the release, no declared total), the round trip back, the automatic rule still firing and still being overridable, and three absence cases.
tsc --noEmit clean; css-literals and frontend-typecheck via pre-commit.
The accessible name is asserted, not assumed, through the browser's own computation (page.getByRole('switch', {name})). wa-switch happens to get it right, and for a third reason again: its <input role="switch"> sits inside a native <label> that also holds the <slot>, so the name is computed across the flattened tree from light-DOM text. This app has shipped the opposite twice — wa-slider and config-field.
Not done here
No e2e spec: the fixture library has no partly-owned MBID-matched album to drive one against, and staging one is a larger piece of work than the feature. The component tier exercises the real element with the real store code.
Answers #7 — the next item of the roadmap's (#73) Phase 1, unblocked by #16.
## What was wrong
An album the user holds part of showed only the tracks on disk, with nothing to say the rest existed. The page could already draw the full release with the missing rows dimmed — it just could not be **asked**. The automatic rule fires on `completeness.known`, which needs either the files' per-disc total or the catalog's `total_tracks`.
Neither reaches most albums, and the second is worse than it looks.
## Measured, while confirming Direction part 2
The shipped artifact does **not** carry `total_tracks`:
```
$ curl -sSI .../generic/yellowjacket-core-index/latest/core-index.db.zst
last-modified: Mon, 10 Aug 2026 04:38:16 GMT
$ sqlite3 core-index.db \
"SELECT COUNT(*) FROM pragma_table_info('explore_index') WHERE name='total_tracks';"
0
$ sqlite3 core-index.db "SELECT COUNT(*) FROM explore_index;"
1079667
```
The column landed on 2026-08-16; the artifact is from 08-10, and `index-artifact.yml` is a weekly cron rather than a push trigger. So `completenessAnswer()`'s catalog fallback answers 0 for **every** user today. `artifactHasTotals()` is doing precisely its job — which is why nothing is failing — but a probe that makes a column optional also makes its absence silent. Noted on #88, which is the publish that carries it, and in `.planning/NOTES.md`.
That is the argument for Direction part 1 being the real ask.
## Commits
| Commit | Issue |
| --- | --- |
| `feat(explore): let the album page be asked for the whole tracklist` | #7 |
## What it does
A "Show the whole album" switch above the tracklist, flipping the synthetic "Your Library" entry between the local files and the release — the same rendering the automatic rule produces, reached deliberately.
## Three things that are load-bearing
- **`showFullTracklist` is a tri-state**, `null` meaning "follow the automatic rule". The rule is right when it fires and the switch must agree with the page it sits on rather than starting out contradicting it; a plain boolean would need its default recomputed every time the completeness answer moved underneath it. The user outranks it in both directions.
- **`fullReleaseCluster()` falls back to the highest-scoring cluster.** `findLibraryCluster` is a guess over the `inLibrary` flags and returns *nothing* when none are set — exactly the untagged library this exists for, so without the fallback the control would be absent precisely where it is needed.
- **It appears only where it can change what is on screen**: against the library entry, with a release to switch to, and only when the two tracklists differ. A complete album's release has the same rows as its files, so the switch would redraw the same list and read as broken — the same test the version dropdown one section up already answers.
## Verification actually run
- `make ui-test` — 844 passed (74 files), up from 843.
- `frontend/test/components/album-full-tracklist.test.ts` — 8 specs: the report's own case (2 local, 12 on the release, no declared total), the round trip back, the automatic rule still firing and still being overridable, and three absence cases.
- `tsc --noEmit` clean; `css-literals` and `frontend-typecheck` via pre-commit.
**The accessible name is asserted, not assumed**, through the browser's own computation (`page.getByRole('switch', {name})`). `wa-switch` happens to get it right, and for a third reason again: its `<input role="switch">` sits inside a native `<label>` that also holds the `<slot>`, so the name is computed across the flattened tree from light-DOM text. This app has shipped the opposite twice — `wa-slider` and `config-field`.
## Not done here
No e2e spec: the fixture library has no partly-owned MBID-matched album to drive one against, and staging one is a larger piece of work than the feature. The component tier exercises the real element with the real store code.
Closes #7
An album the user holds part of showed only the tracks on disk, with
nothing to say the rest existed. The page could already draw the full
release with the missing rows dimmed -- it just could not be asked: the
automatic rule fires on `completeness.known`, which depends on the files
declaring a per-disc total, or failing that on the catalog's own
`total_tracks`.
Neither reaches most albums. #16 fixed the first input for anything
tagged from now on, and the second is worse than it looks: the published
artifact is from 2026-08-10 and the column landed on 08-16, so
`completenessAnswer()`'s catalog fallback answers 0 for every user until
the index job republishes. Measured, and noted on #88, which is the
publish that carries it.
So the control is explicit. A "Show the whole album" switch flips the
synthetic "Your Library" entry between the local files and the release,
which is the same rendering, reached deliberately rather than inferred.
Three things about it are load-bearing:
- `showFullTracklist` is a tri-state, `null` meaning "follow the
automatic rule". The rule is right when it fires, and the switch has
to agree with the page it is sitting on rather than starting out
contradicting it -- a plain boolean would need its default recomputed
every time the completeness answer moved underneath it. The user
outranks the rule in both directions.
- `fullReleaseCluster()` falls back to the highest-scoring cluster.
`findLibraryCluster` is a guess over the `inLibrary` flags and returns
nothing at all when none are set, which is exactly the untagged
library this exists for -- without the fallback the control would be
absent precisely where it is needed. The sublabel names the release
either way rather than leaving the user to wonder whose tracklist they
are reading.
- It appears only where it can change what is on screen: against the
library entry, with a release to switch to, and only when the two
tracklists differ. A complete album's release has the same rows as its
files, so the switch would redraw the same list and read as broken --
the same test the version dropdown one section up already answers.
The accessible name is asserted rather than assumed, through the
browser's own computation. `wa-switch` happens to get it right, and for
a third reason again: its `<input role="switch">` sits inside a native
`<label>` that also holds the `<slot>`, so the name is computed across
the flattened tree from light-DOM text. This app has shipped the
opposite twice.
Closes#7
logan
merged commit 18a08daa91 into main2026-08-19 01:10:34 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Answers #7 — the next item of the roadmap's (#73) Phase 1, unblocked by #16.
What was wrong
An album the user holds part of showed only the tracks on disk, with nothing to say the rest existed. The page could already draw the full release with the missing rows dimmed — it just could not be asked. The automatic rule fires on
completeness.known, which needs either the files' per-disc total or the catalog'stotal_tracks.Neither reaches most albums, and the second is worse than it looks.
Measured, while confirming Direction part 2
The shipped artifact does not carry
total_tracks:The column landed on 2026-08-16; the artifact is from 08-10, and
index-artifact.ymlis a weekly cron rather than a push trigger. SocompletenessAnswer()'s catalog fallback answers 0 for every user today.artifactHasTotals()is doing precisely its job — which is why nothing is failing — but a probe that makes a column optional also makes its absence silent. Noted on #88, which is the publish that carries it, and in.planning/NOTES.md.That is the argument for Direction part 1 being the real ask.
Commits
feat(explore): let the album page be asked for the whole tracklistWhat it does
A "Show the whole album" switch above the tracklist, flipping the synthetic "Your Library" entry between the local files and the release — the same rendering the automatic rule produces, reached deliberately.
Three things that are load-bearing
showFullTracklistis a tri-state,nullmeaning "follow the automatic rule". The rule is right when it fires and the switch must agree with the page it sits on rather than starting out contradicting it; a plain boolean would need its default recomputed every time the completeness answer moved underneath it. The user outranks it in both directions.fullReleaseCluster()falls back to the highest-scoring cluster.findLibraryClusteris a guess over theinLibraryflags and returns nothing when none are set — exactly the untagged library this exists for, so without the fallback the control would be absent precisely where it is needed.Verification actually run
make ui-test— 844 passed (74 files), up from 843.frontend/test/components/album-full-tracklist.test.ts— 8 specs: the report's own case (2 local, 12 on the release, no declared total), the round trip back, the automatic rule still firing and still being overridable, and three absence cases.tsc --noEmitclean;css-literalsandfrontend-typecheckvia pre-commit.The accessible name is asserted, not assumed, through the browser's own computation (
page.getByRole('switch', {name})).wa-switchhappens to get it right, and for a third reason again: its<input role="switch">sits inside a native<label>that also holds the<slot>, so the name is computed across the flattened tree from light-DOM text. This app has shipped the opposite twice —wa-sliderandconfig-field.Not done here
No e2e spec: the fixture library has no partly-owned MBID-matched album to drive one against, and staging one is a larger piece of work than the feature. The component tier exercises the real element with the real store code.
Closes #7