+**Payload record naming is collision-scoped in Python, Java and Kotlin ([#219](https://github.com/metaobjectsdev/metaobjects/issues/219) stages 2–3, [#220](https://github.com/metaobjectsdev/metaobjects/issues/220)).** When two `object.value`s share a bare short name across packages (`acme::alpha::Note` + `acme::beta::Note`, both reachable from one payload by fully-qualified `@objectRef` — valid metadata since ADR-0041/0042), each port's payload generator silently produced the wrong output: **Python** deduped nested classes by `fqn()`, which returns the bare name when a loaded object's own `package` is unset, collapsing the two `Note`s into one `NotePayload` and dropping the second shape; **Java** and **Kotlin** are one-file-per-record emitters, so both records were named `NotePayload` and written to the same path — the second silently **clobbered** the first, last-wins. All three now run ADR-0044's three-pass pipeline: an FQN-keyed reference-closure walk, then name assignment (bare `<Short>Payload` when unique in the artifact's collision domain — the module for Python, the output package for Java/Kotlin; a package-derived name such as `AcmeAlphaNotePayload` for **every** colliding member; hard failure with `ERR_PAYLOAD_NAME_COLLISION` if a derived name still collides), then emission through the name map. **Not breaking** — names change only where output was silently wrong; non-colliding output is byte-identical, pinned per port. The Kotlin xpkg-collision conformance test (#220) is upgraded from asserting a file exists to running the payload generator, asserting two distinct classes, and compiling the output.
0 commit comments