mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-09-22 10:33:27 +00:00
987fc79fde
PLAN-2857 U1, second slice: the doors that take CALLER-SUPPLIED field values now refuse a relation value that does not name a live item in the declared target collection — create, update (full fields), update (fields_patch), and bulk update. The server half adds the one thing the store resolver deliberately does not: visibility. It folds into the SAME `not_found` reason rather than getting its own, because "that item exists but you may not see it" is an existence oracle, and this codebase has a standing rule against handing one out. Ordering at every door is after the shape check and after coercion, so one bad value produces one error rather than two describing it differently, and so the value is in its final form when it is resolved. `fields_patch` examines only the keys the patch carries — the resolver skips absent keys — so an unresolvable value already stored on an item is not re-litigated by an update that does not touch it. That mirrors the undeclared-key rule immediately above it, and it is what stops this turning every edit of a legacy item into a failure. Refusals use the ORDINARY `validation_error` shape with no new details key. The MCP stdio transport classifies errors by matching CLI stderr prose, so a structured field it cannot see would help nobody there, and a new error shape is a contract change for every client. Existing suites unchanged: internal/server ok (224.5s), internal/store ok (258.0s), internal/items ok. Nothing in the tree was writing a bogus relation value through these doors, which is what made this slice safe to land before the per-door pins.