Repository navigation
feat!: scope audits, schemas and hooks, add seed audits and gate targets on attached audits - #855
Merged
Merged
Conversation
Generic and singular audits, reusable schemas, and named SQL and Python hooks become declaration kinds in the existing declaration-scope machinery. They can live in project-wide roles or under <folder>/_sqlbuild/ roles, and follow the macro placement and visibility rules; attachments generated by audit factories count as consumers. Declaration files resolve macros, enums, and constants from their owner folder. Singular audits must reference two or more models, or a model plus a source, seed, or table function (P004). Audit files are discovered only from generic/ and singular/ roles. Seed YAML audits now compile and run after the seed loads in sqb build, blocking dependants on error. Unknown seed YAML keys are compile errors. BREAKING CHANGE: audit files outside audits/generic/ and audits/singular/ no longer compile; single-model, source-only, seed-only, and resource-free singular audits fail with P004; top-level audits, schemas, and hooks used only under one folder must move to that folder's _sqlbuild/ roles; unknown seed YAML keys are rejected.
Update the declaration-scope overview, placement, and visibility pages, the audits, seeds, schemas, hooks, and sqb init pages, and state that functions stay project-wide. Regenerate the bundled skill references.
…rces or table functions Also stop rejecting organizational folders named audits, schemas, or hooks inside project-wide declaration roles; only _sqlbuild and legacy macro, enum, and constant role names are rejected there.
Scoped audits, schemas, and hooks change the resource and declaration kinds in scope output, so sqb scope --json moves to schema_version 2 and the scope metadata consumed by Rules moves to 3. Document the project-wide [scopes] enforce_placement switch for staged adoption. BREAKING CHANGE: sqb scope --json reports schema_version 2.
Named hooks are now scoped declarations, so hooks that no model attaches are unused declarations. The generated benchmark projects never attached theirs; stop writing them and refresh the affected summaries and output fingerprints. Compile output is otherwise unchanged.
An attached audit that read anything besides its target (and, for models, the target's upstream) used to fall back to the end of the build, so an error failure no longer protected the target or its dependants. Attached audits now always gate their target. Every other model, seed, source, or table function an audit reads becomes an ordering edge: model and seed targets wait for those reads, and a source target's dependent models do. Model audits still run against the staged relation before promotion, source and seed audits before any dependant is built, and an error failure blocks the target and everything downstream. Partial builds read unselected resources from their existing tables. reuse_from never reuses proof for audits that read outside the target's lineage. An attached audit that reads a resource built from its own target is now a compile error (P005) pointing to a singular audit. This replaces the blanket rejection of source audits that reference models: a source audit may read a model that is not built from the source and waits for it. BREAKING CHANGE: attached audits that read a resource built from their target fail to compile with P005 instead of running at the end of the build; move those checks into singular audits.
A source's audits run before any model that has the source among its execution dependencies, including a source added by another audit's read. Gate edges only covered models whose SQL read the source, so a source audit reached through another audit could run before the resources it reads were built. Compute the triggering models to a fixed point over lineage and gate edges so every one of them waits for the source audit's reads.
Singular-audit attachment was inferred from the execution graph, which now includes attached-audit gate edges, so an unrelated attached audit could move a singular audit from the end of the build onto a model. Infer it from lineage dependencies only.
kvlonge
enabled auto-merge (squash)
September 27, 2026 16:57
Attached audits now gate their target, so a model whose audit reads an unselected seed needs that seed to exist, like any other upstream dependency. The parity test planned against an empty warehouse.
kvlonge
disabled auto-merge
September 27, 2026 17:33
Source, seed, and end-of-build audits ran outside any node's exception boundary, so an audit query that raised crashed sqb build with a traceback and no JSON. Catch Exception around those audit executions, as the model node boundary does, and record an error result carrying the message. Like a model audit that raises, it fails whatever its severity: dependants of the target are blocked and the build exits non-zero. The message appears in the check's execution_error JSON field and in the terminal failure summary. sqb audit already reports these errors through its own path.
Selecting +x follows data lineage, but buildability also checks resources that attached audits read, so a missing audit read failed with a generic "missing upstream dependencies" list. When a missing resource is required only through an audit's ordering edge, S301 now names the audit, its target, and the read. Data-lineage misses keep the existing wording, and mixed failures list both kinds. Edge origins no longer record audit reads that are already data-lineage edges.
Identical output has measured 12.5-18.4 s across CI runs; the same-runner ratio guard remains the regression gate.
kvlonge
enabled auto-merge (squash)
September 27, 2026 17:55
Fixed wall-clock budgets set just above the last CI measurement kept failing on runner noise (identical output varies by up to 50% between runs). Set them to about 1.5x typical CI time so they catch gross regressions; the same-runner ratio guards remain the precise gate.
The scoped-declarations E2E hook created its log table on first use, so two models running the hook concurrently raced on CREATE TABLE in DuckDB. Create it before the build. Dense 3000 and 5000 budgets become loose ceilings like the fresh and cache budgets; the same-runner ratio stays the regression gate.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Generic audits, reusable schemas and named hooks were project-wide only, singular audits accepted single-model checks, seeds had no audits, and attached audits that read other resources ran at the end of the build after their target was already published.
Changes
<folder>/_sqlbuild/when used under one folder, visible only where placed. Unused ones are errors;[scopes] enforce_placement = falsereports placement findings as warnings.P004). Theaudits/fallback is removed.audits:run after the seed loads insqb build;errorfailures block dependants.P005. Singular audit attachment is unchanged.S301names the audit when a missing resource is needed only by an audit read.sqb scope --jsonschema_version 2; Rules scope metadata version 3.BREAKING CHANGE: audits, schemas and hooks must be placed and used per the scope rules, singular audits must be cross-resource, and cross-resource attached audits now gate their target.
Verification
make test(7,814 passed) andmake check-cipass; hygiene scan clean.P005, partial builds,--no-audits, audit execution errors.