@cratis/pi 7.21.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 (81) hide show
  1. package/package/corpus/skills/cratis-screenplay-automations-and-translations/SKILL.md +31 -15
  2. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/audit-format.md +4 -3
  3. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/automation-patterns.md +13 -15
  4. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/cases-to-specify.md +4 -4
  5. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/effects-and-idempotency.md +21 -0
  6. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/provenance.md +4 -2
  7. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/todo-list-example.md +7 -4
  8. package/package/corpus/skills/cratis-screenplay-automations-and-translations/verification.json +4 -4
  9. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/SKILL.md +41 -38
  10. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/complete-examples.md +1 -1
  11. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/invocation-identity.md +84 -0
  12. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/refusals-and-redelivery.md +102 -0
  13. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/specifying-triggers-and-clock.md +4 -2
  14. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/verification.json +1 -1
  15. package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +57 -44
  16. package/package/corpus/skills/cratis-screenplay-command-surface/references/compliance.md +154 -0
  17. package/package/corpus/skills/cratis-screenplay-command-surface/references/context.md +57 -0
  18. package/package/corpus/skills/cratis-screenplay-command-surface/references/generated-values-and-responses.md +15 -13
  19. package/package/corpus/skills/cratis-screenplay-command-surface/references/operations.md +80 -0
  20. package/package/corpus/skills/cratis-screenplay-command-surface/references/policy-persona-seed.md +23 -1
  21. package/package/corpus/skills/cratis-screenplay-command-surface/verification.json +8 -2
  22. package/package/corpus/skills/cratis-screenplay-discovery/SKILL.md +19 -9
  23. package/package/corpus/skills/cratis-screenplay-discovery/references/interview-questions.md +1 -1
  24. package/package/corpus/skills/cratis-screenplay-discovery/references/storming-loop.md +6 -5
  25. package/package/corpus/skills/cratis-screenplay-event-modeling/SKILL.md +10 -8
  26. package/package/corpus/skills/cratis-screenplay-event-modeling/references/naming-primitives.md +5 -3
  27. package/package/corpus/skills/cratis-screenplay-event-modeling/references/nine-steps.md +6 -5
  28. package/package/corpus/skills/cratis-screenplay-event-modeling/references/parsed-not-runnable.md +41 -49
  29. package/package/corpus/skills/cratis-screenplay-legacy-extraction/SKILL.md +15 -5
  30. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/generate-notes.md +48 -8
  31. package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +47 -42
  32. package/package/corpus/skills/cratis-screenplay-model-authoring/references/language-reference.md +79 -15
  33. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-loop.md +49 -11
  34. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +155 -14
  35. package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +3 -3
  36. package/package/corpus/skills/cratis-screenplay-model-review/SKILL.md +19 -7
  37. package/package/corpus/skills/cratis-screenplay-model-review/references/anti-patterns.md +1 -1
  38. package/package/corpus/skills/cratis-screenplay-model-review/references/checklist.md +11 -2
  39. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/SKILL.md +3 -3
  40. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/completeness-self-check.md +1 -1
  41. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/verdicts-and-modes.md +1 -1
  42. package/package/corpus/skills/cratis-screenplay-read-surface/SKILL.md +17 -0
  43. package/package/corpus/skills/cratis-screenplay-read-surface/references/guarded-actions.md +79 -0
  44. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/SKILL.md +11 -9
  45. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/gap-fill-handoff.md +6 -3
  46. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/renderability-gate.md +1 -1
  47. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/verification.json +2 -2
  48. package/package/corpus/skills/cratis-screenplay-scenario-coverage/SKILL.md +3 -2
  49. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/spec-forms-by-mode.md +13 -2
  50. package/package/corpus/skills/cratis-screenplay-slice-design/SKILL.md +13 -3
  51. package/package/corpus/skills/cratis-screenplay-slice-design/references/command-inventory.md +5 -3
  52. package/package/corpus/skills/cratis-screenplay-slice-design/references/review-questions.md +2 -1
  53. package/package/corpus/skills/cratis-screenplay-slice-design/references/rule-layers.md +4 -3
  54. package/package/corpus/skills/cratis-screenplay-slice-design/references/slicing.md +40 -0
  55. package/package/corpus/skills/cratis-screenplay-specifications/SKILL.md +24 -16
  56. package/package/corpus/skills/cratis-screenplay-specifications/references/examples-and-routes.md +111 -0
  57. package/package/corpus/skills/cratis-screenplay-specifications/references/reactions-and-cascades.md +5 -6
  58. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/SKILL.md +22 -8
  59. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/chronicle-boundaries.md +8 -4
  60. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/consistency-and-concurrency.md +10 -0
  61. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/stream-patterns.md +13 -2
  62. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/streams-example.md +3 -3
  63. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/verification.json +2 -2
  64. package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +44 -35
  65. package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet-example.md +3 -3
  66. package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet.md +58 -2
  67. package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +128 -10
  68. package/package/corpus/skills/cratis-screenplay-toolchain/references/doc-contradictions.md +13 -1
  69. package/package/corpus/skills/cratis-screenplay-toolchain/references/executable-subset.md +37 -13
  70. package/package/corpus/skills/cratis-screenplay-toolchain/references/provenance.md +10 -2
  71. package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +23 -1
  72. package/package/corpus/skills/cratis-screenplay-toolchain/references/sources-and-streams.md +111 -27
  73. package/package/corpus/skills/cratis-screenplay-toolchain/references/traps.md +27 -6
  74. package/package/corpus/skills/cratis-screenplay-toolchain/references/verdicts.md +34 -16
  75. package/package/corpus/skills/cratis-screenplay-toolchain/references/versions.md +98 -136
  76. package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +13 -5
  77. package/package/corpus/skills/cratis-screenplay-ui-composition/references/screen-composition-contract.md +20 -0
  78. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +10 -6
  79. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +8 -1
  80. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/verification.json +2 -2
  81. package/package.json +1 -1
@@ -0,0 +1,102 @@
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
+ # Refusal handling and redelivery intent
5
+
6
+ ## Contents
7
+
8
+ - Select a refusal
9
+ - Branch values and acknowledgement
10
+ - Redeliver an existing occurrence
11
+ - Recovery boundaries
12
+
13
+ ## Select a refusal
14
+
15
+ At Screenplay 4.125.0 these forms are authoring-only: binding refuses the whole
16
+ model with PLAY0268, even when the source is valid. Do not execute them as append
17
+ scenarios or silently drop branches. Sources: released `reactions.md`,
18
+ `specifications.md`, decision 0030.
19
+
20
+ Inside an `invokes` block, ordered selectors state intended recovery:
21
+
22
+ | Selector | Matches at future admission |
23
+ | --- | --- |
24
+ | `on refused` | Validation or constraint, not authorization |
25
+ | `on refused by validation` | Input/concept/require rejection |
26
+ | `on refused by constraint` | Any constraint rejection |
27
+ | `on refused by constraint <Name>` | One unambiguously resolved applicable constraint |
28
+ | `on refused by authorization` | Unauthorized, never an opaque policy's Unsupported result |
29
+
30
+ The first matching selector wins. Repeated selectors or narrower branches after
31
+ covering branches report PLAY0540; bare refusal does not cover authorization.
32
+ Unknown named constraints report PLAY0542; known but inapplicable constraints
33
+ also report PLAY0540. Authorization recovery requires a deliberate trusted path,
34
+ not a fictional caller supplied by `given caller`. On current source a declared
35
+ reaction `runs as` affects identity diagnostics, but refusal branches themselves
36
+ remain unadmitted; do not infer their execution from that separate capability.
37
+
38
+ ## Branch values and acknowledgement
39
+
40
+ A branch contains leaf `acknowledge` alone, or ordinary `produces <Event>` blocks
41
+ with mappings and optional `for`. Empty branches, repeated acknowledgement,
42
+ acknowledgement plus productions, operations, inline events and attachments refuse.
43
+ Acknowledgement states a terminal disposition, not a successful command or fact.
44
+
45
+ Branch event mappings may use String values `$refusal.reason` (validation,
46
+ constraint, authorization), `$refusal.message` (verbatim details, including symbolic
47
+ localization keys), and `$refusal.constraint` only in constraint selectors.
48
+ Unknown members, wrong scope or incompatible targets report PLAY0541. Messages
49
+ are display details, not stable identity; trigger inputs remain available, read
50
+ aliases do not become branch inputs.
51
+
52
+ The intended admitted behavior stops remaining invocations of that trigger after
53
+ handling a refusal, but lets other reactions/cascades from accepted facts settle.
54
+ The refused command adds no facts; branch appends obey normal constraints and
55
+ cannot catch their own refusal through another branch. Unhandled refusal retains
56
+ earlier accepted facts. This is a future contract, not passing runner behavior.
57
+
58
+ ## Redeliver an existing occurrence
59
+
60
+ The complete authoring model below compiles without warnings on 4.125.0;
61
+ `screenplay test` intentionally returns 3/unbound with PLAY0268 for redelivery
62
+ and no-event assertion, not a recovery pass:
63
+
64
+ ```screenplay
65
+ module Billing
66
+ feature Claims
67
+ slice Automation Recovery
68
+ event Approved
69
+ invoice String
70
+ reaction Claimer
71
+ when Approved
72
+ specification Recovery
73
+ given Approved
74
+ for "invoice-1"
75
+ invoice = "invoice-1"
76
+ when redelivered Approved to Claimer
77
+ for "invoice-1"
78
+ invoice = "invoice-1"
79
+ then no events
80
+ ```
81
+
82
+ `to <Reaction>` must resolve to one observer of the event (PLAY0544). Optional
83
+ `for`, payload values and stream/no-stream route narrow effective given occurrences;
84
+ exactly one definitely matching occurrence and no unknown candidates are required
85
+ (PLAY0543). Equal duplicate givens are still separate candidates. A locator with
86
+ no route is a wildcard; explicit stream ids compare canonically, and `no stream`
87
+ selects only unrouted givens. This is the sole action, not an extra action after
88
+ append. Intended delivery uses the existing occurrence, never appends it again.
89
+
90
+ Leaf `then no events` explicitly expects no new facts after a non-append action.
91
+ It may accompany view/query/response assertions, not events, any-order events,
92
+ error or denial. It is invalid after `when append` (PLAY0545), and remains
93
+ unadmitted even on a model without a refusal branch.
94
+
95
+ ## Recovery boundaries
96
+
97
+ Exceptions, infrastructure/contract errors, Unsupported and concurrency conflicts
98
+ are not refusals. There is no `by concurrency`: transient contention fails/retries,
99
+ not acknowledgement. Ordinary redelivery is not replay. Neither these forms nor
100
+ an observer/occurrence locator prove runtime deduplication, a cascade-wide
101
+ transaction, once-only delivery or exactly-once external effects. Specify the
102
+ actual recovery owner and target enforcement before making those claims.
@@ -18,8 +18,10 @@ specification IssuingTheWeeklyDigest
18
18
  ```
19
19
 
20
20
  Under `cratis` before 3.28.2 these actions parsed and were checked against the application
21
- but bound to nothing (`PLAY0268` names ESM v6, decision 0022); on 3.28.2 they bind. Either way
22
- no command runs them: report such a specification as authored, not executed. Clock rules: the clock is UTC and exact; an
21
+ but bound to nothing (`PLAY0268` names ESM v6, decision 0022); on 3.28.2 they bind.
22
+ Current standalone 4.125.0 executes admitted scenarios through `screenplay test`
23
+ or MCP `run-specifications`; source compilation alone is authored evidence.
24
+ Clock rules: the clock is UTC and exact; an
23
25
  occurrence fires once when it is **due after `given clock` and at or before
24
26
  `when clock`**, in time order; intervals count from the Unix epoch; `when clock`
25
27
  needs `given clock`, so equal instants fire nothing. Limits: 10,000 occurrences per
@@ -57,7 +57,7 @@
57
57
  },
58
58
  {
59
59
  "kind": "skill-contains",
60
- "value": "Screenplay#383"
60
+ "value": "ESM v10"
61
61
  },
62
62
  {
63
63
  "kind": "skill-contains",
@@ -31,16 +31,12 @@ source is the single flow model.
31
31
  | `Cratis.Screenplay` | `4.31.0` | Original examples and executable boundaries |
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
- | `Cratis.Screenplay` | `4.68.0` (`79801bf`) | Current pin: generated values and responses (ESM v7): decisions 0025 and 0026, `commands.md`, `Semantics/Versions.cs`, `SemanticModelBinder.CommandProductions.cs` |
34
+ | `Cratis.Screenplay` | `4.68.0` (`79801bf`) | Historical generated-value/response rule probes (ESM v7) |
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 |
35
36
 
36
- The update follows `commands.md`, `events.md`, `types.md`, `diagnostics.md`,
37
- `mcp/authoring-tools.md` and decision 0023 at that main commit (after v4.52.0).
38
- Compilation checks syntax and model consistency, not reference execution.
39
-
40
- Checked against the Screenplay repository at tag `v4.31.0` (commit `355dffb`):
41
- `Documentation/screenplay/{commands,constraints,policies,context,concepts,diagnostics}.md`
42
- and decisions 0001 and 0003 established the original baseline. Changed examples
43
- use the newer main commit above; do not attribute their verification to the old tag.
37
+ Historical examples/probes retain the table's original versions; current source
38
+ guidance is not a relabeled old execution result. Compilation checks syntax and
39
+ model consistency, not reference execution. Pins: toolchain `references/versions.md`.
44
40
 
45
41
  "Parses" and "runs" are different claims. The executable profile, and what
46
42
  each construct binds to, is in the `cratis-screenplay-model-authoring` language
@@ -54,8 +50,8 @@ concept DiscountPercentage : Decimal
54
50
  validate
55
51
  >= 0 message "A discount cannot be negative"
56
52
  <= 100 message "A discount cannot exceed 100 percent"
57
- concept PersonName : String @pii
58
- pii reason "Billing contact name; lawful basis: contract performance."
53
+ concept PersonName : String pii
54
+ pii reason "Identifies the billing contact."
59
55
  concept InvoiceStatus : Enum
60
56
  draft
61
57
  sent
@@ -65,28 +61,19 @@ concept InvoiceStatus : Enum
65
61
  The seven primitives are `Uuid`, `String`, `Int`, `Decimal`, `Bool`, `Date` and
66
62
  `DateTime`. `Enum` is **not** one of them — it is a separate concept kind, which
67
63
  is why the compiler says *expected … or Enum* rather than listing it among them.
68
- Attributes `@pii` and `@sensitive`, each with at most one `reason`; a
69
- reason for an attribute the concept does not declare is an error. **Compliance is
70
- inherited** — a property typed with a `@pii` concept is PII everywhere. The
71
- executable model does not bind compliance attributes (`PLAY0268`, "compliance attributes
72
- require portable data-subject semantics"), so a `@pii` model stops at authorable (V1);
73
- keep the attribute, because the classification is the point, and never drop it to bind
74
- or render.
75
-
76
- `@pii` is personal data (erasable); `@sensitive` is an **operational secret** (API key,
77
- token, a company's bank account number): encrypted at rest without erasure and withheld
78
- from the causation chain (Screenplay decision 0034, Screenplay#384). C# providers render
79
- `@sensitive` as `[Encrypted]` + `[NotAudited]`, `@pii` as `[PII]`, and `@pii @sensitive`
80
- as `[PII]` only, because Chronicle rejects `[PII]` with `[Encrypted]` (`CHR0053`); Stage
81
- renders this from v4.29.0. The executable model still stops at `PLAY0268` for either.
82
-
83
- ⚠️ **Identifiers are neither `@pii` nor `@sensitive`.** Chronicle rejects `[PII]` on an
84
- event source id (`CHR0034`) and `[Encrypted]` on one (`CHR0052`); Screenplay reports
85
- `PLAY0515` for `@pii` from Screenplay 4.69.1 and for `@sensitive` from 4.84.1, on a
86
- command identifier, an explicit `for` destination or an event source identifier; earlier
87
- versions compile it silently and only Chronicle catches it. Keep the stream identity a surrogate `Uuid`
88
- concept and carry the personal value (name, email) as a separate `@pii` property and a
89
- 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).
90
77
 
91
78
  ⚠️ **Enum trap.** A value literally named `validate` is read as an empty validate
92
79
  block. Write `@validate` for the value; the compiler warns when it sees the
@@ -245,8 +232,8 @@ choosing or omitting `for` on a production, or fixing `PLAY0469`-`PLAY0478`.
245
232
 
246
233
  - **Mapping sources** that bind to the executable model: a command property
247
234
  (`= invoiceNumber`), a literal (`= "draft"`, `= 0`), `$context.occurred`, and
248
- the caller's audit identity (`$context.identity.id`/`.name`/`.userName`, the
249
- 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.
250
237
  `$context.tenant`, claims, roles, causation, `$env.` values, templates and
251
238
  computed expressions parse but block binding (`PLAY0268`).
252
239
  - **`for <identifier>`** on an indented line names the event source the event is
@@ -271,6 +258,23 @@ produces when isProForma == true
271
258
  for invoiceId
272
259
  ```
273
260
 
261
+ ## Routes and external operations
262
+
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
269
+ and nested `streamId =` form are in `cratis-screenplay-toolchain`
270
+ `references/sources-and-streams.md`.
271
+
272
+ Use `system`, `uses` and inline/standalone `operation` declarations to state
273
+ external work in the authored production sequence, with execute/compensate phase
274
+ intent. These remain unadmitted (PLAY0268), not post-commit reactions. Read
275
+ [operation intent](references/operations.md) for forms, boundaries and checked
276
+ failure/compensation specification syntax.
277
+
274
278
  ## `concurrency`
275
279
 
276
280
  Five dimensions, each at most once, and at most one `concurrency` block per
@@ -292,8 +296,9 @@ to the routed scope. This does not make command `reads` protected.
292
296
 
293
297
  ## Generated values and responses (ESM v7)
294
298
 
295
- A `generated` property and a `returns` response need standalone `screenplay` 4.68.0; the cratis CLI reports
296
- `PLAY0268` and Stage refuses them, so such a command is **not rendered yet**: hand-write it.
299
+ Generated values/responses bind as ESM v7, including in the current CLI bundle.
300
+ CLI 3.41.0 admits v7 to Stage planning; its canonical corpus gets generated-value
301
+ and response refusals STAGE-ESM-028/029. Binding is not a render claim.
297
302
  Read [references/generated-values-and-responses.md](references/generated-values-and-responses.md) when adding or
298
303
  reviewing `generated` properties, `returns` responses, or decision 0023 constructs.
299
304
  Read `cratis-screenplay-toolchain/references/generated-responses-example.md` when adding generated command values or response assertions and you need a complete compiled example.
@@ -340,7 +345,15 @@ not both win — a `validate` rule cannot do that.
340
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
341
346
  declaring a policy, a persona, or a `seed` block.
342
347
 
343
- ## `$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`
344
357
 
345
358
  Four contexts, and **what each omits is load-bearing** — when writing a code body or a context/expression mapping, read
346
359
  [context.md](references/context.md) for the full member lists, the declarative
@@ -355,10 +368,9 @@ Four contexts, and **what each omits is load-bearing** — when writing a code b
355
368
 
356
369
  ## Verify
357
370
 
358
- - [ ] Standalone `screenplay <model> --warnaserror` (4.68.0) reports zero errors and zero
359
- warnings; or `cratis screenplay validate --warnings-as-errors` on the model folder
360
- (3.28.2 and 3.28.3 bundle Screenplay 4.66.0, ESM v6 at most; before 3.28.2 bundled 4.60.1, ESM v5
361
- or lower). Name which tool produced the result.
371
+ - [ ] Validate the complete model root with warnings as errors; name the tool,
372
+ version and result. Current pins: standalone 4.127.0 / CLI 3.41.0; bundle
373
+ compatibility and execution are separate checks.
362
374
  - [ ] No unintended `PLAY0478` or `PLAY0479` information remains.
363
375
  - [ ] At most one command property carries `identifier`, and no event property does.
364
376
  - [ ] Format rules live on the `concept`; state-dependent rules are specifications.
@@ -367,8 +379,9 @@ Four contexts, and **what each omits is load-bearing** — when writing a code b
367
379
  is stated.
368
380
  - [ ] Constraints are `unique` forms; no `file` constraint stands in for another rule.
369
381
  - [ ] Each policy has one `require` or one implementation, not both.
370
- - [ ] Personal data is `@pii` on the concept, with a reason; no identifier concept is `@pii`;
371
- 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.
372
385
  - [ ] No `handler` where the model must bind, and no bodied construct described as
373
386
  runnable or renderable without saying which tool admits it.
374
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
@@ -50,6 +51,15 @@ time: `CommandAs<T>()`, `ArgumentsAs<T>()`, `ArtifactAs<T>()`, `ValueAs<T>()`, a
50
51
  `StateAs<T>()`/`EventAs<T>()` on the reducer context. A payload of another type
51
52
  throws `ContextPayloadTypeMismatch`.
52
53
 
54
+ At Screenplay 4.125.0, typed contexts before generation (`CommandValidation`,
55
+ `ConceptValidation`, `RulePredicate`, `PolicyPredicate`) expose **input properties
56
+ only**. Generated values exist only after authorization/validation, so they are
57
+ absent from those shapes. A generated identifier's policy subject is `unavailable`,
58
+ not the eventual id; never authorize against it. The handler CommandContext retains
59
+ the full command shape, including generated properties. Sidecars belong to the same
60
+ compilation/revision as their requirements, not a shape borrowed from another model.
61
+ Source: `v4.125.0:Documentation/screenplay/context.md`.
62
+
53
63
  ## The values they carry
54
64
 
55
65
  | Type | Members |
@@ -88,6 +98,52 @@ roles, claims and causation report `PLAY0268`.
88
98
 
89
99
  An unknown `$context.` path is reported, so a typo does not silently become null.
90
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
+
91
147
  ## Production metadata is not a context expression
92
148
 
93
149
  `namespace`, `sequence`, `correlation`, `causation`, `causedBy` and `occurred`
@@ -102,6 +158,7 @@ occurrence metadata; use `given clock`, never `given time`, to state scenario ti
102
158
 
103
159
  | Root | Where | Yields |
104
160
  | --- | --- | --- |
161
+ | `$identity.<property>` | caller expression | built-in caller value or declared authoring detail; execution admission is narrower |
105
162
  | `$env.<VAR_NAME>` | mapping sources | an environment variable |
106
163
  | `$eventContext.<property>` | **projections only** | `occurred`, `sequenceNumber`, `correlationId`, `eventSourceId` |
107
164
  | `$eventSourceId` | **projections only** | shorthand for `$eventContext.eventSourceId` |
@@ -1,10 +1,13 @@
1
1
  ## Generated values and responses (ESM v7)
2
2
 
3
- A `generated` command property and a `returns` response bind and execute from the standalone
4
- `screenplay` 4.68.0 (ESM v7, decision 0026; `commands.md` "Generated values and responses" at
5
- `v4.68.0`). The cratis CLI 3.28.3 bundles 4.66.0 and reports `PLAY0268` for them, and Stage 4.24.2
6
- refuses ESM v7 with `STAGE-ESM-016` (tracked in Stage#201), so a command that uses them is
7
- **not rendered yet**: hand-write it (gap-fill) with the model as the contract. Complete compiled example:
3
+ A `generated` command property and `returns` response bind and reference-execute
4
+ as ESM v7. Current pins are standalone Screenplay 4.127.0 and CLI 3.41.0
5
+ (bundled Screenplay 4.114.0/Stage 4.51.3); `cratis-screenplay-toolchain`
6
+ `references/versions.md` owns the table. CLI#261 is closed: CLI now admits v7
7
+ to Stage planning, but its v7 canonical corpus receives Stage generated-value
8
+ and response refusals STAGE-ESM-028/029. Do not turn this into a blanket compiler
9
+ refusal or promise a render from binding alone. Preserve the contract for gap-fill
10
+ where admission refuses. Historical rules below were read at 4.68.0. Complete compiled example:
8
11
  `cratis-screenplay-toolchain` `references/generated-responses-example.md`.
9
12
 
10
13
  ```screenplay excerpt
@@ -40,12 +43,11 @@ Rules (all read at `v4.68.0`):
40
43
  - Generated values give no idempotency, retry or deduplication guarantee. Specifications supply fixtures and assert
41
44
  the response: `cratis-screenplay-specifications`.
42
45
 
43
- Other decision 0023 constructs are still **authorable, never executable** (binding reports `PLAY0268`, so
44
- they stop a model at V1): operations, and named event sources and streams with command routes
45
- (`eventsource`, `stream`, `streamId`). **No supported ESM version admits them**, and they have no version number
46
- yet (decision 0025 numbers a version only at its release-ready admission). Syntax or MCP acceptance is not proof of
47
- execution. A model using sources, streams or routes can be authored and validated, but
48
- not bound, run or rendered; hand-write the code with the model as contract
49
- (`cratis-screenplay-toolchain` `references/sources-and-streams.md`). `derive` and `provide` have no documented syntax at that tag; treat them as
50
- planned and do not write them.
46
+ Operations remain authorable/unadmitted (PLAY0268). Named event sources,
47
+ streams and command/specification routes instead bind and reference-execute as
48
+ ESM v8 at 4.125.0; CLI 3.41.0 render refuses versions above v7 before planning
49
+ (CLI-RENDER-004). Syntax/MCP acceptance alone is not execution. Source/stream
50
+ forms and realization boundary: `cratis-screenplay-toolchain`
51
+ `references/sources-and-streams.md`. Do not infer further syntax or provider
52
+ admission from decision numbers.
51
53