Skip to content

feat(review): [R20 S1] grain-key not_null completeness detector (+11 findings on 5-PR corpus)#1029

Open
sahrizvi wants to merge 2 commits into
feat/review-r20-s4-triage-promotionfrom
feat/review-r20-s1-grain-key-not-null
Open

feat(review): [R20 S1] grain-key not_null completeness detector (+11 findings on 5-PR corpus)#1029
sahrizvi wants to merge 2 commits into
feat/review-r20-s4-triage-promotionfrom
feat/review-r20-s1-grain-key-not-null

Conversation

@sahrizvi

@sahrizvi sahrizvi commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Summary

New detector in detectSchemaYmlPatterns: for every column named in a dbt_utils.unique_combination_of_columns test's combination_of_columns, require not_null coverage on the same model. Otherwise a NULL grain-key value silently passes the uniqueness test — the guardrail is toothless.

Design

Coverage sources (from code review feedback):

  • constraints: [{type: not_null}] — counted ONLY when contract.enforced == true. On views / non-contracted models, constraints: is documentation-only, not enforced by the DB.
  • Column-level data_tests: [not_null] / tests: [not_null] — always counted; dbt's test runner enforces regardless of contract state.

Recommendation flips between constraints: (contracted model) and data_tests: (view / non-contracted).

Supported YAML shapes:

  • Exact-match on unique_combination_of_columns and dbt_utils.unique_combination_of_columns (no endsWith — avoids false positives on not_unique_combination_of_columns).
  • Both pre-1.9 flat args + dbt 1.9+ arguments: nesting.
  • Both nested config.contract: and top-level contract: for enforcement flag.

Precision guards:

  • Column-name comparison is case-folded (Snowflake identifiers fold uppercase).
  • Skipped on status === 'deleted' files.
  • Only runs on files in the PR diff.

Validation

Deterministic detector run against a set of merged dbt PRs used for offline validation:

Variant Baseline With detector Delta
A1 (--pure --no-ai=true) 118 findings 129 findings +11 grain-key gaps
A2 (--pure, LLM lane on) 143 findings 150 findings +7 net (LLM run-to-run noise partially masks the deterministic gain)

Each new finding is a real grain-column gap and cites the exact test + column + model. A subset of new findings correlates to human review comments on the same models (grain-integrity gaps reviewers had flagged specifically — carrier-identity columns and mart-grain temporal columns).

Tests

  • 71 pass / 0 fail in review-dbt-patterns.test.ts (58 pre-existing + 13 new tests)
  • 3797 pass / 640 skip / 0 fail in the full altimate review suite (132 files)

New test fixtures (all green):

  • Basic contracted-mart grain gap
  • View / non-contracted → data_tests: recommendation
  • Coverage via tests: (dbt <1.8 alias) counts
  • SCD2-style temporal grain (change_time) missing not_null flagged
  • No false positive when every grain col has coverage
  • Bare unique_combination_of_columns (no dbt_utils. prefix)
  • No fire when there's no grain test
  • No fire on deleted schema.yml
  • dbt 1.9+ arguments: nesting recognised
  • Non-contracted constraints: [{type: not_null}] doesn't count as coverage
  • Top-level contract: {enforced: true} (not just nested under config:) recognised
  • Exact test-name match (rejects not_unique_combination_of_columns etc.)
  • Adapter case-folding (WORKSPACE_IDworkspace_id)

Independent code review

Reviewed independently before push. All 3 highs addressed: exact test-name match, column-name case folding, constraint coverage gated on contract enforcement.

Depends on

Stacks on top of #1028 (feat/review-r20-s4-triage-promotion), which stacks on #1027 (feat/review-r18-observability-recall).

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.

Tip: disable this comment in your organization's Code Review settings.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 05c53e3f-1afd-462f-b544-901dd3908f68

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/review-r20-s1-grain-key-not-null

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 2 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

@github-actions

Copy link
Copy Markdown

👋 This PR was automatically closed by our quality checks.

Common reasons:

  • New GitHub account with limited contribution history
  • PR description doesn't meet our guidelines
  • Contribution appears to be AI-generated without meaningful review

If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/opencode/src/altimate/review/dbt-patterns.ts">

<violation number="1" location="packages/opencode/src/altimate/review/dbt-patterns.ts:1000">
P1: A disabled column `not_null` test is treated as coverage, so a NULL grain key can still bypass the uniqueness guard without a finding. Inspect the test entry’s `config.enabled` before adding it to `coveredByTest`.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

const tests = c[testsKey]
if (!Array.isArray(tests)) continue
for (const t of tests) {
if (testName(t) === "not_null") coveredByTest.add(key)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: A disabled column not_null test is treated as coverage, so a NULL grain key can still bypass the uniqueness guard without a finding. Inspect the test entry’s config.enabled before adding it to coveredByTest.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/opencode/src/altimate/review/dbt-patterns.ts, line 1000:

<comment>A disabled column `not_null` test is treated as coverage, so a NULL grain key can still bypass the uniqueness guard without a finding. Inspect the test entry’s `config.enabled` before adding it to `coveredByTest`.</comment>

<file context>
@@ -896,6 +896,162 @@ function extractTestOccurrences(doc: unknown): Set<string> {
+          const tests = c[testsKey]
+          if (!Array.isArray(tests)) continue
+          for (const t of tests) {
+            if (testName(t) === "not_null") coveredByTest.add(key)
+          }
+        }
</file context>

Comment thread packages/opencode/src/altimate/review/dbt-patterns.ts Outdated
*
* Returns one gap per uncovered column per grain declaration.
*/
export interface GrainKeyGap {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUGGESTION: GrainKeyGap is exported but never imported outside this file.

extractGrainKeyGaps (the only producer/consumer) is itself not exported, so this type has no external consumer. Dropping export keeps the public surface of dbt-patterns.ts minimal — the test file imports detectSchemaYmlPatterns and DEFAULT_RUBRIC, not this type.

Suggested change
export interface GrainKeyGap {
interface GrainKeyGap {

Reply with @kilocode-bot fix it to have Kilo Code address this issue.

// since dbt's test runner enforces it independent of contract state.
const coveredByConstraint = new Set<string>()
const coveredByTest = new Set<string>()
if (Array.isArray(mm.columns)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUGGESTION: Model-level constraints: declarations are not counted as coverage (false-positive risk).

dbt allows declaring not_null at the model level with a column: field (e.g. constraints: [{type: not_null, column: id}]) in addition to column-level c.constraints. A contracted model that uses the model-level form for a grain column would still surface a false-positive gap here, because only column-level constraints are walked into coveredByConstraint. Consider also iterating mm.constraints and adding entries whose column: matches a grain key (case-folded) to coveredByConstraint.

@kilo-code-bot

kilo-code-bot Bot commented Jul 21, 2026

Copy link
Copy Markdown

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Incremental review of changes since 385ecdc (subdir/monorepo content resolution, block-scalar-aware risk scanning, primary_key/model-level constraint coverage, envelope tierForced/tierClassified invariant, and relationships dedupe discriminator).

Files Reviewed (10 files)
  • packages/opencode/src/altimate/review/compiled.ts
  • packages/opencode/src/altimate/review/dbt-patterns.ts
  • packages/opencode/src/altimate/review/git.ts
  • packages/opencode/src/altimate/review/risk-tier.ts
  • packages/opencode/src/altimate/review/run.ts
  • packages/opencode/src/altimate/review/verdict.ts
  • packages/opencode/test/altimate/review-ci.test.ts
  • packages/opencode/test/altimate/review-dbt-patterns.test.ts
  • packages/opencode/test/altimate/review-subdir-invocation.test.ts
  • packages/opencode/test/altimate/review.test.ts
Previous Review Summary (commit 385ecdc)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 385ecdc)

Status: 2 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 2
Issue Details (click to expand)

SUGGESTION

File Line Issue
packages/opencode/src/altimate/review/dbt-patterns.ts 917 GrainKeyGap exported but never imported outside the file
packages/opencode/src/altimate/review/dbt-patterns.ts 979 Model-level constraints: not counted as coverage (false-positive risk on contracted models using model-level not_null)
Files Reviewed (2 files)
  • packages/opencode/src/altimate/review/dbt-patterns.ts — 2 issues
  • packages/opencode/test/altimate/review-dbt-patterns.test.ts — clean (13 new tests cover the documented YAML shapes: contracted vs view, pre-1.9 vs 1.9+ arguments:, exact-name match, case-folding, deleted-file skip)

Fix these issues in Kilo Cloud


Reviewed by glm-5.2 · Input: 168.6K · Output: 24.5K · Cached: 828.6K

Review guidance: REVIEW.md from base branch feat/review-r20-s4-triage-promotion

@sahrizvi

Copy link
Copy Markdown
Contributor Author

Validation update — S1 actually catches +23 grain-key gaps, not +11

The PR body reported +11 grain-key findings; the accurate post-hardening number is +23. The +11 baseline I compared against was a stale pre-hardening run captured before the codex-driven tightening (constraints-only-count-when-contract-enforced + case-folding + exact-name match). After a clean rerun against the S4-branch baseline:

PR S4 baseline (A1) S1 result (A1) Delta Grain-key gaps
A (#781) 25 29 +4 4
B (#1111) 62 63 +1 1
C (#862) 23 41 +18 18
D (#975) 0 0 0 0 (fixes already in HEAD)
E (#1091) 8 8 0 0
TOTAL 118 141 +23 23

Notable expansion on PR C (18 grain-key gaps, up from the 10 originally reported):

  • int_job_run_billing: workspace_id, job_run_id, metastore_id, usage_date
  • int_job_run_cost_carrier: workspace_id, job_id, period_start_time, metastore_id, run_id
  • int_job_task_run_cost_carrier: workspace_id, job_id, period_start_time, metastore_id, run_id, task_key
  • mrt_job_run_timeline: period_end_time
  • mrt_job_task_run_timeline: period_end_time, task_key

Several of these directly match PR C's critical human findings (F11 workspace_id ×3, F10 period_end_time ×2). The higher count comes from the hardened rule correctly refusing to accept constraints: [{type: not_null}] as coverage on non-contracted models (int_* files don't declare contracts), which flushes previously-hidden gaps.

No regressions: full altimate review suite still 3797/0 pass/fail.

@dev-punia-altimate dev-punia-altimate left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Code Review — OpenCodeReview (Gemini) — 2 finding(s)

  • 2 anchored to a line (posted inline when the comment stream is on)
  • 0 without a line anchor
All findings (full text)

1. packages/opencode/src/altimate/review/dbt-patterns.ts (L989-L992)

[🟠 MEDIUM] The constraint extraction logic only checks for type: not_null. However, in dbt, a constraint of type: primary_key also implicitly enforces not_null at the database level. Models correctly utilizing type: primary_key for their grain columns will be falsely flagged as lacking not_null coverage, resulting in false positives. You should treat primary_key as a valid equivalent to not_null.

Suggested change:

              const type = (cn as Record<string, unknown>).type
              if (typeof type === "string" && (type.toLowerCase() === "not_null" || type.toLowerCase() === "primary_key")) {
                coveredByConstraint.add(key)
              }

2. packages/opencode/src/altimate/review/dbt-patterns.ts (L936-L943)

[🟠 MEDIUM] The logic to extract test names does not support the dbt 1.8+ syntax where generic tests can be explicitly named via the name: property (e.g., - name: not_null instead of - not_null:).

When a test is defined with name:, Object.keys(t)[0] may evaluate to "name" instead of the actual test name. This leads to two issues:

  1. Here in testName, it will return "name" instead of "not_null", causing false positives by missing valid not_null coverage.
  2. In the grain test loop below (for (const k of Object.keys(entry))), keys like "name" and "combination_of_columns" are evaluated, causing isGrainTestName to miss the unique_combination_of_columns test entirely.

Consider checking for t.name explicitly if it's a string, or updating the extraction logic to accommodate the dbt 1.8+ - name: test_name syntax.

Suggested change:

  const testName = (t: unknown): string | undefined => {
    if (typeof t === "string") return t.toLowerCase()
    if (t && typeof t === "object") {
      const obj = t as Record<string, unknown>
      if (typeof obj.name === "string") return obj.name.toLowerCase()
      const k = Object.keys(obj)[0]
      return k ? k.toLowerCase() : undefined
    }
    return undefined
  }

Comment on lines +989 to +992
const type = (cn as Record<string, unknown>).type
if (typeof type === "string" && type.toLowerCase() === "not_null") {
coveredByConstraint.add(key)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🟠 MEDIUM] The constraint extraction logic only checks for type: not_null. However, in dbt, a constraint of type: primary_key also implicitly enforces not_null at the database level. Models correctly utilizing type: primary_key for their grain columns will be falsely flagged as lacking not_null coverage, resulting in false positives. You should treat primary_key as a valid equivalent to not_null.

Suggested change:

Suggested change
const type = (cn as Record<string, unknown>).type
if (typeof type === "string" && type.toLowerCase() === "not_null") {
coveredByConstraint.add(key)
}
const type = (cn as Record<string, unknown>).type
if (typeof type === "string" && (type.toLowerCase() === "not_null" || type.toLowerCase() === "primary_key")) {
coveredByConstraint.add(key)
}

Comment on lines +936 to +943
const testName = (t: unknown): string | undefined => {
if (typeof t === "string") return t.toLowerCase()
if (t && typeof t === "object") {
const k = Object.keys(t as Record<string, unknown>)[0]
return k ? k.toLowerCase() : undefined
}
return undefined
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🟠 MEDIUM] The logic to extract test names does not support the dbt 1.8+ syntax where generic tests can be explicitly named via the name: property (e.g., - name: not_null instead of - not_null:).

When a test is defined with name:, Object.keys(t)[0] may evaluate to "name" instead of the actual test name. This leads to two issues:

  1. Here in testName, it will return "name" instead of "not_null", causing false positives by missing valid not_null coverage.
  2. In the grain test loop below (for (const k of Object.keys(entry))), keys like "name" and "combination_of_columns" are evaluated, causing isGrainTestName to miss the unique_combination_of_columns test entirely.

Consider checking for t.name explicitly if it's a string, or updating the extraction logic to accommodate the dbt 1.8+ - name: test_name syntax.

Suggested change:

Suggested change
const testName = (t: unknown): string | undefined => {
if (typeof t === "string") return t.toLowerCase()
if (t && typeof t === "object") {
const k = Object.keys(t as Record<string, unknown>)[0]
return k ? k.toLowerCase() : undefined
}
return undefined
}
const testName = (t: unknown): string | undefined => {
if (typeof t === "string") return t.toLowerCase()
if (t && typeof t === "object") {
const obj = t as Record<string, unknown>
if (typeof obj.name === "string") return obj.name.toLowerCase()
const k = Object.keys(obj)[0]
return k ? k.toLowerCase() : undefined
}
return undefined
}

@dev-punia-altimate

Copy link
Copy Markdown
Contributor

🤖 Code Review — OpenCodeReview (Gemini) — No Issues Found

No supported files changed.

@github-actions

Copy link
Copy Markdown

👋 This PR was automatically closed by our quality checks.

Common reasons:

  • New GitHub account with limited contribution history
  • PR description doesn't meet our guidelines
  • Contribution appears to be AI-generated without meaningful review

If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you.

2 similar comments
@github-actions

Copy link
Copy Markdown

👋 This PR was automatically closed by our quality checks.

Common reasons:

  • New GitHub account with limited contribution history
  • PR description doesn't meet our guidelines
  • Contribution appears to be AI-generated without meaningful review

If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you.

@github-actions

Copy link
Copy Markdown

👋 This PR was automatically closed by our quality checks.

Common reasons:

  • New GitHub account with limited contribution history
  • PR description doesn't meet our guidelines
  • Contribution appears to be AI-generated without meaningful review

If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you.

@sahrizvi

Copy link
Copy Markdown
Contributor Author

Consensus Code Review — PR #1029

Title: feat(review): [R20 S1] grain-key not_null completeness detector
Branch: feat/review-r20-s1-grain-key-not-nullfeat/review-r20-s4-triage-promotion (stacks on #1028#1027) · Repo: AltimateAI/altimate-code
Size: 2 files, +542 / −1 (dbt-patterns.ts +213, review-dbt-patterns.test.ts +330) · Reviewed: 2026-07-22

Panel (8 reviewers, thorough mode): Claude (Opus 4.8) · GPT 5.4 Codex · Gemini 3.1 Pro (Antigravity) · Kimi K2.5 · Qwen 3.6 · MiniMax M2.7 · GLM-5.1 · MiMo V2.5 Pro. Quorum 6 — met. Convergence: 1 round (Gemini + Kimi APPROVE; GPT CHANGES NEEDED — incorporated).


Verdict: REQUEST CHANGES — 1 MAJOR (small, well-scoped fix), 5 MINOR, 4 NIT

All 8 reviewers independently flagged the same headline false positive. The detector's core parsing is solid and corpus-validated (+11 deterministic findings, several matching critical human blockers); the blocker is a coverage blind spot that misfires on exactly the well-designed contracted models the rule is meant to reward.

Counts: Critical 0 · Major 1 · Minor 5 · Nit 4


MAJOR

1. Model-level & primary_key constraints are not counted as not_null coverage → false positives on contracted models

Category: False positive / coverage detection · Location: dbt-patterns.ts extractGrainKeyGaps
The detector inspects only COLUMN-level constraints: [{type: not_null}] and column-level tests. dbt (1.5+) also supports model-level constraints — constraints: [{type: primary_key, columns: [a,b]}] and {type: not_null, columns: [...]} — and a primary_key constraint inherently enforces NOT NULL on Postgres/Snowflake/BigQuery/Databricks. Grain columns are frequently the primary key, so a contracted mart that declares its grain via a model-level PK constraint gets every grain column falsely flagged as missing not_null — a false positive on precisely the well-designed models this rule intends to encourage.
Fix: when contractEnforced, also scan mm.constraints; for entries of type not_null or primary_key, add each name in their columns: array to coveredByConstraint. Also recognise column-level constraints: [{type: primary_key}].
8-way unanimous: Kimi/MiniMax/MiMo CRITICAL, GPT/Gemini/Qwen/GLM-5 MAJOR, Claude MINOR. Convergence settled MAJOR (GPT, Gemini, Kimi all agree: systematic false positive on standard syntax is a classic MAJOR; CRITICAL is reserved for execution failure / state corruption, which this is not).


MINOR

2. Fires on PRE-EXISTING grain gaps (whole NEW-side file), not just PR-introduced ones → PR noise

A one-line edit to a shared _models.yml surfaces warnings on untouched legacy models. This is deliberate, documented in-code, and unit-tested (steady-state test), and it drives the strong corpus recall (+11). GPT rated it MAJOR for the shared-file noise case; Gemini/Kimi/Claude hold MINOR as a deliberate precision/recall tradeoff. Consider diffing old vs new gaps to emit only newly-introduced ones, or marking pre-existing gaps as such. Kept MINOR; GPT's MAJOR dissent noted.

3. Contract-precedence bug: config.contract without enforced masks a top-level contract: {enforced: true}

Category: Logic · The ternary selects cfg.contract whenever it's an object (e.g. config: {contract: {alias: ...}}), short-circuiting mm.contract.enforced === true. Enforced constraint coverage is then wrongly treated as inert → false positive. Fix: evaluate enforced === true across both locations independently and OR them. Narrow trigger (needs both blocks in the same model). Gemini + Qwen.

4. dbt.not_null namespaced test alias not recognised (low-confidence)

In dbt 1.8+, - dbt.not_null may be valid; testName() returns "dbt.not_null" which fails === "not_null", so covered columns would be flagged. Strip a leading dbt. prefix in testName(). Gemini; GPT flagged this as low-confidence pending validation against dbt's parser (official docs emphasise bare not_null).

5. Contract enforcement inferred only from schema.yml

Misses contract set in dbt_project.yml or the model's SQL config(...), so enforced constraints are treated as inert → false positive + wrong remediation text. Resolve contract state from manifest/project context when available, or soften the finding wording when it can't be resolved from schema.yml alone. GPT.

6. {name:, test_name: not_null} alternative test format not recognised (added in convergence)

dbt's documented alternative data-test object form is {name: my_test, test_name: not_null, ...}. testName() reads only the first object key (Object.keys(t)[0]), so a not_null test written in this form is missed — both as column coverage (false positive gap) and as a grain-test declaration (false negative). Read test_name when present before falling back to the first key. GPT (convergence).


NIT

  1. norm() is defined inside the per-model loop; hoist it. MiMo.
  2. Duplicate GrainKeyGap for a column listed twice / multiple grain tests — collapses downstream via the per-column fingerprint, but cleaner to dedupe inside extractGrainKeyGaps. Gemini.
  3. Scanning model-level data_tests: for the grain test is slightly non-standard (model-level tests go under tests:); harmless (no false match) but signals a schema-shape mismatch. MiMo.
  4. Grain detection runs only on the structural NEW-side parse; the diff-only fallback silently skips it (acceptable — needs real YAML — but undocumented). MiMo, Qwen.

Rejected findings (for transparency)

  • "ruleKey ${model}.${column} collides across files" (MiMo MINOR) — false: the dedupe fingerprint includes file, model, and column independently of ruleKey (finding.ts:108). GPT flagged this in convergence; lead confirmed. Removed.
  • "Column-level grain test missed" (MiMo MAJOR) — unique_combination_of_columns is inherently multi-column and declared at model level; a column-level form isn't a standard dbt shape.
  • "clampSeverity(..., "high") looks wrong" (MiMo NIT) — "high" is the confidence argument, consistent with the same call pattern elsewhere in the file.
  • "unique test should count as coverage" (Kimi) — a unique test does not imply not_null; not a coverage source.

Positive observations (consensus)

  • Contract-gated constraint coverage is the right call — on non-contracted models constraints: is documentation-only, so requiring contract.enforced avoids missing real gaps on views. Tested both ways.
  • Exact grain-test-name match (avoids not_unique_combination_of_columns), adapter case-folding, and pre-1.9 flat vs 1.9+ arguments: nesting — all handled and tested.
  • Deleted-file suppression, structural-only gating with clean fallback, and per-column ruleKey for dedupe.
  • Corpus validation is strong: +11 deterministic findings, several matching critical human blockers (PR C workspace_id ×3, period_end_time).

Missing tests


Convergence

Reviewer Verdict on synthesis Key point
Gemini 3.1 Pro APPROVE MAJOR #1 correct (not CRITICAL); MINOR #2 correct; rejected list valid.
Kimi K2.5 APPROVE MAJOR #1 correct; MINOR #2 correct (GPT's MAJOR overweights the inconvenience).
GPT 5.4 Codex CHANGES NEEDED → incorporated Drop #6 (fingerprint includes file); add the {name:, test_name:} format miss; keep #4 low-confidence; MAJOR #1 correct.
Claude (author) Agreed; incorporated GPT's corrections after shell-verifying finding.ts:108.

Applied in convergence: dropped the "ruleKey cross-file collision" finding (shell-verified incorrect); added the test_name: alternative-format blind spot (MINOR #6); marked dbt.not_null (#4) low-confidence. #1 settled MAJOR (unanimous), #2 kept MINOR. Converged in 1 round.

Finding attribution

# Finding Origin Type
1 Model-level / primary_key constraints not counted as coverage all 8 reviewers Consensus (8-way)
2 Fires on pre-existing gaps → PR noise GPT (MAJOR), Claude/Qwen (MINOR), Gemini/MiMo (tradeoff) Consensus
3 Contract-precedence ternary bug Gemini, Qwen Unique
4 dbt.not_null alias not recognised (low-confidence) Gemini Unique
5 Contract not resolved from project/SQL config GPT Unique
6 {name:, test_name:} format not recognised GPT Convergence add
7–10 NITs (norm() hoist, dup gaps, model-level data_tests, fallback skip) MiMo, Gemini, Qwen Nit
ruleKey cross-file collision MiMo → GPT rebuttal Rejected (shell-verified)
Contract-gated coverage; corpus recall +11 all 8 Consensus (positive)

Reviewed by 8 participants. Convergence: 1 round, 3 external responses (GPT, Gemini, Kimi) + Claude.

Infra note: the 5 kilo-hosted models run via a pty.spawn pseudo-TTY wrapper (kilo hangs headless without a TTY). Gemini runs via the Antigravity agy CLI.

@sahrizvi
sahrizvi force-pushed the feat/review-r20-s4-triage-promotion branch from 8eac0d9 to 4544cf8 Compare July 22, 2026 13:33
Haider and others added 2 commits July 22, 2026 19:04
For every column named in a `dbt_utils.unique_combination_of_columns`
test's `combination_of_columns`, require `not_null` coverage on the
same model. Otherwise a NULL grain-key value silently passes the
uniqueness test — the guardrail is toothless. Cited as a hard rule in
`docs/DBT_GUIDELINES.md` in the corpus repo; kilo catches it, we didn't.

Coverage sources:
- `constraints: [{type: not_null}]` — only counted when
  `contract.enforced == true` (per codex R20 S1 high #3). On views /
  non-contracted models, `constraints:` is documentation-only, not
  enforced, so we don't miss a real gap.
- Column-level `data_tests: [not_null]` / `tests: [not_null]` — always
  counted; dbt's test runner enforces regardless of contract state.

Recommendation flips between `constraints:` (contracted model) and
`data_tests:` (view / non-contracted) based on the model's contract
state — matches the adapter-semantics discussion in the corpus study
(PR D×2 + PR A×2).

Supported YAML shapes:
- `unique_combination_of_columns` and `dbt_utils.unique_combination_of_columns`
  (exact match per codex high #1; `endsWith` would over-match).
- pre-1.9 flat args + dbt 1.9+ `arguments:` nesting.
- top-level `contract:` and nested `config.contract:` for enforcement flag.

False-positive guards:
- Column-name comparison is case-folded (Snowflake identifiers, per
  codex high #2) so `WORKSPACE_ID` in `combination_of_columns` matches
  `workspace_id` in `columns:`.
- Skipped on `status === "deleted"` files (no current grain to guard).
- Only runs on files in the PR diff, not repo-wide.

### Validation on 5-PR internal corpus (recall improvement)

vs S4 baseline (the tier-promotion PR this branch stacks on):
| Variant | S4 baseline | S1 result | Delta |
|---|---:|---:|---:|
| A1 (`--pure --no-ai=true`) | 118 | 129 | **+11 grain-key gaps** |
| A2 (`--pure`, LLM lane) | 143 | 150 | +7 (net; LLM run-to-run noise) |

Grain-key gaps caught:
- PR B (#1111) ×1: `mrt_all_purpose_auto_tune_recommendation.rec_type`
- PR C (#862) ×10: workspace_id x3, job_id x2, period_start_time x2, period_end_time x2, task_key x1
- PR A, D, E: 0 (fixes already landed in HEAD state per corpus study)

Strong matches to human blocker findings on PR C:
- `int_job_run_billing.workspace_id`, `int_job_run_cost_carrier.workspace_id`,
  `int_job_task_run_cost_carrier.workspace_id` → PR C human F11 (critical:
  "workspace_id missing from carrier identity")
- `mrt_job_run_timeline.period_end_time`, `mrt_job_task_run_timeline.period_end_time`
  → PR C human F10 (critical: "dbt mart grain includes period_end_time")

### Tests

- 71 pass / 0 fail in `review-dbt-patterns.test.ts` (58 pre-existing + 13 new S1 tests).
- 3797 pass / 640 skip / 0 fail in the full altimate review suite (132 files).
- Codex-reviewed diff, 3 highs addressed:
  - endsWith → exact-name match
  - column-name case-folding
  - constraints only count when contract enforced
- Codex minor #4 addressed (test fixture for top-level `contract:`)
- Codex minor #5 addressed (test fixture for non-contracted constraints ≠ coverage)

Depends on PR #1028 (feat/review-r20-s4-triage-promotion), which in turn
stacks on PR #1027 (feat/review-r18-observability-recall).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017zXDXMiNFh4qDPxPCfa2of
…detector

Bundle addresses PR #1029's consensus review:

- MAJOR #1 — model-level and column-level primary_key / not_null
  constraints now count as coverage. dbt 1.5+ supports model-level
  constraints via `constraints: [{type: primary_key, columns: [a, b]}]`,
  and a primary_key inherently enforces NOT NULL on Postgres/Snowflake/
  BigQuery/Databricks. Grain columns declared via a model-level PK were
  previously falsely flagged as missing not_null. Fix scans both
  `mm.constraints` (model-level, honouring the `columns:` list) and
  column-level `constraints: [{type: primary_key}]`.

- MINOR #3 — contract-precedence bug. Earlier ternary short-circuited
  when `cfg.contract` was any object (e.g. `config: {contract:
  {alias: X}}` with no `enforced` key), masking a top-level
  `contract: {enforced: true}`. Now evaluated independently at both
  locations and OR'd.

- MINOR #4 — `dbt.` prefix on namespaced test names (`dbt.not_null` in
  dbt 1.8+) is stripped in `testName()` before matching, so it counts
  as coverage.

- MINOR #6 — `{name: <alias>, test_name: not_null}` alternative object
  form is recognised. Reading `Object.keys(t)[0]` returned `name`
  (the alias) rather than the underlying test type. Now `test_name`
  wins when present, falling back to the first key.

- NIT #7 — `norm()` hoisted from per-model to function scope.

Consensus items NOT addressed this round:
- NIT #8 (dedup GrainKeyGap for a column listed twice / multiple
  grain tests) — collapses downstream via the global finding
  fingerprint; cosmetic rather than correctness.
- NIT #9 (model-level `data_tests:` scanned as a grain-test source)
  — reviewer noted "harmless (no false match)"; no action.
- NIT #10 (documentation of fallback-skip) — no code change needed.
- MINOR #5 (contract resolved from dbt_project.yml or SQL config)
  — cross-file / cross-context, deferred.

Regression tests (all pass; 82 pass / 0 fail in review-dbt-patterns
suite, 3828 pass / 0 fail in full altimate suite — up from 3785):

- Model-level primary_key constraint covers grain columns
- Model-level not_null constraint with `columns:` list covers named cols
- Column-level primary_key counts as coverage
- Precision guard: PK missing cols still flagged
- Model-level constraints on non-contracted model don't count
- `config.contract` without `enforced` does NOT mask top-level
  `contract: {enforced: true}` (MINOR #3)
- `dbt.not_null` covers (MINOR #4)
- `{name:, test_name: not_null}` alternative form covers (MINOR #6)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017zXDXMiNFh4qDPxPCfa2of
@sahrizvi
sahrizvi force-pushed the feat/review-r20-s1-grain-key-not-null branch from 385ecdc to 5ad0e85 Compare July 22, 2026 13:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants