Summary
The projection sub-language (PDL) is the only way a document can define a read model, and it is declarative-only. Two read-model shapes that Arc supports as first-class citizens therefore cannot be described:
- Reducers — read models folded from events by code (
IReducerFor<T>). The fold logic legitimately lives in code; but the document cannot even say "this read model is reduced from these events by this file", the way reactor, constraint, and command handler already pair a declarative header with a file reference.
- Computed read models — models with no event feed at all, composed by querying over other read models. They surface in the document only as query return types, with no definition anywhere.
Evidence (real application)
Generating from Ada (Cratis.Arc.Screenplay 20.65.0):
- 9 ×
SP0020 [Warning] '<X>Reducer' folds events into '<X>' with code, which Screenplay has no counterpart for, so only the events it observes are stated (e.g. CustomerCandidateReportReducer, CustomerRequestWorkspaceReducer). The emission masquerades as a mapping-less projection — a reader cannot tell a reducer from an underspecified projection.
- 13 read models in the source are computed/query-only (compose over other read models) — they have no definition in the document at all.
Suggested direction
- A
reducer construct symmetric with the existing code-carrying constructs:
reducer CustomerCandidateReport => CustomerCandidateReport
on RequestCandidatePresented
on RequestCandidateWon
file CustomerPortal/Report/Report.cs
(observed events are declarative and validator-checkable; the fold stays in code, exactly like a reactor's handler.)
- For computed read models, at minimum a declaration that names the model and the read models it composes over (
readmodel X from Y, Z + file), so the document introduces every type its queries return.
Context
Found while validating a generated 5,348-line document from a production Arc application against its source. Related: #29 (complex value types), #30 (one projection per slice).
Summary
The projection sub-language (PDL) is the only way a document can define a read model, and it is declarative-only. Two read-model shapes that Arc supports as first-class citizens therefore cannot be described:
IReducerFor<T>). The fold logic legitimately lives in code; but the document cannot even say "this read model is reduced from these events by this file", the wayreactor,constraint, and commandhandleralready pair a declarative header with afilereference.Evidence (real application)
Generating from Ada (
Cratis.Arc.Screenplay20.65.0):SP0020 [Warning] '<X>Reducer' folds events into '<X>' with code, which Screenplay has no counterpart for, so only the events it observes are stated(e.g.CustomerCandidateReportReducer,CustomerRequestWorkspaceReducer). The emission masquerades as a mapping-less projection — a reader cannot tell a reducer from an underspecified projection.Suggested direction
reducerconstruct symmetric with the existing code-carrying constructs:(observed events are declarative and validator-checkable; the fold stays in code, exactly like a reactor's handler.)
readmodel X from Y, Z+file), so the document introduces every type its queries return.Context
Found while validating a generated 5,348-line document from a production Arc application against its source. Related: #29 (complex value types), #30 (one projection per slice).