@cratis/pi 7.128.0 → 7.129.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.
- package/package/corpus/product-sync.json +4 -4
- package/package/corpus/skills/cratis-application-slice-conformance/SKILL.md +1 -1
- package/package/corpus/skills/cratis-arc-react-page/references/from-screenplay.md +5 -5
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/SKILL.md +6 -1
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/automation-patterns.md +1 -1
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/cases-to-specify.md +5 -5
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/statemachines-and-workflows.md +164 -0
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/todo-list-example.md +12 -15
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/translate-example.md +10 -4
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/complete-examples.md +2 -2
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/invocation-identity.md +8 -2
- package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +5 -4
- package/package/corpus/skills/cratis-screenplay-command-surface/references/described-handlers.md +12 -8
- package/package/corpus/skills/cratis-screenplay-command-surface/references/validate-rules.md +5 -5
- package/package/corpus/skills/cratis-screenplay-command-surface/verification.json +1 -1
- package/package/corpus/skills/cratis-screenplay-event-modeling/references/nine-steps.md +6 -3
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/generated-recovery.md +4 -4
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/language-reference.md +2 -2
- package/package/corpus/skills/cratis-screenplay-read-surface/references/named-keys.md +3 -1
- package/package/corpus/skills/cratis-screenplay-read-surface/references/screen-patterns.md +2 -2
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/SKILL.md +4 -4
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/renderability-gate.md +6 -5
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/SKILL.md +2 -2
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/invoicing-dues-design.md +0 -3
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/invoicing-dues-example.md +8 -3
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/scenario-examples.md +17 -9
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/spec-forms-by-mode.md +4 -3
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/version-skew.md +25 -14
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/view-and-story-specs.md +7 -6
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/verification.json +1 -1
- package/package/corpus/skills/cratis-screenplay-slice-design/references/read-model-design.md +1 -1
- package/package/corpus/skills/cratis-screenplay-slice-design/references/slicing.md +1 -1
- package/package/corpus/skills/cratis-screenplay-slice-design/references/worked-example.md +3 -3
- package/package/corpus/skills/cratis-screenplay-specifications/SKILL.md +4 -2
- package/package/corpus/skills/cratis-screenplay-specifications/references/actions-beyond-commands.md +4 -2
- package/package/corpus/skills/cratis-screenplay-specifications/references/child-ordering.md +12 -3
- package/package/corpus/skills/cratis-screenplay-specifications/references/reactions-and-cascades.md +70 -21
- package/package/corpus/skills/cratis-screenplay-specifications/references/vocabulary.md +3 -2
- package/package/corpus/skills/cratis-screenplay-specifications/verification.json +2 -2
- package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +3 -3
- package/package/corpus/skills/cratis-screenplay-toolchain/references/automation-translate-example.md +5 -8
- package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet-example.md +12 -11
- package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet.md +1 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostic-arguments.md +1 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +2 -2
- package/package/corpus/skills/cratis-screenplay-toolchain/references/executable-subset.md +10 -7
- package/package/corpus/skills/cratis-screenplay-toolchain/references/language-admission.md +4 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/preferred-syntax.md +4 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +4 -4
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract-exceptions.json +0 -70
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +4743 -623
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/traps.md +1 -1
- package/package/corpus/skills/cratis-screenplay-ui-composition/SKILL.md +6 -0
- package/package/corpus/skills/cratis-screenplay-ui-composition/references/action-subjects.md +73 -0
- package/package/corpus/skills/cratis-screenplay-ui-composition/references/file-references.md +4 -3
- package/package/corpus/skills/cratis-screenplay-ui-composition/references/response-continuations.md +1 -1
- package/package/corpus/skills/cratis-screenplay-ui-composition/references/worked-flow.md +1 -1
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +6 -5
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +8 -5
- package/package.json +1 -1
|
@@ -42,10 +42,10 @@ mode; query-performer gaps are a separate contract, not completed behavior. Prot
|
|
|
42
42
|
support is not generated-app protection.
|
|
43
43
|
Preserve contracts; reference success is not target realization.
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
older binders use PLAY0268. Read [renderability gate](references/renderability-gate.md)
|
|
45
|
+
A file/inline command handler binds beside unconditional `produces` with a resolved
|
|
46
|
+
body (v23 result contract, Screenplay 4.250.0); without them it refuses PLAY0800 with a
|
|
47
|
+
required typed `arguments.subject`. 4.210.0 to 4.249.x refuse every attached handler
|
|
48
|
+
with PLAY0800; older binders use PLAY0268. Read [renderability gate](references/renderability-gate.md)
|
|
49
49
|
when classifying a handler or other binding refusal; never parse message text.
|
|
50
50
|
|
|
51
51
|
Inline bodies (`csharp`, `typescript`, `react`, `html`, `sql`, `java`) are opaque and reach the target
|
package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/renderability-gate.md
CHANGED
|
@@ -10,10 +10,11 @@ probe reports and choosing what to do. Do not copy the code table here.
|
|
|
10
10
|
1. The CLI compiles and binds the **whole** model with its **bundled** Screenplay (the ESM level it renders is bounded by the bundle; older bundles bound less). Binding is never scoped:
|
|
11
11
|
any binding error blocks even a `--scope` render. Binding errors are `PLAY0268` (outside the admitted vertical), `PLAY0269`
|
|
12
12
|
(deferred), `PLAY0270` (report-only information), `PLAY0271` (legacy semantics) and `PLAY0273`
|
|
13
|
-
(a specification shape).
|
|
14
|
-
(`CommandHandlerRequiresAttachment`)
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
(a specification shape). A file/inline command handler without unconditional `produces`
|
|
14
|
+
or a resolved body instead reports PLAY0800 (`CommandHandlerRequiresAttachment`); beside
|
|
15
|
+
unconditional `produces` with a resolved body it binds as the v23 result contract.
|
|
16
|
+
Requires Screenplay 4.250.0 (`screenplay --version`); 4.210.0 to 4.249.x refuse every
|
|
17
|
+
attached handler with PLAY0800 and older bundled binders use PLAY0268 for these handlers. Hosts read the required typed `arguments.subject`
|
|
17
18
|
to identify the command, never the message.
|
|
18
19
|
2. Execution planning builds the plan and can emit `PLAN-*` diagnostics before Stage runs.
|
|
19
20
|
3. Stage plans the target and admits or rejects each member: `STAGE-ESM-0xx`; profile and path
|
|
@@ -36,7 +37,7 @@ ESM). Only the probe answers renderability. `PLAY0270` entries are information,
|
|
|
36
37
|
| --- | --- | --- | --- |
|
|
37
38
|
| **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
39
|
| **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` and a list-query `by` block remain PLAY0268; an unsupported query performer (observable, a non-C# body, or a missing, changed or non-compiling body) becomes an explicit implementation gap, while a verified C# body renders ([performer bodies](../../cratis-screenplay-read-surface/SKILL.md#performer-bodies-are-rendered)); a read model with several key parts or a projection keyed by parts (v27) refuses `STAGE-ESM-048` (always for a DateTime or decimal key part; the decimal refusal lifts with Stage#847 once Chronicle#5427 lands) 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
|
-
| **Implementation attachment** |
|
|
40
|
+
| **Implementation attachment** | the handler shape, not future ESM admission | file/inline command handlers without unconditional `produces` or a resolved body (PLAY0800; typed `subject` names the command) | declare unconditional `produces` beside a resolved body, split variable outcomes into separate commands, or keep the model contract and gap-fill the slice in code |
|
|
40
41
|
| **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
42
|
| **Environment** | not the model | restore failures, missing SDK, a destination that is not writable | fix the environment or report blocked |
|
|
42
43
|
|
|
@@ -175,8 +175,8 @@ Use a separate `when added` append when initial observations should produce a fa
|
|
|
175
175
|
Read captures-and-reactions `references/record-capture-specifications.md` for the
|
|
176
176
|
prerequisite and runnable cases. Include first, changed and unchanged rows in the matrix.
|
|
177
177
|
|
|
178
|
-
##
|
|
179
|
-
|
|
178
|
+
## Reaction chains: one slice per specification
|
|
179
|
+
A specification runs only its own slice. Prove a chain across slices link by link: the command's spec states its own events, the Automation's `when append` spec states what it appends, and `then invokes <Command>` (ESM v34) states a command it invokes in another slice. Another slice's event in a spec is PLAY0285. Never delete the reaction. Read [references/version-skew.md](references/version-skew.md) when a spec reports PLAY0285 or the bundled compiler is older than the standalone tool.
|
|
180
180
|
|
|
181
181
|
## Gate
|
|
182
182
|
A scope is spec-complete only when: the matrix has no `open`, `question` or `gap` cell (or the
|
|
@@ -203,9 +203,6 @@ module Invoicing
|
|
|
203
203
|
then PaymentReversed
|
|
204
204
|
for "9c1f0a52-6a4e-4b1c-9f55-0d2c7b8e1a01"
|
|
205
205
|
amount = 130
|
|
206
|
-
then RefundRequested
|
|
207
|
-
for "9c1f0a52-6a4e-4b1c-9f55-0d2c7b8e1a01"
|
|
208
|
-
amount = 130
|
|
209
206
|
|
|
210
207
|
specification RejectingAReversalWithoutAReceivedPayment
|
|
211
208
|
given caller
|
|
@@ -227,9 +227,6 @@ module Invoicing
|
|
|
227
227
|
for "9c1f0a52-6a4e-4b1c-9f55-0d2c7b8e1a01"
|
|
228
228
|
outcome = "declined"
|
|
229
229
|
reason = "Card declined"
|
|
230
|
-
then PaymentDeclined
|
|
231
|
-
for "9c1f0a52-6a4e-4b1c-9f55-0d2c7b8e1a01"
|
|
232
|
-
reason = "Card declined"
|
|
233
230
|
|
|
234
231
|
slice Automation RecordPaymentOutcome
|
|
235
232
|
reaction ReceivedTranslator
|
|
@@ -247,6 +244,14 @@ module Invoicing
|
|
|
247
244
|
event PaymentReceived
|
|
248
245
|
event PaymentDeclined
|
|
249
246
|
reason String
|
|
247
|
+
specification RecordingADeclinedPayment
|
|
248
|
+
when append PaymentGatewayResultReceived
|
|
249
|
+
for "9c1f0a52-6a4e-4b1c-9f55-0d2c7b8e1a01"
|
|
250
|
+
outcome = "declined"
|
|
251
|
+
reason = "Card declined"
|
|
252
|
+
then PaymentDeclined
|
|
253
|
+
for "9c1f0a52-6a4e-4b1c-9f55-0d2c7b8e1a01"
|
|
254
|
+
reason = "Card declined"
|
|
250
255
|
|
|
251
256
|
slice StateView OpenInvoices
|
|
252
257
|
description "Todo list: membership means 'still to collect'; there is no status flag."
|
package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/scenario-examples.md
CHANGED
|
@@ -104,9 +104,9 @@ design-mode rejection spec and `recorded` in the matrix. See `RejectingSettlemen
|
|
|
104
104
|
in `invoicing-dues-design.md`; it is never prose and never a spec that pretends to enforce it.
|
|
105
105
|
|
|
106
106
|
## 3. External failure: the capture, then the retry
|
|
107
|
-
Two separate obligations. First, the **capture specification**: concrete external input in,
|
|
108
|
-
|
|
109
|
-
vocabulary; a separate Automation records the local outcome. The capture uses
|
|
107
|
+
Two separate obligations. First, the **capture specification**: concrete external input in, the
|
|
108
|
+
provider's fact out. The provider's refusal is a fact (never a `then error`), kept in the provider's
|
|
109
|
+
vocabulary; a separate Automation records the local outcome and states it in its own specification. The capture uses
|
|
110
110
|
`when added` for first sight and a separate `when outcome` for updates. An update
|
|
111
111
|
spec needs `given capture` with the same key's earlier record; the first record's
|
|
112
112
|
fields are not modifications (root, child or nested). See captures-and-reactions
|
|
@@ -121,6 +121,15 @@ specification TranslatingADeclinedCardResult
|
|
|
121
121
|
for "9c1f0a52-6a4e-4b1c-9f55-0d2c7b8e1a01"
|
|
122
122
|
outcome = "declined"
|
|
123
123
|
reason = "Card declined"
|
|
124
|
+
```
|
|
125
|
+
The Automation that records the local outcome proves its own link in its own slice
|
|
126
|
+
(a specification runs only its slice, Screenplay decision 0115):
|
|
127
|
+
```screenplay excerpt parent=references/invoicing-dues-example.md#1
|
|
128
|
+
specification RecordingADeclinedPayment
|
|
129
|
+
when append PaymentGatewayResultReceived
|
|
130
|
+
for "9c1f0a52-6a4e-4b1c-9f55-0d2c7b8e1a01"
|
|
131
|
+
outcome = "declined"
|
|
132
|
+
reason = "Card declined"
|
|
124
133
|
then PaymentDeclined
|
|
125
134
|
for "9c1f0a52-6a4e-4b1c-9f55-0d2c7b8e1a01"
|
|
126
135
|
reason = "Card declined"
|
|
@@ -153,9 +162,11 @@ model; it tests the projection only, never the translation.
|
|
|
153
162
|
|
|
154
163
|
## 4. Compensation
|
|
155
164
|
A reversal needs a paid history, the reversal action and the exact consequence. The command spec
|
|
156
|
-
|
|
157
|
-
`RefundRequested`
|
|
158
|
-
|
|
165
|
+
states the command's own fact (`PaymentReversed`); the `RequestRefunds` Automation states
|
|
166
|
+
`RefundRequested` in its own specification, because a specification runs only its own slice
|
|
167
|
+
(Screenplay decision 0115). `RefundRequested` is a recorded request, not proof that money moved.
|
|
168
|
+
An automation that invokes another slice's command states it with `then invokes <Command>`
|
|
169
|
+
(ESM v34). What the target must do to deliver the refund is a requirement, not a spec.
|
|
159
170
|
From `invoicing-dues-design.md` (design mode; the specs do not run):
|
|
160
171
|
```screenplay excerpt parent=references/invoicing-dues-design.md#1 expect PLAY0516 test=unbound
|
|
161
172
|
specification ReversingAReceivedPayment
|
|
@@ -174,9 +185,6 @@ specification ReversingAReceivedPayment
|
|
|
174
185
|
then PaymentReversed
|
|
175
186
|
for "9c1f0a52-6a4e-4b1c-9f55-0d2c7b8e1a01"
|
|
176
187
|
amount = 130
|
|
177
|
-
then RefundRequested
|
|
178
|
-
for "9c1f0a52-6a4e-4b1c-9f55-0d2c7b8e1a01"
|
|
179
|
-
amount = 130
|
|
180
188
|
|
|
181
189
|
specification RequestingARefundAfterAReversal
|
|
182
190
|
when append PaymentReversed
|
package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/spec-forms-by-mode.md
CHANGED
|
@@ -29,7 +29,8 @@ Typed example/override forms: `cratis-screenplay-specifications`
|
|
|
29
29
|
| `when query` -> `then result` / `then no result` | yes | yes | same as `then query`: only the query-only cases below |
|
|
30
30
|
| `given clock` / `when clock`, `when trigger`, record-source `given`/`when capture` | yes | yes (standalone and any cratis whose compiler admits v6; an older bundle does not, see toolchain `references/executable-subset.md`) | no |
|
|
31
31
|
| Event-source capture fixtures | `given <FromEvent>` / `when append <FromEvent>`, not capture records (PLAY0701) | admitted root capture behavior executes; see `public-event-coverage.md` for prerequisites and limits | separate target admission |
|
|
32
|
-
| Command spec listing reaction cascade events | yes (v6 semantics) |
|
|
32
|
+
| Command spec listing its own slice's reaction cascade events | yes (v6 semantics) | yes; another slice's event is PLAY0285 (decision 0115); see SKILL.md "Reaction chains" | no: STAGE-ESM-011; generated CommandScenario does not settle reactions |
|
|
33
|
+
| `then invokes <Command>` in an Automation spec | yes | yes, ESM v34 | Stage spec runner compares it; the Cratis renderer refuses models after v33 (STAGE-ESM-016) |
|
|
33
34
|
| `generated <name> = <value>` under `when`, `then returns` (ESM v7) | yes | yes on a compiler that admits v7 (PLAY0268 on an older bundle) | yes on Stage for supported UUID/String strategies and v15 freshness and scalar/named responses; unsupported types/combinations remain -028/-038 |
|
|
34
35
|
| v15 generation strategy fixtures and used-source rejection | yes | strict encoding/size/case/version/variant; Contract for invalid pins, Concurrency for reused source | supported strategies/freshness render; invalid pins refuse -011, unpinned unordered/projected assertions -038; source: command-surface `references/generated-values-and-responses.md` |
|
|
35
36
|
| `then events in any order` | yes | yes | yes |
|
|
@@ -44,13 +45,13 @@ Typed example/override forms: `cratis-screenplay-specifications`
|
|
|
44
45
|
| Date rules using `today`, `$context`, mixed `Date`/`DateTime`, concept or reaction-`where` positions; nested paths | spec them in design | rule does not bind: `recorded` | `recorded` |
|
|
45
46
|
| Bodied rules, code policies | spec them | spec reported **unsupported**, never passed | no |
|
|
46
47
|
| Pending described command handlers (v23) | specify intent | binds; denial/validation execute, body-reaching specs Unsupported ImplementationBody; all-Unsupported is not green | STAGE-IMPL-002 even Stub mode |
|
|
47
|
-
| Attached command handlers | spec them in design |
|
|
48
|
+
| Attached command handlers | spec them in design | beside unconditional `produces` with a resolved body: binds v23, a spec reaching the body is Unsupported (`ImplementationBody`); otherwise PLAY0800, no spec runs | Stage renders a C# body; generated specifications execute verified synchronous C# handlers |
|
|
48
49
|
| `file` constraints | spec them in design | blocked: PLAY0268 at binding, no spec runs (V3 blocked) | no |
|
|
49
50
|
| Query `performer`s | spec them in design | opaque read: PLAY0270 information, left out of the executable model; a spec that reads it is left out, every other spec still runs ([version gate](../../cratis-screenplay-toolchain/references/executable-subset.md#code-attachments-what-binds-what-never-does); older compilers report PLAY0268) | no |
|
|
50
51
|
| Atomic reaction mode (v22) | declare for new models | failed batch adds no facts or view changes; earlier batches/commands remain; `then error` alone is insufficient | v22 STAGE-ESM-016; mode in admitted v23–v27 STAGE-ESM-043 |
|
|
51
52
|
| Protected command reads (v25) | declare opt-in for eligible reads | absence Validation; matching intervening facts Conflict; race vectors are not a new spec construct | Cratis C# rendering in a new enough bundle (STAGE-ESM-044 before, or for unpreservable shapes); semantic Host/executor execute admitted reads, non-Error protected requirements STAGE-ESM-045; v25 pair admitted |
|
|
52
53
|
|
|
53
|
-
Requires Screenplay 4.
|
|
54
|
+
Requires Screenplay 4.250.0 (`screenplay --version`) for attached handlers beside `produces` to bind; 4.210.0 to 4.249.x report PLAY0800 for every attached handler and older binders use PLAY0268. Other PLAY0268 families are unchanged.
|
|
54
55
|
|
|
55
56
|
Requires Screenplay 4.105.0 or later (`screenplay --version`) for list-query specifications, and 4.143.0 or later for collection equality filters (ESM v14).
|
|
56
57
|
|
package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/version-skew.md
CHANGED
|
@@ -1,14 +1,25 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
How to specify
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
# Specifying reaction chains across slices and compiler versions
|
|
2
|
+
|
|
3
|
+
How to specify a chain of reactions, and what `PLAY0285` means on each compiler.
|
|
4
|
+
|
|
5
|
+
Requires Screenplay 4.246.0 or later (`screenplay --version`) for single-slice runs and `then invokes`.
|
|
6
|
+
|
|
7
|
+
A specification runs only the slice that declares it (Screenplay decision 0115, for every model
|
|
8
|
+
and version). A chain across slices is proved link by link:
|
|
9
|
+
- The command's slice: `when <Command>` states the command's own events.
|
|
10
|
+
- The Automation slice: `when append <Trigger>` states what its reaction appends, and
|
|
11
|
+
`then invokes <Command>` (ESM v34) states a command it invokes in another slice.
|
|
12
|
+
- The invoked command's slice: `when <Command>` states that command's events.
|
|
13
|
+
|
|
14
|
+
A command spec that states another slice's event is refused with `PLAY0285` (unreachable)
|
|
15
|
+
and fails at run time with "Expected N fact(s), got M". That is a modeling error: move
|
|
16
|
+
the expectation to the slice that produces it. Never delete the reaction.
|
|
17
|
+
|
|
18
|
+
Older compilers:
|
|
19
|
+
- A compiler older than ESM v6 does not trace reactions and can report `PLAY0285` on a
|
|
20
|
+
reaction in the specification's own slice. That is tool skew: validate with the
|
|
21
|
+
standalone `screenplay <folder> --warnaserror --no-color` or a current
|
|
22
|
+
`cratis screenplay validate <folder> --warnings-as-errors`, and record which tool gave which verdict.
|
|
23
|
+
- A compiler that predates `then invokes` refuses it. With only such a tool, keep the
|
|
24
|
+
automation's own appended facts in its spec and record the pending hand-over expectation
|
|
25
|
+
in `STATE.md` as known-incomplete.
|
package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/view-and-story-specs.md
CHANGED
|
@@ -142,12 +142,13 @@ not prove an entire list is empty: assert the unkeyed list query itself (an unke
|
|
|
142
142
|
- **Projection lag**: a spec asserts the settled state. If a screen decision depends on the view
|
|
143
143
|
being current (a booking screen that must not offer a taken berth), that is not protection:
|
|
144
144
|
the command needs its own constraint, or the rule is `recorded` as target-enforced.
|
|
145
|
-
- **Rebuild**: a view rebuilt from all facts must give the same rows.
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
(`UnsupportedEventContext`)
|
|
149
|
-
|
|
150
|
-
|
|
145
|
+
- **Rebuild**: a view rebuilt from all facts must give the same rows. The reference runner
|
|
146
|
+
refuses every event-context path except the event source id and, from Screenplay 4.254.0,
|
|
147
|
+
`$eventContext.occurred` in `from`, `every` and `children` blocks
|
|
148
|
+
(`UnsupportedEventContext` otherwise). `occurred` executes only for a fact appended during
|
|
149
|
+
the run under `given clock` (`when append` or a command's production); a `given` fact
|
|
150
|
+
carries no occurrence time and the specification reports unsupported. Record the
|
|
151
|
+
remaining cases as capability gaps (keep the mapping and the intended spec in design mode).
|
|
151
152
|
- **Corrections and backdated facts**: a correction is a new fact; specify the view after it.
|
|
152
153
|
If a fact carries a business date earlier than its occurrence, specify which date the view
|
|
153
154
|
shows.
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
{ "kind": "skill-contains", "value": "Once, idempotent, exactly once are different claims" },
|
|
11
11
|
{ "kind": "skill-contains", "value": "Unauthorized is never `then error`" },
|
|
12
12
|
{ "kind": "skill-contains", "value": "find-specification-obligations" },
|
|
13
|
-
{ "kind": "skill-contains", "value": "
|
|
13
|
+
{ "kind": "skill-contains", "value": "A specification runs only its own slice." },
|
|
14
14
|
{ "kind": "skill-contains", "value": "One behaviour per spec" },
|
|
15
15
|
{ "kind": "skill-contains", "value": "No command has only two specs" },
|
|
16
16
|
{ "kind": "skill-contains", "value": "not scenario-complete" },
|
|
@@ -83,7 +83,7 @@ module Moorings
|
|
|
83
83
|
query WaitingRequests => WaitingRequest[]
|
|
84
84
|
screen WaitingListPage
|
|
85
85
|
data WaitingRequest via query WaitingRequests
|
|
86
|
-
action AssignBerth
|
|
86
|
+
action AssignBerth for item
|
|
87
87
|
slice StateChange AssignBerth
|
|
88
88
|
command AssignBerth
|
|
89
89
|
berthRequestId BerthRequestId identifier
|
|
@@ -121,8 +121,8 @@ module Lockers
|
|
|
121
121
|
column number label "Locker"
|
|
122
122
|
column volume label "Volume (l)"
|
|
123
123
|
column assigned label "Taken"
|
|
124
|
-
action InstallLocker
|
|
125
|
-
action AssignLocker
|
|
124
|
+
action InstallLocker for screen
|
|
125
|
+
action AssignLocker for item
|
|
126
126
|
specification RefusingAnAnonymousLockerLookup
|
|
127
127
|
given caller
|
|
128
128
|
then query LockerById
|
|
@@ -273,7 +273,7 @@ module Lockers
|
|
|
273
273
|
screen MyRequest
|
|
274
274
|
title "My locker request"
|
|
275
275
|
data RequestStatus via query RequestById
|
|
276
|
-
action RequestLocker
|
|
276
|
+
action RequestLocker for screen
|
|
277
277
|
specification FollowingARequestToAssignment
|
|
278
278
|
given caller
|
|
279
279
|
authenticated
|
|
@@ -186,8 +186,10 @@ Read [references/actions-beyond-commands.md](references/actions-beyond-commands.
|
|
|
186
186
|
|
|
187
187
|
## Reactions and cascades (ESM v6)
|
|
188
188
|
|
|
189
|
-
From ESM v6 every action sets reactions off and `then` events compare
|
|
190
|
-
Read [references/reactions-and-cascades.md](references/reactions-and-cascades.md) when a specification's expected events include what a reaction appends, when a cascade, clock tick or invoked command is involved, or when
|
|
189
|
+
From ESM v6 every action sets reactions off. A specification runs only the slice that declares it: only that slice's reactions, captures and publications run, and `then` events compare the new facts of that slice. A specification whose action is a command goes in the slice that declares the command and states the command's own events. Another slice's event is `PLAY0285` (unreachable): state it in the slice that produces it. An automation states a command it invokes in another slice with `then invokes <Command>` (ESM v34).
|
|
190
|
+
Read [references/reactions-and-cascades.md](references/reactions-and-cascades.md) when a specification's expected events include what a reaction appends, when a cascade, clock tick or invoked command is involved, or when a compiler reports `PLAY0285` (it holds the "Version skew and `PLAY0285`" section).
|
|
191
|
+
|
|
192
|
+
A `statemachine` or `workflow` (ESM v36) carries its own specifications with `then is`, `then sends`, `then starts`, `outcome`, `then completes`, `then fails at` and `then waits at`. Read automations-and-translations [state machines and workflows](../cratis-screenplay-automations-and-translations/references/statemachines-and-workflows.md) when specifying either.
|
|
191
193
|
|
|
192
194
|
## Published-event specifications (released ESM v9)
|
|
193
195
|
|
package/package/corpus/skills/cratis-screenplay-specifications/references/actions-beyond-commands.md
CHANGED
|
@@ -21,8 +21,10 @@ Event captures use the typed event fixtures and overlay rules in
|
|
|
21
21
|
|
|
22
22
|
Use `given clock`, never `given time`, to state the scenario occurrence time and
|
|
23
23
|
assert a value mapped from `$context.occurred`. In a command's `produces`, that
|
|
24
|
-
mapping executes when the scenario has `given clock`.
|
|
25
|
-
|
|
24
|
+
mapping executes when the scenario has `given clock`. `$eventContext.occurred` in a
|
|
25
|
+
projection is the fact's occurrence time: the reference runner executes it in `from`,
|
|
26
|
+
`every` and `children` blocks for facts appended during the run under `given clock`, and a
|
|
27
|
+
`given` fact carries none (Unsupported).
|
|
26
28
|
|
|
27
29
|
**Which tools bind these actions.** A compiler that admits ESM v6 binds the clock, trigger
|
|
28
30
|
and capture actions, and the `Automation` and `Translate` slices, reactions and captures they
|
|
@@ -69,7 +69,10 @@ module Orders
|
|
|
69
69
|
orderId = "00000000-0000-0000-0000-000000000001"
|
|
70
70
|
then readmodel OrderView
|
|
71
71
|
orderId = "00000000-0000-0000-0000-000000000001"
|
|
72
|
-
lines
|
|
72
|
+
lines
|
|
73
|
+
item
|
|
74
|
+
lineNumber = 1
|
|
75
|
+
amount = 10
|
|
73
76
|
specification ChildBeforeGivenParent
|
|
74
77
|
given LineAdded
|
|
75
78
|
orderId = "00000000-0000-0000-0000-000000000001"
|
|
@@ -79,7 +82,10 @@ module Orders
|
|
|
79
82
|
orderId = "00000000-0000-0000-0000-000000000001"
|
|
80
83
|
then readmodel OrderView
|
|
81
84
|
orderId = "00000000-0000-0000-0000-000000000001"
|
|
82
|
-
lines
|
|
85
|
+
lines
|
|
86
|
+
item
|
|
87
|
+
lineNumber = 1
|
|
88
|
+
amount = 10
|
|
83
89
|
specification ParentBeforeChild
|
|
84
90
|
given OrderAdded
|
|
85
91
|
orderId = "00000000-0000-0000-0000-000000000001"
|
|
@@ -89,7 +95,10 @@ module Orders
|
|
|
89
95
|
amount = 10
|
|
90
96
|
then readmodel OrderView
|
|
91
97
|
orderId = "00000000-0000-0000-0000-000000000001"
|
|
92
|
-
lines
|
|
98
|
+
lines
|
|
99
|
+
item
|
|
100
|
+
lineNumber = 1
|
|
101
|
+
amount = 10
|
|
93
102
|
specification ParentNeverArrives
|
|
94
103
|
given LineAdded
|
|
95
104
|
orderId = "00000000-0000-0000-0000-000000000001"
|
package/package/corpus/skills/cratis-screenplay-specifications/references/reactions-and-cascades.md
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
|
+
## Contents
|
|
2
|
+
|
|
3
|
+
- Reactions and cascades (ESM v6)
|
|
4
|
+
- An automation states the commands it invokes (ESM v34)
|
|
5
|
+
- The public event is stated in the publishing slice
|
|
6
|
+
- Version skew and `PLAY0285`
|
|
7
|
+
|
|
1
8
|
## Reactions and cascades (ESM v6)
|
|
2
9
|
|
|
3
10
|
From ESM v6 every action sets reactions off: after a command, an append, a clock
|
|
4
11
|
tick, a trigger or a capture record, each new fact runs the reactions to its event,
|
|
5
|
-
and what those append or invoke runs more, until nothing is left.
|
|
6
|
-
|
|
12
|
+
and what those append or invoke runs more, until nothing is left.
|
|
13
|
+
|
|
14
|
+
A specification runs only the slice that declares it (Screenplay decision 0115, every
|
|
15
|
+
model and version from Screenplay 4.246.0). Only that slice's reactions, captures and
|
|
16
|
+
outbound publications run; another slice's never do, so their facts cannot appear in
|
|
17
|
+
`then`, read-model or query assertions. `then` events compare the new facts of the
|
|
18
|
+
specification's own slice. A chain across slices is proved link by link: each slice's
|
|
19
|
+
specification states its own link.
|
|
7
20
|
|
|
8
21
|
```screenplay expect PLAY0469
|
|
9
22
|
concept InvoiceId : Uuid
|
|
@@ -17,16 +30,12 @@ module Collections
|
|
|
17
30
|
invoiceId = invoiceId
|
|
18
31
|
event InvoiceSent
|
|
19
32
|
invoiceId InvoiceId
|
|
20
|
-
specification
|
|
21
|
-
given clock "2026-10-02T09:00:00Z"
|
|
33
|
+
specification SendingAnInvoice
|
|
22
34
|
when SendInvoice
|
|
23
35
|
invoiceId = "9c858901-8a57-4791-81fe-4c455b099bc9"
|
|
24
36
|
then InvoiceSent
|
|
25
37
|
for "9c858901-8a57-4791-81fe-4c455b099bc9"
|
|
26
38
|
invoiceId = "9c858901-8a57-4791-81fe-4c455b099bc9"
|
|
27
|
-
then ReminderScheduled
|
|
28
|
-
for "9c858901-8a57-4791-81fe-4c455b099bc9"
|
|
29
|
-
scheduledAt = "2026-10-02T09:00:00Z"
|
|
30
39
|
slice Automation Reminders
|
|
31
40
|
reaction ReminderScheduler
|
|
32
41
|
description "Schedules a reminder when an invoice is sent"
|
|
@@ -37,11 +46,25 @@ module Collections
|
|
|
37
46
|
scheduledAt = $context.occurred
|
|
38
47
|
event ReminderScheduled
|
|
39
48
|
scheduledAt DateTime
|
|
49
|
+
specification SendingAnInvoiceSchedulesAReminder
|
|
50
|
+
given clock "2026-10-02T09:00:00Z"
|
|
51
|
+
when append InvoiceSent
|
|
52
|
+
for "9c858901-8a57-4791-81fe-4c455b099bc9"
|
|
53
|
+
invoiceId = "9c858901-8a57-4791-81fe-4c455b099bc9"
|
|
54
|
+
then ReminderScheduled
|
|
55
|
+
for "9c858901-8a57-4791-81fe-4c455b099bc9"
|
|
56
|
+
scheduledAt = "2026-10-02T09:00:00Z"
|
|
40
57
|
```
|
|
41
58
|
|
|
42
59
|
- A specification whose action is a command goes in the slice that declares that
|
|
43
60
|
command, here `SendInvoice`, not in the `Automation` slice that reacts: a command
|
|
44
61
|
from another slice is `PLAY0273` "command is unresolved in its slice" at binding.
|
|
62
|
+
It states the command's own events. The reminder is the `Reminders` slice's link,
|
|
63
|
+
stated there with `when append InvoiceSent`.
|
|
64
|
+
- Stating another slice's event in a command specification is `PLAY0285` (the
|
|
65
|
+
outcome is unreachable from the specification's slice) and fails at run time with
|
|
66
|
+
"Expected N fact(s), got M". Move the expectation to the slice that produces it;
|
|
67
|
+
never delete the reaction.
|
|
45
68
|
- A reaction invocation without a declared actor has no caller and a gated
|
|
46
69
|
command denies. Reaction `runs as system role "<Role>"` supplies the
|
|
47
70
|
authenticated system actor (ESM v10); `given caller` does not. Each command is
|
|
@@ -59,21 +82,47 @@ module Collections
|
|
|
59
82
|
or mixed effects (`-037`). Single-hop reaction append specs render; deeper appends and
|
|
60
83
|
command specs cascading into reactions remain `-011`. Keep refused scope as gap-fill against this contract: `cratis-screenplay-render-and-gap-fill`.
|
|
61
84
|
|
|
62
|
-
###
|
|
85
|
+
### An automation states the commands it invokes (ESM v34)
|
|
86
|
+
|
|
87
|
+
When a slice's reaction invokes a command another slice owns, that command is decided
|
|
88
|
+
against the world, so the reaction's `on refused` branches behave as before, but its
|
|
89
|
+
facts belong to the other slice and are not kept. The automation states the hand-over
|
|
90
|
+
with `then invokes`, the command and the values it passes (the complete model is the
|
|
91
|
+
`Reminders` slice in captures-and-reactions `references/complete-examples.md`):
|
|
92
|
+
|
|
93
|
+
```screenplay excerpt
|
|
94
|
+
specification ClosingAPaidInvoice
|
|
95
|
+
when trigger PaymentFileArrived
|
|
96
|
+
invoiceId = "9c858901-8a57-4791-81fe-4c455b099bc9"
|
|
97
|
+
amount = 120
|
|
98
|
+
then invokes CloseInvoice
|
|
99
|
+
invoiceId = "9c858901-8a57-4791-81fe-4c455b099bc9"
|
|
100
|
+
reason = "paid"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
- When a specification states at least one `then invokes`, the invocations the slice's
|
|
104
|
+
reactions made must match them exactly in count and order (any order under
|
|
105
|
+
`then events in any order`), comparing only the stated values. A refused invocation
|
|
106
|
+
counts too. A specification that states none does not compare invocations.
|
|
107
|
+
- `then invokes` selects ESM v34. The Stage spec runner compares it; the Cratis
|
|
108
|
+
renderer refuses models after v33 with `STAGE-ESM-016`.
|
|
109
|
+
- The invoked command's own events are proved by that command's slice, in its own
|
|
110
|
+
`when <Command>` specification.
|
|
111
|
+
|
|
112
|
+
### The public event is stated in the publishing slice
|
|
63
113
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
114
|
+
An outbound Translate slice that publishes a public event from private events states it
|
|
115
|
+
in its own `when append <PrivateEvent>` specification. The command that produces the
|
|
116
|
+
private event states only its own events (decision 0115 replaces the earlier rule that
|
|
117
|
+
the command's specification listed the public event).
|
|
68
118
|
|
|
69
|
-
### Version skew
|
|
119
|
+
### Version skew and `PLAY0285`
|
|
70
120
|
|
|
71
|
-
`PLAY0285` (a specification's expected event contradicts every producer of its
|
|
72
|
-
`when` command)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
green. Validate with the standalone tool or a current `cratis`, record which tool gave which
|
|
121
|
+
`PLAY0285` (a specification's expected event contradicts every possible producer of its
|
|
122
|
+
`when` command) follows the reactions, invocations and publications declared in the
|
|
123
|
+
specification's own slice. From Screenplay 4.246.0 it refuses another slice's event as
|
|
124
|
+
unreachable, and that is a modeling error: move the expectation to the slice that
|
|
125
|
+
produces the event. A compiler older than ESM v6 does not trace reactions at all and
|
|
126
|
+
can report `PLAY0285` on a reaction in the specification's own slice; that is tool skew.
|
|
127
|
+
Validate with the standalone tool or a current `cratis`, record which tool gave which
|
|
79
128
|
verdict, and see `cratis-screenplay-toolchain`.
|
|
@@ -33,7 +33,8 @@ This reference holds the given/when/then construct table and the enumeration and
|
|
|
33
33
|
| `then error` | a validation or constraint rejection, reason unnamed |
|
|
34
34
|
| `then denied` | an authorization denial (`Unauthorized`) |
|
|
35
35
|
| `for <value>` | the event source of a `given`/`then` event, or of the `when` command or appended event |
|
|
36
|
-
| `<property> = <value>` | a literal
|
|
36
|
+
| `<property> = <value>` | a scalar literal or `null` |
|
|
37
|
+
| `<property>` with an indented block | an object (`member = value` lines) or a list (one `item` line per element); `<property> none` is an empty list. Screenplay has no JSON: `lines = [...]` is PLAY0833 |
|
|
37
38
|
|
|
38
39
|
## Composite-keyed read models
|
|
39
40
|
|
|
@@ -42,7 +43,7 @@ read model with two or more `key` marks, and every specification over it, with P
|
|
|
42
43
|
|
|
43
44
|
- `given readmodel` and `then readmodel` state every key part (missing part PLAY0351,
|
|
44
45
|
repeated part PLAY0519).
|
|
45
|
-
- `then no readmodel <Type> for
|
|
46
|
+
- `then no readmodel <Type> for`, with one indented `part = value` line per part, names every part (missing PLAY0661,
|
|
46
47
|
unknown PLAY0662, repeated member PLAY0294).
|
|
47
48
|
- `when query` or `then query … arguments` supplies every `by` part of a single-instance
|
|
48
49
|
query, or the equality filters of a list query (missing, unknown or repeated PLAY0468).
|
|
@@ -77,11 +77,11 @@
|
|
|
77
77
|
},
|
|
78
78
|
{
|
|
79
79
|
"kind": "skill-contains",
|
|
80
|
-
"value": "Version skew
|
|
80
|
+
"value": "Version skew and `PLAY0285`"
|
|
81
81
|
},
|
|
82
82
|
{
|
|
83
83
|
"kind": "skill-contains",
|
|
84
|
-
"value": "
|
|
84
|
+
"value": "never delete the reaction", "file": "references/reactions-and-cascades.md"
|
|
85
85
|
},
|
|
86
86
|
{ "kind": "skill-contains", "value": "Examples typed from another document", "file": "references/examples-and-routes.md" },
|
|
87
87
|
{ "kind": "skill-contains", "value": "`PLAY0520`", "file": "references/examples-and-routes.md" }
|
|
@@ -114,9 +114,9 @@ with ordered imports means future files need explicit imports.
|
|
|
114
114
|
filters, opaque `scoped to` and a `by` block on a list query remain PLAY0268; a `performer` query is an opaque read left out of the executable model (PLAY0270; [version gate](references/executable-subset.md#code-attachments-what-binds-what-never-does)). Read
|
|
115
115
|
read-surface [equality filters](../cratis-screenplay-read-surface/references/equality-filters.md).
|
|
116
116
|
Pending handlers beside unconditional productions bind as described commands (v23),
|
|
117
|
-
but reached bodies are Unsupported; attached file/inline handlers
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
but reached bodies are Unsupported; attached file/inline handlers bind the same way
|
|
118
|
+
beside unconditional `produces` with a resolved body and otherwise
|
|
119
|
+
refuse PLAY0800.
|
|
120
120
|
Requires Screenplay 4.210.0 (`screenplay --version`); older binders use PLAY0268 for this refusal. Read `arguments.subject`, not the message, for the command.
|
|
121
121
|
Eligible protected reads opt into v25; legacy reads and `concurrency` retain PLAY0271.
|
|
122
122
|
Concept compliance binds as v13 (precise refusals: command-surface `references/compliance.md`);
|
package/package/corpus/skills/cratis-screenplay-toolchain/references/automation-translate-example.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Automation and Translate example (ESM v6)
|
|
2
2
|
|
|
3
|
-
Executable Automation and Translate slices. Binds as `executableReady` on the standalone tool and on
|
|
3
|
+
Executable Automation and Translate slices. Binds as `executableReady` (ESM v34, for `then invokes`) on the standalone tool and on a CLI whose bundled compiler is Screenplay 4.246.0 or later; see [executable-subset.md](executable-subset.md) for what renders. Shows a reaction `produces` cascade, `invokes`, `where`, clock `at`, an application trigger, a capture with translate and a transition `when`, and v6 specifications. Each specification states only its own slice (Screenplay decision 0115); the automation states the command it invokes with `then invokes` (ESM v34).
|
|
4
4
|
|
|
5
5
|
The `Renew` command is ungated so that the reaction can invoke it: this is a syntax demonstration, not a safe production design. Reactions invoke with no caller, so a real model needs a trusted path (see [cratis-screenplay-automations-and-translations](../../cratis-screenplay-automations-and-translations/SKILL.md)).
|
|
6
6
|
|
|
@@ -23,12 +23,9 @@ module Membership
|
|
|
23
23
|
given clock "2026-10-05T09:00:00Z"
|
|
24
24
|
when Subscribe
|
|
25
25
|
memberId = "5b6c1f7e-2d3a-4e8b-9c0d-1a2b3c4d5e6f"
|
|
26
|
-
then MemberSubscribed //
|
|
26
|
+
then MemberSubscribed // its own slice only: Onboarding states WelcomeSent
|
|
27
27
|
for "5b6c1f7e-2d3a-4e8b-9c0d-1a2b3c4d5e6f"
|
|
28
28
|
subscribedAt = "2026-10-05T09:00:00Z"
|
|
29
|
-
then WelcomeSent
|
|
30
|
-
for "5b6c1f7e-2d3a-4e8b-9c0d-1a2b3c4d5e6f"
|
|
31
|
-
sentAt = "2026-10-05T09:00:00Z"
|
|
32
29
|
|
|
33
30
|
slice StateChange Renew
|
|
34
31
|
command Renew // ungated for the demo only: reactions invoke with no caller
|
|
@@ -78,9 +75,9 @@ module Membership
|
|
|
78
75
|
when trigger RenewalFileArrived
|
|
79
76
|
memberId = "5b6c1f7e-2d3a-4e8b-9c0d-1a2b3c4d5e6f"
|
|
80
77
|
months = 12
|
|
81
|
-
then MembershipRenewed
|
|
82
|
-
|
|
83
|
-
months
|
|
78
|
+
then invokes Renew // ESM v34: the hand-over; Renew's slice proves MembershipRenewed
|
|
79
|
+
memberId = "5b6c1f7e-2d3a-4e8b-9c0d-1a2b3c4d5e6f"
|
|
80
|
+
months = 12
|
|
84
81
|
specification IssuingTheWeeklyReport
|
|
85
82
|
given clock "2026-10-05T07:00:00Z"
|
|
86
83
|
when clock "2026-10-05T07:30:00Z"
|