You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ADR-0007 defines a paradigm-subtyped source catalog (rdb / document / search / … with per-paradigm @kind/@role); #195 rules that origin.* declares semantic intent and the SQL view is just one lowering ("anything that only makes sense for an RDB is a defect"). Both halves are accepted; the composition is missing. Today derivation is welded to source.rdb — SelectSpec → a SQL view only. This FR generalizes projection materialization from RDB-only to one derivation spec, N lowerings.
Unifying model
A projection = a declared field set (fail-closed exposure) + a semantic derivation graph (extends for shape, origin.* for data — pure, deterministic, backend-free per #195) + zero-or-more materializations (source.<paradigm> @kind @role). Materialization is a property, never the essence: the same node materializes as a SQL view, an Elasticsearch index, a Mongo view, or nothing (a wire-only DTO). FR-024 already says this for surfaces ("one projection serves multiple surfaces"); extend it to backends.
What maps cleanly
origin.passthrough = field mapping / denormalized copy. Universal.
origin.aggregate / origin.first = same semantic contract (deterministic reduction/argmax along @via, pinned empty-set/tie-break/null behavior); only the evaluation time differs — query-time (RDB view), refresh-time (matview), write/maintenance-time (search index). Generalize source-kinds.md's matview note into doctrine: evaluation/refresh discipline is a property of the materialization (@kind/@role), never of the derivation. A search index is, semantically, a materializedView in a different paradigm — the taxonomy already contains its hardest case.
origin.collection (nested view-objects) — never lowers to RDB view DDL (a payload-assembly concept today), but lowers natively to document/search (nested docs, ES nested mappings). The document paradigm completes the origin vocabulary rather than straining it.
What is legitimately per-backend (and what is NOT)
Per-backend: physical attrs (@index/@analyzer/@mappingsRef, exactly where @column/@schema live for rdb), lowerings, and an origin × (paradigm, @kind) capability matrix with load-time errors (e.g. origin.first on a paradigm that can't express argmax → a clear error, not silent omission — the lesson of extract-view-spec.ts:226-231). Not per-backend origin vocabularies or projection subtypes (a defect per #195). Search scoring/analyzers are physical/query-time, not derivation — they never touch the taxonomy.
Proposed first slice
Generalize SelectSpec → "one derivation spec, N lowerings."
Implement the first non-RDB materialization (source.document or source.search from the ADR-0007 catalog).
Ship the capability matrix with load-time errors.
Give origin.collection its first persisted lowering (document/search nested).
Summary
ADR-0007 defines a paradigm-subtyped source catalog (
rdb / document / search / …with per-paradigm@kind/@role); #195 rules thatorigin.*declares semantic intent and the SQL view is just one lowering ("anything that only makes sense for an RDB is a defect"). Both halves are accepted; the composition is missing. Today derivation is welded tosource.rdb—SelectSpec→ a SQL view only. This FR generalizes projection materialization from RDB-only to one derivation spec, N lowerings.Unifying model
A projection = a declared field set (fail-closed exposure) + a semantic derivation graph (
extendsfor shape,origin.*for data — pure, deterministic, backend-free per #195) + zero-or-more materializations (source.<paradigm> @kind @role). Materialization is a property, never the essence: the same node materializes as a SQL view, an Elasticsearch index, a Mongo view, or nothing (a wire-only DTO). FR-024 already says this for surfaces ("one projection serves multiple surfaces"); extend it to backends.What maps cleanly
origin.passthrough= field mapping / denormalized copy. Universal.origin.computed= per-row expression. Mongo$project1:1 (meta migrate: aggregate/monitoring read-model views can't be modeled as projections — 4 missing origin/field capabilities #195 already calls it the most portable construct).origin.aggregate/origin.first= same semantic contract (deterministic reduction/argmax along@via, pinned empty-set/tie-break/null behavior); only the evaluation time differs — query-time (RDB view), refresh-time (matview), write/maintenance-time (search index). Generalizesource-kinds.md's matview note into doctrine: evaluation/refresh discipline is a property of the materialization (@kind/@role), never of the derivation. A search index is, semantically, amaterializedViewin a different paradigm — the taxonomy already contains its hardest case.origin.collection(nested view-objects) — never lowers to RDB view DDL (a payload-assembly concept today), but lowers natively to document/search (nested docs, ES nested mappings). The document paradigm completes the origin vocabulary rather than straining it.What is legitimately per-backend (and what is NOT)
Per-backend: physical attrs (
@index/@analyzer/@mappingsRef, exactly where@column/@schemalive for rdb), lowerings, and an origin × (paradigm, @kind) capability matrix with load-time errors (e.g.origin.firston a paradigm that can't express argmax → a clear error, not silent omission — the lesson ofextract-view-spec.ts:226-231). Not per-backend origin vocabularies or projection subtypes (a defect per #195). Search scoring/analyzers are physical/query-time, not derivation — they never touch the taxonomy.Proposed first slice
SelectSpec→ "one derivation spec, N lowerings."source.documentorsource.searchfrom the ADR-0007 catalog).origin.collectionits first persisted lowering (document/search nested).