feat(dpp)!: refersTo propertyAgreement binds referring and referenced document properties - #4505
Conversation
…d document properties
A permanentDocument reference may now declare
propertyAgreement: { <referring property>: <referenced property> } — each
pair must hold as an EQUALITY between the referring document's value and
the referenced document's, enforced by consensus at document write time.
For Yappr this binds a like's hashtag to its referenced post's, so a like
under #dash can never point at a post living under #btc.
Zero new reads: both validation layers already fetch exactly what
agreement needs. Contract registration already resolves the referenced
doctype (memoized + billed) — declarations are validated there: both
properties exist, are plain values, and share one value kind (identifier
with or without its own reference annotation counts as one kind; a
cross-kind equality could never be satisfied and would brick the
doctype). Document write time already fetches the full referenced
document for the existence check and discarded the body — now each pair
is compared through the two doctypes' own key encodings (one
deterministic normal form per value kind, so identifiers stored as bytes
and carried as identifiers compare equal). Replaces re-validate when the
reference OR any referring agreement property changed.
Meta-schema v3 gains the keyword (editable until the PV14 release
ships); the parser accepts it only on permanentDocument references, 1-10
pairs. Two consensus errors appended:
ReferencedDocumentPropertyAgreementInvalidError (40126, registration)
and ReferencedDocumentPropertyMismatchError (40127, write time). The
yappr-likes fixture now declares the hashtag agreement, so every
existing lifecycle test exercises the agreeing direction implicitly.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Warning Review limit reachedNext included review available in 21 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (20)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
🕓 Ready for review — next in queue (commit 14a9d9f) |
|
📖 Book Preview built successfully. Download the preview from the workflow artifacts. Updated at 2026-08-28T10:36:42.249Z |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## v4.2-dev #4505 +/- ##
============================================
+ Coverage 82.98% 83.37% +0.38%
============================================
Files 2744 2773 +29
Lines 368407 373254 +4847
============================================
+ Hits 305740 311200 +5460
+ Misses 62667 62054 -613
🚀 New features to boost your workflow:
|
|
Reviewed, nice feature |
…rence metadata PR #4450 (refersTo reference metadata) and PR #4505 (propertyAgreement on permanentDocument references) were developed in parallel and merged without a rebase between them: #4450's exhaustive destructure of DocumentPropertyReferenceTarget::PermanentDocument does not mention the propertyAgreement field #4505 added, so v4.2-dev fails E0027 in wasm-dpp2 (and everything downstream: wasm-sdk, js-evo-sdk). Rather than ignoring the field, surface it: a permanentDocument reference object now carries propertyAgreement as a plain { referring: referenced } record when the declaration has one, absent otherwise — matching the schema's own omission and the absent-field convention of the other optional target fields. TS custom section, specs (presence + absence) and the js-evo-sdk README updated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Issue being fixed or feature implemented
indexOnly follow-up: refersTo property agreement. A
likereferences apostand both carry ahashtag, but nothing bound them — a like under#dashcould reference a post living under#btc, silently corrupting every hashtag-scoped count and ranking. Contracts can now declare that a property of the referring document must EQUAL a property of the referenced document, enforced by consensus at write time.What was done?
Schema. A
permanentDocumentreference may declare"propertyAgreement": { "<referring property>": "<referenced property>" }(1–10 pairs, dotted paths admitted). Meta-schema v3 gains the keyword — the file is explicitly editable until the PV14 release ships — and the parser (apply_property_reference, PV14-only) accepts it only onpermanentDocumentreferences.DocumentPropertyReferenceTarget::PermanentDocumentgains the field; contracts serialize their schemas and rebuild document types on load, so nothing changes on the wire.Zero new reads — the headline of the design pass. Both validation layers already fetch exactly what agreement needs:
data_contract_reference_validation, in place): the referenced doctype is already resolved (foreign contracts memoized + billed). Declarations are validated there — both properties exist, are plain values (no object containers), the referring property is not the reference itself, and the two share one value kind (sizes may differ;Identifierwith or without its own reference annotation counts as one kind). A cross-kind equality could never be satisfied and would brick every create of the doctype, so it is refused at registration with the newReferencedDocumentPropertyAgreementInvalidError(40126).document_reference_validation, in place): the full referenced document was already fetched for the existence check and its body discarded. Now each pair is compared — through the two doctypes' own key encodings, giving one deterministic normal form per value kind, so an identifier stored as bytes and one carried as an identifier compare equal. Any absence or inequality → the newReferencedDocumentPropertyMismatchError(40127). Replace transitions re-validate when the reference OR any referring agreement property changed (the changed-fields gate now binds the agreement's referring properties too).Both errors are appended to
StateError(append-only wire enum, discriminants pinned 99/100).How Has This Been Tested?
permanentDocument; refused on other reference types; empty map refused; non-string values refused.{ "hashtag": "hashtag" }onlike.postId, so every existing lifecycle test exercises the agreeing direction implicitly; a new test pins the refusal of a#btclike on a#dashpost.--all-targetsand clippy-D warningsclean.Breaking Changes
Consensus: a new contract keyword and two new consensus errors, all PV14-only (unreleased) and extended in place per the stack convention. Contracts without the keyword parse and validate byte-identically; below PV14 the keyword is rejected by meta-schema v2 as before.
Checklist:
Remaining indexOnly follow-ups (tracked, not here): platform-test-suite functional spec, sum axes via SumItem, timeRange buckets.
🤖 Generated with Claude Code