@cratis/pi 7.22.0 → 7.23.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 (53) hide show
  1. package/package/corpus/skills/cratis-screenplay-automations-and-translations/SKILL.md +13 -4
  2. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/SKILL.md +4 -3
  3. package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +37 -36
  4. package/package/corpus/skills/cratis-screenplay-command-surface/references/compliance.md +154 -0
  5. package/package/corpus/skills/cratis-screenplay-command-surface/references/context.md +48 -0
  6. package/package/corpus/skills/cratis-screenplay-command-surface/references/generated-values-and-responses.md +1 -1
  7. package/package/corpus/skills/cratis-screenplay-command-surface/verification.json +6 -0
  8. package/package/corpus/skills/cratis-screenplay-discovery/SKILL.md +10 -3
  9. package/package/corpus/skills/cratis-screenplay-discovery/references/interview-questions.md +1 -1
  10. package/package/corpus/skills/cratis-screenplay-event-modeling/SKILL.md +3 -3
  11. package/package/corpus/skills/cratis-screenplay-event-modeling/references/naming-primitives.md +5 -3
  12. package/package/corpus/skills/cratis-screenplay-event-modeling/references/parsed-not-runnable.md +3 -1
  13. package/package/corpus/skills/cratis-screenplay-legacy-extraction/SKILL.md +10 -2
  14. package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +5 -2
  15. package/package/corpus/skills/cratis-screenplay-model-authoring/references/language-reference.md +33 -6
  16. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-loop.md +15 -1
  17. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +37 -1
  18. package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +1 -1
  19. package/package/corpus/skills/cratis-screenplay-model-review/SKILL.md +8 -1
  20. package/package/corpus/skills/cratis-screenplay-model-review/references/checklist.md +1 -1
  21. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/SKILL.md +3 -3
  22. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/completeness-self-check.md +1 -1
  23. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/verdicts-and-modes.md +1 -1
  24. package/package/corpus/skills/cratis-screenplay-read-surface/SKILL.md +7 -0
  25. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/SKILL.md +3 -3
  26. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/renderability-gate.md +1 -1
  27. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/spec-forms-by-mode.md +1 -1
  28. package/package/corpus/skills/cratis-screenplay-slice-design/SKILL.md +10 -1
  29. package/package/corpus/skills/cratis-screenplay-slice-design/references/command-inventory.md +2 -1
  30. package/package/corpus/skills/cratis-screenplay-slice-design/references/review-questions.md +2 -1
  31. package/package/corpus/skills/cratis-screenplay-slice-design/references/rule-layers.md +4 -3
  32. package/package/corpus/skills/cratis-screenplay-specifications/SKILL.md +1 -1
  33. package/package/corpus/skills/cratis-screenplay-specifications/references/examples-and-routes.md +8 -0
  34. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/SKILL.md +18 -4
  35. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/chronicle-boundaries.md +8 -4
  36. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/consistency-and-concurrency.md +10 -0
  37. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/stream-patterns.md +9 -0
  38. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/streams-example.md +3 -3
  39. package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +12 -5
  40. package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet-example.md +2 -2
  41. package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet.md +12 -1
  42. package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +75 -5
  43. package/package/corpus/skills/cratis-screenplay-toolchain/references/doc-contradictions.md +8 -1
  44. package/package/corpus/skills/cratis-screenplay-toolchain/references/executable-subset.md +19 -4
  45. package/package/corpus/skills/cratis-screenplay-toolchain/references/provenance.md +7 -1
  46. package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +16 -1
  47. package/package/corpus/skills/cratis-screenplay-toolchain/references/sources-and-streams.md +21 -0
  48. package/package/corpus/skills/cratis-screenplay-toolchain/references/traps.md +18 -1
  49. package/package/corpus/skills/cratis-screenplay-toolchain/references/verdicts.md +7 -6
  50. package/package/corpus/skills/cratis-screenplay-toolchain/references/versions.md +10 -3
  51. package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +6 -0
  52. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +2 -2
  53. package/package.json +1 -1
@@ -59,7 +59,8 @@ sends again.
59
59
  A field left out of `map` still passes through the capture's working record: omission is not
60
60
  redaction. Check the append mappings and every resulting event property, and record whether
61
61
  the target stores raw or last-seen source records and how they are minimized.
62
- Personal data kept in events needs `@pii` on its concept and a purpose; keep the annotation
62
+ Personal data kept in events needs bare `pii` on its concept and a declared purpose
63
+ (see command-surface `references/compliance.md`); keep the marker
63
64
  even when it blocks binding. Never record bearer tokens, magic links or signed URLs as facts
64
65
  (a keyed hash or reference at most), and never put PII on the event-source id.
65
66
 
@@ -123,7 +124,15 @@ or actor that nobody confirmed. Read `references/worked-integration.md` when you
123
124
  `runs as system role "<Role>"` (ESM v10). An undeclared actor remains caller-less.
124
125
  CLI/Stage realization is a separate gap; a returned-command reactor uses
125
126
  `[ExecuteCommandsAsSystem("<role>")]` and the matching policy. Never strip a
126
- gate or supply `given caller` as a fictional reaction identity.
127
+ gate or supply `given caller` as a fictional reaction identity. Arc supplies a
128
+ system principal only to reactors marked `[ExecuteCommandsAsSystem]`; without
129
+ it there is no principal and `[Authorize]`/`[Roles]` deny. `runs as` covers returned
130
+ or invoked commands, not imperative pipeline calls, reads, productions or causation.
131
+ On Screenplay 4.127.0 run `--check privilege --warnaserror` (PLAY0652) for
132
+ confused-deputy paths: every trigger-event producer must require **all** declared
133
+ system roles. Ungated commands/captures/reaction productions warn; opaque gates
134
+ are information, not proven safe. An OR alternative does not require a role.
135
+ Clock/application triggers have no producer and are silent; still review trust.
127
136
  5. **Trace inputs.** Every trigger value, command input, event property and destination needs a
128
137
  supported source; every filter a business reason. Gaps are questions, not invented mappings.
129
138
  6. **Repetition and termination.** Identify one logical work occurrence and what a retry is. Guard the
@@ -140,7 +149,7 @@ or actor that nobody confirmed. Read `references/worked-integration.md` when you
140
149
  ## Rules
141
150
  **Compiler contracts** (diagnostics at 4.66.0)
142
151
  - No inline `produces event` in a reaction (PLAY0474); declare reaction-produced events in the slice.
143
- - Effects sit under a trigger; only `description` and `where` are reaction-level; one `where` per
152
+ - Effects sit under a trigger; `description`, `where` and current `runs as` are reaction-level; one `where` per
144
153
  reaction (PLAY0252); a trigger may not repeat (PLAY0253).
145
154
  - Clock triggers take no values (PLAY0450) and no `by` on reads (PLAY0443). `for each <View>` is
146
155
  reserved, not available.
@@ -161,7 +170,7 @@ or actor that nobody confirmed. Read `references/worked-integration.md` when you
161
170
  record. A fan-out records one outcome per item; partial success is failure at an effect boundary
162
171
  (`cratis-engineering-effect-boundaries`), never a batch "done" while members failed.
163
172
  - Infrastructure (logging, caching, retries, outbox plumbing) is never a Translate slice.
164
- - Personal data kept in events needs `@pii` on its concept; keep it even when it blocks binding or render.
173
+ - Personal data kept in events needs `pii` on its concept; keep it even when it blocks binding or render.
165
174
  - Code bodies (`file`, inline fences) document realization; no local engine runs them.
166
175
 
167
176
  **Review questions**
@@ -77,7 +77,8 @@ scenario, claim/unknown semantics and PLAY0647–0652/0557 diagnostics.
77
77
 
78
78
  CLI 3.41.0's 4.114.0 compiler rejects this source with PLAY0137; its version gate
79
79
  and Stage 4.51.3 planner admit only through v7. Target realization is gap-fill,
80
- using Arc `[ExecuteCommandsAsSystem]` for returned commands. Each invoked command
80
+ using Arc `[ExecuteCommandsAsSystem]` for returned commands. Without that attribute
81
+ Arc supplies no principal and `[Authorize]`/`[Roles]` deny. Each invoked command
81
82
  is atomic, not the whole cascade; earlier accepted facts remain after a later refusal.
82
83
 
83
84
  ⚠️ **Declared, not enforced.** A trigger `reads` gives no runtime protection. From
@@ -177,7 +178,7 @@ optional.
177
178
 
178
179
  ⚠️ **Indentation decides what is a trigger and what is an effect.** `produces`,
179
180
  `invokes`, `file` and inline code belong **inside** the trigger block, indented
180
- under `when`/`every`/`at`. Only `description` and `where` sit at reaction level.
181
+ under `when`/`every`/`at`. `description`, `where` and `runs as` sit at reaction level.
181
182
  Outdenting an effect gives *Expected a trigger in reaction body, got 'invokes …'*
182
183
  (`PLAY0137`) — the compiler is looking for another trigger where the effect is.
183
184
 
@@ -239,7 +240,7 @@ append-time constraints. `invokes` asks for a command, which additionally runs t
239
240
  command's authorization, validation and requirements, and may reject.
240
241
  Using `produces` for both would say those are the same kind of consequence.
241
242
 
242
- **Who is the caller of an `invokes`?** Nobody; see *Caller-less invokes and unprotected reads* above before writing one.
243
+ **Who is the caller of an `invokes`?** Nobody unless `runs as` declares the actor; see *Caller-less invokes and unprotected reads* above before writing one.
243
244
 
244
245
  Both are declarations of *what happens*, not of how — a trigger can state its
245
246
  consequences **and** carry a `file` or an inline block in a tagged fence
@@ -32,7 +32,7 @@ source is the single flow model.
32
32
  | `Cratis.Screenplay` | main `fd18129` | Inline events, repairs and canonical `optional`; changed examples compiled |
33
33
  | `Cratis.Screenplay` | `4.66.0` (`c89198b`) | Binding behaviour of `handler`, code attachments, `persona` and compliance attributes: `Semantics/SemanticModelBinder*.cs`, `Diagnostics/DiagnosticCodes.cs` |
34
34
  | `Cratis.Screenplay` | `4.68.0` (`79801bf`) | Historical generated-value/response rule probes (ESM v7) |
35
- | `Cratis.Screenplay` | `4.125.0` | Current source guidance: routes, operations, negation, protected identifiers and pre-generation contexts; released `commands.md`, `operations.md`, `policies.md`, `context.md`, `diagnostics.md` |
35
+ | `Cratis.Screenplay` | `4.127.0` | Current identity and compliance guidance: released `identity.md`, `context.md`, `concepts.md`, `purposes.md`, `events.md`, `diagnostics.md`; changed examples compiled |
36
36
 
37
37
  Historical examples/probes retain the table's original versions; current source
38
38
  guidance is not a relabeled old execution result. Compilation checks syntax and
@@ -50,8 +50,8 @@ concept DiscountPercentage : Decimal
50
50
  validate
51
51
  >= 0 message "A discount cannot be negative"
52
52
  <= 100 message "A discount cannot exceed 100 percent"
53
- concept PersonName : String @pii
54
- pii reason "Billing contact name; lawful basis: contract performance."
53
+ concept PersonName : String pii
54
+ pii reason "Identifies the billing contact."
55
55
  concept InvoiceStatus : Enum
56
56
  draft
57
57
  sent
@@ -61,31 +61,19 @@ concept InvoiceStatus : Enum
61
61
  The seven primitives are `Uuid`, `String`, `Int`, `Decimal`, `Bool`, `Date` and
62
62
  `DateTime`. `Enum` is **not** one of them — it is a separate concept kind, which
63
63
  is why the compiler says *expected … or Enum* rather than listing it among them.
64
- Attributes `@pii` and `@sensitive`, each with at most one `reason`; a
65
- reason for an attribute the concept does not declare is an error. **Compliance is
66
- inherited** — a property typed with a `@pii` concept is PII everywhere. The
67
- executable model does not bind compliance attributes (`PLAY0268`, "compliance attributes
68
- require portable data-subject semantics"), so a `@pii` model stops at authorable (V1);
69
- keep the attribute, because the classification is the point, and never drop it to bind
70
- or render.
71
-
72
- `@pii` is personal data (erasable); `@sensitive` is an **operational secret** (API key,
73
- token, a company's bank account number): encrypted at rest without erasure and withheld
74
- from the causation chain (Screenplay decision 0034, Screenplay#384). C# providers render
75
- `@sensitive` as `[Encrypted]` + `[NotAudited]`, `@pii` as `[PII]`, and `@pii @sensitive`
76
- as `[PII]` only, because Chronicle rejects `[PII]` with `[Encrypted]` (`CHR0053`); Stage
77
- renders this from v4.29.0. The executable model still stops at `PLAY0268` for either.
78
-
79
- ⚠️ **Identifiers are neither `@pii` nor `@sensitive`.** Chronicle rejects `[PII]` on an
80
- event source id (`CHR0034`) and `[Encrypted]` on one (`CHR0052`); Screenplay reports
81
- `PLAY0515` for `@pii` from Screenplay 4.69.1 and for `@sensitive` from 4.84.1, on a
82
- command identifier, an explicit `for` destination or an event source identifier; earlier
83
- versions compile it silently and only Chronicle catches it. Current PLAY0515
84
- also covers scalar stream-id types, composite parts and nested route mapping
85
- sources. It is a source error, including typed destinations, not a binding-only
86
- warning. Keep the stream identity a surrogate `Uuid`
87
- concept and carry the personal value (name, email) as a separate `@pii` property and a
88
- secret as a `@sensitive` property.
64
+ Use bare `pii` for personal data (`personal` is the same marker) and `secret`
65
+ for operational secrets. **Compliance is inherited** from concepts, including
66
+ nested uses. Either marker blocks executable binding with PLAY0268; keep the
67
+ protection. `pii personal` is redundant and warns PLAY0653. Legacy `@pii`,
68
+ `sensitive` and `@sensitive` remain accepted with PLAY0565 information and a repair.
69
+ Read [compliance and purposes](references/compliance.md) for reasons, special/criminal
70
+ qualifiers, secret scopes, provider mappings, purpose declarations and coverage checks.
71
+
72
+ **Identifiers cannot be personal data or secrets.** PLAY0515 is a source error
73
+ for command identifiers, typed `for` destinations, event-source identities,
74
+ scalar/composite stream-id types and nested route mapping sources, including legacy
75
+ markers. Keep a surrogate identity and carry protected data in the payload.
76
+ Chronicle likewise rejects `[PII]`/`[Encrypted]` identifiers (CHR0034/CHR0052).
89
77
 
90
78
  ⚠️ **Enum trap.** A value literally named `validate` is read as an empty validate
91
79
  block. Write `@validate` for the value; the compiler warns when it sees the
@@ -244,8 +232,8 @@ choosing or omitting `for` on a production, or fixing `PLAY0469`-`PLAY0478`.
244
232
 
245
233
  - **Mapping sources** that bind to the executable model: a command property
246
234
  (`= invoiceNumber`), a literal (`= "draft"`, `= 0`), `$context.occurred`, and
247
- the caller's audit identity (`$context.identity.id`/`.name`/`.userName`, the
248
- same values as `$context.causedBy.*`). The last two select ESM v2.
235
+ the caller's audit identity (`$identity.id`/`.name`/`.userName`, also supported
236
+ as `$context.identity.id`/`.name`/`.userName`, the same values as `$context.causedBy.*`). The last two select ESM v2.
249
237
  `$context.tenant`, claims, roles, causation, `$env.` values, templates and
250
238
  computed expressions parse but block binding (`PLAY0268`).
251
239
  - **`for <identifier>`** on an indented line names the event source the event is
@@ -272,8 +260,12 @@ produces when isProForma == true
272
260
 
273
261
  ## Routes and external operations
274
262
 
275
- Named event sources/streams and command routes bind as ESM v8 at 4.125.0;
276
- CLI 3.41.0 render rejects models above v7. The complete checked route example
263
+ Named event sources/streams and command routes bind as ESM v8 (verified at 4.125.0);
264
+ CLI 3.41.0 render rejects models above v7. A routed command's identifier and
265
+ known event destinations must match the source's nominal identifier type
266
+ (PLAY0504, error). Allocation uses the generated identifier's type, or without
267
+ one requires a UUID-based source. Composite `streamId` routes map every named
268
+ part exactly once; scalar `streamId T` and `streamId = x` remain valid. The complete checked route example
277
269
  and nested `streamId =` form are in `cratis-screenplay-toolchain`
278
270
  `references/sources-and-streams.md`.
279
271
 
@@ -353,7 +345,15 @@ not both win — a `validate` rule cannot do that.
353
345
  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
354
346
  declaring a policy, a persona, or a `seed` block.
355
347
 
356
- ## `$context`
348
+ ## Event data subject
349
+
350
+ One event property may carry trailing `subject`; it identifies the person whose
351
+ data the event holds, not the stream identity. Only unprotected required scalar
352
+ String/Uuid or String/Uuid/Int-backed concepts are allowed. The mark is report-only
353
+ (PLAY0270), changes no ESM bytes and emits no C# `[Subject]` yet; read models are
354
+ not supported. See [subject lineage](references/compliance.md#identify-the-person-not-the-stream).
355
+
356
+ ## `$context` and `$identity`
357
357
 
358
358
  Four contexts, and **what each omits is load-bearing** — when writing a code body or a context/expression mapping, read
359
359
  [context.md](references/context.md) for the full member lists, the declarative
@@ -369,7 +369,7 @@ Four contexts, and **what each omits is load-bearing** — when writing a code b
369
369
  ## Verify
370
370
 
371
371
  - [ ] Validate the complete model root with warnings as errors; name the tool,
372
- version and result. Current pins: standalone 4.125.0 / CLI 3.41.0; bundle
372
+ version and result. Current pins: standalone 4.127.0 / CLI 3.41.0; bundle
373
373
  compatibility and execution are separate checks.
374
374
  - [ ] No unintended `PLAY0478` or `PLAY0479` information remains.
375
375
  - [ ] At most one command property carries `identifier`, and no event property does.
@@ -379,8 +379,9 @@ Four contexts, and **what each omits is load-bearing** — when writing a code b
379
379
  is stated.
380
380
  - [ ] Constraints are `unique` forms; no `file` constraint stands in for another rule.
381
381
  - [ ] Each policy has one `require` or one implementation, not both.
382
- - [ ] Personal data is `@pii` on the concept, with a reason; no identifier concept is `@pii`;
383
- operational secrets are `@sensitive` (never `@pii`), and no identifier concept carries either.
382
+ - [ ] Personal data is `pii` on the concept; operational secrets are `secret`;
383
+ no identifier or subject concept carries either. Reasons explain the value,
384
+ while purposes declare basis/retention; run `--check purposes` separately.
384
385
  - [ ] No `handler` where the model must bind, and no bodied construct described as
385
386
  runnable or renderable without saying which tool admits it.
386
387
  - [ ] No event carries an optional property covering two situations.
@@ -0,0 +1,154 @@
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
+ # Personal data, secrets and processing purposes
5
+
6
+ ## Contents
7
+
8
+ - Classify the value on its concept
9
+ - Declare the use separately
10
+ - Identify the person, not the stream
11
+
12
+ Authority: Screenplay v4.127.0 `concepts.md`, `purposes.md`, `events.md` and
13
+ `diagnostics.md`; decision 0041. These declarations do not establish lawful
14
+ processing or enforce retention. Check provider support separately.
15
+
16
+ ## Classify the value on its concept
17
+
18
+ ```screenplay
19
+ concept Email : String pii
20
+ pii reason "Contact address"
21
+ concept MedicalNote : String personal
22
+ personal special health
23
+ concept ConvictionNote : String pii
24
+ pii criminal
25
+ concept PartnerApiKey : String secret
26
+ secret scope namespace
27
+ secret reason "Credential for the partner API"
28
+ ```
29
+
30
+ `personal` is an alias of `pii`, not a second classification; canonical printing
31
+ writes `pii`. Write one marker. `pii personal`, `pii pii`, `secret secret` and
32
+ `@pii @pii` report one PLAY0653 warning per header. Both compilers retain the
33
+ first occurrence of each marker and attach body settings to it. The concept-line
34
+ repair removes later tokens with `PreserveTrivia`, retaining notes and comments.
35
+
36
+ `@pii`, `sensitive` and `@sensitive` still compile but are deprecated: one PLAY0565
37
+ information diagnostic per line. The line/document repair migrates them to bare
38
+ `pii`/`secret` without moving notes. `--warnaserror` does not fail on information.
39
+ Unknown markers report PLAY0566. Never remove protection to get a model to bind.
40
+
41
+ A reason is an optional free-text note about the value, not a lawful basis,
42
+ purpose or retention policy. At most one reason per declared marker; a reason for
43
+ an absent marker is an error. Classification is inherited through concept uses,
44
+ including fields nested in composite types; do not put markers on properties or
45
+ composite types.
46
+
47
+ `pii special` requires one of `racialOrEthnicOrigin`, `politicalOpinions`,
48
+ `religiousOrPhilosophicalBeliefs`, `tradeUnionMembership`, `genetic`, `biometric`,
49
+ `health`, `sexLifeOrSexualOrientation` (GDPR Art. 9(1)). `pii criminal` records
50
+ Art. 10 data and may coexist with `special`. These qualifiers require `pii`;
51
+ unknown categories and repeated `special` lines are errors (PLAY0570/0571).
52
+ A photograph alone is not biometric identification data.
53
+
54
+ `secret scope` accepts `subject`, `namespace`, `global`; omitted scope retains
55
+ Chronicle's Subject default. Scope on `pii`, duplicate scope and unknown values
56
+ are errors (PLAY0567/0568). Explicit scope on `pii secret` warns (PLAY0569),
57
+ because only `[PII]` renders. Changing scope for persisted event uses requires a
58
+ new event generation.
59
+
60
+ C# provider mapping: `pii` → `[PII]`; `secret` → `[Encrypted]` + `[NotAudited]`;
61
+ `pii secret` → `[PII]` only (Chronicle refuses `[PII]` with `[Encrypted]`, CHR0053).
62
+ This mapping is not admission: either marker, including qualifiers and scopes,
63
+ still blocks executable binding with PLAY0268. Subject lineage is a different
64
+ role, described below.
65
+
66
+ ## Declare the use separately
67
+
68
+ ```screenplay
69
+ concept ContactName : String pii
70
+ pii reason "Identifies the customer's contact"
71
+ purpose Billing
72
+ description "Issue invoices and collect payment"
73
+ basis contract
74
+ subjects customer, customerContact
75
+ retention "Until the customer relationship ends"
76
+ recipient "Payment provider"
77
+ module Finance
78
+ purpose Billing
79
+ feature Invoices
80
+ slice StateChange RecordContact
81
+ command RecordContact
82
+ name ContactName
83
+ ```
84
+
85
+ A top-level `purpose` has optional singleton `description`, `basis` (optional
86
+ quoted legal reference), `interest`, `condition` (optional quoted reference),
87
+ `authorization`, `subjects` (comma-separated categories), `retention`, and
88
+ `erasure exception`; `recipient` and `transfer "<destination>" safeguard
89
+ "<safeguard>" repeat. Text fields are quoted; description also accepts a text
90
+ fence. Unknown closed values or repeated singleton fields are errors.
91
+
92
+ - `basis`: `consent`, `contract`, `legalObligation`, `vitalInterests`, `publicTask`,
93
+ `legitimateInterests` (Art. 6(1)). The last needs a nonblank `interest` statement;
94
+ inconsistent interest/basis warns (PLAY0601).
95
+ - `condition`: `explicitConsent`, `employmentLaw`, `vitalInterests`, `notForProfit`,
96
+ `madePublic`, `legalClaims`, `substantialPublicInterest`, `healthCare`,
97
+ `publicHealth`, `research` (Art. 9(2)).
98
+ - `erasure exception`: `expression`, `legalObligation`, `publicTask`,
99
+ `publicHealth`, `archiving`, `legalClaims` (Art. 17(3)).
100
+
101
+ Repeat `purpose <Name>` on modules, features or slices. Coverage is the **union**
102
+ of those references and ancestors' references, unlike authorization's AND rule.
103
+ Unresolved references warn (PLAY0600). Purpose metadata adds no ESM bytes and
104
+ reports PLAY0270; it does not implement consent, a legal hold or crypto-shredding.
105
+
106
+ Run `screenplay <root> --check purposes --warnaserror`: PLAY0602–0606 prompt for
107
+ uncovered personal data (including nested concepts), missing special-category
108
+ conditions, criminal authorization, bases and unused purposes. Ordinary compile
109
+ does not run this check. Findings are investigation prompts, never a legal verdict.
110
+
111
+ `screenplay report processing <root> --format markdown|json|csv` derives the
112
+ processing record; optional `--controller-name` and `--controller-contact` are
113
+ explicit inputs, never inferred. MCP `processing-record` returns revision-bound,
114
+ count/byte-bounded pages (`offset`, `expectedSourceRevision`); repeat controller
115
+ inputs across pages. Invalid source prevents reporting; binding is not required.
116
+ Opaque code/imports/runtime protections are not inferred. Zero purposes yields
117
+ zero rows, not compliance. Special/criminal data prompts a DPIA assessment, not a
118
+ claim of large-scale processing. An erasure exception with reachable `pii` flags
119
+ that per-subject crypto-shredding also destroys data kept for that purpose.
120
+ Move legal declarations out of old reasons by hand; repairs never guess them.
121
+
122
+ ## Identify the person, not the stream
123
+
124
+ An event property may end in `subject`, last among modifiers (before `=` on an
125
+ inline mapping). Each generation may choose one mark independently:
126
+
127
+ ```screenplay
128
+ concept CustomerId : Uuid
129
+ module Billing
130
+ feature Contact
131
+ slice StateChange ChangeContact
132
+ event CustomerContactChanged
133
+ customerId CustomerId subject
134
+ note String
135
+ ```
136
+
137
+ Required scalar `String`/`Uuid`, concepts over either, and Int-backed concepts
138
+ are allowed. Bare Int, optional/collection/composite values, enums, Decimal,
139
+ Bool and dates are refused. A `pii` or `secret` concept is refused because
140
+ `EventContext.Subject` is plaintext. Use a surrogate identity; an empty String
141
+ cannot be detected statically and Chronicle falls back to the event source.
142
+ Equal identity strings across entity kinds share one subject; favor Uuid.
143
+
144
+ PLAY0590–0595 cover multiple marks, invalid/protected types, wrong owner,
145
+ unsupported read-model marks and repeated/out-of-order modifiers. The mark is
146
+ report-only (PLAY0270): it changes no ESM bytes or runtime value and emits no
147
+ C# `[Subject]` yet. Without a supplied subject the runtime's
148
+ `$eventContext.subject` defaults to the event source. Do not promise propagation,
149
+ erasure, export or redaction from this declaration. MCP exposes `isSubject` and
150
+ event summaries' `subject.source` (`eventSource` or `property`).
151
+
152
+ The event data subject, `secret scope subject` (encryption scope), and policy
153
+ `matches subject` (the thing acted on, not the caller) are three different roles.
154
+ For actual Chronicle erasure and attributes, use `cratis-chronicle-compliance`.
@@ -5,6 +5,7 @@
5
5
  - The four contexts
6
6
  - The values they carry
7
7
  - Reaching the context declaratively
8
+ - Caller paths and identity details
8
9
  - Production metadata is not a context expression
9
10
  - The other expression roots
10
11
  - Templates and literals
@@ -97,6 +98,52 @@ roles, claims and causation report `PLAY0268`.
97
98
 
98
99
  An unknown `$context.` path is reported, so a typo does not silently become null.
99
100
 
101
+ ## Caller paths and identity details
102
+
103
+ At Screenplay 4.127.0, `$identity.<property>` is the same caller value as
104
+ `$context.identity.<property>`. Prefer `$identity` in new mappings; the older root
105
+ is supported, not deprecated. The `cratis` CLI 3.41.0 bundles Screenplay 4.114.0, which predates both:
106
+ its parser rejects a top-level `identity` block (`PLAY0001`), and with `--executable` it reads a
107
+ `$identity.<property>` mapping as a raw expression (`PLAY0268`). Check these with standalone 4.127.0,
108
+ and keep `$context.identity.<property>` where a model must go through `cratis render` today. Built-ins are `id`, `name`, `userName`,
109
+ `isAuthenticated`, `roles`, `claims.<name>` (everything after `claims.` is opaque).
110
+ Bare `$identity` reports PLAY0152; unknown properties report PLAY0155. Only
111
+ `$identity.id`/`.name`/`.userName` bind in portable `produces` mappings, exactly
112
+ like the older forms; roles, authentication status and claims still report PLAY0268.
113
+
114
+ A top-level `identity` block declares additional typed caller details:
115
+
116
+ ```screenplay
117
+ identity
118
+ description "What the application knows about whoever is calling"
119
+ department String optional from claim "department"
120
+ organization Organization optional from query MyOrganization by $identity.id
121
+ module Organizations
122
+ feature Membership
123
+ slice StateView Mine
124
+ readmodel Organization
125
+ name String
126
+ query MyOrganization => Organization optional
127
+ by userId String
128
+ ```
129
+
130
+ At most one block per document and assembled folder; layout expansion writes it
131
+ to `application.play`. Each unique detail has exactly one source: opaque claim,
132
+ keyed single-result query, tagged inline code fence or repository-relative `file`.
133
+ It cannot redeclare built-ins. Claim/query sources have no body; refresh/cache
134
+ belongs to the runtime. Query sources need `by <expression>` using only token
135
+ built-ins, claims or literals, never another detail, input, environment or view.
136
+ The query's effective authorization must not depend on details. Result type must
137
+ match; an optional query result needs an optional detail, while a required result
138
+ may populate an optional detail. Details may themselves be optional or collections.
139
+
140
+ The block is **authoring metadata**, not runtime source resolution or ESM data.
141
+ Declarations alone do not block executable readiness. Executable reads of
142
+ `$identity.<detail>` report PLAY0268; `$context.identity` stays built-ins only.
143
+ `scoped to` is an opaque scope name, not a detail reference. PLAY0633–0646 diagnose
144
+ source/header/type/cardinality errors; there are no automatic identity repairs.
145
+ Authority: v4.127.0 `identity.md`, `context.md`, `diagnostics.md`.
146
+
100
147
  ## Production metadata is not a context expression
101
148
 
102
149
  `namespace`, `sequence`, `correlation`, `causation`, `causedBy` and `occurred`
@@ -111,6 +158,7 @@ occurrence metadata; use `given clock`, never `given time`, to state scenario ti
111
158
 
112
159
  | Root | Where | Yields |
113
160
  | --- | --- | --- |
161
+ | `$identity.<property>` | caller expression | built-in caller value or declared authoring detail; execution admission is narrower |
114
162
  | `$env.<VAR_NAME>` | mapping sources | an environment variable |
115
163
  | `$eventContext.<property>` | **projections only** | `occurred`, `sequenceNumber`, `correlationId`, `eventSourceId` |
116
164
  | `$eventSourceId` | **projections only** | shorthand for `$eventContext.eventSourceId` |
@@ -1,7 +1,7 @@
1
1
  ## Generated values and responses (ESM v7)
2
2
 
3
3
  A `generated` command property and `returns` response bind and reference-execute
4
- as ESM v7. Current pins are standalone Screenplay 4.125.0 and CLI 3.41.0
4
+ as ESM v7. Current pins are standalone Screenplay 4.127.0 and CLI 3.41.0
5
5
  (bundled Screenplay 4.114.0/Stage 4.51.3); `cratis-screenplay-toolchain`
6
6
  `references/versions.md` owns the table. CLI#261 is closed: CLI now admits v7
7
7
  to Stage planning, but its v7 canonical corpus receives Stage generated-value
@@ -3,6 +3,12 @@
3
3
  "input": "Declare a Screenplay command with validation, authorization, a uniqueness constraint and a state-dependent rule.",
4
4
  "fixtures": [],
5
5
  "assertions": [
6
+ { "kind": "skill-contains", "value": "PLAY0653" },
7
+ { "kind": "skill-contains", "value": "personal` is an alias of `pii", "file": "references/compliance.md" },
8
+ { "kind": "skill-contains", "value": "report-only (PLAY0270)", "file": "references/compliance.md" },
9
+ { "kind": "skill-contains", "value": "--check purposes", "file": "references/compliance.md" },
10
+ { "kind": "skill-contains", "value": "PLAY0633–0646", "file": "references/context.md" },
11
+ { "kind": "skill-contains", "value": "The block is **authoring metadata**", "file": "references/context.md" },
6
12
  { "kind": "skill-contains", "value": "main `fd18129`" },
7
13
  { "kind": "skill-contains", "value": "produces event ProjectRenamed", "file": "references/inline-events.md" },
8
14
  { "kind": "skill-contains", "value": "name ProjectName = name", "file": "references/inline-events.md" },
@@ -54,7 +54,7 @@ Statements here were checked at those tags:
54
54
  | `<Type>[]`, shapes must be declared; `@pii` and `reason` on concepts | `v4.66.0:Documentation/screenplay/events.md`, `concepts.md` |
55
55
  | `then denied`, `given caller`, `then error` | `v4.66.0:Documentation/screenplay/specifications.md` |
56
56
  | PII on an event-source id is rejected by Chronicle (CHR0034); nullable event properties warn (CHR0012) | Chronicle `v19.32.0:Source/Clients/DotNET.CodeAnalysis/DiagnosticIds.cs` |
57
- | Any `@pii` or `@sensitive` on a concept fails binding (PLAY0268) | `v4.66.0:Source/DotNET/Screenplay/Semantics/SemanticModelBinder.Concepts.cs:21-24` |
57
+ | Any `@pii` or `@sensitive` on a concept fails binding (PLAY0268) at 4.66.0; current markers are in `cratis-screenplay-command-surface` | `v4.66.0:Source/DotNET/Screenplay/Semantics/SemanticModelBinder.Concepts.cs:21-24` |
58
58
 
59
59
  Every complete `screenplay` fence in this skill compiles with the standalone compiler
60
60
  4.68.0 (`--warnaserror`) and with `cratis screenplay validate --warnings-as-errors` 3.28.2.
@@ -123,8 +123,15 @@ decided apart from what you assumed. Never guess silently.
123
123
  two business facts that make it meaningful. A simple state transition may carry no payload
124
124
  beyond its identity: do not pad events with fields just to reach a count. Domain names; `<Type>[]` for collections (declare the `type`); a
125
125
  `concept` for a value with its own meaning; classify personal data on the concept with
126
- `@pii` and a reason now. `@pii` compiles but does not bind (PLAY0268 at 4.66.0): record it
127
- as a known target gap; never drop it to get a clean result.
126
+ bare `pii` and a reason now; operational secrets use `secret` (4.127.0).
127
+ Either blocks binding (PLAY0268); record the gap, never drop protection.
128
+ Ask what use, lawful basis, retention, recipient/transfer and erasure needs the
129
+ data serves; declare those in a `purpose`, not a concept reason. Special/criminal
130
+ qualifiers describe the value, not legal permission. See command-surface
131
+ `references/compliance.md` for purpose coverage checks and the processing record.
132
+ For who-is-calling details, distinguish token claims from a keyed single-result
133
+ identity-source query or opaque implementation. The `identity` block is metadata;
134
+ executable detail reads remain unsupported. See `references/context.md` in command-surface.
128
135
  7. **Validate, gate, hand off.** After a coherent batch of edits (not every sentence) run V1
129
136
  with the tool and version named (`cratis-screenplay-toolchain`). Stop storming a workflow
130
137
  when the user says it is complete or both closing questions return nothing new; unattended,
@@ -21,7 +21,7 @@ assumption you take instead of asking.
21
21
  | Outside | Which outside parties or systems send or receive information here? | Later translations and contracts | they send facts we rely on: ask how we recognise which of our records it concerns |
22
22
  | Corrections | Can a recorded fact turn out wrong? How is it put right today? | Correction and reversal events instead of edits | "we just edit it": ask who needs to know it was changed |
23
23
  | History | What would an auditor, a regulator or an angry customer ask to see later? | Finds facts that look like detail but must be kept | a calculation must be shown later: treat it as a fact |
24
- | People's data | Which values identify or describe a person? How long may we keep them? | `@pii` on concepts before event shapes settle | data about two people in one fact: consider separate facts |
24
+ | People's data | Which values identify or describe a person? For what use, basis, retention, recipients/transfers and erasure exceptions? | bare `pii` on concepts; purpose declarations separate from reasons | special/criminal data needs declared safeguards; two people in one fact may need separate facts |
25
25
  | Volume | How often does this happen, and how long does one instance live? | Informs stream design later; never a reason to drop a fact | an instance lives for years: note it for stream review |
26
26
  | Input | What do we have to go on: written rules, a rough list, word of mouth, a running system? | Sets how hard to sweep | only word of mouth: run every sweep lens |
27
27
  | Who decides | Who has the final word on what this means for the business? | Separates decisions from assumptions | no one present: mark meaning as assumption to confirm |
@@ -53,7 +53,7 @@ Framework repositories and brownfield work that has not opted in stay code-first
53
53
  handlers, adapters, and scope Stage cannot render yet (the model stays the contract).
54
54
  - **Never:** use code as a shortcut around the model; change the model to match
55
55
  existing code; edit Stage-managed output; leave a modeled rule living only in
56
- code; weaken protection (authorization, `@pii`, rules) so a model compiles or renders.
56
+ code; weaken protection (authorization, `pii`, rules) so a model compiles or renders.
57
57
 
58
58
  **2. Run the lifecycle.** Load `cratis-screenplay-modeling-lifecycle` for modes, the
59
59
  independent verdicts V1-V5, the P0-P9 phases with their gates, stop-or-assume,
@@ -131,7 +131,7 @@ What binds depends on **which tool** you ask, so name the tool and its version:
131
131
  - `reads` and `concurrency` on a command do not bind (`PLAY0271`), so no decision is
132
132
  protected against stale state. A reaction trigger's `reads` that only `invokes` is
133
133
  report-only intent (`PLAY0270`); one that `produces` directly fails binding (`PLAY0268`).
134
- - `persona` declarations are report-only and never block; `@pii` and `@sensitive`
134
+ - `persona` declarations are report-only and never block; bare `pii` and `secret`
135
135
  concepts do block binding (`PLAY0268`). Keep them anyway: the classification is
136
136
  part of the model. Report the block.
137
137
  - Generated values/responses bind and reference-execute as v7; sources, streams
@@ -243,7 +243,7 @@ compile or will not be safe. Both are deliberate.
243
243
  ## Naming the primitives is the highest-value work
244
244
 
245
245
  Name concepts before events, classify personal data at the concept, keep events past tense and single-purpose, and never put the event-source identity in an event payload.
246
- Read [references/naming-primitives.md](references/naming-primitives.md) when declaring concepts, `@pii` classification, event shapes, `identifier`, inline events or `id "<old name>"` pins.
246
+ Read [references/naming-primitives.md](references/naming-primitives.md) when declaring concepts, `pii` classification, event shapes, `identifier`, inline events or `id "<old name>"` pins.
247
247
 
248
248
  ## Quick gate - before specifications are called done
249
249
 
@@ -5,10 +5,12 @@
5
5
  `Decimal`, `Bool`, `Date` and `DateTime`; `Enum` is a separate concept kind,
6
6
  with its values indented beneath.
7
7
  - **Classify personal data at the concept**, with a reason:
8
- `concept PersonName : String @pii` plus an indented `pii reason "..."`. Every
8
+ `concept PersonName : String pii` plus an indented `pii reason "..."`. Every
9
9
  usage inherits it; a reason for an attribute the concept does not declare is an
10
- error. Decide this before fixing event shapes - erasure follows the subject and
11
- the subject follows the stream.
10
+ error. Decide this before fixing event shapes; purpose/basis/retention belong in
11
+ processing-purpose declarations, not a reason. An event subject defaults to the
12
+ source unless supplied; the trailing event-property `subject` mark is report-only
13
+ at 4.127.0, not runtime lineage. See command-surface `references/compliance.md`.
12
14
  - **Events are past tense and self-describing** - `InvoiceRegistered`, never
13
15
  `Created`. One purpose per event; an event needing an optional property to cover
14
16
  two situations is two events.
@@ -22,7 +22,9 @@ Pins and consumer boundaries: toolchain `references/versions.md`.
22
22
  | Construct | Current standalone disposition |
23
23
  | --- | --- |
24
24
  | `persona`, domain/authentication metadata | Report-only; unknown named policies remain source defects |
25
- | Compliance concepts | Preserve protection; portable binding gaps are not permission to remove it |
25
+ | Compliance concepts | Bare `pii`/`secret` (4.127.0); binding still refuses PLAY0268, never remove protection |
26
+ | Identity details / processing purposes / event subject | Report-only metadata (4.127.0); executable detail reads refuse PLAY0268, not source declaration errors |
27
+ | Composite stream ids | v8 routing; complete named parts/canonical comparisons, PLAY0515 refuses protected keys/sources; not a legacy text split |
26
28
  | Command reads/concurrency | Legacy unprotected decisions, PLAY0271 |
27
29
  | Invokes-only trigger reads | Report-only, not protected state; direct production with reads refuses |
28
30
  | Generated values/responses | v7 binding/reference execution; Stage 4.51.3 member refusals STAGE-ESM-028/029 |
@@ -153,7 +153,15 @@ chain per slice before handoff (evidence template); never manufacture references
153
153
  in the model today**, target named; a unique index with business meaning becomes
154
154
  `unique ... on <every event that sets it>` with `released by`
155
155
  (`references/rule-modeling.md`);
156
- - keep `@pii` / `@sensitive` and authorization found in code; every role gate has `authorize`
156
+ - preserve personal-data/secret protection and authorization found in code,
157
+ using bare `pii` / `secret` (4.127.0); deprecated marker repairs keep legal
158
+ notes intact, never guess a purpose or basis. Derive purpose/use/retention
159
+ declarations only from evidence or expert decisions; run `--check purposes`
160
+ and inspect the processing record as prompts, not a legal verdict. Keep
161
+ hand-joined legacy ids scalar; never infer composite parts by splitting text.
162
+ Event `subject` is report-only; distinguish observed lineage from runtime
163
+ realization. See command-surface `references/compliance.md`.
164
+ Every role gate has `authorize`
157
165
  plus a `then denied` spec, else a recorded gap; rules you cannot express truthfully are
158
166
  recorded one by one, never fabricated.
159
167
  3. Cite evidence ids in each slice `description` ("Evidence: E3, E7"). Read `references/intent-example.md` when authoring the intentional candidate to check the complete example of evidence citations, re-slicing, constraints, authorization and recorded state-dependent rules.
@@ -195,7 +203,7 @@ handoff packet appended, first line `Outcome:`; no prose reports in the model ro
195
203
  same-application canonical exports with authoritative catalogs; it does not guess
196
204
  rename continuity, run specifications or prove recovered behavior. Inspect
197
205
  incomplete sections and exclusions before using the result in the loss report.
198
- - Never weaken protection (authorization, `@pii`, rules) to make the candidate compile.
206
+ - Never weaken protection (authorization, `pii`, rules) to make the candidate compile.
199
207
 
200
208
  ## Gate
201
209
 
@@ -23,7 +23,7 @@ contract is in `cratis-screenplay-ui-composition`.
23
23
 
24
24
  ## Verified product sources
25
25
 
26
- Current authoring/MCP guidance follows Screenplay v4.125.0
26
+ Current authoring/MCP guidance follows Screenplay v4.127.0
27
27
  `Documentation/screenplay/mcp/`, `ast-authoring.md`, `folders.md`, `vscode.md`.
28
28
  Discover installed tools and schemas; CLI bundles can differ from the standalone
29
29
  tool. Pins are in `cratis-screenplay-toolchain` `references/versions.md`.
@@ -178,6 +178,8 @@ each lost comment (`PLAY0288` also reports their count and lines). Untouched
178
178
  documents retain exact bytes. A printer that loses requested structural fields
179
179
  rejects the plan.
180
180
 
181
+ `identityMigrationIssues`: read the [MCP loop](references/mcp-loop.md).
182
+
181
183
  ## Repair or extract before rewriting
182
184
 
183
185
  Read `read-workspace` with `view: "diagnostics"`, then `view: "repairs"` at the
@@ -199,6 +201,7 @@ from silently changing the reviewed candidate.
199
201
  No automatic generation-evolution repair ships.
200
202
  - `PLAY0479`: migrate optionality spelling with `PreserveTrivia`; document scope
201
203
  migrates all occurrences together. Keep the `query Q => observable?` exception.
204
+ - Compliance repairs PLAY0565/0653: [MCP tool guide](references/mcp-tools.md).
202
205
 
203
206
  Use `propose-extract-inline-event` on the inline `EventSyntax` handle before adding
204
207
  a generation (canonical formatting consent; refuses comment loss; no reverse
@@ -303,7 +306,7 @@ a generated app that silently drops authored UI. Use the Screenplay-owned canoni
303
306
  corpus fixture path when it exists instead of copying `.play` examples into this
304
307
  repository.
305
308
 
306
- Repair and refactoring guidance follows Screenplay v4.125.0. The Cratis
309
+ Repair and refactoring guidance follows Screenplay v4.127.0. The Cratis
307
310
  CLI bundles its own Screenplay version, so check the installed `tools/list`
308
311
  schemas before relying on a view or argument named here (for example
309
312
  `dropped-comments` or `implementation-requirements`). Do not invent a command,