I never merged the four sources. Every style claim is stored with the source that made it, and agreement is computed afterwards as a separate derived layer that can be recomputed without re-scraping anything.
A genre called Corrido had 64 artists in it. Thirty-eight were Mexican, none were Spanish, and the entry was for the Spanish dance of that name. Nothing about the data looked wrong.
The visualization I built to show off the graph is what put artists and geography on the same screen, which is the only reason that kind of error is visible at all.
Every artist in Orpheus, a music knowledge graph of 43,000 rooms that you can walk around at orpheus.rocks, is assembled from four places that were never designed to work together.
Wikipedia has prose and an infobox, written by people, in whatever vocabulary felt right that day. Wikidata has structured claims, sparse but deliberate, with stable identifiers. MusicBrainz has meticulous release data and community tags. Spotify has popularity and follower counts and almost nothing else.
Ask all four what genre an artist plays and you get four answers with different vocabularies, different coverage, and different reasons to be trusted. Wikipedia’s infobox is generous and casual. Wikidata’s genre claims are rarer and more careful. MusicBrainz tags are whatever a community member typed.
The obvious move is to merge them into one answer at the point of ingestion. I want to explain why I did not, because it is the single decision that has paid off most, and it is boring.
Do not merge. Record who said what.
Every style claim is stored as its own row, tagged with the source that made it.
Wikipedia contributes two kinds, its infobox and the style pages an artist is
listed on, so four sources make five tags: infobox, pages_appears_on,
wikidata, mbzngs, spotify. A separate pass computes one more kind of row,
consolidated, which is the weighted aggregate the rest of the system reads.
The consolidation normalizes weights so that the generous source does not drown the careful one. Wikipedia’s infobox asserts far more genres than Wikidata does, and without normalization it simply wins every disagreement by volume.
I have changed that weighting several times. Each change cost a script run over data I already had. Had I merged at ingest, each one would have cost a re-scrape of four APIs, and I would have changed it less often, which is the real damage: a reconciliation you cannot cheaply revise is a reconciliation you stop questioning.
Then I built a picture of it, and the picture changed the data
Before any of this had a website, it had a dashboard called Ariadne, built in Tableau. It was meant as a way to show the graph to other people: a network diagram of styles, and you click one.
Building it forced a change to the data underneath. A style network alone is abstract, so the dashboard grew two more panels: “Who is this style?”, a sortable table of its artists, and “Where is this style?”, a map of where those artists are from. Neither was possible without joining artist data onto styles, which the pipeline had not been doing. The visualization is what made that join necessary.
That turns out to matter far beyond the dashboard, for a reason I did not anticipate.
The genre with sixty-four artists and the wrong identity
Everything in the corpus is keyed by Wikidata identifier. That is a good decision and it rests on an assumption worth saying out loud: that the identifier we stored is the entity we meant.
Here is what it looks like when it is not.
The corpus held a style called Corrido, identifier Q15306187, whose
Wikidata entry describes “a traditional style of dance and music of Spain”. It
had 64 member artists.
The Mexican corrido is Q869210. We had the Spanish one.
It happened because every source asserts a genre by name. The string
"corrido" arrives from an infobox, gets resolved to whichever Wikidata entity
carries that label, and a homonym won. Every subsequent pass reinforced it,
because the name still matched.
It was not alone. Banda music pointed at an entry for the music of the Banda people, a Central African ethnic group, and held 48 artists, 31 of them Mexican. Western music pointed at a French article about European art music, and contained Gene Autry, Roy Rogers and the Sons of the Pioneers.
Nothing here looks broken. The rows are populated, the counts are healthy, the page renders, and a style with 64 members and a Spanish-language description is entirely unremarkable, so every automated check I had was happy.
What makes it visible is putting the artists’ geography next to the style, which is the join the dashboard forced me to build. It was built as a demo, and it turned out to be the best correctness tool I have.
Two more ways identity breaks
Since I was looking, the same assumption broke twice more, both in ways that leave healthy-looking data.
The identifier moves. Wikidata editors merge duplicate items constantly, and the loser becomes a redirect. Nothing tells you. The corpus held the band Savages under two identifiers with 9 and 8 style memberships respectively, one band split in half, and because a merged identifier looks unfamiliar to the ingest gate, the survivor had been re-imported later as a brand new artist. This kind of failure does not just leave stale rows, it manufactures fresh duplicates on every later pass.
The identifier is right and the foreign key is wrong. Chasing a gap of 144 rows after rebuilding the discographies, I found 11 MusicBrainz ids each claimed by two different artists. Of the first five I repaired, four had no discography at all, because the collision had quietly handed every one of their releases to their namesake.
None of these is a scraping bug. In every case the fetch worked, the row is populated, and the result is plausible. That is the whole problem.
What I would take from this
If you are pulling one picture of the world out of several sources that disagree:
- Never merge at ingest. Store the claim with the claimant. Reconciliation is then a view you can change for the cost of a script run, and you will change it, which is the point.
- Normalize for how talkative a source is. The most generous source wins every disagreement by volume unless you stop it, and generosity is not accuracy.
- Match on identifiers, and then check that the identifier is the thing you meant. Name matching is how the Spanish corrido got 38 Mexican artists, and identifier matching would have prevented it. But identifiers drift, merge, and get attached to the wrong entity, so being identifier-canonical moves the problem rather than ending it.
- Build the picture earlier than you think you need it. The most useful correctness tool I have was built as a demo. Counts and null checks cannot see a plausible roster under a wrong heading. A map can.
The uncomfortable summary is that every failure on this page produced data that looked completely healthy, and the thing that caught them was looking at it in a form where the wrongness had somewhere to show.
The graph is at orpheus.rocks, and Ariadne, the dashboard that started it, is on Tableau Public.
Next in the series: Forty-three thousand rooms and no server →
Siegfried Martens, 26 August 2026. Part of the Daedalus notes: what was built, what it measured, and what the measurement could not see. Questions and corrections to daedalus@s-martens.com.