The owner block is compared field by field, so changing a dri or adding a
contact while the team is unchanged surfaces the specific change rather than an
opaque whole-owner modification. Contacts are keyed by type:value; a purpose
change on an existing contact is a modification. The service.image comparison
includes the private flag, so toggling image privacy is reported even when the
ref is unchanged.
Inline configuration values are the provider's own defaults, not part of the
consumer-facing contract surface, so value changes are diffed key by key (e.g.
configurations[app].values.replicas) and classified NON_BREAKING.
Adding a health or metrics block (or one of its fields) is a new capability
and classifies as NON_BREAKING; removing the interface/path loses a runtime
check and classifies as POTENTIAL_BREAKING. initialDelaySeconds is always
NON_BREAKING. Health and metrics are compared field by field — a whole-block
add or remove surfaces as the corresponding per-field changes.
Parameters are identified by name + in (location: query, path, header, cookie). A parameter renamed or moved to a different location is treated as a removal + addition.
Schema files referenced by configurations[].schema, policies[].schema, or the auto-detected policy/schema.json are compared recursively. Every structural difference — properties, types, constraints, defaults, enums, etc. — is detected and classified.
All readiness changes are classified as NON_BREAKING — readiness tracks operational
maturity and does not affect runtime compatibility. Adding or removing the whole
readiness block surfaces as a single readiness change; otherwise the gate
fields (expires, minScore, partialCredit) are compared individually. Checks
are keyed by id, and a check whose status, weight, evidence or any other
field changed is reported as a modification of that check (e.g.
readiness.checks[dashboard]). The readiness.history revision log is not diffed:
it is an append-only changelog that changes on every release and would only add
noise.