Chapter 11 · Surrogate Keys, Late-Arriving Facts/Dimensions, Deletes, Restatements, and History Corrections

Design a Correction Workflow that Preserves Reproducibility While Supporting Authorized Restatements

Run a versioned AtlasMart correction workflow with before/after controls, audit ledgers, reproducibility hashes, replay safety, impact analysis, and rollback-by-new-revision semantics.

Intermediate → Advanced135–155 minutesCorrection/reproducibility suitePython stdlib sqlite3 · local/syntheticLast reviewed: September 2026

Learning outcomes

A trustworthy warehouse must be able to explain not only today's answer but why yesterday's published answer changed. The final Chapter 11 lab runs a correction sequence from the accepted Chapter 10 state through a backdated dimension split, fact re-keying, a late sale, an authorized metric restatement, source deletion, and a privacy workflow—without deleting the evidence needed to reconstruct each checkpoint.

01

Run the complete correction sequence with deterministic controls and warehouse-state hashes.

02

Use correction, dimension-change, tombstone, and deletion ledgers as separate audit surfaces.

03

Prove replay safety for the late fact, correction, source delete, and erasure request.

04

Distinguish current published state from superseded revisions retained for reproducibility.

05

Define rollback as another authorized/versioned transition instead of deleting correction evidence.

Chapter 11 continuity contract

Chapter 11 preserves all accepted AtlasMart contracts from Chapters 01–10. Before this chapter, current sales contain seven paid order-line facts, four paid orders, nine units, 625 paid GMV, 380 cost-at-sale, and 245 gross profit. Customer history uses Chapter 07's half-open business-effective intervals; Chapter 08 special dimensions, Chapter 09 bridges, and Chapter 10 fact-shape contracts remain valid. Chapter 11 adds versioned fact revisions and correction/audit surfaces without changing the business grain. A backdated C001 segment correction affects historical attribution, one late order line increases the current sales population, and one authorized O1002 amount correction changes a published metric under an explicit restatement record.

Execution, legal, and interpretation note

The mandatory lab is synthetic, local, and disposable. It uses Python's standard-library sqlite3 module and SHA-256 hashes only as reproducibility evidence. The lab proves local key-resolution, revision, temporal, and audit mechanics; it does not prove distributed exactly-once delivery, legal compliance, production deletion completeness, or cloud-warehouse behavior. Privacy/erasure requirements depend on applicable law, controller policy, purpose, retention obligations, backups/exports, and other state surfaces.

Important boundary

A reproducibility hash proves byte-for-byte equality of the selected local state surfaces under this canonical serialization. It does not prove business correctness by itself, and a different serialization or engine may produce a different hash for semantically equivalent data.

1. Acceptance sequence and controls

Stage Current lines Orders Units GMV Cost Gross profit
Accepted Chapter 10 baseline 7 4 9 625 380 245
After backdated dimension split + key restatement 7 4 9 625 380 245
After late O1000 line arrives 8 5 10 700 425 275
After authorized O1002 amount restatement 8 5 10 690 425 265
After source-delete + privacy workflow 8 5 10 690 425 265

The sequence deliberately contains two kinds of correction. The backdated segment split changes dimension attribution but preserves 625 baseline GMV. The late O1000 line adds 75 GMV. The finance-authorized O1002 restatement subtracts 10 GMV, producing final current GMV 690. Delete/privacy workflows then leave sales measures unchanged.

2. Reproducibility hashes at each checkpoint

Checkpoint Warehouse state SHA-256
Baseline 12d653cd547d4b0a04722689830ca703971a3032d1ac5d907f2fc6c06e24b1aa
After backdated dimension correction a418b1b20fbc70707127139217c978fca3b7486bace762d4512087ecd9a24c39
After late fact 6e3cae5162a2a66e42882d7060dad8873dda01fe6f680184b609b869d5d3f12d
After metric restatement 0504f85f8426220bd1e4f232faffd289edc643e84a2b150b98ea2d00793dc91f
Final after delete/erasure workflows cee78f4d83444e9fdcd98b3d1dbaebfcd2c48bf8c8d9f41f9383ee0cad2bbdad

Each hash covers current fact revisions, complete customer-history rows, correction records, tombstones, and deletion manifests under a canonical JSON serialization. Store the hash with batch/release metadata if consumers need evidence that a snapshot is reproducible.

3. End-to-end deterministic acceptance script

chapter11_acceptance.py
conn = build_base_conn()assert fact_controls(conn) == (7,4,9,625,380,245)# 1) retroactive dimension correctionassert apply_backdated_segment(conn) == 'split_interval'changed = restate_dimension_keys(    conn,'D-CUST-001','2026-09-18T08:30:00','2026-09-19T00:00:00')assert len(changed) == 2assert fact_controls(conn) == (7,4,9,625,380,245)# 2) late fact resolves event-time versionsk = apply_late_fact(conn)assert conn.execute('SELECT segment FROM dim_customer_history WHERE customer_sk=?',(sk,)).fetchone()[0] == 'Growth'assert apply_late_fact(conn) == 'replay_ignored'assert fact_controls(conn) == (8,5,10,700,425,275)# 3) authorized metric restatementassert apply_metric_restatement(conn) == (200,190)assert apply_metric_restatement(conn) == 'replay_ignored'assert fact_controls(conn) == (8,5,10,690,425,265)# 4) lifecycle/privacy workflows do not silently change salesassert apply_source_delete(conn) == 'inactivated'assert apply_privacy_erasure(conn)[0] != apply_privacy_erasure.__name__  # illustrative call site; run once in real scriptassert fact_controls(conn) == (8,5,10,690,425,265)

The actual generated fixture executes the erasure exactly once and separately verifies replay returns replay_ignored; the compact lesson snippet emphasizes the sequence rather than duplicating the full helper implementation.

4. Audit surfaces answer different questions

Audit surface Question answered Do not use it as
dimension_change_ledger which descriptive attribute changed, from/to what value, and effective when? proof that every affected fact was restated
correction_ledger which fact revision changed, why, who authorized it, and before/after hashes? a substitute for the source event itself
source_tombstone which source delete signal was observed and when? a GDPR decision record
deletion_manifest what privacy-oriented technical scope was applied and verified? a repository of erased clear-text values
warehouse state hash is this selected canonical state identical to a known checkpoint? business correctness or legal-compliance proof

5. Current state and historical state are both first-class

The current BI view should filter is_current=1 fact revisions. Reproducibility/debugging workflows may query superseded revisions by correction ID or recorded time. Do not expose revision mechanics accidentally to every analyst; provide governed current and audit views with explicit semantics.

current_vs_audit.sql
-- current published salesSELECT * FROM fact_sales_revision WHERE is_current=1;-- audit trail for corrected O1002 line 1SELECT order_id,line_no,revision_no,extended_amount,is_current,correction_id,recorded_atFROM fact_sales_revisionWHERE order_id='O1002' AND line_no=1ORDER BY revision_no;

The audit query shows both 200 and 190 revisions, with only the corrected revision current.

6. Rollback means a new governed revision

If the O1002 correction is later found wrong, do not delete revision 2 and resurrect revision 1 invisibly. Create a new authorized correction (revision 3) that restores the approved value, record who authorized it and why, recompute affected aggregates, and publish a new state hash. This keeps the sequence of published truths reproducible.

7. Downstream impact and communication

Before publishing a restatement, identify dashboards, extracts, semantic metrics, aggregates, financial reports, ML features, caches, and external data products that consume the affected rows or attributes. A correction can preserve total GMV while changing segment attribution, or change GMV while leaving dimensions untouched. The notification should state which semantics changed, effective period, correction ID, before/after controls, and whether consumers need refresh or backfill.

8. Cleanup/reset

The mandatory lab is in-memory SQLite. Closing the process discards all tables; calling build_base_conn() recreates the accepted Chapter 10 baseline. No production data, credentials, or paid services are involved.

Knowledge check

Check your understanding

  1. Why keep superseded fact revisions after a correction?
  2. What is the final current GMV in the canonical Chapter 11 sequence?
  3. Why does the backdated segment correction not change GMV?
  4. How should a rollback of a published correction be represented?
  5. What does a warehouse state hash not prove?
Review the answers

1. They let the warehouse reconstruct what was previously published and explain why the current answer changed.

2. 690: 625 baseline + 75 late sale - 10 authorized amount restatement.

3. It changes customer-version attribution, not the atomic sales measures.

4. As another authorized/versioned correction with its own evidence, not by deleting the correction history.

5. It does not prove semantic correctness, legal compliance, or equivalence across different serializations/engines by itself.

Summary and next step

Chapter 11 now treats identity, lateness, deletion, and correction as explicit state transitions with evidence. Chapter 12 next moves upstream to source-system profiling, data contracts, lineage, and ingestion readiness so ambiguous or unstable source semantics are caught before they reach these correction workflows.

Authoritative references

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only Ethereum or ERC-20 compatible assets to this address.