0.14.0
Immutable
release. Only release title and notes can be modified.
v0.14.0
Adds a payload-parity findings lane: richter now notices when a model field is added but never reaches the API Resource that renders it — the shape behind a setting that saves fine yet silently reverts on the client. Sourced from production dogfood, where this was the single most-reproduced defect class. Advisory only; nothing about the risk level, the --fail-on gate, or affected-tests changes.
Added
- Payload-parity detection. When a diff adds a name to a model's
$fillable,$casts, orcasts(), richter checks the resources that render that model and reports — under Findings — any that mirror the model's other fields but omit the newly added one. Findings are advisory strings only; they never feedrisk,--fail-on, oraffected-tests.- Candidate resources are matched by graph wiring first (the controllers/actions that touch the model and the resources they return), falling back to conventional names (
App\Http\Resources\PostResource,PostCollection, or the model name as a namespace segment) andApp\Transformersonly when nothing is wired. - Deliberately no-guess: the default
mirror_thresholdof1.0fires only on an exact mirror, and any resource whosetoArray()the parser cannot statically enumerate — a spread,array_merge,mergeWhen,parent::toArray(),only(), or a dynamic key — is skipped rather than guessed at. Constant-based field names and keys (Post::TITLE) are resolved on both sides.
- Candidate resources are matched by graph wiring first (the controllers/actions that touch the model and the resources they return), falling back to conventional names (
- Configuration:
payload_parity.{enabled, mirror_threshold, ignore}inconfig/richter.php. On by default.ignoresuppresses a specific field (App\Models\Post::internal_flag) or a whole resource (its FQCN). --no-payload-parityonrichter:detect-changesdisables the lane for a single run.expect_findingon benchmark cases (and a--expect-findingoption onrichter:benchmark:add) asserts that a replayed case surfaces a finding containing a given substring — scoring a checker's identification, not just the blast radius it elevates.
Compatibility
No breaking changes. The lane is purely additive: the --json contract is unchanged (findings remains a list<string>), and existing reports read identically with the lane disabled. A project that wants it off sets payload_parity.enabled to false or passes --no-payload-parity.
Full Changelog: v0.13.0...v0.14.0