Setu · an archived project

The evidence

Setu looked for duplicate companies in Singapore's registry and found none. Every claim in the account is here, in a form you can check. Captured 2026-07-31 from the running system, on its last day.

What the detector actually scored

The detector flagged 58 candidate duplicate pairs. Where both companies carried an ACRA identifier, the pair could be settled outright: two different registry identifiers means two different legal entities, with no judgement required.

BandPrecisionWilson LBDecisive (true/false)Unmeasurable
fuzzy0.0000.00052 (0 / 52)2
normalized name0.0000.0001 (0 / 1)3

Zero true positives over 53 decisive pairs. Five more had no anchor on both sides and are reported separately rather than folded in, because a number that quietly absorbs its own unmeasurable cases is not a measurement.

The publish gate read both bands as closed and published nothing, across the whole run. The public precision figure stayed at unmeasured by design.

The council, and what the summary could not tell me

174 verdicts across 58 pairs, from two vendors. A merge required both vendor families to agree independently; an abstention from either blocked it.

RoleModelMergeKeep apartAbstain
proposerclaude-sonnet-4-64531
skepticdeepseek-v4-pro0508
judgeclaude-sonnet-4-64531

Zero merges executed. On all four pairs where proposer and judge argued to merge, the skeptic abstained with a parse failure — output the client could not read. Not one of the four was stopped by a reasoned objection. Proposer and judge are the same vendor; the independent second opinion never arrived on any pair that mattered.

This is what a working case looks like, where the skeptic did return a verdict:

Skeptic · deepseek-v4-pro · keep apart · 1.00
Conflicting registry identifiers: Entity A has UEN 202606644K, Entity B has UEN 202626578N. Different government-issued IDs are conclusive proof of distinct legal entities, regardless of other similarities. The name similarity (NEXORA vs NEXCOR) is superficial, and the low detector score (0.330) further supports separation.

And this is what all four merge candidates looked like:

Skeptic · deepseek-v4-pro · abstain · 0.00
abstain: MemberOutputError

Do former names need a third-party index?

Searching UNITED OVERSEAS LAND on the official registry portal on 2026-07-31 returned:

UOL GROUP LIMITED
Formerly known as
UNITED OVERSEAS LAND LIMITED
UEN 196300438C · Live Company

No. The registrar resolves former names itself and labels them in the result. The 101,501-name index Setu carried was redundant for its whole life.

How much fuzzy matching the procurement join needed

All 18,464 government procurement awards, reduced to 6,151 distinct supplier names, sampled at random with a fixed seed.

78.6%

matched a registered company exactly — 393 of 500, 95% confidence interval 74.8 to 82.0. Normalising punctuation and legal suffixes recovered none of the 107 misses. Relaxing to trigram similarity produced candidates, and inspection of the candidates is the finding:

SimilaritySupplierNearest registered company
0.833SP CONSULTANCYSP HR CONSULTANCY
0.800KAK SOLUTIONS PTE. LTD.KARA SOLUTIONS PTE. LTD.
0.762ANTHOLOGY INTERNATIONAL PRIVATE LIMITEDANZ INTERNATIONAL PRIVATE LIMITED
0.711BLACKPEAK (SINGAPORE) PTE. LIMITEDBLACKBERRY SINGAPORE PTE. LIMITED
0.688TAN BOON KEETAN BOON KENG

Lowering the threshold does not recover true matches here. It manufactures false ones — the same failure the anchor measurement found on the registry, reached from an unrelated direction. The misses are individuals, foreign companies, sole traders and entities since struck off. They have no counterpart to match against.

Every assumption that went unchecked

The assumptionCost to checkWhat it was
The registry holds duplicates worth detectingone report53 checkable pairs, 53 different companies, 0 duplicates
The registrar cannot search former namesfive minutesIt can, and it prints the former name in the result
Zero merges proved the adversarial design workedone query4 of 4 blocked by a parse failure, not by an argument
The unmatched suppliers need fuzzy matchingone scanSimilarity returns BLACKPEAK/BLACKBERRY; there is nothing to match to
46 of 48 suppliers matchone seeded sample78.6%; the first sample was the head of the table
The misses match at no similarity thresholdone measurementWrong as stated; 8 of 107 exceed 0.7
A phantom row came from names with line breaksone raw dumpNo. The fix was a no-op and the result was byte-identical
Then it came from supplier names with line breaksone queryNo. It was a database client status line counted as data

The last four happened on the day the account was written, two of them while correcting the other two.

Decisions, including the one that warned me

Twenty-four decision records were written as the work happened, with the rejected options kept alongside the chosen one. Four are worth reading against what followed.

ADR-0015 — the quality oracle. Rejected "council consensus is the quality signal" on the grounds that it is self-certification with correlated blind spots. It states that consensus is not correctness. I then took the council's zero merges as evidence the design worked, without reading the transcripts, which is precisely the error this record rejects. The architecture was right and I did not follow it.

ADR-0018 — the publish gate. Rejected putting the precision thresholds in environment configuration, on the grounds that a live unattended publisher must not be able to have its own bar lowered. Safety policy stays in versioned code. This one held.

ADR-0010 — the resolver. Rejected auto-merging high-confidence pairs to cut review load, because there was no measured precision yet: surface, measure, then graduate. Had this gone the other way, the system would have merged 53 pairs of unrelated companies.

ADR-0014 — the council. Rejected a single model and same-family majority vote, requiring two vendors to concur on a destructive action. The design was sound; the failure was that a vendor going silent looks identical to a vendor agreeing, unless you read the transcript.

The raw material

Every file the numbers above came from. Checksums are in the manifest.

Counts describing the registry snapshot are as captured between 2026-07-14 and 2026-07-31. The ingest never removed entities that stopped being Live, so the entity count is an upper bound. Source: ACRA via data.gov.sg, under the Singapore Open Data Licence.