Repository navigation
#447 — intra-model column edges (pass-through/rename) as SpanRole::Column - #460
Conversation
…s SpanRole::Column CLL-2: the projection-provenance pass. The CTE engine now walks every body's `select.projection` on the SAME single parse (the #40 retain-don't-recompute pattern — no second parse) and writes POD column-lineage facts back to the domain `CteGraph`: - `ColumnEdge { from_col, to_col, kind, confidence }` (+ `ColumnScope`, `ColumnRef`, `ColumnEdgeKind` (Recce 5-way), `ColumnEdgeConfidence`), additive `CteGraph::column_edges` with builder + accessor. - `ColumnSpan` facts folded into the v2-reserved `SpanRole::Column { node_id, column }` source-map entries — each a sub-range of the owning `CteBody` entry (contains_range-verified), projected through `CodeMapPayload.column_spans`. Tier-1 MVP = pass-through (`c.email AS email`) + rename (`c.email AS contact_email`) only — the Identifier / aliased CompoundIdentifier cases the existing walker reaches. Confidence tracks SQL explicitness (never-a-false-claim): Resolved (qualified / single-source via `sole_relation_leaf`), Ambiguous (unqualified multi-source → fan out to every candidate, never dropped), Opaque (`SELECT *` / `q.*` → a virtual `*→*` edge, badged). Expression provenance (`coalesce(...)`) emits NO Derived edge — honest absence, deferred to CLL-3. Downstream impact (B) and intra-model upstream trace (C) fall out as traversals of the one edge set. The render layer projects the edges into `column_lineage.edges` (additive, skip-if-empty so older payloads stay byte-stable). Report + explore goldens regenerated (additive `column_lineage.edges` + `code_map.column_spans`); source-map-completeness gate green; zero-egress + headless E2E green against the regen. Closes #447 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0199AmBCec5kyVEEF1Qd7TSF
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
|
Warning Review limit reached
More reviews will be available in 30 minutes and 12 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 To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (8)
📝 WalkthroughWalkthroughThis PR implements CLL-2 (Tier-1 intra-model column lineage): new domain PODs ( ChangesCLL-2 Intra-model column lineage
Sequence Diagram(s)sequenceDiagram
participant build_graph as build_graph (cte_engine.rs)
participant collect_column_lineage
participant collect_body_column_lineage
participant CteGraph
participant SourceMap
participant CodeMapPayload as render.rs
build_graph->>collect_column_lineage: compiled_sql, ctes, terminal query
loop per CTE body + terminal body
collect_column_lineage->>collect_body_column_lineage: body, node_id
collect_body_column_lineage-->>collect_column_lineage: ColumnEdge[] + ColumnSpan[]
end
collect_column_lineage-->>build_graph: ColumnLineage { edges, spans }
build_graph->>CteGraph: .with_column_edges(edges).with_column_spans(spans)
CteGraph->>SourceMap: from_cte_graph → SpanRole::Column entries
SourceMap->>CodeMapPayload: column_spans() → BTreeMap<node∫column, SourceSpan>
CodeMapPayload-->>render.rs: column_spans field (JSON, skipped when empty)
CteGraph-->>render.rs: column_edges() → ColumnLineagePayload.edges (JSON)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
📄 Rendered report previewAll golden examples regenerated cleanly. 🟡 Golden examplesCommitted to
🐶 Live dogfood previewThis PR doesn't touch 🧭 Explore previewThe two-page 🟡 Golden exploreThe committed
🐶 Live exploreThis PR doesn't touch ▶ Open ↗ opens the report or explorer in your browser in one The Pages preview may take ~1 min to update after this comment Alternative: GitHub CLI# gh CLI >= 2.63 extracts into ./report-preview-playground/.
gh run download 27938668114 -R breezy-bays-labs/cute-dbt -n report-preview-playground
open report-preview-playground/playground-report.htmlPosted by |
There was a problem hiding this comment.
Code Review
This pull request implements Tier-1 intra-model column lineage (CLL-2) in the CTE engine. It introduces new domain models for column edges, scopes, and spans, and implements a projection-provenance pass to statically resolve pass-through and renamed columns during the single-parse AST walk. These column edges and spans are folded into the source map and rendered in the output payload, enabling column-level tracking and UI anchors. Comprehensive unit tests have been added to verify the lineage resolution, serialization, and span containment. There are no review comments provided, and the implementation appears solid, so I have no additional feedback to provide.
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.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@examples/jaffle-shop-report.html`:
- Line 2583: The baseline field in the cute-dbt-data JSON embedded in the script
tag contains a repo-relative path "tests/fixtures/jaffle-shop-baseline.json"
instead of a simple filename. Change the baseline value to use only the simple
filename "jaffle-shop-baseline.json" by removing the directory path prefix, so
the JSON object at the start of the cute-dbt-data script contains just the
filename without any repo-relative path references.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3792b15f-162f-4aa6-9fbb-915ac10a6c3c
⛔ Files ignored due to path filters (1)
tests/snapshots/render_integration__rendered_chrome_jaffle_shop.snapis excluded by!**/*.snap
📒 Files selected for processing (14)
examples/comments-showcase-report.htmlexamples/diff-showcase-report.htmlexamples/explore-macro/tests.htmlexamples/explore-seed/tests.htmlexamples/explore/tests.htmlexamples/jaffle-shop-report.htmlexamples/playground-report.htmlexamples/prdiff-minidag-report.htmlexamples/seed-showcase-report.htmlsrc/adapters/cte_engine.rssrc/adapters/render.rssrc/domain/cte.rssrc/domain/mod.rssrc/domain/source_map.rs
… edges (never-a-false-claim); reserve Opaque for unknown-external + push_span degrade test + strip insta artifact A star over a KNOWN intra-model CTE (e.g. jaffle-shop's `… renamed as (select id as customer_id, …) select * from renamed`) was marked `confidence: opaque` with a virtual `*→*` edge — a FALSE CLAIM baked into the committed goldens: `renamed`'s output columns ARE resolvable. The design (column-lineage-feasibility §3 Tier-1) explicitly scopes intra-model star EXPANSION into CLL-2. - cte_engine: thread a per-CTE resolved-output-columns map through the projection pass (declaration order); a `select * from <known_cte>` / `q.*` now EXPANDS into one `PassThrough`/`Resolved` edge per upstream output column. `Opaque` + the virtual `*→*` edge is now reserved STRICTLY for a star over an UNKNOWN external relation (or a CTE whose own projection is itself non-enumerable) — honest degrade, never a fabricated column list. Corrected the comment that mis-scoped intra-CTE star expansion to CLL-4. - TDD: `column_lineage_star_over_known_cte_expands_not_opaque` (+ the `q.*` and the still-Opaque honest-gap cases); kept the existing `column_lineage_opaque_star_over_unknown_external`. - Kill the `push_span` boundary-guard surviving mutant: split the guard into `span_to_source_span` (testable with synthetic spans) and add `degraded_spans_are_dropped_not_fabricated` (line-0 sentinel, inverted range, and a control ending exactly at sql.len()). - Strip the transient `assertion_line: 227` insta header from the jaffle-shop snapshot. - Regenerate the report + explore goldens: the `renamed.* → opaque` edge is GONE, replaced by per-column Resolved edges; the `raw_customers.* → source.* opaque` edge stays (correct external). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0199AmBCec5kyVEEF1Qd7TSF
|
✅ Merged CLL-2 (#447) — intra-model column edges. 5/5 source-map-spine MVP slices complete. What landed: the projection-provenance pass — for each CTE/terminal body, every output column resolves to its input(s): pass-through + rename as Quality: council review (cao/ceng/cpo clean, cqo concerns). The CQO lens + synthesizer caught a never-a-false-claim violation — a fully-resolvable Follow-ups: #461 (pre-existing baseline-path), #462 (Source-kind disambiguation for CLL-4), #463 (badge-WHY copy + showcase). Merged autonomously under the overnight build mandate. The deterministic source-map-spine MVP is complete (S0–S2, S3+CLL-1, CLL-2). Next: the raw-zone build (the final core slice), then the PR #440 refresh + Claude Design handoff. |
Closes #447
Summary
CLL-2 of the source-map-spine epic (#442): the projection-provenance pass. The CTE engine now walks every body's
select.projectionon the SAME single parse (the cute-dbt#40 retain-don't-recompute pattern — no second parse) and writes POD column-lineage facts back to the domainCteGraph. B (downstream impact) and C (intra-model upstream trace) fall out as traversals of the one edge set.What landed
src/domain/cte.rs) —ColumnScope(Intra/Cross),ColumnRef,ColumnEdgeKind(Recce 5-way: pass_through/renamed/derived/source/join_key,#[non_exhaustive]),ColumnEdgeConfidence(resolved/ambiguous/opaque),ColumnEdge. AdditiveCteGraph::column_edges+column_spanswith builders/accessors (skip_serializing_if = Vec::is_empty→ byte-stable when empty).SpanRole::Column { node_id, column }— the v2-reserved slot landed insrc/domain/source_map.rs;ColumnSpanfacts fold intoSpanRole::Columnentries, each a sub-range of the owningCteBody(contains_range-verified), projected throughCodeMapPayload.column_spans.src/adapters/cte_engine.rs) — Tier-1 MVP = pass-through (c.email AS email) + rename (c.email AS contact_email) only (the Identifier / aliased CompoundIdentifier cases the existing walker reaches). Confidence tracks SQL explicitness: Resolved (qualified / single-source viasole_relation_leaf), Ambiguous (unqualified multi-source → fan out to every candidate, never dropped), Opaque (SELECT */q.*→ virtual*→*edge).coalesce(...)emits NO Derived edge — honest absence, deferred to CLL-3.column_lineage.edgespopulated fromgraph.column_edges()(additive, skip-if-empty).The AST walk stays in the adapter (
sqlparserforbidden indomain/bytests/domain_clean_arch.rs); it writes POD facts back.TDD-first
10 engine tests (pass-through, rename, single-source unqualified, ambiguous fan-out, opaque star, derived-absence, downstream reverse index, upstream trace dead-ends at the ref boundary, column-span sub-range, canonical vocab) + domain serde round-trips + source-map Column-fold tests — written before the implementation.
Gates (all green)
cargo fmt --check·cargo clippy --all-targets --locked -D warnings·cargo nextest run(2438 pass) ·cargo test --test bdd·RUSTDOCFLAGS=-D warnings cargo doc --no-deps --locked·cargo deny check·headless_zero_egress -- --ignored(12 pass, real Chromiumfile://) ·headless_toggle -- --ignored(125 pass) · domain hexagonal-purity · source-map-completeness (509 node checks, 0 violations).Golden impact (consequence)
Report goldens (jaffle-shop, playground, diff-showcase, macro-heavy?, seed-showcase, prdiff-minidag, comments-showcase) + explore
tests.htmlpages regenerated — additivecolumn_lineage.edges+code_map.column_spans. Thediff-showcase-findings.jsonenvelope is unchanged (findings unaffected). Both arms byte-verified against the renderer; the committed jaffle-shop/playground goldens now visibly carry the column edges (dogfood).🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation