@cratis/pi 7.75.0 → 7.77.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 (88) hide show
  1. package/package/corpus/harnesses/copilot/instructions/authoring-skills.instructions.md +2 -0
  2. package/package/corpus/harnesses/copilot/instructions/capability-is-not-authority.instructions.md +4 -0
  3. package/package/corpus/harnesses/copilot/instructions/efcore.instructions.md +2 -0
  4. package/package/corpus/harnesses/copilot/instructions/vertical-slices.instructions.md +6 -4
  5. package/package/corpus/product-sync.json +14 -14
  6. package/package/corpus/rules/authoring-skills.md +2 -0
  7. package/package/corpus/rules/capability-is-not-authority.md +4 -0
  8. package/package/corpus/rules/efcore.md +2 -0
  9. package/package/corpus/rules/general.md +1 -0
  10. package/package/corpus/rules/vertical-slices.md +6 -4
  11. package/package/corpus/skills/cratis-application-react-specifications/SKILL.md +4 -4
  12. package/package/corpus/skills/cratis-application-slice-specifications/SKILL.md +1 -1
  13. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authorization.md +9 -0
  14. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/observable-emission-guards.md +12 -3
  15. package/package/corpus/skills/cratis-arc-command/references/decisions-and-routing.md +11 -0
  16. package/package/corpus/skills/cratis-arc-command-execution/SKILL.md +3 -0
  17. package/package/corpus/skills/cratis-arc-command-execution/references/occurrence-commands.md +78 -0
  18. package/package/corpus/skills/cratis-arc-command-validation/SKILL.md +11 -37
  19. package/package/corpus/skills/cratis-arc-command-validation/references/input-binding.md +49 -0
  20. package/package/corpus/skills/cratis-arc-command-validation/references/read-model-resolution.md +25 -0
  21. package/package/corpus/skills/cratis-arc-command-validation/references/validation-severity.md +21 -0
  22. package/package/corpus/skills/cratis-arc-ef-core-migration/SKILL.md +7 -1
  23. package/package/corpus/skills/cratis-arc-hosting/SKILL.md +3 -0
  24. package/package/corpus/skills/cratis-arc-hosting/references/connection-resolution.md +61 -0
  25. package/package/corpus/skills/cratis-arc-query-kotlin/SKILL.md +1 -1
  26. package/package/corpus/skills/cratis-arc-query-paging/SKILL.md +4 -2
  27. package/package/corpus/skills/cratis-arc-query-typescript/SKILL.md +1 -1
  28. package/package/corpus/skills/cratis-arc-react-page/references/queries-and-commands.md +14 -1
  29. package/package/corpus/skills/cratis-arc-validation-kotlin/SKILL.md +1 -1
  30. package/package/corpus/skills/cratis-arc-validation-typescript/SKILL.md +1 -1
  31. package/package/corpus/skills/cratis-chronicle-client-dotnet/SKILL.md +5 -0
  32. package/package/corpus/skills/cratis-chronicle-client-dotnet/references/immediate-append-refusal.md +40 -0
  33. package/package/corpus/skills/cratis-chronicle-client-dotnet/references/lifecycle.md +4 -0
  34. package/package/corpus/skills/cratis-chronicle-client-dotnet/references/occurrences.md +89 -0
  35. package/package/corpus/skills/cratis-chronicle-client-dotnet/references/pinned-generation-delivery.md +33 -3
  36. package/package/corpus/skills/cratis-chronicle-client-elixir/SKILL.md +1 -1
  37. package/package/corpus/skills/cratis-chronicle-client-kotlin/SKILL.md +1 -1
  38. package/package/corpus/skills/cratis-chronicle-client-typescript/SKILL.md +1 -1
  39. package/package/corpus/skills/cratis-chronicle-decision-reads/SKILL.md +5 -2
  40. package/package/corpus/skills/cratis-chronicle-decision-reads/references/admission-and-ownership.md +18 -1
  41. package/package/corpus/skills/cratis-chronicle-event-type-migration/references/pinned-generations.md +6 -0
  42. package/package/corpus/skills/cratis-chronicle-hosting/SKILL.md +3 -0
  43. package/package/corpus/skills/cratis-chronicle-hosting/references/operations.md +26 -0
  44. package/package/corpus/skills/cratis-chronicle-hosting/references/storage-resolution.md +55 -0
  45. package/package/corpus/skills/cratis-chronicle-multi-tenancy/SKILL.md +3 -0
  46. package/package/corpus/skills/cratis-chronicle-multi-tenancy/references/remove-namespace.md +38 -0
  47. package/package/corpus/skills/cratis-chronicle-projection/references/definition-changes.md +26 -0
  48. package/package/corpus/skills/cratis-chronicle-projection/references/model-bound-attributes.md +8 -0
  49. package/package/corpus/skills/cratis-chronicle-reactor/SKILL.md +5 -22
  50. package/package/corpus/skills/cratis-chronicle-reactor/references/starting-and-replaying.md +33 -0
  51. package/package/corpus/skills/cratis-chronicle-read-model/SKILL.md +9 -2
  52. package/package/corpus/skills/cratis-chronicle-read-model/references/queries.md +9 -4
  53. package/package/corpus/skills/cratis-chronicle-reducer/SKILL.md +4 -0
  54. package/package/corpus/skills/cratis-multi-service-architecture/SKILL.md +9 -3
  55. package/package/corpus/skills/cratis-performance-review/SKILL.md +4 -1
  56. package/package/corpus/skills/cratis-screenplay-automations-and-translations/SKILL.md +2 -2
  57. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/realization-and-gap-fill.md +10 -2
  58. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/SKILL.md +9 -9
  59. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/atomic-batches-and-source-mappings.md +2 -2
  60. package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +11 -11
  61. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +9 -0
  62. package/package/corpus/skills/cratis-screenplay-model-authoring/references/model-notes.md +41 -23
  63. package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +8 -3
  64. package/package/corpus/skills/cratis-screenplay-projections/SKILL.md +19 -12
  65. package/package/corpus/skills/cratis-screenplay-projections/references/pdl-grammar.md +37 -2
  66. package/package/corpus/skills/cratis-screenplay-projections/verification.json +11 -0
  67. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/SKILL.md +37 -40
  68. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/gap-fill-handoff.md +3 -2
  69. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/renderability-gate.md +1 -1
  70. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/verification.json +4 -2
  71. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/coverage-matrix.md +9 -0
  72. package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +13 -30
  73. package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +39 -6
  74. package/package/corpus/skills/cratis-screenplay-toolchain/references/executable-subset.md +5 -2
  75. package/package/corpus/skills/cratis-screenplay-toolchain/references/language-admission.md +15 -5
  76. package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +7 -4
  77. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +12 -1
  78. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
  79. package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +9 -2
  80. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +38 -56
  81. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +23 -13
  82. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/date-comparisons.md +44 -0
  83. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/rendered-application.md +8 -2
  84. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/sandbox-and-specrunner.md +59 -8
  85. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/verification.json +7 -3
  86. package/package/corpus/skills/guiding-refactoring-with-code-health/SKILL.md +1 -1
  87. package/package/corpus/skills/safeguarding-ai-generated-code/SKILL.md +1 -1
  88. package/package.json +1 -1
@@ -5,6 +5,8 @@
5
5
  - Grammar
6
6
  - Parser regexes
7
7
  - Diagnostics
8
+ - Event scope
9
+ - Projection-level directives
8
10
  - Syntax that parses but means something else
9
11
  - Flat composite read-model keys
10
12
  - Worked examples
@@ -147,20 +149,53 @@ LiteralKeyword = "literal", " ", Literal ; (* parsed at the Expr level *)
147
149
  | `PLAY0191` | A read model is built by more than one projection or reducer |
148
150
  | `PLAY0192` | A read model is declared more than once |
149
151
  | `PLAY0295`–`PLAY0299` | An `$eventContext` path the event-context catalog does not have; `PLAY0299` also warns when a dynamic dictionary key uses a `$` source other than `$eventContext` |
150
- | `PLAY0380` | Chronicle drops part of a construct: `all` below the top level, or `automap` on a joined event |
152
+ | `PLAY0380` | Only `all` inside `children`/`nested`: loses its subscription to every event type and behaves as `every` |
151
153
  | `PLAY0381` | A projection-level `key` routes no event |
152
154
  | `PLAY0382`–`PLAY0385` | Variant errors: no `enters on`, shared mapping missing on a variant, duplicate variant name, entering event claimed twice |
153
155
  | `PLAY0397` | Inline code uses a language line instead of a tagged fence |
154
156
  | `PLAY0398` / `PLAY0399` | A reducer mixes bodied and body-less rules / observes one event twice |
155
157
 
158
+ ## Event scope
159
+
160
+ Requires Screenplay 4.212.3 (`screenplay --version`) for the ordinary compilation
161
+ error `PLAY0801` (`DuplicateEventInProjectionScope`) in both compilers; older
162
+ executable binding rejected duplicate uses later with `PLAY0273`.
163
+
164
+ A level is the projection root, one `children` block, one `nested` block or one
165
+ variant. Within that level, `from` (including each event in `from A, B` lists),
166
+ `remove with`, `remove via join` and `clear with` share one set of event names.
167
+ All `join` events at that level share a separate set: an event may occur once in
168
+ `from` and once in a join, but not twice in either set. Each children, nested and
169
+ variant block starts fresh sets; separate projections are independent.
170
+
171
+ The check compares authored event names ordinally, without resolving
172
+ qualifications or generations. It reports the second and each later reference;
173
+ identical or different keys do not change the rule. One event cannot update two
174
+ rows of the same level through two `from` blocks with different keys. Combine
175
+ mappings for the same row into one block. Only a genuinely second domain fact
176
+ warrants another event; never invent events only to satisfy the read side.
177
+ These scope checks do not establish executable or renderer admission.
178
+
179
+ ## Projection-level directives
180
+
181
+ `description "..."` (or a fenced text block) on the projection header (report-only `PLAY0270`; variants
182
+ and nested blocks take none), `no automap`, `sequence <name>`, `file <path>`. `sequence` is a realization
183
+ concern and does not bind to the executable model. A mapping target may end in a dynamic dictionary
184
+ key, `count eventCountByType.$eventContext.eventType.id` (one entry per distinct value); only
185
+ `$eventContext` resolves there, any other `$` text is a literal key with warning `PLAY0299`.
186
+
156
187
  ## Syntax that parses but means something else
157
188
 
189
+ An `automap` / `no automap` under a joined event (`with …`) is honored for that
190
+ event alone; without one, it follows its level's auto-map. Requires Screenplay
191
+ 4.212.4 (`screenplay --version`) for executable binding; older binders replace the
192
+ joined event's setting with the level's. It does not report `PLAY0380`.
193
+
158
194
  | Syntax | What Chronicle and the executable model do |
159
195
  | --- | --- |
160
196
  | `key` on the projection | Nothing: events route by the `from` key, then the event source id (`PLAY0381`) |
161
197
  | `from X` with no key | Routes by the event source id, never by another `from`'s key |
162
198
  | `join … on …` | Updates existing instances only; never creates one; the name after `join` is discarded |
163
- | `automap` under a joined event | Replaced by the auto-map of the join's level (`PLAY0380`) |
164
199
  | `all` inside `children`/`nested` | Behaves as `every` (`PLAY0380`) |
165
200
  | `$causedBy.<x>` | Does not bind; use `$eventContext.causedBy.<x>` |
166
201
  | Templates in mappings or keys | Do not bind |
@@ -9,7 +9,18 @@
9
9
  { "kind": "skill-contains", "value": "Look first for the project's existing `.play` files" },
10
10
  { "kind": "skill-contains", "value": "`cratis ai install` manages `.cratis/ai/`, never model files" },
11
11
  { "kind": "skill-contains", "value": "AutoMap is on by default" },
12
+ { "kind": "skill-contains", "value": "decides auto-mapping for that event alone" },
13
+ { "kind": "skill-contains", "value": "without one, the joined event follows its level's auto-map" },
14
+ { "kind": "skill-contains", "value": "Requires Screenplay 4.212.4" },
15
+ { "kind": "skill-contains", "value": "| `PLAY0380` | Only `all` inside `children`/`nested`:", "file": "references/pdl-grammar.md" },
16
+ { "kind": "skill-contains", "value": "It does not report `PLAY0380`.", "file": "references/pdl-grammar.md" },
12
17
  { "kind": "skill-contains", "value": "PLAY0191" },
18
+ { "kind": "skill-contains", "value": "One event type is used once per projection level (`PLAY0801`)" },
19
+ { "kind": "skill-contains", "value": "cannot update two rows at that level, even with different keys" },
20
+ { "kind": "skill-contains", "value": "events only to satisfy the read side" },
21
+ { "kind": "skill-contains", "value": "`clear with` share one set of event names", "file": "references/pdl-grammar.md" },
22
+ { "kind": "skill-contains", "value": "Each children, nested and\nvariant block starts fresh sets", "file": "references/pdl-grammar.md" },
23
+ { "kind": "skill-contains", "value": "older\nexecutable binding rejected duplicate uses later with `PLAY0273`", "file": "references/pdl-grammar.md" },
13
24
  { "kind": "skill-contains", "value": "every event type in the system" },
14
25
  { "kind": "skill-contains", "value": "references/pdl-grammar.md" },
15
26
  { "kind": "skill-contains", "value": "Do not write `key` on the projection." },
@@ -36,24 +36,21 @@ Tool versions are covered in `cratis-screenplay-toolchain` `SKILL.md`; read it b
36
36
 
37
37
  Read [language admission](../cratis-screenplay-toolchain/references/language-admission.md)
38
38
  for v22–v25: Stage rendering refuses atomic batches, described bodies (even Stub mode)
39
- and protected reads. Semantic Host/executor support is not generated-app protection.
39
+ but renders admitted protected reads in a supporting bundle. Semantic Host/executor
40
+ support is not generated-app protection.
40
41
  Preserve contracts; reference success is not target realization.
41
42
 
42
- File/inline command handlers refuse PLAY0800 (`CommandHandlerRequiresAttachment`):
43
- a permanent requirement for a constrained implementation attachment. Gap-fill the
44
- slice in code rather than wait for a new ESM version. Hosts identify the command
45
- through the required typed `arguments.subject`, not message text. Requires
46
- Screenplay 4.210.0 (`screenplay --version`); older binders use PLAY0268 for these
47
- handlers. Other PLAY0268 families still mean not representable in a supported ESM
48
- version yet; triage details: [renderability gate](references/renderability-gate.md).
43
+ File/inline command handlers permanently require constrained attachments: gap-fill
44
+ in code, not by waiting for ESM admission. Requires Screenplay 4.210.0
45
+ (`screenplay --version`) for PLAY0800 and required typed `arguments.subject`;
46
+ older binders use PLAY0268. Read [renderability gate](references/renderability-gate.md)
47
+ when classifying a handler or other binding refusal; never parse message text.
49
48
 
50
49
  ## Interview phase
51
- **Skip if** the request names the model root, the application name, the destination and the
52
- decision on non-renderable scope. Otherwise ask only what is missing:
53
- Ask only what is missing: the model and accepted version, the application name for `--name` (identical on every re-render), the destination, the decision if admission fails (the three cases below), and the seams (`Customizations/`). Read [references/delivery-protocol.md](references/delivery-protocol.md) ("Interview batch for render delivery") for the defaults.
54
-
55
- Unattended: assume visibly (probe destination, default name from the model root folder), never
56
- assume an answer to 4, and record it as `blocked` for the user.
50
+ Ask only for missing inputs: accepted model/root, stable `--name`, destination,
51
+ non-renderable-scope decision and seams. Read [references/delivery-protocol.md](references/delivery-protocol.md)
52
+ when selecting defaults. Unattended, state probe-name/destination assumptions;
53
+ never assume the non-renderable-scope decision: record it as blocked.
57
54
 
58
55
  ## The three cases (decide first, say which one applies)
59
56
 
@@ -63,36 +60,33 @@ assume an answer to 4, and record it as `blocked` for the user.
63
60
  | **B. Generated base plus authorized gap-fill** | an admitted render (whole, or a `--scope` of the admitted slices) exists and the user separately authorized hand-written scope, or a seam the model names needs an adapter | the generated output stays managed and untouched; hand-written code lives in `Customizations/` or a separate project (seam adapters by this skill, business gap-fill by `slice-implementer`), serves named model elements only, never claims render admission, and V5 is reported for the generated base **with its scope stated** |
64
61
  | **C. Fully hand-written delivery** | the scope cannot render and no generated base is wanted | `slice-implementer` delivers it with the model as the contract (`references/gap-fill-handoff.md`); V5 is `not run: no render` |
65
62
 
66
- Evolved events are gap-fill too: Stage still refuses any evolved event and its dependent scope with `STAGE-ESM-026`, because it cannot render Chronicle event-type migrations yet (Stage#204). Events at their initial revision still render. Hand-write the evolved events and their migrations per `cratis-chronicle-event-type-migration`, with the model as the contract.
63
+ Evolved events and dependent scope refuse `STAGE-ESM-026`; initial revisions render.
64
+ Gap-fill migrations per `cratis-chronicle-event-type-migration`, preserving the model contract.
67
65
 
68
- Supported UUID/String generation strategies, v15 freshness and scalar/named `returns`
69
- responses, fixtures and `then returns` render with the CLI and Stage. Unsupported generated
66
+ Supported UUID/String generation, v15 freshness, responses, fixtures and
67
+ `then returns` render. Unsupported generated
70
68
  types (`STAGE-ESM-028`) and result combinations (`-038`) still require case A or C:
71
69
  preserve the model and its specifications. See Stage's `references/admission.md`.
72
70
  Supported event-triggered Automation slices also render as managed Chronicle reactors;
73
- refused reactions, captures and Translate slices remain gap-fill.
74
-
75
- Models with event sources, streams or command routes bind and reference-execute as ESM v8 on the standalone
76
- tool, so report V3 and V4 from that tool. The CLI/Stage pair
77
- (`cratis-screenplay-toolchain/references/renderable-subset.md`) reaches v8 route checks
78
- and construct admission through v27 (Requires Cratis CLI 3.75.0; older bundles stop earlier, v28 is `CLI-RENDER-004`). Public/foreign events and production overrides
79
- still refuse; semantic reaction/reducer filters and role/authenticated `runs as` render.
80
- Claim-reading/opaque system gates, legacy actor/filter paths and mixed effects still refuse. Keep refused scope as case A/C,
81
- never infer target support from binding. Read Stage's `references/admission.md` and
82
- toolchain `references/sources-and-streams.md`.
83
-
84
- **Mixed reaction effects.** A reaction that both `produces` events and `invokes` commands is refused by
85
- Stage (`STAGE-ESM-037`) although Arc runs one reactor returning events
86
- and commands (events appended first as one batch, then commands in order, no cross-effect
87
- transaction; a retry can repeat the events). The scaffold now includes the mixed-result handler,
88
- but Stage still refuses it because redelivery can duplicate events. `[OnceOnly]` excludes replay,
89
- not retries. Keep the modeled reaction whole; gap-fill needs a proven retry-safe realization,
90
- not splitting or dropping effects to get a render. Source: Stage
91
- `Documentation/reference/reaction-rendering.md`.
92
-
93
- Read Stage's `references/admission.md` when checking v17/v19 or query validation:
94
- primitive query arguments still answer absence, not Screenplay's Validation.
95
- Query errors need v18 admission; do not delete rules or claim parity.
71
+ refused reactions, captures and Translate slices remain gap-fill. A `given clock` fixture
72
+ in the semantic executor is not support for rendering clock triggers.
73
+ Requires Stage 4.141.0 to render v26 Date/DateTime command comparisons; older renderers
74
+ refuse `STAGE-ESM-046`. Read [rendered date comparisons](../cratis-stage-rendering-and-sandbox/references/date-comparisons.md)
75
+ when delivering dates for remaining refusals and input-binding differences.
76
+
77
+ Source/stream routes bind and reference-execute as v8; target admission is separate.
78
+ Requires Cratis CLI 3.75.0 for v27 admission; older bundles stop earlier, v28 is
79
+ `CLI-RENDER-004`. Read toolchain `references/renderable-subset.md` and
80
+ `references/sources-and-streams.md` when delivering routes, actor gates or filters.
81
+ Preserve refused public/foreign events, production overrides and opaque gates as A/C.
82
+
83
+ **Mixed effects (`STAGE-ESM-037`).** Keep the reaction whole: returned events append
84
+ before commands and redelivery can duplicate them. `[OnceOnly]` excludes replay,
85
+ not retries. Read Stage's [admission](../cratis-stage-rendering-and-sandbox/references/admission.md)
86
+ when gap-filling a mixed reaction; prove retry safety, never split or drop effects.
87
+
88
+ Read Stage's `references/admission.md` when checking v17/v19 or query validation;
89
+ query errors need v18 admission. Preserve rules and test rejection separately from absence.
96
90
 
97
91
  Two rules hold in every case: a customization never makes a rejected model renderable, and
98
92
  a whole-application V5 is never claimed from a subset. `--scope` renders an admitted part (the whole
@@ -114,6 +108,9 @@ model still compiles and binds) and its V5 states the scope.
114
108
  (repeatable) to render an admitted part. Classify every
115
109
  diagnostic with `references/renderability-gate.md`: model fix in the chosen mode,
116
110
  capability gap, permanent implementation-attachment requirement, tool skew or environment. Group by code and count; do not paste the list.
111
+ Requires Stage 4.146.0 for collecting independent admission refusals in one plan;
112
+ earlier renderers reveal later batches after earlier fixes. Profile/version failures
113
+ still stop first. Classify all returned refusals before the next probe.
117
114
  3. **When admission fails** (case A) present the options, the user decides:
118
115
  (a) keep design mode and record the gaps; (b) narrow to renderable mode, where the modeler
119
116
  changes the model for business reasons and **without** removing protection (`pii`,
@@ -107,8 +107,9 @@ reaction or drop an effect to dodge rendering.
107
107
 
108
108
  Preserve declared `reaction batches atomic` boundaries: each trigger occurrence's
109
109
  direct productions and each selected refusal branch are separate batches, with
110
- invoked commands independent. Stage refuses v22 (STAGE-ESM-016) and atomic mode
111
- in admitted v23–v27 (STAGE-ESM-043); the declaration is not external-effect deduplication.
110
+ invoked commands independent. Atomic mode refuses STAGE-ESM-043.
111
+ Requires Stage 4.139.0 for v22 admission; older Stage reports -016.
112
+ The declaration is not external-effect deduplication.
112
113
  For described handlers, hand off only payload computation under the v23 result
113
114
  contract; Stage STAGE-IMPL-002 means no stubs, even Stub mode. Protected v25 reads
114
115
  render from Stage 4.138.0 (STAGE-ESM-044 from older bundles, or for shapes it cannot
@@ -35,7 +35,7 @@ ESM). Only the probe answers renderability. `PLAY0270` entries are information,
35
35
  | Class | Meaning | Typical examples (each verified in `admission.md`) | Action |
36
36
  | --- | --- | --- | --- |
37
37
  | **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 |
38
- | **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 or a projection keyed by parts (v27) refuses `STAGE-ESM-048` and a single-instance query by parts `STAGE-ESM-047` (Chronicle#4265); 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 reads the renderer cannot preserve, or any protected read in an older CLI bundle (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`); described handlers (v23, STAGE-IMPL-002 even Stub mode), atomic mode (STAGE-ESM-016 for v22, STAGE-ESM-043 in admitted v23–v27) | keep the model; fallback record entry; options a to c in `SKILL.md`; link the Stage issue |
38
+ | **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 or a projection keyed by parts (v27) refuses `STAGE-ESM-048` and a single-instance query by parts `STAGE-ESM-047` (Chronicle#4265); 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 reads the renderer cannot preserve, or any protected read in an older CLI bundle (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`); described handlers (v23, STAGE-IMPL-002 even Stub mode), atomic mode (STAGE-ESM-043; v22 admission Requires Stage 4.139.0, older Stage reports -016) | keep the model; fallback record entry; options a to c in `SKILL.md`; link the Stage issue |
39
39
  | **Implementation attachment** | a permanent limitation, not future ESM admission | file/inline command handlers (PLAY0800; typed `subject` names the command) | keep the model contract and gap-fill the slice in code with a constrained implementation attachment; do not wait for a new ESM version |
40
40
  | **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 |
41
41
  | **Environment** | not the model | restore failures, missing SDK, a destination that is not writable | fix the environment or report blocked |
@@ -38,13 +38,15 @@
38
38
  },
39
39
  {
40
40
  "kind": "skill-contains",
41
- "value": "Keep refused scope as case A/C"
41
+ "value": "Preserve refused public/foreign events, production overrides and opaque gates as A/C"
42
42
  },
43
43
  {
44
44
  "kind": "skill-contains",
45
45
  "value": "STAGE-ESM-026"
46
46
  },
47
- { "kind": "skill-contains", "value": "render with the CLI and Stage" },
47
+ { "kind": "skill-contains", "value": "`then returns` render" },
48
+ { "kind": "skill-contains", "value": "Requires Stage 4.141.0" },
49
+ { "kind": "skill-contains", "value": "Requires Stage 4.146.0" },
48
50
  { "kind": "skill-contains", "value": "Unsupported generated\ntypes (`STAGE-ESM-028`) and result combinations (`-038`)" },
49
51
  { "kind": "skill-contains", "value": "authored-UI parity" },
50
52
  { "kind": "skill-contains", "value": "responsible tool version" }
@@ -11,6 +11,15 @@
11
11
  Write it **before** drafting specs, keep it in `.ai-work/screenplay/<model-slug>/coverage.md` (or the
12
12
  `STATE.md` beside it), and update it with the specs. Reviewers check it against the model. Screenplay 4.127.0 MCP `find-specification-obligations` seeds the inventory (SPEC001–SPEC008), for command success, requirements, command/concept validation, effective authorization gates, value constraints, read models, projection removals and reaction outcomes. A met row proves matching authored presence, not full coverage or passing execution: the matrix still records domain judgments and scenario types the heuristic cannot infer.
13
13
 
14
+ For SPEC004, a gated query's denial can use `when query <Query>` with
15
+ `then denied`, or no `when` and exactly one `then query <Query>` with `arguments`
16
+ and no `result`, followed by `then denied`. The read-only form meets that query's
17
+ denial obligation, not the returned read model's SPEC006 assertion obligation.
18
+ Keep a separate view state, absence or query-result specification.
19
+ Requires Screenplay 4.212.2 (`screenplay --version`) for this inventory matching;
20
+ older servers miss the read-only denial for SPEC004 and count it for SPEC006.
21
+ Upgrade before gating on those rows; a met denial still proves presence, not execution.
22
+
14
23
  ## Cell values
15
24
  - `spec <Name>` - written; the name exists in the model.
16
25
  - `n/a: <domain reason>` - the situation cannot occur in this business. "Keeps it short" is not
@@ -8,9 +8,8 @@ license: MIT
8
8
 
9
9
  Read [preferred syntax](references/preferred-syntax.md) when writing or reviewing `.play`.
10
10
 
11
- This skill owns tool selection, verdict meaning and admission. Modeling method
12
- lives in `cratis-screenplay-modeling-lifecycle`; construct syntax lives in command,
13
- projection, read-surface, capture/reaction, specification and UI skills.
11
+ This skill owns tool selection, verdicts and admission. Modeling method lives in
12
+ `cratis-screenplay-modeling-lifecycle`; syntax lives in the construct skills.
14
13
 
15
14
  ## Locate the model
16
15
 
@@ -90,14 +89,12 @@ Independent results, not a ladder. Read `references/verdicts.md` for the command
90
89
  | V4 | reference specifications run | `screenplay test` or MCP `run-specifications`; unsupported/unbound is not a pass; rendered Debug tests are V5.tests, never V4 |
91
90
  | V5 | rendered and target-verified | `cratis render`, then Debug build and tests; report admission, publication, build and tests separately |
92
91
 
93
- V2 and V3 need MCP (V3 alone can also be read from `cratis screenplay validate --executable <root>`, labeled as the bundled compiler): send `initialize`, then `notifications/initialized`, and start the
94
- server with a fixed root. A subagent without MCP reports "V2 not run: no MCP in this agent".
95
-
96
- One line per verdict, tool first, for example `V1 pass (screenplay <version>, 3 files)` and
97
- `V3 blocked: PLAY0268 x3 (context filter, enum compliance)`. Name the source identity (commit plus the digest from
98
- the source-identity helper (`cratis-screenplay-modeling-lifecycle` `references/verdicts-and-modes.md` "Source identity")) the verdict ran on; keep it apart from the MCP
99
- `modelRevision`, which is semantic and, without `.screenplay/identities.json`,
100
- changes with the root folder name.
92
+ V2 needs MCP; V3 also supports `cratis screenplay validate --executable <root>`
93
+ (labeled as the bundled compiler). Read [verdict commands](references/verdicts.md)
94
+ for MCP initialization, source identity and reporting. Without MCP, report
95
+ `V2 not run: no MCP in this agent`. Report each verdict separately with tool,
96
+ version, source identity and any blocking codes; MCP `modelRevision` is semantic,
97
+ not the source identity.
101
98
 
102
99
  ## Subsets (write from the one your mode needs)
103
100
 
@@ -163,25 +160,11 @@ changes with the root folder name.
163
160
 
164
161
  ## Edit strategy
165
162
 
166
- - **Discover the capabilities available** (tool, version, `tools/list`, model root) once,
167
- then prefer typed, identity-preserving MCP operations (`propose-ast`, `propose-rename`,
168
- `propose-repair`, `propose-extract-inline-event`).
169
- - **Bounded text edits** are for edits that leave catalog addresses unchanged (descriptions,
170
- rule and expression bodies, mappings between existing members): a small `.play` diff
171
- followed by V1. Without `.screenplay/identities.json`, plain text edits are fine. Never use a
172
- text edit to get around an MCP refusal.
173
- - **Catalog-changing edits** belong to the identity owner (the session that owns MCP). When
174
- `.screenplay/identities.json` exists, adding, removing or renaming an addressed element
175
- (declarations, properties of commands, events, read models, composite types and triggers,
176
- queries, query arguments, specifications), moving declarations, creating, deleting, renaming
177
- or moving a mapped `.play` document (`IdentityMappingConflict`) and persisted event contract
178
- evolution go through MCP, and `id` pins alone
179
- are not enough: a session without MCP returns the request to the owning session.
180
- - AST JSON costs several times the text it replaces; use it where a typed operation is the
181
- only identity-safe route.
182
- - Proposals are connection-local (at most 16); `apply` writes `.screenplay/identities.json`
183
- and is not crash-atomic; never retry `apply` after `ApplyOutcomeUnknown`. Loop details:
184
- `cratis-screenplay-model-authoring`.
163
+ Read [the MCP authoring loop](../cratis-screenplay-model-authoring/references/mcp-loop.md)
164
+ when editing: the identity owner uses typed proposals for catalog-changing edits;
165
+ text edits never bypass a refusal. Without MCP, return identity-affecting work
166
+ to its owner. Proposals are connection-local; apply is not crash-atomic, and an
167
+ unknown apply outcome requires recovery, not retry.
185
168
 
186
169
  ## Top traps
187
170
 
@@ -8,6 +8,7 @@
8
8
  - Explicit enum member numbers
9
9
  - Reserved stored names and event pins
10
10
  - Named keys, production routes and observer filters
11
+ - Projection event scope (PLAY0801)
11
12
  - Reducer instance identity (PLAY0690)
12
13
  - Caller identity, compliance and routes
13
14
  - Specification metadata, callers, cases and locators
@@ -147,6 +148,25 @@ Overrides/filters select released ESM v10; malformed routes also use PLAY0504.
147
148
  Read read-surface `references/named-keys.md` and
148
149
  [production routes and filters](production-routes-and-filters.md).
149
150
 
151
+ ## Projection event scope (PLAY0801)
152
+
153
+ Requires Screenplay 4.212.3 (`screenplay --version`) for this ordinary compilation
154
+ check in both C# and TypeScript; older executable binding rejected these duplicate
155
+ uses later with PLAY0273.
156
+
157
+ | Code | Severity | Meaning / fix |
158
+ | --- | --- | --- |
159
+ | PLAY0801 | E | `DuplicateEventInProjectionScope`: an event name occurs more than once in one projection level's event set or separate join set. Reports the second and each later reference, even with identical or different keys. Combine same-row mappings into one block; one event cannot update two rows of that level through two `from` blocks. |
160
+
161
+ A level is the root, one `children` block, one `nested` block or one variant.
162
+ `from` (including each event in `from A, B` lists), `remove with`, `remove via join`
163
+ and `clear with` share one set of event names. `join` events have their own set:
164
+ once in `from` and once in a join is allowed. Each children, nested and variant
165
+ block starts fresh sets; separate projections are independent. Names compare
166
+ ordinally without resolving qualifications or generations. If the domain has a
167
+ genuine second fact, model it as its own event; never invent events only to
168
+ satisfy the read side. Full scope guidance: projections `references/pdl-grammar.md`.
169
+
150
170
  ## Reducer instance identity (PLAY0690)
151
171
 
152
172
  | Code | Severity | Meaning / fix |
@@ -299,6 +319,17 @@ as errors if gating. Ordinary compile success does not imply these ran:
299
319
  | purposes | PLAY0602–0606 | Personal-data coverage, special/criminal safeguards, basis and unused-purpose prompts; union of ancestor/direct references |
300
320
  | personas | PLAY0574–0576 | Unused personas, unreachable gates and ambiguous buildable policy alternatives; unsynthesizable/undecidable is unknown |
301
321
 
322
+ For `query-keys` (PLAY0535), a collection `by` can match a same-named compatible
323
+ read-model field or composite key part, or the identity. A single-result `by`
324
+ still matches the identity, not an arbitrary field. Parameter optionality is
325
+ ignored for compatibility; `optional` alone does not establish a match. Identity
326
+ inference uses only single-result keyed queries, not collection queries, with
327
+ structurally resolved projection keys as fallback. Performer-served views,
328
+ tenant-context parameters and unknown identity types are skipped.
329
+ Requires Screenplay 4.212.1 (`screenplay --version`) for this check alignment;
330
+ older tools can warn on valid collection fields or optional parameters and infer
331
+ identity from collection queries. Upgrade before using those warnings as a gate.
332
+
302
333
  Whole-source errors skip completeness checks. Unknown/opaque coverage is not
303
334
  invented: report skipped status/coverage and walk field lineage manually.
304
335
 
@@ -359,20 +390,22 @@ refusal reasons. Read [language admission](language-admission.md) before changin
359
390
  | PLAY0785 | Ambiguous view path; use distinct aliases on repeated reads |
360
391
  | PLAY0786 (I) | Eligible legacy model; preview typed preamble repair, individually review absence/conflict semantics |
361
392
  | PLAY0787 (W) | Exact deprecated Studio text-rule pattern; repair to literal rule or equality, preserving message/severity |
362
- | STAGE-ESM-043 | Atomic mode not realized, even in admitted v23–v27; retain declaration and gap-fill |
393
+ | STAGE-ESM-043 | Atomic mode not realized in admitted v22–v27; retain declaration and gap-fill (v22 admission Requires Stage 4.139.0; older Stage reports -016) |
363
394
  | STAGE-ESM-047 | Single-instance query by composite key parts (v27) in the renderer, until Chronicle can look up composite keys (Chronicle#4265); keep the query, gap-fill |
364
395
  | STAGE-ESM-048 | Read model with several key parts, or projection keyed by parts (v27), in the renderer or legacy syntax engine; keep the model, gap-fill |
365
396
  | STAGE-ESM-044 | Renderer refuses a protected read despite v25 admission: any protected read in a bundle that predates protected-read rendering, afterwards only shapes it cannot preserve (constrained events, read paths in `produces when`, optional/collection/composite/mistyped mapping targets, freshness scopes), naming the reason; the legacy Host/structural runner refuse the preamble. Semantic Host/executor support is separate; keep protection and gap-fill generated-app scope |
366
397
  | STAGE-ESM-045 | Non-Error protected requirement; semantic Host/executor refuse before execution, including reaction-invoked commands; keep severity and report Unsupported |
367
398
  | STAGE-IMPL-002 | Described handler body not realized by Stage, even Stub mode; no stubs emitted |
399
+ | STAGE-IMPL-003 | Reached reducer or command/concept validation body in semantic Host/executor; owner and RequirementId named, unrelated behavior remains admitted (Requires Stage 4.145.0; older engines refuse unrelated behavior too) |
400
+ | STAGE-PROFILE-001 to -006 | Shared target profile-input findings: unknown package, missing layout, incompatible packages, missing theme, invalid root template, unresolved blueprint template (Requires Stage 4.143.0; older consumers may check only in the CLI) |
368
401
 
369
402
  Invalid match syntax remains PLAY0367. Property/concept text rules bind v24;
370
403
  `contains`/`starts with` in conditions only still fail PLAY0268. Stage rejects
371
- v22/v28 and mixed pairs with STAGE-ESM-016; v23–v27 admission does not implement
372
- bodies or batches, the renderer refuses protected reads it cannot preserve (STAGE-ESM-044; every
373
- protected read in an older bundle), v26 date comparisons (STAGE-ESM-046) and composite read-model
374
- keys (STAGE-ESM-048/-047). Read
375
- [language admission](language-admission.md) for the stricter Host outside-append guard.
404
+ v28 and mixed pairs with STAGE-ESM-016; v1–v27 admission does not implement
405
+ bodies or batches. The renderer refuses protected reads it cannot preserve (STAGE-ESM-044; every
406
+ protected read in an older bundle), unsupported date-comparison shapes (STAGE-ESM-046;
407
+ all date comparisons before Stage 4.141.0) and composite read-model keys (STAGE-ESM-048/-047).
408
+ Read [language admission](language-admission.md) for Host outside-append commit behavior.
376
409
  Requires Stage 4.129.0 for semantic Host/executor protected reads; older engines refuse -044.
377
410
 
378
411
  ## Binding (V2 and V3) - see `executable-subset.md` for the full table
@@ -266,8 +266,11 @@ DateTime input needs an offset or `Z`, else Validation rejects before rules, eve
266
266
  for skipped comparisons. `then` matching stays ordinal. Invalid date literals or
267
267
  offset-less DateTime literals in admitted comparisons report PLAY0273. Read
268
268
  [date comparisons](../../cratis-screenplay-command-surface/references/date-comparisons.md)
269
- for the complete window model and retained PLAY0268 refusals. The Stage renderer refuses
270
- v26 date comparisons with STAGE-ESM-046, independently of standalone binding/reference execution.
269
+ for the complete window model and retained PLAY0268 refusals. Requires Stage 4.141.0
270
+ for rendered date comparisons; older renderers refuse STAGE-ESM-046. Read
271
+ [rendered dates](../../cratis-stage-rendering-and-sandbox/references/date-comparisons.md)
272
+ when checking remaining refusals and input-binding differences. Standalone binding/reference
273
+ execution is independent of rendering.
271
274
 
272
275
  ## Flat composite read-model keys (ESM v27)
273
276
 
@@ -9,11 +9,11 @@ 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–v27 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 admitted with a supporting bundle; atomic mode 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 renderer renders protected reads in a new enough bundle (STAGE-ESM-044 before it, and for shapes it cannot preserve); 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 admitted; Host/executor run it, renderer and legacy engines refuse STAGE-ESM-046 |
16
+ | v26 | Chronological command Date/DateTime comparisons | Same-primitive `==`, `!=`, `>`, `>=`, `<`, `<=`; DateTime UTC ticks and pre-rule offset validation | v26 admitted; Host/executor run it; renderer supports admitted shapes with remaining STAGE-ESM-046 refusals; legacy engines refuse -046 |
17
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 admitted; Host runs it, renderer refuses STAGE-ESM-048/-047, executor refuses specs over it |
18
18
  | v28 | `==`/`!=` between Uuid values in command `require` and `produces when` | Uuid properties, Uuid concepts and identities, canonical literals; protected read paths in `require` only | v28 refused STAGE-ESM-016 |
19
19
 
@@ -35,7 +35,7 @@ Requires Stage 4.124.0 for v24 text-rule admission (`cratis --version` identifie
35
35
 
36
36
  Requires Stage 4.127.0 for v25 version admission; older renderers refuse v25 with STAGE-ESM-016. Requires Stage 4.138.0 for the Cratis renderer to render protected reads as Arc read protection; earlier renderers, and reads it cannot preserve, refuse STAGE-ESM-044 and emit no artifacts. `cratis render` gets this from the first CLI that bundles Stage 4.138.0; CLI 3.75.0 bundles Stage 4.137.0.
37
37
 
38
- Requires Stage 4.129.0 for semantic Host/executor protected reads; older engines refuse STAGE-ESM-044. Absence rejects before requirements/generation; read properties feed requirements and productions. Non-Error protected requirements refuse STAGE-ESM-045, including reaction invocations. Legacy Host/structural runner retain -044. The Host faults on any outside append, stricter than reference dependency-scoped conflicts; see [sandbox boundaries](../../cratis-stage-rendering-and-sandbox/references/sandbox-and-specrunner.md#protected-command-reads).
38
+ Requires Stage 4.129.0 for semantic Host/executor protected reads; older engines refuse STAGE-ESM-044. Absence rejects before requirements/generation; read properties feed requirements and productions. Non-Error protected requirements refuse STAGE-ESM-045, including reaction invocations. Legacy Host/structural runner retain -044. Requires Stage 4.142.0 for outside facts to participate in decide/commit, with unrelated appends absorbed; older Hosts fault on any outside append; see [sandbox boundaries](../../cratis-stage-rendering-and-sandbox/references/sandbox-and-specrunner.md#protected-command-reads).
39
39
 
40
40
  Read [atomic batches and event-source invocation mappings](../../cratis-screenplay-captures-and-reactions/references/atomic-batches-and-source-mappings.md)
41
41
  for atomic boundaries and the source-identity mapping prerequisite. Start new models
@@ -74,10 +74,20 @@ the same condition without Uuid operands keeps its earlier version. To see the s
74
74
  the model with the `screenplay` MCP server and call `read-workspace` with `view` `executable-model`:
75
75
  `languageVersion` reads `28.0`.
76
76
 
77
- Stage's semantic engines admit exact v1–v21 and v23–v27 pairs. V22/v28 and mixed
78
- pairs refuse STAGE-ESM-016. Admission of v23–v27 is not admission of described bodies,
77
+ Stage's semantic engines admit exact v1–v27 pairs. V28 and mixed
78
+ pairs refuse STAGE-ESM-016.
79
+ Requires Stage 4.139.0 for v22; older Stage refuses -016.
80
+ Admission is not admission of described bodies,
79
81
  atomic mode or composite-key rendering, and protected reads render only in a bundle that supports them. A CLI may bundle an older compiler/Stage pair: run no-write render
80
82
  admission rather than transferring a standalone verdict. Pattern diagnostics arise
81
83
  in Screenplay before rendering; diagnostic arguments add no ESM version or new tool.
82
84
 
83
85
  Requires Stage 4.135.0 for v26 admission and 4.137.0 for v27; older Stage refuses them with STAGE-ESM-016.
86
+ Requires Stage 4.141.0 to render date comparisons; older renderers refuse -046.
87
+ Read [rendered dates](../../cratis-stage-rendering-and-sandbox/references/date-comparisons.md)
88
+ when checking remaining -046 shapes and input-binding differences.
89
+ Requires Stage 4.145.0 for reach-scoped reducer/validation-body refusals
90
+ (STAGE-IMPL-003); older engines refuse unrelated behavior too. Described command
91
+ handlers retain STAGE-IMPL-002; renderer implementation admission is unchanged.
92
+ Read [sandbox boundaries](../../cratis-stage-rendering-and-sandbox/references/sandbox-and-specrunner.md)
93
+ when a semantic run reaches a body or uses an authored reaction clock.
@@ -23,10 +23,13 @@ and concept compliance (v13) render.
23
23
 
24
24
  The language is frozen at ESM v1–v28 ([the freeze decision](https://github.com/Cratis/Screenplay/blob/main/decisions/0092-the-language-is-frozen-at-esm-v28.md)): no new versions, constructs, keywords or grammar, except a construct for a real model that is blocked with no model-side alternative, accepted in its own record. Model with what v1–v28 offers; when Stage, `cratis render` or Studio does not support a construct yet, treat the typed refusal as a platform gap to report, since consumers are catching up to v28, not a reason to wait for new language.
25
25
 
26
- Stage admits exact ESM v1–v21 and v23–v27 pairs; v22/v28 and mixed pairs
27
- refuse STAGE-ESM-016. Chronological command Date/DateTime comparisons select v26:
28
- the Host and executor run them, but the renderer refuses STAGE-ESM-046, so they are not renderable. Keep the
29
- rule and use authorized gap-fill. Version admission is separate from construct support.
26
+ Stage admits exact ESM v1–v27 pairs; v28 and mixed pairs refuse STAGE-ESM-016.
27
+ Requires Stage 4.139.0 for v22 admission; older Stage refuses v22 with -016,
28
+ while atomic mode remains -043. Chronological command dates select v26.
29
+ Requires Stage 4.141.0 to render Date/DateTime comparisons; older renderers refuse -046.
30
+ Read [rendered dates](../../cratis-stage-rendering-and-sandbox/references/date-comparisons.md)
31
+ when checking remaining -046 shapes and input-binding differences. Version admission
32
+ is separate from construct support.
30
33
  Requires Stage 4.106.0 for v18 admission; older Stage refuses it with `STAGE-ESM-016`.
31
34
  For generated-concept v20/v21 admission and construct prerequisites, read
32
35
  [Stage admission](../../cratis-stage-rendering-and-sandbox/references/admission.md).
@@ -33536,7 +33536,7 @@
33536
33536
  "severities": [
33537
33537
  "warning"
33538
33538
  ],
33539
- "title": "A projection construct binds, but Chronicle\u0027s projection lowering drops part of it: all inside a children or nested block loses its subscription to every event type, and an auto-map setting on a joined event is replaced by the level\u0027s.",
33539
+ "title": "A projection construct binds, but Chronicle\u0027s projection lowering drops part of it: all inside a children or nested block loses its subscription to every event type.",
33540
33540
  "reserved": false,
33541
33541
  "retired": false
33542
33542
  },
@@ -37838,6 +37838,17 @@
37838
37838
  "meaning": "The command whose handler requires a constrained implementation attachment."
37839
37839
  }
37840
37840
  ]
37841
+ },
37842
+ {
37843
+ "code": "PLAY0801",
37844
+ "name": "DuplicateEventInProjectionScope",
37845
+ "severity": "error",
37846
+ "severities": [
37847
+ "error"
37848
+ ],
37849
+ "title": "An event is used more than once in one projection level\u0027s event or join set.",
37850
+ "reserved": false,
37851
+ "retired": false
37841
37852
  }
37842
37853
  ],
37843
37854
  "mcpTools": [
@@ -47,7 +47,7 @@
47
47
  { "kind": "skill-contains", "value": "XML doc comments" },
48
48
  { "kind": "skill-contains", "value": "cratis screenplay validate" },
49
49
  { "kind": "skill-contains", "value": "validating one file with `cratis screenplay validate file.play`", "file": "references/traps.md" },
50
- { "kind": "skill-contains", "value": "`notifications/initialized`" },
50
+ { "kind": "skill-contains", "value": "`notifications/initialized`", "file": "references/verdicts.md" },
51
51
  { "kind": "skill-contains", "value": "Pending described handlers bind but do not execute their bodies" },
52
52
  { "kind": "skill-contains", "value": "STAGE-ESM-043", "file": "references/language-admission.md" },
53
53
  { "kind": "skill-contains", "value": "v25", "file": "references/language-admission.md" },
@@ -64,6 +64,13 @@
64
64
  { "kind": "skill-contains", "value": "RejectsAUsedGeneratedSource", "file": "references/generation-strategies-example.md" },
65
65
  { "kind": "skill-contains", "value": "bind as ESM v8" },
66
66
  { "kind": "skill-contains", "value": "PLAY0530/0531", "file": "references/diagnostics.md" },
67
- { "kind": "skill-contains", "value": "Editor versus C# verdicts", "file": "references/diagnostics.md" }
67
+ { "kind": "skill-contains", "value": "Requires Screenplay 4.212.1", "file": "references/diagnostics.md" },
68
+ { "kind": "skill-contains", "value": "Identity\ninference uses only single-result keyed queries", "file": "references/diagnostics.md" },
69
+ { "kind": "skill-contains", "value": "Editor versus C# verdicts", "file": "references/diagnostics.md" },
70
+ { "kind": "skill-contains", "value": "PLAY0801 | E | `DuplicateEventInProjectionScope`", "file": "references/diagnostics.md" },
71
+ { "kind": "skill-contains", "value": "Requires Screenplay 4.212.3", "file": "references/diagnostics.md" },
72
+ { "kind": "skill-contains", "value": "`clear with` share one set of event names", "file": "references/diagnostics.md" },
73
+ { "kind": "skill-contains", "value": "`join` events have their own set", "file": "references/diagnostics.md" },
74
+ { "kind": "skill-contains", "value": "Each children, nested and variant\nblock starts fresh sets", "file": "references/diagnostics.md" }
68
75
  ]
69
76
  }