You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit fbc13d8
Browse filesBrowse the repository at this point in the historyBrowse files
fix(api-contract): settle the empty-PATCH contract at 200, and gate it
FR-037 PATCH-5 has always said a patch stripping to zero caller assignments
reads the current row back. Nothing in the corpus asserted it, so the ports
drifted to five answers for one input: TS 500 on the generated mount and 200 on
the reference lane (fixed last commit), C# and Java 400 "validation" from their
base AuthorApiServer while TphReferenceServer and JsonbReferenceServer in the
same directory 200'd, Kotlin 200, Python 200.
Both 400s cited "per FR-035". FR-035's own spec says the opposite. The rule was
settled the whole time; what was missing was a fixture, and an unasserted corner
is where divergence lives — this is the second contract this week found drifting
behind a comment that called it deliberately unsettled.
The C# and Java fix is the REMOVAL of an empty-SET guard. Both already appended
the @autoset:onUpdate stamp unconditionally on the next line, so dropping the
guard makes the SET non-empty on its own and the ordinary write path answers
correctly. Nothing else moves.
That also settles how PATCH-3 and PATCH-5 meet, which the fixture forced into
the open: the server-side stamp IS an assignment, so on an entity carrying an
onUpdate column the literal zero-assignment read-back path is never reached, and
an empty patch bumps the stamp like any other write. The read-back path is
reachable only for an entity with no such column. Both routes answer 200 with
the current row, which is why the contract is stable either way. PATCH-5's
wording is corrected: it read "no write is executed", true only in the second
case. patch-empty-noop.yaml asserts the bump via fieldsNotEqual, the exact
inverse of autoset-patch.yaml.
r2 pins the arm a short-circuit misses: a no-op patch must still 404 on a row
that does not exist, or the fast path becomes a hole reporting success for any
id — on a TPH route, a hole through which one subtype answers for another's row.
Verified in all five ports, both lanes each: TS 58, Python 89, C# 101, Java 58,
Kotlin 58, all green.
Also corrects a stale count in docs/CONFORMANCE.md: the m2m sub-corpus prose
said 8 while the directory held 9 (route-spelling-multiword-collection.yaml
landed in 5efdb9e and only the table was updated).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015NrWUxA6euwvnFcwKxcK6A
0 commit comments