Release digest: July 27 - August 3, 2026 (Week 31)
- Chronicle.Kotlin (Release v2.1.2): Documentation page snippets are compiled against the real library, so the pages cannot drift from the API again.
- Arc (Release v20.69.0): A quick fix for
ARCCHR0008, rewriting a command’s data annotations[Key]into the Chronicle one (#2303) - Stage (Release v1.1.0): Commands append the events their
producesdeclarations describe. The guardingwhencondition is evaluated against the incoming payload, and each event property is resolved from a command property, a constant, the occurred time, the calling identity, an environment variable, or an interpolated template. - Stage (Release v1.1.0): The event model intermediate format carries a command’s
producesdeclarations, so any consumer of the format — not just the host — can see which events a command appends and under what condition. - Stage (Release v1.1.0): The model’s event types are registered with Chronicle at startup, so a play session’s event types are listed in the Workbench and the projections reference types the kernel knows about.
- Chronicle (Release v16.13.0): Captures are persisted per event store and survive kernel restarts - started captures resume automatically on startup (#3560)
- Chronicle (Release v16.13.0): Start/Stop lifecycle for captures - a started capture runs on its poll interval via Orleans reminders and can not be changed until it is stopped (#3560)
- Chronicle (Release v16.13.0): The capturing engine polls API sources through their configured HTTP external service (basic, bearer and OAuth authorization), diffs items by the capture’s key property and appends events for added, removed, changed and value-transition when clauses (#3560)
- Chronicle (Release v16.13.0): Events ingested by a capture carry a
capturecausation andCapture+ capture-name tags (#3560) - Chronicle (Release v16.13.0): Getting events by tags - the event sequence read surface supports an any-of tags filter across MongoDB, SQL and in-memory storage (#3560)
- Chronicle (Release v16.13.0): Captures Workbench page persists to the kernel, shows live status, and has a data view showing the events a capture has ingested, with a toggle back to the editor (#3560)
- Chronicle (Release v16.13.0): The capture editor validates against the backend while typing - compiler errors and semantic problems such as unknown external services, event types or poll intervals show as markers - and completes external service and event type names (#3560)
- Chronicle (Release v16.13.0):
ICapturesservice contract with save, delete, start, stop, get, observe and validate-declaration operations (#3560) - Chronicle (Release v16.12.0): Several event types declared under the same constraint name form one constraint allowing at most one event from that set per event source, making mutually exclusive outcomes enforceable at append time.
- Chronicle (Release v16.12.0):
CHR0039warns when aTask-returning testing assertion is discarded rather than awaited, where it can never fail andCS4014does not fire. - Arc (Release v20.68.0): A command declares the key its read models are loaded by, in an application without Chronicle: a property marked with the data annotations
[Key], or anICanProvideKeyForCommandcomposing it. The key may be aGuid,int,long,string, or aConceptAs<T>wrapping one of those (#2303) - Arc (Release v20.68.0):
ICanResolveKeyForCommand, for keying commands your own way across an application. It is asked before the rule Arc ships, whichever order the two are discovered in (#2303) - Arc (Release v20.68.0):
ARCCHR0008reports a command marking its key with the data annotations[Key]in an application that uses Chronicle, where it silently resolves nothing (#2303) - Chronicle.Mcp (Release v1.3.2):
describe_systemtool that deduces the system in an event store — clustering event types into entities, placing every event in its entity’s lifecycle, and mapping read surfaces and automations — with narrative guidance for describing the system and telling its story - Chronicle.Mcp (Release v1.3.2):
suggest_next_event_typestool that finds lifecycle gaps (no explicit creation, a life without an end, facts frozen at creation) and suggests grounded event types to introduce next - Chronicle.Mcp (Release v1.3.2):
run_ad_hoc_projectiontool that folds events into per-event-source instances on demand with AutoMap semantics, answering ad-hoc queries without registering a projection - Chronicle.Mcp (Release v1.3.2): MCP prompts
describe_system,suggest_next_event_types, andquery_systempackaging the workflows for clients that surface prompts - Chronicle.Mcp (Release v1.3.2): Documentation for the new capabilities in the design-time docs, README, and getting started
- cli (Release v2.3.4):
cratis runreports startup progress while the Stage container boots and printsReadyonce the sandbox can actually accept requests. - cli (Release v2.3.4):
cratis run --verbosestreams the container’s output, as the command previously always did. - cli (Release v2.3.4):
cratis runwith-o jsonor-o json-compactemits the resolved endpoints, event model, and event store when the session becomes ready. - cli (Release v2.3.4): Markdown linting and link verification now run on pull requests that touch the documentation.
- Stage (Release v1.0.6): The Chronicle Workbench is now exposed from the Stage image on port
35000, so a play session’s events, observers and read models can be inspected while it runs. Publish the port and browsehttps://localhost:35000— the kernel’s API and OAuth authority are served there too. - Stage (Release v1.0.6): The container prints the session’s URLs — Stage API, API reference and Workbench — when it starts.
- Stage (Release v1.0.6): Documentation for both images and for a running session: what is inside them, how they boot, their ports, mount points and configuration, and every URL a session exposes.
- cli (Release v2.3.2):
cratis runnow publishes the Chronicle Workbench alongside the Stage API, so a play session’s events, observers and read models can be inspected while it runs. The Workbench is athttps://localhost:35000— sign in with the Stage image’s development credentials. - cli (Release v2.3.2):
--workbench-portoption oncratis runfor choosing the host port the Workbench is published on. - Chronicle (Release v16.11.0): New
defunctSiloCleanupPeriodanddefunctSiloExpirationclustering configuration settings controlling how often defunct silo entries are swept out of the Orleans membership table and at what age they are removed. Defaults: sweep every hour, remove entries older than three hours; set the period to00:00:00to disable the sweep. - Arc (Release v20.66.0): A read model backed by Entity Framework Core or MongoDB can be injected by key into a command’s
Handle(),Provide(), andCommandValidator<>, with nothing to wire up — an entity carried by aReadOnlyDbContextresolves by its primary key, a[ReadModel]held in MongoDB by its document_id. Nullable and non-nullable resolution behave as for a Chronicle-backed read model (#2303) - Arc (Release v20.66.0):
ICanResolveReadModelForCommand, for making the read models of another store injectable into a command the same way. A provider states whether it owns the read models it reports or can merely load them, so which one resolves a read model does not depend on registration order (#2303) - Arc (Release v20.66.0):
SP0041reports what an application says about how it is served and a Screenplay has no counterpart for: a query the host pages and sorts, and every route template declared with[Path],[Route]or an HTTP verb, including inherited ones (#2415) - Arc (Release v20.66.0):
SP0042reports the tags a read model carries, which the document has nowhere to hold while an event’s tags are printed (#2415) - Arc (Release v20.66.0): Chronicle 16.9.2:
ComplianceMetadataActionFailedreplaces the bareInvalidOperationExceptionwhen applying or releasing compliance metadata fails. On a failed release it names the property, the subject the value was released under, and explains that the value was encrypted under a different subject, pointing at CHR0038 — rather than surfacing only the underlying OpenSSLoaep decoding error. - Arc (Release v20.66.0): Chronicle 16.10.0:
[Replay]on a reactor handler method, marking it as the one to run while the observer is replaying. Only the marked handler runs during a replay; an event type without one behaves exactly as before. (cratis/chronicle#845) - Arc (Release v20.66.0): Chronicle 16.10.0:
IEventStore.IdentitieswithRename(subject, name), exposing the identity renaming the kernel already supported to the .NET client. (cratis/chronicle#1684) - Arc (Release v20.66.0): Chronicle 16.10.0:
[JsonSchemaType(typeof(T))]on a type, overriding how it is represented in the JSON schema generated for events and read models. Compliance metadata and nullability are preserved. (cratis/chronicle#1470) - Arc (Release v20.66.0): Chronicle 16.10.0:
AddCratisChronicleMongoDB()for Aspire, provisioning a MongoDB container that initiates itself as a single-node replica set and hands back adirectConnectionconnection string. (cratis/chronicle#3400) - Arc (Release v20.66.0): Chronicle 16.10.0:
IReactorMiddleware.BeforeInvokeandAfterInvokeoverloads that receive theReactorIdof the reactor observing the event. Chronicle calls these; they default to the existing overloads, so a middleware written against the previous interface keeps working unchanged. (cratis/chronicle#1009) - Arc (Release v20.66.0): Chronicle 16.10.0:
CompliancePropertyNotFoundInSchema, thrown when a property being applied or released has no counterpart in the schema. The message names the property path, the compliance subject, and the - AuthProxy (Release v2.10.2):
Cratis:AuthProxy:Sessionconfiguration section:Lifetime,SlidingExpiration,IdentityRevalidationInterval,TenantRevalidationInterval(zero/negative interval opts out), with documentation. - Arc (Release v20.65.4): Chronicle 16.9.2:
ComplianceMetadataActionFailedreplaces the bareInvalidOperationExceptionwhen applying or releasing compliance metadata fails. On a failed release it names the property, the subject the value was released under, and explains that the value was encrypted under a different subject, pointing at CHR0038 — rather than surfacing only the underlying OpenSSLoaep decoding error. - Arc (Release v20.65.4): Chronicle 16.10.0:
[Replay]on a reactor handler method, marking it as the one to run while the observer is replaying. Only the marked handler runs during a replay; an event type without one behaves exactly as before. (cratis/chronicle#845) - Arc (Release v20.65.4): Chronicle 16.10.0:
IEventStore.IdentitieswithRename(subject, name), exposing the identity renaming the kernel already supported to the .NET client. (cratis/chronicle#1684) - Arc (Release v20.65.4): Chronicle 16.10.0:
[JsonSchemaType(typeof(T))]on a type, overriding how it is represented in the JSON schema generated for events and read models. Compliance metadata and nullability are preserved. (cratis/chronicle#1470) - Arc (Release v20.65.4): Chronicle 16.10.0:
AddCratisChronicleMongoDB()for Aspire, provisioning a MongoDB container that initiates itself as a single-node replica set and hands back adirectConnectionconnection string. (cratis/chronicle#3400) - Arc (Release v20.65.4): Chronicle 16.10.0:
IReactorMiddleware.BeforeInvokeandAfterInvokeoverloads that receive theReactorIdof the reactor observing the event. Chronicle calls these; they default to the existing overloads, so a middleware written against the previous interface keeps working unchanged. (cratis/chronicle#1009) - Arc (Release v20.65.4): Chronicle 16.10.0:
CompliancePropertyNotFoundInSchema, thrown when a property being applied or released has no counterpart in the schema. The message names the property path, the compliance subject, and the properties the schema does declare. (cratis/chronicle#690) - Arc (Release v20.65.4): Chronicle 16.10.0: An overview on the
cratis/chronicleDocker Hub repository covering the published tag variants, ports, quick start and the environment variables that configure the server. (cratis/chronicle#1277) - Chronicle (Release v16.10.0):
[Replay]on a reactor handler method, marking it as the one to run while the observer is replaying. Only the marked handler runs during a replay; an event type without one behaves exactly as before. (#845) - Chronicle (Release v16.10.0):
IEventStore.IdentitieswithRename(subject, name), exposing the identity renaming the kernel already supported to the .NET client. (#1684) - Chronicle (Release v16.10.0):
[JsonSchemaType(typeof(T))]on a type, overriding how it is represented in the JSON schema generated for events and read models. Compliance metadata and nullability are preserved. (#1470) - Chronicle (Release v16.10.0):
AddCratisChronicleMongoDB()for Aspire, provisioning a MongoDB container that initiates itself as a single-node replica set and hands back adirectConnectionconnection string. (#3400) - Chronicle (Release v16.10.0):
IReactorMiddleware.BeforeInvokeandAfterInvokeoverloads that receive theReactorIdof the reactor observing the event. Chronicle calls these; they default to the existing overloads, so a middleware written against the previous interface keeps working unchanged. (#1009) - Chronicle (Release v16.10.0):
CompliancePropertyNotFoundInSchema, thrown when a property being applied or released has no counterpart in the schema. The message names the property path, the compliance subject, and the properties the schema does declare. (#690) - Chronicle (Release v16.10.0): An overview on the
cratis/chronicleDocker Hub repository covering the published tag variants, ports, quick start and the environment variables that configure the server. (#1277) - cli (Release v2.3.1):
cratis screenplay generateproduces a Cratis Screenplay.playdocument from the source of an Arc application, without running it (#44) - cli (Release v2.3.1):
cratis screenplay validatecompiles.playfiles and reports their diagnostics, exiting non-zero when any are errors - Arc (Release v20.65.2): The integration specifications a slice carries are recovered into
specificationblocks, so a document states what the application is specified to do rather than only what it declares; a scenario with a step that cannot be read statically is reported rather than guessed at (#2404) - Arc (Release v20.65.2): An application split across several projects is described as one document: a namespace two projects declare into is one slice, a concept is declared once however many projects refer to it, and an event a sibling project declares is declared rather than imported (#2399)
- Arc (Release v20.65.2): Events declared outside the application being read are imported by name, so a generated document no longer refers to an event it never introduces (#2394)
- Arc (Release v20.65.2): Concepts reached only through a child record or a read model property are declared, so their validation rules and personal-data marking appear in the document instead of going missing (#2400)
- Arc (Release v20.65.2): A validation message looked up from a resource is written as the key it is looked up by, so the document states which message a rule carries without baking one culture into it (#2409)
- Arc (Release v20.65.2): A screen binding a query declared in another slice is reported, naming the screen, the query and the slice it lives in, instead of being dropped without a word (#2396)
- Screenplay (Release v1.6.3): A general
@escape for names that collide with a directive keyword.@tag TagTypedeclares a property calledtag,@authorize AuthorizationCodea property calledauthorize,@validatean enumeration value calledvalidate, and@key = xa projection mapping ontokey. The escape already existed in projections and now works for property lines, property mappings, enumeration values and projectionfrommappings everywhere. (#27) - Screenplay (Release v1.6.2):
screenplay <file>.playcompiles a single file. Pointing the tool at a file previously failed withDirectory '<path>' does not exist, so verifying one generated document meant copying it into a scratch directory first. (#31) - Screenplay (Release v1.6.2):
--warnaserrormakes warnings fail the run with exit code1, so a pipeline that generates documents can require them to be clean. (#31) - Screenplay (Release v1.6.2):
IPlayFileCompiler.CompileFile(path)compiles one known.playfile without going through directory discovery. (#31) - Arc (Release v20.65.1): Generated documents are compiled before they are returned; one the Screenplay language rejects is reported as an error naming the first rejected line, so a host exits non-zero instead of writing a document that does not compile
- Arc (Release v20.65.0):
Cratis.Arc.Screenplaypackage that generates a Screenplay.playdocument describing an Arc application - concepts, policies, modules, features and slices, with the commands, events, queries, projections, reactors, constraints and screens in each - Arc (Release v20.65.0): Generation from source rather than from a running application, so a
.playfile can be produced from a checkout and regenerated in CI - Arc (Release v20.65.0): Generation from a Roslyn
Compilation, so the package can be driven from a CLI, an MSBuild task or a source generator - Arc (Release v20.65.0): Diagnostics naming any construct that has no Screenplay counterpart, and where it was found
- Arc (Release v20.65.0): Model-bound
[ChildrenFrom]and[Nested]projections are recovered, matching what the fluent form already produced (#2385) - Arc (Release v20.65.0): Named authorization policies are recovered, with their requirements read from
AddPolicyregistrations where those can be read (#2386) - Arc (Release v20.65.0): Aggregate roots are followed from the command that reaches them, so a handler that mutates an aggregate states the events it produces
- Arc (Release v20.65.0): Screens are declared for the component beside each slice
- Chronicle (Release v16.9.2):
ComplianceMetadataActionFailedreplaces the bareInvalidOperationExceptionwhen applying or releasing compliance metadata fails. On a failed release it names the property, the subject the value was released under, and explains that the value was encrypted under a different subject, pointing at CHR0038 — rather than surfacing only the underlying OpenSSLoaep decoding error. - Arc (Release v20.64.0): Optional
eventSourceFactoryprop on<Arc />(andGlobals.eventSourceFactory) that lets you substitute theEventSourceimplementation used by SSE observable query connections, falling back to the globalEventSourceconstructor when not set. This unblocks environments like React Native that lack a nativeEventSourceor need a more reliable native SSE client (#2376) - Arc (Release v20.64.0): Document
eventSourceFactoryin the Arc configuration reference and add a “Custom EventSource Factory” section with a React Native example - Chronicle (Release v16.9.1):
[PII]can now be applied to a value-object type, classifying every value it holds wherever that type appears. - Chronicle (Release v16.9.1):
[PII]can now be applied to a property typed as a value object, with the same effect scoped to that property. - Chronicle (Release v16.9.0):
CHR0038: a model-bound[Join<TEvent>]copying a[PII]value out of a stream that is not the read model’s own compliance subject is now an error at build time, instead of freezing every partition of the projection at runtime with an OpenSSLoaep decoding error. - Chronicle (Release v16.9.0):
InvalidDatabaseNamewhen the event store name and namespace compose a name MongoDB rejects, naming the event store, the namespace, and the offending character instead of the driver’s bareInvalid namespace specified. - Arc (Release v20.63.0):
TenantId.DefaultandTenantId.IsDefaultfor treating the default tenant — unset, or named — consistently across tenant-partitioned storage. - cli (Release v2.3.0):
CRATIS_NO_UPDATE_CHECKdisables the update check. - cli (Release v2.3.0): README GIFs, with the tapes and fixture that re-render them.
- Chronicle (Release v16.8.0): Benchmarks for projection, reducer and reactor throughput, projection replay, and passive-versus-materialized read models.
- Chronicle (Release v16.8.0): Benchmarks comparing a single silo against a two-silo cluster, including a split-role topology.
- Chronicle (Release v16.8.0): Startup warning when a clustered deployment is configured against local-only storage.
- Chronicle (Release v16.8.0): Clustering configuration documentation covering environment requirements, multi-node compose, and placement behavior.
- Chronicle (Release v16.8.0):
Jobs.StepCheckpointFlushInterval, bounding how long a job step may hold an unpersisted checkpoint. - Chronicle (Release v16.8.0):
ReadModels.GuardSinkWritesOnWatermark, the kill switch for the crash-recovery write guard. - Chronicle (Release v16.8.0):
Events.ConstraintsVersionCheckInterval, bounding how often an active event sequence checks for constraint changes. - Chronicle.Mcp (Release v1.3.0):
describe_event_typetool — an event type’s real fields and types, read from its registered schema. - Chronicle.Mcp (Release v1.3.0):
scaffold_read_modeltool — generates a reviewable read model + model-bound projection from chosen event types, surfaces existing projections that already read them, and returns no code (rather than a fabricated shape) when the requested event types are not registered. - Chronicle.Mcp (Release v1.3.0):
audit_unconsumed_event_typestool — reports event types nothing reads, plus consumers that reference an event type id that no longer exists. - Chronicle.Mcp (Release v1.3.0):
generate_event_catalogtool — a living data dictionary of every event type, its fields, and its consumers. - Chronicle.Mcp (Release v1.3.0):
explain_causal_tracetool — an event source’s ordered history with correlation and causation, for narrating what happened and why. - Chronicle.Mcp (Release v1.3.0): A Documentation folder covering getting started, configuration, how the server works, and a page per capability.
Changed
Section titled “Changed”- Arc (Release v20.69.2): Updated
Cratis.Chroniclefrom 16.10.0 to 16.13.3. - Arc (Release v20.69.2): Updated
Cratis.FundamentalsandCratis.Metrics.Roslynto 7.16.8, so a collection absent from a payload deserializes to an empty array rather thanundefined. - Chronicle (Release v16.13.2):
[OnceOnly]on a reactor handler method now takes effect — the handler is skipped for replayed events while the rest of the reactor still replays. Only class-level placement was honored before. - Chronicle (Release v16.13.2): The kernel now warns when it skips a concurrency check because the append declared a concurrency scope with no expected sequence number.
- Chronicle.Kotlin (Release v2.1.2): Getting started and reference pages now match the current client API — published
2.1.1coordinates,ChronicleOptions.development()/fromConnectionString, and the required event type registration step. - Chronicle.Kotlin (Release v2.1.2): Java examples use the
io.cratis.chronicle.javabridges, since every call into the kernel is a Kotlinsuspendfunction. - Chronicle.Kotlin (Release v2.1.2): The Docker Compose snippet starts a usable kernel: the development image with MongoDB storage on the single port Chronicle now serves.
- Chronicle.Kotlin (Release v2.1.2): Configuration reference documents the connection string grammar, its query options, and the real TLS and authentication behavior.
- cli (Release v2.4.0):
cratis screenplay generaterun against a solution now describes each application in it as its own module, taken from the outermost namespace segment, rather than gathering them all into one module named after the solution. Passing--modulestill produces that single module, and generating from a single project is unchanged. - Arc (Release v20.69.0):
ARCCHR0008says what happens if it is left alone — Chronicle resolves a new event source id for the command and every read model keyed by it resolves to nothing — and reports on the attribute rather than the property name (#2303) - Stage (Release v1.1.0): Each command execution appends to its own event source. Screenplay does not declare which command value identifies the event source, so events cannot yet be correlated across commands; that needs the language to say which property is the identity.
- Chronicle (Release v16.12.0): A
[PII]value that Chronicle never encrypted is passed through untouched when releasing, instead of being blanked. - Arc (Release v20.67.0): A Screenplay document generated from several projects now declares one module per outermost namespace segment, instead of gathering every project into a single module named after the solution. Naming a module still produces that one module, and generating from a single project is unchanged. (#2399)
- Fundamentals (Release v7.16.7): Subjects returned by
InvokeAndWrapWithSubjectandInvokeAndWrapWithTransformSubject, andTransformingSubjectitself, replay their most recent value to new subscribers. A subscriber attaching after a value has been produced now sees the current state rather than waiting for the next change. - cli (Release v2.3.5):
screenplay generatedescribes every project of a solution in one document, instead of reporting a solution that holds more than one project as ambiguous and generating nothing - cli (Release v2.3.5): The domain defaults to the solution name when several projects are read;
--domainstill overrides it - cli (Release v2.3.5): The generated result names the projects the document was generated from
- Chronicle.Mcp (Release v1.3.2): Updated all dependencies to their latest versions, including Chronicle 16.11.1 and the MCP SDK 2.0.0
- Chronicle.Mcp (Release v1.3.2): The default connection string is now
chronicle://localhost:35000— Chronicle 16.11 removed thedisableTlsflag; the client always uses TLS, withskipTlsValidationcontrolling certificate validation - Stage (Release v1.0.8): Upgraded
Cratis.Chronicle.Contractsfrom 16.10.0 to 16.11.1. - Stage (Release v1.0.8): [x]
dotnet build Stage.slnx(Debug) — 0 warnings, 0 errors - Stage (Release v1.0.8): [x]
dotnet build Stage.slnx -c Release(Release) — 0 warnings, 0 errors - Stage (Release v1.0.8): [x]
dotnet test Stage.slnx— all tests pass (68/68 in Contracts) - Chronicle (Release v16.11.1): Updated Cratis.Arc to 20.66.1 across NuGet and npm, picking up the fix for observable queries over primitive collections delivering empty values
- Chronicle (Release v16.11.1): The SimpleConsole sample generates its 50-employee demo data set on demand with the
Gkey instead of seeding it at startup - cli (Release v2.3.4):
cratis runhides the Stage container’s output while it starts, and shows the reported error plus the captured output if it stops before becoming ready. - cli (Release v2.3.4):
cratis runnames the container it starts, so a running sandbox is recognizable indocker ps. - cli (Release v2.3.4):
Ctrl+Concratis runstops the sandbox and waits for Docker to remove it before exiting, instead of terminating the command while the container is still running. - Stage (Release v1.0.7): The startup banner and the documentation now state that the Workbench port is HTTPS only, and name the empty-response symptom you get from using
http://. The kernel multiplexes HTTP/1.1 and HTTP/2 on that port through ALPN, which requires TLS, so there is no plaintext mode for it —https://localhost:35000is the address. - cli (Release v2.3.3):
cratis runnow states that the Chronicle Workbench is HTTPS only when it prints the URL, and the documentation names the empty-response symptom (ERR_EMPTY_RESPONSE,curl: (52) Empty reply from server) you get from reaching it ashttp://. The Chronicle port multiplexes HTTP/1.1 and HTTP/2 through ALPN, which requires TLS, so it has no plaintext mode. - cli (Release v2.3.2):
cratis runprints both the Stage API and the Chronicle Workbench URL when a session starts. - cli (Release v2.3.2): Package references updated to their latest releases, including Chronicle 16.11.0, Screenplay 1.6.4 and Fundamentals 7.16.6.
- cli (Release v2.3.2): The
disableTlsconnection-string option is replaced byskipTlsValidation, following Chronicle 16.11.0. The client always connects over TLS; the option now only controls whether the server’s certificate is validated, which is what lets the CLI trust a development server’s self-signed certificate. - Stage (Release v1.0.5):
cratis/stageandcratis/stage-specrunnerare now built from host-built, framework-dependent binaries and copied into the images, instead of compiling inside the Docker build — no more .NET compilation under QEMU emulation for the arm64 leg of the multi-arch publish. - Stage (Release v1.0.5):
dockerize.shmoves to the repository root and publishes both apps before building both images. - Stage (Release v1.0.2): The publish pipeline now also cuts a release when
.github/workflows/publish.ymlitself changes, so pipeline-only fixes (like this one) can ship without an unrelatedSource/change. - AuthProxy (Release v2.10.2): The auth session is bounded by an absolute lifetime (default 12h, configurable via
Cratis:AuthProxy:Session:Lifetime); sliding expiration is off by default so activity cannot extend a session indefinitely. The auth cookie remains session-scoped, so closing the browser ends it. - AuthProxy (Release v2.10.2): The identity-details cookie now expires after the identity re-validation interval (default 10 min), forcing periodic re-resolution of identity and authorization instead of living for the whole browser session.
- AuthProxy (Release v2.10.2): A tenant resolved through the selection strategy is re-validated against the tenants endpoint on an interval (default 10 min); when the tenant is no longer available to the user, the tenant cookies are cleared and the request replays through fresh resolution.
- AuthProxy (Release v2.10.2): Auth, correlation, and nonce cookies now use
SecurePolicy.SameAsRequestinstead ofNone. - Arc (Release v20.65.4):
Cratis.Chronicle,Cratis.Chronicle.AspNetCoreandCratis.Chronicle.Testingare updated to16.10.0 - Arc (Release v20.65.4): Chronicle 16.9.2:
CHR0038now also reports the fluentbuilder.Join<TEvent>(_ => _.On(...))form, not just the model-bound[Join<TEvent>]attribute. A[PII]value counts as reaching the read model through an explicit.Set(...).To(...)mapping or through AutoMap matching an identically named property. - Arc (Release v20.65.4): Chronicle 16.10.0: Registering event types on conn
- Chronicle (Release v16.10.0): Registering event types on connect issues one read and one bulk write for the whole batch instead of several round trips per event type, so startup no longer scales its database round trips with the number of event types. (#984)
- Arc (Release v20.65.2): A host compilation that does not fully compile is reported as an error only when nothing trustworthy was recovered from it; when artifacts were recovered anyway it is a warning stating how many, and generation succeeds instead of failing (#2393)
- Arc (Release v20.65.2): A specification value that is a freshly generated identity is no longer reported as unreadable, since an identity the source generates states nothing for the document to carry (#2404)
- Screenplay (Release v1.5.3): String literals now support the backslash escapes
\",\\,\n,\rand\t. Any other backslash sequence is kept verbatim, so regular expression operands such asmatches "^\d+$"keep their meaning. (#25) - Chronicle (Release v16.9.2):
CHR0038now also reports the fluentbuilder.Join<TEvent>(_ => _.On(...))form, not just the model-bound[Join<TEvent>]attribute. A[PII]value counts as reaching the read model through an explicit.Set(...).To(...)mapping or through AutoMap matching an identically named property. - Chronicle (Release v16.9.0): Documented Chronicle’s MongoDB database naming, including that read models of the default namespace use the bare event store name while event sequences suffix every namespace.
- Chronicle (Release v16.8.1): The Kernel serves the Workbench UI from the web root next to the binary as well as from the copy embedded in
Cratis.Chronicle.Workbench, using whichever is present - Chronicle (Release v16.8.1): The warning logged when no Workbench UI can be found now names the web root that was checked
- cli (Release v2.3.0): Generated
CHRONICLE.mdpoints connection troubleshooting atcratis chronicle diagnose. - cli (Release v2.3.0): Workbench Overview names the sidebar entry to reach failures and recommendations.
- Chronicle (Release v16.8.0): Reduced storage round-trips and CPU on the append, observer, and projection paths through event-type schema caching, debounced observer-state persistence, memoized projection key resolution, striped projection locking, subscribed-queue routing, and coalesced observer dispatch.
- Chronicle (Release v16.8.0): Appends no longer block on slow observer consumption; a full delivery queue spills to the observer catch-up path instead of applying backpressure.
- Chronicle (Release v16.8.0): Event batches are routed only to queues whose subscribed observers care about the batch’s event types, and queues prefer co-location with their event sequence.
- Chronicle (Release v16.8.0): Projections whose key collapses several partitions onto one read-model document now handle all partitions through a single activation.
- Chronicle (Release v16.8.0): Documentation no longer claims projections and reducers are idempotent across a crash; that guarantee covers a deliberate replay only.
- Chronicle (Release v16.8.0):
SaveChanges,ProjectionPipelineManagerandReducerPipelineFactoryeach take an additional constructor parameter, which is source-breaking for anyone constructing them directly. - Chronicle.Mcp (Release v1.3.0): Updated to the Chronicle 16.x client (
Cratis.Chronicle.Connections/.Contracts16.0.6).
- Fundamentals (Release v7.16.8):
JsonSerializergives a field declared as a collection an empty array when the property is missing from the payload, instead ofundefined. Producers legitimately omit empty collections, so readers previously needed a null guard on every collection to work around a value that contradicted its own declared type. An explicitnullstill deserializes asnull. - Chronicle (Release v16.13.3): The MongoDB event sequence storage narrows the tail sequence number by an actual event source type, and stops narrowing on the
Default/Unspecifiedsentinel. It had the check inverted, so asking for the tail of one event source type answered across every type, and asking for the tail of everything answered with only the events carrying the sentinel. - Chronicle (Release v16.13.3): The optimistic concurrency strategy reads the expected tail with the same narrowing it puts on the scope. It read the tail of the event source alone while the kernel validates through the scope’s stream type, stream id and event source type, so the two could disagree — reporting conflicts between independent appends, or missing real ones.
- Arc (Release v20.69.1): A command scoped with
concurrency: truenow actually participates in the concurrency check. The scope carries an expected sequence number resolved by the configured concurrency strategy, instead of a hardcodedEventSequenceNumber.Unavailablethat the kernel skipped. - Arc (Release v20.69.1): Declaring
concurrency: trueno longer leaves a command with weaker protection than declaring nothing. The scope it built was notNotSet, so it displaced the strategy the event sequence would otherwise have applied. - Arc (Release v20.69.1): The scope is bound to the event source being appended to. A null event source id made the kernel compute the tail across every event source sharing the type.
- Arc (Release v20.69.1): A command appending across streams gets a concurrency scope per target event source, instead of one scope carrying a single stream’s expected tail applied to all of them.
- Chronicle (Release v16.13.2): A 16.12 or newer kernel can now read constraint definitions written by an older kernel, so an in-place upgrade no longer breaks constraint registration and client startup.
- Chronicle (Release v16.13.2): Recovering a failed partition no longer clears it without re-running the handler, silently losing the missed side effect.
- Chronicle (Release v16.13.2): The observer management API’s
try-recover-failed-partitionandreplayroutes were swapped, so recovery replayed and replay retried. - Chronicle (Release v16.13.2): A job step that handled no events no longer overwrites the sequence number recorded by an earlier step that did.
- Chronicle.Kotlin (Release v2.1.2): Reducer examples take state as nullable, matching the
nullpassed for an event source’s first event. - Chronicle.Kotlin (Release v2.1.2):
@Projectionno longer documents areadModelparameter, which does not exist;@Pii,@FromEventand@SetFromdocument their missing parameters. - Chronicle.Kotlin (Release v2.1.2):
@Reactorand@ReducerKDoc states thatiddefaults to the class simple name, not the fully-qualified name. - Chronicle.Kotlin (Release v2.1.2): Documentation link verification no longer skips every link and reports success after scanning nothing.
- Stage (Release v1.1.0): Read models populate again. The sink the read models project into was identified by an invented GUID; Chronicle identifies sink types by well-known name, so every projection write was rejected as an unknown sink — surfacing as a failed observer partition rather than a registration error.
- Chronicle (Release v16.13.1): The Workbench lists event stores against in-memory and SQL storage. Each caller observing event stores now gets its own subject, so one client disconnecting no longer ends event store observation for every other client in the process.
- Chronicle (Release v16.13.1): The Workbench lists event types against in-memory storage. Registered event types are now read back —
GetLatestForAllEventTypes,GetForandGetAllGenerationsForEventTypereturned an empty sequence regardless of what had been registered, andObserveLatestForAllEventTypesreturned a subject that was never fed. An event type nobody registered still resolves to an empty schema, so unknown event content is preserved as before. - Chronicle (Release v16.13.1): Observable queries no longer lose the first value when their source emits it synchronously on subscribe, via
Cratis.Fundamentals7.16.7. Every observable query backed by in-memory storage produced its first value that way. - Chronicle (Release v16.13.0): SQL event storage silently dropped event tags on append; they are now persisted and returned when reading events (#3560)
- Chronicle (Release v16.12.0): Releasing a
[PII]value encrypted under a different subject no longer fails the whole read model and the query returning it. That property is surfaced as empty and the diagnostic goes to the Kernel log. - Chronicle (Release v16.12.0): Releasing a
[PII]value for a subject that never had an encryption key no longer returns an empty value indistinguishable from crypto-shredded erasure. - Arc (Release v20.68.0): Injecting a read model into a command no longer fails as a validation error in an application that has Entity Framework Core or MongoDB but no Chronicle (#2303)
- Fundamentals (Release v7.16.7): Observable queries no longer lose the value their source emits synchronously on subscribe.
InvokeAndWrapWithSubject,InvokeAndWrapWithTransformSubject, andTransformingSubjectnow buffer the most recent value, so the consumer that subscribes after wrapping still receives the current state. - Fundamentals (Release v7.16.7): The source subscription is now disposed when the wrapping subject completes, instead of leaking for the lifetime of the source.
- cli (Release v2.3.7): The update hint no longer stays silent for up to 24 hours after a release. An “up to date” answer is now re-checked within the hour, so a check that ran moments before a release no longer hides every release after it.
- cli (Release v2.3.7): Homebrew and other native installs are now checked against the GitHub releases they actually update from, rather than the NuGet package they never install.
- cli (Release v2.3.7):
cratis updatenow always asks the source rather than trusting a cached answer. - cli (Release v2.3.7): The update hint no longer goes missing after commands that take more than five seconds, such as
workbench,run, andscreenplay generate. - cli (Release v2.3.6):
cratis screenplay generatefailing withCould not load file or assembly 'Microsoft.CodeAnalysis.Workspaces', on both thedotnet toolpackage and the native downloads. - cli (Release v2.3.6):
cratis screenplay generatefailing withThe build host could not be foundon the native Homebrew and release downloads. - Arc (Release v20.62.6): Fixed an unbounded recursion that overflowed the stack and terminated the process when deserializing a read model with an interface- or abstract-typed polymorphic member (a [DerivedType] hierarchy) from MongoDB. The derived-type discriminator convention is now registered for the concrete derived types’ class maps as well, and an unresolvable polymorphic value now surfaces as a catchable exception instead of crashing the process.
- cli (Release v2.3.5): A project named exactly
SpecsorTestswas taken for part of the application, putting test-only artifacts in the document - Chronicle (Release v16.11.1): Workbench views fed by name collections — event store selection, namespaces, sequences, the namespace selector, and projection preview — show their data again instead of blank entries
- Chronicle (Release v16.11.1): Connected Clients shows one stable row per client instead of growing by one row per heartbeat
- Chronicle (Release v16.11.1): Time Machine loads snapshots instead of spinning on “Loading snapshots…” forever, and states it clearly when an instance has no snapshots
- cli (Release v2.3.4):
cratis runno longer leaves the container running when the command is interrupted without Docker being signalled too. - cli (Release v2.3.4): Documentation link verification checked nothing — skipping localhost also skipped the local server linkinator crawls through, so every run passed after scanning zero links.
- Arc (Release v20.66.1): Observable queries returning a collection of primitives (
string, numeric,bool) now deliver the actual values instead of empty ones, both for the initial payload and for change-set deltas - Arc (Release v20.66.1): Observable queries returning a single primitive value now deliver that value instead of an empty one
- Arc (Release v20.66.1): Observable queries that describe themselves with
Objectnow pass their payload through instead of losing it - Stage (Release v1.0.6): The specification runner container no longer fails when run without arguments. Its default
--modelpointed at/model/event-model.json, but a model is a folder of.playfiles, so the default is now the/modelfolder itself. - Chronicle (Release v16.11.0): Chronicle Server with MongoDB clustering now cleans up defunct silo membership entries automatically. Orleans ships with the cleanup disabled, so repeated restarts and failed rollouts accumulated dead silo entries forever, making joining nodes stall while validating against them.
- Stage (Release v1.0.5):
$causedBy.name/$causedBy.userName/$causedBy.subjectmappings in projections no longer fail registration withUnknown read model property expression '$causedBy(name)'— they now resolve through the event context’s causing identity. - Stage (Release v1.0.5): Composite projection keys (
key <Name>with parts) no longer fail registration — the Screenplay key type name is no longer emitted into the$composite(...)expression. - Stage (Release v1.0.5): A package-version-only bump (
Directory.Packages.props/Directory.Build.props) now triggers the publish workflow, so dependency updates can cut a release. - Stage (Release v1.0.3):
cratis/stage-specrunnerfailed to build in Release withCS0246: FactAttribute could not be found. The Dockerfile never copiedSource/Directory.Build.targets, the file that strips inline spec folders (for_*/,when_*/,given/) from Release builds, so the Screenplay event-model-loader specs were compiled without a test framework reference. - Stage (Release v1.0.2):
cratis/stageandcratis/stage-specrunnerare now built and pushed for bothlinux/amd64andlinux/arm64, fixingno matching manifest for linux/arm64/v8when pulling on arm64 hosts. - Chronicle (Release v16.10.0): Reading back a job whose request was not yet assigned no longer fails with a
NullReferenceException, losing the status and progress the job state was written to record. (#3541) - Chronicle (Release v16.10.0): Reducer failures are written to the client log. A reducer method that throws was reported to the kernel as a failed observation without ever appearing in the client’s own log. (#1395)
- Chronicle (Release v16.10.0): Applying or releasing compliance metadata for a property the schema does not declare no longer fails with a bare
Sequence contains no matching element. (#690) - Chronicle (Release v16.10.0): Applying or releasing compliance metadata no longer fails when a schema flattened across inheritance declares the same property name more than once. (#690)
- cli (Release v2.3.1): Projects whose resource classes are generated during the build are read correctly, instead of appearing not to compile (#49)
- cli (Release v2.3.1): The generated document is written even when generation reports errors, so a partial result can be inspected rather than lost (#49)
- Arc (Release v20.65.3): Roles declared with the
[Roles("...")]constructor form are read by the proxy generator, not only the named-argument form (#2381) - Arc (Release v20.65.2): A command handing work to an aggregate root declared in another project is read instead of failing (#2399)
- Arc (Release v20.65.2): Source written by the build no longer counts as part of a slice, removing incorrect reports of a slice being spread over several folders (#2395)
- Arc (Release v20.65.2): Names carrying separators read as words instead of running together, so a constraint named
unique-timesheet-startis written asUniqueTimesheetStart(#2398) - Arc (Release v20.65.2): A validation rule comparing one property against another is written as the comparison it is, rather than dropped as carrying no value (#2403)
- Arc (Release v20.65.2): A validation rule guarded by a condition names that condition when it is left out, so what was dropped can be read (#2403)
- Arc (Release v20.65.2): A validation message written as a lambda returning a constant is recovered; one that cannot be recovered now names the expression it could not read (#2397)
- Arc (Release v20.65.2): Personal data marking is applied to the value a collection holds, not only to properties holding it directly (#2401)
- Arc (Release v20.65.2): Commented-out imports in a component are no longer read as bindings the component makes (#2401)
- Arc (Release v20.65.2): Parameters the host supplies, such as cancellation and paging, are left out of what a query asks a caller for (#2401)
- Arc (Release v20.65.2): Accented characters survive in names instead of losing their accent (#2401)
- Screenplay (Release v1.6.4): The only analyzer warning left in the repository (
IDE0305). A Debug build is now clean, so a newly introduced warning is visible rather than lost next to a standing one. - Chronicle (Release v16.9.4): Two links in the concepts docs pointed at
/arc/backend/chronicle/aggregates/aggregate-root.md, which no longer exists — the Arc page isdefining-an-aggregate-root.md. This was breaking the Documentation site’s internal-links check. - Screenplay (Release v1.6.3): A command property named
description,validate,handlerorconcurrencyno longer fails to compile. Those directives take no operand, so a line with property shape is now read as a property;description "..."andvalidate csharpkeep their directive meaning. (#27) - Screenplay (Release v1.6.3):
tag TagTypein an event body no longer silently becomes a static tag and drops the property — it still declares the tag, but the compiler now warns that the line does not declare what it looks like and points at the@tagescape. (#27) - Screenplay (Release v1.6.3): A bare
validatein an enumeration concept no longer silently becomes an empty validate block that swallows the value — it still opens the block, but the compiler now warns and points at the@validateescape. (#27) - Screenplay (Release v1.6.3): The printer re-escapes names that collide with a directive keyword, so a document containing them survives print, compile and reprint. (#27)
- Screenplay (Release v1.5.3):
ScreenplayPrinterno longer emits culture-dependent numbers.decimal,float,intandlongliterals previously fell through to a culture-sensitiveToString()and printed5,5on a comma-decimal machine, producing text that failed to compile. (#25) - Screenplay (Release v1.5.3):
ScreenplayPrinternow escapes quotes and backslashes in every string it emits —description, validationmessage, screenlabelandtitle, seed group ids, specification errors, capture translations and separators, policy roles and claims, and tags. A value containing a"previously terminated the literal early and produced invalid output. (#25) - Screenplay (Release v1.5.3): Comment stripping and top-level splitting no longer treat an escaped quote as the end of a string. (#25)
- Chronicle (Release v16.9.3):
CHR0038no longer reports a fluent join when AutoMap cannot carry the value across —[NoAutoMap]on the read model, and[NoAutoMap]on the target property of a positional record, were both still reported. Since the rule is an error, each was a build break on correct code. - Chronicle (Release v16.9.1): A
[PII]concept held in a collection is now encrypted. It previously lost its classification and was stored in the clear, even though the same concept type was encrypted as a scalar. - Chronicle (Release v16.9.1): A compliance marker covering a whole value object now releases back into an object instead of a raw string, which previously left the read model unable to materialize.
- Chronicle (Release v16.9.1): A property covered by a compliance marker as a whole is no longer also descended into, which encrypted members whose mutations were discarded and, on release, decrypted members that were never separately encrypted.
- Chronicle (Release v16.8.1): The Workbench UI is reachable again in the published container images -
https://localhost:35000serves the Workbench instead of returning 401 - Arc (Release v20.63.0): A tenant named
Defaultnow resolves the unsuffixed MongoDB database, matching where Chronicle materializes the default namespace’s read models. Previously it resolved<database>+Default, which does not exist, so bothIMongoCollection<TReadModel>one-shot reads and.Observe()live queries returned no rows without erroring. - cli (Release v2.3.0): Chronicle commands in the generated
CHRONICLE.mdwere missing theirchroniclegroup and failed with “Unknown command”. - cli (Release v2.3.0):
cratis config showandcratis events haswere referenced in generated docs but do not exist. - cli (Release v2.3.0): Workbench opened with an empty content pane until the first keypress.
- cli (Release v2.3.0): Workbench AI description advertised number keys 1-9, which are not bound.
- cli (Release v2.3.0): README’s Linux install command returned 404; release assets carry the version in the filename.
- Chronicle (Release v16.8.0): Projection read models could be corrupted in a multi-silo cluster when replay and catch-up ran the read-modify-write cycle concurrently for a partition-collapsing key.
- Chronicle (Release v16.8.0): Accumulating projections and reducers no longer double-count events re-delivered by crash recovery, except where a resumed catch-up re-cuts the original batch boundaries.
- Chronicle (Release v16.8.0): Every replay job reported
CompletedWithFailures, because benign step-start outcomes were counted as failures and no failed-step record was written. - Chronicle (Release v16.8.0): Resuming a job reported a healthy running step as a failed resume, and reported genuine resume failures as successes.
- Chronicle (Release v16.8.0):
[Unique]could reject a value nothing held on in-memory storage, because changing a constrained value never released the previous one. - Chronicle (Release v16.8.0): Joined projection changes after the first were silently dropped, leaving a stale read model with no error.
- Chronicle (Release v16.8.0): Concurrent resolution of event-store and namespace storage could serve a stale event-type schema or leave two sinks for one read model with divergent replay state.
- Chronicle (Release v16.8.0): A cached event-type schema was nev
- Chronicle.Mcp (Release v1.3.1): The getting-started documentation linked to
../Source/docker-compose.yml, a repository file the aggregated docs site does not publish, which failed the site’s internal link check. It now links to the file on GitHub.
Removed
Section titled “Removed”- cli (Release v2.3.5): The
CLI0002ambiguous-project error, which no longer has a situation to report - Chronicle (Release v16.9.1):
PIIAppliedToNonConceptAsType— applying[PII]to a type that does not derive fromConceptAs<T>is now supported, so the exception can no longer be thrown. - Chronicle.Mcp (Release v1.3.0): The
ManagementPortoption and itsCHRONICLE_MANAGEMENT_PORTenvironment variable. In Chronicle 16.x the OAuth token endpoint is derived from the server address, so a separate management port is no longer used.
Security
Section titled “Security”- No updates
Deprecated
Section titled “Deprecated”- Arc (Release v20.69.0):
CommandContextExtensions.GetResolvedKey(CommandContext, IServiceProvider). A command’s key is now resolved while the command context values are being built, soGetResolvedKey()reads it without a service provider (#2303)