AI-Native Catalogue Enrichment Service
A catalogue-enrichment service built AI-native from a 1,675-line specification and zero code — 39% of consequential decisions made by a human, zero wrong writes to production
What is AI-Native Catalogue Enrichment Service?
A standalone micro-application built for the operator of a scheduled music-broadcast platform (client unnamed by agreement): roughly 85,000 catalogue songs had no cover artwork and no safe way to source it at scale. The service searches a music provider's public catalogue (Spotify), scores candidates deterministically, and writes artwork back to the live catalogue under human control. The entire system was built AI-native — from three written specification documents and no code — with a human making four in every ten consequential decisions, every one recorded in an auditable ledger.
Why can’t 85,000 songs be enriched by hand?
A missed artwork match is recoverable; a wrong one silently corrupts the catalogue at volume. The build had to source artwork for ~85,000 songs against a third-party catalogue whose own search is not exact, write into a live MySQL 5.7 database the client's platform depends on, and do it through an AI-native process fast enough to be worth doing — without ever letting an unreviewed wrong match reach production.
How AI-Native Catalogue Enrichment Service works
Built from 1,675 lines of specification (objective, invariants, schema, scoring weights, retry matrix, acceptance criteria) with AI drafting architecture, schema, concurrency and tests, and a human deciding domain facts, product judgement, and every irreversible action. Matching is deterministic and explainable — no machine learning in the matching path, every decision stores its score and reasoning. A 29-case labelled fixture gates all threshold changes on precision (zero incorrect automatic matches permitted); schema tests run against a pinned MySQL 5.7 container; concurrency is asserted against the real engine; 41% of the Java written is test code. Batch execution has atomic work claiming, distributed locking, and a dry-run mode that computes everything and writes nothing. The core engine is built and verified, with the first production writes deliberately scoped — five songs verified row by row, then a second bounded batch, every change attributable to a job identifier and reversible with a single statement. Full-catalogue rollout is in progress and operations hardening is not yet done — stated plainly, because a case study that omits the unfinished work is not a case study. The human-decision ledger closed at 16 of 41 consequential decisions (39%) — an enumerable count, not an impression.
Case Study in Depth
Starting from 1,675 lines of specification and zero code
The project began with three documents and no repository: a ~900-line specification (27 sections covering objective, boundaries, architecture, schema, scoring weights, thresholds, a retry matrix, 11 work packages and acceptance criteria), ~390 lines of engineering rules, and ~380 lines of agent operating rules with authentication invariants and a security review checklist. Two properties of that input mattered more than its length. It stated invariants, not just features — "a missed match is recoverable; a wrong artwork assignment silently corrupts the catalogue" decided a dozen later arguments without anyone re-litigating them. And it pre-empted a specific wrong turn by name, correcting upfront the plausible misconception that one identity provider could authorise calls to a different provider's API.
“A specification that says what must never happen is worth more to an AI-native build than one that says only what should.”
The operating model: AI drafts, a human decides
The split was not evenly distributed across the work — and that is the point. Human attention concentrated where it was worth most: domain facts the model could not know (which database, which table, which column), product judgement with no technically correct answer (when one recording appears on an album, a single and three compilations, which cover art is "right" is a taste decision about a catalogue, not an engineering one), and authorisation of anything irreversible — no write reached the production catalogue without explicit, scoped approval. Everything else — architecture, schema shape, concurrency strategy, error taxonomy, test design — was drafted by the model and reviewed rather than directed.
The decision ledger — 41 consequential decisions, auditable, not asserted
The ledger classifies the human's sixteen: four domain facts the model could not know, six product judgements with no technically correct answer, six authorisations of irreversible actions. The model's twenty-five span architecture, schema design under the real engine's constraints, and ten safety decisions — from structurally unobtainable tokens to single-statement paired writes.
When evidence outranked the design
The specification survived, but not unamended. Six changes came from the client correcting the brief — the instructive one being the datastore. The spec named PostgreSQL; the real catalogue was MySQL 5.7, which parses CHECK constraints and silently ignores them. A schema written to the specification would have carried constraints that enforced nothing, and nobody would have known. The fix expressed those vocabularies as ENUM, with tests proving the database itself rejects a bad value. When a specification and reality disagree about infrastructure, the risk is rarely the obvious incompatibility — it is the silent one.
The larger category of change could only be learned by running against real data. The provider's own search is not exact — a query naming a song's specific version returned zero results while the same query without it returned nine, so the service relaxes its search while keeping its judgement strict. Region selection was corrected by measurement, not reasoning, after the plausible choice silently deleted a fifth of the coverage. And the first live run invalidated a core assumption: the winner-margin rule, designed to flag genuine ambiguity, fired on 6 of 10 songs because the same recording legitimately appears on an album, a single and a compilation with identical scores — extrapolated across ~85,000 songs, it would have flooded a review queue no human would ever clear. The rule wasn't wrong; its scope was. A rule that is correct on ten hand-written examples can still be unusable at catalogue scale.
Caught: precision 1.000 → 0.700
A late instruction — "match title and artist exactly" — was implemented as exactly that. The labelled fixture immediately reported six wrong automatic matches: a live recording matched to a studio song, an instrumental to a vocal, one remix to a completely different remix. A song's version is part of its identity, not a detail about it. Had this shipped, it would have attached wrong cover art quietly and at volume. The fixture caught it in seconds.
Caught: a near-miss threshold one word away from auto-approval
Arithmetic review showed a title 91% similar to the source reached exactly the automatic-approval threshold — a song one word different could have been approved with no human involvement. Closed by requiring exact identity before anything unreviewed is written.
Caught: every repository silently bound to the wrong database
Declaring a second database connection suppressed the framework's default, binding every repository — including user identity and credentials — to the client's song catalogue instead of the application's own database. A test written specifically to assert the two databases stay separate caught it; it reproduced only in the production configuration.
“Tests prove what you thought to ask. Running the real artefact proves what you did not.”
Verification as evidence, not reassurance
The acceptance bar lives in files, not conversations. A 29-case labelled fixture covers exact matches, Unicode, punctuation, multi-artist credits, live, remix, remaster, cover, karaoke, duplicate titles and no-match — with precision as the gate: zero incorrect automatic matches permitted, because a missed match is recoverable and a wrong one is not. Threshold changes require fixture evidence, not argument. Authoritative schema tests run against a pinned MySQL 5.7 container because that is where the silent-CHECK behaviour lives; concurrency is asserted, not assumed — twelve threads racing for one work item produce exactly one winner, forty items across eight workers partition with zero overlap. 41% of the Java written is test code. That ratio was not a target; it is what proving these properties actually cost.
Delivered
Core engine built and verified
A fully standalone service — own build, database, migrations, security configuration, review interface, container image — reaching the client's catalogue only through one narrow adapter. Deterministic, explainable matching; encrypted provider credentials verified end-to-end; batch execution with abandoned-work recovery and dry-run. First production writes deliberately scoped: five songs verified row by row, then a second bounded batch, every change attributable and reversible with a single statement.
In progress
Full-catalogue rollout
The engine is proven; the rollout is not. The production footprint remains intentionally small, and least-privilege database credentials are specified but not yet applied.
Not yet done
Operations hardening
Metrics, alerting, deployment automation, and rollback rehearsal — stated plainly, because a case study that omits the unfinished work is not a case study. The production footprint remains deliberately small, and this page will say so until that changes.
Related Projects
Music-Broadcast Platform Modernization
ModernizationModernizing a live multi-site music-broadcast platform — mobile API, admin panel, cross-platform app redesign, and an owned analytics stack
View case study
Hop Orbits
MarketplaceMulti-vendor marketplace — co-founded and architected
View case study
Legionella 360
Compliance / SaaSMulti-tenant SaaS platform for Legionella risk assessment & regulatory compliance (ISTISAN 22/33)
View case studyLike what you see? Let's build something together.
Send Project Brief →