Awesome Reviewers expert instructions

domains / / kUbernetes/kUbernetes

Defaulting and DV Rules

When evolving an API with new fields, treat defaulting/mirroring and declarative validation as a coupled compatibility problem. 1) Mirror/default fields must preserve client intent

raw .md API Go

When evolving an API with new fields, treat defaulting/mirroring and declarative validation as a coupled compatibility problem.

1) Mirror/default fields must preserve client intent

  • If you introduce a new field that “mirrors” legacy fields via defaulting, explicitly document and test the patch/update behavior for skewed clients.
  • Ensure old clients can still set legacy fields (e.g., hostNetwork) without being unintentionally overwritten by defaulting derived from new fields (e.g., defaultNetwork).
  • If the only safe reconciliation requires both fields to agree, enforce this contract (via validation) and/or implement update strategies that either (a) assist only in well-defined legacy-to-new migrations or (b) fail with a clear error when the request is ambiguous.

2) Declarative validation migration: only remove manual checks when it’s truly equivalent

  • If the DV mechanism can’t express the constraint due to API shape/nullability limitations, keep handwritten validation and add a comment explaining why it can’t be migrated yet.
  • If DV tags are alpha/beta/still shadowed, keep manual validation as the authoritative behavior until the corresponding tags graduate to stable.
  • Be careful with DV “shadowing” scope: DV tags on a field may cause validation to apply to parent fields/other constraints unexpectedly. Keep DV changes limited to the intended constraint.

Practical pattern

  • Prefer “validation + explicit reconciliation” over implicit defaulting that overwrites other fields.
  • Keep handwritten validation until DV is demonstrably equivalent in behavior (including error locations/messages you rely on).

Illustrative (constraint kept manual when DV can’t represent the mutual exclusion)

// Exactly one of Value or ValueFrom must be specified.
// TODO: DV migration blocked by current API shape (non-nilable/union tag limitations).
func validateCounter(c *ConsumeCounter, fldPath *field.Path) field.ErrorList {
	allErrs := field.ErrorList{}
	if c.Value == (resource.Quantity{}) == (c.ValueFrom == nil) {
		allErrs = append(allErrs, field.Invalid(fldPath, c,
			"exactly one of value or valueFrom must be specified"))
	}
	return allErrs
}

Result: API additions remain patch-compatible across client versions, and constraints don’t silently change semantics during DV migration.