dbt-native Python CLI for running Anarchitects Governance checks against dbt projects.
Project description
anarchitecture-dbt-governance
anarchitecture-dbt-governance is a Python CLI for running Anarchitects Governance checks against existing dbt projects. It installs the dbt-governance command, runs from a dbt project root or with --project-dir, is not a dbt package, is not installed with dbt deps, and uses a pinned Node runtime internally.
The CLI reads dbt artifacts, optionally runs dbt parse when you allow it, invokes @anarchitects/governance-runtime-dbt over a process/JSON boundary, and renders governance output for local use and CI.
Installation
Use a Python package installer, not dbt deps.
pipx and uv tool are the recommended choices for CLI-style usage:
pipx install anarchitecture-dbt-governance
uv tool install anarchitecture-dbt-governance
Use pip when you want the CLI inside a project virtualenv or CI environment:
pip install anarchitecture-dbt-governance
Requirements
- Python
>=3.9,<4 - Node.js
>=20 <25 - An existing dbt project with
dbt_project.yml - Existing dbt artifacts, or permission to let the host run
dbt parse - Package-manager access to install or verify the pinned runtime package
@anarchitects/governance-runtime-dbt@0.1.0
Notes:
- This package is a Python CLI used alongside dbt.
- It is not a dbt package.
- It is not installed through
packages.yml. - It does not use
dbt deps. - The runtime executable it manages internally is
dbt-governance-runtime.
Quickstart
From an existing dbt project root:
dbt-governance init
dbt-governance setup
dbt parse
dbt-governance check
If you want the host to generate manifest.json when it is missing:
dbt-governance check --parse
If you want to point at a project explicitly:
dbt-governance check --project-dir ./path/to/dbt/project
Generate reports:
dbt-governance check --report-path target/governance-report.json
dbt-governance report --format markdown --report-path target/governance-report.md
What The CLI Does
The host lifecycle is:
- Resolve the dbt project from the current directory or
--project-dir. - Load
governance.ymlif present, or use host defaults. - Resolve dbt artifact path hints such as
manifest.jsonandcatalog.json. - Use existing artifacts, or optionally run
dbt parsewhenmanifest.jsonis missing and--parseorhost.artifactMode: use-existing-or-parseallows it. - Verify or install the pinned runtime package
@anarchitects/governance-runtime-dbt@0.1.0. - Invoke
dbt-governance-runtimethrough a process/JSON boundary. - Render human output to stdout, machine-readable JSON to stdout, or write JSON/markdown reports.
- Map the result to deterministic exit codes.
Configuration Overview
dbt-governance distinguishes two kinds of configuration:
governance.yml: host-local configuration for CLI behavior, dbt artifact lifecycle, runtime setup, routing, output, and CI behavior.- Governance profile content: runtime/core/extension-owned semantics such as layers, ownership, domains, metrics, and rule configuration.
Current implementation detail:
- The host validates
profile.pathas a string andprofile.documentas an object. - The runtime evaluates
profile.document. profile.pathis forwarded as metadata and path context, but the current host/runtime path does not load a separategovernance.profile.ymlfile for semantic evaluation.
Practical consequence:
- Put effective governance profile content under
profile.documenttoday. - If you also keep a separate
governance.profile.ymlin your repository, treat it as your own companion file and keep it in sync yourself.
Config precedence is:
CLI flags > governance.yml > host defaults
Default config lookup:
- With
--config, the CLI loads that explicit file. - Without
--config, the CLI looks forgovernance.ymlin--project-dirwhen provided. - Otherwise it looks in the current working directory.
governance.yml Reference
Allowed top-level sections:
profileadapterextensionruntimehost
Example:
profile:
path: governance.profile.yml
document:
name: dbt
layers:
- staging
- intermediate
- marts
allowedDomainDependencies:
customer:
- customer
finance:
- finance
sales:
- sales
ownership:
required: true
health:
statusThresholds:
goodMinScore: 85
warningMinScore: 70
metrics: {}
rules:
ownership-presence:
enabled: true
severity: warning
options:
required: true
documentation-gap:
enabled: true
severity: warning
options:
metadataKeys:
- documentation
requireAny: true
adapter:
paths:
projectDir: .
dbtProjectPath: dbt_project.yml
targetPath: target
manifestPath: target/manifest.json
catalogPath: target/catalog.json
runResultsPath: target/run_results.json
sourcesPath: target/sources.json
options:
validationMode: strict
extension:
options: {}
runtime:
cacheDir: .anarchitecture/dbt-governance/runtime
reportPath: target/governance-report.json
host:
artifactMode: use-existing-or-parse
output: human
ci:
failOnBlockingViolations: true
profile
path: optional string path hint. The host validates and forwards it, but does not load that file for semantic evaluation.document: optional object. This is the effective governance profile input used by the runtime.
The host only validates that profile.document is an object. Profile semantics are owned by the runtime, core, and dbt extension.
adapter.paths
projectDir: optional project directory override.dbtProjectPath: optional path todbt_project.yml.targetPath: optional target directory override. Default dbt artifact directory istarget/.manifestPath: optional path tomanifest.json.catalogPath: optional path tocatalog.json.runResultsPath: optional path torun_results.json.sourcesPath: optional path tosources.json.
These are path hints passed through to the dbt adapter/runtime boundary. The host performs lightweight path checks only.
adapter.options
validationMode: confirmed supported adapter option. Allowed values arestrictandlenient.
adapter.options is adapter-owned and routed to @anarchitects/governance-adapter-dbt.
extension.options
extension.options is extension-owned and routed unchanged to @anarchitects/governance-extension-dbt.
For end users, the stable configuration surface today is primarily:
- dbt metadata inside your dbt project
- governance profile rules under
profile.document.rules
The host does not validate extension-owned option keys beyond requiring extension.options to be an object.
runtime
cacheDir: optional runtime cache directory.reportPath: optional default report output path.
If runtime.cacheDir is omitted, the host uses a controlled cache under the user cache directory. The runtime is installed locally there, not globally.
host
artifactMode: one ofrequire-existing,use-existing-only,use-existing-or-parseoutput: one ofhuman,jsonci.failOnBlockingViolations: boolean
Behavior:
- default host values are
artifactMode: require-existing,output: human, andci.failOnBlockingViolations: true require-existing:manifest.jsonmust already exist.use-existing-only: use existing artifacts and never invokedbt parse.use-existing-or-parse: use existing artifacts when available; otherwise invokedbt parse.
governance.profile.yml Reference
The governance profile is the semantic input that drives core and dbt-specific governance behavior.
Current implementation note:
profile.documentis the active evaluated profile input.- A separate
governance.profile.ymlfile is not automatically loaded by the current host/runtime path. - If you keep
governance.profile.ymlin your repository, treat the schema below as the content you must mirror intoprofile.document.
Example effective profile document:
name: dbt
layers:
- staging
- intermediate
- marts
allowedDomainDependencies:
customer:
- customer
finance:
- finance
sales:
- sales
ownership:
required: true
health:
statusThresholds:
goodMinScore: 85
warningMinScore: 70
metrics: {}
rules:
ownership-presence:
enabled: true
severity: warning
options:
required: true
documentation-gap:
enabled: true
severity: warning
options:
metadataKeys:
- documentation
requireAny: true
Confirmed profile fields evaluated by the runtime today:
namedescriptionlayersallowedDomainDependenciesownership.requiredhealth.statusThresholds.goodMinScorehealth.statusThresholds.warningMinScoremetricsrules
If profile.document is omitted entirely, the runtime defaults to:
name: dbtlayers: ["staging", "intermediate", "marts"]allowedDomainDependencies: {}ownership.required: truehealth.statusThresholds.goodMinScore: 85health.statusThresholds.warningMinScore: 70metrics: {}
Important honesty point:
allowedLayerDependenciesexists in the canonical core profile model, but this host/runtime path does not currently parse it fromprofile.document.- For layer behavior today, prefer
layersplus explicit rule configuration such asdbt/no-disallowed-layer-dependencyandlayer-boundary.
If a profile field is not listed above, assume it is not part of the stable evaluated surface for this CLI path yet.
Core Rules Vs dbt-Specific Rules
Reports can contain both canonical core rules and dbt-specific extension rules.
Core rules come from @anarchitects/governance-core and operate on normalized governance nodes and relations:
ownership-presencedocumentation-gaplayer-boundarydomain-boundarymissing-domainmissing-layerproject-name-conventiontag-convention
dbt-specific rules come from @anarchitects/governance-extension-dbt and operate on dbt-specific metadata interpretation:
dbt/no-disallowed-layer-dependencydbt/no-mart-to-mart-dependencydbt/critical-models-require-ownerdbt/public-models-require-descriptiondbt/critical-models-require-testsdbt/public-models-require-contractdbt/cross-domain-dependencies-require-approval
Use core rules for canonical governance expectations. Use dbt rules for dbt-specific semantics such as dbt descriptions, tests, contracts, and dbt lineage approval metadata.
Ownership Semantics
ownership-presence is a core rule.
- Source:
@anarchitects/governance-core - Rule ID:
ownership-presence - Category:
ownership - Default severity:
warning - Active when ownership is required by profile defaults or rule options
What it checks:
- canonical node ownership data, not raw dbt YAML directly
- a node passes when it has
node.ownership.team - a node also passes when it has at least one
node.ownership.contactsentry
If both are missing, the rule emits a violation such as:
Node dim_customers has no canonical ownership metadata or configuration.
dbt-specific caveat:
meta.owneronly helps if the adapter/runtime path maps it into canonical ownership.- Raw dbt metadata existing does not automatically mean the core rule passes.
- dbt-specific ownership diagnostics and rules are separate from the core rule.
Enable explicitly:
profile:
document:
rules:
ownership-presence:
enabled: true
severity: warning
options:
required: true
Disable explicitly:
profile:
document:
rules:
ownership-presence:
enabled: false
Documentation Semantics
documentation-gap is a core rule.
- Source:
@anarchitects/governance-core - Rule ID:
documentation-gap - Category:
documentation - Default severity:
warning - Default options:
metadataKeys: ["documentation"]requireAny: true
What it checks:
- canonical node metadata, not dbt
description:directly - by default a node is considered documented when
node.metadata.documentation === true - it also passes when
node.metadata.documentation === "true"
If no configured metadata key is present, the rule emits a violation such as:
Missing documentation metadata for node fct_orders.
Important distinction:
- dbt
description:is not automatically the same thing as canonicalnode.metadata.documentationfor the core rule. - dbt-specific description checks are separate, especially
dbt/public-models-require-description. - The dbt extension can derive dbt documentation facts for dbt-specific behavior, but the core rule still evaluates canonical metadata keys.
Enable explicitly:
profile:
document:
rules:
documentation-gap:
enabled: true
severity: warning
options:
metadataKeys:
- documentation
requireAny: true
Disable explicitly:
profile:
document:
rules:
documentation-gap:
enabled: false
Layer Governance Semantics
staging -> intermediate -> marts is an Anarchitects governance default inspired by common dbt conventions. It is not a dbt platform default, and dbt itself does not enforce those layers.
The current runtime defaults to these layers when the profile does not define them:
stagingintermediatemarts
Related rules:
- dbt-specific rule:
dbt/no-disallowed-layer-dependency - core rule:
layer-boundary
Default upstream behavior for the dbt-specific rule:
stagingmay depend onstagingintermediatemay depend onstagingandintermediatemartsmay depend onintermediateandmarts
For custom layer names, the dbt rule uses the order from profile.document.layers. If you want to remove ambiguity, set allowedUpstreamByLayer explicitly.
Example:
profile:
document:
name: dbt
layers:
- staging
- intermediate
- marts
rules:
dbt/no-disallowed-layer-dependency:
enabled: true
severity: error
options:
allowedUpstreamByLayer:
staging:
- staging
intermediate:
- staging
- intermediate
marts:
- intermediate
- marts
dbt/no-mart-to-mart-dependency can be configured independently:
profile:
document:
rules:
dbt/no-mart-to-mart-dependency:
enabled: true
severity: warning
options:
martLayers:
- marts
dbt Metadata Conventions
The dbt adapter/extension path can derive governance facts from normalized dbt metadata. Supported conventions today include:
description:for dbt-specific description/documentation behaviormeta.domainmeta.layermeta.ownermeta.governedmeta.publicmeta.criticalitytags: ["layer:<name>"]tags: ["public"]tags: ["published"]tags: ["governed"]- contract metadata preserved through dbt validation metadata
- test presence preserved through dbt validation metadata
Supported ownership mapping sources include:
- canonical
node.ownership.team metadata.dbt.resource.ownermetadata.dbt.resource.groupmetadata.dbt.resource.meta.owner
Supported domain mapping sources include:
- canonical
node.classification.domain metadata.dbt.resource.meta.domain
Supported layer mapping sources include:
- canonical
node.classification.layer metadata.dbt.resource.meta.layerlayer:<name>tags- supported path conventions for common dbt layer folders
Supported public/governed interface markers include:
meta.public: truemeta.governed: true- tags
public,published, orgoverned
Supported criticality mapping:
meta.criticality: "high"or another non-empty string
Supported cross-domain approval metadata paths for
dbt/cross-domain-dependencies-require-approval:
dbt.governance.crossDomainApproveddbt.lineage.crossDomainApproveddbt.lineage.approved
Truth-like approval values accepted there include true, "true", "approved", and "yes".
Example dbt model configuration:
models:
- name: customer_public_mart
description: Public customer mart for downstream analytics
tags:
- layer:marts
- public
meta:
domain: customer
layer: marts
owner: analytics-engineering
public: true
criticality: high
governance:
crossDomainApproved: true
config:
contract:
enforced: true
Important distinction:
- dbt metadata helps the adapter/extension derive governance facts.
- Core rules still evaluate canonical governance fields after normalization.
- If your dbt project carries metadata but a canonical core rule still fails, check whether the relevant canonical field was actually derived.
Commands Reference
dbt-governance init
Creates a starter governance.yml.
Options:
--project-dir--config--force
Behavior:
- writes a starter config
- refuses to overwrite an existing config by default
- overwrites only when
--forceis set
dbt-governance setup
Installs or verifies the pinned Node runtime package in the controlled cache.
Options:
--config
dbt-governance doctor
Reports host, config, Node, package-manager, runtime-manifest, and installed runtime status.
Options:
--config
dbt-governance check
Runs the host lifecycle, invokes the runtime, renders a result, and exits with a governance-aware process code.
Options:
--project-dir--profiles-dir--target--target-path--config--use-existing-artifacts--parse--json--report-path
Notes:
--jsonwrites the machine-readable report JSON to stdout only.--report-pathwrites a machine-readable JSON report file.
dbt-governance report
Runs the same lifecycle as check, then renders the result as json or markdown.
Options:
--project-dir--profiles-dir--target--target-path--config--use-existing-artifacts--parse--format json--format markdown--report-path
Notes:
reportre-runs the governance lifecycle; it is not a converter for an existing report file.- If
--formatis omitted, the default isjsonwhenhost.outputisjson, otherwisemarkdown.
dbt Artifact Lifecycle
Artifact behavior today:
manifest.jsonis required- optional artifacts are
catalog.json,run_results.json, andsources.json - the default target directory is
target/ - an existing
manifest.jsonis preferred --parserunsdbt parseonly whenmanifest.jsonis missing--use-existing-artifactsnever invokes dbt- the host performs lightweight path checks only
- the runtime/adapter own artifact loading, validation, normalization, and dbt-to-governance mapping
When the host invokes dbt, it runs:
dbt parse --project-dir <project-dir> [--profiles-dir ...] [--target ...] [--target-path ...]
Runtime Setup
Pinned runtime metadata:
- package:
@anarchitects/governance-runtime-dbt - version:
0.1.1 - executable:
dbt-governance-runtime - Node range:
>=20 <25
Operational behavior:
dbt-governance setupinstalls or verifies that exact runtime versiondbt-governance doctorreports compatibility and runtime state- the runtime is installed in a controlled cache
- there is no global runtime install
- the host does not install
latest - incompatible or mismatched runtime metadata is treated as a tooling/runtime failure, not a governance finding
Output Modes And Reports
Supported output behavior:
- default
checkoutput is human-readable text check --jsonemits structured JSON to stdoutcheck --report-path <file>writes a JSON report envelope to a filereport --format jsonrenders JSONreport --format markdownrenders markdown
The structured JSON output can include host metadata, diagnostics, result data, runtime metadata, and resolved artifact information when available.
CI Usage
Example GitHub Actions workflow:
name: dbt-governance
on:
pull_request:
push:
branches: [main]
jobs:
governance:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install dbt Governance host
run: pip install anarchitecture-dbt-governance
- name: Install dbt dependencies if needed
run: dbt deps
- name: Build dbt artifacts
run: dbt parse
- name: Install pinned governance runtime
run: dbt-governance setup
- name: Run governance checks
run: dbt-governance check --report-path target/governance-report.json
- uses: actions/upload-artifact@v4
if: always()
with:
name: governance-report
path: target/governance-report.json
host.ci.failOnBlockingViolations controls whether blocking violations produce exit code 1 or whether the check still exits successfully with 0.
Exit Codes
0: successful check with no blocking violations, or blocking violations are allowed becausehost.ci.failOnBlockingViolations=false1: successful check with blocking violations whenhost.ci.failOnBlockingViolations=true2: host, dbt, runtime setup, or runtime invocation failure3: unsupported or incompatible runtime or contract
Interpretation:
- exit code
1is a governance failure - exit codes
2and3are tooling, runtime, or environment failures
Troubleshooting
dbt-governance: command not found
The package is not installed in the active environment, or the CLI script directory is not on PATH. Reinstall with pipx, uv tool, or pip, then confirm dbt-governance --help works.
Package installed but command still not on PATH
This is usually a Python environment or shell path issue. Prefer pipx or uv tool for CLI usage, or activate the correct virtualenv before invoking the command.
dbt_project.yml not found
Run the CLI from the dbt project root or pass --project-dir to the dbt project directory.
manifest.json not found
Generate artifacts first with dbt parse, or rerun dbt-governance check --parse, or switch host.artifactMode to use-existing-or-parse.
dbt executable not found
The host can only run dbt parse when a dbt executable is available on PATH. Install dbt or avoid parse mode by supplying existing artifacts.
dbt parse failed
Fix the underlying dbt project, target, or profile problem first. The host surfaces dbt stdout and stderr details through diagnostics.
dbt profile not found
If dbt parse needs a non-default profiles directory or target, pass --profiles-dir and --target.
Unsupported Node version
Install a Node version in the supported range >=20 <25. Node 22 is a safe choice for CI.
npm or runtime package-manager access unavailable
The host must be able to verify or install the pinned runtime package. Ensure npm is available on PATH and can install packages in the local runtime cache.
Runtime package install failed
Check Node, package-manager availability, registry access, and local cache directory permissions. Re-run dbt-governance doctor to confirm compatibility details.
Runtime executable missing
Run dbt-governance setup again. If the package installs but the executable is still missing, inspect the runtime cache and doctor output.
Invalid runtime JSON output
The runtime process must emit a single JSON object on stdout. This is a runtime/tooling failure and exits with code 2.
Incompatible runtime metadata
If the runtime reports a different package or version than the pinned manifest expects, the host exits with code 3.
Invalid governance.yml
The host validates YAML syntax, top-level shape, supported top-level sections, and section types. Regenerate with dbt-governance init --force if needed, then reapply your changes carefully.
Blocking violations fail CI
That is expected when host.ci.failOnBlockingViolations=true. Set it to false only if you intentionally want governance findings to be non-blocking.
dbt descriptions exist but documentation-gap still appears
documentation-gap is a core rule that checks canonical metadata keys such as documentation, not raw dbt description: directly. A dbt description can still satisfy dbt-specific rules while the core rule remains active.
dbt owner metadata exists but ownership-presence still appears
ownership-presence checks canonical ownership fields such as node.ownership.team or node.ownership.contacts. Raw dbt ownership metadata only helps if the adapter/extension path resolves it into those canonical fields.
Architecture Boundary
dbt project
-> dbt artifacts
-> dbt-governance Python host
-> dbt-governance-runtime process/JSON boundary
-> governance runtime
-> governance adapter/extension/core
-> reports
Responsibility split:
- the host owns CLI UX, artifact lifecycle orchestration, runtime setup, invocation, rendering, and exit codes
- the runtime owns TypeScript composition
- the adapter owns dbt artifact loading, validation, normalization, and generic canonical projection
- the extension owns dbt-specific interpretation, rules, signals, diagnostics, metrics, and recommendations
- core owns canonical governance contracts and built-in rules
Development
For workspace development inside this monorepo:
yarn nx run governance-host-dbt:lint
yarn nx run governance-host-dbt:test
yarn nx run governance-host-dbt:e2e
yarn nx run governance-host-dbt:build
Links
- PyPI: https://pypi.org/project/anarchitecture-dbt-governance/
- npm runtime: https://www.npmjs.com/package/@anarchitects/governance-runtime-dbt
- Repository: https://github.com/anarchitects/anarchitecture-community
- Runtime package docs: packages/governance/runtime-dbt/README.md
- dbt adapter docs: packages/governance/adapter-dbt/README.md
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file anarchitecture_dbt_governance-0.0.6.tar.gz.
File metadata
- Download URL: anarchitecture_dbt_governance-0.0.6.tar.gz
- Upload date:
- Size: 32.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.22 {"installer":{"name":"uv","version":"0.11.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
38837697c82ead42194097afb6d8e08f93318bbc5a82a77a07b4df196e676745
|
|
| MD5 |
ce47f95267904660f0d3b1f322ea0ffe
|
|
| BLAKE2b-256 |
48881f7c9ceb887a33cfb24c01ff003f3db696d3f9f3c7717071fe5a777a70a3
|
File details
Details for the file anarchitecture_dbt_governance-0.0.6-py3-none-any.whl.
File metadata
- Download URL: anarchitecture_dbt_governance-0.0.6-py3-none-any.whl
- Upload date:
- Size: 39.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.22 {"installer":{"name":"uv","version":"0.11.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d27f1555df02a00f9b6d7cc14c50180d33774ae7473473084ec5de9296a626a1
|
|
| MD5 |
39c0417c9f572a53bf2624c2d0cdb288
|
|
| BLAKE2b-256 |
4dbfb0752e633cd1d63b3e6c68ea4309361a9eddc0c58dede73d7c1d35fa1bef
|