Skip to content

#341 — domain: composite-key enforcement inference (unique_combination_of_columns join) - #342

Merged
cmbays merged 3 commits into
mainfrom
governance-341-composite-key
Jun 13, 2026
Merged

cmbays merged 3 commits into
mainfrom
governance-341-composite-key

Conversation

@cmbays

@cmbays cmbays commented Jun 13, 2026 •

Copy link
Copy Markdown
Contributor

Closes #341. Part of #260 (PR-review governance surfaces).

The composite-aware enforcement-reality inference, completing the Slice 3 (#339) deferral. A declared COMPOSITE primary-key / unique constraint asserts the TUPLE is unique (backed by unique_combination_of_columns, not per-column), so it now emits ONE tuple-keyed finding — never the false per-column "unbacked" claim the #339 guard silenced.

What this adds

AC coverage

Dogfood (the dogfood rule)

Added a synthetic COMPOSITE primary_key constraint on fct_patient_summary over (patient_id, year_actual) to playground-current.json — matching the model's already-present dbt_utils.unique_combination_of_columns test over the same set — so the diff-showcase golden surfaces a real Covered composite annotation end-to-end (constraint.primary_key[(patient_id, year_actual)], backed by the real test node). Surgical single-field edit (validated: only that node's constraints changed); MANIFEST.toml sha256 + description updated (synthetic_only intact, no root_path leak).

Gating verified — the #339 leak fix holds: the new constraint changes ONLY the diff-showcase (experimental:"1"). The governance-off playground report AND the gate-free explore page stay byte-identical (enforcement is experiment-gated; both use the gated default policy).

Gates (all green, both golden arms)

  • fmt · clippy --all-targets --locked -D warnings on a clean build (exit 0) · nextest (1838) · coverage 98.61% (≥85) · crap4rs PASS (backing_test_for_columns 2, all touched fns <15)
  • bdd (28) · doc -D warnings · deny · heuristics ledger byte-identical · fixture-manifest gate
  • REPORT goldens (jaffle/playground/diff-showcase) AND EXPLORE golden (dag.html + tests.html) byte-identical · governance + enforcement + composite-enforcement + explore-zero-egress headless (real Chromium)

🤖 Generated with Claude Code


Open in Stage

…_of_columns join)

Closes #341. Part of #260 (epic — PR-review governance surfaces).

The composite-aware enforcement-reality inference, completing the Slice 3
(#339) deferral. A declared COMPOSITE primary-key / unique constraint
asserts the TUPLE is unique (backed by unique_combination_of_columns, not
per-column), so it now emits ONE tuple-keyed finding — never the false
per-column "unbacked" claim the #339 guard silenced.

- domain (governance.rs): new `backing_test_for_columns(manifest, model,
  columns) -> Option<&NodeId>` — the composite-aware uniqueness backing
  join by SET EQUALITY (case-insensitive). REUSES the #259 grain
  recognizer (`uniqueness_test_columns`, now `pub(crate)`) for "which
  columns does this test assert unique?" — one authority across grain +
  enforcement. Set equality, NOT subset: a test over a proper subset (or
  superset) of the tuple does NOT back it (the #341 partial-overlap AC).
  `backing_test_for` (the #339 single-column seam) now delegates its
  PK/Unique path to `backing_test_for_columns(&[column])` (so a single
  column also matches a 1-element combination test) and keeps the
  not_null path. Real-node-id attribution preserved (`Verdict::Covered.by`
  carries the real unique_combination_of_columns test id).
- domain (checks.rs): the detector model moves from `(column, kind)` to a
  `DeclaredConstraint { columns, kind }` tuple — model-level constraints
  (single OR composite, no longer filtered) + column-level (single). The
  construct names the tuple: `constraint.primary_key[(a, b)]`; a single
  column keeps `[id]`. Removed the #339 `columns().len() == 1` composite
  filter.

DOGFOOD (the dogfood rule): added a synthetic COMPOSITE primary_key
constraint on fct_patient_summary over (patient_id, year_actual) to
playground-current.json — matching the model's ALREADY-PRESENT
dbt_utils.unique_combination_of_columns test — so the diff-showcase golden
surfaces a real Covered composite annotation end-to-end. Surgical
single-field edit (validated: only that node's `constraints` changed);
MANIFEST.toml sha256 + description updated (synthetic_only intact, no
root_path leak). Gating verified: the new constraint changes ONLY the
diff-showcase (experimental:"1") — the governance-off playground report
AND the gate-free explore page stay byte-identical (the #339 leak fix
holds).

Tests: backing_test_for_columns (set-equal / order+case-independent /
subset-not-covered / superset-not-covered / single-column / empty /
disabled); detector (one tuple finding / covered-by-combination /
order-independent / partial-overlap-uncovered / single-column-unique-does-
not-cover-tuple / single-column-still-fires); not_null + Other-kind
backing edges; the #259 grain test scoped to its group (the composite PK
now also fires enforcement on that model); the findings snapshot
regenerated (composite finding only); composite headless guard (the tuple
annotation renders on the showcase, real Chromium).

Gates (both golden arms): fmt; clippy --all-targets --locked -D warnings
on a CLEAN build (exit 0); nextest (1838); coverage 98.61% (>=85);
crap4rs PASS (backing_test_for_columns 2, all touched fns <15); bdd (28);
doc -D warnings; deny; heuristics ledger byte-identical; fixture-manifest
gate; REPORT goldens (jaffle/playground/diff-showcase) AND EXPLORE golden
(dag.html + tests.html) byte-identical; governance + enforcement +
composite-enforcement + explore-zero-egress headless.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 13, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

@cmbays, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 35 minutes and 49 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ad553210-3c3a-4b3c-8482-a12b7222e200

📥 Commits

Reviewing files that changed from the base of the PR and between da84c10 and e33fb3c.

⛔ Files ignored due to path filters (1)
  • tests/snapshots/check_engine__playground_unique_key_findings.snap is excluded by !**/*.snap
📒 Files selected for processing (8)
  • examples/diff-showcase-report.html
  • src/domain/checks.rs
  • src/domain/governance.rs
  • src/domain/mod.rs
  • tests/check_engine.rs
  • tests/fixtures/MANIFEST.toml
  • tests/fixtures/playground-current.json
  • tests/headless_toggle.rs
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch governance-341-composite-key

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 and usage tips.

@cmbays cmbays added the type:feature New capability label Jun 13, 2026
@github-actions

github-actions Bot commented Jun 13, 2026 •

Copy link
Copy Markdown
Contributor

📄 Rendered report preview

All golden examples regenerated cleanly.

🟡 Golden examples

Committed to examples/ and byte-identity gated — the canonical reports contributors and consumers browse. Stable across PRs.

Report View Download
playground-report.html ▶ Open ↗ ⬇ Download
jaffle-shop-report.html ▶ Open ↗ ⬇ Download
diff-showcase-report.html ▶ Open ↗ ⬇ Download

🐶 Live dogfood preview

This PR doesn't touch dbt-project/, so there's no live dogfood preview.

🧭 Explore preview

The two-page cute-dbt explore explorer — dag.html (model lineage) + tests.html (unit-test viewer). Same golden/live split as the report.

🟡 Golden explore

The committed examples/explore/ playground golden (the full synthetic playground manifest). Byte-identity gated in Example report check. Stable across PRs.

Page View Download
explore/dag.html ▶ Open ↗ ⬇ Download
explore/tests.html ▶ Open ↗ ⬇ Download

🐶 Live explore

This PR doesn't touch dbt-project/, so there's no live explore preview.

▶ Open ↗ opens the report or explorer in your browser in one
click — published to this repo's GitHub Pages under
/pr-342/.
⬇ Download fetches the same self-contained HTML as a workflow
artifact (auth-gated; works fully offline). Either way the report
makes zero external resource requests.

The Pages preview may take ~1 min to update after this comment
posts. On PRs from forks the Open link is unavailable (read-only
token) — use Download.

Alternative: GitHub CLI
# gh CLI >= 2.63 extracts into ./report-preview-playground/.
gh run download 27466101241 -R breezy-bays-labs/cute-dbt -n report-preview-playground
open report-preview-playground/playground-report.html

Posted by report-preview.yml for e33fb3ceec5b86ba18e86851c05cb7b16baa827b. Affordance only — never blocks merge.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request implements composite-key enforcement inference (cute-dbt#341), updating the constraint checking logic to support column tuples instead of flattening them to single columns. It introduces the DeclaredConstraint struct, updates the backing test matching to use set-equality over column sets, and adds comprehensive tests. The review feedback suggests two performance and correctness improvements: first, sorting columns case-insensitively and deferring owned String allocations during composite constraint deduplication to ensure order-independent deduplication; second, avoiding temporary BTreeSet allocations when checking uniqueness test set equality by using direct iterator-based checks.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/domain/checks.rs
Comment thread src/domain/governance.rs Outdated
cmbays and others added 2 commits June 13, 2026 07:55
…ensitive dedup

Re-gate corrective on #342 — a correctness inconsistency the founder gate
caught + 2 gemini threads:

1. SUBSET, not set-equality (the correctness bug). `backing_test_for_columns`
   used set-EQUALITY, contradicting the #259 grain `covers_key` two
   functions away (which uses test_cols ⊆ key). Grain is right:
   mathematically `{a}` unique ⟹ `(a, b)` unique, so a uniqueness test on a
   proper SUBSET of a composite key IS a stronger guarantee that backs it.
   Set-equality emitted a false "unbacked" whenever a subset test existed —
   a never-a-false-claim violation. Changed the matcher to
   `test_cols.is_subset(key)` (mirroring grain's direction exactly, reusing
   the same `uniqueness_test_columns` extractor). Exact match is the subset
   boundary (still backs); a superset or partial-overlap (not contained)
   does not. Fixed the contradictory doc comments (governance.rs +
   checks.rs). Tests rewritten: subset-backs (was wrongly does-not-back),
   single-column-unique-covers-composite, exact-match-backs; added
   superset-not-covers + partial-overlap-not-covers (both at the
   backing_test_for_columns unit level AND the detector level).

2. Order-insensitive dedup (gemini, checks.rs). `declared_unique_constraints`
   deduped on an ordered `Vec<String>`, so `(a, b)` and `(b, a)` — the same
   uniqueness key — counted twice. Dedup now keys on the lowercased column
   SET (BTreeSet); the first-declared order is kept for the construct id's
   display. Added a both-orders → one-finding detector test.

3. perf nit (gemini, governance.rs) — `uniqueness_test_covers_key` builds a
   small per-candidate column set; N (PK/unique columns per test) is tiny.
   Negligible; replied on the thread, not changed.

Dogfood golden UNCHANGED: the showcase's fct_patient_summary composite PK
is backed by an EXACT-match combination test, which still backs under
subset (exact match ⊆ itself) — diff-showcase byte-identical (verified).

Gates (both golden arms): fmt; clippy --all-targets --locked -D warnings
on a CLEAN build (exit 0); nextest (1843); coverage 98.62% (>=85); crap4rs
PASS (backing_test_for_columns 2, uniqueness_test_covers_key 6, all <15);
bdd (28); doc -D warnings; deny; heuristics ledger byte-identical; REPORT
goldens (jaffle/playground/diff-showcase) AND EXPLORE golden (dag.html +
tests.html) byte-identical; governance + enforcement + composite headless.

Closes #341. Part of #260.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cmbays
cmbays merged commit 1e1c88a into main Jun 13, 2026
35 checks passed
@cmbays
cmbays deleted the governance-341-composite-key branch June 13, 2026 12:47
github-actions Bot added a commit that referenced this pull request Jun 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:feature New capability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Composite-key enforcement inference (one tuple-keyed finding + unique_combination_of_columns join)

1 participant