@cratis/pi 7.112.0 → 7.114.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package/corpus/harnesses/copilot/instructions/application-profile.instructions.md +1 -1
- package/package/corpus/harnesses/copilot/instructions/orleans.instructions.md +10 -2
- package/package/corpus/harnesses/copilot/instructions/pull-requests.instructions.md +7 -0
- package/package/corpus/harnesses/copilot/instructions/specs.csharp.instructions.md +4 -4
- package/package/corpus/harnesses/copilot/instructions/vertical-slices.instructions.md +1 -1
- package/package/corpus/hooks/scripts/cratis-store-mutations.json +4 -0
- package/package/corpus/product-sync.json +88 -88
- package/package/corpus/rules/application-profile.md +1 -1
- package/package/corpus/rules/orleans.md +10 -2
- package/package/corpus/rules/pull-requests.md +7 -0
- package/package/corpus/rules/specs.csharp.md +4 -4
- package/package/corpus/rules/vertical-slices.md +1 -1
- package/package/corpus/skills/cratis-application-slice-specifications/references/query-and-decision-scenarios.md +19 -0
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/SKILL.md +8 -0
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authproxy.md +26 -0
- package/package/corpus/skills/cratis-arc-command/references/proxy-generation.md +10 -1
- package/package/corpus/skills/cratis-arc-command-execution/SKILL.md +3 -2
- package/package/corpus/skills/cratis-arc-command-execution/references/occurrence-commands.md +7 -6
- package/package/corpus/skills/cratis-arc-command-validation/SKILL.md +5 -0
- package/package/corpus/skills/cratis-arc-command-validation/references/input-binding.md +17 -0
- package/package/corpus/skills/cratis-arc-command-validation/references/protected-validator-construction.md +94 -0
- package/package/corpus/skills/cratis-arc-ef-core-migration/SKILL.md +18 -0
- package/package/corpus/skills/cratis-arc-query-paging/SKILL.md +11 -4
- package/package/corpus/skills/cratis-arc-query-paging/references/live-query-processing.md +71 -0
- package/package/corpus/skills/cratis-arc-react-page/SKILL.md +11 -0
- package/package/corpus/skills/cratis-arc-validation-kotlin/SKILL.md +20 -3
- package/package/corpus/skills/cratis-chronicle-cli-operations/SKILL.md +11 -2
- package/package/corpus/skills/cratis-chronicle-cli-operations/references/command-effects.md +7 -0
- package/package/corpus/skills/cratis-chronicle-cli-operations/references/project-tooling.md +91 -0
- package/package/corpus/skills/cratis-chronicle-cli-operations/references/recovery-and-comparison.md +68 -0
- package/package/corpus/skills/cratis-chronicle-client-elixir/SKILL.md +12 -0
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/decision-reads.md +10 -0
- package/package/corpus/skills/cratis-chronicle-client-go/SKILL.md +12 -2
- package/package/corpus/skills/cratis-chronicle-client-kotlin/SKILL.md +4 -0
- package/package/corpus/skills/cratis-chronicle-client-kotlin/references/annotations-and-handlers.md +6 -1
- package/package/corpus/skills/cratis-chronicle-client-kotlin/references/fundamentals-migration.md +48 -0
- package/package/corpus/skills/cratis-chronicle-client-typescript/SKILL.md +18 -0
- package/package/corpus/skills/cratis-chronicle-client-typescript/references/lifecycle.md +7 -0
- package/package/corpus/skills/cratis-chronicle-read-model/references/queries.md +5 -3
- package/package/corpus/skills/cratis-cli-terminal-workbench/SKILL.md +5 -1
- package/package/corpus/skills/cratis-components-common-controls/SKILL.md +11 -0
- package/package/corpus/skills/cratis-components-data-surfaces/SKILL.md +5 -0
- package/package/corpus/skills/cratis-components-data-surfaces/references/query-table-updates.md +51 -0
- package/package/corpus/skills/cratis-components-schema-editor/references/tree-layout.md +18 -0
- package/package/corpus/skills/cratis-components-stepper-command-dialog/SKILL.md +11 -0
- package/package/corpus/skills/cratis-fundamentals-type-discovery/SKILL.md +13 -0
- package/package/corpus/skills/cratis-orleans-jobs/SKILL.md +39 -51
- package/package/corpus/skills/cratis-orleans-jobs/references/lifecycle-and-placement.md +52 -0
- package/package/corpus/skills/cratis-orleans-jobs/references/state-machines.md +3 -1
- package/package/corpus/skills/cratis-release-notes/SKILL.md +23 -0
- package/package/corpus/skills/cratis-screenplay-command-surface/references/protected-reads.md +3 -2
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/prologue-safety.md +14 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
- package/package/corpus/skills/cratis-specifications-csharp/SKILL.md +14 -2
- package/package/corpus/skills/cratis-specifications-csharp/references/running-specs.md +8 -1
- package/package/corpus/skills/cratis-specifications-csharp/references/shared-lifecycle.md +19 -2
- package/package.json +1 -1
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Query and decision scenarios
|
|
2
2
|
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- Query pipeline
|
|
6
|
+
- Guarded decisions
|
|
7
|
+
- Sources
|
|
8
|
+
|
|
3
9
|
<!-- Copyright (c) Cratis. All rights reserved. -->
|
|
4
10
|
<!-- Licensed under the MIT license. See LICENSE file in the project root for full license information. -->
|
|
5
11
|
|
|
@@ -52,6 +58,13 @@ not a caller-supplied tenant filter. Compare whole returned items when the contr
|
|
|
52
58
|
value; otherwise assert each named value. A query backed by a database still needs that provider's
|
|
53
59
|
integration setup: scenario pins do not replace arbitrary stores.
|
|
54
60
|
|
|
61
|
+
`QueryScenario` owns and disposes its provider. Dispose the scenario (prefer
|
|
62
|
+
`DisposeAsync` for async-owned resources) as well as individual observations.
|
|
63
|
+
Register dependencies in `Services` before the first execution. Scenario
|
|
64
|
+
execution runs the query through Arc's hosted query pipeline and establishes context
|
|
65
|
+
before `Provide`/`Handle` on the command path. A direct static query call does not
|
|
66
|
+
cover those pipeline hooks.
|
|
67
|
+
|
|
55
68
|
## Guarded decisions
|
|
56
69
|
|
|
57
70
|
Create `new CommandScenario<TCommand>()`. It selects Chronicle's in-process decision
|
|
@@ -87,6 +100,12 @@ read-model dictionary is the only backing are **legacy-mode** warnings, not a
|
|
|
87
100
|
reason to fake protected decision readers. Keep non-key enumeration/provider
|
|
88
101
|
boundaries explicit in either mode; decision mode is not a MongoDB substitute.
|
|
89
102
|
|
|
103
|
+
The default Chronicle-backed `CommandScenario` discovers constraints
|
|
104
|
+
automatically. Assert real constraint refusals instead of disabling them. Do not
|
|
105
|
+
subclass or substitute Chronicle's `EventScenario`; use its public
|
|
106
|
+
seeding/assertion surface or explicit `UseDecisionReads` mode, not a synthetic
|
|
107
|
+
EventScenario facade.
|
|
108
|
+
|
|
90
109
|
## Sources
|
|
91
110
|
|
|
92
111
|
- [Query scenarios](https://github.com/Cratis/Arc/blob/main/Documentation/backend/csharp/testing/query-scenario.md)
|
|
@@ -179,6 +179,14 @@ filters, and system-execution.
|
|
|
179
179
|
`Task<AuthenticationResult> HandleAuthentication(IHttpRequestContext context)`.
|
|
180
180
|
Implement it and it is discovered — there is **no** `IArcBuilder` extension and
|
|
181
181
|
**no** options type for authentication.
|
|
182
|
+
Requires Arc 22.139.0 for handlers to opt out of anonymous endpoints through
|
|
183
|
+
`AppliesToAnonymousEndpoints => false`. The default is `true`: existing handlers
|
|
184
|
+
keep running and may establish an identity even when no credential is required.
|
|
185
|
+
Opt out when a handler only rejects credentials and contributes no identity on
|
|
186
|
+
those endpoints. A handler that still runs can inspect the endpoint's anonymous
|
|
187
|
+
metadata and return `AuthenticationResult.Anonymous` instead of rejecting a
|
|
188
|
+
credential the endpoint never required. Specify anonymous and protected requests;
|
|
189
|
+
anonymous access does not bypass other authorization boundaries.
|
|
182
190
|
|
|
183
191
|
Arc ships `MicrosoftIdentityPlatformAuthenticationHandler` in `Arc.Core`, which
|
|
184
192
|
reads the forwarded principal. See
|
|
@@ -23,6 +23,32 @@ The headers are **not signed**. A backend cannot tell a request that came throug
|
|
|
23
23
|
|
|
24
24
|
`IdentityVerification` on an AuthProxy service defaults to `Required` (fail closed). Only a `2xx` with `"isAuthorized": true` admits the caller. A `404`, an unreachable backend, a timeout (default ten seconds), any other non-`2xx`, an empty or unparseable body, a missing verdict, or `isAuthorized: false` all deny. The earlier `BestEffort` mode denied only on `403`. Consequently your `IProvideIdentityDetails` result is the admission verdict at the proxy, not only display data: return `IsUserAuthorized = false` deliberately, and keep the endpoint reachable and fast. A service can opt back into `BestEffort` explicitly; do not do that to hide a broken identity endpoint.
|
|
25
25
|
|
|
26
|
+
## Multi-host sessions are opt-in
|
|
27
|
+
|
|
28
|
+
Requires AuthProxy 2.32.4 for the multi-host/crawler/invitation contract below; check the deployed version, or retain host-only sessions and the older error-page contract.
|
|
29
|
+
|
|
30
|
+
Defaults stay host-only with cookie name
|
|
31
|
+
`.Cratis.AuthProxy.Auth.v2`, per-host handshakes and relative return URLs.
|
|
32
|
+
`Session:CookieDomain` shares sessions beneath a parent domain;
|
|
33
|
+
`Session:CookieName` isolates independent deployments. `SignIn:CallbackHost`
|
|
34
|
+
centralizes OAuth/OIDC handshakes and requires the cookie domain. Restrict
|
|
35
|
+
`AllowedHosts`; never broaden hosts merely to make shared cookies work.
|
|
36
|
+
|
|
37
|
+
The callback and declared service hosts must lie inside the cookie domain;
|
|
38
|
+
`SubHost` tenant resolution cannot be combined with it. Absolute returns require
|
|
39
|
+
the callback host and an allowed origin inside that domain on the request's
|
|
40
|
+
scheme; otherwise they reduce to a local path. Invitations, credential links and
|
|
41
|
+
registration still start on their original host and need provider callbacks
|
|
42
|
+
there. Use the product's one-proxy/several-hosts migration guide, not an inferred
|
|
43
|
+
cross-domain cookie recipe.
|
|
44
|
+
|
|
45
|
+
`AuthProxy:SearchIndexing:Exclude` optionally serves anonymous
|
|
46
|
+
`robots.txt` and adds `X-Robots-Tag: noindex, nofollow`. It is off by default and
|
|
47
|
+
is a crawler policy, not authorization. Invitation error-page tokens
|
|
48
|
+
`{{invitedEmail}}` and `{{assertedEmail}}` are blank for addresses outside ASCII
|
|
49
|
+
letters, digits and `._+-@`; do not assume these placeholders always contain text.
|
|
50
|
+
Signed-in `/register` forwarding needs no host workaround.
|
|
51
|
+
|
|
26
52
|
## Tenants and services
|
|
27
53
|
|
|
28
54
|
AuthProxy resolves the tenant through ordered strategies under `Cratis:AuthProxy:TenantResolutions` (`Host`, `Claim`, `Route`, `Specified`, `Default`, `SubHost`, `Selection`). The result reaches the backend as `x-cratis-tenant-id`, which is Arc's default tenant header, so an Arc application behind AuthProxy needs no tenancy configuration and the `UseHeaderTenancy("Tenant-ID")` workaround seen in older applications can be removed.
|
|
@@ -16,7 +16,7 @@ Reference the build package from the project that contains the commands,
|
|
|
16
16
|
queries and read models, and set an output path:
|
|
17
17
|
|
|
18
18
|
```xml
|
|
19
|
-
<PackageReference Include="Cratis.Arc.ProxyGenerator.Build" Version="22.
|
|
19
|
+
<PackageReference Include="Cratis.Arc.ProxyGenerator.Build" Version="22.139.0" />
|
|
20
20
|
|
|
21
21
|
<PropertyGroup>
|
|
22
22
|
<CratisProxiesOutputPath>$(MSBuildThisFileDirectory)../<Web>/src/api</CratisProxiesOutputPath>
|
|
@@ -47,6 +47,8 @@ switches without a declared default are off when absent.
|
|
|
47
47
|
| --- | --- | --- |
|
|
48
48
|
| `CratisProxiesOutputPath` | empty | Where to write. Empty disables generation entirely |
|
|
49
49
|
| `CratisProxiesInputAssembly` | empty | Overrides the assembly to read |
|
|
50
|
+
| `CratisProxiesIncremental` | `true` | Requires Arc 22.138.0; reuse unchanged owned output; set `false` to regenerate every build |
|
|
51
|
+
| `CratisProxiesFileHeader` | project setting | Requires Arc 22.123.0; otherwise uses `.editorconfig` `file_header_template`, or no header; `none` disables it |
|
|
50
52
|
| `CratisProxiesSegmentsToSkip` | empty | Leading namespace segments to drop from the output path |
|
|
51
53
|
| `CratisProxiesLibraryMode` | `false` | Generates for a library rather than an application |
|
|
52
54
|
| `CratisProxiesSkipOutputDeletion` | **`true`** | Already the default — the generator does not wipe the output folder |
|
|
@@ -70,6 +72,13 @@ are optional. Sources:
|
|
|
70
72
|
`Tools/ProxyGenerator.Build/build/Cratis.Arc.ProxyGenerator.Build.targets` under
|
|
71
73
|
`Source/DotNET`.
|
|
72
74
|
|
|
75
|
+
Incremental generation fingerprints assemblies, generator/configuration, validation metadata
|
|
76
|
+
and owned output. A changed or missing generated file forces regeneration, as
|
|
77
|
+
does a previous warning so diagnostics remain visible. It does not make a
|
|
78
|
+
hand-edited generated file an input. Configure `file_header_template` explicitly
|
|
79
|
+
if you previously relied on the built-in Cratis MIT header; it is no longer
|
|
80
|
+
inserted without configuration.
|
|
81
|
+
|
|
73
82
|
Item groups the target also forwards: `AssemblyToPackageMapping`,
|
|
74
83
|
`ExcludeType`, `ExcludeNamespace`, `NamespaceRoot`, and `TypeToTsType`.
|
|
75
84
|
|
|
@@ -101,8 +101,9 @@ if (result.IsSuccess)
|
|
|
101
101
|
}
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
`Execute<TResult>` accepts an assignable response, such as an array requested
|
|
105
|
+
as `IEnumerable<T>` or a concrete value requested as an interface/base type.
|
|
106
|
+
⚠️ An incompatible non-null response still throws `InvalidCastException`. When the handler returns no response, or the
|
|
106
107
|
command failed for any reason, `Response` is `default` — a failed result never
|
|
107
108
|
carries a response, because the pipeline clears it once the execution scopes
|
|
108
109
|
have completed.
|
package/package/corpus/skills/cratis-arc-command-execution/references/occurrence-commands.md
CHANGED
|
@@ -61,12 +61,13 @@ key where that service supports it; otherwise an external effect can repeat.
|
|
|
61
61
|
Return events from the command, or use transactional appends. Do not complete a
|
|
62
62
|
stream or commit an aggregate early inside the executor's command.
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
64
|
+
Requires Arc 22.118.0 for the keyed executor to refuse immediate appends
|
|
65
|
+
**before transport**, with neither appended events nor an effect receipt. Arc
|
|
66
|
+
22.117.x detected `OccurrenceCommandAppendedImmediately` only after an append
|
|
67
|
+
could escape; upgrade rather than treating that detection as retry safety.
|
|
68
|
+
Use `.Transactional` or returned events, and assert that a forbidden direct
|
|
69
|
+
append writes nothing. For a custom non-executor boundary, read
|
|
70
|
+
**cratis-chronicle-client-dotnet**'s immediate-append refusal reference.
|
|
70
71
|
|
|
71
72
|
## Verify
|
|
72
73
|
|
|
@@ -142,6 +142,11 @@ public class TransferFundsValidator : CommandValidator<TransferFunds>
|
|
|
142
142
|
- A validator that itself throws does not become a 500 — Arc catches it and
|
|
143
143
|
emits a validation error with reason `ValidatorFailed`, returning 400.
|
|
144
144
|
|
|
145
|
+
Read [protected validator construction](references/protected-validator-construction.md)
|
|
146
|
+
for plain read-model constructor inputs under `On`, the separate untrimmed-JIT
|
|
147
|
+
provider opt-in for decision tokens outside `On`, and generated composite-key
|
|
148
|
+
metadata. Do not conflate metadata coverage with validator certification.
|
|
149
|
+
|
|
145
150
|
## Step 4 — Data the handler needs: `Provide()`
|
|
146
151
|
|
|
147
152
|
`Provide()` runs after authorization and validation and before `Handle()`. Its
|
|
@@ -15,6 +15,14 @@ with `DateTime command property '<member>' requires an explicit offset or Z.`
|
|
|
15
15
|
`DateTimeOffset` retains the input offset; `DateTime` becomes UTC. The attribute
|
|
16
16
|
is in `Cratis.Arc.Commands`.
|
|
17
17
|
|
|
18
|
+
Requires Arc 22.120.0 for concepts over `DateTime` or `DateTimeOffset` with
|
|
19
|
+
Arc's default JSON options. Concepts over `DateOnly` are refused as a
|
|
20
|
+
configuration error: calendar dates have no offset. The marker affects
|
|
21
|
+
JSON-bound properties, including nested collection elements, not query strings
|
|
22
|
+
or route scalars. Use reflection-based JSON metadata for these properties;
|
|
23
|
+
System.Text.Json source-generated metadata does not support derived
|
|
24
|
+
`JsonConverterAttribute` markers.
|
|
25
|
+
|
|
18
26
|
## Malformed bodies still authorize
|
|
19
27
|
|
|
20
28
|
Requires Arc 22.110.0 for authorization-before-binding-failure handling on
|
|
@@ -31,6 +39,15 @@ policies can run; built-in role, claim, name and authenticated-user requirements
|
|
|
31
39
|
are already resource-free. Do not mark a requirement resource-free if it reads
|
|
32
40
|
the command.
|
|
33
41
|
|
|
42
|
+
## Annotations on concepts
|
|
43
|
+
|
|
44
|
+
Requires Arc 22.121.2 for data annotations on command properties and model-bound
|
|
45
|
+
query parameters to validate a concept's wrapped value: `[Required]` rejects an
|
|
46
|
+
empty wrapped string, `[Range]` checks the primitive, and `[StringLength]` does
|
|
47
|
+
not throw on the wrapper. This uses generated validation metadata; types without
|
|
48
|
+
that metadata (including external assemblies) keep the previous behavior. Do
|
|
49
|
+
not assume annotations replace a concept's reusable validator.
|
|
50
|
+
|
|
34
51
|
## Validation members are field paths
|
|
35
52
|
|
|
36
53
|
Requires Arc 22.115.0 for **all** `ValidationResult.Members` paths to be
|
|
@@ -0,0 +1,94 @@
|
|
|
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 validator construction and key metadata
|
|
5
|
+
|
|
6
|
+
## Plain read models under On
|
|
7
|
+
|
|
8
|
+
Requires Arc 22.106.0 for plain Chronicle read-model dependencies in
|
|
9
|
+
`CommandValidator<T>` constructors under read protection `On`. Those reads share
|
|
10
|
+
the command's fold cache and append guard with `Provide`/`Handle`. Let convention
|
|
11
|
+
discovery register a transient validator. Scoped/singleton/factory/instance
|
|
12
|
+
registrations are refused; a plain transient self-binding is also allowed.
|
|
13
|
+
Ineligible construction fails closed; never fall back to unguarded reads. Use
|
|
14
|
+
`[LookUpBy(nameof(Command.Property))]` on each constructor read for multiple
|
|
15
|
+
keys. Another source/stream can instead be read explicitly in `Provide`.
|
|
16
|
+
|
|
17
|
+
## Explicit decision tokens outside On
|
|
18
|
+
|
|
19
|
+
Requires Arc 22.126.0 for the opt-in construction of validators taking
|
|
20
|
+
`DecisionRead<T>` or command-aware `IDecisionReads` on `[ProtectedDecision]`
|
|
21
|
+
commands outside `On`. This is **untrimmed JIT only**, not trimmed JIT or
|
|
22
|
+
NativeAOT, and not a switch making every DI container trusted.
|
|
23
|
+
|
|
24
|
+
Install `ProtectedDecisionServiceProviderFactory` from
|
|
25
|
+
`Cratis.Arc.DependencyInjection` as the host's actual Microsoft DI factory
|
|
26
|
+
**after** `AddCratisArc`, passing the desired `ServiceProviderOptions` explicitly.
|
|
27
|
+
Without them both `ValidateScopes` and `ValidateOnBuild` default to false; host
|
|
28
|
+
Development settings are not inherited. `BuildProtectedDecisionServiceProvider`
|
|
29
|
+
is for independently owned service collections, not a second root inside the
|
|
30
|
+
running host. Execute in a native child scope (or the pipeline's scope-owning
|
|
31
|
+
overload), never directly on that root. Default `CommandScenario` does not opt in.
|
|
32
|
+
|
|
33
|
+
Register Chronicle through Arc's `WithChronicle`. Do not replace readers or
|
|
34
|
+
re-register tokens. Arc records origins at root construction; copied descriptors,
|
|
35
|
+
a wrapper provider, custom container or later collection mutation cannot acquire
|
|
36
|
+
that evidence.
|
|
37
|
+
|
|
38
|
+
Every validator/collaborator needs exactly one public constructor and a fully
|
|
39
|
+
inspectable transient graph. Arc constructs fresh instances for the invocation.
|
|
40
|
+
It refuses scoped/singleton validators or collaborators, application validator
|
|
41
|
+
bindings, factory/instance dependencies, cycles, keyed/open generic/deferred or
|
|
42
|
+
optional dependencies, provider/scope accessors and collections (including token
|
|
43
|
+
collections). Plain models and raw `IReadModels`, `IEventStore` or `IEventLog`
|
|
44
|
+
are refused on this path: use tokens or choose `On`.
|
|
45
|
+
|
|
46
|
+
Requires Arc 22.126.0 for
|
|
47
|
+
`services.AddProtectedDecisionValidator<TValidator>(configure)`. Use it instead
|
|
48
|
+
of an application DI factory when adding rules. The callback runs once on the
|
|
49
|
+
actual fresh instance before validation; thrown callbacks fail the command and
|
|
50
|
+
callback denials are not bypassed. It can replace one Arc convention binding,
|
|
51
|
+
not an explicit application registration. Extra explicit bindings refuse the
|
|
52
|
+
protected path. Ordinary commands still use normal constructor resolution.
|
|
53
|
+
|
|
54
|
+
Arc checks rule/component identities before invocation and refuses changed or
|
|
55
|
+
cross-scope/reused instances. Construction and cleanup failures block before
|
|
56
|
+
commit even with allowed-severity overrides. Arc disposes owned validators and
|
|
57
|
+
collaborators in reverse order; DI owns read leaves. This is not a sandbox for
|
|
58
|
+
trusted constructor/callback code, mutable captures, static reads or nested-child
|
|
59
|
+
rule changes. `Validate` stays advisory and creates a separate invocation; only
|
|
60
|
+
Execute enrolls its decision for append-time checking. Under `Off`, choose the
|
|
61
|
+
blocking severity needed for business denials.
|
|
62
|
+
|
|
63
|
+
## Generated key metadata is not validator certification
|
|
64
|
+
|
|
65
|
+
`CommandReadModelKeys` registers command property/model-key metadata.
|
|
66
|
+
Requires Arc 22.125.0 for generated composite-key descriptors and
|
|
67
|
+
`ProtectedReadModelKeyAccessors`, which registers exact-type composite members.
|
|
68
|
+
These optimize matching; they do not authorize a read or certify a validator's
|
|
69
|
+
dependency graph.
|
|
70
|
+
|
|
71
|
+
Known concrete composite keys receive generated complete descriptors. For an
|
|
72
|
+
external/runtime key, register `ProtectedReadModelKeyAccessors.Register<T>` with
|
|
73
|
+
every public readable non-indexed instance property, including inherited ones,
|
|
74
|
+
before commands run. Generated metadata uses `DeclareKeyTypes` for startup
|
|
75
|
+
coverage checks; that is not a replacement for registering member accessors.
|
|
76
|
+
Duplicate registration fails. Do not omit a member or treat a
|
|
77
|
+
base descriptor as covering a derived runtime type. Missing declared metadata
|
|
78
|
+
fails with `ProtectedReadModelKeyAccessorMissing`.
|
|
79
|
+
|
|
80
|
+
Requires Arc 22.134.0 for `ReadProtection:RequireGeneratedMetadata` (false by
|
|
81
|
+
default). Enabling it rejects missing command/model metadata instead of using
|
|
82
|
+
reflection. `ProtectedReadModelKeyOptions.Strict` is also false by default;
|
|
83
|
+
strict composite matching or a restricted runtime requires exact accessors.
|
|
84
|
+
Untrimmed JIT can use the compatibility reflection path when strict mode is off.
|
|
85
|
+
ARC0030 is the composite coverage warning. Do not suppress it or promise
|
|
86
|
+
NativeAOT support for the unrelated dynamic validator opt-in.
|
|
87
|
+
|
|
88
|
+
## Specify the boundary
|
|
89
|
+
|
|
90
|
+
Cover a fresh allowed/denied validator, callback-added denial and exception,
|
|
91
|
+
refused DI graphs and cleanup failure, and repeated validation/execution without
|
|
92
|
+
reusing an instance. For keys, cover inherited/flattened members, exact derived
|
|
93
|
+
types, missing metadata under strict settings and generated versus compatibility
|
|
94
|
+
matching. An advisory Validate success is not proof that Execute commits.
|
|
@@ -187,6 +187,24 @@ Mark the corresponding property `[Json]`.
|
|
|
187
187
|
`migrationBuilder.GetDatabaseType()` is available when a migration genuinely has
|
|
188
188
|
to branch per provider.
|
|
189
189
|
|
|
190
|
+
## Tracked and native upserts
|
|
191
|
+
|
|
192
|
+
Requires Arc 22.135.0 for `DbSet<TEntity>.UpsertAsync(item, cancellationToken)`.
|
|
193
|
+
On supported SQL Server, PostgreSQL and SQLite mappings it executes an immediate,
|
|
194
|
+
parameterized native upsert matching the complete primary key, including composite
|
|
195
|
+
keys and value converters. Native key matching and writing are atomic. It uses
|
|
196
|
+
the context's connection/current transaction, bypasses tracking and does not
|
|
197
|
+
refresh generated values or already tracked instances. It adds no retry policy.
|
|
198
|
+
|
|
199
|
+
Use application-assigned keys and single-table scalar mappings. Unsupported
|
|
200
|
+
providers or mappings (including unset generated keys, SQL Server identity
|
|
201
|
+
columns, navigations, owned entities, shadow properties, inheritance and multiple
|
|
202
|
+
tables) fall back to tracked persistence and require `SaveChangesAsync`. The
|
|
203
|
+
existing `Upsert(item)` always uses tracked read-then-write persistence and also
|
|
204
|
+
requires saving; that path is not an atomic database upsert. Choose it explicitly
|
|
205
|
+
when deferred persistence is required. Do not rely on fallback for concurrency
|
|
206
|
+
protection or assume the native path flushes pending tracked changes.
|
|
207
|
+
|
|
190
208
|
## Observing an EF Core read model
|
|
191
209
|
|
|
192
210
|
`DbSet<T>` gains `Observe(filter?, configure?)`, `ObserveSingle(filter?, configure?)`
|
|
@@ -56,10 +56,12 @@ Sources: `Arc.Core/Queries/QueryStringQueryRequestReader.cs`,
|
|
|
56
56
|
|
|
57
57
|
## Which return shapes page
|
|
58
58
|
|
|
59
|
-
A query is an eligible public
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
A query is an eligible public static method on the `[ReadModel]` type,
|
|
60
|
+
discovered by its return type.
|
|
61
|
+
Requires Arc 22.121.0 for non-public statics to be
|
|
62
|
+
excluded even with `[Query]` (ARC0029 warns); older Arc exposes internal methods
|
|
63
|
+
as endpoints too. Read **cratis-chronicle-read-model**'s query reference for
|
|
64
|
+
explicit `[Query]` discovery and older-version limits.
|
|
63
65
|
|
|
64
66
|
| Return | Paged? | How |
|
|
65
67
|
| --- | --- | --- |
|
|
@@ -174,6 +176,11 @@ For composed MongoDB/EF observations, pass `ignoreQueryContext: true` to
|
|
|
174
176
|
auxiliary sources so only the primary consumes client paging/sorting and writes
|
|
175
177
|
totals. Single-instance observations emit `default` when absent, deleted or
|
|
176
178
|
outside the filter; guard `hasData`/`isReady` in React.
|
|
179
|
+
Requires Arc 22.117.1 for
|
|
180
|
+
`ObserveSingle`/`ObserveById` never to page or count; their retained
|
|
181
|
+
`ignoreQueryContext` argument has no effect. Use collection results for paging.
|
|
182
|
+
Read [live query processing](references/live-query-processing.md) for shared
|
|
183
|
+
MongoDB watches, emitted-value interception and calendar-bound answers.
|
|
177
184
|
Source: [MongoDB observations](https://github.com/Cratis/Arc/blob/main/Documentation/backend/csharp/mongodb/observing-collections.md).
|
|
178
185
|
|
|
179
186
|
## Consume it from the frontend
|
|
@@ -0,0 +1,71 @@
|
|
|
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
|
+
# Live query processing
|
|
5
|
+
|
|
6
|
+
## Shared MongoDB watches
|
|
7
|
+
|
|
8
|
+
Requires Arc 22.136.0. MongoDB `Observe()` uses a shared database-level watch keyed by deployment and
|
|
9
|
+
database rather than opening a collection watch for every observer. Each
|
|
10
|
+
observation keeps its filter, paging and tenant context.
|
|
11
|
+
Requires Arc 22.137.0 for observations of collections created by the caller's
|
|
12
|
+
own `MongoClient` to receive changes. The watcher derives the deployment key
|
|
13
|
+
from the database client instead of requiring prior registration. Joined observations coalesce refresh notifications into one pending
|
|
14
|
+
refresh and re-read every joined source. Snapshot read failures receive a
|
|
15
|
+
bounded retry burst; exhaustion waits for a later notification rather than
|
|
16
|
+
spinning or buffering unbounded work.
|
|
17
|
+
|
|
18
|
+
Watch reconnects resume from the token when possible and request a new snapshot
|
|
19
|
+
when the token cannot resume. The watch reopens before asking for snapshots so
|
|
20
|
+
writes during the read are still observed. Disposing one observer does not stop
|
|
21
|
+
the shared watch; disposing its subject or losing the last subscriber stops that
|
|
22
|
+
observation's refresh work and prevents a late emission. Shared watches do not
|
|
23
|
+
replace each subscription's cancellation and disposal.
|
|
24
|
+
|
|
25
|
+
## Intercept the emitted model, not its wrapper
|
|
26
|
+
|
|
27
|
+
Implement `Cratis.Arc.Queries.IInterceptReadModel<T>` with
|
|
28
|
+
`Task<T> Intercept(T readModel)`. Return a copy when transforming data that another
|
|
29
|
+
subscriber could share. A non-abstract open generic `IInterceptReadModel<T>`
|
|
30
|
+
implementation must target exactly its own type parameter; closed
|
|
31
|
+
implementations also work.
|
|
32
|
+
|
|
33
|
+
Interception runs for supported direct/hub streaming emissions and observable
|
|
34
|
+
HTTP snapshot/wait results in the requesting subscriber's scope and identity. Interceptors run before emission guards; a thrown interceptor
|
|
35
|
+
fails the result rather than exposing the untransformed value. Ordinary model
|
|
36
|
+
queries and Arc-wrapped MVC GETs also intercept results; `[AspNetResult]` opts
|
|
37
|
+
out of that result processing. Interceptors are transformations, **not access
|
|
38
|
+
control**. Filter rows/fields and authorize independently on every exposed path,
|
|
39
|
+
and specify snapshot, SSE/WebSocket and hub paths separately.
|
|
40
|
+
|
|
41
|
+
## Date-sensitive answers without data changes
|
|
42
|
+
|
|
43
|
+
Requires Arc 22.138.0 for `Cratis.Arc.Calendar`. Inject `IApplicationCalendar` and
|
|
44
|
+
pass an instant to `Read`; it does not read the clock. Zone precedence is an
|
|
45
|
+
operation-declared zone, then the first non-null `ICanProvideTenantCalendar`
|
|
46
|
+
answer, then `Cratis:Arc:Calendar:TimeZone` (default `UTC`). Headers and query
|
|
47
|
+
arguments cannot choose it. Configured and tenant-provider ids must be usable
|
|
48
|
+
IANA ids: unknown, Windows-only and nonzero fixed-offset ids fail with
|
|
49
|
+
`TimeZoneIsNotAnIanaZone`,
|
|
50
|
+
never a silent UTC fallback. Containers need time-zone data (`tzdata`).
|
|
51
|
+
|
|
52
|
+
A live "due today" answer needs candidates observed **without a clock-dependent
|
|
53
|
+
store filter**, or tomorrow's members will never enter the source. Use
|
|
54
|
+
`IClockBoundaries.Begin(tenant, operationZone, token)` to obtain a
|
|
55
|
+
`ClockBoundaryContext`, then `candidates.ReevaluateAtBoundaries(context,
|
|
56
|
+
(candidates, reading) => new ClockEvaluation<TAnswer>(answer, nextBoundary))`.
|
|
57
|
+
`LocalDateChanges.NextLocalDateChange(reading.Zone, reading.Instant)` handles
|
|
58
|
+
midnight, skipped dates and backwards date transitions. `reading.Today.AddDays`
|
|
59
|
+
steps calendar days; subtracting elapsed hours from the instant is different
|
|
60
|
+
across daylight-saving changes.
|
|
61
|
+
|
|
62
|
+
Every next boundary must be strictly after the evaluated instant or null;
|
|
63
|
+
otherwise the stream fails with `ClockBoundaryIsNotInTheFuture`. The first result
|
|
64
|
+
always emits; equal subsequent answers do not (collections compare in order).
|
|
65
|
+
Evaluation is serialized in the context's tenant. The zone is fixed at Begin;
|
|
66
|
+
application changes require restart and tenant-zone changes affect new
|
|
67
|
+
subscriptions. The operator connects on first subscription and disposes timer
|
|
68
|
+
and candidates on last unsubscribe, cancellation, error or completion. It does
|
|
69
|
+
not accept `OnNext`. Use the registered `TimeProvider` and a `FakeTimeProvider`
|
|
70
|
+
with `Advance` to specify boundary changes without sleeps. This is not a
|
|
71
|
+
continuously ticking `now` or an advanceable clock in query scenarios.
|
|
@@ -45,6 +45,17 @@ import { Dialog } from '@cratis/components/Dialogs';
|
|
|
45
45
|
import { DialogProps, DialogResult, useDialog } from '@cratis/arc.react/dialogs';
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
+
## Guid command fields
|
|
49
|
+
|
|
50
|
+
Requires Components 4.31.0 and matching Arc/Arc React 22.19.1 for GuidField invalid-draft execution blocking; check `yarn why @cratis/components` and `yarn why @cratis/arc.react`, or keep a host-validated field.
|
|
51
|
+
|
|
52
|
+
Opt into `GuidField` from `@cratis/components/CommandForm`. It binds native
|
|
53
|
+
Fundamentals `Guid` values, accepts partial text drafts and never generates an
|
|
54
|
+
identifier. Register it once through `registerFieldTypeProvider` for
|
|
55
|
+
`AutoCommandForm`; it is not a built-in provider. Invalid drafts clear the bound
|
|
56
|
+
value. Preserve host-set errors and use `resetKey` to discard an unchanged empty
|
|
57
|
+
value's draft.
|
|
58
|
+
|
|
48
59
|
## Initial focus
|
|
49
60
|
|
|
50
61
|
`DialogInitialFocus.Confirm` is the default and arms the confirm button, so a destructive dialog uses `DialogInitialFocus.Cancel`. Read [dialogs.md](references/dialogs.md) for the three options.
|
|
@@ -183,6 +183,21 @@ when omission is invalid for the selected query.
|
|
|
183
183
|
|
|
184
184
|
### `ConceptValidator<TConcept>`
|
|
185
185
|
|
|
186
|
+
Requires Arc.Kotlin 7.8.0 for shared Fundamentals concepts and their validators; check `./gradlew dependencies`, or retain the legacy Arc concepts and validators until upgrading.
|
|
187
|
+
|
|
188
|
+
Prefer `io.cratis.fundamentals.concepts.ConceptAs` for new concepts and
|
|
189
|
+
`FundamentalsConceptValidator<TConcept>` for their rules. It implements
|
|
190
|
+
`ModelValidator<TConcept>` and exposes `conceptType` plus
|
|
191
|
+
`validate(concept): List<ValidationResult>`; read the primitive via `value()`.
|
|
192
|
+
JSON, validation, proxy generation, Spring conversion, Chronicle bridging and
|
|
193
|
+
testing recognize the shared concept type. The old Arc `ConceptAs` extends it
|
|
194
|
+
and is deprecated, as is `ArcCamelCase` (use Fundamentals `toCamelCase`).
|
|
195
|
+
Existing Arc concepts/validators keep compiling and linking unchanged.
|
|
196
|
+
|
|
197
|
+
The legacy Arc concept example below remains valid with `ConceptValidator` and
|
|
198
|
+
its `value` property; do not copy that property shape to a new Fundamentals-only
|
|
199
|
+
concept, whose interface method is `value()`.
|
|
200
|
+
|
|
186
201
|
A reusable invariant on a `ConceptAs<T>` concept type, walked automatically
|
|
187
202
|
wherever that concept type appears — command, nested model, collection,
|
|
188
203
|
array, or map — without each owner repeating the rule. Matching uses
|
|
@@ -206,9 +221,11 @@ Jakarta `Validator` bean. Exclude one direct edge deliberately with
|
|
|
206
221
|
Java record component/field) whose *declared* type implements `ConceptAs`. A
|
|
207
222
|
scalar root, a collection element, or a nested path cannot be excluded this
|
|
208
223
|
way — register the nested owner type and its direct member instead. Excluding
|
|
209
|
-
an edge suppresses
|
|
210
|
-
`
|
|
211
|
-
run.
|
|
224
|
+
an edge suppresses concept-rule execution there, including
|
|
225
|
+
`FundamentalsConceptValidator`; owner rules, exact `ModelValidator` rules,
|
|
226
|
+
Jakarta constraints, and root typed validators still run.
|
|
227
|
+
|
|
228
|
+
Requires Arc.Kotlin 7.8.1 for exclusions to suppress FundamentalsConceptValidator; check `./gradlew dependencies`, or upgrade before relying on a shared-concept exclusion.
|
|
212
229
|
|
|
213
230
|
### `ModelValidator<T>`
|
|
214
231
|
|
|
@@ -60,6 +60,10 @@ Two things worth knowing before running it:
|
|
|
60
60
|
connection guidance in a repository-owned project context file; never patch
|
|
61
61
|
packaged or generated bytes.
|
|
62
62
|
|
|
63
|
+
Read [project tooling](references/project-tooling.md) for embedded release notes,
|
|
64
|
+
cached templates, managed MCP registration and install-only versus harness AI
|
|
65
|
+
conformance checks. Updating instructions does not run those behavior checks.
|
|
66
|
+
|
|
63
67
|
## Reach the right server
|
|
64
68
|
|
|
65
69
|
The connection string resolves in this exact order:
|
|
@@ -180,6 +184,10 @@ needs Chronicle 19.29.0 or later, resets the retry budget and retries unless `--
|
|
|
180
184
|
is given; handler side effects may repeat. `retry-partition` exits non-zero
|
|
181
185
|
when quarantined or not failed. `jobs resume` resumes Stopped jobs, not Failed.
|
|
182
186
|
|
|
187
|
+
Read [recovery outcomes and namespace comparison](references/recovery-and-comparison.md)
|
|
188
|
+
for refusal-aware job actions, retained-job deletion, observer-wide failed-partition
|
|
189
|
+
recovery, exact manual stream reopening and bounded metadata comparison.
|
|
190
|
+
|
|
183
191
|
## Before you change anything
|
|
184
192
|
|
|
185
193
|
Default to read-only inspection. A request to diagnose a live store does not
|
|
@@ -188,12 +196,13 @@ authorize replay, retry, removal, quarantine clearing, or another mutation.
|
|
|
188
196
|
These commands mutate the running store:
|
|
189
197
|
|
|
190
198
|
- `chronicle observers replay`, `replay-partition`, `retry-partition`,
|
|
191
|
-
`clear-quarantine`
|
|
199
|
+
`retry-failed-partitions`, `clear-quarantine`
|
|
192
200
|
- `chronicle observers remove` — destructive across every namespace of the event
|
|
193
201
|
store: definition, state, handled counts, failures and projection definition;
|
|
194
202
|
read model data stays. Refused while running or subscribed, no force flag.
|
|
195
203
|
- `chronicle observers clear-partition-quarantine` — may retry the handler
|
|
196
|
-
- `chronicle jobs stop`, `chronicle jobs resume`
|
|
204
|
+
- `chronicle jobs stop`, `chronicle jobs resume`, `chronicle jobs delete`
|
|
205
|
+
- `chronicle streams closed reopen` — exact manual scope repair with a reason
|
|
197
206
|
- `chronicle recommendations perform`, `chronicle recommendations ignore`
|
|
198
207
|
- `chronicle subscriptions add`, `chronicle subscriptions remove`
|
|
199
208
|
- `chronicle users add`, `chronicle users remove`
|
|
@@ -20,6 +20,7 @@ non-read-only commands.
|
|
|
20
20
|
| `workbench` | destructive | false (its actions have their own dialogs) |
|
|
21
21
|
| `applications add` | mutating | false |
|
|
22
22
|
| `applications remove` | destructive | true |
|
|
23
|
+
| `jobs delete` | destructive | true |
|
|
23
24
|
| `jobs resume` | mutating | true |
|
|
24
25
|
| `jobs stop` | mutating | true |
|
|
25
26
|
| `observers clear-partition-quarantine` | mutating | true |
|
|
@@ -27,14 +28,20 @@ non-read-only commands.
|
|
|
27
28
|
| `observers remove` | destructive | true |
|
|
28
29
|
| `observers replay` | destructive | true |
|
|
29
30
|
| `observers replay-partition` | destructive | true |
|
|
31
|
+
| `observers retry-failed-partitions` | mutating | true |
|
|
30
32
|
| `observers retry-partition` | mutating | true |
|
|
31
33
|
| `recommendations ignore` | mutating | true |
|
|
32
34
|
| `recommendations perform` | destructive | true |
|
|
35
|
+
| `streams closed reopen` | mutating | true |
|
|
33
36
|
| `subscriptions add` | mutating | false |
|
|
34
37
|
| `subscriptions remove` | destructive | true |
|
|
35
38
|
| `users add` | mutating | false |
|
|
36
39
|
| `users remove` | destructive | true |
|
|
37
40
|
|
|
41
|
+
See [recovery outcomes](recovery-and-comparison.md) for CLI/server floors and
|
|
42
|
+
acceptance versus completed work. `jobs delete` exits nonzero on declined/unavailable
|
|
43
|
+
confirmation; success means deletion requested, not completed removal.
|
|
44
|
+
|
|
38
45
|
The remaining Chronicle commands are cataloged read-only, including
|
|
39
46
|
`report-error`; the guard deliberately blocks that command because it opens an
|
|
40
47
|
external browser issue form. `chronicle version` is not a command in this
|
|
@@ -0,0 +1,91 @@
|
|
|
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
|
+
# CLI updates and project tooling
|
|
5
|
+
|
|
6
|
+
This complements live-store operations; it does not grant permission to install
|
|
7
|
+
servers, change a repository or run quota-consuming agent sessions. Inspect the
|
|
8
|
+
installed version with `cratis --version` and its catalog before using a flag.
|
|
9
|
+
|
|
10
|
+
## Inspect the upgrade, not a remembered bundle
|
|
11
|
+
|
|
12
|
+
Requires CLI 3.87.0 for offline embedded release notes:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
cratis release-notes --since <version> -o json
|
|
16
|
+
cratis release-notes --version <version>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`cratis update` displays the skipped releases after its update results. Requires
|
|
20
|
+
3.89.0 for `cratis new` to use the template set cached at `~/.cratis/templates`:
|
|
21
|
+
first use downloads from NuGet; offline use can reuse a complete cached set.
|
|
22
|
+
`cratis new cratis --language csharp --version <version>` selects a version for
|
|
23
|
+
one run rather than replacing the installed choice. `cratis update` refreshes
|
|
24
|
+
compatible templates without downgrading or failing the CLI update when refresh
|
|
25
|
+
fails; `--no-templates` skips it. CLI and template versions are separate. Do not
|
|
26
|
+
silently enable scaffold scripts; preserve the template's `--allow-scripts`
|
|
27
|
+
choice. Multi-service orchestration still needs explicit per-store settings.
|
|
28
|
+
|
|
29
|
+
For `cratis render` / `run`, read **cratis-screenplay-render-and-gap-fill** and
|
|
30
|
+
**cratis-stage-rendering-and-sandbox**. Their bundled renderer determines support;
|
|
31
|
+
a CLI upgrade can change admission, generated output and the default container
|
|
32
|
+
without changing the model. Never infer support from the ESM version alone or
|
|
33
|
+
edit generated output to make an older CLI accept it.
|
|
34
|
+
|
|
35
|
+
## Managed AI installation and MCP
|
|
36
|
+
|
|
37
|
+
Requires CLI 3.77.1 for `.pi/agents` to link to Pi-native corpus adapters when
|
|
38
|
+
available, falling back to canonical agents only for older corpora. Do not
|
|
39
|
+
hand-edit generated adapters to restore missing tools; update the CLI/corpus.
|
|
40
|
+
|
|
41
|
+
Requires 3.90.0 for profile-selected servers in the corpus's `mcp-servers.json` to
|
|
42
|
+
be registered by `cratis ai install` / `update` in Claude Code, Copilot, Cursor,
|
|
43
|
+
Codex and OpenCode. Installation registers configuration; it does not start the
|
|
44
|
+
servers. Deselecting/uninstalling removes only unchanged owned entries. Foreign
|
|
45
|
+
or modified entries remain conflicts, even with force. Resolve a conflict by
|
|
46
|
+
intentionally renaming/removing your entry or disabling that server with
|
|
47
|
+
`mcpServers.<id>.enabled = false` in the project configuration; do not overwrite
|
|
48
|
+
it speculatively. Pi supports only Screenplay through its native extension and
|
|
49
|
+
reports other servers unsupported. An invalid selected descriptor is reported
|
|
50
|
+
and skipped; successful guidance installation does not prove MCP availability.
|
|
51
|
+
Installing a server does not authorize its tools or commands.
|
|
52
|
+
|
|
53
|
+
## Deterministic AI checks versus harness behavior
|
|
54
|
+
|
|
55
|
+
Requires CLI 3.98.0 for opt-in `cratis ai test`. Each fixture × harness uses a
|
|
56
|
+
fresh temporary workspace with the fixture's selected profiles/languages; the
|
|
57
|
+
invoking repository is unchanged. It is **not** a security sandbox: fixture
|
|
58
|
+
commands and harnesses still have host tools/authentication. Trust the source,
|
|
59
|
+
request the intended session/budget, and keep transcripts off unless needed.
|
|
60
|
+
The default fixture root is `Evaluations/conformance`; `--fixtures` overrides
|
|
61
|
+
it, `--fixture` selects names, and `--harnesses claude,codex` narrows adapters.
|
|
62
|
+
`--output json` is this command's structured format, not proof of a passing run.
|
|
63
|
+
|
|
64
|
+
Requires 3.100.0 for install-only CI without a harness, credentials or model quota:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
cratis ai test --source <corpus> --install-only --output json
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
This runs install-phase checks for declared harness ids (or the configured ids
|
|
71
|
+
when a fixture declares none), narrowed by `--harnesses`. Result-phase checks
|
|
72
|
+
stay `not_run`; no install checks means skipped, not behavioral conformance.
|
|
73
|
+
Normal mode rejects missing/modified installations unless corpus-source mode is
|
|
74
|
+
selected. `--source`/`CRATIS_AI_SOURCE` selects a trusted local corpus.
|
|
75
|
+
|
|
76
|
+
Fixtures require a non-optional result check even in install-only mode. File
|
|
77
|
+
checks choose one path/glob; an empty glob match fails. Install checks cannot be
|
|
78
|
+
commands. A result command uses `run: ["executable", "argument"]` with no implicit
|
|
79
|
+
shell and cannot also declare file path/glob/pattern fields. Invalid check shapes
|
|
80
|
+
are errors. Paths and links cannot escape the workspace.
|
|
81
|
+
|
|
82
|
+
A timeout kills the process tree; output is capped. Requested `--timeout` and
|
|
83
|
+
`--max-budget-usd` can lower, not raise, fixture limits. Claude enforces a spending
|
|
84
|
+
limit; Codex reports that bound `not_enforced`. Missing harnesses/credentials are
|
|
85
|
+
skipped with a reason, never passed. Exit 0 can mean all skipped or no selected
|
|
86
|
+
runs: inspect counts and `no fixtures ran successfully`. Exit 1 means fixture,
|
|
87
|
+
harness or check failures/errors; exit 2 means usage/install errors. Installed
|
|
88
|
+
file hashes, observed tool reads and check results are separate evidence levels;
|
|
89
|
+
unknown reads remain unknown. `--keep-transcripts` retains best-effort-redacted
|
|
90
|
+
temporary output; inspect it for secrets before sharing. Passing install checks
|
|
91
|
+
is not proof that an agent read or obeyed the guidance.
|