@@ -65,12 +65,20 @@ var coverageDimensions = []coverageDimension{
6565 // hand back. Resolving one anyway would emit a recipe whose driver story
6666 // is wrong rather than merely generic.
6767 //
68- // That is a property of installing NVIDIA drivers on Linux, not of this
69- // catalog's shape, so it holds for external --data catalogs too. The
70- // assumption that would break it is a cluster whose node pools run
71- // different operating systems; AICR models that as separate recipes
72- // today (see ADR-018, which partitions a resolved recipe by component
73- // class and explicitly does not change resolution).
68+ // The driver argument is a property of installing NVIDIA drivers on Linux
69+ // rather than of this catalog's shape, so it carries to external --data
70+ // catalogs. Note what that does and does not claim: it says os is the
71+ // right dimension to demand, NOT that every catalog shape is served well
72+ // by demanding it. A split-coverage external catalog (service overlay,
73+ // os-agnostic accelerator overlay, one os-gated tuned leaf) is rejected
74+ // here asking for an os, because no single overlay carries the stated
75+ // combination. That is deliberate and the escape hatch is explicit:
76+ // declare an os-agnostic overlay carrying the combination, which is the
77+ // same assertion eks.yaml makes.
78+ //
79+ // The assumption that would break the driver argument itself is a cluster
80+ // whose node pools run different operating systems. AICR has no model for
81+ // that; it is expressed as separate recipes.
7482 {name : string (FieldOS ), value : func (c * Criteria ) string { return string (c .OS ) }, strict : true },
7583 {name : string (FieldPlatform ), value : func (c * Criteria ) string { return string (c .Platform ) }},
7684}
@@ -258,7 +266,7 @@ func (s *MetadataStore) verifyCriteriaCoverage(criteria *Criteria, appliedOverla
258266 // overlay covers the combination. Joint sufficiency catches that, and
259267 // absorbs the retired requireOSIfNeeded guard (issue #1782).
260268 if gaps := s .strictDimensionGaps (criteria , appliedOverlays ); len (gaps ) > 0 {
261- return strictGapError (criteria , gaps )
269+ return strictGapError (criteria , gaps , excluded , warnings )
262270 }
263271 return nil
264272 }
@@ -562,7 +570,16 @@ func (s *MetadataStore) inheritanceChainNames(overlay *RecipeMetadata) []string
562570// context uses its own key rather than `uncovered`: pkg/client/v1 relaxation
563571// CLEARS uncovered dimensions and retries, which here would discard the check
564572// and return the partial recipe that issue #1542 fixed.
565- func strictGapError (criteria * Criteria , gaps []strictGap ) error {
573+ //
574+ // excluded/warnings are attached exactly as the completeness path attaches
575+ // them. reachesUnappliedOverlay probes through the UNFILTERED overlay set, so
576+ // on the evaluator path an overlay that would cover the combination but was
577+ // removed by a failing constraint still counts as reachable. Without this
578+ // context the caller is told to state an os, supplies it, and only then meets
579+ // the real constraint failure. The demand itself is still correct — the
580+ // combination genuinely is not covered — so this is a diagnosis aid, not a
581+ // gate: the error stands either way.
582+ func strictGapError (criteria * Criteria , gaps []strictGap , excluded []ExcludedOverlay , warnings []ConstraintWarning ) error {
566583 clauses := make ([]string , 0 , len (gaps ))
567584 entries := make ([]map [string ]any , 0 , len (gaps ))
568585 for _ , gap := range gaps {
@@ -573,8 +590,15 @@ func strictGapError(criteria *Criteria, gaps []strictGap) error {
573590 "validValues" : gap .validValues ,
574591 })
575592 }
593+ ctx := map [string ]any {"strictDimensions" : entries }
594+ if len (excluded ) > 0 {
595+ ctx ["excludedOverlays" ] = excluded
596+ }
597+ if len (warnings ) > 0 {
598+ ctx ["constraintWarnings" ] = warnings
599+ }
576600 return aicrerrors .NewWithContext (aicrerrors .ErrCodeInvalidRequest ,
577601 fmt .Sprintf ("%s has no recipe covering that combination; specify %s" ,
578602 criteria .String (), strings .Join (clauses , ", " )),
579- map [ string ] any { "strictDimensions" : entries } )
603+ ctx )
580604}
0 commit comments