@cratis/pi 7.74.0 → 7.76.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 (75) hide show
  1. package/package/corpus/harnesses/copilot/instructions/vertical-slices.instructions.md +6 -4
  2. package/package/corpus/harnesses/pi/extensions/cratis-hooks/index.ts +5 -2
  3. package/package/corpus/hooks/README.md +27 -3
  4. package/package/corpus/hooks/scripts/cratis-quality-gate.sh +67 -4
  5. package/package/corpus/hooks/scripts/quality-gates.json +7 -1
  6. package/package/corpus/product-sync.json +14 -14
  7. package/package/corpus/rules/general.md +1 -0
  8. package/package/corpus/rules/vertical-slices.md +6 -4
  9. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authorization.md +9 -0
  10. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/observable-emission-guards.md +12 -3
  11. package/package/corpus/skills/cratis-arc-command/references/decisions-and-routing.md +11 -0
  12. package/package/corpus/skills/cratis-arc-command-execution/SKILL.md +3 -0
  13. package/package/corpus/skills/cratis-arc-command-execution/references/occurrence-commands.md +78 -0
  14. package/package/corpus/skills/cratis-arc-command-validation/SKILL.md +10 -36
  15. package/package/corpus/skills/cratis-arc-command-validation/references/input-binding.md +49 -0
  16. package/package/corpus/skills/cratis-arc-command-validation/references/read-model-resolution.md +25 -0
  17. package/package/corpus/skills/cratis-arc-command-validation/references/validation-severity.md +21 -0
  18. package/package/corpus/skills/cratis-arc-ef-core-migration/SKILL.md +7 -1
  19. package/package/corpus/skills/cratis-arc-hosting/SKILL.md +3 -0
  20. package/package/corpus/skills/cratis-arc-hosting/references/connection-resolution.md +61 -0
  21. package/package/corpus/skills/cratis-arc-query-paging/SKILL.md +4 -2
  22. package/package/corpus/skills/cratis-arc-react-page/references/queries-and-commands.md +14 -1
  23. package/package/corpus/skills/cratis-chronicle-client-dotnet/SKILL.md +5 -0
  24. package/package/corpus/skills/cratis-chronicle-client-dotnet/references/immediate-append-refusal.md +40 -0
  25. package/package/corpus/skills/cratis-chronicle-client-dotnet/references/lifecycle.md +4 -0
  26. package/package/corpus/skills/cratis-chronicle-client-dotnet/references/occurrences.md +89 -0
  27. package/package/corpus/skills/cratis-chronicle-client-dotnet/references/pinned-generation-delivery.md +33 -3
  28. package/package/corpus/skills/cratis-chronicle-decision-reads/SKILL.md +5 -2
  29. package/package/corpus/skills/cratis-chronicle-decision-reads/references/admission-and-ownership.md +18 -1
  30. package/package/corpus/skills/cratis-chronicle-event-type-migration/references/pinned-generations.md +6 -0
  31. package/package/corpus/skills/cratis-chronicle-hosting/SKILL.md +3 -0
  32. package/package/corpus/skills/cratis-chronicle-hosting/references/operations.md +26 -0
  33. package/package/corpus/skills/cratis-chronicle-hosting/references/storage-resolution.md +55 -0
  34. package/package/corpus/skills/cratis-chronicle-multi-tenancy/SKILL.md +3 -0
  35. package/package/corpus/skills/cratis-chronicle-multi-tenancy/references/remove-namespace.md +38 -0
  36. package/package/corpus/skills/cratis-chronicle-projection/references/definition-changes.md +26 -0
  37. package/package/corpus/skills/cratis-chronicle-projection/references/model-bound-attributes.md +8 -0
  38. package/package/corpus/skills/cratis-chronicle-reactor/SKILL.md +5 -22
  39. package/package/corpus/skills/cratis-chronicle-reactor/references/starting-and-replaying.md +33 -0
  40. package/package/corpus/skills/cratis-chronicle-read-model/SKILL.md +9 -2
  41. package/package/corpus/skills/cratis-chronicle-read-model/references/queries.md +9 -4
  42. package/package/corpus/skills/cratis-chronicle-reducer/SKILL.md +4 -0
  43. package/package/corpus/skills/cratis-multi-service-architecture/SKILL.md +9 -3
  44. package/package/corpus/skills/cratis-performance-review/SKILL.md +4 -1
  45. package/package/corpus/skills/cratis-screenplay-automations-and-translations/SKILL.md +2 -2
  46. package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/realization-and-gap-fill.md +10 -2
  47. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/SKILL.md +9 -9
  48. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/atomic-batches-and-source-mappings.md +2 -2
  49. package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +11 -11
  50. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +9 -0
  51. package/package/corpus/skills/cratis-screenplay-model-authoring/references/model-notes.md +41 -23
  52. package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +8 -3
  53. package/package/corpus/skills/cratis-screenplay-projections/SKILL.md +19 -12
  54. package/package/corpus/skills/cratis-screenplay-projections/references/pdl-grammar.md +37 -2
  55. package/package/corpus/skills/cratis-screenplay-projections/verification.json +11 -0
  56. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/SKILL.md +37 -40
  57. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/gap-fill-handoff.md +3 -2
  58. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/renderability-gate.md +1 -1
  59. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/verification.json +4 -2
  60. package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/coverage-matrix.md +9 -0
  61. package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +13 -30
  62. package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +39 -6
  63. package/package/corpus/skills/cratis-screenplay-toolchain/references/executable-subset.md +5 -2
  64. package/package/corpus/skills/cratis-screenplay-toolchain/references/language-admission.md +15 -5
  65. package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +7 -4
  66. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +12 -1
  67. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
  68. package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +9 -2
  69. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +38 -56
  70. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +23 -13
  71. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/date-comparisons.md +44 -0
  72. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/rendered-application.md +8 -2
  73. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/sandbox-and-specrunner.md +59 -8
  74. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/verification.json +7 -3
  75. package/package.json +1 -1
@@ -11,9 +11,8 @@ ships a **renderer** (a .NET library, driven from a terminal by `cratis render`)
11
11
  disposable **sandbox** container (`cratis/stage`, started by `cratis run`) and a
12
12
  **specification runner** container (`cratis/stage-specrunner`).
13
13
 
14
- The admitted model shape is deliberately small. A model Stage cannot render exactly
15
- produces **no artifacts at all**, never thinner ones. Render the model to find out
16
- whether it is admitted; reading the admission rules is not a render result.
14
+ A model Stage cannot render exactly produces **no artifacts**, never thinner ones.
15
+ Probe the model; admission rules are not a render result.
17
16
 
18
17
  Requires cratis CLI ≥ 3.57 (`cratis --version`) to render ESM v14 and v15 models; an older CLI refuses newer ESM versions with `CLI-RENDER-004` (or `STAGE-ESM-016` from Stage directly).
19
18
 
@@ -22,9 +21,9 @@ Requires Cratis CLI 3.74.0 to render ESM v21–v26 models and 3.75.0 for v27; CL
22
21
  ## Batches, described handlers, text rules and protected reads
23
22
 
24
23
  Read [language admission](../cratis-screenplay-toolchain/references/language-admission.md)
25
- for v22–v25: text rules render, atomic batches/protected reads/described bodies do
26
- not. The semantic Host and specification runner execute admitted protected reads;
27
- that is not rendering. Stub mode emits no described-body stubs. Keep protection and report refusal.
24
+ for v22–v25: text rules and admitted protected reads render; atomic batches and
25
+ described bodies do not. Semantic execution is separate from rendering. Stub mode
26
+ emits no described-body stubs. Keep protection and report refusal.
28
27
 
29
28
  ## When to use
30
29
 
@@ -73,12 +72,15 @@ Order: recover any interrupted publication, compile, bind, build the plan, plan
73
72
  Exit `0` is a published render, `5` is a refusal with nothing published (diagnostics are
74
73
  printed), `1` is a missing input. Add `-o json` for the counts and the publication receipt.
75
74
 
76
- Facts that surprise:
75
+ Key facts:
77
76
 
78
77
  - **Binding uses the CLI's bundled compiler**, not the standalone one. Version admission
79
- does not imply construct support: exact ESM v1–v21 and v23–v27 pairs are admitted,
80
- while v22/v28 and mixed pairs refuse `STAGE-ESM-016`. Date/DateTime command comparisons (v26)
81
- execute in the semantic Host and executor but refuse `STAGE-ESM-046` in the renderer. Pattern/random generation and checksum validation
78
+ does not imply construct support: exact ESM v1–v27 pairs are admitted;
79
+ v28 and mixed pairs refuse `STAGE-ESM-016`. Requires Stage 4.139.0 for v22 admission;
80
+ older Stage refuses v22 with `-016`, while atomic mode still refuses `-043`.
81
+ Requires Stage 4.141.0 to render v26 Date/DateTime command comparisons; older
82
+ renderers refuse `-046`. Read [references/date-comparisons.md](references/date-comparisons.md)
83
+ when rendering dates for the remaining refusals and input-binding differences. Pattern/random generation and checksum validation
82
84
  render with an admitting renderer; `generate rule` renders in a new enough bundle (the Host and legacy syntax engine still refuse it with `STAGE-ESM-028`).
83
85
  Read [references/admission.md](references/admission.md) for the introducing-release
84
86
  prerequisites, all-Proven unpinned specifications and construct/pin checks (-011/-038).
@@ -116,7 +118,10 @@ modified stale artifacts. Recovery runs before planning:
116
118
 
117
119
  ## Admission
118
120
 
119
- One blocker publishes nothing. Codes, limits and fixes: [references/admission.md](references/admission.md).
121
+ One blocker publishes nothing. Requires Stage 4.146.0 to collect independent admission
122
+ refusals in one plan; older renderers stop at earlier batches of checks. Target-profile
123
+ and unaudited-version refusals still stop first. Codes, limits and fixes:
124
+ [references/admission.md](references/admission.md).
120
125
 
121
126
  - **Renders:** concepts/types/collections/optionals; portable StateChange and StateView slices,
122
127
  flat/scoped projections, pure reducers and reducer `from` filters; keyed optional snapshots,
@@ -139,11 +144,9 @@ One blocker publishes nothing. Codes, limits and fixes: [references/admission.md
139
144
  for ESM admission. Read the required typed `arguments.subject` for the command,
140
145
  never match message text. Requires Screenplay 4.210.0 (`screenplay --version`);
141
146
  older bundled binders use PLAY0268 for these handlers.
142
- - **Binding refusals (`PLAY0268`/`PLAY0271`):** legacy reads, `concurrency`,
143
- context/single-result filters, opaque scope/performer, a list-query `by` block,
144
- enum/identity compliance and subject lineage. Eligible protected reads bind v25;
145
- pending handlers with unconditional productions bind v23, but neither renders. A read model with several key parts (v27) is admitted but refuses rendering (`STAGE-ESM-048`).
146
- Never drop protection.
147
+ - **Binding refusals:** read toolchain `references/executable-subset.md` for
148
+ `PLAY0268`/`PLAY0271` families; binding is not rendering. V27 keys are admitted
149
+ but refuse rendering (`STAGE-ESM-048`). Never drop protection.
147
150
 
148
151
  A refusal is not a licence to weaken the model: drop no specification, event generation or
149
152
  protection to get a render; keep the model, record the capability gap and gap-fill.
@@ -156,19 +159,15 @@ prose is not enforced. A documentation edit changes managed-file hashes (a `--ch
156
159
  Generated identities: read [shop strategy choices](references/choosing-generation.md) before
157
160
  rendering a model with generated values. Case tables and whole numbers:
158
161
  [case tables and whole numbers](references/case-tables-and-whole-numbers.md).
159
- `[ProtectedDecision]` and `DecisionRead<T>` are available to gap-fill code, not
160
- automatically emitted or protected by Stage; admission and unit-of-work enrollment still matter.
162
+ Gap-fill `[ProtectedDecision]`/`DecisionRead<T>` use still needs admission and
163
+ unit-of-work enrollment.
161
164
 
162
165
  ## What it emits
163
166
 
164
- At application scope the plan holds the scaffold plus the modeled artifacts: a `.csproj`
165
- and `.slnx`, `Program.cs`, `appsettings.json`, `docker-compose.yml`, the Directory props
166
- files, a policy registration and generated policies, `Common/<Concept>.cs`, one
167
- `<Module>/<Feature>/<Slice>/` folder per slice with the `[Command]` record and `Handle()`,
168
- the `[EventType]` event, the validator and the `[ReadModel]` with its query, `scene.json`,
169
- and a React/Vite frontend scaffold (`.frontend/`, `package.json`, `tsconfig.json`,
170
- `.gitignore`). Per-file detail, the scaffold's dependency set and the `Customizations/`
171
- contract, including the opt-in self-reducing layout for confirmed new Cratis C# applications:
167
+ Application plans hold the backend scaffold, concepts, commands/events/validators,
168
+ read models/queries and policies, plus Scene and React/Vite frontend artifacts.
169
+ Read the per-file scaffold, dependency and `Customizations/` contract, including
170
+ the opt-in self-reducing layout for confirmed new Cratis C# applications:
172
171
  [references/rendered-application.md](references/rendered-application.md). Scene
173
172
  package ids, host capabilities and the boundary from hand-built Components pages:
174
173
  [references/scene-runtime.md](references/scene-runtime.md). A complete renderable model:
@@ -193,36 +192,19 @@ Silent fallback to a default screen is a failure, not a partial render.
193
192
 
194
193
  ## Sandbox and specification runner
195
194
 
196
- `cratis run [PATH]` (Docker required) starts `cratis/stage` on the folder or file: Stage
197
- API on `9090`, Chronicle Workbench on `https://localhost:35000`. It is a **partial,
198
- disposable runtime**, not a generated application. `cratis run` runs the `semantic` engine
199
- (Requires Cratis CLI 3.73.0); Stage's semantic engine is the only engine going forward. The legacy
200
- EventModel engine (older CLIs, or the image without `Stage__Runtime__Engine=semantic`) is legacy; do not rely on it.
201
- It appends modeled
202
- `produces` facts and echoes the payload. It refuses missing required properties and
203
- simple literal `validate` rules on top-level properties, but enforces no other rule, no
204
- constraint and no command or query authorization; the semantic engine enforces them and
205
- refuses what it cannot execute (HTTP 501). The legacy engine
206
- also refuses routed models (`STAGE-ESM-030`), composite read-model keys (v27) and protected reads (`STAGE-ESM-044`); the semantic engine runs composite keys.
207
- Requires Cratis CLI 3.75.0 for `cratis run` to run v27 composite keys.
208
- Requires Stage 4.129.0 for semantic Host/runner protected reads; older engines refuse
209
- `STAGE-ESM-044`. Required absence rejects before requirements/generation, read properties
210
- feed requirements and productions, and non-Error protected requirements refuse
211
- `STAGE-ESM-045`, including reaction invocations. The Host faults on any outside append,
212
- even unrelated facts; this is stricter than reference dependency-scoped conflicts.
213
- Callers are built from unsigned headers, so
214
- authorization there is not a security boundary.
215
-
216
- `cratis/stage-specrunner` checks modeled specifications and writes a results file. The
217
- default `structural` engine is deprecated and model-level only; `--engine semantic`
218
- executes admitted specs through Arc's in-memory pipeline and reports `Passed`, `Failed`,
219
- `Unsupported` or `Cancelled`. A green result is Stage semantic-engine evidence: not V4 and
220
- not a rendered Debug test run. Commands, the report schema and limits:
221
- [references/sandbox-and-specrunner.md](references/sandbox-and-specrunner.md).
222
-
223
- Specification runner exit codes: `0` means the run completed and the results file was
224
- written **even when a specification failed**, so read the outcomes; `1` is a missing or
225
- uncompilable input; `2` a missing required argument or an invalid semantic option.
195
+ `cratis run [PATH]` (Docker required) starts the disposable `cratis/stage`, not a
196
+ generated application: API on `9090`, Workbench on `https://localhost:35000`.
197
+ Requires Cratis CLI 3.73.0 for the semantic engine by default, 3.75.0 for v27 keys;
198
+ older CLIs use the legacy EventModel engine, which does not enforce authorization.
199
+ Unsigned caller headers make sandbox authorization no security boundary.
200
+ Read [references/sandbox-and-specrunner.md](references/sandbox-and-specrunner.md)
201
+ before running either image: engine selection, protected reads, outside-append
202
+ conflicts/retries, reached bodies, authored occurrence and generated-spec limits live there.
203
+
204
+ `cratis/stage-specrunner --engine semantic` reports `Passed`, `Failed`, `Unsupported`
205
+ or `Cancelled`; deprecated structural mode is model-level only. Neither proves V4
206
+ or rendered Debug tests. Exit `0` means the report was written **even on failed specs**:
207
+ read outcomes. Exit `1` means missing/uncompilable input; `2` invalid arguments.
226
208
 
227
209
  ## Behavior walk (optional, after V3)
228
210
 
@@ -11,10 +11,10 @@
11
11
  - Specification rules (`STAGE-ESM-011`)
12
12
  - Refusals seen while drafting a model
13
13
 
14
- Stage admits exact ESM v1–v21 and v23–v27 language/semantic pairs, then checks
15
- constructs. V22, v28 and mixed or unknown pairs report `STAGE-ESM-016`. `cratis render` admits
16
- ESM v1–v27: Stage plans each model and refuses the constructs it cannot render with typed `STAGE-ESM-*`
17
- codes (a v22 model reports `STAGE-ESM-016`; v26 date comparisons report `STAGE-ESM-046`; v27 composite
14
+ Stage admits exact ESM v1–v27 language/semantic pairs, then checks
15
+ constructs. V28 and mixed or unknown pairs report `STAGE-ESM-016`. `cratis render` admits
16
+ ESM v1–v27: Stage plans each model and refuses the constructs it cannot render with typed `STAGE-*`
17
+ codes (atomic batches report `STAGE-ESM-043`; unsupported v26 date shapes `STAGE-ESM-046`; v27 composite
18
18
  read-model keys report `STAGE-ESM-048`/`-047`). The CLI refuses
19
19
  a bound model above v27 with `CLI-RENDER-004` before planning; a construct its bundled compiler cannot bind
20
20
  reports PLAY0268 instead.
@@ -38,15 +38,16 @@ opaque/unsupported rules refuse -005 before pin evaluation. Independent executio
38
38
  always needs pins.
39
39
  Requires Stage 4.124.0 for v24 text-rule admission (`cratis --version` identifies the CLI bundle); older renderers refuse v24 with STAGE-ESM-016.
40
40
  Requires Stage 4.127.0 for v25 version admission; older renderers refuse v25 with STAGE-ESM-016. Requires Stage 4.138.0 for the Cratis renderer to render protected reads as Arc read protection (`[ReadProtection(On)]`, a nullable read-model `Handle` parameter per read with `[LookUpBy]`, the `<View> '<key>' does not exist.` rejection, requirements evaluated in `Handle` after the reads; generated specifications run in decision mode); `cratis render` gets it from the first CLI that bundles Stage 4.138.0, and earlier bundles (CLI 3.75.0 bundles 4.137.0) refuse every protected read with STAGE-ESM-044. Reads it cannot preserve faithfully stay STAGE-ESM-044 and name the reason: constrained events, read paths in `produces when`, mappings to optional, collection, composite or mistyped event properties, generated-value freshness scopes. See [protected reads](../../cratis-screenplay-command-surface/references/protected-reads.md).
41
- Requires Stage 4.129.0 for semantic Host/executor protected reads; older engines refuse STAGE-ESM-044. Required absence rejects before requirements or generation; read-backed requirements and produced-event mappings execute. Non-Error protected requirements refuse STAGE-ESM-045, including reaction invocations. See [sandbox boundaries](sandbox-and-specrunner.md#protected-command-reads) for ordering and the Host's stricter outside-append fault boundary.
41
+ Requires Stage 4.129.0 for semantic Host/executor protected reads; older engines refuse STAGE-ESM-044. Required absence rejects before requirements or generation; read-backed requirements and produced-event mappings execute. Non-Error protected requirements refuse STAGE-ESM-045, including reaction invocations. See [sandbox boundaries](sandbox-and-specrunner.md#protected-command-reads) for ordering and outside-append commit boundaries.
42
42
  Described handlers refuse STAGE-IMPL-002, even Stub mode; atomic mode in an
43
43
  admitted pair refuses STAGE-ESM-043. Version admission never implements a body,
44
44
  batch or composite-key rendering. Chronological Date/DateTime command comparisons
45
- select v26. The semantic Host and specification executor run them; the renderer,
46
- legacy engines and default sandbox engine refuse them with STAGE-ESM-046, naming the
47
- property, and emit no artifacts. Standalone reference success is not rendering. Keep
48
- the date rule and use authorized gap-fill rather than downgrading to ordinal text or
49
- millisecond precision.
45
+ select v26. The semantic Host and specification executor run them.
46
+ Requires Stage 4.139.0 for v22 admission; older Stage refuses v22 with -016.
47
+ Requires Stage 4.141.0 for rendered date comparisons; older renderers and legacy
48
+ engines refuse -046. Read [date comparisons](date-comparisons.md) when rendering
49
+ v26 for the remaining -046 shapes and input-binding differences. Keep refused date
50
+ rules; never downgrade to ordinal text or millisecond precision.
50
51
 
51
52
  Requires Stage 4.135.0 for v26 admission; older Stage refuses v26 with STAGE-ESM-016.
52
53
 
@@ -61,6 +62,13 @@ prerequisite. The exhaustive construct table is `references/renderable-subset.md
61
62
  One blocking diagnostic fails the **whole** plan and nothing is published (exit 5).
62
63
  Informational diagnostics (`PLAY0270` authoring metadata, `PLAY0469`, `STAGE-ESM-023`) do not.
63
64
 
65
+ Requires Stage 4.146.0 for one plan collecting all independent version-feature,
66
+ implementation-envelope, typed-context, event-lineage, slice, specification and Scene
67
+ admission refusals; older renderers return earlier batches first. Duplicate refusals
68
+ are listed once; refusals already collected survive an unexpected model shape.
69
+ A target-profile mismatch or unaudited ESM version still stops before these checks.
70
+ Classify the complete plan before editing; another probe is still required after fixes.
71
+
64
72
  A refusal can come from four layers, and the code tells you which: compilation and binding
65
73
  (`PLAY*`, from the CLI's bundled Screenplay), execution planning (`PLAN-*`), Stage
66
74
  admission (`STAGE-*`) and the CLI itself (`CLI-RENDER-*`). A publication conflict (a
@@ -149,13 +157,13 @@ Requires Stage 4.90.0 for snapshot/live lists, 4.96.0 for non-text secrets and 4
149
157
  | `STAGE-ESM-005` | Code validation or rule predicate bodies; or a command beyond the first capability (optional event property, event revision other than the first, validation or requirement that cannot be rendered, neither `produces` nor a response) | Use declarative validation; non-initial event generations are not rendered |
150
158
  | `STAGE-ESM-006` | `produces` that cannot render without changing its destination or mappings (expression/enum conditions, literal or computed mappings, `for` not a command identifier, mappings not one-to-one with event properties, duplicate tags) | Map properties one to one; supported conditional productions render as guarded events, not separate commands |
151
159
  | `STAGE-ESM-007`, `-008`, `-009` | Projection count per read model (exactly one projection or reducer each); unresolvable properties or no single read-model transition (**flat** projections only); affected instance not one, not keyed by an event property, or not the event-source identity (flat projections only) | One projection per read model; see "Projections" below |
152
- | `STAGE-ESM-010` | A query is neither an optional snapshot lookup by the read-model identifier nor a supported snapshot/observable collection query; each query is checked on its own. Both collection modes render. Concept-typed keys and filters retain Arc validation, including composite members and collection elements; nullable concept keys or optional concept filters with `not empty` cannot preserve null semantics | Keyed `XById => X optional` queries or snapshot/observable lists. Equality filters render on both collections; DateTime filters, required filters after optional ones and unsupported null-validation shapes refuse 010. Filter-name collisions refuse 012. Context/single-result filters, opaque scope/performer and a list-query `by` block remain PLAY0268; a read model with several key parts (v27) refuses `STAGE-ESM-016` |
160
+ | `STAGE-ESM-010` | A query is neither an optional snapshot lookup by the read-model identifier nor a supported snapshot/observable collection query; each query is checked on its own. Both collection modes render. Concept-typed keys and filters retain Arc validation, including composite members and collection elements; nullable concept keys or optional concept filters with `not empty` cannot preserve null semantics | Keyed `XById => X optional` queries or snapshot/observable lists. Equality filters render on both collections; DateTime filters, required filters after optional ones and unsupported null-validation shapes refuse 010. Filter-name collisions refuse 012. Context/single-result filters, opaque scope/performer and a list-query `by` block remain PLAY0268; a read model with several key parts (v27) refuses `STAGE-ESM-048` |
153
161
  | `STAGE-ESM-011` | A specification cannot render (see the rules below) | Reshape it only if the assertion keeps its meaning; otherwise keep the specification, record the gap, and gap-fill with the specification as the oracle. Never weaken or delete it to get a render |
154
162
  | `STAGE-ESM-012` | Generated C# names collide (properties, types, namespaces, constraints) | Rename |
155
163
  | `STAGE-ESM-013` | An event-context value other than `$context.occurred` mapped in `produces` | Map a command property when that preserves the meaning; otherwise gap-fill |
156
164
  | `STAGE-ESM-014` | A constraint Chronicle cannot reproduce (kind, scope, message; multi-claim in one command; optional or composite targets) | A different constraint is a requirement change for the model owner; otherwise gap-fill |
157
165
  | `STAGE-ESM-015` | Authorization Stage cannot render exactly: a role-claim URI, an opaque policy nested inside a condition, an unresolved or non-portable policy, no single identifier, an opaque-policy subject that is not text, Uuid, Date or DateTime (a restriction on opaque-policy subjects, separate from declarative claim targets), an unsupported claim artifact. Role-only, authenticated, opaque pure policies, claim conditions with Uuid, Date, DateTime or text targets (numeric and Boolean claim matches render as always false) and `not`/and/or render; roles are read through the identity's `RoleClaimType` | Reshape the policy to a portable condition; otherwise gap-fill |
158
- | `STAGE-ESM-016` | Model language/semantic pair is not admitted by the installed Stage; exact v1–v21 and v23–v27 pairs are admitted, v22/v28 and mixed pairs refused; older Stage also refuses the versions listed in the minimums above. A CLI bundle reports `CLI-RENDER-004` above its ceiling (v27 for CLI 3.75.0) first. v14 filters and v15 generation join v11 numbers, v12 enum numbers and v13 compliance as supported constructs, not blanket construct support | Not fixable by editing: the model needs a newer renderer. Keep the model, record the gap, gap-fill |
166
+ | `STAGE-ESM-016` | Model language/semantic pair is not admitted by the installed Stage; exact v1–v27 pairs are admitted, v28 and mixed pairs refused; older Stage also refuses the versions listed in the minimums above. A CLI bundle reports `CLI-RENDER-004` above its ceiling (v27 for CLI 3.75.0) first. v14 filters and v15 generation join v11 numbers, v12 enum numbers and v13 compliance as supported constructs, not blanket construct support | Not fixable by editing: the model needs a newer renderer. Keep the model, record the gap, gap-fill |
159
167
  | `STAGE-ESM-017` | Read model or projection cannot render (property names that collide with Chronicle paths or expression syntax, mappings that overwrite the key or child identity, composite keys, unsupported `all` mappings, the refused scope shapes below) | Reshape the projection without changing what it records, or record the gap |
160
168
  | `STAGE-ESM-018` | `$strings.` key missing in the default locale or containing formatting characters | Fix the strings |
161
169
  | `STAGE-ESM-019` | Reducer structure or body not admitted (outside a `StateView`, impure, does not compile), or a `generate rule` body that does not compile or produces a compiler warning | An equivalent pure body, or gap-fill |
@@ -179,9 +187,11 @@ Requires Stage 4.90.0 for snapshot/live lists, 4.96.0 for non-text secrets and 4
179
187
  | `STAGE-ESM-043` | `reaction batches atomic` in an admitted version pair | Keep the batch boundary; gap-fill without splitting it |
180
188
  | `STAGE-ESM-044` | A protected read the Cratis renderer cannot preserve faithfully, naming the reason (every protected read before Stage 4.138.0); the legacy Host/structural runner refuse the preamble | Keep protection; gap-fill the refused command; semantic Host/executor support is separate from generated-app enforcement |
181
189
  | `STAGE-ESM-047`, `-048` | ESM v27 composite read-model keys: `-048` read model with several key parts or projection keyed by parts (also the legacy syntax engine); `-047` single-instance query by parts | Keep the model; gap-fill the composite-keyed scope |
182
- | `STAGE-ESM-046` | Date/DateTime comparison in `require`, `produces when` or a validation rule (including through concepts) in the renderer, legacy engines or default sandbox engine; names the property | Keep the date rule; the semantic Host/executor run it; deliver rendering through gap-fill that compares exact calendar dates and UTC ticks |
190
+ | `STAGE-ESM-046` | Compared DateTime concept with compliance or optionality, or a non-camel-case compared DateTime property; older renderers and legacy engines refuse all date comparisons | Keep the date rule and protection; see [date comparisons](date-comparisons.md) |
183
191
  | `STAGE-ESM-045` | Non-Error requirement on a protected command, including reaction-invoked commands; semantic admission refuses before reads, requirements or facts | Keep the severity contract; record the execution gap, never silently promote or drop the requirement |
184
192
  | `STAGE-IMPL-002` | Described command handler, naming command and RequirementId; also refused in Stub mode | Supply authorized implementation outside rendering; no generated stub is emitted |
193
+ | `STAGE-IMPL-003` | Semantic Host/executor reaches a reducer or command/concept validation body; names owner and RequirementId (Requires Stage 4.145.0; older engines refuse unrelated behavior too) | Keep the body; run unaffected scope separately and gap-fill reached behavior. Renderer admission is unchanged |
194
+ | `STAGE-PROFILE-001` to `-006` | Profile input cannot be honored: unknown package, missing layout, incompatible packages, missing theme, invalid root template or unresolved blueprint template | Fix the named input without substituting a different shell. Requires Stage 4.143.0 for shared `CratisRendering.ResolveProfileInputs(scene, approvedPackages)` findings; older consumers may have CLI-only checks |
185
195
  | `STAGE-ESM-037` | Events and commands from one handler, even across separate triggers on the same event in one reaction. The scaffold's Arc supports mixed results, but appends events before commands; a refused command causes redelivery and duplicate events | **Do not split the modeled reaction or drop an effect.** Gap-fill only with a proven retry-safe implementation; `[OnceOnly]` excludes replay, not retry |
186
196
  | `STAGE-ESM-023` | Information: transition bodies analysed | none |
187
197
  | `STAGE-CRATIS-001` to `-005` | Profile or `scene.json` not the package-owned shape; unrecognized or missing scaffold input; artifact path collision (`-004`, for example case names that normalize to one path); a modeled module or feature that would render into the reserved `Customizations/` (`-005`) | Rename the module, feature or case |
@@ -0,0 +1,44 @@
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
+ # Rendering Date and DateTime comparisons
5
+
6
+ Requires Stage 4.141.0 to render ESM v26 comparisons; older renderers refuse them
7
+ with `STAGE-ESM-046`. Check `cratis --version` and its bundled Stage before rendering;
8
+ a newer standalone Screenplay does not upgrade the CLI renderer.
9
+
10
+ The Cratis renderer emits comparisons in command `require`, `produces when` and
11
+ command/property validation rules. Date compares calendar days with `DateOnly`;
12
+ DateTime compares UTC instants with `DateTimeOffset` at tick precision, not text
13
+ or millisecond precision. Absence passes validation rules. Date predicates are
14
+ server-side `.Must` rules; no client-side date comparator is extracted.
15
+
16
+ Every compared DateTime command property carries Arc's `ExplicitOffset` marker:
17
+ input without an offset or `Z` is rejected. A compared DateTime concept binds as
18
+ `DateTimeOffset` and converts back to the concept in events, rules and responses.
19
+ That workaround cannot preserve every shape. `STAGE-ESM-046` names the property for:
20
+
21
+ - a compared DateTime concept carrying compliance;
22
+ - an optional compared DateTime concept;
23
+ - a compared DateTime property whose name is not camel case.
24
+
25
+ Keep compliance and optionality: these are gaps, not reasons to change the model.
26
+ Date comparisons from protected-read operands are not rendered. Reaction date
27
+ conditions are not admitted by the language. Legacy engines retain `-046`.
28
+
29
+ ## Input and expectation differences
30
+
31
+ With a named authorization policy, an unauthorized caller sending an unbindable
32
+ date body receives Validation rather than 403: Arc binds the body before Stage's
33
+ named policy evaluates. Test this boundary; do not claim identical denial ordering.
34
+ Rendered DateTime `then` expectations compare instants, while reference expectations
35
+ remain ordinal text comparisons; the binder requires expected event values to match
36
+ the produced spelling.
37
+
38
+ ## Verify
39
+
40
+ Run `cratis render <root> --name <App> --destination <out>`, then build and test the
41
+ rendered project in Debug, in separate bounded calls. Admission/publication, build
42
+ and specification outcomes are separate results. Check valid offset inputs,
43
+ offset-less rejections and calendar-day/UTC-instant boundaries; retain any typed
44
+ refusal rather than replacing the comparison with text ordering.
@@ -15,6 +15,10 @@ image, Cratis Components, Scene, Fundamentals, Vite and React). The pins belong
15
15
  renderer: read them from the rendered `.csproj`, `docker-compose.yml` and `package.json`, never
16
16
  from this skill. Moving them is a renderer change, so a re-render
17
17
  under a newer Stage is how they change; never bump a managed file.
18
+ Requires Stage 4.144.0 for backend pins derived at build time from Stage's central
19
+ package versions and shared frontend pins following Stage's frontend manifest;
20
+ older renderers use separately maintained scaffold pins. Regeneration updates
21
+ existing applications; it does not float dependencies in an already rendered app.
18
22
 
19
23
  | Item | Value |
20
24
  | --- | --- |
@@ -36,8 +40,10 @@ Consequences: `[ProtectedDecision]` (`Cratis.Arc.Chronicle.ReadModels`) and
36
40
  in the scaffold's package set, as is `[ExecuteCommandsAsSystem]`. This is API
37
41
  availability, not Stage emission or runtime protection: gap-fill must opt into
38
42
  the protected command profile and enroll an admitted projection/key read in the
39
- active unit of work. The Cratis C# renderer does not turn `.play` `reads`/`require` into protected decisions;
40
- semantic Host/executor support is separate from generated-application protection.
43
+ active unit of work. Requires Stage 4.138.0 for Cratis C# rendering of admitted
44
+ `.play` protected reads as Arc read protection; older renderers refuse them with
45
+ `STAGE-ESM-044`, as do shapes the renderer cannot preserve. Semantic Host/executor
46
+ support is separate from generated-application protection.
41
47
  Hand-written scope that needs a newer dependency can raise its version through
42
48
  `Customizations/Dependencies.props` (explicit `Version`, imported last; central management
43
49
  is off), but any override must be proven with a restore and build. The compose file binds local ports `27017` and
@@ -5,6 +5,7 @@
5
5
  - The sandbox: a partial, disposable runtime
6
6
  - Protected command reads
7
7
  - Date comparisons (v26)
8
+ - Implementation bodies and authored occurrence
8
9
  - Refusals shared by both engines
9
10
  - The specification runner
10
11
  - Choosing between them
@@ -124,10 +125,20 @@ execution. This includes reaction-invoked commands, even a specification expecti
124
125
  rejection: the outcome is `Unsupported`, before seeding facts, not a passing refusal.
125
126
  Do not change modeled severity to get an executable result.
126
127
 
127
- The semantic Host faults the session on **any outside append** to its event log,
128
- even an unrelated one, before committing an accepted command. This interim guard
129
- is stricter than the reference's dependency-scoped decide/commit conflicts; do not
130
- claim full reference conflict parity or generated-application protection.
128
+ Requires Stage 4.142.0 for decide/commit against outside facts; older Hosts fault
129
+ on any outside append. The Host decides on the session world, reads the outside
130
+ suffix and commits against the extended world. A later fact matching a protected
131
+ read's key and event contracts causes a concurrency conflict without faulting the
132
+ session; unrelated facts remain for commit-time constraints and projections.
133
+ Outside facts do not fire reactions again. Refusals retain their outcome.
134
+
135
+ The root/reaction batch uses one guarded write against the durable pre-batch tail,
136
+ even for a successful empty batch. A definitive guard loss may retry the same
137
+ decision, preserving generated values, only when settlement invoked no commands.
138
+ An invocation or eight unsuccessful attempts returns a conflict. An unknown write
139
+ outcome or unreadable/unsupported outside history faults the session, never retries
140
+ as success. Legacy custom appenders without these capabilities retain conservative
141
+ checks. These are Host guarantees, not generated-application evidence.
131
142
 
132
143
  ## Date comparisons (v26)
133
144
 
@@ -136,14 +147,54 @@ The semantic Host and specification executor compare `Date` as calendar days and
136
147
  `DateTime` as UTC ticks in `require`, `produces when` and validation rules, including
137
148
  through concepts. A participating `DateTime` input without an offset or `Z` rejects
138
149
  with Validation after authorization and before any rule. `then` stays ordinal. The
139
- renderer, legacy engines and default sandbox engine refuse these comparisons with
140
- `STAGE-ESM-046`, naming the property; no date validators or artifacts are emitted.
150
+ Cratis renderer renders these comparisons from Stage 4.141.0; older renderers and
151
+ legacy engines refuse `STAGE-ESM-046`. Read [date comparisons](date-comparisons.md)
152
+ when checking remaining renderer refusals and input-binding differences.
141
153
 
142
154
  One ordering differs from the reference: the reference checks authorization, then
143
155
  offsets, then opaque C# validation, so an offset-less DateTime beside opaque
144
156
  validation is a Validation rejection there. The specification executor refuses opaque
145
- validation at run admission and the Host refuses it before authorization, so both Stage
146
- paths report `Unsupported`, which never counts as a pass.
157
+ validation when reached at specification admission and the Host refuses a command
158
+ that reaches it before authorization, so both Stage paths report `Unsupported`,
159
+ which never counts as a pass.
160
+
161
+ ## Implementation bodies and authored occurrence
162
+
163
+ Requires Stage 4.145.0 for reach-scoped reducer and validation refusals; older semantic
164
+ engines refuse unrelated behavior when any such body exists. Neither Host nor executor
165
+ runs these bodies. `STAGE-IMPL-003` names the reached owner and RequirementId:
166
+
167
+ - command under test and commands invoked by reactions reach command validation;
168
+ - command input and query argument types reach concept rules through composites,
169
+ collections and optionals;
170
+ - given, appended or produced events reach reducer transitions; read-model assertions
171
+ and queries reach the corresponding reducer too;
172
+ - potential reaction effects are included without evaluating guards, including effects
173
+ of an action expected to be refused.
174
+
175
+ Unrelated commands, queries and specifications remain admitted. Reducer refusals use
176
+ Projection capability; validation refusals use Command. This does not relax live-world
177
+ history rebuilding or renderer admission, nor described-handler `STAGE-IMPL-002`.
178
+
179
+ Requires Stage 4.141.1 for authored occurrence in event-reaction specifications; older
180
+ executors refuse clocks beside reactions. Independent command, append and named-redelivery
181
+ specifications accept `given clock` at or after the Unix epoch in whole milliseconds.
182
+ Offset-bearing source clocks normalize to UTC; the same instant reaches direct/cascading
183
+ productions, invocation arguments, invoked commands and refusal productions. Redelivery
184
+ uses the scenario clock, not the given event's timestamp.
185
+
186
+ No authored clock means no reaction occurrence: a reached production using
187
+ `$context.occurred` rejects with `Reaction '<name>' uses $context, which needs the scenario's 'given clock'.`;
188
+ an invocation argument instead rejects as unresolved in its declared root scope.
189
+ A false `where` skips evaluation; the executor never invents wall time. The fixture
190
+ supplies time, not audit identity: `$eventSourceId`/`$eventContext.eventSourceId` and
191
+ `$context.causedBy.*` remain `STAGE-ESM-013`, even under `runs as system`.
192
+
193
+ Clock/application/startup/shutdown triggers and `when clock`/trigger/capture actions
194
+ remain `STAGE-ESM-024`. **A clock fixture is not a scheduler.** Generated backend
195
+ occurrence mappings use `EventContext.Occurred`, but context-dependent generated
196
+ reaction specs retain `-011`; generated append/redelivery clock fixtures retain `-024`.
197
+ Rendered clock fixtures remain command-only.
147
198
 
148
199
  ## Refusals shared by both engines
149
200
 
@@ -19,12 +19,16 @@
19
19
  { "kind": "skill-contains", "value": "**Render never builds, tests or runs**" },
20
20
  { "kind": "skill-contains", "value": "`[ProtectedDecision]`" },
21
21
  { "kind": "skill-contains", "value": "`Customizations/`" },
22
- { "kind": "skill-contains", "value": "`Stage__Runtime__Engine=semantic`" },
23
- { "kind": "skill-contains", "value": "`--engine semantic`" },
22
+ { "kind": "skill-contains", "value": "`Stage__Runtime__Engine=semantic`", "file": "references/sandbox-and-specrunner.md" },
23
+ { "kind": "skill-contains", "value": "`--engine semantic`", "file": "references/sandbox-and-specrunner.md" },
24
24
  { "kind": "skill-contains", "value": "Requires Cratis CLI 3.64.0 for `--engine`", "file": "references/sandbox-and-specrunner.md" },
25
25
  { "kind": "skill-contains", "value": "the environment setting below", "file": "references/sandbox-and-specrunner.md" },
26
26
  { "kind": "skill-contains", "value": "fresh in-memory Chronicle log per specification", "file": "references/sandbox-and-specrunner.md" },
27
- { "kind": "skill-contains", "value": "exact ESM v1–v21 and v23–v27 pairs" },
27
+ { "kind": "skill-contains", "value": "exact ESM v1–v27 pairs" },
28
+ { "kind": "skill-contains", "value": "Requires Stage 4.141.0", "file": "references/date-comparisons.md" },
29
+ { "kind": "skill-contains", "value": "Requires Stage 4.142.0", "file": "references/sandbox-and-specrunner.md" },
30
+ { "kind": "skill-contains", "value": "STAGE-IMPL-003", "file": "references/sandbox-and-specrunner.md" },
31
+ { "kind": "skill-contains", "value": "Requires Stage 4.146.0" },
28
32
  { "kind": "skill-contains", "value": "STAGE-ESM-044" },
29
33
  { "kind": "skill-contains", "value": "STAGE-IMPL-002" },
30
34
  { "kind": "skill-contains", "value": "all-Proven rules permit unpinned rendered", "file": "references/admission.md" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cratis/pi",
3
- "version": "7.74.0",
3
+ "version": "7.76.0",
4
4
  "description": "Configuration-aware Cratis AI integration for Pi",
5
5
  "type": "module",
6
6
  "files": [