From 3378153ba759ea055e17d87502fc6f41b700b9ce Mon Sep 17 00:00:00 2001 From: delchev Date: Mon, 7 Sep 2026 14:43:29 +0300 Subject: [PATCH] forms: a relation.field may cross models The spec described a form's relation.field as a one-hop to-one without saying which models the hop may reach, and implementations read that as local-only - so the relation a document's form most needs to read a field of, its counterparty, was refused. State it: the hop may be cross-model, resolved against the owner's model at generation time, the same one-hop path a notify recipient takes, and a field the owner does not declare must be reported rather than silently dropped. Co-Authored-By: Claude Opus 5 --- versions/1.2.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/versions/1.2.md b/versions/1.2.md index f321557..b1c20e8 100644 --- a/versions/1.2.md +++ b/versions/1.2.md @@ -793,6 +793,10 @@ forms: Generates one form per `forms[]` entry. Controls are typed by looking each field up against the bound entity (string to a text input, integer / decimal to a number input, boolean to a checkbox, date to a date picker, and so on). Actions become buttons, coloured by name (approve to positive; reject / decline / delete / cancel to negative; save / submit to emphasised). +A `relation.field` entry reads a field of a one-hop to-one relation, read-only — the related record is loaded for the form rather than typed into it. The relation MAY be **cross-model**: a document's form can show a field of the entity another module owns (an invoice's Send form showing the customer's address), which is the same one-hop path a [`notify`](#notifications) recipient takes. + +**Normative.** For a cross-model `relation.field`, the relation's `model:` MUST be declared in [`uses`](#reuse-dont-redefine--uses), and the referenced field is validated against the **owner's** model at generation time rather than against the local document. A conforming generator MUST report a field the owner model does not declare instead of dropping the control silently: a control bound to a value nothing ever provides is indistinguishable from a record that has no value. + ### actions — custom buttons Developer-defined buttons that open a custom page — the escape hatch when a workflow or a generated screen is not enough: