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
{{ message }}
Repository navigation
Retire assembly origins on object.value (one spelling of derived read shape) — RULED: batch into the pre-1.0 consolidation #210
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.
Ruling (2026-08-05): DO IT — but not yet, and not as written
Trigger: the close of the Phase-1 feedback window, landed as part of the single pre-1.0
breaking-consolidation batch. Never as a standalone release. If nothing else breaking has
surfaced within ~90 days of the launch, it ships alone as that batch.
Scope — narrower than the original proposal
The proposal above retires allorigin.* on object.value. That is broader than the doctrine
the loader already encodes, and broader than the seam actually justifies.
Retire the ASSEMBLY origins on values — origin.aggregate, origin.computed, origin.collection, origin.first become illegal on a value-hosted field (a new ERR_SUBTYPE_RULE_VIOLATION case).
Keep origin.passthrough on values. FR-015 parameter VOs (source.rdb @parameterRef)
stay exactly as they are. The loader already draws this line — validation-passes.tsvalidateOriginPaths:
FR-024 B5: object.value hosts are EXEMPT from @via inference and cardinality checks —
a value's origin.passthrough is FR-015 parameter lineage (values are constructed,
never assembled; spec §7), not an assembly path.
A proc arg is caller-constructed input; routing it through object.projection would violate
the direction-of-flow principle this issue itself invokes. Retiring its lineage would also
silently drop the _checkPassthroughType / ERR_PASSTHROUGH_TYPE_MISMATCH type-preservation
check on proc args — a real regression, not a cleanup.
Widen @payloadRef / @responseRef to accept an object.projection carrying zero source.* children. Today this is a hard check on OBJECT_SUBTYPE_VALUE
(validation-passes.ts, gated by fixtures/conformance/error-template-payload-ref-not-value,
whose meaning flips).
No new vocabulary required.origin.collection is already registered (required @via),
and a sourceless projection loads legally today — validateProjectionLicensing has no
source-required rule and validateDerivedFieldProvidability exempts projections. This sits in
the ADR-0046 / Non-persisted shapes (messages/DTOs) can't declare field-level references to entities #238 cost class: a child-licensing + validation-rule change.
But expected-registry.json DOES change.object.value's rules string reads
"constructed — by a caller, by assembly, or by embedding". That string is byte-checked, so
all five ports' embedded definitions sync in lockstep.
Drop the "total value purity" framing. It was never achievable: ADR-0046's @enforce: false
navigation-only reference already made value rules conditional, and parameter lineage keeps them
so. The post-ruling rule is better because it is subtype-scoped rather than context-scoped:
Passthrough on a value is lineage. Assembly origins live on projections.
Why do it at all
Near-zero usage, and that only worsens. A scan of every conformance fixture, the examples/ tree and the public reference app found a handful of fixture dirs and one teaching
example (examples/advanced-modelingProgramDescriptionPayload). The reference app — the
heaviest prompt-pillar consumer, 18 files of payload VOs — uses zero. Migration cost is at
its historical minimum.
This is a live behavioral divergence, not a prose seam. Payload-origin handling already
differs across ports: Kotlin (KotlinPayloadGenerator) and Python (payload_vo_generator)
resolve origins for payload field typing; TS and C# are origin-blind; Java carries a standing KNOWN_GAPS deferral. It is only benign because verify: origin.passthrough field type must match its source unless an explicit transform is declared #185's ERR_PASSTHROUGH_TYPE_MISMATCH makes
origin-derived typing redundant with declared typing. That debt gets paid either way — finished
in five ports, or retired in five. Retiring is strictly cheaper and deletes the open question.
Declining does not avoid the cost, it defers it into a post-1.0 world where it becomes a
Metamodel 2.0 event.
Why not now
"Mostly node-type relabeling" is half true. Fixture churn is trivially small. The code churn
sits in the payload tier — this repo's recent cross-port bug hotspot (ADR-0044 #219/#220 took
three stages; #228 found the extract tier resolving payload refs package-blind, both latent behind
green suites). The riskiest piece: every port's projection fan-out must cleanly no-op on a sourceless projection, and #248 ("persistability derives from a declared source.*") shipped npm-only, so four ports have never seen one.
Honest estimate: comparable to #228 plus a breaking loader rule — a 1–2 week focused effort with
the no-mistakes gate, with the real risk concentrated in the four non-TS ports' dispatch rather
than in diff size. That is not work to discover during a launch that showcases the prompt pillar.
Sequencing
Phase-1 launch ships first, untouched, on 0.20.x.
During the feedback window, land two free, non-breaking preludes that de-risk the real
work (filed separately, both blocking this issue):
Then this rides the one pre-1.0 consolidation batch, before any quiet-period declaration.
ADR-0035 §3: a breaking move during the run-up restarts the quiet-period clock, so it must be
batched, and it must land while 1.0 remains unscheduled — which it explicitly is.
What would reverse this ruling
Phase-1 feedback showing real adopters authoring assembly origins on payload VOs. Each one
raises migration cost and argues the pattern is loved rather than vestigial; more than a couple
→ decline and document the rule-of-thumb instead.
1.0 being scheduled imminently off strong Phase-1 signal. Then the seam is not worth restarting
the clock: ship 1.0, document the rule-of-thumb, and let this be a 2.0 candidate.
changed the title [-]Total value purity: retire origin.* on object.value (one spelling of derived read shape)[/-][+]Retire assembly origins on object.value (one spelling of derived read shape) — RULED: batch into the pre-1.0 consolidation[/+]on Aug 5, 2026
Preludes filed and blocking this issue: #270 (retire redundant payload origin-typing in Kotlin/Python, close Java's KNOWN_GAPS entry as moot) and #271 (port #248's persistability-from-source contract cross-port; prove each fan-out no-ops on a sourceless projection). #271 also carries the falsification signal — if any port needs new vocabulary to handle a sourceless projection, it reopens this ruling.
Batch scope note: the pre-1.0 consolidation batch this issue rides now also carries the @role registry change from #212 — removing publish from source.rdb @role's allowedValues (live in expected-registry.json, spec/metamodel/db.json, and five ports' embedded definitions), and possibly the wider shrink to primary | replica pending the sub-decision recorded there. Same class as this issue's object.valuerules-string change: lockstep across five ports, technically breaking, zero fixtures affected. Batching them means one window, one review.
Batch scope, updated: the @role change riding this batch is now the full shrink to primary | replica (ruled on #212), not just the publish removal. Cross-port verification closed the gate — every read of @role in all five ports is an equality test against primary; Java OMDB has zero role usage, and Kotlin/Python's write-through read paths are explicitly documented "role-agnostic" (they find the replica by @kind). index/cache/publish/mirror become reserved-not-registered per the ADR-0040 precedent. One pre-landing check inherited from that ruling: these are shipped registered members, so re-run ADR-0036's adopter scan plus the public reference app before removing them — zero uses were verified in this repo only.
Correction to this ruling's prelude framing. It describes #270 as "output-identical post-#185." That is false, and the correction makes the prelude more necessary rather than less.
#270 is a bug fix: Kotlin's and Python's payload origin.collection handling discards the field's declared @objectRef and substitutes the @via relationship's entity shape, so a declared curated VO silently becomes the full entity — defeating the payload-bloat contract this pillar exists to enforce. TypeScript's origin-blindness is the correct baseline, not the gap. Full recon on #270.
Bearing on this issue: #210 does not subsume #270, and the dependency direction is unchanged. Post-#210, @payloadRef widens to sourceless projections whose fields are also explicitly declared, so declared-driven payload emission is the right contract through and after the transition — no port ever needs payload-tier origin typing.
One item to fold into this batch's scope:validateOriginPaths has no origin.collection branch at all — collection is the one origin subtype whose declared-vs-derived agreement the loader never checks, which is exactly why the Kotlin/Python divergence went unnoticed. Since this batch retires assembly origins (including collection) from object.value, the validation gap dies with it on values; if collection remains reachable on projections, the agreement check belongs here rather than as a separate issue.
Shipped in 0.21.0 / 7.21.0 — a coordinated MINOR across all four registries (npm 0.21.0 · PyPI 0.21.0 · NuGet 0.21.0 · Maven 7.21.0), the pre-1.0 breaking slot.
Merged as #276; commits 6c73e77a → e0e561ab → 9c4fbadd → 286bba78 → 03a7eed7. local-ci green 9/9 on the merge SHA.
origin.aggregate, origin.computed, origin.collection and origin.first on an object.value-hosted field now fail load with ERR_SUBTYPE_RULE_VIOLATION in all four loaders. origin.passthrough stays legal on a value, exactly as the ruling required — there it is FR-015 parameter lineage, not assembly, and retiring it would have silently dropped the ERR_PASSTHROUGH_TYPE_MISMATCH check on stored-proc arguments. The durable rule is now encoded in ADR-0028: "passthrough on a value is lineage; assembly origins live on projections."
The migration path is additive: @payloadRef/@responseRef accept a sourceless object.projection, so a payload that was assembling values re-hosts as a projection and keeps its origins.
Implementation note worth recording. Rather than patching four subtype branches per port, the ban is one named ASSEMBLY_ORIGIN_SUBTYPES set hoisted above the origin dispatch in every loader — so cross-port coverage is a property of the constant rather than of locating four sites, and a future fifth assembly origin is caught automatically. Both TS and Python tests assert set-equality between their fixture tables and that constant, closing a children: [undefined] vacuity hole. Now-unreachable value-host arms were removed with comments naming why, not left behind.
A third breaking change surfaced in review
The ruling anticipated two. Final review found a third: a payload's nested field.object @objectRef must now target an object.value. TypeScript, C# and Python did not filter nested targets before — that shape loaded and emitted a nested interface from the entity. It is now a fail-closed loader rule (one rule, four loaders) rather than five per-port codegen filters, reusing ERR_SUBTYPE_RULE_VIOLATION. It carries its own section and rewrite rule in the guide.
An independent adjudication earlier in this batch is why it landed in the loader: filtering one port's payload closure without its extract closure would have emitted mappers constructing classes that no longer exist — strictly worse than the bloat it removed.
Also fixed, found by the release gate
runner.ts's dbImport/dialect guard keyed on subType !== OBJECT_SUBTYPE_VALUE, so a sourceless projection — the shape this release's own migration guide tells adopters to create — would have demanded database config and thrown (Only a value-object-only model may omit them.) for an object that provably emits zero DB code. It now keys on hasAnyRdbSource, which is #248's persistability-from-source doctrine and was the last subtype-based persistability check in the codebase. Regression test covers the exact migration-guide shape.
Preludes
Both closed. #270 shipped in 0.20.16 (and turned out to affect Java too, which its own text had recorded as a correct reference port). #271 was discharged — its premise was falsified by recon; every port already accepted a sourceless projection with no new vocabulary, retiring this ruling's ADR-0023 falsifier.
Gates
No new vocabulary, attributes or error codes (ADR-0023). Registry manifest diff confined to three object.value/object.projection doctrinal strings. All codegen golden output and every Kotlin snapshot byte-identical — including the re-hosted payload-with-origins snapshot, which regenerated byte-for-byte because #270 had already made those emitters declared-type-authoritative. Conformance corpus 262 → 270.
Seven new fixtures for this issue: error-value-origin-{aggregate,collection,computed,first}, template-payload-ref-sourceless-projection, error-template-payload-ref-sourced-projection, error-payload-nested-object-ref-entity.
Activity
docs(roadmap): track the projection/view-materialization epic (#206-212)
dmealing commentedon Aug 5, 2026
Ruling (2026-08-05): DO IT — but not yet, and not as written
Trigger: the close of the Phase-1 feedback window, landed as part of the single pre-1.0
breaking-consolidation batch. Never as a standalone release. If nothing else breaking has
surfaced within ~90 days of the launch, it ships alone as that batch.
Scope — narrower than the original proposal
The proposal above retires all
origin.*onobject.value. That is broader than the doctrinethe loader already encodes, and broader than the seam actually justifies.
Retire the ASSEMBLY origins on values —
origin.aggregate,origin.computed,origin.collection,origin.firstbecome illegal on a value-hosted field (a newERR_SUBTYPE_RULE_VIOLATIONcase).Keep
origin.passthroughon values. FR-015 parameter VOs (source.rdb @parameterRef)stay exactly as they are. The loader already draws this line —
validation-passes.tsvalidateOriginPaths:A proc arg is caller-constructed input; routing it through
object.projectionwould violatethe direction-of-flow principle this issue itself invokes. Retiring its lineage would also
silently drop the
_checkPassthroughType/ERR_PASSTHROUGH_TYPE_MISMATCHtype-preservationcheck on proc args — a real regression, not a cleanup.
Widen
@payloadRef/@responseRefto accept anobject.projectioncarrying zerosource.*children. Today this is a hard check onOBJECT_SUBTYPE_VALUE(
validation-passes.ts, gated byfixtures/conformance/error-template-payload-ref-not-value,whose meaning flips).
No new vocabulary required.
origin.collectionis already registered (required@via),and a sourceless projection loads legally today —
validateProjectionLicensinghas nosource-required rule and
validateDerivedFieldProvidabilityexempts projections. This sits inthe ADR-0046 / Non-persisted shapes (messages/DTOs) can't declare field-level references to entities #238 cost class: a child-licensing + validation-rule change.
But
expected-registry.jsonDOES change.object.value'srulesstring reads"constructed — by a caller, by assembly, or by embedding". That string is byte-checked, so
all five ports' embedded definitions sync in lockstep.
Drop the "total value purity" framing. It was never achievable: ADR-0046's
@enforce: falsenavigation-only reference already made value rules conditional, and parameter lineage keeps them
so. The post-ruling rule is better because it is subtype-scoped rather than context-scoped:
Why do it at all
examples/tree and the public reference app found a handful of fixture dirs and one teachingexample (
examples/advanced-modelingProgramDescriptionPayload). The reference app — theheaviest prompt-pillar consumer, 18 files of payload VOs — uses zero. Migration cost is at
its historical minimum.
differs across ports: Kotlin (
KotlinPayloadGenerator) and Python (payload_vo_generator)resolve origins for payload field typing; TS and C# are origin-blind; Java carries a standing
KNOWN_GAPSdeferral. It is only benign because verify: origin.passthrough field type must match its source unless an explicit transform is declared #185'sERR_PASSTHROUGH_TYPE_MISMATCHmakesorigin-derived typing redundant with declared typing. That debt gets paid either way — finished
in five ports, or retired in five. Retiring is strictly cheaper and deletes the open question.
Metamodel 2.0 event.
Why not now
"Mostly node-type relabeling" is half true. Fixture churn is trivially small. The code churn
sits in the payload tier — this repo's recent cross-port bug hotspot (ADR-0044 #219/#220 took
three stages; #228 found the extract tier resolving payload refs package-blind, both latent behind
green suites). The riskiest piece: every port's projection fan-out must cleanly no-op on a
sourceless projection, and #248 ("persistability derives from a declared
source.*") shippednpm-only, so four ports have never seen one.
Honest estimate: comparable to #228 plus a breaking loader rule — a 1–2 week focused effort with
the no-mistakes gate, with the real risk concentrated in the four non-TS ports' dispatch rather
than in diff size. That is not work to discover during a launch that showcases the prompt pillar.
Sequencing
0.20.x.work (filed separately, both blocking this issue):
KNOWN_GAPSentry as moot (output-identical post-verify: origin.passthrough field type must match its source unless an explicit transform is declared #185);
subType === "value"compare — any custom object subtype silently becomes a table #248's persistability-from-source contract cross-port.ADR-0035 §3: a breaking move during the run-up restarts the quiet-period clock, so it must be
batched, and it must land while 1.0 remains unscheduled — which it explicitly is.
What would reverse this ruling
raises migration cost and argues the pattern is loved rather than vestigial; more than a couple
→ decline and document the rule-of-thumb instead.
subType === "value"compare — any custom object subtype silently becomes a table #248 prelude revealing that any port's projection fan-out cannot cleanly no-op on asourceless projection without new vocabulary (e.g. a marker distinguishing a wire-assembled
projection from a DB one). New vocabulary is a different cost class under ADR-0023 and reopens
the call.
the clock: ship 1.0, document the rule-of-thumb, and let this be a 2.0 candidate.
[-]Total value purity: retire origin.* on object.value (one spelling of derived read shape)[/-][+]Retire assembly origins on object.value (one spelling of derived read shape) — RULED: batch into the pre-1.0 consolidation[/+]dmealing commentedon Aug 5, 2026
Preludes filed and blocking this issue: #270 (retire redundant payload origin-typing in Kotlin/Python, close Java's
KNOWN_GAPSentry as moot) and #271 (port #248's persistability-from-source contract cross-port; prove each fan-out no-ops on a sourceless projection). #271 also carries the falsification signal — if any port needs new vocabulary to handle a sourceless projection, it reopens this ruling.docs(roadmap): record the #210 ruling and its two blocking preludes
dmealing commentedon Aug 5, 2026
Batch scope note: the pre-1.0 consolidation batch this issue rides now also carries the
@roleregistry change from #212 — removingpublishfromsource.rdb @role'sallowedValues(live inexpected-registry.json,spec/metamodel/db.json, and five ports' embedded definitions), and possibly the wider shrink toprimary | replicapending the sub-decision recorded there. Same class as this issue'sobject.valuerules-string change: lockstep across five ports, technically breaking, zero fixtures affected. Batching them means one window, one review.docs(roadmap): record the #212 ruling and the @ROLE sub-decision it s…
dmealing commentedon Aug 5, 2026
Batch scope, updated: the
@rolechange riding this batch is now the full shrink toprimary | replica(ruled on #212), not just thepublishremoval. Cross-port verification closed the gate — every read of@rolein all five ports is an equality test againstprimary; Java OMDB has zero role usage, and Kotlin/Python's write-through read paths are explicitly documented "role-agnostic" (they find the replica by@kind).index/cache/publish/mirrorbecome reserved-not-registered per the ADR-0040 precedent. One pre-landing check inherited from that ruling: these are shipped registered members, so re-run ADR-0036's adopter scan plus the public reference app before removing them — zero uses were verified in this repo only.docs(roadmap): rule the @ROLE vocabulary sub-decision (shrink to prim…
docs(adr): amend ADR-0007 per the #212 ruling — admission test + @ROLE …
test(#271): pin sourceless projections cross-port; retire #210's fals…
dmealing commentedon Aug 6, 2026
Correction to this ruling's prelude framing. It describes #270 as "output-identical post-#185." That is false, and the correction makes the prelude more necessary rather than less.
#270 is a bug fix: Kotlin's and Python's payload
origin.collectionhandling discards the field's declared@objectRefand substitutes the@viarelationship's entity shape, so a declared curated VO silently becomes the full entity — defeating the payload-bloat contract this pillar exists to enforce. TypeScript's origin-blindness is the correct baseline, not the gap. Full recon on #270.Bearing on this issue: #210 does not subsume #270, and the dependency direction is unchanged. Post-#210,
@payloadRefwidens to sourceless projections whose fields are also explicitly declared, so declared-driven payload emission is the right contract through and after the transition — no port ever needs payload-tier origin typing.One item to fold into this batch's scope:
validateOriginPathshas noorigin.collectionbranch at all — collection is the one origin subtype whose declared-vs-derived agreement the loader never checks, which is exactly why the Kotlin/Python divergence went unnoticed. Since this batch retires assembly origins (includingcollection) fromobject.value, the validation gap dies with it on values; ifcollectionremains reachable on projections, the agreement check belongs here rather than as a separate issue.docs(plan): resumable execution plan for the projection/payload vocab…
Merge pull request #276 from metaobjectsdev/feat/role-shrink-and-210
docs: propagate the conformance fixture count 262 -> 270
chore(release): 0.21.0 coordinated MINOR (npm/PyPI/NuGet 0.21.0 · Mav…
dmealing commentedon Aug 8, 2026
Shipped in
0.21.0/7.21.0— a coordinated MINOR across all four registries (npm0.21.0· PyPI0.21.0· NuGet0.21.0· Maven7.21.0), the pre-1.0 breaking slot.Merged as #276; commits
6c73e77a→e0e561ab→9c4fbadd→286bba78→03a7eed7.local-cigreen 9/9 on the merge SHA.Migration guide:
docs/features/migrations/value-assembly-origins-and-source-role-shrink.md, also reachable from the0.x-to-1.0hub §7.What shipped
origin.aggregate,origin.computed,origin.collectionandorigin.firston anobject.value-hosted field now fail load withERR_SUBTYPE_RULE_VIOLATIONin all four loaders.origin.passthroughstays legal on a value, exactly as the ruling required — there it is FR-015 parameter lineage, not assembly, and retiring it would have silently dropped theERR_PASSTHROUGH_TYPE_MISMATCHcheck on stored-proc arguments. The durable rule is now encoded in ADR-0028: "passthrough on a value is lineage; assembly origins live on projections."The migration path is additive:
@payloadRef/@responseRefaccept a sourcelessobject.projection, so a payload that was assembling values re-hosts as a projection and keeps its origins.Implementation note worth recording. Rather than patching four subtype branches per port, the ban is one named
ASSEMBLY_ORIGIN_SUBTYPESset hoisted above the origin dispatch in every loader — so cross-port coverage is a property of the constant rather than of locating four sites, and a future fifth assembly origin is caught automatically. Both TS and Python tests assert set-equality between their fixture tables and that constant, closing achildren: [undefined]vacuity hole. Now-unreachable value-host arms were removed with comments naming why, not left behind.A third breaking change surfaced in review
The ruling anticipated two. Final review found a third: a payload's nested
field.object @objectRefmust now target anobject.value. TypeScript, C# and Python did not filter nested targets before — that shape loaded and emitted a nested interface from the entity. It is now a fail-closed loader rule (one rule, four loaders) rather than five per-port codegen filters, reusingERR_SUBTYPE_RULE_VIOLATION. It carries its own section and rewrite rule in the guide.An independent adjudication earlier in this batch is why it landed in the loader: filtering one port's payload closure without its extract closure would have emitted mappers constructing classes that no longer exist — strictly worse than the bloat it removed.
Also fixed, found by the release gate
runner.ts'sdbImport/dialectguard keyed onsubType !== OBJECT_SUBTYPE_VALUE, so a sourceless projection — the shape this release's own migration guide tells adopters to create — would have demanded database config and thrown(Only a value-object-only model may omit them.)for an object that provably emits zero DB code. It now keys onhasAnyRdbSource, which is #248's persistability-from-source doctrine and was the last subtype-based persistability check in the codebase. Regression test covers the exact migration-guide shape.Preludes
Both closed. #270 shipped in
0.20.16(and turned out to affect Java too, which its own text had recorded as a correct reference port). #271 was discharged — its premise was falsified by recon; every port already accepted a sourceless projection with no new vocabulary, retiring this ruling's ADR-0023 falsifier.Gates
No new vocabulary, attributes or error codes (ADR-0023). Registry manifest diff confined to three
object.value/object.projectiondoctrinal strings. All codegen golden output and every Kotlin snapshot byte-identical — including the re-hostedpayload-with-originssnapshot, which regenerated byte-for-byte because #270 had already made those emitters declared-type-authoritative. Conformance corpus 262 → 270.Seven new fixtures for this issue:
error-value-origin-{aggregate,collection,computed,first},template-payload-ref-sourceless-projection,error-template-payload-ref-sourced-projection,error-payload-nested-object-ref-entity.feat(all-ports): the filter-operator band is field-level -- an int-ba…
feat(metamodel)!: origin.collection retires to reserved-not-registered (