Skip to content

docs(design): ADR-015 recipe-declared configuration profiles#1762

Open
yuanchen8911 wants to merge 1 commit into
NVIDIA:mainfrom
yuanchen8911:adr-015-recipe-declared-params
Open

docs(design): ADR-015 recipe-declared configuration profiles#1762
yuanchen8911 wants to merge 1 commit into
NVIDIA:mainfrom
yuanchen8911:adr-015-recipe-declared-params

Conversation

@yuanchen8911

@yuanchen8911 yuanchen8911 commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds ADR-015: recipe-declared configuration profiles. An overlay may declare a single named profile enum (e.g. gpuStack: operator | csp-managed); exactly one value is selected at recipe generation and hydrated into the artifact with a compact ownership record — so multiple qualified cluster configurations per criteria combination stay validated against the recipe. The design is deliberately minimal:

  • Existing fragment syntax only (componentRefs[].overrides + constraints) — no new templating, no parameter language.
  • No component-set mutation: fragments only re-configure components already enabled in the composition; conditional installation is expressed through values-gated components (chart renders nothing unless the value selects it), and true addition/removal stays a future amendment.
  • Byte-identical behavior for unprofiled recipes, digests included — nothing changes until a family explicitly declares a profile.
  • Explicit conversion boundaries: converting a family is a documented qualification + cut-over event (new artifact apiVersion, regenerated evidence, /v1/v2 client migration), never an implicit upgrade.
  • One authoritative output invariant: before any output is written, the effective configuration must equal the selected recipe at every locked path and presence state, and no output surface may expose a locked path as install-time-mutable; per-surface checks are diagnostics only.

Motivation / Context

One criteria combination increasingly maps to more than one valid cluster configuration (GKE device-plugin ownership, AKS driver-only vs operator-managed pools). Today the only outlets are bundle-time --set (invisible to validation — the deployed config silently diverges from what aicr validate checks) or new criteria axes (recipe-matrix growth).

The ADR chooses a middle path. It specifies the required amendments to the #1327 allocation-policy model (recipe-declared external advertiser, recomputed complete-tuple locking, hydration-boundary coherence checks, one dependency-neutral descriptor + evaluator) and an explicit ADR-011 amendment (profile-bearing recipes ride a new artifact apiVersion so released binaries fail closed instead of silently dropping the profile).

Motivating examples (both specified in the ADR):

  • GKE GPU-stack ownership, three valuesoperator (GKE driver + Operator's plugin; stock, opt-out label required), csp-managed (GKE driver + GKE's managed plugin; advertiser: external, opposite label constraint), and operator-selfdriver (driver installed by a new values-gated gcp-driver-installer component + Operator's plugin — the DGXC/NKX case, declared once its durable ownership-mode distinguishing signal is identified).
  • AKS unmanaged-pool driver/toolkit ownership — GPU-Operator-managed vs the AKS "Driver only" install profile (driver.enabled=false, toolkit.enabled=false, operator.runtimeClass=nvidia-container-runtime, all three together).

The profile direction reached consensus in internal design discussion (2026-07-14). Remaining decision points are listed in the ADR's Deferred Adoption Decisions section — none changes the mechanism or gates acceptance; each is routed to #1761 or the consumer work that resolves it. The Deferred Decision 4 catalog-compatibility follow-up is filed as #1812.

Fixes: N/A
Related: #1761 (implementation tracking), #1755 (GKE label check — first GKE consumer dependency), #1327 (allocation-policy contract being amended)

Type of Change

  • Documentation update

Component(s) Affected

  • Docs/examples (docs/, examples/)

Implementation Notes

Design-only PR — no code changes. Key decisions recorded in the ADR:

  • Single profile per resolved composition — generic multi-params rejected (Alternative C).
  • Compact ownership record persisted in the artifact: owned-path union across all declared values, component presence as the synthetic enabled path.
  • GPU allocation policy: device-plugin production default with recipe-configured DRA opt-in #1327 policy closure recomputed at every RecipeResult boundary from one canonical descriptor + shared evaluator. Rendered outputs are the exception — descriptor-expansion remediation is outcome-based (regenerate every previously rendered profiled output that diverges or stays install-time-mutable at a newly locked path, or conservatively all affected outputs), and each expansion is a re-qualification/evidence re-signing event with profile-bearing evidence current only when both the recipe digest and the scoped descriptor identity (the descriptor entries contributing to that recipe's effective closure) match (a profile-scoped ADR-007 amendment).
  • advertiser: external as the only reserved marker.
  • Closed, strictly-decoded fragment schema — value level: advertiser/constraints/componentRefs; each ref: name/overrides only; no valuesFile; existing components only.
  • Resolved policy value unchanged (device-plugin-extended-resource).
  • New recipe apiVersion for profile-bearing artifacts (explicit ADR-011 amendment) so released binaries reject rather than silently ignore profiles.

Compatibility: landing the mechanism alone is non-breaking by construction.

  • A composition without a profile declaration produces byte-identical artifacts (legacy apiVersion, unchanged digests) — existing overlays, generated recipes, committed evidence, /v1 endpoints, and released binaries are unaffected.
  • Exactly six day-1 behavior changes land, all fail-closed tightenings on inputs invalid under the ADR: aicr mirror list gains the shared context-aware validation gate (no rejection for well-formed recipes; it validates a defensive copy, so Discover output and the caller's artifact are unchanged); raw-artifact boundaries reject unknown-apiVersion artifacts that today pass unchecked; legacy/empty-version artifacts carrying selectedProfile are newly rejected (today's non-strict decode silently drops the field); legacy/empty-version profile-declaring overlays are newly rejected at catalog load (today the kind-only loader silently yields an unprofiled catalog); new-version overlays without a declaration are newly rejected at catalog load (today accepted kind-only); and /v1 requests carrying explicit profile input are newly rejected (today the parameter is silently dropped).
  • All breaking effects on well-formed inputs (new apiVersion, digest changes, family-wide /v1 rejection of ordinary criteria requests, evidence re-signing) are deferred to each family's explicit profile conversion — a documented per-family qualification and cut-over event (see the ADR's Consequences section).

Design-review PR: implementation (#1761) starts after this design is accepted.

Testing

Doc-only change: a single new file, docs/design/015-recipe-configuration-profiles.md. No code, no user-facing docs pages, no sidebar entries (design docs are not part of the Fern site).

Full make qualify was run against an earlier revision of this file and passed (78.8% coverage, zero lint issues, 23/23 E2E, vulnerability gate). Subsequent revisions are prose-only edits to the same single file with no new external links, verified with scoped checks per the doc-only rule: heading/anchor hygiene reviewed, git diff --check clean, and Fern Docs CI (including the link checker) passing on the pushed head.

Risk Assessment

  • Low — Isolated change, well-tested, easy to revert

Rollout notes: N/A — no behavior change until #1761 lands.

Checklist

  • Tests pass locally (make test with -race)
  • Linter passes (make lint)
  • I did not skip/disable tests to make CI green
  • I added/updated tests for new functionality
  • I updated docs if user-facing behavior changed
  • Changes follow existing patterns in the codebase
  • Commits are cryptographically signed (git commit -S)

@yuanchen8911 yuanchen8911 added the theme/recipes Recipe expansion, overlays, mixins, and component registry label Jul 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds ADR-015 for recipe-declared configuration profiles. It defines profile declarations and fragments, generation-time selection and validation, ownership manifests in RecipeResult, bundle-time locking, allocation-policy advertiser rules, hydration validation, artifact compatibility, alternatives, consequences, and GKE/AKS adoption sequencing.

Estimated code review effort: 3 (Moderate) | ~25 minutes

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the ADR and its main subject: recipe-declared configuration profiles.
Description check ✅ Passed The description is directly about the same design change and matches the documented changeset.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/design/015-recipe-configuration-profiles.md`:
- Around line 116-120: Clarify the profile fragment contract in the ADR by
defining which validation fields profile values may adjust, how those
adjustments merge with base validation, and how conflicting values are resolved;
alternatively, remove optional validation adjustments from the documented
profile syntax and related description.
- Around line 141-161: Update the AKS “driver-only” example in the configuration
profiles documentation so it is clearly marked illustrative/TBD and
non-shippable, or remove the example entirely. Do not present driver-only as a
usable profile until an authoritative node-pool-mode validation signal is
identified and documented.
- Around line 237-240: Define the missing-default case in the profile validation
algorithm: when the caller omits --profile and the declaration provides no
default, require an explicit selection and return ErrCodeInvalidRequest.
Preserve declared-default application when available and enforce exactly one
profile value for the resulting recipe.
- Around line 270-278: Update the hydration verification described in the recipe
configuration profile design to validate the complete effective profile
manifest, including non-policy locks such as driver.enabled, toolkit.enabled,
and dcgmExporter.env, rather than only the allocation-policy closure. Since
hydration retains only the selected profile and manifest, specify persisting
sufficient declaration/provenance data or validating the full manifest without
consulting the catalog, and apply the same correction to the related section
around lines 373-393.
- Around line 270-278: Update the profile-selection specification near the
manifest description to define one normalization step across CLI arguments,
config files, client options, query parameters, and request bodies. Require
contradictory selector values to be rejected rather than resolved by precedence,
and state that only a consistent normalized selection may reach adoptRecipe and
RecipeMetadata.Spec.
- Around line 359-367: Update the canonical `#1327` policy closure in the recipe
configuration profile documentation to include both `gpu-operator` and
`gpu-operator-ocp`. Ensure the shared descriptor covers each advertiser’s
`devicePlugin.enabled` and `enabled` paths, including their aliases, so OCP
profile-owned policy values are locked.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 08e93d0c-c7e8-4acd-b807-07ea3e1f10be

📥 Commits

Reviewing files that changed from the base of the PR and between 3574f80 and 84ae4a8.

📒 Files selected for processing (1)
  • docs/design/015-recipe-configuration-profiles.md

Comment thread docs/design/015-recipe-configuration-profiles.md Outdated
Comment thread docs/design/015-recipe-configuration-profiles.md Outdated
Comment thread docs/design/015-recipe-configuration-profiles.md Outdated
Comment thread docs/design/015-recipe-configuration-profiles.md Outdated
Comment thread docs/design/015-recipe-configuration-profiles.md Outdated
@yuanchen8911
yuanchen8911 force-pushed the adr-015-recipe-declared-params branch 4 times, most recently from 1efa627 to 9de71c8 Compare July 15, 2026 16:26

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/design/015-recipe-configuration-profiles.md`:
- Around line 452-472: Update PrepareAndValidate to require selectedProfile
whenever an advertiser declaration exists, verify its profile name and value
against the persisted declaration, and validate the complete manifest including
non-policy locks. Reject incoherent advertiser tuples, including advertiser:
operator when both the operator device plugin and DRA are enabled, while
preserving complete allocation-policy closure validation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 18bb9d08-2c3e-4cc5-a066-ca5c12959329

📥 Commits

Reviewing files that changed from the base of the PR and between 63558de and 9de71c8.

📒 Files selected for processing (1)
  • docs/design/015-recipe-configuration-profiles.md

Comment thread docs/design/015-recipe-configuration-profiles.md Outdated
@yuanchen8911
yuanchen8911 force-pushed the adr-015-recipe-declared-params branch 8 times, most recently from e52aa21 to 50ccb07 Compare July 15, 2026 17:43
@yuanchen8911
yuanchen8911 force-pushed the adr-015-recipe-declared-params branch 9 times, most recently from acc9b80 to 57deb76 Compare July 16, 2026 17:49
@github-actions

Copy link
Copy Markdown
Contributor

@yuanchen8911
yuanchen8911 force-pushed the adr-015-recipe-declared-params branch from 43a5d2d to e7b7085 Compare July 16, 2026 22:28
@github-actions

Copy link
Copy Markdown
Contributor

@yuanchen8911
yuanchen8911 force-pushed the adr-015-recipe-declared-params branch from e7b7085 to 6a99627 Compare July 16, 2026 22:34
@github-actions

Copy link
Copy Markdown
Contributor

@yuanchen8911 yuanchen8911 changed the title WIP: docs(design): ADR-015 recipe-declared configuration profiles docs(design): ADR-015 recipe-declared configuration profiles Jul 16, 2026
@yuanchen8911
yuanchen8911 marked this pull request as ready for review July 16, 2026 22:47
@yuanchen8911
yuanchen8911 requested a review from a team as a code owner July 16, 2026 22:47
@yuanchen8911

Copy link
Copy Markdown
Contributor Author

Ready for design review. Orientation is in the PR description; the full design is docs/design/015-recipe-configuration-profiles.md.

Please focus on (1) whether the proposed design is sound, and (2) opportunities to simplify — the ADR holds itself to "every element must trace to a concrete failure it prevents," and challenges under that bar are welcome. The Deferred Adoption Decisions section at the end of the doc is non-gating (each item is routed to implementation or consumer work); implementation tracking is #1761.

@github-actions

Copy link
Copy Markdown
Contributor

@yuanchen8911
yuanchen8911 force-pushed the adr-015-recipe-declared-params branch from b8cb79d to 368d30d Compare July 16, 2026 23:22
@github-actions

Copy link
Copy Markdown
Contributor

Signed-off-by: Yuan Chen <yuanchen97@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/docs size/XL theme/recipes Recipe expansion, overlays, mixins, and component registry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants