fix(serve): variant scope uses binding embedded in the variant file (REQ-106)#335
Merged
Conversation
…REQ-106) User-reported (Ford variant corpus): the serve dashboard reported bound_artifact_count: 0 for every variant, while the CLI `variant solve --binding <variant-file>` reported the correct counts. Root cause: ProjectVariants::discover only loaded a *separate* project-level binding (artifacts/bindings.yaml). When the `bindings:` section is embedded in the variant file itself (the variant IS its own binding model), no separate file exists, so `self.binding` was None and collect_bound_ids returned an empty set for every variant. Fix: during discovery, also parse each variant file as a FeatureBinding; if it carries a non-empty `bindings:` section, store it keyed by variant name. `resolve()` and `validation_status()` now select the binding via `binding_for(name)` — the variant's own embedded binding takes precedence, falling back to the project-level bindings.yaml. This mirrors the CLI's `--binding <variant-file>` self-reference. Tests: resolve_uses_binding_embedded_in_variant_file (embedded binding, NO separate bindings.yaml, asserts non-zero bound count via both resolve() and validation_status()); project_binding_still_used_when_no_embedded (regression guard for the project-level path). Fixes: REQ-106 Refs: REQ-083, REQ-007 Verifies: REQ-106 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
📐 Rivet artifact deltaNo artifact changes in this PR. Code-only changes (renderer, CLI wiring, tests) don't touch the artifact graph. |
There was a problem hiding this comment.
⚠️ Performance Alert ⚠️
Possible performance regression was detected for benchmark 'Rivet Criterion Benchmarks'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.
| Benchmark suite | Current: fb7da50 | Previous: 0d5c308 | Ratio |
|---|---|---|---|
traceability_matrix/1000 |
58180 ns/iter (± 547) |
45419 ns/iter (± 360) |
1.28 |
This comment was automatically generated by workflow using github-action-benchmark.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
User-reported (Ford variant corpus): the
rivet servedashboard reportedbound_artifact_count: 0for every variant, while the CLIvariant solve --binding <variant-file>reported the correct counts (16 / 13 / 17).Root cause:
ProjectVariants::discoveronly loaded a separate project-level binding (artifacts/bindings.yaml). When thebindings:section is embedded in the variant file itself (the variant IS its own binding model), no separate file exists →self.binding = None→collect_bound_idsreturned an empty set for every variant.Fix: during discovery, also parse each variant file as a
FeatureBinding; if it carries a non-emptybindings:section, store it keyed by variant name.resolve()andvalidation_status()select the binding viabinding_for(name)— the variant's own embedded binding takes precedence, falling back to the project-levelbindings.yaml. Mirrors the CLI's--binding <variant-file>self-reference.Tests
resolve_uses_binding_embedded_in_variant_file— embedded binding, no separatebindings.yaml, asserts non-zero bound count via bothresolve()andvalidation_status()(the /variants overview path).project_binding_still_used_when_no_embedded— regression guard for the project-level path.Test plan
cargo test -p rivet-cli --bins variant— 8 pass (2 new)Fixes: REQ-106
🤖 Generated with Claude Code