@cratis/pi 7.128.0 → 7.130.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/coordinator.md +1 -1
- package/package/corpus/agents/orchestrator.md +1 -1
- package/package/corpus/agents/planner.md +1 -1
- package/package/corpus/harnesses/copilot/instructions/csharp.instructions.md +2 -2
- package/package/corpus/harnesses/copilot/instructions/framework.instructions.md +1 -1
- package/package/corpus/harnesses/copilot/instructions/orleans.instructions.md +2 -1
- package/package/corpus/harnesses/copilot/instructions/pull-requests.instructions.md +1 -1
- package/package/corpus/harnesses/copilot/instructions/specs.csharp.instructions.md +1 -1
- package/package/corpus/harnesses/pi/agents/coordinator.md +1 -1
- package/package/corpus/harnesses/pi/agents/orchestrator.md +1 -1
- package/package/corpus/harnesses/pi/agents/planner.md +1 -1
- package/package/corpus/harnesses/pi/extensions/cratis-hooks/index.ts +1 -1
- package/package/corpus/hooks/README.md +17 -5
- package/package/corpus/hooks/pre-commit.md +2 -2
- package/package/corpus/hooks/scripts/cratis-quality-gate.sh +1 -0
- package/package/corpus/hooks/scripts/cratis-run-specs.sh +147 -0
- package/package/corpus/hooks/scripts/quality-gates.json +5 -7
- package/package/corpus/product-sync.json +4 -4
- package/package/corpus/rules/csharp.md +2 -2
- package/package/corpus/rules/framework.md +1 -1
- package/package/corpus/rules/orleans.md +2 -1
- package/package/corpus/rules/pull-requests.md +1 -1
- package/package/corpus/rules/specs.csharp.md +1 -1
- package/package/corpus/skills/binlog-generation/SKILL.md +1 -1
- package/package/corpus/skills/coverage-analysis/references/setup-discovery.md +1 -1
- package/package/corpus/skills/cratis-application-slice-conformance/SKILL.md +1 -1
- package/package/corpus/skills/cratis-application-slice-specifications/SKILL.md +1 -1
- package/package/corpus/skills/cratis-arc-command-execution/references/command-refusals.md +1 -1
- package/package/corpus/skills/cratis-arc-command-execution/references/occurrence-commands.md +1 -1
- package/package/corpus/skills/cratis-arc-command-operation/references/testing.md +1 -1
- package/package/corpus/skills/cratis-arc-command-validation/references/input-binding.md +1 -1
- package/package/corpus/skills/cratis-arc-command-validation/references/validation-severity.md +1 -1
- package/package/corpus/skills/cratis-arc-react-page/references/from-screenplay.md +5 -5
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/immediate-append-refusal.md +1 -1
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/occurrences.md +1 -1
- package/package/corpus/skills/cratis-chronicle-event-constraints/references/storage-uniqueness.md +1 -1
- package/package/corpus/skills/cratis-chronicle-event-specifications/SKILL.md +1 -1
- package/package/corpus/skills/cratis-chronicle-event-type-migration/references/explicit-migrations.md +1 -1
- package/package/corpus/skills/cratis-chronicle-reactor/references/starting-and-replaying.md +1 -1
- package/package/corpus/skills/cratis-chronicle-read-model/references/collection-observation.md +1 -1
- package/package/corpus/skills/cratis-chronicle-read-model-specifications/SKILL.md +1 -1
- package/package/corpus/skills/cratis-ci-pipeline-performance/SKILL.md +1 -1
- package/package/corpus/skills/cratis-ci-pipeline-performance/references/build-once-and-shard.md +7 -3
- package/package/corpus/skills/cratis-ci-pipeline-performance/references/flaky-and-hung-jobs.md +1 -1
- package/package/corpus/skills/cratis-ci-pipeline-performance/references/test-setup-cost.md +1 -1
- package/package/corpus/skills/cratis-commits-and-pull-requests/references/pr-labels-and-release.md +1 -1
- package/package/corpus/skills/cratis-engineering-ci-gates/SKILL.md +3 -2
- package/package/corpus/skills/cratis-engineering-local-cross-repo-verification/SKILL.md +5 -1
- package/package/corpus/skills/cratis-engineering-local-cross-repo-verification/references/worked-examples.md +17 -8
- package/package/corpus/skills/cratis-orchestration-lanes/references/context-handoff.md +1 -1
- package/package/corpus/skills/cratis-orchestration-lanes/references/lane-brief.md +2 -2
- 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/delivery-protocol.md +2 -2
- 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 +8 -5
- 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/fast-path.md +1 -1
- 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-toolchain/references/verdicts.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-specifications-csharp/references/running-specs.md +7 -3
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +8 -6
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +8 -5
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/render-example.md +1 -1
- package/package/corpus/skills/csharp-refactoring/SKILL.md +2 -2
- package/package/corpus/skills/eliminate-redundant-restores/SKILL.md +2 -1
- package/package/corpus/skills/filter-syntax/SKILL.md +1 -1
- package/package/corpus/skills/msbuild/references/build-perf-baseline.md +4 -1
- package/package/corpus/skills/run-tests/SKILL.md +9 -0
- package/package.json +1 -1
|
@@ -83,9 +83,9 @@ module Marina
|
|
|
83
83
|
screen BerthListScreen
|
|
84
84
|
title "Berths"
|
|
85
85
|
data BerthListView[] via query ListBerths
|
|
86
|
-
action BookBerth
|
|
86
|
+
action BookBerth for screen
|
|
87
87
|
label "Book a berth"
|
|
88
|
-
action CancelBerth
|
|
88
|
+
action CancelBerth for item
|
|
89
89
|
table BerthListView
|
|
90
90
|
column boatName label "Boat"
|
|
91
91
|
on row-click navigate to BerthDetailsScreen by berthId
|
|
@@ -94,7 +94,7 @@ module Marina
|
|
|
94
94
|
data BerthListView via query GetBerth by berthId
|
|
95
95
|
summary BerthListView
|
|
96
96
|
field boatName label "Boat"
|
|
97
|
-
action CancelBerth
|
|
97
|
+
action CancelBerth for item
|
|
98
98
|
navigate to BerthListScreen
|
|
99
99
|
|
|
100
100
|
form BookBerthForm for BookBerth
|
|
@@ -119,8 +119,8 @@ field because `berthId` is the identifier, not something the user types.
|
|
|
119
119
|
| `table BerthListView` with `column boatName label "Boat"` | `<DataPage.Columns><Column field='boatName' header='Boat' /></DataPage.Columns>`; one `Column` per modeled `column`, no extras | Verified |
|
|
120
120
|
| A second `table` on one screen | `DataTableForQuery` / `DataTableForObservableQuery` ([data-tables.md](data-tables.md)) | Verified |
|
|
121
121
|
| `summary BerthListView` with `field boatName label "Boat"` | Plain markup in the page or in `detailsComponent` (`{ item }`), one labelled line per modeled `field` | Gap: this skill's verified sources name no summary component |
|
|
122
|
-
| `action BookBerth` with `label "Book a berth"` | `<MenuItem label='Book a berth' icon={...} command={() => showBookBerth()} />` plus `CommandDialog` and `useDialog
|
|
123
|
-
| `action CancelBerth` on a list with a table | `MenuItem` with `disableOnUnselected`; the selected row supplies the identifier | Verified prop |
|
|
122
|
+
| `action BookBerth for screen` with `label "Book a berth"` | `<MenuItem label='Book a berth' icon={...} command={() => showBookBerth()} />` plus `CommandDialog` and `useDialog`; no row fills its inputs | Verified |
|
|
123
|
+
| `action CancelBerth for item` on a list with a table | `MenuItem` with `disableOnUnselected`; the selected row supplies the identifier | Verified prop |
|
|
124
124
|
| `action` with no `label` | The model gives no text. Use the command name, spaced, and report it | Gap |
|
|
125
125
|
| `action X` with `navigate to S [by p]` | Navigate to the page for `S` after the command succeeds, in `onSuccess`; pass `p` from the response or the row | Assumption: `screens.md` does not say when it navigates. The form's `on submit` is defined as "after a successful submit"; confirm with the model owner |
|
|
126
126
|
| `on row-click navigate to S by p` | `DataPage` and `DataTableForQuery` forward no row-click prop (only `DataTableCore` has `onRowClick`, and it takes rows, not a query). Use controlled `selection` and `onSelectionChange` to navigate, or a link in a `Column` `body` | Gap: selection is not a click; report which you chose |
|
package/package/corpus/skills/cratis-chronicle-client-dotnet/references/immediate-append-refusal.md
CHANGED
|
@@ -36,5 +36,5 @@ In a spec, attempt an immediate append through both the current event log and a
|
|
|
36
36
|
previously captured reference; assert that neither reaches transport. Assert
|
|
37
37
|
that transactional work commits with its receipt, that an unsupported kernel
|
|
38
38
|
fails closed, and that borrowed frames cannot complete another owner's unit.
|
|
39
|
-
Run
|
|
39
|
+
Run the owning project's built spec executable (see [specs.csharp](../../../rules/specs.csharp.md)). In-process proof is not a substitute for
|
|
40
40
|
integration coverage of the storage provider's transaction boundary.
|
|
@@ -81,7 +81,7 @@ a handler through in-process ingress, claims, receipts and completion:
|
|
|
81
81
|
|
|
82
82
|
There are no background workers, automatic lease renewals or reminders in this
|
|
83
83
|
scenario; it does not prove behavior in a real multi-node cluster. Run
|
|
84
|
-
|
|
84
|
+
the owning spec project's built executable (see [specs.csharp](../../../rules/specs.csharp.md)) and assert duplicate ingress, redelivery,
|
|
85
85
|
terminal refusal, lost reply and unsupported-capability paths.
|
|
86
86
|
|
|
87
87
|
Requires Chronicle 19.78.0 for `Defaults` and `EventStoreForTesting` constructors
|
package/package/corpus/skills/cratis-chronicle-event-constraints/references/storage-uniqueness.md
CHANGED
|
@@ -22,7 +22,7 @@ complete: the first claimant in event-log order retains the value, later duplica
|
|
|
22
22
|
claims are logged and skipped. Reindexing does not retract their stored events.
|
|
23
23
|
Older kernels can fail the reindex instead.
|
|
24
24
|
|
|
25
|
-
Run the affected specifications with
|
|
25
|
+
Run the affected specifications with the owning project's built spec executable (see [specs.csharp](../../../rules/specs.csharp.md)), asserting a second source's
|
|
26
26
|
rejection, unchanged original claim after a failed move, and successful reuse
|
|
27
27
|
after release. Real SQL integration must prove two competing claims cannot both
|
|
28
28
|
succeed; an in-memory pass does not prove the SQL index was upgraded.
|
|
@@ -229,6 +229,6 @@ assert the value can be claimed again.
|
|
|
229
229
|
## How it is proven
|
|
230
230
|
|
|
231
231
|
`dotnet build` in Debug (which compiles the `#if DEBUG` specification code) and
|
|
232
|
-
|
|
232
|
+
the owning project's built spec executable (see [specs.csharp](../../rules/specs.csharp.md)), both clean. A constraint specification is only meaningful if it
|
|
233
233
|
has been seen to fail: remove the seeding `Given` once and confirm the
|
|
234
234
|
specification goes red before trusting it green.
|
|
@@ -41,6 +41,6 @@ the store-local alias. Custom schema generators resolving explicit compensation
|
|
|
41
41
|
targets need the registry-aware overloads or throw
|
|
42
42
|
`RegistryAwareEventTypeSchemasNotSupported`.
|
|
43
43
|
|
|
44
|
-
Run `dotnet build -c Debug` and migration
|
|
44
|
+
Run `dotnet build -c Debug` and migration spec executables (see [specs.csharp](../../../rules/specs.csharp.md)); assert both
|
|
45
45
|
directions and real observer delivery where pinning or protected-value release
|
|
46
46
|
matters. A successful nomination alone does not prove a generation can be read.
|
|
@@ -29,5 +29,5 @@ handler is still subscribed to.
|
|
|
29
29
|
|
|
30
30
|
Verify first registration, restart with an existing position, replay and
|
|
31
31
|
failed-partition redelivery separately. Assert the external effect count, not
|
|
32
|
-
only that the handler was invoked. Run
|
|
32
|
+
only that the handler was invoked. Run the owning spec project's built executable (see [specs.csharp](../../../rules/specs.csharp.md));
|
|
33
33
|
server-first compatibility and durable positions also need kernel integration.
|
package/package/corpus/skills/cratis-chronicle-read-model/references/collection-observation.md
CHANGED
|
@@ -41,7 +41,7 @@ pretending observation succeeded.
|
|
|
41
41
|
|
|
42
42
|
## Verify
|
|
43
43
|
|
|
44
|
-
Run `dotnet build -c Debug` and
|
|
44
|
+
Run `dotnet build -c Debug` and the owning query spec executable (see [specs.csharp](../../../rules/specs.csharp.md)). Cover
|
|
45
45
|
empty, add, update, remove, filter exit and disposal.
|
|
46
46
|
Requires Arc 22.87.0 for Chronicle observations in `QueryScenario`.
|
|
47
47
|
Requires Arc 22.91.1 with Chronicle 19.59.1 for default-mode children/joins/reducers. Scenario rebuilds do
|
|
@@ -283,6 +283,6 @@ Read `references/view-lifecycle-checks.md` when delivering a read model from a c
|
|
|
283
283
|
|
|
284
284
|
## How it is proven
|
|
285
285
|
|
|
286
|
-
`dotnet build` in Debug and
|
|
286
|
+
`dotnet build` in Debug and the owning project's built spec executable (see [specs.csharp](../../rules/specs.csharp.md)), both clean. A projection
|
|
287
287
|
specification is only meaningful once it has been seen to fail: drop one seeded
|
|
288
288
|
event and confirm the assertion goes red before trusting it green.
|
|
@@ -75,7 +75,7 @@ named reference before applying one.
|
|
|
75
75
|
**Build once, shard the tests.** Fits execution-bound workflows where build and
|
|
76
76
|
tests run serially or several jobs each rebuild. Default: one job builds in
|
|
77
77
|
`Release`, uploads the output with `actions/upload-artifact`, and a matrix of shard jobs downloads it and runs
|
|
78
|
-
`dotnet test --no-build`. Pitfall: a shard whose filter matches nothing still
|
|
78
|
+
each built spec executable; only VSTest projects use `dotnet test <project> --no-build`. Pitfall: a shard whose filter matches nothing still
|
|
79
79
|
passes, so assert that every shard ran tests. Read
|
|
80
80
|
`references/build-once-and-shard.md` when applying or reviewing this.
|
|
81
81
|
|
package/package/corpus/skills/cratis-ci-pipeline-performance/references/build-once-and-shard.md
CHANGED
|
@@ -75,15 +75,19 @@ jobs:
|
|
|
75
75
|
with:
|
|
76
76
|
name: build-output
|
|
77
77
|
- run: tar --zstd -xf build-output.tar.zst
|
|
78
|
+
# Example assumes each xUnit v3 mtp-off AssemblyName matches its directory.
|
|
79
|
+
# Use evaluated TargetPath for custom outputs; TUnit/native runners need their own report flags.
|
|
80
|
+
# Only VSTest uses dotnet test <project> --no-build --configuration Release with --logger/--results-directory.
|
|
78
81
|
- name: Test the shard's projects
|
|
79
82
|
env:
|
|
80
83
|
PROJECTS: ${{ matrix.projects }}
|
|
81
84
|
run: |
|
|
82
85
|
failed=0
|
|
83
86
|
for project in $PROJECTS; do
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
+
mkdir -p "$RUNNER_TEMP/test-results"
|
|
88
|
+
# xUnit v3 mtp-off example: resolve each project's actual AssemblyName/TFM.
|
|
89
|
+
"$project/bin/Release/net10.0/$(basename "$project")" \
|
|
90
|
+
-trx "$RUNNER_TEMP/test-results/$(basename "$project").trx" || failed=1
|
|
87
91
|
done
|
|
88
92
|
exit "$failed"
|
|
89
93
|
- name: Verify every project ran tests
|
package/package/corpus/skills/cratis-ci-pipeline-performance/references/flaky-and-hung-jobs.md
CHANGED
|
@@ -24,7 +24,7 @@ cost runner-minutes and developer trust; diagnose before retrying.
|
|
|
24
24
|
## Find hangs and crashes in .NET
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
dotnet test
|
|
27
|
+
dotnet test VSTest.Specs.csproj --configuration Release --no-build \
|
|
28
28
|
--blame-hang --blame-hang-timeout 5m --blame-hang-dump-type mini \
|
|
29
29
|
--blame-crash --blame-crash-dump-type mini \
|
|
30
30
|
--results-directory TestResults
|
|
@@ -32,7 +32,7 @@ Measure before guessing, with the language's profiler on the test process:
|
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
34
|
dotnet tool install --global dotnet-trace
|
|
35
|
-
dotnet-trace collect --format speedscope --
|
|
35
|
+
dotnet-trace collect --format speedscope -- ./<project-dir>/bin/Release/<TFM>/<AssemblyName>
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
Read the inclusive time of the setup methods. Pass means the profile names the
|
package/package/corpus/skills/cratis-commits-and-pull-requests/references/pr-labels-and-release.md
CHANGED
|
@@ -81,7 +81,7 @@ Documentation-only changes use repository-supported non-release intent, ordinari
|
|
|
81
81
|
Before marking code/automation work ready, select the affected-project gates that apply from the following list; run wider checks for cross-cutting changes and repository-required merge/release gates:
|
|
82
82
|
|
|
83
83
|
- `dotnet build`: zero errors, zero warnings
|
|
84
|
-
- `dotnet test
|
|
84
|
+
- Built C# spec executables: all specs pass; `dotnet test <project> --no-build` only for VSTest (see specs.csharp)
|
|
85
85
|
- `yarn lint`: zero errors
|
|
86
86
|
- `npx tsc -b`: zero TypeScript errors
|
|
87
87
|
- Code follows all project coding standards and conventions
|
|
@@ -81,8 +81,9 @@ a red run to discover the next failure.
|
|
|
81
81
|
|
|
82
82
|
Several agents, worktrees or builds often share one machine. Keep it responsive:
|
|
83
83
|
|
|
84
|
-
- Cap parallelism, for example `dotnet build -m:2`,
|
|
85
|
-
|
|
84
|
+
- Cap parallelism, for example `dotnet build -m:2`, built spec executables with their
|
|
85
|
+
runner-specific thread limit, and `vitest run --maxWorkers=2`. Do not pass MSBuild
|
|
86
|
+
`-m` to executables; `dotnet test <project> --no-build -m:2` is VSTest-only.
|
|
86
87
|
- Run one heavy phase at a time (build, then specs, then frontend lint and
|
|
87
88
|
tests), never several at once.
|
|
88
89
|
- Do not start a heavy phase while another agent's runs in the same machine's
|
|
@@ -162,9 +162,13 @@ From the consumer root, with the printed NuGet environment sourced:
|
|
|
162
162
|
|
|
163
163
|
```bash
|
|
164
164
|
dotnet build path/to/consumer.slnx -c Release -warnaserror
|
|
165
|
-
|
|
165
|
+
./<integration-project-dir>/bin/Release/<TFM>/<AssemblyName> <runner-specific-filter>
|
|
166
166
|
```
|
|
167
167
|
|
|
168
|
+
Resolve the integration project's actual built spec entrypoint and filter syntax with
|
|
169
|
+
[running-specs](../cratis-specifications-csharp/references/running-specs.md); without
|
|
170
|
+
apphost use `dotnet <TargetPath.dll>`. Only VSTest uses `dotnet test <project> -c Release
|
|
171
|
+
--no-build --filter '<regression>'`. Keep the sourced local NuGet environment.
|
|
168
172
|
Substitute the repository's actual commands; for frontend fixes run build, lint,
|
|
169
173
|
specs and the previously broken UI action. Pass: the reproducing spec/action now
|
|
170
174
|
succeeds, at least one intended filtered spec actually ran, and the consumer's
|
|
@@ -50,10 +50,14 @@ step. Apply the entry point's check/restore/cleanup sequence to both repositorie
|
|
|
50
50
|
export CHRONICLE_KERNEL_VERSION="$stamp"
|
|
51
51
|
cd "$consumer"
|
|
52
52
|
dotnet build path/to/Studio.slnx -c Release -p:StudioFullBuild=true -warnaserror
|
|
53
|
-
|
|
54
|
-
--filter '<regression>'
|
|
53
|
+
./<integration-project-dir>/bin/Release/<TFM>/<AssemblyName> <runner-specific-filter>
|
|
55
54
|
```
|
|
56
55
|
|
|
56
|
+
Resolve the actual output and filter for `Source/Integrations/Specs/Specs.csproj`
|
|
57
|
+
via [running-specs](../../cratis-specifications-csharp/references/running-specs.md).
|
|
58
|
+
Without apphost use `dotnet <TargetPath.dll>`; only VSTest uses
|
|
59
|
+
`dotnet test <project> -c Release --no-build --filter '<regression>'`.
|
|
60
|
+
Inspect the current consumer workflow before claiming CI equivalence.
|
|
57
61
|
Studio defaults kernel selection to the client version when the environment
|
|
58
62
|
override is absent. Ensure logs show the stamped local image. Local Debug
|
|
59
63
|
Studio builds skip analyzers; use `-p:StudioFullBuild=true` to match CI analyzer
|
|
@@ -83,9 +87,11 @@ bash "$local" use-nuget "$arc" "$stamp"
|
|
|
83
87
|
Gates (Arc `dotnet-build.yml`), run in this order after sourcing the printed env:
|
|
84
88
|
`yarn install --immutable`; in `Source/DotNET/Screenplay.Embedded`: `npm ci --workspaces=false`,
|
|
85
89
|
`npm run typecheck`, `npm test`, `npm run build`; `dotnet build --configuration Release
|
|
86
|
-
-p:CratisSpecsTargetFramework=net10.0`; then
|
|
87
|
-
|
|
88
|
-
--shard specs-N` prints.
|
|
90
|
+
-p:CratisSpecsTargetFramework=net10.0`; then each project's evaluated Release/net10.0
|
|
91
|
+
spec executable (or `dotnet <TargetPath.dll>` without apphost) for each project that
|
|
92
|
+
`python3 scripts/ci-test-shards.py projects --shard specs-N` prints. Only identified
|
|
93
|
+
VSTest projects use `dotnet test <project> --no-build --configuration Release --framework
|
|
94
|
+
net10.0`. Inspect the current consumer workflow before claiming equivalence. Finish by listing Arc's `obj/project.assets.json` files for the stamp.
|
|
89
95
|
|
|
90
96
|
- Pass: the Fundamentals IDs in `project.assets.json` are at the stamp, build has 0 warnings and 0 errors, 18 spec projects run and none fail.
|
|
91
97
|
- Time: pack about 4 min, build about 6 min, the spec projects about 18 min.
|
|
@@ -134,9 +140,12 @@ bash "$local" use-nuget "$direct" "$stamp"
|
|
|
134
140
|
```
|
|
135
141
|
|
|
136
142
|
Gates (Direct `build.yml`): `dotnet build Source/Direct/Direct.csproj -c Release
|
|
137
|
-
-p:DisableProxyGenerator=true`, the same in Debug with `-warnaserror`,
|
|
138
|
-
|
|
139
|
-
|
|
143
|
+
-p:DisableProxyGenerator=true`, the same in Debug with `-warnaserror`, then the project's
|
|
144
|
+
verified built Debug spec entrypoint. Build `Source/Assurance/Assurance.csproj` in the
|
|
145
|
+
matching configuration and run its verified spec entrypoint too; do not guess assembly
|
|
146
|
+
names or start an application server. See [running-specs](../../cratis-specifications-csharp/references/running-specs.md);
|
|
147
|
+
only VSTest uses `dotnet test <project> --no-build` in that configuration. Inspect the
|
|
148
|
+
current consumer workflow before claiming equivalence. Then check `project.assets.json`. Image-based specs also need the producer image tag.
|
|
140
149
|
|
|
141
150
|
- Pass for a consumer whose pins lag the producer: every Chronicle ID is in the feed at the
|
|
142
151
|
stamp, the Release build with the owner's floors passes, and `project.assets.json` shows every
|
|
@@ -59,7 +59,7 @@ Cap export retries at five and surface the final failure.
|
|
|
59
59
|
|
|
60
60
|
## Verified facts (with evidence)
|
|
61
61
|
- Cap and spec committed: `git log -1` shows the SHA above.
|
|
62
|
-
- Spec project passes:
|
|
62
|
+
- Spec project passes: `./Source/Export.Specs/bin/Debug/net10.0/Export.Specs` exit 0 at that SHA.
|
|
63
63
|
- Pull request is open: `gh pr list --head export-retry` shows one entry; CI run
|
|
64
64
|
`1234567890` is in progress.
|
|
65
65
|
|
|
@@ -60,12 +60,12 @@ C# rules.
|
|
|
60
60
|
**Decisions already made:** the cap is five and is a constant, not
|
|
61
61
|
configuration.
|
|
62
62
|
|
|
63
|
-
**Gate command:**
|
|
63
|
+
**Gate command:** `./Source/Export.Specs/bin/Debug/net10.0/Export.Specs`.
|
|
64
64
|
|
|
65
65
|
**Done =**
|
|
66
66
|
- [ ] A failing upload stops after five attempts and reports the error
|
|
67
67
|
- [ ] A spec covers the fifth failure and a success on the third attempt
|
|
68
|
-
- [ ]
|
|
68
|
+
- [ ] `./Source/Export.Specs/bin/Debug/net10.0/Export.Specs` exits 0
|
|
69
69
|
- [ ] `git diff --stat` shows only the owned files
|
|
70
70
|
|
|
71
71
|
**Stop and report if:** a public type must change, or another file needs edits.
|
|
@@ -95,7 +95,12 @@ another version behaves the same.
|
|
|
95
95
|
|
|
96
96
|
## When / when not
|
|
97
97
|
- Use: "when X happens, then ...", schedules, retries, work queues, notifications, webhooks, APIs,
|
|
98
|
-
files or message feeds, events imported from another context, legacy sync
|
|
98
|
+
files or message feeds, events imported from another context, legacy sync, lifecycles and
|
|
99
|
+
longer processes.
|
|
100
|
+
- A lifecycle (where one thing is and what moves it on) is a `statemachine`; a process that
|
|
101
|
+
sends several commands, waits, asks for approval or gives up after a deadline is a
|
|
102
|
+
`workflow` (ESM v36). Read
|
|
103
|
+
[state machines and workflows](references/statemachines-and-workflows.md) before modeling either.
|
|
99
104
|
- Not for: reaction, trigger or CDL grammar (`cratis-screenplay-captures-and-reactions`); stream
|
|
100
105
|
identity and invariants (`cratis-screenplay-streams-and-consistency`); UI interactions such as
|
|
101
106
|
`on click` (`cratis-screenplay-ui-composition`); hand-written reactors (`cratis-chronicle-reactor`).
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
- 9. Fan-out
|
|
14
14
|
- 10. Long-running process shapes
|
|
15
15
|
|
|
16
|
-
Complete compiled example: `todo-list-example.md` (binds as ESM
|
|
16
|
+
Complete compiled example: `todo-list-example.md` (binds as ESM v34 for `then invokes`; the list query
|
|
17
17
|
excerpt binds too, and the retry sweep that needs code is shown as a marked excerpt).
|
|
18
18
|
|
|
19
19
|
## 1. Deciding whether it is an automation
|
|
@@ -63,11 +63,11 @@ One spec in the slice does not cover the others.
|
|
|
63
63
|
- Current admitted Automation/Translate specifications run through standalone
|
|
64
64
|
`screenplay test` or MCP `run-specifications`. Validate/render alone is not V4;
|
|
65
65
|
report unsupported/unbound separately from passing scenarios.
|
|
66
|
-
- A
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
then
|
|
70
|
-
(
|
|
66
|
+
- A specification runs only its own slice (Screenplay decision 0115). A command spec
|
|
67
|
+
states the command's own events; the Automation states what its reaction appends in
|
|
68
|
+
its own `when append <Trigger>` spec, and a command it invokes in another slice with
|
|
69
|
+
`then invokes <Command>` (ESM v34). Another slice's event in a spec is PLAY0285
|
|
70
|
+
(unreachable). See `cratis-screenplay-scenario-coverage`.
|
|
71
71
|
- `given capture` never persists between specs: state the baseline in each record
|
|
72
72
|
update spec. First records (root, child, nested) are added only; field-change
|
|
73
73
|
`and`/`or` and transitions need previous state. Expressions/maps/unguarded record
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# State machines and workflows (ESM v36)
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- Which construct
|
|
6
|
+
- Complete example
|
|
7
|
+
- Specifications
|
|
8
|
+
- Diagnostics and targets
|
|
9
|
+
|
|
10
|
+
Requires Screenplay 5.1.0 or later (`screenplay --version`). Sources: Screenplay
|
|
11
|
+
`Documentation/screenplay/statemachines.md`, `workflows.md` and decision 0124.
|
|
12
|
+
|
|
13
|
+
## Which construct
|
|
14
|
+
|
|
15
|
+
| The domain says | Model |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| "When X happens, do Y", one step | An `Automation` slice with a reaction |
|
|
18
|
+
| Where one thing is in its lifecycle, and what moves it on | A `statemachine` that follows the thing's read model |
|
|
19
|
+
| A longer process: several commands, a choice, a wait for a fact or a person, a deadline, a fan-out | A `workflow` with one run per subject |
|
|
20
|
+
|
|
21
|
+
A state machine never decides on commands: it follows facts that already happened. Entering
|
|
22
|
+
a state may `send` a command or `start` a workflow; both may run again on redelivery, so the
|
|
23
|
+
command or workflow must be safe to repeat. A workflow is how a process waits, retries, asks
|
|
24
|
+
for approval and gives up; do not chain reactions across slices to imitate one.
|
|
25
|
+
|
|
26
|
+
Both are top-level declarations, siblings of `trigger` and `policy`. They name commands,
|
|
27
|
+
events, read models and personas declared in slices of any module. A model that declares one
|
|
28
|
+
selects ESM v36.
|
|
29
|
+
|
|
30
|
+
## Complete example
|
|
31
|
+
|
|
32
|
+
This model compiles with `--warnaserror` and its three specifications pass with
|
|
33
|
+
`screenplay test`:
|
|
34
|
+
|
|
35
|
+
```screenplay
|
|
36
|
+
concept InvoiceId : Uuid
|
|
37
|
+
persona FinanceController
|
|
38
|
+
module Billing
|
|
39
|
+
feature Invoices
|
|
40
|
+
slice StateChange SendInvoice
|
|
41
|
+
command SendInvoice
|
|
42
|
+
invoiceId InvoiceId identifier
|
|
43
|
+
produces event InvoiceSent
|
|
44
|
+
slice StateChange MarkOverdue
|
|
45
|
+
command MarkOverdue
|
|
46
|
+
invoiceId InvoiceId identifier
|
|
47
|
+
produces event InvoiceMarkedOverdue
|
|
48
|
+
slice StateChange PayInvoice
|
|
49
|
+
command PayInvoice
|
|
50
|
+
invoiceId InvoiceId identifier
|
|
51
|
+
produces event InvoicePaid
|
|
52
|
+
slice StateChange SendReminder
|
|
53
|
+
command SendReminder
|
|
54
|
+
invoiceId InvoiceId identifier
|
|
55
|
+
produces event ReminderSent
|
|
56
|
+
slice StateChange WriteOffInvoice
|
|
57
|
+
command WriteOffInvoice
|
|
58
|
+
invoiceId InvoiceId identifier
|
|
59
|
+
produces event InvoiceWrittenOff
|
|
60
|
+
slice StateView InvoiceStatus
|
|
61
|
+
readmodel Invoice
|
|
62
|
+
invoiceId InvoiceId key
|
|
63
|
+
status String
|
|
64
|
+
projection Invoices => Invoice
|
|
65
|
+
from InvoiceSent
|
|
66
|
+
invoiceId = $eventSourceId
|
|
67
|
+
status = "sent"
|
|
68
|
+
from InvoiceMarkedOverdue
|
|
69
|
+
status = "overdue"
|
|
70
|
+
from InvoicePaid
|
|
71
|
+
status = "paid"
|
|
72
|
+
query InvoiceById => Invoice optional
|
|
73
|
+
by invoiceId InvoiceId
|
|
74
|
+
|
|
75
|
+
statemachine InvoiceLifecycle
|
|
76
|
+
description "Where an invoice is, from sent to settled"
|
|
77
|
+
follows Invoice
|
|
78
|
+
state Sent initial
|
|
79
|
+
on InvoiceMarkedOverdue -> Overdue
|
|
80
|
+
on InvoicePaid -> Paid
|
|
81
|
+
state Overdue
|
|
82
|
+
entering start CollectOverdue
|
|
83
|
+
on InvoicePaid -> Paid
|
|
84
|
+
on InvoiceWrittenOff -> WrittenOff
|
|
85
|
+
state Paid final
|
|
86
|
+
state WrittenOff final
|
|
87
|
+
|
|
88
|
+
specification GoingOverdueStartsCollection
|
|
89
|
+
given InvoiceSent
|
|
90
|
+
for "9c858901-8a57-4791-81fe-4c455b099bc9"
|
|
91
|
+
when append InvoiceMarkedOverdue
|
|
92
|
+
for "9c858901-8a57-4791-81fe-4c455b099bc9"
|
|
93
|
+
then is Overdue
|
|
94
|
+
then starts CollectOverdue
|
|
95
|
+
|
|
96
|
+
workflow CollectOverdue
|
|
97
|
+
description "Reminds the customer, waits for payment and asks finance before writing off"
|
|
98
|
+
for Invoice
|
|
99
|
+
trigger when InvoiceLifecycle enters Overdue
|
|
100
|
+
-> Remind
|
|
101
|
+
action Remind sends SendReminder
|
|
102
|
+
next -> AwaitPayment
|
|
103
|
+
wait AwaitPayment for InvoicePaid expires after 14 days
|
|
104
|
+
expired -> ApproveWriteOff
|
|
105
|
+
approval ApproveWriteOff by FinanceController expires after 7 days
|
|
106
|
+
approved -> WriteOff
|
|
107
|
+
action WriteOff sends WriteOffInvoice
|
|
108
|
+
|
|
109
|
+
specification AnUnpaidInvoiceIsWrittenOff
|
|
110
|
+
given InvoiceSent
|
|
111
|
+
for "9c858901-8a57-4791-81fe-4c455b099bc9"
|
|
112
|
+
when append InvoiceMarkedOverdue
|
|
113
|
+
for "9c858901-8a57-4791-81fe-4c455b099bc9"
|
|
114
|
+
outcome AwaitPayment expired
|
|
115
|
+
outcome ApproveWriteOff approved
|
|
116
|
+
then sends SendReminder
|
|
117
|
+
then sends WriteOffInvoice
|
|
118
|
+
then completes
|
|
119
|
+
|
|
120
|
+
specification TheRunWaitsForPayment
|
|
121
|
+
given InvoiceSent
|
|
122
|
+
for "9c858901-8a57-4791-81fe-4c455b099bc9"
|
|
123
|
+
when append InvoiceMarkedOverdue
|
|
124
|
+
for "9c858901-8a57-4791-81fe-4c455b099bc9"
|
|
125
|
+
then sends SendReminder
|
|
126
|
+
then waits at AwaitPayment
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
- `follows Invoice` / `for Invoice`: the read model whose key is one instance (one run per
|
|
130
|
+
invoice). A transition condition (`on E when <condition> -> S`) reads that read model after
|
|
131
|
+
the event; a condition over an optional property is refused at binding.
|
|
132
|
+
- Exactly one `initial` state; a `final` state has no transitions. An event takes the first
|
|
133
|
+
transition on it, in declaration order across the whole machine, whose condition holds and
|
|
134
|
+
whose target the current state allows. Anything else is ignored, not an error.
|
|
135
|
+
- Workflow nodes: `trigger` (`on <Event>`, `when <StateMachine> enters <State>`, `every`,
|
|
136
|
+
`at`, `manual`), `action <Name> sends <Command> [attempts n] [timeout] [retry after]`,
|
|
137
|
+
`decide <Name> when <condition>` with exactly two outlets, `wait` for an event or a
|
|
138
|
+
duration, `approval <Name> by <Persona or Policy>`, `foreach <Name> over <collection>` and
|
|
139
|
+
`join all|any|at least n`. Edges are `<outlet> -> <Node>` under their node.
|
|
140
|
+
- An unconnected negative outlet (`failed`, `rejected`, `expired`) fails the run; an
|
|
141
|
+
unconnected positive outlet ends that branch. Give every event wait and approval an
|
|
142
|
+
`expires after` (PLAY0849 warns otherwise).
|
|
143
|
+
|
|
144
|
+
## Specifications
|
|
145
|
+
|
|
146
|
+
| Construct | Lines |
|
|
147
|
+
| --- | --- |
|
|
148
|
+
| `statemachine` | `given <Event>`, `when append <Event>`, `then is <State>`, `then sends <Command>`, `then starts <Workflow>` (every command and workflow, in order) |
|
|
149
|
+
| `workflow` | `given <Event>`, `when append <Event>` or `when start <key>`, `outcome <Node> <outlet>`, `then sends <Command>` (every one, in order), `then completes`, `then fails at <Node>`, `then waits at <Node>` |
|
|
150
|
+
|
|
151
|
+
The reference evaluator steps the run deterministically. A wait or approval with no stated
|
|
152
|
+
`outcome` suspends the run (`then waits at`); an action defaults to `next`; a wait for a
|
|
153
|
+
duration resumes at once.
|
|
154
|
+
|
|
155
|
+
## Diagnostics and targets
|
|
156
|
+
|
|
157
|
+
- State machines: PLAY0834-PLAY0842 (missing or duplicate `initial` is PLAY0835, an
|
|
158
|
+
unreachable state warns PLAY0836, an undeclared reference is PLAY0840).
|
|
159
|
+
- Workflows: PLAY0843-PLAY0851 (no trigger is PLAY0844, a bad outlet PLAY0847, a decision
|
|
160
|
+
without exactly two outlets PLAY0848, an undeclared reference PLAY0851); PLAY0839 and
|
|
161
|
+
PLAY0841 are shared.
|
|
162
|
+
- Stage refuses ESM v36 models with `STAGE-ESM-016`; every other model renders as
|
|
163
|
+
before. The durable engine is Cratis.Orleans; its hosting and adapters are outside this
|
|
164
|
+
reference.
|
|
@@ -5,14 +5,15 @@
|
|
|
5
5
|
- Design-only additions
|
|
6
6
|
|
|
7
7
|
A complete model: a result opens a work item, a reaction invokes a command, the command's fact
|
|
8
|
-
closes the item.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
`
|
|
15
|
-
|
|
8
|
+
closes the item. `then invokes` selects ESM v34 (`executableReady: true` from Screenplay 4.246.0),
|
|
9
|
+
standalone and through `cratis screenplay mcp`. The Stage spec runner compares `then invokes`, but the
|
|
10
|
+
Cratis renderer refuses models after v33 with `STAGE-ESM-016`; keep the specifications intact. A compiler
|
|
11
|
+
that stops before v34 refuses `then invokes`. Versions: `cratis-screenplay-toolchain` `SKILL.md`.
|
|
12
|
+
|
|
13
|
+
Each specification states only its own slice (Screenplay decision 0115): `RecordingAPass`
|
|
14
|
+
states `CoursePassed`, `SendingAfterAPass` states the hand-over with `then invokes
|
|
15
|
+
SendCertificate` (ESM v34), and `SendingACertificate` states `CertificateSent`. `given clock`
|
|
16
|
+
supplies the instant that `$context.occurred` needs.
|
|
16
17
|
Current admitted scenarios can be run with
|
|
17
18
|
standalone `screenplay test` or MCP `run-specifications`.
|
|
18
19
|
|
|
@@ -58,7 +59,7 @@ module Courses
|
|
|
58
59
|
CoursePassed
|
|
59
60
|
for enrolmentId
|
|
60
61
|
enrolmentId = enrolmentId // copied on purpose: the reaction selects it as a value
|
|
61
|
-
completedAt = $context.occurred // carried on the fact
|
|
62
|
+
completedAt = $context.occurred // carried on the fact, so every reader sees the same instant
|
|
62
63
|
produces when passed == false
|
|
63
64
|
CourseFailed
|
|
64
65
|
for enrolmentId
|
|
@@ -81,9 +82,6 @@ module Courses
|
|
|
81
82
|
for "0d3b9e2a-6c4f-4f1e-8b7a-5e2d1c3b4a01"
|
|
82
83
|
enrolmentId = "0d3b9e2a-6c4f-4f1e-8b7a-5e2d1c3b4a01"
|
|
83
84
|
completedAt = "2026-10-05T08:00:00Z"
|
|
84
|
-
then CertificateSent
|
|
85
|
-
for "0d3b9e2a-6c4f-4f1e-8b7a-5e2d1c3b4a01"
|
|
86
|
-
sentAt = "2026-10-05T08:00:00Z"
|
|
87
85
|
specification RefusingANonCoordinator
|
|
88
86
|
given caller
|
|
89
87
|
authenticated
|
|
@@ -180,9 +178,8 @@ module Certification
|
|
|
180
178
|
for "0d3b9e2a-6c4f-4f1e-8b7a-5e2d1c3b4a01"
|
|
181
179
|
enrolmentId = "0d3b9e2a-6c4f-4f1e-8b7a-5e2d1c3b4a01"
|
|
182
180
|
completedAt = "2026-10-05T08:00:00Z"
|
|
183
|
-
then
|
|
184
|
-
|
|
185
|
-
sentAt = "2026-10-05T08:00:00Z"
|
|
181
|
+
then invokes SendCertificate
|
|
182
|
+
enrolmentId = "0d3b9e2a-6c4f-4f1e-8b7a-5e2d1c3b4a01"
|
|
186
183
|
```
|
|
187
184
|
|
|
188
185
|
## Design-only additions
|
|
@@ -93,9 +93,6 @@ module Exams
|
|
|
93
93
|
for "7e9d1c2b-4a3f-4e5d-8c6b-1a2b3c4d5e06"
|
|
94
94
|
outcome = "passed"
|
|
95
95
|
score = 87
|
|
96
|
-
then ExamPassed
|
|
97
|
-
for "7e9d1c2b-4a3f-4e5d-8c6b-1a2b3c4d5e06"
|
|
98
|
-
score = 87
|
|
99
96
|
slice Automation RecordExamResult
|
|
100
97
|
reaction PassTranslator
|
|
101
98
|
when ProctorResultReceived
|
|
@@ -115,6 +112,14 @@ module Exams
|
|
|
115
112
|
constraint OneResultPerAttempt
|
|
116
113
|
unique event ExamPassed
|
|
117
114
|
unique event ExamFailed
|
|
115
|
+
specification RecordingAPass
|
|
116
|
+
when append ProctorResultReceived
|
|
117
|
+
for "7e9d1c2b-4a3f-4e5d-8c6b-1a2b3c4d5e06"
|
|
118
|
+
outcome = "passed"
|
|
119
|
+
score = 87
|
|
120
|
+
then ExamPassed
|
|
121
|
+
for "7e9d1c2b-4a3f-4e5d-8c6b-1a2b3c4d5e06"
|
|
122
|
+
score = 87
|
|
118
123
|
specification RefusingASecondResult
|
|
119
124
|
given ExamPassed
|
|
120
125
|
for "7e9d1c2b-4a3f-4e5d-8c6b-1a2b3c4d5e06"
|
|
@@ -131,7 +136,8 @@ module Exams
|
|
|
131
136
|
- Keep the capture and its appended event in Translate; put reactions to that local
|
|
132
137
|
event in a separate Automation. Co-location in a directionless Translate warns
|
|
133
138
|
PLAY0694 and fails `--warnaserror`; explicit inbound refuses it with PLAY0616.
|
|
134
|
-
|
|
139
|
+
A specification runs only its own slice (Screenplay decision 0115), so `TranslatingAPass`
|
|
140
|
+
states the Translate slice's fact and `RecordingAPass` states the Automation's result.
|
|
135
141
|
- `when added` records first sight; the separate `when outcome` append handles
|
|
136
142
|
later changes. For an update spec, seed the same reference with `given capture`.
|
|
137
143
|
Requires Screenplay 4.175.0 or later (`screenplay --version`); older evaluators
|
|
@@ -289,8 +289,8 @@ module Collections
|
|
|
289
289
|
when trigger PaymentFileArrived
|
|
290
290
|
invoiceId = "9c858901-8a57-4791-81fe-4c455b099bc9"
|
|
291
291
|
amount = 120
|
|
292
|
-
then
|
|
293
|
-
|
|
292
|
+
then invokes CloseInvoice
|
|
293
|
+
invoiceId = "9c858901-8a57-4791-81fe-4c455b099bc9"
|
|
294
294
|
reason = "paid"
|
|
295
295
|
specification IssuingTheWeeklyDigest
|
|
296
296
|
given clock "2026-10-05T07:00:00Z"
|
|
@@ -54,10 +54,16 @@ module Work
|
|
|
54
54
|
specification ProcessingRequestedWork
|
|
55
55
|
when append WorkRequested
|
|
56
56
|
workId = "work-1"
|
|
57
|
-
then
|
|
58
|
-
|
|
57
|
+
then invokes RecordWork
|
|
58
|
+
workId = "work-1"
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
+
The automation states the hand-over with `then invokes` (ESM v34). `RecordWork` is
|
|
62
|
+
decided under the declared system identity, so a denial would reach the reaction's
|
|
63
|
+
refusal branches, but `WorkRecorded` belongs to the `RecordWork` slice and is not kept
|
|
64
|
+
in this specification (Screenplay decision 0115). `RecordWork`'s own slice proves the
|
|
65
|
+
event with a `when RecordWork` specification.
|
|
66
|
+
|
|
61
67
|
## Diagnostics and target boundaries
|
|
62
68
|
|
|
63
69
|
- PLAY0647: malformed, repeated or misplaced identity, including duplicate/empty roles.
|