Summary
When a mixin constraint fails in evaluateMixinConstraints, the current behavior resets the entire recipe to base-only output — all non-base overlays are excluded, including unrelated overlays (e.g., monitoring-hpa) that had nothing to do with the failing mixin. ExcludedOverlays also over-reports by including ancestors in the exclusion list, contradicting the field contract.
Current Behavior
evaluateMixinConstraints (metadata_store.go:440-456) iterates all appliedOverlays and excludes every non-base entry:
for _, name := range *appliedOverlays {
if name != baseRecipeName {
*excludedOverlays = append(*excludedOverlays, name)
}
}
This is intentionally conservative (documented in code comments as of PR #501), but has two problems:
- Unrelated overlays get excluded as collateral
ExcludedOverlays includes ancestors, which should not appear per the field contract
Proposed Fix
- Scope the reset to only the candidate chain that declared the failing mixin, not all applied overlays
- Add exclusion reason to
ExcludedOverlays (e.g., Reason: "mixin-constraint-failed" vs Reason: "constraint-failed") for debugging visibility
- Exclude only leaf overlays, not ancestors, from the exclusion list
Context
Identified during cross-review of PR #501. The all-or-nothing behavior is safe (returns more restrictive output, not less) but can confuse operators when unrelated components disappear from the recipe.
Related: #501
Summary
When a mixin constraint fails in
evaluateMixinConstraints, the current behavior resets the entire recipe to base-only output — all non-base overlays are excluded, including unrelated overlays (e.g.,monitoring-hpa) that had nothing to do with the failing mixin.ExcludedOverlaysalso over-reports by including ancestors in the exclusion list, contradicting the field contract.Current Behavior
evaluateMixinConstraints(metadata_store.go:440-456) iterates allappliedOverlaysand excludes every non-base entry:This is intentionally conservative (documented in code comments as of PR #501), but has two problems:
ExcludedOverlaysincludes ancestors, which should not appear per the field contractProposed Fix
ExcludedOverlays(e.g.,Reason: "mixin-constraint-failed"vsReason: "constraint-failed") for debugging visibilityContext
Identified during cross-review of PR #501. The all-or-nothing behavior is safe (returns more restrictive output, not less) but can confuse operators when unrelated components disappear from the recipe.
Related: #501