@cratis/pi 7.95.0 → 7.96.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.
@@ -247,6 +247,10 @@ store gets replayed. A failed partition you have not yet explained is not a
247
247
  thing to clear: read it, fix the handler, then replay. Clearing it first
248
248
  destroys the evidence and the same failure returns on the next event.
249
249
 
250
+ ## Compare a namespace with its model
251
+
252
+ `cratis screenplay conform-namespace` is read-only and sits outside the `chronicle` group and its guard: it reads the registry, observers and event metadata of one namespace and compares them with a `.play` model. Use it for a post-deploy check; the procedure and exit codes are in `cratis-screenplay-render-and-gap-fill` [post-deploy check](../cratis-screenplay-render-and-gap-fill/references/post-deploy-check.md). Its exit `4` is a refused read: obtain a context with read access, never widen permissions.
253
+
250
254
  ## What the CLI cannot do
251
255
 
252
256
  There is no `delete`, `purge`, `redact`, or `revise` command. Event redaction
@@ -205,6 +205,7 @@ Read [references/neighbouring-skills.md](references/neighbouring-skills.md) when
205
205
  - `references/renderability-gate.md` - classify the probe's codes, estimate the blast radius.
206
206
  - `references/delivery-protocol.md` - inputs, commands, reading results, `Customizations/`.
207
207
  - `references/gap-fill-handoff.md` - the brief for `slice-implementer`, fallback record flow.
208
+ - `references/post-deploy-check.md` - after deployment, compare the model with a running namespace using `cratis screenplay conform-namespace`; read-only, with its exit codes.
208
209
  - `references/drift-and-fallback-record.md` - drift, publication refusals, the fallback record, code changed since verification.
209
210
  - Read `references/hand-written-changes.md` when investigating hand-written changes against the contract; it defines finding kinds, resolution routing and the report.
210
211
  - Read `references/worked-example.md` when preparing the classification and report for a refused render; it contains a complete model.
@@ -0,0 +1,57 @@
1
+ <!-- Copyright (c) Cratis. All rights reserved. -->
2
+ <!-- Licensed under the MIT license. See LICENSE file in the project root for full license information. -->
3
+
4
+ # Post-deploy check: does the running namespace match the model
5
+
6
+ After a render is delivered and deployed, `cratis screenplay conform-namespace` compares the
7
+ compiled model with what one running Chronicle namespace holds. Render verification and
8
+ `conform` never see the running store; this check does. How to read its verdict is in the
9
+ toolchain's [observation comparison](../../cratis-screenplay-toolchain/references/observation-comparison.md),
10
+ including the CLI version it needs.
11
+
12
+ ## Run it
13
+
14
+ ```bash
15
+ cratis screenplay conform-namespace <model-root> --event-store <store> --namespace <namespace> -o json-compact
16
+ ```
17
+
18
+ - Pass the model root (the root `.play` file or the folder of one application), never a single
19
+ fragment of a folder.
20
+ - Name the event store and namespace explicitly. The built-in default is never assumed, and a
21
+ name differing only in case is reported, not chosen for you.
22
+ - `--sequence` selects another sequence (default `event-log`); `--from`, `--to` and `--max-events`
23
+ bound the scan (default `100000` events, up to the tail captured at the start).
24
+ - Add `--fail-on-drift` in a pipeline so the exit code carries the verdict.
25
+
26
+ ## Authorization and effect
27
+
28
+ The command is read-only: it never replays observers, appends events or changes the model, and
29
+ it is not a `chronicle` command, so the Chronicle mutation guard does not apply. It still needs a
30
+ connection to the target server with permission to read the event type registry, observers and
31
+ event metadata. Use the context the user named; resolve it as in `cratis-chronicle-cli-operations`.
32
+ Do not log in, switch contexts or point at another environment to make it work. A production
33
+ namespace is checked only when the request named it.
34
+
35
+ ## Act on the result
36
+
37
+ | Exit | Meaning | Act |
38
+ | --- | --- | --- |
39
+ | `0` | The comparison ran | Read `hasDrift` and the findings; drift alone does not fail without `--fail-on-drift` |
40
+ | `7` | Known drift (with `--fail-on-drift`) | Triage each Drift finding: fix the model through the model workflow, or fix the deployment; never edit a rendered file to silence it |
41
+ | `8` | Inconclusive (with `--fail-on-drift`), or the scan was interrupted | Report inconclusive; widen coverage or wait for lagging reactors, then rerun once |
42
+ | `5` | Model errors, missing store, namespace or sequence, invalid bounds | Fix the input; nothing was compared |
43
+ | `2` | Server unreachable | Report the connection failure; do not retry through another route |
44
+ | `3` | Chronicle refused or failed a read | Report it; no snapshot was built |
45
+ | `4` | Authorization missing for a read | Ask the user for a context with read access; do not widen permissions yourself |
46
+
47
+ Exit `4` for a refused read and exit `8` for an interrupted scan require Cratis CLI 3.89.1 or later
48
+ (`cratis --version`). On an older CLI, treat any exit other than `0` and `7` as "not compared".
49
+
50
+ A failed read is never an empty store.
51
+
52
+ ## Report
53
+
54
+ Record the verdict next to the deployment: model identity, event store, namespace, sequence,
55
+ examined range against the captured tail, `Complete`, Drift findings and Unknown reasons. A
56
+ partial or inconclusive result is reported as such, never as a pass. Remediation that changes
57
+ the model or code returns to the render and gap-fill procedure.
@@ -65,7 +65,7 @@ superseded statement needs context; exceptions do not change the contract.
65
65
  | | Standalone `screenplay` | `cratis screenplay ...` |
66
66
  | --- | --- | --- |
67
67
  | Check root | `screenplay <root> --warnaserror --no-color` | `cratis screenplay validate <root> --warnings-as-errors -o json-compact` |
68
- | 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` |
68
+ | 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`, `cratis screenplay conform-namespace` |
69
69
  | Declared gate | `screenplay <root> --print-gate`, `--format json`, `--no-gate-file` | `validate <root> --print-gate`, `--no-gate-file`; the same `screenplay.json` |
70
70
  | Reference execution | `screenplay test <root>` or MCP `run-specifications` | Discover bundled MCP capability; target tests are not V4 |
71
71
  | MCP | `screenplay mcp <root>`; discover schemas | `cratis screenplay mcp [root]`; registered by `cratis ai install` |
@@ -96,6 +96,8 @@ for MCP initialization, source identity and reporting. Without MCP, report
96
96
  version, source identity and any blocking codes; MCP `modelRevision` is semantic,
97
97
  not the source identity.
98
98
 
99
+ Read [observation comparison](references/observation-comparison.md) when asking whether a running namespace holds what the model declares, or when reading a `conform-namespace` verdict. It differs from model comparison (model versus model) and `conform` (model versus code).
100
+
99
101
  ## Subsets (write from the one your mode needs)
100
102
 
101
103
  - **Design**: every construct family parses; use it to model first. Compiled shapes:
@@ -0,0 +1,83 @@
1
+ <!-- Copyright (c) Cratis. All rights reserved. -->
2
+ <!-- Licensed under the MIT license. See LICENSE file in the project root for full license information. -->
3
+
4
+ # Observation comparison: model versus running store
5
+
6
+ Requires Cratis CLI 3.85.0 or later (`cratis --version`) for `cratis screenplay conform-namespace`, and
7
+ 3.89.1 or later for the refused-read exit `4` and clean Ctrl+C handling described below; older CLIs lack
8
+ the verb. Without it, report "observation comparison not run" and do not substitute `conform`.
9
+
10
+ ## Three comparisons, three questions
11
+
12
+ | Comparison | Compares | Answers | Does not answer |
13
+ | --- | --- | --- | --- |
14
+ | Model comparison (`semantic-diff`) | two authored models | what changed between revisions | whether anything runs |
15
+ | `cratis screenplay conform` | a model with source code | whether hand-written code realizes the slice | whether the deployed system did it |
16
+ | Observation comparison (`cratis screenplay conform-namespace`) | a compiled model with a bounded snapshot of one running Chronicle namespace | do the observed event relationships agree with the model | payload agreement, behavior, specifications passing |
17
+
18
+ Reach for observation comparison after a deploy, or when a namespace may have diverged from the
19
+ model: are the declared event types registered, were undeclared events appended, did each command
20
+ and reactor append what the model says it produces, and are the declared reactions subscribed.
21
+ It reads event metadata only, never payloads, event source ids or command values.
22
+
23
+ ## Read the verdict
24
+
25
+ The host reports three verdict values and a separate completeness flag.
26
+
27
+ | `HasDrift` | Meaning | Action |
28
+ | --- | --- | --- |
29
+ | true | Known drift exists, even if other evidence is incomplete | Triage each Drift finding |
30
+ | false | The comparison was complete and found no drift | Report no drift, with the scope |
31
+ | null (omitted in JSON, `inconclusive` in human output) | Drift is neither established nor ruled out | Report inconclusive; never turn it into "no drift" |
32
+
33
+ `Complete` is true only when the scan covered the sequence fully **and** no finding is Unknown.
34
+ A report can have `HasDrift` true and `Complete` false.
35
+
36
+ ## Finding outcomes
37
+
38
+ | Outcome | Reading |
39
+ | --- | --- |
40
+ | Drift | The store disagrees with the model on something the evidence establishes |
41
+ | Informational | A difference that is not a contradiction, such as a declared event that has not yet been appended |
42
+ | Unknown | The evidence cannot establish agreement or disagreement; the reason says why |
43
+ | Excluded | Outside this application, such as a foreign event or a platform consumer |
44
+
45
+ Typical Drift: a declared event type missing from the registry, an undeclared event appended,
46
+ an undeclared generation, a mapped producer appending outside its declared productions, or a
47
+ declared reaction with no subscription.
48
+
49
+ ## Unknown reasons
50
+
51
+ | Reason | What to do |
52
+ | --- | --- |
53
+ | `PartialCoverage` | Widen the range (`--from`, `--to`, `--max-events`) and rerun |
54
+ | `UnattributedEvents` | Events without a command or reactor in their causation; the producer cannot be judged |
55
+ | `UnmappedProducer`, `UnmappedConstruct`, `AmbiguousIdentity` | The model name did not map to exactly one observed identity; do not guess one |
56
+ | `OpaqueReaction`, `ConditionalProduction`, `DescribedHandler`, `NonEventTrigger` | The model does not state the production unconditionally, so absence proves nothing |
57
+ | `ConsumerBehind` | The reactor has not reached the tail; wait for it and rerun |
58
+ | `ConsumerKindNotCompared` | Projections and reducers are not compared; their subscriptions are never evidence either way |
59
+
60
+ ## Pitfalls
61
+
62
+ - "No matching appends within coverage" does not mean the command or reactor never ran. It is
63
+ Informational: no attributed event shows that it ran inside the examined range.
64
+ - Scanned absence under partial coverage is Unknown, never drift. Registry checks are the
65
+ exception: the event-type registry is read in full, so a declared event that is not registered
66
+ (`EventNotRegistered`) is drift whatever the coverage. A missing production is drift only
67
+ with full coverage, an unambiguous producer mapping, another event attributed to that producer,
68
+ and no unattributed appends of the expected type.
69
+ - Presence is stronger than absence: an undeclared event that was appended is drift even under
70
+ partial coverage.
71
+ - A clean result proves only the relationships it checked. Read the report's not-established
72
+ statements; they list the limits.
73
+ - Event generations are approximated: each appended event counts against the highest registered
74
+ generation of its type.
75
+ - One sequence is compared per run, `event-log` by default.
76
+
77
+ ## Report it
78
+
79
+ State the verdict value, `Complete`, the event store, namespace and sequence, the examined range
80
+ against the captured tail, each Drift finding with its statement, and each Unknown reason. The
81
+ post-deploy procedure and its exit codes are in
82
+ [post-deploy check](../../cratis-screenplay-render-and-gap-fill/references/post-deploy-check.md).
83
+ Run the comparison through the CLI; no MCP tool offers it.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cratis/pi",
3
- "version": "7.95.0",
3
+ "version": "7.96.0",
4
4
  "description": "Configuration-aware Cratis AI integration for Pi",
5
5
  "type": "module",
6
6
  "files": [