@cratis/pi 7.38.3 → 7.39.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/agents/screenplay-modeler.md +1 -1
- package/package/corpus/agents/screenplay-reviewer.md +1 -1
- package/package/corpus/product-sync.json +3 -3
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/SKILL.md +1 -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/public-events-and-direction.md +2 -5
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/todo-list-example.md +2 -5
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/translate-example.md +2 -5
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/SKILL.md +7 -11
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/complete-examples.md +6 -15
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/specifying-triggers-and-clock.md +1 -1
- package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +14 -15
- package/package/corpus/skills/cratis-screenplay-command-surface/references/compliance.md +2 -2
- package/package/corpus/skills/cratis-screenplay-command-surface/references/enum-numbers.md +2 -5
- package/package/corpus/skills/cratis-screenplay-command-surface/references/inline-events.md +23 -1
- package/package/corpus/skills/cratis-screenplay-discovery/references/provenance.md +1 -1
- package/package/corpus/skills/cratis-screenplay-event-modeling/references/invoicing-example.md +3 -7
- package/package/corpus/skills/cratis-screenplay-event-modeling/references/nine-steps.md +7 -10
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/generate-notes.md +1 -1
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/intent-example.md +3 -8
- package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +8 -3
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/language-reference.md +7 -5
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-loop.md +26 -6
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +40 -0
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/property-links.md +3 -1
- package/package/corpus/skills/cratis-screenplay-model-review/references/checklist.md +1 -1
- package/package/corpus/skills/cratis-screenplay-model-review/references/report-template.md +1 -1
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/verdicts-and-modes.md +3 -2
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/worked-example.md +2 -6
- package/package/corpus/skills/cratis-screenplay-projections/SKILL.md +2 -0
- package/package/corpus/skills/cratis-screenplay-read-surface/SKILL.md +26 -18
- package/package/corpus/skills/cratis-screenplay-read-surface/references/equality-filters.md +211 -0
- package/package/corpus/skills/cratis-screenplay-read-surface/references/screen-patterns.md +2 -5
- package/package/corpus/skills/cratis-screenplay-read-surface/verification.json +4 -0
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/renderability-gate.md +1 -1
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/worked-example.md +2 -5
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/SKILL.md +4 -1
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/berth-reservations.md +8 -19
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/invoicing-dues-design.md +8 -20
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/invoicing-dues-example.md +9 -23
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/scenario-examples.md +9 -3
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/spec-forms-by-mode.md +3 -2
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/view-and-story-specs.md +2 -1
- package/package/corpus/skills/cratis-screenplay-slice-design/SKILL.md +7 -4
- package/package/corpus/skills/cratis-screenplay-slice-design/references/model-reasoning.md +2 -5
- package/package/corpus/skills/cratis-screenplay-slice-design/references/read-model-design.md +5 -10
- package/package/corpus/skills/cratis-screenplay-slice-design/references/worked-example.md +8 -19
- package/package/corpus/skills/cratis-screenplay-specifications/SKILL.md +17 -25
- package/package/corpus/skills/cratis-screenplay-specifications/references/actions-beyond-commands.md +2 -1
- package/package/corpus/skills/cratis-screenplay-specifications/references/persona-callers-and-cases.md +2 -5
- package/package/corpus/skills/cratis-screenplay-specifications/references/source-notes.md +10 -0
- package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/streams-example.md +10 -24
- package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +11 -6
- package/package/corpus/skills/cratis-screenplay-toolchain/references/automation-translate-example.md +4 -10
- package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet-example.md +9 -20
- package/package/corpus/skills/cratis-screenplay-toolchain/references/doc-contradictions.md +2 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/executable-example.md +3 -7
- package/package/corpus/skills/cratis-screenplay-toolchain/references/executable-subset.md +24 -8
- package/package/corpus/skills/cratis-screenplay-toolchain/references/pdl-example.md +27 -69
- package/package/corpus/skills/cratis-screenplay-toolchain/references/preferred-syntax.md +73 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +2 -2
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract-exceptions.json +21 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +7 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/sources-and-streams.md +1 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/traps.md +2 -2
- package/package/corpus/skills/cratis-screenplay-toolchain/references/verdicts.md +14 -2
- package/package/corpus/skills/cratis-screenplay-toolchain/references/versions.md +25 -5
- package/package/corpus/skills/cratis-screenplay-ui-composition/SKILL.md +7 -11
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +2 -2
- package/package.json +1 -1
|
@@ -48,13 +48,9 @@ module Invoicing
|
|
|
48
48
|
amount Decimal
|
|
49
49
|
validate
|
|
50
50
|
amount > 0 message "An invoice needs an amount above zero"
|
|
51
|
-
produces InvoiceIssued
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
amount = amount
|
|
55
|
-
event InvoiceIssued
|
|
56
|
-
member MemberId
|
|
57
|
-
amount Decimal
|
|
51
|
+
produces event InvoiceIssued
|
|
52
|
+
member MemberId = member
|
|
53
|
+
amount Decimal = amount
|
|
58
54
|
constraint IssueOnce
|
|
59
55
|
unique event InvoiceIssued
|
|
60
56
|
|
|
@@ -94,17 +90,12 @@ module Invoicing
|
|
|
94
90
|
description "An invoice ends either settled or voided, never both: SettleOrVoid declares the exclusivity per invoice, enforced at append. Rules about the invoice's stored state are in invoicing-dues-design.md."
|
|
95
91
|
command SettleInvoice
|
|
96
92
|
invoiceId InvoiceId identifier
|
|
97
|
-
produces InvoiceSettled
|
|
98
|
-
for invoiceId
|
|
93
|
+
produces event InvoiceSettled
|
|
99
94
|
command VoidInvoice
|
|
100
95
|
invoiceId InvoiceId identifier
|
|
101
96
|
reason String
|
|
102
|
-
produces InvoiceVoided
|
|
103
|
-
|
|
104
|
-
reason = reason
|
|
105
|
-
event InvoiceSettled
|
|
106
|
-
event InvoiceVoided
|
|
107
|
-
reason String
|
|
97
|
+
produces event InvoiceVoided
|
|
98
|
+
reason String = reason
|
|
108
99
|
constraint SettleOrVoid
|
|
109
100
|
unique event InvoiceSettled
|
|
110
101
|
unique event InvoiceVoided
|
|
@@ -170,9 +161,7 @@ module Invoicing
|
|
|
170
161
|
description "Starts a payment attempt. PaymentRequested says only that we asked the gateway; it is NOT the outcome. The outcome arrives later as an external fact (slice PaymentGatewayResults). A request may be repeated after a decline, so there is deliberately no once-only constraint here."
|
|
171
162
|
command RequestPayment
|
|
172
163
|
invoiceId InvoiceId identifier
|
|
173
|
-
produces PaymentRequested
|
|
174
|
-
for invoiceId
|
|
175
|
-
event PaymentRequested
|
|
164
|
+
produces event PaymentRequested
|
|
176
165
|
|
|
177
166
|
specification RequestingPayment
|
|
178
167
|
given caller
|
|
@@ -374,11 +363,8 @@ module Invoicing
|
|
|
374
363
|
amount Decimal
|
|
375
364
|
validate
|
|
376
365
|
amount > 0 message "A top-up needs an amount above zero"
|
|
377
|
-
produces CreditToppedUp
|
|
378
|
-
|
|
379
|
-
amount = amount
|
|
380
|
-
event CreditToppedUp
|
|
381
|
-
amount Decimal
|
|
366
|
+
produces event CreditToppedUp
|
|
367
|
+
amount Decimal = amount
|
|
382
368
|
|
|
383
369
|
specification ToppingUpCredit
|
|
384
370
|
given caller
|
package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/scenario-examples.md
CHANGED
|
@@ -26,7 +26,7 @@ Screenplay specifications.
|
|
|
26
26
|
|---|---|---|
|
|
27
27
|
| Given | the facts that exist, each with its `for` source: `given InvoiceIssued` with `for "<invoice id>"` | "given an invoice" with no fact, no source |
|
|
28
28
|
| When | one action with every input stated | an action with inputs left to defaults |
|
|
29
|
-
| Then (success) | every
|
|
29
|
+
| Then (success) | every expected event with payload and an explicit `for`, including events the command declares inline (the inline default applies to the `produces event` declaration, not to the expectation) | "an event is produced" |
|
|
30
30
|
| Then (refusal) | `then error "Invoice already settled"`, the rule's own message | `then error` with no message, or `then error ""` |
|
|
31
31
|
| Then (denial) | `then denied` | `then error` for a caller who is not allowed |
|
|
32
32
|
| Reason | slice `documentation` says why the rule exists | the rule appears only in a spec title |
|
|
@@ -204,7 +204,13 @@ specification MemberCreditAccumulatesTopUps
|
|
|
204
204
|
```
|
|
205
205
|
|
|
206
206
|
## 6. Views: list contents and the empty list
|
|
207
|
-
A list query asserts one `result` block per expected row
|
|
207
|
+
A list query asserts one `result` block per expected row: count is exact, but rows
|
|
208
|
+
match by read model and key regardless of order. The
|
|
208
209
|
empty-list intent is a separate claim from a keyed row being absent (`view-and-story-specs.md`
|
|
209
210
|
"Removal is a positive obligation"). The backing example proves the keyed forms only; whole-list
|
|
210
|
-
queries are executable too (`ListOpenInvoices` in the backing example);
|
|
211
|
+
queries are executable too (`ListOpenInvoices` in the backing example); caller-supplied equality filters on collections bind as ESM v14 since 4.143.0.
|
|
212
|
+
Pass `by` and filters in query arguments; PLAY0468 reports unknown, repeated or
|
|
213
|
+
missing required arguments. Optional filters may be omitted, supplied null is refused.
|
|
214
|
+
Context-sourced/single-result filters, opaque `scoped to`/`performer`, and composite
|
|
215
|
+
`by` remain PLAY0268. Compiled coverage and renderer ceilings:
|
|
216
|
+
read-surface [equality filters](../../cratis-screenplay-read-surface/references/equality-filters.md).
|
package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/spec-forms-by-mode.md
CHANGED
|
@@ -17,7 +17,8 @@ Typed example/override forms: `cratis-screenplay-specifications`
|
|
|
17
17
|
| `when append <Event>` | yes | yes | no |
|
|
18
18
|
| `then readmodel` / `then query` (keyed `ById`, `arguments`, `result`) | yes | yes | yes |
|
|
19
19
|
| `then query` on an unfiltered list or a list narrowed by one `by` key (observable too) | yes | yes since 4.105.0: no `arguments` for an unkeyed list, one `result` per row stating the read-model identifier, no `result` = empty list | observable lists render, a non-observable list is `STAGE-ESM-010` (Stage 4.73.1) |
|
|
20
|
-
|
|
|
20
|
+
| Collection query with caller-supplied equality `filter`, including observable | yes | yes since 4.143.0, ESM v14: same-named scalar property/type, AND with `by`; optional omission allowed, supplied null refused; PLAY0468 checks arguments; row order does not matter | no on Stage 4.73.1 (v10 ceiling) or latest checked 4.80.0 (v13 ceiling) |
|
|
21
|
+
| Context `from`, single-result filters, `scoped to`, `performer` or composite `by` | yes | PLAY0268: query context, collection-only filtering, opaque scope/implementation or multipart lookup are unadmitted | no |
|
|
21
22
|
| `then no readmodel <RM> for "<key>"` | yes | yes | no |
|
|
22
23
|
| `when query` -> `then result` / `then no result` | yes | yes | same as `then query`: only the query-only cases below |
|
|
23
24
|
| `given clock` / `when clock`, `when trigger`, `given`/`when capture` | yes | yes (standalone and any current cratis; history: a cratis before 3.28.2 bundle no, see versions.md) | no |
|
|
@@ -40,7 +41,7 @@ cratis before 3.28.2 bundle is available). Mark each such spec in the coverage m
|
|
|
40
41
|
`gap: <reason>` for the narrower modes so the verification and render phases know what will not execute.
|
|
41
42
|
|
|
42
43
|
## Executable mode
|
|
43
|
-
- Every gated spec has `given caller`; every
|
|
44
|
+
- Every gated spec has `given caller`; every given/expected event has `for`, and so does every plain `produces <Name>` (inline `produces event` omits it and defaults to the identifier).
|
|
44
45
|
- Each read model has one key shared by its keyed `=> RM optional` queries; the identifier equals
|
|
45
46
|
the projection's effective key (`cratis-screenplay-slice-design` `references/read-model-design.md`
|
|
46
47
|
decision table). View specs assert through a keyed query.
|
package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/view-and-story-specs.md
CHANGED
|
@@ -119,7 +119,8 @@ Keep three claims apart:
|
|
|
119
119
|
- one stored instance is absent: `then no readmodel`;
|
|
120
120
|
- a query returns no rows: `then query` without `result`, or `when query` + `then no result`;
|
|
121
121
|
- a list-valued property is empty: assert that property as `[]`.
|
|
122
|
-
List-query results use repeated `result` blocks; count
|
|
122
|
+
List-query results use repeated `result` blocks; count is exact and rows match
|
|
123
|
+
by read model and instance key regardless of order. A keyed lookup does
|
|
123
124
|
not prove an entire list is empty: assert the unkeyed list query itself (an unkeyed query takes no
|
|
124
125
|
`arguments`; each `result` row states the read-model identifier, else PLAY0351). A snapshot list does not render
|
|
125
126
|
(`STAGE-ESM-010`, Stage 4.73.1); an `observable` list does. Record that rendering limit.
|
|
@@ -73,7 +73,7 @@ report and slice `documentation`, and continue.
|
|
|
73
73
|
`Save`, `Set`, `Change`, `Manage` + noun) means several decisions share a form: ask which
|
|
74
74
|
separate reasons change these values, then split (`references/slicing.md` *Generic edits*).
|
|
75
75
|
One input per thing the caller decides or supplies; `identifier` on the property naming the
|
|
76
|
-
instance (omit only for allocation); `
|
|
76
|
+
instance (omit only for allocation); inline `produces event <Name>` (no `for`) when the command owns the event; plain `produces <Name>` needs `for <identifier>`. Trace each input
|
|
77
77
|
(`references/field-lineage.md`). A conditional input is a granularity question: two
|
|
78
78
|
decisions are two commands; one decision with a dependent rule is an implication
|
|
79
79
|
(`require a == false or b > c`). Never a boolean attestation input (`confirmsX == true`)
|
|
@@ -157,9 +157,12 @@ report and slice `documentation`, and continue.
|
|
|
157
157
|
conventional `*Id` only with an admitted list query and no single-instance identifier).
|
|
158
158
|
Queryless read models need explicit `key`.
|
|
159
159
|
- At most one builder (projection or reducer) per read model (`PLAY0191`).
|
|
160
|
-
- A query's `by` goes on its own body line.
|
|
161
|
-
|
|
162
|
-
|
|
160
|
+
- A query's `by` goes on its own body line. Optional keyed and collection queries
|
|
161
|
+
bind, including observable delivery. Caller-supplied equality filters on collections
|
|
162
|
+
bind as ESM v14 since 4.143.0; `by` ANDs with supplied filters. `from`, single-result
|
|
163
|
+
filters, scope, performer and composite `by` remain PLAY0268 for their respective
|
|
164
|
+
context/cardinality/opaque/multipart gaps. Read read-surface
|
|
165
|
+
[equality filters](../cratis-screenplay-read-surface/references/equality-filters.md).
|
|
163
166
|
- A `unique` constraint names a property the event declares directly; the constraint name is
|
|
164
167
|
its identity (renaming starts an empty index).
|
|
165
168
|
- Unauthorized is `then denied`; a broken rule is `then error`; authorization runs first.
|
|
@@ -37,11 +37,8 @@ module Billing
|
|
|
37
37
|
```
|
|
38
38
|
recordId String identifier
|
|
39
39
|
amount Int
|
|
40
|
-
produces AmountRecorded
|
|
41
|
-
|
|
42
|
-
amount = amount
|
|
43
|
-
event AmountRecorded
|
|
44
|
-
amount Int
|
|
40
|
+
produces event AmountRecorded
|
|
41
|
+
amount Int = amount
|
|
45
42
|
specification RecordingAnAmount
|
|
46
43
|
description "Witnesses that the agreed amount is retained"
|
|
47
44
|
when RecordAmount amount = 10
|
package/package/corpus/skills/cratis-screenplay-slice-design/references/read-model-design.md
CHANGED
|
@@ -136,8 +136,8 @@ it stays.
|
|
|
136
136
|
| The person... | Design-mode query | Executable/renderable scope |
|
|
137
137
|
|---|---|---|
|
|
138
138
|
| opens one thing | `XById => RM optional` + `by xId XId` | binds at 4.135.0 with caller-supplied `by`; check target renderer |
|
|
139
|
-
| scans a list | `ListX => RM[]` (optionally `observable`, `filter`) | collection
|
|
140
|
-
| sees their own rows | list with scope/`from` on the caller | scope and context-derived `by` remain PLAY0268
|
|
139
|
+
| scans a list | `ListX => RM[]` (optionally `observable`, `filter`) | collection/observable delivery bind; caller-supplied equality filters bind since 4.143.0 as ESM v14; check target renderer |
|
|
140
|
+
| sees their own rows | list with scope/`from` on the caller | scope and context-derived `by`/`filter` remain PLAY0268 because portable scope/query context is unadmitted; caller-supplied filters are not access control |
|
|
141
141
|
| sees a site-wide figure | singleton read model, `from <Event> key literal "global"` on every `from` (a projection-level `key` routes nothing, PLAY0381; example in Screenplay `projections/keys.md`, "Literal keys") | check the binding (V3, `cratis-screenplay-toolchain`) |
|
|
142
142
|
|
|
143
143
|
- `observable` when people are expected to see others' or automation's changes while looking
|
|
@@ -231,11 +231,8 @@ module Berths
|
|
|
231
231
|
command BookBerth
|
|
232
232
|
bookingId BookingId identifier
|
|
233
233
|
berth BerthName
|
|
234
|
-
produces BerthBooked
|
|
235
|
-
|
|
236
|
-
berth = berth
|
|
237
|
-
event BerthBooked
|
|
238
|
-
berth BerthName
|
|
234
|
+
produces event BerthBooked
|
|
235
|
+
berth BerthName = berth
|
|
239
236
|
specification BookingABerth
|
|
240
237
|
given caller
|
|
241
238
|
authenticated
|
|
@@ -250,9 +247,7 @@ module Berths
|
|
|
250
247
|
description "A skipper cancels a booking they no longer need"
|
|
251
248
|
command CancelBooking
|
|
252
249
|
bookingId BookingId identifier
|
|
253
|
-
produces BookingCancelled
|
|
254
|
-
for bookingId
|
|
255
|
-
event BookingCancelled
|
|
250
|
+
produces event BookingCancelled
|
|
256
251
|
|
|
257
252
|
slice StateView OpenBookings
|
|
258
253
|
description "The harbour office lists bookings that still hold a berth. BerthBooked sets berth: the booking enters the list. BookingCancelled removes it: a cancelled booking never shows."
|
|
@@ -62,13 +62,9 @@ module Lockers
|
|
|
62
62
|
number LockerNumber
|
|
63
63
|
volume Litres
|
|
64
64
|
authorize IsAttendant
|
|
65
|
-
produces LockerInstalled
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
volume = volume
|
|
69
|
-
event LockerInstalled
|
|
70
|
-
number LockerNumber
|
|
71
|
-
volume Litres
|
|
65
|
+
produces event LockerInstalled
|
|
66
|
+
number LockerNumber = number
|
|
67
|
+
volume Litres = volume
|
|
72
68
|
constraint UniqueLockerNumber
|
|
73
69
|
unique number on LockerInstalled
|
|
74
70
|
message "That locker number is already installed"
|
|
@@ -141,13 +137,9 @@ module Lockers
|
|
|
141
137
|
command RequestLocker
|
|
142
138
|
requestId RequestId identifier
|
|
143
139
|
preferredVolume Litres
|
|
144
|
-
produces LockerRequested
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
requestedAt = $context.occurred
|
|
148
|
-
event LockerRequested
|
|
149
|
-
preferredVolume Litres
|
|
150
|
-
requestedAt DateTime
|
|
140
|
+
produces event LockerRequested
|
|
141
|
+
preferredVolume Litres = preferredVolume
|
|
142
|
+
requestedAt DateTime = $context.occurred
|
|
151
143
|
specification RequestingALocker
|
|
152
144
|
given caller
|
|
153
145
|
authenticated
|
|
@@ -180,11 +172,8 @@ module Lockers
|
|
|
180
172
|
message "The locker is not free"
|
|
181
173
|
require request.state == "waiting"
|
|
182
174
|
message "The request is not waiting for a locker"
|
|
183
|
-
produces LockerAssigned
|
|
184
|
-
|
|
185
|
-
requestId = requestId
|
|
186
|
-
event LockerAssigned
|
|
187
|
-
requestId RequestId
|
|
175
|
+
produces event LockerAssigned
|
|
176
|
+
requestId RequestId = requestId
|
|
188
177
|
constraint OneRequestPerLocker
|
|
189
178
|
unique event LockerAssigned
|
|
190
179
|
message "The locker is already assigned"
|
|
@@ -6,23 +6,19 @@ license: MIT
|
|
|
6
6
|
|
|
7
7
|
# Screenplay specifications
|
|
8
8
|
|
|
9
|
+
Read [preferred syntax](../cratis-screenplay-toolchain/references/preferred-syntax.md) when writing or reviewing `.play`.
|
|
10
|
+
|
|
9
11
|
A `specification` is the acceptance criterion for a slice, written in the same
|
|
10
12
|
document as the behavior it pins. Given/when/then, in business language, with
|
|
11
13
|
concrete data.
|
|
12
14
|
|
|
13
15
|
## Locate the model
|
|
14
16
|
|
|
15
|
-
Look first for the project's existing `.play` files:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
location or search the whole repository before checking it.
|
|
21
|
-
|
|
22
|
-
`cratis ai install` manages `.cratis/ai/`, never model files. Never
|
|
23
|
-
hand-copy Screenplay source between repositories. Keep Markdown that explains,
|
|
24
|
-
questions or navigates the model in the repository's documentation; the `.play`
|
|
25
|
-
source is the single flow model.
|
|
17
|
+
Look first for the project's existing `.play` files: their folder is the model.
|
|
18
|
+
For a new model, check `Source/` or `src/`, else use `Screenplay/` at the repository
|
|
19
|
+
root. Never put a model under `.cratis/` or hand-copy it between repositories.
|
|
20
|
+
`cratis ai install` manages `.cratis/ai/`, never model files. Keep explanatory
|
|
21
|
+
Markdown in project documentation; `.play` is the single flow model.
|
|
26
22
|
|
|
27
23
|
## Verified product sources
|
|
28
24
|
|
|
@@ -34,20 +30,15 @@ Specification syntax was checked against Screenplay v4.127.0 `specifications.md`
|
|
|
34
30
|
older probes in the table remain historical. Pins: `cratis-screenplay-toolchain`
|
|
35
31
|
`references/versions.md`. Compile commands check source, not reference execution.
|
|
36
32
|
Use `screenplay test` or MCP `run-specifications` for V4; Stage/target tests are
|
|
37
|
-
separate evidence.
|
|
33
|
+
separate evidence. On Screenplay **4.145.0 and later**, propose → review →
|
|
34
|
+
`run-specifications` with `proposalId` → apply.
|
|
35
|
+
PLAY0285 (an impossible `then`) unbinds the whole model and blocks every spec.
|
|
36
|
+
Unsupported/unbound is never a pass. Typed examples and
|
|
38
37
|
route assertions are in [examples and routes](references/examples-and-routes.md).
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
example below now uses inline events and canonical optionality; keep its current
|
|
44
|
-
compile check distinct from that historical execution evidence.
|
|
45
|
-
|
|
46
|
-
The specification actions beyond commands (`given clock`, `when clock`,
|
|
47
|
-
`when trigger`, `given capture`, `when capture`, `when query`, `then result`,
|
|
48
|
-
`then no result`) were checked against tag `v4.48.0` (commit `3baf4a4`):
|
|
49
|
-
`Documentation/screenplay/{specifications,diagnostics}.md` and the proposed
|
|
50
|
-
decision 0022. They do not exist before v4.48.0.
|
|
39
|
+
Read [source notes](references/source-notes.md) for the original v4.31.0
|
|
40
|
+
reference-runner evidence and v4.48.0 action syntax. Historical evidence is not
|
|
41
|
+
current execution evidence; run the changed examples at the standalone pin.
|
|
51
42
|
|
|
52
43
|
## Reference execution — what actually runs
|
|
53
44
|
|
|
@@ -171,8 +162,9 @@ the one-rejection rule (`PLAY0273`) are reported only when the model binds, so
|
|
|
171
162
|
`when append`, a model before ESM v6 expects the appended fact itself; from
|
|
172
163
|
ESM v6 the appended event is the action and `then` lists only what followed it.
|
|
173
164
|
- **Read models and query rows:** only the asserted properties must match
|
|
174
|
-
(subset); add `exactly` to require every property.
|
|
175
|
-
|
|
165
|
+
(subset); add `exactly` to require every property. Query row count is exact;
|
|
166
|
+
collection rows match by read model/key regardless of order. Ordering within a
|
|
167
|
+
collection-valued property is unchanged. A missing property does not match an asserted `null`.
|
|
176
168
|
- **Rejections:** `then error "<message>"` matches the message whatever the rule's
|
|
177
169
|
validation severity; no form asserts severity. Bare `then error` never matches
|
|
178
170
|
a denial. Quote a localized key: `then error "$strings.invoices.reasonRequired"`.
|
package/package/corpus/skills/cratis-screenplay-specifications/references/actions-beyond-commands.md
CHANGED
|
@@ -21,7 +21,8 @@ report the complete example in [reactions-and-cascades.md](reactions-and-cascade
|
|
|
21
21
|
|
|
22
22
|
- **Screenplay 4.66.0 (ESM v6, from 4.61.0), standalone and `cratis` 3.28.2:** the clock, trigger
|
|
23
23
|
and capture actions, and the `Automation` and `Translate` slices, reactions and
|
|
24
|
-
captures they drive, bind. The reference runner executes them
|
|
24
|
+
captures they drive, bind. The reference runner executes them through `screenplay test` or MCP
|
|
25
|
+
`run-specifications`, with
|
|
25
26
|
the semantics in [Reactions and cascades](reactions-and-cascades.md).
|
|
26
27
|
- **`cratis` before 3.28.2 (Screenplay 4.60.1, ESM v1-v5):**
|
|
27
28
|
**`when query` executed. The clock, trigger and capture actions did not.** They parsed, printed and were
|
|
@@ -63,11 +63,8 @@ module Billing
|
|
|
63
63
|
validate
|
|
64
64
|
require amount > 0
|
|
65
65
|
message "The amount must be positive"
|
|
66
|
-
produces AmountRecorded
|
|
67
|
-
|
|
68
|
-
amount = amount
|
|
69
|
-
event AmountRecorded
|
|
70
|
-
amount Int
|
|
66
|
+
produces event AmountRecorded
|
|
67
|
+
amount Int = amount
|
|
71
68
|
specification RecordingAmounts
|
|
72
69
|
description "An accountant can record a positive amount"
|
|
73
70
|
parameter amount Int
|
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
|
|
4
4
|
# Retained source notes
|
|
5
5
|
|
|
6
|
+
Original evidence: Screenplay v4.31.0 (`355dffb`),
|
|
7
|
+
`Documentation/screenplay/{specifications,policies,constraints,readmodels,diagnostics}.md`.
|
|
8
|
+
The original worked example had reference-runner evidence at that tag; inline
|
|
9
|
+
events and canonical optionality added later need their own current check.
|
|
10
|
+
|
|
11
|
+
Actions beyond commands (`given clock`, `when clock`, `when trigger`, `given capture`,
|
|
12
|
+
`when capture`, `when query`, `then result`, `then no result`) were checked at
|
|
13
|
+
v4.48.0 (`3baf4a4`), `Documentation/screenplay/{specifications,diagnostics}.md`
|
|
14
|
+
and proposed decision 0022. These actions do not exist before v4.48.0.
|
|
15
|
+
|
|
6
16
|
| Package | Version | Purpose |
|
|
7
17
|
| --- | --- | --- |
|
|
8
18
|
| `Cratis.Screenplay` | `4.31.0` | Original parser, binder and reference execution evidence |
|
|
@@ -49,13 +49,9 @@ module Membership
|
|
|
49
49
|
email Email
|
|
50
50
|
name String
|
|
51
51
|
authorize IsCoordinator
|
|
52
|
-
produces MemberRegistered
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
name = name
|
|
56
|
-
event MemberRegistered
|
|
57
|
-
email Email
|
|
58
|
-
name String
|
|
52
|
+
produces event MemberRegistered
|
|
53
|
+
email Email = email
|
|
54
|
+
name String = name
|
|
59
55
|
constraint UniqueMemberEmail
|
|
60
56
|
unique email on MemberRegistered
|
|
61
57
|
ignore casing
|
|
@@ -102,11 +98,8 @@ module Courses
|
|
|
102
98
|
command OpenCourse
|
|
103
99
|
courseId CourseId identifier
|
|
104
100
|
seats Int
|
|
105
|
-
produces CourseOpened
|
|
106
|
-
|
|
107
|
-
seats = seats
|
|
108
|
-
event CourseOpened
|
|
109
|
-
seats Int
|
|
101
|
+
produces event CourseOpened
|
|
102
|
+
seats Int = seats
|
|
110
103
|
specification OpeningACourse
|
|
111
104
|
given caller
|
|
112
105
|
authenticated
|
|
@@ -176,13 +169,9 @@ module Courses
|
|
|
176
169
|
validate
|
|
177
170
|
require course.openSeats > 0
|
|
178
171
|
message "The course is full" // NOT enforced: the view lags (PLAY0268 at binding)
|
|
179
|
-
produces MemberEnrolled
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
memberId = memberId
|
|
183
|
-
event MemberEnrolled
|
|
184
|
-
courseId CourseId
|
|
185
|
-
memberId MemberId
|
|
172
|
+
produces event MemberEnrolled
|
|
173
|
+
courseId CourseId = courseId // cross-stream references are payload
|
|
174
|
+
memberId MemberId = memberId
|
|
186
175
|
constraint OneActiveEnrolmentPerMemberAndCourse
|
|
187
176
|
unique courseId, memberId on MemberEnrolled
|
|
188
177
|
released by EnrolmentWithdrawn
|
|
@@ -276,11 +265,8 @@ module Courses
|
|
|
276
265
|
validate
|
|
277
266
|
require enrolment.courseId == courseId
|
|
278
267
|
message "The enrolment does not belong to that course" // NOT enforced today
|
|
279
|
-
produces EnrolmentWithdrawn
|
|
280
|
-
|
|
281
|
-
courseId = courseId
|
|
282
|
-
event EnrolmentWithdrawn
|
|
283
|
-
courseId CourseId
|
|
268
|
+
produces event EnrolmentWithdrawn
|
|
269
|
+
courseId CourseId = courseId
|
|
284
270
|
constraint WithdrawOnce
|
|
285
271
|
unique event EnrolmentWithdrawn
|
|
286
272
|
specification WithdrawingAnEnrolment
|
|
@@ -6,6 +6,8 @@ license: MIT
|
|
|
6
6
|
|
|
7
7
|
# Screenplay toolchain
|
|
8
8
|
|
|
9
|
+
Read [preferred syntax](references/preferred-syntax.md) when writing or reviewing `.play`.
|
|
10
|
+
|
|
9
11
|
Which tool to run, what its result means, and what each tool can and cannot admit. This
|
|
10
12
|
skill answers "does it compile, bind, render, and which compiler said so". The method
|
|
11
13
|
(what to model, in which order, with which gates) lives in
|
|
@@ -22,7 +24,7 @@ files is one application: always check the folder, never one file of it.
|
|
|
22
24
|
|
|
23
25
|
When choosing or upgrading a tool, or checking version-specific capabilities, read `references/versions.md`; it is the only version table, and other skills point to it. For exact diagnostic codes, MCP names/parameters and standalone CLI options, search the large published [references/screenplay-contract.json](references/screenplay-contract.json), pinned by [references/screenplay-contract.version](references/screenplay-contract.version), rather than loading it in full. Locate a diagnostic by its exact `code` (for example `"code": "PLAY0029"`), a tool by its exact `name` (for example `"name": "read-workspace"`), or a command in `cliCommands`; read the matched object for retirement, parameters or options. [references/screenplay-contract-exceptions.json](references/screenplay-contract-exceptions.json) records reasoned exceptions for historical statements; it does not change the current contract.
|
|
24
26
|
|
|
25
|
-
The standalone pin is Screenplay 4.
|
|
27
|
+
The standalone pin is Screenplay 4.145.0.
|
|
26
28
|
CLI and bundled package pins: `references/versions.md`. The single version table records
|
|
27
29
|
released source evidence and historical probes separately; do not relabel an old
|
|
28
30
|
render/browser result as a probe of the current packages.
|
|
@@ -31,7 +33,7 @@ Historical screens-release evidence: CLI 3.40.7 / Stage 4.51.1 / bundled
|
|
|
31
33
|
Screenplay 4.114.0 opened the canonical corpus with `executableReady true`
|
|
32
34
|
and the stdio transcript exposed 37 tools; standalone language 4.122.0 was
|
|
33
35
|
recorded in that vector. These retained results are not a rerun on CLI 3.53.1
|
|
34
|
-
or Screenplay 4.
|
|
36
|
+
or Screenplay 4.145.0.
|
|
35
37
|
|
|
36
38
|
## Ground rules
|
|
37
39
|
|
|
@@ -44,7 +46,7 @@ or Screenplay 4.142.0.
|
|
|
44
46
|
3. **Pick the compiler deliberately and name it.** Standalone `screenplay` for
|
|
45
47
|
current language checks and reference specifications; `cratis` for rendering
|
|
46
48
|
and generation. Bundled and standalone versions differ (CLI 3.53.1 bundles 4.137.0;
|
|
47
|
-
the standalone pin is 4.
|
|
49
|
+
the standalone pin is 4.145.0). Report both tool and
|
|
48
50
|
version, rather than transferring a verdict across releases.
|
|
49
51
|
4. **Know the mode** (design, executable, renderable) and write from its subset.
|
|
50
52
|
5. **Capability is not correctness.** The tool you ran decides what is accepted today; the
|
|
@@ -91,7 +93,7 @@ server with a fixed root when the tool is older than 4.63.2 (the roots bug hit 4
|
|
|
91
93
|
4.60.1 bundled by cratis before 3.28.2; 4.66.0 and later and cratis 3.28.2 are fine). A subagent without MCP reports "V2 not run: no MCP in this agent".
|
|
92
94
|
|
|
93
95
|
One line per verdict, tool first, for example `V1 pass (screenplay 4.142.0, 3 files)` and
|
|
94
|
-
`V3 blocked: PLAY0268 x3 (filter
|
|
96
|
+
`V3 blocked: PLAY0268 x3 (context filter, enum compliance)`. Name the source identity (commit plus the digest from
|
|
95
97
|
the source-identity helper (`cratis-screenplay-modeling-lifecycle` `references/verdicts-and-modes.md` "Source identity")) the verdict ran on; keep it apart from the MCP
|
|
96
98
|
`modelRevision`, which is semantic and, without `.screenplay/identities.json`,
|
|
97
99
|
changes with the root folder name.
|
|
@@ -101,7 +103,10 @@ changes with the root folder name.
|
|
|
101
103
|
- **Design**: every construct family parses; use it to model first. Compiled shapes:
|
|
102
104
|
`references/cheat-sheet.md`. Read [references/cheat-sheet-example.md](references/cheat-sheet-example.md) when you need one complete design-mode document with every construct family.
|
|
103
105
|
- **Executable** (binds, V3): `references/executable-subset.md`. Optional keyed lookups, unfiltered
|
|
104
|
-
lists and lists narrowed by one `by` key (observable too);
|
|
106
|
+
lists and lists narrowed by one `by` key (observable too); caller-supplied equality
|
|
107
|
+
filters on collections bind as v14 since 4.143.0. Context `from`, single-result
|
|
108
|
+
filters, opaque `scoped to`/`performer` and composite `by` remain PLAY0268. Read
|
|
109
|
+
read-surface [equality filters](../cratis-screenplay-read-surface/references/equality-filters.md). No handler (PLAY0268, with or without `implementation`/`hint`); `reads` and
|
|
105
110
|
`concurrency` do not bind (PLAY0271); concept compliance binds as v13 on standalone
|
|
106
111
|
4.142.0 (since 4.141.0), not the pinned CLI (precise refusals: command-surface `references/compliance.md`);
|
|
107
112
|
v6 constructs bind on Screenplay 4.61 or
|
|
@@ -168,7 +173,7 @@ All 44, with fixes: `references/traps.md`. Read `references/traps.md` when diagn
|
|
|
168
173
|
Read [references/diagnostics.md](references/diagnostics.md) when a PLAY, STAGE or CLI-RENDER diagnostic needs its meaning and fix. Read [references/doc-contradictions.md](references/doc-contradictions.md) when the Screenplay documentation and the compiler disagree and you must decide which to trust.
|
|
169
174
|
|
|
170
175
|
1. Clean V1 is not executable: only MCP (V2) or `render` binds.
|
|
171
|
-
2.
|
|
176
|
+
2. Prefer inline `produces event` for a command-owned event; plain command productions need explicit `for <identifier>`.
|
|
172
177
|
3. PLAY0029 is a warning: validate with warnings as errors.
|
|
173
178
|
4. Validate the folder; name the compiler (cli#244, cli#242).
|
|
174
179
|
5. V1 warns on undeclared projection targets (`PLAY0514`) and removal/capture
|
package/package/corpus/skills/cratis-screenplay-toolchain/references/automation-translate-example.md
CHANGED
|
@@ -17,11 +17,8 @@ module Membership
|
|
|
17
17
|
slice StateChange Subscribe
|
|
18
18
|
command Subscribe
|
|
19
19
|
memberId MemberId identifier
|
|
20
|
-
produces MemberSubscribed
|
|
21
|
-
|
|
22
|
-
subscribedAt = $context.occurred
|
|
23
|
-
event MemberSubscribed
|
|
24
|
-
subscribedAt DateTime
|
|
20
|
+
produces event MemberSubscribed
|
|
21
|
+
subscribedAt DateTime = $context.occurred
|
|
25
22
|
specification SubscribingAMember
|
|
26
23
|
given clock "2026-10-05T09:00:00Z"
|
|
27
24
|
when Subscribe
|
|
@@ -39,11 +36,8 @@ module Membership
|
|
|
39
36
|
months Int
|
|
40
37
|
validate
|
|
41
38
|
months > 0 message "Renew for at least one month"
|
|
42
|
-
produces MembershipRenewed
|
|
43
|
-
|
|
44
|
-
months = months
|
|
45
|
-
event MembershipRenewed
|
|
46
|
-
months Int
|
|
39
|
+
produces event MembershipRenewed
|
|
40
|
+
months Int = months
|
|
47
41
|
specification RejectingAZeroRenewal
|
|
48
42
|
when Renew
|
|
49
43
|
memberId = "5b6c1f7e-2d3a-4e8b-9c0d-1a2b3c4d5e6f"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
One complete document with every construct family. Design mode, not executable. Prose rules: [cheat-sheet.md](cheat-sheet.md); tool versions: [versions.md](versions.md); what binds: [executable-subset.md](executable-subset.md).
|
|
4
4
|
|
|
5
|
-
Binding blockers: unquoted import, `reads` (PLAY0271), `starts with
|
|
5
|
+
Binding blockers: unquoted import, `reads` (PLAY0271), `starts with`. Caller-supplied collection equality filters bind as ESM v14 since 4.143.0; context/single-result filters remain blocked. Executable shapes are in the sibling examples. The bare-marker fence compiles warning-free on standalone 4.127.0; the earlier legacy-marker version compiled on 4.66.0 and CLI 3.28.2. `RecordingAPayment` lists the `InvoiceClosed` cascade, which the cratis 3.27.1 bundle (4.60.1) rejected with a false PLAY0285 ("outcome cannot be produced by 'RecordPayment'"); 3.28.2 accepts it.
|
|
6
6
|
|
|
7
7
|
Concept compliance itself binds as ESM v13 on standalone 4.142.0 (first released
|
|
8
8
|
in 4.141.0); reasons remain report-only PLAY0270. CLI 3.53.1 bundles Screenplay
|
|
@@ -135,9 +135,7 @@ module Billing
|
|
|
135
135
|
command CancelInvoice
|
|
136
136
|
invoiceId InvoiceId identifier
|
|
137
137
|
authorize CanManage
|
|
138
|
-
produces InvoiceCancelled
|
|
139
|
-
for invoiceId
|
|
140
|
-
event InvoiceCancelled
|
|
138
|
+
produces event InvoiceCancelled
|
|
141
139
|
specification CancellingAnInvoice
|
|
142
140
|
given caller
|
|
143
141
|
authenticated
|
|
@@ -161,7 +159,7 @@ module Billing
|
|
|
161
159
|
number String
|
|
162
160
|
query InvoiceById => InvoiceRow optional // keyed optional lookup (unfiltered lists bind too)
|
|
163
161
|
by invoiceId InvoiceId
|
|
164
|
-
query ListInvoices => observable InvoiceRow[] //
|
|
162
|
+
query ListInvoices => observable InvoiceRow[] // caller-supplied equality filter: ESM v14 since 4.143.0
|
|
165
163
|
filter number String optional
|
|
166
164
|
projection InvoiceList => InvoiceRow
|
|
167
165
|
from InvoiceRegistered
|
|
@@ -214,13 +212,9 @@ module Billing
|
|
|
214
212
|
paymentId PaymentId identifier
|
|
215
213
|
invoiceId InvoiceId
|
|
216
214
|
amount Decimal
|
|
217
|
-
produces PaymentRecorded
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
amount = amount
|
|
221
|
-
event PaymentRecorded
|
|
222
|
-
invoiceId InvoiceId
|
|
223
|
-
amount Decimal
|
|
215
|
+
produces event PaymentRecorded
|
|
216
|
+
invoiceId InvoiceId = invoiceId // cross-stream reference is payload
|
|
217
|
+
amount Decimal = amount
|
|
224
218
|
specification RecordingAPayment
|
|
225
219
|
given caller
|
|
226
220
|
authenticated
|
|
@@ -242,9 +236,7 @@ module Housekeeping // no gates: this reaction
|
|
|
242
236
|
slice StateChange CloseInvoice
|
|
243
237
|
command CloseInvoice
|
|
244
238
|
invoiceId InvoiceId identifier
|
|
245
|
-
produces InvoiceClosed
|
|
246
|
-
for invoiceId
|
|
247
|
-
event InvoiceClosed
|
|
239
|
+
produces event InvoiceClosed
|
|
248
240
|
specification ClosingAnInvoice
|
|
249
241
|
when CloseInvoice
|
|
250
242
|
invoiceId = "9c858901-8a57-4791-81fe-4c455b099bc9"
|
|
@@ -254,11 +246,8 @@ module Housekeeping // no gates: this reaction
|
|
|
254
246
|
slice StateChange MarkOverdue
|
|
255
247
|
command MarkOverdue
|
|
256
248
|
invoiceId InvoiceId identifier
|
|
257
|
-
produces InvoiceMarkedOverdue
|
|
258
|
-
|
|
259
|
-
overdueAt = $context.occurred
|
|
260
|
-
event InvoiceMarkedOverdue
|
|
261
|
-
overdueAt DateTime
|
|
249
|
+
produces event InvoiceMarkedOverdue
|
|
250
|
+
overdueAt DateTime = $context.occurred
|
|
262
251
|
// No command spec here: under ESM v6 it must list the ReminderSent cascade. The file is
|
|
263
252
|
// RecordingAPayment's cascade got a false PLAY0285 on cratis before 3.28.2; 3.28.2 accepts it.
|
|
264
253
|
// The cascade form: automation-translate-example.md (SubscribingAMember).
|
|
@@ -41,13 +41,14 @@ read from source or documentation.
|
|
|
41
41
|
| 7 | interaction examples | `D/interactions.md:33` uses `button` | PLAY0103; `on double click` on `table` compiles though not in the EBNF |
|
|
42
42
|
| 8 | where screens live | `D/screens.md:3` "inside `StateView` slices" | samples also put dialogs in `StateChange` |
|
|
43
43
|
| 9 | where reducers live | `D/slices.md:74` and `D/glossary.md:21` call a reducer an `Automation` thing vs `D/slices.md:87` (`StateView`) | `StateView` (samples) |
|
|
44
|
+
| Query rows | Older specification guidance promises authored result-row order | Screenplay v4.145.0 `specifications.md:307-319,426`: compare collections without regard to order, by read-model/key and exact count. Event ordering and collection-valued property ordering are separate |
|
|
44
45
|
| 10 | `then` after `when append` | `D/specifications.md:67` "must match exactly the appended fact" vs `:232` and `:282` (v6: what followed it) | v6 text on the standalone tool; before v6, `:67` |
|
|
45
46
|
| 11 | constraint collision across sources | `D/constraints.md:118` "cannot yet show" vs `D/specifications.md:77` (`for` lets a spec claim a value on another source) | `specifications.md` (newer) |
|
|
46
47
|
| 12 | capture backtick `when` | opaque (`D/captures/grammar.md:321`) vs small portable grammar (`D/captures.md:94`) | both: storage versus binder |
|
|
47
48
|
| 13 | clock boundary | resolved: an occurrence fires if due **after** the given clock and **at or before** the when clock (`D/specifications.md:282-284`; `Semantics/Execution/SemanticClock.cs`, `at > from && at <= to`). Given equal to when fires nothing, so the Screenplay sample `Samples/Commerce/Fulfillment/Shipping/ReleasePickingWave.play:20-22` (06:00 to 06:00, expecting `PickingWaveReleased`) is wrong | the code; never write given equal to when. A Screenplay issue for the sample is a candidate |
|
|
48
49
|
| 14 | `$causedBy` | not evaluable (#4119), not ESM | showcase only |
|
|
49
50
|
| 15 | literal keys | `key literal "global"` vs `key "global"` | both compile; prefer `literal` |
|
|
50
|
-
| 16 | query admission | `D/queries.md:74`
|
|
51
|
+
| 16 | query admission | Older `D/queries.md:74` and historical binder probes rejected live/collection/filter queries | Current v4.145.0 `queries.md` admits collection/observable queries and caller-supplied equality filters (ESM v14 since 4.143.0). Context `from`, single-result filters, opaque scope/performer and composite `by` remain PLAY0268 with specific reasons; source/refusal details: read-surface `references/equality-filters.md` |
|
|
51
52
|
| 17 | `@pii` | `D/concepts.md:3,33` "Chronicle applies `@pii` and `@sensitive` rules automatically" | the historical binder rejected any compliance attribute (PLAY0268); standalone 4.142.0 admits concept compliance as v13 (since 4.141.0) with narrower enum/identity/subject-lineage refusals (command-surface `references/compliance.md`). Keep protection; the pinned CLI still reports V3 blocked. `@sensitive` means an operational secret (`[Encrypted]` + `[NotAudited]`; Screenplay decision 0034); the historically probed tools (standalone 4.68.0, bundle 4.66.0) do **not** report `PLAY0515` (`@pii` from 4.69.1, `@sensitive` from 4.84.1): there only Chronicle catches either attribute on an event-source identifier, at build time of the generated code (CHR0034 for `@pii`, CHR0052 for `@sensitive`) |
|
|
52
53
|
| 18 | read-model identity | `D/readmodels.md:32` "from the keyed query" | at 4.135.0 explicit `key` wins; else single-instance queries agree on one read-model `by` property; only with none and an admitted list query does conventional `*Id` inference run (collection-key exclusions: read-surface `references/named-keys.md`). Queryless views need explicit `key` |
|
|
53
54
|
| 19 | `$strings` constraint messages | `D/constraints.md:31` vs `D/internationalization.md:55` | the compiler keeps the key; realization localizes |
|