@cratis/pi 6.1.0 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/SKILL.md +90 -15
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/verification.json +5 -1
- package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +162 -64
- package/package/corpus/skills/cratis-screenplay-command-surface/references/context.md +20 -8
- package/package/corpus/skills/cratis-screenplay-command-surface/verification.json +33 -1
- package/package/corpus/skills/cratis-screenplay-event-modeling/SKILL.md +63 -31
- package/package/corpus/skills/cratis-screenplay-event-modeling/references/nine-steps.md +35 -13
- package/package/corpus/skills/cratis-screenplay-event-modeling/verification.json +12 -0
- package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +50 -9
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/language-reference.md +78 -22
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +21 -5
- package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +16 -0
- package/package/corpus/skills/cratis-screenplay-projections/SKILL.md +155 -43
- package/package/corpus/skills/cratis-screenplay-projections/references/pdl-grammar.md +81 -37
- package/package/corpus/skills/cratis-screenplay-projections/verification.json +6 -1
- package/package/corpus/skills/cratis-screenplay-read-surface/SKILL.md +64 -17
- package/package/corpus/skills/cratis-screenplay-read-surface/verification.json +4 -1
- package/package/corpus/skills/cratis-screenplay-specifications/SKILL.md +201 -115
- package/package/corpus/skills/cratis-screenplay-specifications/verification.json +13 -1
- package/package/corpus/skills/cratis-screenplay-ui-composition/SKILL.md +133 -24
- package/package/corpus/skills/cratis-screenplay-ui-composition/verification.json +4 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"skill": "cratis-screenplay-command-surface",
|
|
3
|
-
"input": "Declare a Screenplay command with validation, authorization and
|
|
3
|
+
"input": "Declare a Screenplay command with validation, authorization, a uniqueness constraint and a state-dependent rule.",
|
|
4
4
|
"fixtures": [],
|
|
5
5
|
"assertions": [
|
|
6
6
|
{
|
|
@@ -26,6 +26,38 @@
|
|
|
26
26
|
{
|
|
27
27
|
"kind": "skill-contains",
|
|
28
28
|
"value": "`identifier` on an **event** property is an error"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"kind": "skill-contains",
|
|
32
|
+
"value": "`reads` is not a protected read"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"kind": "skill-contains",
|
|
36
|
+
"value": "Adding a\n`concurrency` block does not fix this"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"kind": "skill-contains",
|
|
40
|
+
"value": "Validation severity is not compiler severity"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"kind": "skill-contains",
|
|
44
|
+
"value": "Chronicle's constraints enforce **uniqueness only**"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"kind": "skill-contains",
|
|
48
|
+
"value": "Do not use `constraint … file <Path>` for other rules"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"kind": "skill-contains",
|
|
52
|
+
"value": "combine with AND, in authored"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"kind": "skill-contains",
|
|
56
|
+
"value": "(`PLAY0441`)"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"kind": "skill-contains",
|
|
60
|
+
"value": "never both (`PLAY0440`)"
|
|
29
61
|
}
|
|
30
62
|
]
|
|
31
63
|
}
|
|
@@ -32,11 +32,14 @@ source is the single flow model.
|
|
|
32
32
|
|
|
33
33
|
| Package | Version | Purpose |
|
|
34
34
|
| --- | --- | --- |
|
|
35
|
-
| `Cratis.Screenplay` | `4.
|
|
36
|
-
| `Cratis.Screenplay.Tool` | `4.
|
|
35
|
+
| `Cratis.Screenplay` | `4.31.0` | Compiler: parser, validator, diagnostics, folder merge, semantic binder |
|
|
36
|
+
| `Cratis.Screenplay.Tool` | `4.31.0` | The `screenplay` dotnet tool |
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
Checked against the Screenplay repository at tag `v4.31.0` (commit `355dffb`):
|
|
39
|
+
`Documentation/screenplay/{slices,commands,folders,printing,interactions,specifications}.md`,
|
|
40
|
+
`projections/keys.md`, and decisions 0001 to 0014. The examples in
|
|
41
|
+
[nine-steps.md](references/nine-steps.md) compile with that version's compiler.
|
|
42
|
+
Reverify before claiming another version behaves the same.
|
|
40
43
|
|
|
41
44
|
> **Method lineage.** The two-phase process, the nine steps, the four patterns and
|
|
42
45
|
> the GWT discipline follow **Event Modeling** (Adam Dymitruk; Martin Dilger,
|
|
@@ -83,9 +86,9 @@ Every behavior is exactly one. An unknown slice type is a compile error:
|
|
|
83
86
|
appear as many times as the behavior needs. Only `description` is limited to one.
|
|
84
87
|
|
|
85
88
|
**Automation has four required components** — a triggering occurrence, the state
|
|
86
|
-
it consults, conditional logic, and a resulting command
|
|
87
|
-
are always unconditionally co-produced, it is **not** an
|
|
88
|
-
one `StateChange` slice with several `produces` blocks.
|
|
89
|
+
it consults (the trigger's `reads`), conditional logic, and a resulting command
|
|
90
|
+
or event. If the events are always unconditionally co-produced, it is **not** an
|
|
91
|
+
automation: model it as one `StateChange` slice with several `produces` blocks.
|
|
89
92
|
|
|
90
93
|
**Translation is workflow-specific anti-corruption.** Generic infrastructure every
|
|
91
94
|
workflow needs (event persistence, message transport) is not a `Translate` slice.
|
|
@@ -96,11 +99,16 @@ Two divergences matter, and getting them wrong produces a model that will not
|
|
|
96
99
|
compile or will not be safe. Both are deliberate.
|
|
97
100
|
|
|
98
101
|
- **A command may read state.** The generic method forbids `ReadModel → Command`
|
|
99
|
-
edges. Screenplay ships `reads <ReadModel> [by <property>]`
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
edges. Screenplay ships `reads <ReadModel> [as <alias>] [by <property>]` so the
|
|
103
|
+
model shows what a state-dependent decision consulted. **It is not a protected
|
|
104
|
+
read today:** nothing checks at append time that the state is still current,
|
|
105
|
+
the executable model rejects `reads` and `concurrency` (`PLAY0271`), and adding
|
|
106
|
+
`concurrency` does not make the decision safe (decision 0003, Screenplay #129).
|
|
107
|
+
Model uniqueness as a `unique` constraint; for any other state-dependent rule,
|
|
108
|
+
record that the target must enforce it consistently. Do not use `reads` to
|
|
109
|
+
fetch data the command could carry as input. A reaction trigger declares the
|
|
110
|
+
views an automation decides from with the same `reads`, and the same caveat
|
|
111
|
+
applies.
|
|
104
112
|
- **Some validation *does* belong in the model.** The generic method routes format
|
|
105
113
|
rules to the type system. Screenplay's type system *is* the `concept`, and a
|
|
106
114
|
concept carries its own `validate` block — so a format rule lives on the concept
|
|
@@ -122,7 +130,7 @@ compile or will not be safe. Both are deliberate.
|
|
|
122
130
|
`Created`. One purpose per event; an event needing an optional property to cover
|
|
123
131
|
two situations is two events.
|
|
124
132
|
- **The event-source identity is never an event property.** The command binds it
|
|
125
|
-
with `identifier` on
|
|
133
|
+
with `identifier` on at most one property; marking an *event* property
|
|
126
134
|
`identifier` is an error: *an event never carries its event source id*.
|
|
127
135
|
- **Domain facts, not runtime context.** Test: would this field have the same value
|
|
128
136
|
if the event were replayed on a different machine? If not, it does not belong.
|
|
@@ -170,8 +178,13 @@ produced in another resolves. Compiling files individually reports unknown types
|
|
|
170
178
|
events and policies (`PLAY0165`, `PLAY0166`, `PLAY0167`) that are not missing.
|
|
171
179
|
Duplicates *across* files are real errors naming both ends (`PLAY0172`, `PLAY0173`).
|
|
172
180
|
|
|
173
|
-
Round-tripping a folder does not preserve
|
|
174
|
-
|
|
181
|
+
Round-tripping a folder does not preserve the order of **modules, features and
|
|
182
|
+
slices**: they come back sorted by name, and members of one module or feature
|
|
183
|
+
that come from different files print in canonical kind order. Order *within* one
|
|
184
|
+
file is kept, and some order carries meaning: `authorize` gates and policy
|
|
185
|
+
operands evaluate left to right, and specification events compare in authored
|
|
186
|
+
order unless `then events in any order` is stated. Never encode meaning in the
|
|
187
|
+
order of modules, features or slices.
|
|
175
188
|
|
|
176
189
|
## Verify
|
|
177
190
|
|
|
@@ -188,26 +201,45 @@ screenplay .cratis/screenplay/ --warnaserror
|
|
|
188
201
|
- [ ] Personal data is classified on the `concept`, with a reason.
|
|
189
202
|
- [ ] Specifications name the rejections, not only the happy path.
|
|
190
203
|
- [ ] If the model must reach a runtime, every slice is `StateChange` or
|
|
191
|
-
`StateView` and
|
|
204
|
+
`StateView` and binds to the executable model (below).
|
|
192
205
|
|
|
193
206
|
## Parsed is not runnable
|
|
194
207
|
|
|
195
208
|
The compiler accepts far more than anything executes. Between the syntax tree and
|
|
196
|
-
any runtime sits the **executable semantic model (ESM
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
209
|
+
any runtime sits the **executable semantic model (ESM)**, and it fails closed:
|
|
210
|
+
what it cannot represent reports `PLAY0268` or `PLAY0271` and the model does not
|
|
211
|
+
bind. Keep four states apart when you report on a model: **parsed** (the
|
|
212
|
+
`screenplay` tool), **bound** (ESM), **reference-executed** (specifications pass
|
|
213
|
+
the reference runner) and **target-executed** (Stage or a rendered application).
|
|
214
|
+
|
|
215
|
+
The ESM version follows from what the model uses: v1 by default, v2 for typed
|
|
216
|
+
event-source facts (`produces … for <identifier>` when the event does not repeat
|
|
217
|
+
the identifier, `for` values in specifications, and `$context.occurred` or caller
|
|
218
|
+
identity in `produces`), v3 for code the model hands off (bodied reducers, code
|
|
219
|
+
validation, code policies). Code binds as an opaque requirement; the reference
|
|
220
|
+
runner reports any specification that needs it as unsupported.
|
|
221
|
+
|
|
222
|
+
For event modeling, the consequential boundaries today are:
|
|
223
|
+
|
|
224
|
+
- `Automation` and `Translate` slices, reactions, captures and triggers do not
|
|
225
|
+
bind: *Slice '<name>' of type '<type>' is not admitted by ESM v1.*
|
|
226
|
+
- `reads` and `concurrency` do not bind (`PLAY0271`), so no decision is protected
|
|
227
|
+
against stale state.
|
|
228
|
+
- `persona` and `@pii`/`@sensitive` concepts do not bind yet. Keep them: the
|
|
229
|
+
classification is part of the model.
|
|
230
|
+
- UI constructs are deferred with information `PLAY0269`; they never block.
|
|
231
|
+
|
|
232
|
+
The full disposition table is in the `cratis-screenplay-model-authoring` language
|
|
233
|
+
reference. Model the wider language freely when the `.play` file **is** the
|
|
234
|
+
deliverable — documentation, review, a shared description of a system. Never
|
|
235
|
+
read a clean `screenplay` run as evidence a construct works downstream.
|
|
236
|
+
|
|
237
|
+
Decision 0006 shipped in Screenplay 4.31.0: a reaction trigger can declare the
|
|
238
|
+
views it decides from with `reads` (see `cratis-screenplay-captures-and-reactions`),
|
|
239
|
+
but nothing enforces them yet. Decisions 0007 to 0014 (affected read-model
|
|
240
|
+
instances, one data subject per event, external event origin, query paging and
|
|
241
|
+
live change sets, event generations, typed context descriptors) are accepted but
|
|
242
|
+
**not available**. Do not write their syntax; note the need in prose instead.
|
|
211
243
|
|
|
212
244
|
## Route near misses
|
|
213
245
|
|
|
@@ -18,7 +18,8 @@ module Invoicing
|
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
`description` is the optional **first body line** of a module, feature, slice,
|
|
21
|
-
persona or command; at most one. Use a fenced ```
|
|
21
|
+
persona or command; at most one. Use a fenced block tagged ` ```text ` when one line
|
|
22
|
+
is not enough (a bare fence warns with `PLAY0397`).
|
|
22
23
|
|
|
23
24
|
## Step 2 — Brainstorm events
|
|
24
25
|
|
|
@@ -39,8 +40,8 @@ does not belong in an event.
|
|
|
39
40
|
Arrange into the timeline — the plot. *"What happens first? And then what
|
|
40
41
|
happens?"* Identify the happy path **and** the alternative and error paths.
|
|
41
42
|
|
|
42
|
-
**Output:** the order the slices will be written in.
|
|
43
|
-
|
|
43
|
+
**Output:** the order the slices will be written in. A folder round-trip sorts
|
|
44
|
+
modules, features and slices by name, so the timeline is documentation, not
|
|
44
45
|
structure.
|
|
45
46
|
|
|
46
47
|
## Step 4 — Create wireframes
|
|
@@ -48,7 +49,7 @@ structure.
|
|
|
48
49
|
These need not be the real UI. Their purpose is a complete accounting of what a
|
|
49
50
|
user can **see** and what they can **do** at each interaction point.
|
|
50
51
|
|
|
51
|
-
```
|
|
52
|
+
```text
|
|
52
53
|
+-------------------------------+
|
|
53
54
|
| Register Invoice |
|
|
54
55
|
+-------------------------------+
|
|
@@ -67,7 +68,11 @@ input** (something provided). If you cannot trace a field, something is missing.
|
|
|
67
68
|
same time?"* If yes, the wireframe shows a list or table, not a single-item view.
|
|
68
69
|
|
|
69
70
|
**Output:** the `screen` declarations, at Level 1 (intent) for now —
|
|
70
|
-
`data <ReadModel> via query <Query>` plus `action <Command>`.
|
|
71
|
+
`data <ReadModel> via query <Query>` plus `action <Command>`. When the wireframe
|
|
72
|
+
says what a click, submit or screen entry *does* (confirm, refresh, navigate,
|
|
73
|
+
open a dialog), capture it as an `on` block or a named `behavior` attached with
|
|
74
|
+
`uses` — see `cratis-screenplay-ui-composition`. An `action` alone does not say
|
|
75
|
+
what happens afterwards.
|
|
71
76
|
|
|
72
77
|
## Step 5 — Identify commands
|
|
73
78
|
|
|
@@ -77,8 +82,10 @@ did they provide? Under what circumstances would this NOT happen?"*
|
|
|
77
82
|
Commands are imperative and present tense: `RegisterInvoice`, `ProcessPayment`.
|
|
78
83
|
**Commands can fail; events cannot.**
|
|
79
84
|
|
|
80
|
-
**Output:** the `command` declaration with its properties,
|
|
81
|
-
|
|
85
|
+
**Output:** the `command` declaration with its properties, its `identifier`
|
|
86
|
+
property (at most one; leave it out only when the runtime should allocate a new
|
|
87
|
+
identity), `authorize`, and `produces`. Excerpt: the concepts, the policy and the
|
|
88
|
+
event are declared elsewhere in the model.
|
|
82
89
|
|
|
83
90
|
```screenplay
|
|
84
91
|
slice StateChange RegisterInvoice
|
|
@@ -107,7 +114,7 @@ need to determine its next action?"*
|
|
|
107
114
|
|
|
108
115
|
Verify **every** field traces back to an event:
|
|
109
116
|
|
|
110
|
-
```
|
|
117
|
+
```text
|
|
111
118
|
InvoiceListReadModel:
|
|
112
119
|
invoiceId <- InvoiceRegistered.invoiceId
|
|
113
120
|
invoiceNumber <- InvoiceRegistered.invoiceNumber
|
|
@@ -121,15 +128,21 @@ a collection type, not a singular value.
|
|
|
121
128
|
builds it. **Exactly one thing may build a read model** — two builders is a
|
|
122
129
|
compile error (`PLAY0191`).
|
|
123
130
|
|
|
131
|
+
Key **every** `from` on the value that identifies the instance. A `from` without a
|
|
132
|
+
key routes by the event's event source id, not by the key of another `from`, and
|
|
133
|
+
a `key` written directly on the projection routes nothing (`PLAY0381`). Excerpt:
|
|
134
|
+
the concepts and events are declared elsewhere, and both events carry `invoiceId`.
|
|
135
|
+
|
|
124
136
|
```screenplay
|
|
125
137
|
slice StateView InvoiceList
|
|
126
138
|
readmodel InvoiceListReadModel
|
|
139
|
+
invoiceId InvoiceId
|
|
127
140
|
invoiceNumber InvoiceNumber
|
|
128
141
|
status InvoiceStatus
|
|
129
142
|
projection InvoiceList => InvoiceListReadModel
|
|
130
143
|
from InvoiceRegistered key invoiceId
|
|
131
144
|
status = "draft"
|
|
132
|
-
from InvoiceSent
|
|
145
|
+
from InvoiceSent key invoiceId
|
|
133
146
|
status = "sent"
|
|
134
147
|
query ListInvoices => InvoiceListReadModel[]
|
|
135
148
|
```
|
|
@@ -148,7 +161,11 @@ event. **Test:** *"Can this automatic response ever be skipped or vary based on
|
|
|
148
161
|
system state?"* If no, it is co-production — one `StateChange` slice with several
|
|
149
162
|
`produces` blocks, not an `Automation` slice.
|
|
150
163
|
|
|
151
|
-
**Output:** the `reaction`, in an `Automation` slice.
|
|
164
|
+
**Output:** the `reaction`, in an `Automation` slice. It documents the automation;
|
|
165
|
+
it does not bind to the executable model today. When the automation decides from
|
|
166
|
+
a view, declare it under the trigger with `reads` (see
|
|
167
|
+
`cratis-screenplay-captures-and-reactions`). Excerpt: the event and the
|
|
168
|
+
command are declared in their own slices.
|
|
152
169
|
|
|
153
170
|
```screenplay
|
|
154
171
|
slice Automation ChaseOverdueInvoices
|
|
@@ -179,7 +196,9 @@ need it?"* If every workflow needs it, it is cross-cutting infrastructure, **not
|
|
|
179
196
|
a `Translate` slice.
|
|
180
197
|
|
|
181
198
|
**Output:** the `capture` in a `Translate` slice, and any `trigger` declaration
|
|
182
|
-
for a name only an integration knows.
|
|
199
|
+
for a name only an integration knows. A `trigger` is an application signal a
|
|
200
|
+
reaction consumes; it is not how a button click is modeled (that is a UI `on`
|
|
201
|
+
clause).
|
|
183
202
|
|
|
184
203
|
```screenplay
|
|
185
204
|
trigger BuildFinished
|
|
@@ -201,8 +220,11 @@ Bad slices: *"Set up database"* (technical, no user value), *"Implement invoicin
|
|
|
201
220
|
**Slice independence.** Slices sharing an event schema are **independent** —
|
|
202
221
|
connected by the event contract, not by execution order. A `StateChange` slice is
|
|
203
222
|
specified by asserting on produced events; a `StateView` slice is specified with
|
|
204
|
-
synthetic `given` events
|
|
205
|
-
|
|
223
|
+
synthetic `given` events, or with `when append <Event>` to run one event through
|
|
224
|
+
constraints and projections. Neither needs the other implemented first. Do not
|
|
225
|
+
build artificial dependency chains. An authorized command's specifications state
|
|
226
|
+
the caller explicitly with `given caller` and assert refusals with `then denied`
|
|
227
|
+
(see `cratis-screenplay-specifications`).
|
|
206
228
|
|
|
207
229
|
**Output:** the complete `feature` → `slice` tree, ready for the specifications.
|
|
208
230
|
|
|
@@ -30,6 +30,18 @@
|
|
|
30
30
|
{
|
|
31
31
|
"kind": "skill-contains",
|
|
32
32
|
"value": "is not admitted by ESM v1"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"kind": "skill-contains",
|
|
36
|
+
"value": "It is not a protected"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"kind": "skill-contains",
|
|
40
|
+
"value": "**reference-executed**"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"kind": "skill-contains",
|
|
44
|
+
"value": "are accepted but\n**not available**"
|
|
33
45
|
}
|
|
34
46
|
]
|
|
35
47
|
}
|
|
@@ -12,8 +12,21 @@ the compiler already knows declarations, references, hierarchy and source owners
|
|
|
12
12
|
|
|
13
13
|
Screenplay remains experimental. **Valid source is not necessarily executable.**
|
|
14
14
|
It does not generate or run an application; Stage owns rendering/runtime admission.
|
|
15
|
-
See the [language reference](references/language-reference.md) for constructs
|
|
16
|
-
the complete canonical model.
|
|
15
|
+
See the [language reference](references/language-reference.md) for constructs,
|
|
16
|
+
the executable profile and the complete canonical model.
|
|
17
|
+
|
|
18
|
+
## Verified product sources
|
|
19
|
+
|
|
20
|
+
| Package | Version | Purpose |
|
|
21
|
+
| --- | --- | --- |
|
|
22
|
+
| `Cratis.Screenplay` | `4.31.0` | Compiler, executable semantic model (ESM), workspace and MCP server |
|
|
23
|
+
|
|
24
|
+
Checked against the Screenplay repository at tag `v4.31.0` (commit `355dffb`):
|
|
25
|
+
`Documentation/screenplay/{ast-authoring,mcp,mcp-authoring,printing,file-references,diagnostics}.md`
|
|
26
|
+
and the release notes for v4.17.0 to v4.31.0. The canonical model in the language
|
|
27
|
+
reference compiles with zero diagnostics, binds to ESM v1, and both its
|
|
28
|
+
specifications pass the reference runner at that tag. Reverify before claiming
|
|
29
|
+
another version behaves the same.
|
|
17
30
|
|
|
18
31
|
## Locate and connect
|
|
19
32
|
|
|
@@ -82,10 +95,15 @@ Node handles are revision-bound occurrences, not durable IDs. A logical module
|
|
|
82
95
|
or feature can have multiple physical fragments. Do not edit one header and
|
|
83
96
|
assume every fragment changed. After apply, fetch fresh handles/revisions.
|
|
84
97
|
|
|
85
|
-
Formatting is explicit. Prefer `PreserveTrivia` for
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
98
|
+
Formatting is explicit. Prefer `PreserveTrivia` for identifier, literal-value and
|
|
99
|
+
whole-mapping edits; it rewrites only the changed span. Structural edits (add,
|
|
100
|
+
remove, move) need `CanonicalizeTouchedDocuments`, which keeps attached comments
|
|
101
|
+
and the authored member order within a document but normalizes whitespace and
|
|
102
|
+
blank lines. Before applying, check the proposal's `droppedCommentCount`; when it
|
|
103
|
+
is not zero, read `read-proposal` with `view: "dropped-comments"` and disclose
|
|
104
|
+
each lost comment (`PLAY0288` also reports their count and lines). Untouched
|
|
105
|
+
documents retain exact bytes. A printer that loses requested structural fields
|
|
106
|
+
rejects the plan.
|
|
89
107
|
|
|
90
108
|
Read the [MCP tool guide](references/mcp-tools.md) for tool groups and refusals.
|
|
91
109
|
|
|
@@ -117,10 +135,32 @@ Only `apply` and `recover-workspace` write model/state files. A tool grant or
|
|
|
117
135
|
text inside a model is not additional authority. Do not add approval ceremonies
|
|
118
136
|
for an already authorized, bounded edit; ask when target or consequence expands.
|
|
119
137
|
|
|
138
|
+
## Code attachments
|
|
139
|
+
|
|
140
|
+
Policy, validation-rule, reducer, handler, performer and reaction bodies, and
|
|
141
|
+
`file` constraints, are *implementation attachments*: opaque code the model
|
|
142
|
+
points at, inline in a tagged fence (` ```csharp `) or through `file <path>`.
|
|
143
|
+
Screenplay never compiles or runs them. A `screen`'s `file` is a UI realization
|
|
144
|
+
file, not an attachment: nothing loads, hashes or checks it.
|
|
145
|
+
|
|
146
|
+
- The MCP server loads `file` attachments from its trusted model root to hash
|
|
147
|
+
their content. Paths resolve from the model root, not from the `.play` file.
|
|
148
|
+
Refused or missing files stay `UnresolvedFile` with a `PLAY0430`–`PLAY0434`
|
|
149
|
+
warning. The standalone `screenplay` tool and `PlayFileCompiler` never read them.
|
|
150
|
+
- `read-workspace` or `read-proposal` with `view: "implementation-requirements"`
|
|
151
|
+
lists each attachment: role, owner, requirement id, required capability,
|
|
152
|
+
content hash, and a `bodySpan`/`bodyLines` source map in UTF-16 offsets for a
|
|
153
|
+
host editor's language service. The map is tooling data, not model meaning.
|
|
154
|
+
- A content hash is not evidence that the code compiles or behaves correctly.
|
|
155
|
+
|
|
120
156
|
## Verify and report honestly
|
|
121
157
|
|
|
122
158
|
- Require zero source errors and investigate every warning.
|
|
123
159
|
- Confirm reference safety, identity continuity and exact intended source changes.
|
|
160
|
+
- Report which of the four states you checked: **parsed**, **bound**,
|
|
161
|
+
**reference-executed**, **target-executed**. The
|
|
162
|
+
[language reference](references/language-reference.md#source-validity-is-not-execution)
|
|
163
|
+
defines them. `screenplay --warnaserror` checks parsing only.
|
|
124
164
|
- Distinguish authoring acceptance from `executableReady`; unsupported backend
|
|
125
165
|
capabilities are not a reason to drop source constructs or invent stubs.
|
|
126
166
|
- If execution is intended, validate with the owning downstream runtime as well.
|
|
@@ -133,9 +173,10 @@ The ordinary CLI remains useful for whole-folder validation:
|
|
|
133
173
|
cratis screenplay validate .cratis/screenplay --warnings-as-errors
|
|
134
174
|
```
|
|
135
175
|
|
|
136
|
-
MCP
|
|
137
|
-
|
|
138
|
-
|
|
176
|
+
MCP guidance here follows the Screenplay 4.31.0 server documentation. The Cratis
|
|
177
|
+
CLI bundles its own Screenplay version, so check the installed `tools/list`
|
|
178
|
+
schemas before relying on a view or argument named here (for example
|
|
179
|
+
`dropped-comments` or `implementation-requirements`). Do not invent a command,
|
|
139
180
|
parameter, syntax node or downstream capability.
|
|
140
181
|
|
|
141
182
|
## Route near misses
|
package/package/corpus/skills/cratis-screenplay-model-authoring/references/language-reference.md
CHANGED
|
@@ -6,16 +6,20 @@
|
|
|
6
6
|
The `.play` source is plain UTF-8 text. Nesting is indentation-based, without
|
|
7
7
|
braces or terminators. A construct owns the content indented beneath it. `//`
|
|
8
8
|
starts a comment; escape reserved words inside a block with a leading `@`.
|
|
9
|
+
The grammar in `Documentation/screenplay/grammar.md` of the Screenplay
|
|
10
|
+
repository is the full list; this page is the authoring summary.
|
|
9
11
|
|
|
10
12
|
## Accepted constructs
|
|
11
13
|
|
|
12
14
|
**Top level:** `domain`, `import`, `concept`, `type`, `policy`, `persona`,
|
|
13
|
-
`authentication`, `
|
|
15
|
+
`authentication`, `trigger`, `theme`, `layout`, `ui profile`, `behavior`,
|
|
16
|
+
`module`, `seed`.
|
|
14
17
|
|
|
15
|
-
**Inside a module:** `description`, `screen`/`dialog` templates,
|
|
16
|
-
`contribute`, `feature`.
|
|
18
|
+
**Inside a module:** `description`, `authorize`, `screen`/`dialog` templates,
|
|
19
|
+
`form`, `contribute`, `on`/`uses` behavior attachments, `feature`.
|
|
17
20
|
|
|
18
|
-
**Inside a feature:** `description`, nested `feature`, `slice`,
|
|
21
|
+
**Inside a feature:** `description`, `authorize`, nested `feature`, `slice`,
|
|
22
|
+
`contribute`, `on`/`uses` behavior attachments.
|
|
19
23
|
|
|
20
24
|
| Slice type | Meaning | Typical contents |
|
|
21
25
|
| --- | --- | --- |
|
|
@@ -24,23 +28,27 @@ starts a comment; escape reserved words inside a block with a leading `@`.
|
|
|
24
28
|
| `Automation` | React to something happening | Reaction |
|
|
25
29
|
| `Translate` | Translate external data into events | Capture |
|
|
26
30
|
|
|
27
|
-
Any slice can contain `description`, `event`, `command`, `query`,
|
|
28
|
-
`capture`, `reaction`, `screen`, `constraint`, `specification`,
|
|
29
|
-
`reducer`. An unknown slice construct is only a warning
|
|
30
|
-
never accept a warning-free claim without
|
|
31
|
+
Any slice can contain `description`, `file`, `event`, `command`, `query`,
|
|
32
|
+
`projection`, `capture`, `reaction`, `screen`, `constraint`, `specification`,
|
|
33
|
+
`readmodel` and `reducer`. An unknown slice construct is only a warning
|
|
34
|
+
(`PLAY0029`) and its block is skipped; never accept a warning-free claim without
|
|
35
|
+
compiling the entire document set.
|
|
31
36
|
|
|
32
|
-
Concept primitives are `Uuid`, `String`, `Int`, `Decimal`, `Bool`, `Date
|
|
33
|
-
`DateTime
|
|
34
|
-
can carry `@pii`, `@sensitive`, reasons and validation.
|
|
37
|
+
Concept primitives are `Uuid`, `String`, `Int`, `Decimal`, `Bool`, `Date` and
|
|
38
|
+
`DateTime`; `Enum` is a separate concept kind whose members are indented below
|
|
39
|
+
it. Concepts can carry `@pii`, `@sensitive`, reasons and validation.
|
|
35
40
|
|
|
36
|
-
Projections and captures use their dedicated sub-grammars.
|
|
37
|
-
`
|
|
38
|
-
|
|
41
|
+
Projections and captures use their dedicated sub-grammars. Inline code uses a
|
|
42
|
+
tagged fence (` ```csharp `); the older language-line form still parses with
|
|
43
|
+
warning `PLAY0397`. Query the MCP's `syntax-schema` instead of inventing JSON
|
|
44
|
+
members or translating names from memory.
|
|
39
45
|
|
|
40
46
|
## Canonical complete model
|
|
41
47
|
|
|
42
48
|
The RegisterProject conformance vector is the narrow executable example shared
|
|
43
49
|
by downstream tooling. Its source is shipped in `Cratis.Screenplay.CanonicalCorpus`.
|
|
50
|
+
At v4.31.0 it compiles with zero diagnostics, binds to ESM v1, and both
|
|
51
|
+
specifications pass the reference runner.
|
|
44
52
|
|
|
45
53
|
```screenplay
|
|
46
54
|
concept ProjectId : Uuid
|
|
@@ -94,15 +102,63 @@ module Projects
|
|
|
94
102
|
|
|
95
103
|
## Source validity is not execution
|
|
96
104
|
|
|
97
|
-
|
|
98
|
-
imports, policies, personas, triggers, authorization, opaque handlers and many
|
|
99
|
-
advanced query/projection forms may be valid source but unsupported by the
|
|
100
|
-
backend. Authoring must retain that source rather than downgrade it to a stub.
|
|
105
|
+
A construct can be in one of four states. Say which one you checked.
|
|
101
106
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
107
|
+
| State | What establishes it | What it does not prove |
|
|
108
|
+
| --- | --- | --- |
|
|
109
|
+
| **Parsed** | `screenplay <folder> --warnaserror` or MCP authoring diagnostics: syntax plus model consistency | Binding, execution, or anything about attached code (the tool never reads `file` attachments) |
|
|
110
|
+
| **Bound** | Semantic binding to the executable semantic model (ESM): MCP `executableReady`, executable diagnostics | That the reference execution plan admits the model, or that any specification passes |
|
|
111
|
+
| **Reference-executed** | The reference runner passes the specification | Target behavior; opaque code never runs here |
|
|
112
|
+
| **Target-executed** | Stage or a rendered application runs it with the implementations supplied | Nothing further in Screenplay |
|
|
113
|
+
|
|
114
|
+
The ESM version is selected by what a model uses, never by the author:
|
|
115
|
+
|
|
116
|
+
- **v1** is the default.
|
|
117
|
+
- **v2** is selected by typed event-source facts: `produces … for <identifier>`
|
|
118
|
+
when the event does not repeat the identifier, `for` values in specifications,
|
|
119
|
+
and `$context.occurred` or caller identity in `produces`.
|
|
120
|
+
- **v3** is selected by implementation attachments: a reducer whose rules all
|
|
121
|
+
have bodies, a named `rule` with a body, a fenced `validate` block, or a
|
|
122
|
+
`policy` implemented in code or a file. They bind as opaque requirements with
|
|
123
|
+
capability `pure`. The reference runner returns `SemanticUnsupported` whenever
|
|
124
|
+
it would need one, so a specification that depends on one never passes.
|
|
125
|
+
|
|
126
|
+
Binding is not the last gate before the reference runner. The runner needs an
|
|
127
|
+
execution plan, and the plan is created only when every reachable capability is
|
|
128
|
+
admitted. One refused construct blocks the whole plan, so no specification in
|
|
129
|
+
the model runs, including specifications that never touch it.
|
|
130
|
+
|
|
131
|
+
What binds today, what the reference execution plan refuses, what is opaque, and
|
|
132
|
+
what blocks binding (Screenplay v4.31.0):
|
|
133
|
+
|
|
134
|
+
| Disposition | Constructs |
|
|
135
|
+
| --- | --- |
|
|
136
|
+
| Binds and runs in the reference runner | `StateChange`/`StateView` slices; `produces` including `when` conditions over command properties and literal tags; the portable validation rules, `matches email`, quoted `matches` patterns and `require` over command properties; declarative policies and `authorize` on modules, features, commands and keyed queries; `unique` constraints; projections as Chronicle lowers them, including variants, except the projection constructs in the next row; specifications, including `given caller`, `then denied` and `when append` |
|
|
137
|
+
| Binds, but the reference execution plan refuses it | A projection-level `remove via join`; `all` beside removals, `children` or `nested`; a `join`, `children` or `remove via join` inside `nested`; any event-context value other than the event source identity in a projection mapping or key, such as `$eventContext.occurred`, `$eventContext.sequenceNumber` or `$eventContext.causedBy.subject` (`$eventSourceId` and `$eventContext.eventSourceId` run) |
|
|
138
|
+
| Binds as opaque code (v3); reference runner reports unsupported | Bodied reducers, bodied named rules, fenced `validate` blocks, code or file policies |
|
|
139
|
+
| Blocks binding (`PLAY0268`) | `Automation` and `Translate` slices, reactions (with or without trigger `reads`), captures, top-level `trigger`, `persona`, `@pii`/`@sensitive` concepts, command `handler`, bare `rule <Name>`, `require` or conditions over read-model paths, dates and `today` in comparisons, `$context.tenant`/claims/roles/causation in `produces`, `$env` conditions, `file` constraints, a read model whose keyed queries in its own slice do not share one `by` property (none, or two different properties; several queries over the same property bind), any query other than `=> <ReadModel>?` with one caller-supplied `by` argument (so also observable, filtered, scoped and performer-backed queries), `$causedBy` and templates in projections |
|
|
140
|
+
| Blocks binding (`PLAY0271`, legacy meaning) | Command `reads` and `concurrency` |
|
|
141
|
+
| Deferred (`PLAY0269`, information) | Screens, layouts, templates, forms, contributions, UI profiles, themes, behaviors and `on`/`uses` |
|
|
142
|
+
| Metadata only (`PLAY0270`, information) | `domain`, `seed`, descriptions and `file` provenance on declarations |
|
|
143
|
+
|
|
144
|
+
The table is a snapshot, not a contract: ask the binder (MCP executable
|
|
145
|
+
diagnostics) rather than extrapolating from it. Retain valid source that the
|
|
146
|
+
backend cannot represent rather than downgrading it to a stub. The MCP does not
|
|
147
|
+
run specifications, compile embedded code, generate an application, or follow
|
|
148
|
+
realization files. Stage owns rendering and runtime admission.
|
|
149
|
+
|
|
150
|
+
## Not in the language yet
|
|
151
|
+
|
|
152
|
+
Decision 0006 shipped in Screenplay 4.31.0: a reaction trigger may declare
|
|
153
|
+
`reads <View> [as <alias>] [by <trigger value>]` (see
|
|
154
|
+
`cratis-screenplay-captures-and-reactions`). Reactions still block binding, so
|
|
155
|
+
those reads are declared, not enforced.
|
|
156
|
+
|
|
157
|
+
Screenplay decisions 0007 to 0014 are accepted but not implemented. Do not write
|
|
158
|
+
their syntax: affected-instance declarations, per-event data subjects, external event origin, query paging/sorting/change-set delivery, event
|
|
159
|
+
generations, a typed context descriptor or command-handler role, code round-trip
|
|
160
|
+
equivalence, or typed diagnostic repairs. Model today's syntax and record the
|
|
161
|
+
gap in prose or an issue.
|
|
106
162
|
|
|
107
163
|
## Editor support
|
|
108
164
|
|
|
@@ -19,9 +19,9 @@ these short descriptions.
|
|
|
19
19
|
| Understanding | `describe-application`, `search-declarations`, `find-declaration`, `declaration-details` | Navigate logical hierarchy and inspect bounded details |
|
|
20
20
|
| References and examples | `find-references`, `dependencies`, `find-fixtures`, `find-assertion-gaps` | Inspect declared relationships and authored examples, not executed coverage |
|
|
21
21
|
| Source and validation | `diagnostics`, `read-document`, `merged-document`, `syntax-schema` | Read exact source or typed structure and diagnose problems |
|
|
22
|
-
| Workspace inspection | `open-workspace`, `read-workspace`, `read-ast`, `workspace-state`, `export-workspace` | Obtain current identities, handles, readiness and durable-state status |
|
|
22
|
+
| Workspace inspection | `open-workspace`, `read-workspace`, `read-ast`, `workspace-state`, `export-workspace` | Obtain current identities, handles, readiness, code attachment requirements and durable-state status |
|
|
23
23
|
| Planning | `propose-ast`, `propose-rename`, `propose`, `recommend-layout`, `expand-layout` | Produce validated, reviewable candidates without writing them |
|
|
24
|
-
| Review | `read-proposal`, `discard-proposal` | Inspect exact changes or abandon a connection-local proposal |
|
|
24
|
+
| Review | `read-proposal`, `discard-proposal` | Inspect exact changes, dropped comments and proposed attachments, or abandon a connection-local proposal |
|
|
25
25
|
| Effects | `apply`, `recover-workspace` | Apply an accepted plan or explicitly recover an interrupted write |
|
|
26
26
|
|
|
27
27
|
`propose` is the executable-only whole-document interface. Prefer `propose-ast`
|
|
@@ -62,9 +62,25 @@ expand the user's requested authority.
|
|
|
62
62
|
|
|
63
63
|
## Formatting and recovery limits
|
|
64
64
|
|
|
65
|
-
Verified trivia patches preserve bytes outside the changed
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
Verified trivia patches (`PreserveTrivia`) preserve bytes outside the changed
|
|
66
|
+
identifier, literal or mapping. Structural edits require explicit
|
|
67
|
+
`CanonicalizeTouchedDocuments`: attached comments and authored member order
|
|
68
|
+
within a document are kept, whitespace and blank lines are normalized, and a
|
|
69
|
+
comment that cannot be placed is dropped. Every proposal reports
|
|
70
|
+
`droppedCommentCount`; `read-proposal` with `view: "dropped-comments"` lists each
|
|
71
|
+
one with path, line, column and text. Disclose non-zero counts before applying.
|
|
72
|
+
Untouched files remain byte-identical.
|
|
73
|
+
|
|
74
|
+
## Code attachments
|
|
75
|
+
|
|
76
|
+
`read-workspace` and `read-proposal` accept `view: "implementation-requirements"`.
|
|
77
|
+
Each entry names the role, owner, requirement id, required capability,
|
|
78
|
+
attachment resolution and content hash, plus `bodySpan` and `bodyLines`: a source
|
|
79
|
+
map in UTF-16 offsets for a host editor's language service. The server loads
|
|
80
|
+
`file` attachments from its trusted root for hashing only and warns with
|
|
81
|
+
`PLAY0430` to `PLAY0434` for refused or missing files. Attachment hashes can change between
|
|
82
|
+
pages without changing `expectedRevision`; re-read the view when you need a
|
|
83
|
+
stable snapshot. No tool compiles or runs attached code.
|
|
68
84
|
|
|
69
85
|
Apply journals its inverse before changing source/state, stages private bytes and
|
|
70
86
|
verifies results. Recovery refuses unexpected third-party content. The model root
|
|
@@ -42,6 +42,22 @@
|
|
|
42
42
|
{
|
|
43
43
|
"kind": "skill-contains",
|
|
44
44
|
"value": "`Safe`"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"kind": "skill-contains",
|
|
48
|
+
"value": "Report which of the four states you checked"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"kind": "skill-contains",
|
|
52
|
+
"value": "`view: \"dropped-comments\"`"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"kind": "skill-contains",
|
|
56
|
+
"value": "`view: \"implementation-requirements\"`"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"kind": "skill-contains",
|
|
60
|
+
"value": "Screenplay never compiles or runs them"
|
|
45
61
|
}
|
|
46
62
|
]
|
|
47
63
|
}
|