diff --git a/versions/1.2.md b/versions/1.2.md index f321557..2bd6c1c 100644 --- a/versions/1.2.md +++ b/versions/1.2.md @@ -492,10 +492,21 @@ A guard compares a keyed [aggregate](#aggregates--keyed-cross-entity-totals) aga `immutableWhen` requires a `function: EntityStatus` relation; `immutable: true` needs none and is mutually exclusive with it. System / workflow writes stay possible — corrections to an immutable record are flow-generated reversals, never edits. +An entity's immutability also covers its **composition children**, which declare none of their own and whose writes maintain the master's derived values — see [`locksWithMaster`](#lockswithmaster--a-child-collection-that-outlives-its-masters-lock) for the collection that must outlive the lock. + +> **Normative.** +> A generator MUST refuse a user create, update or delete of a composition child whose master is +> currently immutable, unless that child declares `locksWithMaster: false`. The refusal MUST cover +> every user surface it generates, not only the affordances it renders: a child write that +> maintains the master's derived values — a line that resums the document's totals — reaches +> exactly what the lock protects, and permitting it undoes the lock through a different door. It +> MUST NOT extend to system / workflow writes, which are what corrects an immutable record. + ### locksWithMaster — a child collection that outlives its master's lock -An entity's immutability covers **that entity**. A composition child is a different entity, so a -master that locks says nothing about whether its child collections should: +An entity's immutability covers that entity **and the collections composed into it**. For some +children that default is wrong — a master that freezes its own content says nothing about a +collection recording what happens to the document afterwards: ```yaml - name: Invoice @@ -512,7 +523,8 @@ different lifecycles on the same document. > **Normative.** > `locksWithMaster` defaults to **true**, so a child that says nothing keeps freezing with its -> master. +> master — in the affordances a generator renders for that collection AND in the writes it accepts +> for it (see [immutability](#immutablewhen--immutable--user-write-immutability)). > A generator MUST NOT extend a master's user-write immutability to a child collection declared > `locksWithMaster: false` — including the affordances it renders for that collection, not merely > the writes it accepts. A read-only rendering that the server would have permitted is the same