Problem
dbt-pr-review verifies modified models via base-vs-head equivalence, but for greenfield (git-added) models there is no reference, so the reviewer can only lint them — the verification ceiling is "it builds + whatever tests the author happened to write." missingGrainTestLane detects the gap but does nothing about it.
Approach (BAIR "Intelligence is Free" — data systems by agents)
Auxiliary agent that generates tests from a new model's declared intent to expand the spec, in two strictly separated tracks:
- Track A (deterministic, block-eligible): materialize dbt constraints the author declared but did not enforce (
schema.yml not_null/unique/accepted_values/relationships, contract types). Assertion built from the parsed constraint — no LLM in the blocking path, so it can't be tricked into a back-labeled false positive.
- Track B (LLM, advisory): propose new tests from soft intent (descriptions,
ref() edges, PR text). Emitted at confidence: unknown, structurally excluded from the verdict — never blocks.
Specs: packages/opencode/specs/greenfield-spec-test-synthesis.md (+ corrective-app-memory.md for the P2 feedback loop).
Phasing
- P0 (this issue's first PR): propose-only — generate candidate tests + a committable
schema.yml patch, all non-blocking. Authoring help, not "verification."
- P1:
declaredConstraints(model) runner API + execution + the one deterministic blocking path + verdict-layer enforcement + assertion sandbox.
- P2: corrective per-repo memory feeding priors back into generation.
Problem
dbt-pr-reviewverifies modified models via base-vs-head equivalence, but for greenfield (git-added) models there is no reference, so the reviewer can only lint them — the verification ceiling is "it builds + whatever tests the author happened to write."missingGrainTestLanedetects the gap but does nothing about it.Approach (BAIR "Intelligence is Free" — data systems by agents)
Auxiliary agent that generates tests from a new model's declared intent to expand the spec, in two strictly separated tracks:
schema.ymlnot_null/unique/accepted_values/relationships, contract types). Assertion built from the parsed constraint — no LLM in the blocking path, so it can't be tricked into a back-labeled false positive.ref()edges, PR text). Emitted atconfidence: unknown, structurally excluded from the verdict — never blocks.Specs:
packages/opencode/specs/greenfield-spec-test-synthesis.md(+corrective-app-memory.mdfor the P2 feedback loop).Phasing
schema.ymlpatch, all non-blocking. Authoring help, not "verification."declaredConstraints(model)runner API + execution + the one deterministic blocking path + verdict-layer enforcement + assertion sandbox.