@cratis/pi 7.67.0 → 7.68.1
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/hooks/scripts/cratis-check-pr.mjs +23 -3
- package/package/corpus/product-sync.json +1 -1
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/state-and-recovery.md +1 -0
- 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 +3 -1
- 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 +5 -0
- package/package/corpus/skills/cratis-screenplay-slice-design/SKILL.md +3 -5
- package/package/corpus/skills/cratis-screenplay-slice-design/references/read-model-design.md +4 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +5 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet.md +15 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +13 -2
- package/package/corpus/skills/cratis-screenplay-toolchain/references/traps.md +1 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/references/verdicts.md +64 -3
- package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +7 -1
- package/package.json +1 -1
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
import { spawnSync } from 'node:child_process';
|
|
6
6
|
import { createHash } from 'node:crypto';
|
|
7
|
-
import { mkdirSync, readFileSync, readdirSync, statSync, writeFileSync, renameSync } from 'node:fs';
|
|
7
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync, renameSync } from 'node:fs';
|
|
8
8
|
import { homedir } from 'node:os';
|
|
9
|
-
import { isAbsolute, join, resolve } from 'node:path';
|
|
9
|
+
import { dirname, isAbsolute, join, resolve } from 'node:path';
|
|
10
10
|
import { parseArgs } from 'node:util';
|
|
11
11
|
import { Script } from 'node:vm';
|
|
12
12
|
import { fileURLToPath } from 'node:url';
|
|
@@ -16,6 +16,7 @@ const commandTimeout = 15_000;
|
|
|
16
16
|
const reviewedRulesRef = '40125b4fcae388e62ed9471edfffd0e991422f0a';
|
|
17
17
|
const hookMode = process.argv[2] === '--hook';
|
|
18
18
|
let claudeHook = false;
|
|
19
|
+
let invocation = {};
|
|
19
20
|
const hookWarnings = [];
|
|
20
21
|
const warningLine = line => /^(::warning\b|::notice title=Release notes (?:drift )?not checked|Warning:)/.test(line);
|
|
21
22
|
const warning = message => {
|
|
@@ -25,6 +26,23 @@ const warning = message => {
|
|
|
25
26
|
const run = (command, args, options = {}) => spawnSync(command, args, {
|
|
26
27
|
encoding: 'utf8', timeout: commandTimeout, maxBuffer: 32 * 1024 * 1024, ...options,
|
|
27
28
|
});
|
|
29
|
+
// A bare ENOENT cannot be told apart from a path resolved against the wrong directory, a copy of this
|
|
30
|
+
// checker from another checkout, or a file that is not there yet. Naming all of those lets the next
|
|
31
|
+
// occurrence be diagnosed instead of retried.
|
|
32
|
+
function readBodyFile(value) {
|
|
33
|
+
const resolved = resolve(value);
|
|
34
|
+
try {
|
|
35
|
+
return readFileSync(resolved, 'utf8');
|
|
36
|
+
} catch (error) {
|
|
37
|
+
const parent = dirname(resolved);
|
|
38
|
+
const details = [`--body-file value: ${value}`, `path tried: ${resolved}`,
|
|
39
|
+
`parent directory exists: ${existsSync(parent)}`, `file exists now: ${existsSync(resolved)}`,
|
|
40
|
+
`checker working directory: ${process.cwd()}`,
|
|
41
|
+
...Object.entries(invocation).map(([name, detail]) => `${name}: ${detail}`),
|
|
42
|
+
`checker script: ${fileURLToPath(import.meta.url)}`];
|
|
43
|
+
throw new Error(`cannot read the pull-request body file (${error.code || error.message}); ${details.join('; ')}`, { cause: error });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
28
46
|
const gh = (args, options = {}) => {
|
|
29
47
|
const result = run('gh', args, options);
|
|
30
48
|
if (result.error || result.status !== 0) throw new Error(`gh ${args[0]} failed: ${result.stderr?.trim() || result.error?.message || result.status}`);
|
|
@@ -156,7 +174,7 @@ function check(argv, repositoryCallers, lookupOptions) {
|
|
|
156
174
|
for (const label of split(values['add-label'])) labels.add(label);
|
|
157
175
|
const intent = intents.filter(label => labels.has(label));
|
|
158
176
|
if (intent.length !== 1) throw new Error(`Exactly one release-intent label is required (major/minor/patch/no-release); found ${intent.join(', ') || 'none'}.`);
|
|
159
|
-
const body = values['body-file'] ?
|
|
177
|
+
const body = values['body-file'] ? readBodyFile(values['body-file']) : pull.body || '';
|
|
160
178
|
let repository = values.repo;
|
|
161
179
|
let defaultBranch = git(['symbolic-ref', '--short', 'refs/remotes/origin/HEAD']).replace(/^origin\//, '') || 'main';
|
|
162
180
|
try {
|
|
@@ -324,6 +342,7 @@ function hook() {
|
|
|
324
342
|
if (typeof text !== 'string' || !/\bgh\s+pr\s+(create|edit)\b/.test(text.replace(/\\\r?\n/g, ''))) return 0;
|
|
325
343
|
// Match each simple command, never the same text inside an echo/grep argument.
|
|
326
344
|
let cwd = payload.cwd || process.cwd();
|
|
345
|
+
invocation = { 'hook payload directory': payload.cwd || '(none)' };
|
|
327
346
|
let knownDirectory = true;
|
|
328
347
|
let parsed;
|
|
329
348
|
try { parsed = commands(text); } catch (error) { if (!optedIn(cwd)) return 0; throw error; }
|
|
@@ -386,6 +405,7 @@ function hook() {
|
|
|
386
405
|
if (targetedRepository) lookupEnvironment.GH_REPO = targetedRepository;
|
|
387
406
|
else delete lookupEnvironment.GH_REPO;
|
|
388
407
|
process.chdir(cwd);
|
|
408
|
+
invocation['command directory'] = cwd;
|
|
389
409
|
const code = check(args, repositoryCallers, { env: lookupEnvironment });
|
|
390
410
|
if (code !== 0 && code !== 3) throw new Error('The pull-request body or release intent failed cratis-check-pr. Fix the reported violations before retrying.');
|
|
391
411
|
}
|
|
@@ -201,7 +201,7 @@
|
|
|
201
201
|
],
|
|
202
202
|
"rules": []
|
|
203
203
|
},
|
|
204
|
-
"notes": "Standalone 4.204.0 and byte-identical compiler contract pinned. 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."
|
|
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",
|
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
|
|
@@ -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
|
|
@@ -261,7 +261,9 @@ What the executable model does with it (ESM v3):
|
|
|
261
261
|
rules is `PLAY0398`; two rules for one event is `PLAY0399`; a reducer with no
|
|
262
262
|
bodies is rejected with a hint to write a projection.
|
|
263
263
|
- The key is **always the event source id** — a reducer cannot route by an event
|
|
264
|
-
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)).
|
|
265
267
|
- The body is an opaque attachment identified by a content hash, never compiled
|
|
266
268
|
or run by Screenplay. The reference runner cannot compute reducer state, so a
|
|
267
269
|
specification that reads a reducer-built read model reports unsupported and
|
|
@@ -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
|
}
|
|
@@ -186,6 +186,10 @@ Specs pass `by` and filters by name (PLAY0468 for unknown, repeated or missing
|
|
|
186
186
|
required arguments); collection results match by read model/key regardless of
|
|
187
187
|
row order. Details and renderer limits: [equality filters](references/equality-filters.md).
|
|
188
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
|
+
|
|
189
193
|
## `screen` — three levels
|
|
190
194
|
|
|
191
195
|
The examples below are excerpts: each screen sits in a slice, and the queries,
|
|
@@ -303,6 +307,7 @@ binding failures are errors.
|
|
|
303
307
|
- [ ] Every authorized query has a specification with `given caller`, including a
|
|
304
308
|
`then denied` case.
|
|
305
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`).
|
|
306
311
|
- [ ] No screen reference is left ambiguous or unresolved.
|
|
307
312
|
- [ ] Every UI binding that consumes screen data (component context, toolbar
|
|
308
313
|
parameter, dialog input, outlet route) has a source in the screen contract
|
|
@@ -38,8 +38,7 @@ Ask the batch below only for what the request leaves open: (1) origin of each ac
|
|
|
38
38
|
## Procedure
|
|
39
39
|
|
|
40
40
|
1. **Fix the mode** for the scope (`cratis-screenplay-modeling-lifecycle`): design, executable
|
|
41
|
-
or renderable. It decides which shapes you may use (steps 6, 9). Read the existing model
|
|
42
|
-
before adding to it.
|
|
41
|
+
or renderable. It decides which shapes you may use (steps 6, 9). Read the existing model first.
|
|
43
42
|
2. **Find each event's origin.** For every event ask who or what makes it happen and through
|
|
44
43
|
which path: a persona's screen `action` or form, a reaction's `invokes`, a capture. The
|
|
45
44
|
origin must be **reachable** (some screen, form, reaction or integration leads to the
|
|
@@ -54,8 +53,7 @@ Ask the batch below only for what the request leaves open: (1) origin of each ac
|
|
|
54
53
|
separate reasons change these values, then split (`references/slicing.md` *Generic edits*).
|
|
55
54
|
One input per thing the caller decides or supplies; `identifier` on the property naming the
|
|
56
55
|
instance (omit only for allocation); inline `produces event <Name>` (no `for`) when the command owns the event; plain `produces <Name>` needs `for <identifier>`. Trace each input
|
|
57
|
-
(`references/field-lineage.md`) and list the values each rule reads: input, state or context
|
|
58
|
-
(`references/command-inventory.md`). A conditional input is a granularity question: two
|
|
56
|
+
(`references/field-lineage.md`) and list the values each rule reads: input, state or context. A conditional input is a granularity question: two
|
|
59
57
|
decisions are two commands; one decision with a dependent rule is an implication
|
|
60
58
|
(`require a == false or b > c`). Never a boolean attestation input (`confirmsX == true`)
|
|
61
59
|
standing in for a rule. Place each rule in its layer (`references/rule-layers.md`). A rule
|
|
@@ -89,7 +87,7 @@ Ask the batch below only for what the request leaves open: (1) origin of each ac
|
|
|
89
87
|
6. **Design the read side** (`references/read-model-design.md`). Enumerate every screen and
|
|
90
88
|
automation first: one read model per screen component or automation need; the typical
|
|
91
89
|
slice is `read model -> screen -> command -> event`. Pick the builder (declarative projection first, reducer when
|
|
92
|
-
guards cannot be expressed). The query follows the business view: a list where people scan a
|
|
90
|
+
guards cannot be expressed; a lookup `by` another identity type warns `PLAY0690`). The query follows the business view: a list where people scan a
|
|
93
91
|
list, a keyed lookup where they open one thing. For **executable or renderable scope**, every
|
|
94
92
|
read model needs one unambiguous identity: explicit trailing `key` first. Read `references/read-model-design.md` ("Executable identity of a read model") for the fallback order, the key decision table and the Stage rule.
|
|
95
93
|
|
package/package/corpus/skills/cratis-screenplay-slice-design/references/read-model-design.md
CHANGED
|
@@ -130,7 +130,10 @@ Observable delivery does not make a materialized projection decision-consistent;
|
|
|
130
130
|
decision needs a guarded read (`rule-layers.md`, `cratis-screenplay-streams-and-consistency`). Prefer a
|
|
131
131
|
declarative projection (mappings, event joins, counters, bounded children, removals); a join
|
|
132
132
|
consumes event facts, not another read model. Use a reducer when prior-state, attempt or
|
|
133
|
-
ordering guards cannot be expressed declaratively
|
|
133
|
+
ordering guards cannot be expressed declaratively, and the view is only ever looked up by the
|
|
134
|
+
event-source identity: a reducer cannot be re-keyed, so a query `by` another identity type warns
|
|
135
|
+
`PLAY0690`; aggregate by a payload value with a projection keyed on each `from`, or a join
|
|
136
|
+
(projections [reducer identity](../../cratis-screenplay-projections/references/reducer-identity.md)). Review every writer of a property: AutoMap
|
|
134
137
|
can introduce updates from other events. Use variants only when lifecycle stages have different
|
|
135
138
|
shapes. Keep growing histories in a separate view; never combine several people's PII under
|
|
136
139
|
one read-model instance (compose queries across person-scoped views instead).
|
|
@@ -39,6 +39,10 @@ superseded statement needs context; exceptions do not change the contract.
|
|
|
39
39
|
2. **Check the folder, warnings as errors.** `screenplay <folder> --warnaserror` or
|
|
40
40
|
`cratis screenplay validate <folder> --warnings-as-errors`. Warnings hide defects:
|
|
41
41
|
PLAY0029 (a misspelt keyword or a `type` inside a slice) drops a construct silently.
|
|
42
|
+
A committed `screenplay.json` at the model root declares the repository's gate (checks, warnings
|
|
43
|
+
as errors, scope, open questions): run without repeating those flags (confirm with
|
|
44
|
+
`--print-gate` before dropping `--warnaserror`), read it with
|
|
45
|
+
`--print-gate`, and treat a refused file as "could not run" (`references/verdicts.md`).
|
|
42
46
|
3. **Pick the compiler deliberately and name it.** Standalone `screenplay` for
|
|
43
47
|
language checks and reference specifications; `cratis` for rendering
|
|
44
48
|
and generation. Report both tool and version, rather than transferring a verdict across
|
|
@@ -63,6 +67,7 @@ superseded statement needs context; exceptions do not change the contract.
|
|
|
63
67
|
| --- | --- | --- |
|
|
64
68
|
| Check root | `screenplay <root> --warnaserror --no-color` | `cratis screenplay validate <root> --warnings-as-errors -o json-compact` |
|
|
65
69
|
| Scope/checks | `--scope <address>`, `--check <names>`; a scoped pass is not whole-application success | `validate --executable` (bundled binder, no write), `--check <names>`, `--scope`; `render --scope`/`--check`; `cratis screenplay conform` |
|
|
70
|
+
| Declared gate | `screenplay <root> --print-gate`, `--format json`, `--no-gate-file` | `validate <root> --print-gate`, `--no-gate-file`; the same `screenplay.json` |
|
|
66
71
|
| Reference execution | `screenplay test <root>` or MCP `run-specifications` | Discover bundled MCP capability; target tests are not V4 |
|
|
67
72
|
| MCP | `screenplay mcp <root>`; discover schemas | `cratis screenplay mcp [root]`; registered by `cratis ai install` |
|
|
68
73
|
| Render boundary | Binder admission is not Stage admission | The CLI renders only ESM versions it knows; a newer bound model gets `CLI-RENDER-004` |
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Contents
|
|
4
4
|
|
|
5
|
+
- Validation commands and the gate file
|
|
5
6
|
- Samples and preview fixtures
|
|
6
7
|
- Lexical and structural rules
|
|
7
8
|
- Exact numeric source mode
|
|
@@ -57,6 +58,20 @@ by `for_Documentation/when_comparing_the_grammar_against_the_parsers.cs`),
|
|
|
57
58
|
Screenplay CI (`when_compiling_every_example.cs`) against repository main: the standalone
|
|
58
59
|
compiler; the compiler bundled in `cratis` can be older and lack the newest ESM versions.
|
|
59
60
|
|
|
61
|
+
## Validation commands and the gate file
|
|
62
|
+
|
|
63
|
+
```shell
|
|
64
|
+
screenplay <root> --warnaserror --no-color # V1; also reads <root>/screenplay.json
|
|
65
|
+
screenplay <root> --print-gate # effective gate and each value's source, no compile
|
|
66
|
+
screenplay <root> --format json # one JSON report: diagnostics, gate, exitCode
|
|
67
|
+
screenplay <root> --no-gate-file --check all # bypass the file for one run
|
|
68
|
+
screenplay test <root> # V4
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`screenplay.json` (authored, beside `.screenplay/`) holds `validation.checks`, `warningsAsErrors`, `scope`
|
|
72
|
+
and `openQuestions`; unknown keys or check names are refused (exit 2), never ignored. Details and
|
|
73
|
+
precedence: [verdicts](verdicts.md).
|
|
74
|
+
|
|
60
75
|
## Samples and preview fixtures
|
|
61
76
|
|
|
62
77
|
Invoicing is a warning-free syntax showcase, not a runnable whole-language proof.
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
- Explicit enum member numbers
|
|
9
9
|
- Reserved stored names and event pins
|
|
10
10
|
- Named keys, production routes and observer filters
|
|
11
|
+
- Reducer instance identity (PLAY0690)
|
|
11
12
|
- Caller identity, compliance and routes
|
|
12
13
|
- Specification metadata, callers, cases and locators
|
|
13
14
|
- Guarded interaction diagnostics
|
|
@@ -146,6 +147,16 @@ Overrides/filters select released ESM v10; malformed routes also use PLAY0504.
|
|
|
146
147
|
Read read-surface `references/named-keys.md` and
|
|
147
148
|
[production routes and filters](production-routes-and-filters.md).
|
|
148
149
|
|
|
150
|
+
## Reducer instance identity (PLAY0690)
|
|
151
|
+
|
|
152
|
+
| Code | Severity | Meaning / fix |
|
|
153
|
+
| --- | --- | --- |
|
|
154
|
+
| PLAY0690 | W | A reducer instance is keyed by the event-source id, so a reducer-backed scalar query `by` another nominal type, or a reducer whose complete producers use several identity types, warns. Reducers cannot be re-keyed: use a projection with a property key on each `from`, or a join for existing instances |
|
|
155
|
+
|
|
156
|
+
Fails `--warnaserror`. Compares declared nominal types only where producers are known (command `for`, implicit or generated identifiers, reaction `for`); plain `produces` without `for`, reactions without `for`, captures, seeds and code are not compared. Native C# only: a clean editor proves nothing. Example and limits: projections [reducer identity](../../cratis-screenplay-projections/references/reducer-identity.md).
|
|
157
|
+
|
|
158
|
+
Requires Screenplay 4.170.0 or later (`screenplay --version`); an older compiler does not report it, and `cratis screenplay validate` reports it only when its bundled compiler is that new.
|
|
159
|
+
|
|
149
160
|
## Caller identity, compliance and routes
|
|
150
161
|
|
|
151
162
|
| Code | Severity | Meaning / fix |
|
|
@@ -309,8 +320,8 @@ identity details (0633–0646), compliance/subject checks, reaction identity
|
|
|
309
320
|
A shared catalog code is not proof that a check is implemented in both compilers.
|
|
310
321
|
|
|
311
322
|
C# CLI/MCP owns whole-application scoped diagnostics, opt-in completeness
|
|
312
|
-
(including PLAY0530–0537, PLAY0602–0606 and PLAY0652),
|
|
313
|
-
checks PLAY0650/0651, semantic binding and PLAY0546 (a negated claim targets optional,
|
|
323
|
+
(including PLAY0530–0537, PLAY0602–0606 and PLAY0652), reducer identity
|
|
324
|
+
PLAY0690, bound reaction gate checks PLAY0650/0651, semantic binding and PLAY0546 (a negated claim targets optional,
|
|
314
325
|
unavailable-subject or non-text data). The VS Code repair bridge is not a general
|
|
315
326
|
C# validator. A clean editor is not V1 for the complete application, V3 binding
|
|
316
327
|
or V4 execution. Run the CLI or MCP for those verdicts.
|
|
@@ -69,3 +69,4 @@ Traps 39 to 44 are tool traps.
|
|
|
69
69
|
42. A symlinked model path is refused by the MCP server (macOS `/tmp` is a symlink); pass the physical path. Proposals are connection-local (at most 16); `apply` persists identities to `.screenplay/identities.json` and is not crash-atomic across files; never retry `apply` after `ApplyOutcomeUnknown`.
|
|
70
70
|
43. `modelRevision` is canonical semantic (line positions and descriptions do not change it; a file move only if it changes logical placement or application identity) and, without `identities.json`, changes with the root folder name; it is not comparable with a render's `semanticRevision`. Source identity for verdicts is the commit plus the digest from the source-identity helper (`cratis-screenplay-modeling-lifecycle` `references/verdicts-and-modes.md` "Source identity").
|
|
71
71
|
44. `cratis render` neither builds nor tests; `--name` is required for plain source; `.cratis-render/` is control state and is never staged; rendered apps pin their own Arc and Chronicle versions (`[ProtectedDecision]` is available to gap-fill, not automatically emitted). `cratis` file mode versus folder mode (trap 6) and a stale `cratis` on `PATH` (`which -a cratis`) both silently change what a verdict means.
|
|
72
|
+
45. A reducer cannot be re-keyed: its instances follow the event-source id, so a query `by` another identity type warns PLAY0690 (`--warnaserror` fails it; editors only show it when the host supplies native findings). Aggregate by a payload value with a projection keyed on each `from`, or a join: projections [reducer identity](../../cratis-screenplay-projections/references/reducer-identity.md).
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
## Contents
|
|
4
4
|
|
|
5
5
|
- V1: authorable
|
|
6
|
+
- Declared validation gate (`screenplay.json`)
|
|
6
7
|
- Release-baseline gate (independent of V1–V5)
|
|
7
8
|
- V2: executable diagnostics
|
|
8
9
|
- V3: binding-ready
|
|
@@ -51,8 +52,67 @@ render, V1 and V5 from the CLIs. Read installed versions with `screenplay --vers
|
|
|
51
52
|
- Warnings are failures here. PLAY0029 (a construct dropped silently) and the unresolved-name
|
|
52
53
|
warnings are the defects this verdict exists to catch.
|
|
53
54
|
- Syntax and consistency checks (PLAY0282 to PLAY0294) run; binding does not.
|
|
55
|
+
- A `screenplay.json` at the model root supplies checks, warnings-as-errors, scope and open-questions
|
|
56
|
+
mode to both commands above, so they need not repeat those flags; drop `--warnaserror` only when
|
|
57
|
+
`--print-gate` shows `warningsAsErrors: true`. Read the effective gate before
|
|
58
|
+
reporting (next section).
|
|
54
59
|
- Report: `V1 pass (screenplay <version>, 3 files)`, `V1 fail: PLAY0029 in a.play, line 12`.
|
|
55
60
|
|
|
61
|
+
## Declared validation gate (`screenplay.json`)
|
|
62
|
+
|
|
63
|
+
A repository declares its V1 gate once, in an authored `screenplay.json` at the model root,
|
|
64
|
+
beside the tool-owned `.screenplay/`. Prefer it to repeating `--check`, `--warnaserror`,
|
|
65
|
+
`--scope` and `--open-questions` in every script: every run then enforces the same gate.
|
|
66
|
+
`screenplay.json` is the only file there people write; no tool creates or edits it.
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"$schema": "https://raw.githubusercontent.com/Cratis/Screenplay/main/Documentation/screenplay/screenplay-v1.schema.json",
|
|
71
|
+
"validation": {
|
|
72
|
+
"checks": ["field-origins", "query-keys", "navigation"],
|
|
73
|
+
"warningsAsErrors": true,
|
|
74
|
+
"scope": "Workspaces.Tracking",
|
|
75
|
+
"openQuestions": "fail"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
- Every member is optional. A `checks` item is one check name, diagnostic code or `all`
|
|
81
|
+
(never a comma list); `all` expands to every check the running tool supports, so an upgrade can
|
|
82
|
+
strengthen the gate, while an explicit list pins it. `openQuestions` is `report` or `fail`;
|
|
83
|
+
omitted means notes are not evaluated.
|
|
84
|
+
- The model root is the nearest folder at or above the target (a file's parent) that holds
|
|
85
|
+
`screenplay.json` or `.screenplay/`. The search includes but never crosses the first folder with
|
|
86
|
+
`.git`; with no match the target folder is the root and the defaults apply. Nested models keep
|
|
87
|
+
their own gates; imports never affect the search.
|
|
88
|
+
- A command-line option replaces only its own setting. Omitting `--warnaserror` keeps
|
|
89
|
+
`warningsAsErrors: true`, and any `--check` replaces the file's whole list. `--no-gate-file`
|
|
90
|
+
ignores the file, even an invalid one; a relaxed run is not the repository's gate, so say so.
|
|
91
|
+
|
|
92
|
+
| Need | Standalone | `cratis screenplay validate` |
|
|
93
|
+
| --- | --- | --- |
|
|
94
|
+
| Effective gate and the source of each value, no compile (exit 0 unless the file is refused) | `screenplay <root> --print-gate` (text) | `--print-gate` (text, or the gate object under `-o json`) |
|
|
95
|
+
| Machine-readable verdict | `--format json`: one document with `diagnostics`, `openQuestions`, `refusal`, `exitCode`, `gate` | `-o json-compact`: the summary carries `gate` |
|
|
96
|
+
| Ignore the file | `--no-gate-file` | `--no-gate-file` |
|
|
97
|
+
|
|
98
|
+
Each gate value reports `commandLine`, `file` or `default` as its source. Report the gate with
|
|
99
|
+
the verdict: `V1 pass (screenplay <version>, gate screenplay.json: field-origins, query-keys,
|
|
100
|
+
warnings as errors, 3 files)`.
|
|
101
|
+
|
|
102
|
+
**A refused gate file is "could not run", never a pass or a fail.** Malformed JSON, a duplicate
|
|
103
|
+
member, an unknown key, an unknown check name or a wrong type is refused as invalid, and a
|
|
104
|
+
directory, symlink or unreadable file is refused as unreadable; neither is ignored or repaired. The
|
|
105
|
+
standalone tool exits **2** and the CLI exits **1**, each with `path:line:column`. Report
|
|
106
|
+
`V1 not run: gate file refused (<path:line:column>)`, fix the file and rerun.
|
|
107
|
+
A scope declared in the file combined with `cratis screenplay validate --executable` also exits 1:
|
|
108
|
+
check binding separately or pass `--no-gate-file` and name it.
|
|
109
|
+
|
|
110
|
+
Requires Screenplay 4.165.0 or later (`screenplay --version`) for `screenplay.json`, `--format`,
|
|
111
|
+
`--print-gate` and `--no-gate-file`; an older tool does not read the file and runs without the
|
|
112
|
+
gate, so a clean result there says nothing about it. `cratis screenplay validate` reads the file
|
|
113
|
+
from Cratis CLI 3.65.0 or later (`cratis --version`); an older CLI ignores it, so use the standalone
|
|
114
|
+
tool for the gate.
|
|
115
|
+
|
|
56
116
|
## Release-baseline gate (independent of V1–V5)
|
|
57
117
|
|
|
58
118
|
Run `screenplay baseline check <model-root>` before accepting edits to released event
|
|
@@ -180,9 +240,10 @@ What Stage admits: `renderable-subset.md`.
|
|
|
180
240
|
|
|
181
241
|
| Layer | Route | Result |
|
|
182
242
|
| --- | --- | --- |
|
|
183
|
-
| Source validation | `screenplay <root> --warnaserror --no-color` | 0 clean; 1 reported defects; 2 could not run or invalid arguments or input. `--scope` limits the reported set, not compilation |
|
|
243
|
+
| Source validation | `screenplay <root> --warnaserror --no-color` | 0 clean; 1 reported defects; 2 could not run or invalid arguments or input, including a refused `screenplay.json`. `--scope` limits the reported set, not compilation |
|
|
244
|
+
| Declared gate | `screenplay <root> --print-gate`; `--format json`; `--no-gate-file` | Reads `screenplay.json`; `--print-gate` exits 0 without compiling unless the file is refused; a gate-promoted warning or an open question in `fail` mode exits 1 |
|
|
184
245
|
| Completeness | add `--check <name>[,<name>]` (repeatable) or `--check all` | Opt-in warnings; whole-source errors skip checks, not pass them |
|
|
185
|
-
| CLI source validation | `cratis screenplay validate <root> --warnings-as-errors -o json-compact` | Read the producer exit and the JSON errors, warnings and file count |
|
|
246
|
+
| CLI source validation | `cratis screenplay validate <root> --warnings-as-errors -o json-compact` | Read the producer exit and the JSON errors, warnings and file count; 5 validation error (including gate-promoted warnings), 1 invalid input (including a refused `screenplay.json`) |
|
|
186
247
|
| Binding | MCP workspace readiness and `executable-diagnostics` | V2 reads diagnostics; V3 requires binding with no blocking diagnostics |
|
|
187
248
|
| Reference specifications | `screenplay test <root> [--filter <address>] [--format text\|json]`, or MCP `run-specifications` (`specification`, `scope`, `offset`, `limit`, `expectedSourceRevision`, `proposalId`) | 0 all selected passed; 1 failed; 2 invalid arguments, input, selection or IO; 3 unsupported or unbound. Counts of zero do not prove coverage |
|
|
188
249
|
| Release baseline | `screenplay baseline admit <root> --release <label>`; `screenplay baseline check <root>` | 0 success; 1 changed or missing revision; 2 unavailable, unreadable or invalid input or write failure |
|
|
@@ -221,7 +282,7 @@ change ESM or V1–V5 verdicts. Read model-authoring
|
|
|
221
282
|
[model notes](../../cratis-screenplay-model-authoring/references/model-notes.md) when
|
|
222
283
|
recording, resolving, paging or reviewing orphan impact.
|
|
223
284
|
|
|
224
|
-
Requires Screenplay 4.144.0 or later (`screenplay --version`) for `--open-questions
|
|
285
|
+
Requires Screenplay 4.144.0 or later (`screenplay --version`) for `--open-questions`. `cratis screenplay validate` accepts the same option from Cratis CLI 3.60.0 or later (exit 5 when a question remains in `fail` mode, 1 when notes are unreadable); with an older CLI use the standalone tool. `validation.openQuestions` in `screenplay.json` selects the mode without the flag.
|
|
225
286
|
|
|
226
287
|
## Revisions and descriptions
|
|
227
288
|
|
|
@@ -16,7 +16,13 @@
|
|
|
16
16
|
{ "kind": "skill-contains", "value": "the **whole source, stream and stream id**", "file": "references/production-routes-and-filters.md" },
|
|
17
17
|
{ "kind": "play-compiles" },
|
|
18
18
|
{ "kind": "skill-contains", "value": "Requires Screenplay 4.144.0", "file": "references/verdicts.md" },
|
|
19
|
-
{ "kind": "skill-contains", "value": "
|
|
19
|
+
{ "kind": "skill-contains", "value": "accepts the same option from Cratis CLI 3.60.0", "file": "references/verdicts.md" },
|
|
20
|
+
{ "kind": "skill-contains", "value": "A refused gate file is \"could not run\"", "file": "references/verdicts.md" },
|
|
21
|
+
{ "kind": "skill-contains", "value": "Requires Screenplay 4.165.0 or later", "file": "references/verdicts.md" },
|
|
22
|
+
{ "kind": "skill-contains", "value": "Cratis CLI 3.65.0 or later", "file": "references/verdicts.md" },
|
|
23
|
+
{ "kind": "skill-contains", "value": "--print-gate", "file": "references/cheat-sheet.md" },
|
|
24
|
+
{ "kind": "skill-contains", "value": "PLAY0690", "file": "references/diagnostics.md" },
|
|
25
|
+
{ "kind": "skill-contains", "value": "Requires Screenplay 4.170.0 or later", "file": "references/diagnostics.md" },
|
|
20
26
|
{ "kind": "skill-contains", "value": "--open-questions fail", "file": "references/verdicts.md" },
|
|
21
27
|
{ "kind": "skill-contains", "value": "unreadable notes exit **2**", "file": "references/verdicts.md" },
|
|
22
28
|
{ "kind": "skill-contains", "value": "MCP/CLI only, **no PLAY code**", "file": "references/verdicts.md" },
|