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
#248 established the contract that an
object's participation in persistence derives from a declared or inherited source.* child,
never from a hardcoded object-subtype check. It shipped npm-only (migrate-ts + codegen-ts),
because schema is TS-owned per ADR-0015 and no other port has a migrate engine.
But the contract is not only about migrate. Every port's projection fan-out dispatches on
source kind — view-kind projections get a read-only DTO, proc-kind projections get FR-015
proc-callables. None of the four non-TS ports has ever been handed a projection with zero source.* children, because nothing produces one today.
Why this matters
#210 will make sourceless projections
a first-class, commonly-authored shape: prompt payloads become projections with no source. On the
day that lands, four ports' fan-out meets an input it has never seen. The failure mode is not a
clean error — it is a @kind switch falling through, or a generator emitting a DTO that assumes a
table.
Verifying and fixing the dispatch before the breaking change, as its own non-breaking unit, is
what keeps #210's risk in the diff rather than in the fan-out.
Scope
For Java, Kotlin, C# and Python (TS already has it via #248):
Establish what each port's projection/entity fan-out currently keys on — an explicit
object-subtype check, a @kind lookup, or the presence of a source.
Prove each port cleanly no-ops on a projection with zero sources: no DDL, no table-assuming
DTO, no silent fall-through. A sourceless projection should generate its read shape and nothing
else.
Gate
A shared conformance fixture declaring a sourceless object.projection, exercised by all five
ports. Existing output must be byte-identical for every model that has a source (this is
additive tolerance, not a behaviour change).
Follow the ADR-0039 own-accessor discipline when reading the source.* child — a projection may
inherit its source through extends, so the read must be resolving, not own-only.
If any port cannot no-op on a sourceless projection without new vocabulary — e.g. a marker
attribute distinguishing a wire-assembled projection from a database-backed one — that is a
different cost class under ADR-0023 and reopens the #210 ruling. Report it there rather than
inventing the attribute.
Summary
#248 established the contract that an
object's participation in persistence derives from a declared or inherited
source.*child,never from a hardcoded object-subtype check. It shipped npm-only (
migrate-ts+codegen-ts),because schema is TS-owned per ADR-0015 and no other port has a migrate engine.
But the contract is not only about migrate. Every port's projection fan-out dispatches on
source kind — view-kind projections get a read-only DTO, proc-kind projections get FR-015
proc-callables. None of the four non-TS ports has ever been handed a projection with zero
source.*children, because nothing produces one today.Why this matters
#210 will make sourceless projections
a first-class, commonly-authored shape: prompt payloads become projections with no source. On the
day that lands, four ports' fan-out meets an input it has never seen. The failure mode is not a
clean error — it is a
@kindswitch falling through, or a generator emitting a DTO that assumes atable.
Verifying and fixing the dispatch before the breaking change, as its own non-breaking unit, is
what keeps #210's risk in the diff rather than in the fan-out.
Scope
For Java, Kotlin, C# and Python (TS already has it via #248):
object-subtype check, a
@kindlookup, or the presence of a source.source.*child, matching Persistability is decided by a hardcodedsubType === "value"compare — any custom object subtype silently becomes a table #248'scontract.
DTO, no silent fall-through. A sourceless projection should generate its read shape and nothing
else.
Gate
object.projection, exercised by all fiveports. Existing output must be byte-identical for every model that has a source (this is
additive tolerance, not a behaviour change).
source.*child — a projection mayinherit its source through
extends, so the read must be resolving, not own-only.Falsification signal for #210
If any port cannot no-op on a sourceless projection without new vocabulary — e.g. a marker
attribute distinguishing a wire-assembled projection from a database-backed one — that is a
different cost class under ADR-0023 and reopens the #210 ruling. Report it there rather than
inventing the attribute.