Classification Rules

Diff Guardian classifies API changes using a set of structural rules. Each rule targets a specific symbol type (function, interface, enum, or type alias) and assigns a severity: breaking, warning, or safe. Click any rule to see its full documentation with before/after code examples.


Viewing rules in your terminal

Run npx dg rules to list all active rules with their IDs, names, and target types.

Severity levels

SeverityExit CodeMeaning
BREAKING1Callers will fail. Blocks CI in strict mode.
WARNING0 (or 1 if failOnWarnings)Non-breaking but worth reviewing.
SAFE0Harmless API expansion.

Function rules

R01Parameter RemovedBREAKING

A parameter is removed from a function signature. Any caller that passes this argument will break.

Languages: All
processPayment(amount, currency) -> processPayment(amount)
R02Parameter ReorderedBREAKING

The order of parameters changes. Callers using positional arguments will receive wrong values.

Languages: All
createUser(name, age) -> createUser(age, name)
R03Required Param AddedBREAKING

A new required parameter is added. All existing callers will be missing the new argument.

Languages: All
fetchUser(id) -> fetchUser(id, token)
R04Param Type NarrowedBREAKING

A parameter type becomes more restrictive. Callers passing the previously-valid broader type will fail.

Languages: All
process(input: string | number) -> process(input: string)
R05Optional Param AddedSAFE

A new optional parameter is added. Existing callers are unaffected.

Languages: All
fetch(url) -> fetch(url, options?)
R06Return NullableWARNING

The return type now includes null or undefined. Callers not checking for null may crash.

Languages: All
getUser(): User -> getUser(): User | null
R07Return NarrowedSAFE

The return type becomes more specific. Callers expecting the broader type are safe.

Languages: All
getValue(): string | number -> getValue(): string
R08UnexportedBREAKING

A previously exported symbol is no longer exported. All external importers will break.

Languages: All
export function calc() -> function calc()
R11Sync to AsyncBREAKING

A synchronous function becomes async. The return value changes from T to Promise<T>.

Languages: All
function getData(): Data -> async function getData(): Promise<Data>
R12Param Type WidenedSAFE

A parameter type becomes more permissive. All existing callers remain valid.

Languages: All
parse(input: string) -> parse(input: string | Buffer)
R13Generic NarrowedBREAKING

A generic type parameter gains a stricter constraint. Callers using types that no longer satisfy the constraint will fail.

Languages: TS, Java, Rust
transform<T>(v: T) -> transform<T extends Serializable>(v: T)
R14Rest ParameterWARNING

A rest parameter is added or removed, changing the argument collection behavior.

Languages: All
log(msg: string) -> log(...msgs: string[])
R15Overload RemovedBREAKING

A function overload signature is removed. Callers invoking the removed overload will fail to compile.

Languages: TS, Java
function parse(s: string): T; (removed)
R16Overload AddedSAFE

A new overload signature is added. Existing callers are unaffected.

Languages: TS, Java
function parse(s: string): T; function parse(n: number): T; (added)
R17Static ChangedBREAKING

A method changes between static and instance (or vice versa). All call sites change syntax.

Languages: TS, Java
static create() -> create() (or vice versa)
R18Param Mutability NarrowedBREAKING

A parameter type gains a mutability constraint (e.g., readonly removed), breaking callers passing readonly data.

Languages: TS, Rust
process(data: readonly T[]) -> process(data: T[])
R19Param Mutability WidenedSAFE

A parameter gains a readonly constraint. Callers passing mutable data automatically satisfy the new constraint.

Languages: TS, Rust
process(data: T[]) -> process(data: readonly T[])
R20Visibility NarrowedBREAKING

A class method's access modifier becomes more restrictive. External consumers or subclasses lose access.

Languages: TS, Java, Rust
public render() -> protected render()
R21Async to SyncBREAKING

An async function becomes synchronous. Callers using .then() or await will crash.

Languages: All
async function fetchData() -> function fetchData()
R22Return NeverBREAKING

A return type transitions to 'never' (TS) or '!' (Rust), indicating the function now always throws or diverges.

Languages: TS, Rust
process(): Result -> process(): never
R23Default Value ChangedWARNING

A parameter's default value is modified. Callers omitting this argument will silently receive different behavior.

Languages: All
retry(count = 3) -> retry(count = 1)
R24Constructor ChangedBREAKING

A class constructor's parameters change structurally. All 'new ClassName()' instantiations may fail.

Languages: All
constructor(name: string) -> constructor(name: string, id: number)
R28Visibility WidenedSAFE

A previously internal symbol becomes exported. The API surface expands, but existing callers are unaffected.

Languages: All
function helper() -> export function helper()

Interface rules

Enum rules