From f0a42ee649b1a8d98ada993eb6c559bd0efc275a Mon Sep 17 00:00:00 2001 From: delchev Date: Sat, 15 Aug 2026 22:19:46 +0300 Subject: [PATCH 1/2] docs: an unrecognised key is an authoring error, never ignored Mirrors the specification change: the Unrecognised keys rule in Authoring rules, and the sharpened seed-row rule (a field name, a to-one relation name, or the stage marker - and what accepting anything else silently costs). --- docs/spec/data.md | 2 +- docs/spec/index.md | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/spec/data.md b/docs/spec/data.md index d28763d..a5e3c41 100644 --- a/docs/spec/data.md +++ b/docs/spec/data.md @@ -36,7 +36,7 @@ Generates a seed-import descriptor + CSV per seed. Two shapes: - **`file: data/.csv`** — an authored CSV under a `data/` subfolder, right for bulk nomenclatures and prepopulated demo data. A foreign key is set by the relation name (`Country: 34`). ::: info Normative -Row keys must match a field or relation name **exactly** (case-sensitive). A key matching neither is an authoring error — a silently dropped column becomes a NOT NULL failure at import time. +Row keys must match a field name, a **to-one** relation name (a collection has no column to set), or the `stage` marker below, **exactly** (case-sensitive). A key matching none of those is an authoring error, reported with the nearest declared name — see [unrecognised keys](/spec/#unrecognised-keys). Accepting it would drop the column, and a dropped NOT NULL foreign key makes the import skip **every** row: a nomenclature that imports as zero rows, behind a fully green pipeline. ::: A seed with `language: ` is a **translation** seed: it fills the per-language values of a `multilingual: true` entity, carrying the base row's `id` plus the translatable fields only. diff --git a/docs/spec/index.md b/docs/spec/index.md index 7160085..1f4da3d 100644 --- a/docs/spec/index.md +++ b/docs/spec/index.md @@ -167,6 +167,22 @@ These rules keep the file diff-stable, safe to parse, and friendly for both huma - **No type tags.** Blocked by the safe parser. - **Quote unquoted braces in scalars.** `to: {member.email}` is parsed by YAML as an object, not a string - write `to: member.email`. Braces are only for `{...}` interpolation inside `subject` / `body` text. - **An event-binding key is `event:`, never `on:`** - YAML 1.1 resolves a bare `on` (and `off` / `yes` / `no`) to a boolean. An action key is `do:`. +- **Only the keys this specification declares exist, and they are case-sensitive.** An invented key, or a case slip (`Required:` for `required:`), is an authoring error - never a key that is accepted and ignored. + +### Unrecognised keys + +A typed mapping normally drops a key it does not know. That silence is the worst failure this format can have: the file is accepted, generation succeeds, the application deploys, and the only symptom is that the promise the author wrote is absent at runtime - with every step of the pipeline reporting success. The rule is therefore the same one the format applies to a reference it cannot resolve. + +::: info Normative +A conforming generator MUST report a key it does not recognise as an authoring error rather than +ignoring it, and the report MUST name the key, where it appears, and - where one exists - the +nearest declared name. Key names are **case-sensitive**: a key differing from a declared one only in +case is unrecognised, and the report SHOULD say so, since it is the slip hardest to see by eye. This +applies equally to a [seed row](/spec/data#seeds), whose keys are the target entity's own names +rather than this specification's. A map whose keys are drawn from the model being described (a +`map:` projection, a relation's `where:`, a widget's `at:`) is validated against that model, not +against this vocabulary. +::: ## In this section From 9cd9ac23821c2359c55c9b35a0082c65e641a92f Mon Sep 17 00:00:00 2001 From: delchev Date: Sun, 16 Aug 2026 01:29:10 +0300 Subject: [PATCH 2/2] docs: a step argument is recognised per step kind Mirrors the specification change: the per-kind rule for a step's args, the list of blocks that are a fixed vocabulary despite being written as a mapping, and a delegate's injected fields: added to the free-form list. --- docs/spec/index.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/spec/index.md b/docs/spec/index.md index 1f4da3d..51eb56f 100644 --- a/docs/spec/index.md +++ b/docs/spec/index.md @@ -180,8 +180,20 @@ nearest declared name. Key names are **case-sensitive**: a key differing from a case is unrecognised, and the report SHOULD say so, since it is the slip hardest to see by eye. This applies equally to a [seed row](/spec/data#seeds), whose keys are the target entity's own names rather than this specification's. A map whose keys are drawn from the model being described (a -`map:` projection, a relation's `where:`, a widget's `at:`) is validated against that model, not -against this vocabulary. +`map:` projection, a relation's `where:`, a widget's `at:`, a delegate's injected `fields:`) is +validated against that model, not against this vocabulary. +::: + +Being written as a mapping does not make a block free-form. A process [`trigger:`](/spec/processes), +an [`abortOn:`](/spec/processes#aborton-cancel-the-instance-on-a-terminal-status), a glue +[`event:`](/spec/glue#notifications) binding, a step's [`args:`](/spec/processes) and the blocks +nested inside them are each a fixed vocabulary, and a key outside it is unrecognised like any other. + +::: info Normative +A step's `args:` are recognised **per step kind**: an argument declared on a kind that does not read +it (a decision's `if` on a user task, a boundary `timeout` on a service task) MUST be reported like +an unrecognised one, and the report SHOULD name the kind that does read it. This is the same failure +and not a lesser one - the step reads nothing, so the argument does nothing. ::: ## In this section