---
title: Rules Reference
description: All 45 Specdiff rules with default severities and direction-aware behavior.
url: https://pr-1-7cfcfe393d12.thally.app/specdiff-rules
---

# Rules Reference

All 45 Specdiff rules with default severities and direction-aware behavior.

Specdiff ships with 45 built-in rules. Each rule has a stable code, a default
severity, and an applies-to scope indicating whether it fires for JSON Schema
documents, OpenAPI documents, or both.

## Direction-aware severity

Twelve of the 45 rules have severity that varies depending on the direction of
data flow. For example, adding a required property is breaking for a request
schema (callers do not send it yet) but informational for a response schema
(consumers get a stronger guarantee).

The `severityFor(code, direction)` function from `@specdiff/core` resolves the
effective severity for a given rule and direction. It consults the
`DIRECTION_SEVERITY` table first, then falls back to the rule's
`defaultSeverity`. The `"neutral"` direction mirrors the request column because
it takes the validation-centric reading that standalone JSON Schema validators
use.

---

## JSON Schema rules

These rules fire for both JSON Schema and OpenAPI documents (inside parameter,
request body, and response schemas). 24 rules.

| Code | Default Severity | Title | Direction-Aware |
| --- | --- | --- | --- |
| `type-changed` | breaking | Type changed | No |
| `property-removed` | breaking | Property removed | No |
| `property-added` | info | Optional property added | No |
| `required-property-added` | breaking | Required property added | Yes |
| `required-added` | breaking | Existing property became required | Yes |
| `required-removed` | info | Property no longer required | Yes |
| `enum-value-removed` | breaking | Enum value removed | Yes |
| `enum-value-added` | info | Enum value added | Yes |
| `additional-properties-restricted` | breaking | Additional properties restricted | Yes |
| `additional-properties-relaxed` | info | Additional properties relaxed | No |
| `constraint-tightened` | breaking | Constraint tightened | Yes |
| `constraint-relaxed` | info | Constraint relaxed | Yes |
| `format-changed` | warning | Format changed | No |
| `nullable-removed` | breaking | Null no longer accepted | Yes |
| `nullable-added` | info | Null now accepted | Yes |
| `default-changed` | warning | Default changed | No |
| `description-changed` | info | Description changed | No |
| `composition-variant-removed` | breaking | Composition variant removed | Yes |
| `composition-variant-added` | info | Composition variant added | Yes |
| `items-changed` | breaking | Array items definition changed shape | No |
| `const-changed` | breaking | Constant changed | No |
| `deprecated-added` | warning | Marked deprecated | No |
| `readonly-writeonly-changed` | warning | readOnly/writeOnly changed | No |
| `unresolved-ref` | warning | Unresolved `$ref` | No |

---

## OpenAPI rules

These rules fire only for OpenAPI documents. 21 rules.

| Code | Default Severity | Title |
| --- | --- | --- |
| `endpoint-removed` | breaking | Endpoint removed |
| `endpoint-added` | info | Endpoint added |
| `operation-removed` | breaking | Operation removed |
| `operation-added` | info | Operation added |
| `operation-id-changed` | warning | operationId changed |
| `parameter-removed` | breaking | Parameter removed |
| `required-parameter-added` | breaking | Required parameter added |
| `optional-parameter-added` | info | Optional parameter added |
| `parameter-required-changed` | breaking | Parameter required flag changed |
| `request-body-required-added` | breaking | Request body became required |
| `request-body-media-type-removed` | breaking | Request media type removed |
| `request-body-media-type-added` | info | Request media type added |
| `response-removed` | breaking | Response removed |
| `response-added` | info | Response added |
| `response-media-type-removed` | breaking | Response media type removed |
| `response-media-type-added` | info | Response media type added |
| `security-requirement-added` | breaking | Security requirement added |
| `security-requirement-removed` | info | Security requirement removed |
| `server-removed` | warning | Server removed |
| `server-added` | info | Server added |
| `deprecated-operation` | warning | Operation deprecated |

---

## Direction-aware rules detail

The following 12 rules have severity that differs depending on whether the
schema describes a request or a response. The `"neutral"` direction uses the
same severity as `"request"`.

| Code | Request | Response | Neutral |
| --- | --- | --- | --- |
| `required-added` | breaking | info | breaking |
| `required-property-added` | breaking | info | breaking |
| `required-removed` | info | breaking | info |
| `enum-value-added` | info | warning | info |
| `enum-value-removed` | breaking | info | breaking |
| `constraint-tightened` | breaking | info | breaking |
| `constraint-relaxed` | info | warning | info |
| `additional-properties-restricted` | breaking | info | breaking |
| `nullable-added` | info | breaking | info |
| `nullable-removed` | breaking | info | breaking |
| `composition-variant-added` | info | warning | info |
| `composition-variant-removed` | breaking | info | breaking |

**Why direction matters:** Validation-centric thinking ("stricter is breaking")
is only correct for data flowing into a service (requests). For data flowing
out (responses), consumers are broken by losing guarantees — a field that is no
longer required, a nullable value that appears unexpectedly, or an enum value
they have never seen. The direction system lets Specdiff adjust severities
automatically when it knows which side of the API a schema belongs to.

For OpenAPI documents, the direction is inferred from context (request body
schemas use request direction, response schemas use response direction). For
standalone JSON Schema documents, set the direction explicitly via the
`direction` option or the `--direction` CLI flag.