Skip to content

#267 — config-tree attribution: fqn-prefix widening + provenance chips - #284

Merged
cmbays merged 6 commits into
mainfrom
domain-267-config-tree-attribution
Jun 12, 2026
Merged

cmbays merged 6 commits into
mainfrom
domain-267-config-tree-attribution

Conversation

@cmbays

@cmbays cmbays commented Jun 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The #262 epic's C2 slice (CORE appetite): a dbt_project.yml config-tree edit is the ONE scope-widening category — by-DEFINITION change, TOTAL tier (founder gate 2026-06-11). A +config subtree edit now selects the models whose fqn falls under the edited tree path into the report's scope, with provenance chips naming the contributing subtree.

Closes #267

What landed

Domain — the matcher (src/domain/project_def.rs)

  • ConfigLeafPath — structured leaf identity carried on ProjectChange.tree for config-tree changes; one label/dotted-path format authority, so the panel rows and the attribution can never drift.
  • attribute_config_tree_changes — mirrors fusion's get_config_for_fqn exactly (dbt-parser dbt_project_config.rs:109-122 @ 9977b6cbb1b761065536300037560d8e3c037011): fqn-segment prefix descent breaking on the first missing child, deepest-match-wins per key (children inherit unset fields — recur_build_dbt_project_config:297-336, default_to). A model is selected exactly when its fqn-resolved value differs between the old and new models: trees — an edit shadowed by a deeper unchanged setting selects nothing; package subtrees never select own-project models; empty-fqn nodes are never guessed.
  • ProjectFacts.config_attributions — per-model attribution map; every panel-degrade arm attributes nothing (no parsed pair ⇒ never a guessed widening).

Scope widening (src/domain/scope.rs)

  • widen_with_config_attributions — union semantics, never replacement: attributed models join models_in_scope, their unit tests join in_scope as context (the same target_modified ⇒ test in-scope OR-arm both scope sources apply), changed untouched, changed ⊆ in_scope preserved by construction.

CLI (src/cli/mod.rs)

  • gather_project_facts moves before scope selection (it now feeds it) and takes the manifest; the run loop widens the selection, so scope counts integrate and Stage-2 preflight sees the true in-scope set. Baseline arm and every fallback arm widen nothing.

Render (src/adapters/render.rs, templates)

  • Model rows: ModelPayload.config_attributions chips — +materialized via dbt_project.yml · models.healthcare_analytics.marts — rendered per model selection beside the model selector; hidden (out of the AT tree) for unattributed models.
  • Panel: models:-section config-tree rows gain the affected-models listing — counts always explicit (TOTAL tier, a truthful "affects 0 models in this manifest" included); names inline up to the R1b cap (10), past it collapsed into a <details> listing ("listed, not individually rendered"). Non-models: sections make no claim. Panel template edits stay inside the row loop (hooks/dispatch row region untouched — adapters: hooks + dispatch panel rows — operation-node surfacing + diff-index path normalization #269 runs concurrently).

Matcher property-test inventory (house exhaustive style, no proptest dep)

  • attribution_membership_is_exactly_contiguous_fqn_prefix_descent — exhaustive edit-path × fqn pool: selection ⇔ contiguous-prefix membership
  • attribution_deepest_match_wins_a_shadowed_edit_selects_nothing_under_the_shadow
  • attribution_root_tree_edit_selects_all_own_project_models
  • attribution_package_subtree_never_selects_own_project_models
  • attribution_selects_models_under_the_edited_subtree_by_fqn_prefix
  • attribution_removal_attributes_to_the_removed_leaf / attribution_addition_attributes_to_the_added_leaf
  • attribution_of_a_non_config_tree_change_is_empty (reflexivity), attribution_never_selects_an_empty_fqn_or_non_model_node, attribution_ignores_non_models_sections
  • serde round-trips: ConfigAttribution, ProjectFacts (+ empty-map omission for pre-domain: config-tree change attribution — fqn prefix matching, scope widening + provenance chips #267 byte stability)
  • widening: widen_adds_attributed_models_and_their_tests_as_context, widen_with_empty_attributions_is_identity, widen_unions_with_an_existing_selection_never_replaces, widen_skips_an_attribution_for_a_node_absent_from_the_manifest

BDD (same feature file — the 23-count mirrors untouched)

  • A folder config edit widens the models under that subtree into scope with provenance chips — marts edit widens fct_daily (chip materialized via models.bdd_project.marts), keeps stg_raw out, pulls the widened model's unit test in as context (changed: false), panel row states "affects 1 model — widened into report scope: fct_daily".
  • A project-level config edit honors deepest-match-wins and skips shadowed models — the models.bdd_project edit widens stg_raw (chip via models.bdd_project) while the marts-shadowed fct_daily stays out.

Dogfood — diff-showcase golden

The existing synthetic patch's marts +materialized view→table hunk now widens the 20 marts models into the showcase: all 20 render with chips, the panel row shows "affects 20 models — widened into report scope, listed below" with the R1b overflow <details> exercised in the canonical artifact; staging/intermediate models stay out (precision visible). jaffle-shop + playground goldens pick up only the static chrome additions (baseline arm never widens); explore pages unchanged. git diff --text -U0 -- examples/ audited intended-only; no path leaks (/Users|cmbays grep clean).

Gates (run directly, fresh-worktree lefthook caveat honored)

  • cargo fmt --all --check ✓ · cargo clippy --all-targets --locked -- -D warnings ✓ (by exit code)
  • cargo nextest run --locked ✓ 1459 passed · BDD cargo test --test bdd ✓ 23 features / 176 scenarios / 1150 steps
  • headless pair ✓ headless_zero_egress -- --ignored (11) + headless_toggle -- --ignored (78, incl. the new chip + affected-listing guards)
  • cargo doc --no-deps --locked -D warnings ✓ and --document-private-items ✓ · cargo deny check ✓
  • crap4rs scorecard (local, crap4rs.toml + fresh lcov): 0 above threshold (25), worst 24.1, PASS
  • insta snapshots updated (skeleton + chrome — intended-only static additions, audited)

🤖 Generated with Claude Code


Open in Stage

Summary by CodeRabbit

Release Notes

  • New Features
    • Added attribution badges displaying which configuration changes affect specific models
    • Models automatically expand into analysis scope when their configuration changes
    • Enhanced project definition panel with affected models listing for configuration edits

github-actions Bot and others added 4 commits June 12, 2026 02:38
…pe widening, provenance chips

The C2 slice of epic #262 (founder gate 2026-06-11): a dbt_project.yml
config-tree edit is the ONE widening category — by-DEFINITION change,
TOTAL tier.

- domain/project_def: ConfigLeafPath (structured leaf identity on
  ProjectChange.tree, one label/path format authority), ConfigAttribution,
  and attribute_config_tree_changes — fusion's get_config_for_fqn
  fqn-segment prefix descent (dbt-parser dbt_project_config.rs:109-122 @
  9977b6cbb1b7) with deepest-match-wins shadowing; chips name the edited
  winning subtree; empty-fqn nodes are never guessed; ProjectFacts gains
  the per-model attribution map (degrade arms attribute nothing).
- domain/scope: widen_with_config_attributions — union semantics
  (attributed models join models_in_scope, their unit tests join in_scope
  as context, changed untouched, changed ⊆ in_scope preserved).
- cli: gather_project_facts moves BEFORE scope selection and now takes
  the manifest; categorized panels carry attributions; the run loop
  widens the selection so scope counts + Stage-2 preflight see the true
  in-scope set.
- adapters/render + templates: ModelPayload.config_attributions chips
  ("+materialized via dbt_project.yml · models.shop.marts", JS-rendered
  per model selection), and the panel's models:-section config-tree rows
  gain the affected-models listing — counts always explicit, names inline
  up to the R1b cap (10), past it collapsed into a <details> listing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…apshot updates

- features/project_definition.feature: two subprocess round-trip
  scenarios — the marts-folder edit widens the subtree's models into
  scope with chips + the affected-models row (and pulls the widened
  model's unit test in as context, not changed); the project-level edit
  honors deepest-match-wins (the marts-shadowed model stays out, the
  staging model widens with a models.bdd_project chip). Same feature
  file — the 23-count mirrors are untouched.
- steps: canonical dbt_project.yml gains the project-level
  +materialized line (line 11, lines 1-10 byte-stable); fqn-bearing
  manifest builders (model_node_with_fqn).
- headless_toggle: the committed-showcase guard now pins the
  "affects 20 models" sentence, the R1b overflow <details>, staging
  exclusion, and the landing model's chip text; new synthetic guard for
  chip visible/hidden states.
- insta snapshots: the static model-attribution element + #267 CSS
  (intended-only drift, audited).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… diff-showcase)

The existing synthetic patch's marts +materialized hunk now widens the
20 marts models into the diff-showcase scope: every one renders with its
provenance chip, and the panel's config-tree row shows the capped
affected-models listing (20 > the R1b inline cap, so the collapsed
listing is exercised in the canonical artifact). jaffle-shop +
playground pick up only the static chrome additions (baseline arm never
widens). Explore pages unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…c backticks

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

coderabbitai Bot commented Jun 12, 2026 •

Copy link
Copy Markdown

Review Change Stack

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 42 minutes and 57 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ 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: 4ae20ac2-5d36-4cae-869c-7eae3c9ffa4c

📥 Commits

Reviewing files that changed from the base of the PR and between bf2e2f7 and 5de5beb.

📒 Files selected for processing (3)
  • src/adapters/render.rs
  • src/domain/scope.rs
  • src/domain/state.rs
📝 Walkthrough

Walkthrough

This PR implements config-tree change attribution (issue #267) to map dbt_project.yml config edits to affected models via FQN prefix matching, widen those models into scope, and render provenance chips in both JSON payload and UI panel listings.

Changes

Config-tree attribution and provenance

Layer / File(s) Summary
Config-tree attribution domain types
src/domain/project_def.rs
Adds ConfigLeafPath struct to identify changed config leaves by section/segments/key, and ConfigAttribution struct mapping key and path to affected models. Updates ProjectChange with optional tree: Option<ConfigLeafPath> field and ProjectFacts with config_attributions: BTreeMap<String, Vec<ConfigAttribution>>.
Config-tree diffing and model attribution resolution
src/domain/project_def.rs
Refactors diff_config_tree to construct ConfigLeafPath for each differing +key leaf and attach it to ProjectChange::tree. Adds new public attribute_config_tree_changes function and resolve_key_for_fqn helper to resolve which models are affected by config edits using FQN prefix matching ("deepest match wins" semantics).
Scope widening with config attributions
src/domain/scope.rs, src/domain/mod.rs
Implements widen_with_config_attributions to expand scope by adding attributed model node IDs and their context tests while preserving changed ⊆ in_scope invariant. Updates domain re-exports to include ConfigAttribution, ConfigLeafPath, attribute_config_tree_changes, and widen_with_config_attributions.
CLI execution flow and fact gathering
src/cli/mod.rs
Reorders execute_report to call gather_project_facts before scope selection (with access to current manifest), threads config_attributions into widen_with_config_attributions to expand scope, then performs Stage-2 preflight with widened selection. Updates gather_project_facts and gather_project_facts_with_reader to accept manifest and compute attributions; updates project_change_panel to return both panel and attribution map.
Render payload and project panel with attributions
src/adapters/render.rs
Adds config_attributions: Vec<ConfigAttribution> field to ModelPayload (with serde skip-when-empty for byte stability) and populates it during build_payload_with_externals. Extends ProjectPanelRowView with affected_text and affected_overflow fields; implements affected_models_strings helper to format affected-models listings with cap/overflow behavior; updates project_panel_view signature to accept attribution map and attach listings only for config-tree "models:" rows.
Server-side template structure and styling
templates/report.html, templates/report.css
Adds conditional DOM rendering for affected-models details (<details> element with collapsed model list) in project-definition panel rows with overflow, hidden model-attribution row placeholder (data-testid="model-attribution"), and CSS styling for affected-models summaries and provenance chip containers with tokenized background/border styling.
Client-side provenance chip rendering
templates/interaction.js, examples/jaffle-shop-report.html, examples/playground-report.html
Implements renderModelAttribution(m) to iterate m.config_attributions and render one chip per entry with "+ key via dbt_project.yml · path" format, toggling container visibility. Wires into renderForSelectedModel() flow for per-model refresh. Replicates CSS and JavaScript across both example report files.
Test infrastructure and comprehensive coverage
tests/steps/builders.rs, tests/steps/project_definition.rs, features/project_definition.feature, tests/headless_toggle.rs, src/domain/project_def.rs, src/domain/scope.rs, src/cli/mod.rs, src/adapters/render.rs
Adds model_node_with_fqn builder for FQN-aware test manifests. Introduces BDD steps to construct manifests with models/tests and assert model widening, attribution presence by key/path, and context test treatment. Adds feature scenarios validating subtree/project-level config edits with "deepest-match-wins" behavior. Includes extensive unit tests covering JSON payload omission/emission, affected-models cap/overflow, FQN matching with shadowing/edge cases, and integration test assertions for panel and chip rendering.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • breezy-bays-labs/cute-dbt#38: Establishes the report rendering pipeline and payload schema that this PR extends with config_attributions provenance chips via src/adapters/render.rs and template wiring.
  • breezy-bays-labs/cute-dbt#216: Concurrently modifies ModelPayload and shared render types in src/adapters/render.rs; coordination needed for schema merges.
  • breezy-bays-labs/cute-dbt#194: Extends renderForSelectedModel() in templates/interaction.js with new per-model render helpers, sharing similar client-side refresh wiring as this PR's renderModelAttribution(m) integration.

🐰 Configuring the deepest paths,
Models bloom where YAML leaves trace,
Chips of truth on every face—
FQN's march through attribution's dance,
Scope widens with each change's glance! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main feature: config-tree attribution with fqn-prefix widening and provenance chips, matching the PR's core objectives.
Linked Issues check ✅ Passed All acceptance criteria from issue #267 are met: fqn-prefix matcher with deepest-match semantics is implemented, affected models are widened into scope with provenance chips, and R1b cap is applied to panel listings.
Out of Scope Changes check ✅ Passed All changes are directly aligned with #267 objectives: config-tree attribution domain logic, scope widening, CLI integration, render/template chips, and comprehensive test coverage.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch domain-267-config-tree-attribution

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.

@ghost

ghost commented Jun 12, 2026 •

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Jun 12, 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
diff-showcase-report.html ▶ Open ↗ ⬇ Download
playground-report.html ▶ Open ↗ ⬇ Download
jaffle-shop-report.html ▶ Open ↗ ⬇ Download

🐶 Live dogfood preview

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

▶ Open ↗ opens the report in your browser in one click —
published to this repo's GitHub Pages under /pr-284/.
⬇ 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 27400081243 -R breezy-bays-labs/cute-dbt -n report-preview-playground
open report-preview-playground/playground-report.html

Posted by report-preview.yml for 5de5bebd2aff8e8741bcb3c643d83ff6ebaff7a1. 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 config-tree change attribution and scope widening (cute-dbt#267), allowing dbt_project.yml config-tree edits to automatically bring affected models and their unit tests into the report scope. It introduces FQN-prefix matching with deepest-match-wins resolution, updates the CLI execution flow, and adds UI elements like provenance chips and affected-model listings. The review feedback suggests performance optimizations in affected_models_strings and widen_with_config_attributions to avoid unnecessary string cloning and collection allocations by using borrowed slices and in-place mutation.

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/adapters/render.rs Outdated
Comment thread src/domain/scope.rs

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

🧹 Nitpick comments (1)
src/domain/project_def.rs (1)

1024-1057: ⚡ Quick win

Expand the serde matrix for the new additive fields.

These tests only cover one populated ConfigAttribution and one populated ProjectFacts case. They don't pin the load-bearing combinations introduced here: ProjectChange.tree omitted vs present, ConfigLeafPath.segments empty vs non-empty, and config_attributions omitted vs populated. This payload is explicitly additive, so the repo's usual table-driven round-trip matrix would give much better regression coverage here.

As per coding guidelines, property tests are required for JSON serde round-trip behavior. Based on learnings, this repo expects those round-trips to be covered with exhaustive table-driven matrices rather than one-off examples.

🤖 Prompt for 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.

In `@src/domain/project_def.rs` around lines 1024 - 1057, Add
table-driven/property tests to expand JSON serde coverage for the new additive
fields: replace or supplement the one-off tests
(config_attribution_round_trips_through_json and
project_facts_with_attributions_round_trip_and_empty_map_is_omitted) with a
matrix of cases that exercise combinations of ProjectChange.tree omitted vs
present, ConfigLeafPath.segments empty vs non-empty, and config_attributions
omitted vs populated; for each case serialize with serde_json::to_string and
deserialize back with serde_json::from_str and assert equality (use
ConfigAttribution, ProjectFacts, ProjectChange, ConfigLeafPath and the
config_attributions map identifiers to build test inputs), and add a
property/test harness (table of struct cases or proptest) so all combinations
are round-trip covered.

Sources: Coding guidelines, Learnings

🤖 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 `@src/adapters/render.rs`:
- Around line 3231-3291: Add a table-driven serde round-trip test that
exhaustively covers presence/absence combinations of config_attributions for
models instead of only asserting serialized key count in
build_payload_attaches_config_attribution_chips_to_widened_models: create a
matrix of cases (e.g., model with Some(vec!), model with Some(empty vec), model
with None/omitted) and for each case call build_payload_with_externals to
produce payload, serialize with serde_json::to_string, then deserialize back
into the payload type and assert equality as well as explicit checks for whether
config_attributions is omitted from JSON when None/empty according to
skip_serializing_if; reference the existing test function name, the
ConfigAttribution struct, payload.models entries (fct and stg lookups), and
build_payload_with_externals to locate where to add the new table-driven
assertions.
- Around line 1519-1528: The dedupe currently inserts leaf_segment(node_id) into
the BTreeSet which collapses distinct full model IDs that share the same bare
name; change affected_models_by_leaf to insert the full node_id (or the unique
model ID string) into the BTreeSet (e.g., out.entry((attribution.path.clone(),
attribution.key.clone())).or_default().insert(node_id.clone())) so
deduping/counting uses full IDs, then defer deriving display names (calling
leaf_segment or applying disambiguation) at render time when building the
human-facing list; apply the same change wherever leaf_segment(node_id) is
inserted into these dedupe sets within this function.

In `@src/domain/project_def.rs`:
- Around line 573-580: changed_models_tree_keys currently collects keys into a
BTreeSet which deduplicates identical keys and collapses multiple edits for the
same model; change it to preserve every occurrence (and original order) by
returning a Vec<&String> (or Vec<&str>) and collecting with .map(|t|
&t.key).collect::<Vec<_>>() instead of .collect() into a BTreeSet; update the
signature of changed_models_tree_keys and any callers (e.g., attribute_one_fqn
and the analogous logic flagged at 588-614) to iterate over the Vec and emit a
ConfigAttribution for each contributing tree/key occurrence rather than only
once per unique key.

---

Nitpick comments:
In `@src/domain/project_def.rs`:
- Around line 1024-1057: Add table-driven/property tests to expand JSON serde
coverage for the new additive fields: replace or supplement the one-off tests
(config_attribution_round_trips_through_json and
project_facts_with_attributions_round_trip_and_empty_map_is_omitted) with a
matrix of cases that exercise combinations of ProjectChange.tree omitted vs
present, ConfigLeafPath.segments empty vs non-empty, and config_attributions
omitted vs populated; for each case serialize with serde_json::to_string and
deserialize back with serde_json::from_str and assert equality (use
ConfigAttribution, ProjectFacts, ProjectChange, ConfigLeafPath and the
config_attributions map identifiers to build test inputs), and add a
property/test harness (table of struct cases or proptest) so all combinations
are round-trip covered.
🪄 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: d7435d15-7a42-4b1f-a2c3-bfbfdb581d6d

📥 Commits

Reviewing files that changed from the base of the PR and between b8cffa9 and bf2e2f7.

⛔ Files ignored due to path filters (2)
  • tests/snapshots/golden_report__rendered_report_skeleton.snap is excluded by !**/*.snap
  • tests/snapshots/render_integration__rendered_chrome_jaffle_shop.snap is excluded by !**/*.snap
📒 Files selected for processing (15)
  • examples/diff-showcase-report.html
  • examples/jaffle-shop-report.html
  • examples/playground-report.html
  • features/project_definition.feature
  • src/adapters/render.rs
  • src/cli/mod.rs
  • src/domain/mod.rs
  • src/domain/project_def.rs
  • src/domain/scope.rs
  • templates/interaction.js
  • templates/report.css
  • templates/report.html
  • tests/headless_toggle.rs
  • tests/steps/builders.rs
  • tests/steps/project_definition.rs

Comment thread src/adapters/render.rs
Comment thread src/adapters/render.rs
Comment thread src/domain/project_def.rs
github-actions Bot and others added 2 commits June 12, 2026 02:52
Gemini review threads on #284:

- affected_models_strings: the inline (≤ R1b cap) arm now joins straight
  from borrowed &str — the owned name list is cloned only on the
  over-cap arm that actually returns it. (The inline arm still allocates
  its Vec<&str> + the joined String — the win is the N avoided String
  clones, not zero allocation.)
- widen_with_config_attributions: in-place union over the by-value
  ScopeSelection via new Extend impls on InScopeSet/ModelInScopeSet (the
  FromIterator companions, ModifiedSet::insert mutator precedent) —
  pre-existing members are no longer re-cloned into rebuilt sets; the
  per-key NodeId is allocated once and reused for both the manifest
  existence probe and the membership set. A fully borrowed &str keyset
  would not save that allocation: Manifest::node keys on &NodeId with no
  Borrow<str> bridge, so the probe needs the owned id either way.

Pure refactor: output byte-identical (goldens + snapshots untouched).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…bare-name twins

CodeRabbit thread on #284: affected_models_by_leaf deduped by bare model
name, so a section-root edit selecting same-named models across packages
(legal since dbt 1.6 two-arg ref) would under-count — a TOTAL-tier
truthfulness corner. The dedupe/count set now carries full node ids;
display names derive at sentence-build time (affected_display_names),
keeping the bare selector-vocabulary form wherever unique and falling
back to the full node id only on collision, so the listing never shows
two indistinguishable entries.

Also pins the config_attributions wire shape explicitly in the payload
test (present-with-content + absent — the Vec field's two states).

Committed goldens are byte-identical (single-package fixtures; verified
by regen). New regression: affected_models_count_by_node_id_and_
disambiguate_bare_name_twins.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cmbays
cmbays merged commit 49d054b into main Jun 12, 2026
33 checks passed
@cmbays
cmbays deleted the domain-267-config-tree-attribution branch June 12, 2026 07:04
@cmbays

cmbays commented Jun 12, 2026

Copy link
Copy Markdown
Contributor Author

Overnight orchestration wrap-up

Merged as 49d054b (squash) under Christopher's overnight authority — CI fully green on the final head, 2 Gemini allocation threads dispositioned (applied; pushed as 5de5beb), 0 unresolved. Issue #267 auto-closed ✔.

What shipped (#262 C2, the lane's ONE widening category): the fqn-prefix descent matcher verified against fusion's get_config_for_fqn + recur_build_dbt_project_config at the pinned SHA (break-on-first-miss descent, deepest-match-wins via default_to inheritance), two-sided old/new resolution so shadowed edits select nothing — sound TOTAL-tier attribution. Config-tree edits in dbt_project.yml now widen the in-scope set (union, never replaces) with provenance chips naming the contributing subtree, the affected-row sentence, and the R1b cap with overflow details — all visible in the diff-showcase golden (20 marts models widened with chips).

🤖 Generated with Claude Code

github-actions Bot added a commit that referenced this pull request Jun 12, 2026
cmbays pushed a commit that referenced this pull request Jun 12, 2026
…panel intents

Both #262 slices land on the same panel: #267's config-tree rows keep
their affected-models sentence + R1b overflow listing and the
provenance chips; #269's hooks rows keep the operation-node SQL diff
slot and the dispatch row its UNKNOWN-tier banner. ProjectChange
carries both additive fields (hook + tree); project_change_panel
threads the manifest once for both consumers (hook enrichment +
fqn attribution); project_panel_row composes both row decorations.
Goldens regenerated over the merged tree (never hand-picked) — the
diff-showcase now renders the 20-model widening listing AND the
hooks/dispatch rows; deltas audited intended-only. Full gate sweep
re-run green (fmt, clippy --locked, nextest 1489, bdd 179, headless
11+79, doc both modes, deny, crap4rs 2278 fns 0 above threshold).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

domain: config-tree change attribution — fqn prefix matching, scope widening + provenance chips

1 participant