Skip to content

Total value purity: retire origin.* on object.value (one spelling of derived read shape) #210

Description

@dmealing

Summary

There are currently two spellings of "derived read shape": object.projection (+ origin.*, the SQL/read-model path) and object.value (+ origin.*, used for FR-004 prompt/template payloads). FR-024 §1 states outright that these arose "by accident of which feature shipped them," migrated one (entity+extends+view), and spared the other. The value spelling is a grandfathered compatibility spelling, not a principled category — and it leaves a permanent "why are there two?" seam every adopter re-asks.

The principled boundary (direction of data flow)

  • Projection = system-PRODUCED output. Derived from the entity graph, read-only at the subtype level, optionally addressable (borrowed identity ⇒ get-by-id) and/or materialized, referenced as an operation's outputRef.
  • Value = caller-CONSTRUCTED input / embedded shape. Command inputs, proc args (@parameterRef), embedded VOs whose storage belongs to the owning entity's field. Never populated, never sourced, never keyed; content equality.

A payload the framework assembles from Author.name + count(posts) + a nested collection is system-produced derived output — a projection by every test above. Calling its assembly "construction" stretches the population doctrine past usefulness (templates-and-payloads.md notes the payload codegen path is already shared with the projection path).

Proposal (pre-1.0, within ADR-0035's window)

  • Retire origin.* on object.value.
  • Let template.* @payloadRef accept sourceless projections.
  • Nested payload shapes become sourceless projections reached by origin.collection.

Then value purity becomes total — no identity, no source, no origins — so the value rule regime is trivially checkable (child-licensing, not conditional rules), and the ecosystem has exactly one spelling of "derived read shape."

Cost / benefit

Payload-VO codegen paths + conformance fixtures churn across 5 ports — but mostly node-type relabeling, since the payload path already shares the projection codegen path. Benefit: the projection/value boundary stops being a recurring question, and "value" becomes a clean, total-purity category. If the churn is declined, the fallback rule of thumb ("origins on a value are legal only inside template-payload assembly; any top-level, independently addressable derived read shape is a projection") leaves the seam permanently.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:metamodelMetamodel vocabulary / loaderenhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions