@cratis/pi 7.62.0 → 7.64.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package/corpus/product-sync.json +9 -9
- package/package/corpus/skills/cratis-application-slice-conformance/SKILL.md +1 -1
- package/package/corpus/skills/cratis-arc-command/references/generated-values.md +27 -12
- package/package/corpus/skills/cratis-arc-command/references/shop-generation.md +17 -6
- package/package/corpus/skills/cratis-fundamentals-concept/SKILL.md +10 -2
- package/package/corpus/skills/cratis-fundamentals-concept/references/shop-generation.md +49 -6
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/SKILL.md +43 -41
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/cases-to-specify.md +11 -2
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/integration-interview.md +24 -0
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/public-events-and-direction.md +76 -10
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/realization-and-gap-fill.md +5 -0
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/todo-list-example.md +1 -1
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/translate-example.md +39 -23
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/references/translation-patterns.md +35 -12
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/SKILL.md +51 -81
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/atomic-batches-and-source-mappings.md +83 -0
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/capture-map-and-example.md +14 -4
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/reaction-forms.md +59 -0
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/record-capture-specifications.md +60 -0
- package/package/corpus/skills/cratis-screenplay-captures-and-reactions/references/specifying-triggers-and-clock.md +5 -1
- package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +37 -30
- package/package/corpus/skills/cratis-screenplay-command-surface/references/date-comparisons.md +100 -0
- package/package/corpus/skills/cratis-screenplay-command-surface/references/described-handlers.md +82 -0
- package/package/corpus/skills/cratis-screenplay-command-surface/references/generated-values-and-responses.md +82 -28
- package/package/corpus/skills/cratis-screenplay-command-surface/references/protected-reads.md +113 -0
- package/package/corpus/skills/cratis-screenplay-command-surface/references/shop-generation.md +45 -12
- package/package/corpus/skills/cratis-screenplay-command-surface/references/text-and-match-rules.md +119 -0
- package/package/corpus/skills/cratis-screenplay-command-surface/references/validate-rules.md +26 -6
- package/package/corpus/skills/cratis-screenplay-command-surface/verification.json +13 -3
- package/package/corpus/skills/cratis-screenplay-event-modeling/SKILL.md +12 -12
- package/package/corpus/skills/cratis-screenplay-event-modeling/references/parsed-not-runnable.md +5 -3
- package/package/corpus/skills/cratis-screenplay-event-modeling/verification.json +5 -1
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/SKILL.md +2 -2
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/evidence-table-template.md +1 -1
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/generated-recovery.md +51 -14
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/intent-example.md +5 -0
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/loss-report-template.md +2 -1
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/rule-modeling.md +6 -3
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/signal-to-intent.md +1 -1
- package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +22 -28
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/choosing-generation.md +20 -7
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/language-reference.md +13 -6
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-loop.md +9 -1
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +58 -10
- package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +4 -2
- package/package/corpus/skills/cratis-screenplay-model-review/SKILL.md +2 -5
- package/package/corpus/skills/cratis-screenplay-model-review/references/anti-patterns.md +2 -2
- package/package/corpus/skills/cratis-screenplay-model-review/references/checklist.md +2 -2
- package/package/corpus/skills/cratis-screenplay-model-review/references/quick-self-check.md +2 -1
- package/package/corpus/skills/cratis-screenplay-model-review/references/review-questions.md +3 -2
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/principles.md +1 -1
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/vocabulary-map.md +1 -1
- package/package/corpus/skills/cratis-screenplay-read-surface/SKILL.md +2 -3
- package/package/corpus/skills/cratis-screenplay-read-surface/references/named-keys.md +3 -1
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/SKILL.md +8 -3
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/gap-fill-handoff.md +8 -0
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/renderability-gate.md +6 -4
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/SKILL.md +48 -30
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/berth-reservations.md +10 -4
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/invoicing-dues-design.md +15 -4
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/invoicing-dues-example.md +25 -20
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/public-event-coverage.md +14 -3
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/scenario-examples.md +9 -3
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/references/spec-forms-by-mode.md +9 -4
- package/package/corpus/skills/cratis-screenplay-slice-design/SKILL.md +3 -1
- package/package/corpus/skills/cratis-screenplay-slice-design/references/command-inventory.md +4 -4
- package/package/corpus/skills/cratis-screenplay-slice-design/references/rule-layers.md +4 -2
- package/package/corpus/skills/cratis-screenplay-slice-design/references/slicing.md +4 -3
- package/package/corpus/skills/cratis-screenplay-slice-design/references/worked-example.md +8 -8
- package/package/corpus/skills/cratis-screenplay-specifications/SKILL.md +69 -47
- package/package/corpus/skills/cratis-screenplay-specifications/references/actions-beyond-commands.md +11 -1
- package/package/corpus/skills/cratis-screenplay-specifications/references/generated-fixtures.md +48 -17
- package/package/corpus/skills/cratis-screenplay-specifications/references/outcome-comparison.md +6 -0
- package/package/corpus/skills/cratis-screenplay-specifications/references/vocabulary.md +14 -1
- package/package/corpus/skills/cratis-screenplay-streams-and-consistency/SKILL.md +25 -21
- package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/boundaries.md +2 -2
- package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/consistency-and-concurrency.md +9 -3
- package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/multi-service-models.md +4 -3
- package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/streams-example.md +7 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +32 -22
- package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet-example.md +3 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet.md +47 -2
- package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostic-arguments.md +60 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +66 -6
- package/package/corpus/skills/cratis-screenplay-toolchain/references/executable-subset.md +67 -23
- package/package/corpus/skills/cratis-screenplay-toolchain/references/generation-checks.md +93 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/references/generation-strategies-example.md +117 -35
- package/package/corpus/skills/cratis-screenplay-toolchain/references/language-admission.md +61 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/references/preferred-syntax.md +3 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +27 -10
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +3489 -335
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/traps.md +5 -3
- package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +6 -1
- package/package/corpus/skills/cratis-screenplay-ui-composition/SKILL.md +8 -53
- package/package/corpus/skills/cratis-screenplay-ui-composition/references/file-references.md +2 -2
- package/package/corpus/skills/cratis-screenplay-ui-composition/references/interaction-example.md +54 -0
- package/package/corpus/skills/cratis-screenplay-ui-composition/verification.json +6 -3
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +30 -29
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +39 -9
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/choosing-generation.md +28 -8
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/publication-and-recovery.md +31 -0
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/sandbox-and-specrunner.md +8 -0
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/verification.json +4 -1
- package/package.json +1 -1
|
@@ -0,0 +1,113 @@
|
|
|
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
|
+
# Protected command reads
|
|
5
|
+
|
|
6
|
+
## Contents
|
|
7
|
+
|
|
8
|
+
- Admission and paths
|
|
9
|
+
- Absence and races
|
|
10
|
+
- Repair and target boundary
|
|
11
|
+
|
|
12
|
+
Requires Screenplay 4.193.0 or later (`screenplay --version`); older compilers refuse command reads with PLAY0271 and read paths with PLAY0268.
|
|
13
|
+
|
|
14
|
+
Declare `command reads protected` once in the application-root document. Imported
|
|
15
|
+
commands inherit it. This selects ESM v25, including when text rules are used, and
|
|
16
|
+
records `commandReadMode: "protected"`. Without it, legacy reads retain PLAY0271,
|
|
17
|
+
read paths retain PLAY0268, and bytes/version stay unchanged. A higher ESM version
|
|
18
|
+
alone never opts an application in.
|
|
19
|
+
|
|
20
|
+
Complete model:
|
|
21
|
+
|
|
22
|
+
```screenplay
|
|
23
|
+
domain Inventory
|
|
24
|
+
command reads protected
|
|
25
|
+
module Stock
|
|
26
|
+
feature Allocation
|
|
27
|
+
slice StateView CurrentStock
|
|
28
|
+
event StockCounted
|
|
29
|
+
quantity Int
|
|
30
|
+
event StockRemoved
|
|
31
|
+
readmodel Current
|
|
32
|
+
id String key
|
|
33
|
+
quantity Int
|
|
34
|
+
projection CurrentProjection => Current
|
|
35
|
+
from StockCounted
|
|
36
|
+
remove with StockRemoved
|
|
37
|
+
slice StateChange Allocate
|
|
38
|
+
command Allocate
|
|
39
|
+
id String identifier
|
|
40
|
+
stockId String
|
|
41
|
+
reads Current by stockId
|
|
42
|
+
validate
|
|
43
|
+
require Current.quantity > 0
|
|
44
|
+
message "Stock must be available"
|
|
45
|
+
produces Allocated
|
|
46
|
+
for id
|
|
47
|
+
quantity = Current.quantity
|
|
48
|
+
event Allocated
|
|
49
|
+
quantity Int
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Admission and paths
|
|
53
|
+
|
|
54
|
+
`reads <View> [as <alias>] [by <input>]` looks up required state. Omitted `by` uses
|
|
55
|
+
the declared command identifier; no identifier is PLAY0782. Repeated reads of a
|
|
56
|
+
view each need a distinct alias; paths use the alias rather than the view name.
|
|
57
|
+
Aliases start with a lowercase letter or underscore.
|
|
58
|
+
|
|
59
|
+
Every read must satisfy both boundaries:
|
|
60
|
+
|
|
61
|
+
- A finite non-empty set of event-log event types builds the view, including removal
|
|
62
|
+
handling; the key is event-source identity only.
|
|
63
|
+
- The lookup key is a required scalar non-generated command input: String, a String
|
|
64
|
+
concept or canonical GUID.
|
|
65
|
+
|
|
66
|
+
PLAY0781 refuses reducers, joins (including removal joins), children/nested scopes,
|
|
67
|
+
`every`/`all`, payload/composite keys, missing removals, empty handled-event sets,
|
|
68
|
+
named sources/streams, singleton views and unsupported/generated/optional/collection
|
|
69
|
+
keys. Its closed reasons are Reducer, Join, Children, OpenSubscription, PayloadKey,
|
|
70
|
+
ByParts, NoRemoval, EmptyHandledSet, NamedSourceOrStream, Singleton, KeyType,
|
|
71
|
+
GeneratedKey, OptionalKey and CollectionKey. `optional`, `advisory` and `via query`
|
|
72
|
+
remain refused; `via query` uses parser code PLAY0175. There is no unguarded fallback.
|
|
73
|
+
|
|
74
|
+
Single-level `read.property` paths bind in `require` operands and produced-event
|
|
75
|
+
mapping sources only. Deeper paths and read paths in `produces when`, response
|
|
76
|
+
fields, `for`, routes and derive/provide remain PLAY0268. Unknown read/property
|
|
77
|
+
paths report PLAY0784; ambiguous view paths report PLAY0785. A command with both
|
|
78
|
+
`reads` and `concurrency` reports PLAY0783: do not guess which boundary wins.
|
|
79
|
+
|
|
80
|
+
## Absence and races
|
|
81
|
+
|
|
82
|
+
Execution orders authorization → property rules → required reads → derive/provide
|
|
83
|
+
→ requirements → productions/responses. Missing state rejects with Validation and
|
|
84
|
+
message `<ReadModel> '<key>' does not exist.` before evaluating requirements or
|
|
85
|
+
mappings. Property-rule rejection therefore wins over absence.
|
|
86
|
+
|
|
87
|
+
Decide records the unfiltered fact-log boundary, read key and handled event types.
|
|
88
|
+
A matching fact after that boundary makes commit return Conflict /
|
|
89
|
+
DecisionStateChanged with no command facts, including publications. Irrelevant
|
|
90
|
+
facts do not conflict and remain in the committed world. Even a no-fact command is
|
|
91
|
+
checked. Race cases are evaluator vectors, not a new `.play` specification construct.
|
|
92
|
+
|
|
93
|
+
Specify present/absent state, rule refusal and denial. Assert no new facts and
|
|
94
|
+
unchanged views on failure; use target concurrency tests to prove actual storage
|
|
95
|
+
protection. Ordinary injected read models are not protected decisions; uniqueness
|
|
96
|
+
still belongs in a `unique` append constraint.
|
|
97
|
+
|
|
98
|
+
## Repair and target boundary
|
|
99
|
+
|
|
100
|
+
PLAY0780 rejects duplicate, conflicting or non-root preambles. Informational
|
|
101
|
+
PLAY0786 identifies an eligible legacy model at its first command read. Discover
|
|
102
|
+
`read-workspace view=repairs`, then `propose-repair` with current workspace/catalog
|
|
103
|
+
revisions and canonical formatting consent; review with `read-proposal` before
|
|
104
|
+
explicit `apply`. The repair inserts into the domain document or sole document,
|
|
105
|
+
refuses ambiguous roots and requires individual review, never fix-all. It changes
|
|
106
|
+
absence/conflict behavior, not merely formatting.
|
|
107
|
+
|
|
108
|
+
Stage admits ESM v25 but refuses protected reads with STAGE-ESM-044 in rendering,
|
|
109
|
+
Host serving and specification execution; a reference pass is not Stage or Arc
|
|
110
|
+
realization. Preserve the model's protection and deliver authorized hand-written
|
|
111
|
+
consistency enforcement through the render-and-gap-fill workflow. Never remove
|
|
112
|
+
the preamble to get a render. `screenplay <root> --warnaserror` must exit zero;
|
|
113
|
+
`screenplay test <root>` separately establishes reference behavior, not target support.
|
package/package/corpus/skills/cratis-screenplay-command-surface/references/shop-generation.md
CHANGED
|
@@ -1,22 +1,30 @@
|
|
|
1
1
|
<!-- Copyright (c) Cratis. All rights reserved. -->
|
|
2
2
|
<!-- Licensed under the MIT license. See LICENSE file in the project root for full license information. -->
|
|
3
3
|
|
|
4
|
-
# The shop in Screenplay:
|
|
4
|
+
# The shop in Screenplay: generated values
|
|
5
|
+
|
|
6
|
+
## Contents
|
|
7
|
+
|
|
8
|
+
- Choosing a strategy
|
|
9
|
+
- When not to generate
|
|
10
|
+
- Sources
|
|
5
11
|
|
|
6
12
|
## Choosing a strategy
|
|
7
13
|
|
|
8
14
|
Use the same vocabulary as the [Fundamentals/Arc shop](../../cratis-fundamentals-concept/references/shop-generation.md),
|
|
9
15
|
but only the released language realization: CustomerId is `cus_` + uppercase
|
|
10
|
-
ULID, OrderId is `typeid "order"`, and InviteCode is NanoID.
|
|
16
|
+
ULID, OrderId is `typeid "order"`, and InviteCode is NanoID. InvoiceNumber uses
|
|
17
|
+
a readable date/checksum pattern; TicketNumber is an Int pickup-ticket value. Their strategies
|
|
11
18
|
belong to concepts; command properties only say `generated`/`generated identifier`.
|
|
12
19
|
The existing [strategy reference](generated-values-and-responses.md) owns exact
|
|
13
20
|
encodings, entropy, MCP edits, fixtures and freshness.
|
|
14
21
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
Context-member
|
|
22
|
+
Requires Screenplay 4.172.0 or later (`screenplay --version`) for pattern/random/rule
|
|
23
|
+
and checksum validation (ESM v21); older compilers refuse them with PLAY0268.
|
|
24
|
+
`generate rule Name` can attach code with Now/Tenant context, but the reference
|
|
25
|
+
runner never executes it: pin the whole String result. TypeID itself has no
|
|
26
|
+
tenant slot. Context-member factory recovery still stays in code. Stage's
|
|
27
|
+
time-ordered factories use the command receipt, not an invented wall-clock value.
|
|
20
28
|
|
|
21
29
|
The shop's ApiKey remains a **secret**. In .NET its factory is `Bytes(32)` and its
|
|
22
30
|
concept is `[NotAudited]`. It is never an identifier (event-source IDs are plaintext
|
|
@@ -35,6 +43,11 @@ concept OrderId : String
|
|
|
35
43
|
concept InviteCode : String
|
|
36
44
|
generate nanoid
|
|
37
45
|
concept ApiKey : String secret
|
|
46
|
+
concept InvoiceNumber : String
|
|
47
|
+
generate pattern "INV-{yyyy}{MM}-#{7}" checksum luhn
|
|
48
|
+
validate checksum luhn
|
|
49
|
+
concept TicketNumber : Int
|
|
50
|
+
generate random 100000..999999
|
|
38
51
|
module Shop
|
|
39
52
|
feature Customers
|
|
40
53
|
slice StateChange Register
|
|
@@ -58,22 +71,39 @@ module Shop
|
|
|
58
71
|
inviteCode = "abcdefghijklmnopqrstu"
|
|
59
72
|
feature Orders
|
|
60
73
|
slice StateChange Place
|
|
74
|
+
constraint UniqueInvoiceNumber
|
|
75
|
+
unique invoiceNumber on OrderPlaced
|
|
76
|
+
constraint UniquePickupTicket
|
|
77
|
+
unique pickupTicket on OrderPlaced
|
|
61
78
|
command PlaceOrder
|
|
62
79
|
orderId OrderId generated identifier
|
|
80
|
+
invoiceNumber InvoiceNumber generated
|
|
81
|
+
pickupTicket TicketNumber generated
|
|
63
82
|
produces event OrderPlaced
|
|
83
|
+
invoiceNumber InvoiceNumber = invoiceNumber
|
|
84
|
+
pickupTicket TicketNumber = pickupTicket
|
|
64
85
|
returns orderId
|
|
65
86
|
specification PlacesWithPinnedValue
|
|
87
|
+
given clock "2026-10-02T09:00:00Z"
|
|
66
88
|
when PlaceOrder
|
|
67
89
|
for "order_0000000000e008000000000000"
|
|
90
|
+
generated invoiceNumber = "INV-202610-00000004"
|
|
91
|
+
generated pickupTicket = 123456
|
|
68
92
|
then OrderPlaced
|
|
69
93
|
for "order_0000000000e008000000000000"
|
|
94
|
+
invoiceNumber = "INV-202610-00000004"
|
|
95
|
+
pickupTicket = 123456
|
|
70
96
|
then returns "order_0000000000e008000000000000"
|
|
71
97
|
```
|
|
72
98
|
|
|
73
99
|
Each property is server-owned, not a client-minted input. The ApiKey declaration
|
|
74
100
|
is not permission to replace its secret contract with an ordinary random String.
|
|
75
|
-
|
|
76
|
-
|
|
101
|
+
The invoice date segments use the pinned UTC clock; it does not draw a portable
|
|
102
|
+
ULID or TypeID fixture. Checksum validation is authored separately from generation.
|
|
103
|
+
Dates/check digits add no entropy. The short invoice and ticket values use
|
|
104
|
+
single-property unique constraints; neither is a generated identifier. Whole-source
|
|
105
|
+
freshness protects the OrderId destination, not every generated payload value.
|
|
106
|
+
A duplicate-source specification should
|
|
77
107
|
expect Concurrency with no new facts or response, not a regenerated ID.
|
|
78
108
|
|
|
79
109
|
## When not to generate
|
|
@@ -83,10 +113,13 @@ idempotency keys, authorization, gapless invoice numbers or proof of projection
|
|
|
83
113
|
readiness. A reference InviteCode is not automatically a credential; if possession
|
|
84
114
|
confers access, protect it as a secret and do not claim this generated String
|
|
85
115
|
example realizes that credential behavior. Never drop ApiKey's secret marker to
|
|
86
|
-
make its generation bind/render.
|
|
87
|
-
|
|
116
|
+
make its generation bind/render. A pattern is not gapless/sequential numbering;
|
|
117
|
+
check digits catch typos, not forgery. ESM v21 binds and reference-executes with
|
|
118
|
+
pins. Requires Stage 4.118.0 for checksum validation and 4.119.0 for pattern/random
|
|
119
|
+
rendering; older renderers refuse those constructs. `generate rule` still refuses
|
|
120
|
+
STAGE-ESM-028. Sequence allocation and secret generation stay explicit gaps.
|
|
88
121
|
|
|
89
|
-
##
|
|
122
|
+
## Sources
|
|
90
123
|
|
|
91
124
|
Screenplay `Documentation/screenplay/generated-values/choosing.md`,
|
|
92
125
|
`Documentation/screenplay/generated-values.md`,
|
package/package/corpus/skills/cratis-screenplay-command-surface/references/text-and-match-rules.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
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
|
+
# Literal text rules and portable matching
|
|
5
|
+
|
|
6
|
+
## Contents
|
|
7
|
+
|
|
8
|
+
- Literal text rules
|
|
9
|
+
- Portable `matches`
|
|
10
|
+
- Studio replacements and public check APIs
|
|
11
|
+
|
|
12
|
+
## Literal text rules
|
|
13
|
+
|
|
14
|
+
Requires Screenplay 4.184.0 or later (`screenplay --version`) for literal text rules and pattern admission checks; older compilers do not admit these rule forms.
|
|
15
|
+
|
|
16
|
+
Prefer a literal rule over a regex when the requirement is plain text. Complete example:
|
|
17
|
+
|
|
18
|
+
```screenplay
|
|
19
|
+
concept InvoiceReference : String
|
|
20
|
+
validate
|
|
21
|
+
contains "-"
|
|
22
|
+
not contains " "
|
|
23
|
+
starts with "INV-"
|
|
24
|
+
ends with "-NOK"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
These concept/command-property rules select ESM v24. They compare UTF-16 code units
|
|
28
|
+
ordinally, without case folding or normalization. Use one non-enum text value and a
|
|
29
|
+
quoted literal operand, not a property, collection or regex. An absent optional
|
|
30
|
+
value passes; add `not empty` to require presence. An empty operand makes `contains`,
|
|
31
|
+
`starts with` and `ends with` pass, and `not contains` fail for present text.
|
|
32
|
+
Equality and inequality remain `== "x"` and `!= "x"`.
|
|
33
|
+
|
|
34
|
+
This is not condition grammar: `contains`/`starts with` in `require`, `produces when`
|
|
35
|
+
or reaction `where` remain PLAY0268. Those conditions admit scalar equality and
|
|
36
|
+
numeric ordering, not the property text rules.
|
|
37
|
+
|
|
38
|
+
Requires Stage 4.124.0 for v24 text-rule admission (`cratis --version` identifies the CLI bundle); older renderers refuse v24 with STAGE-ESM-016.
|
|
39
|
+
|
|
40
|
+
Stage admits v24 and executes these four rules on its Host and specification
|
|
41
|
+
executor, rendering ordinal UTF-16 comparisons without regex or a Screenplay
|
|
42
|
+
runtime dependency. The legacy EventModel syntax engine drops these rules; use
|
|
43
|
+
semantic admission, never infer support from that engine's output.
|
|
44
|
+
|
|
45
|
+
## Portable `matches`
|
|
46
|
+
|
|
47
|
+
Requires Screenplay 4.183.0 or later (`screenplay --version`); older compilers use platform matching and may accept nonportable constructs.
|
|
48
|
+
|
|
49
|
+
A quoted pattern is a flagless JavaScript expression restricted to a portable linear
|
|
50
|
+
dialect, not arbitrary ECMAScript or .NET regex. It searches any substring unless
|
|
51
|
+
anchored. Screenplay uses its own Thompson automaton, without timeout or host-engine
|
|
52
|
+
settings. Syntax remains `matches "^INV-[0-9]{6}$"` or `matches email`.
|
|
53
|
+
|
|
54
|
+
| Admitted | Meaning |
|
|
55
|
+
| --- | --- |
|
|
56
|
+
| Literals, `.`, `^`, `$`, alternation | `$` is strict end of input, not before a final newline |
|
|
57
|
+
| `(…)`, `(?:…)`, `(?<name>…)` | ASCII names `[A-Za-z_][A-Za-z0-9_]*`; duplicate names only in disjoint alternatives; names that can match together report PLAY0367 |
|
|
58
|
+
| Classes, negation, single-character ranges | Unions/complements use set semantics |
|
|
59
|
+
| `\d \D \w \W \s \S` | `\d` is ASCII digits, `\w` ASCII letters/digits/underscore |
|
|
60
|
+
| `\t \n \r \f \v`, `\0` not before a digit, `\xHH`, `\uHHHH` | UTF-16 code-unit escapes |
|
|
61
|
+
| Escaped syntax characters and `\/` | `\-` also inside a class |
|
|
62
|
+
| `* + ? {n} {n,} {n,m}` and lazy forms | No stacked quantifiers |
|
|
63
|
+
|
|
64
|
+
`\s` includes U+00A0, U+FEFF and Unicode line/paragraph separators; it excludes
|
|
65
|
+
U+0085. Dot excludes LF, CR, U+2028 and U+2029. `\w` excludes U+0130.
|
|
66
|
+
`matches email` is conservative, not RFC 5322: one `@`, nonempty local part without
|
|
67
|
+
whitespace/`@`, and at least two nonempty domain parts without whitespace/`@`.
|
|
68
|
+
A no-break space therefore fails email validation. Other bare names report PLAY0366.
|
|
69
|
+
|
|
70
|
+
PLAY0367 means invalid syntax, including stacked quantifiers. PLAY0699 means a
|
|
71
|
+
construct outside the dialect: lookarounds, backreferences, word boundaries,
|
|
72
|
+
Unicode properties, code-point escapes, control/octal/identity escapes, .NET-only
|
|
73
|
+
anchors/options/class subtraction, empty classes, stray brackets, class escapes as
|
|
74
|
+
range endpoints, or non-ASCII group names. Use explicit classes, UTF-16/hex escapes,
|
|
75
|
+
`^`/`$`, or a literal text rule where equivalent. A length-only lookahead can become
|
|
76
|
+
an anchored counted repeat; there is no general lookaround replacement.
|
|
77
|
+
|
|
78
|
+
Limits are 1,000 decoded UTF-16 code units and 3,000 expanded nodes. Literals,
|
|
79
|
+
classes, anchors and each optional/loop/alternative choice point count one. Counted
|
|
80
|
+
repeats multiply their body by the upper bound (unbounded: lower bound plus one),
|
|
81
|
+
adding optional/loop choices. `x{1500}` counts 1,500; `a{0,1500}` and `(a*){1500}`
|
|
82
|
+
count 3,000. Exceeding either limit reports PLAY0699 before automaton construction.
|
|
83
|
+
|
|
84
|
+
Older serialized ESM retains authored pattern bytes and loads, but invalid/refused
|
|
85
|
+
patterns plan as UnsupportedValidation and generation checks report Unproven;
|
|
86
|
+
re-authoring reports PLAY0367/PLAY0699.
|
|
87
|
+
Browser matching remains advisory: JavaScript may backtrack even on admitted
|
|
88
|
+
`(a+)+$`. The server-side linear check is authoritative.
|
|
89
|
+
|
|
90
|
+
## Studio replacements and public check APIs
|
|
91
|
+
|
|
92
|
+
Only exact escaped-literal Studio shapes desugar with warning PLAY0787, not PLAY0699:
|
|
93
|
+
|
|
94
|
+
| Decoded pattern (`L` is an escaped literal) | Replacement |
|
|
95
|
+
| --- | --- |
|
|
96
|
+
| `^(?![\s\S]*L)` | `not contains "literal"` |
|
|
97
|
+
| `L(?![\s\S])` | `ends with "literal"` |
|
|
98
|
+
| `^L(?![\s\S])` | `== "literal"` |
|
|
99
|
+
| `^(?!L$)` or `^(?!L(?![\s\S]))` | `!= "literal"` |
|
|
100
|
+
|
|
101
|
+
Recognition requires a lossless escape/decode round trip: Studio v1 uses
|
|
102
|
+
.NET Regex.Escape; v2 escapes `\ ^ $ . | ? * + ( ) [ ] { } /`. Other lookarounds
|
|
103
|
+
remain refused. Plain `L`, `^L`, `^L$` and `L$` are unchanged. Syntax retains the
|
|
104
|
+
original text, while binding stores the ordinal rule. Old ESM evaluates these exact
|
|
105
|
+
patterns as replacements without changing bytes. The editor quick fix and MCP
|
|
106
|
+
`propose-repair` migrate to literal rules preserving message/severity; preview the
|
|
107
|
+
revision-bound canonical-formatting proposal before explicit apply.
|
|
108
|
+
|
|
109
|
+
C#: `Cratis.Screenplay.Semantics.PortableMatchPattern.Check(pattern)`.
|
|
110
|
+
TypeScript: import `checkPortableMatchPattern` from `@cratis/screenplay-compiler`.
|
|
111
|
+
Both return PortableMatchCheck: status, code, construct, UTF-16 offset in the decoded
|
|
112
|
+
pattern, suggestion, description and optional replacement `{ kind, value }`.
|
|
113
|
+
Statuses are Admitted, Deprecated, Refused, Invalid (lowercase strings in TypeScript).
|
|
114
|
+
Admitted has no code; Deprecated is PLAY0787, Refused PLAY0699, Invalid PLAY0367.
|
|
115
|
+
Replacement kinds are Equal, NotEqual, Contains, NotContains, StartsWith, EndsWith.
|
|
116
|
+
Checking never executes a pattern or constructs a platform regex.
|
|
117
|
+
|
|
118
|
+
Validate with `screenplay <root> --warnaserror`, then execute acceptance/refusal
|
|
119
|
+
examples through `screenplay test <root>`; source validation alone is not a rule test.
|
package/package/corpus/skills/cratis-screenplay-command-surface/references/validate-rules.md
CHANGED
|
@@ -10,9 +10,28 @@
|
|
|
10
10
|
| `== <v>` / `!= <v>` | `currency == "NOK"`, `status != draft` |
|
|
11
11
|
| `length == <n>` | `currency length == 3` |
|
|
12
12
|
| `matches email` | the only named pattern; any other name is `PLAY0366` |
|
|
13
|
-
| `matches "<regex>"` |
|
|
13
|
+
| `matches "<regex>"` | Portable linear dialect; any substring unless anchored `^…$`; invalid syntax PLAY0367, refused constructs PLAY0699 |
|
|
14
|
+
| `contains "<text>"` / `not contains "<text>"` | Ordinal substring presence/absence on scalar non-enum text |
|
|
15
|
+
| `starts with "<text>"` / `ends with "<text>"` | Ordinal prefix/suffix; quoted literal operands, not conditions |
|
|
14
16
|
| `all > <v>` / `all >= <v>` | `lines.quantity all > 0` |
|
|
15
17
|
| `rule <Name>` | `orgNumber rule BeAValidOrganizationNumber` |
|
|
18
|
+
| `checksum luhn|mod11|mod97` | String concept `validate checksum luhn`; validates supplied/stored values too |
|
|
19
|
+
|
|
20
|
+
Requires Screenplay 4.172.0 or later (`screenplay --version`) for checksum rules
|
|
21
|
+
(ESM v21); older compilers refuse them with PLAY0268. A pattern's `checksum`
|
|
22
|
+
modifier generates check digits but does not add validation. Check digits catch
|
|
23
|
+
typos, not forgery. For generated-concept proof statuses, deterministic regex
|
|
24
|
+
limits and PLAY0688 repairs, read [generated rules](generated-values-and-responses.md#generated-concept-rules-esm-v20).
|
|
25
|
+
|
|
26
|
+
## Date and DateTime comparisons
|
|
27
|
+
|
|
28
|
+
Requires Screenplay 4.199.0 (ESM v26; `screenplay --version`); older binders refuse
|
|
29
|
+
with PLAY0268. Command/property rules admit `==`, `!=`, `>`, `>=`, `<`, `<=` against
|
|
30
|
+
a same-primitive date literal only, for example `to >= "2026-01-01T00:00:00Z"` on
|
|
31
|
+
DateTime. Property-to-property comparisons instead use `require to >= from`.
|
|
32
|
+
Date rules on concepts remain refused; an absent optional value passes rules
|
|
33
|
+
except `not empty`. Read [date comparisons](date-comparisons.md) for UTC ticks,
|
|
34
|
+
input offsets, refused positions and the complete retention-window specifications.
|
|
16
35
|
|
|
17
36
|
## `not empty` means non-blank text
|
|
18
37
|
|
|
@@ -60,10 +79,11 @@ validate
|
|
|
60
79
|
|
|
61
80
|
A bodied rule or fenced block on a validation, rule or policy binds as opaque code
|
|
62
81
|
(ESM v3): the reference runner reports it unsupported, and a target must supply the
|
|
63
|
-
implementation.
|
|
64
|
-
|
|
65
|
-
|
|
82
|
+
implementation. Attached command handlers and `file` constraints remain PLAY0268
|
|
83
|
+
(only `unique` constraints bind). Pending command handlers beside unconditional
|
|
84
|
+
`produces` instead bind as described commands; see [described handlers](described-handlers.md).
|
|
85
|
+
Literal text rules, portable patterns and Studio desugaring: [text and match rules](text-and-match-rules.md).
|
|
66
86
|
Stage renders pure reducer transitions and opaque policy bodies, but refuses command and
|
|
67
87
|
concept code validations and rule predicates (STAGE-ESM-005): those are gap-fill code. Prefer a
|
|
68
|
-
declarative rule when one can say it. What binds and what the executable model rejects
|
|
69
|
-
|
|
88
|
+
declarative rule when one can say it. What binds and what the executable model rejects
|
|
89
|
+
(date comparisons outside command positions, nested-path rules): `cratis-screenplay-toolchain` `references/executable-subset.md`.
|
|
@@ -4,6 +4,14 @@
|
|
|
4
4
|
"fixtures": [],
|
|
5
5
|
"assertions": [
|
|
6
6
|
{ "kind": "play-compiles" },
|
|
7
|
+
{ "kind": "skill-contains", "value": "require to >= from", "file": "references/date-comparisons.md" },
|
|
8
|
+
{ "kind": "skill-contains", "value": "RejectingAMissingOffset", "file": "references/date-comparisons.md" },
|
|
9
|
+
{ "kind": "skill-contains", "value": "STAGE-ESM-016", "file": "references/date-comparisons.md" },
|
|
10
|
+
{ "kind": "skill-contains", "value": "Unsupported (`ImplementationBody`)", "file": "references/described-handlers.md" },
|
|
11
|
+
{ "kind": "skill-contains", "value": "including Stub mode", "file": "references/described-handlers.md" },
|
|
12
|
+
{ "kind": "skill-contains", "value": "DecisionStateChanged", "file": "references/protected-reads.md" },
|
|
13
|
+
{ "kind": "skill-contains", "value": "checkPortableMatchPattern", "file": "references/text-and-match-rules.md" },
|
|
14
|
+
{ "kind": "skill-contains", "value": "U+00A0", "file": "references/text-and-match-rules.md" },
|
|
7
15
|
{ "kind": "skill-contains", "value": "screenplay_declaration_details", "file": "references/generated-values-and-responses.md" },
|
|
8
16
|
{ "kind": "skill-contains", "value": "do not hand-edit the text", "file": "references/generated-values-and-responses.md" },
|
|
9
17
|
{ "kind": "skill-contains", "value": "A CLI-bundled MCP can lack this summary", "file": "references/generated-values-and-responses.md" },
|
|
@@ -42,7 +50,7 @@
|
|
|
42
50
|
},
|
|
43
51
|
{
|
|
44
52
|
"kind": "skill-contains",
|
|
45
|
-
"value": "
|
|
53
|
+
"value": "A file/code `handler` cannot coexist with `produces`"
|
|
46
54
|
},
|
|
47
55
|
{
|
|
48
56
|
"kind": "skill-contains",
|
|
@@ -54,11 +62,11 @@
|
|
|
54
62
|
},
|
|
55
63
|
{
|
|
56
64
|
"kind": "skill-contains",
|
|
57
|
-
"value": "
|
|
65
|
+
"value": "command reads protected"
|
|
58
66
|
},
|
|
59
67
|
{
|
|
60
68
|
"kind": "skill-contains",
|
|
61
|
-
"value": "
|
|
69
|
+
"value": "reads/concurrency cannot combine (PLAY0783)"
|
|
62
70
|
},
|
|
63
71
|
{
|
|
64
72
|
"kind": "skill-contains",
|
|
@@ -93,6 +101,8 @@
|
|
|
93
101
|
"value": "Generated identifiers need Uuid or String backing and at least 64 random bits.", "file": "references/generated-values-and-responses.md"
|
|
94
102
|
},
|
|
95
103
|
{ "kind": "skill-contains", "value": "Generated values and responses (ESM v7 and v15)" },
|
|
104
|
+
{ "kind": "skill-contains", "value": "names that can match together report PLAY0367", "file": "references/text-and-match-rules.md" },
|
|
105
|
+
{ "kind": "skill-contains", "value": "or reaction `where` remain PLAY0268", "file": "references/text-and-match-rules.md" },
|
|
96
106
|
{ "kind": "skill-contains", "value": "Generated values are not request inputs", "file": "references/generated-values-and-responses.md" },
|
|
97
107
|
{ "kind": "skill-contains", "value": "Generated-concept validation rules select ESM v20", "file": "references/generated-values-and-responses.md" },
|
|
98
108
|
{ "kind": "skill-contains", "value": "PLAY0688 and a violating example", "file": "references/generated-values-and-responses.md" },
|
|
@@ -108,7 +108,7 @@ The independent verdicts V1 to V5 that report them are in
|
|
|
108
108
|
`cratis-screenplay-modeling-lifecycle`.
|
|
109
109
|
|
|
110
110
|
What binds depends on **which tool** you ask, so name the tool and its version:
|
|
111
|
-
Read [references/parsed-not-runnable.md](references/parsed-not-runnable.md) (section "What binds depends on which tool") when stating what a tool binds or renders (`
|
|
111
|
+
Read [references/parsed-not-runnable.md](references/parsed-not-runnable.md) (section "What binds depends on which tool") when stating what a tool binds or renders (legacy reads and `concurrency` fail with `PLAY0271`; protected command reads opt into v25; `persona` declarations are report-only; an older bundle reports *Slice '<name>' of type '<type>' is not admitted by ESM v1.*).
|
|
112
112
|
|
|
113
113
|
The ESM versions, the full disposition table and the Step 7 clock example's binding
|
|
114
114
|
result are in [references/parsed-not-runnable.md](references/parsed-not-runnable.md)
|
|
@@ -169,19 +169,19 @@ compile or will not be safe. Both are deliberate.
|
|
|
169
169
|
|
|
170
170
|
- **A command may read state.** The generic method forbids `ReadModel -> Command`
|
|
171
171
|
edges. Screenplay ships `reads <ReadModel> [as <alias>] [by <property>]` so the
|
|
172
|
-
model shows what a state-dependent decision consulted.
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
172
|
+
model shows what a state-dependent decision consulted. Application-root
|
|
173
|
+
`command reads protected` admits eligible command reads as v25: absent state
|
|
174
|
+
rejects and matching decide/commit changes conflict. Read
|
|
175
|
+
[protected reads](../cratis-screenplay-command-surface/references/protected-reads.md)
|
|
176
|
+
for the strict shape and paths. Legacy reads remain PLAY0271; `concurrency` is
|
|
177
|
+
not protection and cannot combine with protected reads. Stage refuses protected reads
|
|
178
|
+
(STAGE-ESM-044), not v25 itself: name target enforcement separately rather than claiming a render.
|
|
179
|
+
Write state-dependent rules as `reads` plus `require` with an indented message;
|
|
180
|
+
mark refused shapes as unenforced and name the intended target mechanism. Model uniqueness as a `unique` constraint. Never copy state into a
|
|
181
181
|
command input, add an attestation flag, or hide the rule in `handler` prose. Do not
|
|
182
182
|
use `reads` to fetch data the command could carry as input. A reaction trigger
|
|
183
|
-
declares
|
|
184
|
-
|
|
183
|
+
declares consulted views with `reads`, but trigger reads remain unprotected;
|
|
184
|
+
decide in an invoked command instead.
|
|
185
185
|
- **Some validation *does* belong in the model.** The generic method routes format
|
|
186
186
|
rules to the type system. Screenplay's type system *is* the `concept`, and a
|
|
187
187
|
concept carries its own `validate` block - so a format rule lives on the concept
|
package/package/corpus/skills/cratis-screenplay-event-modeling/references/parsed-not-runnable.md
CHANGED
|
@@ -34,7 +34,7 @@ Tool versions and consumer boundaries: toolchain `SKILL.md`.
|
|
|
34
34
|
| Compliance concepts | Bare `pii`/`personal` and `secret`, qualifiers and scope bind as v13; enum/identity compliance and events combining personal or explicitly subject-scoped secret values with an explicit `subject` mark refuse PLAY0268 at binding only. A CLI bundle that admits v13 binds markers; Stage renders v13 protection, not protected identities/enums or subject lineage. Never remove protection |
|
|
35
35
|
| Identity details / processing purposes / event subject | Report-only metadata; executable detail reads refuse PLAY0268, not source declaration errors |
|
|
36
36
|
| Composite stream ids | v8 routing; complete named parts/canonical comparisons, PLAY0515 refuses protected keys/sources; not a legacy text split |
|
|
37
|
-
| Command reads/concurrency |
|
|
37
|
+
| Command reads/concurrency | Eligible reads opt into v25 with `command reads protected`; legacy reads/concurrency retain PLAY0271; Stage refuses protected reads (STAGE-ESM-044), not the v25 pair |
|
|
38
38
|
| Invokes-only trigger reads | Report-only, not protected state; direct production with reads refuses |
|
|
39
39
|
| Generated values/responses | v7 binding/reference execution; v15 strategies/strict fixtures/freshness. Stage renders supported UUID/String strategies, responses and fixtures; unsupported types/combinations remain -028/-038 |
|
|
40
40
|
| Sources/streams and command/specification routes | v8 binding/reference execution; the CLI (toolchain `references/renderable-subset.md`) reaches Stage checks through its bundled ceiling (v16 without v17 support) |
|
|
@@ -70,8 +70,10 @@ accepted proposal or parsed node with a running application.
|
|
|
70
70
|
- `Automation` and `Translate` slices, reactions, captures and triggers bind (ESM v6) on the
|
|
71
71
|
standalone tool and a CLI bundle that admits v6. (An older bundle
|
|
72
72
|
reports *Slice '<name>' of type '<type>' is not admitted by ESM v1.*) Stage renders supported event-triggered Automation, not Translate/captures or non-event triggers.
|
|
73
|
-
-
|
|
74
|
-
|
|
73
|
+
- Eligible command reads bind/reference-execute with `command reads protected`
|
|
74
|
+
(v25); legacy reads and `concurrency` remain PLAY0271. Read command-surface
|
|
75
|
+
[protected reads](../../cratis-screenplay-command-surface/references/protected-reads.md)
|
|
76
|
+
for admission, absence/conflicts and Stage refusal. A reaction trigger's `reads` that only `invokes` is
|
|
75
77
|
report-only intent (`PLAY0270`); one that `produces` directly fails binding (`PLAY0268`).
|
|
76
78
|
- `persona` declarations are report-only and never block; bare `pii` and `secret`
|
|
77
79
|
concepts bind as ESM v13 (Requires Screenplay 4.141.0 or later); Stage renders admitted v13 protection.
|
|
@@ -137,8 +137,8 @@ chain per slice before handoff (`references/evidence-table-template.md`, "Tracea
|
|
|
137
137
|
- one StateChange per decision a person or system makes; events are facts experts recognise;
|
|
138
138
|
consequences (counters, denormalised copies) become projections; an automation only when
|
|
139
139
|
evidence shows a separate decision; no generic names (`Update/Edit/Save<Noun>`, `<Noun>Updated`): split by intent;
|
|
140
|
-
- refusals, state-dependent rules (`reads` + `require
|
|
141
|
-
|
|
140
|
+
- refusals, state-dependent rules (`reads` + `require` with eligible protected-read
|
|
141
|
+
opt-in; legacy/refused shapes marked unenforced and target realization named), unique indexes and preserved `pii` / `secret` protection:
|
|
142
142
|
`references/rule-modeling.md`. Every role gate has `authorize` plus a `then denied` spec,
|
|
143
143
|
else a recorded gap; rules you cannot express truthfully are recorded one by one, never
|
|
144
144
|
fabricated.
|
|
@@ -57,7 +57,7 @@ Example rows:
|
|
|
57
57
|
| id | source | locator | observed fact | technical shape | strength | classification | gen. disposition | candidate | decision | decided by | verdict |
|
|
58
58
|
|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
59
59
|
| E1 | dynamic | capture 0007, `POST /api/checkins` | taking in a coat writes two tables | insert `Checkins`; update `Hooks(occupied)`; 201 x41, 409 x3 | Observed | intent (take in) + consequence (hook) | n/a | `TakeInCoat` -> `CoatTakenIn`; occupancy via projection | change | proposed | not asked |
|
|
60
|
-
| E2 | code | `CheckinService.cs` | 409 when the hook is already free, message "That coat is not on a hook" | throws `ConflictException` | Read | intent (rule) | n/a | `reads CoatStatus` + `require
|
|
60
|
+
| E2 | code | `CheckinService.cs` | 409 when the hook is already free, message "That coat is not on a hook" | throws `ConflictException` | Read | intent (rule) | n/a | legacy control: `reads CoatStatus` + `require` without protected opt-in; inspect v25 admission, record refused shape/Stage target gap in LOSS.md | keep | proposed | not asked |
|
|
61
61
|
| E3 | static | `static.play`, SP0016 at `CheckinValidator` | validation rule held to a condition is emitted unconditionally; the condition is lost | `When(x => x.IsVip)` | Exact (loss) | unknown | Lowered without its condition (semantic mismatch, reported by SP0016) | none yet | undecided | - | question Q4: when does the rule really apply? read `CheckinValidator` and ask an expert |
|
|
62
62
|
| E4 | dynamic | uncorrelated txn, `Hooks` nightly 02:00 | hook flags reset without a command | update `Hooks(*)` daily | Observed | unexplained | n/a | none | undecided | - | question Q5 |
|
|
63
63
|
|