dbt / Advanced: evidence, isolation and recoverable releases / Lesson 13
Artifacts, lineage and audit evidence
Read project and invocation metadata through versioned schemas without mistaking a manifest for a successful data run.
On this page
Lesson goals
- Distinguish manifest, run results, catalog and freshness evidence.
- Join resource identity and invocation context with explicit provenance.
Different artifacts answer different questions
A manifest describes parsed project resources and relationships. Run results describe outcomes for a particular invocation’s processed resources, while catalog and freshness artifacts have different production conditions and contents. A node appearing in a manifest is not proof that it ran or passed tests. A successful model result is not proof that every downstream report was selected. Keep the command, invocation and project revision with each artifact. Names and production details evolve across dbt generations, so inspect the artifact’s declared schema rather than assuming every JSON file is interchangeable.
Schema version is part of the reader contract
Official artifact metadata includes fields such as dbt_version, dbt_schema_version, generated_at and invocation_id. Artifact schemas are versioned independently and can change across framework minor releases. A local metadata-review model below names fields to inspect without pretending to be a complete native manifest. Real readers should validate against the exact declared schema and tolerate only documented evolution. Resource unique_id is generally a better join key than a display name alone, but it still needs package, project and invocation context when comparing histories.
{"scope":"local artifact review model","inspect_metadata":["dbt_version","dbt_schema_version","generated_at","invocation_id"],"resource_id":"model.library_analytics.fct_loans","dependency_ids":["model.library_analytics.stg_loans"]}
A local summary, not a schema-valid native manifest or evidence of a real invocation.
Validate declared edges without claiming dbt parsing
The complete Python example topologically orders a tiny dependency map. It proves that the declared chain has the expected prerequisite order under this model. It does not discover refs from project files, interpret Jinja conditions or reproduce dbt’s parser. A cycle would require a redesigned dependency boundary, while independent nodes can admit several valid orders. Graph metadata can support impact analysis only if the underlying project relationships were declared correctly. A hidden hardcoded table reference remains invisible to this simple model and can also undermine real lineage.
from graphlib import TopologicalSorter
graph = {
'stg_loans': set(),
'fct_loans': {'stg_loans'},
'daily_branch_activity': {'fct_loans'},
}
order = list(TopologicalSorter(graph).static_order())
assert order == ['stg_loans', 'fct_loans', 'daily_branch_activity']
print(' -> '.join(order))
stg_loans -> fct_loans -> daily_branch_activity
Executed only as an isolated standard-library graph model. It imports no dbt package and reads no project or warehouse.
Retain statuses and timing within their exact scope
Join run-result resource identifiers to compatible manifest metadata and preserve whether a resource succeeded, warned, failed, errored or was skipped under its documented resource semantics. Skipped is not a passing assertion, and wall-clock invocation time includes work beyond one database query. Adapter responses and query identifiers can help authorized target diagnostics, but their fields are target-dependent. Do not add timings from concurrent nodes as if they equal total elapsed time. A partial invocation can still leave built relations, so audit evidence must connect outcomes with publication and recovery decisions.
Artifacts are operational data with access requirements
Compiled SQL, descriptions, source names and custom metadata can reveal sensitive structure or data. Store approved artifacts with retention and access controls, redact secrets and avoid publishing a whole target directory as a routine support attachment. Preserve baseline state artifacts separately from new outputs when comparisons depend on them. This course generates no native dbt artifact or catalog and invokes no command. Its validation checks JSON structure and the exact tiny graph program only, without claiming artifact-schema validation, warehouse query timing or completeness of a real lineage inventory.
Common errors and fixes
A manifest node is reported as successfully built
- Why it happens
- Parsed project presence was confused with invocation outcome.
- How to fix it
- Match compatible run results and verify the selected execution scope.
- Prevent it next time
- Keep project revision, invocation and schema metadata together.
A custom artifact reader breaks after a minor upgrade
- Why it happens
- The reader assumed an unversioned stable JSON shape.
- How to fix it
- Inspect dbt_schema_version and update against official schemas.
- Prevent it next time
- Test readers with explicit artifact-version fixtures.
Concurrent node durations are summed as elapsed time
- Why it happens
- Parallel work timing was confused with invocation wall-clock duration.
- How to fix it
- Record both resource timings and the overall observation boundary.
- Prevent it next time
- Label every timing source and aggregation rule.
Check your understanding
1. What does the local graph program prove about the dbt project?
Show worked solution
Only the order of the explicitly supplied three-node model. It does not parse actual project refs or validate a manifest schema. To audit a real project, use compatible approved artifacts and keep their provenance and unresolved relationships visible.
2. Can a skipped test be counted as a passed assertion?
Show worked solution
No. Preserve the documented status and investigate why execution did not occur. The project may still contain the test definition, but definition presence is not evidence of evaluation. Tie publication acceptance to the required executed checks rather than a convenient aggregate success count.
Key takeaways
- Artifact identity, schema and invocation provenance are inseparable.
- Lineage and execution outcomes establish different facts.