@@ -247,18 +247,15 @@ spec:
247247 componentRefs:
248248 - name: gcp-driver-installer
249249 overrides:
250- install: false # every value assigns every union path
250+ # every value assigns every union path; nested gate — see the
251+ # amendment on operator-selfdriver below.
252+ installer: {enabled: false}
251253 - name: gpu-operator
252254 overrides:
253255 devicePlugin: {enabled: true}
254256 constraints:
255257 - name: NodeTopology.gpu-nodes.label # requires #1755
256258 value: gke-no-default-nvidia-gpu-device-plugin=true
257- # Amended 2026-08-22: DD5 symmetry — this value asserts the
258- # ABSENCE of the installer's ownership marker at readiness.
259- readinessConstraints:
260- - name: NodeTopology.gpu-nodes.label
261- value: "!feature.node.kubernetes.io/gcp-driver-installer"
262259 # GKE-installed driver AND GKE's managed device plugin — a
263260 # default-provisioned GKE cluster (no node label required). The
264261 # declared default: the only value satisfied with zero setup.
@@ -267,7 +264,7 @@ spec:
267264 componentRefs:
268265 - name: gcp-driver-installer
269266 overrides:
270- install: false
267+ installer: {enabled: false}
271268 - name: gpu-operator
272269 overrides:
273270 devicePlugin: {enabled: false}
@@ -296,13 +293,6 @@ spec:
296293 constraints :
297294 - name : NodeTopology.gpu-nodes.label
298295 value : gke-no-default-nvidia-gpu-device-plugin=true
299- # Amended 2026-08-22: the DD5 distinguishing signal — a property
300- # the value's own deployment creates, absent from any
301- # pre-deployment snapshot — is declared under readinessConstraints
302- # and evaluated by the validate pre-flight only.
303- readinessConstraints :
304- - name : NodeTopology.gpu-nodes.label
305- value : feature.node.kubernetes.io/gcp-driver-installer=true
306296` ` `
307297
308298The GKE declaration lives once in ` gke-cos`; accelerator/intent leaves
@@ -530,7 +520,7 @@ to the surviving composition:
530520 # digest, so ordering must be byte-stable
531521 # Post-DD5 state shown; the initial recording is
532522 # gpu-operator: [devicePlugin.enabled, enabled] only.
533- gcp-driver-installer: [enabled, install ]
523+ gcp-driver-installer: [enabled, installer.enabled ]
534524 gpu-operator: [devicePlugin.enabled, enabled]
535525 ` ` `
536526
@@ -1542,40 +1532,37 @@ work that resolves it.
15421532 **Proposed: identify a durable signal during the value's adoption;
15431533 the `operator` and `csp-managed` values do not wait on it.**
15441534
1545- *Amended 2026-08-22 (issue # 1716).* Two parts land with the value's
1546- adoption :
1547-
1548- - **Mechanism.** `ProfileValue` gains `readinessConstraints` — same
1549- catalog-load validation as `constraints` with per-phase name
1550- deduplication (the same measurement path may carry a generation
1551- pre-condition and a readiness post-deployment state — this is
1552- exactly the DD5 shape, since both signals here are
1553- ` NodeTopology.gpu-nodes.label` readings), routed into
1554- ` spec.validation.readiness.constraints` at resolution and **never
1555- evaluated at generation time**. This is required for any
1556- post-deployment signal : generation-time evaluation runs against a
1557- pre-deployment snapshot in which the signal cannot yet exist, and
1558- the overlay-level readiness block cannot vary per value. The
1559- ` aicr validate` readiness pre-flight evaluates them with the same
1560- fail-closed exit as every other readiness gate.
1561- - **Signal.** GCP-native labels cannot distinguish the two unmanaged
1562- values : both require identical pool shapes
1563- (`gpu-driver-version=disabled` + the opt-out label; Google's own
1564- installer DaemonSet schedules only where
1565- ` cloud.google.com/gke-gpu-driver-version` is absent, so a
1566- version-labeled pool is unreachable for either). The signal is
1567- therefore AICR-owned : the `gcp-driver-installer` DaemonSet stamps
1568- a durable node label after a successful install;
1569- ` operator-selfdriver` asserts it under `readinessConstraints` and
1570- ` operator` (shipped name `driver-installer`) asserts its absence —
1571- both declarations land together with the value's adoption (the
1572- sketch above shows the declared shape).
1573- A further hardening — a generation-time
1574- ` !cloud.google.com/gke-gpu-driver-version` constraint on both
1575- unmanaged values, converting the documented "opt-out label +
1576- managed install = driverless pool" misconfiguration into a
1577- fail-closed recipe error — is DEFERRED : a value may carry one
1578- constraint per measurement path per phase, and
1579- ` NodeTopology.gpu-nodes.label` is already occupied at generation
1580- by the pool-label constraint. It requires a conjunction grammar
1581- for the label form, tracked as follow-up work.
1535+ *Amended 2026-08-24: mechanism only.* `ProfileValue` gains
1536+ ` readinessConstraints` — same catalog-load validation as `constraints`
1537+ with per-phase name deduplication (the same measurement path may carry
1538+ a generation-time pre-condition and a readiness-time post-deployment
1539+ state), routed into `spec.validation.readiness.constraints` at
1540+ resolution and **never evaluated at generation time**. The
1541+ ` aicr validate` readiness pre-flight evaluates them with the same
1542+ fail-closed exit as every other readiness gate.
1543+
1544+ The mechanism exists for values whose distinguishers are
1545+ deployment-created — where no generation-time reading can hold. Two
1546+ rules govern its use :
1547+
1548+ - **The self-falsifying pre-condition trap.** Generation-time
1549+ constraints are re-evaluated by the validate pre-flight, so a
1550+ pre-condition that the value's own success erases (e.g. "no NVIDIA
1551+ driver loaded" on a value whose operator installs the driver) must
1552+ never be declared as a generation constraint — it fails every
1553+ post-deployment validate on a correctly working cluster. Such state
1554+ belongs in `readinessConstraints`, asserted in its post-deployment
1555+ form.
1556+ - **Self-rendered readings do not qualify.** A reading the selected
1557+ bundle itself renders (e.g. deployed ClusterPolicy fields) is
1558+ satisfied by construction under every value — it is a useful
1559+ rendered-policy **drift check**, but it cannot serve as a value's
1560+ distinguishing constraint. Qualification requires cluster state
1561+ independent of the bundle's own output (provider properties, node
1562+ labels set at provisioning, externally-owned objects).
1563+
1564+ This PR resolves no GKE signal : the GKE family's DD5 question was
1565+ settled separately by value replacement (see the adoption-step
1566+ amendment), and its shipped values are generation-time
1567+ distinguishable. The mechanism's consumers are families whose values
1568+ are distinct cluster shapes with deployment-created distinguishers.
0 commit comments