@cratis/pi 7.106.0 → 7.107.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.
@@ -171,9 +171,9 @@
171
171
  }
172
172
  ],
173
173
  "synced": {
174
- "version": "4.235.0",
175
- "date": "2026-10-19",
176
- "by": "Cratis/AI#837"
174
+ "version": "4.244.0",
175
+ "date": "2026-10-20",
176
+ "by": "Cratis/AI#891"
177
177
  },
178
178
  "covers": {
179
179
  "skills": [
@@ -113,7 +113,7 @@ module Integration
113
113
  source events
114
114
  from ShipmentDispatched
115
115
  from ShipmentDelivered
116
- key orderId
116
+ key orderId is event source
117
117
  append OrderDispatched
118
118
  when added
119
119
  carrier = $.carrier
@@ -163,6 +163,13 @@ must be required on every `from` event (PLAY0700); `$eventSourceId` and other co
163
163
  keys are refused. An empty or whitespace-only text key fails execution, even in a
164
164
  given before the action; non-text/non-numeric keys are Unsupported.
165
165
 
166
+ The example declares `is event source` because the producer sources every event by
167
+ `orderId`.
168
+ Requires Screenplay 4.242.0 and ESM v33. A fixture `for` must then equal the key;
169
+ without `for`, it takes the key. Unmarked captures stay unchanged. Other
170
+ sources or non-single-property keys report PLAY0809, with no automatic repair. Read
171
+ [event-source keys](../../cratis-screenplay-captures-and-reactions/references/capture-map-and-example.md#keying-by-the-event-source).
172
+
166
173
  Givens fold in authored order without appending. Each event overlays its top-level
167
174
  properties onto state for that typed key: absent properties retain earlier values;
168
175
  objects/lists replace whole values. First sight is `added` only, unchanged overlays
@@ -8,6 +8,10 @@
8
8
  { "kind": "skill-contains", "value": "then OrderShipped", "file": "references/public-events-and-direction.md" },
9
9
  { "kind": "skill-contains", "value": "typed Unsupported", "file": "references/public-events-and-direction.md" },
10
10
  { "kind": "play-compiles" },
11
+ { "kind": "skill-contains", "value": "key orderId is event source", "file": "references/public-events-and-direction.md" },
12
+ { "kind": "skill-contains", "value": "Requires Screenplay 4.242.0 and ESM v33", "file": "references/public-events-and-direction.md" },
13
+ { "kind": "skill-contains", "value": "PLAY0809, with no automatic repair", "file": "references/public-events-and-direction.md" },
14
+ { "kind": "skill-contains", "value": "Unmarked captures stay unchanged", "file": "references/public-events-and-direction.md" },
11
15
  { "kind": "skill-contains", "value": "`[ExecuteCommandsAsSystem(\"<role>\")]`" },
12
16
  { "kind": "skill-contains", "value": "ESM v10" },
13
17
  { "kind": "skill-contains", "value": "STAGE-ESM-024" },
@@ -1,5 +1,11 @@
1
1
  # Capture map and example
2
2
 
3
+ ## Contents
4
+
5
+ - Capture excerpt
6
+ - Capture `map`
7
+ - Keying by the event source
8
+
3
9
  ## Capture excerpt
4
10
 
5
11
  ```screenplay excerpt
@@ -57,6 +63,11 @@ reference is handed records (`given capture`, `when capture`) and never contacts
57
63
  (PLAY0700). Events append to the event source the key names, and
58
64
  `$context.occurred` is supplied by the scenario's `given clock`.
59
65
 
66
+ For a producer that sources every event by this key, declare
67
+ `key <property> is event source` (ESM v33, Screenplay 4.242.0).
68
+ See [Keying by the event source](#keying-by-the-event-source) below for the promise, fixture `for`
69
+ checks and the PLAY0809 restriction to single-property `source events` keys.
70
+
60
71
  An event's external origin is declared on the `event` itself with `event X from "<origin>"` (ESM v9);
61
72
  outside records still enter through a `capture` in a `Translate` slice
62
73
  (`cratis-screenplay-automations-and-translations` `references/public-events-and-direction.md`).
@@ -87,3 +98,71 @@ compile error. Split it into two `append` blocks.
87
98
 
88
99
  **`children <collection> identified by <path>`** and **`nested <path>`** each take
89
100
  an optional `map` and any number of `append` blocks.
101
+
102
+ ## Keying by the event source
103
+
104
+ Requires Screenplay 4.242.0 or later (`screenplay --version`). The marker selects
105
+ ESM v33 and serializes `keyIsEventSource` beside `sourceEvents`. A capture without
106
+ it keeps its earlier behavior, version and bytes.
107
+
108
+ Declare `key <property> is event source` only when the producer sources **every**
109
+ captured event by that property's value. This is a promise about the foreign
110
+ stream, not a request to move an event to another source. It lets a renderer that
111
+ admits v33 narrow an inbox history read by event source id. Binding and reference
112
+ execution do not prove the renderer or deployed observer realizes that promise.
113
+
114
+ Only a `source events` capture with a single property key may declare the marker.
115
+ Other capture sources or key shapes report PLAY0809, an error with no automatic
116
+ repair. The key must still be required on every `from` event (PLAY0700); the marker
117
+ does not permit `$eventSourceId` as the key expression.
118
+
119
+ ### Typed fixtures
120
+
121
+ - An explicit fixture `for` must equal the key. A mismatch rejects execution with
122
+ a contract rejection naming the capture, event and both values. Do not turn it
123
+ into an accepted `then no events` scenario.
124
+ - A fixture without `for` takes the key as its source **before** projections and
125
+ reactions see it, so `$eventSourceId` is the key.
126
+ - The check also runs while establishing givens, including a world with no action.
127
+ - Without the marker, an optional foreign fixture `for` stays opaque non-empty
128
+ text, independent of the capture key. Do not add the marker just to fix a fixture.
129
+
130
+ This complete model uses a producer that sources dispatches by `orderId`:
131
+
132
+ ```screenplay
133
+ module Shipping
134
+ feature Tracking
135
+ slice Translate ReceiveDispatches
136
+ direction inbound
137
+ event ParcelDispatched from "carrier"
138
+ orderId String
139
+ event DispatchRecorded
140
+ orderId String
141
+ capture DispatchFeed
142
+ source events
143
+ from ParcelDispatched
144
+ key orderId is event source
145
+ append DispatchRecorded
146
+ when added
147
+ orderId = $.orderId
148
+ specification RecordingADispatch
149
+ when append ParcelDispatched
150
+ for "order-42"
151
+ orderId = "order-42"
152
+ then DispatchRecorded
153
+ for "order-42"
154
+ orderId = "order-42"
155
+ specification TakingTheKeyAsSource
156
+ when append ParcelDispatched
157
+ orderId = "order-42"
158
+ then DispatchRecorded
159
+ for "order-42"
160
+ orderId = "order-42"
161
+ ```
162
+
163
+ Changing the first fixture's `for` to `"other-order"` rejects the run; it is not a
164
+ new stream to accept silently. Test that rejection and the given-only mismatch
165
+ through evaluator outcomes as well as the two successful source forms.
166
+
167
+ Authority: Screenplay [captures](https://github.com/Cratis/Screenplay/blob/main/Documentation/screenplay/captures.md#keying-by-the-event-source)
168
+ and [capture grammar](https://github.com/Cratis/Screenplay/blob/main/Documentation/screenplay/captures/grammar.md).
@@ -5,6 +5,14 @@
5
5
  "assertions": [
6
6
  { "kind": "skill-contains", "value": "unrouted facts never match" },
7
7
  { "kind": "skill-contains", "value": "source events" },
8
+ { "kind": "skill-contains", "file": "references/capture-map-and-example.md", "value": "PLAY0809, an error" },
9
+ { "kind": "skill-contains", "file": "references/capture-map-and-example.md", "value": "ESM v33" },
10
+ { "kind": "skill-contains", "file": "references/capture-map-and-example.md", "value": "key orderId is event source" },
11
+ { "kind": "skill-contains", "file": "references/capture-map-and-example.md", "value": "`keyIsEventSource` beside `sourceEvents`" },
12
+ { "kind": "skill-contains", "file": "references/capture-map-and-example.md", "value": "earlier behavior, version and bytes" },
13
+ { "kind": "skill-contains", "file": "references/capture-map-and-example.md", "value": "An explicit fixture `for` must equal the key" },
14
+ { "kind": "skill-contains", "file": "references/capture-map-and-example.md", "value": "A fixture without `for` takes the key as its source" },
15
+ { "kind": "skill-contains", "file": "references/capture-map-and-example.md", "value": "givens, including a world with no action" },
8
16
  { "kind": "play-compiles" },
9
17
  {
10
18
  "kind": "skill-contains",
@@ -8,6 +8,7 @@
8
8
  - Exact numeric source mode
9
9
  - Clause order inside a command (canonical)
10
10
  - Slice contents (typical)
11
+ - Event-source capture keys (ESM v33)
11
12
  - `$context.` paths (command `produces`)
12
13
  - `$eventContext.` (projections)
13
14
  - PDL quick reference (most forms are compiled in `pdl-example.md` or `cheat-sheet-example.md`; `remove via join` and `$eventContext.occurred` are not)
@@ -139,6 +140,17 @@ description, properties, `reads`, `authorize`, `validate`, `produces`/`handler`,
139
140
  - `slice Translate <Behaviour>`: capture and/or translator reaction + both vocabularies' events.
140
141
  - Declare each event once, in the slice that produces it; reference it by name elsewhere.
141
142
 
143
+ ## Event-source capture keys (ESM v33)
144
+
145
+ For inbound `source events` captures only, a single-property
146
+ `key <property> is event source` promises every incoming event is sourced by that
147
+ key (Screenplay 4.242.0; serializes `keyIsEventSource` beside `sourceEvents`).
148
+ Other sources/key shapes report PLAY0809, with no automatic repair. Explicit typed
149
+ fixture `for` must equal the key; omission takes the key before projections/reactions,
150
+ including givens without an action. Unmarked captures keep earlier semantics.
151
+ An admitting renderer may narrow history reads by event source id; binding is not target evidence.
152
+ Read [event-source keys](../../cratis-screenplay-captures-and-reactions/references/capture-map-and-example.md#keying-by-the-event-source) for the complete example.
153
+
142
154
  ## `$context.` paths (command `produces`)
143
155
  `occurred`, `tenant`, `command.<p>`, `arguments.<p>`, `causedBy.subject|name|userName`,
144
156
  `causation.type`, `identity.id|name|userName|isAuthenticated|roles|claims.<n>`.
@@ -5,6 +5,7 @@
5
5
  - Warnings that hide defects (always validate with `--warnings-as-errors`)
6
6
  - Source reference and identifier checks
7
7
  - Public events and translation direction
8
+ - Event-source capture keys
8
9
  - Explicit enum member numbers
9
10
  - Reserved stored names and event pins
10
11
  - Named keys, production routes and observer filters
@@ -97,6 +98,20 @@ Requires Screenplay 4.176.0 or later for PLAY0694; older compilers leave the
97
98
  legacy directionless co-location unchecked. Full capture execution and ordering:
98
99
  automations-and-translations `references/public-events-and-direction.md`.
99
100
 
101
+ ## Event-source capture keys
102
+
103
+ Requires Screenplay 4.242.0 or later (`screenplay --version`); the marker selects ESM v33.
104
+
105
+ | Code | Severity | Meaning / fix |
106
+ | --- | --- | --- |
107
+ | PLAY0809 | E | `key <property> is event source` outside a single-property `source events` capture key. Declare it only when every captured event is sourced by that property. Other sources or key shapes are errors, with no automatic repair. |
108
+
109
+ Marked typed fixtures reject an explicit `for` that differs from the key. Without
110
+ `for`, the fixture takes the key before projections/reactions. The contract checks
111
+ givens too, even without an action. This execution rejection is not PLAY0809 and
112
+ not a successful `then no events` outcome. Unmarked captures retain prior semantics.
113
+ Read captures-and-reactions [event-source keys](../../cratis-screenplay-captures-and-reactions/references/capture-map-and-example.md#keying-by-the-event-source).
114
+
100
115
  ## Explicit enum member numbers
101
116
 
102
117
  Source errors; the pins bind as ESM v12:
@@ -19,6 +19,7 @@ exact language/semantic pairs; binding, reference execution and rendering are se
19
19
  | v29 | `decimals <= N`; `add`/`subtract` by `a * b`; a concept mapped to another concept over the same primitive (decision 0098) | Decimal-places rule on a Decimal concept or property; the exact decimal product; the conversion is admitted only when the target declares no rule or compliance the source does not, never for enums, composites or optional into required | v29 refused until Stage admits it |
20
20
  | v30 | A command `produces ... for <required scalar property>` (several event sources); a specification `given generated <Command>.<property> = <value>` (decision 0098) | Several sources in one accepted command; pinned generated values for reaction-invoked commands, taken in authored order | v30 refused until Stage admits it |
21
21
  | v31 | A policy `require anonymous` for a public command or query | A deliberately public surface; the policy is the whole effective authorization | v31 refused until Stage admits it |
22
+ | v33 | `key <property> is event source` on a single-property `source events` capture (Screenplay 4.242.0; PLAY0809) | Serializes `keyIsEventSource` beside `sourceEvents`. Promises every incoming event is sourced by that key; explicit fixture `for` must equal it, while omission takes the key before projections/reactions. Checks also run on givens without an action. Unmarked captures keep earlier behavior/version/bytes | An admitting renderer may narrow history reads by event source id; binding alone does not prove target realization |
22
23
 
23
24
  Constructs of decision 0098 with no executable-model content need no version: application-level toolbar buttons in the layout's `navigation topbar` region (`button <id> title "..." slice <Slice>` with an optional indented `authorize <Policy>`), a command specification that states the public event its outbound Translate slice publishes (no more false `PLAY0285`), and a capture over events that copies a list (`lines = $.lines`) or fans out with `children lines identified by sku`. Check `screenplay --version` against the release that admitted v29 and v30 before relying on them.
24
25