@cratis/pi 7.124.0 → 7.125.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.
Files changed (28) hide show
  1. package/package/corpus/agents/spec-writer.md +1 -1
  2. package/package/corpus/harnesses/copilot/instructions/application-profile.instructions.md +1 -1
  3. package/package/corpus/harnesses/copilot/instructions/framework.instructions.md +1 -0
  4. package/package/corpus/harnesses/copilot/instructions/specs.csharp.instructions.md +1 -1
  5. package/package/corpus/harnesses/copilot/instructions/specs.scenarios.csharp.instructions.md +4 -4
  6. package/package/corpus/harnesses/copilot/instructions/verification-discipline.instructions.md +1 -0
  7. package/package/corpus/harnesses/copilot/instructions/vertical-slices.instructions.md +1 -1
  8. package/package/corpus/harnesses/pi/agents/spec-writer.md +1 -1
  9. package/package/corpus/rules/application-profile.md +1 -1
  10. package/package/corpus/rules/framework.md +1 -0
  11. package/package/corpus/rules/general.md +2 -1
  12. package/package/corpus/rules/specs.csharp.md +1 -1
  13. package/package/corpus/rules/specs.scenarios.csharp.md +4 -4
  14. package/package/corpus/rules/verification-discipline.md +1 -0
  15. package/package/corpus/rules/vertical-slices.md +1 -1
  16. package/package/corpus/skills/cratis-application-slice-specifications/SKILL.md +5 -4
  17. package/package/corpus/skills/cratis-application-slice-specifications/references/query-and-decision-scenarios.md +14 -16
  18. package/package/corpus/skills/cratis-arc-command/SKILL.md +1 -1
  19. package/package/corpus/skills/cratis-arc-command/references/decisions-and-routing.md +13 -7
  20. package/package/corpus/skills/cratis-arc-command-validation/SKILL.md +3 -3
  21. package/package/corpus/skills/cratis-chronicle-decision-reads/SKILL.md +2 -2
  22. package/package/corpus/skills/cratis-chronicle-decision-reads/references/choosing-how-a-rule-holds.md +5 -6
  23. package/package/corpus/skills/cratis-ci-pipeline-performance/SKILL.md +8 -4
  24. package/package/corpus/skills/cratis-ci-pipeline-performance/references/test-setup-cost.md +15 -0
  25. package/package/corpus/skills/cratis-specifications-csharp/SKILL.md +2 -3
  26. package/package/corpus/skills/cratis-specifications-csharp/references/application-scenarios.md +4 -4
  27. package/package/corpus/skills/cratis-specifications-csharp/references/running-specs.md +1 -1
  28. package/package.json +1 -1
@@ -94,7 +94,7 @@ public class and_all_information_is_valid : Specification
94
94
 
95
95
  ### What to specify
96
96
 
97
- 0. **Every contract specification first** — one spec each, named after it, using the contract's example values. Then add the code-derived cases below that the contract lacks and report them as proposals for the contract (the `.play` model when one covers the slice, otherwise the agreed outline); never present them as contract coverage. A `.play` specification maps to a plain-call spec for a pure decision, with a scenario added only for the composition or application-owned race policy it proves; never edit, skip or delete a spec derived from the contract to make code pass — change the code or return an edit request.
97
+ 0. **Every contract specification first** — one spec each, named after it, using the contract's example values. Then add the code-derived cases below that the contract lacks and report them as proposals for the contract (the `.play` model when one covers the slice, otherwise the agreed outline); never present them as contract coverage. A `.play` specification maps to a plain-call spec for a pure decision, with a scenario added only for the pipeline composition it proves (never a simulated race); never edit, skip or delete a spec derived from the contract to make code pass — change the code or return an edit request.
98
98
  1. **Happy path** — succeeds, correct event(s) appended.
99
99
  2. **Each validation failure** — call the validator directly with supplied state; pipeline validation specs assert **both** `ShouldNotBeSuccessful()` and `ShouldHaveValidationErrors()`. Do not assert on message strings by default; assert exact text only when that wording is the specified behavior, and name that behavior in the fact. Violate **only** the rule the spec is named after (build the command valid in every other respect), or a neighbouring rule makes it pass.
100
100
  3. **Business-rule violations** — call `Handle()` or the validator directly with the required model state and assert each rejection. Arc/Chronicle specs alone prove platform concurrency, conflict refusal and isolation. The application's only decision-read spec obligation is the single cheap shape-admission spec in `specs.scenarios.csharp.md`; do not repeat guard scenarios per decision.
@@ -74,7 +74,7 @@ Tagged **[contract]** (framework-enforced) or **[convention]** (house default).
74
74
  3. **Code level** — infrastructure (hosting, DI composition, identity wiring, CI, deployment), clients, Screenplay code attachments and handlers, adapters in the render's customization area, and scope Stage cannot render yet (the model remains the contract). Framework repositories and brownfield work that is not opted in also stay code-first. Only the entry-point session may propose a model, at most once per session and never for trivial, bug-fix, infrastructure, client, framework or brownfield-maintenance work; if declined, do not ask again. Confirm Module/Feature, slice name, slice type and domain requirements as before; for new behavior or unclear event vocabulary run **cratis-chronicle-event-modeling** first, and record the agreed outline (fields, events, rules, scenarios) where the team tracks work, if anywhere. If you write code first where a model exists, say the model now lags.
75
75
  4. **Trivial changes** keep the proportional-delegation policy; Phases 1–3 below apply to code you write at either level.
76
76
  - **Phase 1 — Backend.** Implement a coherent slice change. **Gate:** incremental Debug build of the affected project (regenerates proxies, compiles `#if DEBUG` spec code).
77
- - **Phase 2 — Specs.** Mandatory for every slice type. Start with plain calls for pure command/validator/reducer decisions with supplied read-model state; add scenarios only for pipeline/authorization wiring, constraints, declarative mapping or application-owned race policies. Follow [specs.scenarios.csharp.md](./specs.scenarios.csharp.instructions.md) for shared setup and cost budgets. **Gate:** tests pass.
77
+ - **Phase 2 — Specs.** Mandatory for every slice type. Start with plain calls for pure command/validator/reducer decisions with supplied read-model state; add scenarios only for pipeline/authorization wiring, constraints or declarative mapping. Follow [specs.scenarios.csharp.md](./specs.scenarios.csharp.instructions.md) for shared setup and cost budgets. **Gate:** tests pass.
78
78
  - **Phase 3 — Frontend.** Build from the generated proxies, register in the composition page, wire routing. **Gate:** lint, conditional test, build.
79
79
 
80
80
  **Backend before frontend, always** — the frontend depends on proxies that exist only after a successful build. Generate proxies from the **Debug** build (house convention); verify Release without re-running the generator: `dotnet build -c Release -p:CratisProxiesOutputPath=`. Why that property, and what to do when nothing is generated: the **cratis-arc-command** skill's proxy-generation reference.
@@ -50,6 +50,7 @@ Repo conventions follow from this: `Source/DotNET` + `Source/JavaScript` for dua
50
50
  - **Backward compatibility is a contract.** A change to a public type, attribute, interface, or generated-proxy shape is a breaking change for every downstream app — label PRs by semver impact (`major`/`minor`/`patch`) and treat removals/renames of public surface as `major`.
51
51
  - **Convention discovery is built here.** `IInstancesOf<T>` / `IImplementationsOf<T>`, attribute-based discovery, and source generation are the mechanisms the framework *provides*; use them internally too rather than hand-registration where a convention fits. A Fundamentals project reference does not carry the type-discovery analyzer like its NuGet package does: reference `Fundamentals.TypeDiscovery.Generator` explicitly, or your project's types may be absent from the generated universe.
52
52
  - **Source generators / analyzers** (Arc's proxy generator, Fundamentals) follow Roslyn conventions; their output is consumed verbatim by apps, so treat generated shape as public API.
53
+ - **Analyzers and generators are written for speed** (fast feedback is a product requirement): incremental generators only; a syntactic prefilter (name or kind) before any semantic bind; compute shared evidence once per compilation, never once per analyzer or per symbol; touch it only after cheap relevance checks; never rebind every call site of the compilation. Each expensive analyzer gets a performance spec.
53
54
  - **Orleans grains** in the Chronicle kernel follow `orleans.md`.
54
55
  - **An alternate implementation of an interface must match the primary one's *semantics*, not just its signature.** Chronicle ships several implementations of the same storage interfaces (MongoDB, SQL, in-memory) and the in-memory ones exist precisely so the real kernel code paths can run without infrastructure. When you touch one, **diff it against the persistent implementations** — the signature tells you nothing about the contract. The specific trap: query criteria carry **sentinels meaning "do not narrow"** (`EventSourceId.Unspecified`, `EventSourceType.Unspecified`/`Default`, `EventStreamType.All`, `EventStreamId.Default`, an empty event-type set). Callers asking for "everything" pass those sentinels, never `null`, so a plain `is not null` check narrows every row away and the read silently returns nothing. A divergence here does not fail — it makes specs pass vacuously, which is worse.
55
56
  - **A stub that silently succeeds is a bug, not a placeholder.** An unimplemented method returning `Task.CompletedTask`/an empty result lets a spec assert on work that never happened. Implement it, or make it fail loudly — never leave it quietly lying.
@@ -12,7 +12,7 @@ Extends the base [specs.md](./specs.instructions.md) (folder structure, naming,
12
12
 
13
13
  > **Which spec surface?**
14
14
  > - **Framework / library code** (Chronicle kernel, Arc pipeline, source generators, Fundamentals): the `Specification` base + NSubstitute in this file is the dominant mode — unit-test the classes under test in isolation. Reach for a `*Scenario` helper (in [specs.scenarios.csharp.md](./specs.scenarios.csharp.instructions.md)) **only** when testing the very engine your repo provides — Arc → `CommandScenario`, Chronicle → the event/projection/reactor scenarios. The **cratis-application-slice-specifications** skill is application-oriented, not for general framework specs.
15
- > - **Event-sourced applications on Cratis** (commands, projections, reducers, reactors, constraints): use this base plus a direct call by default for pure `Handle()`, validator and reducer decisions with supplied read-model state; add scenarios only for pipeline/authorization wiring, constraints, declarative projections or application-owned race policies — see **[specs.scenarios.csharp.md](./specs.scenarios.csharp.instructions.md)** (`profile: application`) and the **cratis-application-slice-specifications** skill.
15
+ > - **Event-sourced applications on Cratis** (commands, projections, reducers, reactors, constraints): use this base plus a direct call by default for pure `Handle()`, validator and reducer decisions with supplied read-model state; add scenarios only for pipeline/authorization wiring, constraints or declarative projections — see **[specs.scenarios.csharp.md](./specs.scenarios.csharp.instructions.md)** (`profile: application`) and the **cratis-application-slice-specifications** skill.
16
16
 
17
17
  `Cratis.Specifications` keeps the approach of Machine.Specifications (MSpec): `Establish → Because → should_` maps to "Given → When → Then" and keeps each spec focused on *one setup, one action, one set of assertions*.
18
18
 
@@ -15,16 +15,16 @@ Specs are **mandatory for every slice type**, including reactors.
15
15
 
16
16
  ## Start with the plain call; add a scenario where it adds proof
17
17
 
18
- **Judgment-shaped convention:** call pure `Handle()`, validators, reducers and reactor decisions directly with their inputs, including read-model state. Add a scenario only for pipeline/authorization wiring, constraints, declarative projection mapping or an application-owned race policy. Do not repeat every decision through the pipeline; name the extra behavior each scenario proves.
18
+ **Judgment-shaped convention:** call pure `Handle()`, validators, reducers and reactor decisions directly with their inputs, including read-model state. Add a scenario only for pipeline/authorization wiring, constraints or declarative projection mapping. Do not repeat every decision through the pipeline; name the extra behavior each scenario proves.
19
19
 
20
- **Application specs supply state, not decision-read infrastructure.** Call `Handle()` or the validator directly with supplied read-model state. Never call `UseDecisionReads`, configure protection modes, seed events solely for infrastructure, or re-prove the platform's concurrency, conflict-refusal or isolation matrix; Arc/Chronicle specs own it. The application's **only decision-read spec obligation** is one cheap assembly-level shape-admission spec: `DecisionReadAdmissions.ShouldAdmitDecisionReadsIn(assembly)` (`Cratis.Arc.Chronicle.Testing.Commands`). It checks the application's own models/projections without executing commands or running Chronicle, not the platform guards. An application-owned race policy may justify a scenario; assert its business outcome. Report harness state-setup gaps upstream; never weaken production guards for test speed.
20
+ **Application specs supply state, not decision-read infrastructure.** Call `Handle()` or the validator directly with supplied read-model state. Never call `UseDecisionReads`, configure protection modes, seed events solely for infrastructure, or re-prove the platform's concurrency, conflict-refusal or isolation matrix; Arc/Chronicle specs own it. The application's **only decision-read spec obligation** is one cheap assembly-level shape-admission spec: `DecisionReadAdmissions.ShouldAdmitDecisionReadsIn(assembly)` (`Cratis.Arc.Chronicle.Testing.Commands`). It checks the application's own models/projections without executing commands or running Chronicle, not the platform guards. Never simulate competing appends either (`AppendConcurrently` or any hand-built interleaving): concurrency is a framework concern a developer should not think about in tests, and Arc and Chronicle specs prove it. A rule that must hold under races is expressed in production by taking the read model as a `Handle` parameter under `[ReadProtection(On)]`; the spec gives that read model's state and asserts the outcome. Report harness state gaps upstream; never weaken production guards for speed. `AppendConcurrently` is an advanced framework-verification API: use only for an explicit need. Direction, no release claim: Arc will obsolete `UseDecisionReads`.
21
21
 
22
22
  **Share setup and budget cost (judgment-shaped).** Keep shared lifecycle on; use `[PerFactSpecificationLifecycle]` only on a class whose facts genuinely mutate shared state and cannot move that mutation into `Because`. Plain decision specs should take roughly milliseconds; measure scenario facts and justify seconds by the extra behavior they prove. Compare TRX durations and suite wall time with unchanged concurrency; see [running-specs.md](../../../skills/cratis-specifications-csharp/references/running-specs.md). Do not multiply scenario startup by splitting assertions into classes or opting the project out of shared lifecycle.
23
23
 
24
24
  | Tool | Tests | Use when |
25
25
  |---|---|---|
26
26
  | `Specification` (plain call) | `Handle()`, `Handle(providedValue)`, validator/reducer logic or a reactor's decision as a method call; or an isolated class with mocked collaborators | **default** for a decision that is a pure function of its arguments |
27
- | `CommandScenario<TCommand>` | the real Arc command pipeline — authorization + validators + `Provide()` + `Handle()` + appended events | pipeline wiring, authorization, constraints or an application-owned race policy adds proof |
27
+ | `CommandScenario<TCommand>` | the real Arc command pipeline — authorization + validators + `Provide()` + `Handle()` + appended events | pipeline wiring, authorization or constraints adds proof |
28
28
  | `QueryScenario<TReadModel>` | query pipeline: argument conversion, authorization, validation, interceptors; `Observe` buffers emissions | query composition matters; real MongoDB observations still need infrastructure |
29
29
  | `EventScenario` | Chronicle-level append semantics, no command pipeline | constraint violations, raw stream sequencing/concurrency |
30
30
  | `ReadModelScenario<TReadModel>` | projection/reducer state from a sequence of events (auto-detects model-bound / fluent / reducer) | one class per read model, many read-only assertions on shared setup |
@@ -121,7 +121,7 @@ arguments?, paging?, sorting?)`; `Observe(...)` returns `QueryObservation.Initia
121
121
  and buffered `Next()`. Configure principal/policies in `Services`; schemes fail
122
122
  closed without HTTP. Chronicle query `Given` can seed keyed models/events.
123
123
 
124
- For query setup and application-owned race policies, see **cratis-application-slice-specifications**,
124
+ For query setup, see **cratis-application-slice-specifications**,
125
125
  `references/query-and-decision-scenarios.md`. Framework read-protection guards are not application spec obligations.
126
126
 
127
127
  ### `EventScenario` — constraints & append semantics
@@ -14,6 +14,7 @@ authored a file or preserve a chain of evidence about how it arrived.
14
14
  - Run one phase per command with its real exit status. Budget targeted checks around 120 seconds and build/test phases around 300 seconds; explain any longer budget first, and obtain explicit approval before a phase exceeds 600 seconds. Stop on a failure; do not blindly retry or repeat passing tests on unchanged inputs without a flaky-test hypothesis or required matrix.
15
15
  - Separate status/fetch from builds, Debug from Release, each test project, and frontend lint/compile/test/build. Do not combine these into an opaque command with a large outer timeout. Expose progress and cancellation; report the precise failed or timed-out phase and do not continue dependent phases after failure.
16
16
  - Never use `build/test | grep | sort/head/tail` as gate evidence. Capture the producer's exit status before summarising output; `pipefail` alone is insufficient with early-closing consumers such as `head`. Printed zero-error counts are not proof of success. Preserve needed full diagnostics in task-scoped `.ai-work/` logs rather than hiding them in `/tmp`.
17
+ - Fast feedback is a product requirement: a spec takes milliseconds, the suite seconds; specs share setup and run in parallel; analyzers must not halt builds. CI builds the spec path without analyzers and enforces them, warnings as errors, in a parallel required job; the pre-push gate runs them. A slowdown is a defect.
17
18
  - Add a focused specification for every behavior or rejection rule you change.
18
19
  - Keep each check deterministic and runnable locally and in CI.
19
20
  - Never replace a real behavior check with a checksum, inventory, generated
@@ -21,7 +21,7 @@ This file is the reference for *what* goes in each part of a slice. Layout, slic
21
21
 
22
22
  - .NET / C# (ASP.NET Core) — **Cratis Arc** for CQRS / model-bound commands and queries, **Cratis Chronicle** for event sourcing, MongoDB or EF Core for read models.
23
23
  - React + TypeScript (Vite) — Cratis Components 4.x + Arc-generated proxies, MVVM. Vitest + Mocha/Chai/Sinon for frontend specs.
24
- - xUnit + Cratis.Specifications + NSubstitute for C# specs (`Specification` plus a direct call for pure command/validator/reducer decisions with supplied state; add scenarios only for pipeline/authorization wiring, constraints, declarative projections or application-owned race policies — see [specs.md](./specs.instructions.md)).
24
+ - xUnit + Cratis.Specifications + NSubstitute for C# specs (`Specification` plus a direct call for pure command/validator/reducer decisions with supplied state; add scenarios only for pipeline/authorization wiring, constraints or declarative projections — see [specs.md](./specs.instructions.md)).
25
25
 
26
26
  ## Proxy generation — the build dependency
27
27
 
@@ -89,7 +89,7 @@ public class and_all_information_is_valid : Specification
89
89
 
90
90
  ### What to specify
91
91
 
92
- 0. **Every contract specification first** — one spec each, named after it, using the contract's example values. Then add the code-derived cases below that the contract lacks and report them as proposals for the contract (the `.play` model when one covers the slice, otherwise the agreed outline); never present them as contract coverage. A `.play` specification maps to a plain-call spec for a pure decision, with a scenario added only for the composition or application-owned race policy it proves; never edit, skip or delete a spec derived from the contract to make code pass — change the code or return an edit request.
92
+ 0. **Every contract specification first** — one spec each, named after it, using the contract's example values. Then add the code-derived cases below that the contract lacks and report them as proposals for the contract (the `.play` model when one covers the slice, otherwise the agreed outline); never present them as contract coverage. A `.play` specification maps to a plain-call spec for a pure decision, with a scenario added only for the pipeline composition it proves (never a simulated race); never edit, skip or delete a spec derived from the contract to make code pass — change the code or return an edit request.
93
93
  1. **Happy path** — succeeds, correct event(s) appended.
94
94
  2. **Each validation failure** — call the validator directly with supplied state; pipeline validation specs assert **both** `ShouldNotBeSuccessful()` and `ShouldHaveValidationErrors()`. Do not assert on message strings by default; assert exact text only when that wording is the specified behavior, and name that behavior in the fact. Violate **only** the rule the spec is named after (build the command valid in every other respect), or a neighbouring rule makes it pass.
95
95
  3. **Business-rule violations** — call `Handle()` or the validator directly with the required model state and assert each rejection. Arc/Chronicle specs alone prove platform concurrency, conflict refusal and isolation. The application's only decision-read spec obligation is the single cheap shape-admission spec in `specs.scenarios.csharp.md`; do not repeat guard scenarios per decision.
@@ -73,7 +73,7 @@ Tagged **[contract]** (framework-enforced) or **[convention]** (house default).
73
73
  3. **Code level** — infrastructure (hosting, DI composition, identity wiring, CI, deployment), clients, Screenplay code attachments and handlers, adapters in the render's customization area, and scope Stage cannot render yet (the model remains the contract). Framework repositories and brownfield work that is not opted in also stay code-first. Only the entry-point session may propose a model, at most once per session and never for trivial, bug-fix, infrastructure, client, framework or brownfield-maintenance work; if declined, do not ask again. Confirm Module/Feature, slice name, slice type and domain requirements as before; for new behavior or unclear event vocabulary run **cratis-chronicle-event-modeling** first, and record the agreed outline (fields, events, rules, scenarios) where the team tracks work, if anywhere. If you write code first where a model exists, say the model now lags.
74
74
  4. **Trivial changes** keep the proportional-delegation policy; Phases 1–3 below apply to code you write at either level.
75
75
  - **Phase 1 — Backend.** Implement a coherent slice change. **Gate:** incremental Debug build of the affected project (regenerates proxies, compiles `#if DEBUG` spec code).
76
- - **Phase 2 — Specs.** Mandatory for every slice type. Start with plain calls for pure command/validator/reducer decisions with supplied read-model state; add scenarios only for pipeline/authorization wiring, constraints, declarative mapping or application-owned race policies. Follow [specs.scenarios.csharp.md](./specs.scenarios.csharp.md) for shared setup and cost budgets. **Gate:** tests pass.
76
+ - **Phase 2 — Specs.** Mandatory for every slice type. Start with plain calls for pure command/validator/reducer decisions with supplied read-model state; add scenarios only for pipeline/authorization wiring, constraints or declarative mapping. Follow [specs.scenarios.csharp.md](./specs.scenarios.csharp.md) for shared setup and cost budgets. **Gate:** tests pass.
77
77
  - **Phase 3 — Frontend.** Build from the generated proxies, register in the composition page, wire routing. **Gate:** lint, conditional test, build.
78
78
 
79
79
  **Backend before frontend, always** — the frontend depends on proxies that exist only after a successful build. Generate proxies from the **Debug** build (house convention); verify Release without re-running the generator: `dotnet build -c Release -p:CratisProxiesOutputPath=`. Why that property, and what to do when nothing is generated: the **cratis-arc-command** skill's proxy-generation reference.
@@ -49,6 +49,7 @@ Repo conventions follow from this: `Source/DotNET` + `Source/JavaScript` for dua
49
49
  - **Backward compatibility is a contract.** A change to a public type, attribute, interface, or generated-proxy shape is a breaking change for every downstream app — label PRs by semver impact (`major`/`minor`/`patch`) and treat removals/renames of public surface as `major`.
50
50
  - **Convention discovery is built here.** `IInstancesOf<T>` / `IImplementationsOf<T>`, attribute-based discovery, and source generation are the mechanisms the framework *provides*; use them internally too rather than hand-registration where a convention fits. A Fundamentals project reference does not carry the type-discovery analyzer like its NuGet package does: reference `Fundamentals.TypeDiscovery.Generator` explicitly, or your project's types may be absent from the generated universe.
51
51
  - **Source generators / analyzers** (Arc's proxy generator, Fundamentals) follow Roslyn conventions; their output is consumed verbatim by apps, so treat generated shape as public API.
52
+ - **Analyzers and generators are written for speed** (fast feedback is a product requirement): incremental generators only; a syntactic prefilter (name or kind) before any semantic bind; compute shared evidence once per compilation, never once per analyzer or per symbol; touch it only after cheap relevance checks; never rebind every call site of the compilation. Each expensive analyzer gets a performance spec.
52
53
  - **Orleans grains** in the Chronicle kernel follow `orleans.md`.
53
54
  - **An alternate implementation of an interface must match the primary one's *semantics*, not just its signature.** Chronicle ships several implementations of the same storage interfaces (MongoDB, SQL, in-memory) and the in-memory ones exist precisely so the real kernel code paths can run without infrastructure. When you touch one, **diff it against the persistent implementations** — the signature tells you nothing about the contract. The specific trap: query criteria carry **sentinels meaning "do not narrow"** (`EventSourceId.Unspecified`, `EventSourceType.Unspecified`/`Default`, `EventStreamType.All`, `EventStreamId.Default`, an empty event-type set). Callers asking for "everything" pass those sentinels, never `null`, so a plain `is not null` check narrows every row away and the read silently returns nothing. A divergence here does not fail — it makes specs pass vacuously, which is worse.
54
55
  - **A stub that silently succeeds is a bug, not a placeholder.** An unimplemented method returning `Task.CompletedTask`/an empty result lets a spec assert on work that never happened. Implement it, or make it fail loudly — never leave it quietly lying.
@@ -13,7 +13,7 @@ Profile-specific rules declare a **`profile:`** in their frontmatter (`applicati
13
13
 
14
14
  > **Arc is a standalone CQRS framework — not bound to event sourcing.** Even within the application profile, Arc provides model-bound commands/queries, validation, authorization, and full-stack proxy generation, and works **without** Chronicle (Arc.Core does not depend on Chronicle). A `[Command]` `Handle()` does not *have* to append events — it can return a response, return `void`, or work through injected services. The event-sourcing behavior (a returned event gets appended; `EventForEventSourceId`; "never inject `IEventLog`") comes from the **Arc + Chronicle** integration. This application is event-sourced, so the slice guidance assumes event-sourced commands — read the event-centric rules as the *house default for this app*, not universal Arc laws.
15
15
 
16
- The framework is convention-over-configuration. **Idiomatic Cratis is the goal — not custom abstractions over it.** When something is unclear, prefer the Cratis convention; do not invent. The rules and skills under `.cratis/ai/` are the authoritative answer — if your question is not answered there, ask rather than inferring framework behavior from package internals.
16
+ The framework is convention-over-configuration. **Idiomatic Cratis is the goal — not custom abstractions over it.** Always recommend the idiomatic way unless explicitly needed otherwise. When something is unclear, prefer the Cratis convention; do not invent. The rules and skills under `.cratis/ai/` are the authoritative answer — if your question is not answered there, ask rather than inferring framework behavior from package internals.
17
17
 
18
18
  ## Project Philosophy
19
19
 
@@ -52,6 +52,7 @@ obtaining credentials, and other local conventions ("Product policy" above).
52
52
  - Project context may explain which approved secret mechanism or local setup to
53
53
  use, but it must never contain credential values, tokens, keys, passwords, or
54
54
  other secrets.
55
+ - A repository's accepted decision records (`decisions/`) and project rules bind AI work: read those matching your paths, follow them, never work around one.
55
56
  - Project-specific guidance wins when it deliberately narrows shared behavior,
56
57
  but it may not weaken organization security, authorization, or required
57
58
  quality gates.
@@ -11,7 +11,7 @@ Extends the base [specs.md](./specs.md) (folder structure, naming, philosophy) w
11
11
 
12
12
  > **Which spec surface?**
13
13
  > - **Framework / library code** (Chronicle kernel, Arc pipeline, source generators, Fundamentals): the `Specification` base + NSubstitute in this file is the dominant mode — unit-test the classes under test in isolation. Reach for a `*Scenario` helper (in [specs.scenarios.csharp.md](./specs.scenarios.csharp.md)) **only** when testing the very engine your repo provides — Arc → `CommandScenario`, Chronicle → the event/projection/reactor scenarios. The **cratis-application-slice-specifications** skill is application-oriented, not for general framework specs.
14
- > - **Event-sourced applications on Cratis** (commands, projections, reducers, reactors, constraints): use this base plus a direct call by default for pure `Handle()`, validator and reducer decisions with supplied read-model state; add scenarios only for pipeline/authorization wiring, constraints, declarative projections or application-owned race policies — see **[specs.scenarios.csharp.md](./specs.scenarios.csharp.md)** (`profile: application`) and the **cratis-application-slice-specifications** skill.
14
+ > - **Event-sourced applications on Cratis** (commands, projections, reducers, reactors, constraints): use this base plus a direct call by default for pure `Handle()`, validator and reducer decisions with supplied read-model state; add scenarios only for pipeline/authorization wiring, constraints or declarative projections — see **[specs.scenarios.csharp.md](./specs.scenarios.csharp.md)** (`profile: application`) and the **cratis-application-slice-specifications** skill.
15
15
 
16
16
  `Cratis.Specifications` keeps the approach of Machine.Specifications (MSpec): `Establish → Because → should_` maps to "Given → When → Then" and keeps each spec focused on *one setup, one action, one set of assertions*.
17
17
 
@@ -14,16 +14,16 @@ Specs are **mandatory for every slice type**, including reactors.
14
14
 
15
15
  ## Start with the plain call; add a scenario where it adds proof
16
16
 
17
- **Judgment-shaped convention:** call pure `Handle()`, validators, reducers and reactor decisions directly with their inputs, including read-model state. Add a scenario only for pipeline/authorization wiring, constraints, declarative projection mapping or an application-owned race policy. Do not repeat every decision through the pipeline; name the extra behavior each scenario proves.
17
+ **Judgment-shaped convention:** call pure `Handle()`, validators, reducers and reactor decisions directly with their inputs, including read-model state. Add a scenario only for pipeline/authorization wiring, constraints or declarative projection mapping. Do not repeat every decision through the pipeline; name the extra behavior each scenario proves.
18
18
 
19
- **Application specs supply state, not decision-read infrastructure.** Call `Handle()` or the validator directly with supplied read-model state. Never call `UseDecisionReads`, configure protection modes, seed events solely for infrastructure, or re-prove the platform's concurrency, conflict-refusal or isolation matrix; Arc/Chronicle specs own it. The application's **only decision-read spec obligation** is one cheap assembly-level shape-admission spec: `DecisionReadAdmissions.ShouldAdmitDecisionReadsIn(assembly)` (`Cratis.Arc.Chronicle.Testing.Commands`). It checks the application's own models/projections without executing commands or running Chronicle, not the platform guards. An application-owned race policy may justify a scenario; assert its business outcome. Report harness state-setup gaps upstream; never weaken production guards for test speed.
19
+ **Application specs supply state, not decision-read infrastructure.** Call `Handle()` or the validator directly with supplied read-model state. Never call `UseDecisionReads`, configure protection modes, seed events solely for infrastructure, or re-prove the platform's concurrency, conflict-refusal or isolation matrix; Arc/Chronicle specs own it. The application's **only decision-read spec obligation** is one cheap assembly-level shape-admission spec: `DecisionReadAdmissions.ShouldAdmitDecisionReadsIn(assembly)` (`Cratis.Arc.Chronicle.Testing.Commands`). It checks the application's own models/projections without executing commands or running Chronicle, not the platform guards. Never simulate competing appends either (`AppendConcurrently` or any hand-built interleaving): concurrency is a framework concern a developer should not think about in tests, and Arc and Chronicle specs prove it. A rule that must hold under races is expressed in production by taking the read model as a `Handle` parameter under `[ReadProtection(On)]`; the spec gives that read model's state and asserts the outcome. Report harness state gaps upstream; never weaken production guards for speed. `AppendConcurrently` is an advanced framework-verification API: use only for an explicit need. Direction, no release claim: Arc will obsolete `UseDecisionReads`.
20
20
 
21
21
  **Share setup and budget cost (judgment-shaped).** Keep shared lifecycle on; use `[PerFactSpecificationLifecycle]` only on a class whose facts genuinely mutate shared state and cannot move that mutation into `Because`. Plain decision specs should take roughly milliseconds; measure scenario facts and justify seconds by the extra behavior they prove. Compare TRX durations and suite wall time with unchanged concurrency; see [running-specs.md](../skills/cratis-specifications-csharp/references/running-specs.md). Do not multiply scenario startup by splitting assertions into classes or opting the project out of shared lifecycle.
22
22
 
23
23
  | Tool | Tests | Use when |
24
24
  |---|---|---|
25
25
  | `Specification` (plain call) | `Handle()`, `Handle(providedValue)`, validator/reducer logic or a reactor's decision as a method call; or an isolated class with mocked collaborators | **default** for a decision that is a pure function of its arguments |
26
- | `CommandScenario<TCommand>` | the real Arc command pipeline — authorization + validators + `Provide()` + `Handle()` + appended events | pipeline wiring, authorization, constraints or an application-owned race policy adds proof |
26
+ | `CommandScenario<TCommand>` | the real Arc command pipeline — authorization + validators + `Provide()` + `Handle()` + appended events | pipeline wiring, authorization or constraints adds proof |
27
27
  | `QueryScenario<TReadModel>` | query pipeline: argument conversion, authorization, validation, interceptors; `Observe` buffers emissions | query composition matters; real MongoDB observations still need infrastructure |
28
28
  | `EventScenario` | Chronicle-level append semantics, no command pipeline | constraint violations, raw stream sequencing/concurrency |
29
29
  | `ReadModelScenario<TReadModel>` | projection/reducer state from a sequence of events (auto-detects model-bound / fluent / reducer) | one class per read model, many read-only assertions on shared setup |
@@ -120,7 +120,7 @@ arguments?, paging?, sorting?)`; `Observe(...)` returns `QueryObservation.Initia
120
120
  and buffered `Next()`. Configure principal/policies in `Services`; schemes fail
121
121
  closed without HTTP. Chronicle query `Given` can seed keyed models/events.
122
122
 
123
- For query setup and application-owned race policies, see **cratis-application-slice-specifications**,
123
+ For query setup, see **cratis-application-slice-specifications**,
124
124
  `references/query-and-decision-scenarios.md`. Framework read-protection guards are not application spec obligations.
125
125
 
126
126
  ### `EventScenario` — constraints & append semantics
@@ -13,6 +13,7 @@ authored a file or preserve a chain of evidence about how it arrived.
13
13
  - Run one phase per command with its real exit status. Budget targeted checks around 120 seconds and build/test phases around 300 seconds; explain any longer budget first, and obtain explicit approval before a phase exceeds 600 seconds. Stop on a failure; do not blindly retry or repeat passing tests on unchanged inputs without a flaky-test hypothesis or required matrix.
14
14
  - Separate status/fetch from builds, Debug from Release, each test project, and frontend lint/compile/test/build. Do not combine these into an opaque command with a large outer timeout. Expose progress and cancellation; report the precise failed or timed-out phase and do not continue dependent phases after failure.
15
15
  - Never use `build/test | grep | sort/head/tail` as gate evidence. Capture the producer's exit status before summarising output; `pipefail` alone is insufficient with early-closing consumers such as `head`. Printed zero-error counts are not proof of success. Preserve needed full diagnostics in task-scoped `.ai-work/` logs rather than hiding them in `/tmp`.
16
+ - Fast feedback is a product requirement: a spec takes milliseconds, the suite seconds; specs share setup and run in parallel; analyzers must not halt builds. CI builds the spec path without analyzers and enforces them, warnings as errors, in a parallel required job; the pre-push gate runs them. A slowdown is a defect.
16
17
  - Add a focused specification for every behavior or rejection rule you change.
17
18
  - Keep each check deterministic and runnable locally and in CI.
18
19
  - Never replace a real behavior check with a checksum, inventory, generated
@@ -20,7 +20,7 @@ This file is the reference for *what* goes in each part of a slice. Layout, slic
20
20
 
21
21
  - .NET / C# (ASP.NET Core) — **Cratis Arc** for CQRS / model-bound commands and queries, **Cratis Chronicle** for event sourcing, MongoDB or EF Core for read models.
22
22
  - React + TypeScript (Vite) — Cratis Components 4.x + Arc-generated proxies, MVVM. Vitest + Mocha/Chai/Sinon for frontend specs.
23
- - xUnit + Cratis.Specifications + NSubstitute for C# specs (`Specification` plus a direct call for pure command/validator/reducer decisions with supplied state; add scenarios only for pipeline/authorization wiring, constraints, declarative projections or application-owned race policies — see [specs.md](./specs.md)).
23
+ - xUnit + Cratis.Specifications + NSubstitute for C# specs (`Specification` plus a direct call for pure command/validator/reducer decisions with supplied state; add scenarios only for pipeline/authorization wiring, constraints or declarative projections — see [specs.md](./specs.md)).
24
24
 
25
25
  ## Proxy generation — the build dependency
26
26
 
@@ -12,7 +12,7 @@ Start a pure decision with a plain method call: `Handle()`,
12
12
  `Handle(providedValue)`, reducer logic or a reactor's decision needs no host,
13
13
  services or harness, including direct validator calls with supplied read-model state.
14
14
  Add scenarios only for pipeline/authorization wiring, constraints, declarative
15
- mapping or application-owned race policies; follow the
15
+ mapping; follow the
16
16
  [scenario selection and cost rule](../../rules/specs.scenarios.csharp.md). The scenario family
17
17
  exercises the real Arc and Chronicle code paths in-process — no HTTP, no fixture,
18
18
  no server.
@@ -207,14 +207,15 @@ do not replay a projection merely to feed a pure command decision.
207
207
  Both builder methods return `void`; there is nothing to await.
208
208
 
209
209
  Read protection is invisible to application spec authors. Never configure modes,
210
- call `UseDecisionReads`, seed events solely for infrastructure, or re-prove
211
- the platform concurrency/guard matrix. Keep one cheap assembly-level
210
+ call `UseDecisionReads`, simulate competing appends (`AppendConcurrently`), seed
211
+ events solely for infrastructure, or re-prove the platform concurrency/guard
212
+ matrix: give state, assert the outcome. Keep one cheap assembly-level
212
213
  `DecisionReadAdmissions.ShouldAdmitDecisionReadsIn(assembly)` spec for the
213
214
  application's own model/projection shapes: its only decision-read spec obligation.
214
215
  If the harness cannot accept required state, report the upstream gap; never weaken
215
216
  production guards for test speed. Read
216
217
  [query and decision scenarios](references/query-and-decision-scenarios.md) for
217
- query pipelines and application-owned race policies.
218
+ query pipelines.
218
219
 
219
220
  Validator and `Provide()` dependencies are registered in `_scenario.Services`;
220
221
  the concrete validator itself is discovered automatically.
@@ -3,7 +3,7 @@
3
3
  ## Contents
4
4
 
5
5
  - Query pipeline
6
- - Application-owned race policies
6
+ - Decision specifications
7
7
  - Sources
8
8
 
9
9
  <!-- Copyright (c) Cratis. All rights reserved. -->
@@ -67,7 +67,7 @@ execution runs the query through Arc's hosted query pipeline and establishes con
67
67
  before `Provide`/`Handle` on the command path. A direct static query call does not
68
68
  cover those pipeline hooks.
69
69
 
70
- ## Application-owned race policies
70
+ ## Decision specifications
71
71
 
72
72
  Start with a direct decision call supplied with read-model state. Follow the
73
73
  [scenario rule](../../../rules/specs.scenarios.csharp.md): application authors do
@@ -89,22 +89,20 @@ method bodies are not statically discovered. If the harness cannot accept
89
89
  required state for a business decision, report the upstream gap; never weaken
90
90
  production guards or invent guard doubles.
91
91
 
92
- Add a `CommandScenario<TCommand>` only when the application owns a race policy:
93
- for example, two callers reserving the last seat must produce one reservation
94
- and the specified rejection or retry outcome. Name that business contract and
95
- assert it, rather than repeating the platform's generic stale-read tests.
92
+ Do not add a scenario to prove a race. A rule such as "two callers reserving the last
93
+ seat yield one reservation" is specified from state: supply a read model with no seats
94
+ left and assert the rejection, then supply one seat and assert the reservation.
95
+ Simulating competing appends is a framework concern a developer should not think
96
+ about in tests; Arc and Chronicle prove it. `AppendConcurrently` stays a public but
97
+ advanced framework-verification API (hidden from IntelliSense), outside application
98
+ testing guidance; use it only for a specific, explicit need. Production expresses
99
+ the guarantee with the read model as a `Handle` parameter under
100
+ `[ReadProtection(On)]`. Direction, not a release claim: Arc will obsolete
101
+ `UseDecisionReads`; do not adopt it.
102
+ `ShouldHaveCompletedStream(ClosedStreamScope)` may assert that a decision completed a
103
+ stream at the exact source and route (`Cratis.Arc.Chronicle.Testing.Commands`).
96
104
  Use event history only when it is part of the domain example.
97
105
 
98
- For an application-owned race/retry policy only, `AppendConcurrently(id, events...)`
99
- (or its routed overload) can supply controlled interference. It is not required
100
- for every guarded decision. Requires Arc 22.92.0 without explicit decision-read
101
- setup; older limitations are upgrade/report concerns, not application setup
102
- instructions. A competing append alone proves no policy: assert the intended
103
- business outcome and ensure the decision would otherwise append.
104
- `ShouldHaveCompletedStream(ClosedStreamScope)` can assert an application-owned
105
- completion outcome at the exact source and route. These APIs are in
106
- `Cratis.Arc.Chronicle.Testing.Commands`.
107
-
108
106
  The Chronicle-backed `CommandScenario` discovers constraints automatically.
109
107
  Assert domain constraint refusals instead of disabling them; use `EventScenario`
110
108
  for append-time uniqueness examples. Do not subclass or substitute its engine.
@@ -276,7 +276,7 @@ Components guidance, not to this skill.
276
276
 
277
277
  Start pure `Handle()` and validator decisions with direct calls and supplied
278
278
  read-model state. Add scenarios only for pipeline/authorization wiring,
279
- constraints or application-owned race policies, not read-protection plumbing;
279
+ constraints, never read-protection plumbing or simulated concurrency;
280
280
  follow the [scenario selection and cost rule](../../rules/specs.scenarios.csharp.md).
281
281
 
282
282
  - The command is a `record`, carries `[Command]`, and declares a public instance
@@ -15,6 +15,13 @@ Source: Arc. These features require `Cratis.Arc.Chronicle`.
15
15
 
16
16
  ## Pick the guarded read
17
17
 
18
+ **Idiomatic default:** a state-dependent rule takes the read model as a `Handle()`
19
+ (or validator-constructor) parameter, with `[ReadProtection(On)]` where it must hold
20
+ under concurrent writers. Do not take `IDecisionReads` in `Handle()`: it is not
21
+ recommended with Arc and is not an investment target. A computed key stays in
22
+ `Provide()` until a read-model parameter covers it. Direction, not a release claim:
23
+ Arc will pin protected parameters so the idiomatic shape needs no further ceremony.
24
+
18
25
  Under read protection `On` (`<CratisReadProtection>On</CratisReadProtection>`, or
19
26
  `[ReadProtection(ReadProtectionMode.On)]` on a command), a read model that is a
20
27
  parameter of `Handle()` or of a `CommandValidator<T>` constructor is read fresh from
@@ -178,19 +185,18 @@ source id/type and stream route; reactor tuples/collections cannot mix it with e
178
185
  Call `Handle()` and validators directly with read-model state for pure business
179
186
  decisions. Follow the [scenario rule](../../../rules/specs.scenarios.csharp.md):
180
187
  read-protection plumbing is invisible to application spec authors. They never
181
- call `UseDecisionReads`, configure modes, seed events solely for infrastructure,
182
- or re-prove the platform concurrency, conflict-refusal or isolation matrix;
188
+ call `UseDecisionReads`, configure modes, simulate competing appends
189
+ (`AppendConcurrently`), seed events solely for infrastructure, or re-prove the platform concurrency, conflict-refusal or isolation matrix;
183
190
  Arc/Chronicle specs own it. The application's only decision-read spec obligation
184
191
  is one cheap assembly-level shape-admission spec from that rule.
185
192
  Never weaken production guards for test speed. Report a harness state-setup gap
186
193
  upstream instead of working around it in application specs.
187
194
 
188
- Add scenarios for pipeline/authorization wiring, constraints or an application-owned
189
- race policy. Name the domain outcome (for example, one successful reservation and
190
- one rejection), not the generic guard behavior. Read
195
+ Add scenarios for pipeline/authorization wiring or constraints. Never simulate
196
+ competing appends: assert the business outcome from supplied state (for example, no
197
+ copies left rejects). Read
191
198
  [query and decision scenarios](../../cratis-application-slice-specifications/references/query-and-decision-scenarios.md)
192
- for controlled interference and completion assertions. Keep shared lifecycle on
193
- and measure the added cost.
199
+ for the query and decision setup. Keep shared lifecycle on and measure the added cost.
194
200
 
195
201
  ## Sources
196
202
 
@@ -268,10 +268,10 @@ authorization and camelCase member paths are separate contracts.
268
268
 
269
269
  Every rule gets a failure specification: instantiate the validator with its
270
270
  read-model state and validate directly, asserting the specific rejection. Add
271
- `CommandScenario<TCommand>` only for pipeline/authorization wiring, constraints
272
- or an application-owned race policy. Follow the
271
+ `CommandScenario<TCommand>` only for pipeline/authorization wiring, constraints.
272
+ Follow the
273
273
  [scenario rule](../../rules/specs.scenarios.csharp.md): application specs never
274
- configure read-protection modes, call `UseDecisionReads`, seed events solely for
274
+ configure read-protection modes, call `UseDecisionReads`, simulate competing appends, seed events solely for
275
275
  infrastructure, or re-prove platform guards. Keep the single cheap assembly-level
276
276
  application-shape admission spec specified by that rule; it is the application's
277
277
  only decision-read spec obligation. Report harness gaps upstream; never weaken
@@ -199,5 +199,5 @@ deciding writer is guarded or the rule is a constraint.
199
199
  changes, absence guards, empty checked appends, isolation and commit lifecycle.
200
200
  Their real-client/kernel integration proves the boundary; a default
201
201
  `EventScenario` scope strategy returning `None` is not concurrency evidence.
202
- - An application-owned race/retry policy may justify a focused scenario, not
203
- repetition of that matrix. Never weaken production guards for spec speed.
202
+ - Application specs never simulate competing appends or repeat that matrix.
203
+ Never weaken production guards for spec speed.
@@ -316,12 +316,11 @@ assembly-level `DecisionReadAdmissions.ShouldAdmitDecisionReadsIn(assembly)`
316
316
  check of its own models/projections, not per-decision scenarios. Production
317
317
  protection stays unchanged regardless of spec cost.
318
318
 
319
- A scenario is justified for an application-owned race policy: for example, two
320
- borrowers competing for the last copy must yield one loan and the specified
321
- rejection or retry. Assert that domain outcome, not the engine's generic append
322
- conditions. See [query and decision scenarios](../../cratis-application-slice-specifications/references/query-and-decision-scenarios.md)
323
- for controlled interference. If the harness cannot accept required state, report
324
- the upstream gap rather than adding infrastructure setup to application specs.
319
+ Do not simulate competing appends in an application spec, even for a rule such as
320
+ two borrowers competing for the last copy. Give the state (no copies left) and assert
321
+ the domain outcome (rejected); the guarantee that only one wins is proven by Arc and
322
+ Chronicle. If the harness cannot accept required state, report the upstream gap
323
+ rather than adding infrastructure setup to application specs.
325
324
 
326
325
  ## Costs
327
326
 
@@ -144,10 +144,14 @@ handle it. Pitfall: without `merge_group` the required check never reports in th
144
144
  queue. Read `references/required-checks-and-path-filters.md`.
145
145
 
146
146
  **Compile once, analyze once.** Fits any workflow where one push compiles the same
147
- code several times. Default: build once and reuse the output; run analyzers in one
148
- parallel lint job instead of in every build, and let that job fail early on compile
149
- and analyzer errors before long test legs. Pitfall: dropping analyzers from the only
150
- build that consumers enforce. Read `references/test-setup-cost.md`.
147
+ code several times. Default: build the spec path without analyzers
148
+ (`-p:RunAnalyzers=false`) and reuse the output; enforce every analyzer with warnings
149
+ as errors in one parallel **required** job that fails early on compile and analyzer
150
+ errors, while the local fast loop may skip analyzers and the pre-push gate runs them.
151
+ Pitfall: dropping analyzers from the only build that consumers enforce, or leaving
152
+ the analyzer job out of the required checks. Measure analyzer cost per rule before
153
+ and after (binlog analyzer timings), and fix a slow analyzer at its source rather
154
+ than switching it off. Read `references/test-setup-cost.md`.
151
155
 
152
156
  **Cores per job before job count.** Fits uniformly slow jobs. Default: check `nproc`
153
157
  and the runner's resources before sharding; undersized runners make every job slow.
@@ -11,6 +11,7 @@ a suite re-tests a dependency, or when compile errors surface late.
11
11
  - Test each guarantee where it can break
12
12
  - Surface compile errors early
13
13
  - Count compiles per push
14
+ - Analyzer cost
14
15
 
15
16
  ## Time hidden outside per-test timing
16
17
 
@@ -80,3 +81,17 @@ Each extra compile is avoidable: build once, reuse the output (see
80
81
  `build-once-and-shard.md`). Analyzers can roughly double compile time; run them once
81
82
  in a parallel lint job and disable them in the shared build, while keeping the
82
83
  strictest configuration that consumers enforce somewhere on the required path.
84
+
85
+ ## Analyzer cost
86
+
87
+ Analyzers that run in the spec path stall every build. Take per-analyzer timings
88
+ from a binlog of the slow project, with the same inputs and concurrency before and
89
+ after. Rank by cumulative time per rule, not by assembly. Three results are
90
+ typical: rules that cannot apply to the repository (switch them off; a bulk
91
+ severity setting can run an analyzer whose own rules are `none`), an analyzer that
92
+ rebinds the whole compilation (fix it upstream: syntactic prefilter, evidence
93
+ computed once per compilation, touched only after cheap relevance checks), and
94
+ generators, which are rarely the cost. In one measured application, compiling with
95
+ analyzers took 395 s, 180 s after removing inapplicable rules, and 90 s with
96
+ analyzers off. Pass means the spec-path build skips analyzers, the parallel
97
+ required job still fails on any analyzer warning, and both timings are recorded.
@@ -13,7 +13,7 @@ of contents, and each file states one setup, one action, and one or more
13
13
  focused assertions.
14
14
 
15
15
  Read [query and decision scenarios](../cratis-application-slice-specifications/references/query-and-decision-scenarios.md)
16
- when specifying query emissions or application-owned race policies.
16
+ when specifying query emissions.
17
17
  Follow the [scenario selection and cost rule](../../rules/specs.scenarios.csharp.md):
18
18
  application specs supply read-model state and test business decisions, never
19
19
  read-protection plumbing. `Perform`/`Observe` need configured services/principal;
@@ -90,8 +90,7 @@ before changing runner or package family.
90
90
  The plain `Specification` base is the universal foundation and the dominant mode
91
91
  in library and framework code. In applications, start pure decisions with a
92
92
  plain call, including direct validator calls, and add scenarios only for
93
- pipeline/authorization wiring, constraints, declarative mapping or application-owned
94
- race policies. Keep shared lifecycle on; measure scenario cost using
93
+ pipeline/authorization wiring, constraints, or declarative mapping. Keep shared lifecycle on; measure scenario cost using
95
94
  [running-specs.md](references/running-specs.md). Read
96
95
  [application-scenarios.md](references/application-scenarios.md) before using
97
96
  one. Out-of-process integration specifications are an advanced case reserved for
@@ -10,18 +10,18 @@
10
10
 
11
11
  The four scenario helpers exercise the real Arc and Chronicle pipelines
12
12
  in-process. Follow the [scenario selection and cost rule](../../../rules/specs.scenarios.csharp.md):
13
- use them for pipeline/authorization wiring, constraints, declarative mapping or an
14
- application-owned race policy; specify pure `Handle()`, validator, reducer and
13
+ use them for pipeline/authorization wiring, constraints, or declarative mapping;
14
+ specify pure `Handle()`, validator, reducer and
15
15
  reactor decisions first as plain calls with supplied read-model state. A library or framework repository reaches for a scenario only to test the
16
16
  very engine it provides.
17
17
 
18
18
  Read [query and decision scenarios](../../cratis-application-slice-specifications/references/query-and-decision-scenarios.md)
19
- when using `QueryScenario<T>`, buffered emissions or application-owned race policies.
19
+ when using `QueryScenario<T>`, or buffered emissions.
20
20
  Read-protection plumbing is the harness's responsibility, never application setup.
21
21
 
22
22
  | Helper | Exercises | Use for |
23
23
  | --- | --- | --- |
24
- | `CommandScenario<TCommand>` | Authorization, validators, `Provide()`, `Handle()`, appended events | Pipeline wiring, authorization, domain constraints/race policies |
24
+ | `CommandScenario<TCommand>` | Authorization, validators, `Provide()`, `Handle()`, appended events | Pipeline wiring, authorization, domain constraints |
25
25
  | `QueryScenario<TReadModel>` | Argument conversion, authorization, validation, interceptors and buffered observations | Query pipeline behavior |
26
26
  | `EventScenario` | Chronicle append semantics without the command pipeline | Domain constraints; raw engine guards belong in framework specs |
27
27
  | `ReadModelScenario<TReadModel>` | Projection or reducer state from a sequence of events | Declarative mapping/wiring, one class per model |
@@ -63,7 +63,7 @@ project on its own; `dotnet test` on the whole solution does not work there.
63
63
  Apply the [scenario cost budget](../../../rules/specs.scenarios.csharp.md): plain
64
64
  decision specs should take roughly milliseconds, not seconds. Measure scenario
65
65
  facts and justify their cost by pipeline/authorization wiring, constraints,
66
- declarative mapping or an application-owned race policy that a plain call cannot
66
+ or declarative mapping that a plain call cannot
67
67
  prove. Prefer fewer startups, not fewer assertions or weaker production guards.
68
68
 
69
69
  Capture TRX for the affected project before and after the change. With VSTest,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cratis/pi",
3
- "version": "7.124.0",
3
+ "version": "7.125.0",
4
4
  "description": "Configuration-aware Cratis AI integration for Pi",
5
5
  "type": "module",
6
6
  "files": [