GTR096: FixTestParamQualification, qualify a flat 24.2 test param name

Contract: behaviour-preserving (crossing-gated, test-metadata only).

The transform

Rewrite a flat <test> <param name="child"> to its fully-qualified parent|...|child path, but only when child resolves to exactly one nested input parameter (test_param_qualify.plan_test_param_qualifications). Applied on the upgrade path once a tool crosses profile >= 24.2 (the runtime-gated crossing gate, codemod §24).

Proof

  • It is the migration Galaxy prescribes. From profile 24.2 a test parameter targeting a nested input must be fully qualified (lib/galaxy/tool_util/parameters/case.py, the extra="forbid" model + flat_state_path); the Galaxy upgrade message says so verbatim. Qualifying the name is exactly the documented fix.

  • It edits only <tests>. No <command>, <inputs>, <outputs>, or any other runtime element is touched, so the tool’s runtime behaviour is preserved by construction (the same class of guarantee as a <tests>-only edit can give).

  • The unique-leaf precondition preserves the test’s intent. The rewrite is made only when the leaf name resolves to exactly one input parameter and that parameter is nested; a name matching no input (a typo, a removed parameter, or a Galaxy built-in such as chromInfo), a top-level input (already correct), or more than one input (ambiguous) is left untouched. So the unqualified name already referred unambiguously to that one parameter, and its qualified form refers to the same one, so the fix can only ever turn an error into the correct spelling, never change which parameter a test sets.

  • Verified by execution. The behavior gate credits 24_2_fix_test_case_validation only when re-detection (test_case_check, itself parity-gated against Galaxy’s real validator with zero unsound suppressions) proves the tests clean after the rewrite; a tool the fix does not fully clear is left blocked and, by the crossing gate, its tests are not edited at all. The corpus parity oracle (scripts.measure test-case-validation-truth) holds the zero-unsound contract across every test-shipping tool on each refresh.

Scope (sizing, not soundness)

scripts.measure test-param-qualification: the unique-leaf qualification unblocks 159 tools the 24.2 checker otherwise stops; the rest of the unqualified-name cases are typos, removed parameters, or ambiguous leaves the fix soundly declines. See docs/galaxy_reimplementations.md and codemod docs/decisions.md §48.