GTR036 — Replace deprecated <output type="data"> (codemod)

Contract: behaviour-preserving.

Claim

Renaming <output type="data"> to <data> (dropping the attribute) is a parse-level no-op.

Proof

Galaxy routes an <output type="data"> through the same _parse as <data> (tool_util/parser/xml.py:548-563).

Proof — the collection variant (ledger item C3, shipped)

The same routing block remaps the deprecated collection path in place — attrib["type"] = unicodify(collection_type), attrib["type_source"] = unicodify(collection_type_source) — then parses via the same _parse_collection as a <collection>. unicodify(None) is None (typed overload, util/__init__.py:1190-1196), which reads identically to an absent attribute, so when collection_type is present the static rewrite mirrors the remap exactly.

Scope boundary

<output type="collection"> with no collection_type stays advisory — and the degenerate case is now verified broken (2026-06-10): Galaxy’s tree is lxml (galaxy.util re-exports from lxml import etree, util/__init__.py:85), so the deprecated path’s attrib["type"] = unicodify(None) raises TypeError at load — the tool never worked. <output> with no type (an expression output — a different kind) also stays advisory. Shipped at ~1-tool / ~0-tool corpus incidence — “not gated on corpus frequency” (the ledger’s precedent rule).