# Stem-Player Site Categorization — a study in doing it without fraud

A 5-angle survey + a 3-layer adversarial critique of how to categorize our stem-player catalog, with every empirical claim checked against the disk. Live: https://drwu-htmls.vercel.app/stem-categorization-study

## ① The situation
Our players live on `/stems-board` and `/all-sites`. Today they are organized **by how each file was made** (pipeline stage), not by what a listener wants. The `BANDS` registry carries no browse metadata. Three problems: no browse facets (past ~20 items a flat grid breaks), the spine leaks our plumbing, and there is no honest metadata spine, which is where the fraud risk starts.

## ② What most people do (survey, 5 angles)
- **Sample/loop libraries (Splice, Loopcloud, Output Arcade):** faceted orthogonal tagging, technical axes machine-extracted at ingest, facets double as live transforms. Breaks for us: assumes atomic royalty-free blocks, no field for owner-band or stem-lane shape.
- **Stem/DJ/karaoke (Moises, NI STEMS, djay, Karaoke-Version):** track-as-row, stem-as-control-strip, browse by artist/title, process hidden. Our grid leads with the one axis they all hide and omits the axes they all lead with.
- **Streaming (Spotify, Apple, Bandcamp, Tidal):** immutable Artist>Album>Track spine, browse as secondary indexes, mood/algorithm need scale we lack. Bandcamp (hierarchy + human editorial + tags) is our real analog.
- **Metadata standards (MusicBrainz, Discogs, ID3, RYM):** layered hybrid — a checkable identity spine, a fenced opinion folksonomy, a derived-feature layer kept in separate columns. The rule: a field is honest only if DERIVED or labeled EDITORIAL.
- **IA theory (Ranganathan, Morville, Nielsen):** faceted classification beats trees and free tags; keep a flat default + progressive disclosure; a facet earns its place only if it splits the set into 2–8 non-trivial buckets; heavy facet chrome is premature until the catalog roughly doubles.

## ③ Three critique layers
1. **Naive fix (genre dropdown + artist A-Z):** killed — genre-first inverts an ~80% prog/post-rock corpus into one fat bucket + singletons; genre is non-orthogonal; artist A-Z is a sort not a find. Proposed: flat default + small derivable facet rail. Admitted: never inspected the folders.
2. **Counted the files:** format facet is all-mp3 (one bucket); stem-lane shape is the most homogeneous axis, not the most heterogeneous; artist/year/genre/owner live only in typed title strings, so "fraud-check re-derives" was checking facts not in the bytes. Proposed: listen-vs-analyze spine, one `players.json` with DERIVED/STATED flags, constants → badges. Admitted: the STATED tag has no external referent.
3. **Read the generator and the deploy, then left the frame:** Layer 2's "verify 6 lanes on disk" gate is not runnable (top items have zero local audio, served cross-origin); lane-count is per-song (36/60/72-file albums); the "16-player corpus" is a phantom (17-slug set with 3 non-players). Deepest cut: **categorization was never the job** — at 14 owned records there is no findability problem, there is a point-of-view problem. Proposed: a curation-argument task with an MBID-anchored provenance spine. Admitted, most honestly: a thesis has no gate, and if the 14 are an accretion not a canon, manufacturing a thesis is its own quiet fraud.

## ④ Verified on disk (3/3)
- **Roster is not 16:** `PLAYERS` in `build_topic_boards.py:95` = 17 slugs; 3 are non-players (`m4aupload`, `believeyoume-chord-rail`, `mashup-dashboard`). Real count: 14.
- **Top two items have no local audio:** `believeyoume-stems/` and `beachhouse-stems/` hold only `index.html` + `index.md`, 0 audio (cross-origin from drwu-media).
- **Lane-count is per-song:** rush=36, mars-volta=60, dream-theater=72 audio files — multi-song albums.

## ⑤ How we innovate authentically
1. **Reconcile the roster first** (drop the 3 non-players) so the count is real.
2. **Two-level registry:** `players.json` (album: artist/album/year/owner) + child `songs[]` (lane_count, has_guide) derived from the real manifest.
3. **Lead with a thesis, sort by meaning:** one owner-written through-line, his own band placed deliberately among its influences (the Bandcamp / 33⅓ model). Owner-vs-reference becomes the layout's center, not a boolean.
4. **Make provenance real:** capture a MusicBrainz release-group ID per album so the closeout gate can verify stated year/artist against an external authority; label the thesis/order/genre as the owner's editorial claim; wire the registry check into `ship.py` so a missing row blocks deploy.
- **Caveat 1 — test the null hypothesis:** maybe the honest answer is a flat grid in a deliberate order + one caption, nothing more.
- **Caveat 2 — do not manufacture a canon:** the thesis is honest only if the curation is real; that sentence is the owner's to write, not ours to generate.

## ⑥ The fraud line
**Categorization is a provenance problem, not a taxonomy problem.** A field is honest only when its value is re-derivable from the bytes or an external authority, or it is plainly labeled as the owner's claim. Anything in the middle is opinion wearing a fact's clothes, and that is the whole of the fraud.

---
Built from an 8-agent workflow (5 survey + 3 critique), every empirical claim checked against `~/Projects/drwu-htmls/public`.
