Drop royalty statements (and optional contracts) → normalized dataset.
↑
Drop royalty statement files here
CSV · XLSX · PDF — multiple files OK
↑
Contracts (optional)
PDF · DOCX — indexed for clause search
✓ Good: built_to_spill, other_lives, eben ·
✗ Avoid: bts_sx, other_lives_pias, built_to_spill_pub (these create dataset splits — one artist's data ends up scattered across multiple datasets)
▸ Dataset Tools
▸ Normalization Pipeline
Full pipeline for a dataset already in datasets/<name>/data_raw/:
CSV normalization → export folders → parquet→DuckDB → benchmark & Qdrant.
▸ Multi-Label Dataset
Build multiple label DuckDB databases for one dataset. Provide a JSON array of
{"source_label","output_label"} mappings.
▸ Band Builder (server folder)
Build a complete multi-label dataset from a server-side folder path.
Scan auto-detects label sub-folders and contracts; edit the config JSON before building.
▸ Advanced Pipeline
Low-level normalization / parquet→DuckDB pipeline stages. Blank fields use
their server-side defaults. Run stages in order 1→8.
Stage 1 · Full Normalization
Stage 2 · Export Folders
Stage 3 · Freeze Baseline
Stages 4-6 · Parquet→DuckDB
Stage 7 · Benchmark Parquet vs CSV
Stage 8 · Build ATO/TBD Qdrant
Build Dataset from Parquets / Index Contracts
Datasets
Dataset
DB Size
Labels
When
Dashboard
Overview of uploaded artist data.
Select an artist from the top-right dropdown to view their data summary.
Summaries
Each period compares the label's own summary totals against our independent line-by-line count of the statement detail. Status says whether the two numbers agree; the Why column says why.
Match — the label's total and our own count agree. Verified. Match (known difference) — the numbers differ, but this label is on the reviewed list below and this period's gap fits that reason. Doesn't fit pattern — check — the label has a known reason, but this period's gap does not fit its usual pattern. Investigate this period. Totals only — can't verify — the label sent totals only (no line items), so there is nothing to double-check against. Verify vs the printed statement. Missing summary — we hold line-item detail for this period but no summary covers it (a coverage gap). Mismatch — check — the numbers don't match and there is no known reason. A real red flag.
Benchmark
Compare rates across labels for the same DSP. Find underpayment.
Five methods, head-to-head, on LXNGVX/BROKE. Wiki v2 (commit
0ea7d04) addresses
Giovani's 5 critiques of the earlier framing. Headline: B-dist + E
converge ~20-27%.
Method
Spotify result
When to use
A — Peer median(current)
18.0%
Headline backstop, consistent with prior reports
B — Lowest-CV consensus cell(argmin)
18.8% (Amazon)
One cell — selection-on-noise. Replaced by B-dist below.
B-dist — Full consensus distribution 🥇
26.3%(IQR 23.3–30.0, n=52)
Defensible Method B reading — distribution beats argmin (Giovani #3)
B⁺ — Per-DSP CV leaderboard
gated
Spotify-AD US CV=0.147 would beat Amazon IF LANGA SALES_TYPE vocab is fixed (it isn't — see outcome C 2026-06-14)
C — Units-weighted mean
22.3%
Sanity check vs A — catches peer catalog imbalance
D — Cross-DSP ratio(multi-anchor)
60.2% (see caveat)
Sp/Ap ratios span 6.8× — weakly identified. Use as pattern argument, not point estimate.
E — Per-anchor matched-cell 🥇
see live ↓
Default headline. Controls territory × period mix at scale. Live numbers in the breakdown below (sourced from /api/benchmark/per_anchor_implied_eff) — they shift slightly as new peers ingest or peer-set policy evolves; the offline 2026-06-14 snapshot in the wiki was BMG 19.4% / SX 21.7% / LEX 27.3%.
Recommended stack (Giovani 2026-06-12):"B-dist + E for the headline (both ~26%), D multi-anchor for the pattern, A/C as backstops — a genuinely strong methodology stack."
🔧 Peer-set policy (2026-06-14 resolution)
UMG schemas use raw gross levels OK for level methods (A, C, D) but
produce 145× distortion in ratio methods (B, B⁺, E) due to gross/artist
ratio instability across DSPs (Giovani 2026-06-11). So: UMG-in for level methods,
UMG-out for ratio methods. Method E numbers below exclude UMG; Method A/C/D
numbers above include it.
Method E — Per-anchor matched-cell implied effective % (the headline)
For each peer label separately, match LANGA cells to peer cells at
(DSP=SPOTIFY × TERRITORY × PERIOD), compute median (LANGA artist rate ÷
peer gross rate). Each row is an independent inference from
non-overlapping evidence. Convergence across anchors is the credibility
signal. Live numbers below from /api/benchmark/per_anchor_implied_eff.
Loading Method E…
Method B-dist — Full consensus-cell distribution
Method B picked the argmin(CV) cell — one bulletproof cell, but
Giovani's critique: "argmin(CV) is selection-on-noise — one cell is an
anecdote." B-dist reports the full distribution of consensus cells
(CV<0.30, n_peers≥3, LANGA-matched). Central tendency ~26%, IQR 23–30% —
not the same number as B's single-cell 18.8%.
CV phrasing: "CV=0.24" means stddev = 24% of mean, not "rates span ±24%". Sorted by CV ascending — top rows are the strongest cross-label consensus.
Pick an artist (top-right) and click Load consensus leaderboard to compute the live Method-B consensus cells for that client. wiki §B leaderboard
⚠️ Method D multi-anchor caveat
Method D's per-peer Spotify÷Apple ratios span 6.8× (0.106
to 0.723). UMG's Apple rate ($0.0249/stream) is 4-5× higher than other
peers — almost certainly the 145× anchor bug bleeding through. Spotify÷Amazon
ratios cluster much tighter (1.4×, 0.34–0.48). Switch
the primary anchor to Amazon if you cite Method D at all.
>100% results on Pandora/Deezer are assumption failures, NOT over-collection.
When Method D returns "LANGA is 208% on Pandora," the anchor assumption broke
down for that DSP. Do NOT cite "LANGA over-collects on Pandora."
Per Giovani: "D multi-anchor for the pattern argument." The pattern
survives multi-anchor; the specific 60.2% number does not.
Within-statement — per-song rate vs contract %
For each song, computes the median per-unit net rate ÷ the cell median across
identical (DSP × Sales Type × Territory × Period) cells. If the label applies
each song's contract % inside the rate, the implied effective % matches the
contract. A gap means the song is being paid as if it had a different contract.
Select an artist with contract data (LXNGVX).
Cross-label dispersion fingerprint (deal-proof)
Within identical Spotify-family (DSP × Sales Type × Territory × Period) cells
holding ≥ 4 songs / ≥ 5K units, measures how much per-song rates spread
inside the same cell. Single-deal peers pay every song at one
statement-level split (CV near 0, p90/p10 near 1.0). LANGA's LXNGVX
subset spreads by the contract's full effective-% range —
independent corroboration of the within-statement r=+0.99, without
relying on any cross-label level.
Loading dispersion fingerprint…
Cross-label — implied total compression vs peer-label gross
Per DSP, compares the artist's per-unit net against the peer-label
median gross rate. The ratio (implied artist effective %) is
total compression — it already contains the within-statement contract-baking
effect above. Math:
artist_rate / peer_gross = contract% × (BROKE_gross / peer_gross).
Do not multiply this by the within-statement gap — it's already in the number.
Rows shown when n_peers ≥ 3. UGC / non-comparable-units DSPs (YouTube, SoundCloud,
Snapchat, Meta) are flagged — their per-stream unit semantics differ across labels.
Loading cross-label comparison…
📌 Reading the implied effective % above
The implied effective % shown per DSP IS total compression — it already contains the within-statement contract-baking effect (Layer 2, the r=+0.993 finding above). Mathematically:
Do not multiply implied eff% by the per-song gap — that double-counts Layer 2. To isolate the market-rate-floor compression alone (Layer 1, BROKE_gross / peer_gross), divide implied eff% by the song's contract effective %.
The headline finding for the demand letter: on major DSPs (Spotify, Apple, Amazon) the implied effective % comes in well below the artist's lowest contract effective %. Combined with the 0% BROKE gross visibility, the decomposition requires label-side gross data — which BROKE doesn't report. That omission is itself the reportable finding.
Cross-label time trend — Spotify rate ratio over time
Per peer label, monthly median of (LANGA rate ÷ peer rate) on matched
Spotify-family (Territory × Period) cells. A monotonic rise with stable
peer rates per cell = LANGA's catalog mix is shifting toward higher
effective-% songs over time (not a rate change). Match on
(Territory × Period) only — historical choice from when SALES_TYPE
vocab differed across labels; the Method B surfaces now resolve
vocabularies through the shared tier cell key, so extending this
trend match to tier grain is a candidate upgrade.
Loading time trend…
Cross-label — granular rate ratios (Jon's Q2)
Per peer label × DSP family, median of (client rate ÷ peer rate) on
identical (DSP × Sales Type × Territory × Period) cells. Below 1 = client pays less; above 1 = client pays more.
Note: peer rates are artist-side net under THEIR artist's deal — deal-confounded by design. Use the implied-compression table above
for the deal-proof signal; this table answers Jon's literal "Broke Spotify rate vs other label Spotify rate" question.
Loading granular cross-label ratios…
⚠️ Caveats — what we can't prove from statements alone
Per-DSP comparison conflates label cut with rate quality. A label may report ANY rate as "gross" depending on internal accounting. UMG's Spotify gross rate may itself be after some publisher / distribution cut. The peer median is the recorded gross, not necessarily the rate Spotify wired. Treat the implied effective % as an upper bound.
Sample mix differs across labels. UMG's 12B Spotify units include all genres, territories, and tier mixes. LXNGVX's 146M units skew heavily to specific territories and ad-supported tiers. A cell-level analysis would correct for this; per-DSP analysis cannot.
SALES_TYPE vocab mismatch — resolved at the benchmark layer. The Method B surfaces now key cells on the shared SALES_TYPE tier (query-time resolution through sales_type_tiers.json), so BROKE's PREMIUM/AD/GENERIC and legacy UMG/PIAS/LEX vocabularies land in common cells, with UGC/BRK granularity preserved and ledger rows excluded. The strict-grain trend table above still matches on (Territory × Period) pending its tier-grain upgrade; consensus in some cells remains peer-scarcity-bound (inferred-gross peers are excluded by design, e.g. undifferentiated-streaming cells).
BROKE's 0% gross is the headline issue. Without label-side cooperation (or a subpoena), the cross-label gross comparison Jon proposed cannot be done at the level of rigor that would survive a labor auditor's scrutiny. The workaround above is informative but not legally watertight.
YouTube outperforms. YOUTUBE VIDEO sits materially higher in implied effective % than other DSPs. Worth investigating whether YouTube's payout structure (UGC vs official video) somehow bypasses the rate-baking pattern, or whether BROKE just hasn't tuned the YouTube path the same way.
✅ Recommendations / next discovery items
Subpoena / request BROKE's label-side statements from CBMG (what the DSPs actually paid CBMG). That's the gross floor we need to close the case. Statements alone can't produce it — BROKE doesn't report gross.
Compare BROKE's Spotify gross-rate to a known-good peer at the same TERRITORY mix. Specifically, isolate cells in Latin America (Mexico, Brazil) where LXNGVX traffic concentrates, vs LEX (Dent May) which also has strong LatAm Spotify volume. If LANGA's gross there is materially below LEX's, that's the rate-floor evidence Jon needs.
For the Tritone audit product: add a "gross visibility" tile to the per-label health pane. Labels reporting <50% gross-amount-populated should get a flag. This is a generalized version of the BROKE finding — any label with hidden gross is a forensic risk.
Engineering follow-up: the cross-label benchmark UI's compare_rates() silently uses artist_amount when gross_amount is missing. That's a misleading default — it makes the comparison look apples-to-apples when it isn't. Should either fail loud or surface a "comparing different bases" warning when gross coverage is asymmetric.
SALES_TYPE alignment (separate from this audit): landed at the cell-key layer — the benchmark resolves every label's vocabulary through the shared tier map at query time, no fleet reprocess required. Remaining alignment work sits at ingest: the Carpark profile fix (SALES_TYPE should be NULL there) and a reprocess pass so the LICENSE→LICENSING and BMG value-map unifications reach stored rows.
Solid line = your STREAMING rate (Spotify / Apple / Amazon / YouTube /
Pandora / etc.). Dashed line = cross-client market avg.
Two reference bands:Mechanical Min /
Mechanical Max ($0.0007–$0.001)
applies to mechanical publishers (BMG / Kobalt /
Peermusic / etc.) ·
PRO Perf Min /
PRO Perf Max ($0.00005–$0.00015)
applies to PRO-only datasets (ASCAP / BMI / SESAC).
PROs collect performance royalties at roughly 1/10th of mechanical
rates, so artists whose only publisher is a PRO will naturally sit
in the lower band. Compare to the band matching your
publisher type.
Income mix by channel — $ per period
Stacked bars show artist $ from each performance channel per period.
PROs (ASCAP / BMI / SESAC) collect across many channels with very
different per-unit economics, so this view shows WHERE the money is —
stream rate comparison only makes sense for the STREAMING segment.
STREAMING · SATELLITE · TERRESTRIAL_RADIO · BACKGROUND_MUSIC · AV_BROADCAST · PERFORMANCE_OTHER · MECHANICAL · SYNC · LYRICS get their own segments where present.
Top earning works
Loading…
Source breakdown
No source society data for this dataset.
Select a specific artist to see KPI cards + breakdown tables.
Income group breakdown
Per-DSP rates by income type
Sub-publisher routing
Publishing source-data quality
Per-schema source-data health. gross_mirrored = AMOUNT_RECEIVED
equals ARTIST_AMOUNT on ≥50% of rows (no gross transparency, same evidentiary
class as BROKE's 0% gross). constant_income_group = INCOME_GROUP
has one value MECHANICAL across all rows. PRO labels (ASCAP / BMI) at
PERFORMANCE 100% are correct and not flagged.
Single-Label Drill-Down
Granular per-period rates for one label (no rollup).
Click Run Audit to generate a ranked list of claims you can take to your label.
Audit Scorecard
Audit Findings
Data Quality
Contract Reconciliation
Contract Terms
🌍 Territory Variance
Statistical signals (territory rate vs platform median) to investigate. Detailed
adds per-platform rate spread + all underpayment anomalies and a downloadable XLSX with the full
platform × territory matrix.
Anomalies
Suspicious patterns in your statement data — returns, chargebacks, gross-without-net rows, and other red flags worth investigating before citing them as fraud.
Deterministic risk SIGNALS to investigate (not confirmed fraud). Detailed adds
risk-by-territory / DSP / period drill-downs and a downloadable XLSX with the full ranked cohort list.
📊 Contract Royalty Rate Audit
Deterministic (no LLM): contract rates vs effective statement rates, per income type & territory.
Same data → identical report. Uses the Dataset / Label selected above.
Detailed adds the full breakdown — contract %, gross→net equation, statement rates by
revenue stream, per-territory audit verdicts, physical deep-dive — plus a downloadable XLSX with the
complete format × territory matrix.
💸 Recoupment Audit
Deterministic (no LLM): contract recoupable terms vs statement expense recoupment.
Same data → identical report. Detailed adds recoupment by category and
by period (balance trajectory), outside-contract flags, and a downloadable XLSX with the
full category × period matrix. Uses the Dataset / Label selected above.
📈 Unit-Rate Benchmark Audit
Deterministic (no LLM): $/unit per DSP / territory / period vs industry reference benchmarks;
flags low-Z-score cells. Uses the Dataset / Label selected above.
🎬 Sync / Licensing Audit
Deterministic (no LLM): sync/licensing income capture vs the contract sync rate & commission.
Uses the Dataset / Label selected above.
💿 Physical-Sales Integrity Audit
Deterministic (no LLM): physical units vs revenue, container/packaging deductions,
returns/reserves within contract limits. Uses the Dataset / Label selected above.
📉 Stream-Rate Benchmark (Method B)
Deterministic (no LLM): per-stream $/unit vs cross-dataset consensus cells (DSP × sales-type × territory),
coverage-gated. Uses the Dataset / Label selected above.
Running audit...
Deep Audit (Multi-Agent)
Runs 4 specialized domain agents in parallel (Financial, Fraud, Contract, Benchmark).
Uses the Dataset / Label selected above.
Running multi-agent audit (can take minutes)...
Field Value Inventory
Distinct value distribution for TERRITORY / SALES_DATE / DSP / SALES_TYPE.
Uses the Dataset / Label selected above.
Building inventory...
Health Check
Runs the dataset smoke test against the optional Qdrant URL.
Running smoke test...
Validation Checklist
6-step operator sign-off for the selected dataset/label: data quality gate,
contract verification, rate reconciliation, recoupment, income % validation, sign-off.
Running 6-step checklist…
Chat — Tool Agent
Ask questions about your data; the agent calls SQL / contract-search / audit tools.
Scoped to the dataset selected above. Use "Force a tool" to pin the agent to a single audit tool.
▸ Advanced
▸ Tool Trace
▸ Tool Calls (debug JSON)
Agent thinking...
Reports
Generate exportable audit reports and deep-dive analyses.
▸ Report Parameters
Optional tuning — applied when you click a report card below.
Revenue Segments
Pivot analysis by platform, year, territory, artist, sales type.
Error Quantification
Total money left on table. Breakdown by error type.
Platform Benchmarking
Per-platform per-year streaming rates with Z-score anomalies.
Detect contract rate violations with ≥95% confidence.
Cross-Label Benchmark
Compare same-platform rates across multiple labels of one dataset.
Cross-Dataset Benchmark
Compare how multiple datasets are paid by the same DSP/period.
MLC Search
Search public MLC database for works and writers.
🔀 Cross-Label Benchmark
Compares how the same DSP pays across multiple labels of the dataset selected above.
Comparing labels...
Generating report...
🌐 Cross-Dataset Benchmark
Compare how different bands / datasets are paid by the same DSP in the same period.
Pick two or more datasets from the dropdown.
Comparing datasets...
MLC Search
Tools
SQL queries, contract search, and more.
SQL Query
Results
Contract Clause Search
Results
Contract Files (PDF catalog)
Lists the contract PDFs on file for an artist and opens each via a
short-lived (5 min) download link. Separate from clause search
above — this is the source documents themselves.
Loading…
Mapping Manager — Wizard
Default All datasets / All labels = cross-label vocabulary
curation (canonical maps apply globally). Narrow to a specific dataset + label
for the focused 4-step bootstrap workflow (label confirmation → simple values →
SOURCE parsing → INCOME_TYPE).
Pick an artist from the top-right dropdown. The Master / Publishing
sub-tab below decides which side (master vs publishing dataset) the
wizard targets. "All Artists" enables cross-label vocabulary curation.
①Label
②Simple values
③SOURCE parsing
④INCOME_TYPE
Pick a dataset (artist) above to begin the 4-step normalization wizard.
Use "All datasets (cross-label)" only for global vocabulary curation across every label.
① Label
Confirm the auto-detected publisher/label for this dataset. The label drives which
per-publisher rules apply in steps 3 and 4.
(detecting…)
② Simple values
Normalize the 1-to-1 bucket maps first. These are independent of SOURCE.
when you've reviewed every simple-value map
③ SOURCE parsing
SOURCE columns pack multiple dimensions into one cell (e.g. Kobalt
APPLE MUSIC - FAMILY - GERMANY). Cross-column correlation panel
below shows the relationship between raw SOURCE and the simpler columns —
use it to spot patterns before parser rules ship.
Top 50 SOURCE patterns by row count, paired with DSP_RAW / TERRITORY_RAW / SALES_TYPE_RAW.
Pick a specific dataset above to load the SOURCE correlation table.
parser rules ship in a follow-up PR
④ Publishing income
Publishing-side classification. INCOME_GROUP is the high-level bucket
(Mech / Perf / Sync / Lyrics / Other); INCOME_TYPE is the detail row
underneath (e.g. Streaming Mechanical, Radio Performance). Both are
separate from the master-side maps in Step 2.
Reprocess this label
Re-ingest the current dataset's parquet artifact with the new mappings applied.
Triggers the PR #359 background job. Polls progress every 3 s.
Idle
Working...
Raw Statement Rows
Source rows exactly as delivered by the label — every column verbatim, before any normalization. Compare against normalized data or flag anomalies at the source.
Rows
Clear Response Caches
Drops every in-memory response cache (forensic, publishing, benchmark dropdowns,
datasets list) so the next page load sees fresh numbers immediately instead of
waiting for the 2h TTL. Use after an UPDATE/backfill against the underlying tables.
Reclassify Publishing Schemas
Backfills DSP_PARSED / SOURCE_SOCIETY / SOURCE_SUBPUBLISHER on prod publishing
schemas straight from the canonical mapping JSONs — no reingest. Idempotent;
run after a new mapping entry lands or when a schema shows the 100% NULL
DSP_PARSED symptom. Writes to production MotherDuck.
Backfilling…
Synthetic Band Generator
Generates a synthetic label band, optionally plants known fraud patterns
(F1–F18), runs it through the real ingest/summary/expense pipeline,
and scores what the audit engine catches (recall) vs. misses. Clean mode
instead checks a fraud-free band comes out penny-green on every invariant.
Dev/local only — builds write-mode local databases, so it is
disabled in production.
none = clean-mode invariant check · all = plant all 18 frauds ·
or a comma list (F1 rate underpayment, F4 phantom cost, F7 roll-forward break, …).
Fraud mode runs the pipeline twice (baseline + planted); allow ~15–20s.