Device Source of Truth

I built a device registry inside Disney to put hardware, DRM, codecs and readiness in one place. This demo is a fork of that system, reseeded with data I invented.


The answer depended on who you asked

Can this device support Dolby Vision? Which partners still run an ADK build that just went end-of-life? When a partner replaces its OS stack—Amazon moving Fire TV to Vega OS—which devices are affected, and what is their certification status?

At Disney, I kept hearing these questions from partner engineering, certification, support and platform teams. The answers existed. Finding them was the problem.

They were in Airtable, Datadog, partner-submitted Excel questionnaires, and spreadsheets that different teams updated on different schedules.

I saw support tickets that should have been lookups, launch timelines slip while teams reconciled records, and partner conversations without a shared set of facts. That is my account of the cost. The repository does not document those outcomes.

I built Device Source of Truth inside Disney to import those sources into one shared schema: a record I could query and audit. It came from the partner-engineering work I spent a decade doing there. It was the tool I’d wished existed before I sat down to build it.

What is on this page is a fork of that system, running on data I invented for it. It is the same codebase with the real records replaced, rather than a reimplementation from memory or the production instance.

Five feeds, one gate

The registry takes five feeds: an AllModels device-inventory CSV, Airtable intake requests, partner-key mappings and telemetry snapshots exported from Datadog, and a partner’s Excel questionnaire.

The questionnaire commonly has 100–150 answered questions across sixteen sections. AI reads it in 30-pair batches and maps it onto a 260-field device model. Extraction first shipped fire-and-forget, then was rebuilt as an idempotent per-device task queue with retry and stale-job recovery.

I kept the same rule across the feeds: preview before committing, and require an admin for every commit.

I did not model those four teams as personas. I used three roles: a viewer reads the registry, an editor authors records and stages the questionnaire import, and an admin alone commits or deletes. Fifty of the API’s sixty role guards are admin-only. That is where I put the risk boundary.

There is a limit to that rule. On four feeds, the interface requires the preview, but an admin can call the commit route directly without seeing it. On questionnaire intake, the server refuses to commit until every staged record has been reviewed.

Figure 1

Exceptions are work, not errors. I made telemetry rows for an unknown device or partner key raise an alert with Register Device or Create Key attached. The work item carries its remedy.

Creating a key auto-dismisses every matching alert server-side. Registering a device closes its alert from the client, through the ordinary dismiss route. The other four feeds raise no alerts; they show exceptions inline in their previews.

The exception queue on the deployed demo: fifteen alerts, every one of the two types the system actually emits—Unregistered Device and New Partner Key, both raised by telemetry uploads. Each alert carries its own remedy—Register Device, Create Key, or Dismiss—and a dismissed row keeps its reason and the actor who dismissed it, so a closed exception still explains itself.
Figure 2: The exception queue on the deployed demo: fifteen alerts, every one of the two types the system actually emits—Unregistered Device and New Partner Key, both raised by telemetry uploads. Each alert carries its own remedy—Register Device, Create Key, or Dismiss—and a dismissed row keeps its reason and the actor who dismissed it, so a closed exception still explains itself.
  • 260 fieldsthe device model I map a partner's questionnaire onto, from 100–150 answered questions
  • 5 feedseach feed previews before committing; all five commits require an admin
  • 3 rolesviewer, editor, admin—fifty of the API's sixty role guards are admin-only
  • Private repothe demo stops at a restricted login; the screenshots show what I can make public

The decisions

I let the same codebase treat AI confidence differently in two places. On CSV disambiguation, a name resolved at 0.90 stops asking its clarification question, though the import still needs preview and commit. On questionnaire intake, confidence colors the review screen and decides nothing. Every questionnaire still needs review.

Extraction was allowed to be the labor and never the authority. The first decision below explains why. The others cover older snapshots, stale answers and partner names that refuse to stay tidy.

All four decisions are pending. The workflows shipped, and the captures show them in the deployed demo. The restricted login prevents a public check of their current operation, and no artifact records a team adopting the tool. I can show the implementation. I cannot claim a usage outcome.

  1. TrustPending

    Extraction proposes; a human signs

    What I encountered
    The heaviest intake is a partner's Excel questionnaire: commonly 100–150 answered questions across sixteen sections, mapped onto a 260-field device model. AI reads it in 30-pair batches and proposes values, with a self-reported confidence for each extracted field. I could have let a high enough number commit the record.
    Over
    Auto-commit above a confidence threshold. I already let confidence settle name matches on the CSV path: at 0.90 it auto-resolves without asking a clarification question. I set that threshold. The CSV still needs an admin-confirmed preview, so the difference is what the number can decide before sign-off. On questionnaire intake, it decides nothing.
    What I decided
    I gave confidence no authority. The number is stored once and shown as a review badge. Every questionnaire needs review, and its only commit route requires an admin. The server refuses until every intake partner is reviewed, a partner is assigned, every device is approved or rejected, and every conflict with the existing registry is resolved.
    Why
    A wrong CSV match mislabels one row, with an import preview still ahead of it. A wrong questionnaire field becomes the registry's answer about DRM or codec support. I wanted to trust that answer. The spec states the boundary: no questionnaire data enters the database without my explicit review.
    Cost
    Intake cannot run unattended. Every questionnaire waits for an admin to walk a four-step wizard and review every device. AI saves drafting work; throughput still depends on one reviewer's attention.
    Validation boundary
    The approve route refuses server-side while anything is unreviewed. The model's confidence has exactly one consumer: the review screen. I still need a live intake queue to tell me whether mandatory review catches extraction errors or only adds friction.
Extraction proposes; a human signs, on the deployed demo. A four-step wizard—Assign Partner, Review Devices, Resolve Conflicts, Sign Off—holds three intake partners at pending review. Each extracted device carries its own Approve and Reject, a 44-fields-extracted count, and the registry's verdict on whether it matches an existing record. The server enforces what the wizard shows: the approve route refuses while any of it is unresolved.
Figure 3: Extraction proposes; a human signs, on the deployed demo. A four-step wizard—Assign Partner, Review Devices, Resolve Conflicts, Sign Off—holds three intake partners at pending review. Each extracted device carries its own Approve and Reject, a 44-fields-extracted count, and the registry's verdict on whether it matches an existing record. The server enforces what the wizard shows: the approve route refuses while any of it is unresolved.
  1. IntegrityPending

    An older snapshot does not silently win

    What I encountered
    Telemetry arrives as CSV snapshots, sometimes out of order. Re-upload last month's export and it can overwrite this month's record. Last-write-wins is the easy default: the most recent upload wins, even when its data is older.
    Over
    Last-write-wins. It usually gives the right answer, which makes the old-export mistake easy to miss. The corruption appears only when someone re-uploads an older file.
    What I decided
    I made the preview flag rows older than the stored snapshot and warn before they overwrite newer data. The commit skips them unless the admin overrides each row by index. The result returns a count of stale rows overwritten.
    Why
    A registry that a well-formed file can silently regress is not a source of truth; it is a cache with better branding. I wanted a person to say so, row by row, before older data replaced newer data, and a record of what they overwrote.
    Cost
    Backfilling history now takes one override per stale row, by index. Skipped rows do not enter a queue: the commit counts them as no-change and moves on. An unattended import still finishes, minus those rows, and its response cannot distinguish them from rows that already matched. The preview is the only warning, before commit.
  2. FreshnessPending

    Freshness is shown, never enforced

    What I encountered
    The answers get older between partner uploads. I could have hidden stale devices, blocked a query, or required a fresh import before the registry answered.
    Over
    Enforce freshness: exclude stale records from queries and exports, alert on age, or require a re-import before answering.
    What I decided
    I chose a badge: fresh under 48 hours, aging under seven days, stale beyond. One client function hardcodes both thresholds and calculates age from the stored telemetry timestamp when the browser renders. The result is not persisted, and nothing else consults it.
    Why
    I wanted the reader to see how old the data was and decide whether that mattered. Nine-day-old telemetry can be disqualifying during an incident and fine for a planning meeting. The system knows the age; only the reader knows the stakes.
    Cost
    Nobody has to look at the badge. Staleness triggers no alert, removes nothing from an export, and blocks no workflow. I built no mechanism that makes anyone act on age.
Freshness is shown, never enforced, on the deployed demo. This device wears its own doubts: the badge reads "Updated 9 days ago" against a 28-day telemetry window—past the seven-day threshold, so the record presents as stale rather than being hidden or blocked. Nothing downstream acts on that badge. The record stays usable and its uncertainty stays visible, which is the whole of the decision. The reader decides whether nine days is fine for planning or unacceptable mid-incident.
Figure 4: Freshness is shown, never enforced, on the deployed demo. This device wears its own doubts: the badge reads "Updated 9 days ago" against a 28-day telemetry window—past the seven-day threshold, so the record presents as stale rather than being hidden or blocked. Nothing downstream acts on that badge. The record stays usable and its uncertainty stays visible, which is the whole of the decision. The reader decides whether nine days is fine for planning or unacceptable mid-incident.
  1. IdentityPending

    Aliases resolve; they do not merge

    What I encountered
    The same operator arrives under different identifiers: a key in telemetry, a friendly name in the key mapping, a name in the questionnaire header. I could have picked a canonical name, merged the records, and deleted the variants.
    What I decided
    I put an alias registry in front of the partner records. Names resolve by exact match, then registered alias, then fuzzy similarity at 0.90. Alias hits are tagged direct or contextual: some names need the feed's context to resolve correctly. On the partner-key CSV import, an unmatched name creates a partner instead of failing the file.
    Why
    The next export will send the variant names again. Merging the records would only let the next import recreate the duplicate. I kept the raw names resolvable to a canonical partner so the mess stayed at ingestion.
    Cost
    The ambiguity is managed forever instead of eliminated once. Every feed carrying a partner name uses the resolver; an admin maintains the alias rules by hand. Telemetry resolves by partner key. A flat partner list still needs that machinery in front of it. I do not yet know whether the alias registry absorbs real upstream drift or becomes permanent admin toil.

Nothing real is on display

I invented all the data in those screenshots. Forking the working system was the cheap half. Making it safe to show took the rest.

A scrub replaced the deployed records in August 2026. The instance has used synthetic seed data since: invented operators under an invented streaming group, a synthetic marker on every seeded document, and a dataset header that opens “Every name in this file is invented.”

Where production said ADK, the demo says SEK, an invented kit name. That rename happens in the display layer; the schema keeps its field names. SEK in a screenshot tells you the data is fake.

I kept the repository private. Scrubbing deployed data did not remove the real partner identities from specs and history. A public repository link would return a 404 to everyone else, so this page has none. The demo button stops at a domain-restricted login.

The screenshots are what I can make inspectable: real workflows, invented data.

What I learned

A source of truth is not a database with all the data in it. It’s a system that decides three things and says them out loud: what can become authoritative, what requires a human, and what happens when two sources disagree.

DST did not eliminate ambiguity. It gave ambiguity somewhere to live. Stale records keep their age visible. Aliases stay at ingestion because the next export will send those names again. Unknown devices become work items with a remedy attached. AI extraction stays a proposal until someone signs it.

I could have treated normalization as tidying up. Instead, I took on a badge nobody must read, an alias registry to maintain by hand, a queue that only closes when a person works it, and an intake pipeline that cannot run unattended.

What those choices buy is a registry that never asserts more than it can defend. For a system whose entire job is being believed, that is the trade I wanted to make.