Summary
Payload-origin handling diverges across the five ports today, and the divergence is
load-bearing for nothing. Retiring it is output-identical and de-risks #210.
| Port |
Today |
| Kotlin |
KotlinPayloadGenerator resolves origin.* for payload field typing |
| Python |
payload_vo_generator resolves origin.* for payload field typing |
| TypeScript |
origin-blind |
| C# |
origin-blind |
| Java |
standing KNOWN_GAPS deferral (codegen-spring/.../KNOWN_GAPS.md), also listed as an open question in CLAUDE.md |
The divergence is benign only because #185 made origin.passthrough type-preserving
(ERR_PASSTHROUGH_TYPE_MISMATCH, with @convert: true as the opt-out). A passthrough field's
declared type must already match its @from source, so deriving the payload field's type through
the origin is redundant with reading the declared type — the two can no longer disagree.
Why now
This is the first of two non-breaking preludes to
#210 (assembly origins retire from
object.value). Doing it first means #210's payload-tier change lands against five ports that
agree, instead of three different behaviours. Payload emission is this repo's recent cross-port
bug hotspot — ADR-0044 (#219/#220) took three stages to land, and #228 found the extract tier
resolving payload refs package-blind — so reducing the surface before the breaking change is
worth more than the diff suggests.
Scope
- Kotlin — delete the origin-resolution path in
KotlinPayloadGenerator; type payload fields
from the declared field type.
- Python — same in
payload_vo_generator.
- Java — close the
KNOWN_GAPS payload-origin.* entry as moot (not "deferred"), and
drop the matching open question from CLAUDE.md.
- TypeScript / C# — no change; verify they stay origin-blind.
Gate
Output must be byte-identical in every port — this is a dead-code removal, not a behaviour
change. Pin it: run the render / payload conformance corpora before and after and diff the
emitted payload records. Any byte that moves means the redundancy claim above is wrong for some
shape, and that shape belongs in a fixture before this lands.
Non-goals
Summary
Payload-origin handling diverges across the five ports today, and the divergence is
load-bearing for nothing. Retiring it is output-identical and de-risks #210.
KotlinPayloadGeneratorresolvesorigin.*for payload field typingpayload_vo_generatorresolvesorigin.*for payload field typingKNOWN_GAPSdeferral (codegen-spring/.../KNOWN_GAPS.md), also listed as an open question inCLAUDE.mdThe divergence is benign only because #185 made
origin.passthroughtype-preserving(
ERR_PASSTHROUGH_TYPE_MISMATCH, with@convert: trueas the opt-out). A passthrough field'sdeclared type must already match its
@fromsource, so deriving the payload field's type throughthe origin is redundant with reading the declared type — the two can no longer disagree.
Why now
This is the first of two non-breaking preludes to
#210 (assembly origins retire from
object.value). Doing it first means #210's payload-tier change lands against five ports thatagree, instead of three different behaviours. Payload emission is this repo's recent cross-port
bug hotspot — ADR-0044 (#219/#220) took three stages to land, and #228 found the extract tier
resolving payload refs package-blind — so reducing the surface before the breaking change is
worth more than the diff suggests.
Scope
KotlinPayloadGenerator; type payload fieldsfrom the declared field type.
payload_vo_generator.KNOWN_GAPSpayload-origin.*entry as moot (not "deferred"), anddrop the matching open question from
CLAUDE.md.Gate
Output must be byte-identical in every port — this is a dead-code removal, not a behaviour
change. Pin it: run the render / payload conformance corpora before and after and diff the
emitted payload records. Any byte that moves means the redundancy claim above is wrong for some
shape, and that shape belongs in a fixture before this lands.
Non-goals
origin.*stays licensed onfield.base; nothing inexpected-registry.jsonmoves.object.value— that is Retire assembly origins on object.value (one spelling of derived read shape) — RULED: batch into the pre-1.0 consolidation #210.