@cratis/pi 7.90.1 → 7.92.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 (19) hide show
  1. package/package/corpus/product-sync.json +3 -3
  2. package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +1 -1
  3. package/package/corpus/skills/cratis-screenplay-command-surface/references/inline-events.md +4 -1
  4. package/package/corpus/skills/cratis-screenplay-command-surface/references/policy-persona-seed.md +53 -1
  5. package/package/corpus/skills/cratis-screenplay-legacy-extraction/SKILL.md +1 -1
  6. package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +1 -1
  7. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-loop.md +1 -1
  8. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +36 -5
  9. package/package/corpus/skills/cratis-screenplay-model-authoring/references/property-links.md +22 -1
  10. package/package/corpus/skills/cratis-screenplay-model-authoring/references/repairs.md +5 -2
  11. package/package/corpus/skills/cratis-screenplay-model-review/SKILL.md +4 -1
  12. package/package/corpus/skills/cratis-screenplay-model-review/references/checklist.md +1 -1
  13. package/package/corpus/skills/cratis-screenplay-read-surface/SKILL.md +6 -1
  14. package/package/corpus/skills/cratis-screenplay-specifications/references/vocabulary.md +4 -0
  15. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/SKILL.md +3 -1
  16. package/package/corpus/skills/cratis-screenplay-toolchain/references/language-admission.md +1 -0
  17. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +5019 -893
  18. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
  19. package/package.json +1 -1
@@ -171,9 +171,9 @@
171
171
  }
172
172
  ],
173
173
  "synced": {
174
- "version": "4.216.0",
175
- "date": "2026-10-18",
176
- "by": "Cratis/AI#784"
174
+ "version": "4.232.0",
175
+ "date": "2026-10-19",
176
+ "by": "Cratis/AI#823"
177
177
  },
178
178
  "covers": {
179
179
  "skills": [
@@ -272,7 +272,7 @@ Chronicle's constraints enforce **uniqueness only**; use one when two concurrent
272
272
  ## `policy` and `persona`
273
273
 
274
274
  A policy has **exactly one** `require` line (`PLAY0441`) **or** one implementation, never both (`PLAY0440`). Read [references/policy-persona-seed.md](references/policy-persona-seed.md) when
275
- declaring a policy, a persona, or a `seed` block.
275
+ declaring a policy (including `require anonymous` for a deliberately public command or query), a persona, or a `seed` block.
276
276
 
277
277
  ## Event data subject
278
278
 
@@ -80,6 +80,9 @@ MCP can declare a missing produced event (`PLAY0166`), add explicit routing
80
80
  (`PLAY0478`), remove a redundant pin (`PLAY0471`), or remove an inline identifier
81
81
  copy (`PLAY0469`). The last **changes the event contract**, retires a property,
82
82
  refuses affected consumers/opaque implementations and is not fix-all. It does
83
- not establish that stored data is safe to migrate. Use
83
+ not establish that stored data is safe to migrate; for a contract that may have been
84
+ stored, `propose-property` `remove` with `newGeneration: true` extracts the event and
85
+ drafts a new generation (a source draft, never deployment ready; requires Screenplay
86
+ 4.232.0, `screenplay --version`). Use
84
87
  `cratis-screenplay-model-authoring` for discovery, preview, extraction and rename.
85
88
 
@@ -1,5 +1,12 @@
1
1
  # Policies, personas and seed
2
2
 
3
+ ## Contents
4
+
5
+ - `policy` and `persona`
6
+ - Anonymous policy
7
+ - Policy negation
8
+ - `seed`
9
+
3
10
  ## `policy` and `persona`
4
11
 
5
12
  ```screenplay
@@ -20,7 +27,7 @@ persona Accountant
20
27
  policy IsAccountant
21
28
  ```
22
29
 
23
- Condition atoms: `authenticated`, `role "<name>"`, and
30
+ Condition atoms: `authenticated`, `anonymous`, `role "<name>"`, and
24
31
  `claim "<name>" matches subject | "<value>" | <path>`. A policy has **exactly one**
25
32
  `require` line — continue the condition on deeper-indented lines instead of adding
26
33
  a second (`PLAY0441`) — **or** one implementation (a tagged ` ```csharp ` block or
@@ -29,6 +36,51 @@ runner; a code policy binds as opaque ESM v3 and needs a target to evaluate it.
29
36
  A `persona` is authoring metadata: the binder reports it as information `PLAY0270`
30
37
  (report-only) and it does not block binding; an unknown policy it lists is an error.
31
38
 
39
+ ## Anonymous policy
40
+
41
+ Requires Screenplay 4.231.0 (ESM v31; `screenplay --version`); older compilers reject
42
+ `require anonymous`. A policy with `require anonymous` exposes a public command or
43
+ query, such as sign-up. The condition always holds, for callers with and without an
44
+ identity alike. Only a model that declares one selects v31.
45
+
46
+ ```screenplay
47
+ concept SubscriberId : Uuid
48
+ concept EmailAddress : String
49
+ policy PublicAccess
50
+ require anonymous
51
+ module Newsletter
52
+ feature Signup
53
+ slice StateChange SubscribeToNewsletter
54
+ command SubscribeToNewsletter
55
+ subscriberId SubscriberId identifier
56
+ email EmailAddress
57
+ authorize PublicAccess
58
+ produces event SubscriberSignedUp
59
+ email EmailAddress = email
60
+ specification SubscribingWithoutAnIdentity
61
+ when SubscribeToNewsletter
62
+ subscriberId = "3fa85f64-5717-4562-b3fc-2c963f66afa6"
63
+ email = "ada@example.com"
64
+ then SubscriberSignedUp
65
+ email = "ada@example.com"
66
+ ```
67
+
68
+ `anonymous` must be the command's or query's whole effective authorization:
69
+
70
+ | Code | Refused |
71
+ | --- | --- |
72
+ | PLAY0804 | combined with another condition in `require` |
73
+ | PLAY0805 | negated; write `authenticated` instead |
74
+ | PLAY0806 | combined with another policy in `authorize` |
75
+ | PLAY0807 | under or above another module, feature, command or query gate |
76
+
77
+ A specification of such a command or query may omit `given caller`; every other
78
+ authorized specification still needs one (`PLAY0389`).
79
+
80
+ **Security:** `anonymous` declares a public surface on purpose. Never use it to make a
81
+ model compile or to silence a missing-`authorize` or caller finding; model the real
82
+ policy instead, because a generated application renders it as an open endpoint.
83
+
32
84
  ## Policy negation
33
85
 
34
86
  `not <condition>` is a portable ESM v7 policy-condition
@@ -133,7 +133,7 @@ chain per slice before handoff (`references/evidence-table-template.md`, "Tracea
133
133
  `cratis-screenplay-slice-design` for slices, `cratis-screenplay-streams-and-consistency` for
134
134
  identity and invariants). To move an already authored slice or feature to its right parent, use
135
135
  the MCP `propose-move` tool (identity-preserving; it refuses identity loss, collisions and
136
- captures) rather than retyping the declarations (`cratis-screenplay-model-authoring`):
136
+ name capture (a reference that would resolve to a different declaration); it also moves a single declaration between slices from Screenplay 4.230.0) rather than retyping the declarations (`cratis-screenplay-model-authoring`):
137
137
  - one StateChange per decision a person or system makes; events are facts experts recognise;
138
138
  consequences (counters, denormalised copies) become projections; an automation only when
139
139
  evidence shows a separate decision; no generic names (`Update/Edit/Save<Noun>`, `<Noun>Updated`): split by intent;
@@ -175,7 +175,7 @@ Choose formatting and disclose dropped comments before apply:
175
175
 
176
176
  ## Repair or extract before rewriting
177
177
 
178
- Read `read-workspace` with `view: "repairs"` at the same revision as diagnostics and pass the repair to `propose-repair`; use `propose-extract-inline-event` before adding generations. `PLAY0469` changes the event contract, so ask about stored contracts first. No automatic generation-evolution repair ships. `PLAY0479`: migrate optionality spelling with `PreserveTrivia`. `eventNeverPersisted: true` cannot unfreeze admitted revisions. Differing event pins carry `storedName` in ESM v16, shared by all generations and unique (PLAY0472). Read [references/repairs.md](references/repairs.md) when fixing `PLAY0166`, `PLAY0478`, `PLAY0516` or `PLAY0683`, or admitting a [release baseline](references/release-baseline.md). Read [references/destination-intent-repair.md](references/destination-intent-repair.md) when `PLAY0470` needs a repair.
178
+ Read `read-workspace` with `view: "repairs"` at the same revision as diagnostics and pass the repair to `propose-repair`; use `propose-extract-inline-event` before adding generations, or let a `remove` with `newGeneration: true` extract the inline event itself, as [property links](references/property-links.md) describes. `PLAY0469` changes the event contract, so ask about stored contracts first. No automatic generation-evolution repair ships. `PLAY0479`: migrate optionality spelling with `PreserveTrivia`. `eventNeverPersisted: true` cannot unfreeze admitted revisions. Differing event pins carry `storedName` in ESM v16, shared by all generations and unique (PLAY0472). Read [references/repairs.md](references/repairs.md) when fixing `PLAY0166`, `PLAY0478`, `PLAY0516` or `PLAY0683`, or admitting a [release baseline](references/release-baseline.md). Read [references/destination-intent-repair.md](references/destination-intent-repair.md) when `PLAY0470` needs a repair.
179
179
 
180
180
  ## Choose a readable layout
181
181
 
@@ -218,7 +218,7 @@ connection. Passing `open-workspace.path` does **not** avoid it, because the err
218
218
  | Edit class | Examples | Route |
219
219
  | --- | --- | --- |
220
220
  | Address-preserving | descriptions; bodies of rules and expressions; mappings between members that already exist; any edit that adds, removes or renames no addressed element. Also every edit in a model with no `.screenplay/identities.json` except persisted names | bounded text edit of the `.play` file, then compile the folder; or `propose-ast` |
221
- | Catalog-changing (identity file present) | add, remove or rename a declaration (slice, command, event, read model, projection, ...), a property of a command, event, read model, composite type or trigger, a query, a query argument or a specification; create, delete, rename or move a mapped `.play` document (McpState refuses reopening with `IdentityMappingConflict`; use document operations in `propose-ast`); rename, remove or move an event, command, read model, constraint, module, feature or slice; move declarations between files (slices and features across logical parents: `propose-move`); contract evolution of a persisted event (new generation, property added, removed or retyped) | `propose-rename` or a reviewed `propose-ast`; never a blind text rename. Renaming a constraint resets its uniqueness index: ask first unless the request names it, then report the reset. A persisted event rename needs `id "OldName"` (added by default) |
221
+ | Catalog-changing (identity file present) | add, remove or rename a declaration (slice, command, event, read model, projection, ...), a property of a command, event, read model, composite type or trigger, a query, a query argument or a specification; create, delete, rename or move a mapped `.play` document (McpState refuses reopening with `IdentityMappingConflict`; use document operations in `propose-ast`); rename, remove or move an event, command, read model, constraint, module, feature or slice; move declarations between files (slices and features across logical parents, and single declarations between slices: `propose-move`); contract evolution of a persisted event (new generation, property added, removed or retyped) | `propose-rename` or a reviewed `propose-ast`; never a blind text rename. Renaming a constraint resets its uniqueness index: ask first unless the request names it, then report the reset. A persisted event rename needs `id "OldName"` (added by default) |
222
222
  | Concept `generate` | set/change/remove strategy and modifiers | `propose-ast` replaces `ConceptSyntax.generation` (`GenerationSyntax`; omit/null to remove), or reviewed `propose-source`; never hand-edit `generate` text. Preserve other concept members and inspect executable diagnostics: sequence PLAY0682, generated secrets PLAY0268, generated-rule proofs PLAY0688/0689, finite-support failures PLAY0691/0692. Pattern/random/rule and checksum validation bind as ESM v21 (Requires Screenplay 4.172.0, `screenplay --version`; older compilers refuse PLAY0268). Read `mcp-tools.md#concept-generation` for `arguments`, exact support and `rules[]`, not parsed diagnostic prose. |
223
223
  | Repair | `PLAY0166`, `0478`, `0469`, `0471`, `0479`, `0516`, `0563`, `0564`, `0565`, `0614`, `0653`, `0683`, `0684` (and recipe-only `0397`); `PLAY0470` only with author intent ([destination intent repair](destination-intent-repair.md)) | `propose-repair` with `formatting`; PLAY0166/0478 may pin attachment evidence (`pinRepairEvidence` and `expectedRepairEvidenceRevision`), never fix-all PLAY0478 |
224
224
  | Inline event extraction | `produces event ...` to a declared event | `propose-extract-inline-event` |
@@ -25,7 +25,7 @@
25
25
  - Formatting and recovery limits
26
26
  - Code attachments
27
27
 
28
- The standalone MCP server lists 44 tools (including the MCP-Apps visualization tool); `tools/list` is the authority for the installed server.
28
+ The standalone MCP server lists 46 tools from Screenplay 4.228.0 (including the MCP-Apps visualization tool); `tools/list` is the authority for the installed server, and the CLI-bundled MCP (`cratis screenplay mcp`) can be an older Screenplay that lacks newer tools.
29
29
 
30
30
  The supported CLI launch is `cratis screenplay mcp <model-root>`, or `cratis screenplay mcp`
31
31
  alone inside a project, where the CLI locates the model (the project's `.play` files, else
@@ -50,16 +50,26 @@ the [MCP loop](mcp-loop.md).
50
50
  | Group | Tools | Intent |
51
51
  | --- | --- | --- |
52
52
  | Understanding | `describe-application`, `search-declarations`, `find-declaration`, `declaration-details` | Navigate logical hierarchy and inspect bounded details |
53
- | References and examples | `find-references`, `dependencies`, `dependency-graph`, `find-fixtures`, `find-assertion-gaps`, `find-specification-obligations`, `find-modeling-smells`, `semantic-diff` | Inspect declared relationships and authored examples, not executed coverage |
53
+ | References and examples | `find-references`, `dependencies`, `dependency-graph`, `find-fixtures`, `find-assertion-gaps`, `find-specification-obligations`, `find-modeling-smells`, `trace-lineage`, `semantic-diff` | Inspect declared relationships and authored examples, not executed coverage |
54
54
  | Source and validation | `diagnostics`, `ui-profiles`, `read-document`, `merged-document`, `syntax-schema` | Read exact source or typed structure and diagnose problems |
55
55
  | Workspace inspection | `open-workspace`, `read-workspace`, `read-ast`, `workspace-state`, `export-workspace`, `repair-capabilities` | Obtain current identities, handles, readiness, code attachment requirements, source-map locations, durable-state status and the repair catalog |
56
56
  | Visual (MCP-Apps hosts only) | `visualize-model` | Draw the board for the model or a `proposalId`; its `sketch` argument previews a what-if of whole documents. Reads only |
57
- | Planning | `propose-source`, `propose-ast`, `propose-rename`, `propose-move`, `propose-repair`, `propose-property`, `propose-number-enum-members`, `propose-extract-inline-event`, `propose`, `recommend-layout`, `expand-layout` | Produce validated, reviewable candidates without writing them |
57
+ | Planning | `propose-source`, `propose-ast`, `propose-rename`, `propose-move`, `propose-repair`, `propose-property`, `propose-number-enum-members`, `propose-extract-inline-event`, `propose-inline-event`, `propose`, `recommend-layout`, `expand-layout` | Produce validated, reviewable candidates without writing them |
58
58
  | Review | `read-proposal`, `discard-proposal` | Inspect exact changes, dropped comments and proposed attachments, or abandon a connection-local proposal |
59
59
  | Reference execution | `run-specifications` | Run the workspace or a retained proposal candidate read-only; not attached code or target tests |
60
60
  | Effects | `apply`, `recover-workspace` | Apply an accepted plan or explicitly recover an interrupted write |
61
61
 
62
- `propose-move` moves a slice to another feature, or a feature to another module or feature, keeping identities: copy the `target` and `newParent` `{kind, parts}` addresses from the identity inventory and pass `expectedRevision` and `expectedCatalogRevision`. It repairs qualified references and `depends on`, and refuses identity loss, capture, collisions, descendant destinations, inherited authorization or screen-interaction changes and glob imports; review `moveReport` (`identityMigrations`, `referenceRepairs`, `fragmentsMoved`). It does not rename events, change pins or move files, and declaration moves between slices are deferred. Use it for legacy re-slicing instead of retyping declarations. Its report document fields are plain strings, not nested identity objects.
62
+ `propose-move` moves a slice to another feature, a feature to another module or feature, or a single command, event, read model, projection, query, reaction or capture to another slice, keeping identities: copy the `target` and `newParent` `{kind, parts}` addresses from the identity inventory (`newParent` is the destination slice for a declaration) and pass `expectedRevision` and `expectedCatalogRevision`. It repairs qualified references and `depends on`, and refuses identity loss, collisions, descendant destinations, name capture (a reference that would resolve to a different declaration), inherited authorization or screen-interaction changes and glob imports; review `moveReport` (`identityMigrations`, `referenceRepairs`, `fragmentsMoved`, and `specificationsCarried` for a declaration). It does not rename events, change pins or move files. Use it for legacy re-slicing instead of retyping declarations. Its report document fields are plain strings, not nested identity objects.
63
+
64
+ A declaration move follows these rules:
65
+
66
+ - A specification that covers only the moved declaration moves with it. A specification covers a declaration when it is a matching specification of one of its `find-specification-obligations` obligations, or when its `when` step names it; a `given` or `then` reference alone is not coverage.
67
+ - The move is refused when a specification also covers a declaration that stays, when an obligation the source slice met would no longer be met or the move would introduce an unmet obligation, on a name collision, for an inline declaration (such as an inline `produces event`), a declaration written in more than one fragment, a standalone specification, screen, constraint or module, and when an unqualified reference would resolve differently. Qualify that reference first.
68
+ - Screen `execute`, `refresh` and `navigate to` targets that name the declaration are repaired, not moved.
69
+ - Slice-level events named by `produces` do not travel with a command, and a projection's `from` may name an event declared in another slice; move such an event with its own `propose-move` only when it should change slices. A command's inline events go with it.
70
+ - Event names and pins stay untouched, and assigned identities follow the declaration.
71
+
72
+ Requires Screenplay 4.230.0 (`screenplay --version`) for declaration moves; older servers move only slices and features.
63
73
 
64
74
  Requires Screenplay 4.211.0 (`screenplay --version`) for string conflict/move-report document fields and independent reference-edit batches; older servers can emit objects and refuse independent remove/add batches. Upgrade before relying on this contract.
65
75
 
@@ -309,7 +319,7 @@ with `view: "diagnostics"`, then `view: "repairs"` at the current revision.
309
319
  | `PLAY0166` | Declare a missing command-produced event in its slice. Infer known command-path types (retaining concepts) or `$context.occurred` as `DateTime`; refuse uncertain/conflicting shapes, imports, existing declarations, cross-file producers and parser-invalid workspaces. |
310
320
  | `PLAY0478` | Add `for <identifier>` to a plain production. Both models must be executable; refuse a version change or retargeting another production. This changes routing: accept only if the identifier, not allocation, is intended; `canFixAll: false`. |
311
321
  | `PLAY0471` | Remove a redundant event id only with unchanged executable model, catalog and comments. |
312
- | `PLAY0469` | Remove an inline same-source identifier property and mapping, retiring its semantic address. This changes the contract; `canFixAll` is false. Refuse other consumers, opaque impact, changed routing or comment loss. Plain contracts get guidance only. |
322
+ | `PLAY0469` | Remove an inline same-source identifier property and mapping, retiring its semantic address. This changes the contract; `canFixAll` is false. Refuse other consumers, opaque impact, changed routing or comment loss. Plain contracts get guidance only. For a contract that may have been stored, use `propose-property` `remove` with `newGeneration: true` instead. |
313
323
  | `PLAY0479` | Migrate one optional type spelling, or all in a document, preserving syntax and trivia. Exclude `query Q => observable?`. |
314
324
  | `PLAY0563/0564` | Expand a one-line interaction alternative / turn a strict item `where` into one block-form `when`. Individual review, canonical formatting, no pinned evidence; refuse comment loss. Opaque non-item-condition text has no PLAY0564 repair. |
315
325
  | `PLAY0614` | Declare Translate direction only when exactly one inbound/outbound interpretation fits public metadata; never change event visibility to make a repair fit. |
@@ -347,6 +357,27 @@ tags and identities survive; canonical ESM must stay byte-identical and every
347
357
  comment must survive exactly once. Extract before adding `generation`, not after
348
358
  making the document parser-invalid. This is a refactoring, not a diagnostic repair.
349
359
 
360
+ Requires Screenplay 4.228.0 (`screenplay --version`) for `propose-inline-event`.
361
+
362
+ `propose-inline-event` is the inverse: it folds a slice-level event with exactly one
363
+ production into an inline event on that production, takes the same `subject`,
364
+ revisions and `formatting: "CanonicalizeTouchedDocuments"`, and preserves executable
365
+ bytes and identities. Use it to undo an extraction when the event has one producer and
366
+ no other consumer. It refuses when the fold could change meaning: a conditional
367
+ production (`when`), incomplete mappings, generations, an external origin or public
368
+ event, cross-slice or cross-document use, opaque or handler text, comments that would
369
+ be lost, or any reference other than the single production. Read the refusal and
370
+ leave the event standalone; never work around it with text edits.
371
+
372
+ Requires Screenplay 4.223.0 (`screenplay --version`) for `trace-lineage`.
373
+
374
+ `trace-lineage` takes a read-model property `address` and returns a paged tree
375
+ (`limit`, `offset`) from the property through projection or reducer mappings, joins and
376
+ child mappings to the event property, then to the producing command property or capture
377
+ source. A broken hop is reported where the chain breaks, several sources appear as
378
+ branches and code the model cannot see into is marked opaque. It is read-only and
379
+ advisory.
380
+
350
381
  Requires Screenplay 4.153.0 or later (`screenplay --version`) for `propose-rename` to consult release-baseline mutability; before it, `propose-rename` pins the previous effective name without a baseline.
351
382
 
352
383
  `propose-rename` consults release-baseline mutability: without a
@@ -8,6 +8,7 @@
8
8
  - Address and query
9
9
  - Read evidence, not just a count
10
10
  - Propose a property change
11
+ - Remove from an inline event
11
12
  - Add with explicit sources and fixtures
12
13
 
13
14
  Property-path evidence in `find-references` and `dependencies` is read-only inspection.
@@ -140,8 +141,10 @@ with `expectedRevision`, `expectedCatalogRevision`, `action: "rename"|"remove"`,
140
141
  or `alsoRemove` entries are `{ "target": <handle>, "expectedName": <name> }`.
141
142
  Select only intended command, current-event and non-key read-model properties:
142
143
  chain membership establishes eligibility, not permission to edit every field.
143
- Off-chain selections refuse atomically (`HopNotOnChain`). Historical generations, inline events,
144
+ Off-chain selections refuse atomically (`HopNotOnChain`). Historical generations,
144
145
  keys, opaque or incomplete links and unsupported spans refuse rather than guess.
146
+ Inline events refuse `InlineEventRequiresExtraction` unless the action is `remove`
147
+ with `newGeneration: true` (see [inline events](#remove-from-an-inline-event)).
145
148
 
146
149
  Rename repairs proven references and fixtures. Renaming only a command input
147
150
  keeps the event payload name; broken AutoMap links become explicit mappings.
@@ -175,6 +178,24 @@ have equal revisions. `[]` means no accepted planned event edits, not success;
175
178
  there is no singular `property.generation`. `deployableWithoutTransformation`
176
179
  and `esmVersionKnown` are independent of authoring acceptance.
177
180
 
181
+ ## Remove from an inline event
182
+
183
+ Requires Screenplay 4.232.0 (`screenplay --version`) for inline-event removal;
184
+ older releases refuse inline events.
185
+
186
+ `action: "remove"` with `newGeneration: true` on an inline event extracts it to its
187
+ owning slice in the same proposal (explicit `CanonicalizeTouchedDocuments` consent
188
+ required) and drafts generation N+1 without the member and its mappings. Generation N
189
+ keeps the member; the contract identity and property identities stay. This is how to
190
+ retire a command identifier copied into a stored event payload (`PLAY0469`).
191
+ Without `newGeneration`, an inline event still refuses `InlineEventRequiresExtraction`:
192
+ extract it first with `propose-extract-inline-event`.
193
+
194
+ The report adds `evolutionDraft` (true when any selected event uses `newGeneration`)
195
+ and `extractedInlineEvents` (always an array). An evolution draft is source only: no
196
+ migrator is declared and `deployableWithoutTransformation` stays false. Never present
197
+ it as migration, deployment or replay ready; Chronicle still needs a transformation.
198
+
178
199
  ## Add with explicit sources and fixtures
179
200
 
180
201
  Read the declaration's original `read-ast` handle. Send `action: "add"`, both
@@ -19,8 +19,11 @@ from silently changing the reviewed candidate.
19
19
  new timeline findings; evidence pinning is unsupported for this repair.
20
20
  - `PLAY0469` removes an inline identifier payload copy: it **changes the event
21
21
  contract**, refuses consumer/opaque impact, has no fix-all, and the catalog does
22
- not prove events were persisted, so ask about stored contracts first.
23
- No automatic generation-evolution repair ships.
22
+ not prove events were persisted, so ask about stored contracts first. For a
23
+ contract that may have been stored, use `propose-property` `remove` with
24
+ `newGeneration: true` instead: it drafts a new generation (see
25
+ [property planning](property-links.md#remove-from-an-inline-event)).
26
+ The repair itself never drafts a generation.
24
27
  - `PLAY0479`: migrate optionality spelling with `PreserveTrivia`; document scope
25
28
  migrates all occurrences together. Keep the `query Q => observable?` exception.
26
29
  - `PLAY0470` is repaired only from an author-supplied destination intent, never
@@ -63,7 +63,10 @@ model's behalf.
63
63
  refused change needs a `then error` spec; each command missing from the table is investigated.
64
64
  5. **Lineage and completeness** (phase 3). Backward: every read-model field to an event field,
65
65
  `$eventSourceId`, literal or documented derivation, to a command input, `$context`, capture field
66
- or literal, to the screen, reaction or integration that supplies it. AutoMap fills same-named
66
+ or literal, to the screen, reaction or integration that supplies it. Trace a field with the
67
+ `screenplay` MCP server's `trace-lineage` tool (paged tree, breaks, branches and opaque hops
68
+ are reported) rather than stitching `dependencies` calls; confirm each hop in the model.
69
+ Requires Screenplay 4.223.0 (`screenplay --version`); on older releases use `dependencies`. AutoMap fills same-named
67
70
  fields silently: count them. Forward: every event to a consumer or a terminal reason; every
68
71
  command input to an event field or a rule. Before calling data missing, search the model.
69
72
  6. **Phased checklist** (phases 4-10): ownership, event quality, events versus views, rules and
@@ -173,7 +173,7 @@ Nebulit (`provenance.md`).
173
173
  | G4 | A command invoked by a reaction is not gated by a caller policy, unless a trusted-path decision is recorded | reactions, `authorize` | D (silent = major) |
174
174
  | G5 | Row scoping (whose data) is part of the view, not a filter the caller supplies | queries | D |
175
175
  | G6 | Every persona Cannot line resolves to an executable gate (`authorize` policy, or ownership `claim "x" matches subject\|<command property>`, or a Uuid `require <command property> == <protected read path>`) and a `then denied` spec whose caller is synthesized with `given caller as <Persona>` or explicitly carries the effective-gate roles/claims; otherwise recorded as a gap. Persona text is intent only | personas, policies, specs | D |
176
- | G7 | Every command and query under an inherited module/feature `authorize` has its own `then denied` spec; authorization shared by a feature is declared at feature/module level so new paths inherit it | policies, specs | D |
176
+ | G7 | Every command and query under an inherited module/feature `authorize` has its own `then denied` spec; authorization shared by a feature is declared at feature/module level so new paths inherit it. `require anonymous` is flagged on anything the business did not name public; it must be the whole authorization, preferably in a separate public module, and is not the same as omitting `authorize` | policies, specs | D (major when it exposes another person's data) |
177
177
  | G8 | Ownership/claim targets are a supported scalar (text, Uuid, Date or DateTime render; a numeric or Boolean target is always denied; other shapes and a command without exactly one identifier are STAGE-ESM-015): noted | policies | C (renderable mode) |
178
178
 
179
179
  ## Phase 10. Views, queries and screens (4 checks, H1-H4)
@@ -77,6 +77,11 @@ query ListInvoices => InvoiceListReadModel[]
77
77
  authorize IsAuthenticated
78
78
  ```
79
79
 
80
+ A deliberately public query (no identity needed) uses a policy with `require anonymous`
81
+ as its whole authorization, ideally in a separate public module; leaving `authorize` off
82
+ is not the same thing. Rules and diagnostics:
83
+ [anonymous policy](../cratis-screenplay-command-surface/references/policy-persona-seed.md#anonymous-policy).
84
+
80
85
  **Name the compiler and renderer.** Optional keyed queries and collection queries
81
86
  bind, including `observable`. Caller-supplied equality
82
87
  filters on collections bind as ESM v14; `from`, single-result filters, `scoped to`,
@@ -305,7 +310,7 @@ binding failures are errors.
305
310
  - [ ] `observable` is present exactly where the caller should see changes without
306
311
  asking again.
307
312
  - [ ] Every authorized query has a specification with `given caller`, including a
308
- `then denied` case.
313
+ `then denied` case (a query authorized only by an anonymous policy may omit `given caller`).
309
314
  - [ ] Each read model has exactly one builder and every field traces to an event.
310
315
  - [ ] A reducer-built view's `by` type matches its events' event-source identity (`PLAY0690`).
311
316
  - [ ] No screen reference is left ambiguous or unresolved.
@@ -54,6 +54,10 @@ The complete model with these specifications is in read-surface `references/name
54
54
 
55
55
  ## Parse and binding diagnostics
56
56
 
57
+ A command or query authorized only by an anonymous policy may omit `given caller`;
58
+ every other authorized specification needs one (PLAY0389). See
59
+ [anonymous policy](../../cratis-screenplay-command-surface/references/policy-persona-seed.md#anonymous-policy).
60
+
57
61
  PLAY0358 is a syntax error; PLAY0388 also occurs at parse time for extra text
58
62
  after `then denied`. PLAY0350, PLAY0352, PLAY0388 for mixed outcomes, PLAY0389 and
59
63
  the one-rejection rule PLAY0273 occur only at binding. Source validation alone
@@ -100,7 +100,9 @@ Unattended work takes the conservative option and marks it `ASSUMED` in model
100
100
  ## Rules
101
101
  **Compiler contracts** (diagnostics; capability per tool in the toolchain `references/executable-subset.md`)
102
102
  - `identifier` on an event property is PLAY0019; the source id is never payload by declaration.
103
- Copying it as a payload value is PLAY0469 (information, warning for inline events).
103
+ Copying it as a payload value is PLAY0469 (information, warning for inline events);
104
+ for a possibly stored contract, retire it as an evolution draft with `propose-property`
105
+ `remove` + `newGeneration: true`, not by editing the event in place (model-authoring [property planning](../cratis-screenplay-model-authoring/references/property-links.md#remove-from-an-inline-event)).
104
106
  - In the executable model a production's `for` must resolve to the command's scalar identifier:
105
107
  one command writes one stream declaratively; described handlers bind v23 but
106
108
  their payload-only contract does not grant arbitrary destinations.
@@ -18,6 +18,7 @@ exact language/semantic pairs; binding, reference execution and rendering are se
18
18
  | v28 | `==`/`!=` between Uuid values in command `require` and `produces when` | Uuid properties, Uuid concepts and identities, canonical literals; protected read paths in `require` only | v28 refused STAGE-ESM-016 |
19
19
  | v29 | `decimals <= N`; `add`/`subtract` by `a * b`; a concept mapped to another concept over the same primitive (decision 0098) | Decimal-places rule on a Decimal concept or property; the exact decimal product; the conversion is admitted only when the target declares no rule or compliance the source does not, never for enums, composites or optional into required | v29 refused until Stage admits it |
20
20
  | v30 | A command `produces ... for <required scalar property>` (several event sources); a specification `given generated <Command>.<property> = <value>` (decision 0098) | Several sources in one accepted command; pinned generated values for reaction-invoked commands, taken in authored order | v30 refused until Stage admits it |
21
+ | v31 | A policy `require anonymous` for a public command or query | A deliberately public surface; the policy is the whole effective authorization | v31 refused until Stage admits it |
21
22
 
22
23
  Constructs of decision 0098 with no executable-model content need no version: application-level toolbar buttons in the layout's `navigation topbar` region (`button <id> title "..." slice <Slice>` with an optional indented `authorize <Policy>`), a command specification that states the public event its outbound Translate slice publishes (no more false `PLAY0285`), and a capture over events that copies a list (`lines = $.lines`) or fans out with `children lines identified by sku`. Check `screenplay --version` against the release that admitted v29 and v30 before relying on them.
23
24