@@ -476,14 +476,44 @@ on any overlay are rejected at load time (`ErrCodeInvalidRequest`) to
476476prevent silent match-all behaviour; operators must remove or zero that
477477field before upgrading.
478478
479- **Composition with the OS guard.** `requireOSIfNeeded` (the joint
480- service+accelerator OS gate) is a separate, pre-existing check and runs
481- *first*, before the merge. It is **not subsumed** by the coverage
482- post-condition : coverage is satisfied when service and accelerator are each
483- honored by *some* overlay independently, while the OS guard demands *one*
484- overlay carry both service and accelerator together before it will consider
485- the OS-agnostic tier served. Both checks apply; a request can trip either
486- one independently.
479+ **Joint sufficiency.** Per-dimension coverage is necessary but not
480+ sufficient. It is satisfied when `service` and `accelerator` are each honored
481+ by *some* overlay independently, even when no single overlay carries the
482+ combination and the combination's content lives only on an OS-gated leaf. The
483+ caller then receives a recipe that silently never applied it.
484+ ` verifyCriteriaCoverage` therefore also enforces a second condition
485+ (issue # 1782): resolution fails when **no applied overlay jointly carries
486+ every stated dimension** *and* stating a strict dimension would reach an
487+ overlay currently being skipped.
488+
489+ Both halves matter. The first is the escape hatch that keeps the generic tier
490+ valid : ` --service eks` resolves through `eks.yaml`, which carries the whole
491+ stated combination, and is never asked for an OS. The second is what detects
492+ the loss.
493+
494+ ` os` is the only **strict** dimension, and `coverage.go` records why. Every
495+ other dimension degrades to a smaller but coherent recipe when omitted : no
496+ ` --platform` yields no Slurm or Kubeflow layer, no `--intent` yields untuned
497+ GPU Operator values. `os` decides whether the driver can be installed at all.
498+ On Ubuntu the GPU Operator installs it, so an OS-agnostic recipe is a real
499+ answer and `eks.yaml` carries no `os`; on COS the operator installs no driver
500+ and the device-plugin owner differs, which is why every `gke` overlay is
501+ OS-gated and no OS-agnostic GKE recipe exists to return. That is a property of
502+ installing NVIDIA drivers on Linux rather than of this catalog's shape, so it
503+ holds for external `--data` catalogs too.
504+
505+ This condition replaced the `requireOSIfNeeded` guard, which ran before the
506+ merge and hardcoded three separate scopes : it only fired when `service` was
507+ stated, only compared `service`+`accelerator` regardless of what the caller
508+ asked for, and only ever demanded `os`. Only the last survives.
509+ ` coverage_subsumption_test.go` keeps the retired guard as a test-only oracle
510+ and asserts over generated catalogs that every query it would have rejected is
511+ still rejected.
512+
513+ A joint-sufficiency failure carries `details.strictDimensions`, **not**
514+ `details.uncovered`. The distinction is load-bearing : ` pkg/client/v1`
515+ relaxation clears uncovered dimensions and retries, which here would discard
516+ the check and return the partial recipe that # 1542 fixed.
487517
488518**Evaluator error classification is fail-closed.** During constraint
489519evaluation on the snapshot-driven path, `ErrCodeNotFound` (the evaluator's
0 commit comments