@cratis/pi 7.28.0 → 7.28.1
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/rules/reactors.md +30 -0
- package/package/corpus/rules/specs.scenarios.csharp.md +41 -0
- package/package/corpus/skills/cratis-application-slice-specifications/SKILL.md +13 -0
- package/package/corpus/skills/cratis-chronicle-reactor/SKILL.md +16 -1
- package/package/corpus/skills/cratis-chronicle-reactor/references/specifications.md +85 -0
- package/package/corpus/skills/cratis-specifications-csharp/SKILL.md +13 -0
- package/package/corpus/skills/cratis-specifications-csharp/references/application-scenarios.md +41 -0
- package/package.json +1 -1
|
@@ -278,4 +278,34 @@ async Task Because() => await _scenario.Given.ForEventSource(_id).Events(new Inv
|
|
|
278
278
|
[Fact] async Task should_notify_about_the_issued_invoice() => await _notifications.Received(1).Notify(Arg.Is<string>(_ => _.Contains("INV-1001")));
|
|
279
279
|
```
|
|
280
280
|
|
|
281
|
+
### Read-model dependencies in scenarios — Chronicle 19.46.0+
|
|
282
|
+
|
|
283
|
+
`ReactorScenario<TReactor>` does **not** build read models from `Given` events,
|
|
284
|
+
including `[Passive]` models. Seed the handler's read-model parameter explicitly
|
|
285
|
+
before firing the trigger:
|
|
286
|
+
|
|
287
|
+
```csharp
|
|
288
|
+
void Establish() => _scenario.Given.ForEventSourceId(_id).ReadModel(_order);
|
|
289
|
+
async Task Because() => await _scenario.Given.ForEventSource(_id).Events(_orderPlaced);
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
In a separate absence specification, replace the seeding with
|
|
293
|
+
`_scenario.Given.ForEventSourceId(_id).NoReadModel<Order>()` to deliberately pass
|
|
294
|
+
`null` to an `Order?` parameter. Without either setup, resolution to `null` throws
|
|
295
|
+
`ReadModelNotSeededForReactorScenario` (`Cratis.Chronicle.Testing.Reactors`), even
|
|
296
|
+
for a nullable parameter. Its message names the type and missing key, suggests
|
|
297
|
+
both setup methods, and lists other seeded keys for that type when any exist.
|
|
298
|
+
Use the key from `ICanResolveReadModelKey.Resolve` for seeding or absence when
|
|
299
|
+
implemented, not the triggering source id. `NoReadModel<T>()` does not remove a
|
|
300
|
+
seeded instance. This guard applies to `EventStoreForTesting`, not an explicitly
|
|
301
|
+
supplied store of another type; production read-model resolution is unchanged.
|
|
302
|
+
|
|
303
|
+
Also in Chronicle 19.46.0+, `Events(...)` surfaces a synchronously throwing
|
|
304
|
+
handler's own exception, preserving its stack, rather than the reflection
|
|
305
|
+
`TargetInvocationException`. Capture it with `Catch.Exception` and assert the
|
|
306
|
+
handler's exception type. `EventContext.From(...)` now defaults an omitted
|
|
307
|
+
`occurred` to `DateTimeOffset.UtcNow`, not local `Now`; scenario contexts,
|
|
308
|
+
`EventContext.Empty` and `EmptyWithEventSourceId(...)` use that helper. An
|
|
309
|
+
explicit occurrence time is preserved, not normalized to UTC.
|
|
310
|
+
|
|
281
311
|
For reactors that return side-effect events, assert the resulting appends through the scenario's event store; for non-event side effects, assert on the mocked services (as above). See [specs.scenarios.csharp.md](./specs.scenarios.csharp.md) for the full `*Scenario` family.
|
|
@@ -160,6 +160,47 @@ async Task Because() => await _scenario.Given.ForEventSource(_id).Events(new Aut
|
|
|
160
160
|
[Fact] async Task should_notify() => await _service.Received(1).Notify("Jane Austen");
|
|
161
161
|
```
|
|
162
162
|
|
|
163
|
+
#### Read-model setup — Chronicle 19.46.0+
|
|
164
|
+
|
|
165
|
+
In a class-based `ReactorScenario<TReactor>`, `Given` events invoke the reactor;
|
|
166
|
+
they **do not materialize read models**, even `[Passive]` ones. For each
|
|
167
|
+
read-model handler parameter, choose one setup before `Because()`:
|
|
168
|
+
|
|
169
|
+
```csharp
|
|
170
|
+
// Present-state specification: supply the instance the handler must receive.
|
|
171
|
+
void Establish() => _scenario.Given.ForEventSourceId(_id).ReadModel(_author);
|
|
172
|
+
|
|
173
|
+
// Separate absence specification: deliberately let an Author? parameter receive null.
|
|
174
|
+
void Establish() => _scenario.Given.ForEventSourceId(_id).NoReadModel<Author>();
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
These are alternatives in **separate specification classes**, not two
|
|
178
|
+
`Establish()` methods in one class. Both builders return
|
|
179
|
+
`ReactorSourceGivenBuilder<TReactor>` for chaining; neither setup is async.
|
|
180
|
+
Use the triggering event-source id by default, or the key returned by the
|
|
181
|
+
reactor's `ICanResolveReadModelKey.Resolve` when implemented. An absence
|
|
182
|
+
declaration is for that exact type and key and does not delete a seeded model.
|
|
183
|
+
|
|
184
|
+
If a recognized read-model parameter resolves to `null` without declared absence,
|
|
185
|
+
`Events(...)` throws `ReadModelNotSeededForReactorScenario` from
|
|
186
|
+
`Cratis.Chronicle.Testing.Reactors`, even if the parameter is nullable. The
|
|
187
|
+
message names the full type and missing key, explains `ReadModel(...)` and
|
|
188
|
+
`NoReadModel<T>()`, and lists seeded keys for that type when any exist. Fix the
|
|
189
|
+
fixture or its key; do not add `NoReadModel<T>()` just to silence missing setup.
|
|
190
|
+
The guard applies to `EventStoreForTesting`; it does not alter production
|
|
191
|
+
resolution or an explicitly supplied event store of another type.
|
|
192
|
+
|
|
193
|
+
**Handler failures:** in Chronicle 19.46.0+, a synchronous handler throw surfaces
|
|
194
|
+
its own exception, not `TargetInvocationException`, with its handler stack
|
|
195
|
+
preserved. Use `await Catch.Exception(() => _scenario.Given.ForEventSource(_id).Events(...))`
|
|
196
|
+
and assert the handler's exception type.
|
|
197
|
+
|
|
198
|
+
**Occurrence time:** in Chronicle 19.46.0+, `EventContext.From(...)` uses
|
|
199
|
+
`DateTimeOffset.UtcNow` when `occurred` is omitted (previously local `Now`).
|
|
200
|
+
`ReactorScenario` builds its contexts through this helper, as do
|
|
201
|
+
`EventContext.Empty` and `EmptyWithEventSourceId(...)`. Explicit occurrence times
|
|
202
|
+
keep their supplied offset; the positional constructor has no such default.
|
|
203
|
+
|
|
163
204
|
## Out-of-process Chronicle integration specs (advanced)
|
|
164
205
|
|
|
165
206
|
Reserve these for the host/transport boundary the scenario helpers can't reach. They test a complete slice — HTTP request → command → append → constraint → projection — against a real Chronicle store, and live under `when_<behavior>/` directly inside the slice folder (no `for_` folder; the "unit" is the whole slice).
|
|
@@ -30,6 +30,10 @@ This skill decides **when to add a scenario** and **what to cover**. The C# mech
|
|
|
30
30
|
|
|
31
31
|
> Re-verified at the versions above by **symbol and signature**: every type, attribute and member this skill names exists at that tag, and the public surface it describes is unchanged since the previous verification (Chronicle 16.45.x / Arc 22.10.4 — the Chronicle 16→18 client diff is converters, options and doc comments; no type was removed or renamed). Behavior claims were verified at the earlier tag unless a section says otherwise.
|
|
32
32
|
|
|
33
|
+
Reactor read-model setup and the `EventContext.From` UTC default below are
|
|
34
|
+
verified separately at **Chronicle 19.46.0**, the minimum version for that
|
|
35
|
+
guidance; see `cratis-chronicle-reactor/references/specifications.md` for sources.
|
|
36
|
+
|
|
33
37
|
`Cratis.Testing` is the meta-package that brings `Cratis.Arc.Testing` and
|
|
34
38
|
`Cratis.Arc.Chronicle.Testing` together. Reverify against the owning product
|
|
35
39
|
repository before claiming support for another version.
|
|
@@ -112,6 +116,15 @@ keep a scenario for that wiring and for appended-event behavior.
|
|
|
112
116
|
| Automation or Translation — a reactor | `ReactorScenario<TReactor>` | `cratis-specifications-csharp` |
|
|
113
117
|
| A host, transport, or real-infrastructure boundary | Out-of-process integration | `cratis-specifications-csharp` |
|
|
114
118
|
|
|
119
|
+
For a class-based reactor scenario on **Chronicle 19.46.0+**, explicitly seed
|
|
120
|
+
handler read-model parameters with `Given.ForEventSourceId(id).ReadModel(instance)`
|
|
121
|
+
or declare intentional absence with `.NoReadModel<T>()`. An unseeded model throws
|
|
122
|
+
`ReadModelNotSeededForReactorScenario` even if nullable; `Given` events do not
|
|
123
|
+
build read models, including passive ones. Use the reactor's resolved key, not
|
|
124
|
+
necessarily the trigger's source id. This is **not** the command-scenario event
|
|
125
|
+
seeding described in Step 5. Read `cratis-chronicle-reactor` for the setup examples,
|
|
126
|
+
exception diagnostics, synchronous handler throws and UTC context defaults.
|
|
127
|
+
|
|
115
128
|
## Step 3 — Cover every outcome of a State Change slice
|
|
116
129
|
|
|
117
130
|
One specification class for **each** of:
|
|
@@ -45,6 +45,11 @@ This skill is verified against these exact sources:
|
|
|
45
45
|
| `Cratis.Chronicle` | `18.3.0` | `Cratis.Chronicle.Reactors`, `Cratis.Chronicle.Reactors.SideEffects`, `Cratis.Chronicle.EventSequences`, `Cratis.Chronicle.Events` |
|
|
46
46
|
| `Cratis.Chronicle.CodeAnalysis` | `18.3.0` | `CHR0004`, `CHR0005`, `CHR0008`, `CHR0013`, `CHR0022`, `CHR0031`, `CHR0032` |
|
|
47
47
|
|
|
48
|
+
Scenario read-model seeding/absence, synchronous handler exception propagation,
|
|
49
|
+
and the `EventContext.From` UTC default are verified separately at **Chronicle
|
|
50
|
+
19.46.0**; they require **19.46.0+**. See the source paths in
|
|
51
|
+
[references/specifications.md](references/specifications.md).
|
|
52
|
+
|
|
48
53
|
Reverify product sources before claiming support for another version.
|
|
49
54
|
|
|
50
55
|
> **There is no `ReactorSideEffect` type.** It does not exist in Chronicle, in
|
|
@@ -363,7 +368,17 @@ when they serve that concern.
|
|
|
363
368
|
|
|
364
369
|
Start with `Specification` plus a direct call for pure reactor decisions; add `ReactorScenario<TReactor>` only where invocation, dependency wiring or side effects contribute proof. Specify the contract, not only the happy path: field lineage, contract-authorized filtering, repeated delivery, and unrelated events.
|
|
365
370
|
|
|
366
|
-
|
|
371
|
+
In Chronicle **19.46.0+**, a handler's unseeded read-model parameter throws
|
|
372
|
+
`ReadModelNotSeededForReactorScenario`, even if nullable. Seed it through
|
|
373
|
+
`Given.ForEventSourceId(id).ReadModel(instance)`, or declare intentional absence
|
|
374
|
+
with `.NoReadModel<T>()`. Use the resolved read-model key; `Given` events do not
|
|
375
|
+
build read models, including passive ones. A synchronous handler throw surfaces
|
|
376
|
+
the handler's exception rather than a reflection wrapper, and the scenario's
|
|
377
|
+
`EventContext.Occurred` defaults to UTC.
|
|
378
|
+
|
|
379
|
+
Read [references/specifications.md](references/specifications.md) before writing
|
|
380
|
+
or reviewing reactor specifications; it shows both setup alternatives and the
|
|
381
|
+
scope of these scenario-only guards.
|
|
367
382
|
|
|
368
383
|
## Verify
|
|
369
384
|
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
# Reactor specifications
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- Specifications
|
|
6
|
+
- Read-model setup — Chronicle 19.46.0+
|
|
7
|
+
- Exceptions and occurrence time — Chronicle 19.46.0+
|
|
8
|
+
- Contract coverage
|
|
9
|
+
|
|
1
10
|
## Specifications
|
|
2
11
|
|
|
3
12
|
Start with `Specification` plus a direct call for pure reactor decisions,
|
|
@@ -9,6 +18,82 @@ non-event side effects; for handlers that return events, assert the resulting
|
|
|
9
18
|
appends through the scenario's event store. Cover the replay path separately
|
|
10
19
|
when the reactor has `[OnceOnly]` or `[Replay]` handlers.
|
|
11
20
|
|
|
21
|
+
## Read-model setup — Chronicle 19.46.0+
|
|
22
|
+
|
|
23
|
+
Class-based `ReactorScenario<TReactor>` does not build read models from `Given`
|
|
24
|
+
events, **including passive models**. Seed a pre-built instance in `Establish()`:
|
|
25
|
+
|
|
26
|
+
```csharp
|
|
27
|
+
void Establish() => _scenario.Given.ForEventSourceId(_id).ReadModel(_order);
|
|
28
|
+
async Task Because() => await _scenario.Given.ForEventSource(_id).Events(_orderPlaced);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
For a **separate absence specification**, use this setup instead, so an `Order?`
|
|
32
|
+
handler parameter deliberately receives `null`:
|
|
33
|
+
|
|
34
|
+
```csharp
|
|
35
|
+
void Establish() => _scenario.Given.ForEventSourceId(_id).NoReadModel<Order>();
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The builders live in `Cratis.Chronicle.Testing.Reactors`. Exact signatures on
|
|
39
|
+
`ReactorSourceGivenBuilder<TReactor>` (`where TReactor : class, IReactor`):
|
|
40
|
+
|
|
41
|
+
```csharp
|
|
42
|
+
public ReactorSourceGivenBuilder<TReactor> ReadModel<TReadModel>(TReadModel readModel)
|
|
43
|
+
where TReadModel : class;
|
|
44
|
+
public ReactorSourceGivenBuilder<TReactor> NoReadModel<TReadModel>()
|
|
45
|
+
where TReadModel : class;
|
|
46
|
+
public Task Events(params object[] events);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Both `Given.ForEventSource(EventSourceId)` and
|
|
50
|
+
`Given.ForEventSourceId(EventSourceId)` return this builder. Seed or declare
|
|
51
|
+
absence using the triggering source id by default, or the key returned by
|
|
52
|
+
`ICanResolveReadModelKey.Resolve` when implemented. Declarations are shared
|
|
53
|
+
across the scenario's builders, match the **exact type and key**, and do not
|
|
54
|
+
remove a seeded instance. Do not declare absence to hide forgotten setup.
|
|
55
|
+
|
|
56
|
+
If a recognized read-model parameter resolves to `null` without declared
|
|
57
|
+
absence, `Events(...)` throws `ReadModelNotSeededForReactorScenario` from
|
|
58
|
+
`Cratis.Chronicle.Testing.Reactors`, **even for nullable parameters**. Its message
|
|
59
|
+
names the full read-model type and key, tells you to seed via `ReadModel(...)`
|
|
60
|
+
or declare `NoReadModel<T>()`, and lists other seeded keys for that type when
|
|
61
|
+
any exist. Check the key first if the fixture already seeds that type. This
|
|
62
|
+
guard applies only when the scenario uses `EventStoreForTesting` (including an
|
|
63
|
+
explicit instance); an explicitly supplied store of another type and production
|
|
64
|
+
read-model resolution are unchanged.
|
|
65
|
+
|
|
66
|
+
## Exceptions and occurrence time — Chronicle 19.46.0+
|
|
67
|
+
|
|
68
|
+
`Events(...)` rethrows a synchronously throwing handler's **own exception**,
|
|
69
|
+
unwrapping the `TargetInvocationException` previously surfaced by reflection,
|
|
70
|
+
and preserves the handler stack. Capture with
|
|
71
|
+
`await Catch.Exception(() => _scenario.Given.ForEventSource(_id).Events(_orderPlaced))`
|
|
72
|
+
and assert the handler's exception type, not a reflection wrapper.
|
|
73
|
+
|
|
74
|
+
`EventContext.From(...)` defaults omitted `occurred` to `DateTimeOffset.UtcNow`
|
|
75
|
+
(previously `DateTimeOffset.Now`). `ReactorScenario` uses this helper, as do
|
|
76
|
+
`EventContext.Empty` and `EmptyWithEventSourceId(...)`. Explicit timestamps keep
|
|
77
|
+
their supplied offset; the positional constructor does not default `Occurred`.
|
|
78
|
+
For deterministic time-dependent plain-call specs, supply a fixed occurrence
|
|
79
|
+
time rather than asserting an exact current instant.
|
|
80
|
+
|
|
81
|
+
Verified against **Chronicle tag `v19.46.0`**:
|
|
82
|
+
|
|
83
|
+
- `Source/Clients/Testing/Reactors/ReactorSourceGivenBuilder.cs` and
|
|
84
|
+
`ReactorScenarioGivenBuilder.cs`: seeding, absence and builder signatures.
|
|
85
|
+
- `Source/Clients/Testing/Reactors/ScenarioReactorMethodArgumentsResolver.cs` and
|
|
86
|
+
`ReadModelNotSeededForReactorScenario.cs`: guard scope, resolved key and message.
|
|
87
|
+
- `Source/Clients/Testing/Reactors/ReactorScenario.cs`: synchronous exception
|
|
88
|
+
unwrapping and context creation.
|
|
89
|
+
- `Source/Clients/DotNET/Events/EventContext.cs`: UTC default and explicit time.
|
|
90
|
+
- `Source/Clients/Testing.Specs/Reactors/for_ReactorScenario/when_resolving_read_model_dependencies/`:
|
|
91
|
+
seeded, absent, nullable, passive, custom-key and explicit-store examples.
|
|
92
|
+
- `Source/Clients/Testing.Specs/Reactors/for_ReactorScenario/when_a_reactor_handler_throws_synchronously.cs`
|
|
93
|
+
and `when_a_reactor_reads_the_occurrence_time.cs`: handler exception and UTC specs.
|
|
94
|
+
|
|
95
|
+
## Contract coverage
|
|
96
|
+
|
|
12
97
|
Specify the contract, not only the happy path:
|
|
13
98
|
|
|
14
99
|
- **Field lineage.** For each returned command or event, a specification asserts
|
|
@@ -22,6 +22,11 @@ This skill is verified against these exact public releases:
|
|
|
22
22
|
| `Cratis.Arc.Testing` | `22.16.0` | `CommandScenario<TCommand>` and `CommandResult` assertions |
|
|
23
23
|
| `Cratis.Chronicle.Testing` | `18.3.0` | `EventScenario`, `ReadModelScenario<T>`, `ReactorScenario<T>` |
|
|
24
24
|
|
|
25
|
+
Reactor read-model seeding/absence, synchronous handler exceptions and the
|
|
26
|
+
`EventContext.From` UTC default are verified separately at **Chronicle 19.46.0**
|
|
27
|
+
and require **19.46.0+**; see the ReactorScenario section in
|
|
28
|
+
[application-scenarios.md](references/application-scenarios.md).
|
|
29
|
+
|
|
25
30
|
Generated-value scenario pinning is verified separately against
|
|
26
31
|
`Cratis.Arc.Testing` **22.68.0** (introduced in **22.67.0**).
|
|
27
32
|
|
|
@@ -83,6 +88,14 @@ never produces a concurrency violation. `ShouldHaveConcurrencyViolations()`
|
|
|
83
88
|
cannot pass for such an append and its negation passes vacuously — specify concurrency against the
|
|
84
89
|
real kernel with an out-of-process integration specification instead.
|
|
85
90
|
|
|
91
|
+
For a class-based `ReactorScenario<TReactor>` on **Chronicle 19.46.0+**, seed each
|
|
92
|
+
handler read-model parameter with `Given.ForEventSourceId(id).ReadModel(instance)`
|
|
93
|
+
or declare intentional absence with `.NoReadModel<T>()`; `Given` events do not
|
|
94
|
+
build it, even if passive. Missing setup throws
|
|
95
|
+
`ReadModelNotSeededForReactorScenario` even for a nullable parameter. Use the
|
|
96
|
+
resolved read-model key. See the ReactorScenario reference for diagnostics,
|
|
97
|
+
exception capture and UTC occurrence-time defaults.
|
|
98
|
+
|
|
86
99
|
Specification projects are named `<Source>.Specs` and run on xUnit.
|
|
87
100
|
|
|
88
101
|
### Pin server-generated Handle values
|
package/package/corpus/skills/cratis-specifications-csharp/references/application-scenarios.md
CHANGED
|
@@ -262,6 +262,47 @@ async Task Because() =>
|
|
|
262
262
|
Construct with an `IServiceProvider` of substituted collaborators and assert on
|
|
263
263
|
those substitutes after `Given` fires the events.
|
|
264
264
|
|
|
265
|
+
### Read-model parameters — Chronicle 19.46.0+
|
|
266
|
+
|
|
267
|
+
`Given` events invoke the reactor; they **do not build read models**, including
|
|
268
|
+
passive ones. In the present-state specification, seed a pre-built instance:
|
|
269
|
+
|
|
270
|
+
```csharp
|
|
271
|
+
void Establish() => _scenario.Given.ForEventSourceId(_id).ReadModel(_author);
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
In a **separate absence specification**, deliberately let an `Author?` handler
|
|
275
|
+
parameter receive `null`:
|
|
276
|
+
|
|
277
|
+
```csharp
|
|
278
|
+
void Establish() => _scenario.Given.ForEventSourceId(_id).NoReadModel<Author>();
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Both return `ReactorSourceGivenBuilder<TReactor>` for chaining, not a `Task`.
|
|
282
|
+
Use the triggering source id by default or `ICanResolveReadModelKey.Resolve`'s
|
|
283
|
+
key when implemented. Absence matches the exact type and key and does not remove
|
|
284
|
+
a seeded instance. Missing setup throws `ReadModelNotSeededForReactorScenario`
|
|
285
|
+
(`Cratis.Chronicle.Testing.Reactors`), **even for nullable parameters**. Its
|
|
286
|
+
message names the type/key, explains both setups, and lists other seeded keys
|
|
287
|
+
for that type when any exist. Fix the fixture/key rather than hiding missing
|
|
288
|
+
setup with `NoReadModel<T>()`. This guard applies to `EventStoreForTesting`, not
|
|
289
|
+
production resolution or an explicitly supplied store of another type.
|
|
290
|
+
|
|
291
|
+
Also in **Chronicle 19.46.0+**, a synchronous handler throw surfaces its own
|
|
292
|
+
exception, not reflection's `TargetInvocationException`, preserving the handler
|
|
293
|
+
stack. Capture with `await Catch.Exception(() => _scenario.Given.ForEventSource(_id).Events(...))`
|
|
294
|
+
and assert the handler's exception type.
|
|
295
|
+
|
|
296
|
+
`EventContext.From(...)` defaults omitted `occurred` to `DateTimeOffset.UtcNow`,
|
|
297
|
+
previously local `Now`. Scenario contexts, `EventContext.Empty` and
|
|
298
|
+
`EmptyWithEventSourceId(...)` use this helper; explicit times retain their offset,
|
|
299
|
+
and the positional constructor has no such default.
|
|
300
|
+
|
|
301
|
+
Sources at **Chronicle tag `v19.46.0`**:
|
|
302
|
+
`Source/Clients/Testing/Reactors/{ReactorScenario,ReactorSourceGivenBuilder,ScenarioReactorMethodArgumentsResolver,ReadModelNotSeededForReactorScenario}.cs`
|
|
303
|
+
and `Source/Clients/DotNET/Events/EventContext.cs`. For exact signatures and
|
|
304
|
+
source-backed examples, read `cratis-chronicle-reactor/references/specifications.md`.
|
|
305
|
+
|
|
265
306
|
## Application conventions
|
|
266
307
|
|
|
267
308
|
- **Use a per-specification fixture value for anything under a shared uniqueness
|