Code analysis
These ARCCHR#### Roslyn diagnostics belong to Arc’s Chronicle integration, not to standalone Arc or every project that references pure Chronicle. They catch integration mistakes while you build, so a misplaced key, ambiguous identity, or unsupported handler shape is visible before a request reaches production.
Rules overview
Section titled “Rules overview”| Rule | Severity | What it checks |
|---|---|---|
| ARCCHR0001 | Error | Recognized aggregate event-handler candidates have supported signatures. |
| ARCCHR0002 | Warning | Multiple candidate command identities without an explicit provider/recognized return exemption. |
| ARCCHR0003 | Warning | Reactor access to the default event log instead of returned side effects. |
| ARCCHR0004 | Warning | Redundant explicit id on [EventType]: empty, or equal to the type name. |
| ARCCHR0005 | Warning | Chronicle usage and AddCratisArc appear in one project without integration setup. |
| ARCCHR0006 | Warning | Manual reactor command execution without method- or class-level [OnceOnly]. |
| ARCCHR0007 | Warning | A command Handle() or Provide() parameter is IEventLog or an implementing type. |
| ARCCHR0008 | Warning | Data annotations [Key] used where Chronicle key resolution applies. |
| ARCCHR0009 | Warning | Likely secret command values lack audit exclusion metadata. |
| ARCCHR0010 | Warning | A keyless command returns a raw Guid beside statically identifiable untargeted events. |
| ARCCHR0011 | Info | Under Off, plain read-model parameters or IReadModels.GetInstanceById calls in event-producing command or validator code. |
| ARCCHR0012 | Info / Warning under On | Immediate appends beside protected decisions or under On. |
| ARCCHR0013 | Info | A command or aggregate root names an event source with [EventSourceType] and a definition with that name exists in the compilation. |
| ARCCHR0014 | Warning | A reactor or reducer is filtered with [FromEventSource<T>(stream)] to a stream the definition does not declare. |
| ARCCHR0015 | Warning | A model-bound command handler declares a nullable event, directly or in a supported awaitable/union branch. |
| ARCCHR0016 | Warning | concurrency: true on a stream-metadata attribute of a command whose Handle() returns EventsWithConcurrencyScopes. |
| ARCCHR0017 | Error | An [EventStreamId] template on a command names an unusable property or has malformed braces. |
| ARCCHR0018 | Warning | An [EventStreamId] template on a reactor, where it is used literally. |
| ARCCHR0019 | Warning | A conventional query resembling a read-model fold; discovery is unchanged. |
| ARCCHR0020 | Warning | A literal wrapper route names a stream its known definition does not declare. |
| ARCCHR0021 | Info | Legacy wrapper strings name a declared stream but drop its definition. |
| ARCCHR0022 | Warning | A command-key aggregate accompanies returned or appended events targeting a generated parameter. |
| ARCCHR0023 | Warning / Info | Distinguishing read-model keys with several or no matching command properties; repeated lookup keys. |
| ARCCHR0024 | Warning | Statically refused read shapes in Measure or On. |
| ARCCHR0025 | Warning / Info | Read-model or explicit Chronicle service dependencies in keyless event-producing commands. |
| ARCCHR0026 | Info / Warning under On | MongoDB collection parameters containing recognizable Chronicle-backed models. |
| ARCCHR0027 | Warning | A visible OnRefused callback returns a statically invalid refusal production. |
| ARCCHR0028 | Warning | Raw Chronicle reads and explicit read bypasses under On. |
| ARCCHR0029 | Error | Conflicting protected and advisory declarations. |
| ARCCHR0031 | Error | Invalid explicit LookUpBy property or non-model parameter. |
| ARCCHR0032 | Info | Inert or redundant declarations. |
| ARCCHR0033 | Warning | Aggregate and protected plain read on the same key under On. |
| ARCCHR0034 | Info | Method-level advisory does not cover read parameters. |
| ARCCHR0035 | Warning | Early aggregate commit under On. |
| ARCCHR0036 | Warning | Exact scope coverage of a protected read is not proven, including validator-first stream reads. |
| ARCCHR0037 | Error | Per-stream model parameter does not match the command route, or uses LookUpBy. |
| ARCCHR0038 | Info | Per-stream model guard widens through another read or declared concurrency. |
| ARCCHR0040 | Info | Prefer a read-model parameter over a direct decision-reader or token parameter. |
ARCCHR0039 was removed and its ID is retired; it is never reused. A command’s Handle() may take any dependency, including IDecisionReads and DecisionRead<T>. ARCCHR0040 offers Info-only guidance for those two direct parameters; it imposes no dependency restriction and can be suppressed with a reason for an acquisition gap.
A command that has [EventStreamId(value)] and also implements ICanProvideEventStreamId is reported by Chronicle’s own analyzer as CHR0027, not by an Arc rule. [EventStreamId("")] and [EventStreamId(null)] declare no id, so ARCCHR0017 stays silent for them.
Quick fixes
Section titled “Quick fixes”| Rule | Fix |
|---|---|
| ARCCHR0008 | Rewrite to the fully qualified Chronicle Key attribute. |
| ARCCHR0010 | Compiler-checked local replacement with EventSourceId<Guid> for supported direct tuple syntax. |
| ARCCHR0013 | Replace matching source/stream attributes with a typed event source definition. |
| ARCCHR0031 | Use nameof for a nearby command lookup property. |
| ARCCHR0021 | Replace legacy wrapper route strings with the matching definition and stream. |
| ARCCHR0015 | Compiler-checked replacement of a nullable event with an explicit event-or-validation result and rejection placeholders. |
| ARCCHR0016 | Remove concurrency: true from the attribute. |
| ARCCHR0019 | Preview whole-type explicit query selection, retaining intended endpoints. |
The other rules have no automatic fix. A fix can change behavior: in particular ARCCHR0010 changes the persistence target when the Guid was an ordinary response.
Installation
Section titled “Installation”Install the optional Arc integration package:
dotnet add package Cratis.Arc.ChronicleIt brings in Cratis.Arc.Chronicle.CodeAnalysis, which supplies these analyzers and code fixes. Complete the integration setup to connect Arc’s command pipeline to Chronicle.
Pure Cratis.Chronicle provides event sourcing without Arc; referencing it alone does not install Arc’s integration diagnostics. If a diagnostic is missing, check that your application’s resolved dependencies include Cratis.Arc.Chronicle.CodeAnalysis.