@cratis/pi 7.61.0 → 7.63.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/spec-writer.md +2 -2
- package/package/corpus/harnesses/copilot/instructions/application-profile.instructions.md +2 -2
- package/package/corpus/harnesses/copilot/instructions/glossary.instructions.md +2 -2
- package/package/corpus/harnesses/copilot/instructions/specs.scenarios.csharp.instructions.md +7 -4
- package/package/corpus/harnesses/copilot/instructions/vertical-slices.instructions.md +22 -13
- package/package/corpus/product-sync.json +11 -10
- package/package/corpus/prompts/add-business-rule.prompt.md +1 -1
- package/package/corpus/rules/application-profile.md +2 -2
- package/package/corpus/rules/glossary.md +2 -2
- package/package/corpus/rules/specs.scenarios.csharp.md +7 -4
- package/package/corpus/rules/vertical-slices.md +22 -13
- package/package/corpus/skills/cratis-application-slice-conformance/SKILL.md +1 -1
- package/package/corpus/skills/cratis-application-slice-specifications/SKILL.md +4 -3
- package/package/corpus/skills/cratis-application-slice-specifications/references/query-and-decision-scenarios.md +12 -3
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/SKILL.md +12 -7
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authorization.md +11 -11
- package/package/corpus/skills/cratis-arc-command/SKILL.md +3 -2
- package/package/corpus/skills/cratis-arc-command/references/decisions-and-routing.md +95 -51
- package/package/corpus/skills/cratis-arc-command/references/fresh-identifiers.md +5 -2
- package/package/corpus/skills/cratis-arc-command/references/generated-values.md +27 -12
- package/package/corpus/skills/cratis-arc-command/references/read-model-injection.md +9 -5
- package/package/corpus/skills/cratis-arc-command/references/shop-generation.md +17 -6
- package/package/corpus/skills/cratis-arc-command-validation/SKILL.md +99 -52
- package/package/corpus/skills/cratis-chronicle-decision-reads/SKILL.md +37 -15
- package/package/corpus/skills/cratis-chronicle-decision-reads/references/admission-and-ownership.md +3 -2
- package/package/corpus/skills/cratis-chronicle-decision-reads/references/choosing-how-a-rule-holds.md +277 -138
- package/package/corpus/skills/cratis-chronicle-event-constraints/SKILL.md +4 -4
- package/package/corpus/skills/cratis-chronicle-event-modeling/SKILL.md +6 -4
- package/package/corpus/skills/cratis-chronicle-read-model/SKILL.md +2 -1
- package/package/corpus/skills/cratis-chronicle-reducer/SKILL.md +6 -3
- package/package/corpus/skills/cratis-code-review/SKILL.md +6 -3
- package/package/corpus/skills/cratis-fundamentals-concept/SKILL.md +10 -2
- package/package/corpus/skills/cratis-fundamentals-concept/references/shop-generation.md +49 -6
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/SKILL.md +43 -41
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/cases-to-specify.md +11 -2
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/integration-interview.md +24 -0
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/public-events-and-direction.md +76 -10
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/realization-and-gap-fill.md +5 -0
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/todo-list-example.md +1 -1
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/translate-example.md +39 -23
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/translation-patterns.md +35 -12
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/SKILL.md +51 -81
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/atomic-batches-and-source-mappings.md +83 -0
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/capture-map-and-example.md +14 -4
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/reaction-forms.md +59 -0
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/record-capture-specifications.md +60 -0
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/specifying-triggers-and-clock.md +5 -1
- package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +26 -28
- package/package/corpus/skills/cratis-screenplay-command-surface/references/described-handlers.md +82 -0
- package/package/corpus/skills/cratis-screenplay-command-surface/references/generated-values-and-responses.md +82 -28
- package/package/corpus/skills/cratis-screenplay-command-surface/references/protected-reads.md +113 -0
- package/package/corpus/skills/cratis-screenplay-command-surface/references/shop-generation.md +45 -12
- package/package/corpus/skills/cratis-screenplay-command-surface/references/text-and-match-rules.md +119 -0
- package/package/corpus/skills/cratis-screenplay-command-surface/references/validate-rules.md +14 -4
- package/package/corpus/skills/cratis-screenplay-command-surface/verification.json +10 -3
- package/package/corpus/skills/cratis-screenplay-event-modeling/SKILL.md +12 -12
- package/package/corpus/skills/cratis-screenplay-event-modeling/references/parsed-not-runnable.md +5 -3
- package/package/corpus/skills/cratis-screenplay-event-modeling/verification.json +5 -1
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/SKILL.md +2 -2
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/evidence-table-template.md +1 -1
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/generated-recovery.md +51 -14
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/intent-example.md +5 -0
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/loss-report-template.md +2 -1
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/rule-modeling.md +6 -3
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/signal-to-intent.md +1 -1
- package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +22 -28
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/choosing-generation.md +20 -7
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/language-reference.md +12 -6
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-loop.md +9 -1
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +58 -10
- package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +4 -2
- package/package/corpus/skills/cratis-screenplay-model-review/SKILL.md +2 -5
- package/package/corpus/skills/cratis-screenplay-model-review/references/anti-patterns.md +2 -2
- package/package/corpus/skills/cratis-screenplay-model-review/references/checklist.md +2 -2
- package/package/corpus/skills/cratis-screenplay-model-review/references/quick-self-check.md +2 -1
- package/package/corpus/skills/cratis-screenplay-model-review/references/review-questions.md +3 -2
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/principles.md +1 -1
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/vocabulary-map.md +1 -1
- package/package/corpus/skills/cratis-screenplay-read-surface/SKILL.md +2 -3
- package/package/corpus/skills/cratis-screenplay-read-surface/references/named-keys.md +3 -1
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/SKILL.md +8 -3
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/gap-fill-handoff.md +8 -0
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/renderability-gate.md +6 -4
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/SKILL.md +36 -29
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/berth-reservations.md +6 -0
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/invoicing-dues-design.md +15 -4
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/invoicing-dues-example.md +25 -20
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/public-event-coverage.md +14 -3
- 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 +7 -3
- package/package/corpus/skills/cratis-screenplay-slice-design/SKILL.md +3 -1
- package/package/corpus/skills/cratis-screenplay-slice-design/references/command-inventory.md +4 -4
- package/package/corpus/skills/cratis-screenplay-slice-design/references/rule-layers.md +4 -2
- package/package/corpus/skills/cratis-screenplay-slice-design/references/slicing.md +4 -3
- package/package/corpus/skills/cratis-screenplay-slice-design/references/worked-example.md +8 -8
- package/package/corpus/skills/cratis-screenplay-specifications/SKILL.md +49 -47
- package/package/corpus/skills/cratis-screenplay-specifications/references/actions-beyond-commands.md +11 -1
- package/package/corpus/skills/cratis-screenplay-specifications/references/generated-fixtures.md +48 -17
- package/package/corpus/skills/cratis-screenplay-specifications/references/vocabulary.md +14 -1
- package/package/corpus/skills/cratis-screenplay-streams-and-consistency/SKILL.md +25 -21
- package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/boundaries.md +2 -2
- package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/consistency-and-concurrency.md +14 -6
- package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/multi-service-models.md +4 -3
- package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/streams-example.md +7 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +30 -22
- package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet-example.md +3 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet.md +47 -2
- package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostic-arguments.md +60 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +65 -5
- package/package/corpus/skills/cratis-screenplay-toolchain/references/executable-subset.md +50 -22
- package/package/corpus/skills/cratis-screenplay-toolchain/references/generation-checks.md +93 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/references/generation-strategies-example.md +117 -35
- package/package/corpus/skills/cratis-screenplay-toolchain/references/language-admission.md +46 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/references/preferred-syntax.md +3 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +25 -10
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +1800 -50
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/traps.md +5 -3
- package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +6 -1
- package/package/corpus/skills/cratis-screenplay-ui-composition/SKILL.md +8 -53
- package/package/corpus/skills/cratis-screenplay-ui-composition/references/file-references.md +2 -2
- package/package/corpus/skills/cratis-screenplay-ui-composition/references/interaction-example.md +54 -0
- package/package/corpus/skills/cratis-screenplay-ui-composition/verification.json +6 -3
- package/package/corpus/skills/cratis-specifications-csharp/SKILL.md +3 -2
- package/package/corpus/skills/cratis-specifications-csharp/references/application-scenarios.md +1 -1
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +30 -29
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +36 -9
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/choosing-generation.md +28 -8
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/publication-and-recovery.md +31 -0
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/sandbox-and-specrunner.md +8 -0
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/verification.json +4 -1
- package/package.json +1 -1
|
@@ -118,15 +118,23 @@ Sources and the complete shop example: [shop generation](references/shop-generat
|
|
|
118
118
|
## Choosing a strategy
|
|
119
119
|
|
|
120
120
|
The shared shop uses CustomerId (`cus_` + ULID), context-aware OrderId (TypeID),
|
|
121
|
-
InviteCode (NanoID),
|
|
121
|
+
InviteCode (NanoID), readable InvoiceNumber (pattern with checksum), random Int64
|
|
122
|
+
TicketNumber and secret ApiKey (`Bytes(32)`, `[NotAudited]` in its host).
|
|
122
123
|
Read [choices, time/tenant context and protection](references/shop-generation.md).
|
|
123
124
|
Requires Fundamentals 7.24.0 for these newer helpers; the earlier
|
|
124
125
|
UUID examples remain supported.
|
|
126
|
+
Requires Fundamentals 7.25.0 for `GenerateValue.Pattern(pattern, checksum)`, its
|
|
127
|
+
`(pattern, context, checksum)` overload, `Integer(minimum, maximum)` and
|
|
128
|
+
`HasValidChecksum(value, checksum)` (`dotnet list package --include-transitive`);
|
|
129
|
+
older packages lack them. Read the shop reference for exact signatures and UTC
|
|
130
|
+
patterns before using them; do not hand-roll checksum or random-range algorithms.
|
|
125
131
|
|
|
126
132
|
## When not to generate
|
|
127
133
|
|
|
128
134
|
Client-supplied identities stay inputs; random generation is not idempotency or
|
|
129
|
-
gapless numbering.
|
|
135
|
+
gapless/sequential numbering. Patterns are readable references, not allocators or
|
|
136
|
+
secrets; check digits catch typos, not forgery. Short codes need collision handling
|
|
137
|
+
and uniqueness/freshness enforcement appropriate to their role. UUIDs are not credentials. Byte generation can create a secret
|
|
130
138
|
in Fundamentals, but audit suppression, authorized delivery and hash storage are separate
|
|
131
139
|
host responsibilities; never treat randomness as protection.
|
|
132
140
|
|
|
@@ -15,12 +15,14 @@ A shop can use CustomerId (`cus_` + ULID) for
|
|
|
15
15
|
recognizable time-ordered customer references, OrderId (TypeID) for typed order
|
|
16
16
|
references, InviteCode (NanoID) for opaque invitation references, and ApiKey
|
|
17
17
|
(`Bytes(32)`) for a 256-bit credential. UUID remains the ordinary identity choice;
|
|
18
|
-
encoded bytes make an exact entropy budget explicit.
|
|
18
|
+
encoded bytes make an exact entropy budget explicit. InvoiceNumber uses a readable
|
|
19
|
+
pattern with Luhn check digit; TicketNumber uses an inclusive random Int64 range
|
|
20
|
+
for pickup tickets. Prefixes, dates and checksums add no entropy.
|
|
19
21
|
UUIDv7/ULID/TypeID reveal time and are not monotonic within a millisecond.
|
|
20
22
|
An invitation reference here is not by itself permission to join the shop; if
|
|
21
23
|
possession is the authorization mechanism, treat it as a protected credential too.
|
|
22
24
|
|
|
23
|
-
This complete concept excerpt requires `Cratis.Fundamentals` 7.
|
|
25
|
+
This complete concept excerpt requires `Cratis.Fundamentals` 7.25.0 or later and,
|
|
24
26
|
for the ApiKey audit attribute, `Cratis.Arc.Chronicle`. These are
|
|
25
27
|
non-stream references; use `EventSourceId<string>` instead only if a concept
|
|
26
28
|
actually identifies a Chronicle event source.
|
|
@@ -49,6 +51,17 @@ public record InviteCode(string Value) : ConceptAs<string>(Value), IGeneratable<
|
|
|
49
51
|
public static InviteCode New() => new(GenerateValue.NanoId());
|
|
50
52
|
}
|
|
51
53
|
|
|
54
|
+
public record InvoiceNumber(string Value) : ConceptAs<string>(Value), IGeneratableInContext<InvoiceNumber>
|
|
55
|
+
{
|
|
56
|
+
public static InvoiceNumber New(GenerationContext context) =>
|
|
57
|
+
new(GenerateValue.Pattern("INV-{yyyy}{MM}-#{7}", context, Checksum.Luhn));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public record TicketNumber(long Value) : ConceptAs<long>(Value), IGeneratable<TicketNumber>
|
|
61
|
+
{
|
|
62
|
+
public static TicketNumber New() => new(GenerateValue.Integer(100000, 999999));
|
|
63
|
+
}
|
|
64
|
+
|
|
52
65
|
[NotAudited]
|
|
53
66
|
public record ApiKey(string Value) : ConceptAs<string>(Value), IGeneratable<ApiKey>
|
|
54
67
|
{
|
|
@@ -80,13 +93,39 @@ Do not present a tenant-prefixed custom string as standard TypeID.
|
|
|
80
93
|
|
|
81
94
|
Use the context form only for time/tenant-dependent generation. If both interfaces
|
|
82
95
|
are implemented, callers choose context; the interfaces themselves do not dispatch.
|
|
83
|
-
|
|
84
|
-
before the Unix epoch. A fixed context fixes the timestamp, not random suffixes.
|
|
96
|
+
Time-ordered built-in context overloads reject default Now (`MissingGenerationTime`)
|
|
97
|
+
and time before the Unix epoch. A fixed context fixes the timestamp, not random suffixes.
|
|
98
|
+
|
|
99
|
+
Requires Cratis.Fundamentals 7.25.0 for `Pattern`, `Integer`, `Checksum` and
|
|
100
|
+
`HasValidChecksum` (`dotnet list package --include-transitive`); older packages
|
|
101
|
+
lack these helpers. Upgrade deliberately or retain the existing factory.
|
|
102
|
+
|
|
103
|
+
`GenerateValue.Pattern(string pattern, Checksum checksum = Checksum.None)` is the
|
|
104
|
+
date-free overload; `Pattern(string pattern, GenerationContext context,
|
|
105
|
+
Checksum checksum = Checksum.None)` uses `context.Now` in UTC for date segments.
|
|
106
|
+
A date pattern without context throws `PatternRequiresGenerationContext`;
|
|
107
|
+
default Now on the context overload throws `MissingGenerationTime`.
|
|
108
|
+
Use `#` for digits, `?` for uppercase letters, `*` for letters/digits, positive
|
|
109
|
+
ASCII classes and repeats up to 64. UTC segments are `{yyyy}`, `{yy}`, `{MM}`, `{dd}`.
|
|
110
|
+
The appended checksum uses every preceding ASCII digit, including date digits:
|
|
111
|
+
`Checksum.Luhn` and `Mod11` append one digit, `Mod97` two; Mod11 excludes payloads
|
|
112
|
+
that would need digit 10. Output including suffix is limited to 256 characters.
|
|
113
|
+
|
|
114
|
+
Generation does not add a validator. Use
|
|
115
|
+
`GenerateValue.HasValidChecksum(value, Checksum.Luhn)` in the concept's validator
|
|
116
|
+
when supplied/stored values must obey the arithmetic too; combine it with shape
|
|
117
|
+
validation. `Integer(long minimum, long maximum)` returns `long`, includes both
|
|
118
|
+
endpoints and supports the full Int64 range with unbiased secure randomness.
|
|
119
|
+
Enforce unique short payload codes at append: randomness alone does not reserve
|
|
120
|
+
one, and event-source freshness does not protect a different payload value.
|
|
85
121
|
|
|
86
122
|
## When not to generate
|
|
87
123
|
|
|
88
124
|
- Client-minted customer/order IDs stay inputs. Do not replace them on retry.
|
|
89
|
-
- Random values supply neither idempotency nor gapless
|
|
125
|
+
- Random values and readable patterns supply neither idempotency nor gapless/sequential
|
|
126
|
+
invoice allocation. A legally gapless invoice number needs an allocator.
|
|
127
|
+
- Check digits detect transcription mistakes, not forgery or authorization; patterns
|
|
128
|
+
are not secrets. Low-entropy codes need explicit collision/uniqueness handling.
|
|
90
129
|
- An ID is not an authentication token or authorization policy.
|
|
91
130
|
- ApiKey is a **secret**, not an event-source ID: event-source IDs are plaintext metadata
|
|
92
131
|
and cannot be encrypted. Use a separate `ApiKeyId` as the identity and keep ApiKey a
|
|
@@ -102,7 +141,11 @@ before the Unix epoch. A fixed context fixes the timestamp, not random suffixes.
|
|
|
102
141
|
|
|
103
142
|
Fundamentals `Source/DotNET/Fundamentals/Concepts/GenerationContext.cs`,
|
|
104
143
|
`IGeneratableInContext.cs`, `GenerateValue.TimeOrderedStrings.cs`,
|
|
105
|
-
`GenerateValue.RandomStrings.cs
|
|
144
|
+
`GenerateValue.RandomStrings.cs`, `GenerateValue.Patterns.cs`,
|
|
145
|
+
`GenerateValue.Numbers.cs`, `Checksum.cs`; at Fundamentals v7.25.0,
|
|
146
|
+
`Documentation/csharp/generating-values/patterns.md`,
|
|
147
|
+
`Documentation/csharp/generating-values/reference.md` and
|
|
148
|
+
`Documentation/csharp/generating-values/context.md`.
|
|
106
149
|
Arc `Source/DotNET/Chronicle/Commands/NotAuditedAttribute.cs`,
|
|
107
150
|
`CommandCausationValues.cs` (command/type/property exclusion only, never
|
|
108
151
|
payload encryption or log protection);
|
|
@@ -12,37 +12,41 @@ guarantees. Then write it as `Automation` and `Translate` slices that say truthf
|
|
|
12
12
|
protected, what is only recorded, and who acts. Grammar depth is in
|
|
13
13
|
`cratis-screenplay-captures-and-reactions`; this skill owns the decisions.
|
|
14
14
|
|
|
15
|
-
**Translation crosses an application boundary:**
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
**Translation crosses an application boundary:** private-to-private follow-up is
|
|
16
|
+
Automation, even if a reactor realizes it. Keep captures in Translate and reactions
|
|
17
|
+
to their local facts in separate Automation slices. Read
|
|
18
|
+
[public events and direction](references/public-events-and-direction.md) when
|
|
19
|
+
choosing direction, folding events or specifying publication: it owns the ESM v9
|
|
20
|
+
forms, PLAY0616 and directionless Translate's PLAY0694 split boundary.
|
|
21
|
+
Requires Screenplay 4.176.0 or later (`screenplay --version`) for PLAY0694; older compilers leave that directionless shape unchecked.
|
|
22
22
|
One `source events` capture reads one origin (event store); split several origins.
|
|
23
23
|
Requires Screenplay 4.155.0 (`screenplay --version`) for PLAY0687; older tools leave it unchecked.
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
identity, effect and pending-work contract at that point; do not postpone it to the final review.
|
|
25
|
+
Model behavior first; code implements external calls, adapters, actors and refused
|
|
26
|
+
target scope. Follow `cratis-screenplay-modeling-lifecycle` for session discipline
|
|
27
|
+
and `cratis-screenplay-toolchain` for verdicts. Settle input, identity, effect and
|
|
28
|
+
pending-work contracts when changing each reaction/capture, not at final review.
|
|
30
29
|
|
|
31
30
|
## Tool and realization facts (read before promising anything)
|
|
32
|
-
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
31
|
+
- V1, V3, V4 and target rendering are separate; name the compiler and never remove
|
|
32
|
+
a refused construct. Run `screenplay test` or MCP `run-specifications` for V4.
|
|
33
|
+
- Read [realization and gap-fill](references/realization-and-gap-fill.md) before
|
|
34
|
+
promising Automation/Translate delivery (STAGE-ESM-024).
|
|
35
|
+
- Invokes have no caller without `runs as`. Read captures-and-reactions
|
|
36
|
+
[invocation identity](../cratis-screenplay-captures-and-reactions/references/invocation-identity.md)
|
|
37
|
+
for the ESM v10 actor and role/authenticated versus claim/opaque admission.
|
|
38
|
+
|
|
39
|
+
## Atomic production boundaries and source identity
|
|
40
|
+
|
|
41
|
+
Start new models with application-root `reaction batches atomic` (ESM v22 or later).
|
|
42
|
+
Each trigger occurrence's direct productions and each selected refusal branch are
|
|
43
|
+
separate all-or-none batches; invoked commands remain independent. Absence retains
|
|
44
|
+
legacy per-fact behavior even at later versions. Assert no failed-batch facts and
|
|
45
|
+
unchanged views, not only `then error`. Stage refuses v22 (STAGE-ESM-016) and
|
|
46
|
+
atomic mode in admitted v23/v24 models (STAGE-ESM-043); keep the semantics as gap-fill.
|
|
47
|
+
Read [atomic batches and source mappings](../cratis-screenplay-captures-and-reactions/references/atomic-batches-and-source-mappings.md)
|
|
48
|
+
when choosing these boundaries or mapping an invoked identifier from `$eventSourceId`
|
|
49
|
+
(or `$eventContext.eventSourceId`) instead of copying it into event payload.
|
|
46
50
|
|
|
47
51
|
## Effect guarantees and recovery traps
|
|
48
52
|
| Guarantee | What it promises | What can show it |
|
|
@@ -102,19 +106,9 @@ of each, and how each record finds our entity (the correlation strategy); and fo
|
|
|
102
106
|
occurrence, the effect and who acts. Cite existing answers instead of asking again. Missing
|
|
103
107
|
correlation is the most common cause of failed integrations: surface it first.
|
|
104
108
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
topic, file), format, who authenticates it?" Follow-up per system: "Does the record carry our
|
|
109
|
-
entity id, or do we need to remember their id against ours?"
|
|
110
|
-
2. **Mapping.** "For the hardest record: does it map directly to one fact of ours, need several
|
|
111
|
-
facts, or need data we already hold?" Follow-up if not direct: "What do we look up, and what
|
|
112
|
-
happens when the record arrives before that data exists?"
|
|
113
|
-
3. **Automations.** "What happens on its own after <fact>? Can it fail, wait, or need a person? What
|
|
114
|
-
do people see meanwhile? Who is allowed to do it?" Follow-up: "What makes it stop? What if it ran
|
|
115
|
-
twice?"
|
|
116
|
-
4. **Recovery.** "Which records or steps can we not accept, and who fixes them, how, and how does
|
|
117
|
-
processing resume?"
|
|
109
|
+
Read [integration interview prompts](references/integration-interview.md) when
|
|
110
|
+
sources, mapping, automation ownership or recovery are unsettled. Ask one group at
|
|
111
|
+
a time; treat "unsure" as an open question.
|
|
118
112
|
|
|
119
113
|
**Unattended:** assume visibly. Record each assumption as a labelled open decision in `STATE.md`
|
|
120
114
|
(`.ai-work/screenplay/<model-slug>/STATE.md`), mark the dependent slice open, never write a mapping
|
|
@@ -155,7 +149,8 @@ or actor that nobody confirmed. Read `references/worked-integration.md` when you
|
|
|
155
149
|
7. **Translate outside facts** (`references/translation-patterns.md`): enter only via `capture` or a
|
|
156
150
|
translator reaction, in a `Translate` slice; correlate first; keep the external fact distinct from
|
|
157
151
|
ours; trace source fields *and* every required target field; decide dedup, ordering and recovery
|
|
158
|
-
ownership. A
|
|
152
|
+
ownership. A reaction to a capture's local fact is a separate Automation, not a
|
|
153
|
+
second job inside Translate. A worker after translation needs a distinct local decision, obligation or effect.
|
|
159
154
|
8. **Specify and audit.** Work through `references/cases-to-specify.md` per declaration and hand the
|
|
160
155
|
named cases to `cratis-screenplay-scenario-coverage`. Produce the audit in `references/audit-format.md`.
|
|
161
156
|
|
|
@@ -167,9 +162,16 @@ or actor that nobody confirmed. Read `references/worked-integration.md` when you
|
|
|
167
162
|
- Clock triggers take no values (PLAY0450) and no `by` on reads (PLAY0443). `for each <View>` is
|
|
168
163
|
reserved, not available.
|
|
169
164
|
- Capture `when` cannot mix `and` and `or` (PLAY0089). A capture without `key` does not bind.
|
|
165
|
+
- For `source events`, `key` is a required property on every `from` event (PLAY0700);
|
|
166
|
+
specs supply `given <Event>` / `when append <Event>`, not capture records (PLAY0701).
|
|
167
|
+
- First sight is `added` only. Use `when added` separately for initial facts; seed
|
|
168
|
+
record updates with `given capture` of the same key. Read captures-and-reactions
|
|
169
|
+
`references/record-capture-specifications.md` for the prerequisite and child/nested rules.
|
|
170
170
|
- Current V1 warns on undeclared capture/removal events (PLAY0166); V3 remains a
|
|
171
171
|
separate binder check.
|
|
172
|
-
- A trigger with `reads` that `produces` directly fails binding: decide in a command.
|
|
172
|
+
- A trigger with `reads` that `produces` directly fails binding: decide in a command.
|
|
173
|
+
Command reads can protect with `command reads protected` and admitted shapes (v25);
|
|
174
|
+
trigger reads cannot. Stage refuses protected reads (STAGE-ESM-044); target protection remains a separate check.
|
|
173
175
|
- An authorized command exercised in a spec without `given caller` is PLAY0389 at binding.
|
|
174
176
|
- A list query (`=> Item[]`) binds (a snapshot list is not rendered, `STAGE-ESM-010`);
|
|
175
177
|
a clock sweep that iterates items needs a code body the reference does not run
|
|
@@ -30,7 +30,9 @@ One spec in the slice does not cover the others.
|
|
|
30
30
|
## Translations
|
|
31
31
|
| Case | Question | Typical shape |
|
|
32
32
|
|---|---|---|
|
|
33
|
-
|
|
|
33
|
+
| first sight | new record key arrives | record `when capture`, `when added` append -> `then <Fact>` and any separate Automation follow-up |
|
|
34
|
+
| update | a field changes for a known key | `given capture` same key's previous record + `when capture`; field-change append holds |
|
|
35
|
+
| consumed public event | capture has `source events` | `given <FromEvent>` / `when append <FromEvent>`, never capture-record fixtures (PLAY0701) |
|
|
34
36
|
| arrives before our entity | the reference is unknown to us | decide: park, reject, or record an orphan fact for follow-up |
|
|
35
37
|
| duplicate delivery | same record again | `given capture` (same record) + `when capture`: nothing new; or constraint rejection on our fact |
|
|
36
38
|
| out of order | an older record after a newer one | `given capture` newer + `when capture` older; expected outcome stated |
|
|
@@ -66,4 +68,11 @@ One spec in the slice does not cover the others.
|
|
|
66
68
|
tool's compiler stops before v6 does it report a false PLAY0285 on a cascade:
|
|
67
69
|
then keep the cascade out of the command spec, specify it in the Automation slice
|
|
68
70
|
(`when append <Trigger>`) and record the expectation. See `cratis-screenplay-scenario-coverage`.
|
|
69
|
-
- `given capture` never persists between specs: state the baseline in each
|
|
71
|
+
- `given capture` never persists between specs: state the baseline in each record
|
|
72
|
+
update spec. First records (root, child, nested) are added only; field-change
|
|
73
|
+
`and`/`or` and transitions need previous state. Expressions/maps/unguarded record
|
|
74
|
+
appends are unchanged. See captures-and-reactions `references/record-capture-specifications.md`.
|
|
75
|
+
- For `source events`, use prior typed events instead of `given capture`; cover
|
|
76
|
+
first added, per-key overlays, unchanged input, independent keys and optional
|
|
77
|
+
foreign `for` unrelated to the content key. Reference execution does not prove
|
|
78
|
+
capture redelivery deduplication or observer ordering.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<!-- Copyright (c) Cratis. All rights reserved. -->
|
|
2
|
+
<!-- Licensed under the MIT license. See LICENSE file in the project root for full license information. -->
|
|
3
|
+
|
|
4
|
+
# Integration interview prompts
|
|
5
|
+
|
|
6
|
+
Ask one group at a time, following up from the answer. Accept "unsure" as an open
|
|
7
|
+
question, not an invented answer.
|
|
8
|
+
|
|
9
|
+
1. **Sources.** "Which systems send us facts? For each: name, record types, channel
|
|
10
|
+
(webhook, poll, topic, file), format, who authenticates it?" Follow-up per system:
|
|
11
|
+
"Does the record carry our entity id, or do we need to remember their id against ours?"
|
|
12
|
+
2. **Mapping.** "For the hardest record: does it map directly to one fact of ours, need
|
|
13
|
+
several facts, or need data we already hold?" Follow-up if not direct: "What do we
|
|
14
|
+
look up, and what happens when the record arrives before that data exists?"
|
|
15
|
+
3. **Automations.** "What happens on its own after <fact>? Can it fail, wait, or need a
|
|
16
|
+
person? What do people see meanwhile? Who is allowed to do it?" Follow-up: "What
|
|
17
|
+
makes it stop? What if it ran twice?"
|
|
18
|
+
4. **Recovery.** "Which records or steps can we not accept, and who fixes them, how,
|
|
19
|
+
and how does processing resume?"
|
|
20
|
+
|
|
21
|
+
Skip questions already answered by the brief or model. Missing correlation is the
|
|
22
|
+
most common cause of failed integrations: surface it first. Unattended work records
|
|
23
|
+
assumptions as labeled open decisions in `.ai-work/screenplay/<model-slug>/STATE.md`
|
|
24
|
+
and marks dependent slices open, never inventing mappings or actors.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- Copyright (c) Cratis. All rights reserved. -->
|
|
2
2
|
<!-- Licensed under the MIT license. See LICENSE file in the project root for full license information. -->
|
|
3
3
|
|
|
4
|
-
# Public events and translation direction
|
|
4
|
+
# Public events and translation direction
|
|
5
5
|
|
|
6
6
|
## Contents
|
|
7
7
|
|
|
@@ -100,26 +100,92 @@ module Integration
|
|
|
100
100
|
direction inbound
|
|
101
101
|
event ShipmentDispatched from "shipping"
|
|
102
102
|
orderId OrderId
|
|
103
|
-
|
|
103
|
+
carrier String
|
|
104
|
+
event ShipmentDelivered from "shipping"
|
|
104
105
|
orderId OrderId
|
|
106
|
+
status String
|
|
107
|
+
event OrderDispatched
|
|
108
|
+
carrier String
|
|
109
|
+
event OrderDeliveryRecorded
|
|
110
|
+
carrier String
|
|
111
|
+
status String
|
|
105
112
|
capture ShipmentTracking
|
|
106
113
|
source events
|
|
107
114
|
from ShipmentDispatched
|
|
115
|
+
from ShipmentDelivered
|
|
108
116
|
key orderId
|
|
109
117
|
append OrderDispatched
|
|
110
|
-
|
|
118
|
+
when added
|
|
119
|
+
carrier = $.carrier
|
|
120
|
+
append OrderDeliveryRecorded
|
|
121
|
+
when status
|
|
122
|
+
carrier = $.carrier
|
|
123
|
+
status = $.status
|
|
124
|
+
specification RecordingTheFirstDispatch
|
|
125
|
+
when append ShipmentDispatched
|
|
126
|
+
orderId = "3fa85f64-5717-4562-b3fc-2c963f66afa6"
|
|
127
|
+
carrier = "DHL"
|
|
128
|
+
then OrderDispatched
|
|
129
|
+
for "3fa85f64-5717-4562-b3fc-2c963f66afa6"
|
|
130
|
+
carrier = "DHL"
|
|
131
|
+
specification FoldingEarlierDispatchIntoDelivery
|
|
132
|
+
given ShipmentDispatched
|
|
133
|
+
orderId = "3fa85f64-5717-4562-b3fc-2c963f66afa6"
|
|
134
|
+
carrier = "DHL"
|
|
135
|
+
when append ShipmentDelivered
|
|
136
|
+
orderId = "3fa85f64-5717-4562-b3fc-2c963f66afa6"
|
|
137
|
+
status = "delivered"
|
|
138
|
+
then OrderDeliveryRecorded
|
|
139
|
+
for "3fa85f64-5717-4562-b3fc-2c963f66afa6"
|
|
140
|
+
carrier = "DHL"
|
|
141
|
+
status = "delivered"
|
|
142
|
+
specification IgnoringAnUnchangedDispatch
|
|
143
|
+
given ShipmentDispatched
|
|
144
|
+
orderId = "3fa85f64-5717-4562-b3fc-2c963f66afa6"
|
|
145
|
+
carrier = "DHL"
|
|
146
|
+
when append ShipmentDispatched
|
|
147
|
+
orderId = "3fa85f64-5717-4562-b3fc-2c963f66afa6"
|
|
148
|
+
carrier = "DHL"
|
|
149
|
+
then no events
|
|
111
150
|
```
|
|
112
151
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
152
|
+
Requires Screenplay 4.171.0 or later (`screenplay --version`) for event-capture
|
|
153
|
+
reference execution and PLAY0700/0701; older runners do not deliver these inputs
|
|
154
|
+
to captures. Run `screenplay <model> --warnaserror`, then `screenplay test <model>`:
|
|
155
|
+
zero diagnostics and all three capture specifications passed are the pass signals.
|
|
156
|
+
|
|
157
|
+
Present the consumed public event itself: `given <Event>` / `when append <Event>`.
|
|
158
|
+
Fields are typed by its local declaration. `given capture` / `when capture` is
|
|
159
|
+
PLAY0701, with a repair only for exactly one `from` event (several are ambiguous).
|
|
160
|
+
`for` is optional on foreign fixtures: when supplied, it is opaque nonempty text
|
|
161
|
+
identifying the foreign source, not the capture key. A content key such as `orderId`
|
|
162
|
+
must be required on every `from` event (PLAY0700); `$eventSourceId` and other context
|
|
163
|
+
keys are refused. An empty or whitespace-only text key fails execution, even in a
|
|
164
|
+
given before the action; non-text/non-numeric keys are Unsupported.
|
|
165
|
+
|
|
166
|
+
Givens fold in authored order without appending. Each event overlays its top-level
|
|
167
|
+
properties onto state for that typed key: absent properties retain earlier values;
|
|
168
|
+
objects/lists replace whole values. First sight is `added` only, unchanged overlays
|
|
169
|
+
append nothing, and field/`and`/`or`/transition guards require a modification. An
|
|
170
|
+
append without `when` holds on any change, not on every delivery. Maps apply to
|
|
171
|
+
before and after states; `$.field` reads the mapped merged state. An expression
|
|
172
|
+
guard evaluates the after state only on a change. Root `when removed` never holds.
|
|
173
|
+
|
|
174
|
+
Captures run after reactions to the same input settle; each capture append settles
|
|
175
|
+
its own cascade before the next. Mixed capture/reaction assertions may need
|
|
176
|
+
`then events in any order`: reference order does not prove independent observer
|
|
177
|
+
order. Only `$context.occurred` (from `given clock`) is admitted; other context
|
|
178
|
+
members fail binding. `children`/`nested` over events remain Unsupported, as do
|
|
179
|
+
composite/list values used as scalars or watched by guards. Reference state never
|
|
180
|
+
persists between specifications and does not prove redelivery deduplication,
|
|
181
|
+
source acknowledgement, retry safety or context propagation. A passing reference
|
|
182
|
+
scenario is not renderer admission; Stage must refuse forms Chronicle cannot realize.
|
|
117
183
|
|
|
118
184
|
## Admission and evidence
|
|
119
185
|
|
|
120
|
-
ESM v9
|
|
121
|
-
|
|
122
|
-
|
|
186
|
+
ESM v9 is selected by use of public events, origins, direction, event-target
|
|
187
|
+
builders or events-source captures. Publication and admitted event-capture
|
|
188
|
+
reference scenarios execute; imported shapes still refuse binding.
|
|
123
189
|
Stage 4.52.0 (previous CLI 3.46.1, history) audited only through v7. The CLI/Stage pair (toolchain `references/renderable-subset.md`)
|
|
124
190
|
reaches construct admission through its bundled ceiling but still refuses publication (STAGE-ESM-032), foreign
|
|
125
191
|
events/events-source captures (STAGE-ESM-033); source admission is not rendering.
|
|
@@ -22,6 +22,11 @@ recovery behavior rather than assuming this handler supplies all-or-nothing sett
|
|
|
22
22
|
rejected model renderable, and never claim a whole-application V5 from a subset. Choose the route
|
|
23
23
|
with `cratis-screenplay-render-and-gap-fill`.
|
|
24
24
|
|
|
25
|
+
Application-root `reaction batches atomic` also blocks Stage delivery: v22
|
|
26
|
+
refuses STAGE-ESM-016; mode in admitted v23–v25 refuses STAGE-ESM-043. Preserve the
|
|
27
|
+
per-occurrence/selected-branch batch boundary and independent invoked commands.
|
|
28
|
+
Atomic appends do not prove redelivery deduplication or external exactly-once effects.
|
|
29
|
+
|
|
25
30
|
## Where the pieces go (hand-written)
|
|
26
31
|
| Model element | Realization | Skill |
|
|
27
32
|
|---|---|---|
|
|
@@ -188,7 +188,7 @@ module Certification
|
|
|
188
188
|
## Design-only additions
|
|
189
189
|
|
|
190
190
|
Two things a real queue often wants stay out of the complete model above: a list query (the
|
|
191
|
-
visible queue) and a retry sweep that reads the whole view. The list query binds (Stage
|
|
191
|
+
visible queue) and a retry sweep that reads the whole view. The list query binds (Stage renders snapshot and observable lists); the sweep needs a code body the
|
|
192
192
|
reference does not run, and durable per-item fan-out is outside the language. Say so
|
|
193
193
|
in the verdict.
|
|
194
194
|
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
# Example: a
|
|
1
|
+
# Example: a capture and its follow-up Automation
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- Model
|
|
6
|
+
- Notes for the reader
|
|
2
7
|
|
|
3
8
|
A complete model: a webhook record from an outside proctoring service is captured, kept as an
|
|
4
|
-
external fact in the provider's vocabulary, then
|
|
9
|
+
external fact in the provider's vocabulary, then followed by a separate Automation that records our result. It
|
|
5
10
|
binds as ESM v6 (`executableReady: true`), standalone and through `cratis screenplay mcp`; a
|
|
6
11
|
compiler that stops before v6 compiles it (V1) but rejects the Translate slice at binding
|
|
7
12
|
(PLAY0268). `cratis render` refuses it (`STAGE-ESM-016` or `STAGE-ESM-024`, by renderer).
|
|
@@ -10,6 +15,8 @@ Read the slice `description`: it is the per-field disposition (map, translate, i
|
|
|
10
15
|
states what this example does not do. Examples never show the whole integration contract; use
|
|
11
16
|
`references/integration-contracts.md` and `references/worked-integration.md` for the rest.
|
|
12
17
|
|
|
18
|
+
## Model
|
|
19
|
+
|
|
13
20
|
```screenplay
|
|
14
21
|
// Translate slice. Correlation is created on OUR side: BookExam allocates the attempt id and the
|
|
15
22
|
// realization hands it to the proctoring service as its reference; the service's webhook echoes
|
|
@@ -57,7 +64,7 @@ module Exams
|
|
|
57
64
|
then denied
|
|
58
65
|
|
|
59
66
|
slice Translate ImportProctorResults
|
|
60
|
-
description "Per external field: reference -> correlation key (our attempt id, echoed); outcome -> translated to our enum; score -> kept; examinerNote -> ignored (free text, may hold personal data, no consumer). Repeated delivery: the first record of a key appends once (`when added
|
|
67
|
+
description "Per external field: reference -> correlation key (our attempt id, echoed); outcome -> translated to our enum; score -> kept; examinerNote -> ignored (free text, may hold personal data, no consumer). Repeated delivery: the first record of a key appends once (`when added`); later records compare outcome only. An unchanged outcome appends nothing, even if the score changed, so it does not implement score corrections. OneResultPerAttempt refuses a second local result. Changed outcomes and score-only corrections need an explicit correction policy (open decision, recorded in STATE.md, not an overwrite) before this is a complete integration."
|
|
61
68
|
capture ProctorResults
|
|
62
69
|
source webhook
|
|
63
70
|
path /webhooks/proctoring/results
|
|
@@ -70,15 +77,13 @@ module Exams
|
|
|
70
77
|
when added
|
|
71
78
|
outcome = $.outcome
|
|
72
79
|
score = $.score
|
|
80
|
+
append ProctorResultReceived
|
|
81
|
+
when outcome
|
|
82
|
+
outcome = $.outcome
|
|
83
|
+
score = $.score
|
|
73
84
|
event ProctorResultReceived
|
|
74
85
|
outcome ProctorOutcome
|
|
75
86
|
score Int
|
|
76
|
-
event ExamPassed
|
|
77
|
-
score Int
|
|
78
|
-
event ExamFailed
|
|
79
|
-
constraint OneResultPerAttempt
|
|
80
|
-
unique event ExamPassed
|
|
81
|
-
unique event ExamFailed
|
|
82
87
|
specification TranslatingAPass
|
|
83
88
|
when capture ProctorResults
|
|
84
89
|
reference = "7e9d1c2b-4a3f-4e5d-8c6b-1a2b3c4d5e06"
|
|
@@ -91,18 +96,7 @@ module Exams
|
|
|
91
96
|
then ExamPassed
|
|
92
97
|
for "7e9d1c2b-4a3f-4e5d-8c6b-1a2b3c4d5e06"
|
|
93
98
|
score = 87
|
|
94
|
-
|
|
95
|
-
given ExamPassed
|
|
96
|
-
for "7e9d1c2b-4a3f-4e5d-8c6b-1a2b3c4d5e06"
|
|
97
|
-
score = 87
|
|
98
|
-
when append ProctorResultReceived
|
|
99
|
-
for "7e9d1c2b-4a3f-4e5d-8c6b-1a2b3c4d5e06"
|
|
100
|
-
outcome = "failed"
|
|
101
|
-
score = 40
|
|
102
|
-
then error "Constraint 'OneResultPerAttempt' is violated: the event source already has the constrained event."
|
|
103
|
-
|
|
104
|
-
slice Automation TranslateProctorResults
|
|
105
|
-
description "Our facts from the provider's: the translators react to the external fact the Translate slice records"
|
|
99
|
+
slice Automation RecordExamResult
|
|
106
100
|
reaction PassTranslator
|
|
107
101
|
when ProctorResultReceived
|
|
108
102
|
outcome
|
|
@@ -115,11 +109,33 @@ module Exams
|
|
|
115
109
|
outcome
|
|
116
110
|
produces ExamFailed
|
|
117
111
|
where outcome == "failed"
|
|
112
|
+
event ExamPassed
|
|
113
|
+
score Int
|
|
114
|
+
event ExamFailed
|
|
115
|
+
constraint OneResultPerAttempt
|
|
116
|
+
unique event ExamPassed
|
|
117
|
+
unique event ExamFailed
|
|
118
|
+
specification RefusingASecondResult
|
|
119
|
+
given ExamPassed
|
|
120
|
+
for "7e9d1c2b-4a3f-4e5d-8c6b-1a2b3c4d5e06"
|
|
121
|
+
score = 87
|
|
122
|
+
when append ProctorResultReceived
|
|
123
|
+
for "7e9d1c2b-4a3f-4e5d-8c6b-1a2b3c4d5e06"
|
|
124
|
+
outcome = "failed"
|
|
125
|
+
score = 40
|
|
126
|
+
then error "Constraint 'OneResultPerAttempt' is violated: the event source already has the constrained event."
|
|
118
127
|
```
|
|
119
128
|
|
|
120
|
-
Notes for the reader
|
|
129
|
+
## Notes for the reader
|
|
121
130
|
|
|
122
|
-
-
|
|
131
|
+
- Keep the capture and its appended event in Translate; put reactions to that local
|
|
132
|
+
event in a separate Automation. Co-location in a directionless Translate warns
|
|
133
|
+
PLAY0694 and fails `--warnaserror`; explicit inbound refuses it with PLAY0616.
|
|
134
|
+
`then` lists every new fact, so `TranslatingAPass` includes the Automation result.
|
|
135
|
+
- `when added` records first sight; the separate `when outcome` append handles
|
|
136
|
+
later changes. For an update spec, seed the same reference with `given capture`.
|
|
137
|
+
Requires Screenplay 4.175.0 or later (`screenplay --version`); older evaluators
|
|
138
|
+
treat a first record's fields as changed.
|
|
123
139
|
- The unauthenticated-booking spec needs an explicit `given caller` (empty means no caller);
|
|
124
140
|
an authorized command exercised without one is PLAY0389 at binding.
|
|
125
141
|
- Authenticity of the webhook, tenant ownership and a score-correction policy are not in the
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Translation patterns
|
|
2
2
|
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- 1. Where outside facts may enter
|
|
6
|
+
- 2. Correlation first
|
|
7
|
+
- 3. Two vocabularies
|
|
8
|
+
- 4. Per-field disposition
|
|
9
|
+
- 5. Dedup and ordering
|
|
10
|
+
- 6. Corrections from outside
|
|
11
|
+
- 7. Specifying translations
|
|
12
|
+
|
|
3
13
|
Complete compiled example: `translate-example.md` (binds as ESM v6; a compiler that stops before v6
|
|
4
14
|
compiles it but rejects the slice at binding).
|
|
5
15
|
|
|
@@ -7,8 +17,15 @@ compiles it but rejects the slice at binding).
|
|
|
7
17
|
Only two routes, both in a `Translate` slice:
|
|
8
18
|
- **`capture`** over a source (api poll, webhook, message topic): key, map, conditional
|
|
9
19
|
appends. Change detection compares each record with the last one seen for the same key.
|
|
10
|
-
- **translator `reaction`** over
|
|
11
|
-
|
|
20
|
+
- **translator `reaction`** over a foreign public event declared with its origin.
|
|
21
|
+
Opaque unquoted imports do not bind. A reaction to a local event a capture
|
|
22
|
+
appended is a follow-up Automation in a separate slice, not another translation.
|
|
23
|
+
|
|
24
|
+
A directionless Translate with an unrouted reaction to its own capture's appends
|
|
25
|
+
(including children/nested) warns PLAY0694 and fails `--warnaserror`; explicitly
|
|
26
|
+
inbound local-event consumption is PLAY0616. Keep the capture in Translate and
|
|
27
|
+
choose a separate Automation slice and its specs; there is no automatic repair.
|
|
28
|
+
Requires Screenplay 4.176.0 or later (`screenplay --version`) for PLAY0694; older compilers leave the directionless shape unchecked.
|
|
12
29
|
Not a translation: our own event-to-event follow-up (Automation), infrastructure plumbing,
|
|
13
30
|
and raw database row changes published as-is.
|
|
14
31
|
|
|
@@ -25,8 +42,8 @@ thing by it. Keep it as a property when it is needed to correlate or deduplicate
|
|
|
25
42
|
## 3. Two vocabularies
|
|
26
43
|
- The capture appends an **external fact** in the provider's terms (`ProctorResultReceived`
|
|
27
44
|
with a translated `outcome`).
|
|
28
|
-
-
|
|
29
|
-
each guarded by our constraints.
|
|
45
|
+
- Reactions to that local fact record further **our facts** (`ExamPassed`, `ExamFailed`)
|
|
46
|
+
in a separate Automation slice, each guarded by our constraints.
|
|
30
47
|
- A further worker needs a distinct local decision, obligation or external effect; otherwise
|
|
31
48
|
project views from our fact directly.
|
|
32
49
|
- Name our facts for what they mean to us, not for the transport (`<X>Synced`,
|
|
@@ -78,11 +95,17 @@ is a new fact for us (`ResultCorrected`), never an overwrite. Mutually exclusive
|
|
|
78
95
|
event with `released by` or a separate correction flow is right.
|
|
79
96
|
|
|
80
97
|
## 7. Specifying translations
|
|
81
|
-
- `when capture <Capture>` with
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
unchanged
|
|
86
|
-
|
|
87
|
-
-
|
|
88
|
-
|
|
98
|
+
- Record sources: `when capture <Capture>` with source fields -> `then` every new
|
|
99
|
+
fact, including follow-up Automation appends. A first record of a key is added
|
|
100
|
+
only: use a separate `when added` append for first sight, keeping the field guard
|
|
101
|
+
for updates. Seed updates with `given capture` of the same key. Child/nested
|
|
102
|
+
additions follow the same rule; expressions, maps and unguarded appends are unchanged.
|
|
103
|
+
Requires Screenplay 4.175.0 or later (`screenplay --version`); older evaluators
|
|
104
|
+
treat first-record fields as changed.
|
|
105
|
+
- Event sources: `given <FromEvent>` / `when append <FromEvent>`, never capture
|
|
106
|
+
records (PLAY0701). The key is required on every source event (PLAY0700).
|
|
107
|
+
Read [public event captures](public-events-and-direction.md) for executable examples,
|
|
108
|
+
overlay semantics and their prerequisite.
|
|
109
|
+
- `when append <LocalFact>` -> `then <OurFact>` tests the follow-up Automation alone.
|
|
110
|
+
- Run admitted cases with `screenplay test <model>`; all selected specs must pass.
|
|
111
|
+
Case list: `cases-to-specify.md`.
|