feat(engine): config-group misplacement guard — reject incoherent args + pinned schema (C5)#923
Merged
Merged
Conversation
…rs (C5 misplacement guard)
A config group's `[args]` exist solely to fill its `schema_template`. A
member that also pins its own `target.schema` overrides the group
(sidecar > group), so the template is bypassed and the args are dead —
an incoherent config that usually masks a routing mistake ("I thought
[args] routed this model, but the pin sends it elsewhere"). This now
fails the load with `ModelError::GroupArgsWithPinnedSchema`.
Most of C5 (schema derived from metadata; hard-block override for
enforced groups) was already delivered by C4's config groups + enforce.
This adds the one remaining guard — the args+pin contradiction.
- Detected in the shared `resolve_model_config` chokepoint next to the
`enforce` check, so it covers both `.sql` and `.rocky` for free.
- Group-schema resolution is now lazy: a model that pins its own schema
skips the template entirely, so a legitimate pin-without-args override
no longer errors on an unfilled placeholder it never uses.
- No ModelConfig churn, no new warning channel — a load error fails
compile, same path as `GroupOverride`.
Allowed cases unchanged: pin a schema with no args (override), or supply
args with no pin (route via template). Only the contradiction is rejected.
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.
What
The buildable remainder of C5. Most of C5 — "a model's target schema derives from its location/metadata" — was already delivered by C4: config groups derive a member's schema from
schema_template+ per-model[args], andenforce = truehard-blocks an override for enforced groups. This PR adds the one piece that was missing: the misplacement guard for the incoherent config the plan calls "a misplaced model fails compile."A group's
[args]exist solely to fill itsschema_template. If a member also pins its owntarget.schema, the pin wins (sidecar > group), so the template is bypassed and the args are dead. That's never a valid override — it usually masks a routing mistake ("I thought[args]routed this model, but the pin sends it elsewhere"). It now fails the load:ModelError::GroupArgsWithPinnedSchema. Pin a schema or supply args, not both.How
resolve_model_configchokepoint, next to the existingenforcecheck — so it covers both.sqland.rockyfor free (.rockyregression included). NoModelConfigchurn, no new warning channel; a load error fails compile, the same pathGroupOverridealready uses.{region}placeholder for a template it never uses. ([args]is template-only — verified no other consumer — and unreleased, so no existing project changes behavior.)Allowed cases (unchanged)
GroupOverride.Only the contradiction (group with a template + args + pin) is rejected. Two existing tests that encoded the now-forbidden args+pin pattern were updated to the coherent override (pin, no args).
Verification
cargo test --all-features -p rocky-core -p rocky-compilergreen (incl. the guard, the allowed companion, and the.rockyregression);cargo fmt --check+clippy --all-targets --all-featuresclean.🤖 Generated with Claude Code