@cratis/pi 7.65.0 → 7.67.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/package/corpus/product-sync.json +3 -3
  2. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/realization-and-gap-fill.md +1 -1
  3. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/atomic-batches-and-source-mappings.md +1 -1
  4. package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +4 -3
  5. package/package/corpus/skills/cratis-screenplay-command-surface/references/date-comparisons.md +13 -2
  6. package/package/corpus/skills/cratis-screenplay-model-authoring/references/language-reference.md +2 -2
  7. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +2 -2
  8. package/package/corpus/skills/cratis-screenplay-model-authoring/references/screen-authoring-workflow.md +13 -0
  9. package/package/corpus/skills/cratis-screenplay-model-review/references/checklist.md +1 -1
  10. package/package/corpus/skills/cratis-screenplay-model-review/references/public-keys-and-routes.md +4 -2
  11. package/package/corpus/skills/cratis-screenplay-projections/SKILL.md +5 -0
  12. package/package/corpus/skills/cratis-screenplay-projections/references/pdl-grammar.md +42 -2
  13. package/package/corpus/skills/cratis-screenplay-read-surface/SKILL.md +9 -7
  14. package/package/corpus/skills/cratis-screenplay-read-surface/references/equality-filters.md +1 -1
  15. package/package/corpus/skills/cratis-screenplay-read-surface/references/named-keys.md +168 -58
  16. package/package/corpus/skills/cratis-screenplay-read-surface/verification.json +2 -2
  17. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/gap-fill-handoff.md +1 -1
  18. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/renderability-gate.md +1 -1
  19. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/scenario-examples.md +2 -2
  20. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/spec-forms-by-mode.md +3 -3
  21. package/package/corpus/skills/cratis-screenplay-slice-design/SKILL.md +2 -2
  22. package/package/corpus/skills/cratis-screenplay-slice-design/references/public-boundaries-and-keys.md +5 -3
  23. package/package/corpus/skills/cratis-screenplay-slice-design/references/read-model-design.md +3 -2
  24. package/package/corpus/skills/cratis-screenplay-specifications/SKILL.md +3 -2
  25. package/package/corpus/skills/cratis-screenplay-specifications/references/query-rejections.md +4 -0
  26. package/package/corpus/skills/cratis-screenplay-specifications/references/vocabulary.md +17 -0
  27. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/SKILL.md +3 -1
  28. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/read-model-keys.md +46 -0
  29. package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +6 -5
  30. package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet.md +2 -2
  31. package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostic-arguments.md +7 -0
  32. package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +30 -6
  33. package/package/corpus/skills/cratis-screenplay-toolchain/references/executable-subset.md +31 -9
  34. package/package/corpus/skills/cratis-screenplay-toolchain/references/language-admission.md +15 -5
  35. package/package/corpus/skills/cratis-screenplay-toolchain/references/preferred-syntax.md +2 -1
  36. package/package/corpus/skills/cratis-screenplay-toolchain/references/production-routes-and-filters.md +1 -1
  37. package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +3 -3
  38. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +3241 -1287
  39. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
  40. package/package/corpus/skills/cratis-screenplay-toolchain/references/traps.md +2 -2
  41. package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +1 -1
  42. package/package/corpus/skills/cratis-screenplay-ui-composition/SKILL.md +4 -3
  43. package/package/corpus/skills/cratis-screenplay-ui-composition/references/application-shell.md +1 -1
  44. package/package/corpus/skills/cratis-screenplay-ui-composition/references/screen-composition-contract.md +1 -1
  45. package/package/corpus/skills/cratis-screenplay-ui-composition/references/ui-profile-and-theme.md +124 -2
  46. package/package/corpus/skills/cratis-screenplay-ui-composition/verification.json +25 -0
  47. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +5 -4
  48. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +12 -7
  49. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/sandbox-and-specrunner.md +17 -0
  50. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/verification.json +1 -1
  51. package/package.json +1 -1
@@ -31,7 +31,7 @@ ESM). Only the probe answers renderability. `PLAY0270` entries are information,
31
31
  | Class | Meaning | Typical examples (each verified in `admission.md`) | Action |
32
32
  | --- | --- | --- | --- |
33
33
  | **Model fix (in mode)** | the model is in, or the user chose, renderable mode and breaks its own subset in a way that has a renderable equivalent with the same meaning | a `produces` whose `for` is not the command identifier; two projections for one read model (`-007`); a policy Stage cannot express portably (`-015`; role-only and opaque pure policies render) | edit request to the modeler session with address, change and rationale |
34
- | **Capability gap** | the intended meaning needs a construct Stage does not render yet | DateTime equality filters and required parameters after optional filters (`-010`); context/single-result filters, opaque `scoped to`/`performer` and composite `by` remain PLAY0268; Translate, clocks, captures, non-event triggers and opaque reaction bodies (`-024`); claim-reading/opaque `runs as` gates (`-034`), legacy `from` (`-035`), mixed effects in one handler (`-037`, retries can duplicate events; keep it whole), unsupported reaction mappings (`-039`); unsupported generated types/result combinations (`-028`/`-038`); `then no readmodel` (`-027`); evolved events (`STAGE-ESM-026`); unsupported expression/enum production conditions (`-006`; supported conditional productions render); legacy reads (`PLAY0271`), protected-read rendering (STAGE-ESM-044 despite v25 admission; semantic Host/executor support is separate); code validation (`-005`); protected identities/enums (`-040`) or unadmitted explicit subject lineage (`PLAY0268`); attached command handlers (PLAY0268), described handlers (v23, STAGE-IMPL-002 even Stub mode), atomic mode (STAGE-ESM-016 for v22, STAGE-ESM-043 in admitted v23–v25) | keep the model; fallback record entry; options a to c in `SKILL.md`; link the Stage issue |
34
+ | **Capability gap** | the intended meaning needs a construct Stage does not render yet | DateTime equality filters and required parameters after optional filters (`-010`); context/single-result filters, opaque `scoped to`/`performer` and a list-query `by` block remain PLAY0268; a read model with several key parts (v27) refuses `STAGE-ESM-016`; Translate, clocks, captures, non-event triggers and opaque reaction bodies (`-024`); claim-reading/opaque `runs as` gates (`-034`), legacy `from` (`-035`), mixed effects in one handler (`-037`, retries can duplicate events; keep it whole), unsupported reaction mappings (`-039`); unsupported generated types/result combinations (`-028`/`-038`); `then no readmodel` (`-027`); evolved events (`STAGE-ESM-026`); unsupported expression/enum production conditions (`-006`; supported conditional productions render); legacy reads (`PLAY0271`), protected-read rendering (STAGE-ESM-044 despite v25 admission; semantic Host/executor support is separate); code validation (`-005`); protected identities/enums (`-040`) or unadmitted explicit subject lineage (`PLAY0268`); attached command handlers (PLAY0268), described handlers (v23, STAGE-IMPL-002 even Stub mode), atomic mode (STAGE-ESM-016 for v22, STAGE-ESM-043 in admitted v23–v26) | keep the model; fallback record entry; options a to c in `SKILL.md`; link the Stage issue |
35
35
  | **Tool skew** | the bundled compiler disagrees with documented semantics | the false `PLAY0285` on reaction cascades from an older bundle; codes the standalone compiler does not raise | record in the session state and the fallback record; never "fix" a correct model |
36
36
  | **Environment** | not the model | restore failures, missing SDK, a destination that is not writable | fix the environment or report blocked |
37
37
 
@@ -219,6 +219,6 @@ empty-list intent is a separate claim from a keyed row being absent (`view-and-s
219
219
  queries are executable too (`ListOpenInvoices` in the backing example); caller-supplied equality filters on collections bind as ESM v14.
220
220
  Pass `by` and filters in query arguments; PLAY0468 reports unknown, repeated or
221
221
  missing required arguments. Optional filters may be omitted, supplied null is refused.
222
- Context-sourced/single-result filters, opaque `scoped to`/`performer`, and composite
223
- `by` remain PLAY0268. Compiled coverage and renderer ceilings:
222
+ Context-sourced/single-result filters, opaque `scoped to`/`performer`, and a list-query
223
+ `by` block remain PLAY0268. Compiled coverage and renderer ceilings:
224
224
  read-surface [equality filters](../../cratis-screenplay-read-surface/references/equality-filters.md).
@@ -18,7 +18,7 @@ Typed example/override forms: `cratis-screenplay-specifications`
18
18
  | `then readmodel` / `then query` (keyed `ById`, `arguments`, `result`) | yes | yes | yes |
19
19
  | `then query` on an unfiltered list or a list narrowed by one `by` key (observable too) | yes | yes: no `arguments` for an unkeyed list, one `result` per row stating the read-model identifier, no `result` = empty list | snapshot and observable lists render |
20
20
  | Collection query with caller-supplied equality `filter`, including observable | yes | yes, ESM v14: same-named scalar property/type, AND with `by`; optional omission allowed, supplied null refused; PLAY0468 checks arguments; row order does not matter | yes on supported snapshot/observable collections; DateTime/filter parameter order refuse -010; independent Stage executor still refuses filtered assertions (-010) |
21
- | Context `from`, single-result filters, `scoped to`, `performer` or composite `by` | yes | PLAY0268: query context, collection-only filtering, opaque scope/implementation or multipart lookup are unadmitted | no |
21
+ | Context `from`, single-result filters, `scoped to`, `performer` or a list-query `by` block | yes | PLAY0268: query context, collection-only filtering, opaque scope/implementation or a multipart list lookup are unadmitted | no |
22
22
  | `then no readmodel <RM> for "<key>"` | yes | yes | no |
23
23
  | `when query` -> `then result` / `then no result` | yes | yes | same as `then query`: only the query-only cases below |
24
24
  | `given clock` / `when clock`, `when trigger`, record-source `given`/`when capture` | yes | yes (standalone and any cratis whose compiler admits v6; an older bundle does not, see toolchain `references/executable-subset.md`) | no |
@@ -34,12 +34,12 @@ Typed example/override forms: `cratis-screenplay-specifications`
34
34
  | Refusal branches, `$refusal` | yes | ESM v19; first matching branch wins | Stage supported subset; -039 for unfaithful refusal details/trigger groups, -011 for specification limits |
35
35
  | Query `then error` | yes | ESM v18; one query/one error, no result/denial | requires target v18 admission; a v19-capable renderer does not necessarily admit v18 |
36
36
  | Composite (JSON) values in specs | yes | yes | no |
37
- | Same-primitive `Date`/`DateTime` comparisons in `require`, `produces when` and command or property validation rules (v26; Requires Screenplay 4.199.0; see [date comparisons](../../cratis-screenplay-command-surface/references/date-comparisons.md)) | spec them | binds and executes; a `DateTime` input without an offset is a Validation rejection | v26 STAGE-ESM-016: gap-fill |
37
+ | Same-primitive `Date`/`DateTime` comparisons in `require`, `produces when` and command or property validation rules (v26; Requires Screenplay 4.199.0; see [date comparisons](../../cratis-screenplay-command-surface/references/date-comparisons.md)) | spec them | binds and executes; a `DateTime` input without an offset is a Validation rejection | Host/executor run it (Requires Stage 4.135.0); renderer STAGE-ESM-046: gap-fill |
38
38
  | Date rules using `today`, `$context`, mixed `Date`/`DateTime`, concept or reaction-`where` positions; nested paths | spec them in design | rule does not bind: `recorded` | `recorded` |
39
39
  | Bodied rules, code policies | spec them | spec reported **unsupported**, never passed | no |
40
40
  | Pending described command handlers (v23) | specify intent | binds; denial/validation execute, body-reaching specs Unsupported ImplementationBody; all-Unsupported is not green | STAGE-IMPL-002 even Stub mode |
41
41
  | Attached command handlers, `file` constraints, query `performer`s | spec them in design | blocked: PLAY0268 at binding, no spec runs (V3 blocked) | no |
42
- | Atomic reaction mode (v22) | declare for new models | failed batch adds no facts or view changes; earlier batches/commands remain; `then error` alone is insufficient | v22 STAGE-ESM-016; mode in admitted v23–v25 STAGE-ESM-043 |
42
+ | Atomic reaction mode (v22) | declare for new models | failed batch adds no facts or view changes; earlier batches/commands remain; `then error` alone is insufficient | v22 STAGE-ESM-016; mode in admitted v23–v26 STAGE-ESM-043 |
43
43
  | Protected command reads (v25) | declare opt-in for eligible reads | absence Validation; matching intervening facts Conflict; race vectors are not a new spec construct | Cratis C# rendering STAGE-ESM-044; semantic Host/executor execute admitted reads, non-Error protected requirements STAGE-ESM-045; v25 pair admitted |
44
44
 
45
45
  Requires Screenplay 4.105.0 or later (`screenplay --version`) for list-query specifications, and 4.143.0 or later for collection equality filters (ESM v14).
@@ -122,7 +122,7 @@ Ask the batch below only for what the request leaves open: (1) origin of each ac
122
122
 
123
123
  - At most one `identifier` per command; never on an event property or read-model property (use `key`). At most one builder per read model (`PLAY0191`). Read `references/read-model-design.md` ("Identifier and key contract") for the exact rules.
124
124
 
125
- - A query's `by` goes on its own body line; `from`, single-result filters, scope, performer and composite `by` remain `PLAY0268`; equality filters on collections bind as ESM v14. Read `references/read-model-design.md` ("Query binding") for the binding rules.
125
+ - A query's `by` goes on its own body line; `from`, single-result filters, scope, performer and a list-query `by` block remain `PLAY0268`; equality filters on collections bind as ESM v14. Read `references/read-model-design.md` ("Query binding") for the binding rules.
126
126
 
127
127
  - A `unique` constraint names a property the event declares directly; the constraint name is
128
128
  its identity (renaming starts an empty index).
@@ -146,7 +146,7 @@ collections, invariants, who sees which rows); report a finding only with a doma
146
146
 
147
147
  ## Public boundaries and view identity
148
148
 
149
- Translate crosses an application boundary (inbound consumes foreign public events; outbound folds private facts into exactly one local public event type); commands never publish public events. Mark view identity with trailing `key`; composite view keys remain unadmitted (`PLAY0268`) - keep the true identity and report the gap. Read [references/public-boundaries-and-keys.md](references/public-boundaries-and-keys.md) when a slice crosses an application boundary or a view needs a composite identity.
149
+ Translate crosses an application boundary (inbound consumes foreign public events; outbound folds private facts into exactly one local public event type); commands never publish public events. Mark view identity with trailing `key`; flat composite view keys bind as ESM v27 (Requires Screenplay 4.204.0) - keep the true identity. Read [references/public-boundaries-and-keys.md](references/public-boundaries-and-keys.md) when a slice crosses an application boundary or a view needs a composite identity.
150
150
 
151
151
  ## Identity-affecting edits on an existing model
152
152
 
@@ -11,6 +11,8 @@ the slice outline and trace every exported field; read automations-and-translati
11
11
  Mark view identity with trailing `key`. Use a composite key for independent view
12
12
  coordinates (resource + period), a natural single id for one entity's state.
13
13
  Supply every named part in single-instance queries and command/trigger reads;
14
- see read-surface `references/named-keys.md`. Composite view keys remain
15
- unadmitted (PLAY0268), unlike admitted composite stream routes.
16
- Keep the true identity and report the gap rather than inventing a concatenated id.
14
+ see read-surface `references/named-keys.md`. Flat composite view keys bind as ESM v27
15
+ (older binders refuse with PLAY0268; compiler requirement in named-keys), as do composite
16
+ stream routes. Command and trigger reads by parts stay refused, and Stage does not admit
17
+ v27. Keep the true identity rather than inventing a concatenated id; choosing between
18
+ shapes: streams-and-consistency `references/read-model-keys.md`.
@@ -327,8 +327,9 @@ module Berths
327
327
  - A query's `by` goes on its own body line. Optional keyed and collection queries
328
328
  bind, including observable delivery. Caller-supplied equality filters on collections
329
329
  bind as ESM v14; `by` ANDs with supplied filters. `from`, single-result
330
- filters, scope, performer and composite `by` remain PLAY0268 for their respective
331
- context/cardinality/opaque/multipart gaps. Read read-surface
330
+ filters, scope, performer and a `by` block on a list query remain PLAY0268 for their
331
+ respective context/cardinality/opaque/multipart gaps. A composite-keyed optional
332
+ single-instance query takes a `by` block naming every part (ESM v27). Read read-surface
332
333
  [equality filters](../../cratis-screenplay-read-surface/references/equality-filters.md).
333
334
 
334
335
  ## Executable identity of a read model
@@ -175,8 +175,9 @@ Use `when append <PrivateEvent>` then `then <PublicEvent>`, not `then readmodel`
175
175
  follow-up events are exhaustive and ordered. Read
176
176
  [publication and fold cases](../cratis-screenplay-automations-and-translations/references/public-events-and-direction.md)
177
177
  when specifying outbound facts or event-source captures: it owns the minimum
178
- compiler, PLAY0700/0701, key folding and Unsupported boundaries. Composite view
179
- fixtures remain unadmitted; see read-surface `references/named-keys.md`.
178
+ compiler, PLAY0700/0701, key folding and Unsupported boundaries. Composite-keyed
179
+ view fixtures state every key part (Requires Screenplay 4.204.0, ESM v27); see
180
+ `references/vocabulary.md` and read-surface `references/named-keys.md`.
180
181
 
181
182
  ## Reusable fixtures, routes and recovery intent
182
183
 
@@ -10,6 +10,10 @@ through their concept's `validate` rules in every ESM version. An omitted option
10
10
  filter is not validated. A violation is a Validation rejection carrying the rule's
11
11
  message; a valid key with no matching instance is absence.
12
12
 
13
+ On a composite-keyed read model every `by` part of a single-instance query is validated
14
+ the same way; an argument that breaks a part's concept rule binds and rejects with
15
+ Validation (Requires Screenplay 4.204.0, ESM v27).
16
+
13
17
  Use exactly one query request and one `then error`, bare or with a message. No
14
18
  command/append/reaction action, result, `then no result` or `then denied` may
15
19
  accompany it (PLAY0465). An actionless `then query` with `arguments` and no `result`
@@ -35,6 +35,23 @@ This reference holds the given/when/then construct table and the enumeration and
35
35
  | `for <value>` | the event source of a `given`/`then` event, or of the `when` command or appended event |
36
36
  | `<property> = <value>` | a literal, `null`, or a one-line JSON-shaped object or list: `lines = [{"sku":"A-1","quantity":2}]` |
37
37
 
38
+ ## Composite-keyed read models
39
+
40
+ Requires Screenplay 4.204.0 (ESM v27; `screenplay --version`); older binders refuse a
41
+ read model with two or more `key` marks, and every specification over it, with PLAY0268.
42
+
43
+ - `given readmodel` and `then readmodel` state every key part (missing part PLAY0351,
44
+ repeated part PLAY0519).
45
+ - `then no readmodel <Type> for {"part":"value",...}` names every part (missing PLAY0661,
46
+ unknown PLAY0662, repeated member PLAY0294).
47
+ - `when query` or `then query … arguments` supplies every `by` part of a single-instance
48
+ query, or the equality filters of a list query (missing, unknown or repeated PLAY0468).
49
+ - A single-instance `then result` may omit parts the arguments supply; list rows state
50
+ every part. A stated part that disagrees with the argument fails to match at run time.
51
+ - Parts match one by one in any order; Uuid parts compare as ordinal text.
52
+
53
+ The complete model with these specifications is in read-surface `references/named-keys.md`.
54
+
38
55
  ## Parse and binding diagnostics
39
56
 
40
57
  PLAY0358 is a syntax error; PLAY0388 also occurs at parse time for extra text
@@ -138,6 +138,8 @@ Requires Chronicle 19.59.6 or later (19.59.3 for the InMemory provider) for the
138
138
 
139
139
  **Modeling defaults** (deviate with a recorded reason)
140
140
  - One business identity per stream; cross-stream references are payload properties.
141
+ - A read model's key is not a stream identity. Read [references/read-model-keys.md](references/read-model-keys.md)
142
+ when choosing one id, flat composite key parts (v27) or a composite-typed key.
141
143
  - Copy the source id into the payload only when a consumer needs it as a value.
142
144
  - Give each invariant an authoritative atomic decision point and inspect every path that could
143
145
  violate it. A constraint violation rejects that command's whole append set; a reaction cascade
@@ -145,7 +147,7 @@ Requires Chronicle 19.59.6 or later (19.59.3 for the InMemory provider) for the
145
147
  - New models declare `reaction batches atomic`: direct productions per trigger
146
148
  occurrence and each selected refusal branch are separate batches; invoked commands
147
149
  stay independent. Legacy absence retains per-fact appends. Stage refuses v22
148
- with STAGE-ESM-016 and atomic mode in admitted v23–v25 with STAGE-ESM-043. Read
150
+ with STAGE-ESM-016 and atomic mode in admitted v23–v26 with STAGE-ESM-043. Read
149
151
  [atomic boundaries](../cratis-screenplay-captures-and-reactions/references/atomic-batches-and-source-mappings.md)
150
152
  when defining failure rollback; batching is not redelivery deduplication.
151
153
  - Match duplicate protection to scope. A property constraint lets a source re-claim its own
@@ -0,0 +1,46 @@
1
+ <!-- Copyright (c) Cratis. All rights reserved. -->
2
+ <!-- Licensed under the MIT license. See LICENSE file in the project root for full license information. -->
3
+
4
+ # Read-model keys: one id, flat parts or a composite-typed key
5
+
6
+ Requires Screenplay 4.204.0 (ESM v27; `screenplay --version`) for a read model with two or
7
+ more `key` marks; older binders refuse it with PLAY0268. A read model with one `key` mark
8
+ keeps its earlier version and bytes.
9
+
10
+ A read model's key says which instance a lookup or projection reaches. It is not a stream
11
+ identity and not an atomic decision point: choose it after the streams, and keep invariants
12
+ in constraints and commands.
13
+
14
+ ## Choose the shape
15
+
16
+ | Business shape | Key | Why |
17
+ | --- | --- | --- |
18
+ | The view is one entity's state | One natural `key` property (default) | Binds on every supported version, and the event source usually supplies it |
19
+ | Independent coordinates identify the view (resource and period, plant and field), read by filtering on some parts or by all parts | Several flat `key` properties (v27) | Each part keeps its name and type; a list narrows by any part with equality filters |
20
+ | One value object already identifies the entity everywhere (it is also a command or event value) | One `key` property whose type is a composite `type` | Executes on earlier versions; projections use a typed `key TypeName` block |
21
+
22
+ A read model has exactly one of the two composite shapes: mixing flat parts with a
23
+ composite-typed key is PLAY0660, though one application may hold read models of both.
24
+ Do not concatenate parts into a string id to avoid a composite key, and do not invent a
25
+ composite type only to carry flat parts: both hide the identity the model should state.
26
+
27
+ ## What flat parts do and do not do
28
+
29
+ - **Equality is per part**, in any order. Uuid parts compare as ordinal text with no case
30
+ folding, so write one spelling of each uuid in events, fixtures and query arguments.
31
+ - **A projection names every part** in an untyped `key` block on each root `from` and
32
+ `remove with`. The parts come from the event payload; they need not match the event
33
+ source. `remove with` deletes one instance and a later `from` recreates it.
34
+ - **A composite key does not enforce uniqueness.** Two events can still claim the same
35
+ part values; use a `unique` constraint over the same properties when the store must
36
+ refuse the duplicate (`references/consistency-and-concurrency.md`).
37
+ - **Lookups.** An optional single-instance query names every part in a `by` block; a list
38
+ uses equality filters. A command or reaction that must read the view by parts is refused
39
+ (PLAY0271, PLAY0781 ByParts, or PLAY0268 for a producing reaction), so decide on a stream
40
+ the command owns instead, or restructure the read. Do not drop the read to bind.
41
+ - **Limits.** Joins, `children`, `nested`, `every`, `all`, `variant` and reducers on the
42
+ composite-keyed view are PLAY0268. Stage refuses v27 with STAGE-ESM-016, so deliver it
43
+ through gap-fill with the model as the contract.
44
+
45
+ Read read-surface `references/named-keys.md` for one complete executable example and the
46
+ projections skill `references/pdl-grammar.md` for the key block syntax.
@@ -101,7 +101,7 @@ changes with the root folder name.
101
101
  - **Executable** (binds, V3): `references/executable-subset.md`. Optional keyed lookups, unfiltered
102
102
  lists and lists narrowed by one `by` key (observable too) bind; caller-supplied equality
103
103
  filters on collections bind as ESM v14. Context `from`, single-result
104
- filters, opaque `scoped to`/`performer` and composite `by` remain PLAY0268. Read
104
+ filters, opaque `scoped to`/`performer` and a `by` block on a list query remain PLAY0268. Read
105
105
  read-surface [equality filters](../cratis-screenplay-read-surface/references/equality-filters.md).
106
106
  Pending handlers beside unconditional productions bind as described commands (v23),
107
107
  but reached bodies are Unsupported; attached handlers remain PLAY0268.
@@ -120,9 +120,10 @@ changes with the root folder name.
120
120
  - **Public contracts and routes (v9/v10/v11):** public contracts and direction select v9;
121
121
  reaction identity, production overrides and observer filters select v10;
122
122
  qualifying retained non-route Double literals select v11.
123
- Composite view keys remain authoring-only (PLAY0268), while one explicit
124
- `key` binds. Read `references/production-routes-and-filters.md` and read-surface
125
- `references/named-keys.md`.
123
+ Flat composite read-model keys select v27 (Requires Screenplay 4.204.0; older binders
124
+ report PLAY0268); one explicit `key` keeps its earlier version. Read
125
+ `references/production-routes-and-filters.md`, [language admission](references/language-admission.md)
126
+ and read-surface `references/named-keys.md`.
126
127
  - **Enum numbers (v12):** read command-surface `references/enum-numbers.md` for
127
128
  pins, stored numbers and Stage output; `references/diagnostics.md` owns PLAY0667–0671.
128
129
  - **Concept strategies (v15):** read
@@ -189,7 +190,7 @@ Read [references/diagnostics.md](references/diagnostics.md) when a PLAY, STAGE o
189
190
  7. Mark read-model identity with trailing `key`, not `identifier`. Otherwise single-instance
190
191
  queries must agree on `by`; only with none and an admitted list query can `*Id`
191
192
  inference run. Queryless views need `key` (read-surface `references/named-keys.md`).
192
- Align projection keys. Multipart keys remain PLAY0268.
193
+ Align projection keys; several parts need an untyped `key` block (v27).
193
194
  8. Projection `key` routes only on `from`; joins never create; `all` is per source.
194
195
  9. `null` only for optional read-model properties in specifications.
195
196
  10. `then` events are exhaustive and ordered; after `when append` they list only what followed.
@@ -28,8 +28,8 @@ keeping the capture in Translate. No automatic split.
28
28
  Requires Screenplay 4.176.0 or later; older compilers leave that shape unchecked.
29
29
  Read
30
30
  [public contracts](../../cratis-screenplay-automations-and-translations/references/public-events-and-direction.md).
31
- View properties use trailing `key`; multipart `by` query/read blocks remain
32
- PLAY0268, not v10. Read [named keys](../../cratis-screenplay-read-surface/references/named-keys.md).
31
+ View properties use trailing `key`; several parts select v27 (not v10), with a `by` block on
32
+ an optional single-instance query and equality filters on lists. Read [named keys](../../cratis-screenplay-read-surface/references/named-keys.md).
33
33
  Production `stream Source.Stream` overrides and reaction/reducer `from Source[.Stream]`
34
34
  select released v10: [routes and filters](production-routes-and-filters.md).
35
35
  Qualifying non-route Double literals select v11;
@@ -49,6 +49,13 @@ a separate `case` names an expansion. Argument order is immaterial.
49
49
  | PLAY0524 | `specification` (declaration), `step` (keyword), `stepIndex` (index), `property`, `type`, `example?`, `case?`, `parameter?` |
50
50
  | PLAY0525, PLAY0526 | `example` |
51
51
  | PLAY0583 | `case?`, `parameter?`, `type?`, `text?` |
52
+ | PLAY0790, PLAY0794, PLAY0799 | `profile`, `template`, `blueprint?` |
53
+ | PLAY0791 | `profile`, `template` (the layout name) |
54
+ | PLAY0792 | `profile`, `template`, `blueprint` |
55
+ | PLAY0793 | `profile`, `template`, `blueprint`, `version` |
56
+ | PLAY0795 | `profile`, `template`, `blueprint?`, `outlet` |
57
+ | PLAY0796 | `profile`, `template`, `blueprint?`, `option` |
58
+ | PLAY0797 | `profile`, `value` |
52
59
 
53
60
  For PLAY0524, `step` is given, given readmodel, when, when append or then.
54
61
  `stepIndex` counts every authored given/when/then clause once across all forms,
@@ -11,6 +11,7 @@
11
11
  - Caller identity, compliance and routes
12
12
  - Specification metadata, callers, cases and locators
13
13
  - Guarded interaction diagnostics
14
+ - UI profile shell: root template, options, appearance
14
15
  - Structural completeness and timeline checks
15
16
  - Editor versus C# verdicts
16
17
  - Consistency errors (V1: the model contradicts itself)
@@ -136,9 +137,11 @@ Target evidence: a renderer must admit ESM v16 and preserve `storedName`, or ref
136
137
  | PLAY0665 | E | Invalid/duplicate/child-bearing/unresolved source/stream filter or filtered reaction with a non-event trigger |
137
138
  | PLAY0666 | W | Filter excludes all statically known effective producer routes; C# only, handlers/foreign origins suppress it |
138
139
 
139
- Queries and trigger reads have no PLAY0661 repair. Composite view keys, query
140
- blocks and their fixtures remain PLAY0268, while one explicit key binds
141
- byte-identically to inference. Fixtures missing any part report PLAY0351.
140
+ Queries and trigger reads have no PLAY0661 repair. Flat composite view keys bind as v27;
141
+ projection or removal key blocks missing a part report PLAY0661 and bad parts PLAY0662.
142
+ One explicit key binds byte-identically to inference. Fixtures missing any part
143
+ report PLAY0351. Joins, children, `every`, `all`, `nested`, `variant`, reducers and
144
+ list-query `by` blocks over a composite-keyed view are PLAY0268.
142
145
  Overrides/filters select released ESM v10; malformed routes also use PLAY0504.
143
146
  Read read-surface `references/named-keys.md` and
144
147
  [production routes and filters](production-routes-and-filters.md).
@@ -248,6 +251,26 @@ comment loss and do not support pinned evidence. TypeScript diagnoses but does
248
251
  not offer these repairs. Preview through MCP `propose-repair`, never text-patch
249
252
  around a refusal. Condition/subject errors also use guarded-action PLAY0341–0348.
250
253
 
254
+ ## UI profile shell: root template, options, appearance
255
+
256
+ Requires Screenplay 4.200.0 or later (`screenplay --version`); 4.197.0 reads the syntax without the checks. The fix for each is in
257
+ `../../cratis-screenplay-ui-composition/references/ui-profile-and-theme.md`.
258
+
259
+ | Code | Severity | Meaning / fix |
260
+ | --- | --- | --- |
261
+ | PLAY0788 | E | A `root template` / `new screens use template` line is malformed, or pins a version on an own template. |
262
+ | PLAY0789 | E | A malformed or repeated `appearance` line, or a second `appearance` block. |
263
+ | PLAY0790 | E | The template is not declared (or the blueprint does not ship it). Declare it or take it from a blueprint. |
264
+ | PLAY0791 | W | The profile selects its shell with the legacy `layout <Name>`. Write `root template <Name>`; the quick fix rewrites it (or removes the ignored line beside a `root template`). |
265
+ | PLAY0792 | E | The blueprint is not in the profile's `packages` (or not installed). |
266
+ | PLAY0793 | W | The pinned `version` range is not satisfied by the installed blueprint (catalog hosts only). |
267
+ | PLAY0794 | E | The root template cannot be the shell (not a layout or application-scope template, fits a slot, `scopes` without `application`). |
268
+ | PLAY0795 | E | The root template has no `content` slot. |
269
+ | PLAY0796 | W | An `option` the shell does not expose. |
270
+ | PLAY0797 | E | Color scheme is not `light`, `dark` or `system`, or the accent is not a hex colour. |
271
+ | PLAY0798 | E | More than one `root template` in a profile. |
272
+ | PLAY0799 | E | `new screens use template` cannot start a screen in a feature. |
273
+
251
274
  ## Structural completeness and timeline checks
252
275
 
253
276
  Opt in with `--check <names>` or MCP diagnostics `checks`, then treat warnings
@@ -325,15 +348,16 @@ refusal reasons. Read [language admission](language-admission.md) before changin
325
348
  | PLAY0785 | Ambiguous view path; use distinct aliases on repeated reads |
326
349
  | PLAY0786 (I) | Eligible legacy model; preview typed preamble repair, individually review absence/conflict semantics |
327
350
  | PLAY0787 (W) | Exact deprecated Studio text-rule pattern; repair to literal rule or equality, preserving message/severity |
328
- | STAGE-ESM-043 | Atomic mode not realized, even in admitted v23–v25; retain declaration and gap-fill |
351
+ | STAGE-ESM-043 | Atomic mode not realized, even in admitted v23–v26; retain declaration and gap-fill |
329
352
  | STAGE-ESM-044 | Cratis C# renderer refuses protected reads despite v25 admission; semantic Host/executor support is separate; keep protection and gap-fill generated-app scope |
330
353
  | STAGE-ESM-045 | Non-Error protected requirement; semantic Host/executor refuse before execution, including reaction-invoked commands; keep severity and report Unsupported |
331
354
  | STAGE-IMPL-002 | Described handler body not realized by Stage, even Stub mode; no stubs emitted |
332
355
 
333
356
  Invalid match syntax remains PLAY0367. Property/concept text rules bind v24;
334
357
  `contains`/`starts with` in conditions only still fail PLAY0268. Stage rejects
335
- v22/v26 and mixed pairs with STAGE-ESM-016; v23–v25 admission does not implement
336
- bodies, batches or rendered protected reads (STAGE-ESM-044). Requires Stage 4.129.0
358
+ v22/v27 and mixed pairs with STAGE-ESM-016; v23–v26 admission does not implement
359
+ bodies, batches or rendered protected reads (STAGE-ESM-044), and the renderer refuses
360
+ v26 date comparisons with STAGE-ESM-046. Requires Stage 4.129.0
337
361
  for semantic Host/executor protected reads; older engines refuse -044. Read
338
362
  [language admission](language-admission.md) for the stricter Host outside-append guard.
339
363
 
@@ -11,6 +11,7 @@
11
11
  - Generated values and responses (ESM v7)
12
12
  - Released public boundaries and observer routes
13
13
  - Chronological command date comparisons (ESM v26)
14
+ - Flat composite read-model keys (ESM v27)
14
15
  - Code attachments (what binds, what never does)
15
16
  - Refused (code, reason): fix, or record as a mode gap
16
17
  - Not refused, but do not rely on it
@@ -41,7 +42,7 @@ Complete examples that bind live in `executable-example.md`, `pdl-example.md` (p
41
42
  `automation-translate-example.md` (ESM v6) and `generated-responses-example.md` (ESM v7).
42
43
 
43
44
  For atomic batches (v22), described handlers (v23), ordinal text rules (v24) and
44
- protected reads (v25) and chronological command dates (v26), read
45
+ protected reads (v25), chronological command dates (v26) and composite keys (v27), read
45
46
  [language admission](language-admission.md). A later
46
47
  version alone does not enable either application opt-in.
47
48
 
@@ -86,10 +87,10 @@ Requires Screenplay 4.141.0 or later (`screenplay --version`) to bind concept co
86
87
  none supplies identity and an admitted list query exists does conventional
87
88
  `*Id` inference run (collection-key exclusions: read-surface `references/named-keys.md`).
88
89
  Queryless read models need an explicit `key`. Explicit single keys preserve
89
- equivalent inferred ESM bytes. Composite read-model keys, query `by` blocks and
90
- their fixtures remain PLAY0268. Collections and observable delivery bind.
90
+ equivalent inferred ESM bytes. Flat composite read-model keys bind as v27
91
+ (see below). Collections and observable delivery bind.
91
92
  Caller-supplied equality filters on collections also bind as ESM v14; context
92
- sources, single-result filters, scope, performer and composite `by` remain blocked.
93
+ sources, single-result filters, scope, performer and a list-query `by` block remain blocked.
93
94
  - One projection per read model: `from`, `every`, `all` (one block per level), `join`,
94
95
  `children`, `nested`, `remove with`, `remove via join` (binds; blocks the execution plan at the projection level, see below), `clear with`, counters, `add`,
95
96
  `subtract`, `set`, `clear`, variants, and the identifier mapped from the projection's key (`xId = $eventSourceId` only for an event-source key).
@@ -264,15 +265,36 @@ DateTime input needs an offset or `Z`, else Validation rejects before rules, eve
264
265
  for skipped comparisons. `then` matching stays ordinal. Invalid date literals or
265
266
  offset-less DateTime literals in admitted comparisons report PLAY0273. Read
266
267
  [date comparisons](../../cratis-screenplay-command-surface/references/date-comparisons.md)
267
- for the complete window model and retained PLAY0268 refusals. Stage refuses v26
268
- with STAGE-ESM-016, independently of standalone binding/reference execution.
268
+ for the complete window model and retained PLAY0268 refusals. The Stage renderer refuses
269
+ v26 date comparisons with STAGE-ESM-046, independently of standalone binding/reference execution.
270
+
271
+ ## Flat composite read-model keys (ESM v27)
272
+
273
+ Requires Screenplay 4.204.0 (ESM v27; `screenplay --version`); older binders refuse a
274
+ read model with two or more `key` marks with PLAY0268. Binding admits a model with
275
+ several flat scalar key parts when:
276
+
277
+ - root `from` and `remove with` blocks name every part in an untyped `key` block;
278
+ - a list query narrows with equality filters, and an optional single-instance query
279
+ names every part in a `by` block;
280
+ - fixtures state every part (`given readmodel`, `then readmodel`, `then no readmodel`).
281
+
282
+ Models with one `key` mark keep their earlier version and bytes. Refused with PLAY0268:
283
+ joins, `children`, `remove via join`, `every`, `all`, `nested`, `clear with`, `variant`
284
+ and reducers on the composite-keyed read model, a list query with a `by` block, a
285
+ non-optional single-instance return, and command reads (PLAY0271, or PLAY0781
286
+ ByParts under `command reads protected`) or trigger reads that produce directly.
287
+ Stage refuses v27 with STAGE-ESM-016, independently of standalone binding and
288
+ reference execution. Read read-surface
289
+ [named keys](../../cratis-screenplay-read-surface/references/named-keys.md) for the
290
+ complete example.
269
291
 
270
292
  ## Code attachments (what binds, what never does)
271
293
 
272
294
  Pending `handler implementation` beside unconditional `produces` binds as a described
273
295
  command (v23). Its payload-only body returns Unsupported ImplementationBody when reached;
274
296
  denial/validation specs still run. Read [language admission](language-admission.md) for
275
- v22–v26 and [described handlers](../../cratis-screenplay-command-surface/references/described-handlers.md)
297
+ v22–v27 and [described handlers](../../cratis-screenplay-command-surface/references/described-handlers.md)
276
298
  for the result contract. Attached handlers remain unbound.
277
299
 
278
300
  Inline fences (`csharp`, `typescript`, `react`, `html`, `sql`) and `file <path>` attach
@@ -316,7 +338,7 @@ bodies still leave their owner non-executable.
316
338
  | `Automation` or `Translate` slice, `reaction`, `capture`, `trigger`; `given clock`, `when clock`, `when trigger`, `when capture` | PLAY0268 | **older bundled compilers only**; current compilers bind them (ESM v6) |
317
339
  | Unquoted `import Other.Contract` | PLAY0268 | external contract import is not bound |
318
340
  | `pii` or `secret` on a concept | PLAY0268 | Older compilers refuse it outright. Current compilers admit v13 except enum/identity compliance and events mixing personal or explicitly subject-scoped secret values with explicit subject marks; see `compliance.md` in command-surface references |
319
- | `query` with a composite `by` block, or `by ... from` context-derived arguments | PLAY0268 | composite `by` blocks remain unadmitted. An optional scalar snapshot lookup, an unfiltered list (`RM[]`) and a list narrowed by one caller-supplied `by` key bind, in their `observable` form too |
341
+ | `query` with a `by` block over a list, or `by ... from` context-derived arguments | PLAY0268 | a `by` block binds only on an optional single-instance query (v27). An optional scalar snapshot lookup, an unfiltered list (`RM[]`) and a list narrowed by one caller-supplied `by` key bind, in their `observable` form too |
320
342
  | Context `from`, single-result filters, `scoped to`, `performer` queries | PLAY0268 | Typed query context, filtering of single results, opaque scope and query implementation remain unadmitted; each refusal names its reason. Caller-supplied collection equality filters bind as v14. `observable` goes in the return position (`=> observable RM[]`); as a body line it is PLAY0048 |
321
343
  | `contains` or `starts with` in conditions only | PLAY0268 | conditions admit scalar equality and numeric ordering, plus same-primitive command date comparisons from v26; property/concept text rules bind as v24 |
322
344
  | Date comparisons with mixed primitives, `$context` (including occurred), `today`, protected read paths, optional condition operands, concept rules or reaction `where` | PLAY0268 | v26 admits only command conditions and command/property literal validation rules |
@@ -338,7 +360,7 @@ bodies still leave their owner non-executable.
338
360
  | `generated` or `returns` on an older compiler | PLAY0268 | admitted from ESM v7, see above |
339
361
  | Operations or systems, `numbers exact` source mode | PLAY0268 | not admitted by any supported ESM version; one such construct leaves the **whole** application without an executable model. Event sources/streams/routes instead bind as ESM v8 on the current compiler (`sources-and-streams.md`) |
340
362
  | Spec of a gated command or query without `given caller` | PLAY0389 | module and feature gates count |
341
- | `given` or `then readmodel` missing key parts | PLAY0351 | explicit `key` marks replace inference; composite fixtures need every part but remain unadmitted |
363
+ | `given` or `then readmodel` missing key parts | PLAY0351 | explicit `key` marks replace inference; composite fixtures need every part (v27) |
342
364
  | When-less spec asserting events or errors | PLAY0352 | |
343
365
  | `null` in command or event values | PLAY0350 | Chronicle semantics, not only a binder limit: an optional fact is a separate event (nullable event properties are CHR0012) |
344
366
  | `for` with no unambiguous destination type | PLAY0273 | |
@@ -1,7 +1,7 @@
1
1
  <!-- Copyright (c) Cratis. All rights reserved. -->
2
2
  <!-- Licensed under the MIT license. See LICENSE file in the project root for full license information. -->
3
3
 
4
- # Language admission: batches, described bodies, text, reads and dates
4
+ # Language admission: batches, described bodies, text, reads, dates and composite keys
5
5
 
6
6
  Select the highest version required by constructs in the model. A newer version
7
7
  alone never opts into either application mode. Consumers must explicitly admit
@@ -9,11 +9,12 @@ exact language/semantic pairs; binding, reference execution and rendering are se
9
9
 
10
10
  | ESM | Selecting construct | Binding/reference behavior | Stage boundary |
11
11
  | --- | --- | --- | --- |
12
- | v22 | Application-root `reaction batches atomic` | Direct productions per trigger occurrence and each selected refusal branch are separate atomic batches; commands remain independent | v22 refused STAGE-ESM-016; mode in admitted v23–v25 refused STAGE-ESM-043 |
12
+ | v22 | Application-root `reaction batches atomic` | Direct productions per trigger occurrence and each selected refusal branch are separate atomic batches; commands remain independent | v22 refused STAGE-ESM-016; mode in admitted v23–v26 refused STAGE-ESM-043 |
13
13
  | v23 | Pending `handler implementation` beside unconditional `produces` | Payload-only body; PLAY0695 information; reaching body gives Unsupported ImplementationBody | v23 admitted, body refused STAGE-IMPL-002 in renderer/Host/executor, even Stub mode |
14
14
  | v24 | `contains`, `not contains`, `starts with`, `ends with` property/concept rules | Ordinal UTF-16, absent optional passes; not text-condition operators | v24 admitted; semantic Host/executor and generated ordinal comparisons preserve rules |
15
15
  | v25 | Application-root `command reads protected` | Admitted reads in requirements/mappings, absence Validation, matching decide/commit changes Conflict | v25 admitted; Cratis C# renderer refuses STAGE-ESM-044; semantic Host/executor execute reads, non-Error protected requirements refuse STAGE-ESM-045 |
16
- | v26 | Chronological command Date/DateTime comparisons | Same-primitive `==`, `!=`, `>`, `>=`, `<`, `<=`; DateTime UTC ticks and pre-rule offset validation | v26 refused STAGE-ESM-016 |
16
+ | v26 | Chronological command Date/DateTime comparisons | Same-primitive `==`, `!=`, `>`, `>=`, `<`, `<=`; DateTime UTC ticks and pre-rule offset validation | v26 admitted; Host/executor run it, renderer and legacy engines refuse STAGE-ESM-046 |
17
+ | v27 | A read model with two or more `key` marks | Untyped projection `key` blocks, equality-filter lists, single-instance `by` blocks, per-part fixtures | v27 refused STAGE-ESM-016 |
17
18
 
18
19
  Requires Screenplay 4.181.0 or later (`screenplay --version`) for atomic batches; older compilers cannot admit the preamble.
19
20
 
@@ -25,6 +26,8 @@ Requires Screenplay 4.193.0 or later (`screenplay --version`) for protected read
25
26
 
26
27
  Requires Screenplay 4.199.0 (ESM v26; `screenplay --version`) for date comparisons; older binders report PLAY0268.
27
28
 
29
+ Requires Screenplay 4.204.0 (ESM v27; `screenplay --version`) for composite read-model keys; older binders report PLAY0268.
30
+
28
31
  Requires Stage 4.124.0 for v24 text-rule admission (`cratis --version` identifies the CLI bundle); older renderers refuse v24 with STAGE-ESM-016. V23 admission alone does not implement described bodies.
29
32
 
30
33
  Requires Stage 4.127.0 for v25 version admission; older renderers refuse v25 with STAGE-ESM-016. The Cratis C# renderer still refuses protected reads with STAGE-ESM-044; no artifacts are emitted.
@@ -56,8 +59,15 @@ positions, invalid date literals or offset-less DateTime literals use PLAY0273.
56
59
  Read [date comparisons](../../cratis-screenplay-command-surface/references/date-comparisons.md)
57
60
  for the complete interval example and input/target boundaries.
58
61
 
59
- Stage's semantic engines admit exact v1–v21 and v23–v25 pairs. V22/v26 and mixed
60
- pairs refuse STAGE-ESM-016. Admission of v23–v25 is not admission of described bodies,
62
+ For v27, read read-surface [named keys](../../cratis-screenplay-read-surface/references/named-keys.md)
63
+ for the one complete example and every refusal. Only a model with a read model of two or
64
+ more key parts selects v27; one `key` mark keeps its earlier version and bytes. To see the
65
+ selected version, open the model with the `screenplay` MCP server and call `read-workspace`
66
+ with `view` `executable-model`: `languageVersion` reads `27.0`.
67
+
68
+ Stage's semantic engines admit exact v1–v21 and v23–v26 pairs. V22/v27 and mixed
69
+ pairs refuse STAGE-ESM-016. Requires Stage 4.135.0 for v26 admission; older Stage
70
+ refuses v26 with STAGE-ESM-016. Admission of v23–v26 is not admission of described bodies,
61
71
  atomic mode or rendered protected reads. A CLI may bundle an older compiler/Stage pair: run no-write render
62
72
  admission rather than transferring a standalone verdict. Pattern diagnostics arise
63
73
  in Screenplay before rendering; diagnostic arguments add no ESM version or new tool.
@@ -5,7 +5,7 @@
5
5
 
6
6
  Use these forms when writing or reviewing `.play`. Acceptance of an older
7
7
  spelling is not a recommendation to teach it. Information diagnostics do not
8
- fail `--warnaserror`; the corpus verification gate rejects the eleven style codes
8
+ fail `--warnaserror`; the corpus verification gate rejects the twelve style codes
9
9
  below even when a fence declares `expect`, unless an exact, reasoned migration
10
10
  exception exists in the verifier's preferred-syntax allowlist. That allowlist also
11
11
  covers deliberate legacy explanations in prose; stale entries fail.
@@ -24,6 +24,7 @@ covers deliberate legacy explanations in prose; stale entries fail.
24
24
  | Interaction guard | Block-form `when` alternatives | Opaque interaction `where` on click, double click or select | PLAY0564 (warning or information) |
25
25
  | Projection transition cardinality | Source binding emits `One` | Constructed/deserialized ESM v1–v3 `ZeroOrOne` / `Many` | PLAY0445 (warning; ESM-only, not a source spelling) |
26
26
  | Command decision reads | `command reads protected` after reviewing every read's admission, absence and conflict semantics | Eligible legacy command reads without the application-root preamble | PLAY0786 (information; individual typed repair review, never fix-all) |
27
+ | Profile shell | `root template <Name>` in a `ui profile` | `layout <Name>` in a `ui profile` | PLAY0791 (warning; quick fix) |
27
28
  | Literal text rules | `starts with`, `ends with`, `contains`, `not contains` or equality, preserving message and severity | Exact deprecated Studio `matches` shapes | PLAY0787 (warning; not arbitrary regex rewriting) |
28
29
 
29
30
  `query Q => observable?` is not a legacy optional type suffix and has no keyword
@@ -103,7 +103,7 @@ and wrong source/stream, and unrouted input. Read [specification route forms](so
103
103
 
104
104
  ESM v10 carries reaction system identity, production route overrides and observer filters as one
105
105
  frozen contract. A consumer admitting v10 must include all three, not just identity.
106
- Composite **read-model** keys are separate and remain unadmitted (PLAY0268).
106
+ Composite **read-model** keys are separate and select v27 (`language-admission.md`).
107
107
 
108
108
  The CLI/Stage pair admits through its newest version to construct checks: production overrides
109
109
  still refuse STAGE-ESM-036; reaction/reducer filters render on the semantic path,
@@ -21,9 +21,9 @@ and concept compliance (v13) render.
21
21
 
22
22
  ## Current admission
23
23
 
24
- Stage admits exact ESM v1–v21 and v23–v25 pairs; v22/v26 and mixed pairs
24
+ Stage admits exact ESM v1–v21 and v23–v26 pairs; v22/v27 and mixed pairs
25
25
  refuse STAGE-ESM-016. Chronological command Date/DateTime comparisons select v26:
26
- standalone binding/reference execution does not make them renderable. Keep the
26
+ the Host and executor run them, but the renderer refuses STAGE-ESM-046, so they are not renderable. Keep the
27
27
  rule and use authorized gap-fill. Version admission is separate from construct support.
28
28
  Requires Stage 4.106.0 for v18 admission; older Stage refuses it with `STAGE-ESM-016`.
29
29
  For generated-concept v20/v21 admission and construct prerequisites, read
@@ -46,7 +46,7 @@ This table is a reading of the renderer's admission, not a render result: run th
46
46
  | Area | Renders | Refused (code) |
47
47
  | --- | --- | --- |
48
48
  | Slice kinds | `StateChange`, `StateView`, supported event-triggered `Automation` with Chronicle reactors | Translate, captures, non-event triggers, opaque bodies, clock/trigger/capture specs (`-024`); claim-reading/opaque `runs as` gates (`-034`), mixed effects from one handler (`-037`, redelivery can duplicate events), unsupported conditions/destinations/mappings (`-039`). Keep refused reactions whole |
49
- | Queries | optional keyed snapshot lookups; snapshot or observable collections, keyed or unkeyed, with v14 equality filters | context/single-result filters, opaque `scoped to`/`performer` and composite `by`: PLAY0268. DateTime filters and required parameters after optional filters refuse `-010`; filter-name collisions refuse `-012`; concept arguments retain Arc validation, including nested members/elements; nullable keys or optional concept filters with `not empty` refuse `-010` rather than changing null behavior |
49
+ | Queries | optional keyed snapshot lookups; snapshot or observable collections, keyed or unkeyed, with v14 equality filters | context/single-result filters, opaque `scoped to`/`performer` and a list-query `by` block: PLAY0268; v27 composite keys: STAGE-ESM-016. DateTime filters and required parameters after optional filters refuse `-010`; filter-name collisions refuse `-012`; concept arguments retain Arc validation, including nested members/elements; nullable keys or optional concept filters with `not empty` refuse `-010` rather than changing null behavior |
50
50
  | Authorization | role-only, authenticated, opaque pure policies, claim conditions with Uuid, Date, DateTime or text targets (numeric and Boolean claim matches render as always false), `not`/and/or; roles read through the identity's `RoleClaimType` | role-claim URIs, nested opaque policies, unresolved or non-portable policies, no single identifier, opaque-policy subjects that are not text, Uuid, Date or DateTime (`STAGE-ESM-015`, a restriction separate from declarative claim targets) |
51
51
  | Event sources, streams, routes (ESM v8) | rendered, including routed read-model/query companion replay | reserved stored names, unformattable routed fixtures (`STAGE-ESM-030`) |
52
52
  | Numbers, case tables | whole numbers as `long` from ESM v8; case tables | out-of-`int` literals below v8 (`STAGE-ESM-031`) |