@cratis/pi 7.62.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 (103) hide show
  1. package/package/corpus/product-sync.json +9 -9
  2. package/package/corpus/skills/cratis-application-slice-conformance/SKILL.md +1 -1
  3. package/package/corpus/skills/cratis-arc-command/references/generated-values.md +27 -12
  4. package/package/corpus/skills/cratis-arc-command/references/shop-generation.md +17 -6
  5. package/package/corpus/skills/cratis-fundamentals-concept/SKILL.md +10 -2
  6. package/package/corpus/skills/cratis-fundamentals-concept/references/shop-generation.md +49 -6
  7. package/package/corpus/skills/cratis-screenplay-automations-and-translations/SKILL.md +43 -41
  8. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/cases-to-specify.md +11 -2
  9. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/integration-interview.md +24 -0
  10. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/public-events-and-direction.md +76 -10
  11. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/realization-and-gap-fill.md +5 -0
  12. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/todo-list-example.md +1 -1
  13. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/translate-example.md +39 -23
  14. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/translation-patterns.md +35 -12
  15. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/SKILL.md +51 -81
  16. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/atomic-batches-and-source-mappings.md +83 -0
  17. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/capture-map-and-example.md +14 -4
  18. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/reaction-forms.md +59 -0
  19. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/record-capture-specifications.md +60 -0
  20. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/specifying-triggers-and-clock.md +5 -1
  21. package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +26 -28
  22. package/package/corpus/skills/cratis-screenplay-command-surface/references/described-handlers.md +82 -0
  23. package/package/corpus/skills/cratis-screenplay-command-surface/references/generated-values-and-responses.md +82 -28
  24. package/package/corpus/skills/cratis-screenplay-command-surface/references/protected-reads.md +113 -0
  25. package/package/corpus/skills/cratis-screenplay-command-surface/references/shop-generation.md +45 -12
  26. package/package/corpus/skills/cratis-screenplay-command-surface/references/text-and-match-rules.md +119 -0
  27. package/package/corpus/skills/cratis-screenplay-command-surface/references/validate-rules.md +14 -4
  28. package/package/corpus/skills/cratis-screenplay-command-surface/verification.json +10 -3
  29. package/package/corpus/skills/cratis-screenplay-event-modeling/SKILL.md +12 -12
  30. package/package/corpus/skills/cratis-screenplay-event-modeling/references/parsed-not-runnable.md +5 -3
  31. package/package/corpus/skills/cratis-screenplay-event-modeling/verification.json +5 -1
  32. package/package/corpus/skills/cratis-screenplay-legacy-extraction/SKILL.md +2 -2
  33. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/evidence-table-template.md +1 -1
  34. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/generated-recovery.md +51 -14
  35. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/intent-example.md +5 -0
  36. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/loss-report-template.md +2 -1
  37. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/rule-modeling.md +6 -3
  38. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/signal-to-intent.md +1 -1
  39. package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +22 -28
  40. package/package/corpus/skills/cratis-screenplay-model-authoring/references/choosing-generation.md +20 -7
  41. package/package/corpus/skills/cratis-screenplay-model-authoring/references/language-reference.md +12 -6
  42. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-loop.md +9 -1
  43. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +58 -10
  44. package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +4 -2
  45. package/package/corpus/skills/cratis-screenplay-model-review/SKILL.md +2 -5
  46. package/package/corpus/skills/cratis-screenplay-model-review/references/anti-patterns.md +2 -2
  47. package/package/corpus/skills/cratis-screenplay-model-review/references/checklist.md +2 -2
  48. package/package/corpus/skills/cratis-screenplay-model-review/references/quick-self-check.md +2 -1
  49. package/package/corpus/skills/cratis-screenplay-model-review/references/review-questions.md +3 -2
  50. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/principles.md +1 -1
  51. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/vocabulary-map.md +1 -1
  52. package/package/corpus/skills/cratis-screenplay-read-surface/SKILL.md +2 -3
  53. package/package/corpus/skills/cratis-screenplay-read-surface/references/named-keys.md +3 -1
  54. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/SKILL.md +8 -3
  55. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/gap-fill-handoff.md +8 -0
  56. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/renderability-gate.md +6 -4
  57. package/package/corpus/skills/cratis-screenplay-scenario-coverage/SKILL.md +36 -29
  58. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/berth-reservations.md +6 -0
  59. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/invoicing-dues-design.md +15 -4
  60. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/invoicing-dues-example.md +25 -20
  61. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/public-event-coverage.md +14 -3
  62. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/scenario-examples.md +9 -3
  63. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/spec-forms-by-mode.md +7 -3
  64. package/package/corpus/skills/cratis-screenplay-slice-design/SKILL.md +3 -1
  65. package/package/corpus/skills/cratis-screenplay-slice-design/references/command-inventory.md +4 -4
  66. package/package/corpus/skills/cratis-screenplay-slice-design/references/rule-layers.md +4 -2
  67. package/package/corpus/skills/cratis-screenplay-slice-design/references/slicing.md +4 -3
  68. package/package/corpus/skills/cratis-screenplay-slice-design/references/worked-example.md +8 -8
  69. package/package/corpus/skills/cratis-screenplay-specifications/SKILL.md +49 -47
  70. package/package/corpus/skills/cratis-screenplay-specifications/references/actions-beyond-commands.md +11 -1
  71. package/package/corpus/skills/cratis-screenplay-specifications/references/generated-fixtures.md +48 -17
  72. package/package/corpus/skills/cratis-screenplay-specifications/references/vocabulary.md +14 -1
  73. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/SKILL.md +25 -21
  74. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/boundaries.md +2 -2
  75. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/consistency-and-concurrency.md +9 -3
  76. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/multi-service-models.md +4 -3
  77. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/streams-example.md +7 -0
  78. package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +30 -22
  79. package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet-example.md +3 -1
  80. package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet.md +47 -2
  81. package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostic-arguments.md +60 -0
  82. package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +65 -5
  83. package/package/corpus/skills/cratis-screenplay-toolchain/references/executable-subset.md +50 -22
  84. package/package/corpus/skills/cratis-screenplay-toolchain/references/generation-checks.md +93 -0
  85. package/package/corpus/skills/cratis-screenplay-toolchain/references/generation-strategies-example.md +117 -35
  86. package/package/corpus/skills/cratis-screenplay-toolchain/references/language-admission.md +46 -0
  87. package/package/corpus/skills/cratis-screenplay-toolchain/references/preferred-syntax.md +3 -1
  88. package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +25 -10
  89. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +1800 -50
  90. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
  91. package/package/corpus/skills/cratis-screenplay-toolchain/references/traps.md +5 -3
  92. package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +6 -1
  93. package/package/corpus/skills/cratis-screenplay-ui-composition/SKILL.md +8 -53
  94. package/package/corpus/skills/cratis-screenplay-ui-composition/references/file-references.md +2 -2
  95. package/package/corpus/skills/cratis-screenplay-ui-composition/references/interaction-example.md +54 -0
  96. package/package/corpus/skills/cratis-screenplay-ui-composition/verification.json +6 -3
  97. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +30 -29
  98. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +36 -9
  99. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/choosing-generation.md +28 -8
  100. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/publication-and-recovery.md +31 -0
  101. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/sandbox-and-specrunner.md +8 -0
  102. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/verification.json +4 -1
  103. package/package.json +1 -1
@@ -0,0 +1,60 @@
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
+ # First sight and updates in record captures
5
+
6
+ Requires Screenplay 4.175.0 or later (`screenplay --version`); older reference evaluators treat fields of a first record as changed. Upgrade before relying on added-only outcomes.
7
+
8
+ For `source api`, webhook, poll and other record sources, a first record of a typed key is **added only**. `when <field>`, field-change `and`/`or` and transitions need an earlier record of that same key. For an update scenario, seed it with `given capture`. A baseline for another key does not count. To record both first sight and later changes, use separate appends with `when added` and `when <field>`; do not replace the update guard with `when added`.
9
+
10
+ This applies independently to each child identity in its parent's previous collection and each nested record: a missing/null previous nested value is new, and every child of a new parent is new. Expression guards still evaluate the mapped current record on first sight; maps and unguarded appends keep their meaning. These record fixtures are not valid for `source events`: use typed events instead (automations-and-translations [public event captures](../../cratis-screenplay-automations-and-translations/references/public-events-and-direction.md)).
11
+
12
+ The complete model separates a new observation, an update and an unchanged repeat:
13
+
14
+ ```screenplay
15
+ domain LegacyBilling
16
+ module Integration
17
+ feature Invoices
18
+ slice Translate ImportInvoiceStatus
19
+ event InvoiceStatusObserved
20
+ status String
21
+ capture InvoiceRecords
22
+ source api
23
+ api LegacyBilling
24
+ route /invoices
25
+ poll 5m
26
+ key id
27
+ append InvoiceStatusObserved
28
+ when added
29
+ status = $.status
30
+ append InvoiceStatusObserved
31
+ when status
32
+ status = $.status
33
+ specification RecordingFirstSight
34
+ when capture InvoiceRecords
35
+ id = "inv-42"
36
+ status = "sent"
37
+ then InvoiceStatusObserved
38
+ for "inv-42"
39
+ status = "sent"
40
+ specification RecordingAnUpdate
41
+ given capture InvoiceRecords
42
+ id = "inv-42"
43
+ status = "sent"
44
+ when capture InvoiceRecords
45
+ id = "inv-42"
46
+ status = "paid"
47
+ then InvoiceStatusObserved
48
+ for "inv-42"
49
+ status = "paid"
50
+ specification IgnoringAnUnchangedRecord
51
+ given capture InvoiceRecords
52
+ id = "inv-42"
53
+ status = "paid"
54
+ when capture InvoiceRecords
55
+ id = "inv-42"
56
+ status = "paid"
57
+ then no events
58
+ ```
59
+
60
+ Run `screenplay <model> --warnaserror` (zero errors/warnings), then `screenplay test <model>` (all three specifications passed). Each specification supplies its own immutable baseline; no last-seen record persists between runs. Reference execution never contacts the configured API and does not prove source acknowledgement or retry safety.
@@ -3,7 +3,11 @@
3
3
  **Specify what sets them off** (execution from ESM v6): `when clock "<instant>"`
4
4
  for a reaction on `every` or `at`, `when trigger <Trigger>` with its values for one
5
5
  on an application trigger, and `given capture` / `when capture <Capture>` with the
6
- source record's fields for a capture, then the events that should follow.
6
+ source record's fields for a record capture, then the events that should follow.
7
+ For `source events`, use `given <FromEvent>` / `when append <FromEvent>` instead
8
+ (PLAY0701). First sight is `added` only; update guards need the same key's prior
9
+ record or events. See [record capture cases](record-capture-specifications.md) and
10
+ [public event captures](../../cratis-screenplay-automations-and-translations/references/public-events-and-direction.md).
7
11
  `given clock` fixes the occurrence time, so values mapped from `$context.occurred`
8
12
  can be asserted. Excerpt of the complete example in [complete-examples.md](complete-examples.md):
9
13
 
@@ -50,9 +50,8 @@ concept InvoiceStatus : Enum
50
50
  paid
51
51
  ```
52
52
 
53
- The seven primitives are `Uuid`, `String`, `Int`, `Decimal`, `Bool`, `Date` and
54
- `DateTime`. `Enum` is **not** one of them — it is a separate concept kind, which
55
- is why the compiler says *expected … or Enum* rather than listing it among them.
53
+ Primitives: `Uuid`, `String`, `Int`, `Decimal`, `Bool`, `Date`, `DateTime`.
54
+ `Enum` is a separate concept kind; details: `references/enum-numbers.md`.
56
55
  Use bare `pii` (`personal` alias) and `secret` on concepts; **Compliance is inherited**.
57
56
  Keep protection even when a compiler or renderer refuses it. Read
58
57
  [compliance and purposes](references/compliance.md) for ESM v13, binder-only refusals,
@@ -106,12 +105,12 @@ fix to migrate. `--warnaserror` does not reject information diagnostics.
106
105
  properties, `reads`, `authorize`, `validate`, `produces`/`handler`, `concurrency`.
107
106
  Keep to it.
108
107
 
109
- ⚠️ **`produces` and `handler` are mutually exclusive** — declaring both is an
110
- error. Everything else may repeat except `description` (one) and `concurrency`
111
- (one). A `handler` parses but **never binds**, with or without an `implementation`
112
- or `hint`: the binder reports `PLAY0268` ("handler requires a constrained
113
- implementation attachment"), and a `handler` is not one of the opaque bodies below.
114
- Prefer `produces` when the model must run or render.
108
+ A file/code `handler` cannot coexist with `produces` and still fails binding
109
+ with PLAY0268. A pending `handler implementation` beside unconditional `produces`
110
+ is a described command (ESM v23): the body owns payload values only. Prefer plain
111
+ `produces` for declarative logic. Read [described handlers](references/described-handlers.md)
112
+ when logic needs prose, for the result contract, PLAY0695–0698, Unsupported
113
+ ImplementationBody and Stage's STAGE-IMPL-002 refusal (no stubs, even in Stub mode).
115
114
 
116
115
  ## `identifier` — the stream boundary decision
117
116
 
@@ -149,18 +148,11 @@ alias on **every** read (`PLAY0410`), aliases are unique (`PLAY0411`) and must n
149
148
  match a command property (`PLAY0412`). A `require` path uses the alias, or the
150
149
  view name when that view is read once.
151
150
 
152
- ⚠️ **`reads` is not a protected read.** It documents the read-model-to-command
153
- arrow of the event model; nothing checks at append time that the state is still
154
- current. The executable model rejects every `reads` and `concurrency` with
155
- `PLAY0271`, and `require` over a read-model path with `PLAY0268`, until
156
- decision-consistent reads exist. Adding a
157
- `concurrency` block does not fix this: its scope is not the read's watermark, and the
158
- combination is planned to become an error once protected reads ship.
159
- When a rule depends on state:
160
-
161
- - if it is uniqueness, declare a `unique` constraint (below);
162
- - otherwise state the rule, and say in review that the target implementation
163
- must enforce it consistently. Do not claim the model guarantees it.
151
+ Opt eligible state reads into application-root `command reads protected` (v25).
152
+ Absence rejects; matching intervening facts conflict. Read [protected reads](references/protected-reads.md)
153
+ for strict admission, paths and PLAY0780–0786. Legacy reads stay unprotected;
154
+ reads/concurrency cannot combine (PLAY0783). Stage refuses protected reads (STAGE-ESM-044), not v25 itself.
155
+ Uniqueness still uses a constraint; reference success is not target realization.
164
156
 
165
157
  Do not use `reads` to fetch data the caller could supply. A composite-key view's `by` block is
166
158
  `PLAY0268` (read-surface `references/named-keys.md`).
@@ -170,8 +162,11 @@ Do not use `reads` to fetch data the caller could supply. A composite-key view's
170
162
  Each rule takes an optional `severity information|warning|error` and then an
171
163
  optional `message "<text>"` (or `$strings.<key>`). The default severity is `error`.
172
164
 
173
- The rule vocabulary (`not empty`, `min`/`max`, comparisons, `length`, `matches`, `all`, `rule <Name>`) is in
165
+ The rule vocabulary (`not empty`, `min`/`max`, comparisons, `length`, literal text rules, `matches`, `all`, `rule <Name>`) is in
174
166
  [references/validate-rules.md](references/validate-rules.md): read it when choosing or writing a rule form.
167
+ Read [text and match rules](references/text-and-match-rules.md) for ordinal `contains`,
168
+ `not contains`, `starts with`, `ends with` (v24), the portable linear match dialect,
169
+ PLAY0699/0787, Studio repairs and public pattern checks. Text rules are not conditions.
175
170
 
176
171
  ⚠️ **Validation severity is not compiler severity.** Every failed rule and
177
172
  `require` rejects the command, at `information` and `warning` too; severity only
@@ -241,8 +236,11 @@ One `concurrency` block per command; it is not bound (`PLAY0271`) and does not p
241
236
 
242
237
  UUID generation/responses bind as v7; serialized concept `generate` selects v15:
243
238
  UUIDv7/ULID/TypeID/NanoID/bytes, strict fixtures and whole-source freshness.
244
- Reuse rejects Concurrency, no append/retry. Generated rules/secrets and pattern/random/rule
245
- remain refused.
239
+ Reuse rejects Concurrency, no append/retry. Rules select v20 (Requires Screenplay
240
+ 4.164.0, `screenplay --version`); pattern/checksum, Int random and attached rules
241
+ select v21 (Requires 4.172.0). Older compilers refuse PLAY0268. Secrets and sequences
242
+ remain refused. Patterns are readable references, not gapless allocators or secrets;
243
+ check digits catch typos, not forgery. Keep uniqueness/freshness enforcement.
246
244
  Read [references/generated-values-and-responses.md](references/generated-values-and-responses.md)
247
245
  for `generated`, `generate`, `returns`, strict fixtures/freshness and renderer limits.
248
246
 
@@ -285,15 +283,15 @@ Four contexts, and **what each omits is load-bearing** — when writing a code b
285
283
  - [ ] At most one command property carries `identifier`, and no event property does.
286
284
  - [ ] Format rules live on the `concept`; state-dependent rules are specifications.
287
285
  - [ ] Every `authorize` combining policies writes `and`/`or` explicitly.
288
- - [ ] No `reads` or `concurrency` is described as protecting a decision; the gap
289
- is stated.
286
+ - [ ] Protected reads opt in, meet admission and distinguish reference protection
287
+ from target realization; legacy reads and `concurrency` imply no protection.
290
288
  - [ ] Constraints are `unique` forms; no `file` constraint stands in for another rule.
291
289
  - [ ] Each policy has one `require` or one implementation, not both.
292
290
  - [ ] Personal data is `pii` on the concept; operational secrets are `secret`;
293
291
  no identifier or subject concept carries either. Reasons explain the value,
294
292
  while purposes declare basis/retention; run `--check purposes` separately.
295
- - [ ] No `handler` where the model must bind, and no bodied construct described as
296
- runnable or renderable without saying which tool admits it.
293
+ - [ ] Described handlers distinguish binding from Unsupported body execution and
294
+ Stage refusal; attached handlers remain unbound. Name the admitting tool.
297
295
  - [ ] No event carries an optional property covering two situations.
298
296
 
299
297
  Compiler versions and admission: `cratis-screenplay-toolchain/SKILL.md`.
@@ -0,0 +1,82 @@
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
+ # Described command handlers
5
+
6
+ Requires Screenplay 4.182.0 or later (`screenplay --version`); older compilers refuse pending handlers with PLAY0268.
7
+
8
+ Use a described command when payload computation needs words rather than an invented
9
+ expression. Prefer ordinary `produces` when the logic is declarative. Do not use a
10
+ described body to reject a command or decide how many events to emit.
11
+
12
+ Complete model:
13
+
14
+ ```screenplay
15
+ domain Billing
16
+ module Invoices
17
+ feature Fees
18
+ slice StateChange ApplyLateFee
19
+ command ApplyLateFee
20
+ invoiceId String identifier
21
+ daysOverdue Int
22
+ validate
23
+ daysOverdue >= 1 message "The invoice must be overdue"
24
+ handler
25
+ implementation
26
+ hint "Calculate the late fee from overdue days using the agreed daily rate"
27
+ produces LateFeeApplied
28
+ for invoiceId
29
+ event LateFeeApplied
30
+ amount Decimal
31
+ ```
32
+
33
+ A pending `implementation` has no `file` or fence. Bare `implementation` is valid;
34
+ optional `hint` lines are ordered, nonblank quoted strings, decoded without trimming.
35
+ One wrapper and at most one payload are permitted. Attaching a file or fence stops
36
+ being a described command: attached handlers still fail binding with PLAY0268 and
37
+ cannot coexist with `produces`.
38
+
39
+ ## Result contract v1
40
+
41
+ | Part | Owner |
42
+ | --- | --- |
43
+ | Events, count, order | Declarative; each unconditional `produces` means exactly one event |
44
+ | Destination, routes, allocation, tags and metadata | Declarative |
45
+ | Generated values and response | Declarative; generation precedes the body |
46
+ | Authorization and validation | Declarative; denial or refusal never reaches the body |
47
+ | Event payload values | Body; mappings are non-normative hints, required properties may be unmapped |
48
+
49
+ Mapping type checks still apply. Neither a renderer nor reference execution evaluates
50
+ these payload mappings. Conditional productions, repeated/occurrence productions,
51
+ body-decided cardinality and body rejection are outside this contract.
52
+
53
+ The command selects ESM v23 with `handler: { requirementId, resultVersion: 1 }`.
54
+ The requirements sidecar carries a Pending CommandHandler requirement with ordered
55
+ hints, context/result versions 1, and provisional/ambiguous flags. Consumers must
56
+ explicitly admit this version, never silently drop the body.
57
+
58
+ | Diagnostic | Meaning and action |
59
+ | --- | --- |
60
+ | PLAY0695 (information) | Described command admitted; command and RequirementId name the missing body |
61
+ | PLAY0696 (error) | No productions, including response-only; add unconditional productions |
62
+ | PLAY0697 (error) | Conditional productions; result v1 needs unconditional events |
63
+ | PLAY0698 (error) | Pending intent plus another handler; keep one handler |
64
+ | PLAY0492–0494 | Invalid wrapper, hint or payload composition; fix the source shape |
65
+
66
+ ## Execution and realization
67
+
68
+ Reference execution runs the gates, routing and generation in ordinary order, then
69
+ returns Unsupported (`ImplementationBody`) on reaching the body, naming command and
70
+ RequirementId. This also applies through an invoking reaction. No payload mapping runs
71
+ and no event is emitted. Denial and validation specifications still execute. Unsupported
72
+ specifications are counted separately; an all-Unsupported run is never green.
73
+
74
+ Stage admits v23 but refuses described handlers with STAGE-IMPL-002 in the renderer,
75
+ Host and specification executor, including Stub mode: it emits no stubs. Hand-write
76
+ the body against the declared contract as authorized gap-fill; do not claim that a
77
+ pending requirement is implementation evidence. Moving the body into `handler file`
78
+ keeps its RequirementId but does not admit that attached handler alongside `produces`.
79
+
80
+ Validate the model root with `screenplay <root> --warnaserror`; expect no errors or
81
+ warnings and PLAY0695 information. Run `screenplay test <root>` separately: body-reaching
82
+ specifications must be reported Unsupported, not passed. Target tests are separate.
@@ -1,4 +1,4 @@
1
- # Generated values and responses (ESM v7 and v15)
1
+ # Generated values, rule proofs and responses
2
2
 
3
3
  ## Contents
4
4
 
@@ -28,16 +28,17 @@ Only the released generation phase is taught here.
28
28
  ## Choosing a strategy
29
29
 
30
30
  Use the [threaded shop model](shop-generation.md): CustomerId is `cus_` + ULID,
31
- OrderId is TypeID, InviteCode is NanoID. It links the same .NET concepts but does
32
- not claim their received-time/tenant context or secret ApiKey Bytes(32) factory
33
- is executable in Screenplay. The table below owns exact strategy shapes.
31
+ OrderId is TypeID, InviteCode is NanoID, InvoiceNumber is a readable pattern with
32
+ Luhn check digit, and TicketNumber is a random Int value. Keep short references
33
+ separate from event-source identities. The table below owns exact strategy shapes.
34
34
 
35
35
  ## When not to
36
36
 
37
37
  Client-minted values remain inputs. Generation is not authorization, idempotency,
38
- gapless invoice allocation or a credential contract. Preserve ApiKey's `secret`
39
- classification without generated properties; context/secret execution remains
40
- Screenplay#616 phases 3/4, not a reason to strip protection.
38
+ gapless/sequential invoice allocation or a credential contract. A pattern is not
39
+ an allocator; check digits catch typing mistakes, not forgery. Preserve ApiKey's
40
+ `secret` classification without generated properties: generated secrets remain
41
+ refused, not a reason to strip protection.
41
42
 
42
43
  ## The concept declares how; the property declares that
43
44
 
@@ -46,7 +47,7 @@ strategies on concepts and `generated`/`generated identifier` on properties.
46
47
  It includes whole-value fixture pins and returned IDs.
47
48
 
48
49
  A generated property must be a required scalar **concept**, not a bare primitive,
49
- optional value or collection. Only Uuid and String generation are executable.
50
+ optional value or collection. Uuid/String generation and Int `random` are executable.
50
51
  A Uuid concept implicitly generates `uuid`; String needs an explicit strategy.
51
52
  Each concept owns at most one `generate` line; there is no per-property override.
52
53
  Generated identifiers need Uuid or String backing and at least 64 random bits.
@@ -59,6 +60,9 @@ Generated identifiers need Uuid or String backing and at least 64 random bits.
59
60
  | `typeid "user"` | String | TypeID 0.3, lowercase Crockford UUIDv7 suffix; 74 random bits; prefix 1–63 lowercase letters/underscores, no leading/trailing underscore; empty prefix omits separator |
60
61
  | `nanoid [size]` | String | Default 21 symbols from `A-Za-z0-9_-`; size 1–256; entropy is size × log2(alphabet size) |
61
62
  | `bytes <count> base64url` / `hex` / `base32` | String | Count 1–512; 8 × count random bits; RFC 4648 without padding; hex lowercase, base32 uppercase; unused trailing bits zero |
63
+ | `pattern "INV-{yyyy}{MM}-#{7}" checksum luhn` | String | Finite readable reference; UTC dates and check digits add no entropy |
64
+ | `random 100000..999999` | Int | Inclusive signed Int64 interval; numeric value, not an identifier |
65
+ | `rule Name` | String | Exactly one file or tagged fence; opaque ValueGeneration implementation with language-neutral Now/Tenant context, String result and unknown entropy |
62
66
 
63
67
  Modifiers occur once each, in any authored order. `prefix "text"` is printable
64
68
  ASCII, at most 32 characters, on uuid/uuidv7/ulid/nanoid/bytes; UUID prefixes need
@@ -71,17 +75,31 @@ identifier; non-identifiers warn PLAY0683 unless a single-property unique
71
75
  constraint covers the mapped event property. That suppression is not a runtime collision guarantee; use the constraint when
72
76
  collisions must reject the command.
73
77
 
74
- `pattern`, `random`, `rule` and checksum syntax parse/print but refuse PLAY0268;
75
- `generate sequence` is reserved (PLAY0682). Generated-concept validation rules select ESM v20; compliance markers, including
76
- generated secrets, remain refused. Do not
77
- remove classification or pretend a random String is a credential contract.
78
+ Requires Screenplay 4.172.0 or later (`screenplay --version`) for pattern/random/rule
79
+ and String-concept `validate checksum luhn|mod11|mod97` (ESM v21); older compilers
80
+ refuse them with PLAY0268. Pattern `#` draws a digit, `?` an uppercase letter,
81
+ `*` an uppercase letter or digit; positive ASCII classes and `{n}`/`{m,n}` repeats
82
+ up to 64 are supported. `{yyyy}`, `{yy}`, `{MM}`, `{dd}` use one UTC date.
83
+ The expanded value, including check digits, is at most 256 characters. Only pattern
84
+ accepts `checksum`; write literals/classes rather than prefix/case/alphabet modifiers.
85
+ Read Cratis/Screenplay `Documentation/screenplay/generated-values/patterns.md`
86
+ for escaping and support limits. PLAY0691 means support counting exhausted its
87
+ budget; PLAY0692 means some date in the 100-year assessment horizon has empty
88
+ support. Neither is a proof warning or permission to redraw.
89
+
90
+ Checksum generation appends one Luhn/Mod11 digit or two Mod97 digits over preceding
91
+ ASCII digits, including date/literal digits. Author `validate checksum` separately
92
+ for arithmetic validation of supplied/stored values and fixtures; generation alone
93
+ checks only suffix shape on fixtures. `generate sequence` stays reserved (PLAY0682),
94
+ and compliance markers on generated concepts, including secrets, remain refused.
95
+ Never remove classification to make a model bind.
78
96
 
79
97
  ## Inspect and edit generation through MCP
80
98
 
81
99
  A concept `generation` summary and entropy repairs are available.
82
100
  Use `screenplay_declaration_details` with `kind: "Concept"`, `view: "summary"`:
83
101
  only authored `generate` gets a block, with strategy, set modifiers,
84
- preview-only arguments, `entropyBits`, `entropyUnknownReason` when null,
102
+ `arguments`, `supportCount`, `entropyBits`, `entropyUnknownReason` when null,
85
103
  `valuesAtOnePercentCollision` and `executable.status`. Status is `admitted` only
86
104
  after whole-model binding, `refused` for errors at this concept/generation, or
87
105
  `notAssessed` with a reason for unrelated binding failures. Empty local codes do
@@ -91,7 +109,7 @@ Set/change/remove `generate` through `screenplay_propose_ast` (replace the conce
91
109
  `GenerationSyntax`, omit/null `generation` to remove) or reviewed
92
110
  `screenplay_propose_source`; do not hand-edit the text. Inspect executable
93
111
  diagnostics independently of authoring acceptance: sequence PLAY0682;
94
- pattern/random/rule PLAY0268; generated-rule proofs PLAY0688/0689. Review, run candidate
112
+ support failures PLAY0691/0692; generated-rule proofs PLAY0688/0689. Review, run candidate
95
113
  specifications where executable, then apply with revisions.
96
114
 
97
115
  `screenplay_repair_capabilities` advertises PLAY0683/0684; workspace repairs supply
@@ -104,12 +122,19 @@ individual review and `CanonicalizeTouchedDocuments`, with no pinned evidence.
104
122
  Length changes affect all concept uses; uniqueness changes append-time behavior.
105
123
  PLAY0688 repair replaces a refuted rule with the strategy-derived `matches`
106
124
  pattern. Review input/stored-value uses because this changes their validation,
107
- not just generation. Checksum repairs remain unadmitted.
125
+ not just generation. A deterministic bounded pattern repair also adds the declared
126
+ checksum validation if absent; review both rule changes. Ambiguous derived regexes
127
+ have no repair. Date/checksum digit shapes alone do not prove containment.
108
128
  A CLI-bundled MCP can lack this summary and these repairs; it still
109
129
  supports existing typed concept proposals.
110
130
 
111
- Requires Screenplay 4.149.0 or later (`screenplay --version`) for the concept `generation` summary and entropy repairs. Full fields, mapping limits and tagged
112
- source evidence: [MCP generation guide](../../cratis-screenplay-model-authoring/references/mcp-tools.md#concept-generation).
131
+ Requires Screenplay 4.173.0 or later (`screenplay --version`) for `arguments`,
132
+ exact support counts, `derivedPattern` and authored-order `rules[]`; older servers
133
+ can expose `previewArguments` instead. Read `rules[].status`, `witness` and `reason`
134
+ instead of parsing diagnostic text. Use `derivedPattern` as `matches` through a
135
+ typed proposal; use the discovered PLAY0688 repair to replace a refuted rule.
136
+ A refuted rule without `diagnosticCode` was not checked by the compiler (for example,
137
+ an unused UUID concept), so do not invent a repair. Full fields and mapping limits: [MCP generation guide](../../cratis-screenplay-model-authoring/references/mcp-tools.md#concept-generation).
113
138
  Sources: Cratis/Screenplay `Documentation/screenplay/generated-values.md`,
114
139
  `Source/DotNET/Screenplay.Mcp/McpGenerationDetails.cs`,
115
140
  `Source/DotNET/Screenplay/Workspaces/WorkspaceGenerationRepairs.cs`.
@@ -135,20 +160,27 @@ that cannot backtrack on generated values. Passing samples alone prove nothing.
135
160
  Providers validate generated values too: a failing fixture is a Contract violation,
136
161
  not client rejection or a reason to redraw. Opaque rules need a target.
137
162
 
138
- Rules select v20 even on implicit UUID generation. No proof status is serialized;
163
+ Generated-concept validation rules select ESM v20 even on implicit UUID generation.
164
+ No proof status is serialized;
139
165
  strategy changes do not silently change rules on stored/input values.
140
166
 
167
+ Tool and renderer authors: read the toolchain's
168
+ [generation checks](../../cratis-screenplay-toolchain/references/generation-checks.md)
169
+ for declaration checks, value checks, strategy discovery and rule proofs.
170
+ Proof status is not serialized; the reference evaluator always requires pins.
171
+
141
172
  ## Version and freshness
142
173
 
143
174
  A serialized concept `generation` member selects **v15**. Implicit Uuid generation
144
175
  and explicit unmodified Uuid `generate uuid` omit it and preserve earlier executable
145
- bytes/revision. A v15 model guards **all** generated destinations, including its
146
- implicit UUIDs. An append whose destination equals any value generated in that
176
+ bytes/revision. Any model with a serialized strategy guards **all** generated destinations,
177
+ including its implicit UUIDs; ESM version alone does not enable the guard. An append whose destination equals any value generated in that
147
178
  invocation requires the **whole source** to have no existing facts, regardless
148
179
  of stream or event type. Multiple initial facts in one invocation are allowed;
149
180
  a skipped production makes no freshness claim. Reuse rejects the whole command
150
181
  with `Concurrency`, appends nothing and does not silently regenerate or retry.
151
- Older models are Unguarded and retain legacy fixture reuse.
182
+ Models without a serialized strategy are Unguarded and retain legacy fixture
183
+ reuse, even if rules select v20.
152
184
 
153
185
  Freshness is neither authorization nor idempotency. Client-minted identifiers
154
186
  remain inputs; protect their invariants with constraints. Never use generation
@@ -158,7 +190,12 @@ Specifications pin values, not seeds: `for` pins a generated identifier;
158
190
  `generated <name> = <value>` pins another generated property. The reference
159
191
  evaluator draws no randomness. From v15 every pin must match exact strategy
160
192
  encoding, size, case, UUID version/variant and zero trailing bits. Invalid pins
161
- are Contract rejections, not client validation failures. Older models retain
193
+ are Contract rejections, not client validation failures. Rule-bearing concepts
194
+ also check rules, including implicit UUID. Pin date segments with `given clock`;
195
+ all segments must match the same UTC instant. Without a clock only digit widths
196
+ are checked, never the wall clock. Opaque generation rules consume String pins
197
+ without executing attached code; opaque validation still yields Unsupported.
198
+ Older rule-free implicit-UUID models retain
162
199
  canonical UUID checks without a version check. Complete executable examples:
163
200
  [generated responses](../../cratis-screenplay-toolchain/references/generated-responses-example.md)
164
201
  and [generation strategies](../../cratis-screenplay-toolchain/references/generation-strategies-example.md).
@@ -188,7 +225,7 @@ and [generation strategies](../../cratis-screenplay-toolchain/references/generat
188
225
  ## What the CLI and Stage realize
189
226
 
190
227
  Stage emits strategy-specific `IGeneratable<T>.New()` factories over Fundamentals
191
- 7.24.0 or later (via the Arc scaffold pin in Stage's `references/rendered-application.md`). v15 generated destinations use explicit
228
+ 7.25.0 or later for pattern/random/checksum (via the Arc scaffold pin in Stage's `references/rendered-application.md`). v15 generated destinations use explicit
192
229
  `EventsWithConcurrencyScopes` with `BeforeFirst` whole-source scopes; Chronicle
193
230
  checks atomically at append: a batch's scopes are checked once against the state before
194
231
  the batch, all or nothing, and a storage retry that renumbers the append checks them again. Generated rejection specs assert
@@ -201,10 +238,12 @@ Requires Stage 4.94.0 or later for receipt-time generation; older factories use
201
238
 
202
239
  | Refusal | Still unsupported |
203
240
  | --- | --- |
204
- | STAGE-ESM-028 | Unknown strategies, non-concepts, optional/collection generation; every explicit strategy on the legacy syntax engine |
205
- | STAGE-ESM-011 | A v15 fixture that does not match its strategy shape |
206
- | STAGE-ESM-038 | Routing combined with generation/responses; generated-property rules/requirements or concept rules; occurrence parameter/response/factory name collisions; unsupported response sources/composites/collections; generated identifier plus destination-less plain production |
207
- | STAGE-ESM-038 | Unpinned generation with unordered event, read-model or query expectations |
241
+ | STAGE-ESM-028 | `generate rule`, unknown strategies, non-concepts, optional/collection generation; every explicit strategy on the legacy syntax engine |
242
+ | STAGE-ESM-011 | A fixture that does not match its strategy shape or concept rules |
243
+ | STAGE-ESM-038 | Routing combined with generation/responses; generated-property rules/requirements; occurrence parameter/response/factory name collisions; unsupported response sources/composites/collections; generated identifier plus destination-less plain production |
244
+ | STAGE-ESM-038 | Unpinned generation with any Unproven/Refuted concept rule, production-condition reads, unordered event/read-model/query expectations or collision-sensitive generated constraints |
245
+ | STAGE-ESM-042 | Unsupported concept-rule kinds; checksum remains refused only on the legacy syntax path |
246
+ | STAGE-ESM-005 | Opaque/unsupported generated-concept rules, before pin evaluation |
208
247
  | STAGE-ESM-004 / -006 | StateChange slices without commands / expression or enum production conditions |
209
248
 
210
249
  Sequence generation is refused at binding (PLAY0682) and never reaches Stage;
@@ -213,7 +252,22 @@ command `given clock` fixtures render when whole milliseconds at or after 1970;
213
252
 
214
253
  Requires Stage 4.95.0 for command clock fixtures, 4.98.0 for multiple commands and
215
254
  conditional productions, and 4.100.0 for generated text unique constraints; older
216
- renderers refuse those shapes. ESM v20 still needs a renderer that admits v20.
255
+ renderers refuse those shapes.
256
+
257
+ Requires Stage 4.109.0 for ESM v20 factories plus `ConceptValidator`; older renderers refuse v20.
258
+ Requires Stage 4.115.0 for ESM v21 admission and all-Proven unpinned generation;
259
+ older renderers require pins even for Proven rules. Unproven/Refuted rules still
260
+ require pins (-038), and invalid pins fail -011.
261
+ Requires Stage 4.117.0 for warning/info-severity generated-concept rules; older
262
+ renderers refuse them with -038. Every severity is enforced as a generation defect.
263
+ Requires Stage 4.118.0 for semantic checksum validation and 4.119.0 for
264
+ pattern/random factories, Host sampling and executor fixture checks; older
265
+ renderers refuse those constructs with -042/-028. Dated patterns use receipt-time
266
+ context; Int ranges render as `long`. `generate rule` still refuses -028.
267
+ Requires Arc.Screenplay 22.107.0 for pattern/random/checksum and self-contained
268
+ String-rule recovery; older adapters leave these factories in code. Recovery is
269
+ not Stage rendering: keep refused rule contracts for gap-fill, never delete rules
270
+ or secret classification.
217
271
 
218
272
  Missing pins in generated Debug specs use `AllowGeneration()` with relational
219
273
  assertions against captured values; v15 captures also check strategy shape.
@@ -0,0 +1,113 @@
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
+ # Protected command reads
5
+
6
+ ## Contents
7
+
8
+ - Admission and paths
9
+ - Absence and races
10
+ - Repair and target boundary
11
+
12
+ Requires Screenplay 4.193.0 or later (`screenplay --version`); older compilers refuse command reads with PLAY0271 and read paths with PLAY0268.
13
+
14
+ Declare `command reads protected` once in the application-root document. Imported
15
+ commands inherit it. This selects ESM v25, including when text rules are used, and
16
+ records `commandReadMode: "protected"`. Without it, legacy reads retain PLAY0271,
17
+ read paths retain PLAY0268, and bytes/version stay unchanged. A higher ESM version
18
+ alone never opts an application in.
19
+
20
+ Complete model:
21
+
22
+ ```screenplay
23
+ domain Inventory
24
+ command reads protected
25
+ module Stock
26
+ feature Allocation
27
+ slice StateView CurrentStock
28
+ event StockCounted
29
+ quantity Int
30
+ event StockRemoved
31
+ readmodel Current
32
+ id String key
33
+ quantity Int
34
+ projection CurrentProjection => Current
35
+ from StockCounted
36
+ remove with StockRemoved
37
+ slice StateChange Allocate
38
+ command Allocate
39
+ id String identifier
40
+ stockId String
41
+ reads Current by stockId
42
+ validate
43
+ require Current.quantity > 0
44
+ message "Stock must be available"
45
+ produces Allocated
46
+ for id
47
+ quantity = Current.quantity
48
+ event Allocated
49
+ quantity Int
50
+ ```
51
+
52
+ ## Admission and paths
53
+
54
+ `reads <View> [as <alias>] [by <input>]` looks up required state. Omitted `by` uses
55
+ the declared command identifier; no identifier is PLAY0782. Repeated reads of a
56
+ view each need a distinct alias; paths use the alias rather than the view name.
57
+ Aliases start with a lowercase letter or underscore.
58
+
59
+ Every read must satisfy both boundaries:
60
+
61
+ - A finite non-empty set of event-log event types builds the view, including removal
62
+ handling; the key is event-source identity only.
63
+ - The lookup key is a required scalar non-generated command input: String, a String
64
+ concept or canonical GUID.
65
+
66
+ PLAY0781 refuses reducers, joins (including removal joins), children/nested scopes,
67
+ `every`/`all`, payload/composite keys, missing removals, empty handled-event sets,
68
+ named sources/streams, singleton views and unsupported/generated/optional/collection
69
+ keys. Its closed reasons are Reducer, Join, Children, OpenSubscription, PayloadKey,
70
+ ByParts, NoRemoval, EmptyHandledSet, NamedSourceOrStream, Singleton, KeyType,
71
+ GeneratedKey, OptionalKey and CollectionKey. `optional`, `advisory` and `via query`
72
+ remain refused; `via query` uses parser code PLAY0175. There is no unguarded fallback.
73
+
74
+ Single-level `read.property` paths bind in `require` operands and produced-event
75
+ mapping sources only. Deeper paths and read paths in `produces when`, response
76
+ fields, `for`, routes and derive/provide remain PLAY0268. Unknown read/property
77
+ paths report PLAY0784; ambiguous view paths report PLAY0785. A command with both
78
+ `reads` and `concurrency` reports PLAY0783: do not guess which boundary wins.
79
+
80
+ ## Absence and races
81
+
82
+ Execution orders authorization → property rules → required reads → derive/provide
83
+ → requirements → productions/responses. Missing state rejects with Validation and
84
+ message `<ReadModel> '<key>' does not exist.` before evaluating requirements or
85
+ mappings. Property-rule rejection therefore wins over absence.
86
+
87
+ Decide records the unfiltered fact-log boundary, read key and handled event types.
88
+ A matching fact after that boundary makes commit return Conflict /
89
+ DecisionStateChanged with no command facts, including publications. Irrelevant
90
+ facts do not conflict and remain in the committed world. Even a no-fact command is
91
+ checked. Race cases are evaluator vectors, not a new `.play` specification construct.
92
+
93
+ Specify present/absent state, rule refusal and denial. Assert no new facts and
94
+ unchanged views on failure; use target concurrency tests to prove actual storage
95
+ protection. Ordinary injected read models are not protected decisions; uniqueness
96
+ still belongs in a `unique` append constraint.
97
+
98
+ ## Repair and target boundary
99
+
100
+ PLAY0780 rejects duplicate, conflicting or non-root preambles. Informational
101
+ PLAY0786 identifies an eligible legacy model at its first command read. Discover
102
+ `read-workspace view=repairs`, then `propose-repair` with current workspace/catalog
103
+ revisions and canonical formatting consent; review with `read-proposal` before
104
+ explicit `apply`. The repair inserts into the domain document or sole document,
105
+ refuses ambiguous roots and requires individual review, never fix-all. It changes
106
+ absence/conflict behavior, not merely formatting.
107
+
108
+ Stage admits ESM v25 but refuses protected reads with STAGE-ESM-044 in rendering,
109
+ Host serving and specification execution; a reference pass is not Stage or Arc
110
+ realization. Preserve the model's protection and deliver authorized hand-written
111
+ consistency enforcement through the render-and-gap-fill workflow. Never remove
112
+ the preamble to get a render. `screenplay <root> --warnaserror` must exit zero;
113
+ `screenplay test <root>` separately establishes reference behavior, not target support.