Follow-up to #219 / ADR-0044. Identified during the Python stage-2 code review.
The gap
#219 fixed collision-scoped naming in the payload-VO generator of every port. But the extract / output-parser tier — which imports the nested payload classes the payload generator emits — still resolves and names them by bare short name, so under a cross-package short-name collision it would import a class the payload generator no longer emits (it now emits the package-qualified AcmeAlphaNotePayload / AcmeBetaNotePayload).
Python (the tier is clearest here):
extractor_generator.py — names/imports nested strict classes via payload_class_name(vo.name) (bare).
extract_delegate_emitter.py — reachable_vos dedupes by cur.name (drops the second same-short-name VO); ref_vo has a bare-tail fallback (ref.rsplit(PACKAGE_SEP,1)[-1], binds whichever loads first); mirror_name / _mapper_name key on vo.name.
The other ports have the same shape in their extract/parser generators.
Why it's latent (not shipped-wrong)
The only cross-package collision fixture (fixtures/template-output-render-conformance/xpkg-collision/) is @kind: document / @format: html. Both the extractor and the extract-lenient half of the output-parser gate on @format ∈ {json, xml}, so this fixture never routes through the affected path. No shipped output is wrong today, and the non-colliding path is unchanged (not a regression). This is exactly the "same disease recurs in sibling generators" follow-up ADR-0044 §Consequences calls out.
Ask
Add a json/xml cross-package short-name collision fixture (a parsed template whose payload reaches two same-short-name VOs across packages) and extend the ADR-0044 three-pass naming to the extract/output-parser tier in all five ports so the imported class names match the payload generator's collision-scoped names. Gate it in the shared corpus.
Follow-up to #219 / ADR-0044. Identified during the Python stage-2 code review.
The gap
#219 fixed collision-scoped naming in the payload-VO generator of every port. But the extract / output-parser tier — which imports the nested payload classes the payload generator emits — still resolves and names them by bare short name, so under a cross-package short-name collision it would import a class the payload generator no longer emits (it now emits the package-qualified
AcmeAlphaNotePayload/AcmeBetaNotePayload).Python (the tier is clearest here):
extractor_generator.py— names/imports nested strict classes viapayload_class_name(vo.name)(bare).extract_delegate_emitter.py—reachable_vosdedupes bycur.name(drops the second same-short-name VO);ref_vohas a bare-tail fallback (ref.rsplit(PACKAGE_SEP,1)[-1], binds whichever loads first);mirror_name/_mapper_namekey onvo.name.The other ports have the same shape in their extract/parser generators.
Why it's latent (not shipped-wrong)
The only cross-package collision fixture (
fixtures/template-output-render-conformance/xpkg-collision/) is@kind: document/@format: html. Both the extractor and the extract-lenient half of the output-parser gate on@format ∈ {json, xml}, so this fixture never routes through the affected path. No shipped output is wrong today, and the non-colliding path is unchanged (not a regression). This is exactly the "same disease recurs in sibling generators" follow-up ADR-0044 §Consequences calls out.Ask
Add a json/xml cross-package short-name collision fixture (a parsed template whose payload reaches two same-short-name VOs across packages) and extend the ADR-0044 three-pass naming to the extract/output-parser tier in all five ports so the imported class names match the payload generator's collision-scoped names. Gate it in the shared corpus.