Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions versions/1.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down