Skip to content

type generalize/specialize rules are asymmetric: response narrowing mis-flagged as breaking, and request-parameter-property is inconsistent #989

@reuvenharrison

Description

@reuvenharrison

Summary

The type-generalized / type-specialized / type-changed rules are not symmetric across locations. Some of the asymmetry is intentional, but it exposes two real gaps, one of which causes a false positive on a backward compatible change.

The full type-change matrix

location generalized (widen) specialized (narrow) changed (incompatible)
request-body-type info missing error
request-parameter-type info missing error
request-property-type info missing error
request-parameter-property-type info error warning
response-body-type missing missing error
response-property-type missing missing error
response-media-type-name error info info

What is intentional

Breaking-ness flips with direction: widening a request is backward compatible (existing clients stay valid), narrowing a request breaks it, and for responses it is the reverse. A dedicated verb is only needed to carve the non-breaking case out of the breaking type-changed default:

  • On the request side, generalized is the safe case and gets its own info-level rule. Both specialized (narrowing) and an incompatible changed are breaking and are already covered by type-changed (error), so a separate request specialized rule adds nothing.

That part is fine and explains why generalize rules outnumber specialize rules.

Gap 1: request-parameter-property is inconsistent with its siblings

request-parameter-property-type has all three variants (generalized info, specialized error, changed warning), while request-body-type, request-parameter-type, and request-property-type only have generalized + changed and fold specialization into type-changed.

The family should behave the same way. Either all request type locations should emit a dedicated specialized rule, or none should (and request-parameter-property-type-specialized should fold into request-parameter-property-type-changed). The request-parameter-property-type-changed being warning while the others are error is also inconsistent.

Gap 2 (real user impact): response type narrowing is mis-reported as breaking

response-body-type and response-property-type only emit *-type-changed (error). They do not split generalize vs specialize. Narrowing a response type (specialize, for example number to integer) is backward compatible, but it is currently reported as a breaking response-*-type-changed error, which can fail a CI gate on a non-breaking change.

response-media-type-name already does this correctly (response-media-type-name-specialized is info). The body/property response type checks should do the same: a response type specialization should be info, a generalization should be error, and only a genuinely incompatible change should be type-changed error.

Suggested fix

  • Add response-body-type-generalized (error), response-body-type-specialized (info), response-property-type-generalized (error), response-property-type-specialized (info), and reserve response-*-type-changed for genuinely incompatible changes. This closes the false positive in Gap 2.
  • Make the request type family consistent (Gap 1): either add request-body-type-specialized / request-parameter-type-specialized / request-property-type-specialized, or remove the lone request-parameter-property-type-specialized in favor of the generic type-changed.

Gap 2 is the higher priority since it affects breaking-change accuracy.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions