@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.
Files changed (132) hide show
  1. package/package/corpus/agents/spec-writer.md +2 -2
  2. package/package/corpus/harnesses/copilot/instructions/application-profile.instructions.md +2 -2
  3. package/package/corpus/harnesses/copilot/instructions/glossary.instructions.md +2 -2
  4. package/package/corpus/harnesses/copilot/instructions/specs.scenarios.csharp.instructions.md +7 -4
  5. package/package/corpus/harnesses/copilot/instructions/vertical-slices.instructions.md +22 -13
  6. package/package/corpus/product-sync.json +11 -10
  7. package/package/corpus/prompts/add-business-rule.prompt.md +1 -1
  8. package/package/corpus/rules/application-profile.md +2 -2
  9. package/package/corpus/rules/glossary.md +2 -2
  10. package/package/corpus/rules/specs.scenarios.csharp.md +7 -4
  11. package/package/corpus/rules/vertical-slices.md +22 -13
  12. package/package/corpus/skills/cratis-application-slice-conformance/SKILL.md +1 -1
  13. package/package/corpus/skills/cratis-application-slice-specifications/SKILL.md +4 -3
  14. package/package/corpus/skills/cratis-application-slice-specifications/references/query-and-decision-scenarios.md +12 -3
  15. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/SKILL.md +12 -7
  16. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authorization.md +11 -11
  17. package/package/corpus/skills/cratis-arc-command/SKILL.md +3 -2
  18. package/package/corpus/skills/cratis-arc-command/references/decisions-and-routing.md +95 -51
  19. package/package/corpus/skills/cratis-arc-command/references/fresh-identifiers.md +5 -2
  20. package/package/corpus/skills/cratis-arc-command/references/generated-values.md +27 -12
  21. package/package/corpus/skills/cratis-arc-command/references/read-model-injection.md +9 -5
  22. package/package/corpus/skills/cratis-arc-command/references/shop-generation.md +17 -6
  23. package/package/corpus/skills/cratis-arc-command-validation/SKILL.md +99 -52
  24. package/package/corpus/skills/cratis-chronicle-decision-reads/SKILL.md +37 -15
  25. package/package/corpus/skills/cratis-chronicle-decision-reads/references/admission-and-ownership.md +3 -2
  26. package/package/corpus/skills/cratis-chronicle-decision-reads/references/choosing-how-a-rule-holds.md +277 -138
  27. package/package/corpus/skills/cratis-chronicle-event-constraints/SKILL.md +4 -4
  28. package/package/corpus/skills/cratis-chronicle-event-modeling/SKILL.md +6 -4
  29. package/package/corpus/skills/cratis-chronicle-read-model/SKILL.md +2 -1
  30. package/package/corpus/skills/cratis-chronicle-reducer/SKILL.md +6 -3
  31. package/package/corpus/skills/cratis-code-review/SKILL.md +6 -3
  32. package/package/corpus/skills/cratis-fundamentals-concept/SKILL.md +10 -2
  33. package/package/corpus/skills/cratis-fundamentals-concept/references/shop-generation.md +49 -6
  34. package/package/corpus/skills/cratis-screenplay-automations-and-translations/SKILL.md +43 -41
  35. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/cases-to-specify.md +11 -2
  36. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/integration-interview.md +24 -0
  37. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/public-events-and-direction.md +76 -10
  38. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/realization-and-gap-fill.md +5 -0
  39. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/todo-list-example.md +1 -1
  40. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/translate-example.md +39 -23
  41. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/translation-patterns.md +35 -12
  42. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/SKILL.md +51 -81
  43. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/atomic-batches-and-source-mappings.md +83 -0
  44. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/capture-map-and-example.md +14 -4
  45. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/reaction-forms.md +59 -0
  46. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/record-capture-specifications.md +60 -0
  47. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/specifying-triggers-and-clock.md +5 -1
  48. package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +26 -28
  49. package/package/corpus/skills/cratis-screenplay-command-surface/references/described-handlers.md +82 -0
  50. package/package/corpus/skills/cratis-screenplay-command-surface/references/generated-values-and-responses.md +82 -28
  51. package/package/corpus/skills/cratis-screenplay-command-surface/references/protected-reads.md +113 -0
  52. package/package/corpus/skills/cratis-screenplay-command-surface/references/shop-generation.md +45 -12
  53. package/package/corpus/skills/cratis-screenplay-command-surface/references/text-and-match-rules.md +119 -0
  54. package/package/corpus/skills/cratis-screenplay-command-surface/references/validate-rules.md +14 -4
  55. package/package/corpus/skills/cratis-screenplay-command-surface/verification.json +10 -3
  56. package/package/corpus/skills/cratis-screenplay-event-modeling/SKILL.md +12 -12
  57. package/package/corpus/skills/cratis-screenplay-event-modeling/references/parsed-not-runnable.md +5 -3
  58. package/package/corpus/skills/cratis-screenplay-event-modeling/verification.json +5 -1
  59. package/package/corpus/skills/cratis-screenplay-legacy-extraction/SKILL.md +2 -2
  60. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/evidence-table-template.md +1 -1
  61. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/generated-recovery.md +51 -14
  62. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/intent-example.md +5 -0
  63. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/loss-report-template.md +2 -1
  64. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/rule-modeling.md +6 -3
  65. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/signal-to-intent.md +1 -1
  66. package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +22 -28
  67. package/package/corpus/skills/cratis-screenplay-model-authoring/references/choosing-generation.md +20 -7
  68. package/package/corpus/skills/cratis-screenplay-model-authoring/references/language-reference.md +12 -6
  69. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-loop.md +9 -1
  70. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +58 -10
  71. package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +4 -2
  72. package/package/corpus/skills/cratis-screenplay-model-review/SKILL.md +2 -5
  73. package/package/corpus/skills/cratis-screenplay-model-review/references/anti-patterns.md +2 -2
  74. package/package/corpus/skills/cratis-screenplay-model-review/references/checklist.md +2 -2
  75. package/package/corpus/skills/cratis-screenplay-model-review/references/quick-self-check.md +2 -1
  76. package/package/corpus/skills/cratis-screenplay-model-review/references/review-questions.md +3 -2
  77. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/principles.md +1 -1
  78. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/vocabulary-map.md +1 -1
  79. package/package/corpus/skills/cratis-screenplay-read-surface/SKILL.md +2 -3
  80. package/package/corpus/skills/cratis-screenplay-read-surface/references/named-keys.md +3 -1
  81. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/SKILL.md +8 -3
  82. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/gap-fill-handoff.md +8 -0
  83. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/renderability-gate.md +6 -4
  84. package/package/corpus/skills/cratis-screenplay-scenario-coverage/SKILL.md +36 -29
  85. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/berth-reservations.md +6 -0
  86. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/invoicing-dues-design.md +15 -4
  87. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/invoicing-dues-example.md +25 -20
  88. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/public-event-coverage.md +14 -3
  89. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/scenario-examples.md +9 -3
  90. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/spec-forms-by-mode.md +7 -3
  91. package/package/corpus/skills/cratis-screenplay-slice-design/SKILL.md +3 -1
  92. package/package/corpus/skills/cratis-screenplay-slice-design/references/command-inventory.md +4 -4
  93. package/package/corpus/skills/cratis-screenplay-slice-design/references/rule-layers.md +4 -2
  94. package/package/corpus/skills/cratis-screenplay-slice-design/references/slicing.md +4 -3
  95. package/package/corpus/skills/cratis-screenplay-slice-design/references/worked-example.md +8 -8
  96. package/package/corpus/skills/cratis-screenplay-specifications/SKILL.md +49 -47
  97. package/package/corpus/skills/cratis-screenplay-specifications/references/actions-beyond-commands.md +11 -1
  98. package/package/corpus/skills/cratis-screenplay-specifications/references/generated-fixtures.md +48 -17
  99. package/package/corpus/skills/cratis-screenplay-specifications/references/vocabulary.md +14 -1
  100. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/SKILL.md +25 -21
  101. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/boundaries.md +2 -2
  102. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/consistency-and-concurrency.md +14 -6
  103. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/multi-service-models.md +4 -3
  104. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/streams-example.md +7 -0
  105. package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +30 -22
  106. package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet-example.md +3 -1
  107. package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet.md +47 -2
  108. package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostic-arguments.md +60 -0
  109. package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +65 -5
  110. package/package/corpus/skills/cratis-screenplay-toolchain/references/executable-subset.md +50 -22
  111. package/package/corpus/skills/cratis-screenplay-toolchain/references/generation-checks.md +93 -0
  112. package/package/corpus/skills/cratis-screenplay-toolchain/references/generation-strategies-example.md +117 -35
  113. package/package/corpus/skills/cratis-screenplay-toolchain/references/language-admission.md +46 -0
  114. package/package/corpus/skills/cratis-screenplay-toolchain/references/preferred-syntax.md +3 -1
  115. package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +25 -10
  116. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +1800 -50
  117. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
  118. package/package/corpus/skills/cratis-screenplay-toolchain/references/traps.md +5 -3
  119. package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +6 -1
  120. package/package/corpus/skills/cratis-screenplay-ui-composition/SKILL.md +8 -53
  121. package/package/corpus/skills/cratis-screenplay-ui-composition/references/file-references.md +2 -2
  122. package/package/corpus/skills/cratis-screenplay-ui-composition/references/interaction-example.md +54 -0
  123. package/package/corpus/skills/cratis-screenplay-ui-composition/verification.json +6 -3
  124. package/package/corpus/skills/cratis-specifications-csharp/SKILL.md +3 -2
  125. package/package/corpus/skills/cratis-specifications-csharp/references/application-scenarios.md +1 -1
  126. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +30 -29
  127. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +36 -9
  128. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/choosing-generation.md +28 -8
  129. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/publication-and-recovery.md +31 -0
  130. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/sandbox-and-specrunner.md +8 -0
  131. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/verification.json +4 -1
  132. 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), and secret ApiKey (`Bytes(32)`, `[NotAudited]` in its host).
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. UUIDs are not credentials. Byte generation can create a secret
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. Prefixes add no entropy.
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.24.0 or later and,
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
- Built-in context overloads reject default Now (`MissingGenerationTime`) and time
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 invoice allocation.
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`; `Documentation/csharp/generating-values.md`.
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:** inbound turns outside data or foreign
16
- public events into private local facts; outbound publishes private facts as one local public
17
- event type. Declare `direction inbound|outbound` when public metadata is used; omission
18
- preserves inbound for translations without a declared direction. Private-to-private follow-up is an
19
- Automation (`produces` or `invokes`), even when a Chronicle reactor realizes it.
20
- Read [public events and direction](references/public-events-and-direction.md) for released
21
- ESM v9 forms, event-target folds, publication specifications and the Unsupported capture limit.
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
- Work in the model first. Code appears only where it is truly needed: the external call, the
26
- source adapter, the trusted actor, and everything Stage cannot render (below). Session and
27
- verdict discipline: `cratis-screenplay-modeling-lifecycle`; tools, versions and verdicts V1 to V5:
28
- `cratis-screenplay-toolchain`. When you add or change a reaction or capture, resolve its input,
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
- - Reactions, clocks, triggers, captures and Automation/Translate slices compile (V1) and bind (V3)
33
- as ESM v6: the standalone tool and a CLI whose bundled compiler admits v6. A compiler that
34
- stops before v6 reports PLAY0268 at binding: report "V3 blocked: PLAY0268 (ESM v6)" and
35
- name the tool, never remove them.
36
- - The pinned standalone tool runs admitted scenarios through `screenplay test` or MCP
37
- `run-specifications`; source validation and render publication do not run V4.
38
- - A renderer can refuse Automation/Translate members (STAGE-ESM-024) it does not realize.
39
- Deliver that scope as authorized gap-fill
40
- (`references/realization-and-gap-fill.md`).
41
- - Reaction `runs as system role "<Role>"` declares an invocation actor (ESM v10).
42
- Without it the invoke has no caller. A compiler or renderer that stops before v10
43
- rejects the syntax (PLAY0137) or refuses it at render admission (CLI-RENDER-004). The CLI/Stage pair (toolchain
44
- `references/renderable-subset.md`) renders role/authenticated reaction identity; claim-reading/opaque gates retain STAGE-ESM-034. Checked model/diagnostics: captures-and-reactions
45
- `references/invocation-identity.md`.
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
- **Critical questions** (ask one group at a time; follow up from the answer; accept "unsure" as an
106
- open question, not an invented answer):
107
- 1. **Sources.** "Which systems send us facts? For each: name, record types, channel (webhook, poll,
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 worker after translation needs a distinct local decision, obligation or effect.
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. `reads` never protects.
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
- | happy path | record arrives, our fact recorded | `when capture` -> `then <External>` + `then <Ours>` |
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 spec that needs it.
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 (released ESM v9)
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
- event OrderDispatched
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
- orderId = $.orderId
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
- This compiles and binds as ESM v9. Evaluating the events-source capture returns
114
- typed Unsupported: the event-payload-to-working-record contract is not admitted.
115
- Do not equate binding with a passing capture specification or invent that mapping.
116
- Keep correlation and resulting private events in the model and report the runtime gap.
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 shipped and is selected only by use of public events,
121
- origins, direction, event-target builders or events-source captures. At 4.135.0,
122
- publication reference scenarios execute; imported shapes still refuse binding.
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 refuses a snapshot list); the sweep needs a code body the
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 Translate slice
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 translated by reactions into our facts. It
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`, Chronicle's first-observation rule); a later delivery of the same key appends nothing, even if the outcome or score changed, so it does not implement 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."
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
- specification RefusingASecondResult
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
- - A capture and the external fact it appends stay in the `Translate` slice; the translator reactions that answer that fact sit in an `Automation` slice beside it (a reaction in the capture's own directionless `Translate` slice is `PLAY0694`). `then` lists every new fact, so `TranslatingAPass` names both the external fact and ours.
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 an event imported from another context (unquoted
11
- `import Context.Event`) or over the external fact a capture appended.
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
- - Translator reactions record **our facts** in business terms (`ExamPassed`, `ExamFailed`),
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 record fields (as the source names them) -> `then` the
82
- external fact and, under v6, what translator reactions appended (`then` lists every new
83
- fact).
84
- - `given capture` for the previous record when a condition compares (`from … to …`,
85
- unchanged redelivery).
86
- - `when append <ExternalFact>` -> `then <OurFact>` to test a translator reaction alone.
87
- - Case list: `cases-to-specify.md`. These forms parse (probed in
88
- `translate-example.md`) but are not executed by any local engine.
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`.