The First Thing You Notice Is What Stops Happening
Govern a BigQuery estate with CoreModels and the change is less a new capability than an absence. The archaeology stops. The "does anyone know what this column is" thread stops. The quarterly scramble to work out what changed since the last review stops, because the answer is already written down, dated, and fingerprinted.
The First Thing You Notice Is What Stops Happening
Govern a BigQuery estate with CoreModels and the change is less a new capability than an absence. The archaeology stops. The "does anyone know what this column is" thread stops. The quarterly scramble to work out what changed since the last review stops, because the answer is already written down, dated, and fingerprinted.
Here is the after-state in practical terms: what a team can actually do once a BigQuery estate is governed, and what each of those things replaced.
Five questions that become one call
"What is in the estate, and how much of it do we govern?" The audit's metrics block answers it every run: datasets in the estate, datasets governed, fields governed, the share of governed nodes that carry a canonical mapping beyond the vendor identity, and the timestamp of the last import. Before, that was a spreadsheet somebody maintained by hand for two months.
"Did anything drift?" One audit call with a fresh extract returns counts by severity, a map of
finding codes to occurrences, the list of drifted objects by their project.dataset.table identity,
and a content fingerprint of the artifact itself. Two runs over the same extract are comparable
facts, not impressions.
"The model changed — what in BigQuery no longer matches?" This is the direction most tools cannot do at all, and it is one call: re-audit. Because import stored a snapshot of the estate as it was parsed, CoreModels can run the same audit engine backwards — the last-known estate against the current governed model — with no fresh extract, no query against BigQuery, and no credentials. When a steward widens a value set on Tuesday afternoon, you know before Tuesday evening which tables are now behind.
"When did we last look, and what did it say?" The history endpoint returns the rolling trail: each recorded run with its timestamp, what triggered it, the counts, the finding codes and the fingerprint. The badge endpoint renders the latest run as an SVG — green for clean, yellow for warnings, red for errors, gray when nothing has been recorded yet — and the same badge is available on the machine-to-machine surface with a user API key, so a pipeline step can fetch it and publish it into a README.
"What should BigQuery look like if it matched the model?" Generation answers in DDL. One call
returns coremodels_bigquery_tables.sql: CREATE TABLE IF NOT EXISTS statements with NOT NULL
where the model requires it, OPTIONS(description=...) on both tables and columns, and — because
BigQuery enforces no keys or check constraints — the governed allowed-value sets and references
written into those descriptions rather than faked as constraints the engine would ignore.
A Tuesday, once the loop is running
09:10. A pull request touches a dataset the finance team depends on. The pipeline re-runs the
extraction query for the affected dataset, posts it to the audit endpoint with an API key, and gets
back one Error: field-type-drift on a single column, governed type and estate type side by side.
The build fails. The report — the audit returns a ready-to-post markdown version alongside the
machine-readable findings — lands in the review as a comment. The conversation that used to happen
three weeks after deployment happens in review, where it is free.
11:30. A new analyst asks which of the four orders-shaped tables is the real one. Instead of
an archaeology exercise across three chat channels, they read the governed model: each table is a
Type identified by its full BigQuery path, carrying the description that was captured from
TABLE_OPTIONS, the column meanings, the agreed value sets, and the references someone actually
decided on.
14:00. A steward adds a permitted value to a status taxonomy — once, in CoreModels, reviewed like any other change to shared meaning. Then a re-audit call reports which BigQuery objects have fallen behind the new model, and the run appends to the history automatically, because that verb's whole job is to leave a trail.
14:20. The catch-up gets generated rather than hand-written. The DDL script comes out of the governed model with the new value set already in the column description, and it goes through code review like any other change. Its header says the posture out loud: meaning changes belong in CoreModels; regenerate the script rather than editing it.
16:45. Nobody opens a status dashboard. The badge is green. That is the status meeting.
Before and after, stated plainly
Before: schema truth lived in the console, meaning lived in people, and the two were reconciled by incident. After: meaning lives in one governed model, and the estate is checked against it on every pull request and every time the model moves.
Before: documentation was a chore that lost to every deadline. After: every undocumented table
is named on every run (table-no-description), and every table hiding ungoverned STRUCT, ARRAY
or JSON payloads is named too (semi-structured-column). Invisible debt becomes a shrinking list.
Before: a second warehouse or a transformation tool meant a second, unrelated inventory. After: when two estates govern the same physical relation, one reconciliation pass links them as one identity with reciprocal same-as assertions, and the link is idempotent — run it again and it refreshes rather than duplicates.
Before: an AI assistant asked about the data guessed or sampled. After: the governed facts are queryable by agents over MCP, so the assistant answers from the agreed model.
What stays honest about the after-state
None of this required a service account. The extraction stays credential-free: your engineer runs the documented query, and the JSON artifact is all CoreModels ever sees.
And the outcomes report their own limits. NUMERIC and BIGNUMERIC columns are governed as
approximated doubles and say so. Semi-structured columns are governed as approximated strings and
say so. Views are skipped by DDL generation, with the skip declared, because views are derived
objects and generating them would overstate what the model knows. On a very large estate, if the
stored snapshot exceeds the storage cap, the import reports snapshotStored: false with a lossiness
record explaining the consequence — fresh-artifact audits keep working; only snapshot-based
re-audits are unavailable.
The immediate payoff is caught drift. The lasting change is quieter: schema arguments move from postmortems into pull requests, and the health of the estate becomes something you can glance at.
The Google BigQuery quickstart walks the whole loop — extract, import, audit, re-audit, badge, generate — in one page.