Measured Behaviour
Published
Money whose owner cannot be identified does not sit still. It goes into a pool, and the pool is distributed to the rightsholders who were identified, in proportion to what they were already paid. That is the documented procedure, it clears the pool exactly, and every recipient is a legitimate rightsholder receiving a legitimate share. We measured what happens when one name decides which of those two things occurs.
Forty lines, twelve works and five rightsholders
We built a distribution run the way one is really shaped: a works registry of twelve recordings across five rightsholders, with three of the five holding most of the catalogue, and a service usage report of forty lines carrying 213,000.00 in receipts.
Thirty-one lines carry clean metadata. Nine are dirty in the ways real reports are dirty: six carry a recycled or mistyped recording code with the right title and artist, three carry no recording code at all. Five more were reported after the claim window closed and three predate the registration of the work they belong to, which is an ordinary back-catalogue situation. The society matches on three identifier fields at sixty-six per cent agreement, refuses to guess at a line with no identifier, holds unclaimed money for the claim period rather than sweeping it into the distribution, and takes twelve per cent administration.
The correct run matches twenty-nine lines and leaves eleven unmatched. It pays 142,718.40 across the five rightsholders and holds 50,820.00 in the pool. The society's own rule - the pool must clear and no more may be paid than was received - passes.
Protected with default settings on five profiles - the ES5 target, the modern target, both emit-gate configurations and the string-encoding profile - the run was byte-identical. What follows required member renaming to reach names on the society's configuration object.
The arm where nothing about the matching changes
unmatchedPolicy decides what happens to money whose owner was not found. This society holds it. The library redistributes it, because redistribution is what clears a pool and a library cannot hold money it does not custody.
Renaming it changed nothing in the matching stage. The same twenty-nine lines matched. The same eleven did not. The pool was the same 50,820.00, to the cent. The receipts were the same 213,000.00, split across the same two reporting services in the same amounts.
What changed is where the 50,820.00 went. Held fell to 0.00 and redistributed rose to 50,820.00. Every one of the five rightsholders was paid more: Arden Publishing 34,249.60 to 44,981.90, Kestrel Records 48,241.60 to 63,358.37, Northfield Music 35,006.40 to 45,975.85, Smallfield Songs 7,304.00 to 9,592.75, Tallow Catalog 17,916.80 to 23,531.13. The distribution total went from 142,718.40 to 187,440.00.
The society's rule passed in both arms and reported the same thing: 213,000.00 received, 213,000.00 accounted for across five rightsholders, eleven unmatched. Both statements are true. Both runs clear.
Why nobody is in a position to notice
Reconciliation is the standard mitigation for money moving between parties, and it is genuinely useful. Here it is not merely closed by construction - it is actively correct. The pool is defined as receipts less what was matched, and it is then distributed in full. The identity holds however the money is split.
The five parties who received the money are real rightsholders. The formula that gave it to them is the society's published one. Their statements are correct: they show a larger figure, and a larger figure on a royalty statement is not a defect anybody queries.
The eleven works whose money moved belong to somebody who is not on the distribution at all, because a society does not send a statement for a work nobody matched. There is no party in the system whose own records would show a discrepancy. The only evidence is a policy line in a configuration dump reading redistribute where the contract says hold.
The matching options move real money too
identifierFields lists three fields; the library knows about one. Renaming it drops the six lines with a bad recording code but good title and artist. Matches fell from twenty-nine to twenty-four, the pool rose from 50,820.00 to 77,680.00 and the distribution fell to 119,081.60.
That failure ran in the safe direction only because this society holds unclaimed money. A society that redistributes - which is the library's default, and one rename away - would have handed the extra 26,860.00 to the same five parties.
requireIdentifier is the guard against guessing. Renaming it made the engine guess at the three lines with no recording code at all: matches rose to thirty-two and the pool fell to 30,380.00. Those three lines were paid to whichever registry entry scored highest, which is exactly the outcome the flag exists to prevent.
claimWindowDays took five late claims to zero and matched thirty-four lines. adminFeePct took the society's own twelve per cent to nothing and paid out 162,180.00 instead of 142,718.40. And renaming the registeredDay field on the registry matched three lines to works that were not yet registered when the usage was reported, taking the pool to 42,600.00. None of the four threw and none changed the receipts.
One honest negative, and one masked half
matchThresholdPct was completely inert. The society requires sixty-six per cent agreement; the library accepts any agreement at all. In this report no line sits between those two values - a line either agrees on all three fields, on two, or on one - so lowering the floor changes nothing.
That is an honest negative about the data, not evidence about the name. It is worth reporting because the union tells a different story: renaming the identifier list and the threshold together produced figures identical to renaming the identifier list alone. A test that ran only the broad pattern would report one failure and see nothing about the threshold at all.
This is the same masked-half shape we measured twice more in the same session, in two unrelated areas. An arm that measures inert is not evidence of safety, and a clean reading on a wide pattern is not evidence about its halves.
What we are not claiming
None of this is a defect in the obfuscator. All five protection profiles produced byte-identical output, in this area and in the four measured alongside it. Every failure above required member renaming to be pointed at names that cross into an unprotected library.
The mitigation is scoping plus one assertion, and the assertion matters more here than anywhere else in this pass, because there is no downstream party who can raise the alarm. Keep MemberRegexp off third-party options literals - the mechanics are in Protect Members - and have the distribution engine report the unmatched policy it actually read, then refuse to run when it does not match the society's rules.
If you are shipping the matching or reporting client itself, Protect an Embeddable JavaScript Widget or SDK covers the configuration for code that runs inside somebody else's page.
Frequently asked questions
Does obfuscation break usage matching?
Not on its own. Protected with default settings on five profiles - the ES5 target, the modern target, both emit-gate configurations and the string-encoding profile - the distribution run was byte-identical. The failures required member renaming to reach the society's configuration object.
What did the unmatched policy arm actually do?
It moved 50,820.00 that was being held for eleven unidentified works into the distribution, where it was split between five rightsholders by market share. The matched count, the unmatched count, the pool total and the receipts were all identical, and the society's own rule passed in both arms.
Would a reconciliation have caught it?
No. The pool is defined as receipts less what was matched and is then distributed in full, so the identity holds however the money is split. Both runs reported 213,000.00 received and 213,000.00 accounted for.
Who would notice?
Nobody in the system. The five parties who received the money are real rightsholders whose statements are correct and larger. The owners of the eleven unmatched works are not on the distribution at all, because no statement is produced for a work nobody matched.
What did the identifier options do?
Renaming the identifier field list dropped the six lines with a bad recording code: matches fell from twenty-nine to twenty-four and the pool rose to 77,680.00. Renaming the require-identifier flag made the engine guess at the three lines with no code at all.
Was any option inert?
The match threshold was, because no line in this report scores between the society's sixty-six per cent and the library's zero. That is a fact about the data rather than about the name - and renaming the threshold together with the identifier list produced figures identical to renaming the list alone.
What is the mitigation?
Scope MemberRegexp away from third-party options literals, and have the distribution engine report the unmatched policy it actually read so a run can refuse to proceed when it disagrees with the society's rules. See Protect Members.
Related reading