DebuggingGENERALTOOL-SPECIFICORG-SPECIFIC

Where Did This Number Come From?

The domain's closing question. Ten things you have to be able to answer about a figure before you are entitled to act on it — and what it means when you cannot answer one.

What actually happensHow to build itCan I trust it?

Who needs this, what one row is, and why the obvious build breaks

Every lesson starts from the consumer, because designing from the source outward is this domain's characteristic mistake.

The question

A tile on the executive dashboard reads 1,245,892. Which model produced it, at what grain, from which authoritative source, through which transformations — and could you reproduce it tomorrow?

Who needs this

The person about to make a decision that costs more than the pipeline did: a finance team closing a quarter, an executive killing a product line, a pricing change, a model trained on last year, a regulator asking how a figure was derived. None of them can inspect the pipeline; all of them will act as though the number is the truth.

What one row is

One number on one tile. Its grain is invisible by construction — aggregation is a lossy operation and the tile is its output, so the whole lesson is the work of recovering the grain, the filter set and the period that the aggregation erased (Grain: What Does One Row Represent?).

The obvious build

Trust the tile. Someone built the dashboard, someone reviewed the SQL, the orchestrator is green and the number is not obviously absurd. This is not laziness — it is how every functioning organisation has to operate most of the time, because verifying every number from source would leave no time to use any of them.

Why it breaks

Two tiles built by two teams show two revenue figures for the same day, both computed correctly from the same warehouse, and neither team can say which definition the executive actually wanted (Two Dashboards, Two Numbers).

How it breaks with real data
  • Two tiles built by two teams show two revenue figures for the same day, both computed correctly from the same warehouse, and neither team can say which definition the executive actually wanted (Two Dashboards, Two Numbers).
  • The tile aggregates a mart that refreshes on its own schedule, an hour behind the model it derives from, so "today" in the tile and "today" in the model are different days for part of every morning (Data Marts).
  • The BI tool applies a join and a filter defined inside the dashboard, after every upstream test has passed. No data test can see it, no lineage tool captures it, and it changes the number (The Metrics Layer).
  • The model was re-run last night with corrected logic, so the same tile shows a different figure from the one quoted in Tuesday's board pack — and nobody kept the version that produced Tuesday's (Validating a Backfill Before You Publish).
  • The transformation uses current_date and a mutable dimension table, so re-running it for an old period produces a *different* answer than it did the first time. The number is not wrong; it is simply not reproducible (Idempotent Data Pipelines).
  • The source that everyone assumed was authoritative for customer_country turns out to be a CRM export that has been stale since a connector broke, and the payments system disagrees with it (Source of Truth).
SourceIngestionRawTransformationValidationStorage ModelServingConsumerObservability

What is actually happening

  • Aggregation destroys information on purpose. SUM(amount) over three hundred thousand rows produces one number and discards every fact about which rows, at what grain, under which filter. Lineage is the only inverse of that operation, and it only exists if something recorded it while the number was being built (Data Lineage).
  • Provenance cannot be reconstructed after the fact with any confidence. A lineage graph drawn from memory six months later is fiction; a lineage graph emitted by the transformation tool as it parses the SQL is evidence (Column-Level Lineage).
  • Reproducibility has exactly three ingredients: the inputs must still exist unchanged, the code must be pinned to the version that ran, and the logic must be deterministic — no now(), no mutable lookup, no dependence on the order rows happened to arrive in (Keeping Raw History: The Recovery Position and the Liability, Reprocessing vs Retrying).
  • Authority is a modelling decision, not a technical fact. When three systems hold customer_country, none of them is authoritative until an organisation decides which one is and makes the others explicitly copies (Source of Truth).
  • Freshness is a property of the specific dataset behind the tile, and the tile inherits the *slowest* hop in its chain rather than the fastest. A five-minute stream feeding an hourly model feeding a daily mart produces a daily number (The Freshness SLO).
  • Completeness and uniqueness are the two properties nothing in the chain promises by default. A warehouse gives you transactional writes; it does not give you the assurance that everything that happened arrived, or that nothing arrived twice (Reconciliation, Deduplication).

The ten questions

Being able to read a dashboard is not the same as being entitled to act on it. The difference is a short list of questions, and the useful property of the list is that each one has a *mechanical* answer — a table you can query, a graph you can walk, a document you can read — or it has no answer at all, which is itself the finding.

Work down the list in order. The first question you cannot answer is where the platform's real gap is, and it is almost never the one people expect. Teams that assume their weak point is compute discover it is question two; teams that have invested heavily in lineage discover it is question nine.

Notice that only three of the ten are about correctness. The rest are about *interpretability* — what the number means, what it excludes, when it was true. A number can be arithmetically flawless and still be unusable because nobody can say what it counts.

The questionHow you answer it mechanicallyWhat it means if you cannot
Which model produced it?Follow the dashboard field to its query, and the query to a named model in the transformation graph.The logic lives in the BI tool. It is untested, unversioned and invisible to every check you have.
What is one row of that model?Read the model's declared grain, then verify it with a uniqueness test on the claimed key.Nobody can write a correct aggregate against it, and a fan-out join will not be noticed.
Which transformations were applied?Walk the model graph upstream: every node is a file of SQL under version control.Some step happens outside the graph — a manual load, a spreadsheet, a stored procedure nobody owns.
Which source is authoritative?Look up the business concept in the catalog and read the declared owning system.You have three copies and no decision, so every disagreement between them is unresolvable.
How fresh is it?Compare the newest complete record in the serving dataset with now, then add the mart interval and the BI cache.Consumers are guessing, and half of them are guessing wrong in the direction that suits them.
Could records be missing?Reconcile a closed period against the source on count and on a summed measure.Completeness is an assumption. It has never been tested and it is the most commonly violated property in the chain.
Could events be duplicated?Assert uniqueness on the business key, and check for fan-out at every join in the model.Every additive measure could be inflated, and inflation is questioned far less often than a shortfall.
Which schema version produced it?Read the contract version recorded with the ingested batch, or the schema registry entry.A silent upstream change can shift a metric with no diff anywhere in your repository.
Can you trace the lineage?Query the column-level graph from the dashboard field to the source column, in both directions.Incidents are searched rather than traced, and blast radius is estimated by asking around.
Can you reproduce it?Re-run the model for a closed period from retained raw inputs at the pinned code version.The number is an artefact. You can quote it; you cannot defend it.

Ten questions, three of which are about arithmetic and seven of which are about meaning. Almost every real dispute about a dashboard turns out to be about one of the seven.

Walking upstream from the tile

GENERALThe upstream walk is a method rather than a tool and works on a whiteboard sketch of the chain. What a lineage tool changes is speed and the ability to answer the reverse question — what else does this feed — which decides blast radius rather than cause.

Debugging a number is always a walk against the direction of the data. You start where the complaint is — the tile — and ask one question at each hop: is the affected period complete and correct here? The first "no" walking upstream is where the incident lives, and everything downstream of it is a symptom.

The reason this works is that each hop holds something different and can corrupt something different. A mart can be stale but not incomplete. A join can fan out but cannot invent a country. Knowing what each node is *capable* of getting wrong turns an open-ended search into six yes/no questions.

The walk terminates in one of four places, and naming which one is the whole diagnosis. The source is genuinely different — a real business change or an application bug, and not your incident. A hop lost data. A hop duplicated data. Or a transformation faithfully implemented a definition that nobody agrees with, which is the case that no technical check will ever find (Two Dashboards, Two Numbers).

From the tile to the committed row
  1. Dashboard tile

    holds One aggregated number, plus a filter set and sometimes a join defined inside the BI tool.

    could corrupt A dashboard-level filter, a default date range, a currency conversion or a blended join that no model, test or lineage tool can see.

    ↑ reads from
  2. Metric definition

    holds The agreed expression of the metric — or, if there is no metrics layer, twenty copies of it.

    could corrupt Two defensible definitions of the same word, applied by different teams to the same underlying rows.

    ↑ reads from
  3. `revenue_daily` mart

    holds One row per country-day with revenue pre-aggregated for query speed.

    could corrupt Refreshing on its own slower schedule, so it lags the model it derives from; aggregating at a grain that cannot be re-split.

    ↑ reads from
  4. `fct_orders`

    holds One row per order, with measures and foreign keys to dimensions.

    could corrupt A fan-out join against a dimension with duplicate or overlapping-validity keys; a status filter that silently drops a category.

    ↑ reads from
  5. `stg_orders`

    holds One row per order, deduplicated and reconstructed from raw change records.

    could corrupt Choosing the latest change by arrival time rather than commit order; a cast that yields null instead of raising; dropping deletes.

    ↑ reads from
  6. Raw landing

    holds Every delivered record exactly as received, immutable, partitioned by arrival.

    could corrupt Nothing, if it is genuinely immutable — which is why it is the only place the walk can end conclusively on your side of the boundary.

    ↑ reads from
  7. Ingestion / CDC

    holds A durable position in the source's change log, and the window it has consumed.

    could corrupt A gap where the connector was down past log retention; a restart from a snapshot that re-emits history; a DDL change it could not decode.

    ↑ reads from
  8. Source database

    holds The authoritative committed state of the business process.

    could corrupt Nothing from this domain's point of view. If the number is already wrong here, it is an application incident and the walk is over (Data Engineering and Backend Engineering).

Eight hops, and only two of them — raw landing and the source — can be ruled out structurally. The other six each need an actual query against the affected period before you are allowed to move upstream of them.

Reproducing the figure

The strongest form of "I know where this number came from" is being able to make it again. Reproduction turns provenance from a story into an experiment, and it fails in ways that are always instructive: the raw partition is gone, the model reads current_date, the dimension it joined has since changed, or the code that ran is not the code in the repository.

The query below is the shape of a provenance check rather than a specific dialect's syntax. What matters is the three arguments it takes — a bounded period, a pinned code version, and an input snapshot — and the assertion at the end. A model that cannot accept all three as inputs cannot be reproduced, and finding that out costs one afternoon rather than one audit.

The second half is the more subtle failure. A model can be perfectly deterministic and still produce a different answer on re-run because a *dimension* changed underneath it. If dim_customer holds only the current tier and a customer was upgraded, then last March's revenue-by-tier is recomputed against today's tiers and quietly changes. Type-2 history is what makes "as of" expressible, and its absence is invisible until you re-run something (SCD Type 2 in Practice, Slowly Changing Dimensions).

A number you can quote
The dashboard says 1,245,892. The model is `revenue_daily`. It ran last night and the DAG was green.
A number you can defend
The figure is `SUM(net_revenue)` over `marts.revenue_daily` for March, at one row per country-day, derived from `fct_orders` at one row per order, from raw change records retained since ingestion, produced by run `2026-03-31T02:14Z` at code version `a91f3c2`, reconciling to the source within zero, reproducible from retained inputs, and excluding internal test accounts by the rule recorded in the metric definition.

The second version is not longer for the sake of rigour. Every clause in it is a question someone will eventually ask under pressure, and each clause is either a fact the platform recorded at build time or a fact that is gone forever. There is no third state where you reconstruct it later.

A reproduction check for a closed period
1-- 1. What was published, and by which run.
2SELECT run_id, code_version, published_at, SUM(revenue) AS published_revenue
3FROM marts.revenue_daily
4WHERE day BETWEEN DATE '2026-03-01' AND DATE '2026-03-31'
5GROUP BY run_id, code_version, published_at;
6
7-- 2. Recompute the same period from retained raw input, at that code version,
8-- writing to a scratch schema no consumer reads.
9-- (The run is parameterised on the period: nothing inside reads the clock.)
10
11-- 3. Assert the two agree, and reconcile both against the source.
12WITH published AS (
13 SELECT day, SUM(revenue) AS amount FROM marts.revenue_daily
14 WHERE day BETWEEN DATE '2026-03-01' AND DATE '2026-03-31' GROUP BY day
15), recomputed AS (
16 SELECT day, SUM(revenue) AS amount FROM scratch.revenue_daily_repro
17 WHERE day BETWEEN DATE '2026-03-01' AND DATE '2026-03-31' GROUP BY day
18)
19SELECT COALESCE(p.day, r.day) AS day,
20 p.amount AS published,
21 r.amount AS recomputed,
22 COALESCE(r.amount, 0) - COALESCE(p.amount, 0) AS drift
23FROM published p
24FULL OUTER JOIN recomputed r ON p.day = r.day
25WHERE p.amount IS DISTINCT FROM r.amount; -- must return zero rows

The FULL OUTER JOIN matters: an inner join hides the days that exist on only one side, which is precisely the missing-partition case you are testing for. And the recompute writes to a scratch schema — a reproduction test that overwrites the thing it is verifying has destroyed its own evidence.

The verdict: trust is a portfolio, never a property

The instinct is to ask whether the data is trustworthy, as though trust were a boolean carried by a dataset. It is not. Trust is the union of what your checks currently assert, and every check has a shape of blindness that is as important as its coverage.

That is why the misses column below is not a caveat but the substance. Four checks that each miss the same class of error give you one check's worth of confidence and four checks' worth of comfort, which is a strictly worse position than having one check and knowing it. Choosing a portfolio means choosing errors you have decided you would rather find from a consumer.

A useful way to select the portfolio: for each check, name the person who would otherwise report the failure and how long it would take them. If the answer is "the CFO, at quarter end", buy the check. If the answer is "an analyst, within a day, and they would tell us", you may reasonably decline it and spend the effort elsewhere (Quality Alerting).

The portfolio behind a defensible number
CheckExpressesCatchesStill misses
Reconciliation against the source for a closed periodThe end of the chain agrees with the beginning on count and on a summed measure.Missing rows, duplicated rows, dropped partitions, fan-out joins, an extract window that closed early — all in one query.Anything wrong identically at both ends; any period that is still open; any column it does not sum. A metric that changed from gross to net reconciles perfectly and reports the wrong thing.
Uniqueness on the declared grain keyOne row of this model really is one of what it claims to be.At-least-once redelivery, a non-idempotent re-run, a join that multiplied rows against a dimension with overlapping validity ranges.A duplicate that arrived under a new key — a producer retry with a fresh event id is two rows with two keys and one real event (Duplicate Rows).
Freshness against a stated target, per datasetThe newest complete record is recent enough for the decisions this table drives.A paused schedule, a stopped source, an upstream that silently produced nothing, a mart that stopped refreshing while its parent kept going.Data that is perfectly fresh and completely wrong. It also fires falsely on any period where the source genuinely produced nothing (Stale Dashboards).
Reproduction of a closed period from retained rawThe published figure is a deterministic function of inputs that still exist.Clock-dependent logic, mutable dimensions, manual edits to a published table, code that was never committed.Correctness. A wrong transformation reproduces flawlessly, and a reproduction test on a model whose inputs were themselves rebuilt proves only that copying is deterministic.
Metric-definition parity across dashboardsTwo tiles claiming the same metric compute it the same way.Definitional drift between teams, a dashboard bypassing the metrics layer, a filter applied in the BI tool that changes the meaning.The case where both dashboards are consistent and both are wrong, which is exactly what you get when both derive from one incorrect upstream model.

Read the misses column as a set. Its union is the space of failures your platform has decided to learn about from a human, and stating that deliberately is the difference between accepted risk and an unpleasant surprise.

Product detail — verify current documentation

Automatic column-level lineage, metrics-layer semantics and dashboard-level governance are areas where catalog and transformation products change quickly. Treat the capability boundary — which of your logic the tool can actually parse — as something to verify against current documentation rather than something to assume.

How to build it

Most important first.

  • Publish, next to every serving dataset, the four facts a consumer needs to interpret it: what one row is, how fresh it is, who owns it, and what is known to be wrong with it. A dataset without those is not an asset (Dataset Documentation, Data Ownership).
  • Generate lineage from the transformation tool rather than maintaining it. Column-level edges parsed from the SQL that actually ran are the only kind that stay true (Column-Level Lineage, The Transformation DAG).
  • Define each metric once, in one place, and make dashboards consume that definition rather than re-implement it. The alternative is twenty defensible definitions and no way to say which one a number used (The Metrics Layer).
  • Make transformations deterministic functions of pinned inputs. Pass the period in as a parameter rather than reading the clock; snapshot the dimensions a run depends on, or model them with validity ranges so "as of" is expressible (SCD Type 2 in Practice, Idempotent Data Pipelines).
  • Keep the raw arrival immutable and retained for at least as long as anyone might reasonably ask you to re-derive a figure. This is the single decision that separates "we can show you how that number was built" from "we cannot" (The Raw Landing Zone).
  • Attach a run identifier to every published row or partition, so a figure can be traced to the exact execution — code version, input range, start time — that produced it (Pipeline Observability).

What this actually promises

Naming the guarantee you do not have is worth more than naming the one you do — everything downstream inherits the weakest promise in the chain.

  • The warehouse guarantees that the query you ran returned what the tables contained at the moment you ran it. That is a real and useful guarantee and it is entirely about storage, not about meaning.
  • Nothing in the chain guarantees completeness unless a reconciliation asserts it, and completeness is the property most often assumed and least often checked (Reconciliation).
  • Nothing guarantees that the *semantics* of a column are what its name suggests. A revenue column that quietly changed from gross to net passes every type check, every uniqueness test and every freshness check there is (Semantic Changes).
  • Reproducibility is guaranteed only if you built for it. Determinism is not a default property of SQL — it is a property of SQL that avoids the clock, avoids mutable lookups and avoids LIMIT without ORDER BY.
  • Lineage tools guarantee coverage of the transformations they can parse. Logic in a stored procedure, a notebook, a spreadsheet or the BI layer is outside that boundary and is exactly where undocumented business rules accumulate (Impact Analysis).

Can I trust it?

A green pipeline is evidence that code ran. These four fields are the evidence that the data is right.

The check that would catch this
  • The check that answers this lesson directly is a reproduction test: re-run the model for a closed period against retained raw inputs and assert the published figure comes back identical. It catches non-determinism, mutable dimensions and undocumented manual edits in one assertion.
  • It misses anything wrong at the source, anything wrong identically in both runs, and everything that happens after the model — a filter added in the BI layer reproduces perfectly and still changes the tile.
  • Pair it with reconciliation against the source for the same period, because reproducibility and correctness are independent properties: a wrong number can be perfectly reproducible (Reconciliation, Data Tests).
Freshness
  • The honest answer to "how fresh is this number" is a chain, not a value: the newest complete record in the serving dataset, plus the mart's own refresh interval, plus whatever the BI layer cached. Publishing one of those three and calling it the freshness misleads every consumer who reads it.
  • Reproducibility and freshness pull in opposite directions. A number pinned to an immutable snapshot is perfectly reproducible and immediately out of date; a number computed against live tables is fresh and different every time you ask.
  • The period a consumer is asking about matters more than the clock. A closed month can be complete and reproducible; the current day is neither, and reporting it with the same confidence is the most common freshness mistake in analytics (Late-Arriving Data).
When the schema or meaning changes
  • When a metric definition changes, every historical figure computed under the old definition becomes incomparable — and the dashboard will happily plot both on one line. Versioning the *definition*, not just the code, is what makes the break visible (Semantic Changes).
  • A schema change upstream can leave the number unchanged today and wrong tomorrow, because the transformation silently absorbed a new enum value into an ELSE branch (Enum Evolution: The New Value That Broke Old Clients, Breaking Schema Changes).
  • Renaming a model breaks the lineage chain unless the tool tracks the rename. A broken chain does not show as an error; it shows as a shorter graph, which looks the same as a simple pipeline (Data Lineage).
How to re-run this safely
  • To reproduce a historical figure you need the raw inputs for that period, the code at the version that ran, and a transformation that does not read the clock. If any of the three is missing, the honest answer to "how was that computed" is that you do not know.
  • When a published figure turns out to be wrong, correct it with a bounded backfill of the affected range, validated against the source before publishing, and keep a record that the range was restated (Planning a Backfill, Validating a Backfill Before You Publish).
  • Never silently restate a number a human has already quoted. The restatement is the incident; the original figure is evidence and should stay retrievable (Data Incidents).

What can go wrong

Failure modes
  • The lineage graph is complete up to the warehouse and stops there, so the last hop — the one where a BI filter changed the metric — is invisible.
  • The reproduction test passes because it re-reads the *serving* table rather than the raw inputs, and therefore proves only that copying is deterministic.
  • Raw retention was shortened to save storage, and the ability to re-derive last year's figures went with it. This failure is discovered only when someone asks, and it has no recovery path (Data Retention).
  • A metrics layer exists and half the dashboards bypass it, so the platform has one authoritative definition and twenty unauthorised ones, which is worse than having none because it creates false confidence.
  • The run identifier is recorded in logs that expire before the questions arrive.
Misreads
  • "It came from the warehouse, so it is authoritative." The warehouse is a destination, not a source. Its authority is entirely inherited from whatever fed it, and it will serve a wrong number with exactly the same confidence as a right one.
  • "We have lineage." Ask whether it is column-level, whether it is generated or maintained, and whether it covers the BI layer. Table-level lineage tells you which model to look at and nothing about which column went wrong.
  • "The number reproduces, so it is correct." Reproducibility and correctness are independent. A transformation with a wrong filter reproduces perfectly every time.
  • "The pipeline is green, so the number is fine." This is the belief the whole domain exists to break, and it survives because it is right the overwhelming majority of the time (The Pipeline Succeeded. The Data Is Wrong.).
  • "Nobody has complained, so the dashboard is right." Nobody complains about a number that is plausible. The failures that get reported are the ones that are absurd, which are the least dangerous kind.
Privacy, retention and access
  • A figure that leaves the company — a regulatory filing, an investor deck, a published metric — carries an implicit claim that it can be substantiated. The retention policy for the inputs behind it is therefore a compliance decision, not a storage decision (Data Retention).
  • Deletion requests and reproducibility are in direct conflict: erasing a person's rows from raw history makes every figure that included them unreproducible. Resolving that requires deciding in advance which aggregates are retained as aggregates (Deletion Requests, Data Minimization).

Operating it

How you see it in production
  • A per-dataset panel that answers the four questions at a glance: grain, freshness against its stated target, owner, last successful run identifier (The Data Quality Dashboard).
  • Column-level lineage from the dashboard field back to the source column, queryable in both directions — upstream for debugging and downstream for blast radius (Impact Analysis).
  • A metric-definition registry with a version and an effective date on each definition, so a chart spanning a definition change can show where it changed (The Metrics Layer).
  • Reproduction-test results as a scheduled check, not a manual exercise. The first time you attempt it should not be during an audit.
What changes at 10x and 100x
  • At 10x datasets, the walk upstream stops being possible by memory and a catalog becomes the difference between a five-minute answer and a two-day one (The Data Catalog).
  • At 100x consumers, the bottleneck is not the graph but the *definitions*: the same metric acquires variants faster than anyone can reconcile them, and the metrics layer stops being a nicety (The Metrics Layer).
  • Retention is the dimension that scales worst, because the demand for reproducibility is driven by regulation and history rather than by data volume, and it only ever grows.
What drives cost here
  • Provenance costs storage — retained raw, retained snapshots, retained run metadata — and that cost grows with history rather than with traffic, which is why it is always cheap this quarter and never cheap in aggregate (Storage Lifecycle).
  • Column-level lineage costs parse time on every model and a metadata store to hold the graph. It is one of the few platform investments whose value is entirely realised during incidents, which makes it perennially hard to fund (Metadata: Technical, Operational and Business).
  • Reproduction tests cost a second full computation of a closed period. Run them on a sample of periods rather than all of them, and on the models whose numbers reach outside the company first.
What this approach costs
  • Everything that makes a number explainable — immutable raw, pinned code, snapshotted dimensions, emitted lineage, a metrics layer — costs storage, latency and the freedom to change quickly. A platform optimised entirely for explainability is slow to evolve.
  • A metrics layer centralises definitions and therefore centralises the argument about them. That argument was always happening; the layer makes it explicit and slower, which is the point and also the complaint.
  • Perfect reproducibility means never changing a transformation in place, which means carrying old logic forward. The realistic target is that any published figure can be explained, not that every figure can be regenerated byte-identically forever.

Where this applies

Almost nothing here is universal. These labels say what each claim is specific to, and where a different engine, format, warehouse or scale would differ.

  • GENERALThe ten questions apply to any analytical figure regardless of stack — the specific tooling that answers each one differs enormously, but a platform that cannot answer question three has the same problem whether it runs on a warehouse or a lakehouse.
  • TOOL-SPECIFICAutomatic column-level lineage depends on the transformation tool parsing the SQL it executes: dbt and similar model-graph tools give it for models they compile, while logic in stored procedures, notebooks or the BI layer produces no edges at all and silently shortens the graph.
  • ORG-SPECIFICWhich source is authoritative for a business concept is decided by an organisation, not discovered in a system. The same three databases can support three different correct answers depending on who owns the concept, and the technical work only starts once that is settled.

Where the depth lives

This domain teaches how data moves and how you know it arrived intact. It hands the rest off by name.

Domains that do not exist yet
  • Distributed Systems owns the guarantees each hop in the upstream walk inherits — delivery semantics, ordering, and what a replay actually replays. When that domain lands, every node in the lineage device here should link into it.
  • DevOps / Production Engineering owns the pinning half of reproducibility: how the transformation code is versioned, built, promoted and rolled back, and how a run records which artefact produced it.