@cratis/pi 7.23.0 → 7.25.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 (116) hide show
  1. package/package/corpus/skills/cratis-application-slice-conformance/SKILL.md +1 -1
  2. package/package/corpus/skills/cratis-application-slice-conformance/references/contract-and-precedence.md +5 -5
  3. package/package/corpus/skills/cratis-application-slice-conformance/verification.json +3 -0
  4. package/package/corpus/skills/cratis-arc-react-page/verification.json +14 -0
  5. package/package/corpus/skills/cratis-screenplay-automations-and-translations/assets/pending-certificates.play +10 -0
  6. package/package/corpus/skills/cratis-screenplay-automations-and-translations/assets/retry-sweep.play +11 -0
  7. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/automation-patterns.md +3 -3
  8. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/cases-to-specify.md +1 -1
  9. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/effects-and-idempotency.md +1 -1
  10. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/integration-contracts.md +1 -1
  11. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/realization-and-gap-fill.md +5 -3
  12. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/todo-list-example.md +3 -3
  13. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/translation-patterns.md +1 -1
  14. package/package/corpus/skills/cratis-screenplay-automations-and-translations/verification.json +1 -0
  15. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/complete-examples.md +1 -1
  16. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/refusals-and-redelivery.md +1 -1
  17. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/verification.json +1 -0
  18. package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +5 -5
  19. package/package/corpus/skills/cratis-screenplay-command-surface/references/context.md +2 -2
  20. package/package/corpus/skills/cratis-screenplay-command-surface/references/operations.md +1 -1
  21. package/package/corpus/skills/cratis-screenplay-command-surface/references/policy-persona-seed.md +1 -1
  22. package/package/corpus/skills/cratis-screenplay-command-surface/references/validate-rules.md +1 -1
  23. package/package/corpus/skills/cratis-screenplay-command-surface/verification.json +1 -0
  24. package/package/corpus/skills/cratis-screenplay-discovery/SKILL.md +6 -5
  25. package/package/corpus/skills/cratis-screenplay-discovery/references/event-naming.md +1 -1
  26. package/package/corpus/skills/cratis-screenplay-discovery/references/facilitation.md +5 -4
  27. package/package/corpus/skills/cratis-screenplay-discovery/references/human-workshop.md +1 -1
  28. package/package/corpus/skills/cratis-screenplay-discovery/references/interview-questions.md +1 -1
  29. package/package/corpus/skills/cratis-screenplay-discovery/references/personas-and-causes.md +7 -4
  30. package/package/corpus/skills/cratis-screenplay-discovery/references/plotting-and-handoff.md +8 -7
  31. package/package/corpus/skills/cratis-screenplay-discovery/references/storming-loop.md +2 -2
  32. package/package/corpus/skills/cratis-screenplay-discovery/verification.json +1 -0
  33. package/package/corpus/skills/cratis-screenplay-event-modeling/SKILL.md +10 -0
  34. package/package/corpus/skills/cratis-screenplay-event-modeling/references/nine-steps.md +3 -4
  35. package/package/corpus/skills/cratis-screenplay-event-modeling/verification.json +1 -0
  36. package/package/corpus/skills/cratis-screenplay-legacy-extraction/SKILL.md +1 -1
  37. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/intent-example.md +1 -1
  38. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/loss-report-template.md +1 -1
  39. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/rule-modeling.md +4 -4
  40. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/signal-to-intent.md +1 -1
  41. package/package/corpus/skills/cratis-screenplay-legacy-extraction/verification.json +1 -0
  42. package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +5 -4
  43. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-loop.md +14 -6
  44. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +71 -8
  45. package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +1 -0
  46. package/package/corpus/skills/cratis-screenplay-model-review/SKILL.md +15 -6
  47. package/package/corpus/skills/cratis-screenplay-model-review/references/anti-patterns.md +1 -1
  48. package/package/corpus/skills/cratis-screenplay-model-review/references/checklist.md +10 -9
  49. package/package/corpus/skills/cratis-screenplay-model-review/references/report-template.md +5 -1
  50. package/package/corpus/skills/cratis-screenplay-model-review/verification.json +2 -1
  51. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/SKILL.md +2 -2
  52. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/opt-in.md +7 -5
  53. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/phases.md +4 -4
  54. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/provenance.md +1 -1
  55. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/reasoning-notes.md +24 -19
  56. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/stop-or-assume.md +1 -1
  57. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/verdicts-and-modes.md +4 -2
  58. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/vocabulary-map.md +1 -1
  59. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/worked-example.md +15 -9
  60. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/verification.json +1 -0
  61. package/package/corpus/skills/cratis-screenplay-projections/SKILL.md +6 -6
  62. package/package/corpus/skills/cratis-screenplay-projections/references/pdl-grammar.md +7 -7
  63. package/package/corpus/skills/cratis-screenplay-projections/verification.json +1 -0
  64. package/package/corpus/skills/cratis-screenplay-read-surface/SKILL.md +10 -7
  65. package/package/corpus/skills/cratis-screenplay-read-surface/references/guarded-actions.md +4 -0
  66. package/package/corpus/skills/cratis-screenplay-read-surface/verification.json +1 -0
  67. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/SKILL.md +4 -3
  68. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/drift-and-ledger.md +1 -1
  69. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/gap-fill-handoff.md +3 -3
  70. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/verification.json +1 -0
  71. package/package/corpus/skills/cratis-screenplay-scenario-coverage/SKILL.md +25 -9
  72. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/berth-reservations.md +1 -1
  73. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/coverage-matrix.md +1 -1
  74. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/invoicing-dues-design.md +6 -1
  75. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/scenario-catalogue.md +7 -4
  76. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/scenario-examples.md +7 -7
  77. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/scenario-workshop.md +1 -1
  78. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/view-and-story-specs.md +1 -1
  79. package/package/corpus/skills/cratis-screenplay-scenario-coverage/verification.json +2 -1
  80. package/package/corpus/skills/cratis-screenplay-slice-design/SKILL.md +12 -7
  81. package/package/corpus/skills/cratis-screenplay-slice-design/references/command-inventory.md +4 -3
  82. package/package/corpus/skills/cratis-screenplay-slice-design/references/field-lineage.md +2 -2
  83. package/package/corpus/skills/cratis-screenplay-slice-design/references/model-reasoning.md +87 -0
  84. package/package/corpus/skills/cratis-screenplay-slice-design/references/provenance.md +1 -1
  85. package/package/corpus/skills/cratis-screenplay-slice-design/references/read-model-design.md +2 -2
  86. package/package/corpus/skills/cratis-screenplay-slice-design/references/rule-layers.md +8 -8
  87. package/package/corpus/skills/cratis-screenplay-slice-design/references/slicing.md +4 -4
  88. package/package/corpus/skills/cratis-screenplay-slice-design/references/worked-example.md +10 -4
  89. package/package/corpus/skills/cratis-screenplay-slice-design/verification.json +1 -0
  90. package/package/corpus/skills/cratis-screenplay-specifications/SKILL.md +22 -5
  91. package/package/corpus/skills/cratis-screenplay-specifications/references/examples-and-routes.md +59 -1
  92. package/package/corpus/skills/cratis-screenplay-specifications/references/persona-callers-and-cases.md +117 -0
  93. package/package/corpus/skills/cratis-screenplay-specifications/references/reactions-and-cascades.md +1 -1
  94. package/package/corpus/skills/cratis-screenplay-specifications/verification.json +2 -1
  95. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/SKILL.md +14 -13
  96. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/boundaries.md +3 -3
  97. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/chronicle-boundaries.md +3 -2
  98. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/consistency-and-concurrency.md +14 -11
  99. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/evolution.md +2 -2
  100. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/streams-example.md +1 -1
  101. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/verification.json +1 -0
  102. package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet-example.md +1 -1
  103. package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +49 -0
  104. package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +6 -3
  105. package/package/corpus/skills/cratis-screenplay-toolchain/references/traps.md +4 -4
  106. package/package/corpus/skills/cratis-screenplay-toolchain/references/versions.md +10 -0
  107. package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +1 -0
  108. package/package/corpus/skills/cratis-screenplay-ui-composition/SKILL.md +11 -9
  109. package/package/corpus/skills/cratis-screenplay-ui-composition/references/guarded-interactions.md +71 -0
  110. package/package/corpus/skills/cratis-screenplay-ui-composition/references/screen-composition-contract.md +6 -6
  111. package/package/corpus/skills/cratis-screenplay-ui-composition/verification.json +1 -0
  112. package/package/corpus/skills/cratis-specification-by-example/verification.json +14 -0
  113. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +5 -2
  114. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/rendered-application.md +17 -6
  115. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/verification.json +2 -1
  116. package/package.json +1 -1
@@ -29,11 +29,11 @@ Screenplay specifications.
29
29
  | Then (success) | every production with payload and `for` | "an event is produced" |
30
30
  | Then (refusal) | `then error "Invoice already settled"`, the rule's own message | `then error` with no message, or `then error ""` |
31
31
  | Then (denial) | `then denied` | `then error` for a caller who is not allowed |
32
- | Reason | the slice `description` says why the rule exists | the rule appears only in a spec title |
32
+ | Reason | slice `documentation` says why the rule exists | the rule appears only in a spec title |
33
33
 
34
34
  ## 1. Command: success, rule rejection and denial
35
35
  One spec for the success, one per rule (varying only the value the rule checks), one denial.
36
- ```screenplay excerpt
36
+ ```screenplay excerpt parent=references/invoicing-dues-example.md#1
37
37
  specification IssuingAnInvoice
38
38
  given caller
39
39
  authenticated
@@ -71,7 +71,7 @@ specification RefusingACallerWithoutTheAccountsRole
71
71
  After which earlier facts must the command be refused? Establish the wrong state with its real
72
72
  facts, not a description of it. Settling a voided invoice and voiding a settled one are different
73
73
  questions: one spec each.
74
- ```screenplay excerpt
74
+ ```screenplay excerpt parent=references/invoicing-dues-example.md#1
75
75
  specification RejectingSettlementOfAVoidedInvoice
76
76
  given caller
77
77
  authenticated
@@ -103,7 +103,7 @@ in `invoicing-dues-design.md`; it is never prose and never a spec that pretends
103
103
  Two separate obligations. First, the **capture specification**: concrete external input in, our
104
104
  facts out. The provider's refusal is a fact (never a `then error`), kept in the provider's
105
105
  vocabulary and then translated.
106
- ```screenplay excerpt
106
+ ```screenplay excerpt parent=references/invoicing-dues-example.md#1
107
107
  specification TranslatingADeclinedCardResult
108
108
  when capture PaymentGatewayResults
109
109
  reference = "9c1f0a52-6a4e-4b1c-9f55-0d2c7b8e1a01"
@@ -121,7 +121,7 @@ Second, the **retry**. `PaymentRequested` only says we asked the gateway; it is
121
121
  After the decline, requesting again is an ordinary accepted command, and its exact declared
122
122
  outcome is `PaymentRequested`, not `PaymentReceived`: the eventual success is a later external
123
123
  fact that arrives through the capture, not something this command produces.
124
- ```screenplay excerpt
124
+ ```screenplay excerpt parent=references/invoicing-dues-example.md#1
125
125
  specification RetryingPaymentAfterADecline
126
126
  given caller
127
127
  authenticated
@@ -149,7 +149,7 @@ lists the declared consequence (`RefundRequested`); the reaction is also specifi
149
149
  `RefundRequested` is a recorded request, not proof that money moved, and there is no
150
150
  `then <Command>` form. What the target must do to deliver the refund is a requirement, not a spec.
151
151
  From `invoicing-dues-design.md` (design mode; the specs do not run at 4.66.0):
152
- ```screenplay excerpt
152
+ ```screenplay excerpt parent=references/invoicing-dues-design.md#1 expect PLAY0516 test=unbound
153
153
  specification ReversingAReceivedPayment
154
154
  given caller
155
155
  authenticated
@@ -185,7 +185,7 @@ ask. Voiding an issued invoice that is not yet paid is the other compensation (t
185
185
  A repeated event type can matter as much as a multi-event lifecycle. Two top-ups of 40 and 70
186
186
  walk a balance to 110; give the second occurrence as the action so the accumulation is what is
187
187
  tested.
188
- ```screenplay excerpt
188
+ ```screenplay excerpt parent=references/invoicing-dues-example.md#1
189
189
  specification MemberCreditAccumulatesTopUps
190
190
  given caller
191
191
  authenticated
@@ -75,7 +75,7 @@ survive; ask what a caller who may not look sees.
75
75
  - Do not perfect a scenario in the room. Capture it with its open question and move on.
76
76
  - Every "what if...?" from anyone becomes a named candidate at once.
77
77
  - Record why a rule behaves as it does when the room explains it; the modeler puts it in the
78
- slice `description`.
78
+ slice `documentation`.
79
79
 
80
80
  ## Multi-role check (before leaving the room)
81
81
  - Domain expert: is this the right business behaviour and message?
@@ -62,7 +62,7 @@ both that the stored row is gone and that the keyed query returns nothing. The w
62
62
  (no key) is a design-mode expectation here: a list-query collection check does not run on the
63
63
  reference route, so record it in the matrix rather than asserting it.
64
64
  The source document also asserts the other terminal outcomes (`InvoiceVoided`, `InvoiceSettled`) the same way; they are not copied here.
65
- ```screenplay excerpt
65
+ ```screenplay excerpt parent=references/invoicing-dues-example.md#1
66
66
  specification OpenInvoicesLifecycle1Empty
67
67
  given caller
68
68
  authenticated
@@ -3,10 +3,11 @@
3
3
  "input": "Write the specifications for a ReserveBerth command and its read model, and tell me what coverage is missing.",
4
4
  "fixtures": [],
5
5
  "assertions": [
6
+ { "kind": "play-compiles" },
6
7
  { "kind": "skill-contains", "value": "Coverage matrix before any spec" },
7
8
  { "kind": "skill-contains", "value": "Once, idempotent, exactly once are different claims" },
8
9
  { "kind": "skill-contains", "value": "Unauthorized is never `then error`" },
9
- { "kind": "skill-contains", "value": "Screenplay#390" },
10
+ { "kind": "skill-contains", "value": "find-specification-obligations" },
10
11
  { "kind": "skill-contains", "value": "v4.68.0" },
11
12
  { "kind": "skill-contains", "value": "false PLAY0285" },
12
13
  { "kind": "skill-contains", "value": "One behaviour per spec" },
@@ -31,7 +31,7 @@ Lifecycle, modes and hand-offs: `cratis-screenplay-modeling-lifecycle`.
31
31
  Skip if the request already names the command origins (screens, reactions, outside systems),
32
32
  the decision behind each shown field, and how fresh each view must be. Otherwise ask, in one
33
33
  batch, only what is missing. Unattended: assume visibly, record each assumption in the phase
34
- report and the slice `description`, and continue.
34
+ report and slice `documentation`, and continue.
35
35
 
36
36
  1. **Origin of each action.** Is it (A) user-initiated only, (B) automated, (C) a mix, or
37
37
  started by a clock or outside system (schedule, webhook, feed)? Impact: separates screen
@@ -80,8 +80,8 @@ report and the slice `description`, and continue.
80
80
  standing in for a rule. Place each rule in its layer (`references/rule-layers.md`). A rule
81
81
  over stored state is written as `reads <View>` + `require ... message "..."` and marked
82
82
  **NOT enforced in the model today** in the slice `description`, with its target named (Arc
83
- `[ProtectedDecision]` + `DecisionRead<T>` on Arc 22.39.0+, not available in Stage-rendered
84
- apps; Chronicle DCB; or a constraint). Never copy state
83
+ `[ProtectedDecision]` + `DecisionRead<T>` on Arc 22.39.0+ (available to gap-fill
84
+ code with Stage 4.51.3's Arc 22.50.5/Chronicle 19.32.0); Chronicle DCB; or a constraint). Never copy state
85
85
  into the command as input or hide a rule in `handler` / hint prose; descriptions are not
86
86
  rendered (Stage#178). Fill the **refusal inventory**: success, each distinct refusal with
87
87
  layer and message, and the denied persona.
@@ -129,7 +129,7 @@ report and the slice `description`, and continue.
129
129
  actor sees each state change's result. Beyond Level 1: `cratis-screenplay-ui-composition`.
130
130
  8. **Lineage pass.** Build the matrix in `references/field-lineage.md` from the `.play` files
131
131
  (read them), not from memory or an earlier summary. For each read model, write one line per
132
- contributing event in its StateView slice `description`: which fields it sets and why. An
132
+ contributing event in its StateView slice `documentation`: which fields it sets and why. An
133
133
  event with no reason does not belong in the view. A field without an origin is a gap: add
134
134
  the missing input or event field, or record an open question. Never invent a source.
135
135
  9. **Slice and continue** (`references/slicing.md`): state-transition table per entity; one
@@ -163,9 +163,14 @@ report and the slice `description`, and continue.
163
163
 
164
164
  - One command per `StateChange` slice (renderable: required, plus no `produces when`).
165
165
  - One business decision usually produces one event; a decision establishing several facts the
166
- business recognises separately may produce several (say why in the `description`).
166
+ business recognises separately may produce several (say why in `documentation`).
167
167
  - Copy an identity into an event payload only when a consumer needs it as a value.
168
- - Keep durable design rationale in slice `description` text, not `//` comments.
168
+ - Keep the one-line summary in `description`, including short status markers such as
169
+ **NOT enforced in the model today** (with its target) or **ASSUMED**; record durable
170
+ reasoning, assumptions, causes and rejected alternatives in fenced Markdown
171
+ `documentation` on the module, feature, slice, command, event, read model or reaction, not `//` comments or disconnected notes. These are report-only, not
172
+ enforcement. Read [model reasoning](references/model-reasoning.md) for owners,
173
+ syntax, folder merge and PLAY0558/0559.
169
174
  - Rule coverage: for each value carrying a rule, list every path that sets it
170
175
  (`references/slicing.md`). A constraint on a claim covers every event setting that claim;
171
176
  value invariants live in the concept so they travel; command-level conditions are reviewed
@@ -199,7 +204,7 @@ Slice design is done when these hold; otherwise report what is open.
199
204
  denied persona); every gated command and query has a `then denied` row.
200
205
  - [ ] Every event is past tense, a specific change, and consumed or justified.
201
206
  - [ ] Every read model has a consumer and, when the scope is executable, one unambiguous key (keyed queries all using the same `by` property).
202
- - [ ] Every StateView `description` gives a reason per contributing event; every read-model
207
+ - [ ] Every StateView's `documentation` gives a reason per contributing event; every read-model
203
208
  field and screen field is traced; every `from` event sets a field.
204
209
  - [ ] No `screen` without `data` or `action`; every acting screen has `data` or a stated
205
210
  exemption.
@@ -16,7 +16,7 @@ and each persona that must be denied becomes a `given caller` fixture. Build it
16
16
  ## Command card
17
17
 
18
18
  Fill one card per command before (or while) writing the slice. Keep it in the phase report;
19
- durable rationale goes in the slice `description`.
19
+ durable rationale goes in fenced Markdown slice `documentation`.
20
20
 
21
21
  ```text
22
22
  Command: <ImperativeBusinessName> (one decision)
@@ -76,7 +76,8 @@ Rules for filling it:
76
76
  as a gap. Persona description text is intent only.
77
77
  - A refusal that depends on stored state is a row marked **NOT enforced in the model today**
78
78
  with its target (Arc `[ProtectedDecision]` + `DecisionRead<T>` where Arc 22.39.0 or later is
79
- available, which Stage-rendered apps are not; Chronicle DCB, or a
79
+ available, including Stage 4.51.3's rendered package set for gap-fill, not emitted
80
+ protection; Chronicle DCB, or a
80
81
  constraint). It still gets a spec row, because the intended behaviour is the contract.
81
82
  - A decided refusal never goes to open questions: it goes here, then to scenarios.
82
83
  - A refusal message is a fact of the design; keep the wording identical in the rule, the
@@ -101,7 +102,7 @@ Rules for filling it:
101
102
  | AssignLocker | caller is not an attendant | `authorize IsAttendant` | denied: Customer | RefusingACustomerAssigningALocker |
102
103
  | AssignLocker | locker already has a request | constraint `OneRequestPerLocker` | "The locker is already assigned" | AppendingASecondAssignmentOfALocker (`when append`: the command's own `require` would reject first) |
103
104
  | AssignLocker | request already has a locker | constraint `OneLockerPerRequest` | "The request already has a locker" | gap |
104
- | AssignLocker | locker is not free | `reads` + `require`, NOT enforced today | "The locker is not free"; target: `[ProtectedDecision]` (Arc 22.39.0+; unavailable in Stage-rendered apps, so a capability gap there) or DCB on the locker stream | RejectingASecondAssignmentOfALocker (pins the message; blocked until the target exists) |
105
+ | AssignLocker | locker is not free | `reads` + `require`, NOT enforced today | "The locker is not free"; target: `[ProtectedDecision]` (Arc 22.39.0+; available to Stage 4.51.3 gap-fill, not emitted protection) or DCB on the locker stream | RejectingASecondAssignmentOfALocker (pins the message; blocked until the target exists) |
105
106
  | AssignLocker | request is not waiting | `reads` + `require`, NOT enforced today | "The request is not waiting for a locker" | gap (same) |
106
107
  | LockerById, ListLockers | caller is anonymous | module `authorize IsAuthenticated` | denied: no caller | RefusingAnAnonymousLockerLookup, RefusingAnAnonymousLockerList |
107
108
  | RequestById | caller is anonymous | module `authorize IsAuthenticated` | denied: no caller | RefusingAnAnonymousRequestLookup |
@@ -33,7 +33,7 @@ Those are the portable sources. The event-source id is the `for` value, not a pr
33
33
  an event field (same-named fields map automatically - AutoMap is on; its matching differs between flat and scoped projections, see `read-model-design.md` "Building it");
34
34
  `$eventSourceId` (the instance identity); a literal (status words); a counter or arithmetic;
35
35
  a join on another event stream; children for collections. A reducer is opaque: write its
36
- lineage in the slice `description`. A read model built by a query `performer` (no events)
36
+ lineage in slice `documentation`. A read model built by a query `performer` (no events)
37
37
  has lineage outside the model; say where.
38
38
 
39
39
  **Screen field** - from the query result named in `data ... via query`. A screen showing a
@@ -74,7 +74,7 @@ Filled for `worked-example.md`:
74
74
 
75
75
  ## The reason line per contributing event
76
76
 
77
- The matrix is the audit; the durable record is the StateView slice `description`: one line per
77
+ The matrix is the audit; the durable record is StateView slice `documentation`: one line per
78
78
  contributing event saying which fields it sets and why. Write it as a tagged text block in a
79
79
  real model (a bare fence warns with `PLAY0397`). `worked-example.md` uses one-string
80
80
  descriptions only so that it stays a single compiling fence.
@@ -0,0 +1,87 @@
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
+ # Keep reasoning on the model
5
+
6
+ Use `description` for a short summary and `documentation` for assumptions,
7
+ boundaries, trade-offs and rejected alternatives. Put reasoning on the declaration
8
+ it explains, not in comments or disconnected session notes. Modules, features,
9
+ slices, commands, events, read models and reactions accept one nonempty block,
10
+ directly in their body (not beneath a reaction trigger). Queries, personas and other
11
+ declarations do not accept `documentation`: keep their intent in `description` (a
12
+ query's ordering, "oldest first", for example). A short status marker such as **NOT
13
+ enforced in the model today** or **ASSUMED** stays in `description`, where a reader
14
+ sees it first; the reasoning behind it goes in `documentation`:
15
+
16
+ ````screenplay
17
+ module Billing
18
+ documentation
19
+ ```markdown
20
+ ## Boundary
21
+ Billing records agreed amounts; payment delivery belongs elsewhere.
22
+ ```
23
+ feature Amounts
24
+ documentation
25
+ ```markdown
26
+ Keep the agreed amount, not a running total.
27
+ ```
28
+ slice StateChange RecordAmount
29
+ documentation
30
+ ```markdown
31
+ A recorded amount is a decision, not a recalculated view.
32
+ ```
33
+ command RecordAmount
34
+ documentation
35
+ ```markdown
36
+ The caller supplies the agreed amount.
37
+ ```
38
+ recordId String identifier
39
+ amount Int
40
+ produces AmountRecorded
41
+ for recordId
42
+ amount = amount
43
+ event AmountRecorded
44
+ amount Int
45
+ specification RecordingAnAmount
46
+ description "Witnesses that the agreed amount is retained"
47
+ when RecordAmount amount = 10
48
+ recordId = "amount-1"
49
+ then AmountRecorded amount = 10
50
+ slice StateView AmountHistory
51
+ readmodel AmountView
52
+ documentation
53
+ ```markdown
54
+ This view is display state, not an atomic decision input.
55
+ ```
56
+ id String
57
+ amount Int
58
+ projection AmountHistory => AmountView
59
+ from AmountRecorded
60
+ id = $eventSourceId
61
+ amount = amount
62
+ query AmountById => AmountView optional
63
+ by id String
64
+ slice Automation ObserveAmount
65
+ reaction ObserveAmount
66
+ documentation
67
+ ```markdown
68
+ Observation does not certify an exactly-once external effect.
69
+ ```
70
+ when AmountRecorded
71
+ ````
72
+
73
+ A specification accepts a `description` naming the behavior it witnesses, not
74
+ `documentation`; longer reasoning belongs to its slice. Projections and screens
75
+ do not accept documentation. `documentation String` remains a typed property
76
+ where properties are allowed; bare `documentation` starts metadata.
77
+
78
+ Both metadata fields are report-only (PLAY0270): no executable bytes,
79
+ `modelRevision` or ESM version change, no rule enforcement or rendered code.
80
+ Canonical printing retains documentation on its owner; source identity changes. MCP `declaration-details` summary exposes
81
+ `description` and `documentation` wherever supported. Folder merge keeps the
82
+ first module/feature block: identical copies are accepted, conflicting copies
83
+ warn PLAY0559. Malformed, empty or repeated blocks report PLAY0558; events retain
84
+ PLAY0477. These diagnostics have no automatic repair; choose the owning text.
85
+
86
+ Authority: Screenplay v4.127.0 `slices.md` and `specifications.md`. The complete
87
+ model above validates and its specification passes on standalone 4.127.0.
@@ -28,7 +28,7 @@ is adapted with the agreement of Martin Dilger and Nebulit GmbH.
28
28
  | `eventmodeling-identifying-outputs/SKILL.md`: events vs read models test, recalculated-state anti-pattern, processor outputs categorized (new event, view update, notification) | `references/read-model-design.md` "Events or views" | shared with TrogonStack's version, including the processor-output categories (row above); adapted closely; the "independent means event" and "no computed fields" rows dropped because decided calculations are facts in Screenplay |
29
29
  | `eventmodeling-identifying-outputs/SKILL.md` Step 5a/5c: enumerate consumers, one component one read model, homogeneous list is one component, wide-fan-in versus cheap fields | `references/read-model-design.md` "Components" | adapted closely; "always split" softened to "split when you can name the consequence" (existing decision); screen copies become one `data` line per component |
30
30
  | `eventmodeling-identifying-outputs/SKILL.md` Step 5d: build read models from the screen's field mappings, not from its title or a summary | `references/read-model-design.md` "Components"; `references/field-lineage.md` | adapted closely |
31
- | `eventmodeling-identifying-outputs/SKILL.md` Step 5h.4, 5i: event-to-field reasoning note, per-node verification result list | `SKILL.md` step 8; `references/read-model-design.md` "Checks before handing off"; `references/field-lineage.md` | adapted closely; the note lives in the StateView slice `description` |
31
+ | `eventmodeling-identifying-outputs/SKILL.md` Step 5h.4, 5i: event-to-field reasoning note, per-node verification result list | `SKILL.md` step 8; `references/read-model-design.md` "Checks before handing off"; `references/field-lineage.md` | adapted closely; the reasoning note lives in StateView slice `documentation` |
32
32
  | `eventmodeling-identifying-outputs/SKILL.md` lines 378-379: before completion re-read every read model and recheck each field and every reason note (roll-ups, additions) | `references/read-model-design.md` "Checks before handing off" | adapted closely; Cratis named-consequence threshold kept instead of "always split" |
33
33
  | `eventmodeling-identifying-outputs/SKILL.md` Interview: calculated fields confirmation wording | `SKILL.md` *Interview phase* question 3 | adapted closely |
34
34
  | `eventmodeling-identifying-inputs/SKILL.md`: automation level and outside-trigger questions, user versus processor commands marked, conditional input pattern, processor failure/retry stated | `SKILL.md` *Interview phase* question 1; `references/command-inventory.md` | adapted closely; `[USER]`/`[AUTO]` kept as plain classification |
@@ -127,7 +127,7 @@ it stays.
127
127
  (worklists, status awaiting an outside answer); one-shot otherwise. Design mode only
128
128
  (PLAY0268). If access can be revoked mid-session, record that the target re-checks per emission.
129
129
  - Never model paging or page size (no syntax, Screenplay#140). State the order in the query
130
- `description` ("oldest first"); an unbounded list is a review question.
130
+ `description` ("oldest first"; queries do not accept `documentation`); an unbounded list is a review question.
131
131
  - A gated keyed query needs its own denial spec.
132
132
 
133
133
  Never drop a list query from a design model just to make it bind; record the capability gap.
@@ -260,7 +260,7 @@ module Berths
260
260
 
261
261
  ## Checks before handing off
262
262
 
263
- - The StateView slice `description` gives, per contributing event, the fields it sets and why
263
+ - StateView slice `documentation` gives, per contributing event, the fields it sets and why
264
264
  (see `LockerBoard` in `worked-example.md`); extend it whenever a `from` is added. Shape of
265
265
  the note: `BerthBooked sets bookingId, status="booked": the view's creation event; the booking
266
266
  does not exist before it.` / `BoatArrived sets status="arrived", arrivedAt: the only
@@ -14,18 +14,18 @@ rendered code (Stage#178): a rule that exists only in prose is unenforced in ren
14
14
  | stored state (record exists, balance, current status) | `reads <View>` + `require <expr> message "..."` | stated intent, **NOT enforced in the model today** (PLAY0268/0271 at binding are expected in design mode; Screenplay#129/#209). Name the target: Arc `[ProtectedDecision]` + `DecisionRead<T>` (Arc 22.39.0 or later), Chronicle DCB (`concurrency` scope), or a constraint |
15
15
 
16
16
  An unguarded materialized read is unsafe for a protected decision; a guarded read is the
17
- supported route. Availability: `[ProtectedDecision]` and `DecisionRead<T>` need Arc 22.39.0 or
18
- later and are **not available in Stage-rendered apps**, whose scaffold pins Arc 22.25.0 (Stage
19
- 4.24.0); never edit the managed dependency files to get them. For rendered scope, record a
20
- capability gap (or a separately verified compatible enforcement path, such as a constraint or
21
- a Chronicle DCB scope) and keep the rule as NOT enforced. Forbidden: caller-supplied copies of state in `require`, boolean attestation
17
+ supported route. Availability: `[ProtectedDecision]` and `DecisionRead<T>` exist in
18
+ Stage 4.51.3's Arc 22.50.5/Chronicle 19.32.0 package set, but Stage does not emit
19
+ protected decisions. Gap-fill must use an admitted projection/key shape and active
20
+ unit-of-work enrollment; do not edit managed dependencies. Keep the `.play` rule
21
+ NOT enforced until its target enforcement is separately verified. Forbidden: caller-supplied copies of state in `require`, boolean attestation
22
22
  inputs (`confirmsX == true`), rules in `handler` / implementation-hint prose.
23
23
 
24
24
  ## Authorization is executable
25
25
 
26
26
  Persona Does/Reads/Cannot text is intent. Every Cannot line resolves to an `authorize` gate
27
- (policy or ownership claim) plus a `then denied` spec whose `given caller` carries the roles
28
- and claims standing for that persona; otherwise record a gap. Every command and query under an
27
+ (policy or ownership claim) plus a `then denied` spec using `given caller as <Persona>` or an explicit
28
+ caller for the effective gate; otherwise record a gap. Every command and query under an
29
29
  inherited module/feature `authorize` gets its own `then denied` spec. Ownership gates need a
30
30
  second caller with another claim value.
31
31
 
@@ -33,7 +33,7 @@ second caller with another claim value.
33
33
 
34
34
  Command property values are, by default, recorded in the causation chain of the events they
35
35
  produce, so treat them as permanent. Newer Chronicle versions can omit causation properties
36
- (`CausationPropertyRetention.Omit`, Chronicle v19.32.0); rendered apps pin Chronicle 19.8.1.
36
+ (`CausationPropertyRetention.Omit`, Chronicle v19.32.0); Stage 4.51.3 rendered apps pin 19.32.0.
37
37
  Verify the actual auditing and retention configuration before relying on omission, and never
38
38
  audit secrets. Classify personal values as bare `pii` and operational secrets as
39
39
  `secret` on their concepts, never the identifier concept. Use a surrogate identity
@@ -23,7 +23,7 @@ step at the end: design each behaviour as its slice, then audit the set.
23
23
  | `Translate` | captures, translated events | the integration (`CarrierManifests`) | see `cratis-screenplay-automations-and-translations` |
24
24
 
25
25
  Screenplay allows several commands or read models in one slice; prefer splitting unless the
26
- behaviour is genuinely one (and say why in the `description`).
26
+ behaviour is genuinely one (and say why in `documentation`).
27
27
 
28
28
  ## Slice dependencies
29
29
 
@@ -89,7 +89,7 @@ Example: Payroll declares Timesheets; its Handover feature declares
89
89
  Timesheets.Approval and sibling Runs. These are dependency inventories, not
90
90
  actual references or execution dependencies:
91
91
 
92
- ```screenplay
92
+ ```screenplay expect PLAY0553
93
93
  module Payroll
94
94
  depends on Timesheets
95
95
  feature Handover
@@ -142,8 +142,8 @@ result in every row and no refusal anywhere, whose event restates most of the en
142
142
  relocated).
143
143
  4. Apply rule coverage (below) to each new path.
144
144
  5. If the business treats a multi-value data-entry correction as one act, keep one correction
145
- command named for the correction (never `Update`), with the reason in the slice
146
- `description`; rule coverage still applies.
145
+ command named for the correction (never `Update`), with the reason in slice
146
+ `documentation`; rule coverage still applies.
147
147
 
148
148
  A repeated-field event is a review signal; it is major only when business meaning is lost, a
149
149
  rule is bypassed or consumers become ambiguous. Historical generations repeat prior shape on
@@ -13,11 +13,17 @@ complete givens) so they are the right form once binding is possible.
13
13
  Lineage matrix: `field-lineage.md`. State-transition table and rule coverage: `slicing.md`.
14
14
  Per-command refusal inventory: `command-inventory.md`.
15
15
 
16
- The per-event reason lines in each StateView `description` are the lineage record
17
- (`field-lineage.md`). Multi-line descriptions use a tagged ` ```text ` fence in a real model;
18
- they are written as one string here so this document stays a single compiling fence.
16
+ This historical compiled example keeps per-event reasoning in StateView
17
+ `description` strings. For current 4.127.0 authoring, keep descriptions as summaries
18
+ and record lineage reasoning in fenced Markdown `documentation` (`field-lineage.md`).
19
+ The historical source below stays unchanged; it is not the current placement recipe.
19
20
 
20
- ```screenplay
21
+ The excerpt's Stage availability note is historical (Stage 4.24.x, Arc 22.25.0).
22
+ Stage 4.51.3 pins Arc 22.50.5/Chronicle 19.32.0, so protected-read APIs are available
23
+ to gap-fill; this neither admits these `.play` rules nor proves target protection.
24
+ The original compiled excerpt is retained unchanged.
25
+
26
+ ```screenplay expect PLAY0516 test=unbound
21
27
  domain Parcelpoint.Lockers
22
28
 
23
29
  concept LockerId : Uuid
@@ -3,6 +3,7 @@
3
3
  "input": "Design the slices for a new capability in a Screenplay model: commands, rules, read models and screens.",
4
4
  "fixtures": [],
5
5
  "assertions": [
6
+ { "kind": "play-compiles" },
6
7
  {
7
8
  "kind": "skill-contains",
8
9
  "value": "NOT enforced in the model today"
@@ -37,7 +37,7 @@ The update follows `commands.md`, `events.md`, `types.md` and
37
37
  `specifications.md` at that main commit (after v4.52.0). This pass compiles the
38
38
  changed examples; it does not rerun the reference runner.
39
39
 
40
- Current specification syntax follows Screenplay v4.125.0 `specifications.md`;
40
+ Current specification syntax follows Screenplay v4.127.0 `specifications.md`;
41
41
  older probes in the table remain historical. Pins: `cratis-screenplay-toolchain`
42
42
  `references/versions.md`. Compile commands check source, not reference execution.
43
43
  Use `screenplay test` or MCP `run-specifications` for V4; Stage/target tests are
@@ -95,13 +95,27 @@ Unsupported is not passed. Report it as "needs a target", not as green. "Specifi
95
95
  and "bound" are never "passing": run the reference CLI/MCP route or the owning
96
96
  target tests, and name the engine, version and expected/discovered selection.
97
97
 
98
+ ## Descriptions, persona callers and case tables
99
+
100
+ Use one `description "<rule or behavior>"` (or a fenced `text` description) to
101
+ name what the specification witnesses. It is report-only (PLAY0270), changing
102
+ neither execution nor ESM bytes. Specifications do not accept `documentation`;
103
+ put longer assumptions and rejected alternatives on the owning slice's fenced
104
+ Markdown `documentation` block.
105
+
106
+ `given caller as <Persona>` expands to one authenticated policy witness before
107
+ binding. Named `parameter`/`case` tables share steps and read values as
108
+ `case.<parameter>`; each case runs independently as `<Specification>_<Case>`.
109
+ Read [persona callers and case tables](references/persona-callers-and-cases.md)
110
+ for synthesis refusals, selection, provenance and a complete passing model.
111
+
98
112
  ## The vocabulary
99
113
 
100
114
  | Construct | Meaning |
101
115
  | --- | --- |
102
116
  | `given <EventType>` | prior state, established by replaying events before the action |
103
117
  | `given readmodel <ReadModelType>` | prior read-model state, established directly — a **complete** instance including its identifier |
104
- | `given caller` | the caller: `authenticated`, `role "<r>"`, repeatable `claim "<type>" = "<value>"`; empty means unauthenticated |
118
+ | `given caller` / `given caller as <Persona>` | explicit caller (`authenticated`, roles, claims; empty means anonymous), or an authenticated synthesized persona witness |
105
119
  | `when <CommandType>` | run a command |
106
120
  | `when append <EventType>` | append one event: constraints and projections run, the command does not; reactions run only from ESM v6, where `then` lists what followed |
107
121
  | `when query <Query>` | perform a query with the argument values beneath it (v4.48.0) |
@@ -146,7 +160,7 @@ Rules the binder enforces:
146
160
  - **`then denied` stands alone**: not with events, errors or state assertions
147
161
  (`PLAY0388`). For a query, pair it with one `then query` that has `arguments`
148
162
  and no `result`.
149
- - **Authorized commands and queries need `given caller`** (`PLAY0389`). The runner
163
+ - **Authorized commands and queries need `given caller` or `given caller as <Persona>`** (`PLAY0389`). The runner
150
164
  never invents a caller.
151
165
  - **`null` only in optional read-model values.** A `null` in a command or event
152
166
  value is `PLAY0350`: an optional fact is a separate event.
@@ -168,7 +182,7 @@ the one-rejection rule (`PLAY0273`) are reported only when the model binds, so
168
182
  - **Rejections:** `then error "<message>"` matches the message whatever the rule's
169
183
  validation severity; no form asserts severity. Bare `then error` never matches
170
184
  a denial. Quote a localized key: `then error "$strings.invoices.reasonRequired"`.
171
- The grammar takes only quoted messages here, never an unquoted `$strings` token
185
+ Besides a String `case.<parameter>`, the grammar takes only quoted messages here, never an unquoted `$strings` token
172
186
  (unlike a rule's `message` operand). The reference runner compares the symbolic key
173
187
  and requires the rejection to carry the string-key marker; it never loads
174
188
  translated text; resolving the key is the realization's job.
@@ -197,7 +211,10 @@ Read [references/reactions-and-cascades.md](references/reactions-and-cascades.md
197
211
 
198
212
  Use typed `example` declarations for repeated event/command/read-model values;
199
213
  step overrides keep the action/outcome visible and carry authored/example/override
200
- provenance. Event `stream`/`no stream` assertions bind as ESM v8; typed `for` and
214
+ provenance. Event examples can carry routes, replaced as a whole by a step.
215
+ Redelivery locators may state `stream` or `no stream` to select one definitely
216
+ matching given occurrence with no undecided candidates (PLAY0543); redelivery
217
+ remains authoring-only. Event `stream`/`no stream` assertions bind as ESM v8; typed `for` and
201
218
  stream ids are not guessed. Read [examples and routes](references/examples-and-routes.md).
202
219
 
203
220
  `given operation ... fails`, `then operation` and `then compensated` describe
@@ -8,6 +8,7 @@
8
8
  - Typed examples
9
9
  - Effective values
10
10
  - Event routes
11
+ - Redelivery locators
11
12
  - Operation and recovery intent
12
13
 
13
14
  ## Typed examples
@@ -96,6 +97,63 @@ Source: v4.127.0 `event-sources.md`, `specifications.md`, `diagnostics.md`.
96
97
  CLI 3.41.0 rendering rejects versions above v7 before planning, even though
97
98
  source compilation and reference routing pass.
98
99
 
100
+ Command and read-model examples refuse routes (PLAY0526). Effective role and
101
+ `for` checks use the inherited or replaced route: inherited `no stream` on a
102
+ `given`/append is PLAY0547; incompatible destination/route pairs are PLAY0550,
103
+ and contradictory expectations PLAY0551. Declaration checks still run on unused
104
+ examples and routes overridden at every use. MCP route rows retain the origin
105
+ (authored/example/override), with the replaced whole route on the stream/no-stream
106
+ row and individual lineage on id parts.
107
+
108
+ ## Redelivery locators
109
+
110
+ `when redelivered <Event> to <Reaction>` may contain a route, using the same scalar
111
+ or complete composite `streamId` shape as event steps. No route is a wildcard;
112
+ `no stream` selects the unrouted given. Compare effective, example-expanded givens.
113
+ Every `for`, payload and route comparison is true, false or unknown: a definite
114
+ mismatch excludes a candidate even when another comparison is unknown. Selection
115
+ needs exactly one definitely matching candidate and **no undecided candidates**
116
+ (PLAY0543). Equal duplicate givens remain separate candidates. Narrow with `for`,
117
+ values, `stream` or `no stream`; do not guess an unknown value. A locator's `for`
118
+ is optional but typed against the routed source when present.
119
+
120
+ This complete syntax-only model validates on 4.127.0; `screenplay test` reports
121
+ PLAY0268 for redelivery, not a passing scenario:
122
+
123
+ ```screenplay test=unbound
124
+ eventsource Account
125
+ identifier String
126
+ stream Transactions
127
+ streamId String
128
+ module Accounts
129
+ feature Recovery
130
+ slice Automation Observe
131
+ event Recorded
132
+ amount Int
133
+ reaction Observer
134
+ when Recorded
135
+ example FirstPartition : Recorded
136
+ for "account-1"
137
+ stream Account.Transactions
138
+ streamId = "first"
139
+ amount = 10
140
+ specification RedeliveringTheSecondPartition
141
+ given FirstPartition
142
+ given FirstPartition
143
+ stream Account.Transactions
144
+ streamId = "second"
145
+ when redelivered Recorded to Observer
146
+ stream Account.Transactions
147
+ streamId = "second"
148
+ then no events
149
+ ```
150
+
151
+ The second given replaces the example's **entire** route, independently of `for`,
152
+ not just its id. PLAY0548 is command-action-only, never a locator route error;
153
+ malformed routes use PLAY0547 and resolution/key-shape errors PLAY0549. MCP labels
154
+ locator fixtures `whenRedeliveredEvent` with route-origin rows. Route admission
155
+ alone does not admit redelivery or `then no events`.
156
+
99
157
  ## Operation and recovery intent
100
158
 
101
159
  Operation failure/request/compensation forms are authoring-only (PLAY0268):
@@ -108,4 +166,4 @@ remain unadmitted; they are not executed append scenarios. Forms, matching,
108
166
  acknowledgement and their whole-model refusal boundary are in
109
167
  captures-and-reactions `references/refusals-and-redelivery.md`.
110
168
 
111
- Authority: Screenplay `v4.125.0:Documentation/screenplay/specifications.md`.
169
+ Authority: Screenplay `v4.127.0:Documentation/screenplay/specifications.md`.