@cratis/pi 7.61.0 → 7.63.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 (132) hide show
  1. package/package/corpus/agents/spec-writer.md +2 -2
  2. package/package/corpus/harnesses/copilot/instructions/application-profile.instructions.md +2 -2
  3. package/package/corpus/harnesses/copilot/instructions/glossary.instructions.md +2 -2
  4. package/package/corpus/harnesses/copilot/instructions/specs.scenarios.csharp.instructions.md +7 -4
  5. package/package/corpus/harnesses/copilot/instructions/vertical-slices.instructions.md +22 -13
  6. package/package/corpus/product-sync.json +11 -10
  7. package/package/corpus/prompts/add-business-rule.prompt.md +1 -1
  8. package/package/corpus/rules/application-profile.md +2 -2
  9. package/package/corpus/rules/glossary.md +2 -2
  10. package/package/corpus/rules/specs.scenarios.csharp.md +7 -4
  11. package/package/corpus/rules/vertical-slices.md +22 -13
  12. package/package/corpus/skills/cratis-application-slice-conformance/SKILL.md +1 -1
  13. package/package/corpus/skills/cratis-application-slice-specifications/SKILL.md +4 -3
  14. package/package/corpus/skills/cratis-application-slice-specifications/references/query-and-decision-scenarios.md +12 -3
  15. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/SKILL.md +12 -7
  16. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authorization.md +11 -11
  17. package/package/corpus/skills/cratis-arc-command/SKILL.md +3 -2
  18. package/package/corpus/skills/cratis-arc-command/references/decisions-and-routing.md +95 -51
  19. package/package/corpus/skills/cratis-arc-command/references/fresh-identifiers.md +5 -2
  20. package/package/corpus/skills/cratis-arc-command/references/generated-values.md +27 -12
  21. package/package/corpus/skills/cratis-arc-command/references/read-model-injection.md +9 -5
  22. package/package/corpus/skills/cratis-arc-command/references/shop-generation.md +17 -6
  23. package/package/corpus/skills/cratis-arc-command-validation/SKILL.md +99 -52
  24. package/package/corpus/skills/cratis-chronicle-decision-reads/SKILL.md +37 -15
  25. package/package/corpus/skills/cratis-chronicle-decision-reads/references/admission-and-ownership.md +3 -2
  26. package/package/corpus/skills/cratis-chronicle-decision-reads/references/choosing-how-a-rule-holds.md +277 -138
  27. package/package/corpus/skills/cratis-chronicle-event-constraints/SKILL.md +4 -4
  28. package/package/corpus/skills/cratis-chronicle-event-modeling/SKILL.md +6 -4
  29. package/package/corpus/skills/cratis-chronicle-read-model/SKILL.md +2 -1
  30. package/package/corpus/skills/cratis-chronicle-reducer/SKILL.md +6 -3
  31. package/package/corpus/skills/cratis-code-review/SKILL.md +6 -3
  32. package/package/corpus/skills/cratis-fundamentals-concept/SKILL.md +10 -2
  33. package/package/corpus/skills/cratis-fundamentals-concept/references/shop-generation.md +49 -6
  34. package/package/corpus/skills/cratis-screenplay-automations-and-translations/SKILL.md +43 -41
  35. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/cases-to-specify.md +11 -2
  36. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/integration-interview.md +24 -0
  37. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/public-events-and-direction.md +76 -10
  38. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/realization-and-gap-fill.md +5 -0
  39. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/todo-list-example.md +1 -1
  40. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/translate-example.md +39 -23
  41. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/translation-patterns.md +35 -12
  42. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/SKILL.md +51 -81
  43. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/atomic-batches-and-source-mappings.md +83 -0
  44. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/capture-map-and-example.md +14 -4
  45. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/reaction-forms.md +59 -0
  46. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/record-capture-specifications.md +60 -0
  47. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/specifying-triggers-and-clock.md +5 -1
  48. package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +26 -28
  49. package/package/corpus/skills/cratis-screenplay-command-surface/references/described-handlers.md +82 -0
  50. package/package/corpus/skills/cratis-screenplay-command-surface/references/generated-values-and-responses.md +82 -28
  51. package/package/corpus/skills/cratis-screenplay-command-surface/references/protected-reads.md +113 -0
  52. package/package/corpus/skills/cratis-screenplay-command-surface/references/shop-generation.md +45 -12
  53. package/package/corpus/skills/cratis-screenplay-command-surface/references/text-and-match-rules.md +119 -0
  54. package/package/corpus/skills/cratis-screenplay-command-surface/references/validate-rules.md +14 -4
  55. package/package/corpus/skills/cratis-screenplay-command-surface/verification.json +10 -3
  56. package/package/corpus/skills/cratis-screenplay-event-modeling/SKILL.md +12 -12
  57. package/package/corpus/skills/cratis-screenplay-event-modeling/references/parsed-not-runnable.md +5 -3
  58. package/package/corpus/skills/cratis-screenplay-event-modeling/verification.json +5 -1
  59. package/package/corpus/skills/cratis-screenplay-legacy-extraction/SKILL.md +2 -2
  60. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/evidence-table-template.md +1 -1
  61. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/generated-recovery.md +51 -14
  62. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/intent-example.md +5 -0
  63. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/loss-report-template.md +2 -1
  64. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/rule-modeling.md +6 -3
  65. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/signal-to-intent.md +1 -1
  66. package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +22 -28
  67. package/package/corpus/skills/cratis-screenplay-model-authoring/references/choosing-generation.md +20 -7
  68. package/package/corpus/skills/cratis-screenplay-model-authoring/references/language-reference.md +12 -6
  69. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-loop.md +9 -1
  70. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +58 -10
  71. package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +4 -2
  72. package/package/corpus/skills/cratis-screenplay-model-review/SKILL.md +2 -5
  73. package/package/corpus/skills/cratis-screenplay-model-review/references/anti-patterns.md +2 -2
  74. package/package/corpus/skills/cratis-screenplay-model-review/references/checklist.md +2 -2
  75. package/package/corpus/skills/cratis-screenplay-model-review/references/quick-self-check.md +2 -1
  76. package/package/corpus/skills/cratis-screenplay-model-review/references/review-questions.md +3 -2
  77. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/principles.md +1 -1
  78. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/vocabulary-map.md +1 -1
  79. package/package/corpus/skills/cratis-screenplay-read-surface/SKILL.md +2 -3
  80. package/package/corpus/skills/cratis-screenplay-read-surface/references/named-keys.md +3 -1
  81. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/SKILL.md +8 -3
  82. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/gap-fill-handoff.md +8 -0
  83. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/renderability-gate.md +6 -4
  84. package/package/corpus/skills/cratis-screenplay-scenario-coverage/SKILL.md +36 -29
  85. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/berth-reservations.md +6 -0
  86. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/invoicing-dues-design.md +15 -4
  87. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/invoicing-dues-example.md +25 -20
  88. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/public-event-coverage.md +14 -3
  89. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/scenario-examples.md +9 -3
  90. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/spec-forms-by-mode.md +7 -3
  91. package/package/corpus/skills/cratis-screenplay-slice-design/SKILL.md +3 -1
  92. package/package/corpus/skills/cratis-screenplay-slice-design/references/command-inventory.md +4 -4
  93. package/package/corpus/skills/cratis-screenplay-slice-design/references/rule-layers.md +4 -2
  94. package/package/corpus/skills/cratis-screenplay-slice-design/references/slicing.md +4 -3
  95. package/package/corpus/skills/cratis-screenplay-slice-design/references/worked-example.md +8 -8
  96. package/package/corpus/skills/cratis-screenplay-specifications/SKILL.md +49 -47
  97. package/package/corpus/skills/cratis-screenplay-specifications/references/actions-beyond-commands.md +11 -1
  98. package/package/corpus/skills/cratis-screenplay-specifications/references/generated-fixtures.md +48 -17
  99. package/package/corpus/skills/cratis-screenplay-specifications/references/vocabulary.md +14 -1
  100. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/SKILL.md +25 -21
  101. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/boundaries.md +2 -2
  102. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/consistency-and-concurrency.md +14 -6
  103. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/multi-service-models.md +4 -3
  104. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/streams-example.md +7 -0
  105. package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +30 -22
  106. package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet-example.md +3 -1
  107. package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet.md +47 -2
  108. package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostic-arguments.md +60 -0
  109. package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +65 -5
  110. package/package/corpus/skills/cratis-screenplay-toolchain/references/executable-subset.md +50 -22
  111. package/package/corpus/skills/cratis-screenplay-toolchain/references/generation-checks.md +93 -0
  112. package/package/corpus/skills/cratis-screenplay-toolchain/references/generation-strategies-example.md +117 -35
  113. package/package/corpus/skills/cratis-screenplay-toolchain/references/language-admission.md +46 -0
  114. package/package/corpus/skills/cratis-screenplay-toolchain/references/preferred-syntax.md +3 -1
  115. package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +25 -10
  116. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +1800 -50
  117. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
  118. package/package/corpus/skills/cratis-screenplay-toolchain/references/traps.md +5 -3
  119. package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +6 -1
  120. package/package/corpus/skills/cratis-screenplay-ui-composition/SKILL.md +8 -53
  121. package/package/corpus/skills/cratis-screenplay-ui-composition/references/file-references.md +2 -2
  122. package/package/corpus/skills/cratis-screenplay-ui-composition/references/interaction-example.md +54 -0
  123. package/package/corpus/skills/cratis-screenplay-ui-composition/verification.json +6 -3
  124. package/package/corpus/skills/cratis-specifications-csharp/SKILL.md +3 -2
  125. package/package/corpus/skills/cratis-specifications-csharp/references/application-scenarios.md +1 -1
  126. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +30 -29
  127. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +36 -9
  128. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/choosing-generation.md +28 -8
  129. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/publication-and-recovery.md +31 -0
  130. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/sandbox-and-specrunner.md +8 -0
  131. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/verification.json +4 -1
  132. package/package.json +1 -1
@@ -26,30 +26,22 @@ Language claims follow Screenplay `reactions.md`, `triggers.md`, `captures.md` a
26
26
  `Documentation/reference/reaction-rendering.md`. Tool versions are covered in toolchain
27
27
  `SKILL.md`; run the examples at the pinned standalone tool before relying on them.
28
28
 
29
- ⚠️ **Which tool admits them depends on its Screenplay version.** The ESM level
30
- decides, not the slice type:
31
-
32
- - **A compiler that admits ESM v6 and v7:** `Automation` and
33
- `Translate` slices, reactions, declared triggers and captures bind, and the
34
- reference runner executes them. The complete example below is
35
- `executableReady` over `screenplay mcp`.
36
- - **A compiler that stops before ESM v6** refuses them and falsely reports PLAY0285
37
- (toolchain `references/diagnostics.md`).
29
+ The compiler's ESM admission decides, not the slice type. Reactions, triggers and
30
+ captures bind/reference-execute from v6; older compilers refuse them. Read toolchain
31
+ `references/diagnostics.md` when diagnosing skew or false PLAY0285 cascades.
38
32
  - **The CLI and Stage** render supported event-triggered Automation, not
39
33
  Translate/captures, non-event triggers or opaque bodies (`-024`). Role/authenticated `runs as`
40
34
  and semantic `from` render; claim/opaque gates, mixed effects and unsupported mappings remain refused;
41
35
  cascade specs remain `-011`. Keep refused scope as gap-fill. Full boundary and source
42
36
  citations: `cratis-stage-rendering-and-sandbox` `references/admission.md`.
43
37
 
44
- Model them whenever the `.play` file is the deliverable, and say which tool bound
45
- them (`cratis-screenplay-toolchain` `references/diagnostics.md` for messages).
46
- Method (the four-part automation test, loops, translations versus automations):
47
- `cratis-screenplay-automations-and-translations`.
38
+ Name the binding tool. For the automation test, loops and translation boundaries,
39
+ read `cratis-screenplay-automations-and-translations`.
48
40
 
49
41
  ## Public boundaries and observer selection
50
42
 
51
43
  Read [ESM v9 translation](../cratis-screenplay-automations-and-translations/references/public-events-and-direction.md)
52
- for `direction`, `source events`/`from`, and its typed Unsupported evaluation.
44
+ for `direction`, `source events`/`from`, typed event fixtures and per-key state folds.
53
45
  One `source events` capture consumes events from exactly one origin (event store).
54
46
  Split inputs from several external systems into one capture per origin; otherwise
55
47
  PLAY0687 reports an error, matching Chronicle's one-inbox-observer boundary.
@@ -60,12 +52,31 @@ for reaction/reducer `from Source[.Stream]`; unrouted facts never match.
60
52
 
61
53
  ## Specify what sets them off
62
54
 
63
- A specification names what sets the automation off: `when clock`, `when trigger`
64
- or `when capture`. Execute admitted scenarios through `screenplay test` or MCP
65
- `run-specifications`; source compilation alone is only authored evidence.
55
+ A specification names its input: `when clock` or `when trigger` for an automation,
56
+ `when capture` for a record source, and `when append <ForeignEvent>` for a capture
57
+ with `source events`. Seed the latter with `given <ForeignEvent>`, never `given capture`
58
+ or `when capture` (PLAY0701). Its key must be a required property of every `from`
59
+ event, never `$eventSourceId` or another context key (PLAY0700).
60
+
61
+ Requires Screenplay 4.171.0 or later (`screenplay --version`) for reference execution of captures over events and PLAY0700/0701; older tools leave event delivery unexecuted.
62
+
63
+ First sight is `added` only, not a field change. Read
64
+ [record capture specifications](references/record-capture-specifications.md) when
65
+ specifying first sight, updates, child/nested additions or unchanged records.
66
+ Execute admitted scenarios through `screenplay test` or MCP `run-specifications`;
67
+ source compilation alone is only authored evidence.
66
68
 
67
69
  Read [references/specifying-triggers-and-clock.md](references/specifying-triggers-and-clock.md) when writing a specification for a reaction, trigger or capture, or when the clock, occurrence or limit rules matter.
68
70
 
71
+ ## Atomic batches and event-source mappings
72
+
73
+ Start new models with application-root `reaction batches atomic`. One trigger's direct
74
+ productions, or one selected refusal branch, append all-or-none; invoked commands stay
75
+ separate. Legacy models without opt-in retain per-fact appends even at newer versions.
76
+ Read [atomic batches and source mappings](references/atomic-batches-and-source-mappings.md)
77
+ for batch failure assertions, PLAY0693, Stage STAGE-ESM-016/043 refusals and
78
+ `invokes` mappings from `$eventSourceId` / `$eventContext.eventSourceId`.
79
+
69
80
  ## Caller-less invokes and unprotected reads
70
81
 
71
82
  **Who is the caller of an `invokes`?** Without a declared actor, nobody.
@@ -90,7 +101,10 @@ ESM v6 the binder refuses to treat it as one: a trigger with `reads` that **prod
90
101
  directly**, or whose effect is an opaque body (`file` or an inline block), fails
91
102
  binding, because its decision dependency cannot be protected. A reaction that only
92
103
  `invokes` a command binds, and the decision, and any protection, belong to that
93
- command's own reads. Command `reads` give none yet either (`PLAY0271`).
104
+ command's own reads. Eligible command reads protect under application-root
105
+ `command reads protected` (ESM v25); legacy reads retain PLAY0271. Read command-surface
106
+ [protected reads](../cratis-screenplay-command-surface/references/protected-reads.md)
107
+ for admission and absence/conflict behavior. Stage admits v25 but refuses protected reads with STAGE-ESM-044.
94
108
  `where` over read paths out of scope, and `where` needs
95
109
  every operand to resolve from the trigger's declared scalar occurrence shape (listed in
96
110
  the input selection or not; nested paths and read aliases fail binding): keep the logic that uses the state in
@@ -123,25 +137,13 @@ The full capture excerpt (`source`, `key`, `map` with `translate`, two `append`
123
137
 
124
138
  Read [references/capture-map-and-example.md](references/capture-map-and-example.md) when writing a capture's `map` block, or when you need the excerpt of a capture with `append` and `children`.
125
139
 
126
- **`source <kind>`** takes free-form settings, so a typo is not caught; **`key <property>`** is required to bind (`PLAY0268`); **`append <Event>`** takes one `when` clause, and `or` and `and` cannot be mixed in one clause (split into two `append` blocks). Read [references/capture-map-and-example.md](references/capture-map-and-example.md) for source kinds, `key` and specification behavior, the `when` forms table, `children` and `nested`.
140
+ **`source <kind>`** takes free-form settings, so a typo is not caught; **`key <property>`** is required to bind (`PLAY0268`); **`append <Event>`** takes at most one `when` clause, and `or` and `and` cannot be mixed in one clause (split into two `append` blocks). Read [references/capture-map-and-example.md](references/capture-map-and-example.md) for source kinds, `key` and specification behavior, the `when` forms table, `children` and `nested`.
127
141
 
128
142
  ## `reaction`
129
143
 
130
- Excerpt; complete document: `references/complete-examples.md`,
131
- "Reaction on a declared trigger with `where` and `invokes`".
132
-
133
- ```screenplay excerpt
134
- slice Automation NotifyOnBuildFailure
135
- reaction NotifyOnFailure
136
- description "Tells the owning team when a watched build fails"
137
- when BuildFinished
138
- repository
139
- outcome
140
- invokes SendFailureNotice
141
- repository = repository
142
- outcome = outcome
143
- where outcome == "failed"
144
- ```
144
+ Read [reaction forms](references/reaction-forms.md) when choosing a trigger,
145
+ selecting occurrence values or mapping `produces` and `invokes`; complete documents
146
+ remain in `references/complete-examples.md`.
145
147
 
146
148
  A reaction declares **at least one trigger**; everything under a trigger is
147
149
  optional.
@@ -152,29 +154,13 @@ under `when`/`every`/`at`. `description`, `where` and `runs as` sit at reaction
152
154
  Outdenting an effect gives *Expected a trigger in reaction body, got 'invokes …'*
153
155
  (`PLAY0137`) — the compiler is looking for another trigger where the effect is.
154
156
 
155
- ### What sets it off
156
-
157
- | Form | Runs |
158
- | --- | --- |
159
- | `when <Name>` | on that event, declared trigger, or registered trigger |
160
- | `every <n> seconds\|minutes\|hours\|days` | on that interval (`n` ≥ 1) |
161
- | `at HH:mm` | every day at that time |
162
- | `at HH:mm on <Weekday>` | every week on that day |
163
- | `at HH:mm on day <n>` | every month on that day (`n` is 1–31) |
164
-
165
- Time is strictly `HH:mm`. Weekday is the full English name.
166
-
167
- ### The values a reaction takes
168
-
169
- A bare name under a trigger says the reaction **uses** that value from the
170
- occurrence. This is a **selection, not a declaration** — the shape belongs to the
171
- event or trigger. Taking a value the occurrence does not carry is reported.
172
-
173
157
  ### `where` — narrowing
174
158
 
175
159
  `where` uses the same condition grammar as `produces … when` and `require`:
176
160
  `==`, `!=`, the ordering operators, `contains` for a substring anywhere,
177
161
  `starts with` for one at the beginning, combined with `and`, `or` and parentheses.
162
+ These text-condition operators parse but refuse executable binding (PLAY0268);
163
+ literal property text rules are a separate v24 contract.
178
164
 
179
165
  ⚠️ **`where` belongs to the reaction, not to one trigger** — it says which
180
166
  occurrences are worth running for, whatever set them off. A second `where` on one
@@ -186,36 +172,16 @@ Inline `produces event <Name>` is command-only (`PLAY0474` in a reaction).
186
172
  Declare reaction-produced events separately and use plain `produces <Name>`.
187
173
  Do not extend the inline command destination default or its repairs to reactions.
188
174
 
189
- Excerpt; complete document: `references/complete-examples.md`,
190
- "Reaction with `produces` and `invokes`":
191
-
192
- ```screenplay excerpt
193
- reaction Provisioner
194
- when InvitationAccepted
195
- workspaceId
196
- produces WorkspaceProvisioned
197
- for workspaceId
198
- workspaceId = workspaceId
199
- invokes SendWelcomeMail
200
- workspaceId = workspaceId
201
- template = "welcome"
202
- ```
203
-
204
175
  A `produces` without `for` appends to the event source of the event that set the
205
176
  reaction off. A clock, application or built-in trigger has no such event, so what it
206
177
  produces needs `for` - a value the trigger carries, or literal text.
207
178
 
208
- **The different word is the point.** `produces` requests a fact append, subject to
209
- append-time constraints. `invokes` asks for a command, which additionally runs the
210
- command's authorization, validation and requirements, and may reject.
211
- Using `produces` for both would say those are the same kind of consequence.
179
+ `produces` requests an append; `invokes` also runs command gates and may reject.
212
180
 
213
181
  **Who is the caller of an `invokes`?** Nobody unless `runs as` declares the actor; see *Caller-less invokes and unprotected reads* above before writing one.
214
182
 
215
- Both are declarations of *what happens*, not of how — a trigger can state its
216
- consequences **and** carry a `file` or an inline block in a tagged fence
217
- (` ```csharp `) that implements them. That code is an implementation attachment:
218
- the model lists it (role, owner, content hash) but never runs it.
183
+ Trigger `file`/tagged-code attachments are inventoried, never reference-executed;
184
+ see the reaction forms reference for their boundary.
219
185
 
220
186
  ### What it decides from — trigger `reads`
221
187
 
@@ -237,11 +203,15 @@ Read [references/trigger-reads-example.md](references/trigger-reads-example.md)
237
203
 
238
204
  A `trigger` declares that a name exists and what an occurrence hands the reaction, never what makes it occur. Built-ins are `Startup` and `Shutdown`. An unknown name warns `PLAY0248`; **An application trigger is not a UI event** (`PLAY0326`); under a reaction trigger, values named `description`, `file`, `produces`, `invokes` or `reads` are written with `@`. Read [references/trigger-declaration.md](references/trigger-declaration.md) when declaring or registering a trigger or resolving a trigger name.
239
205
 
240
- ## Guidance, verbatim
206
+ ## Slice boundaries
207
+
208
+ Requires Screenplay 4.176.0 or later (`screenplay --version`) for PLAY0694; older compilers leave directionless capture-follow-up co-location unchecked.
241
209
 
242
- > - Reactions that only translate events into other events belong in `Translate`
243
- > slices when driven by external data (captures); event-to-event automation stays
244
- > in `Automation` slices.
210
+ > - A capture belongs in `Translate`; a reaction to the local event it appends
211
+ > belongs in a separate `Automation` slice. A directionless Translate containing
212
+ > both warns PLAY0694 (fails `--warnaserror`); explicit inbound refuses it with
213
+ > PLAY0616. A reaction translating a foreign public event can belong in inbound
214
+ > Translate.
245
215
  > - Keep reaction logic small; anything substantial belongs in a `file` reference
246
216
  > where it can be tested on its own.
247
217
  > - Describe the reaction before you implement it — a document full of `file` lines
@@ -267,8 +237,8 @@ A `trigger` declares that a name exists and what an occurrence hands the reactio
267
237
  - [ ] Every name a reaction takes is carried by the event or trigger.
268
238
  - [ ] Each trigger `reads` the views its automation decides from; `by` names a
269
239
  value the trigger takes, and clock triggers read without `by`.
270
- - [ ] Nobody reports trigger or command `reads` as protected; UI clicks are
271
- interactions, not triggers.
240
+ - [ ] Trigger reads are not protection; protected command reads require opt-in,
241
+ admission and separate target realization. UI clicks are interactions.
272
242
  - [ ] Every gated invocation declares its trusted actor with reaction `runs as`
273
243
  (ESM v10) or records the target gap explicitly; `given caller` is not that actor.
274
244
 
@@ -0,0 +1,83 @@
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
+ # Atomic reaction batches and event-source invocation mappings
5
+
6
+ ## Choose the batch boundary
7
+
8
+ Requires Screenplay 4.181.0 or later (`screenplay --version`) for atomic batches; older compilers cannot admit the declaration.
9
+
10
+ Start new models with application-root `reaction batches atomic`, before declarations.
11
+ Declare it once per composed application; imports inherit it. It selects ESM v22 or
12
+ later even before the first reaction. Duplicate, conflicting or invalid declarations
13
+ report PLAY0693. Do not automatically repair by removing it: that changes semantics.
14
+
15
+ One trigger occurrence's direct `produces` list is one all-or-none batch. Each selected
16
+ invocation-refusal branch's productions form another batch. Invoked commands retain
17
+ their own atomic appends; neither separate triggers nor occurrences are combined.
18
+ This is not a transaction around the cascade.
19
+
20
+ Candidates are materialized and append-validated before private projections and
21
+ publications. Primary facts are adopted first, then derived publications; only adopted
22
+ facts start cascades. The complete expanded result must fit the 1,000-new-fact budget
23
+ before adoption; given history does not count. A failed batch leaves its pre-batch
24
+ facts, read models and pending children unchanged. Earlier accepted batches/commands
25
+ remain. Violation order is authored production order, then ordinal constraint name;
26
+ SemanticRejected.Production carries the zero-based index, event contract and route.
27
+ Property-value reservations within a batch are not freed when a source changes value;
28
+ the same source may repeat its own claim.
29
+
30
+ Without the preamble, per-fact production remains legacy behavior, even at a higher
31
+ ESM version. Recompiling never opts an existing model in. Review migration explicitly.
32
+ Atomic batching does not admit direct-production stream routes or closing constraints,
33
+ deduplicate redelivery, promise atomic observer snapshots or resolve unknown storage
34
+ outcomes. `then error` alone is insufficient: also assert no facts from the failed
35
+ batch and unchanged read models with evaluator world/read-model assertions; earlier
36
+ accepted work can remain. `then no events` means accepted zero outcomes and cannot
37
+ accompany `then error`. Do not invent a mixed success/error specification form.
38
+
39
+ Stage refuses ESM v22 with STAGE-ESM-016. Even an admitted v23–v25 model carrying
40
+ atomic mode is refused with STAGE-ESM-043 by renderer, Host and specification executor.
41
+ Keep the declaration and report authorized gap-fill; do not promise a render date or
42
+ strip atomicity to lower the version.
43
+
44
+ MCP `describe-application` reports `reactionProductionMode` and
45
+ `reactionProductionReadiness`; ApplicationSyntax.reactionProductionMode is Atomic.
46
+ Source/AST proposals preserve it; readiness is not target realization.
47
+
48
+ ## Map the triggering event source
49
+
50
+ Requires Screenplay 4.197.1 or later (`screenplay --version`) for event-source `invokes` mappings; older compilers refuse them with PLAY0268.
51
+
52
+ Use context identity rather than duplicating an event source in event payload.
53
+ Complete model (atomic mode deliberately retained despite Stage's refusal):
54
+
55
+ ```screenplay
56
+ domain Orders
57
+ reaction batches atomic
58
+ module Fulfillment
59
+ feature Packing
60
+ slice StateChange PackOrder
61
+ command PackOrder
62
+ orderId String identifier
63
+ produces OrderPacked
64
+ for orderId
65
+ event OrderPacked
66
+ slice Automation PackPlacedOrder
67
+ event OrderPlaced
68
+ reaction PackPlacedOrder
69
+ when OrderPlaced
70
+ invokes PackOrder
71
+ orderId = $eventSourceId
72
+ ```
73
+
74
+ `$eventContext.eventSourceId` is equivalent. The source also works in reaction
75
+ `produces` mappings. The target must be a required scalar; reference execution checks
76
+ the value against that target type without conversion. Clock/application triggers
77
+ have no event source. This is neither clock context nor caller/audit identity and
78
+ does not select a new ESM version: it uses the reaction v6 mapping contract.
79
+ Keep authorization and a trusted reaction `runs as` where the invoked command is gated.
80
+
81
+ Run `screenplay <root> --warnaserror` and `screenplay test <root>`; expect source
82
+ validation and admitted scenarios to pass separately. A Stage refusal remains a
83
+ separate result even when both Screenplay checks pass.
@@ -49,10 +49,13 @@ convention, not enforcement. `source events` (`from <Event>` lines, ESM v9) is t
49
49
  its own closed grammar (PLAY0610/0612/0616/0619/0620).
50
50
 
51
51
  **`key <property>`** names the source property identifying an instance. From ESM v6
52
- a capture without a `key` does not bind (`PLAY0268`). In a specification the
52
+ a capture without a `key` does not bind (`PLAY0268`). For record sources the
53
53
  reference is handed records (`given capture`, `when capture`) and never contacts a
54
- `source`, which stays realization metadata; events append to the event source the
55
- record's `key` names, and `$context.occurred` is the scenario's `given clock`.
54
+ `source`, which stays realization metadata. For `source events`, present a declared
55
+ `from` event with `given <Event>` / `when append <Event>` (PLAY0701 otherwise);
56
+ `key` must be a required property of every source event, not a context key
57
+ (PLAY0700). Events append to the event source the key names, and
58
+ `$context.occurred` is supplied by the scenario's `given clock`.
56
59
 
57
60
  An event's external origin is declared on the `event` itself with `event X from "<origin>"` (ESM v9);
58
61
  outside records still enter through a `capture` in a `Translate` slice
@@ -60,7 +63,14 @@ outside records still enter through a `capture` in a `Translate` slice
60
63
 
61
64
  **`map`** reshapes properties before events are appended (rename, template, `translate`, `split`; mapping sources are `$.`, `$context.` and `$env.`); syntax is in the reference file linked above.
62
65
 
63
- **`append <Event>`** with optional `tag` lines and one `when` clause:
66
+ **First observation is added only**, at root, child and nested levels. Field-change
67
+ and transition guards need a previous record of the same key (`given capture`), or
68
+ earlier typed events for `source events`. Use a separate `when added` append for
69
+ first sight; keep the field guard for updates. Maps, expression guards and unguarded
70
+ record appends are unchanged. Complete runnable record cases:
71
+ [record-capture-specifications.md](record-capture-specifications.md).
72
+
73
+ **`append <Event>`** takes optional `tag` lines and at most one `when` clause:
64
74
 
65
75
  | `when` form | Appends when |
66
76
  | --- | --- |
@@ -0,0 +1,59 @@
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
+ # Reaction trigger and effect forms
5
+
6
+ Excerpts from `complete-examples.md`: "Reaction on a declared trigger with `where`
7
+ and `invokes`" and "Reaction with `produces` and `invokes`".
8
+
9
+ ```screenplay excerpt
10
+ slice Automation NotifyOnBuildFailure
11
+ reaction NotifyOnFailure
12
+ description "Tells the owning team when a watched build fails"
13
+ when BuildFinished
14
+ repository
15
+ outcome
16
+ invokes SendFailureNotice
17
+ repository = repository
18
+ outcome = outcome
19
+ where outcome == "failed"
20
+ ```
21
+
22
+ | Form | Runs |
23
+ | --- | --- |
24
+ | `when <Name>` | on that event, declared trigger, or registered trigger |
25
+ | `every <n> seconds\|minutes\|hours\|days` | on that interval (`n` ≥ 1) |
26
+ | `at HH:mm` | every day at that time |
27
+ | `at HH:mm on <Weekday>` | every week on that day |
28
+ | `at HH:mm on day <n>` | every month on that day (`n` is 1–31) |
29
+
30
+ Time is strictly `HH:mm`. Weekday is the full English name. A bare name under a
31
+ trigger selects a value from the occurrence; it is not a new declaration. Taking
32
+ a value absent from the event/trigger shape is reported.
33
+
34
+ ```screenplay excerpt
35
+ reaction Provisioner
36
+ when InvitationAccepted
37
+ workspaceId
38
+ produces WorkspaceProvisioned
39
+ for workspaceId
40
+ workspaceId = workspaceId
41
+ invokes SendWelcomeMail
42
+ workspaceId = workspaceId
43
+ template = "welcome"
44
+ ```
45
+
46
+ A `produces` without `for` appends to the source of the triggering event. Clock,
47
+ application and built-in triggers need an explicit destination. Producing requests
48
+ an append subject to constraints; invoking also runs command authorization,
49
+ validation and requirements and may reject. They are not interchangeable.
50
+
51
+ These are declarations, not implementations. A trigger can carry a `file` or
52
+ inline tagged fence beside its consequences; the model inventories role, owner
53
+ and content hash but does not execute that attachment. Stage mixed-effect
54
+ refusals and reference unsupported outcomes remain separate checks.
55
+
56
+ `where` is reaction-level, with only one occurrence allowed; combine conditions
57
+ with `and`/`or`. Its source grammar includes `contains` and `starts with`, but the
58
+ executable binder refuses those operators with PLAY0268. Use the literal property
59
+ rules for validation, not as a way around condition admission.
@@ -0,0 +1,60 @@
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
+ # First sight and updates in record captures
5
+
6
+ Requires Screenplay 4.175.0 or later (`screenplay --version`); older reference evaluators treat fields of a first record as changed. Upgrade before relying on added-only outcomes.
7
+
8
+ For `source api`, webhook, poll and other record sources, a first record of a typed key is **added only**. `when <field>`, field-change `and`/`or` and transitions need an earlier record of that same key. For an update scenario, seed it with `given capture`. A baseline for another key does not count. To record both first sight and later changes, use separate appends with `when added` and `when <field>`; do not replace the update guard with `when added`.
9
+
10
+ This applies independently to each child identity in its parent's previous collection and each nested record: a missing/null previous nested value is new, and every child of a new parent is new. Expression guards still evaluate the mapped current record on first sight; maps and unguarded appends keep their meaning. These record fixtures are not valid for `source events`: use typed events instead (automations-and-translations [public event captures](../../cratis-screenplay-automations-and-translations/references/public-events-and-direction.md)).
11
+
12
+ The complete model separates a new observation, an update and an unchanged repeat:
13
+
14
+ ```screenplay
15
+ domain LegacyBilling
16
+ module Integration
17
+ feature Invoices
18
+ slice Translate ImportInvoiceStatus
19
+ event InvoiceStatusObserved
20
+ status String
21
+ capture InvoiceRecords
22
+ source api
23
+ api LegacyBilling
24
+ route /invoices
25
+ poll 5m
26
+ key id
27
+ append InvoiceStatusObserved
28
+ when added
29
+ status = $.status
30
+ append InvoiceStatusObserved
31
+ when status
32
+ status = $.status
33
+ specification RecordingFirstSight
34
+ when capture InvoiceRecords
35
+ id = "inv-42"
36
+ status = "sent"
37
+ then InvoiceStatusObserved
38
+ for "inv-42"
39
+ status = "sent"
40
+ specification RecordingAnUpdate
41
+ given capture InvoiceRecords
42
+ id = "inv-42"
43
+ status = "sent"
44
+ when capture InvoiceRecords
45
+ id = "inv-42"
46
+ status = "paid"
47
+ then InvoiceStatusObserved
48
+ for "inv-42"
49
+ status = "paid"
50
+ specification IgnoringAnUnchangedRecord
51
+ given capture InvoiceRecords
52
+ id = "inv-42"
53
+ status = "paid"
54
+ when capture InvoiceRecords
55
+ id = "inv-42"
56
+ status = "paid"
57
+ then no events
58
+ ```
59
+
60
+ Run `screenplay <model> --warnaserror` (zero errors/warnings), then `screenplay test <model>` (all three specifications passed). Each specification supplies its own immutable baseline; no last-seen record persists between runs. Reference execution never contacts the configured API and does not prove source acknowledgement or retry safety.
@@ -3,7 +3,11 @@
3
3
  **Specify what sets them off** (execution from ESM v6): `when clock "<instant>"`
4
4
  for a reaction on `every` or `at`, `when trigger <Trigger>` with its values for one
5
5
  on an application trigger, and `given capture` / `when capture <Capture>` with the
6
- source record's fields for a capture, then the events that should follow.
6
+ source record's fields for a record capture, then the events that should follow.
7
+ For `source events`, use `given <FromEvent>` / `when append <FromEvent>` instead
8
+ (PLAY0701). First sight is `added` only; update guards need the same key's prior
9
+ record or events. See [record capture cases](record-capture-specifications.md) and
10
+ [public event captures](../../cratis-screenplay-automations-and-translations/references/public-events-and-direction.md).
7
11
  `given clock` fixes the occurrence time, so values mapped from `$context.occurred`
8
12
  can be asserted. Excerpt of the complete example in [complete-examples.md](complete-examples.md):
9
13
 
@@ -50,9 +50,8 @@ concept InvoiceStatus : Enum
50
50
  paid
51
51
  ```
52
52
 
53
- The seven primitives are `Uuid`, `String`, `Int`, `Decimal`, `Bool`, `Date` and
54
- `DateTime`. `Enum` is **not** one of them — it is a separate concept kind, which
55
- is why the compiler says *expected … or Enum* rather than listing it among them.
53
+ Primitives: `Uuid`, `String`, `Int`, `Decimal`, `Bool`, `Date`, `DateTime`.
54
+ `Enum` is a separate concept kind; details: `references/enum-numbers.md`.
56
55
  Use bare `pii` (`personal` alias) and `secret` on concepts; **Compliance is inherited**.
57
56
  Keep protection even when a compiler or renderer refuses it. Read
58
57
  [compliance and purposes](references/compliance.md) for ESM v13, binder-only refusals,
@@ -106,12 +105,12 @@ fix to migrate. `--warnaserror` does not reject information diagnostics.
106
105
  properties, `reads`, `authorize`, `validate`, `produces`/`handler`, `concurrency`.
107
106
  Keep to it.
108
107
 
109
- ⚠️ **`produces` and `handler` are mutually exclusive** — declaring both is an
110
- error. Everything else may repeat except `description` (one) and `concurrency`
111
- (one). A `handler` parses but **never binds**, with or without an `implementation`
112
- or `hint`: the binder reports `PLAY0268` ("handler requires a constrained
113
- implementation attachment"), and a `handler` is not one of the opaque bodies below.
114
- Prefer `produces` when the model must run or render.
108
+ A file/code `handler` cannot coexist with `produces` and still fails binding
109
+ with PLAY0268. A pending `handler implementation` beside unconditional `produces`
110
+ is a described command (ESM v23): the body owns payload values only. Prefer plain
111
+ `produces` for declarative logic. Read [described handlers](references/described-handlers.md)
112
+ when logic needs prose, for the result contract, PLAY0695–0698, Unsupported
113
+ ImplementationBody and Stage's STAGE-IMPL-002 refusal (no stubs, even in Stub mode).
115
114
 
116
115
  ## `identifier` — the stream boundary decision
117
116
 
@@ -149,18 +148,11 @@ alias on **every** read (`PLAY0410`), aliases are unique (`PLAY0411`) and must n
149
148
  match a command property (`PLAY0412`). A `require` path uses the alias, or the
150
149
  view name when that view is read once.
151
150
 
152
- ⚠️ **`reads` is not a protected read.** It documents the read-model-to-command
153
- arrow of the event model; nothing checks at append time that the state is still
154
- current. The executable model rejects every `reads` and `concurrency` with
155
- `PLAY0271`, and `require` over a read-model path with `PLAY0268`, until
156
- decision-consistent reads exist. Adding a
157
- `concurrency` block does not fix this: its scope is not the read's watermark, and the
158
- combination is planned to become an error once protected reads ship.
159
- When a rule depends on state:
160
-
161
- - if it is uniqueness, declare a `unique` constraint (below);
162
- - otherwise state the rule, and say in review that the target implementation
163
- must enforce it consistently. Do not claim the model guarantees it.
151
+ Opt eligible state reads into application-root `command reads protected` (v25).
152
+ Absence rejects; matching intervening facts conflict. Read [protected reads](references/protected-reads.md)
153
+ for strict admission, paths and PLAY0780–0786. Legacy reads stay unprotected;
154
+ reads/concurrency cannot combine (PLAY0783). Stage refuses protected reads (STAGE-ESM-044), not v25 itself.
155
+ Uniqueness still uses a constraint; reference success is not target realization.
164
156
 
165
157
  Do not use `reads` to fetch data the caller could supply. A composite-key view's `by` block is
166
158
  `PLAY0268` (read-surface `references/named-keys.md`).
@@ -170,8 +162,11 @@ Do not use `reads` to fetch data the caller could supply. A composite-key view's
170
162
  Each rule takes an optional `severity information|warning|error` and then an
171
163
  optional `message "<text>"` (or `$strings.<key>`). The default severity is `error`.
172
164
 
173
- The rule vocabulary (`not empty`, `min`/`max`, comparisons, `length`, `matches`, `all`, `rule <Name>`) is in
165
+ The rule vocabulary (`not empty`, `min`/`max`, comparisons, `length`, literal text rules, `matches`, `all`, `rule <Name>`) is in
174
166
  [references/validate-rules.md](references/validate-rules.md): read it when choosing or writing a rule form.
167
+ Read [text and match rules](references/text-and-match-rules.md) for ordinal `contains`,
168
+ `not contains`, `starts with`, `ends with` (v24), the portable linear match dialect,
169
+ PLAY0699/0787, Studio repairs and public pattern checks. Text rules are not conditions.
175
170
 
176
171
  ⚠️ **Validation severity is not compiler severity.** Every failed rule and
177
172
  `require` rejects the command, at `information` and `warning` too; severity only
@@ -241,8 +236,11 @@ One `concurrency` block per command; it is not bound (`PLAY0271`) and does not p
241
236
 
242
237
  UUID generation/responses bind as v7; serialized concept `generate` selects v15:
243
238
  UUIDv7/ULID/TypeID/NanoID/bytes, strict fixtures and whole-source freshness.
244
- Reuse rejects Concurrency, no append/retry. Generated rules/secrets and pattern/random/rule
245
- remain refused.
239
+ Reuse rejects Concurrency, no append/retry. Rules select v20 (Requires Screenplay
240
+ 4.164.0, `screenplay --version`); pattern/checksum, Int random and attached rules
241
+ select v21 (Requires 4.172.0). Older compilers refuse PLAY0268. Secrets and sequences
242
+ remain refused. Patterns are readable references, not gapless allocators or secrets;
243
+ check digits catch typos, not forgery. Keep uniqueness/freshness enforcement.
246
244
  Read [references/generated-values-and-responses.md](references/generated-values-and-responses.md)
247
245
  for `generated`, `generate`, `returns`, strict fixtures/freshness and renderer limits.
248
246
 
@@ -285,15 +283,15 @@ Four contexts, and **what each omits is load-bearing** — when writing a code b
285
283
  - [ ] At most one command property carries `identifier`, and no event property does.
286
284
  - [ ] Format rules live on the `concept`; state-dependent rules are specifications.
287
285
  - [ ] Every `authorize` combining policies writes `and`/`or` explicitly.
288
- - [ ] No `reads` or `concurrency` is described as protecting a decision; the gap
289
- is stated.
286
+ - [ ] Protected reads opt in, meet admission and distinguish reference protection
287
+ from target realization; legacy reads and `concurrency` imply no protection.
290
288
  - [ ] Constraints are `unique` forms; no `file` constraint stands in for another rule.
291
289
  - [ ] Each policy has one `require` or one implementation, not both.
292
290
  - [ ] Personal data is `pii` on the concept; operational secrets are `secret`;
293
291
  no identifier or subject concept carries either. Reasons explain the value,
294
292
  while purposes declare basis/retention; run `--check purposes` separately.
295
- - [ ] No `handler` where the model must bind, and no bodied construct described as
296
- runnable or renderable without saying which tool admits it.
293
+ - [ ] Described handlers distinguish binding from Unsupported body execution and
294
+ Stage refusal; attached handlers remain unbound. Name the admitting tool.
297
295
  - [ ] No event carries an optional property covering two situations.
298
296
 
299
297
  Compiler versions and admission: `cratis-screenplay-toolchain/SKILL.md`.