@cratis/pi 7.66.0 → 7.68.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package/corpus/product-sync.json +3 -3
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/realization-and-gap-fill.md +1 -1
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/atomic-batches-and-source-mappings.md +1 -1
- package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +4 -3
- package/package/corpus/skills/cratis-screenplay-command-surface/references/date-comparisons.md +13 -2
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/language-reference.md +2 -2
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/state-and-recovery.md +1 -0
- package/package/corpus/skills/cratis-screenplay-model-review/references/checklist.md +1 -1
- package/package/corpus/skills/cratis-screenplay-model-review/references/public-keys-and-routes.md +4 -2
- package/package/corpus/skills/cratis-screenplay-model-review/references/report-template.md +2 -2
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/SKILL.md +1 -1
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/phases.md +1 -1
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/stop-or-assume.md +1 -1
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/verdicts-and-modes.md +6 -1
- package/package/corpus/skills/cratis-screenplay-projections/SKILL.md +8 -1
- package/package/corpus/skills/cratis-screenplay-projections/references/pdl-grammar.md +42 -2
- package/package/corpus/skills/cratis-screenplay-projections/references/reducer-identity.md +88 -0
- package/package/corpus/skills/cratis-screenplay-projections/verification.json +2 -1
- package/package/corpus/skills/cratis-screenplay-read-surface/SKILL.md +14 -7
- package/package/corpus/skills/cratis-screenplay-read-surface/references/equality-filters.md +1 -1
- package/package/corpus/skills/cratis-screenplay-read-surface/references/named-keys.md +168 -58
- package/package/corpus/skills/cratis-screenplay-read-surface/verification.json +2 -2
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/gap-fill-handoff.md +1 -1
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/renderability-gate.md +1 -1
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/scenario-examples.md +2 -2
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/spec-forms-by-mode.md +3 -3
- package/package/corpus/skills/cratis-screenplay-slice-design/SKILL.md +5 -7
- package/package/corpus/skills/cratis-screenplay-slice-design/references/public-boundaries-and-keys.md +5 -3
- package/package/corpus/skills/cratis-screenplay-slice-design/references/read-model-design.md +7 -3
- package/package/corpus/skills/cratis-screenplay-specifications/SKILL.md +3 -2
- package/package/corpus/skills/cratis-screenplay-specifications/references/query-rejections.md +4 -0
- package/package/corpus/skills/cratis-screenplay-specifications/references/vocabulary.md +17 -0
- package/package/corpus/skills/cratis-screenplay-streams-and-consistency/SKILL.md +3 -1
- package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/read-model-keys.md +46 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +11 -5
- package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet.md +17 -2
- package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +22 -8
- package/package/corpus/skills/cratis-screenplay-toolchain/references/executable-subset.md +31 -9
- package/package/corpus/skills/cratis-screenplay-toolchain/references/language-admission.md +15 -5
- package/package/corpus/skills/cratis-screenplay-toolchain/references/production-routes-and-filters.md +1 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +3 -3
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +1722 -76
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/traps.md +3 -2
- package/package/corpus/skills/cratis-screenplay-toolchain/references/verdicts.md +64 -3
- package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +8 -2
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +5 -4
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +12 -7
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/sandbox-and-specrunner.md +17 -0
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/verification.json +1 -1
- package/package.json +1 -1
|
@@ -171,9 +171,9 @@
|
|
|
171
171
|
}
|
|
172
172
|
],
|
|
173
173
|
"synced": {
|
|
174
|
-
"version": "4.
|
|
174
|
+
"version": "4.204.0",
|
|
175
175
|
"date": "2026-10-16",
|
|
176
|
-
"by": "Cratis/AI#
|
|
176
|
+
"by": "Cratis/AI#743"
|
|
177
177
|
},
|
|
178
178
|
"covers": {
|
|
179
179
|
"skills": [
|
|
@@ -201,7 +201,7 @@
|
|
|
201
201
|
],
|
|
202
202
|
"rules": []
|
|
203
203
|
},
|
|
204
|
-
"notes": "Standalone 4.201.0 and byte-identical compiler contract pinned. Cratis/AI#733: the ui profile root template, shell options, appearance and new screens default (PLAY0788-PLAY0799, quick fix for the legacy layout line, ui-profiles MCP tool, 44 tools). Cratis/AI#735: chronological Date/DateTime ordering in command conditions and command/property literal validation (ESM v26), UTC tick precision and pre-rule offset validation; then matching remains ordinal. Source-checked Screenplay v4.199.0 commands, diagnostics, interoperability and specifications documentation plus decision 0087. Stage v4.127.1 still refuses v26 with STAGE-ESM-016 (stage-rendering.md and SemanticVersionFeatures.Supports); no render/runtime probe. Cratis/AI#576: prior mechanical compiler catch-up. Language batch #717/#722/#723/#724/#720/#728/#734 teaches atomic reaction batches (v22), described payload handlers (v23), portable linear matching, ordinal text rules (v24), protected command reads (v25), diagnostic arguments and event-source invokes mappings. Facts read at Screenplay v4.198.0 and introducing tags; Stage v4.127.0 admits exact v1-v21 and v23-v25 pairs but refuses v22/v26 and mixed pairs (STAGE-ESM-016), protected reads (044), atomic mode (043) and described handlers (STAGE-IMPL-002), even Stub mode. Stage text rules execute/render; no new renderer/runtime probe or Stage pin uplift. Cratis/AI#706: application navigation regions (module inherit, extend or override), toolbar slice buttons, blueprint template references and sample data packs in cratis-screenplay-ui-composition (references/application-shell.md), with the canonical shell vector and the rejection codes PLAY0710-PLAY0722 and PLAY0740-PLAY0765. Examples moved to the executable-state rules since 4.164: translator reactions in an Automation slice beside the Translate slice (PLAY0694) and the first record of a capture key appended with `when added`. Earlier: Standalone 4.164.0 and byte-identical compiler contract pinned. Cratis/AI#663: one origin per capture (PLAY0687). #668: executable no-event/redelivery v17. #684: concept query-argument validation in every version and query-error assertions v18. #681: executable refusal branches and refusal values v19. #666: proposal summary/severity counts and exact structural source proposals. Generated-concept rules select v20 with PLAY0688/0689 proofs and derived-matches repair; generated secrets and preview strategies remain refused. Release-baseline from-esm admission reads storedName. Standalone binding is not renderer admission: Stage 4.103.0 admits v1-v17 and v19; CLI 3.62.0 bundles Screenplay 4.159.0 / Stage 4.99.0 and renders through v16. Prior evidence remains unless superseded; no new renderer, Docker or browser probe."
|
|
204
|
+
"notes": "Standalone 4.204.0 and byte-identical compiler contract pinned. Cratis/AI#702 and #691: PLAY0690 reducer identity (Screenplay 4.170.0, native compiler only) and the screenplay.json validation gate (Screenplay 4.165.0; cratis screenplay validate reads it from CLI 3.65.0) are taught and probed against the 4.204.0 compiler. Cratis/AI#743: flat composite read-model keys (ESM v27): untyped projection key blocks on root from and remove with, equality-filter lists, single-instance by blocks and per-part fixtures, with PLAY0661/PLAY0662/PLAY0268 refusals checked against the 4.204.0 compiler; Stage origin/main still refuses v27 with STAGE-ESM-016 (stage-rendering.md); Stage v4.135.0 v26 admission (Host and executor run date comparisons; renderer STAGE-ESM-046) was source-checked for this sync; no render or runtime probe. Prior: Standalone 4.201.0 and byte-identical compiler contract pinned. Cratis/AI#733: the ui profile root template, shell options, appearance and new screens default (PLAY0788-PLAY0799, quick fix for the legacy layout line, ui-profiles MCP tool, 44 tools). Cratis/AI#735: chronological Date/DateTime ordering in command conditions and command/property literal validation (ESM v26), UTC tick precision and pre-rule offset validation; then matching remains ordinal. Source-checked Screenplay v4.199.0 commands, diagnostics, interoperability and specifications documentation plus decision 0087. Stage v4.127.1 still refuses v26 with STAGE-ESM-016 (stage-rendering.md and SemanticVersionFeatures.Supports); no render/runtime probe. Cratis/AI#576: prior mechanical compiler catch-up. Language batch #717/#722/#723/#724/#720/#728/#734 teaches atomic reaction batches (v22), described payload handlers (v23), portable linear matching, ordinal text rules (v24), protected command reads (v25), diagnostic arguments and event-source invokes mappings. Facts read at Screenplay v4.198.0 and introducing tags; Stage v4.127.0 admits exact v1-v21 and v23-v25 pairs but refuses v22/v26 and mixed pairs (STAGE-ESM-016), protected reads (044), atomic mode (043) and described handlers (STAGE-IMPL-002), even Stub mode. Stage text rules execute/render; no new renderer/runtime probe or Stage pin uplift. Cratis/AI#706: application navigation regions (module inherit, extend or override), toolbar slice buttons, blueprint template references and sample data packs in cratis-screenplay-ui-composition (references/application-shell.md), with the canonical shell vector and the rejection codes PLAY0710-PLAY0722 and PLAY0740-PLAY0765. Examples moved to the executable-state rules since 4.164: translator reactions in an Automation slice beside the Translate slice (PLAY0694) and the first record of a capture key appended with `when added`. Earlier: Standalone 4.164.0 and byte-identical compiler contract pinned. Cratis/AI#663: one origin per capture (PLAY0687). #668: executable no-event/redelivery v17. #684: concept query-argument validation in every version and query-error assertions v18. #681: executable refusal branches and refusal values v19. #666: proposal summary/severity counts and exact structural source proposals. Generated-concept rules select v20 with PLAY0688/0689 proofs and derived-matches repair; generated secrets and preview strategies remain refused. Release-baseline from-esm admission reads storedName. Standalone binding is not renderer admission: Stage 4.103.0 admits v1-v17 and v19; CLI 3.62.0 bundles Screenplay 4.159.0 / Stage 4.99.0 and renders through v16. Prior evidence remains unless superseded; no new renderer, Docker or browser probe."
|
|
205
205
|
},
|
|
206
206
|
{
|
|
207
207
|
"id": "scene",
|
|
@@ -23,7 +23,7 @@ rejected model renderable, and never claim a whole-application V5 from a subset.
|
|
|
23
23
|
with `cratis-screenplay-render-and-gap-fill`.
|
|
24
24
|
|
|
25
25
|
Application-root `reaction batches atomic` also blocks Stage delivery: v22
|
|
26
|
-
refuses STAGE-ESM-016; mode in admitted v23–
|
|
26
|
+
refuses STAGE-ESM-016; mode in admitted v23–v26 refuses STAGE-ESM-043. Preserve the
|
|
27
27
|
per-occurrence/selected-branch batch boundary and independent invoked commands.
|
|
28
28
|
Atomic appends do not prove redelivery deduplication or external exactly-once effects.
|
|
29
29
|
|
|
@@ -36,7 +36,7 @@ batch and unchanged read models with evaluator world/read-model assertions; earl
|
|
|
36
36
|
accepted work can remain. `then no events` means accepted zero outcomes and cannot
|
|
37
37
|
accompany `then error`. Do not invent a mixed success/error specification form.
|
|
38
38
|
|
|
39
|
-
Stage refuses ESM v22 with STAGE-ESM-016. Even an admitted v23–
|
|
39
|
+
Stage refuses ESM v22 with STAGE-ESM-016. Even an admitted v23–v26 model carrying
|
|
40
40
|
atomic mode is refused with STAGE-ESM-043 by renderer, Host and specification executor.
|
|
41
41
|
Keep the declaration and report authorized gap-fill; do not promise a render date or
|
|
42
42
|
strip atomicity to lower the version.
|
|
@@ -155,8 +155,9 @@ reads/concurrency cannot combine (PLAY0783). The Cratis C# renderer refuses prot
|
|
|
155
155
|
semantic Host/executor support is separate.
|
|
156
156
|
Uniqueness still uses a constraint; reference success is not target realization.
|
|
157
157
|
|
|
158
|
-
Do not use `reads` to fetch data the caller could supply. A composite-key view's `by` block
|
|
159
|
-
`
|
|
158
|
+
Do not use `reads` to fetch data the caller could supply. A composite-key view's `by` block in a
|
|
159
|
+
command read is `PLAY0271`, or `PLAY0781` ByParts under `command reads protected`
|
|
160
|
+
(read-surface `references/named-keys.md`).
|
|
160
161
|
|
|
161
162
|
## `validate`
|
|
162
163
|
|
|
@@ -182,7 +183,7 @@ Requires Screenplay 4.199.0 (ESM v26; `screenplay --version`) for Date/DateTime
|
|
|
182
183
|
comparisons; older binders report PLAY0268. Read [date comparisons](references/date-comparisons.md)
|
|
183
184
|
when ordering a retention window with `require to >= from`, comparing instants
|
|
184
185
|
across offsets, or rejecting offset-less inputs before rules. It covers admitted
|
|
185
|
-
positions, PLAY0268/0273, ordinal `then` matching and Stage's
|
|
186
|
+
positions, PLAY0268/0273, ordinal `then` matching and Stage's STAGE-ESM-046 renderer refusal.
|
|
186
187
|
|
|
187
188
|
**Rules whose logic is code.** A bare `rule <Name>` has no portable meaning (`PLAY0268`) and a bodied rule binds only as
|
|
188
189
|
opaque code. Read [references/validate-rules.md](references/validate-rules.md) when a rule's logic must live in a `file`
|
package/package/corpus/skills/cratis-screenplay-command-surface/references/date-comparisons.md
CHANGED
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
|
|
4
4
|
# Chronological command date comparisons
|
|
5
5
|
|
|
6
|
+
## Contents
|
|
7
|
+
|
|
8
|
+
- Retention window and rejection specifications
|
|
9
|
+
- Missing-offset input rejection
|
|
10
|
+
|
|
6
11
|
Requires Screenplay 4.199.0 (ESM v26; `screenplay --version`); older binders refuse date comparisons with PLAY0268. Upgrade the compiler without weakening the rule.
|
|
7
12
|
|
|
8
13
|
Use `==`, `!=`, `>`, `>=`, `<` or `<=` with matching primitives: Date/Date or
|
|
@@ -27,13 +32,19 @@ Targets must enforce this before deserialization attaches a local offset, and
|
|
|
27
32
|
preserve tick precision or refuse the comparison; JavaScript `Date` alone truncates
|
|
28
33
|
precision. Client validators omit date ordering rules. Optional absent values still
|
|
29
34
|
pass validation rules other than `not empty`; optional condition operands refuse.
|
|
35
|
+
A .NET host that executes commands itself can reuse the reference evaluator's date semantics (Requires Screenplay 4.203.0): see [date comparison checks](https://github.com/Cratis/Screenplay/blob/main/Documentation/screenplay/date-comparison-checks.md) for `SemanticDateComparisons` and `SemanticConditionEvaluator`.
|
|
30
36
|
|
|
31
37
|
PLAY0268 still refuses mixed Date/DateTime, `$context` operands (including
|
|
32
38
|
`$context.occurred`), `today`, protected read paths, date rules on concepts and
|
|
33
39
|
reaction `where`. A refused whole comparison reports only PLAY0268, without
|
|
34
40
|
validating its literals. A `given clock` does not admit `today` or now.
|
|
35
|
-
Stage refuses v26 with STAGE-ESM-016
|
|
36
|
-
|
|
41
|
+
Requires Stage 4.135.0 for v26 admission; older Stage refuses v26 with STAGE-ESM-016.
|
|
42
|
+
The semantic Host and specification executor run the comparisons, including through
|
|
43
|
+
concepts, and reject an offset-less DateTime input after authorization and before any
|
|
44
|
+
rule. The renderer, legacy engines and default sandbox engine refuse them with
|
|
45
|
+
STAGE-ESM-046, naming the property, and emit no artifacts or date validators. Standalone
|
|
46
|
+
binding/reference execution is not rendering: preserve the rule and route delivery to
|
|
47
|
+
authorized gap-fill.
|
|
37
48
|
|
|
38
49
|
## Retention window and rejection specifications
|
|
39
50
|
|
package/package/corpus/skills/cratis-screenplay-model-authoring/references/language-reference.md
CHANGED
|
@@ -272,9 +272,9 @@ See read-surface `references/named-keys.md` for the collection-key exclusion alg
|
|
|
272
272
|
| Described handlers (ESM v23) | Pending implementation beside unconditional produces; payload-only contract, reached body Unsupported ImplementationBody; Stage STAGE-IMPL-002 even Stub mode |
|
|
273
273
|
| Ordinal text rules (ESM v24) | contains/not contains/starts with/ends with on scalar non-enum text properties; quoted literals, not conditions; Stage semantic engines execute/render |
|
|
274
274
|
| Protected command reads (ESM v25) | Root `command reads protected`; eligible read paths in requirements and production mappings, absence Validation, concurrent matching facts Conflict; Stage admits v25; Cratis C# rendering refuses STAGE-ESM-044, semantic Host/executor execute admitted reads with non-Error protected requirements refused STAGE-ESM-045 |
|
|
275
|
-
| Chronological command dates (ESM v26) | Same-primitive Date/DateTime `==`, `!=`, `>`, `>=`, `<`, `<=` in require/produces-when (property or literal RHS) and command/property rules (literal RHS only). DateTime uses UTC ticks, participating offset-less inputs reject Validation before rules; then matching stays ordinal. Requires Screenplay 4.199.0 (`screenplay --version`); older binders refuse PLAY0268. Stage
|
|
275
|
+
| Chronological command dates (ESM v26) | Same-primitive Date/DateTime `==`, `!=`, `>`, `>=`, `<`, `<=` in require/produces-when (property or literal RHS) and command/property rules (literal RHS only). DateTime uses UTC ticks, participating offset-less inputs reject Validation before rules; then matching stays ordinal. Requires Screenplay 4.199.0 (`screenplay --version`); older binders refuse PLAY0268. The Stage Host and executor run v26 (older Stage refuses STAGE-ESM-016); the renderer and legacy engines refuse STAGE-ESM-046 (toolchain `language-admission.md`). Read command-surface `references/date-comparisons.md`. |
|
|
276
276
|
| Current routing and actor admission | Sources/streams and command/specification routes bind and reference-execute as v8; reaction `runs as system role` supplies the invocation actor as v10. Whole-workspace binding determines executable availability; CLI/Stage realization remains separate |
|
|
277
|
-
| Blocks binding (`PLAY0268`) | enum/identity compliance and events combining personal or explicitly subject-scoped secret values with explicit subject marks; a compiler that stops before v13 refuses all `pii`/`secret` concepts ("compliance attributes require portable data-subject semantics"), while v13 binds them and Stage renders protection; attached command `handler` (PLAY0035 beside productions; pending described intent instead binds v23), bare `rule <Name>`, read paths without protected opt-in or in unsupported positions such as `produces when`, date comparisons with mixed primitives, optional condition operands, `$context`, protected read paths or `today`, date rules on concepts or reaction `where`, `$context.tenant`/claims/roles/causation in `produces`, `$env` conditions, `file` constraints, unquoted `import` of an external contract, a read model with neither explicit `key` nor unambiguous query-based identity as described above (
|
|
277
|
+
| Blocks binding (`PLAY0268`) | enum/identity compliance and events combining personal or explicitly subject-scoped secret values with explicit subject marks; a compiler that stops before v13 refuses all `pii`/`secret` concepts ("compliance attributes require portable data-subject semantics"), while v13 binds them and Stage renders protection; attached command `handler` (PLAY0035 beside productions; pending described intent instead binds v23), bare `rule <Name>`, read paths without protected opt-in or in unsupported positions such as `produces when`, date comparisons with mixed primitives, optional condition operands, `$context`, protected read paths or `today`, date rules on concepts or reaction `where`, `$context.tenant`/claims/roles/causation in `produces`, `$env` conditions, `file` constraints, unquoted `import` of an external contract, a read model with neither explicit `key` nor unambiguous query-based identity as described above (several key marks bind as v27; older binders refuse PLAY0268; toolchain `language-admission.md`), queries with context `from` sources (typed query context is unadmitted), single-result filters (collections only), `scoped to` (opaque scope), `performer` (opaque implementation) or a `by` block on a list query or non-optional single result; optional keyed and collection queries, including caller-supplied equality filters and observable delivery, bind, `$causedBy` and templates in projections |
|
|
278
278
|
| Blocks binding (`PLAY0271`, legacy meaning) | Command reads without protected opt-in and `concurrency`; combined protected reads/concurrency is PLAY0783 |
|
|
279
279
|
| Deferred (`PLAY0269`, information) | Screens, layouts, templates, forms, contributions, UI profiles, themes, behaviors and `on`/`uses` |
|
|
280
280
|
| Metadata only (`PLAY0270`, information) | `domain`, `seed`, `persona`, trigger and other descriptions, and `file` provenance on declarations |
|
package/package/corpus/skills/cratis-screenplay-model-authoring/references/state-and-recovery.md
CHANGED
|
@@ -4,6 +4,7 @@ This reference holds identity-state, journal and recovery rules and the readines
|
|
|
4
4
|
|
|
5
5
|
## Preserve state and recover explicitly
|
|
6
6
|
|
|
7
|
+
`.screenplay/` is tool-owned; the only authored file beside it is `screenplay.json`, the validation gate, which no MCP operation writes.
|
|
7
8
|
Commit `.screenplay/identities.json` with the model. Only `apply` writes it;
|
|
8
9
|
`open-workspace` never creates it; text-only models have none. Never delete or
|
|
9
10
|
overwrite conflicting identity state, silently mint IDs on restart, or text-rename
|
|
@@ -180,7 +180,7 @@ Nebulit (`provenance.md`).
|
|
|
180
180
|
| Id | Check | Evidence | Tier |
|
|
181
181
|
|---|---|---|---|
|
|
182
182
|
| H1 | Query shape follows the business view (list where people scan; lookup where they open one) | queries, screens | D |
|
|
183
|
-
| H2 | Executable scope: a keyed `=> RM optional` query with `by` named like a read-model property, or a collection (`=> RM[]`, observable too) with caller-supplied `by` and/or equality filters. `from`, single-result filters, opaque `scoped to`/`performer` and
|
|
183
|
+
| H2 | Executable scope: a keyed `=> RM optional` query with `by` named like a read-model property, or a collection (`=> RM[]`, observable too) with caller-supplied `by` and/or equality filters. `from`, single-result filters, opaque `scoped to`/`performer` and a list-query `by` block remain PLAY0268. A read model with several key parts binds as v27 (Requires Screenplay 4.204.0). The projection routes by the same identity (a `from` key or an event property, or `$eventSourceId`; `$eventSourceId` is not mandated). Filtered models: supported v14 equality filters render within the CLI bundle's ESM ceiling. Renderable scope only: Stage-specific identity/filter limits; keyed optional snapshot lookups and snapshot/observable collections render (Requires Stage 4.90.0 for snapshot lists; older renderers report `STAGE-ESM-010`). Check query concept-validation parity separately; primitive-argument targets answer absence instead of Validation | queries, projections | C (executable); C (render admission, renderable only) |
|
|
184
184
|
| H3 | One builder per read model; projection `key` only on `from` | projections | C |
|
|
185
185
|
| H4 | Screens show one actor's point of view; a form submits one command | screens, forms | D |
|
|
186
186
|
|
package/package/corpus/skills/cratis-screenplay-model-review/references/public-keys-and-routes.md
CHANGED
|
@@ -16,8 +16,10 @@ Add these to the element sweep, with evidence pinned to the declaration:
|
|
|
16
16
|
- Is the view identity explicitly marked `key` or unambiguously inferred? Does each
|
|
17
17
|
single-instance query/read supply every part exactly once, with compatible types,
|
|
18
18
|
and do state fixtures contain all parts? Do PDL keys align with the view's key?
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
Flat composite view keys bind as ESM v27 (older binders refuse with PLAY0268;
|
|
20
|
+
compiler requirement in read-surface `references/named-keys.md`); compilation alone is not executable evidence. Does
|
|
21
|
+
each projection `from` and `remove with` name every part in an untyped `key` block?
|
|
22
|
+
Read read-surface `references/named-keys.md`.
|
|
21
23
|
- Does a production override replace the whole source/stream/id route, rather than
|
|
22
24
|
assume partial inheritance? Is its `for` destination still explicit and compatible?
|
|
23
25
|
Are skipped production routes valid, so eager resolution cannot fail unexpectedly?
|
|
@@ -167,8 +167,8 @@ it. Verify the answer became a specification, a description or a project-owned
|
|
|
167
167
|
decision record; a resolved note is not behavioral proof. Ask the owner to reanchor
|
|
168
168
|
or resolve affected notes before source apply; resolution alone leaves an orphan.
|
|
169
169
|
|
|
170
|
-
The optional `--open-questions fail` gate
|
|
171
|
-
|
|
170
|
+
The optional `--open-questions fail` gate exists on the standalone `screenplay` tool and on
|
|
171
|
+
`cratis screenplay validate` (CLI 3.60.0 or later). Report it separately from V1–V5. Evidence: Screenplay
|
|
172
172
|
`Documentation/screenplay/model-notes.md`,
|
|
173
173
|
`Documentation/screenplay/mcp/reference.md`; source lines in the linked guide.
|
|
174
174
|
|
|
@@ -75,7 +75,7 @@ or **critic** (P4-P5: strict, report first, fix in a separate batch).
|
|
|
75
75
|
## Verdicts (independent evidence, not a ladder)
|
|
76
76
|
| Verdict | Meaning | Does not prove |
|
|
77
77
|
|---|---|---|
|
|
78
|
-
| V1 authorable | compiles, warnings as errors | meaning, binding |
|
|
78
|
+
| V1 authorable | compiles, warnings as errors (declared gate) | meaning, binding |
|
|
79
79
|
| V2 executable diagnostics | the executable model produces none | that specs run |
|
|
80
80
|
| V3 binding-ready | the model binds | that any spec passes |
|
|
81
81
|
| V4 reference specs run | engine, expected vs discovered | rendering or build health |
|
|
@@ -109,7 +109,7 @@ phase, a decision important enough that a later reader could misread the model (
|
|
|
109
109
|
## P6 Accept (the user)
|
|
110
110
|
- **Input**: the reviewed source identity.
|
|
111
111
|
- **Carry-forward**: the accepted **source identity** (`verdicts-and-modes.md`).
|
|
112
|
-
- **Commit at P6**: the accepted `.play` files and `.screenplay/identities.json` when present.
|
|
112
|
+
- **Commit at P6**: the accepted `.play` files, `screenplay.json` (the authored validation gate) when the repository has one, and `.screenplay/identities.json` when present.
|
|
113
113
|
The user commits, or explicitly authorizes the owning session to commit; the modeler never
|
|
114
114
|
commits on its own. Run `cratis-screenplay-modeling-lifecycle`'s `scripts/model-first-status.mjs` to check acceptance, drafts and model changes in progress.
|
|
115
115
|
- **Gate**: explicit acceptance and the model commit before P7-P9. After committing, recompute
|
package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/stop-or-assume.md
CHANGED
|
@@ -64,7 +64,7 @@ consequential policy. Resolving is not implementation; a known refusal still
|
|
|
64
64
|
needs `then error` or `then denied`. Reopen when the evidence ceases to answer it.
|
|
65
65
|
|
|
66
66
|
Question gating is separate from V1: standalone Screenplay 4.144.0 has
|
|
67
|
-
`--open-questions fail
|
|
67
|
+
`--open-questions fail`, and `cratis screenplay validate` has it from CLI 3.60.0. Read toolchain
|
|
68
68
|
`references/verdicts.md` "Model notes gate" when a phase requires no open questions.
|
|
69
69
|
Product evidence: Screenplay `Documentation/screenplay/model-notes.md`,
|
|
70
70
|
`decisions/0045-model-notes-sidecar.md` and the model-authoring source table.
|
package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/verdicts-and-modes.md
CHANGED
|
@@ -48,6 +48,11 @@ V5 rules:
|
|
|
48
48
|
## Commands (enough to check without loading the toolchain skill)
|
|
49
49
|
- V1, preferred: `screenplay <model-folder> --warnaserror --no-color` (check "N file(s) compiled").
|
|
50
50
|
- V1, fallback: `cratis screenplay validate <model-folder> --warnings-as-errors`.
|
|
51
|
+
- The repository's gate file: V1 runs through a `screenplay.json` at the model root when one exists
|
|
52
|
+
(checks, warnings as errors, scope, open questions), so it is part of the verification contract.
|
|
53
|
+
Read the effective gate with `screenplay <model-folder> --print-gate`, name it on the V1 line, and
|
|
54
|
+
never bypass it with `--no-gate-file` without saying so. A refused file is `V1 not run: gate file
|
|
55
|
+
refused`, not a pass. Commands and precedence: toolchain `references/verdicts.md`.
|
|
51
56
|
- V2, V3: the MCP workspace readiness and executable diagnostics.
|
|
52
57
|
- Name tool and version on each line. A tool older than the model's constructs reports false
|
|
53
58
|
failures; see the toolchain skill.
|
|
@@ -56,7 +61,7 @@ V5 rules:
|
|
|
56
61
|
|
|
57
62
|
```text
|
|
58
63
|
Mode: executable Source: <commit+digest from the source-identity helper> / ws <revision> cat <catalogRevision>
|
|
59
|
-
V1 authorable: pass (N files)
|
|
64
|
+
V1 authorable: pass (N files, gate: <screenplay.json or flags>) | fail: PLAYnnnn at file:line - meaning | not run: gate file refused
|
|
60
65
|
V2 diagnostics: none (executable model) | n diagnostics | not run: <reason>
|
|
61
66
|
V3 binding: ready | blocked: PLAYnnnn ... | not run: design mode
|
|
62
67
|
V4 specs: 12 expected / 12 discovered, 11 passed, 1 unsupported (route) | not run: no route
|
|
@@ -100,6 +100,7 @@ the executable model routes any event by it, and it is not a default for the
|
|
|
100
100
|
| From-level block | indented `key invoiceId` inside the `from` |
|
|
101
101
|
| Per event, several events | `from A key idA, B key idB, C` |
|
|
102
102
|
| Composite | `key OrderKey` with indented `<property> = <expr>` parts |
|
|
103
|
+
| Flat composite parts | untyped `key` block naming every key part (Requires 4.204.0; ESM v27) |
|
|
103
104
|
| Literal (constant) | `key literal "site-stats"` — every event updates the **same** instance |
|
|
104
105
|
| Children identity | `children lines identified by lineNumber` |
|
|
105
106
|
| **Default** | **the event source id** — `from X` ≡ `from X key $eventSourceId` |
|
|
@@ -120,6 +121,10 @@ subscribe to it exactly like a standalone event. Verified extraction preserves
|
|
|
120
121
|
canonical ESM and identities, so it changes no projection contract. Removing a
|
|
121
122
|
payload property is different and requires consumer/persistence review.
|
|
122
123
|
|
|
124
|
+
A read model with several flat `key` parts needs that block in every root `from` and
|
|
125
|
+
`remove with` (`PLAY0661`/`PLAY0662`); other blocks and reducers there are `PLAY0268`
|
|
126
|
+
(`references/pdl-grammar.md`).
|
|
127
|
+
|
|
123
128
|
A second key on one `from` is error `PLAY0060`. A template expression in a
|
|
124
129
|
composite key is error `PLAY0073`; an empty composite key is `PLAY0074`.
|
|
125
130
|
|
|
@@ -256,7 +261,9 @@ What the executable model does with it (ESM v3):
|
|
|
256
261
|
rules is `PLAY0398`; two rules for one event is `PLAY0399`; a reducer with no
|
|
257
262
|
bodies is rejected with a hint to write a projection.
|
|
258
263
|
- The key is **always the event source id** — a reducer cannot route by an event
|
|
259
|
-
property. State starts at null; returning null deletes the instance.
|
|
264
|
+
property. State starts at null; returning null deletes the instance. A query
|
|
265
|
+
`by` another identity type warns `PLAY0690`; use a projection keyed on each `from`
|
|
266
|
+
or a join ([reducer identity](references/reducer-identity.md)).
|
|
260
267
|
- The body is an opaque attachment identified by a content hash, never compiled
|
|
261
268
|
or run by Screenplay. The reference runner cannot compute reducer state, so a
|
|
262
269
|
specification that reads a reducer-built read model reports unsupported and
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
- Parser regexes
|
|
7
7
|
- Diagnostics
|
|
8
8
|
- Syntax that parses but means something else
|
|
9
|
+
- Flat composite read-model keys
|
|
9
10
|
- Worked examples
|
|
10
11
|
|
|
11
12
|
Checked against `Documentation/screenplay/projections/{grammar,semantic-model,keys,variants}.md`
|
|
@@ -69,11 +70,11 @@ NestedBlock = "nested", Ident, NL,
|
|
|
69
70
|
ClearWithBlock = "clear", "with", TypeRef, NL ;
|
|
70
71
|
|
|
71
72
|
RemoveWithBlock = "remove", "with", TypeRef, [ "key", Expr ], NL,
|
|
72
|
-
[ INDENT, [ ParentDecl ], DEDENT ] ;
|
|
73
|
+
[ INDENT, [ CompositeKeyDecl ], [ ParentDecl ], DEDENT ] ;
|
|
73
74
|
RemoveWithJoinBlock = "remove", "via", "join", "on", TypeRef, [ "key", Expr ], NL ;
|
|
74
75
|
|
|
75
76
|
KeyDecl = "key", Expr, NL ;
|
|
76
|
-
CompositeKeyDecl= "key", TypeRef, [ "{" ], NL,
|
|
77
|
+
CompositeKeyDecl= "key", [ TypeRef ], [ "{" ], NL,
|
|
77
78
|
INDENT, KeyPart, { NL, KeyPart }, DEDENT, [ "}", NL ] ;
|
|
78
79
|
KeyPart = Ident, "=", Expr ;
|
|
79
80
|
|
|
@@ -172,6 +173,45 @@ LiteralKeyword = "literal", " ", Literal ; (* parsed at the Expr level *)
|
|
|
172
173
|
| `all` beside removals, `children` or `nested` | Binds, but the reference execution plan refuses it |
|
|
173
174
|
| `join`, `children` or `remove via join` inside `nested` | Not wired by Chronicle's engine; binds, but the reference execution plan refuses it |
|
|
174
175
|
|
|
176
|
+
## Flat composite read-model keys
|
|
177
|
+
|
|
178
|
+
Requires Screenplay 4.204.0 (ESM v27; `screenplay --version`); older binders refuse a
|
|
179
|
+
read model with two or more `key` marks with PLAY0268.
|
|
180
|
+
|
|
181
|
+
A read model with several flat `key` properties takes an **untyped** `key` block (no
|
|
182
|
+
type name) in each root `from` and `remove with`, naming every key part once as
|
|
183
|
+
`<property> = <expr>`. It differs from the typed composite key above, which fills one
|
|
184
|
+
single property of composite type.
|
|
185
|
+
|
|
186
|
+
```screenplay excerpt
|
|
187
|
+
projection PaymentTotals => PaymentTotals
|
|
188
|
+
no automap
|
|
189
|
+
from PaymentReceived
|
|
190
|
+
key
|
|
191
|
+
invoiceId = invoice
|
|
192
|
+
method = method
|
|
193
|
+
total = amount
|
|
194
|
+
remove with PaymentRemoved
|
|
195
|
+
key
|
|
196
|
+
invoiceId = invoice
|
|
197
|
+
method = method
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
The block applies to every event the `from` names. Part order does not matter; creating
|
|
201
|
+
an instance writes each part to its property even with `no automap`, and a mapping that
|
|
202
|
+
contradicts a part fails the projection. `remove with` deletes only the instance whose
|
|
203
|
+
parts all match, and a later `from` recreates it.
|
|
204
|
+
|
|
205
|
+
| Written | Code |
|
|
206
|
+
| --- | --- |
|
|
207
|
+
| `from` or `remove with` with no key, `key <expr>`, an inline `from A key x`, or `parent` | PLAY0661 |
|
|
208
|
+
| A part missing from the block | PLAY0661 |
|
|
209
|
+
| An unknown, repeated or ill-typed part, a non-simple expression, or a typed key block on a composite-keyed read model | PLAY0662 |
|
|
210
|
+
| `join`, `children`, `remove via join`, `every`, `all`, `nested`, `clear with`, `variant`, or a reducer on the read model | PLAY0268 |
|
|
211
|
+
|
|
212
|
+
The complete executable example, with queries and specifications, is in read-surface
|
|
213
|
+
`references/named-keys.md`.
|
|
214
|
+
|
|
175
215
|
## Worked examples
|
|
176
216
|
|
|
177
217
|
Each example is an excerpt: the events and read models it names are declared
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Reducer instance identity (PLAY0690)
|
|
2
|
+
|
|
3
|
+
A reducer instance is keyed by the **event-source id** of the event it reduces. A reducer cannot be re-keyed by a payload value, a read-model `key` or a stream partition. A view that must be looked up by anything other than that event-source identity needs a projection.
|
|
4
|
+
|
|
5
|
+
Requires Screenplay 4.170.0 or later (`screenplay --version`) for PLAY0690; an older compiler does not report it, so a clean run there does not clear the mismatch.
|
|
6
|
+
|
|
7
|
+
## What PLAY0690 reports
|
|
8
|
+
|
|
9
|
+
A warning (it fails `--warnaserror`) in two cases:
|
|
10
|
+
|
|
11
|
+
- A reducer-backed query returns one instance `by` a scalar whose nominal type differs from the identity type of an observed event whose producers are all known, for example `by month Month` while the events live on `ResourceId` streams.
|
|
12
|
+
- The producers of one reducer's events use several different nominal identity types, so no single identity can key the instances. One reducer warning replaces the repeated query warnings.
|
|
13
|
+
|
|
14
|
+
This example reports PLAY0690 on `ByMonth`: the instances follow `ResourceId`, not `Month`.
|
|
15
|
+
|
|
16
|
+
```screenplay expect PLAY0690
|
|
17
|
+
concept ResourceId : String
|
|
18
|
+
concept Month : String
|
|
19
|
+
module Work
|
|
20
|
+
feature Reporting
|
|
21
|
+
slice StateView Totals
|
|
22
|
+
event Recorded
|
|
23
|
+
month Month
|
|
24
|
+
hours Decimal
|
|
25
|
+
readmodel Totals
|
|
26
|
+
month Month key
|
|
27
|
+
hours Decimal
|
|
28
|
+
reducer Fold => Totals
|
|
29
|
+
on Recorded
|
|
30
|
+
```csharp
|
|
31
|
+
return context.State is null
|
|
32
|
+
? new(context.Event.month, context.Event.hours)
|
|
33
|
+
: context.State with { hours = context.State.hours + context.Event.hours };
|
|
34
|
+
```
|
|
35
|
+
query ByMonth => Totals optional
|
|
36
|
+
by month Month
|
|
37
|
+
slice StateChange Record
|
|
38
|
+
command Record
|
|
39
|
+
resource ResourceId identifier
|
|
40
|
+
month Month
|
|
41
|
+
hours Decimal
|
|
42
|
+
produces Recorded
|
|
43
|
+
for resource
|
|
44
|
+
month = month
|
|
45
|
+
hours = hours
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Fix
|
|
49
|
+
|
|
50
|
+
To aggregate by a payload value, replace the reducer with a projection that declares a property key on each `from`. The read-model `key` and the `from` key then agree, and the warning is gone:
|
|
51
|
+
|
|
52
|
+
```screenplay
|
|
53
|
+
concept ResourceId : String
|
|
54
|
+
concept Month : String
|
|
55
|
+
module Work
|
|
56
|
+
feature Reporting
|
|
57
|
+
slice StateView Totals
|
|
58
|
+
event Recorded
|
|
59
|
+
month Month
|
|
60
|
+
hours Decimal
|
|
61
|
+
readmodel Totals
|
|
62
|
+
month Month key
|
|
63
|
+
hours Decimal
|
|
64
|
+
projection Fold => Totals
|
|
65
|
+
from Recorded key month
|
|
66
|
+
add hours by hours
|
|
67
|
+
query ByMonth => Totals optional
|
|
68
|
+
by month Month
|
|
69
|
+
slice StateChange Record
|
|
70
|
+
command Record
|
|
71
|
+
resource ResourceId identifier
|
|
72
|
+
month Month
|
|
73
|
+
hours Decimal
|
|
74
|
+
produces Recorded
|
|
75
|
+
for resource
|
|
76
|
+
month = month
|
|
77
|
+
hours = hours
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
When instances already exist under their own identity and another event only enriches them, use a [join](joins.md) instead: it updates the existing instances and never creates one. There is no automatic repair from a reducer to a projection.
|
|
81
|
+
|
|
82
|
+
## What the check compares
|
|
83
|
+
|
|
84
|
+
- It compares declared **nominal** identity types (`Month` and `ResourceId` differ even though both wrap text), never property names, primitive backing, stream ids or fixture values. Equal types do not prove equal runtime ids, and distinct concepts can hold equal values, so a finding is a likely modeling mistake rather than proof.
|
|
85
|
+
- It compares only where the producer is known: a command production with `for`, an implicit or generated command identifier, and a reaction production with an explicit `for`. All producers across the application count, after source and stream filters and production-route overrides.
|
|
86
|
+
- Not compared (unknown provenance): a plain `produces` without `for` (it lands on an identity the request allocates), a reaction without `for`, captures, seeds and code. An unknown producer suppresses the query comparison for that event.
|
|
87
|
+
- Collection queries, performer-served or unbuilt views, projection-backed views and public-event reducer targets do not trigger it.
|
|
88
|
+
- It is a native C# compiler diagnostic: the standalone tool, `cratis screenplay validate` (when its bundled compiler is new enough) and MCP diagnostics report it. The TypeScript compiler and editors only pass through findings the host supplies, so a clean editor is not evidence.
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
{ "kind": "skill-contains", "value": "**routes nothing** (`PLAY0381`)" },
|
|
17
17
|
{ "kind": "skill-contains", "value": "The key is **always the event source id**" },
|
|
18
18
|
{ "kind": "skill-contains", "value": "**A join never creates an" },
|
|
19
|
-
{ "kind": "skill-contains", "value": "Inline code uses a tagged fence" }
|
|
19
|
+
{ "kind": "skill-contains", "value": "Inline code uses a tagged fence" },
|
|
20
|
+
{ "kind": "skill-contains", "value": "PLAY0690", "file": "references/reducer-identity.md" }
|
|
20
21
|
]
|
|
21
22
|
}
|
|
@@ -54,11 +54,13 @@ identity (all such queries must agree). Only with no single-instance identifier
|
|
|
54
54
|
and an admitted list query does the binder infer an unambiguous `*Id`; queryless
|
|
55
55
|
read models need an explicit `key`. See named keys below for collection-key exclusions.
|
|
56
56
|
One explicit key binds byte-identically to equivalent inference. Several marks
|
|
57
|
-
form a composite key
|
|
58
|
-
`by`
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
form a flat composite key: an optional single-instance query names every part in a
|
|
58
|
+
`by` block, a list query narrows with equality filters, and fixtures state every part.
|
|
59
|
+
Requires Screenplay 4.204.0 (ESM v27; `screenplay --version`); older binders refuse
|
|
60
|
+
several key marks with PLAY0268. A list query over such a read model cannot use a
|
|
61
|
+
`by` block (PLAY0268).
|
|
62
|
+
Read [named keys](references/named-keys.md) for one complete executable example,
|
|
63
|
+
trigger/command reads, all-parts fixtures, PLAY0660–0662 and command-read-only PLAY0661 repair.
|
|
62
64
|
A `=>` target resolving to an event is an event-target builder, not a read model;
|
|
63
65
|
keep event and read-model names distinct (see projections' public-event targets).
|
|
64
66
|
|
|
@@ -78,7 +80,7 @@ query ListInvoices => InvoiceListReadModel[]
|
|
|
78
80
|
**Name the compiler and renderer.** Optional keyed queries and collection queries
|
|
79
81
|
bind, including `observable`. Caller-supplied equality
|
|
80
82
|
filters on collections bind as ESM v14; `from`, single-result filters, `scoped to`,
|
|
81
|
-
`performer` and
|
|
83
|
+
`performer` and a `by` block on a list query (or on a non-optional single result) remain PLAY0268, each with its reason. Read
|
|
82
84
|
[equality filters](references/equality-filters.md) for the admitted shape, a complete
|
|
83
85
|
compiled specification model and the Stage/CLI ceilings. Keep a list the domain needs.
|
|
84
86
|
|
|
@@ -177,13 +179,17 @@ primitive/concept/enum properties, same nominal type ignoring optionality, no
|
|
|
177
179
|
`from`, distinct names not repeating `by`. `by` and supplied filters AND together;
|
|
178
180
|
optional filters may be omitted, but supplied null is refused. PLAY0268 still
|
|
179
181
|
rejects context sources, single-result filters, opaque scope/performer and
|
|
180
|
-
|
|
182
|
+
a `by` block on a list query (or on a non-optional single result).
|
|
181
183
|
Authorization runs before lookup, ANDed with module/feature gates; policies see
|
|
182
184
|
only `by`, never filters. Pin denial with `given caller` and `then denied`.
|
|
183
185
|
Specs pass `by` and filters by name (PLAY0468 for unknown, repeated or missing
|
|
184
186
|
required arguments); collection results match by read model/key regardless of
|
|
185
187
|
row order. Details and renderer limits: [equality filters](references/equality-filters.md).
|
|
186
188
|
|
|
189
|
+
A reducer-built view is keyed by event-source id, so a single-instance `by` of another
|
|
190
|
+
nominal type warns `PLAY0690`. Rebuild it as a projection keyed on each `from`: projections
|
|
191
|
+
[reducer identity](../cratis-screenplay-projections/references/reducer-identity.md).
|
|
192
|
+
|
|
187
193
|
## `screen` — three levels
|
|
188
194
|
|
|
189
195
|
The examples below are excerpts: each screen sits in a slice, and the queries,
|
|
@@ -301,6 +307,7 @@ binding failures are errors.
|
|
|
301
307
|
- [ ] Every authorized query has a specification with `given caller`, including a
|
|
302
308
|
`then denied` case.
|
|
303
309
|
- [ ] Each read model has exactly one builder and every field traces to an event.
|
|
310
|
+
- [ ] A reducer-built view's `by` type matches its events' event-source identity (`PLAY0690`).
|
|
304
311
|
- [ ] No screen reference is left ambiguous or unresolved.
|
|
305
312
|
- [ ] Every UI binding that consumes screen data (component context, toolbar
|
|
306
313
|
parameter, dialog input, outlet route) has a source in the screen contract
|
|
@@ -40,7 +40,7 @@ Each binding refusal reports PLAY0268 with its query/filter and reason:
|
|
|
40
40
|
| Filter on a single-result query | Equality filters are admitted only for collections |
|
|
41
41
|
| `scoped to` | The named scope has no portable executable scope contract |
|
|
42
42
|
| `performer` | Query implementation code is opaque, not a portable declarative lookup |
|
|
43
|
-
|
|
|
43
|
+
| `by` block on a collection query | A composite lookup is admitted only for an optional single-instance query; narrow a list by composite-keyed read-model parts with equality filters instead |
|
|
44
44
|
| Filter on a collection/composite property, missing property or mismatched nominal type | The v14 filter contract requires a same-named scalar primitive, concept or enum property with the same type |
|
|
45
45
|
|
|
46
46
|
Keep those intents when the domain needs them; never drop a context source or
|