@cratis/pi 7.74.0 → 7.76.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package/corpus/harnesses/copilot/instructions/vertical-slices.instructions.md +6 -4
- package/package/corpus/harnesses/pi/extensions/cratis-hooks/index.ts +5 -2
- package/package/corpus/hooks/README.md +27 -3
- package/package/corpus/hooks/scripts/cratis-quality-gate.sh +67 -4
- package/package/corpus/hooks/scripts/quality-gates.json +7 -1
- package/package/corpus/product-sync.json +14 -14
- package/package/corpus/rules/general.md +1 -0
- package/package/corpus/rules/vertical-slices.md +6 -4
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authorization.md +9 -0
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/observable-emission-guards.md +12 -3
- package/package/corpus/skills/cratis-arc-command/references/decisions-and-routing.md +11 -0
- package/package/corpus/skills/cratis-arc-command-execution/SKILL.md +3 -0
- package/package/corpus/skills/cratis-arc-command-execution/references/occurrence-commands.md +78 -0
- package/package/corpus/skills/cratis-arc-command-validation/SKILL.md +10 -36
- package/package/corpus/skills/cratis-arc-command-validation/references/input-binding.md +49 -0
- package/package/corpus/skills/cratis-arc-command-validation/references/read-model-resolution.md +25 -0
- package/package/corpus/skills/cratis-arc-command-validation/references/validation-severity.md +21 -0
- package/package/corpus/skills/cratis-arc-ef-core-migration/SKILL.md +7 -1
- package/package/corpus/skills/cratis-arc-hosting/SKILL.md +3 -0
- package/package/corpus/skills/cratis-arc-hosting/references/connection-resolution.md +61 -0
- package/package/corpus/skills/cratis-arc-query-paging/SKILL.md +4 -2
- package/package/corpus/skills/cratis-arc-react-page/references/queries-and-commands.md +14 -1
- package/package/corpus/skills/cratis-chronicle-client-dotnet/SKILL.md +5 -0
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/immediate-append-refusal.md +40 -0
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/lifecycle.md +4 -0
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/occurrences.md +89 -0
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/pinned-generation-delivery.md +33 -3
- package/package/corpus/skills/cratis-chronicle-decision-reads/SKILL.md +5 -2
- package/package/corpus/skills/cratis-chronicle-decision-reads/references/admission-and-ownership.md +18 -1
- package/package/corpus/skills/cratis-chronicle-event-type-migration/references/pinned-generations.md +6 -0
- package/package/corpus/skills/cratis-chronicle-hosting/SKILL.md +3 -0
- package/package/corpus/skills/cratis-chronicle-hosting/references/operations.md +26 -0
- package/package/corpus/skills/cratis-chronicle-hosting/references/storage-resolution.md +55 -0
- package/package/corpus/skills/cratis-chronicle-multi-tenancy/SKILL.md +3 -0
- package/package/corpus/skills/cratis-chronicle-multi-tenancy/references/remove-namespace.md +38 -0
- package/package/corpus/skills/cratis-chronicle-projection/references/definition-changes.md +26 -0
- package/package/corpus/skills/cratis-chronicle-projection/references/model-bound-attributes.md +8 -0
- package/package/corpus/skills/cratis-chronicle-reactor/SKILL.md +5 -22
- package/package/corpus/skills/cratis-chronicle-reactor/references/starting-and-replaying.md +33 -0
- package/package/corpus/skills/cratis-chronicle-read-model/SKILL.md +9 -2
- package/package/corpus/skills/cratis-chronicle-read-model/references/queries.md +9 -4
- package/package/corpus/skills/cratis-chronicle-reducer/SKILL.md +4 -0
- package/package/corpus/skills/cratis-multi-service-architecture/SKILL.md +9 -3
- package/package/corpus/skills/cratis-performance-review/SKILL.md +4 -1
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/SKILL.md +2 -2
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/realization-and-gap-fill.md +10 -2
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/SKILL.md +9 -9
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/atomic-batches-and-source-mappings.md +2 -2
- package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +11 -11
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +9 -0
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/model-notes.md +41 -23
- package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +8 -3
- package/package/corpus/skills/cratis-screenplay-projections/SKILL.md +19 -12
- package/package/corpus/skills/cratis-screenplay-projections/references/pdl-grammar.md +37 -2
- package/package/corpus/skills/cratis-screenplay-projections/verification.json +11 -0
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/SKILL.md +37 -40
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/gap-fill-handoff.md +3 -2
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/renderability-gate.md +1 -1
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/verification.json +4 -2
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/coverage-matrix.md +9 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +13 -30
- package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +39 -6
- package/package/corpus/skills/cratis-screenplay-toolchain/references/executable-subset.md +5 -2
- package/package/corpus/skills/cratis-screenplay-toolchain/references/language-admission.md +15 -5
- package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +7 -4
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +12 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +9 -2
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +38 -56
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +23 -13
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/date-comparisons.md +44 -0
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/rendered-application.md +8 -2
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/sandbox-and-specrunner.md +59 -8
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/verification.json +7 -3
- package/package.json +1 -1
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
# Remove a namespace
|
|
5
|
+
|
|
6
|
+
Requires Chronicle 19.73.0 for `IEventStore.RemoveNamespace`.
|
|
7
|
+
Requires Chronicle 19.75.1 for reminder cleanup.
|
|
8
|
+
Requires Chronicle 19.76.1 for concurrent re-subscription recovery.
|
|
9
|
+
Requires client 19.77.1 for forgetting a removed namespace on reconnect. Check
|
|
10
|
+
with `dotnet list package` and the kernel image tag; older pairs can recreate
|
|
11
|
+
an apparently removed namespace.
|
|
12
|
+
|
|
13
|
+
This is destructive tenant removal, not a way to hide a tenant in the UI.
|
|
14
|
+
Before calling it, confirm the named event store and namespace, the authorized
|
|
15
|
+
scope, backups and application-owned storage disposition. Never target the
|
|
16
|
+
default namespace: its removal is refused. Removing an unknown namespace is a
|
|
17
|
+
no-op, and an interrupted removal can be repeated.
|
|
18
|
+
|
|
19
|
+
Removal first stops listing the namespace, unsubscribes and removes its
|
|
20
|
+
observers and their persistent reminders, then drops provider-owned namespace
|
|
21
|
+
storage and forgets the namespace. Forwarding and pattern observers with no
|
|
22
|
+
saved state are included through their reminders. Re-subscriptions already in
|
|
23
|
+
flight are handled by bounded unsubscribe/remove retries.
|
|
24
|
+
|
|
25
|
+
MongoDB drops its namespace database. SQL and in-memory providers retain their
|
|
26
|
+
namespace data; do not claim removal is erasure in those providers. Application
|
|
27
|
+
read-model databases are not dropped: the application owns that data and its
|
|
28
|
+
separately authorized cleanup.
|
|
29
|
+
|
|
30
|
+
On reconnect a non-default store asks whether its namespace still exists. If
|
|
31
|
+
absent, it releases that store instead of re-registering it; if the kernel
|
|
32
|
+
cannot answer, registration follows the older behavior. Explicitly using the
|
|
33
|
+
namespace again can create it anew. Stop or reroute writers when removal must
|
|
34
|
+
remain final.
|
|
35
|
+
|
|
36
|
+
Verify removal with a matching kernel and provider, including restart and
|
|
37
|
+
reconnect, and separately inspect the disposition of application-owned data.
|
|
38
|
+
Do not create or delete a live tenant merely to test this workflow.
|
|
@@ -23,5 +23,31 @@ history. Sources: `Documentation/projections/registration-lifecycle.md`,
|
|
|
23
23
|
`Documentation/concepts/observers.mdx`, `Observation/Jobs/{CatchUpObserver,ReplayObserver}.cs`
|
|
24
24
|
and `Observation/States/Routing.cs` (under `Source/Kernel/Core/`).
|
|
25
25
|
|
|
26
|
+
## Rolling deployment versions
|
|
27
|
+
|
|
28
|
+
Requires Chronicle 19.79.0 on client and kernel for projection registration's
|
|
29
|
+
`ChronicleOptions.SoftwareVersion`. It defaults to the entry assembly's informational version;
|
|
30
|
+
`Cratis:Chronicle:SoftwareVersion` overrides it, and startup warns on `1.0.0`.
|
|
31
|
+
Check `dotnet list package` and the kernel image tag; older kernels ignore it.
|
|
32
|
+
|
|
33
|
+
The kernel compares semantic-version precedence, including prerelease labels.
|
|
34
|
+
An older definition cannot overwrite a newer stored version, and an older
|
|
35
|
+
full-set registration cannot retire newer projections. Equal, missing or
|
|
36
|
+
unparseable versions retain ordinary registration behavior. An intentional
|
|
37
|
+
rollback must give the older code a software version higher than the stored
|
|
38
|
+
one. Changing only software version does not request a replay; definition
|
|
39
|
+
evolution policy still determines that.
|
|
40
|
+
|
|
41
|
+
## Namespace reconciliation
|
|
42
|
+
|
|
43
|
+
Requires Chronicle 19.81.1 for projections and captures to reconcile subscriptions
|
|
44
|
+
in every namespace, including runtime-created namespaces. Explicit ensure waits
|
|
45
|
+
for healthy subscriptions; implicit first-append creation is reconciled within
|
|
46
|
+
a watchdog interval. A broken definition does not block healthy ones or creation.
|
|
47
|
+
A lost subscription is repaired, but reconciliation never lifts quarantine,
|
|
48
|
+
revives a retired observer, or restarts a stopped/deleted capture. A kernel
|
|
49
|
+
restart or a newly added namespace still ends projection quarantine through a
|
|
50
|
+
fresh subscription; do not interpret ordinary watchdog repair as operator clear.
|
|
51
|
+
|
|
26
52
|
Closing a stream does not erase its events or prevent a projection replay.
|
|
27
53
|
Keep the closing fact as history; see **cratis-chronicle-event-constraints**.
|
package/package/corpus/skills/cratis-chronicle-projection/references/model-bound-attributes.md
CHANGED
|
@@ -59,6 +59,14 @@ pair it with `[NotRewindable]`. `[NotProjected]` excludes a query-assembled memb
|
|
|
59
59
|
from AutoMap and CHR0024. Sources: `Projections/ModelBound/NotProjectedAttribute.cs`,
|
|
60
60
|
`Projections/FromEveryBuilder.cs`, and `Documentation/projections/model-bound/`.
|
|
61
61
|
|
|
62
|
+
Requires Chronicle 19.78.1 for `[FromAll]`/`[FromEvery]` properties under
|
|
63
|
+
`[ChildrenFrom<T>]` or `[Nested]` to be declared on the child itself, including
|
|
64
|
+
the event creating it. Parent all-event mappings are not copied into children.
|
|
65
|
+
Older client definitions with root-declared child mappings work only when the
|
|
66
|
+
root has no property with the same name; otherwise the mapping stays on the
|
|
67
|
+
root until the client is upgraded. Check client/kernel versions and replay
|
|
68
|
+
affected projections to rebuild already materialized child values.
|
|
69
|
+
|
|
62
70
|
## Setting values
|
|
63
71
|
|
|
64
72
|
| Attribute | Arity | Parameters | Targets |
|
|
@@ -133,32 +133,15 @@ re-delivers the event as an ordinary observation, and a `[OnceOnly]` handler run
|
|
|
133
133
|
again. Catch-up and crash redelivery are not replay either; every ordinary
|
|
134
134
|
matching event can run, even on the same source. Keep effects idempotent.
|
|
135
135
|
|
|
136
|
-
**A
|
|
137
|
-
`[
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
observer is replaying or behind: a rebuilding model looks like "never processed".
|
|
142
|
-
Decide from the events or a `[Passive]` model, and specify the replaying case.
|
|
136
|
+
**A new reactor catches up history; `[OnceOnly]` does not stop that.**
|
|
137
|
+
Requires Chronicle 19.70.0 for `[StartAtTail]` to start only its first registration
|
|
138
|
+
at the tail; existing positions remain. Upgrade the server first: older kernels
|
|
139
|
+
ignore it. Read references/starting-and-replaying.md when avoiding pre-registration
|
|
140
|
+
side effects or choosing alternate replay behavior.
|
|
143
141
|
|
|
144
142
|
Analyzer **CHR0022** (warning) requires `[OnceOnly]` on a handler that returns
|
|
145
143
|
event side effects, because a replay would otherwise append duplicates.
|
|
146
144
|
|
|
147
|
-
`Cratis.Chronicle.Reactors.ReplayAttribute` (`[Replay]`) is the other half, and
|
|
148
|
-
targets a method only. Mark a **second** handler for the same event type with it
|
|
149
|
-
when replay needs to do something *different* rather than nothing:
|
|
150
|
-
|
|
151
|
-
```csharp
|
|
152
|
-
public Task <MethodName>(<EventName> @event) => <serviceName>.<Operation>(@event.<Property>);
|
|
153
|
-
|
|
154
|
-
[Replay]
|
|
155
|
-
public Task <MethodName>DuringReplay(<EventName> @event) => Task.CompletedTask;
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
With a `[Replay]` handler present, only it runs during replay. Without one, the
|
|
159
|
-
ordinary handler runs during replay as before. An event type handled *only* by a
|
|
160
|
-
`[Replay]` handler is still subscribed to.
|
|
161
|
-
|
|
162
145
|
## Identity and event sequence
|
|
163
146
|
|
|
164
147
|
`Cratis.Chronicle.Reactors.ReactorAttribute` takes two optional arguments:
|
|
@@ -0,0 +1,33 @@
|
|
|
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
|
+
# Start at the tail and distinguish replay
|
|
5
|
+
|
|
6
|
+
Requires Chronicle 19.70.0 for `[StartAtTail]` in
|
|
7
|
+
`Cratis.Chronicle.Reactors`. Upgrade the server before the client: an older
|
|
8
|
+
server ignores the field and catches up from the beginning. Check with
|
|
9
|
+
`dotnet list package` and the kernel image tag.
|
|
10
|
+
|
|
11
|
+
Put `[StartAtTail]` on a side-effect reactor that should observe only future
|
|
12
|
+
events. It changes the **first registration**: an observer already holding a
|
|
13
|
+
position keeps it. Leaving the attribute in place is safe, but adding it is not
|
|
14
|
+
a command to fast-forward an existing observer. Specify that historical facts
|
|
15
|
+
cause no effect on first registration.
|
|
16
|
+
|
|
17
|
+
`[OnceOnly]` excludes replay, not initial catch-up, failed-partition recovery
|
|
18
|
+
or crash redelivery. Keep side effects idempotent. A reconciliation sweep must
|
|
19
|
+
not decide from a model that is replaying or behind: rebuilding state can look
|
|
20
|
+
like "never processed". Decide from events or a passive model and cover that case.
|
|
21
|
+
|
|
22
|
+
## Alternate replay behavior
|
|
23
|
+
|
|
24
|
+
`Cratis.Chronicle.Reactors.ReplayAttribute` targets a method. Mark a second
|
|
25
|
+
handler for the same event type when replay must do different work. With that
|
|
26
|
+
handler present only it runs during replay; without one, the ordinary handler
|
|
27
|
+
runs unless excluded by `[OnceOnly]`. An event type handled only by a `[Replay]`
|
|
28
|
+
handler is still subscribed to.
|
|
29
|
+
|
|
30
|
+
Verify first registration, restart with an existing position, replay and
|
|
31
|
+
failed-partition redelivery separately. Assert the external effect count, not
|
|
32
|
+
only that the handler was invoked. Run `dotnet test` on the owning spec project;
|
|
33
|
+
server-first compatibility and durable positions also need kernel integration.
|
|
@@ -215,8 +215,8 @@ current rather than eventually consistent.
|
|
|
215
215
|
**Passive is fresher, not safer.** A materialized read may lag the log; a passive
|
|
216
216
|
read is current when read. Neither captures a position or enrolls a guard, so
|
|
217
217
|
neither makes a rule hold when two requests race. To guard a decision use a decision
|
|
218
|
-
read over
|
|
219
|
-
|
|
218
|
+
read over an admitted projection or unfiltered dependency-free reducer, a
|
|
219
|
+
constraint for uniqueness, or an aggregate;
|
|
220
220
|
see [choosing how a rule holds](../cratis-chronicle-decision-reads/references/choosing-how-a-rule-holds.md).
|
|
221
221
|
|
|
222
222
|
**`IMongoCollection<T>` reads only the sink.** It cannot compute passive state:
|
|
@@ -227,6 +227,13 @@ read-model parameter injection) when you need its computed state. Do not remove
|
|
|
227
227
|
Keep secret-bearing state on the protected access path; project only safe
|
|
228
228
|
metadata into a separate list/search model.
|
|
229
229
|
|
|
230
|
+
Requires Chronicle 19.77.3 for strongly consistent per-key projections to fold
|
|
231
|
+
from the start on every read: passive, stream-scoped, wildcard-key and session
|
|
232
|
+
reads immediately reflect revisions, redactions and joined-subject erasure.
|
|
233
|
+
Earlier warm reads can retain old content. Each read costs O(key history), not
|
|
234
|
+
an incremental suffix; prefer materialization for frequent long-history reads.
|
|
235
|
+
Check the deployed kernel tag before relying on this freshness.
|
|
236
|
+
|
|
230
237
|
The number of passive types is not itself a performance smell. Review event
|
|
231
238
|
history length, invocation frequency, and the consistency/security requirement;
|
|
232
239
|
repeated reconstruction of large histories on a hot path is the concern.
|
|
@@ -32,10 +32,15 @@ Chronicle extensions — Chronicle declares no `Observe` on `IMongoCollection<T>
|
|
|
32
32
|
|
|
33
33
|
## Discovery rules
|
|
34
34
|
|
|
35
|
-
Arc discovers **public static** methods
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
Arc discovers eligible **public and internal static** methods on `[ReadModel]`
|
|
36
|
+
types. Internal visibility is not an endpoint privacy boundary. Keep helpers
|
|
37
|
+
outside the read model, regardless of their visibility. Use
|
|
38
|
+
`[ReadModel(RequireQueryAttribute = true)]` and `[Query]` on intended endpoints
|
|
39
|
+
when the type also has folds (`Create`/`Reduce`); `[Query]` alone does not hide
|
|
40
|
+
siblings. Requires Arc 22.27.1 for exclusion of private, protected, special-name
|
|
41
|
+
and compiler-generated methods; older versions can expose private statics too.
|
|
42
|
+
Check with `dotnet list package`; on older versions move helpers out rather
|
|
43
|
+
than relying on visibility. ARC0026 checks invalid/ambiguous
|
|
39
44
|
query declarations; ARCCHR0019 warns about fold-like statics exposed by convention.
|
|
40
45
|
Requires Arc 22.90.0 for automatic exclusion of methods taking the model itself,
|
|
41
46
|
including `Reduce(event, current)`; `[Query]` cannot force such a method into an
|
|
@@ -234,6 +234,10 @@ event means no observer subscription; assembly membership alone is not event
|
|
|
234
234
|
membership. Types implementing `IReducer` stay classic even with a self-shaped
|
|
235
235
|
static helper.
|
|
236
236
|
|
|
237
|
+
Requires Chronicle 19.72.0 for CHR0065 to warn on fold-like methods that are
|
|
238
|
+
misnamed (`Reducer`/`reduce`) or not static and therefore never discovered.
|
|
239
|
+
Check `dotnet list package`; older analyzers can leave those methods silent.
|
|
240
|
+
|
|
237
241
|
Use the existing generic or Type `RegisterReducer` API for explicit self-model
|
|
238
242
|
nomination too; there is no special self API. A self model cannot share ownership
|
|
239
243
|
with a separate reducer, fluent projection or genuine model-bound mappings in the
|
|
@@ -154,9 +154,15 @@ of tags, and export only the fields consumers need. Read
|
|
|
154
154
|
## Versioning contracts
|
|
155
155
|
|
|
156
156
|
A public event type follows the same generation and migration rules as a private
|
|
157
|
-
one (`cratis-chronicle-event-type-migration`).
|
|
158
|
-
|
|
159
|
-
|
|
157
|
+
one (`cratis-chronicle-event-type-migration`). Requires Chronicle 19.66.0 for
|
|
158
|
+
subscription-builder `WithGenerationDelivery(EventGenerationDelivery.Pinned)`
|
|
159
|
+
with typed `WithEventType<TEvent>()` or `WithEventType(id, generation)` to pin
|
|
160
|
+
forwarding into the target inbox. Both stores must register that generation;
|
|
161
|
+
Compatibility remains the default. Read
|
|
162
|
+
../cratis-chronicle-client-dotnet/references/pinned-generation-delivery.md when
|
|
163
|
+
configuring subscription pins and failure behavior. The CLI's `subscriptions add`
|
|
164
|
+
takes ids only; do not invent a generation flag. Prefer additive, optional changes
|
|
165
|
+
to a contract; publish a new
|
|
160
166
|
event type for a breaking change and keep publishing the old one until every
|
|
161
167
|
consumer has moved, rather than adding a generation consumers may not handle.
|
|
162
168
|
Version the contracts package with the contract, and never move a type between
|
|
@@ -80,7 +80,10 @@ behavior this file does not already state.
|
|
|
80
80
|
- Preserve reducer admission and ordering guards when proposing a projection
|
|
81
81
|
conversion; an unconditional setter may resurrect or prematurely create state.
|
|
82
82
|
- Count passive models as inventory, not a smell. Assess history length and read
|
|
83
|
-
frequency against consistency/security needs.
|
|
83
|
+
frequency against consistency/security needs. Requires Chronicle 19.77.3 for
|
|
84
|
+
per-key strongly consistent projection reads to fold from the start each time;
|
|
85
|
+
repeated reads are O(key history), not incremental cache hits. Prefer a
|
|
86
|
+
materialized projection for frequent long-history reads when freshness permits. `IMongoCollection<T>` cannot
|
|
84
87
|
read passive computed state; never materialize secrets to make that query work.
|
|
85
88
|
- Distinguish retained `Observe` state and in-memory emissions from explicit
|
|
86
89
|
recompute queries. Narrow source filters and inspect page-refill/membership
|
|
@@ -42,8 +42,8 @@ Start new models with application-root `reaction batches atomic` (ESM v22 or lat
|
|
|
42
42
|
Each trigger occurrence's direct productions and each selected refusal branch are
|
|
43
43
|
separate all-or-none batches; invoked commands remain independent. Absence retains
|
|
44
44
|
legacy per-fact behavior even at later versions. Assert no failed-batch facts and
|
|
45
|
-
unchanged views, not only `then error`. Stage
|
|
46
|
-
atomic mode
|
|
45
|
+
unchanged views, not only `then error`. Requires Stage 4.139.0 for v22 admission
|
|
46
|
+
(older: -016); atomic mode stays STAGE-ESM-043. Keep as gap-fill.
|
|
47
47
|
Read [atomic batches and source mappings](../cratis-screenplay-captures-and-reactions/references/atomic-batches-and-source-mappings.md)
|
|
48
48
|
when choosing these boundaries or mapping an invoked identifier from `$eventSourceId`
|
|
49
49
|
(or `$eventContext.eventSourceId`) instead of copying it into event payload.
|
|
@@ -22,11 +22,19 @@ recovery behavior rather than assuming this handler supplies all-or-nothing sett
|
|
|
22
22
|
rejected model renderable, and never claim a whole-application V5 from a subset. Choose the route
|
|
23
23
|
with `cratis-screenplay-render-and-gap-fill`.
|
|
24
24
|
|
|
25
|
-
Application-root `reaction batches atomic` also blocks Stage delivery
|
|
26
|
-
|
|
25
|
+
Application-root `reaction batches atomic` also blocks Stage delivery with
|
|
26
|
+
STAGE-ESM-043. Requires Stage 4.139.0 for v22 admission; older Stage reports -016. 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
|
|
|
30
|
+
Requires Stage 4.141.1 for independent event-reaction specifications with `given clock`;
|
|
31
|
+
older executors refuse clocks beside reactions. This supplies `$context.occurred`
|
|
32
|
+
through cascades, invocation arguments and refusal branches, not a scheduler.
|
|
33
|
+
Clock/non-event triggers still refuse `STAGE-ESM-024`. Generated append/redelivery
|
|
34
|
+
clock fixtures retain -024 and context-dependent generated reaction specs retain -011.
|
|
35
|
+
Read [sandbox occurrence boundaries](../../cratis-stage-rendering-and-sandbox/references/sandbox-and-specrunner.md)
|
|
36
|
+
when verifying reaction time in Stage rather than reference execution.
|
|
37
|
+
|
|
30
38
|
## Where the pieces go (hand-written)
|
|
31
39
|
| Model element | Realization | Skill |
|
|
32
40
|
|---|---|---|
|
|
@@ -29,11 +29,11 @@ Language claims follow Screenplay `reactions.md`, `triggers.md`, `captures.md` a
|
|
|
29
29
|
The compiler's ESM admission decides, not the slice type. Reactions, triggers and
|
|
30
30
|
captures bind/reference-execute from v6; older compilers refuse them. Read toolchain
|
|
31
31
|
`references/diagnostics.md` when diagnosing skew or false PLAY0285 cascades.
|
|
32
|
-
- **
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
- **Stage realization:** read `cratis-stage-rendering-and-sandbox` `references/admission.md`
|
|
33
|
+
before claiming rendering. Supported event-triggered Automation renders; captures,
|
|
34
|
+
Translate, clocks and opaque bodies remain gap-fill (`-024`).
|
|
35
|
+
Read [sandbox boundaries](../cratis-stage-rendering-and-sandbox/references/sandbox-and-specrunner.md)
|
|
36
|
+
when checking authored occurrence versus generated-spec limits; a clock fixture is not scheduling.
|
|
37
37
|
|
|
38
38
|
Name the binding tool. For the automation test, loops and translation boundaries,
|
|
39
39
|
read `cratis-screenplay-automations-and-translations`.
|
|
@@ -74,7 +74,7 @@ Start new models with application-root `reaction batches atomic`. One trigger's
|
|
|
74
74
|
productions, or one selected refusal branch, append all-or-none; invoked commands stay
|
|
75
75
|
separate. Legacy models without opt-in retain per-fact appends even at newer versions.
|
|
76
76
|
Read [atomic batches and source mappings](references/atomic-batches-and-source-mappings.md)
|
|
77
|
-
for batch failure assertions, PLAY0693, Stage
|
|
77
|
+
for batch failure assertions, PLAY0693, Stage atomic-mode refusals and
|
|
78
78
|
`invokes` mappings from `$eventSourceId` / `$eventContext.eventSourceId`.
|
|
79
79
|
|
|
80
80
|
## Caller-less invokes and unprotected reads
|
|
@@ -104,9 +104,9 @@ binding, because its decision dependency cannot be protected. A reaction that on
|
|
|
104
104
|
command's own reads. Eligible command reads protect under application-root
|
|
105
105
|
`command reads protected` (ESM v25); legacy reads retain PLAY0271. Read command-surface
|
|
106
106
|
[protected reads](../cratis-screenplay-command-surface/references/protected-reads.md)
|
|
107
|
-
for admission and absence/conflict behavior. Stage
|
|
108
|
-
|
|
109
|
-
|
|
107
|
+
for admission and absence/conflict behavior. Requires Stage 4.138.0 to render
|
|
108
|
+
protected reads; older bundles refuse -044. Semantic Host/executor non-Error
|
|
109
|
+
protected requirements refuse -045.
|
|
110
110
|
`where` over read paths out of scope, and `where` needs
|
|
111
111
|
every operand to resolve from the trigger's declared scalar occurrence shape (listed in
|
|
112
112
|
the input selection or not; nested paths and read aliases fail binding): keep the logic that uses the state in
|
|
@@ -36,8 +36,8 @@ 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
|
|
40
|
-
|
|
39
|
+
Requires Stage 4.139.0 for ESM v22 admission; older Stage refuses STAGE-ESM-016.
|
|
40
|
+
Atomic mode is still 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.
|
|
43
43
|
|
|
@@ -26,6 +26,9 @@ Record open modeling questions as `question` notes in committed
|
|
|
26
26
|
personal data in notes. Read [model notes](references/model-notes.md) when
|
|
27
27
|
listing, recording or resolving questions: `list-model-notes`,
|
|
28
28
|
`propose-model-notes`, `read-proposal view=notes`, refs and orphan review.
|
|
29
|
+
Prefer dotted split-model targets; inspect `substitutions`, also for reanchor,
|
|
30
|
+
and disclose broader owners. The reference covers typed `parts` targets from
|
|
31
|
+
`open-workspace.applicationIdentity`.
|
|
29
32
|
|
|
30
33
|
## Choosing a strategy
|
|
31
34
|
|
|
@@ -45,8 +48,7 @@ Use the declared `screenplay` MCP server (for example `open-workspace`).
|
|
|
45
48
|
Never ask the user which folder to use before trying `open-workspace` without
|
|
46
49
|
arguments; do not invent a root. Read [MCP loop](references/mcp-loop.md) when connecting or switching roots;
|
|
47
50
|
it owns fallback discovery, fixed-root limits and the initialization protocol.
|
|
48
|
-
Discover `tools/list` schemas
|
|
49
|
-
|
|
51
|
+
Discover `tools/list` schemas.
|
|
50
52
|
|
|
51
53
|
Look first for the project's existing `.play` files: their folder is the model.
|
|
52
54
|
New models go in `Source/` or `src/`, else root `Screenplay/`, never `.cratis/`
|
|
@@ -104,9 +106,8 @@ for handler views: `executableReady` means binding, not an implemented body.
|
|
|
104
106
|
|
|
105
107
|
## Compare models
|
|
106
108
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
for paging and proposal review.
|
|
109
|
+
Compare with `main` through `semantic-diff` worktree `path`, not two exports.
|
|
110
|
+
Read [comparison sources](references/mcp-tools.md#semantic-revision-comparison) for paging.
|
|
110
111
|
|
|
111
112
|
## Make one coherent proposal
|
|
112
113
|
|
|
@@ -191,11 +192,10 @@ Commit `.screenplay/identities.json` with the model; only `apply` writes it. Nev
|
|
|
191
192
|
|
|
192
193
|
## Code attachments
|
|
193
194
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
`view: "implementation-requirements"` hashes/maps are not behavioral evidence.
|
|
195
|
+
Screenplay never compiles/runs opaque code attachments or `file` constraints;
|
|
196
|
+
a screen's `file` realizes UI instead. Read [MCP code attachments](references/mcp-tools.md#code-attachments)
|
|
197
|
+
for paths, PLAY0430–PLAY0434 and implementation-requirements views; hashes/maps
|
|
198
|
+
are not behavioral evidence.
|
|
199
199
|
|
|
200
200
|
## Verify and report honestly
|
|
201
201
|
|
|
@@ -225,7 +225,7 @@ Record screen MCP transcripts in `.ai-work/`; render/runtime checks must use the
|
|
|
225
225
|
same source, never an app that silently drops authored UI. Use the Screenplay-owned canonical
|
|
226
226
|
corpus fixture path instead of copying available `.play` fixtures here.
|
|
227
227
|
|
|
228
|
-
Never invent
|
|
228
|
+
Never invent syntax or capabilities.
|
|
229
229
|
|
|
230
230
|
## Route near misses
|
|
231
231
|
|
|
@@ -555,6 +555,15 @@ row is authored presence, not full coverage, causation or a passing specificatio
|
|
|
555
555
|
Bare rejections cannot distinguish message-specific rules; syntax-only owners
|
|
556
556
|
retain information-level readiness reasons. Never invent rules from opaque code.
|
|
557
557
|
|
|
558
|
+
A query's SPEC004 denial matches either `when query <Query>` with `then denied`,
|
|
559
|
+
or a read-only specification with no `when`, exactly one `then query <Query>`
|
|
560
|
+
with `arguments` and no `result`, followed by `then denied`. That read-only denial
|
|
561
|
+
does not meet the returned read model's SPEC006 assertion obligation; add a
|
|
562
|
+
separate state, absence or query-result specification.
|
|
563
|
+
Requires Screenplay 4.212.2 (`screenplay --version`) for this obligation matching;
|
|
564
|
+
older servers miss the read-only denial for SPEC004 and count it for SPEC006.
|
|
565
|
+
Upgrade before treating those rows as a coverage gate.
|
|
566
|
+
|
|
558
567
|
`find-modeling-smells` asks information-level questions, never changes compilation
|
|
559
568
|
or `--warnaserror`: SMELL001 generic event endings, SMELL002 generic command verbs,
|
|
560
569
|
SMELL003 duplicate nonempty event shapes from different commands, SMELL004 event
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
|
|
6
6
|
## Contents
|
|
7
7
|
|
|
8
|
-
- Verified product sources
|
|
9
8
|
- Choose the artifact
|
|
10
9
|
- Anchors and independent state
|
|
11
10
|
- List with bounded, pinned reads
|
|
@@ -14,25 +13,8 @@
|
|
|
14
13
|
- Source proposals can orphan notes
|
|
15
14
|
- Question gate is independent of compilation
|
|
16
15
|
|
|
17
|
-
## Verified product sources
|
|
18
|
-
|
|
19
16
|
Requires Screenplay 4.144.0 or later (`screenplay --version`) for model notes; the CLI-bundled MCP can be older.
|
|
20
17
|
|
|
21
|
-
Sources in `Cratis/Screenplay`:
|
|
22
|
-
|
|
23
|
-
| Contract | Path |
|
|
24
|
-
| --- | --- |
|
|
25
|
-
| Purpose, anchors, decisions and privacy | `Documentation/screenplay/model-notes.md` |
|
|
26
|
-
| Filters, operations, review and orphan disclosure | `Documentation/screenplay/mcp/reference.md`; `Source/DotNET/Screenplay.Mcp/McpNotesSchemas.cs` |
|
|
27
|
-
| Retained proposals, revision guards and notes review | `Source/DotNET/Screenplay.Mcp/McpWorkspaces.Notes.cs` |
|
|
28
|
-
| Operation fields and resolution evidence | `Source/DotNET/Screenplay.Mcp/McpNotesOperations.cs` |
|
|
29
|
-
| Sidecar bytes, absence and canonical revision | `Source/DotNET/Screenplay/Workspaces/ModelNotesStore.cs` |
|
|
30
|
-
| Standalone question gate | `Source/DotNET/Tool/ModelOpenQuestions.cs`; `Documentation/screenplay/model-notes.md` |
|
|
31
|
-
|
|
32
|
-
The source-edit and authoring guides remain useful for the ordinary proposal loop:
|
|
33
|
-
`Documentation/screenplay/mcp/edit.md` and `authoring-tools.md`.
|
|
34
|
-
The notes-specific arguments are in the reference and sources above.
|
|
35
|
-
|
|
36
18
|
## Choose the artifact
|
|
37
19
|
|
|
38
20
|
Record an unresolved modeling choice as a `question` note on the affected element,
|
|
@@ -60,10 +42,45 @@ Notes live beside the model in committed `.screenplay/notes.json`. An anchor is
|
|
|
60
42
|
do not derive them from names. Renames and moves keep notes without rewriting the
|
|
61
43
|
sidecar. `lastAddress` is a display hint, never an anchor.
|
|
62
44
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
45
|
+
Prefer dotted `{ address, kind }` targets for Module, Feature and Slice notes,
|
|
46
|
+
including split models. Repeated Module/Feature headers at the same logical
|
|
47
|
+
address merge across import placements and explicit headers; genuinely ambiguous
|
|
48
|
+
leaf declarations still refuse. A folder is one application, not a separate note
|
|
49
|
+
namespace per file.
|
|
50
|
+
|
|
51
|
+
For a typed `{ kind, parts }` target, copy an address from `read-ast` or
|
|
52
|
+
`read-workspace view=semantics`, or build it from names and the exact
|
|
53
|
+
`applicationIdentity` returned by `open-workspace`. This argument template targets
|
|
54
|
+
a Module (replace the Application key with that response's value):
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"kind": "Module",
|
|
59
|
+
"parts": [
|
|
60
|
+
{ "kind": "Application", "key": "<applicationIdentity from open-workspace>" },
|
|
61
|
+
{ "kind": "Module", "key": "Library" }
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
A typed address needs an existing catalog identity; it refuses when none exists.
|
|
67
|
+
Use the construct's current source handle instead. A target without an identity
|
|
68
|
+
lands on the nearest identified slice, feature, module or application. On an
|
|
69
|
+
unbound model, even a Slice can lack an identity and fall back to Application;
|
|
70
|
+
opening the workspace does not guarantee container identities.
|
|
71
|
+
|
|
72
|
+
Always inspect `substitutions` for both `add` and `reanchor`, even when reanchor
|
|
73
|
+
leaves the note unchanged. Each entry has the requested `target`, resolved
|
|
74
|
+
`anchor`, resolved `address` and `reason`. If the note lands on a broader owner,
|
|
75
|
+
say so to the user and name the intended construct in its text; reanchor once
|
|
76
|
+
the intended owner has an identity. Never report the requested anchor as applied
|
|
77
|
+
without checking the actual owner. Document and authoring-key anchors refuse.
|
|
78
|
+
|
|
79
|
+
Requires Screenplay 4.212.0 (`screenplay --version`) for split dotted-target
|
|
80
|
+
resolution, `open-workspace.applicationIdentity` and complete substitution
|
|
81
|
+
reporting. Older servers can refuse split targets, omit that field or silently
|
|
82
|
+
broaden the anchor; use a catalog address/current handle and inspect the notes
|
|
83
|
+
review's actual anchor, or upgrade before relying on these responses.
|
|
67
84
|
|
|
68
85
|
Notes do not change source, workspace/catalog/semantic revisions, executable
|
|
69
86
|
model bytes or compiler verdicts. Their own `notesRevision` is `nrev1:` plus the
|
|
@@ -141,7 +158,8 @@ revisions just read and an actual declaration address before calling it.
|
|
|
141
158
|
```
|
|
142
159
|
|
|
143
160
|
1. Retain `proposalId`, `afterNotesRevision`, server `addedNotes` IDs and inspect
|
|
144
|
-
`substitutions
|
|
161
|
+
every `substitutions` entry for the actual owner, also for reanchor.
|
|
162
|
+
`changeCount: 0` means no source changes, not no notes change.
|
|
145
163
|
2. Read `read-proposal` with `view: "notes"`: before/after notes revisions and
|
|
146
164
|
paged `{ id, before, after }` pairs. On continuation pin **afterNotesRevision**
|
|
147
165
|
as `expectedNotesRevision`, not the disk revision. Review the entire batch.
|
|
@@ -37,6 +37,11 @@
|
|
|
37
37
|
{ "kind": "skill-contains", "value": "never hand-edit `generate` text", "file": "references/mcp-loop.md" },
|
|
38
38
|
{ "kind": "skill-contains", "value": "Record open modeling questions as `question` notes" },
|
|
39
39
|
{ "kind": "skill-contains", "value": "list-model-notes", "file": "references/model-notes.md" },
|
|
40
|
+
{ "kind": "skill-contains", "value": "`applicationIdentity` returned by `open-workspace`", "file": "references/model-notes.md" },
|
|
41
|
+
{ "kind": "skill-contains", "value": "Repeated Module/Feature headers", "file": "references/model-notes.md" },
|
|
42
|
+
{ "kind": "skill-contains", "value": "Always inspect `substitutions` for both `add` and `reanchor`", "file": "references/model-notes.md" },
|
|
43
|
+
{ "kind": "skill-contains", "value": "even a Slice can lack an identity", "file": "references/model-notes.md" },
|
|
44
|
+
{ "kind": "skill-contains", "value": "older servers miss the read-only denial for SPEC004 and count it for SPEC006", "file": "references/mcp-tools.md" },
|
|
40
45
|
{ "kind": "skill-contains", "value": "`anchor`", "file": "references/model-notes.md" },
|
|
41
46
|
{ "kind": "skill-contains", "value": "`scope`", "file": "references/model-notes.md" },
|
|
42
47
|
{ "kind": "skill-contains", "value": "`state`", "file": "references/model-notes.md" },
|
|
@@ -163,11 +168,11 @@
|
|
|
163
168
|
},
|
|
164
169
|
{
|
|
165
170
|
"kind": "skill-contains",
|
|
166
|
-
"value": "
|
|
171
|
+
"value": "implementation-requirements views"
|
|
167
172
|
},
|
|
168
173
|
{
|
|
169
174
|
"kind": "skill-contains",
|
|
170
|
-
"value": "Screenplay never compiles
|
|
175
|
+
"value": "Screenplay never compiles/runs opaque code attachments"
|
|
171
176
|
},
|
|
172
177
|
{
|
|
173
178
|
"kind": "skill-contains",
|
|
@@ -180,7 +185,7 @@
|
|
|
180
185
|
},
|
|
181
186
|
{
|
|
182
187
|
"kind": "skill-contains",
|
|
183
|
-
"value": "
|
|
188
|
+
"value": "Discover `tools/list` schemas"
|
|
184
189
|
},
|
|
185
190
|
{
|
|
186
191
|
"kind": "skill-contains",
|
|
@@ -28,11 +28,9 @@ source is the single flow model.
|
|
|
28
28
|
|
|
29
29
|
## Product sources
|
|
30
30
|
|
|
31
|
-
Screenplay `Documentation/screenplay/projections/`
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
reducer-body binding (`Semantics/`). Every example below compiles with the standalone compiler.
|
|
35
|
-
Reverify before claiming another version behaves the same.
|
|
31
|
+
Consult Screenplay `Documentation/screenplay/projections/` for grammar and semantics,
|
|
32
|
+
`readmodels.md` for targets and `diagnostics.md` for errors. Verify examples with
|
|
33
|
+
the standalone compiler before claiming another version behaves the same.
|
|
36
34
|
|
|
37
35
|
**Chronicle decides what a projection means.**
|
|
38
36
|
Screenplay owns the grammar; which instance an event affects, what a join may
|
|
@@ -81,11 +79,8 @@ Read [observer filters](../cratis-screenplay-toolchain/references/production-rou
|
|
|
81
79
|
|
|
82
80
|
## Projection-level directives
|
|
83
81
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
concern and does not bind to the executable model. A mapping target may end in a dynamic dictionary
|
|
87
|
-
key, `count eventCountByType.$eventContext.eventType.id` (one entry per distinct value); only
|
|
88
|
-
`$eventContext` resolves there, any other `$` text is a literal key with warning `PLAY0299`.
|
|
82
|
+
Read [projection-level directives](references/pdl-grammar.md#projection-level-directives)
|
|
83
|
+
when using descriptions, `sequence`, `file` or dynamic dictionary-key targets.
|
|
89
84
|
|
|
90
85
|
⚠️ **Do not write `key` on the projection.** It parses, but neither Chronicle nor
|
|
91
86
|
the executable model routes any event by it, and it is not a default for the
|
|
@@ -148,14 +143,26 @@ subscribe to every event type: `all` inside `children` or `nested` behaves as
|
|
|
148
143
|
`lastUpdatedAt`. The `every` block **inside** a `children` block does not accept
|
|
149
144
|
it — it is already in a children context.
|
|
150
145
|
|
|
146
|
+
## One event per level
|
|
147
|
+
|
|
148
|
+
One event type is used once per projection level (`PLAY0801`): two `from` blocks
|
|
149
|
+
cannot update two rows at that level, even with different keys. Combine mappings
|
|
150
|
+
for one row; model a genuine second domain fact as its own event. Never invent
|
|
151
|
+
events only to satisfy the read side. Joins use a separate set; each children,
|
|
152
|
+
nested and variant block starts fresh sets. Read [event scope](references/pdl-grammar.md#event-scope)
|
|
153
|
+
for grouped events, removals and compiler compatibility.
|
|
154
|
+
|
|
151
155
|
## Property mapping and AutoMap
|
|
152
156
|
|
|
153
157
|
⚠️ **AutoMap is on by default.** Matching property names are copied before your
|
|
154
158
|
explicit mappings run, and explicit mappings win. Turn it off with `no automap` at
|
|
155
159
|
**projection**, `every`/`all`, `join`, `children` or `nested` level — it
|
|
156
160
|
**cannot** be toggled inside an individual `from` block. An `automap`/`no automap`
|
|
157
|
-
under a joined event (`with …`)
|
|
158
|
-
|
|
161
|
+
under a joined event (`with …`) decides auto-mapping for that event alone;
|
|
162
|
+
without one, the joined event follows its level's auto-map.
|
|
163
|
+
|
|
164
|
+
Requires Screenplay 4.212.4 (`screenplay --version`) for joined-event auto-map
|
|
165
|
+
overrides in executable binding; older binders replace the setting with the level's.
|
|
159
166
|
|
|
160
167
|
Mapping sources: a property path (`name`, `contactInfo.email`), a literal
|
|
161
168
|
(`true`, `"Pending"`, `42`, `null`), `$eventSourceId`, and
|