@cratis/pi 7.23.0 → 7.24.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 (79) 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-screenplay-automations-and-translations/references/automation-patterns.md +3 -3
  4. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/cases-to-specify.md +1 -1
  5. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/effects-and-idempotency.md +1 -1
  6. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/integration-contracts.md +1 -1
  7. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/realization-and-gap-fill.md +5 -3
  8. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/translation-patterns.md +1 -1
  9. package/package/corpus/skills/cratis-screenplay-discovery/SKILL.md +6 -5
  10. package/package/corpus/skills/cratis-screenplay-discovery/references/event-naming.md +1 -1
  11. package/package/corpus/skills/cratis-screenplay-discovery/references/facilitation.md +5 -4
  12. package/package/corpus/skills/cratis-screenplay-discovery/references/human-workshop.md +1 -1
  13. package/package/corpus/skills/cratis-screenplay-discovery/references/interview-questions.md +1 -1
  14. package/package/corpus/skills/cratis-screenplay-discovery/references/personas-and-causes.md +7 -4
  15. package/package/corpus/skills/cratis-screenplay-discovery/references/plotting-and-handoff.md +8 -7
  16. package/package/corpus/skills/cratis-screenplay-discovery/references/storming-loop.md +2 -2
  17. package/package/corpus/skills/cratis-screenplay-event-modeling/SKILL.md +10 -0
  18. package/package/corpus/skills/cratis-screenplay-event-modeling/references/nine-steps.md +1 -2
  19. package/package/corpus/skills/cratis-screenplay-legacy-extraction/SKILL.md +1 -1
  20. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/loss-report-template.md +1 -1
  21. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/rule-modeling.md +4 -4
  22. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/signal-to-intent.md +1 -1
  23. package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +5 -4
  24. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-loop.md +14 -6
  25. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +71 -8
  26. package/package/corpus/skills/cratis-screenplay-model-review/SKILL.md +15 -6
  27. package/package/corpus/skills/cratis-screenplay-model-review/references/anti-patterns.md +1 -1
  28. package/package/corpus/skills/cratis-screenplay-model-review/references/checklist.md +10 -9
  29. package/package/corpus/skills/cratis-screenplay-model-review/references/report-template.md +5 -1
  30. package/package/corpus/skills/cratis-screenplay-model-review/verification.json +1 -1
  31. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/SKILL.md +2 -2
  32. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/opt-in.md +7 -5
  33. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/phases.md +4 -4
  34. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/provenance.md +1 -1
  35. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/reasoning-notes.md +24 -19
  36. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/stop-or-assume.md +1 -1
  37. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/verdicts-and-modes.md +4 -2
  38. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/vocabulary-map.md +1 -1
  39. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/worked-example.md +15 -9
  40. package/package/corpus/skills/cratis-screenplay-read-surface/SKILL.md +4 -1
  41. package/package/corpus/skills/cratis-screenplay-read-surface/references/guarded-actions.md +4 -0
  42. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/SKILL.md +4 -3
  43. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/drift-and-ledger.md +1 -1
  44. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/gap-fill-handoff.md +3 -3
  45. package/package/corpus/skills/cratis-screenplay-scenario-coverage/SKILL.md +25 -9
  46. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/coverage-matrix.md +1 -1
  47. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/invoicing-dues-design.md +5 -0
  48. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/scenario-catalogue.md +7 -4
  49. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/scenario-examples.md +1 -1
  50. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/scenario-workshop.md +1 -1
  51. package/package/corpus/skills/cratis-screenplay-scenario-coverage/verification.json +1 -1
  52. package/package/corpus/skills/cratis-screenplay-slice-design/SKILL.md +12 -7
  53. package/package/corpus/skills/cratis-screenplay-slice-design/references/command-inventory.md +4 -3
  54. package/package/corpus/skills/cratis-screenplay-slice-design/references/field-lineage.md +2 -2
  55. package/package/corpus/skills/cratis-screenplay-slice-design/references/model-reasoning.md +87 -0
  56. package/package/corpus/skills/cratis-screenplay-slice-design/references/provenance.md +1 -1
  57. package/package/corpus/skills/cratis-screenplay-slice-design/references/read-model-design.md +2 -2
  58. package/package/corpus/skills/cratis-screenplay-slice-design/references/rule-layers.md +8 -8
  59. package/package/corpus/skills/cratis-screenplay-slice-design/references/slicing.md +3 -3
  60. package/package/corpus/skills/cratis-screenplay-slice-design/references/worked-example.md +9 -3
  61. package/package/corpus/skills/cratis-screenplay-specifications/SKILL.md +22 -5
  62. package/package/corpus/skills/cratis-screenplay-specifications/references/examples-and-routes.md +59 -1
  63. package/package/corpus/skills/cratis-screenplay-specifications/references/persona-callers-and-cases.md +117 -0
  64. package/package/corpus/skills/cratis-screenplay-specifications/verification.json +1 -1
  65. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/SKILL.md +14 -13
  66. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/boundaries.md +3 -3
  67. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/chronicle-boundaries.md +3 -2
  68. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/consistency-and-concurrency.md +14 -11
  69. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/evolution.md +2 -2
  70. package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +49 -0
  71. package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +6 -3
  72. package/package/corpus/skills/cratis-screenplay-toolchain/references/traps.md +4 -4
  73. package/package/corpus/skills/cratis-screenplay-toolchain/references/versions.md +10 -0
  74. package/package/corpus/skills/cratis-screenplay-ui-composition/SKILL.md +4 -2
  75. package/package/corpus/skills/cratis-screenplay-ui-composition/references/guarded-interactions.md +71 -0
  76. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +5 -2
  77. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/rendered-application.md +17 -6
  78. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/verification.json +1 -1
  79. package/package.json +1 -1
@@ -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
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`.
@@ -0,0 +1,117 @@
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
+ # Persona callers and named case tables
5
+
6
+ ## Contents
7
+
8
+ - Persona callers
9
+ - Case tables
10
+
11
+ Authority: Screenplay v4.127.0 `specifications.md`, `personas.md` and `mcp/reference.md`.
12
+
13
+ ## Persona callers
14
+
15
+ `given caller as <Persona>` has no body and cannot coexist with an explicit
16
+ `given caller`. It expands before binding into an ordinary authenticated caller
17
+ satisfying every persona policy; persona names remain outside ESM bytes. Required
18
+ atoms are collected first. Policies are visited in declared order, depth first,
19
+ left to right: an already satisfied `or` adds nothing, otherwise the leftmost
20
+ buildable alternative wins. Operand order matters. This witnesses one minimal
21
+ caller, not every caller fitting the persona.
22
+
23
+ Synthesis refuses no policies, any policy containing `not` (including
24
+ `not authenticated`), inline/file policy code, and required non-literal claims.
25
+ An `or` may skip an unsupported claim alternative. The role-URI claim type
26
+ `http://schemas.microsoft.com/ws/2008/06/identity/claims/role` is never synthesized;
27
+ use role atoms, not that claim. Use explicit `given caller` when synthesis is
28
+ refused (binding PLAY0573), never infer a runtime allow/deny. Malformed references,
29
+ body lines or unknown top-level personas report PLAY0572.
30
+
31
+ Hover or `declaration-details` (`kind: "Persona"`, `view: "caller"`) shows the
32
+ chosen caller and policy contributions or refusal. Opt-in `personas` completeness
33
+ checks report personas gating nothing (PLAY0574), gates denying every known
34
+ synthesized persona (PLAY0575), and unpinned buildable alternatives (PLAY0576).
35
+ Unsynthesizable/undecidable callers are unknown, not denials. A persona-backed
36
+ denial still uses `then denied`; a visitor persona is not an anonymous caller.
37
+
38
+ ## Case tables
39
+
40
+ Use tables for validation matrices whose steps stay the same. Rows are **cases**,
41
+ not examples: `example` means a named typed fixture. This complete model's five
42
+ expanded specifications pass in the 4.127.0 reference runner:
43
+
44
+ ```screenplay
45
+ policy IsAccountant
46
+ require role "Accountant"
47
+ policy IsVisitor
48
+ require role "Visitor"
49
+ persona Accountant
50
+ policy IsAccountant
51
+ persona Visitor
52
+ policy IsVisitor
53
+ module Billing
54
+ feature Invoices
55
+ slice StateChange RecordAmount
56
+ command RecordAmount
57
+ recordId String identifier
58
+ amount Int
59
+ authorize IsAccountant
60
+ validate
61
+ require amount > 0
62
+ message "The amount must be positive"
63
+ produces AmountRecorded
64
+ for recordId
65
+ amount = amount
66
+ event AmountRecorded
67
+ amount Int
68
+ specification RecordingAmounts
69
+ description "An accountant can record a positive amount"
70
+ parameter amount Int
71
+ case Small amount = 10
72
+ case Large amount = 100
73
+ given caller as Accountant
74
+ when RecordAmount amount = case.amount
75
+ recordId = "amount-1"
76
+ then AmountRecorded amount = case.amount
77
+ specification RejectingAmounts
78
+ parameter amount Int
79
+ parameter reason String
80
+ case Zero
81
+ amount = 0
82
+ reason = "The amount must be positive"
83
+ case Negative
84
+ amount = -1
85
+ reason = "The amount must be positive"
86
+ given caller as Accountant
87
+ when RecordAmount amount = case.amount
88
+ recordId = "amount-1"
89
+ then error case.reason
90
+ specification RefusingAVisitor
91
+ given caller as Visitor
92
+ when RecordAmount amount = 10
93
+ recordId = "amount-1"
94
+ then denied
95
+ ```
96
+
97
+ Every case assigns every typed parameter exactly once, inline or indented.
98
+ Values are concrete literals or whole single-line objects/lists, never mappings,
99
+ `$` expressions, examples or other case references. `optional` permits `null`,
100
+ not omission or a default; ordinary command/event null restrictions still apply.
101
+
102
+ `case.<parameter>` fills a whole value position, after example expansion and step
103
+ overrides. It works in step assignments, generated fixtures, query arguments and
104
+ results, `for`, absent read-model keys and scalar `streamId` mappings in a restated
105
+ route. Types must match (concept/underlying primitive in either direction is
106
+ allowed); optional cannot feed required. `then error case.reason` needs String.
107
+ Callers, redelivery locators, clocks, declaration names, step kinds and members
108
+ inside structured literals cannot use case values: pass the whole object/list.
109
+
110
+ Each case expands independently to `<Specification>_<Case>`, in case order,
111
+ inheriting the description, with the same executable bytes as hand-expanded
112
+ specifications. Derived names must not collide in scope. Failures name the case.
113
+ Selecting a table address in `run-specifications` or `screenplay test --filter`
114
+ selects all cases; a derived address selects one. MCP specification `cases` pages
115
+ effective addresses and values; `find-fixtures` accepts `case` and retains
116
+ `table`, `case`, `caseParameter` provenance. C# singular `Expand` refuses tables
117
+ (PLAY0589); use `SpecificationExamples.ExpandAll`.
@@ -41,7 +41,7 @@
41
41
  },
42
42
  {
43
43
  "kind": "skill-contains",
44
- "value": "**Authorized commands and queries need `given caller`**"
44
+ "value": "**Authorized commands and queries need `given caller` or `given caller as <Persona>`**"
45
45
  },
46
46
  {
47
47
  "kind": "skill-contains",
@@ -28,8 +28,8 @@ Require target evidence that the check ran: a concurrent first-append scenario a
28
28
  Chronicle, asserting one append wins, one is rejected, and `IAppendResult.ConcurrencyCheckPerformed`
29
29
  is `true` (a skipped check and a passing one look identical otherwise; a current client against
30
30
  an older kernel always reads `false`). This was source- and documentation-inspected, not
31
- concurrency-tested here. Stage-rendered apps pin Chronicle client 19.8.1: do not assume these
32
- APIs exist there; confirm the package version before recommending them.
31
+ concurrency-tested here. Stage 4.51.3 rendered apps pin Chronicle client/kernel 19.32.0
32
+ and Arc 22.50.5; the APIs exist for gap-fill, not as automatically rendered enforcement.
33
33
 
34
34
  ## Verified product sources
35
35
 
@@ -38,7 +38,7 @@ APIs exist there; confirm the package version before recommending them.
38
38
  | Screenplay | v4.68.0 (`79801bf`) | ESM v7 generated values (`generated identifier`, decision 0026) and decision 0025's numbering; the diagnostics below were read at v4.66.0 (`c89198b`): `identifier`, `for`, constraints, generations, `id` pins, diagnostics PLAY0019/0135/0268/0271/0273/0391-0393/0446-0449/0469/0471 |
39
39
  | Chronicle | v19.32.0 (`f17a2ff`) | CHR0012, CHR0034; open defects #3744, #4123, #4131 |
40
40
  | Arc | v22.50.5 | `[ProtectedDecision]` and `DecisionRead<T>` (since v22.39.0) |
41
- | Stage | v4.24.2 | rendered apps pin Arc 22.25.0 and Chronicle client 19.8.1 (unchanged from 4.24.0); admits ESM v4 but refuses evolved events with `STAGE-ESM-026` (migrations not rendered, Stage#204) |
41
+ | Stage | v4.51.3 | rendered apps pin Arc 22.50.5 and Chronicle client/kernel 19.32.0; protected-read APIs available to gap-fill. Historical 4.24.2 admission probe: ESM v4, evolved events refused with `STAGE-ESM-026` |
42
42
 
43
43
  Full pin table: `references/versions.md` in `cratis-screenplay-toolchain`. Re-check the three
44
44
  Chronicle issues before relying on a constraint in a later release.
@@ -58,7 +58,7 @@ Chronicle issues before relying on a constraint in a later release.
58
58
  **Skip if** the user or the model already states the stream identities, who owns each module, how
59
59
  much autonomy each side has, the external systems, and rough growth. Otherwise ask only what is
60
60
  missing, one question at a time, with options. **Unattended:** assume the most conservative
61
- option, mark it `ASSUMED` in the slice or module `description` and in the session `STATE.md`
61
+ option, mark it `ASSUMED` in the slice or module `documentation` and in the session `STATE.md`
62
62
  (`.ai-work/screenplay/<model-slug>/STATE.md`), and continue.
63
63
 
64
64
  1. **Instance.** "What is the real-world thing this stream is about, and when does it start and
@@ -103,8 +103,8 @@ option, mark it `ASSUMED` in the slice or module `description` and in the sessio
103
103
  `unique event`, `released by`); list every event that sets the claimed value;
104
104
  - a state-dependent rule not reducible to those: write `reads <View>` + `require <expr>
105
105
  message "..."` as stated intent (PLAY0268/0271 at binding are expected in design mode) and
106
- mark it **NOT enforced in the model today** in the slice `description`, with requirement,
107
- missing guarantee, race consequence and the named target enforcement. Add a `STATE.md` row
106
+ mark it **NOT enforced in the model today** in the slice `description` with the named target,
107
+ and record requirement, missing guarantee and race consequence in the slice `documentation`. Add a `STATE.md` row
108
108
  with an owner. A general "some rules are unsupported" note is not enough.
109
109
  - Forbidden: a caller-supplied copy of state in `require`, a boolean attestation input
110
110
  (`confirmsX == true`) standing in for a rule, and rules hidden in `handler` or
@@ -118,7 +118,7 @@ option, mark it `ASSUMED` in the slice or module `description` and in the sessio
118
118
  4. **Set granularity.** One decision usually records one event; several facts are fine when each
119
119
  is a fact the business recognises. Different meanings get different events, not a flag with
120
120
  nullable siblings. Event properties are required by default (CHR0012, PLAY0350): an optional
121
- detail is a separate event, and any deviation is justified in the description. One data
121
+ detail is a separate event, and any deviation is justified in the event's `documentation`. One data
122
122
  subject per event; never personal data, a secret, or a `pii`/`secret` concept as
123
123
  identifier or subject (CHR0034, CHR0052, PLAY0515/0592). Use a surrogate identity
124
124
  and protected payload. A stream identity and an event's data subject may differ:
@@ -134,7 +134,7 @@ option, mark it `ASSUMED` in the slice or module `description` and in the sessio
134
134
  interface and processor inventory, one real interaction walked across each boundary, coupling
135
135
  check. Keep team, module, stream and deployment boundaries distinct; inbound facts via
136
136
  Translate; unresolved decisions stay visible.
137
- 7. **Record and gate.** Durable rationale in feature and slice `description`; open consistency
137
+ 7. **Record and gate.** Durable rationale in feature and slice `documentation`; open consistency
138
138
  decisions and capability gaps in `STATE.md`. Then the gate below.
139
139
 
140
140
  ## Rules
@@ -166,9 +166,10 @@ option, mark it `ASSUMED` in the slice or module `description` and in the sessio
166
166
  - Chronicle (open at v19.32.0): the SQL and InMemory providers do not settle unique claims
167
167
  (#3744); index updates run after commit and may fail silently (#4123); composite values can
168
168
  collide on the separator (#4131). A declared constraint is a declaration, not a runtime test.
169
- - `[ProtectedDecision]` is available in Arc v22.39.0 or later, **not** in Stage-rendered apps
170
- (Arc 22.25.0). In a rendered app, record the rule as NOT enforced and choose the stream or
171
- identity redesign (`references/consistency-and-concurrency.md`, section 3).
169
+ - `[ProtectedDecision]` is available in Arc v22.39.0 or later, including Stage 4.51.3's
170
+ rendered package set. It is not emitted protection: gap-fill must enroll an admitted
171
+ decision read, or redesign the stream/identity when the shape is refused
172
+ (`references/consistency-and-concurrency.md`, section 3).
172
173
 
173
174
  **Modeling defaults** (deviate with a recorded reason)
174
175
  - One business identity per stream; cross-stream references are payload properties.
@@ -204,8 +205,8 @@ option, mark it `ASSUMED` in the slice or module `description` and in the sessio
204
205
  Do not report done until all hold; otherwise report what is open:
205
206
  - Every identifier has its identity sentence, the event-membership table and a justified decision.
206
207
  - Every rule has an invariant-table row with an exact construct or limitation reference.
207
- - Every `recorded` rule is in its slice `description` and `STATE.md` with requirement, missing
208
- guarantee, race consequence and intended enforcement owner.
208
+ - Every `recorded` rule has its NOT-enforced marker in the slice `description`, and its requirement,
209
+ missing guarantee, race consequence and intended enforcement owner in the slice `documentation` and `STATE.md`.
209
210
  - Every changed event has compatibility scenarios; identity changes were made by the identity owner.
210
211
  - Every changed boundary has a named owner (or `ASSUMED`), callers, processors and contracts.
211
212
  - Verdicts are stated V1-V5 per `cratis-screenplay-modeling-lifecycle`, each a result or "not run".
@@ -33,7 +33,7 @@ exchange does not make that decision atomic.
33
33
  Run it when ownership, autonomy or integration decisions are missing; skip it when the user or
34
34
  the model already states all three. Ask one question at a time, offer the options, and follow
35
35
  the trigger. Unattended: assume the most conservative option, mark it `ASSUMED` in the slice or
36
- module `description` and in `STATE.md`.
36
+ module `description`, give the reason in its `documentation`, and add it to `STATE.md`.
37
37
 
38
38
  | # | Question (options) | Decides | Follow-up trigger |
39
39
  |---|---|---|---|
@@ -88,7 +88,7 @@ Processors: <trigger -> decision/effect -> result; operational owner>
88
88
  External: <system -> adapter owner -> contract>
89
89
  Open: <unresolved decisions, each also in STATE.md>
90
90
  ```
91
- Keep durable rationale in module, feature and slice descriptions and the record's `Open` lines in
91
+ Keep durable rationale in module, feature and slice `documentation` and the record's `Open` lines in
92
92
  `STATE.md`. Do not build a second catalogue that duplicates the model.
93
93
 
94
94
  ## Cross-boundary walkthrough
@@ -137,7 +137,7 @@ integration support.
137
137
  - Treat a public event like a published API: evolution follows `evolution.md` with the
138
138
  consumers named, and breaking changes become new events.
139
139
  - Screenplay has no public/internal marker. Record the classification in the event's
140
- `description`, and keep the list in `STATE.md`.
140
+ `documentation`, and keep the list in `STATE.md`.
141
141
 
142
142
  ## Crossing a boundary in Screenplay
143
143
  | Situation | Construct |
@@ -10,8 +10,9 @@ event-source id) are present. Three runtime defects are **open at v19.32.0**: #3
10
10
  InMemory providers do not settle unique claims), #4123 (constraint index updates run after commit
11
11
  and fail silently) and #4131 (composite unique constraints collide when a component contains the
12
12
  separator). Arc **v22.50.5** has `[ProtectedDecision]` (since v22.39.0, needs Chronicle 19.23 or
13
- later); Stage-rendered apps pin Arc 22.25.0 and Chronicle client 19.8.1, so it is not available
14
- there (see `consistency-and-concurrency.md` section 3). Re-check the issues before relying on a
13
+ later); Stage 4.51.3 rendered apps pin Arc 22.50.5 and Chronicle client/kernel
14
+ 19.32.0, so the APIs are available to gap-fill, not automatically emitted or
15
+ protected (see `consistency-and-concurrency.md` section 3). Re-check the issues before relying on a
15
16
  constraint in a new release.
16
17
  A concurrency scope's first append is unchecked by default at v19.32.0; see
17
18
  SKILL.md, ‘First append into a scope’.
@@ -71,7 +71,8 @@ Right: write the rule as stated intent and mark it unenforced.
71
71
  - `reads <View> as x by …` plus `require <expr over x> message "…"` on the command (the
72
72
  `StateChange` slice in `streams-example.md`). Binding reports PLAY0271 / PLAY0268; that is
73
73
  expected in design mode, so keep the lines. Do not remove them to pass a tool.
74
- - Slice `description`, one block per rule:
74
+ - Slice `description`: one short marker per rule, `NOT enforced in the model today; target: <mechanism>`.
75
+ - Slice fenced `documentation`, one block per rule:
75
76
  - Requirement: the business rule in business words.
76
77
  - Status: NOT enforced in the model today (Screenplay#129, #209).
77
78
  - Decision inputs: the authoritative facts or state.
@@ -108,15 +109,17 @@ example a course capacity computed from enrolment streams, needs option a or b:
108
109
  deciding fact on the source that owns the state, or give each scarce item its own identity. Sources: Arc `v22.50.5:Documentation/backend/csharp/chronicle/read-models/injecting-into-commands.md`;
109
110
  `chronicle-boundaries.md`.
110
111
 
111
- **Availability caveat for Stage-rendered applications.** `cratis render` scaffolds Arc 22.25.0 and
112
- Chronicle client 19.8.1 (Stage v4.24.0), which predate `[ProtectedDecision]` and `DecisionRead<T>`.
113
- In a rendered app that attribute is not available, so a gap-fill handler cannot use it unless the
114
- application's Arc and Chronicle packages are upgraded as a separately approved change. When they
115
- are not, choose option a or b (put the deciding fact on the stream that owns the state, or give
116
- each scarce item its own identity and claim it with a constraint), or option c, and keep the rule
117
- **NOT enforced in the model today** in the slice description with the race consequence. Never
118
- claim protection for a rendered app because the rule is written as `reads` + `require`, and never
119
- weaken the rule to make it render.
112
+ **Availability in Stage-rendered applications.** Stage v4.51.3 scaffolds Arc 22.50.5
113
+ and Chronicle client/kernel 19.32.0. `[ProtectedDecision]` and `DecisionRead<T>` /
114
+ `IDecisionReads` exist in that package set; source checks are in
115
+ `cratis-stage-rendering-and-sandbox` `references/rendered-application.md`.
116
+ This does not mean Stage emits protected decisions. Gap-fill must opt into the
117
+ protected command profile, use an admitted projection/key shape and enroll the
118
+ read in the active unit of work. For refused shapes choose option a/b (state on
119
+ its owning stream or one identity per scarce item), or agreed compensation c.
120
+ Keep the rule **NOT enforced in the model today** with its race consequence.
121
+ Never infer protection from `.play` `reads` + `require`, weaken the rule to render,
122
+ or edit managed dependency files. Older Stage 4.24.x scaffolds predate these APIs.
120
123
 
121
124
  ## 4. Concurrency scenarios
122
125
  For each enforced or recorded rule write three short scenarios:
@@ -153,7 +156,7 @@ The append may commit while the reply is lost. The caller retries. Decide per co
153
156
  rejection the caller must see; never report it as success;
154
157
  - **new identifier** -> duplicate unless a business-key constraint exists.
155
158
  The model shows only the rejection; payload comparison and outcome replay are target
156
- behaviour. Write the answer in the slice `description`.
159
+ behaviour. Write the answer in the slice `documentation`.
157
160
 
158
161
  ## 7. Ordering
159
162
  - Within one source, facts are in append order. Across sources, do not assume an order
@@ -16,7 +16,7 @@ compatibility scenarios below first; the identity owner then applies the change
16
16
 
17
17
  | Change | Old facts still mean the same? | Screenplay action | Edit class |
18
18
  |---|---|---|---|
19
- | add a property with a business-defined value for old facts | yes | new `generation N+1`, every generation declared in full in the same slice; record the default for old facts in the slice `description` | contract evolution |
19
+ | add a property with a business-defined value for old facts | yes | new `generation N+1`, every generation declared in full in the same slice; record the default and its reason for old facts in slice `documentation` | contract evolution |
20
20
  | add a property with no sensible old value | the old fact lacks information | usually a **new event** for the new situation, or a separate fact recording the extra information | review with the expert |
21
21
  | remove a property | yes, if no reader needs it | new generation without it; every reference fails with PLAY0273 until removed | contract evolution, check readers |
22
22
  | change meaning (same name, different business fact) | **no** | **new event** with its own name; old event stays for history | identity: add, not rename |
@@ -28,7 +28,7 @@ A test for "generation or new event": a new version must be convertible from the
28
28
  without inventing facts. If it is not, it is a different event.
29
29
 
30
30
  ## Compatibility scenarios (write before editing)
31
- For each changed event, answer in the slice `description` or `STATE.md`:
31
+ For each changed event, answer in the slice `documentation` or `STATE.md`:
32
32
  1. **Replay**: does every projection still build from generation 1 facts? Which value do old
33
33
  facts give the new property (default, absent, derived)?
34
34
  2. **Readers**: which projections, reactions, constraints, specifications and other modules
@@ -5,6 +5,8 @@
5
5
  - Warnings that hide defects (always validate with `--warnings-as-errors`)
6
6
  - Source reference and identifier checks
7
7
  - Caller identity, compliance and routes
8
+ - Specification metadata, callers, cases and locators
9
+ - Guarded interaction diagnostics
8
10
  - Structural completeness and timeline checks
9
11
  - Editor versus C# verdicts
10
12
  - Consistency errors (V1: the model contradicts itself)
@@ -111,6 +113,52 @@ concept-subject, line-only `PreserveTrivia` repair, no document-root or pinned
111
113
  repair evidence. PLAY0565 supports one discovered `line` or a document-root
112
114
  migration. Preview every repair; legal notes never move automatically.
113
115
 
116
+ ## Specification metadata, callers, cases and locators
117
+
118
+ Authority: Screenplay v4.127.0 `diagnostics.md`, `specifications.md`, `slices.md`.
119
+
120
+ | Code | Severity | Meaning / fix |
121
+ | --- | --- | --- |
122
+ | PLAY0558 | E | Module/feature/slice/command/read-model/reaction documentation must be one nonempty fenced Markdown block; remove repeats or fix the fence. Events retain PLAY0477. |
123
+ | PLAY0559 | W | Conflicting module/feature documentation across files; first wins. Choose one owning text; identical copies are accepted. |
124
+ | PLAY0572 | E | Malformed/unknown persona caller or body lines; use a declared top-level persona with no body. |
125
+ | PLAY0573 | E (binding) | Persona synthesis refused (no policies, negation, required non-literal/role-URI claim, opaque or unresolved policy); inspect persona/policy/reason and use explicit `given caller`. |
126
+ | PLAY0574 | W | Opt-in `personas`: persona gates nothing. |
127
+ | PLAY0575 | W | Opt-in `personas`: gate denies every synthesized persona; unknown is not denial. |
128
+ | PLAY0576 | I | Opt-in `personas`: multiple unpinned buildable `or` alternatives; inspect chosen witness or pin a policy. |
129
+ | PLAY0577/0578 | E | Malformed parameter/case header; typed parameter has no body/default, case has a name and at most one inline assignment. |
130
+ | PLAY0579/0580 | E | Duplicate parameter/case name. |
131
+ | PLAY0581/0582 | E | Need parameters and cases; every case assigns each parameter exactly once, no extra names. |
132
+ | PLAY0583 | E | Case value is not concrete or cannot normalize to its type. |
133
+ | PLAY0584 | E | Unknown parameter or excluded reference position (callers/redelivery locators/clocks/names/nested literal members). |
134
+ | PLAY0585 | E | Optional parameter feeds required target. |
135
+ | PLAY0586 | E | Derived `<Specification>_<Case>` collides in scope. |
136
+ | PLAY0587 | E | Unknown or incompatible parameter/target type. |
137
+ | PLAY0588 | W | Unused parameter; remove it or use it intentionally. |
138
+ | PLAY0589 | E | Singular effective expansion cannot handle a table; use `ExpandAll`. |
139
+ | PLAY0526 | E | Route in command/read-model example; only event examples carry routes. Top-level `streamId = value` is payload. |
140
+ | PLAY0543 | E | Malformed redelivery or not exactly one definite match with no undecided candidate; narrow `for`, values, `stream` or `no stream`. |
141
+ | PLAY0548 | E | Route on `when <Command>` only; put it on the command declaration. Does not fire on redelivery locators. |
142
+
143
+ Descriptions/documentation are report-only PLAY0270, not executable conditions.
144
+ Case tables and persona callers expand before binding without a new ESM version.
145
+ Routes do not make redelivery executable: it still reports PLAY0268.
146
+
147
+ ## Guarded interaction diagnostics
148
+
149
+ | Code | Severity | Meaning / fix |
150
+ | --- | --- | --- |
151
+ | PLAY0560 | E | Alternatives on a non-item trigger; only click/double click/select admit them. |
152
+ | PLAY0561 | E | Alternatives mixed with plain actions or `where`; choose one form. |
153
+ | PLAY0562 | E | Empty branch; supply a nonempty action list. |
154
+ | PLAY0563 | E | One-line labeled-action `when … execute …` in an interaction; use an indented list. C# offers a typed repair. |
155
+ | PLAY0564 | W/I | Item-trigger opaque `where` deprecated: a strict item condition warns with a C# repair to one `when`, no fallback; other text is information with no repair. Other triggers unchanged. |
156
+
157
+ PLAY0563/0564 repairs need individual review and canonical formatting, refuse
158
+ comment loss and do not support pinned evidence. TypeScript diagnoses but does
159
+ not offer these repairs. Preview through MCP `propose-repair`, never text-patch
160
+ around a refusal. Condition/subject errors also use guarded-action PLAY0341–0348.
161
+
114
162
  ## Structural completeness and timeline checks
115
163
 
116
164
  Opt in with `--check <names>` or MCP diagnostics `checks`, then treat warnings
@@ -126,6 +174,7 @@ as errors if gating. Ordinary compile success does not imply these ran:
126
174
  | navigation | PLAY0537 | Unreachable screens; unreachable cycles do not establish an entry point |
127
175
  | privilege | PLAY0652 | Elevated event-trigger producers must require every actor role; opaque gates are information, clock/application triggers exempt |
128
176
  | purposes | PLAY0602–0606 | Personal-data coverage, special/criminal safeguards, basis and unused-purpose prompts; union of ancestor/direct references |
177
+ | personas | PLAY0574–0576 | Unused personas, unreachable gates and ambiguous buildable policy alternatives; unsynthesizable/undecidable is unknown |
129
178
 
130
179
  Whole-source errors skip completeness checks. Unknown/opaque coverage is not
131
180
  invented: report skipped status/coverage and walk field lineage manually.
@@ -96,9 +96,12 @@ legacy ids or drop protected ids into routing to fit a renderer (PLAY0515).
96
96
  `Customizations/styles.css`. The planner never reads it, and it never binds a modeled
97
97
  reaction or capture. A customization never makes a rejected model renderable.
98
98
  - `cratis render` does **not** build, test or run the application.
99
- - The scaffold pins .NET 10, Arc 22.25.0, Chronicle 19.8.1 and emits a `.frontend/` React/Vite
100
- app (Components 4.14.0, Scene 4.2.0). `Directory.Packages.props` is Stage-managed: do not
101
- edit it. `[ProtectedDecision]` (Arc v22.39.0) is not available in a rendered application.
99
+ - Stage 4.51.3's scaffold pins .NET 10, Arc 22.50.5, Chronicle client/kernel 19.32.0
100
+ and emits a `.frontend/` React/Vite app (Components 4.14.0, Scene 4.10.0).
101
+ `CratisEmbeddedScreenplayEnabled=false`; `Directory.Packages.props` is managed,
102
+ never edit it. `[ProtectedDecision]` / `DecisionRead<T>` are available to gap-fill,
103
+ not Stage-emitted enforcement; projection/key admission and unit-of-work enrollment
104
+ remain required. Source checks: Stage skill `references/rendered-application.md`.
102
105
 
103
106
  ## Reading V5
104
107
 
@@ -29,7 +29,7 @@ exact numbers are documented in the grammar. Compiler syntax: `cheat-sheet.md`.
29
29
  21. Quoted `import "x/*.play"` = my files; unquoted `import Ctx.Event` = another context's contract (does not bind: PLAY0268). [probed]
30
30
  22. Construct keywords are closed (`aggregate`, `saga`, `workflow` do not exist): PLAY0029 or PLAY0001/0022/0024.
31
31
  23. `@` escapes are mandatory for `tag`, `authorize`, `produces`, `reads`, `file`, `validate`, `sequence`, `occurred`, `causedBy`, `namespace`, `correlation`, `causation`, and projection `key`/`parent`/`with` as names.
32
- 24. Comments do not survive canonicalizing edits (PLAY0288 reprint; `droppedCommentCount`); keep durable rationale in `description` text, not `//`.
32
+ 24. Canonicalizing edits can drop unplaceable comments (PLAY0288; inspect `droppedCommentCount`); keep durable rationale in fenced Markdown `documentation`, not `//`, and summaries in `description`. Documentation survives canonical printing but changes neither executable bytes nor `modelRevision`; it is not rendered code.
33
33
  25. MCP writes: propose, review, approval, apply by the identity owner (the session that owns the MCP connection); other subagents return edit requests; proposals are connection-local, at most 16 (`cratis-screenplay-model-authoring`).
34
34
  26. Operations/systems and exact numbers remain unadmitted. Sources/streams/routes bind and reference-execute as ESM v8 at 4.125.0; generated values/responses bind as v7. CLI 3.41.0 renders through v7 only, with construct-specific Stage refusals. Consult released grammar rather than inventing syntax from decisions.
35
35
  27. Translate vs Automation is semantic: external facts become local facts in `Translate`; in-app event-to-event goes in `Automation`.
@@ -43,8 +43,8 @@ exact numbers are documented in the grammar. Compiler syntax: `cheat-sheet.md`.
43
43
  34. A `from <Event> key <property>` routes only if every such event carries that property: an event that frees or updates a row keyed by another stream's id must carry that id in its payload, or the row never changes. Whether the compiler reports a missing key property is unverified [to probe]; check by hand.
44
44
  35. `description`/`documentation` are authoring metadata: board, MCP and Prologue show them; `cratis render` never does (Stage#178). A rule only in prose is unenforced in rendered code; make it a rule layer, a spec or a recorded target requirement.
45
45
  36. One unadmitted construct (operations, exact numbers, refusal/redelivery) blocks whole-model binding. Routing is admitted v8, not one of those constructs; CLI render's v7 boundary is a separate refusal. Do not remove routing or authorization to render a model.
46
- 37. Personas are not in the ESM (Screenplay#254); specs cannot reference them. Write `given caller` as the roles/claims that stand for the persona.
47
- 38. A rule that depends on stored state is `reads <View>` + `require <expr> message "..."` (stated intent; PLAY0268/0271 at binding are expected in design mode). The slice `description` must mark it NOT enforced in the model today (Screenplay#129/#209) and name the target: Arc `[ProtectedDecision]` + `DecisionRead<T>` (Arc v22.39.0 and later; not available in a Stage-rendered app on Arc 22.25.0), Chronicle DCB (`concurrency` scope), or a constraint where one fits. Forbidden: caller-supplied copies of state in `require`, boolean attestation inputs (`confirmsX == true`), rules hidden in `handler`/implementation-hint prose. An unguarded materialized read is unsafe for a protected decision.
46
+ 37. Personas remain outside ESM bytes, but 4.127.0 specifications accept `given caller as <Persona>`: one authenticated deterministic policy witness, not every matching caller. Inspect the chosen `or` branch; use explicit callers when synthesis is refused.
47
+ 38. A rule that depends on stored state is `reads <View>` + `require <expr> message "..."` (stated intent; PLAY0268/0271 at binding are expected in design mode). The slice `description` must mark it NOT enforced in the model today (Screenplay#129/#209) and name the target: Arc `[ProtectedDecision]` + `DecisionRead<T>` (Arc v22.39.0 and later; available to gap-fill on Stage 4.51.3's Arc 22.50.5/Chronicle 19.32.0, not emitted protection), Chronicle DCB (`concurrency` scope), or a constraint where one fits. Forbidden: caller-supplied copies of state in `require`, boolean attestation inputs (`confirmsX == true`), rules hidden in `handler`/implementation-hint prose. An unguarded materialized read is unsafe for a protected decision.
48
48
 
49
49
  Current identity/compliance traps (v4.127.0 `identity.md`, `concepts.md`, `events.md`,
50
50
  `purposes.md`, `diagnostics.md`):
@@ -69,4 +69,4 @@ The SKILL.md top 12: 1, 4, 5, 6, 7, 10, 12, 13, 17, 18, 20, 21 (+ mode/version n
69
69
  41. MCP roots bug (4.63.1 and earlier, including the 4.60.1 bundled by cratis before 3.28.2; not present in 4.66.0 or cratis 3.28.2, probed): a dynamic-root server answers the roots request with an `id: null` error right after `notifications/initialized`; hosts treat it as fatal. `open-workspace.path` does not help. Start with a fixed root (`screenplay mcp <folder>`, `cratis screenplay mcp` in a project with `.cratis/ai.json`) or use 4.63.2 or later (cratis 3.28.2 or later). [source, probed]
70
70
  42. A symlinked model path is refused by the MCP server (macOS `/tmp` is a symlink); pass the physical path. Proposals are connection-local (at most 16); `apply` persists identities to `.screenplay/identities.json` and is not crash-atomic across files; never retry `apply` after `ApplyOutcomeUnknown`. [source]
71
71
  43. `modelRevision` is canonical semantic (line positions and descriptions do not change it; a file move only if it changes logical placement or application identity) and, without `identities.json`, changes with the root folder name; it is not comparable with a render's `semanticRevision`. Source identity for verdicts is the commit plus the digest from the source-identity helper (`cratis-screenplay-modeling-lifecycle` `references/verdicts-and-modes.md` "Source identity"). [probed]
72
- 44. `cratis render` neither builds nor tests; `--name` is required for plain source; `.cratis-render/` is control state and is never staged; Stage-rendered apps are on Arc 22.25.0 (no `[ProtectedDecision]`). `cratis` file mode versus folder mode (trap 6) and a stale `cratis` on `PATH` (`which -a cratis`) both silently change what a verdict means. [source]
72
+ 44. `cratis render` neither builds nor tests; `--name` is required for plain source; `.cratis-render/` is control state and is never staged; Stage 4.51.3 rendered apps pin Arc 22.50.5/Chronicle 19.32.0 (`[ProtectedDecision]` available to gap-fill, not automatically emitted). `cratis` file mode versus folder mode (trap 6) and a stale `cratis` on `PATH` (`which -a cratis`) both silently change what a verdict means. [source]
@@ -23,6 +23,7 @@ probe; older probes retain their original labels in the other references.
23
23
  | Stage bundled by CLI | **4.51.3** | Same file; the CLI's runtime image follows its Stage package version |
24
24
  | Cratis.Arc.Screenplay bundled by CLI | **22.54.0** | Same file; this is the generator package, not a blanket rendered-app dependency pin |
25
25
  | Chronicle / Fundamentals bundled by CLI | **19.32.0 / 7.22.8** | Same file |
26
+ | Stage 4.51.3 rendered backend | **Arc 22.50.5 / Chronicle 19.32.0** | Stage `v4.51.3:Source/Rendering.Cratis/Scaffolding/CratisBackendApplicationScaffoldProfile.cs`; client/testing/image match; scaffold disables embedded reverse extraction |
26
27
 
27
28
  Check the actual executable before relying on this table: `screenplay --version`,
28
29
  `cratis --version`, MCP `initialize` → `serverInfo.version`. An older executable
@@ -93,6 +94,15 @@ PLAY0565 information, duplicates warn PLAY0653. Event `subject` and processing
93
94
  purposes are report-only metadata (PLAY0270); purpose checks/reports do not prove
94
95
  lawfulness or enforce retention. See command-surface context/compliance references.
95
96
 
97
+ Authoring features source-checked in standalone 4.127.0: `propose-source`,
98
+ `find-specification-obligations`, `find-modeling-smells`, specification descriptions,
99
+ container/command/read-model/reaction documentation, routed redelivery locators,
100
+ guarded item interactions, persona callers and named case tables. Discover schemas
101
+ in the older CLI bundle rather than assuming parity. Cases/persona callers expand
102
+ to ordinary ESM; metadata changes no executable bytes. Redelivery remains
103
+ unadmitted even when its route is valid. Details: model-authoring MCP references,
104
+ specifications, UI composition and `diagnostics.md`.
105
+
96
106
  ## Historical probes
97
107
 
98
108
  - Screenplay 4.68.0 admitted v7; CLI 3.28.2/3.28.3 bundled 4.66.0 (v6 at most),
@@ -240,8 +240,10 @@ acts. Three words carry it:
240
240
  | **Action** | a closed set: `execute`, `navigate to`/`navigate back`, `open dialog`/`close dialog`, `refresh`, `set … to`, `notify`, `confirm`, `raise` |
241
241
  | **Behavior** | a bundle of trigger-to-action bindings; inline (`on …`) or named (`behavior` + `uses`) |
242
242
 
243
- A complete example — a named behavior with parameters, attached with `uses`, and
244
- an inline `on` block with a continuation:
243
+ Guarded alternatives and `where` deprecation:
244
+ [guarded interactions](references/guarded-interactions.md).
245
+
246
+ Complete named/inline behavior example:
245
247
 
246
248
  ```screenplay
247
249
  concept InvoiceId : Uuid
@@ -0,0 +1,71 @@
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
+ # Choose a gesture's whole action list
5
+
6
+ `on click`, `on double click` and `on select` accept ordered block-form `when`
7
+ alternatives and an optional final `otherwise`. Use the same strict condition
8
+ language and data-item subject as [guarded screen actions](../../cratis-screenplay-read-surface/references/guarded-actions.md):
9
+ `item.<path>` compared with a literal, joined by `and`, `or` and parentheses.
10
+ At least one `when` and a nonempty action list in every branch are required.
11
+ Do not mix alternatives with plain actions or `where`; a one-line
12
+ `when … execute …` belongs to labeled actions, not interactions.
13
+
14
+ This complete model validates on standalone Screenplay 4.127.0:
15
+
16
+ ```screenplay
17
+ module Billing
18
+ feature Invoices
19
+ slice StateView InvoiceHistory
20
+ event InvoiceRecorded
21
+ status String
22
+ readmodel InvoiceView
23
+ invoiceId String
24
+ status String
25
+ projection Invoices => InvoiceView
26
+ from InvoiceRecorded
27
+ invoiceId = $eventSourceId
28
+ status = status
29
+ query InvoiceById => InvoiceView optional
30
+ by invoiceId String
31
+ screen InvoiceDetails
32
+ data InvoiceView via query InvoiceById by invoiceId
33
+ table InvoiceView
34
+ column status
35
+ on double click
36
+ when item.status == "draft"
37
+ notify info "The draft can be edited"
38
+ refresh InvoiceById
39
+ otherwise
40
+ notify info "Only drafts can be edited"
41
+ ```
42
+
43
+ The first matching branch runs once on the rendered item at gesture time, without
44
+ refetch or re-evaluation while its list runs. No match uses fallback or does
45
+ nothing; **no subject does nothing, including fallback**. Failure, denial or an
46
+ unavailable command never falls through; backend commands retain their rules.
47
+ Unlike labeled actions, no choice was displayed beforehand to refresh at click.
48
+
49
+ A table click/double click uses the activated row; select uses the newly selected
50
+ item, and clearing selection runs nothing. Elsewhere use the nearest enclosing
51
+ single item or selected row, with guarded actions' sibling precedence. Check named
52
+ behaviors at each `uses` site. Component `context` or `selectedItem` bindings do
53
+ not supply the subject in this version; unresolved/equally near subjects report
54
+ PLAY0346.
55
+
56
+ Submit, event, change, interval and application triggers have no alternatives.
57
+ The one-line `on row-click navigate to … by …` remains unchanged. Opaque `where`
58
+ on click/double click/select is deprecated (PLAY0564): strict item conditions warn
59
+ and C# offers a typed repair to one `when` with no fallback; other guard text is
60
+ Information without repair. Other triggers' `where` remains unchanged. Repairs
61
+ require individual review, canonical formatting, preserve comments and refuse
62
+ comment loss; TypeScript diagnoses but offers no repair. PLAY0563 has a C# repair
63
+ expanding a one-line alternative to the block form. Neither repair supports
64
+ pinned evidence.
65
+
66
+ UI is deferred from backend ESM (PLAY0269), not executable gesture proof. The
67
+ board draws a static prototype; renderers must explicitly admit alternatives or
68
+ report unsupported, never flatten them into plain actions.
69
+
70
+ Authority: Screenplay v4.127.0 `interactions.md`, `diagnostics.md`,
71
+ `mcp/authoring-tools.md`; decision 0048.