Replace one abstract step in the gxformat2 draft with a concrete tool step, using the upstream tool summary or, for a tool authored on fallthrough, its GalaxyUserTool definition. One invocation resolves exactly the chosen step’s TODO_* / _plan_* slots into a concrete tool binding, state, and wrapper-determined port names, and returns the mutated draft. This is the “Implement” leaf of the per-step loop owned by advance-galaxy-draft-step.
Single step in scope. This Mold owns the chosen step and the wiring that connects it to ports already in the draft. It does not redesign topology and does not unwind earlier iterations — cross-step rework is the orchestrator’s call.
Sequence
-
Read the step’s plan. From the galaxy-workflow-draft, take the chosen step’s deferred evidence: _plan_state, _plan_context, _plan_in, _plan_out, and any TODO_* slots the template or data-flow brief left for this phase.
-
Bind to the tool summary. Read the galaxy-tool-summary manifest: parsed_tool gives concrete input/output port names and datatypes; shape the step’s state against input_schemas.workflow_step_linked. Set tool_version, and set tool_id — confirming or correcting an identity-pinned id rather than re-deriving a good pin from scratch. For a Tool Shed wrapper the tool_id is the full versioned GUID, <shed>/repos/<owner>/<repo>/<tool>/<tool_version>, ending in the same version as tool_version; a template’s identity pin is often versionless, so append the resolved version. Galaxy invokes workflows with exact tool versions by default (planemo does), and a versionless shed id then fails invocation as “required tools are not installed” although static validation passes. For a built-in/stock tool the tool_id is the bare id (Filter1, Cut1, collection ops) and tool_version must come from the summary’s cached pin — never invent a stock version; the summary already resolved it against the shed via summarize-galaxy-tool. If input_schemas is null, consult warnings[] for why before binding by hand. Read a conditional’s cases from parsed_tool, not the wrapper XML (parsed-tool): its index in whens[] is the case index, and is_default_when marks the default, which need not be case 0.
Authored user-defined tool. When the wrapper is a galaxy-user-tool-definition from author-galaxy-tool-wrapper, there is no tool summary and no toolbox id to bind. Follow galaxy-user-tool-workflow-binding: embed the galaxy-user-tool.yml document unchanged under the step’s run:, and remove tool_id, tool_version, and tool_shed_repository along with any TODO in them. Take in: keys from the definition’s data and collection input names, list every output a consumer uses under out: by its output name, and set non-data values in state by input name. Never name the tool by tool_uuid, tool_id, or content_id alone, and do not register the tool to obtain a uuid.
-
Wire ports. Connect the step’s inputs to their upstream producers and its outputs to downstream consumers per the _plan_in / _plan_out intent, using real wrapper port names. Key a parameter nested in a conditional or section by its |-joined path (input_type|i), and a repeat instance with _N (pick_from_0|value), giving each instance its own entry in the repeat in state (gxformat2-schema). Preserve collection mapping and reduction semantics (galaxy-collection-semantics); for a source-derived shape, check the chosen input/output can actually carry the intended File / list / paired / list:paired shape (nextflow-to-galaxy-channel-shape-mapping).
-
Close shape gaps. When a direct tool connection cannot express the needed shape, insert a built-in collection-operation step (galaxy-collection-tools); for identifier-derived reshaping — regex parsing, nesting swaps, paired assignment — use Apply Rules (galaxy-apply-rules-dsl); for a transform traced to a Nextflow operator (map, join, groupTuple, branch, mix, combine, multiMap), turn it into concrete wiring or a review request via nextflow-operators-to-galaxy-collection-recipes. A built-in step inserted here is itself a stock tool: resolve its concrete tool_version through the galaxy-tool-cache flow (summarize-galaxy-tool on the bare id) rather than guessing — or leave it draft-tier for the next loop iteration to realize.
-
Preserve testability. Keep output labels and collection element identifiers stable and addressable (galaxy-workflow-testability-design). Do not rename a labeled output, drop a checkpoint, or make a final output too weakly assertable just to satisfy this step’s wiring. A dataset rename: names the output after an input with #{input}, or uses a workflow parameter with ${label}. Tool-XML label variables such as ${on_string} are not rename variables; Galaxy treats them as untyped run-time parameters (gxformat2-schema).
-
Validate. Run draft-validate --concrete over the mutated draft: it checks draft-contract rules and gates the extracted concrete subset — including the step just implemented — against full gxformat2. On green, return the draft for the next loop iteration; on red, route the diagnostic back to whichever decision above it implicates.
Failure ownership
When the wrapper can’t cleanly carry what the plan needs — wrong datatype, missing parameter, unsupported collection shape — record where a later failure should be investigated: tool/job failure, data-flow mistake, template wiring mistake, wrapper mismatch, or test/assertion issue. Consult galaxy-tool-job-failure-reference when the selected wrapper has explicit failure semantics (exit-code rules, stdio regex, strict-shell, dynamic outputs); implement the step’s labels and wiring so that evidence survives to runtime rather than being erased by the concretization.
When the step’s declared output cannot be computed from the inputs wired to it — the connection graph says the ports connect, but no wired input carries the evidence the output needs — do not fabricate it. Append a blocking entry to the open-requirements-ledger and fall through to repair-galaxy-draft-topology rather than emitting a step that validates but can’t run. A missing Tool Shed wrapper is not this case; that gap routes through the discover-or-author branch.