Equality is (type, name, writable) — meaningful only within a single
container. name is a field key that's unique within one form or
infolist, not globally, so two components from different resources, or
from a form vs its infolist, can compare equal here while differing in
every other property. Do not put components from different containers
into the same Set or diff them against each other on this equality.
writable is included: a /state round-trip can flip it on a field
whose type and name are otherwise unchanged, and a rebuild that depends
on that difference needs the equality to see it. translatable is
included for the same reason writable is: it is what decides whether
this leaf renders inside a locale-chip group at all.
direction can also be closure-backed and flip on /state, so it must
participate too or a widget diff may retain the old override.
Client-side validation hints. A base-node property in the contract (§5.3),
so every consumer can ask "is this required?" without switching over the
sealed hierarchy. Containers and entries simply carry
ValidationRules.none.
True only on a dotted leaf (caption.ar) whose head attribute
(caption) is translatable on the model — the writable/placeholder
precedent: published only when true, absent everywhere else, including
the undotted scalar sibling. The form screen groups every leaf sharing
a head-of-name into one field slot with locale chips instead of one
stacked field per locale; see ResourceFormScreen's node walk.
False only when the server marks a field it cannot persist — distinct
from disabled, which is a UI decision the user may be able to change
elsewhere. Absent in the contract means true: most fields are
writable, and the key exists to name the exception, not the rule.