conversion run

draft-manuscript-galaxy

paper-to-galaxy — 2026-09-18 18:33 to 2026-09-18 18:33, 1.7 MB on disk.

paper-to-galaxyrev 2pipeline-paper-to-galaxyreconstructed--feedback
run
complete
every intended phase finished
phases
12/12
furthest reached was phase 12
artifacts
14/16
1 declared artifact(s) due but absent
obligations
5 open
13 resolved, 0 surrendered, 0 blocking
feedback
25
0 blocker, 15 major, 10 minor
unmapped
20
1.3 MB no Mold declares

Phases

where the run got to
  1. 01summarize-paperdone · from feedback ledger
  2. 02freeform-summary-to-galaxy-interfacedone · from feedback ledger
  3. 03freeform-summary-to-galaxy-data-flowdone · from feedback ledger
  4. 04compare-against-iwc-exemplardone · from feedback ledger
  5. 05freeform-summary-to-galaxy-templatedone · from feedback ledger
  6. 06advance-galaxy-draft-steploop ×9done · from feedback ledger
  7. 07test-data-resolution→ find-test-datadone · from feedback ledger
  8. 08freeform-summary-to-galaxy-test-plandone · from feedback ledger
  9. 09implement-galaxy-workflow-testdone · from feedback ledger
  10. 10validate-galaxy-workflowdone · from feedback ledger
  11. 11run-workflow-testdone · from feedback ledger
  12. 12debug-galaxy-workflow-outputdone · from feedback ledger

Artifacts

what it declared and what is on disk
phaseartifactfilekindpresencesizemodifiedcopies
phase 1freeform-summaryfreeform-summary.mdmarkdownpresent44.6 KB2026-09-18 18:33
phase 2freeform-galaxy-interfacefreeform-galaxy-interface.mdmarkdownpresent14.5 KB2026-09-18 18:33
phase 2open-requirements-ledgeropen-requirements.ledger.ymlyamlpresent40.6 KB2026-09-18 18:33
phase 3freeform-galaxy-data-flowfreeform-galaxy-data-flow.mdmarkdownpresent17.0 KB2026-09-18 18:33
phase 4iwc-comparison-notesiwc-comparison-notes.mdmarkdownpresent10.5 KB2026-09-18 18:33
phase 4iwc-exemplar-gxformat2iwc-exemplar.gxwf.ymlyamlmissing
phase 5galaxy-workflow-draftgalaxy-workflow-draft.gxwf.ymlyamlpresent37.6 KB2026-09-18 18:33
phase 6galaxy-workflowgalaxy-workflow.gxwf.ymlyamlpresent37.6 KB2026-09-18 18:33
phase 7test-data-refstest-data-refs.jsonjsonpresent17.1 KB2026-09-18 18:33
phase 8galaxy-test-plangalaxy-test-plan.ymlyamlpresent37.4 KB2026-09-18 18:33
phase 9galaxy-workflow-testgalaxy-workflow.gxwf-tests.ymlyamlpresent13.9 KB2026-09-18 18:33
phase 10galaxy-workflow-validation-resultgalaxy-workflow-validation-result.jsonjsonpresent6.5 KB2026-09-18 18:33
phase 11workflow-test-resultworkflow-test-result.jsonjsonpresent9.4 KB2026-09-18 18:33
phase 12workflow-debug-reportworkflow-debug-report.mdmarkdownpresent10.3 KB2026-09-18 18:33
phase —foundry-feedback-ledgerfoundry-feedback.ledger.ymlyamlpresent81.8 KB2026-09-18 18:33
phase —foundry-run-manifestfoundry-run.ymlyamloptional-absent
foundry-feedback-ledgerpresentfoundry-feedback.ledger.yml

Runtime artifact initialized by the harness ([[foundry-feedback-ledger]]).

declared by
— (phase —)
consumed at
nothing downstream reads it
schema
none declared
sha256
5d0435e4417990be680e35bafd7388725056f2d01b464e996a452422c9c66aa1
run:
  pipeline: paper-to-galaxy
  run_slug: draft-manuscript-galaxy
  status: complete

phases:
  - phase: 1
    kind: mold
    skill: summarize-paper
    status: done
    feedback_checked: true
  - phase: 2
    kind: mold
    skill: freeform-summary-to-galaxy-interface
    status: done
    feedback_checked: true
  - phase: 3
    kind: mold
    skill: freeform-summary-to-galaxy-data-flow
    status: done
    feedback_checked: true
  - phase: 4
    kind: mold
    skill: compare-against-iwc-exemplar
    status: done
    feedback_checked: true
  - phase: 5
    kind: mold
    skill: freeform-summary-to-galaxy-template
    status: done
    feedback_checked: true
  - phase: 6
    kind: mold
    skill: advance-galaxy-draft-step
    loop: true
    iterations: 9
    status: done
    feedback_checked: true
  - phase: 7
    kind: branch
    pattern: test-data-resolution
    chain: [paper-to-test-data, find-test-data, user-supplied]
    selected: find-test-data
    status: done
    feedback_checked: true
  - phase: 8
    kind: mold
    skill: freeform-summary-to-galaxy-test-plan
    status: done
    feedback_checked: true
  - phase: 9
    kind: mold
    skill: implement-galaxy-workflow-test
    status: done
    feedback_checked: true
  - phase: 10
    kind: mold
    skill: validate-galaxy-workflow
    status: done
    feedback_checked: true
  - phase: 11
    kind: mold
    skill: run-workflow-test
    status: done
    feedback_checked: true
  - phase: 12
    kind: mold
    skill: debug-galaxy-workflow-output
    status: done
    feedback_checked: true

entries:
  - id: collection-pattern-mocs-ship-without-referenced-pages
    raised_by: freeform-summary-to-galaxy-template
    observed_in:
      mold:
        name: freeform-summary-to-galaxy-template
        path: content/molds/freeform-summary-to-galaxy-template/index.md
        revision: 6
        content_hash: 0a95f8c04465d48131ace523e0b27af53f1ade6e525a9173c5ff1e936ddc3366
        foundry_head: 63a3f9cf9c97a637fe1628d298e524f35709e289
    subject:
      kind: pattern
      label: galaxy-collection-patterns (and sibling galaxy-conditionals-patterns / galaxy-tabular-patterns MOCs)
      locator: content/patterns/galaxy-collection-patterns.md
      content_hash: 9840d686228a254766611196f2be03b2a66119281322c6373ce082cd08e78717
    kind: gap
    severity: minor
    what: "The skill bundle packages `galaxy-collection-patterns.md`, `galaxy-conditionals-patterns.md`, and `galaxy-tabular-patterns.md` as MOC/index pages (frontmatter `pattern_kind: moc`) that only list wikilink-style names of ~15-20 concrete pattern pages each (e.g. `[[fan-in-bundle-consume-and-flatten]]`, `[[collection-unbox-singleton]]`, `[[manifest-to-mapped-collection-lifecycle]]`, `[[tabular-concatenate-collection-to-table]]`). None of the referenced pattern pages themselves -- which per the MOC descriptions should carry the actual worked recipe, concrete tool_id, and state -- are packaged anywhere in this skill bundle's `references/` tree."
    expected: "Either package the linked pattern pages alongside their MOC (as this skill already does for other reference kinds, e.g. `galaxy-workflow-draft-format.md`), or have the MOC entries themselves carry the concrete tool_id / state worked example inline, so a cast skill that is explicitly told (Runtime Notes) not to fetch Foundry source files at runtime can actually resolve a pattern name to a usable recipe from packaged content alone."
    evidence: "For this run, resolving concrete tool identities for the fan-in/flatten/tabular-bridge steps (Collapse Collection, __FLATTEN__, collection_column_join) was only possible because the separately-supplied `iwc-comparison-notes.md` artifact (from a prior pipeline phase) happened to quote inline gxformat2 excerpts naming those tools. Had that artifact not carried those excerpts, the packaged collection/tabular pattern MOCs alone (the on-demand references this Mold's own SKILL.md directs it to for exactly this situation) would have given only a pattern *name* with no way to resolve it to a tool_id or worked state, forcing every such step to Deferred tier even where a concrete built-in exists."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/570

  - id: gxformat2-schema-missing-nested-in-key-convention
    raised_by: advance-galaxy-draft-step
    observed_in:
      mold:
        name: advance-galaxy-draft-step
        path: content/molds/advance-galaxy-draft-step/index.md
        revision: 4
        content_hash: c92d452f69a7b40bcab5fc8e63b03e1e2abf98f2a636abc4c93ad7f3c1d03082
        foundry_head: 63a3f9cf9c97a637fe1628d298e524f35709e289
    subject:
      kind: research
      label: gxformat2-schema
      locator: content/research/gxformat2-schema/index.md
      content_hash: 4fe42382f99655115c53c1afde0da0d0556ad77984da7d0ffa8ab725ea260aa3
    kind: gap
    severity: major
    what: "gxformat2-schema documents that a step's `state` nests conditionals/sections as plain nested YAML (the `state` vs `tool_state` section), but no packaged reference in advance-galaxy-draft-step's, implement-galaxy-tool-step's, or repair-galaxy-draft-topology's bundles documents the companion convention for a step's `in:` connections dict: how to address a nested conditional test-parameter branch or section child as a connection target."
    expected: "Extend gxformat2-schema with an explicit subsection on `in:` key addressing for nested tool state -- the pipe-delimited path convention (e.g. `db_opts|lexicmap_index`, `advanced_settings|align_min_match_pident`) for conditional-branch and section-child parameters -- mirroring the existing `state`-nesting subsection, and include it in implement-galaxy-tool-step's packaged references (the leaf Mold that performs this binding), not just as an assumed convention."
    evidence: "Implementing lexicmap_search (toolshed.g2.bx.psu.edu/repos/iuc/lexicmap/lexicmap_search 0.9.0+galaxy1) required wiring workflow inputs onto a `gx_conditional`'s case-owned parameter (`lexicmap_index`, under `db_opts_selector: db`) and five `gx_section` children of `advanced_settings`. None of this run's loaded, packaged references named or demonstrated the `|`-joined `in:` key form needed to address them; it was inferred from general Galaxy/gxformat2 familiarity outside any packaged bundle content, which the skill's own Runtime Notes direct against ('use only files packaged in this skill bundle and user-supplied artifacts')."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/571

  - id: tool-util-cli-toolshed-fetch-rejects-real-filtered-list-collection-output
    raised_by: advance-galaxy-draft-step
    observed_in:
      mold:
        name: advance-galaxy-draft-step
        path: content/molds/advance-galaxy-draft-step/index.md
        revision: 4
        content_hash: c92d452f69a7b40bcab5fc8e63b03e1e2abf98f2a636abc4c93ad7f3c1d03082
        foundry_head: 63a3f9cf9c97a637fe1628d298e524f35709e289
    subject:
      kind: related-project
      label: "galaxy-tool-util-ts / @galaxy-tool-util/cli (gxwf, galaxy-tool-cache) -- ToolShed-fetch-to-ParsedTool decoder"
      locator: "https://github.com/jmchilton/galaxy-tool-util-ts (packages/cli, @galaxy-tool-util/cli@1.8.1)"
    kind: defect
    severity: major
    what: "`galaxy-tool-cache add`/`summarize` (and `gxwf draft-validate`'s own internal tool-state fetch) fail to fetch or parse a real, currently-published IUC Tool Shed wrapper -- toolshed.g2.bx.psu.edu/repos/iuc/kmindex/kmindex_query -- for every galaxy-suffixed version (tried and reproduced for 0.6.0+galaxy1, 0.6.0+galaxy2, 0.6.1+galaxy2, 0.6.1+galaxy3, 0.6.1+galaxy4, 0.6.1+galaxy5), raising a decode error at `outputs[1].structure: is missing` against the upstream parsedToolSchema's collection-output branch. Only the repo's original unsuffixed '0.6.0' version (which predates the wrapper's `<collection type=\"list\"><filter>...</filter><discover_datasets .../></collection>`-shaped output, added by tools-iuc PR #8208 'support multiple indices simultaneously') parses successfully. `add --galaxy-url https://usegalaxy.org` was also tried as a fallback source and fails the same way (plus a second, `inputs is missing` error on that path)."
    expected: "The ToolShed-fetch-to-ParsedTool decoder should populate `structure` (collection_type/discover_datasets/etc.) for a `<collection type=\"list\">` output that declares `discover_datasets` directly and has no `structured_like`/rules -- this is an ordinary, common IUC wrapper shape (also present, filtered by a sibling `<filter>` block, which the schema has no field for at all -- a second, related lossiness worth tracking) -- rather than failing the whole fetch. `gxwf draft-validate` already degrades this failure gracefully to a `skip_tool_not_found` (not a hard fail) for tool-state checking, which is the right fallback behavior for validate; but `galaxy-tool-cache add`/`summarize` themselves give no such degrade and simply cannot produce a manifest for this real, in-production wrapper at all, blocking the normal automated discover -> summarize -> implement path for any workflow step using it."
    evidence: "Reproduced directly this iteration for kmindex_containment_screen (pinned tool_id toolshed.g2.bx.psu.edu/repos/iuc/kmindex/kmindex_query, tool_version 0.6.1+galaxy4, changeset b6fa25b6b436). Root-caused by fetching the wrapper's real upstream XML at the exact matching changeset (Tool Shed API's own `remote_repository_url` for this changeset pointed to github.com/galaxyproject/tools-iuc/tree/main/tools/kmindex; commit 7681be7f40 on that path declares `<tool ... version=\"@TOOL_VERSION@+galaxy4\">`, an exact match) and comparing its `<outputs>` against the successfully-cached bare-'0.6.0' ParsedTool JSON, which lacks the collection output entirely. Worked around this run by hand-reconstructing galaxy-tool-summary.json's `parsed_tool`/`input_schemas` directly from that verified upstream XML rather than via the normal automated `galaxy-tool-cache` path (documented in that file's own `warnings[]`)."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/572

  - id: implement-galaxy-tool-step-udt-binding-undocumented
    raised_by: advance-galaxy-draft-step
    observed_in:
      mold:
        name: implement-galaxy-tool-step
        path: content/molds/implement-galaxy-tool-step/index.md
        revision: 9
        content_hash: 197be2d9b27741c3f258092f8392654369d1ca234d7fad492387ff69d656292b
        foundry_head: 63a3f9cf9c97a637fe1628d298e524f35709e289
    subject:
      kind: mold
      label: implement-galaxy-tool-step
      locator: content/molds/implement-galaxy-tool-step/index.md
      content_hash: 197be2d9b27741c3f258092f8392654369d1ca234d7fad492387ff69d656292b
    kind: gap
    severity: minor
    what: "summarize-galaxy-tool's own Inputs section states 'Authored UDTs from author-galaxy-tool-wrapper bypass this Mold,' correctly routing a locally-authored `GalaxyUserTool` around tool-summary generation. But nothing downstream documents what happens next: implement-galaxy-tool-step's declared Inputs list only `galaxy-tool-summary` (never a `galaxy-user-tool-definition`), and its procedure text (step 2, 'Bind to the tool summary') only covers a Tool-Shed-pinned wrapper or a bare/stock built-in id -- there is no documented convention for how a step's `tool_id`/`tool_version`/`state` should be populated when the resolved wrapper is an authored UDT instead of either of those two cases (e.g. whether `tool_id` should mirror the UDT's own `id` field with no `tool_shed_repository` block, by analogy to a bare/stock id, or something else)."
    expected: "Extend implement-galaxy-tool-step's declared Inputs to include the `galaxy-user-tool-definition` artifact as an alternate input when the discover-or-author branch fell through to authoring, and add an explicit procedure step (or sub-case under step 2) for binding a step to a UDT: what `tool_id`/`tool_version` should hold, that no `tool_shed_repository` block applies, and how the UDT's own declared `inputs`/`outputs` names become the step's `in:`/`out:` port names -- mirroring the level of detail already given for the Tool-Shed-pin and bare/stock-id cases."
    evidence: "Authored a GalaxyUserTool wrapper this iteration for a step with a confirmed Tool Shed discovery miss. Absent any documented binding convention, proceeded by analogy: set the step's `tool_id` to the UDT's own `id`, `tool_version` to its `version`, and no `tool_shed_repository` block (treating it like a bare/stock tool id). `gxwf draft-validate --concrete` accepted this shape (`draft valid`, `Concrete: OK`) -- the tool_id triggered a live Tool Shed lookup that 404'd and was gracefully downgraded to a `skip_tool_not_found` (the same non-fatal bucket used for an unrelated tool whose fetch failed for network reasons), not validated against the UDT's own declared contract at all. So the binding convention used happened to pass, but this was inferred from a different case's documented pattern, and draft-validate's accept path gives no positive confirmation that a UDT-backed step's ports/state were checked against anything real."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/573

  - id: galaxy-user-tool-authoring-missing-element-identifier-expression
    raised_by: advance-galaxy-draft-step
    observed_in:
      mold:
        name: advance-galaxy-draft-step
        path: content/molds/advance-galaxy-draft-step/index.md
        revision: 4
        content_hash: c92d452f69a7b40bcab5fc8e63b03e1e2abf98f2a636abc4c93ad7f3c1d03082
        foundry_head: 63a3f9cf9c97a637fe1628d298e524f35709e289
    subject:
      kind: research
      label: galaxy-user-tool-authoring
      locator: content/research/galaxy-user-tool-authoring/index.md
      content_hash: 365fad455369945a34bda537c8dbf409a0966f0f88da9fe78b61cff32d5b0d0d
    kind: gap
    severity: minor
    what: "galaxy-user-tool-authoring.md's section 3 ('Expression syntax in shell_command') documents exactly two ways to read a `data` input in a `shell_command`/`configfiles` expression -- a scalar/file path via `$(inputs.NAME.path)` -- and says nothing about a `data` input's other available File-object fields. In particular it never mentions `element_identifier`, even though the installed `@galaxy-tool-util/schema` package's own `gx-data.js` parameter-generation code declares, for the `job_runtime` state representation (the one governing values available inside a running job's command/configfile expressions), a File object shape of `{ class: 'File', basename, location, path, nameroot, nameext, format, size, element_identifier: S.optional(S.String) }` -- i.e. `$(inputs.NAME.element_identifier)` is a real, schema-backed expression, not merely `.path`."
    expected: "Extend galaxy-user-tool-authoring.md section 3 with an explicit line documenting `$(inputs.NAME.element_identifier)` (available when the input is a mapped collection element, matching the classic Galaxy tool-XML idiom already documented elsewhere in this same skill family's convert-nfcore-module-to-galaxy-tool notes: '`$input.element_identifier` in `<command>`'), alongside the existing `.path` documentation -- this is exactly the mechanism an authored UDT needs to preserve a Galaxy collection's per-element identifier into its output content without adding an extra collection-element-identifier-extraction producer step/port to the workflow topology."
    evidence: "Authoring flatten_gene_summary_json_to_row (a GalaxyUserTool mapped one call per gene over a summary_json collection) needed the mapped gene's element_identifier embedded as a literal output column, per this step's own _plan_state ('preserving element_identifier for the join'). galaxy-user-tool-authoring.md's packaged expression-syntax section, read upfront per this skill's own procedure, documents only `.path` and gives no indication `.element_identifier` exists or is valid. Confirmed the field's existence and validity only by grepping the installed `@galaxy-tool-util/cli` npm package's own schema source (`gx-data.js`) directly, outside any packaged skill reference -- exactly the kind of external verification this skill's Runtime Notes direct against ('use only files packaged in this skill bundle and user-supplied artifacts'). Had a different, plausible-but-wrong design been chosen instead (e.g. inserting a `collection_element_identifiers` producer step purely to recover the gene symbol as a wireable parameter), it would have been an avoidable topology change driven by a documentation gap, not a real tool-shape constraint."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/468#issuecomment-5733273474

  - id: gxwf-tool-search-underscore-repo-slug-query-zero-hits
    raised_by: advance-galaxy-draft-step
    observed_in:
      mold:
        name: advance-galaxy-draft-step
        path: content/molds/advance-galaxy-draft-step/index.md
        revision: 4
        content_hash: c92d452f69a7b40bcab5fc8e63b03e1e2abf98f2a636abc4c93ad7f3c1d03082
        foundry_head: 63a3f9cf9c97a637fe1628d298e524f35709e289
    subject:
      kind: related-project
      label: "galaxy-tool-util-ts / @galaxy-tool-util/cli (gxwf tool-search) -- Tool Shed query tokenizer/ranker"
      locator: "https://github.com/jmchilton/galaxy-tool-util-ts (packages/cli, gxwf tool-search, @galaxy-tool-util/cli@1.10.1)"
    kind: defect
    severity: minor
    what: "`gxwf tool-search \"collapse_collections\"` (the literal Tool Shed repo-slug for the exact wrapper this iteration needed, toolshed.g2.bx.psu.edu/repos/nml/collapse_collections) returns `No hits for query: collapse_collections` and exits 2. The space-joined equivalent, `gxwf tool-search \"collapse collections\"`, also returns zero hits. Only a differently-worded query -- `gxwf tool-search \"nml collapse\"` (owner name plus one word) or `gxwf tool-search \"Collapse Collection\"` (the tool's display name, not its repo/id) -- surfaces the tool, and even then only as a lower-ranked hit (#3 of 5) in the owner-name case."
    expected: "The query tokenizer/ranker should score a repo-slug-style query (an underscore-joined or space-joined form of the actual `owner/repo` or `tool_id` string) as at least a partial match against that same repo's own `owner/repo` and `tool_id` fields, rather than zero hits -- a query built directly from a known real repo slug is a common, reasonable way to search and should not require the caller to already know the tool's display name or owner to find it."
    evidence: "Reproduced directly this iteration while resolving kmindex_hit_concat's wrapper (same wrapper already pinned earlier in this run as combine_gene_panel_to_bulk_fasta, nml/collapse_collections/collapse_dataset v5.1.0). `gxwf tool-search \"collapse_collections\"` and `gxwf tool-search \"collapse collections\"` both returned no hits; `gxwf tool-search \"nml collapse\"` returned the correct tool as row 3 of 5; `gxwf tool-search \"Collapse Collection\"` returned it as row 1 of 2. Did not block this iteration (the wrapper identity was already known from the draft's own Identity-pinned `tool_id` and a prior same-run resolution), but would block or mislead a cold discover-shed-tool search that started from only a Tool Shed repo slug."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/574

  - id: gxwf-draft-validate-json-flag-emits-non-json-diagnostics-on-stdout
    raised_by: advance-galaxy-draft-step
    observed_in:
      mold:
        name: advance-galaxy-draft-step
        path: content/molds/advance-galaxy-draft-step/index.md
        revision: 4
        content_hash: c92d452f69a7b40bcab5fc8e63b03e1e2abf98f2a636abc4c93ad7f3c1d03082
        foundry_head: 63a3f9cf9c97a637fe1628d298e524f35709e289
    subject:
      kind: related-project
      label: "galaxy-tool-util-ts / @galaxy-tool-util/cli (gxwf draft-validate) -- --json report emission"
      locator: "https://github.com/jmchilton/galaxy-tool-util-ts (packages/cli, gxwf draft-validate, @galaxy-tool-util/cli@1.8.1)"
    kind: defect
    severity: minor
    what: "`gxwf draft-validate <file> --concrete --json` writes one or more human-readable diagnostic lines (e.g. `toolshed fetch failed (...) for iuc~kmindex~kmindex_query: <huge inline TS type dump>`, followed by an ASCII tree of the failing schema path) directly to stdout, ahead of the actual JSON report object, whenever a tool-state fetch during the --concrete pass fails to decode (same underlying decode failure as ledger entry `tool-util-cli-toolshed-fetch-rejects-real-filtered-list-collection-output`). This happens even though stderr is a separate stream the process already uses for nothing observed in this run's redirection test, and even though `--help` explicitly describes `--json` as '(Output structured JSON report)'."
    expected: "When `--json` is passed, stdout should contain only the single parseable JSON report object (matching the flag's own documented contract); any fetch-failure/decode-diagnostic text (which draft-validate itself already degrades gracefully into the report's own `skip_tool_not_found` status/errors array) should go to stderr, or be folded into the JSON report's own warnings/errors, not interleaved onto stdout ahead of the JSON payload."
    evidence: "Ran `gxwf draft-validate galaxy-workflow-draft.gxwf.yml --concrete --json 1>/tmp/dv.out 2>/tmp/dv.err` this iteration (implementing join_gene_summary_rows_into_manifest, an unrelated step -- the failing tool-state fetch was for a different, already-implemented step, kmindex_containment_screen/kmindex_query, whose Tool Shed fetch fails per the already-tracked cli defect above). `/tmp/dv.err` was empty; `/tmp/dv.out`'s first bytes were the literal diagnostic text `toolshed fetch failed (...` (confirmed via `head -c 1 | xxd` = `t`, not `{`), not JSON. Had to manually locate the first line starting with `{` and slice from there before `json.loads` would parse the report. The same command without `--json` (plain human-readable mode) is unaffected since it is not claiming to emit machine-parseable output. Non-blocking this iteration only because the diagnostic text happened to precede rather than interleave with the JSON block, and because I fell back to line-scanning; a caller doing a naive `stdout | jq` would hard-fail."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/548#issuecomment-5733272931

  - id: paper-to-test-data-no-scoping-or-toolshed-fixture-guidance
    raised_by: paper-to-test-data
    observed_in:
      mold:
        name: paper-to-test-data
        path: content/molds/paper-to-test-data/index.md
        revision: 2
        content_hash: 863d7b503a77fa63449899f124d1669e181fdfd9a72f81f516a219cdc89cb6bb
        foundry_head: 63a3f9cf9c97a637fe1628d298e524f35709e289
    subject:
      kind: mold
      label: paper-to-test-data
      locator: content/molds/paper-to-test-data/index.md
    kind: gap
    severity: minor
    what: "paper-to-test-data's SKILL.md is a single-paragraph procedure ('read freeform-summary, derive test inputs/outputs') with no packaged Load-On-Demand references and no guidance at all for the ordinary case this run hit: the paper's own named datasets (kmindex Logan shards, LexicMap Logan indices) are production/external-service scale and cannot become a fast test fixture as named. Its next-in-chain sibling, find-test-data, packages exactly this guidance -- references/notes/iwc-test-data-conventions.md's 'small is a documented subset of a real source, not a fabricated stand-in' rule, plus an explicit step to search IWC/Tool-Shed fixtures when the source's own named data is the wrong shape/scale. Run head-to-head on the same freeform-summary (this run's phix174 kmindex/LexicMap workflow), paper-to-test-data alone could only restate the summary's already-flagged gaps, while find-test-data's packaged convention led directly to real, reusable, already-committed Tool-Shed test-data (galaxyproject/tools-iuc tools/kmindex/test-data and tools/lexicmap/test-data) that resolved the equivalent structural fixture."
    expected: "paper-to-test-data should either package the same scoping-down / prefer-upstream-test-fixture guidance find-test-data has (so it is not systematically the weaker half of its own declared fallback chain for any workflow with externally-hosted/production-scale reference data), or its own doc should say explicitly when to fall through early (e.g. 'when the paper's cited data is production/external-service scale and not itself a downloadable fixture, this skill's output should mark those inputs resolved: false and the caller should proceed to find-test-data without re-deriving from the same summary') rather than leaving that judgment entirely to the calling harness."
    evidence: "This run (draft-manuscript-galaxy, phase 7): freeform-summary.md names 109 kmindex Logan shards and up to 25 LexicMap Logan indices (Stage B/C) as the workflow's reference-data universe, all hosted only at usegalaxy.org production scale; paper-to-test-data's procedure and references gave no path to anything smaller. find-test-data's iwc-test-data-conventions.md note, read for the same task, pointed directly at checking the pinned tools' own Tool Shed test-data directories, which surfaced real, already-CI-tested small fixtures (tools-iuc kmindex_query.xml test #6 'using register index', lexicmap.xml tests #3/#4/#6) usable as structural smoke-test data for this workflow's kmindex_containment_screen and lexicmap_search steps. Not blocking this run (the harness's own branch protocol tries both skills in order), but paper-to-test-data contributed no incremental value beyond a plain re-read of freeform-summary.md for this workflow's two hardest inputs."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/575

  - id: galaxy-workflow-test-plan-schema-fixture-required-for-scalar-typed-params
    raised_by: freeform-summary-to-galaxy-test-plan
    observed_in:
      mold:
        name: freeform-summary-to-galaxy-test-plan
        path: content/molds/freeform-summary-to-galaxy-test-plan/index.md
        revision: 2
        content_hash: 9c1d56e625a5dd26cb7a82082ac8f4eeb7db287a626bf00e73457c8dd491ad6d
        foundry_head: 63a3f9cf9c97a637fe1628d298e524f35709e289
    subject:
      kind: schema
      label: galaxy-workflow-test-plan (JobInput/Fixture $defs)
      locator: "package://@galaxy-foundry/gxwf-foundry#galaxyWorkflowTestPlanSchema"
      content_hash: 325e9cf1bb5e075fa818dc68868647de95389ca8df8581ee8cf1e2be61196e37
    kind: gap
    severity: minor
    what: "JobInput.fixture is required (non-optional) and always resolves to the Fixture $def, whose four fields (storage, location, checksum, provenance) and whose enum for `storage` (remote-url, in-repo, cvmfs-string, generated-toy, unresolved, null) are all phrased in file/collection-fixture terms. Neither the schema's own field descriptions nor any packaged on-demand note (iwc-test-data-conventions.md, planemo-asserts-idioms.md, galaxy-workflow-testability-design.md) says what to do for a JobInput that is a plain typed scalar workflow parameter (int, float, boolean, or a text param carrying a literal default, e.g. this workflow's kmindex_zvalue=6 or tiling_qc_allow_frameshifts=false) rather than a file or collection. iwc-test-data-conventions.md section 5 covers only the CVMFS/.loc 'bare string matching a data-table value' case, which is a different shape again (a reference-data selector, not an arbitrary typed parameter default)."
    expected: "Either make `fixture` on JobInput conditionally optional/nullable-as-a-whole when the input is a plain scalar parameter (not a file/collection/data-table selector), or add an explicit Fixture convention for this case (e.g. storage: null with the literal default value carried in `location`, as this plan did) so different Molds/runs do not each invent their own encoding for the same common situation."
    evidence: "This run's workflow (galaxy-workflow.gxwf.yml) declares 15 workflow inputs, of which 12 are plain typed scalars with literal pinned defaults (kmindex_zvalue, kmindex_threshold, kmindex_output_format, kmindex_fast, lexicmap_top_n_genomes, lexicmap_advanced_all, and the 6 tiling_qc_* params). Each needed a JobInput entry (required by the TestCase schema) whose required `fixture` object has no natural file/location/checksum reading. Absent any documented convention, this plan used `storage: null` with the default value's string form placed in `location`, and `provenance` noting 'workflow default, per galaxy-workflow.gxwf.yml default' -- a reasoned choice, not a documented one."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/576

  - id: freeform-summary-to-galaxy-test-plan-silent-on-concrete-draft-and-test-data-refs-inputs
    raised_by: freeform-summary-to-galaxy-test-plan
    observed_in:
      mold:
        name: freeform-summary-to-galaxy-test-plan
        path: content/molds/freeform-summary-to-galaxy-test-plan/index.md
        revision: 2
        content_hash: 9c1d56e625a5dd26cb7a82082ac8f4eeb7db287a626bf00e73457c8dd491ad6d
        foundry_head: 63a3f9cf9c97a637fe1628d298e524f35709e289
    subject:
      kind: mold
      label: freeform-summary-to-galaxy-test-plan
      locator: content/molds/freeform-summary-to-galaxy-test-plan/index.md
      content_hash: 9c1d56e625a5dd26cb7a82082ac8f4eeb7db287a626bf00e73457c8dd491ad6d
    kind: gap
    severity: minor
    what: "The Mold's declared Inputs (freeform-summary, freeform-galaxy-interface, freeform-galaxy-data-flow, iwc-comparison-notes, iwc-exemplar-gxformat2) and its 'Labels and fixtures are assumed, not bound' procedure section both describe this skill as operating only against template-era briefs, directing label_status: assumed and workflow.label_source: interface-brief in every case. Nothing in the Mold's own SKILL.md anticipates or documents the case actually encountered in this run: a concrete gxformat2 workflow draft and resolved test-data-refs artifact already existed in the harness run-state by phase 8 and were handed to this invocation as extra grounding context, with an explicit instruction to keep the plan consistent with them. The Mold gives no guidance on whether `label_source` should then be 'draft' (since a concrete draft actually was read) or 'interface-brief' (since that is this Mold's only documented input class), nor on how `label_status` should reflect a label that was cross-checked against a real draft rather than merely assumed from a brief."
    expected: "Document an optional grounding-input case in this Mold's Inputs/Procedure: when a caller also supplies the concrete workflow draft and/or resolved test-data refs (as changeset-to-galaxy-test-plan and the *-test-to-galaxy-test-plan siblings already do for their own analogous 'carry forward' cases), state explicitly which `label_source` and `label_status` values apply, and how far the plan may rely on those artifacts before that reliance should instead be deferred to implement-galaxy-workflow-test's own workflow-label cross-check."
    evidence: "This run's harness passed galaxy-workflow.gxwf.yml (the concrete 9-step draft) and test-data-refs.json (phase 7's resolved gene E/J test-data scoping) as additional context alongside this Mold's normal declared inputs, with an instruction to avoid contradicting them. Absent any packaged guidance for this hybrid situation, this plan set workflow.label_source: draft and label_status: resolved throughout (since every label was in fact read from and matches the concrete draft's own ids), which is a reasoned but undocumented departure from the Mold's own stated 'assumed'/'interface-brief' default behavior."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/577

  - id: tests-format-job-schema-has-no-path-to-an-intermediate-step-input-port
    raised_by: implement-galaxy-workflow-test
    observed_in:
      mold:
        name: implement-galaxy-workflow-test
        path: content/molds/implement-galaxy-workflow-test/index.md
        revision: 8
        content_hash: 966c486ccda2eb1e0f06afa674c5d6b85a7e7bfcc9b1545309e3ef8b1016f931
        foundry_head: 63a3f9cf9c97a637fe1628d298e524f35709e289
    subject:
      kind: schema
      label: "tests-format (Job / TestJob $defs)"
      locator: "package://@galaxy-foundry/gxwf-foundry#testsFormatSchema"
      content_hash: ff0de5041f4c3de0ab7abe9e7555c5a7120665b077f42661461301b0fb26f372
    kind: gap
    severity: major
    what: "The harness's phase-9 task instruction directed constructing a synthetic LexicMap hits TSV and 'wiring it as the lexicmap_results input the test case feeds toward lexicmap_streamer_tiling_qc' so the am3 assertions would be checkable end-to-end. But lexicmap_results is not a top-level workflow input on galaxy-workflow.gxwf.yml -- it is wired to an internal step output (lexicmap_search/out_file). The tests-format schema's `Job` $def (`TestJob.job`) is `additionalProperties: <value-types>` with no structural provision for keying a value to anything but a top-level workflow input label, and the packaged planemo-workflow-test-architecture.md / planemo-asserts-idioms.md notes describe Planemo's `job:` block exclusively in terms of workflow-level inputs. There is no documented (or apparently possible) tests-format mechanism to inject a value onto an intermediate step's input port for a whole-workflow test."
    expected: "Either document explicitly (in tests-format's schema description or in planemo-workflow-test-architecture.md) that a synthetic fixture for an internal step is NOT expressible via `job:` and must instead be pursued via a real registered index/data-table entry or a separate component/tool-level test -- so a Mold is not directed to do something the format cannot express -- or, if Planemo/Galaxy actually has an undocumented mechanism for this (e.g. a `--test_index`-scoped step-parameter override), document and cite it."
    evidence: "This run: after confirming (by reading tests-format.schema.json's Job/TestJob $defs directly) that job keys can only bind workflow-level input labels, test case gene_e_j_am3_diagnostic_synthetic_lexicmap_index in galaxy-workflow.gxwf-tests.yml could not literally wire the synthetic hits TSV onto lexicmap_streamer_tiling_qc's lexicmap_results port. The synthetic fixture was instead staged under test-data/synthetic_am3/ and its expected effects validated by directly executing the real vendored lexicmap_streamer.py script outside of Planemo, with lexicmap_index_selection left as a documented placeholder pending real index construction (galaxy-test-plan.yml unresolved[0]/[1])."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/578

  - id: tests-format-schema-silent-on-sample-sheet-column-definitions-shape
    raised_by: implement-galaxy-workflow-test
    observed_in:
      mold:
        name: implement-galaxy-workflow-test
        path: content/molds/implement-galaxy-workflow-test/index.md
        revision: 8
        content_hash: 966c486ccda2eb1e0f06afa674c5d6b85a7e7bfcc9b1545309e3ef8b1016f931
        foundry_head: 63a3f9cf9c97a637fe1628d298e524f35709e289
    subject:
      kind: research
      label: iwc-test-data-conventions (Collection.rows / sample_sheet shape)
      locator: content/research/iwc-test-data-conventions/index.md
      content_hash: 1921e939703444604440e0768caca6e6b834a73dcfa964f450fa081143e008d3
    kind: gap
    severity: minor
    what: "galaxy-workflow.gxwf.yml's primary input, gene_query_panel, is `collection_type: sample_sheet` with 4 optional per-element `column_definitions` (the per-gene LexicMap sensitivity overrides). tests-format.schema.json's `Collection` $def does carry a `rows` field (additionalProperties: column-name -> array) seemingly meant for exactly this, but neither iwc-test-data-conventions.md (this skill's authoritative note on job/input YAML shapes, which documents List/Paired/list:paired/list:list:paired/composite_data in detail) nor any other packaged note mentions `sample_sheet`, `column_definitions`, or `rows` at all, and a corpus grep for these terms across the whole skill bundle returns nothing beyond the bare schema field."
    expected: "Add a worked `sample_sheet` + `rows:` example to iwc-test-data-conventions.md (or a note it references) alongside the existing collection-shape sections, so a Mold does not have to infer the shape from the schema's generic field alone."
    evidence: "galaxy-workflow.gxwf-tests.yml's test case 2 encodes gene_query_panel's per-gene align_min_match_pident/align_min_match_len/seed_min_prefix/min_qcov_per_genome overrides as `rows: {align_min_match_pident: [60.0, null], ...}` alongside `elements:` -- a reasoned best-effort construction against the bare schema field, passing `gxwf validate-tests --workflow` cleanly, but with no corpus precedent to confirm it is actually what Planemo/Galaxy expects at runtime."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/579

  - id: galaxy-workflow-frame-comments-missing-position-size-rejected-by-real-galaxy-import
    raised_by: implement-galaxy-workflow-test
    observed_in:
      mold:
        name: implement-galaxy-workflow-test
        path: content/molds/implement-galaxy-workflow-test/index.md
        revision: 8
        content_hash: 966c486ccda2eb1e0f06afa674c5d6b85a7e7bfcc9b1545309e3ef8b1016f931
        foundry_head: 63a3f9cf9c97a637fe1628d298e524f35709e289
    subject:
      kind: related-project
      label: "Galaxy (galaxyproject/galaxy) WorkflowCommentModel vs. this pipeline's gxformat2 `comments: type: frame` authoring"
      locator: "galaxyproject/galaxy: lib/galaxy/model/__init__.py (WorkflowCommentModel), lib/galaxy/managers/workflows.py (_workflow_from_raw_description)"
    kind: gap
    severity: major
    what: "Attempting `planemo test --test_index 1 --install_galaxy galaxy-workflow.gxwf.yml` (a bounded attempt at the second validation step of this phase) failed before any test data was staged or any tool was run: Galaxy's real workflow-import API rejected galaxy-workflow.gxwf.yml with HTTP 400, 'Field required in (\"frame\",\"position\")' and 'Field required in (\"frame\",\"size\")'. The workflow's own `comments:` block (4 `type: frame` entries grouping steps into Stage A/B/C/D2, e.g. `{type: frame, label: 'Stage A — input assembly', title: ..., contains_steps: [...]}`) carries no `position`/`size` fields, which real Galaxy's WorkflowCommentModel requires for any frame-type comment. This means the concrete workflow produced by earlier phases (advance-galaxy-draft-step / freeform-summary-to-galaxy-template, whichever Mold first authored these frame comments) is schema-valid enough to pass this pipeline's own `gxwf draft-validate --concrete` gate but is NOT actually importable into a real Galaxy instance."
    expected: "Whichever Mold/reference documents the gxformat2 `comments: type: frame` shape should require (or default) `position: {x, y}` and `size: {width, height}` fields, and `gxwf draft-validate`/`validate-galaxy-workflow` should be extended to catch this class of real-Galaxy-only requirement before a Planemo run discovers it at import time."
    evidence: "Full traceback captured during this phase's `planemo test` attempt: bioblend.ConnectionError: Unexpected HTTP status code: 400, pydantic_core ValidationError 'WorkflowCommentModel: frame.position Field required, frame.size Field required', raised from galaxy.managers.workflows.build_workflow_from_raw_description -> model.WorkflowComment.from_dict on the first frame comment `{id:0, type:frame, data:{title:'Stage A — input assembly'}, child_steps:[15], label:'Stage A — input assembly'}`. This blocked test case 1 before tool installation/dependency resolution was ever reached, so it was not possible to determine whether the kmindex/lexicmap/UDT tool chain itself would install and run cleanly."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/580

  - id: gxwf-validate-connections-flag-crashes-uncaught-on-format2-dict-shaped-step-in
    raised_by: validate-galaxy-workflow
    observed_in:
      mold:
        name: validate-galaxy-workflow
        path: content/molds/validate-galaxy-workflow/index.md
        revision: 5
        content_hash: 74e3743fc376f33c1eb37832ab4869c327d48f87e015c7a38597cf4c4ca939cd
        foundry_head: 79bf5c3ab98eec3a67948d8bdebb9dba7d8a2359
    subject:
      kind: related-project
      label: "galaxy-tool-util-ts / @galaxy-tool-util/cli (gxwf validate --connections) -- normalized-workflow-to-native step builder"
      locator: "https://github.com/jmchilton/galaxy-tool-util-ts (packages/schema, workflow/normalized/toNative.js:429 _extractConnections; packages/connection-validation, graph-builder.js; @galaxy-tool-util/cli@1.10.1)"
    kind: defect
    severity: major
    what: "`gxwf validate galaxy-workflow.gxwf.yml --json --connections` (and the same with `--strict` added) crashes with an uncaught `TypeError: step.in is not iterable` at `toNative.js:429` (`_extractConnections`, called from `_buildToolStep` -> `_buildStep` -> `_buildNativeWorkflow` -> `toNative` -> `_coerceNormalizedNative` -> `buildWorkflowGraph` -> `validateConnectionsReport` -> `buildConnectionReport`), exits 1, and emits no JSON report at all -- not even a `connection_report: null` degrade the way tool-state fetch failures degrade to `skip_tool_not_found`. This workflow's every step's `in:` is an ordinary gxformat2 mapping (`{port_name: source, ...}`, e.g. `in: {input_list: gene_query_panel}`), the standard and only shape gxformat2's own schema documents for step connections (see this same run's `gxformat2-schema-missing-nested-in-key-convention` entry, which independently confirms and cites this `in:` mapping shape). `_extractConnections`'s `for (const stepInput of step.in)` expects `step.in` to already be an array (the native-format shape), so any format2 workflow with a normal dict-shaped `in:` reaching this code path crashes rather than being converted."
    expected: "`_extractConnections` (or its caller) should convert a format2 dict-shaped `step.in` into the array shape it expects before iterating -- the same normalization `toNative` already performs successfully for the plain `gxwf validate` (no `--connections`) path, since that path reads this exact workflow's steps without error. `gxwf validate --connections` should either work on an ordinary format2 workflow or fail gracefully (a caught, reported error in the JSON `connection_report` field, matching the tool-state fetch failure's graceful `skip_tool_not_found` degrade) rather than throwing an uncaught exception that discards the entire report."
    evidence: "Reproduced directly this phase: `gxwf validate galaxy-workflow.gxwf.yml --json --connections` and `gxwf validate galaxy-workflow.gxwf.yml --json --connections --strict` both exit 1 with the identical stack trace, no stdout JSON at all (the process crashes before writing the report object). `gxwf validate galaxy-workflow.gxwf.yml --json --strict` (same workflow, same flags minus `--connections`) exits 0 and produces a full JSON report (5 ok / 0 fail / 4 skip). This skill's own SKILL.md directs using `--connections` 'when tool cache metadata is available and data-shape compatibility matters, especially around collections and map-over' -- squarely this workflow's shape (9 steps, heavy collection map-over across kmindex/lexicmap/UDT steps) -- so the flag's total unusability here is a real, non-hypothetical gap, not an edge case. Worked around by validating without `--connections` and recording collection/map-over shape compatibility as a residual runtime risk instead."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/581

  - id: run-workflow-test-no-mechanism-to-install-authored-galaxyusertool-udts
    raised_by: run-workflow-test
    observed_in:
      mold:
        name: run-workflow-test
        path: content/molds/run-workflow-test/index.md
        revision: 6
        content_hash: unavailable-in-cast
        foundry_head: 79bf5c3ab98eec3a67948d8bdebb9dba7d8a2359
    subject:
      kind: mold
      label: run-workflow-test
      locator: content/molds/run-workflow-test/index.md
    kind: gap
    severity: major
    what: "Neither run-workflow-test's own packaged references (planemo.md, planemo-workflow-test-architecture.md, planemo-asserts-idioms.md, galaxy-workflow-invocation-failure-reference.md) nor author-galaxy-tool-wrapper's (which explicitly states its output is 'a single GalaxyUserTool YAML document, not Galaxy XML') document any mechanism by which a locally-authored GalaxyUserTool YAML definition (no Tool Shed presence) is supposed to reach a Planemo-managed Galaxy's toolbox for a workflow test run. `planemo test`'s only documented tool-injection option, `--extra_tools <file|directory>`, was tried against a directory holding this run's 3 UDT YAML files; planemo emits a `<tool_dir dir=\"...\">` entry into the generated tool_conf.xml (confirmed by reading the generated file directly), and Galaxy's toolbox parses that tool_conf.xml, but Galaxy's classic `tool_dir` scanner only auto-discovers XML tool wrappers -- zero log lines anywhere reference any of the 3 UDT ids/files, and the subsequent real workflow-invocation attempt's HTTP 400 explicitly lists `lexicmap_streamer (version 1.0.0)`, `flatten_gene_summary_json_to_row (version 1.0.0)`, and `kmindex_hit_dedup_max_score (version 1.0.0)` among the 'required tools are not installed', proving the toolbox never registered them at all."
    expected: "Either document a real, working path for a GalaxyUserTool YAML to reach a Planemo-managed toolbox for testing (e.g. a `gxwf`/`galaxy-tool-util` command that lowers `class: GalaxyUserTool` to a classic Galaxy tool XML + script directory that `--extra_tools` can actually load, or an alternate Planemo/Galaxy API this skill bundle should cite), or state explicitly in run-workflow-test's own procedure that an authored UDT with no such lowering step is expected to fail tool-shed/toolbox resolution in a real Planemo run and name the concrete blocking condition as `not-run`/`fail`-with-tool-install-modality rather than leaving the caller to discover this empirically."
    evidence: "Phase 11 of this run (draft-manuscript-galaxy). Copied the 3 UDT YAMLs (galaxy-user-tool.yml, galaxy-user-tool-flatten-gene-summary.yml, galaxy-user-tool-kmindex-hit-dedup-max-score.yml) into a scratch directory and passed it via `planemo test --extra_tools <dir> --install_galaxy --test_index 2 ...`. Verified the generated tmp tool_conf.xml contained `<tool_dir dir=\".../udt-tools\" />`; grepped both this run's planemo-test1.log and planemo-test2.log for the 3 UDT ids/filenames/`GalaxyUserTool` and found zero matches anywhere in either log. The subsequent workflow-invocation attempt for test case 2 (`POST /api/workflows/.../invocations` -> HTTP 400) returned `err_msg: \"Workflow was not invoked; the following required tools are not installed: ... lexicmap_streamer (version 1.0.0), flatten_gene_summary_json_to_row (version 1.0.0), kmindex_hit_dedup_max_score (version 1.0.0), ...\"`, confirming the toolbox has no record of these 3 tool ids under any mechanism this run attempted."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/582

  - id: galaxy-tool-util-replacement-collection-requires-rows-key-unconditionally
    raised_by: run-workflow-test
    observed_in:
      mold:
        name: run-workflow-test
        path: content/molds/run-workflow-test/index.md
        revision: 6
        content_hash: unavailable-in-cast
        foundry_head: 79bf5c3ab98eec3a67948d8bdebb9dba7d8a2359
    subject:
      kind: related-project
      label: "galaxy-tool-util (galaxy.tool_util.cwl.util.replacement_collection) -- Planemo job-input staging for sample_sheet collections"
      locator: "https://github.com/galaxyproject/galaxy (packages/tool_util, lib/galaxy/tool_util/cwl/util.py, galaxy-tool-util==25.1.2, vendored into planemo==0.75.47)"
    kind: defect
    severity: major
    what: "`galaxy.tool_util.cwl.util.replacement_collection()` (the function Planemo's `stage_in`/`galactic_job_json` path uses to turn a tests-format `job:` Collection value into a Galaxy HDCA-creation payload) contains `if collection_type.startswith(\"sample_sheet\"): kwds[\"rows\"] = value[\"rows\"]` -- an unconditional dict-index (not `.get()`) on the job value's optional `rows` key. tests-format.schema.json's own `Collection` $def does not require `rows` (this workflow's own test case 1, `kmindex_wiring_smoke_generic_fixtures`, intentionally omits it -- 'not meaningful for generic non-phiX174 fixture content' -- and that test file already passed `gxwf validate-tests --workflow ... --json` cleanly with `rows` absent). Any `sample_sheet`-typed Collection job input that legitimately omits `rows` therefore crashes Planemo's staging step with an uncaught `KeyError: 'rows'` before any Galaxy invocation is even created, rather than surfacing as a graceful assertion/staging-problem report."
    expected: "`replacement_collection` should use `kwds[\"rows\"] = value.get(\"rows\", {})` (or omit the key entirely when absent, if Galaxy's collection-create API tolerates a missing `rows`), matching the tests-format schema's own treatment of `rows` as optional for a `sample_sheet` Collection value."
    evidence: "Reproduced directly this phase: `planemo test --install_galaxy --test_index 1 --extra_tools <dir> galaxy-workflow.gxwf.yml` crashed with `execution_problem: \"'rows'\"`, `status: \"error\"`, `invocation_details: null`, `job: null` in the structured `tool_test_output.json` -- i.e. staging failed before any Galaxy invocation existed. Full traceback: `planemo/galaxy/activity.py:441 stage_in -> galaxy/tool_util/client/staging.py:275 stage -> galaxy/tool_util/cwl/util.py:388 galactic_job_json -> :234 replacement_item -> :362 replacement_collection -> KeyError: 'rows'`. Confirmed the isolating variable by contrast: test case 2 (`gene_e_j_am3_diagnostic_synthetic_lexicmap_index`), whose `gene_query_panel` Collection DOES carry a `rows:` block, staged past this exact code path without error in the immediately following run and reached a real (differently-failing) workflow-invocation attempt. Installed package confirmed at `galaxy_tool_util-25.1.2.dist-info` under planemo 0.75.47's own venv."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/583

  - id: galaxy-workflow-invocation-check-rejects-previously-installed-tool-as-not-installed
    raised_by: debug-galaxy-workflow-output
    observed_in:
      mold:
        name: debug-galaxy-workflow-output
        path: content/molds/debug-galaxy-workflow-output/index.md
        revision: 5
        content_hash: 100b3f985f8e309092bfd05cf544a8286e0a878ee2df3a155dfebe6fcdb286f0
        foundry_head: 63a3f9cf9c97a637fe1628d298e524f35709e289
    subject:
      kind: research
      label: galaxy-workflow-invocation-failure-reference
      locator: content/research/galaxy-workflow-invocation-failure-reference/index.md
      content_hash: e8115df6ddca447d47d77cb33becda847cdd19b2cbe9924782bfc180b94bb451
    kind: gap
    severity: major
    what: "The note's 'Request-time validation' surface (API error before a useful invocation state exists, e.g. an HTTP 400 'required tools are not installed') gives no guidance on how to tell a genuine per-tool dependency/installation failure apart from a toolbox-state read that is stale relative to the just-completed install/reload cycle. This phase found a concrete, reproducible tell that the note doesn't mention: in this run's test 2, `planemo-test2.log:292` shows `collapse_collections` (providing `collapse_dataset`) was *skipped* for reinstall because its cached status was already 'Installed' -- no fresh clone, no fresh dependency resolution occurred for it this run -- yet the subsequent `POST /api/workflows/.../invocations` 400 (`planemo-test2.log:1775-1796`) still lists `collapse_dataset` among the 'not installed' tools, 54 seconds later, alongside 3 real freshly-cloned Tool Shed tools and 3 never-installable UDTs. A tool with a confirmed pre-existing good install status being rejected is strong evidence the invocation-validation check read stale/incomplete toolbox state rather than a real, current dependency failure for that specific tool -- but nothing in this note documents 'a previously-Installed repository still appearing in the not-installed list' as a diagnostic signal for this class of race, so the classification had to be reconstructed ad hoc from Galaxy install-manager log lines rather than a documented reference path."
    expected: "Add this diagnostic tell to the 'Request-time validation' row (or a new row) in galaxy-workflow-invocation-failure-reference.md: when a tool listed as 'not installed' in a request-time 400 has a repository install-manager log line showing its install was skipped because it was already 'Installed' from a prior/cached run, that is evidence of a toolbox-state read/reload-timing defect rather than a genuine dependency-resolution failure for that tool, and should route debugging toward Galaxy's toolbox-reload/tool-availability-check code path rather than toward the wrapper's conda requirements."
    evidence: "draft-manuscript-galaxy phase 12. `planemo-test2.log:292`: \"Skipping installation of revision 90981f86000f of repository 'collapse_collections' because it was installed with the (possibly updated) revision 90981f86000f and its current installation status is 'Installed'.\" `planemo-test2.log:1775,1796`: `POST /api/workflows/961e7c4742a92de4/invocations HTTP/1.1 400` with `err_msg` listing `collapse_dataset (version 5.1.0)` among 7 'not installed' tools. Last logged `reload_toolbox` control-task cycle completes at `11:50:13,808`; the invocation POST fires at `11:50:58,531`, 45s later -- ruling out an in-flight reload as the immediate cause and pointing instead at how the invocation-validation code path sources its toolbox snapshot."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/584

  - id: galaxy-udt-registration-real-endpoint-is-unprivileged-tools-not-dynamic-tools
    raised_by: run-workflow-test
    observed_in:
      mold:
        name: run-workflow-test
        path: content/molds/run-workflow-test/index.md
        revision: 7
        content_hash: 259675e41c65f7622049cc9ef5f64b7d9f7ac5edb005555a09045e747708218c
        foundry_head: 79bf5c3ab98eec3a67948d8bdebb9dba7d8a2359
    subject:
      kind: related-project
      label: "Galaxy core (lib/galaxy/webapps/galaxy/api) -- dynamic-tool registration endpoints"
      locator: "https://github.com/galaxyproject/galaxy (lib/galaxy/webapps/galaxy/api/dynamic_tools.py, lib/galaxy/webapps/galaxy/api/tools.py)"
    kind: gap
    severity: major
    what: "This run's earlier entry (run-workflow-test-no-mechanism-to-install-authored-galaxyusertool-udts) found no way to load a GalaxyUserTool YAML into a Planemo-managed toolbox and, separately, `POST /api/dynamic_tools` against a real production Galaxy instance (usegalaxy.org) returned HTTP 403 ('You must be an administrator to access this feature'). Neither run-workflow-test's nor author-galaxy-tool-wrapper's packaged references mention that Galaxy exposes a SEPARATE, non-admin-gated endpoint for exactly this: `POST /api/unprivileged_tools`, gated only by a `USER_TOOL_EXECUTE` role plus the instance's `enable_beta_tool_formats` config flag (both satisfied by an ordinary usegalaxy.org account). A regular user's own GalaxyUserTool YAML (converted to the JSON body that endpoint expects) registers there successfully and becomes a real, invocable, user-scoped dynamic tool with a `tool_uuid`."
    expected: "author-galaxy-tool-wrapper and/or run-workflow-test should document `POST /api/unprivileged_tools` as the real-Galaxy registration path for an authored GalaxyUserTool (distinct from the admin-only `/api/dynamic_tools`), including its role/config gating (`USER_TOOL_EXECUTE`, `enable_beta_tool_formats`) and that a successful registration returns a `tool_uuid` a workflow step must reference (see the companion entry on gxformat2 not modeling `tool_uuid`) rather than a bare `tool_id` string."
    evidence: "draft-manuscript-galaxy, post-pipeline deploy step. `POST https://usegalaxy.org/api/dynamic_tools` with a GalaxyUserTool-derived body -> HTTP 403 admin-required. `POST https://usegalaxy.org/api/unprivileged_tools` with the same tool content (after fixing a separate lint defect, see the companion `value: 0` entry) -> 200, returning a real `tool_uuid` for each of this run's 3 UDTs (lexicmap_streamer, flatten_gene_summary_json_to_row, kmindex_hit_dedup_max_score), later confirmed resolvable with zero step errors via `GET /api/workflows/{id}/download` once wired into the imported workflow."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/585

  - id: galaxy-workflow-import-enforces-undocumented-per-field-length-limit-on-step-doc
    raised_by: freeform-summary-to-galaxy-template
    observed_in:
      mold:
        name: freeform-summary-to-galaxy-template
        path: content/molds/freeform-summary-to-galaxy-template/index.md
        revision: 6
        content_hash: 0a95f8c04465d48131ace523e0b27af53f1ade6e525a9173c5ff1e936ddc3366
        foundry_head: 63a3f9cf9c97a637fe1628d298e524f35709e289
    subject:
      kind: related-project
      label: "Galaxy core -- POST /api/workflows gxformat2 import, step doc/annotation field"
      locator: "https://github.com/galaxyproject/galaxy (workflow import/gxformat2 conversion path)"
    kind: defect
    severity: major
    what: "A real Galaxy instance (usegalaxy.org, 26.1.2.dev0) rejects `POST /api/workflows` with an opaque, tracebackless HTTP 500 when any step's `doc:` (annotation) field exceeds a real, undocumented length limit. Bisected directly against the live endpoint: a step `doc` of 2000 characters imports fine; 2398 characters 500s; the limit sits at exactly 2048 characters. Neither `gxwf draft-validate`/`gxwf validate` (both passed clean, repeatedly, on the same file) nor galaxy-workflow-draft-format's or gxformat2-schema's packaged notes model or enforce any such limit -- this run's `freeform-summary-to-galaxy-template` output (and later advance-galaxy-draft-step iterations folding `_plan_context` rationale into `doc:` per that skill's own 'a resolved step carries no _plan_* fields' rule) produced 5 step `doc` fields well over 2048 characters, all invisible to every static check available in this toolchain, only surfacing as a bare 500 at real-Galaxy import time."
    expected: "gxwf's draft-validate/validate should check step (and workflow-level) `doc`/`annotation` field length against Galaxy's real limit (~2048 chars, worth confirming the exact DB column width upstream) and fail with a clear diagnostic naming the offending step and its length, rather than letting a workflow pass all local validation and then 500 opaquely at real-Galaxy import. Separately, freeform-summary-to-galaxy-template's convention of folding full authoring/discovery provenance into a step's `doc:` field (rather than only in the run's own ledgers) should be revised to keep `doc:` short and put full provenance in open-requirements/feedback ledger entries instead, given this real, silent ceiling."
    evidence: "draft-manuscript-galaxy, post-pipeline deploy step. Direct `POST /api/workflows` bisection against https://usegalaxy.org/api/workflows: doc length 2000 -> 200 OK; 2398 -> 500 'Uncaught exception in exposed API method' (no traceback surfaced to the client); 2048 -> 200 OK. Trimmed 5 oversized step `doc` fields in galaxy-workflow.gxwf.yml (kmindex_hit_dedup_max_score, lexicmap_streamer_tiling_qc, and 3 others) from full authoring-provenance prose down to concise summaries, after which the same workflow imported successfully."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/564#issuecomment-5733272414

  - id: galaxy-unprivileged-tools-lint-crashes-on-integer-input-default-value-zero
    raised_by: author-galaxy-tool-wrapper
    observed_in:
      mold:
        name: author-galaxy-tool-wrapper
        path: content/molds/author-galaxy-tool-wrapper/index.md
        revision: 5
        content_hash: cced8f068cd1ce81fefad23a62fdb4d52b3ce805b2231f64a7fe37f258bc1e09
        foundry_head: ac92d2713fb01b07049027e584b8610e07c88d82
    subject:
      kind: related-project
      label: "Galaxy core -- POST /api/unprivileged_tools tool-creation lint (TestsCaseValidation)"
      locator: "https://github.com/galaxyproject/galaxy (unprivileged dynamic-tool creation / tool linting path)"
    kind: defect
    severity: minor
    what: "Galaxy's real tool-creation lint on `POST /api/unprivileged_tools` (invoked via `input_models_for_tool_source` / `TestsCaseValidation`) throws an uncaught, unhelpfully-reported exception ('TestsCaseValidation ... exception is []', no further detail) when a GalaxyUserTool integer input declares `value: 0` as its default -- confirmed by bisecting the tool's own input list live against the real endpoint: identical input with `value: 1` registers successfully, `value: 0` fails every time. galaxy-user-tool-authoring.md (author-galaxy-tool-wrapper's own packaged reference) documents the `value:` field for scalar inputs generally but does not warn that a literal `0` default on an integer input is unsupported."
    expected: "Either fix Galaxy's lint to handle a zero-valued integer default (the underlying bug), or, until fixed, have galaxy-user-tool-authoring.md warn against declaring `value: 0` on an integer/float UDT input and recommend omitting the default (relying on the step's own explicit wired value) when zero is the semantically correct default."
    evidence: "draft-manuscript-galaxy, post-pipeline deploy step. `POST https://usegalaxy.org/api/unprivileged_tools` with the `lexicmap_streamer` UDT (max_internal_stops integer input, `value: 0`) -> HTTP 400, opaque lint exception. Removing the `value: 0` default from that one input (workflow always supplies it explicitly anyway) -> 200 OK, tool registered with a real `tool_uuid`. Re-added the same field with `value: 1` on a throwaway test copy to confirm the value itself (not the field's mere presence) was the trigger."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/586

  - id: gxformat2-step-schema-does-not-model-tool-uuid-for-dynamic-tool-resolution
    raised_by: freeform-summary-to-galaxy-template
    observed_in:
      mold:
        name: freeform-summary-to-galaxy-template
        path: content/molds/freeform-summary-to-galaxy-template/index.md
        revision: 6
        content_hash: 0a95f8c04465d48131ace523e0b27af53f1ade6e525a9173c5ff1e936ddc3366
        foundry_head: 63a3f9cf9c97a637fe1628d298e524f35709e289
    subject:
      kind: related-project
      label: "gxformat2 schema / Galaxy workflow import -- dynamic-tool step resolution"
      locator: "https://github.com/galaxyproject/gxformat2 (step schema), https://github.com/galaxyproject/galaxy (native .ga workflow-step tool_uuid resolution)"
    kind: gap
    severity: major
    what: "A gxformat2 workflow step referencing a real, registered user-scoped dynamic tool (via `POST /api/unprivileged_tools`, see the companion endpoint entry) by bare `tool_id` string alone imports and round-trips (`gxwf convert`) without ever populating or requiring a `tool_uuid` -- but real Galaxy's step-to-tool resolution for a dynamic/unprivileged tool requires the native `.ga` JSON step to carry that tool's real `tool_uuid` explicitly; a bare `tool_id` never resolves to a user-scoped dynamic tool even after it is successfully registered and even though the same `tool_id` string is correct. This left all 3 UDT steps showing 'Tool is not installed' after a clean gxformat2 import, with no schema-level signal of what was missing. Compounded by a second, already-ledgered gxwf defect (`step.in is not iterable` on `gxwf convert`), which blocked using gxwf itself to do the format2->native conversion+injection, forcing a workaround via Galaxy's own `/api/workflows/{id}/download` to get native JSON, hand-inject the 3 real `tool_uuid`s, and re-`POST` that native form."
    expected: "Either extend the gxformat2 step schema/galaxy-workflow-draft-format to model an optional `tool_uuid` field (populated once a dynamic/UDT tool is registered) so a template/draft can carry it through the normal Foundry pipeline, or document explicitly in freeform-summary-to-galaxy-template / advance-galaxy-draft-step / run-workflow-test that a workflow step resolving to a GalaxyUserTool-authored dynamic tool must, at real-Galaxy deployment time, be converted to native `.ga` and have its `tool_uuid` injected post-registration -- this is not currently documented anywhere in the pipeline's packaged references."
    evidence: "draft-manuscript-galaxy, post-pipeline deploy step. gxformat2 import of galaxy-workflow.gxwf.yml (all 3 UDT tool_ids correct, tools already registered via /api/unprivileged_tools) still showed all 3 steps as tool-unresolved in the imported workflow. Fetched the imported workflow natively via `GET /api/workflows/{id}/download`, confirmed each UDT step's JSON had no `tool_uuid` key at all; manually set `tool_uuid` to each of the 3 registered tools' real UUIDs in that native JSON and re-imported via `POST /api/workflows` (native form) -- resulting workflow (id 575e9ee747b2031f) shows zero step errors on the same `GET .../download` check."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/587

  - id: lexicmap-search-sample-sheet-column-to-scalar-port-defect
    raised_by: debug-galaxy-workflow-output
    observed_in:
      mold:
        name: debug-galaxy-workflow-output
        path: content/molds/debug-galaxy-workflow-output/index.md
        revision: 5
        content_hash: 100b3f985f8e309092bfd05cf544a8286e0a878ee2df3a155dfebe6fcdb286f0
        foundry_head: 63a3f9cf9c97a637fe1628d298e524f35709e289
    subject:
      kind: mold
      label: advance-galaxy-draft-step
      locator: content/molds/advance-galaxy-draft-step/index.md
      content_hash: c92d452f69a7b40bcab5fc8e63b03e1e2abf98f2a636abc4c93ad7f3c1d03082
    kind: defect
    severity: major
    what: "advance-galaxy-draft-step's phase 6 iteration 2 (lexicmap_search implementation) wired the workflow's four per-gene LexicMap sensitivity overrides (align_min_match_pident, align_min_match_len, seed_min_prefix, min_qcov_per_genome) directly from `gene_query_panel` (a `sample_sheet` collection whose per-element columns carry these values) onto lexicmap_search's plain scalar `advanced_settings|*` tool ports (`in: advanced_settings|align_min_match_pident: gene_query_panel`, etc.) -- a binding that can never work. A sample_sheet collection's per-element column values are only readable by a tool that itself declares a `data_collection` input accepting `sample_sheet` and reads columns internally via `DatasetCollectionWrapper.sample_sheet_row()` in its own Cheetah/XML template; `lexicmap_search` (iuc/lexicmap 0.9.0+galaxy1) is an ordinary IUC tool with plain float/int scalar parameters and no sample_sheet awareness whatsoever. There is no generic Galaxy workflow-wiring mechanism to bind an arbitrary other tool's scalar parameter to a sample_sheet column at runtime -- rewiring the *connection* alone can never fix this; the whole design of carrying these 4 values as sample_sheet columns was unworkable from the start for feeding a non-sample_sheet-aware tool. Nothing in this pipeline's static checks caught it: `gxwf draft-validate`/`gxwf validate` both passed clean repeatedly on this file (structural validation OK, 0 fail/0 structure_errors), the deploy step's own `GET /api/workflows/{id}/download` check showed zero step errors, and `gxwf validate --connections` (which would in principle check collection-algebra/map-over connection-type compatibility) cannot run at all against this file due to an already-ledgered, unrelated crash (`gxwf-validate-connections-flag-crashes-uncaught-on-format2-dict-shaped-step-in`). The defect was only exposed by a real invocation on live usegalaxy.org: both per-gene lexicmap_search jobs (invocation `7a25084290281d4f`, jobs `bbd44e69cb8906b5703a6db6ea90ddf0` and `bbd44e69cb8906b55890e15ae6aa2602`) errored pre-execution -- no command line, no stdout/stderr, no exit code -- with the job's actual submitted `advanced_settings` tool_state literally holding `\"<galaxy.model.DatasetCollectionElement(99373144) at 0x7f1f8adf6cb0>\"` (the raw Python object repr) in place of a resolved float/int for all four ports."
    expected: "implement-galaxy-tool-step / advance-galaxy-draft-step's packaged references should document, as a hard rule, that a `sample_sheet` collection's per-element columns cannot be wired directly onto another (non-sample_sheet-aware) tool's plain scalar parameter -- only onto a tool that itself declares a `data_collection` input parameter for that sample_sheet. For the common case of needing a per-element-varying scalar value to feed an ordinary tool's parameter, the correct, real Galaxy pattern (verified working here) is: a parallel `list` collection (not `sample_sheet`) whose element_identifiers match the driving collection's, one dataset element per gene holding that gene's real value as plain text, consumed by a Galaxy core `param_value_from_file` (0.1.0) step mapped over it -- note this tool exposes one output port per `param_type` (`text_param` / `integer_param` / `float_param` / `boolean_param`; the packaged references should say to use the port matching the chosen `param_type`, not a generic `output`), whose result then wires into the target tool's scalar port. Separately, `gxwf validate --connections` should (once its unrelated crash is fixed) flag a sample_sheet-to-scalar-parameter connection as a real type error, since it is never valid regardless of collection contents."
    evidence: "draft-manuscript-galaxy, phase 12 (debug-galaxy-workflow-output) + live remediation. Root-caused via `GET /api/jobs/{id}?full=true` on both failed lexicmap_search jobs under invocation `7a25084290281d4f` (history `bbd44e69cb8906b51b4da6f15800819c`), showing the literal `DatasetCollectionElement` repr in `advanced_settings.align_min_match_pident`/`align_min_match_len`/`seed_min_prefix`/`min_qcov_per_genome`, while `db_opts.lexicmap_index` (a real ordinary text-select port) resolved correctly to `\"Viral\"` in the same job -- isolating the fault to the sample_sheet-column ports specifically. Confirmed the real fix mechanism by inspecting `GET /api/tools/param_value_from_file?io_details=true` (four per-param_type output ports, not a single generic one) and rebuilt the binding for real: 4 new real `list` collections created via `POST /api/dataset_collections` (`gene_align_min_match_pident_panel` id `5f39d50dafb0838b`, `gene_align_min_match_len_panel` id `ae22378905d7f2b7`, `gene_seed_min_prefix_panel` id `1ea756628560cfef`, `gene_min_qcov_per_genome_panel` id `7565b2b9a270b623`; each E/J, values 60.0/70.0, 35/50, 15/17, 30.0/0.0 respectively -- J using the wrapper's own confirmed tool defaults 70.0/50/17, min_qcov_per_genome having no real wrapper default so 0.0 (no-op floor) was used deliberately for genes without a production override), plus 4 new `extract_<name>_per_gene` (`param_value_from_file` 0.1.0) steps, rewiring lexicmap_search's 4 broken `in:` ports onto these steps' typed output ports instead of `gene_query_panel`. Fix applied to galaxy-workflow.gxwf.yml (local source of truth) and re-validated clean (`gxwf validate`: 9 ok / 0 fail / 4 skip_tool_not_found, all 4 skips pre-existing UDT/toolshed-fetch gaps unrelated to this change)."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/588

  - id: galaxy-workflow-update-exact-tools-defaults-true-and-discards-per-step-error-detail
    raised_by: debug-galaxy-workflow-output
    observed_in:
      mold:
        name: debug-galaxy-workflow-output
        path: content/molds/debug-galaxy-workflow-output/index.md
        revision: 5
        content_hash: 100b3f985f8e309092bfd05cf544a8286e0a878ee2df3a155dfebe6fcdb286f0
        foundry_head: 63a3f9cf9c97a637fe1628d298e524f35709e289
    subject:
      kind: related-project
      label: "Galaxy core -- PUT /api/workflows/{id} (update_workflow_from_raw_description, WorkflowUpdateOptions)"
      locator: "https://github.com/galaxyproject/galaxy (lib/galaxy/webapps/galaxy/api/workflows.py, lib/galaxy/managers/workflows.py, lib/galaxy/workflow/modules.py)"
    kind: defect
    severity: major
    what: "`PUT /api/workflows/{id}` resolves every step's tool via `trans.app.toolbox.get_tool(tool_id, tool_version=tool_version, exact=exact_tools, tool_uuid=tool_uuid)`, where `exact_tools` (a field on the real `WorkflowUpdateOptions` Pydantic model) defaults to `True` unless the request body explicitly sets it -- the exact same false-positive tool-resolution behavior already observed at invocation time (workaroundable there via `require_exact_tool_versions: false`) recurs at save time with a DIFFERENT, undocumented field name (`exact_tools`, not `require_exact_tool_versions`) and no obvious hint that a save-time escape hatch even exists. Worse: when `get_tool(..., exact=True)` fails for one or more steps, `update_workflow_from_raw_description` builds a real, specific per-step message (`f\"Step {n+1}: Requires tool '{tool_id}'.\"`) into `missing_tool_tups` and raises `MissingToolsException`, but the API handler in `workflows.py` unconditionally rewrites this to a generic `{\"err_msg\": \"This workflow contains missing tools. It cannot be saved until they have been removed from the workflow or installed.\", \"err_code\": 0}` -- discarding the specific, already-computed per-step list before it ever reaches the client, even though every one of the flagged tools was independently confirmed installed at exactly the pinned tool_id/tool_version via `/api/tools/{id}/build`."
    expected: "(1) `PUT /api/workflows/{id}`'s error response should surface the specific per-step missing-tool list it already computed internally (`missing_tool_tups`) instead of discarding it for a generic message with `err_code: 0` -- this alone would have cut a full diagnostic round-trip. (2) Document `exact_tools`/`allow_missing_tools` (WorkflowUpdateOptions' real fields) as the save-time equivalent of invocation-time's `require_exact_tool_versions`/`allow_tool_state_corrections`, ideally in the same place, since a caller who already learned about one escape hatch has no way to guess the other exists under a different name for a different endpoint."
    evidence: "draft-manuscript-galaxy, post-pipeline deploy step. `PUT /api/workflows/575e9ee747b2031f` with a corrected native workflow JSON (bare `{\"workflow\": {...}}` body) -> `{\"err_msg\": \"This workflow contains missing tools...\", \"err_code\": 0}` for 4 tools (collapse_dataset 5.1.0, lexicmap_search 0.9.0+galaxy1, kmindex_query 0.6.1+galaxy4, collection_column_join 0.0.3) independently re-confirmed installed via `/api/tools/{id}/build` moments before and after. Re-submitting the identical `workflow` content with two added top-level sibling keys, `{\"exact_tools\": false, \"allow_missing_tools\": true}`, succeeded immediately with no other change."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/589

  - id: author-galaxy-tool-wrapper-no-check-of-wrapped-scripts-own-declared-input-ordering-assumption
    raised_by: debug-galaxy-workflow-output
    observed_in:
      mold:
        name: debug-galaxy-workflow-output
        path: content/molds/debug-galaxy-workflow-output/index.md
        revision: 5
        content_hash: 100b3f985f8e309092bfd05cf544a8286e0a878ee2df3a155dfebe6fcdb286f0
        foundry_head: 63a3f9cf9c97a637fe1628d298e524f35709e289
    subject:
      kind: mold
      label: author-galaxy-tool-wrapper
      locator: content/molds/author-galaxy-tool-wrapper/index.md
      content_hash: cced8f068cd1ce81fefad23a62fdb4d52b3ce805b2231f64a7fe37f258bc1e09
    kind: gap
    severity: major
    what: "This is NOT a report of a bug in the wrapped script itself (that lived entirely in the user's own private nekrut/disassembler repository and was fixed there directly, with a patch prepared for the user's own separate upstream review -- out of scope for this ledger). The Foundry-relevant gap is in the authoring process: author-galaxy-tool-wrapper wrapped `lexicmap_streamer.py` as the `lexicmap_streamer` GalaxyUserTool without ever checking whether the script's own explicit, self-declared input-ordering assumption actually holds for the real upstream Galaxy tool this step would be wired to consume from in the concrete workflow. The vendored script's own code comment stated the assumption outright ('the stream is grouped by accession one block at a time, so all of an accession's HSPs must be contiguous... detect a reappearance and stop') -- a directly inspectable, static signal that this script's correctness depends on a specific ordering property of its input. Nothing in author-galaxy-tool-wrapper's packaged authoring/review process prompts for cross-checking a wrapped script's own declared input-shape assumptions against the actual, real output ordering of the specific upstream Tool Shed tool (`iuc/lexicmap/lexicmap_search`) it is wired to consume from later in the same workflow (implement-galaxy-tool-step's job, but with no input from authoring about what to check). The gap was only caught because a live, real, production-scale invocation happened to exercise it -- run-workflow-test's own synthetic 3-decoy fixture never could have, since a 3-element fixture is trivially 'grouped' by construction regardless of the bug."
    expected: "author-galaxy-tool-wrapper's review/authoring procedure should add an explicit check step: when a wrapped script's own source/docstring/comments assert an assumption about the shape, ordering, or grouping of its input data (a `sort`/`group`/`contiguous`/'assumes' style comment is a strong, mechanically-greppable signal), the authoring pass should either (a) verify that assumption against the real, documented output-ordering behavior of the specific upstream tool the step will actually be wired to (not just against a hand-built test fixture that can't exercise the failure mode), or (b) explicitly flag the assumption as an open, unverified risk in the step's `doc:`/ledger for a later phase (e.g. run-workflow-test or a dedicated real-data smoke test) to confirm before the workflow is treated as production-ready. A synthetic fixture alone -- however carefully constructed -- cannot substitute for this check when the fixture is, by construction, too small to violate the assumption being tested."
    evidence: "draft-manuscript-galaxy. `lexicmap_streamer.py`'s own committed comment (vendored verbatim into galaxy-user-tool.yml's configfiles entry at authoring time) explicitly named the exact risk that later caused two live job failures on real usegalaxy.org production data (invocation 802eff260023dc62, both lexicmap_streamer_tiling_qc jobs) against the real, correctly-functioning `iuc/lexicmap/lexicmap_search` 0.9.0+galaxy1 output (confirmed via direct byte-range inspection: real LexicMap search output is ranked by match quality across all matched genomes, not grouped by target accession -- the assumption was false for this specific real upstream tool from the start). The 3-decoy synthetic fixture used at test-authoring time (test-data/synthetic_am3/*.tsv) could not have surfaced this: a 3-row/3-accession fixture cannot exhibit a 'reappearing accession' pattern by construction, regardless of whether the underlying assumption holds for real data."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/590

  - id: ga-download-normalizes-tool-id-producing-workflows-that-save-but-cannot-invoke
    raised_by: manual-deploy
    observed_in: null
    subject:
      kind: research
      label: galaxy-workflow-invocation-failure-reference
      locator: content/research/galaxy-workflow-invocation-failure-reference/index.md
      content_hash: null
    kind: defect
    severity: major
    what: "`GET /api/workflows/{id}/download?style=ga` emits each Tool Shed step's `tool_id` as the UNVERSIONED repository path (`toolshed.g2.bx.psu.edu/repos/iuc/kmindex/kmindex_query`) with the version carried separately in `tool_version`. Re-importing that exact document -- the download/edit/upload round trip that any external deploy script performs -- produces a workflow that SAVES successfully, shows `errors: null` on every step via `GET /api/workflows/{id}?legacy=false`, and lints clean, but CANNOT be invoked: `POST /api/workflows/{id}/invocations` returns HTTP 400 `Workflow was not invoked; the following required tools are not installed: <tool> (version <v>)` naming tools that are installed at exactly that id and version. Setting `tool_id` to the full VERSIONED path (`.../kmindex_query/0.6.1+galaxy4`) with no other change makes the same workflow invoke immediately. The round trip is therefore lossy in a way that is invisible until invocation: the format the server hands you back is not a format the server will accept for execution. This is distinct from the existing entry `galaxy-workflow-invocation-check-rejects-previously-installed-tool-as-not-installed`, which describes a STALE-TOOLBOX-READ race under planemo with a reload-timing signature; this defect is deterministic, has no timing component, and reproduces on demand against a long-warm production toolbox."
    expected: "(1) `POST /api/workflows/{id}/invocations` should resolve an unversioned `tool_id` together with the step's own `tool_version` field, exactly as the save path and the editor already do -- or, failing that, the error should say the id is unversioned rather than claiming an installed tool is not installed, which routes debugging toward tool installation instead of toward id formatting. (2) `download?style=ga` should round-trip losslessly: either emit the versioned id, or the invocation check should accept what the download emits. As it stands, the documented way to fetch a workflow produces a document that silently loses executability."
    evidence: "draft-manuscript-galaxy, paper-scale rerun setup, 2026-09-18. ISOLATED on a purpose-built 1-step probe workflow (single `tp_cat` step, plain `POST /api/workflows` body `{\"workflow\": ...}` with NO `exact_tools`/`allow_missing_tools` keys, so those flags are excluded as a cause): `tool_id: .../text_processing/tp_cat` + `tool_version: 9.11+galaxy0` -> invocation 400 `required tools are not installed: .../tp_cat (version 9.11+galaxy0)`; changing ONLY `tool_id` to `.../text_processing/tp_cat/9.11+galaxy0` -> invocation scheduled, jobs ran to `ok`. CORROBORATED on the real workflow 575e9ee747b2031f: version 4 (unversioned ids, from a `download?style=ga` round trip) saved fine with `steps with errors: 0` and every tool independently confirmed present via `GET /api/tools/{versioned-id}`, yet invocation returned 400 listing collapse_dataset 5.1.0, kmindex_query 0.6.1+galaxy4, lexicmap_search 0.9.0+galaxy1 and collection_column_join 0.0.3 as not installed; version 5, identical apart from versioned `tool_id`s, invoked successfully (invocation 6372d41d2d9cf1c6)."
    status: filed
    issue: https://github.com/galaxyproject/foundry/issues/591
foundry-run-manifestoptional-absentfoundry-run.yml

Runtime artifact initialized by the harness ([[foundry-run-manifest]]).

declared by
— (phase —)
consumed at
nothing downstream reads it
schema
none declared
sha256

not on disk.

freeform-galaxy-data-flowpresentfreeform-galaxy-data-flow.md

Reviewable Markdown brief: abstract operations, collection map/reduce choices, shape-changing placeholder steps, unresolved Galaxy tool needs, confidence, open questions.

declared by
freeform-summary-to-galaxy-data-flow (phase 3)
consumed at
4, 5, 8
schema
none declared
sha256
c2551021902c381d7069ab8e3e3b375eaa4288a92e199ba4b56172f9d233a6e1
  • Galaxy Data-Flow Design Brief — Workflow A (SRA Landscape & Spike-In Sieve)
  • 0. Scope (user-confirmed, binding for this run)
  • 1. Workflow-level inputs (Workflow A)
  • 2. Nodes and edges
  • 3. Collection idiom summary
  • 4. Unresolved Galaxy tool needs
  • 5. Placeholder (shape-changing) transformations
  • 6. Confidence summary
  • 7. Open questions carried forward (not resolved by this brief)
  • 8. Open-requirements ledger cross-reference
  • 9. Foundry feedback
freeform-galaxy-interfacepresentfreeform-galaxy-interface.md

Reviewable Markdown brief: Galaxy workflow inputs, outputs, labels, collection shapes, checkpoint outputs, source-summary provenance, confidence, open questions.

declared by
freeform-summary-to-galaxy-interface (phase 2)
consumed at
3, 4, 5, 7, 8
schema
none declared
sha256
92ca4bd05ae5c40dcaa1add9ed6c70defb59a654c72a8c0e21e315941c164cc6
  • Galaxy Workflow Interface Design Brief
  • 0. Scope decision made for this brief (see open-requirements entry `workflow-scope-boundary-unresolved`)
  • 1. Workflow A — SRA Landscape & Spike-In Sieve (Stages A, B, C, D2)
  • 1.1 Inputs
  • 1.2 Outputs
  • 2. Workflow B — Experimental-Evolution Trajectory Validation (Stage E)
  • 2.1 Inputs
  • 2.2 Outputs
  • 3. Workflow C (candidate, lower confidence) — Diversity Reconstruction, VEP Benchmarking, Dual-Coding Calibration (Stages C′, F, G, H)
  • 4. Workflow D (candidate, lowest confidence) — "ChronAeon" Multi-Scale Sieve (Stage I)
  • 5. Collection-shape rationale
  • 6. Labels and testability notes
  • 7. Open questions carried to the open-requirements ledger
  • 8. Foundry feedback
freeform-summarypresentfreeform-summary.md

Methods, tools, sample data, references, and workflow intent extracted from a primary paper, normalized into the shared free-form source summary handoff.

declared by
summarize-paper (phase 1)
consumed at
2, 3, 5, 7, 8
schema
none declared
sha256
31b7c66db81e41795c1c9643fb7f7f6de6da53d98c48df4e8883e8f80ab57cb6
  • Free-Form Source Summary: Planetary-Scale Retrospective DMS of Bacteriophage ΦX174
  • 0. Scope note (read this first)
  • 1. High-level pipeline shape
  • 2. Stage-by-stage detail
  • Stage A — Reference genome and per-gene CDS query panel
  • Stage B — Petabase k-mer containment screen (kmindex, real Galaxy tool)
  • Stage C — Track 1: LexicMap streaming search (real Galaxy tool) + custom tiling/QC client
  • Stage C′ — Track 2: Disassembler / `logan-walker` cDBG traversal (real external tool, Rust)
  • Stage D — Nominal-taxonomy SRA metadata audit
  • Stage D2 — The Sanger `am3` dual-coding molecular fingerprint (core finding, not a tool stage)
  • Stage E — Reference experimental-evolution datasets (real tools: bowtie2 + samtools)
  • Stage F — Wei, Li & Lehner (2026) whole-genome DMS ground truth (external dataset, NOT in repo)
  • Stage G — HyphAeon zero-shot variant-effect prediction (real installed tool)
  • Stage H — Dual-coding / overlapping-frame consequence classification (custom package, real code)
  • Stage I — "ChronAeon Multi-Scale SRA Sieve" (`run_chronaeon_phix174_sieve.py`)
  • Stage J — Fane-mechanics and Bull/Wichman literature cross-referencing (pure pandas, no external tool)
  • Stage K — Figure generation and manuscript QA (project tooling, not science tools)
  • 3. Sample / reference data catalog (for test-data resolution phases)
  • 4. `results/` directory shape (already-computed intermediate/output tables — useful as
  • 5. Tool inventory — real/installable vs. custom/internal
  • 6. Key literature / reference data anchors (for citation/README generation downstream)
  • 7. Assumptions and open gaps (carried forward per skill protocol)
  • 8. Foundry feedback
galaxy-test-planpresentgalaxy-test-plan.yml

Reviewable Galaxy workflow test plan (see [[galaxy-workflow-test-plan]]): synthesized test cases with job inputs, expected outputs, assertion intent, fixture provenance, label assumptions, unresolved mappings, and omissions.

declared by
freeform-summary-to-galaxy-test-plan (phase 8)
consumed at
9
schema
galaxy-workflow-test-plan
sha256
f478f0920e416c66b206955ecabea7d8918c652ad8cbd11200cb790c458008b8
plan_version: "1"

source:
  kind: freeform
  name: "ΦX174 Planetary-Scale Retrospective DMS -- Workflow A (SRA Landscape & Spike-In Sieve)"
  derived_from: intent
  notes: >-
    Synthesized from freeform-summary.md (Stages A, B, C, D2), freeform-galaxy-interface.md
    (Workflow A section), freeform-galaxy-data-flow.md (nodes N1-N7), and
    iwc-comparison-notes.md (no High/Medium-confidence IWC domain exemplar found; kmindex and
    LexicMap do not appear anywhere in the IWC corpus). There is no upstream test-evidence
    (nf-test snapshot, CWL job file) for this project to translate -- every test case and
    assertion below is synthesized from stated workflow intent, the paper's own Table 1 /
    am3-diagnostic numbers, and the concrete workflow's declared step contracts. Grounded
    additionally against galaxy-workflow.gxwf.yml (the concrete 9-step gxformat2 draft) and
    test-data-refs.json (phase 7's gene E/J scoping decision and documented fixture gaps), per
    this run's explicit instruction to use them for consistency even though they are not this
    skill's own declared inputs.

workflow:
  title: "phix174_sra_landscape_spikein_sieve (ΦX174 SRA Landscape & Spike-In Sieve, Workflow A)"
  label_source: draft
  notes: >-
    All workflow_label values below are the literal input/output ids from
    galaxy-workflow.gxwf.yml's inputs:/outputs: blocks (e.g. gene_query_panel,
    gene_e_am3_quarantine_audit), not the interface brief's earlier proposed prose labels
    (e.g. "Gene E am3 quarantine audit"), which in places differ from what the concrete draft
    actually shipped. implement-galaxy-workflow-test should still re-confirm these against the
    live draft before finalizing, since this skill's own declared inputs are the earlier
    template-era briefs (see warnings[0]).

test_cases:
  - id: kmindex_wiring_smoke_generic_fixtures
    doc: >-
      Structural/wiring smoke test for the kmindex containment-screen chain
      (combine_gene_panel_to_bulk_fasta -> kmindex_containment_screen -> kmindex_hit_concat ->
      kmindex_hit_dedup_max_score) and for lexicmap_search's multi-index-selection binding,
      using each pinned Tool Shed wrapper's own real upstream functional-test fixtures (generic,
      non-phiX174 sequences and indices) instead of phiX174 biology. This exists because no
      small, real, locally-buildable Logan-shard kmindex index or Logan-derived LexicMap domain
      index exists at any scale smaller than usegalaxy.org's production data (test-data-refs.json
      gaps "no-real-small-kmindex-logan-shard-subset" and
      "no-real-small-lexicmap-logan-index-subset"). This case proves the workflow's collection
      map-over, multi-select DB/index binding, and per-gene sensitivity-override wiring execute
      without error; it does NOT audit any biological content, including the Gene E am3
      diagnostic (see test case gene_e_j_am3_diagnostic_synthetic_lexicmap_index for that).
      The workflow's mandatory element_identifier=="E" extraction in extract_gene_e_am3_audit
      means every test case, including this one, must still supply an "E"-identified
      gene_query_panel element, even though here it carries generic (non-phiX174) sequence
      content.
    derived_from: intent
    provenance: >-
      test-data-refs.json tool_level_structural_fixtures (kmindex_query test #6 "using register
      index"; lexicmap.xml tests #3/#4/#6); iwc-comparison-notes.md "Test issues" routing note.
    job_inputs:
      - workflow_label: gene_query_panel
        label_status: resolved
        description: >-
          2-element sample_sheet reusing the workflow's mandatory E/J identifiers but populated
          with each pinned tool's own generic upstream test query sequences, not real phiX174
          CDS -- element "E" holds tools-iuc kmindex's query1.fasta content (or lexicmap's
          lexicmap_query3.fasta content), element "J" a second generic sequence from the same
          fixture sets. Per-gene LexicMap sensitivity override columns left unset for both
          (not meaningful for generic sequences).
        collection_shape: sample_sheet
        datatype: fasta
        fixture:
          storage: remote-url
          location: >-
            https://raw.githubusercontent.com/galaxyproject/tools-iuc/main/tools/kmindex/test-data/query1.fasta
            ; https://raw.githubusercontent.com/galaxyproject/tools-iuc/main/tools/lexicmap/test-data/lexicmap_query3.fasta
          checksum: null
          provenance: >-
            tools-iuc kmindex_query.xml test #6 and lexicmap.xml tests #3/#4/#6, both already
            used for upstream CI; not phiX174 biology.
      - workflow_label: kmindex_db_selection
        label_status: resolved
        description: >-
          kmindex's own test-only "register" value, which expands (in the wrapper's own
          functional test) to a real 2-shard multi-select (index1, index2) against a synthetic
          repeat-sequence index bundled in tools-iuc's test-data.
        collection_shape: null
        datatype: null
        fixture:
          storage: unresolved
          location: null
          checksum: null
          provenance: >-
            Value "register" is confirmed only inside kmindex_query.xml's own functional test
            harness; whether a workflow-level Planemo test job can pass it through the same way
            is unconfirmed -- see unresolved[2].
      - workflow_label: kmindex_zvalue
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "6", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: kmindex_threshold
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "0.3", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: kmindex_output_format
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "json", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: kmindex_fast
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "false", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: lexicmap_index_selection
        label_status: resolved
        description: >-
          LexicMap's own real 2-index test combination (db.lmi + db2.lmi), indexing two small
          real viral RefSeq assemblies (GCF_001502155.1, GCF_001502175.1) -- not phiX174 and not
          Logan-derived.
        collection_shape: null
        datatype: null
        fixture:
          storage: unresolved
          location: null
          checksum: null
          provenance: >-
            tools-iuc lexicmap.xml tests #3/#4/#6 combine db.lmi+db2.lmi; whether the exact
            data-table name is reachable from a workflow-level test job is unconfirmed -- see
            unresolved[2].
      - workflow_label: lexicmap_top_n_genomes
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "0", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: lexicmap_advanced_all
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "true", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: tiling_qc_min_coverage
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "0.8", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: tiling_qc_min_coverage_partial
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "0.5", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: tiling_qc_min_pident
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "60", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: tiling_qc_max_internal_stops
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "0", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: tiling_qc_sample_cap
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "10", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: tiling_qc_allow_frameshifts
        label_status: resolved
        description: >-
          Confirmed OFF/False by direct read of nekrut/disassembler's lexicmap_streamer.py
          argparse (store_true, no default=True).
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "false", checksum: null, provenance: "test-data-refs.json inputs (tiling_qc_allow_frameshifts)"}
    expected_outputs:
      - workflow_label: kmindex_accession_union
        label_status: resolved
        description: >-
          Deduplicated accession union across the kmindex "register" test shards. Existence-only:
          the underlying index has no phiX174 biological relationship, so only "the chain ran and
          produced non-empty output" is assertable.
        output_kind: dataset
        collection_shape: null
        assertion_intent:
          - family: has_size
            intent: "Output is non-empty (chain executed and produced a result)."
            expected_value: null
            tolerance: {kind: none, magnitude: null, rationale: "existence-only, no content relationship to phiX174"}
            element_identifier: null
            evidence: intent
            confidence: low
      - workflow_label: clean_full_length_cds_haplotypes
        label_status: resolved
        description: "Per-gene clean haplotype FASTA (sample_sheet). Existence-only per element."
        output_kind: collection
        collection_shape: sample_sheet
        assertion_intent:
          - {family: has_size, intent: "Non-empty output for gene E.", expected_value: null, tolerance: null, element_identifier: "E", evidence: intent, confidence: low}
          - {family: has_size, intent: "Non-empty output for gene J.", expected_value: null, tolerance: null, element_identifier: "J", evidence: intent, confidence: low}
      - workflow_label: clean_haplotype_counts
        label_status: resolved
        description: "Per-gene clean haplotype counts table. Existence-only per element."
        output_kind: collection
        collection_shape: sample_sheet
        assertion_intent:
          - {family: has_n_columns, intent: "Table has a plausible column count (schema smoke check).", expected_value: null, tolerance: null, element_identifier: "E", evidence: intent, confidence: low}
          - {family: has_n_columns, intent: "Table has a plausible column count (schema smoke check).", expected_value: null, tolerance: null, element_identifier: "J", evidence: intent, confidence: low}
      - workflow_label: flagged_accessions
        label_status: resolved
        description: "Per-gene flagged (QC-failed) sequences. Existence-only, not audited for content in this case."
        output_kind: collection
        collection_shape: sample_sheet
        assertion_intent: []
      - workflow_label: flagged_audit_reasons
        label_status: resolved
        description: "Per-gene flagged.tsv. Existence-only in this case; see the other test case for the real am3 assertion."
        output_kind: collection
        collection_shape: sample_sheet
        assertion_intent:
          - {family: has_n_lines, intent: "At least a header line is present.", expected_value: null, tolerance: {kind: none, magnitude: null, rationale: "existence-only"}, element_identifier: "E", evidence: intent, confidence: low}
      - workflow_label: per_gene_ingestion_summary
        label_status: resolved
        description: "Per-gene summary.json. Stochastic/opaque given generic non-phiX174 input; existence-only per corpus convention for JSON of this kind."
        output_kind: collection
        collection_shape: sample_sheet
        assertion_intent:
          - {family: has_text, intent: "Output is well-formed JSON.", expected_value: "{", tolerance: null, element_identifier: "E", evidence: intent, confidence: low}
          - {family: has_text, intent: "Output is well-formed JSON.", expected_value: "{", tolerance: null, element_identifier: "J", evidence: intent, confidence: low}
      - workflow_label: ingestion_manifest_all_genes
        label_status: resolved
        description: "All-gene manifest table. Existence-only (2 data rows expected structurally, not content-checked)."
        output_kind: dataset
        collection_shape: null
        assertion_intent:
          - {family: has_n_lines, intent: "Header plus 2 gene rows (E, J).", expected_value: 3, tolerance: {kind: delta, magnitude: 1, rationale: "tolerate a trailing-newline off-by-one"}, element_identifier: null, evidence: intent, confidence: medium}
      - workflow_label: gene_e_am3_quarantine_audit
        label_status: resolved
        description: >-
          Gene E element of flagged_tsv. In THIS case the "E" element is generic test-fixture
          sequence, not real phiX174 gene E, so no am3 diagnostic content is expected --
          existence-only. The meaningful, content-bearing am3 assertion is in the other test
          case.
        output_kind: dataset
        collection_shape: null
        assertion_intent:
          - family: has_size
            intent: "Output exists (extraction step resolved a real E element and did not error)."
            expected_value: null
            tolerance: {kind: none, magnitude: null, rationale: "existence-only; not phiX174 biology in this case"}
            element_identifier: null
            evidence: intent
            confidence: low

  - id: gene_e_j_am3_diagnostic_synthetic_lexicmap_index
    doc: >-
      Primary functional test for Workflow A's core scientific claim (the paper's Sanger am3
      spike-in diagnostic, freeform-summary.md Stage D2: genome position nt587 G->A causes a
      premature TGG->TAG stop at Gene E codon 7, gpE_W7*). Exercises lexicmap_search ->
      lexicmap_streamer_tiling_qc -> {flatten_gene_summary_json_to_row ->
      join_gene_summary_rows_into_manifest} and -> extract_gene_e_am3_audit end-to-end using a
      small, purpose-built synthetic LexicMap domain index (construction deferred to
      implement-galaxy-workflow-test / a follow-on find-test-data pass; this plan specifies its
      required composition per Fixture.storage=generated-toy) seeded with real cds/E.fasta and
      cds/J.fasta content plus 3 hand-crafted decoy accessions: (1) a Gene-E wildtype-clean
      decoy, (2) a Gene-E am3-positive decoy carrying the exact nt587 G->A / codon-7 TGG->TAG
      substitution, and (3) a Gene-J clean decoy. This is the smallest fixture that can produce a
      real, assertable Gene E am3 quarantine audit without waiting on usegalaxy.org-hosted
      production Logan indices (test-data-refs.json gap
      "no-real-completed-lexicmap-hits-table-for-lexicmap-streamer"). The kmindex chain shares
      the same job (one workflow invocation runs both chains) but is not the focus here and is
      only weakly asserted; see omissions[1].
    derived_from: intent
    provenance: >-
      freeform-summary.md Stage D2 (am3 diagnostic: nt587 G->A, gpE_W7*, 2,215,172/2,392,457 =
      92.59% of evaluated Gene E accessions); test-data-refs.json inputs[0] (real cds/E.fasta,
      cds/J.fasta, per-gene sensitivity overrides) and gaps[2]; galaxy-workflow.gxwf.yml
      extract_gene_e_am3_audit doc (flagged_tsv columns: accession, coverage, mean_pident, flag,
      n_stops, stop_codons, hsps_merged).
    job_inputs:
      - workflow_label: gene_query_panel
        label_status: resolved
        description: >-
          2-element sample_sheet: E = real cds/E.fasta (273 bp CDS) with per-gene LexicMap
          sensitivity override columns populated (align_min_match_pident=60.0,
          align_min_match_len=35, seed_min_prefix=15, min_qcov_per_genome=30.0, sourced from
          logan_remaining_runs.json per test-data-refs.json); J = real cds/J.fasta (114 bp CDS,
          shortest gene in the panel), override columns unset (falls back to wrapper defaults
          70/50/17/unset).
        collection_shape: sample_sheet
        datatype: fasta
        fixture:
          storage: in-repo
          location: "cds/E.fasta, cds/J.fasta"
          checksum: null
          provenance: >-
            test-data-refs.json inputs[0]; real files already used by this project's own
            kmindex/LexicMap submission scripts (submit_kmindex_all_genes.py,
            submit_remaining_logan.py).
      - workflow_label: kmindex_db_selection
        label_status: resolved
        description: "Real Logan shard names, kept only for job completeness; not this case's focus."
        collection_shape: null
        datatype: null
        fixture:
          storage: unresolved
          location: "GENOMIC_PHG,GENOMIC_VRL,METAGENOMIC_ENV"
          checksum: null
          provenance: >-
            test-data-refs.json kmindex_db_selection (real shard names, no backing test-scale
            index -- see unresolved[0]).
      - workflow_label: kmindex_zvalue
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "6", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: kmindex_threshold
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "0.3", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: kmindex_output_format
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "json", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: kmindex_fast
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "false", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: lexicmap_index_selection
        label_status: assumed
        description: >-
          Placeholder data-table name for the not-yet-built synthetic 3-decoy index described in
          this test case's doc (e.g. "PhiX174E_J_Am3ToyIndex"); real value to be assigned once
          the index is constructed.
        collection_shape: null
        datatype: null
        fixture:
          storage: generated-toy
          location: null
          checksum: null
          provenance: >-
            This plan specifies the index's required composition (wildtype-clean Gene E decoy,
            am3-positive Gene E decoy, clean Gene J decoy); construction is deferred -- see
            unresolved[1].
      - workflow_label: lexicmap_top_n_genomes
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "0", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: lexicmap_advanced_all
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "true", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: tiling_qc_min_coverage
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "0.8", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: tiling_qc_min_coverage_partial
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "0.5", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: tiling_qc_min_pident
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "60", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: tiling_qc_max_internal_stops
        label_status: resolved
        description: >-
          workflow default; 0 tolerated internal stops for the CLEAN cohort is exactly what
          routes the am3-positive decoy to the FLAGGED cohort instead.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "0", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: tiling_qc_sample_cap
        label_status: resolved
        description: workflow default.
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "10", checksum: null, provenance: "galaxy-workflow.gxwf.yml default"}
      - workflow_label: tiling_qc_allow_frameshifts
        label_status: resolved
        description: "Confirmed OFF/False from nekrut/disassembler's real argparse source."
        collection_shape: null
        datatype: null
        fixture: {storage: null, location: "false", checksum: null, provenance: "test-data-refs.json inputs (tiling_qc_allow_frameshifts)"}
    expected_outputs:
      - workflow_label: kmindex_accession_union
        label_status: resolved
        description: "Not this case's focus; see omissions[1]."
        output_kind: dataset
        collection_shape: null
        assertion_intent: []
      - workflow_label: clean_full_length_cds_haplotypes
        label_status: resolved
        description: >-
          Per-gene clean haplotype FASTA. Gene E should contain exactly the wildtype-clean decoy
          (the am3-positive decoy is routed to FLAGGED, not here). Gene J should contain its one
          clean decoy.
        output_kind: collection
        collection_shape: sample_sheet
        assertion_intent:
          - family: has_text
            intent: "Gene E's clean cohort contains the wildtype-clean decoy accession, not the am3-positive one."
            expected_value: "E_wildtype_ctrl"
            tolerance: null
            element_identifier: "E"
            evidence: intent
            confidence: medium
          - family: has_text
            intent: "Gene J's clean cohort contains its clean decoy accession."
            expected_value: "J_clean_ctrl"
            tolerance: null
            element_identifier: "J"
            evidence: intent
            confidence: medium
      - workflow_label: clean_haplotype_counts
        label_status: resolved
        description: "Per-gene clean haplotype counts. Gene E: 1 clean haplotype. Gene J: 1 clean haplotype."
        output_kind: collection
        collection_shape: sample_sheet
        assertion_intent:
          - {family: has_n_lines, intent: "Header plus exactly 1 clean haplotype row for gene E.", expected_value: 2, tolerance: {kind: delta, magnitude: 1, rationale: "tolerate trailing-newline off-by-one"}, element_identifier: "E", evidence: intent, confidence: medium}
          - {family: has_n_lines, intent: "Header plus exactly 1 clean haplotype row for gene J.", expected_value: 2, tolerance: {kind: delta, magnitude: 1, rationale: "tolerate trailing-newline off-by-one"}, element_identifier: "J", evidence: intent, confidence: medium}
      - workflow_label: flagged_accessions
        label_status: resolved
        description: "Per-gene flagged (QC-failed) sequences. Gene E should contain exactly the am3-positive decoy. Gene J should be empty."
        output_kind: collection
        collection_shape: sample_sheet
        assertion_intent:
          - family: has_text
            intent: "Gene E's flagged cohort contains the am3-positive decoy accession."
            expected_value: "E_am3_ctrl"
            tolerance: null
            element_identifier: "E"
            evidence: intent
            confidence: medium
      - workflow_label: flagged_audit_reasons
        label_status: resolved
        description: >-
          Per-gene flagged.tsv (columns: accession, coverage, mean_pident, flag, n_stops,
          stop_codons, hsps_merged, per galaxy-workflow.gxwf.yml's confirmed real source read).
          This is the closest upstream signal to the am3 finding before extraction.
        output_kind: collection
        collection_shape: sample_sheet
        assertion_intent:
          - family: has_n_lines
            intent: "Gene E: header plus exactly 1 flagged row (the am3-positive decoy)."
            expected_value: 2
            tolerance: {kind: delta, magnitude: 1, rationale: "tolerate trailing-newline off-by-one"}
            element_identifier: "E"
            evidence: intent
            confidence: medium
          - family: has_text
            intent: "Gene E's flagged row records the premature stop at codon 7, matching the paper's gpE_W7* diagnostic."
            expected_value: "7"
            tolerance: null
            element_identifier: "E"
            evidence: intent
            confidence: medium
          - family: has_n_lines
            intent: "Gene J: header only, no flagged accessions (clean decoy only)."
            expected_value: 1
            tolerance: {kind: delta, magnitude: 0, rationale: "exact -- this fixture is fully controlled/deterministic by design"}
            element_identifier: "J"
            evidence: intent
            confidence: medium
      - workflow_label: per_gene_ingestion_summary
        label_status: resolved
        description: >-
          Per-gene summary.json. Deterministic here (tiny controlled fixture, not the
          stochastic/floating-point-heavy case the existence-only convention targets), so a
          surgical property assertion is used instead of "starts with {".
        output_kind: collection
        collection_shape: sample_sheet
        assertion_intent:
          - family: has_json_property_with_value
            intent: "Gene E evaluated exactly 2 accessions (wildtype-clean + am3-positive decoys)."
            expected_value: 2
            tolerance: null
            element_identifier: "E"
            evidence: intent
            confidence: medium
          - family: has_json_property_with_value
            intent: "Gene E's cohort breakdown records exactly 1 premature-stop (am3-like) flagged accession."
            expected_value: 1
            tolerance: null
            element_identifier: "E"
            evidence: intent
            confidence: medium
          - family: has_json_property_with_value
            intent: "Gene J evaluated exactly 1 accession (its one clean decoy)."
            expected_value: 1
            tolerance: null
            element_identifier: "J"
            evidence: intent
            confidence: medium
      - workflow_label: ingestion_manifest_all_genes
        label_status: resolved
        description: "All-gene manifest table joining the E and J summary rows."
        output_kind: dataset
        collection_shape: null
        assertion_intent:
          - family: has_n_lines
            intent: "Header plus 2 gene rows (E, J)."
            expected_value: 3
            tolerance: {kind: delta, magnitude: 1, rationale: "tolerate trailing-newline off-by-one"}
            element_identifier: null
            evidence: intent
            confidence: medium
          - family: has_text
            intent: "Manifest's first column is the gene symbol (per flatten_gene_summary_json_to_row's own confirmed column-1-is-gene contract)."
            expected_value: "gene"
            tolerance: null
            element_identifier: null
            evidence: intent
            confidence: medium
      - workflow_label: gene_e_am3_quarantine_audit
        label_status: resolved
        description: >-
          FLAGSHIP ASSERTION. Gene E element of flagged_tsv, extracted by
          extract_gene_e_am3_audit (__EXTRACT_DATASET__, by_identifier "E"). With this test
          case's synthetic index, this should contain exactly one row: the am3-positive decoy,
          flagged for a premature stop at codon 7 -- the workflow-level, assertable analog of the
          paper's real finding that 2,215,172/2,392,457 (92.59%) of evaluated Gene E accessions
          carry the nt587 G->A / gpE_W7* substitution. Real full-scale numbers are recorded only
          as directional context in test-data-refs.json and are NOT asserted here (see
          omissions[0]).
        output_kind: dataset
        collection_shape: null
        assertion_intent:
          - family: has_n_lines
            intent: "Exactly one flagged row (header plus the single am3-positive decoy) for the tiny controlled fixture."
            expected_value: 2
            tolerance: {kind: delta, magnitude: 0, rationale: "exact -- this output is a direct extraction of a fully controlled synthetic fixture, not a stochastic tool result"}
            element_identifier: null
            evidence: intent
            confidence: medium
          - family: has_text
            intent: "The flagged row identifies the am3-positive decoy accession."
            expected_value: "E_am3_ctrl"
            tolerance: null
            element_identifier: null
            evidence: intent
            confidence: medium
          - family: has_text
            intent: "The flagged row's stop_codons column records position 7, matching the paper's Gene E codon-7 TGG->TAG (gpE_W7*) diagnostic mutation at genome position nt587 G->A."
            expected_value: "7"
            tolerance: null
            element_identifier: null
            evidence: intent
            confidence: medium

unresolved:
  - kind: fixture
    description: >-
      No small real Logan-shard kmindex index or Logan-derived LexicMap domain index exists for
      any of GENOMIC_PHG/GENOMIC_VRL/METAGENOMIC_ENV or Viral/BacteriaMetagenomic;
      kmindex_db_selection and lexicmap_index_selection therefore cannot be bound to fixtures
      carrying genuine phiX174 containment content at any tier smaller than usegalaxy.org's
      production Logan indices, in either test case.
    blocking: true
    suggested_resolution: >-
      Either obtain usegalaxy.org history/API access to run a real (if slow) end-to-end pass, or
      build a tiny local kmindex/LexicMap index (via kmindex_query's kmindex_build wrapper /
      lexicmap-index.xml) seeded with cds/E.fasta, cds/J.fasta plus the 3 decoy accessions
      described in test case gene_e_j_am3_diagnostic_synthetic_lexicmap_index, named to satisfy
      db_opts|kmindex / db_opts|lexicmap_index's data-table lookup.
  - kind: fixture
    description: >-
      The synthetic 3-decoy LexicMap index (wildtype-clean Gene E, am3-positive Gene E, clean
      Gene J) that test case gene_e_j_am3_diagnostic_synthetic_lexicmap_index depends on does not
      yet exist as a buildable artifact; this plan only specifies its required composition and
      the accession identifiers (E_wildtype_ctrl, E_am3_ctrl, J_clean_ctrl) its assertions
      reference.
    blocking: true
    suggested_resolution: >-
      implement-galaxy-workflow-test (or a follow-on find-test-data pass) should construct the 3
      decoy sequences (derived from real cds/E.fasta / cds/J.fasta with the am3 decoy carrying
      the exact nt587 G->A substitution) and build/register a tiny LexicMap index from them, or
      hand-construct the equivalent LexicMap hit-table TSV directly (per
      test-data-refs.json's confirmed lexicmap_search column schema) if index construction
      proves impractical.
  - kind: fixture
    description: >-
      Whether kmindex's test-only "register" value and lexicmap's db.lmi+db2.lmi test-data names
      (used in test case kmindex_wiring_smoke_generic_fixtures) are addressable from a
      workflow-level Planemo test job the same way they are from each tool's own functional test
      harness is unconfirmed.
    blocking: false
    suggested_resolution: >-
      Confirm via a trial planemo workflow_test invocation; the plan's existing existence-only
      assertion design for that test case already tolerates either outcome.
  - kind: fixture
    description: >-
      No verified phiX174-negative-control SRA accession is documented anywhere in the source
      project (test-data-refs.json gap "no-verified-phix174-negative-control-accession"); a true
      negative-control test case is therefore out of scope for this plan rather than fabricated.
    blocking: false
    suggested_resolution: >-
      User-supplied: name a specific SRA accession known/expected to have zero phiX174
      gene-panel containment, for use as a true-negative case in a future revision of this plan.
  - kind: output-label
    description: >-
      This skill's own declared inputs are the earlier template-era interface/data-flow briefs,
      but all workflow_label values in this plan were instead taken from the concrete
      gxformat2 draft (galaxy-workflow.gxwf.yml), per this run's explicit grounding instruction.
      A strict re-check of every label against the live draft (and against the workflow-label
      cross-check implement-galaxy-workflow-test already performs) is still worthwhile before
      finalizing, since this plan itself was not produced by that cross-check tool.
    blocking: false
    suggested_resolution: null

omissions:
  - target: "Full production-scale run (10 genes x 109 kmindex shards x up to 25 LexicMap indices, ~2.1M accessions)"
    reason: >-
      Explicitly out of scope for a fast workflow test. The real, already-computed full-scale
      numbers in test-data-refs.json
      (expected_output_ground_truth_full_scale_only: gene E total_accessions_evaluated=2392457,
      flagged_internal_stops=2215172, am3_stop_fraction_pct=92.59; gene J
      total_accessions_evaluated=2278534, flagged_internal_stops=63) are retained only as
      directional/sanity-bound references for a future full-scale validation pass against
      usegalaxy.org, not as exact-match assertions in this plan.
    category: out-of-scope
  - target: "kmindex_accession_union content assertions, and all lexicmap/streamer/manifest/am3-audit outputs in test case kmindex_wiring_smoke_generic_fixtures"
    reason: >-
      No small real Logan-shard kmindex index or Logan-derived LexicMap index exists; content in
      that test case has no phiX174 biological relationship, so only existence-level checks are
      asserted there. The content-bearing assertions live in the sibling test case instead.
    category: no-stable-checkpoint
  - target: "True negative-control test case (a confirmed phiX174-negative SRA accession)"
    reason: >-
      No accession is documented anywhere in the source project as a confirmed phiX174 non-hit;
      fabricating one would violate the no-fabrication rule this plan inherits from
      find-test-data (test-data-refs.json gap "no-verified-phix174-negative-control-accession").
    category: out-of-scope
  - target: "LexicMap raw per-gene hit table (lexicmap_search's out_file port)"
    reason: >-
      Not a promoted top-level workflow output (absent from galaxy-workflow.gxwf.yml's outputs:
      block); per galaxy-workflow-testability-design, only labeled workflow-level outputs are
      assertable by a Galaxy workflow test. This intermediate is exercised only indirectly via
      lexicmap_streamer_tiling_qc's own outputs.
    category: no-stable-checkpoint

warnings:
  - code: workflow-label-source-draft-not-brief
    message: >-
      This plan's declared inputs are the earlier template-era interface/data-flow briefs, but a
      concrete gxformat2 workflow draft (galaxy-workflow.gxwf.yml) and resolved test-data-refs.json
      were additionally available and used for grounding, per this run's explicit instructions.
      All workflow_label values were taken from the concrete draft's actual input/output ids, not
      re-derived from the brief's earlier proposed labels, which differ in places (e.g. the
      brief's prose "Gene E am3 quarantine audit" vs. the draft's actual id
      gene_e_am3_quarantine_audit).
    path: "workflow.label_source"
  - code: missing-fixture
    message: >-
      Two shared job inputs (kmindex_db_selection's and lexicmap_index_selection's backing
      indices) and one entire synthetic fixture (the 3-decoy LexicMap index) have no concrete,
      buildable location yet; see unresolved[0] and unresolved[1].
    path: "test_cases[*].job_inputs"
  - code: expression-derived-shape
    message: >-
      flatten_gene_summary_json_to_row's summary_row TSV column list (used for the
      ingestion-manifest and per-gene-summary assertions) was taken from
      galaxy-workflow.gxwf.yml's own step doc text, which itself cites the vendored
      lexicmap_streamer.py source at a pinned commit; this plan's assertion_intent values are
      best-effort against that documented contract, not against an actual executed run.
    path: "test_cases[1].expected_outputs"
galaxy-workflowpresentgalaxy-workflow.gxwf.yml

Concrete gxformat2 workflow (`class: GalaxyWorkflow`) extracted from the fully-concretized draft at loop endstate via [[draft-extract]]: drafty steps dropped, `_plan_*` planning fields stripped, class promoted. The runnable, testable artifact that downstream Molds ([[implement-galaxy-workflow-test]], [[validate-galaxy-workflow]], [[run-workflow-test]]) consume.

declared by
advance-galaxy-draft-step (phase 6)
consumed at
9
schema
none declared
sha256
29cb3a455713cfb6ab719bff88410101a0e783888171132b32ef1ce7b95a6a11

GalaxyWorkflow — 14 step(s), 0 still drafty, 17 input(s), 8 output(s).

steplabeltoolstateplan keys
combine_gene_panel_to_bulk_fastacombine_gene_panel_to_bulk_fastatoolshed.g2.bx.psu.edu/repos/nml/collapse_collections/collapse_datasetresolved
kmindex_containment_screenkmindex_containment_screentoolshed.g2.bx.psu.edu/repos/iuc/kmindex/kmindex_queryresolved
kmindex_hit_concatkmindex_hit_concattoolshed.g2.bx.psu.edu/repos/nml/collapse_collections/collapse_datasetresolved
kmindex_hit_dedup_max_scorekmindex_hit_dedup_max_scorekmindex_hit_dedup_max_scoreresolved
extract_align_min_match_pident_per_geneextract_align_min_match_pident_per_geneparam_value_from_fileresolved
extract_align_min_match_len_per_geneextract_align_min_match_len_per_geneparam_value_from_fileresolved
extract_seed_min_prefix_per_geneextract_seed_min_prefix_per_geneparam_value_from_fileresolved
extract_min_qcov_per_genome_per_geneextract_min_qcov_per_genome_per_geneparam_value_from_fileresolved
nest_gene_panel_for_searchnest_gene_panel_for_search__APPLY_RULES__resolved
lexicmap_searchlexicmap_searchtoolshed.g2.bx.psu.edu/repos/iuc/lexicmap/lexicmap_searchresolved
lexicmap_streamer_tiling_qclexicmap_streamer_tiling_qclexicmap_streamerresolved
flatten_gene_summary_json_to_rowflatten_gene_summary_json_to_rowflatten_gene_summary_json_to_rowresolved
join_gene_summary_rows_into_manifestjoin_gene_summary_rows_into_manifesttoolshed.g2.bx.psu.edu/repos/iuc/collection_column_join/collection_column_joinresolved
extract_gene_e_am3_auditextract_gene_e_am3_audit__EXTRACT_DATASET__resolved
galaxy-workflow-draftpresentgalaxy-workflow-draft.gxwf.yml

gxformat2 draft (see [[galaxy-workflow-draft-format]]): topology fully resolved (workflow inputs, outputs, step set, edges); tool_id / state / tool_shed_repository and wrapper-determined port names may be TODO with free-text _plan_state / _plan_context / _plan_in / _plan_out per step for later implementation Molds.

declared by
advance-galaxy-draft-step, freeform-summary-to-galaxy-template (phase 5, 6)
consumed at
6
schema
galaxy-workflow-draft
sha256
02faf63243fc100e8e3753b19540ada2665f2fb7608ba5be9cfb874ec5a687ee

GalaxyWorkflowDraft — 9 step(s), 0 still drafty, 15 input(s), 8 output(s).

steplabeltoolstateplan keys
combine_gene_panel_to_bulk_fastacombine_gene_panel_to_bulk_fastatoolshed.g2.bx.psu.edu/repos/nml/collapse_collections/collapse_datasetresolved
kmindex_containment_screenkmindex_containment_screentoolshed.g2.bx.psu.edu/repos/iuc/kmindex/kmindex_queryresolved
kmindex_hit_concatkmindex_hit_concattoolshed.g2.bx.psu.edu/repos/nml/collapse_collections/collapse_datasetresolved
kmindex_hit_dedup_max_scorekmindex_hit_dedup_max_scorekmindex_hit_dedup_max_scoreresolved
lexicmap_searchlexicmap_searchtoolshed.g2.bx.psu.edu/repos/iuc/lexicmap/lexicmap_searchresolved
lexicmap_streamer_tiling_qclexicmap_streamer_tiling_qclexicmap_streamerresolved
flatten_gene_summary_json_to_rowflatten_gene_summary_json_to_rowflatten_gene_summary_json_to_rowresolved
join_gene_summary_rows_into_manifestjoin_gene_summary_rows_into_manifesttoolshed.g2.bx.psu.edu/repos/iuc/collection_column_join/collection_column_joinresolved
extract_gene_e_am3_auditextract_gene_e_am3_audit__EXTRACT_DATASET__resolved
galaxy-workflow-testpresentgalaxy-workflow.gxwf-tests.yml

Galaxy workflow test file (tests-format) with job inputs, expected outputs, assertions; passes static schema + label cross-check. Named as the workflow basename + `-tests.yml` so Planemo discovers it as the companion of `galaxy-workflow.gxwf.yml`.

declared by
implement-galaxy-workflow-test (phase 9)
consumed at
nothing downstream reads it
schema
none declared
sha256
e82ad430fae4dad98e6c6859f453cfb9fdb1b0bc47bc41400c935fde71d993bc
# Galaxy workflow test file for galaxy-workflow.gxwf.yml (phix174_sra_landscape_spikein_sieve
# / Workflow A). Assembled by implement-galaxy-workflow-test (phase 9) from galaxy-test-plan.yml,
# galaxy-workflow.gxwf.yml, and test-data-refs.json. All job-input and output labels below are the
# literal input/output ids from galaxy-workflow.gxwf.yml's inputs:/outputs: blocks.
#
# Two test cases, matching galaxy-test-plan.yml exactly:
#   1. kmindex_wiring_smoke_generic_fixtures -- wiring/structural smoke test using each pinned
#      Tool Shed wrapper's own real upstream functional-test fixtures (generic, non-phiX174).
#      Existence-only assertions throughout; does not audit the am3 diagnostic.
#   2. gene_e_j_am3_diagnostic_synthetic_lexicmap_index -- the flagship am3 content test, built
#      around a hand-constructed synthetic 3-decoy LexicMap hits fixture (see
#      test-data/synthetic_am3/). All output assertions in this case were verified by directly
#      executing the real vendored lexicmap_streamer.py (galaxy-user-tool.yml, LexicMapStreamer,
#      commit a51eb58d) against that fixture -- the reported values below are actual observed
#      script output, not guessed.
#
# KNOWN BLOCKING GAP (test case 2, carried from galaxy-test-plan.yml unresolved[0]/[1], both
# blocking): `lexicmap_index_selection` in test case 2 is a PLACEHOLDER value
# ("PhiX174E_J_Am3ToyIndex"). No real small kmindex/LexicMap index exists anywhere at test scale
# (109 Logan kmindex shards and up to 25 LexicMap domain indices are multi-terabyte,
# usegalaxy.org-hosted production data only), and no `lexicmap` or `kmindex` CLI was available in
# this authoring environment to build and register one. Consequently:
#   - lexicmap_search (the real Tool Shed tool immediately upstream of lexicmap_streamer_tiling_qc
#     in the concrete workflow) cannot itself be made to emit the synthetic hits table below when
#     `planemo test` actually invokes this workflow end-to-end -- the tests-format `job:` block can
#     only bind values to top-level workflow input labels (confirmed against
#     references/schemas/tests-format.schema.json's `Job`/`TestJob` defs), and
#     `lexicmap_streamer_tiling_qc`'s `lexicmap_results` port is wired to an internal step output
#     (`lexicmap_search/out_file`), not a workflow input -- there is no schema-supported way to
#     inject a pre-built hits table directly onto that port from this file.
#   - The synthetic fixture (test-data/synthetic_am3/{E,J}.synthetic_lexicmap_hits.tsv plus the 3
#     decoy reference FASTAs) is therefore staged as the validated ground truth this test case's
#     assertions were derived from, and as the input a future real-index-build pass (or a direct
#     component/tool-level test of lexicmap_streamer_tiling_qc alone) should reproduce against.
#   - See foundry-feedback.ledger.yml entry
#     `implement-galaxy-workflow-test-no-tests-format-path-to-intermediate-step-input` for the
#     schema-capability gap this exposed, and the plan's own unresolved[0]/[1] for the upstream
#     index-construction gap.
#   - A full `planemo test` run of this test case is therefore expected to fail or hang at
#     `lexicmap_search` today; this is a deliberate, already-documented deferral to phase 11
#     (run-workflow-test), not an authoring omission.

- doc: >-
    kmindex_wiring_smoke_generic_fixtures: structural/wiring smoke test for the kmindex
    containment-screen chain and lexicmap_search's multi-index-selection binding, using each
    pinned Tool Shed wrapper's own real upstream functional-test fixtures (generic, non-phiX174
    sequences and indices). Proves the workflow's collection map-over, multi-select DB/index
    binding, and per-gene sensitivity-override wiring execute without error. Does NOT audit any
    biological content, including the Gene E am3 diagnostic (see the other test case for that).
  job:
    gene_query_panel:
      class: Collection
      collection_type: sample_sheet
      elements:
        - class: File
          identifier: E
          location: "https://raw.githubusercontent.com/galaxyproject/tools-iuc/main/tools/kmindex/test-data/query1.fasta"
          filetype: fasta
        - class: File
          identifier: J
          location: "https://raw.githubusercontent.com/galaxyproject/tools-iuc/main/tools/lexicmap/test-data/lexicmap_query3.fasta"
          filetype: fasta
      # Per-gene LexicMap sensitivity-override columns (align_min_match_pident, etc.) intentionally
      # left unset (no `rows:` block) -- not meaningful for generic non-phiX174 fixture content,
      # per galaxy-test-plan.yml test_cases[0].job_inputs[0].
    # kmindex_db_selection / lexicmap_index_selection removed 2026-09-18: both ports are
    # `multiple: true` selects that reject a delimited string and require an array, which a
    # gxformat2 `text` input cannot carry. The index lists are now literals in the workflow's
    # kmindex_containment_screen / lexicmap_search step state, so they are no longer job inputs.
    kmindex_zvalue: 6
    kmindex_threshold: 0.3
    kmindex_output_format: "json"
    kmindex_fast: false
    lexicmap_top_n_genomes: 0
    lexicmap_advanced_all: true
    tiling_qc_min_coverage: 0.8
    tiling_qc_min_coverage_partial: 0.5
    tiling_qc_min_pident: 60.0
    tiling_qc_max_internal_stops: 0
    tiling_qc_sample_cap: 10
    tiling_qc_allow_frameshifts: false
  outputs:
    kmindex_accession_union:
      # Existence-only: the underlying index has no phiX174 biological relationship, so only
      # "the chain ran and produced non-empty output" is assertable.
      asserts:
        - has_size: { min: 1 }
    clean_full_length_cds_haplotypes:
      class: Collection
      element_tests:
        E:
          asserts:
            - has_size: { min: 1 }
        J:
          asserts:
            - has_size: { min: 1 }
    clean_haplotype_counts:
      class: Collection
      element_tests:
        E:
          asserts:
            - has_n_columns: { min: 2 }
        J:
          asserts:
            - has_n_columns: { min: 2 }
    flagged_audit_reasons:
      class: Collection
      element_tests:
        E:
          # "At least a header line is present."
          asserts:
            - has_n_lines: { min: 1 }
    per_gene_ingestion_summary:
      class: Collection
      element_tests:
        E:
          asserts:
            - has_text: { text: "{" }
        J:
          asserts:
            - has_text: { text: "{" }
    ingestion_manifest_all_genes:
      asserts:
        - has_n_lines: { n: 3, delta: 1 }
    gene_e_am3_quarantine_audit:
      # Existence-only: this case's "E" element is generic fixture sequence, not real phiX174
      # gene E, so no am3 diagnostic content is expected here.
      asserts:
        - has_size: { min: 1 }

- doc: >-
    gene_e_j_am3_diagnostic_synthetic_lexicmap_index: primary functional test for the paper's
    Sanger am3 spike-in diagnostic (freeform-summary.md Stage D2: genome position nt587 G->A
    causes a premature TGG->TAG stop at Gene E codon 7, gpE_W7*). Exercises
    lexicmap_streamer_tiling_qc -> {flatten_gene_summary_json_to_row ->
    join_gene_summary_rows_into_manifest} and -> extract_gene_e_am3_audit against a hand-built
    synthetic 3-decoy LexicMap hits fixture (test-data/synthetic_am3/) seeded with real
    cds/E.fasta and cds/J.fasta content: (1) a Gene-E wildtype-clean decoy (E_wildtype_ctrl,
    sseq == real E.fasta verbatim), (2) a Gene-E am3-positive decoy (E_am3_ctrl, sseq carries
    the exact nt587 G->A / codon-7 TGG->TAG substitution), (3) a Gene-J clean decoy
    (J_clean_ctrl, sseq == real J.fasta verbatim). All assertion values below were confirmed by
    directly executing the real vendored lexicmap_streamer.py against this fixture with the
    workflow's default tiling_qc_* parameters (see test-data/synthetic_am3/*.tsv header
    comments for full provenance). The kmindex chain shares the same job but is not this case's
    focus and is left unasserted (kmindex_accession_union), matching
    galaxy-test-plan.yml omissions[1].

    KNOWN BLOCKING GAP: `lexicmap_index_selection` here is a placeholder
    ("PhiX174E_J_Am3ToyIndex") -- no real small LexicMap index backs it, and the tests-format
    `job:` block cannot bind the synthetic hits fixture directly onto
    lexicmap_streamer_tiling_qc's internal `lexicmap_results` port (see the file header comment
    above and galaxy-test-plan.yml unresolved[0]/[1]). A full `planemo test` run of this case is
    expected to fail/stall at lexicmap_search until a real toy index is constructed and
    registered; that construction is deferred to a later phase.
  job:
    gene_query_panel:
      class: Collection
      collection_type: sample_sheet
      elements:
        - class: File
          identifier: E
          path: test-data/E.fasta
          filetype: fasta
        - class: File
          identifier: J
          path: test-data/J.fasta
          filetype: fasta
      # Per-gene LexicMap sensitivity-override columns, in column_definitions order
      # (align_min_match_pident, align_min_match_len, seed_min_prefix, min_qcov_per_genome).
      # Populated for E (real per-gene values from logan_remaining_runs.json, per
      # test-data-refs.json); left null for J (falls back to wrapper defaults 70/50/17/unset).
      # NOTE: this skill bundle's packaged references do not document a worked `sample_sheet` /
      # `column_definitions` -> tests-format shape; this `rows:` block is a reasoned best-effort
      # construction against the tests-format.schema.json `Collection.rows` field (a dict of
      # column name -> per-row-aligned array) -- see the feedback ledger entry
      # `tests-format-schema-silent-on-sample-sheet-column-definitions-shape`.
      rows:
        align_min_match_pident: [60.0, null]
        align_min_match_len: [35, null]
        seed_min_prefix: [15, null]
        min_qcov_per_genome: [30.0, null]
    # kmindex_db_selection / lexicmap_index_selection removed 2026-09-18: both ports are
    # `multiple: true` selects that reject a delimited string and require an array, which a
    # gxformat2 `text` input cannot carry. The index lists are now literals in the workflow's
    # kmindex_containment_screen / lexicmap_search step state, so they are no longer job inputs.
    kmindex_zvalue: 6
    kmindex_threshold: 0.3
    kmindex_output_format: "json"
    kmindex_fast: false
    lexicmap_top_n_genomes: 0
    lexicmap_advanced_all: true
    tiling_qc_min_coverage: 0.8
    tiling_qc_min_coverage_partial: 0.5
    tiling_qc_min_pident: 60.0
    tiling_qc_max_internal_stops: 0
    tiling_qc_sample_cap: 10
    tiling_qc_allow_frameshifts: false
  outputs:
    clean_full_length_cds_haplotypes:
      # Gene E's clean cohort should contain exactly the wildtype-clean decoy (the am3-positive
      # decoy is routed to FLAGGED, not here). Gene J's clean cohort should contain its one clean
      # decoy. Confirmed via direct script execution: result_E.clean.accessions.fasta contains
      # only E_wildtype_ctrl; result_J.clean.accessions.fasta contains only J_clean_ctrl.
      class: Collection
      element_tests:
        E:
          asserts:
            - has_text: { text: "E_wildtype_ctrl" }
        J:
          asserts:
            - has_text: { text: "J_clean_ctrl" }
    clean_haplotype_counts:
      # Confirmed: header + exactly 1 clean-haplotype row for both E and J.
      class: Collection
      element_tests:
        E:
          asserts:
            - has_n_lines: { n: 2, delta: 1 }
        J:
          asserts:
            - has_n_lines: { n: 2, delta: 1 }
    flagged_accessions:
      # Confirmed: Gene E's flagged FASTA contains exactly the am3-positive decoy.
      class: Collection
      element_tests:
        E:
          asserts:
            - has_text: { text: "E_am3_ctrl" }
    flagged_audit_reasons:
      # Confirmed via direct script execution (result_E.flagged.tsv):
      #   accession        coverage  mean_pident  flag              n_stops  stop_codons  hsps_merged
      #   E_am3_ctrl        1.0000    99.63        PREMATURE_STOPS   1        7            1
      # header + exactly 1 flagged row for E (stop_codons="7", matching the paper's gpE_W7*
      # codon-7 diagnostic). Gene J's flagged.tsv is header-only (0 flagged rows; clean decoy
      # only) -- confirmed exact 1-line file.
      class: Collection
      element_tests:
        E:
          asserts:
            - has_n_lines: { n: 2, delta: 1 }
            - has_text: { text: "7" }
        J:
          asserts:
            - has_n_lines: { n: 1, delta: 0 }
    per_gene_ingestion_summary:
      # Confirmed via direct script execution (result_E.summary.json / result_J.summary.json):
      # gene E total_accessions_evaluated=2, cohort_breakdown.flagged_premature_stops=1;
      # gene J total_accessions_evaluated=1.
      class: Collection
      element_tests:
        E:
          asserts:
            - has_json_property_with_value: { property: "total_accessions_evaluated", value: "2" }
            - has_json_property_with_value: { property: "flagged_premature_stops", value: "1" }
        J:
          asserts:
            - has_json_property_with_value: { property: "total_accessions_evaluated", value: "1" }
    ingestion_manifest_all_genes:
      asserts:
        - has_n_lines: { n: 3, delta: 1 }
        - has_text: { text: "gene" }
    gene_e_am3_quarantine_audit:
      # FLAGSHIP ASSERTION. Gene E element of flagged_tsv (extract_gene_e_am3_audit,
      # by_identifier "E"). Confirmed identical to result_E.flagged.tsv above: exactly 1 flagged
      # row (header + the single am3-positive decoy), identifying E_am3_ctrl with stop_codons="7"
      # -- the workflow-level, assertable analog of the paper's real finding that
      # 2,215,172/2,392,457 (92.59%) of evaluated Gene E accessions carry the nt587 G->A /
      # gpE_W7* substitution (real full-scale numbers recorded only as directional context in
      # test-data-refs.json, not asserted here).
      asserts:
        - has_n_lines: { n: 2, delta: 0 }
        - has_text: { text: "E_am3_ctrl" }
        - has_text: { text: "7" }
galaxy-workflow-validation-resultpresentgalaxy-workflow-validation-result.json

Terminal gxwf validation handoff: the exact command run, a pass/fail/not-run status, the classified workflow-level diagnostics, and the residual runtime risks static validation cannot settle.

declared by
validate-galaxy-workflow (phase 10)
consumed at
nothing downstream reads it
schema
none declared
sha256
b46b5ac3ea5502df9729475f36b931727c7da56aafec555cba26a05fb1735563
status
pass
iwc-comparison-notespresentiwc-comparison-notes.md

Structural diff against the nearest IWC exemplar(s); guidance for the downstream *-summary-to-galaxy-template Mold before per-step authoring. Carries an inline, bounded gxformat2 excerpt of the nearest exemplar's relevant subgraph under a labeled section, cross-referencing the iwc-exemplar-gxformat2 sibling file.

declared by
compare-against-iwc-exemplar (phase 4)
consumed at
5, 8
schema
none declared
sha256
96038c4fc303b6e2a8478074a30da405bd216216541ed33458e86a32400b5757
  • IWC Exemplar Comparison — Workflow A (SRA Landscape & Spike-In Sieve)
  • Verdict: No High/Medium-confidence domain exemplar
  • Labeled pattern references (Low confidence, NOT domain exemplars)
  • 1. `data-fetching/parallel-accession-download` — cleanest map-over→multi-output→flatten skeleton
  • 2. `microbiome/mags-building/MAGs-generation` — nearest structural analog for N4/N5/N6
  • 3. `microbiome/metagenomic-genes-catalogue` — confirms `pick_value` tool identity
  • Structural diff findings, routed by authoring surface
  • Open-requirements ledger disposition
  • Foundry feedback
iwc-exemplar-gxformat2missingiwc-exemplar.gxwf.yml

Cleaned gxformat2 conversion (via [[convert]] --to format2 --compact) of the nearest IWC exemplar's relevant subgraph — the concrete idiom the downstream template draft pattern-matches against. Bounded to the relevant subgraph, not the whole workflow. Absent when no nearest exemplar is found.

declared by
compare-against-iwc-exemplar (phase 4)
consumed at
5, 8
schema
none declared
sha256

not on disk.

open-requirements-ledgerpresentopen-requirements.ledger.yml

Carried obligations ledger re-emitted by this step: entries it appended or closed updated, every other entry passed through with its provenance intact.

declared by
advance-galaxy-draft-step, compare-against-iwc-exemplar, freeform-summary-to-galaxy-data-flow, freeform-summary-to-galaxy-interface, freeform-summary-to-galaxy-template (phase 2, 3, 4, 5, 6)
consumed at
2, 3, 4, 5, 6
schema
none declared
sha256
3d618582d86d44053aa95bd73af6cb2049bff41bfa02e30a488553124a57bded
topology_repair:
  escalations: 1
  cap: 5
  open_history: [0]

entries:
  - id: workflow-scope-boundary-unresolved
    status: resolved
    kind: gap
    raised_by: freeform-summary-to-galaxy-interface
    unmet: "Whether the target Galaxy workflow covers only Stages A-D2 (SRA landscape / spike-in sieve, the only content currently in draft_manuscript.tex) or the full Stage A-K project pipeline (through HyphAeon VEP benchmarking, dual-coding shadow-effect calibration, and Fane-mechanics synthesis)"
    missing: "The source freeform-summary explicitly leaves this scoping question open (its Section 7, item 1) rather than resolving it"
    resolved_by: freeform-summary-to-galaxy-data-flow
    supersedes: null
    note: "User-confirmed scope decision (2026-09-17): this pipeline run builds only Workflow A (SRA landscape/spike-in sieve, Stages A/B/C/D2) as a single Galaxy workflow. Workflow B (Stage E, experimental-evolution validation, bowtie2/samtools/mpileup) is a confirmed nice-to-have the user wants built as a separate, later workflow -- out of scope for this run, not abandoned. Workflows C and D (Stages C'/F/G/H and Stage I) are out of scope for this run's data-flow design entirely. This brief modeled the full A-K pipeline shape as labeled stages/candidate subworkflows so nothing was silently dropped before this decision; that record is preserved above for provenance."

  - id: kmindex-lexicmap-index-selection-mechanism
    status: resolved
    kind: gap
    raised_by: freeform-summary-to-galaxy-interface
    step: kmindex_containment_screen
    unmet: "How the 109 kmindex Logan DB shards and the 25 LexicMap domain indices (5-index TARGETED_PHAGE_INDICES subset for per-gene runs) should be exposed as Galaxy tool/workflow-level inputs"
    missing: "The freeform-summary only records the DB/index names as hardcoded Python lists (ALL_KMINDEX_DBS, TARGETED_PHAGE_INDICES); the real kmindex_query/lexicmap_search Tool Shed wrapper's parameter schema has not yet been inspected (summarize-galaxy-tool has not run)"
    resolved_by: "Live verification against usegalaxy.org, 2026-09-18. Both `db_opts|kmindex` (kmindex_query 0.6.1+galaxy4) and `db_opts|lexicmap_index` (lexicmap_search 0.9.0+galaxy1) are `type: select, multiple: true` (tool io_details API). A comma-delimited string is REJECTED at parameter validation -- POSTing db_opts|kmindex=\"GENOMIC_PHG,GENOMIC_VRL\" returns \"Parameter 'kmindex': an invalid option ('GENOMIC_PHG,GENOMIC_VRL') was selected\", because a multi-select reads the whole string as ONE option value. The JSON array [\"GENOMIC_PHG\",\"GENOMIC_VRL\"] is accepted and fans out correctly: job bbd44e69cb8906b5eadd64618b449770 in history bbd44e69cb8906b57012ea23efccb56e completed with 32 GENOMIC_PHG + 33 GENOMIC_VRL result datasets. Since a gxformat2 `text` workflow input cannot carry an array, the delimited-string modeling this entry assumed is unusable: the `kmindex_db_selection` and `lexicmap_index_selection` text inputs were REMOVED and the 109 shard names / 5 TARGETED_PHAGE_INDICES are now literal lists in the kmindex_containment_screen and lexicmap_search step state. Trade-off accepted: index sets are no longer settable at invocation time and require editing the workflow."
    supersedes: null
    note: "This brief models index selection as a controlled-vocabulary select/multi-select parameter carrying the known DB/index name lists. Must be reconciled against the actual tool XML during implement-galaxy-tool-step / discover-shed-tool. [freeform-summary-to-galaxy-data-flow, Workflow A only] Cross-checked against the newly confirmed LexicMapStreamer provenance (see lexicmapstreamer-implementation-provenance): the nekrut/disassembler repo implements the multi-HSP tiling/QC client, not the kmindex_query/lexicmap_search Tool Shed wrappers' own DB/index parameter schema, so that discovery does not bear on this entry. Still open pending inspection of the pinned IUC changesets themselves (kmindex_query 0.6.1+galaxy4, lexicmap_search 0.9.0+galaxy1). [compare-against-iwc-exemplar, 2026-09-17] Corpus check (galaxyproject/iwc, 115 workflows) found no workflow exposing a >20-way controlled-vocabulary shard/index select as a workflow input or map-over axis -- the largest comparable case, data-fetching/parallel-accession-download's split_file_to_collection, dynamically chunks an arbitrary-length input file rather than enumerating a fixed named list, a different mechanism. No corpus precedent to draw on; still open, unchanged. [freeform-summary-to-galaxy-template, 2026-09-17] Topology settled `kmindex_db_selection` (N2) and `lexicmap_index_selection` (N4) as plain multi-value `text` workflow inputs consumed entirely inside each tool's own call -- kmindex_containment_screen's declared output is a `list` collection (one element per selected shard) and lexicmap_search's declared output is a `list:list` collection (gene outer axis from the real sample_sheet map-over, index inner axis from the tool's own per-index output declaration), rather than modeling either selection as a second Galaxy-level map-over collection. This is a topology commitment (see galaxy-workflow-draft.gxwf.yml steps kmindex_containment_screen / lexicmap_search); the exact tool-side input widget realizing it is still open and unchanged by this note. [advance-galaxy-draft-step, 2026-09-17] REFUTED in part: summarize-galaxy-tool on the pinned changeset (iuc/lexicmap/lexicmap_search 0.9.0+galaxy1, bcb6caec41eb) shows the wrapper's `parsed_tool` declares exactly one output, `out_file` (plain `data`, format `tabular`) -- no `discover_datasets`, no per-index collection output. There is no 'tool's own per-index output declaration'; that specific claim above is struck. `lexicmap_index` (case `db_opts_selector: db`, 'Locally installed LexicMap indexes') is a `gx_select` with `multiple: true` and dynamic `options: null` -- a single job accepts the full multi-value index selection and returns one aggregate hits table, so lexicmap_search's real per-gene output shape (mapped over `gene_query_panel`) is a flat `list`, not `list:list`. The kmindex/lexicmap side of the index-selection-mechanism question (delimited-text -> multi-select binding; dynamic option population) remains open and unchanged. The invalidated inner-axis/list:list claim's downstream consequence (flatten_lexicmap_results_by_gene's `__FLATTEN__` step assumed a nested input) is tracked separately as blocking entry `lexicmap-search-flatten-shape-mismatch`, superseded by this note. [advance-galaxy-draft-step, 2026-09-17] kmindex side CONFIRMED by direct XML inspection: galaxy-tool-cache add/summarize cannot parse the pinned iuc/kmindex/kmindex_query changeset (0.6.1+galaxy4, b6fa25b6b436) or any other galaxy-suffixed version -- a reproducible cache/parser defect (see galaxy-tool-summary.json warnings[] and the feedback ledger) -- so the wrapper's real upstream XML was read directly (tools-iuc commit 7681be7f40, confirmed via the Tool Shed API's remote_repository_url for this exact changeset) in place of the normal automated summarize-galaxy-tool path. Result: `db_opts|kmindex` (case `db_opts_selector: db`) is a `gx_select` with `multiple: true`, dynamic `options: null` (populated from the `kmindex` Tool Shed data table) -- the same shape as lexicmap_index, confirming this is a native Galaxy multi-select in both wrappers, not a repeat or per-element data input. The command template loops over indices internally (`#for $i, $INDEX in enumerate($INDICES)` on `$db_opts.kmindex.fields.path.split(',')`) and the `output` collection output (`list`, discover_datasets over `query_output/*.json`) fans out to one JSON element per selected shard -- matching the already-settled topology commitment exactly, no scatter/map-over needed. kmindex_containment_screen implemented on this basis this iteration. Still open and non-blocking: whether the scalar `kmindex_db_selection` `text` workflow input's delimited-string value is accepted as-is by a `multiple: true` select at runtime, or needs adaptation to a literal array -- this is a runtime parameter-shape question, not a topology gap, and does not block draft-validate."

  - id: allow-frameshifts-default-unconfirmed
    status: resolved
    kind: gap
    raised_by: freeform-summary-to-galaxy-interface
    step: multi_hsp_tiling_qc
    unmet: "Production default of stream_lexicmap_msa.py's --allow-frameshifts flag"
    missing: "Source prose states the default/production setting could not be confirmed from prose alone"
    resolved_by: advance-galaxy-draft-step
    supersedes: null
    note: "Exposed in this brief as an explicit boolean workflow parameter with no default asserted, rather than assuming reject-by-default. [freeform-summary-to-galaxy-data-flow] User-confirmed (2026-09-17): stream_lexicmap_msa.py's multi-HSP tiling/QC logic (\"LexicMapStreamer\") is not custom glue authored for this project from scratch -- it is backed by a real, existing implementation at https://github.com/nekrut/disassembler (private repo). The --allow-frameshifts production default is therefore expected to be readable directly from that repo's source, not an unrecoverable prose ambiguity. Still open (the value itself has not been read/confirmed) -- tracked as concrete follow-up work in the new lexicmapstreamer-wrapper-authoring-pending entry, to be resolved when that repo is inspected during wrapper authoring. [freeform-summary-to-galaxy-template, 2026-09-17] Carried into galaxy-workflow-draft.gxwf.yml as workflow input `tiling_qc_allow_frameshifts`: type boolean, `optional: true`, no `default:` -- a legal, non-TODO topology expression of \"value genuinely unknown,\" distinct from a topology TODO. Still open. [advance-galaxy-draft-step, 2026-09-17] RESOLVED: the private repo https://github.com/nekrut/disassembler was cloned and python/lexicmap_streamer.py read directly. Its argparse declares `parser.add_argument(\"--allow-frameshifts\", action=\"store_true\", help=...)` with no `default=True` -- Python's argparse gives a bare `action=\"store_true\"` flag an implicit default of `False`. Confirmed production default: OFF/False. The workflow input `tiling_qc_allow_frameshifts` remains `optional: true` with no asserted default at the workflow-input level (a user can still override per-run), but the wrapper itself (galaxy-user-tool.yml, tool_id `lexicmap_streamer`) now reflects the real tool's off-by-default semantics."

  - id: host-biome-platform-stratification-script-gap
    status: open
    kind: dropped
    raised_by: freeform-summary-to-galaxy-interface
    units: "Stage D host/biome/platform metadata stratification of the 2,114,904-accession Logan hit set (the paper's Fig 1B/C percentages)"
    because: "freeform-summary Section 5 (Stage D) states no corresponding script was identified among the root-level .py files; likely produced via ad hoc NCBI Entrez/SRA-metadata queries or manual curation not captured in the repo snapshot"
    unmet: "A reproducible Galaxy step that recomputes the biome/platform stratification numbers"
    missing: "No discoverable tool or script to wrap for this stratification"
    resolved_by: null
    supersedes: null
    note: "Not modeled as an executable workflow step in this brief; recorded as a labelled gap rather than invented as a fabricated step."

  - id: nominal-taxonomy-audit-not-modeled-as-step
    status: resolved
    kind: dropped
    raised_by: freeform-summary-to-galaxy-interface
    units: "Stage D nominal-taxonomy SRA metadata audit (136 runs / 18 BioProjects, manual classification into Experimental Evolution / Platform Benchmarking / Paleogenomics Control / etc.), including the candidate `Nominal-taxonomy BioProject classification table` declared workflow input"
    because: "Source describes this as a manual/registry-based certification exercise, not a computational tool invocation over data the workflow would produce"
    unmet: "N/A — not intended as an executable Galaxy step"
    missing: "No tool; this is curated reference/provenance data, not a computation"
    resolved_by: freeform-summary-to-galaxy-template
    supersedes: null
    note: "Modeled in this brief as a static reference-data input (a BioProject classification table) rather than a workflow step. Downstream data-flow phase should confirm this framing. [freeform-summary-to-galaxy-data-flow, 2026-09-17] Confirmed: no Workflow A node (N1-N7) consumes this table; carried forward as an open framing question (data-flow brief section 7, item 2) rather than dropped outright. [freeform-summary-to-galaxy-template, 2026-09-17] Resolved: the settled N1-N7 topology has no node wired to this table, and per the data-flow brief's own suggestion (\"an unconnected input is unusual for a runnable workflow ... consider dropping it\"), this Mold drops it from galaxy-workflow-draft.gxwf.yml's declared workflow inputs entirely. It remains documentation/provenance context (see this workflow draft's top-level `doc:`), not a Galaxy input or step."

  - id: chronaeon-synthetic-metadata-phase0
    status: open
    kind: dropped
    raised_by: freeform-summary-to-galaxy-interface
    units: "run_chronaeon_phix174_sieve.py Phase 0 fabricated pseudo-collection_date construction feeding hyphaeon autoclock"
    because: "freeform-summary Section 7, item 7 confirms by direct script inspection that Phase 0's collection_date values are hash-derived synthetic placeholders, not real SRA/BioSample metadata"
    unmet: "A genuine collection-date-bearing input to the autoclock step"
    missing: "No real per-accession collection_date source was identified in this repo snapshot"
    resolved_by: null
    supersedes: null
    note: "This brief models autoclock's date-bearing metadata input as an open/external requirement (real SRA BioSample collection dates to be sourced) rather than porting the synthetic generator as if it were a genuine step."

  - id: chronaeon-hardcoded-statistics-phases
    status: open
    kind: dropped
    raised_by: freeform-summary-to-galaxy-interface
    units: "run_chronaeon_phix174_sieve.py Phases 2, 6, 7, 8 (e.g. the Gene D/E and Gene B/A Mann-Whitney medians/p-values, and a per-gene VEP correlation table)"
    because: "freeform-summary Section 7, item 7 confirms these values appear as hardcoded constants written directly into the script, not recomputed from input data at run time"
    unmet: "Genuine, re-executable recomputation of the statistics these phases report"
    missing: "The phases as written are reporting/munging of pre-baked numbers, not real computations"
    resolved_by: null
    supersedes: null
    note: "Only Phases 1/3/4 (the confirmed genuine hyphaeon autoclock/r0/meme CLI invocations) are modeled as real workflow steps in this brief. Phases 2/6/7/8 are excluded pending reimplementation as genuine pandas/scipy steps over live inputs."

  - id: wei-2026-dms-dataset-external-sourcing
    status: open
    kind: gap
    raised_by: freeform-summary-to-galaxy-interface
    unmet: "Concrete, fetchable source location for the Wei, Li & Lehner (2026) whole-genome DMS ground-truth table, a hard input dependency for Stages E/G/H/J"
    missing: "Dataset is not present in the repo; every downstream script expects it at a fixed local path (phix174_WGM/data/...zip) that does not exist in this checkout"
    resolved_by: null
    supersedes: null
    note: "Modeled in this brief as an external reference-data input (bioRxiv doi:10.64898/2026.07.25.740675 supplement / GitHub, exact download mechanism TBD). Must be resolved before test-data resolution phases can fixture it."

  - id: hyphaeon-toolshed-status-unverified
    status: open
    kind: gap
    raised_by: freeform-summary-to-galaxy-interface
    unmet: "Whether HyphAeon (github.com/veg/hyphaeon, CLI + Python package) and the companion hyphaeon_overlaps package are already Tool-Shed-wrapped, conda/pip-installable, or need to be authored from scratch as Galaxy tools"
    missing: "freeform-summary Section 7, item 3 flags this as unverified from the repo alone"
    resolved_by: null
    supersedes: null
    note: "This brief assumes new Galaxy tool wrappers will be authored for both packages; discover-shed-tool should check Tool Shed availability before author-galaxy-tool-wrapper is invoked for either."

  - id: lexicmapstreamer-implementation-provenance
    status: resolved
    kind: gap
    raised_by: freeform-summary-to-galaxy-data-flow
    step: lexicmap_streamer_tiling_qc
    unmet: "Whether stream_lexicmap_msa.py's multi-HSP coordinate tiling / codon QC / haplotype-collapsing logic (the user's \"LexicMapStreamer\") has any existing implementation to wrap, or must be authored as new Galaxy tool code from scratch"
    missing: "freeform-summary's tool inventory (Section 5, 'Custom/internal orchestration code') characterized stream_lexicmap_msa.py as code with no separate installable tool"
    resolved_by: freeform-summary-to-galaxy-data-flow
    supersedes: null
    note: "User-confirmed (2026-09-17): LexicMapStreamer already exists as a real, working implementation in the private repository https://github.com/nekrut/disassembler -- this is the actual code behind stream_lexicmap_msa.py's multi-HSP tiling/QC logic, not something to author from scratch by reverse-engineering the summary's prose. This does not itself discharge the wrapper-authoring obligation -- see lexicmapstreamer-wrapper-authoring-pending for the remaining open work."

  - id: lexicmapstreamer-wrapper-authoring-pending
    status: resolved
    kind: gap
    raised_by: freeform-summary-to-galaxy-data-flow
    step: lexicmap_streamer_tiling_qc
    unmet: "A Galaxy tool wrapper (XML + macros, or a Planemo-testable CLI wrapper) for LexicMapStreamer's multi-HSP tiling/QC/haplotype-collapsing step (Workflow A, node N5)"
    missing: "No Tool Shed wrapper is known to exist yet; the real implementation lives in the private repo https://github.com/nekrut/disassembler and its CLI/API surface, install method, and license have not been inspected in this run"
    resolved_by: advance-galaxy-draft-step
    supersedes: null
    note: "Not a from-scratch authoring problem (see lexicmapstreamer-implementation-provenance) -- discover-shed-tool should first check whether a wrapper already exists for this repo; if not, author-galaxy-tool-wrapper should target the disassembler repo's actual CLI/API rather than reverse-engineering behavior from stream_lexicmap_msa.py prose alone. The --allow-frameshifts default (see allow-frameshifts-default-unconfirmed) and the exact shape of N5's 8 per-gene output artifacts (see freeform-galaxy-data-flow.md §2, node N5) should both be confirmed by reading this repo's source during that authoring pass. [compare-against-iwc-exemplar, 2026-09-17] Corpus search for kmindex/lexicmap/comparable multi-HSP-tiling or haplotype-calling tools returned zero hits across the full IWC corpus -- confirms no shortcut via an existing IWC-adjacent wrapper; the nekrut/disassembler-backed wrapper-authoring path remains the only route. Still open, unchanged. [freeform-summary-to-galaxy-template, 2026-09-17] Topology settled: `lexicmap_streamer_tiling_qc` in galaxy-workflow-draft.gxwf.yml declares all 8 output ports concretely (see n5-output-collection-shape-no-record-precedent, resolved) and is mapped one call per gene. Still open on wrapper identity/authoring; also now the anchor for the am3-diagnostic-granularity question raised in n7-am3-diagnostic-granularity-unconfirmed, since that question turns on the same repo's summary.json / flagged.tsv schema. [advance-galaxy-draft-step, 2026-09-17] RESOLVED: discover-shed-tool re-confirmed the miss this iteration (3 query variants, 0 hits; galaxy-tool-pin.json). https://github.com/nekrut/disassembler was cloned (git clone succeeded; the repo, while described by the user as private, was accessible with this environment's ambient `gh`/git credentials -- no access blocker encountered). python/lexicmap_streamer.py (817 lines) was read directly: pure Python 3 stdlib, no third-party imports; full argparse CLI confirmed (see galaxy-user-tool.yml for the complete flag table). author-galaxy-tool-wrapper produced galaxy-user-tool.yml: `GalaxyUserTool` id `lexicmap_streamer`, version `1.0.0`, container `python:3.13-slim`, the script vendored verbatim (MIT license, (c) Anton Nekrutenko, commit a51eb58) as a `configfiles` entry. All 8 of N5's declared output ports map 1:1 onto the script's real fixed-suffix output files (`.clean.msa.fasta`, `.clean.haplotypes.tsv`, `.clean.accessions.fasta`, `.clean_expanded.accessions.fasta`, `.flagged.accessions.fasta`, `.flagged.tsv`, `.cohort_ledger.tsv`, `.summary.json`) -- no invented outputs, no port left unresolved; `--no-a2m` passed to suppress the one script output (`.a2m`) with no corresponding declared port. galaxy-workflow-draft.gxwf.yml's `lexicmap_streamer_tiling_qc` step now carries this concrete `tool_id`/`tool_version`/`in`/`state`/`out`. CORRECTION surfaced by this reading: the step's `_plan_in` (single semantic port) undercounted the real input surface -- the script requires the per-gene reference CDS FASTA (`-q/--ref`) in addition to the LexicMap hit table; wired to `gene_query_panel`, the same collection `lexicmap_search` already consumes, so no new workflow input or topology change was needed, just an added `in:` entry. `gxwf draft-validate --concrete` returns `draft valid` / `Concrete: OK` on the mutated draft (this step's tool_id resolves to a `skip_tool_not_found` Tool Shed-lookup skip, exactly like the pre-existing kmindex_query skip, not a hard failure)."

  - id: reference-genome-workflow-input-dropped
    status: resolved
    kind: dropped
    raised_by: freeform-summary-to-galaxy-template
    units: "`Reference genome (NC_001422.1)` as a declared Workflow A workflow-level input"
    because: "The settled N1-N7 topology (galaxy-workflow-draft.gxwf.yml) has no node that consumes the whole-genome FASTA -- only the per-gene CDS FASTAs in `gene_query_panel` are used by N1 (combine) and N4 (LexicMap search), matching freeform-summary.md's own language about the 'canonical ΦX174 gene coordinate frame.' freeform-galaxy-data-flow.md §1 and §7 item 1 already flagged this input as unwired and recommended dropping it from Workflow A's declared inputs if the template phase found no consumer, which is what this Mold confirmed."
    unmet: "N/A -- not a computational dependency of any Workflow A step"
    missing: "No node in Workflow A reads the whole-genome FASTA"
    resolved_by: freeform-summary-to-galaxy-template
    supersedes: null
    note: "Dropped from galaxy-workflow-draft.gxwf.yml's declared `inputs:`; recorded in the draft's top-level `doc:` for provenance. This input may belong to Workflow B (Stage E), where `NC_001422.1:2395-2919` is genuinely used for bowtie2/samtools alignment -- out of scope for this run."

  - id: n7-gene-e-audit-source-resolved
    status: resolved
    kind: gap
    raised_by: freeform-summary-to-galaxy-data-flow
    step: extract_gene_e_am3_audit
    unmet: "Whether N7's Gene E am3 quarantine audit is literally the Gene E element of N5's (lexicmap_streamer_tiling_qc's) per-gene summary.json sample_sheet, or a ninth, separate per-gene artifact N5 also emits"
    missing: "freeform-galaxy-data-flow.md §2 N5/N7 and §7 item 3 left this open, resolvable only once the nekrut/disassembler-backed wrapper's real output surface is known"
    resolved_by: freeform-summary-to-galaxy-template
    supersedes: null
    note: "TOPOLOGY DECISION (this Mold must never leave a topology choice as TODO): modeled N7 as an EXTRACTION of the Gene E element of N5's summary.json collection (collection-unbox-singleton / __EXTRACT_DATASET__ by element_identifier == \"E\"), not a distinct ninth artifact. Rationale: freeform-summary.md Stage D2 states the am3 detection logic 'lives inside the QC step of stream_lexicmap_msa.py' (i.e. inside N5) and is only 'summarized in results/02_layer1_quasispecies/gene_e_am3_quarantine_audit.json' -- a path under ChronAeon Phase 2 (freeform-summary.md Stage I), a stage this run's scope decision (workflow-scope-boundary-unresolved) places out of scope for Workflow A, and which freeform-summary.md §7 item 7 / chronaeon-synthetic-metadata-phase0 / chronaeon-hardcoded-statistics-phases flag as partly fabricated-metadata / hardcoded-statistics rather than a reliable recomputation path. Treating N7 as a literal extraction of N5's own Gene E output avoids manufacturing a dependency on that unreliable, out-of-scope stage, and matches the source's own statement that the detection is internal to N5's QC rather than a separate computation. See galaxy-workflow-draft.gxwf.yml step `extract_gene_e_am3_audit`'s `_plan_state` for the full reasoning as carried in the draft itself. This resolution carries one caveat, tracked separately: n7-am3-diagnostic-granularity-unconfirmed."

  - id: n7-am3-diagnostic-granularity-unconfirmed
    status: resolved
    kind: gap
    blocking: false
    raised_by: freeform-summary-to-galaxy-template
    step: extract_gene_e_am3_audit
    unmet: "Whether N5's (lexicmap_streamer_tiling_qc's) per-gene summary.json / flagged.tsv actually carries locus-specific detail (genome position nt587, G->A, codon 7 TGG->TAG) sufficient to reconstruct the paper's '2,215,172/2,392,457 (92.59%) of evaluated Gene E accessions carry this substitution' statistic, as opposed to only an aggregate premature-internal-stop count"
    missing: "freeform-summary.md describes stream_lexicmap_msa.py's QC step as flagging premature internal stop codons generally (via codon-table translation) and describes summary.json as carrying 'quantile distributions, regime diagnostics, multi-HSP recovery counts' -- it does not explicitly confirm the summary.json (or flagged.tsv) schema records the specific substituted nucleotide/codon per flagged accession, only that a stop was found"
    resolved_by: advance-galaxy-draft-step
    supersedes: null
    note: "Not treated as blocking: the underlying computation (per-accession codon-level translation and stop-codon detection) is plausibly already granular enough, since stream_lexicmap_msa.py must inspect individual codons to flag a stop at all -- the open question is only whether that per-accession locus detail is surfaced into N5's declared outputs (summary.json / flagged.tsv) or needs an additional field. To be confirmed during the same nekrut/disassembler wrapper-authoring pass tracked by lexicmapstreamer-wrapper-authoring-pending; if the real repo's outputs do not carry this detail, author-galaxy-tool-wrapper / implement-galaxy-tool-step should add it as a wrapper-level enhancement rather than escalate a topology repair, since the wiring (N7 reads N5's per-gene summary output) remains correct either way. [advance-galaxy-draft-step, 2026-09-17] PARTIALLY CONFIRMED, still open, still non-blocking, but the concern sharpens rather than dissolves: python/lexicmap_streamer.py was read directly. `summary.json` (`summary_data` dict) carries only aggregate quantiles/cohort counts/Shannon entropy plus a `top_10_haplotypes` preview limited to the CLEAN FULL-LENGTH cohort (ranked by count, with `aa_mutations`/`nt_mutations` string fields like `W7*` / `587G>A` that DO encode exact codon/nt position when present) -- it carries no per-accession stop-codon locus list. The literal per-accession, 1-based codon-position detail (`stop_codons` column, e.g. \"2,15\") lives in `flagged.tsv` and `cohort_ledger.tsv`, which N5 also emits as separate declared output ports (`flagged_tsv`, `cohort_ledger_tsv`) but which N7 (`extract_gene_e_am3_audit`, per n7-gene-e-audit-source-resolved) does NOT read -- N7 is wired only to `summary_json`. Since am3 is specifically a PREMATURE STOP mutant, an am3-carrying accession is by construction routed to the FLAGGED cohort (not the CLEAN top_10_haplotypes preview), so summary.json's per-haplotype mutation strings will not surface it either. Net: if the Gene E am3 quarantine audit needs the exact per-accession locus (not just the aggregate `flagged_premature_stops` count that summary.json does carry), N7 is reading the wrong port -- it should read `flagged_tsv` (or `cohort_ledger_tsv`) instead of/in addition to `summary_json`. Left open and non-blocking per this entry's own standing guidance (a topology question for the template tier, out of scope for this single-step iteration, which was scoped to lexicmap_streamer_tiling_qc only) rather than escalated to repair-galaxy-draft-topology on this pass. [advance-galaxy-draft-step, 2026-09-17] RESOLVED while implementing extract_gene_e_am3_audit itself: re-read python/lexicmap_streamer.py (same commit a51eb58d6c1ca941d3fb8d6adf5e8160c3926b91) and re-confirmed the above analysis line-by-line (process_accession_block lines 400-480; flagged.tsv header/rows at lines 365/471/478; cohort_ledger.tsv header/rows at lines 366/480; summary.json construction at lines 599-730). Rewired extract_gene_e_am3_audit's `in:` from `lexicmap_streamer_tiling_qc/summary_json` to `lexicmap_streamer_tiling_qc/flagged_tsv` -- flagged_tsv is the smallest N5 output already filtered to the anomalous/quarantine cohort and already carrying a per-accession `stop_codons` (codon-position) column, which is exactly the per-accession, locus-specific detail this audit needs, whereas cohort_ledger_tsv is an unfiltered superset requiring the consumer to filter by flag itself. This was a same-step port correction (N7 still reads N5, just the correct one of its 8 already-declared output ports), not a topology repair -- no producer node was inserted or removed, so repair-galaxy-draft-topology was not invoked. One residual, explicitly non-blocking limitation remains: neither flagged.tsv nor cohort_ledger.tsv records the literal nucleotide-substitution letters (only the codon index), so reconstructing the paper's exact 'nt587 G->A' phrasing still requires cross-referencing the reference sequence -- this does not affect the correctness of this step's own job (extracting the Gene E element), only a downstream reporting nicety."

  - id: kmindex-hit-merge-no-corpus-precedent
    status: resolved
    kind: gap
    blocking: false
    raised_by: compare-against-iwc-exemplar
    step: kmindex_hit_union
    unmet: "A concrete Galaxy tool/idiom for N3's per-shard kmindex hit-map merge: dedup accessions across ~109 shard JSON files while keeping the max containment score per accession"
    missing: "IWC corpus (galaxyproject/iwc, cloned/pulled 2026-09-17, 115 workflows) has no workflow performing key-based dedup-with-max-score reduction over a list collection. The closest built-in idiom found, Collapse Collection (toolshed.g2.bx.psu.edu/repos/nml/collapse_collections/collapse_dataset, used in microbiome/mags-building/MAGs-generation.ga steps 21-22 and microbiome/metagenomic-genes-catalogue.ga), performs plain concatenation of a list collection into one dataset with no per-key reduction -- it could serve as a first pass (concatenate, then a custom sort/dedup script) but does not implement the max-score-keeping semantics itself."
    resolved_by: freeform-summary-to-galaxy-template
    supersedes: null
    note: "Was carried only as prose in freeform-galaxy-data-flow.md section 4 item 1, never previously promoted to this ledger. Promoted here per compare-against-iwc-exemplar's mandate to record structural divergences with no corpus precedent. Template phase should plan a small custom aggregation step (e.g. a Python/pandas tool) fed by Collapse Collection's concatenated output, rather than expect a single built-in tool to do both. [freeform-summary-to-galaxy-template, 2026-09-17] Resolved: galaxy-workflow-draft.gxwf.yml wires this as two concrete steps -- `kmindex_hit_concat` (Identity-pinned, nml/collapse_collections/collapse_dataset) followed by `kmindex_hit_dedup_max_score` (Deferred, tool_id TODO, _plan_state documents the dedup+max-score reduction). No blocking gap remains; the custom step's wrapper identity is left open for discover-shed-tool / author-galaxy-tool-wrapper, which is an ordinary Deferred-tier obligation, not an unmet topology need. [advance-galaxy-draft-step, 2026-09-17] Wrapper identity now settled: discover-shed-tool re-confirmed the miss (datamash groupby/max rejected -- tabular/pre-sorted input only, cannot parse JSON); author-galaxy-tool-wrapper produced galaxy-user-tool-kmindex-hit-dedup-max-score.yml (GalaxyUserTool, id kmindex_hit_dedup_max_score, version 1.0.0). kmindex_hit_dedup_max_score is now fully concrete in the draft (tool_id/tool_version mirror the UDT identity, ports concatenated_hits/accession_union). No blocking entry raised -- the step's single wired input (kmindex_hit_concat/output) is sufficient to compute its declared output."

  - id: n6-json-flatten-no-corpus-precedent
    status: resolved
    kind: gap
    blocking: false
    raised_by: compare-against-iwc-exemplar
    step: ingestion_manifest_aggregation
    unmet: "A Galaxy tool/idiom to flatten each gene's nested .summary.json (N5 output) into one manifest row before concatenation into Ingestion manifest (all genes)"
    missing: "IWC corpus has a real, directly relevant built-in tool for the tabular half of this bridge -- collection_column_join (toolshed.g2.bx.psu.edu/repos/iuc/collection_column_join/collection_column_join/0.0.3, used in MAGs-generation.ga steps 66-67 and metagenomic-genes-catalogue.ga) joins a list collection of per-element tabular files by an identifier column into one combined table. No corpus workflow performs the JSON-to-tabular-row flattening half; every per-sample tabular input to collection_column_join in the corpus is already tabular going in (e.g. CoverM/Quast/CheckM2 reports), never raw JSON."
    resolved_by: freeform-summary-to-galaxy-template
    supersedes: null
    note: "Confirms freeform-galaxy-data-flow.md section 4 item 5's claim ('no generic Galaxy tool flattens an arbitrary nested per-gene JSON into one manifest row') is correct for the flatten step, but narrows the remaining gap: only a small per-gene JSON-to-TSV-row flattening tool (jq/python) needs to be authored; the subsequent collection-to-table join can reuse the real, named collection_column_join Tool Shed tool rather than a bespoke merge. [freeform-summary-to-galaxy-template, 2026-09-17] Resolved: galaxy-workflow-draft.gxwf.yml wires this as two concrete steps -- `flatten_gene_summary_json_to_row` (Deferred, tool_id TODO, mapped over the gene collection) followed by `join_gene_summary_rows_into_manifest` (Identity-pinned, iuc/collection_column_join/collection_column_join/0.0.3). No blocking gap remains. [advance-galaxy-draft-step, 2026-09-17] Deferred obligation discharged: `gxwf tool-search \"json to tabular\"` found only generic JSON tools (best hit `iuc/jq`, confirmed installable via galaxy-tool-cache add/summarize, changeset 4e62e523c2b6) -- rejected because its `filter`/`arguments` parameters cannot read the mapped input's Galaxy `element_identifier` without an extra `collection_element_identifiers`-style producer step and port, which would be an avoidable topology change. Authored a small GalaxyUserTool instead (`galaxy-user-tool-flatten-gene-summary.yml`, id `flatten_gene_summary_json_to_row`, version `1.0.0`, pure Python 3 stdlib, container `python:3.13-slim`) whose `shell_command` reads `$(inputs.summary_json.element_identifier)` directly -- confirmed valid against the installed `@galaxy-tool-util/schema` package's `gx-data.js` (`job_runtime` File-object shape declares `element_identifier: S.optional(S.String)` alongside `path`; also flagged as an authoring-note documentation gap in the feedback ledger, entry `galaxy-user-tool-authoring-missing-element-identifier-expression`). Output is a two-line TSV (header + one data row), first column `gene` = element_identifier, remaining columns the flat scalar fields of summary.json (regime diagnostics, cohort-breakdown counts, multi-HSP recovery counts, coverage/pident quantiles), read directly from this run's own vendored lexicmap_streamer.py rather than reverse-engineered from prose. `gxwf validate-tool-source galaxy-user-tool-flatten-gene-summary.yml` returns `OK`; `gxwf draft-validate --concrete galaxy-workflow-draft.gxwf.yml` returns `draft valid` / `Concrete: OK` on the mutated draft. join_gene_summary_rows_into_manifest's stale `in:` reference to this step's placeholder port was updated to the real `summary_row` port name (same-step reference fix, not a topology repair; see that step's own `_plan_state`)."

  - id: n5-output-collection-shape-no-record-precedent
    status: resolved
    kind: gap
    blocking: false
    raised_by: compare-against-iwc-exemplar
    step: lexicmap_streamer_tiling_qc
    unmet: "Whether LexicMapStreamer's 8 per-gene output artifacts should be modeled as one sample_sheet:record (named-slot) collection, or as multiple parallel sample_sheet/list collections sharing the gene element_identifier"
    missing: "IWC corpus (115 workflows, galaxyproject/iwc, checked 2026-09-17) contains zero workflows using a record/named-slot collection type (grep -rl 'collection_type.*record' *.ga = 0 hits). The corpus's established idiom for a per-element multi-artifact tool step is N separate parallel list/sample_sheet collections that share the same element_identifier and are recombined post hoc (e.g. via collection_column_join or __FLATTEN__) -- observed directly in microbiome/mags-building/MAGs-generation.ga, where per-sample assembly/binning/QC outputs ride as several parallel collections, not one named-slot collection."
    resolved_by: freeform-summary-to-galaxy-template
    supersedes: null
    note: "Does not resolve freeform-galaxy-data-flow.md section 2 N5's open design recommendation (sample_sheet:record vs. 8 parallel collections) -- it is negative corpus evidence against the record-shaped option. Template phase should default to the corpus-precedented 8-parallel-collections-sharing-element_identifier shape unless a specific reason favors the record shape, since the record shape has no IWC exemplar to validate test/lint conventions against. [freeform-summary-to-galaxy-template, 2026-09-17] Resolved: galaxy-workflow-draft.gxwf.yml's `lexicmap_streamer_tiling_qc` step declares 8 named output ports (TODO_clean_msa_fasta, TODO_clean_haplotypes_tsv, TODO_clean_accessions_fasta, TODO_clean_expanded_accessions_fasta, TODO_flagged_accessions_fasta, TODO_flagged_tsv, TODO_cohort_ledger_tsv, TODO_summary_json), each an independent gene-keyed collection sharing the gene `element_identifier`, per this entry's recommendation -- not a `sample_sheet:record`. Topology decision made; only the wrapper's real port names remain TODO."

  - id: lexicmap-search-flatten-shape-mismatch
    status: resolved
    kind: gap
    blocking: true
    raised_by: advance-galaxy-draft-step
    step: flatten_lexicmap_results_by_gene
    unmet: "flatten_lexicmap_results_by_gene's declared behavior (__FLATTEN__, collapse a gene x index list:list down to a gene-keyed list, per its own doc and the microbiome/mags-building/MAGs-generation.ga __FLATTEN__ precedent it cites) requires a nested list:list input"
    missing: "lexicmap_search's real, pinned Tool Shed wrapper (iuc/lexicmap/lexicmap_search 0.9.0+galaxy1, changeset bcb6caec41eb, confirmed via discover-shed-tool + summarize-galaxy-tool this iteration) declares exactly one output, `out_file` (plain `data`, format `tabular`; no `discover_datasets`, no per-index/collection output). Index selection (`lexicmap_index_selection`) is bound as an in-tool-call multi-select value, not a second Galaxy-level map-over axis (per the already-settled topology commitment in ledger entry `kmindex-lexicmap-index-selection-mechanism`). Mapped over the single `gene_query_panel` axis, lexicmap_search's real output is therefore a flat `list` (one aggregate hits table per gene) -- there is no index axis for `__FLATTEN__` to collapse. draft-validate --concrete already surfaces the immediate symptom: `flatten_lexicmap_results_by_gene: step input \"input\" source \"lexicmap_search/TODO_lexicmap_hits_nested\" references unknown port\" (the port was renamed to the wrapper's real `out_file` while implementing lexicmap_search this iteration); fixing only the reference would silently paper over the deeper shape mismatch."
    resolved_by: repair-galaxy-draft-topology
    supersedes: null
    note: "Raised by advance-galaxy-draft-step (2026-09-17) while implementing lexicmap_search: confirming the real wrapper's output shape refuted the 'tool's own per-index output declaration' claim `kmindex-lexicmap-index-selection-mechanism`'s template-phase note rested on (see that entry's superseding note, same date). lexicmap_search's own step is fully concrete and correct; this entry blocked only on flatten_lexicmap_results_by_gene, which was authored as Resolved against the now-refuted list:list assumption. [repair-galaxy-draft-topology, 2026-09-17] Resolved by narrowing, not by inserting a producer: removed the now-unnecessary `flatten_lexicmap_results_by_gene` (`__FLATTEN__`) step entirely and rewired its sole consumer, `lexicmap_streamer_tiling_qc`'s `TODO_lexicmap_results` port, directly onto `lexicmap_search/out_file`. That real output already carries the exact shape (`list`, 10 elements, gene-keyed) lexicmap_streamer_tiling_qc's own doc says it expects -- no substitute producer was needed, so this is a clean bounded repair, not a workaround. Confirmed no other step or workflow output referenced `flatten_lexicmap_results_by_gene`."
test-data-refspresenttest-data-refs.json

Resolved workflow test inputs and expected outputs derived from paper evidence (URLs, file shapes, expected hashes).

declared by
find-test-data, paper-to-test-data (phase 7)
consumed at
9
schema
none declared
sha256
72295f558a1eee2813d20beb9062c75d72f351c7000cfab420bd32fb0659863b
artifact
test-data-refs
schema_note
Resolved workflow test inputs and expected outputs for galaxy-workflow.gxwf.yml (phix174_sra_landscape_spikein_sieve / Workflow A), derived via foundry-skills:paper-to-test-data then foundry-skills:find-test-data. Selected chain step: find-test-data (see foundry-feedback.ledger.yml phases[7].selected).
workflow
/Users/scottcain/git/dms/draft-manuscript-galaxy/galaxy-workflow.gxwf.yml
inputs
15 item(s)
gaps
4 item(s)
workflow-debug-reportpresentworkflow-debug-report.md

Failure-surface classification with captured job/invocation/collection/assertion evidence and a recommended next step or reference-gap follow-up.

declared by
debug-galaxy-workflow-output (phase 12)
consumed at
nothing downstream reads it
schema
none declared
sha256
7e6fee5351dec299bd4d04810a3fc749966a843579ef0fb5a265a4753a08e245
  • Workflow debug report — galaxy-workflow.gxwf.yml
  • Test 1 — `kmindex_wiring_smoke_generic_fixtures` (test_index 1)
  • Test 2 — `gene_e_j_am3_diagnostic_synthetic_lexicmap_index` (test_index 2)
  • Evidence
  • Feedback ledger
  • Overall assessment of the deliverable
workflow-test-resultpresentworkflow-test-result.json

Structured status plus captured evidence — Planemo result, invocation/history/workflow ids, artifact paths, Galaxy mode, and (on failure) the observed modality and next reference surface — for debug-galaxy-workflow-output. Also the faithful handoff when no test exists or none could be run.

declared by
run-workflow-test (phase 11)
consumed at
12
schema
none declared
sha256
9073963a1fe0b7f6f2df73420c4e61d1a0c4e776ab88941b5d9635011d3f2b4b
{
  "workflow_path": "galaxy-workflow.gxwf.yml",
  "test_file_path": "galaxy-workflow.gxwf-tests.yml",
  "status": "fail",
  "not_run_reason": null,
  "static_validation": {
    "command": "gxwf validate-tests galaxy-workflow.gxwf-tests.yml --workflow galaxy-workflow.gxwf.yml --json",
    "valid": true,
    "errors": []
  },
  "galaxy_mode": {
    "kind": "planemo-managed",
    "install_flags": [
      "--install_galaxy"
    ],
    "galaxy_branch_pinned": false,
    "galaxy_checkout": "~/.planemo/gx_repo (reused cached checkout from phase 9, HEAD 18bb36a9f49071da5e502b162c9a6905d7b78aae, 2026-09-17)",
    "galaxy_venv": "~/.planemo/gx_venv_3 (Python 3.13.5, reused cached venv)",
    "udt_supply_attempt": {
      "mechanism_tried": "planemo test --extra_tools <dir containing the 3 GalaxyUserTool YAML files>",
      "outcome": "did not register any of the 3 UDTs",
      "evidence": "planemo wrote `<tool_dir dir=\".../udt-tools\" />` into the generated tool_conf.xml (confirmed by reading the file directly from the live Planemo temp config dir); Galaxy's toolbox parsed that tool_conf.xml but zero log lines in either run's planemo log reference any of the 3 UDT ids/filenames or `GalaxyUserTool`. The subsequent workflow-invocation HTTP 400 for test case 2 explicitly listed `lexicmap_streamer (version 1.0.0)`, `flatten_gene_summary_json_to_row (version 1.0.0)`, and `kmindex_hit_dedup_max_score (version 1.0.0)` among tools 'not installed', confirming the toolbox never registered them.",
      "root_cause": "Galaxy's classic `tool_dir` toolbox scanner auto-discovers XML tool wrappers only. A GalaxyUserTool YAML document (per author-galaxy-tool-wrapper's own SKILL.md: 'a single GalaxyUserTool YAML document, not Galaxy XML') has no lowering step to XML documented anywhere in this Foundry's packaged references, no `gxwf` subcommand performs this conversion, and no other planemo flag was found that accepts this format directly.",
      "classification": "genuinely unresolved infrastructural gap, not a transient install failure -- logged as feedback ledger entry run-workflow-test-no-mechanism-to-install-authored-galaxyusertool-udts"
    }
  },
  "test_cases": [
    {
      "id": "galaxy-workflow.gxwf.yml_0",
      "name": "kmindex_wiring_smoke_generic_fixtures",
      "test_index": 1,
      "planemo_command": "planemo test --install_galaxy --test_index 1 --extra_tools <udt-dir> --test_output_json planemo-test1-output.json --test_output planemo-test1-output.html galaxy-workflow.gxwf.yml",
      "status": "fail",
      "modality": "staging failure (client-side, pre-invocation)",
      "planemo_result": {
        "execution_problem": "'rows'",
        "status": "error",
        "invocation_details": null,
        "job": null,
        "output_problems": []
      },
      "root_cause": "Uncaught KeyError: 'rows' in galaxy.tool_util.cwl.util.replacement_collection (galaxy-tool-util==25.1.2, vendored into planemo==0.75.47). That function unconditionally executes `kwds[\"rows\"] = value[\"rows\"]` for any collection_type starting with 'sample_sheet'. This test case's gene_query_panel Collection intentionally omits `rows:` (not meaningful for generic non-phiX174 fixture content, per the test file's own comment), which tests-format.schema.json's Collection $def treats as optional -- and this exact test file passed gxwf validate-tests --workflow cleanly with rows absent. No Galaxy invocation was ever created; no tool (kmindex, lexicmap, collapse_dataset, or any UDT) was exercised by this test case.",
      "traceback_tail": "planemo/galaxy/activity.py:441 stage_in -> galaxy/tool_util/client/staging.py:275 stage -> galaxy/tool_util/cwl/util.py:388 galactic_job_json -> :234 replacement_item -> :362 replacement_collection -> KeyError: 'rows'",
      "artifacts": {
        "test_output_json": "planemo-test1-output.json",
        "test_output_html": "planemo-test1-output.html",
        "raw_log": "planemo-test1.log"
      },
      "next_reference_surface": "galaxy.tool_util.cwl.util.replacement_collection source (galaxy_tool_util-25.1.2, vendored in planemo's venv) -- fix or work around the unconditional `value[\"rows\"]` access before this test case can stage at all; see feedback ledger entry galaxy-tool-util-replacement-collection-requires-rows-key-unconditionally"
    },
    {
      "id": "galaxy-workflow.gxwf.yml_1",
      "name": "gene_e_j_am3_diagnostic_synthetic_lexicmap_index",
      "test_index": 2,
      "planemo_command": "planemo test --install_galaxy --test_index 2 --extra_tools <udt-dir> --test_timeout 600 --test_output_json planemo-test2-output.json --test_output planemo-test2-output.html galaxy-workflow.gxwf.yml",
      "status": "fail",
      "modality": "tool-install failure (workflow invocation refused by Galaxy before any job ran)",
      "planemo_result": {
        "execution_problem": "Unexpected HTTP status code: 400: {\"err_msg\":\"Workflow was not invoked; the following required tools are not installed: toolshed.g2.bx.psu.edu/repos/nml/collapse_collections/collapse_dataset (version 5.1.0), toolshed.g2.bx.psu.edu/repos/iuc/lexicmap/lexicmap_search (version 0.9.0+galaxy1), toolshed.g2.bx.psu.edu/repos/iuc/kmindex/kmindex_query (version 0.6.1+galaxy4), lexicmap_streamer (version 1.0.0), flatten_gene_summary_json_to_row (version 1.0.0), kmindex_hit_dedup_max_score (version 1.0.0), toolshed.g2.bx.psu.edu/repos/iuc/collection_column_join/collection_column_join (version 0.0.3)\",\"err_code\":0}",
        "status": "error",
        "invocation_details": null,
        "job": null,
        "output_problems": []
      },
      "root_cause_notes": [
        "The 3 authored UDTs (lexicmap_streamer, flatten_gene_summary_json_to_row, kmindex_hit_dedup_max_score) were never in the toolbox at all -- consistent with test case 1's finding and the confirmed absence of any UDT-related toolbox log lines (see udt_supply_attempt above). This part is a confirmed, structural block.",
        "The real Tool Shed tools (collapse_dataset, lexicmap_search, kmindex_query, collection_column_join) were also reported not-installed, despite install_manager log lines showing 'Cloning repository' for all four (collapse_collections was even logged as already 'Installed' from a cached prior run). Only ~15-48s elapsed between each clone and the invocation attempt. Given a `Solving environment: ...working... failed / PackagesNotFoundError: coreutils=8.25` conda resolution failure was observed for at least one dependency shortly before the invocation attempt (coreutils=8.25 predates osx-arm64 conda-forge/bioconda builds -- a plausible platform-specific limitation of this macOS Apple Silicon host, not necessarily a Galaxy/Foundry defect), this looks like either (a) a genuine dependency-resolution failure for these wrappers on this platform, or (b) a race where planemo attempted the invocation before the async toolbox reload/install-completion signal caught up. This phase did not have time/scope to distinguish (a) from (b); it is deliberately left as the concrete next-step question rather than guessed at."
      ],
      "artifacts": {
        "test_output_json": "planemo-test2-output.json",
        "test_output_html": "planemo-test2-output.html",
        "raw_log": "planemo-test2.log"
      },
      "next_reference_surface": "Galaxy's /api/tool_shed_repositories install-status API and the per-repository dependency-install logs (job_working_directory / conda build logs) for collapse_collections, kmindex, lexicmap, and collection_column_join on this host's osx-arm64 platform -- to determine whether the coreutils=8.25 (or similar) conda resolution genuinely failed for these wrappers versus a toolbox-reload timing race; galaxy-workflow-invocation-failure-reference.md's install/dependency guidance and the already-open feedback entry tool-util-cli-toolshed-fetch-rejects-real-filtered-list-collection-output are related but do not by themselves resolve this.",
      "known_preexisting_deferral": "This test case's lexicmap_index_selection is a documented placeholder (\"PhiX174E_J_Am3ToyIndex\", galaxy-test-plan.yml unresolved[0]/[1]); even if tool-install were resolved, this case was already expected by its own authors to fail/stall at lexicmap_search pending a real toy LexicMap index. That downstream gap was not reached this run because tool-install failed first."
    }
  ],
  "feedback": {
    "entries_appended": [
      "run-workflow-test-no-mechanism-to-install-authored-galaxyusertool-udts",
      "galaxy-tool-util-replacement-collection-requires-rows-key-unconditionally"
    ],
    "ledger_path": "foundry-feedback.ledger.yml"
  },
  "handoff_to_phase_12": {
    "recommended_focus_order": [
      "1. Decide whether to fix/work around galaxy-tool-util's replacement_collection 'rows' KeyError (blocks test case 1 from staging at all) -- this is the cheapest unblock and does not depend on tool installation.",
      "2. Resolve the UDT-installation gap: either author an XML lowering of the 3 GalaxyUserTool definitions for toolbox loading, or find/confirm a genuine Planemo/Galaxy mechanism for YAML-defined tools (none confirmed working in this run).",
      "3. Re-investigate why the 3 real Tool Shed tools also reported not-installed at invocation time on this host/platform -- rule out a conda dependency-resolution failure (coreutils=8.25 on osx-arm64) vs. a toolbox-reload race before concluding tool-install itself is broken.",
      "4. Only after 1-3, the still-open lexicmap_index_selection placeholder (test case 2) becomes the next real blocker."
    ]
  }
}

Obligations

what the workflow still owes

5 open, 13 resolved, 0 surrendered, 5 deliberately dropped. 0 open entries are blocking.

Topology repair: 1 escalation(s) against a cap of 5. Open blockers after each: 0.

chronaeon-hardcoded-statistics-phasesopendroppedfreeform-summary-to-galaxy-interface → still open
unmet
Genuine, re-executable recomputation of the statistics these phases report

The phases as written are reporting/munging of pre-baked numbers, not real computations

units
run_chronaeon_phix174_sieve.py Phases 2, 6, 7, 8 (e.g. the Gene D/E and Gene B/A Mann-Whitney medians/p-values, and a per-gene VEP correlation table)
because
freeform-summary Section 7, item 7 confirms these values appear as hardcoded constants written directly into the script, not recomputed from input data at run time

Only Phases 1/3/4 (the confirmed genuine hyphaeon autoclock/r0/meme CLI invocations) are modeled as real workflow steps in this brief. Phases 2/6/7/8 are excluded pending reimplementation as genuine pandas/scipy steps over live inputs.

chronaeon-synthetic-metadata-phase0opendroppedfreeform-summary-to-galaxy-interface → still open
unmet
A genuine collection-date-bearing input to the autoclock step

No real per-accession collection_date source was identified in this repo snapshot

units
run_chronaeon_phix174_sieve.py Phase 0 fabricated pseudo-collection_date construction feeding hyphaeon autoclock
because
freeform-summary Section 7, item 7 confirms by direct script inspection that Phase 0's collection_date values are hash-derived synthetic placeholders, not real SRA/BioSample metadata

This brief models autoclock's date-bearing metadata input as an open/external requirement (real SRA BioSample collection dates to be sourced) rather than porting the synthetic generator as if it were a genuine step.

host-biome-platform-stratification-script-gapopendroppedfreeform-summary-to-galaxy-interface → still open
unmet
A reproducible Galaxy step that recomputes the biome/platform stratification numbers

No discoverable tool or script to wrap for this stratification

units
Stage D host/biome/platform metadata stratification of the 2,114,904-accession Logan hit set (the paper's Fig 1B/C percentages)
because
freeform-summary Section 5 (Stage D) states no corresponding script was identified among the root-level .py files; likely produced via ad hoc NCBI Entrez/SRA-metadata queries or manual curation not captured in the repo snapshot

Not modeled as an executable workflow step in this brief; recorded as a labelled gap rather than invented as a fabricated step.

hyphaeon-toolshed-status-unverifiedopengapfreeform-summary-to-galaxy-interface → still open
unmet
Whether HyphAeon (github.com/veg/hyphaeon, CLI + Python package) and the companion hyphaeon_overlaps package are already Tool-Shed-wrapped, conda/pip-installable, or need to be authored from scratch as Galaxy tools

freeform-summary Section 7, item 3 flags this as unverified from the repo alone

This brief assumes new Galaxy tool wrappers will be authored for both packages; discover-shed-tool should check Tool Shed availability before author-galaxy-tool-wrapper is invoked for either.

wei-2026-dms-dataset-external-sourcingopengapfreeform-summary-to-galaxy-interface → still open
unmet
Concrete, fetchable source location for the Wei, Li & Lehner (2026) whole-genome DMS ground-truth table, a hard input dependency for Stages E/G/H/J

Dataset is not present in the repo; every downstream script expects it at a fixed local path (phix174_WGM/data/...zip) that does not exist in this checkout

Modeled in this brief as an external reference-data input (bioRxiv doi:10.64898/2026.07.25.740675 supplement / GitHub, exact download mechanism TBD). Must be resolved before test-data resolution phases can fixture it.

allow-frameshifts-default-unconfirmedresolvedgapfreeform-summary-to-galaxy-interfaceadvance-galaxy-draft-step
unmet
Production default of stream_lexicmap_msa.py's --allow-frameshifts flag

Source prose states the default/production setting could not be confirmed from prose alone

Exposed in this brief as an explicit boolean workflow parameter with no default asserted, rather than assuming reject-by-default. [freeform-summary-to-galaxy-data-flow] User-confirmed (2026-09-17): stream_lexicmap_msa.py's multi-HSP tiling/QC logic ("LexicMapStreamer") is not custom glue authored for this project from scratch -- it is backed by a real, existing implementation at https://github.com/nekrut/disassembler (private repo). The --allow-frameshifts production default is therefore expected to be readable directly from that repo's source, not an unrecoverable prose ambiguity. Still open (the value itself has not been read/confirmed) -- tracked as concrete follow-up work in the new lexicmapstreamer-wrapper-authoring-pending entry, to be resolved when that repo is inspected during wrapper authoring. [freeform-summary-to-galaxy-template, 2026-09-17] Carried into galaxy-workflow-draft.gxwf.yml as workflow input `tiling_qc_allow_frameshifts`: type boolean, `optional: true`, no `default:` -- a legal, non-TODO topology expression of "value genuinely unknown," distinct from a topology TODO. Still open. [advance-galaxy-draft-step, 2026-09-17] RESOLVED: the private repo https://github.com/nekrut/disassembler was cloned and python/lexicmap_streamer.py read directly. Its argparse declares `parser.add_argument("--allow-frameshifts", action="store_true", help=...)` with no `default=True` -- Python's argparse gives a bare `action="store_true"` flag an implicit default of `False`. Confirmed production default: OFF/False. The workflow input `tiling_qc_allow_frameshifts` remains `optional: true` with no asserted default at the workflow-input level (a user can still override per-run), but the wrapper itself (galaxy-user-tool.yml, tool_id `lexicmap_streamer`) now reflects the real tool's off-by-default semantics.

kmindex-hit-merge-no-corpus-precedentresolvedgapcompare-against-iwc-exemplarfreeform-summary-to-galaxy-template
unmet
A concrete Galaxy tool/idiom for N3's per-shard kmindex hit-map merge: dedup accessions across ~109 shard JSON files while keeping the max containment score per accession

IWC corpus (galaxyproject/iwc, cloned/pulled 2026-09-17, 115 workflows) has no workflow performing key-based dedup-with-max-score reduction over a list collection. The closest built-in idiom found, Collapse Collection (toolshed.g2.bx.psu.edu/repos/nml/collapse_collections/collapse_dataset, used in microbiome/mags-building/MAGs-generation.ga steps 21-22 and microbiome/metagenomic-genes-catalogue.ga), performs plain concatenation of a list collection into one dataset with no per-key reduction -- it could serve as a first pass (concatenate, then a custom sort/dedup script) but does not implement the max-score-keeping semantics itself.

Was carried only as prose in freeform-galaxy-data-flow.md section 4 item 1, never previously promoted to this ledger. Promoted here per compare-against-iwc-exemplar's mandate to record structural divergences with no corpus precedent. Template phase should plan a small custom aggregation step (e.g. a Python/pandas tool) fed by Collapse Collection's concatenated output, rather than expect a single built-in tool to do both. [freeform-summary-to-galaxy-template, 2026-09-17] Resolved: galaxy-workflow-draft.gxwf.yml wires this as two concrete steps -- `kmindex_hit_concat` (Identity-pinned, nml/collapse_collections/collapse_dataset) followed by `kmindex_hit_dedup_max_score` (Deferred, tool_id TODO, _plan_state documents the dedup+max-score reduction). No blocking gap remains; the custom step's wrapper identity is left open for discover-shed-tool / author-galaxy-tool-wrapper, which is an ordinary Deferred-tier obligation, not an unmet topology need. [advance-galaxy-draft-step, 2026-09-17] Wrapper identity now settled: discover-shed-tool re-confirmed the miss (datamash groupby/max rejected -- tabular/pre-sorted input only, cannot parse JSON); author-galaxy-tool-wrapper produced galaxy-user-tool-kmindex-hit-dedup-max-score.yml (GalaxyUserTool, id kmindex_hit_dedup_max_score, version 1.0.0). kmindex_hit_dedup_max_score is now fully concrete in the draft (tool_id/tool_version mirror the UDT identity, ports concatenated_hits/accession_union). No blocking entry raised -- the step's single wired input (kmindex_hit_concat/output) is sufficient to compute its declared output.

kmindex-lexicmap-index-selection-mechanismresolvedgapfreeform-summary-to-galaxy-interface → Live verification against usegalaxy.org, 2026-09-18. Both `db_opts|kmindex` (kmindex_query 0.6.1+galaxy4) and `db_opts|lexicmap_index` (lexicmap_search 0.9.0+galaxy1) are `type: select, multiple: true` (tool io_details API). A comma-delimited string is REJECTED at parameter validation -- POSTing db_opts|kmindex="GENOMIC_PHG,GENOMIC_VRL" returns "Parameter 'kmindex': an invalid option ('GENOMIC_PHG,GENOMIC_VRL') was selected", because a multi-select reads the whole string as ONE option value. The JSON array ["GENOMIC_PHG","GENOMIC_VRL"] is accepted and fans out correctly: job bbd44e69cb8906b5eadd64618b449770 in history bbd44e69cb8906b57012ea23efccb56e completed with 32 GENOMIC_PHG + 33 GENOMIC_VRL result datasets. Since a gxformat2 `text` workflow input cannot carry an array, the delimited-string modeling this entry assumed is unusable: the `kmindex_db_selection` and `lexicmap_index_selection` text inputs were REMOVED and the 109 shard names / 5 TARGETED_PHAGE_INDICES are now literal lists in the kmindex_containment_screen and lexicmap_search step state. Trade-off accepted: index sets are no longer settable at invocation time and require editing the workflow.
unmet
How the 109 kmindex Logan DB shards and the 25 LexicMap domain indices (5-index TARGETED_PHAGE_INDICES subset for per-gene runs) should be exposed as Galaxy tool/workflow-level inputs

The freeform-summary only records the DB/index names as hardcoded Python lists (ALL_KMINDEX_DBS, TARGETED_PHAGE_INDICES); the real kmindex_query/lexicmap_search Tool Shed wrapper's parameter schema has not yet been inspected (summarize-galaxy-tool has not run)

This brief models index selection as a controlled-vocabulary select/multi-select parameter carrying the known DB/index name lists. Must be reconciled against the actual tool XML during implement-galaxy-tool-step / discover-shed-tool. [freeform-summary-to-galaxy-data-flow, Workflow A only] Cross-checked against the newly confirmed LexicMapStreamer provenance (see lexicmapstreamer-implementation-provenance): the nekrut/disassembler repo implements the multi-HSP tiling/QC client, not the kmindex_query/lexicmap_search Tool Shed wrappers' own DB/index parameter schema, so that discovery does not bear on this entry. Still open pending inspection of the pinned IUC changesets themselves (kmindex_query 0.6.1+galaxy4, lexicmap_search 0.9.0+galaxy1). [compare-against-iwc-exemplar, 2026-09-17] Corpus check (galaxyproject/iwc, 115 workflows) found no workflow exposing a >20-way controlled-vocabulary shard/index select as a workflow input or map-over axis -- the largest comparable case, data-fetching/parallel-accession-download's split_file_to_collection, dynamically chunks an arbitrary-length input file rather than enumerating a fixed named list, a different mechanism. No corpus precedent to draw on; still open, unchanged. [freeform-summary-to-galaxy-template, 2026-09-17] Topology settled `kmindex_db_selection` (N2) and `lexicmap_index_selection` (N4) as plain multi-value `text` workflow inputs consumed entirely inside each tool's own call -- kmindex_containment_screen's declared output is a `list` collection (one element per selected shard) and lexicmap_search's declared output is a `list:list` collection (gene outer axis from the real sample_sheet map-over, index inner axis from the tool's own per-index output declaration), rather than modeling either selection as a second Galaxy-level map-over collection. This is a topology commitment (see galaxy-workflow-draft.gxwf.yml steps kmindex_containment_screen / lexicmap_search); the exact tool-side input widget realizing it is still open and unchanged by this note. [advance-galaxy-draft-step, 2026-09-17] REFUTED in part: summarize-galaxy-tool on the pinned changeset (iuc/lexicmap/lexicmap_search 0.9.0+galaxy1, bcb6caec41eb) shows the wrapper's `parsed_tool` declares exactly one output, `out_file` (plain `data`, format `tabular`) -- no `discover_datasets`, no per-index collection output. There is no 'tool's own per-index output declaration'; that specific claim above is struck. `lexicmap_index` (case `db_opts_selector: db`, 'Locally installed LexicMap indexes') is a `gx_select` with `multiple: true` and dynamic `options: null` -- a single job accepts the full multi-value index selection and returns one aggregate hits table, so lexicmap_search's real per-gene output shape (mapped over `gene_query_panel`) is a flat `list`, not `list:list`. The kmindex/lexicmap side of the index-selection-mechanism question (delimited-text -> multi-select binding; dynamic option population) remains open and unchanged. The invalidated inner-axis/list:list claim's downstream consequence (flatten_lexicmap_results_by_gene's `__FLATTEN__` step assumed a nested input) is tracked separately as blocking entry `lexicmap-search-flatten-shape-mismatch`, superseded by this note. [advance-galaxy-draft-step, 2026-09-17] kmindex side CONFIRMED by direct XML inspection: galaxy-tool-cache add/summarize cannot parse the pinned iuc/kmindex/kmindex_query changeset (0.6.1+galaxy4, b6fa25b6b436) or any other galaxy-suffixed version -- a reproducible cache/parser defect (see galaxy-tool-summary.json warnings[] and the feedback ledger) -- so the wrapper's real upstream XML was read directly (tools-iuc commit 7681be7f40, confirmed via the Tool Shed API's remote_repository_url for this exact changeset) in place of the normal automated summarize-galaxy-tool path. Result: `db_opts|kmindex` (case `db_opts_selector: db`) is a `gx_select` with `multiple: true`, dynamic `options: null` (populated from the `kmindex` Tool Shed data table) -- the same shape as lexicmap_index, confirming this is a native Galaxy multi-select in both wrappers, not a repeat or per-element data input. The command template loops over indices internally (`#for $i, $INDEX in enumerate($INDICES)` on `$db_opts.kmindex.fields.path.split(',')`) and the `output` collection output (`list`, discover_datasets over `query_output/*.json`) fans out to one JSON element per selected shard -- matching the already-settled topology commitment exactly, no scatter/map-over needed. kmindex_containment_screen implemented on this basis this iteration. Still open and non-blocking: whether the scalar `kmindex_db_selection` `text` workflow input's delimited-string value is accepted as-is by a `multiple: true` select at runtime, or needs adaptation to a literal array -- this is a runtime parameter-shape question, not a topology gap, and does not block draft-validate.

lexicmap-search-flatten-shape-mismatchresolvedblockinggapadvance-galaxy-draft-steprepair-galaxy-draft-topology
unmet
flatten_lexicmap_results_by_gene's declared behavior (__FLATTEN__, collapse a gene x index list:list down to a gene-keyed list, per its own doc and the microbiome/mags-building/MAGs-generation.ga __FLATTEN__ precedent it cites) requires a nested list:list input

lexicmap_search's real, pinned Tool Shed wrapper (iuc/lexicmap/lexicmap_search 0.9.0+galaxy1, changeset bcb6caec41eb, confirmed via discover-shed-tool + summarize-galaxy-tool this iteration) declares exactly one output, `out_file` (plain `data`, format `tabular`; no `discover_datasets`, no per-index/collection output). Index selection (`lexicmap_index_selection`) is bound as an in-tool-call multi-select value, not a second Galaxy-level map-over axis (per the already-settled topology commitment in ledger entry `kmindex-lexicmap-index-selection-mechanism`). Mapped over the single `gene_query_panel` axis, lexicmap_search's real output is therefore a flat `list` (one aggregate hits table per gene) -- there is no index axis for `__FLATTEN__` to collapse. draft-validate --concrete already surfaces the immediate symptom: `flatten_lexicmap_results_by_gene: step input "input" source "lexicmap_search/TODO_lexicmap_hits_nested" references unknown port" (the port was renamed to the wrapper's real `out_file` while implementing lexicmap_search this iteration); fixing only the reference would silently paper over the deeper shape mismatch.

Raised by advance-galaxy-draft-step (2026-09-17) while implementing lexicmap_search: confirming the real wrapper's output shape refuted the 'tool's own per-index output declaration' claim `kmindex-lexicmap-index-selection-mechanism`'s template-phase note rested on (see that entry's superseding note, same date). lexicmap_search's own step is fully concrete and correct; this entry blocked only on flatten_lexicmap_results_by_gene, which was authored as Resolved against the now-refuted list:list assumption. [repair-galaxy-draft-topology, 2026-09-17] Resolved by narrowing, not by inserting a producer: removed the now-unnecessary `flatten_lexicmap_results_by_gene` (`__FLATTEN__`) step entirely and rewired its sole consumer, `lexicmap_streamer_tiling_qc`'s `TODO_lexicmap_results` port, directly onto `lexicmap_search/out_file`. That real output already carries the exact shape (`list`, 10 elements, gene-keyed) lexicmap_streamer_tiling_qc's own doc says it expects -- no substitute producer was needed, so this is a clean bounded repair, not a workaround. Confirmed no other step or workflow output referenced `flatten_lexicmap_results_by_gene`.

lexicmapstreamer-implementation-provenanceresolvedgapfreeform-summary-to-galaxy-data-flowfreeform-summary-to-galaxy-data-flow
unmet
Whether stream_lexicmap_msa.py's multi-HSP coordinate tiling / codon QC / haplotype-collapsing logic (the user's "LexicMapStreamer") has any existing implementation to wrap, or must be authored as new Galaxy tool code from scratch

freeform-summary's tool inventory (Section 5, 'Custom/internal orchestration code') characterized stream_lexicmap_msa.py as code with no separate installable tool

User-confirmed (2026-09-17): LexicMapStreamer already exists as a real, working implementation in the private repository https://github.com/nekrut/disassembler -- this is the actual code behind stream_lexicmap_msa.py's multi-HSP tiling/QC logic, not something to author from scratch by reverse-engineering the summary's prose. This does not itself discharge the wrapper-authoring obligation -- see lexicmapstreamer-wrapper-authoring-pending for the remaining open work.

lexicmapstreamer-wrapper-authoring-pendingresolvedgapfreeform-summary-to-galaxy-data-flowadvance-galaxy-draft-step
unmet
A Galaxy tool wrapper (XML + macros, or a Planemo-testable CLI wrapper) for LexicMapStreamer's multi-HSP tiling/QC/haplotype-collapsing step (Workflow A, node N5)

No Tool Shed wrapper is known to exist yet; the real implementation lives in the private repo https://github.com/nekrut/disassembler and its CLI/API surface, install method, and license have not been inspected in this run

Not a from-scratch authoring problem (see lexicmapstreamer-implementation-provenance) -- discover-shed-tool should first check whether a wrapper already exists for this repo; if not, author-galaxy-tool-wrapper should target the disassembler repo's actual CLI/API rather than reverse-engineering behavior from stream_lexicmap_msa.py prose alone. The --allow-frameshifts default (see allow-frameshifts-default-unconfirmed) and the exact shape of N5's 8 per-gene output artifacts (see freeform-galaxy-data-flow.md §2, node N5) should both be confirmed by reading this repo's source during that authoring pass. [compare-against-iwc-exemplar, 2026-09-17] Corpus search for kmindex/lexicmap/comparable multi-HSP-tiling or haplotype-calling tools returned zero hits across the full IWC corpus -- confirms no shortcut via an existing IWC-adjacent wrapper; the nekrut/disassembler-backed wrapper-authoring path remains the only route. Still open, unchanged. [freeform-summary-to-galaxy-template, 2026-09-17] Topology settled: `lexicmap_streamer_tiling_qc` in galaxy-workflow-draft.gxwf.yml declares all 8 output ports concretely (see n5-output-collection-shape-no-record-precedent, resolved) and is mapped one call per gene. Still open on wrapper identity/authoring; also now the anchor for the am3-diagnostic-granularity question raised in n7-am3-diagnostic-granularity-unconfirmed, since that question turns on the same repo's summary.json / flagged.tsv schema. [advance-galaxy-draft-step, 2026-09-17] RESOLVED: discover-shed-tool re-confirmed the miss this iteration (3 query variants, 0 hits; galaxy-tool-pin.json). https://github.com/nekrut/disassembler was cloned (git clone succeeded; the repo, while described by the user as private, was accessible with this environment's ambient `gh`/git credentials -- no access blocker encountered). python/lexicmap_streamer.py (817 lines) was read directly: pure Python 3 stdlib, no third-party imports; full argparse CLI confirmed (see galaxy-user-tool.yml for the complete flag table). author-galaxy-tool-wrapper produced galaxy-user-tool.yml: `GalaxyUserTool` id `lexicmap_streamer`, version `1.0.0`, container `python:3.13-slim`, the script vendored verbatim (MIT license, (c) Anton Nekrutenko, commit a51eb58) as a `configfiles` entry. All 8 of N5's declared output ports map 1:1 onto the script's real fixed-suffix output files (`.clean.msa.fasta`, `.clean.haplotypes.tsv`, `.clean.accessions.fasta`, `.clean_expanded.accessions.fasta`, `.flagged.accessions.fasta`, `.flagged.tsv`, `.cohort_ledger.tsv`, `.summary.json`) -- no invented outputs, no port left unresolved; `--no-a2m` passed to suppress the one script output (`.a2m`) with no corresponding declared port. galaxy-workflow-draft.gxwf.yml's `lexicmap_streamer_tiling_qc` step now carries this concrete `tool_id`/`tool_version`/`in`/`state`/`out`. CORRECTION surfaced by this reading: the step's `_plan_in` (single semantic port) undercounted the real input surface -- the script requires the per-gene reference CDS FASTA (`-q/--ref`) in addition to the LexicMap hit table; wired to `gene_query_panel`, the same collection `lexicmap_search` already consumes, so no new workflow input or topology change was needed, just an added `in:` entry. `gxwf draft-validate --concrete` returns `draft valid` / `Concrete: OK` on the mutated draft (this step's tool_id resolves to a `skip_tool_not_found` Tool Shed-lookup skip, exactly like the pre-existing kmindex_query skip, not a hard failure).

n5-output-collection-shape-no-record-precedentresolvedgapcompare-against-iwc-exemplarfreeform-summary-to-galaxy-template
unmet
Whether LexicMapStreamer's 8 per-gene output artifacts should be modeled as one sample_sheet:record (named-slot) collection, or as multiple parallel sample_sheet/list collections sharing the gene element_identifier

IWC corpus (115 workflows, galaxyproject/iwc, checked 2026-09-17) contains zero workflows using a record/named-slot collection type (grep -rl 'collection_type.*record' *.ga = 0 hits). The corpus's established idiom for a per-element multi-artifact tool step is N separate parallel list/sample_sheet collections that share the same element_identifier and are recombined post hoc (e.g. via collection_column_join or __FLATTEN__) -- observed directly in microbiome/mags-building/MAGs-generation.ga, where per-sample assembly/binning/QC outputs ride as several parallel collections, not one named-slot collection.

Does not resolve freeform-galaxy-data-flow.md section 2 N5's open design recommendation (sample_sheet:record vs. 8 parallel collections) -- it is negative corpus evidence against the record-shaped option. Template phase should default to the corpus-precedented 8-parallel-collections-sharing-element_identifier shape unless a specific reason favors the record shape, since the record shape has no IWC exemplar to validate test/lint conventions against. [freeform-summary-to-galaxy-template, 2026-09-17] Resolved: galaxy-workflow-draft.gxwf.yml's `lexicmap_streamer_tiling_qc` step declares 8 named output ports (TODO_clean_msa_fasta, TODO_clean_haplotypes_tsv, TODO_clean_accessions_fasta, TODO_clean_expanded_accessions_fasta, TODO_flagged_accessions_fasta, TODO_flagged_tsv, TODO_cohort_ledger_tsv, TODO_summary_json), each an independent gene-keyed collection sharing the gene `element_identifier`, per this entry's recommendation -- not a `sample_sheet:record`. Topology decision made; only the wrapper's real port names remain TODO.

n6-json-flatten-no-corpus-precedentresolvedgapcompare-against-iwc-exemplarfreeform-summary-to-galaxy-template
unmet
A Galaxy tool/idiom to flatten each gene's nested .summary.json (N5 output) into one manifest row before concatenation into Ingestion manifest (all genes)

IWC corpus has a real, directly relevant built-in tool for the tabular half of this bridge -- collection_column_join (toolshed.g2.bx.psu.edu/repos/iuc/collection_column_join/collection_column_join/0.0.3, used in MAGs-generation.ga steps 66-67 and metagenomic-genes-catalogue.ga) joins a list collection of per-element tabular files by an identifier column into one combined table. No corpus workflow performs the JSON-to-tabular-row flattening half; every per-sample tabular input to collection_column_join in the corpus is already tabular going in (e.g. CoverM/Quast/CheckM2 reports), never raw JSON.

Confirms freeform-galaxy-data-flow.md section 4 item 5's claim ('no generic Galaxy tool flattens an arbitrary nested per-gene JSON into one manifest row') is correct for the flatten step, but narrows the remaining gap: only a small per-gene JSON-to-TSV-row flattening tool (jq/python) needs to be authored; the subsequent collection-to-table join can reuse the real, named collection_column_join Tool Shed tool rather than a bespoke merge. [freeform-summary-to-galaxy-template, 2026-09-17] Resolved: galaxy-workflow-draft.gxwf.yml wires this as two concrete steps -- `flatten_gene_summary_json_to_row` (Deferred, tool_id TODO, mapped over the gene collection) followed by `join_gene_summary_rows_into_manifest` (Identity-pinned, iuc/collection_column_join/collection_column_join/0.0.3). No blocking gap remains. [advance-galaxy-draft-step, 2026-09-17] Deferred obligation discharged: `gxwf tool-search "json to tabular"` found only generic JSON tools (best hit `iuc/jq`, confirmed installable via galaxy-tool-cache add/summarize, changeset 4e62e523c2b6) -- rejected because its `filter`/`arguments` parameters cannot read the mapped input's Galaxy `element_identifier` without an extra `collection_element_identifiers`-style producer step and port, which would be an avoidable topology change. Authored a small GalaxyUserTool instead (`galaxy-user-tool-flatten-gene-summary.yml`, id `flatten_gene_summary_json_to_row`, version `1.0.0`, pure Python 3 stdlib, container `python:3.13-slim`) whose `shell_command` reads `$(inputs.summary_json.element_identifier)` directly -- confirmed valid against the installed `@galaxy-tool-util/schema` package's `gx-data.js` (`job_runtime` File-object shape declares `element_identifier: S.optional(S.String)` alongside `path`; also flagged as an authoring-note documentation gap in the feedback ledger, entry `galaxy-user-tool-authoring-missing-element-identifier-expression`). Output is a two-line TSV (header + one data row), first column `gene` = element_identifier, remaining columns the flat scalar fields of summary.json (regime diagnostics, cohort-breakdown counts, multi-HSP recovery counts, coverage/pident quantiles), read directly from this run's own vendored lexicmap_streamer.py rather than reverse-engineered from prose. `gxwf validate-tool-source galaxy-user-tool-flatten-gene-summary.yml` returns `OK`; `gxwf draft-validate --concrete galaxy-workflow-draft.gxwf.yml` returns `draft valid` / `Concrete: OK` on the mutated draft. join_gene_summary_rows_into_manifest's stale `in:` reference to this step's placeholder port was updated to the real `summary_row` port name (same-step reference fix, not a topology repair; see that step's own `_plan_state`).

n7-am3-diagnostic-granularity-unconfirmedresolvedgapfreeform-summary-to-galaxy-templateadvance-galaxy-draft-step
unmet
Whether N5's (lexicmap_streamer_tiling_qc's) per-gene summary.json / flagged.tsv actually carries locus-specific detail (genome position nt587, G->A, codon 7 TGG->TAG) sufficient to reconstruct the paper's '2,215,172/2,392,457 (92.59%) of evaluated Gene E accessions carry this substitution' statistic, as opposed to only an aggregate premature-internal-stop count

freeform-summary.md describes stream_lexicmap_msa.py's QC step as flagging premature internal stop codons generally (via codon-table translation) and describes summary.json as carrying 'quantile distributions, regime diagnostics, multi-HSP recovery counts' -- it does not explicitly confirm the summary.json (or flagged.tsv) schema records the specific substituted nucleotide/codon per flagged accession, only that a stop was found

Not treated as blocking: the underlying computation (per-accession codon-level translation and stop-codon detection) is plausibly already granular enough, since stream_lexicmap_msa.py must inspect individual codons to flag a stop at all -- the open question is only whether that per-accession locus detail is surfaced into N5's declared outputs (summary.json / flagged.tsv) or needs an additional field. To be confirmed during the same nekrut/disassembler wrapper-authoring pass tracked by lexicmapstreamer-wrapper-authoring-pending; if the real repo's outputs do not carry this detail, author-galaxy-tool-wrapper / implement-galaxy-tool-step should add it as a wrapper-level enhancement rather than escalate a topology repair, since the wiring (N7 reads N5's per-gene summary output) remains correct either way. [advance-galaxy-draft-step, 2026-09-17] PARTIALLY CONFIRMED, still open, still non-blocking, but the concern sharpens rather than dissolves: python/lexicmap_streamer.py was read directly. `summary.json` (`summary_data` dict) carries only aggregate quantiles/cohort counts/Shannon entropy plus a `top_10_haplotypes` preview limited to the CLEAN FULL-LENGTH cohort (ranked by count, with `aa_mutations`/`nt_mutations` string fields like `W7*` / `587G>A` that DO encode exact codon/nt position when present) -- it carries no per-accession stop-codon locus list. The literal per-accession, 1-based codon-position detail (`stop_codons` column, e.g. "2,15") lives in `flagged.tsv` and `cohort_ledger.tsv`, which N5 also emits as separate declared output ports (`flagged_tsv`, `cohort_ledger_tsv`) but which N7 (`extract_gene_e_am3_audit`, per n7-gene-e-audit-source-resolved) does NOT read -- N7 is wired only to `summary_json`. Since am3 is specifically a PREMATURE STOP mutant, an am3-carrying accession is by construction routed to the FLAGGED cohort (not the CLEAN top_10_haplotypes preview), so summary.json's per-haplotype mutation strings will not surface it either. Net: if the Gene E am3 quarantine audit needs the exact per-accession locus (not just the aggregate `flagged_premature_stops` count that summary.json does carry), N7 is reading the wrong port -- it should read `flagged_tsv` (or `cohort_ledger_tsv`) instead of/in addition to `summary_json`. Left open and non-blocking per this entry's own standing guidance (a topology question for the template tier, out of scope for this single-step iteration, which was scoped to lexicmap_streamer_tiling_qc only) rather than escalated to repair-galaxy-draft-topology on this pass. [advance-galaxy-draft-step, 2026-09-17] RESOLVED while implementing extract_gene_e_am3_audit itself: re-read python/lexicmap_streamer.py (same commit a51eb58d6c1ca941d3fb8d6adf5e8160c3926b91) and re-confirmed the above analysis line-by-line (process_accession_block lines 400-480; flagged.tsv header/rows at lines 365/471/478; cohort_ledger.tsv header/rows at lines 366/480; summary.json construction at lines 599-730). Rewired extract_gene_e_am3_audit's `in:` from `lexicmap_streamer_tiling_qc/summary_json` to `lexicmap_streamer_tiling_qc/flagged_tsv` -- flagged_tsv is the smallest N5 output already filtered to the anomalous/quarantine cohort and already carrying a per-accession `stop_codons` (codon-position) column, which is exactly the per-accession, locus-specific detail this audit needs, whereas cohort_ledger_tsv is an unfiltered superset requiring the consumer to filter by flag itself. This was a same-step port correction (N7 still reads N5, just the correct one of its 8 already-declared output ports), not a topology repair -- no producer node was inserted or removed, so repair-galaxy-draft-topology was not invoked. One residual, explicitly non-blocking limitation remains: neither flagged.tsv nor cohort_ledger.tsv records the literal nucleotide-substitution letters (only the codon index), so reconstructing the paper's exact 'nt587 G->A' phrasing still requires cross-referencing the reference sequence -- this does not affect the correctness of this step's own job (extracting the Gene E element), only a downstream reporting nicety.

n7-gene-e-audit-source-resolvedresolvedgapfreeform-summary-to-galaxy-data-flowfreeform-summary-to-galaxy-template
unmet
Whether N7's Gene E am3 quarantine audit is literally the Gene E element of N5's (lexicmap_streamer_tiling_qc's) per-gene summary.json sample_sheet, or a ninth, separate per-gene artifact N5 also emits

freeform-galaxy-data-flow.md §2 N5/N7 and §7 item 3 left this open, resolvable only once the nekrut/disassembler-backed wrapper's real output surface is known

TOPOLOGY DECISION (this Mold must never leave a topology choice as TODO): modeled N7 as an EXTRACTION of the Gene E element of N5's summary.json collection (collection-unbox-singleton / __EXTRACT_DATASET__ by element_identifier == "E"), not a distinct ninth artifact. Rationale: freeform-summary.md Stage D2 states the am3 detection logic 'lives inside the QC step of stream_lexicmap_msa.py' (i.e. inside N5) and is only 'summarized in results/02_layer1_quasispecies/gene_e_am3_quarantine_audit.json' -- a path under ChronAeon Phase 2 (freeform-summary.md Stage I), a stage this run's scope decision (workflow-scope-boundary-unresolved) places out of scope for Workflow A, and which freeform-summary.md §7 item 7 / chronaeon-synthetic-metadata-phase0 / chronaeon-hardcoded-statistics-phases flag as partly fabricated-metadata / hardcoded-statistics rather than a reliable recomputation path. Treating N7 as a literal extraction of N5's own Gene E output avoids manufacturing a dependency on that unreliable, out-of-scope stage, and matches the source's own statement that the detection is internal to N5's QC rather than a separate computation. See galaxy-workflow-draft.gxwf.yml step `extract_gene_e_am3_audit`'s `_plan_state` for the full reasoning as carried in the draft itself. This resolution carries one caveat, tracked separately: n7-am3-diagnostic-granularity-unconfirmed.

nominal-taxonomy-audit-not-modeled-as-stepresolveddroppedfreeform-summary-to-galaxy-interfacefreeform-summary-to-galaxy-template
unmet
N/A — not intended as an executable Galaxy step

No tool; this is curated reference/provenance data, not a computation

units
Stage D nominal-taxonomy SRA metadata audit (136 runs / 18 BioProjects, manual classification into Experimental Evolution / Platform Benchmarking / Paleogenomics Control / etc.), including the candidate `Nominal-taxonomy BioProject classification table` declared workflow input
because
Source describes this as a manual/registry-based certification exercise, not a computational tool invocation over data the workflow would produce

Modeled in this brief as a static reference-data input (a BioProject classification table) rather than a workflow step. Downstream data-flow phase should confirm this framing. [freeform-summary-to-galaxy-data-flow, 2026-09-17] Confirmed: no Workflow A node (N1-N7) consumes this table; carried forward as an open framing question (data-flow brief section 7, item 2) rather than dropped outright. [freeform-summary-to-galaxy-template, 2026-09-17] Resolved: the settled N1-N7 topology has no node wired to this table, and per the data-flow brief's own suggestion ("an unconnected input is unusual for a runnable workflow ... consider dropping it"), this Mold drops it from galaxy-workflow-draft.gxwf.yml's declared workflow inputs entirely. It remains documentation/provenance context (see this workflow draft's top-level `doc:`), not a Galaxy input or step.

reference-genome-workflow-input-droppedresolveddroppedfreeform-summary-to-galaxy-templatefreeform-summary-to-galaxy-template
unmet
N/A -- not a computational dependency of any Workflow A step

No node in Workflow A reads the whole-genome FASTA

units
`Reference genome (NC_001422.1)` as a declared Workflow A workflow-level input
because
The settled N1-N7 topology (galaxy-workflow-draft.gxwf.yml) has no node that consumes the whole-genome FASTA -- only the per-gene CDS FASTAs in `gene_query_panel` are used by N1 (combine) and N4 (LexicMap search), matching freeform-summary.md's own language about the 'canonical ΦX174 gene coordinate frame.' freeform-galaxy-data-flow.md §1 and §7 item 1 already flagged this input as unwired and recommended dropping it from Workflow A's declared inputs if the template phase found no consumer, which is what this Mold confirmed.

Dropped from galaxy-workflow-draft.gxwf.yml's declared `inputs:`; recorded in the draft's top-level `doc:` for provenance. This input may belong to Workflow B (Stage E), where `NC_001422.1:2395-2919` is genuinely used for bowtie2/samtools alignment -- out of scope for this run.

workflow-scope-boundary-unresolvedresolvedgapfreeform-summary-to-galaxy-interfacefreeform-summary-to-galaxy-data-flow
unmet
Whether the target Galaxy workflow covers only Stages A-D2 (SRA landscape / spike-in sieve, the only content currently in draft_manuscript.tex) or the full Stage A-K project pipeline (through HyphAeon VEP benchmarking, dual-coding shadow-effect calibration, and Fane-mechanics synthesis)

The source freeform-summary explicitly leaves this scoping question open (its Section 7, item 1) rather than resolving it

User-confirmed scope decision (2026-09-17): this pipeline run builds only Workflow A (SRA landscape/spike-in sieve, Stages A/B/C/D2) as a single Galaxy workflow. Workflow B (Stage E, experimental-evolution validation, bowtie2/samtools/mpileup) is a confirmed nice-to-have the user wants built as a separate, later workflow -- out of scope for this run, not abandoned. Workflows C and D (Stages C'/F/G/H and Stage I) are out of scope for this run's data-flow design entirely. This brief modeled the full A-K pipeline shape as labeled stages/candidate subworkflows so nothing was silently dropped before this decision; that record is preserved above for provenance.

Foundry feedback

what the run showed to be wrong with the Foundry

25 entries about the Foundry's own assets. Triage them with the report-foundry-run-feedback skill rather than filing from here.

author-galaxy-tool-wrapper-no-check-of-wrapped-scripts-own-declared-input-ordering-assumptionmajorgapauthor-galaxy-tool-wrapper

This is NOT a report of a bug in the wrapped script itself (that lived entirely in the user's own private nekrut/disassembler repository and was fixed there directly, with a patch prepared for the user's own separate upstream review -- out of scope for this ledger). The Foundry-relevant gap is in the authoring process: author-galaxy-tool-wrapper wrapped `lexicmap_streamer.py` as the `lexicmap_streamer` GalaxyUserTool without ever checking whether the script's own explicit, self-declared input-ordering assumption actually holds for the real upstream Galaxy tool this step would be wired to consume from in the concrete workflow. The vendored script's own code comment stated the assumption outright ('the stream is grouped by accession one block at a time, so all of an accession's HSPs must be contiguous... detect a reappearance and stop') -- a directly inspectable, static signal that this script's correctness depends on a specific ordering property of its input. Nothing in author-galaxy-tool-wrapper's packaged authoring/review process prompts for cross-checking a wrapped script's own declared input-shape assumptions against the actual, real output ordering of the specific upstream Tool Shed tool (`iuc/lexicmap/lexicmap_search`) it is wired to consume from later in the same workflow (implement-galaxy-tool-step's job, but with no input from authoring about what to check). The gap was only caught because a live, real, production-scale invocation happened to exercise it -- run-workflow-test's own synthetic 3-decoy fixture never could have, since a 3-element fixture is trivially 'grouped' by construction regardless of the bug.

expected
author-galaxy-tool-wrapper's review/authoring procedure should add an explicit check step: when a wrapped script's own source/docstring/comments assert an assumption about the shape, ordering, or grouping of its input data (a `sort`/`group`/`contiguous`/'assumes' style comment is a strong, mechanically-greppable signal), the authoring pass should either (a) verify that assumption against the real, documented output-ordering behavior of the specific upstream tool the step will actually be wired to (not just against a hand-built test fixture that can't exercise the failure mode), or (b) explicitly flag the assumption as an open, unverified risk in the step's `doc:`/ledger for a later phase (e.g. run-workflow-test or a dedicated real-data smoke test) to confirm before the workflow is treated as production-ready. A synthetic fixture alone -- however carefully constructed -- cannot substitute for this check when the fixture is, by construction, too small to violate the assumption being tested.
evidence
draft-manuscript-galaxy. `lexicmap_streamer.py`'s own committed comment (vendored verbatim into galaxy-user-tool.yml's configfiles entry at authoring time) explicitly named the exact risk that later caused two live job failures on real usegalaxy.org production data (invocation 802eff260023dc62, both lexicmap_streamer_tiling_qc jobs) against the real, correctly-functioning `iuc/lexicmap/lexicmap_search` 0.9.0+galaxy1 output (confirmed via direct byte-range inspection: real LexicMap search output is ranked by match quality across all matched genomes, not grouped by target accession -- the assumption was false for this specific real upstream tool from the start). The 3-decoy synthetic fixture used at test-authoring time (test-data/synthetic_am3/*.tsv) could not have surfaced this: a 3-row/3-accession fixture cannot exhibit a 'reappearing accession' pattern by construction, regardless of whether the underlying assumption holds for real data.
raised by
debug-galaxy-workflow-output (phase 12)
observed at
issue
https://github.com/galaxyproject/foundry/issues/590
ga-download-normalizes-tool-id-producing-workflows-that-save-but-cannot-invokemajordefectgalaxy-workflow-invocation-failure-reference

`GET /api/workflows/{id}/download?style=ga` emits each Tool Shed step's `tool_id` as the UNVERSIONED repository path (`toolshed.g2.bx.psu.edu/repos/iuc/kmindex/kmindex_query`) with the version carried separately in `tool_version`. Re-importing that exact document -- the download/edit/upload round trip that any external deploy script performs -- produces a workflow that SAVES successfully, shows `errors: null` on every step via `GET /api/workflows/{id}?legacy=false`, and lints clean, but CANNOT be invoked: `POST /api/workflows/{id}/invocations` returns HTTP 400 `Workflow was not invoked; the following required tools are not installed: <tool> (version <v>)` naming tools that are installed at exactly that id and version. Setting `tool_id` to the full VERSIONED path (`.../kmindex_query/0.6.1+galaxy4`) with no other change makes the same workflow invoke immediately. The round trip is therefore lossy in a way that is invisible until invocation: the format the server hands you back is not a format the server will accept for execution. This is distinct from the existing entry `galaxy-workflow-invocation-check-rejects-previously-installed-tool-as-not-installed`, which describes a STALE-TOOLBOX-READ race under planemo with a reload-timing signature; this defect is deterministic, has no timing component, and reproduces on demand against a long-warm production toolbox.

expected
(1) `POST /api/workflows/{id}/invocations` should resolve an unversioned `tool_id` together with the step's own `tool_version` field, exactly as the save path and the editor already do -- or, failing that, the error should say the id is unversioned rather than claiming an installed tool is not installed, which routes debugging toward tool installation instead of toward id formatting. (2) `download?style=ga` should round-trip losslessly: either emit the versioned id, or the invocation check should accept what the download emits. As it stands, the documented way to fetch a workflow produces a document that silently loses executability.
evidence
draft-manuscript-galaxy, paper-scale rerun setup, 2026-09-18. ISOLATED on a purpose-built 1-step probe workflow (single `tp_cat` step, plain `POST /api/workflows` body `{"workflow": ...}` with NO `exact_tools`/`allow_missing_tools` keys, so those flags are excluded as a cause): `tool_id: .../text_processing/tp_cat` + `tool_version: 9.11+galaxy0` -> invocation 400 `required tools are not installed: .../tp_cat (version 9.11+galaxy0)`; changing ONLY `tool_id` to `.../text_processing/tp_cat/9.11+galaxy0` -> invocation scheduled, jobs ran to `ok`. CORROBORATED on the real workflow 575e9ee747b2031f: version 4 (unversioned ids, from a `download?style=ga` round trip) saved fine with `steps with errors: 0` and every tool independently confirmed present via `GET /api/tools/{versioned-id}`, yet invocation returned 400 listing collapse_dataset 5.1.0, kmindex_query 0.6.1+galaxy4, lexicmap_search 0.9.0+galaxy1 and collection_column_join 0.0.3 as not installed; version 5, identical apart from versioned `tool_id`s, invoked successfully (invocation 6372d41d2d9cf1c6).
raised by
manual-deploy
observed at
issue
https://github.com/galaxyproject/foundry/issues/591
galaxy-tool-util-replacement-collection-requires-rows-key-unconditionallymajordefectgalaxy-tool-util (galaxy.tool_util.cwl.util.replacement_collection) -- Planemo job-input staging for sample_sheet collections

`galaxy.tool_util.cwl.util.replacement_collection()` (the function Planemo's `stage_in`/`galactic_job_json` path uses to turn a tests-format `job:` Collection value into a Galaxy HDCA-creation payload) contains `if collection_type.startswith("sample_sheet"): kwds["rows"] = value["rows"]` -- an unconditional dict-index (not `.get()`) on the job value's optional `rows` key. tests-format.schema.json's own `Collection` $def does not require `rows` (this workflow's own test case 1, `kmindex_wiring_smoke_generic_fixtures`, intentionally omits it -- 'not meaningful for generic non-phiX174 fixture content' -- and that test file already passed `gxwf validate-tests --workflow ... --json` cleanly with `rows` absent). Any `sample_sheet`-typed Collection job input that legitimately omits `rows` therefore crashes Planemo's staging step with an uncaught `KeyError: 'rows'` before any Galaxy invocation is even created, rather than surfacing as a graceful assertion/staging-problem report.

expected
`replacement_collection` should use `kwds["rows"] = value.get("rows", {})` (or omit the key entirely when absent, if Galaxy's collection-create API tolerates a missing `rows`), matching the tests-format schema's own treatment of `rows` as optional for a `sample_sheet` Collection value.
evidence
Reproduced directly this phase: `planemo test --install_galaxy --test_index 1 --extra_tools <dir> galaxy-workflow.gxwf.yml` crashed with `execution_problem: "'rows'"`, `status: "error"`, `invocation_details: null`, `job: null` in the structured `tool_test_output.json` -- i.e. staging failed before any Galaxy invocation existed. Full traceback: `planemo/galaxy/activity.py:441 stage_in -> galaxy/tool_util/client/staging.py:275 stage -> galaxy/tool_util/cwl/util.py:388 galactic_job_json -> :234 replacement_item -> :362 replacement_collection -> KeyError: 'rows'`. Confirmed the isolating variable by contrast: test case 2 (`gene_e_j_am3_diagnostic_synthetic_lexicmap_index`), whose `gene_query_panel` Collection DOES carry a `rows:` block, staged past this exact code path without error in the immediately following run and reached a real (differently-failing) workflow-invocation attempt. Installed package confirmed at `galaxy_tool_util-25.1.2.dist-info` under planemo 0.75.47's own venv.
raised by
run-workflow-test (phase 11)
observed at
issue
https://github.com/galaxyproject/foundry/issues/583
galaxy-udt-registration-real-endpoint-is-unprivileged-tools-not-dynamic-toolsmajorgapGalaxy core (lib/galaxy/webapps/galaxy/api) -- dynamic-tool registration endpoints

This run's earlier entry (run-workflow-test-no-mechanism-to-install-authored-galaxyusertool-udts) found no way to load a GalaxyUserTool YAML into a Planemo-managed toolbox and, separately, `POST /api/dynamic_tools` against a real production Galaxy instance (usegalaxy.org) returned HTTP 403 ('You must be an administrator to access this feature'). Neither run-workflow-test's nor author-galaxy-tool-wrapper's packaged references mention that Galaxy exposes a SEPARATE, non-admin-gated endpoint for exactly this: `POST /api/unprivileged_tools`, gated only by a `USER_TOOL_EXECUTE` role plus the instance's `enable_beta_tool_formats` config flag (both satisfied by an ordinary usegalaxy.org account). A regular user's own GalaxyUserTool YAML (converted to the JSON body that endpoint expects) registers there successfully and becomes a real, invocable, user-scoped dynamic tool with a `tool_uuid`.

expected
author-galaxy-tool-wrapper and/or run-workflow-test should document `POST /api/unprivileged_tools` as the real-Galaxy registration path for an authored GalaxyUserTool (distinct from the admin-only `/api/dynamic_tools`), including its role/config gating (`USER_TOOL_EXECUTE`, `enable_beta_tool_formats`) and that a successful registration returns a `tool_uuid` a workflow step must reference (see the companion entry on gxformat2 not modeling `tool_uuid`) rather than a bare `tool_id` string.
evidence
draft-manuscript-galaxy, post-pipeline deploy step. `POST https://usegalaxy.org/api/dynamic_tools` with a GalaxyUserTool-derived body -> HTTP 403 admin-required. `POST https://usegalaxy.org/api/unprivileged_tools` with the same tool content (after fixing a separate lint defect, see the companion `value: 0` entry) -> 200, returning a real `tool_uuid` for each of this run's 3 UDTs (lexicmap_streamer, flatten_gene_summary_json_to_row, kmindex_hit_dedup_max_score), later confirmed resolvable with zero step errors via `GET /api/workflows/{id}/download` once wired into the imported workflow.
raised by
run-workflow-test (phase 11)
observed at
issue
https://github.com/galaxyproject/foundry/issues/585
galaxy-workflow-frame-comments-missing-position-size-rejected-by-real-galaxy-importmajorgapGalaxy (galaxyproject/galaxy) WorkflowCommentModel vs. this pipeline's gxformat2 `comments: type: frame` authoring

Attempting `planemo test --test_index 1 --install_galaxy galaxy-workflow.gxwf.yml` (a bounded attempt at the second validation step of this phase) failed before any test data was staged or any tool was run: Galaxy's real workflow-import API rejected galaxy-workflow.gxwf.yml with HTTP 400, 'Field required in ("frame","position")' and 'Field required in ("frame","size")'. The workflow's own `comments:` block (4 `type: frame` entries grouping steps into Stage A/B/C/D2, e.g. `{type: frame, label: 'Stage A — input assembly', title: ..., contains_steps: [...]}`) carries no `position`/`size` fields, which real Galaxy's WorkflowCommentModel requires for any frame-type comment. This means the concrete workflow produced by earlier phases (advance-galaxy-draft-step / freeform-summary-to-galaxy-template, whichever Mold first authored these frame comments) is schema-valid enough to pass this pipeline's own `gxwf draft-validate --concrete` gate but is NOT actually importable into a real Galaxy instance.

expected
Whichever Mold/reference documents the gxformat2 `comments: type: frame` shape should require (or default) `position: {x, y}` and `size: {width, height}` fields, and `gxwf draft-validate`/`validate-galaxy-workflow` should be extended to catch this class of real-Galaxy-only requirement before a Planemo run discovers it at import time.
evidence
Full traceback captured during this phase's `planemo test` attempt: bioblend.ConnectionError: Unexpected HTTP status code: 400, pydantic_core ValidationError 'WorkflowCommentModel: frame.position Field required, frame.size Field required', raised from galaxy.managers.workflows.build_workflow_from_raw_description -> model.WorkflowComment.from_dict on the first frame comment `{id:0, type:frame, data:{title:'Stage A — input assembly'}, child_steps:[15], label:'Stage A — input assembly'}`. This blocked test case 1 before tool installation/dependency resolution was ever reached, so it was not possible to determine whether the kmindex/lexicmap/UDT tool chain itself would install and run cleanly.
raised by
implement-galaxy-workflow-test (phase 9)
observed at
issue
https://github.com/galaxyproject/foundry/issues/580
galaxy-workflow-import-enforces-undocumented-per-field-length-limit-on-step-docmajordefectGalaxy core -- POST /api/workflows gxformat2 import, step doc/annotation field

A real Galaxy instance (usegalaxy.org, 26.1.2.dev0) rejects `POST /api/workflows` with an opaque, tracebackless HTTP 500 when any step's `doc:` (annotation) field exceeds a real, undocumented length limit. Bisected directly against the live endpoint: a step `doc` of 2000 characters imports fine; 2398 characters 500s; the limit sits at exactly 2048 characters. Neither `gxwf draft-validate`/`gxwf validate` (both passed clean, repeatedly, on the same file) nor galaxy-workflow-draft-format's or gxformat2-schema's packaged notes model or enforce any such limit -- this run's `freeform-summary-to-galaxy-template` output (and later advance-galaxy-draft-step iterations folding `_plan_context` rationale into `doc:` per that skill's own 'a resolved step carries no _plan_* fields' rule) produced 5 step `doc` fields well over 2048 characters, all invisible to every static check available in this toolchain, only surfacing as a bare 500 at real-Galaxy import time.

expected
gxwf's draft-validate/validate should check step (and workflow-level) `doc`/`annotation` field length against Galaxy's real limit (~2048 chars, worth confirming the exact DB column width upstream) and fail with a clear diagnostic naming the offending step and its length, rather than letting a workflow pass all local validation and then 500 opaquely at real-Galaxy import. Separately, freeform-summary-to-galaxy-template's convention of folding full authoring/discovery provenance into a step's `doc:` field (rather than only in the run's own ledgers) should be revised to keep `doc:` short and put full provenance in open-requirements/feedback ledger entries instead, given this real, silent ceiling.
evidence
draft-manuscript-galaxy, post-pipeline deploy step. Direct `POST /api/workflows` bisection against https://usegalaxy.org/api/workflows: doc length 2000 -> 200 OK; 2398 -> 500 'Uncaught exception in exposed API method' (no traceback surfaced to the client); 2048 -> 200 OK. Trimmed 5 oversized step `doc` fields in galaxy-workflow.gxwf.yml (kmindex_hit_dedup_max_score, lexicmap_streamer_tiling_qc, and 3 others) from full authoring-provenance prose down to concise summaries, after which the same workflow imported successfully.
raised by
freeform-summary-to-galaxy-template (phase 5)
observed at
issue
https://github.com/galaxyproject/foundry/issues/564#issuecomment-5733272414
galaxy-workflow-invocation-check-rejects-previously-installed-tool-as-not-installedmajorgapgalaxy-workflow-invocation-failure-reference

The note's 'Request-time validation' surface (API error before a useful invocation state exists, e.g. an HTTP 400 'required tools are not installed') gives no guidance on how to tell a genuine per-tool dependency/installation failure apart from a toolbox-state read that is stale relative to the just-completed install/reload cycle. This phase found a concrete, reproducible tell that the note doesn't mention: in this run's test 2, `planemo-test2.log:292` shows `collapse_collections` (providing `collapse_dataset`) was *skipped* for reinstall because its cached status was already 'Installed' -- no fresh clone, no fresh dependency resolution occurred for it this run -- yet the subsequent `POST /api/workflows/.../invocations` 400 (`planemo-test2.log:1775-1796`) still lists `collapse_dataset` among the 'not installed' tools, 54 seconds later, alongside 3 real freshly-cloned Tool Shed tools and 3 never-installable UDTs. A tool with a confirmed pre-existing good install status being rejected is strong evidence the invocation-validation check read stale/incomplete toolbox state rather than a real, current dependency failure for that specific tool -- but nothing in this note documents 'a previously-Installed repository still appearing in the not-installed list' as a diagnostic signal for this class of race, so the classification had to be reconstructed ad hoc from Galaxy install-manager log lines rather than a documented reference path.

expected
Add this diagnostic tell to the 'Request-time validation' row (or a new row) in galaxy-workflow-invocation-failure-reference.md: when a tool listed as 'not installed' in a request-time 400 has a repository install-manager log line showing its install was skipped because it was already 'Installed' from a prior/cached run, that is evidence of a toolbox-state read/reload-timing defect rather than a genuine dependency-resolution failure for that tool, and should route debugging toward Galaxy's toolbox-reload/tool-availability-check code path rather than toward the wrapper's conda requirements.
evidence
draft-manuscript-galaxy phase 12. `planemo-test2.log:292`: "Skipping installation of revision 90981f86000f of repository 'collapse_collections' because it was installed with the (possibly updated) revision 90981f86000f and its current installation status is 'Installed'." `planemo-test2.log:1775,1796`: `POST /api/workflows/961e7c4742a92de4/invocations HTTP/1.1 400` with `err_msg` listing `collapse_dataset (version 5.1.0)` among 7 'not installed' tools. Last logged `reload_toolbox` control-task cycle completes at `11:50:13,808`; the invocation POST fires at `11:50:58,531`, 45s later -- ruling out an in-flight reload as the immediate cause and pointing instead at how the invocation-validation code path sources its toolbox snapshot.
raised by
debug-galaxy-workflow-output (phase 12)
observed at
issue
https://github.com/galaxyproject/foundry/issues/584
galaxy-workflow-update-exact-tools-defaults-true-and-discards-per-step-error-detailmajordefectGalaxy core -- PUT /api/workflows/{id} (update_workflow_from_raw_description, WorkflowUpdateOptions)

`PUT /api/workflows/{id}` resolves every step's tool via `trans.app.toolbox.get_tool(tool_id, tool_version=tool_version, exact=exact_tools, tool_uuid=tool_uuid)`, where `exact_tools` (a field on the real `WorkflowUpdateOptions` Pydantic model) defaults to `True` unless the request body explicitly sets it -- the exact same false-positive tool-resolution behavior already observed at invocation time (workaroundable there via `require_exact_tool_versions: false`) recurs at save time with a DIFFERENT, undocumented field name (`exact_tools`, not `require_exact_tool_versions`) and no obvious hint that a save-time escape hatch even exists. Worse: when `get_tool(..., exact=True)` fails for one or more steps, `update_workflow_from_raw_description` builds a real, specific per-step message (`f"Step {n+1}: Requires tool '{tool_id}'."`) into `missing_tool_tups` and raises `MissingToolsException`, but the API handler in `workflows.py` unconditionally rewrites this to a generic `{"err_msg": "This workflow contains missing tools. It cannot be saved until they have been removed from the workflow or installed.", "err_code": 0}` -- discarding the specific, already-computed per-step list before it ever reaches the client, even though every one of the flagged tools was independently confirmed installed at exactly the pinned tool_id/tool_version via `/api/tools/{id}/build`.

expected
(1) `PUT /api/workflows/{id}`'s error response should surface the specific per-step missing-tool list it already computed internally (`missing_tool_tups`) instead of discarding it for a generic message with `err_code: 0` -- this alone would have cut a full diagnostic round-trip. (2) Document `exact_tools`/`allow_missing_tools` (WorkflowUpdateOptions' real fields) as the save-time equivalent of invocation-time's `require_exact_tool_versions`/`allow_tool_state_corrections`, ideally in the same place, since a caller who already learned about one escape hatch has no way to guess the other exists under a different name for a different endpoint.
evidence
draft-manuscript-galaxy, post-pipeline deploy step. `PUT /api/workflows/575e9ee747b2031f` with a corrected native workflow JSON (bare `{"workflow": {...}}` body) -> `{"err_msg": "This workflow contains missing tools...", "err_code": 0}` for 4 tools (collapse_dataset 5.1.0, lexicmap_search 0.9.0+galaxy1, kmindex_query 0.6.1+galaxy4, collection_column_join 0.0.3) independently re-confirmed installed via `/api/tools/{id}/build` moments before and after. Re-submitting the identical `workflow` content with two added top-level sibling keys, `{"exact_tools": false, "allow_missing_tools": true}`, succeeded immediately with no other change.
raised by
debug-galaxy-workflow-output (phase 12)
observed at
issue
https://github.com/galaxyproject/foundry/issues/589
gxformat2-schema-missing-nested-in-key-conventionmajorgapgxformat2-schema

gxformat2-schema documents that a step's `state` nests conditionals/sections as plain nested YAML (the `state` vs `tool_state` section), but no packaged reference in advance-galaxy-draft-step's, implement-galaxy-tool-step's, or repair-galaxy-draft-topology's bundles documents the companion convention for a step's `in:` connections dict: how to address a nested conditional test-parameter branch or section child as a connection target.

expected
Extend gxformat2-schema with an explicit subsection on `in:` key addressing for nested tool state -- the pipe-delimited path convention (e.g. `db_opts|lexicmap_index`, `advanced_settings|align_min_match_pident`) for conditional-branch and section-child parameters -- mirroring the existing `state`-nesting subsection, and include it in implement-galaxy-tool-step's packaged references (the leaf Mold that performs this binding), not just as an assumed convention.
evidence
Implementing lexicmap_search (toolshed.g2.bx.psu.edu/repos/iuc/lexicmap/lexicmap_search 0.9.0+galaxy1) required wiring workflow inputs onto a `gx_conditional`'s case-owned parameter (`lexicmap_index`, under `db_opts_selector: db`) and five `gx_section` children of `advanced_settings`. None of this run's loaded, packaged references named or demonstrated the `|`-joined `in:` key form needed to address them; it was inferred from general Galaxy/gxformat2 familiarity outside any packaged bundle content, which the skill's own Runtime Notes direct against ('use only files packaged in this skill bundle and user-supplied artifacts').
raised by
advance-galaxy-draft-step (phase 6)
observed at
issue
https://github.com/galaxyproject/foundry/issues/571
gxformat2-step-schema-does-not-model-tool-uuid-for-dynamic-tool-resolutionmajorgapgxformat2 schema / Galaxy workflow import -- dynamic-tool step resolution

A gxformat2 workflow step referencing a real, registered user-scoped dynamic tool (via `POST /api/unprivileged_tools`, see the companion endpoint entry) by bare `tool_id` string alone imports and round-trips (`gxwf convert`) without ever populating or requiring a `tool_uuid` -- but real Galaxy's step-to-tool resolution for a dynamic/unprivileged tool requires the native `.ga` JSON step to carry that tool's real `tool_uuid` explicitly; a bare `tool_id` never resolves to a user-scoped dynamic tool even after it is successfully registered and even though the same `tool_id` string is correct. This left all 3 UDT steps showing 'Tool is not installed' after a clean gxformat2 import, with no schema-level signal of what was missing. Compounded by a second, already-ledgered gxwf defect (`step.in is not iterable` on `gxwf convert`), which blocked using gxwf itself to do the format2->native conversion+injection, forcing a workaround via Galaxy's own `/api/workflows/{id}/download` to get native JSON, hand-inject the 3 real `tool_uuid`s, and re-`POST` that native form.

expected
Either extend the gxformat2 step schema/galaxy-workflow-draft-format to model an optional `tool_uuid` field (populated once a dynamic/UDT tool is registered) so a template/draft can carry it through the normal Foundry pipeline, or document explicitly in freeform-summary-to-galaxy-template / advance-galaxy-draft-step / run-workflow-test that a workflow step resolving to a GalaxyUserTool-authored dynamic tool must, at real-Galaxy deployment time, be converted to native `.ga` and have its `tool_uuid` injected post-registration -- this is not currently documented anywhere in the pipeline's packaged references.
evidence
draft-manuscript-galaxy, post-pipeline deploy step. gxformat2 import of galaxy-workflow.gxwf.yml (all 3 UDT tool_ids correct, tools already registered via /api/unprivileged_tools) still showed all 3 steps as tool-unresolved in the imported workflow. Fetched the imported workflow natively via `GET /api/workflows/{id}/download`, confirmed each UDT step's JSON had no `tool_uuid` key at all; manually set `tool_uuid` to each of the 3 registered tools' real UUIDs in that native JSON and re-imported via `POST /api/workflows` (native form) -- resulting workflow (id 575e9ee747b2031f) shows zero step errors on the same `GET .../download` check.
raised by
freeform-summary-to-galaxy-template (phase 5)
observed at
issue
https://github.com/galaxyproject/foundry/issues/587
gxwf-validate-connections-flag-crashes-uncaught-on-format2-dict-shaped-step-inmajordefectgalaxy-tool-util-ts / @galaxy-tool-util/cli (gxwf validate --connections) -- normalized-workflow-to-native step builder

`gxwf validate galaxy-workflow.gxwf.yml --json --connections` (and the same with `--strict` added) crashes with an uncaught `TypeError: step.in is not iterable` at `toNative.js:429` (`_extractConnections`, called from `_buildToolStep` -> `_buildStep` -> `_buildNativeWorkflow` -> `toNative` -> `_coerceNormalizedNative` -> `buildWorkflowGraph` -> `validateConnectionsReport` -> `buildConnectionReport`), exits 1, and emits no JSON report at all -- not even a `connection_report: null` degrade the way tool-state fetch failures degrade to `skip_tool_not_found`. This workflow's every step's `in:` is an ordinary gxformat2 mapping (`{port_name: source, ...}`, e.g. `in: {input_list: gene_query_panel}`), the standard and only shape gxformat2's own schema documents for step connections (see this same run's `gxformat2-schema-missing-nested-in-key-convention` entry, which independently confirms and cites this `in:` mapping shape). `_extractConnections`'s `for (const stepInput of step.in)` expects `step.in` to already be an array (the native-format shape), so any format2 workflow with a normal dict-shaped `in:` reaching this code path crashes rather than being converted.

expected
`_extractConnections` (or its caller) should convert a format2 dict-shaped `step.in` into the array shape it expects before iterating -- the same normalization `toNative` already performs successfully for the plain `gxwf validate` (no `--connections`) path, since that path reads this exact workflow's steps without error. `gxwf validate --connections` should either work on an ordinary format2 workflow or fail gracefully (a caught, reported error in the JSON `connection_report` field, matching the tool-state fetch failure's graceful `skip_tool_not_found` degrade) rather than throwing an uncaught exception that discards the entire report.
evidence
Reproduced directly this phase: `gxwf validate galaxy-workflow.gxwf.yml --json --connections` and `gxwf validate galaxy-workflow.gxwf.yml --json --connections --strict` both exit 1 with the identical stack trace, no stdout JSON at all (the process crashes before writing the report object). `gxwf validate galaxy-workflow.gxwf.yml --json --strict` (same workflow, same flags minus `--connections`) exits 0 and produces a full JSON report (5 ok / 0 fail / 4 skip). This skill's own SKILL.md directs using `--connections` 'when tool cache metadata is available and data-shape compatibility matters, especially around collections and map-over' -- squarely this workflow's shape (9 steps, heavy collection map-over across kmindex/lexicmap/UDT steps) -- so the flag's total unusability here is a real, non-hypothetical gap, not an edge case. Worked around by validating without `--connections` and recording collection/map-over shape compatibility as a residual runtime risk instead.
raised by
validate-galaxy-workflow (phase 10)
observed at
issue
https://github.com/galaxyproject/foundry/issues/581
lexicmap-search-sample-sheet-column-to-scalar-port-defectmajordefectadvance-galaxy-draft-step

advance-galaxy-draft-step's phase 6 iteration 2 (lexicmap_search implementation) wired the workflow's four per-gene LexicMap sensitivity overrides (align_min_match_pident, align_min_match_len, seed_min_prefix, min_qcov_per_genome) directly from `gene_query_panel` (a `sample_sheet` collection whose per-element columns carry these values) onto lexicmap_search's plain scalar `advanced_settings|*` tool ports (`in: advanced_settings|align_min_match_pident: gene_query_panel`, etc.) -- a binding that can never work. A sample_sheet collection's per-element column values are only readable by a tool that itself declares a `data_collection` input accepting `sample_sheet` and reads columns internally via `DatasetCollectionWrapper.sample_sheet_row()` in its own Cheetah/XML template; `lexicmap_search` (iuc/lexicmap 0.9.0+galaxy1) is an ordinary IUC tool with plain float/int scalar parameters and no sample_sheet awareness whatsoever. There is no generic Galaxy workflow-wiring mechanism to bind an arbitrary other tool's scalar parameter to a sample_sheet column at runtime -- rewiring the *connection* alone can never fix this; the whole design of carrying these 4 values as sample_sheet columns was unworkable from the start for feeding a non-sample_sheet-aware tool. Nothing in this pipeline's static checks caught it: `gxwf draft-validate`/`gxwf validate` both passed clean repeatedly on this file (structural validation OK, 0 fail/0 structure_errors), the deploy step's own `GET /api/workflows/{id}/download` check showed zero step errors, and `gxwf validate --connections` (which would in principle check collection-algebra/map-over connection-type compatibility) cannot run at all against this file due to an already-ledgered, unrelated crash (`gxwf-validate-connections-flag-crashes-uncaught-on-format2-dict-shaped-step-in`). The defect was only exposed by a real invocation on live usegalaxy.org: both per-gene lexicmap_search jobs (invocation `7a25084290281d4f`, jobs `bbd44e69cb8906b5703a6db6ea90ddf0` and `bbd44e69cb8906b55890e15ae6aa2602`) errored pre-execution -- no command line, no stdout/stderr, no exit code -- with the job's actual submitted `advanced_settings` tool_state literally holding `"<galaxy.model.DatasetCollectionElement(99373144) at 0x7f1f8adf6cb0>"` (the raw Python object repr) in place of a resolved float/int for all four ports.

expected
implement-galaxy-tool-step / advance-galaxy-draft-step's packaged references should document, as a hard rule, that a `sample_sheet` collection's per-element columns cannot be wired directly onto another (non-sample_sheet-aware) tool's plain scalar parameter -- only onto a tool that itself declares a `data_collection` input parameter for that sample_sheet. For the common case of needing a per-element-varying scalar value to feed an ordinary tool's parameter, the correct, real Galaxy pattern (verified working here) is: a parallel `list` collection (not `sample_sheet`) whose element_identifiers match the driving collection's, one dataset element per gene holding that gene's real value as plain text, consumed by a Galaxy core `param_value_from_file` (0.1.0) step mapped over it -- note this tool exposes one output port per `param_type` (`text_param` / `integer_param` / `float_param` / `boolean_param`; the packaged references should say to use the port matching the chosen `param_type`, not a generic `output`), whose result then wires into the target tool's scalar port. Separately, `gxwf validate --connections` should (once its unrelated crash is fixed) flag a sample_sheet-to-scalar-parameter connection as a real type error, since it is never valid regardless of collection contents.
evidence
draft-manuscript-galaxy, phase 12 (debug-galaxy-workflow-output) + live remediation. Root-caused via `GET /api/jobs/{id}?full=true` on both failed lexicmap_search jobs under invocation `7a25084290281d4f` (history `bbd44e69cb8906b51b4da6f15800819c`), showing the literal `DatasetCollectionElement` repr in `advanced_settings.align_min_match_pident`/`align_min_match_len`/`seed_min_prefix`/`min_qcov_per_genome`, while `db_opts.lexicmap_index` (a real ordinary text-select port) resolved correctly to `"Viral"` in the same job -- isolating the fault to the sample_sheet-column ports specifically. Confirmed the real fix mechanism by inspecting `GET /api/tools/param_value_from_file?io_details=true` (four per-param_type output ports, not a single generic one) and rebuilt the binding for real: 4 new real `list` collections created via `POST /api/dataset_collections` (`gene_align_min_match_pident_panel` id `5f39d50dafb0838b`, `gene_align_min_match_len_panel` id `ae22378905d7f2b7`, `gene_seed_min_prefix_panel` id `1ea756628560cfef`, `gene_min_qcov_per_genome_panel` id `7565b2b9a270b623`; each E/J, values 60.0/70.0, 35/50, 15/17, 30.0/0.0 respectively -- J using the wrapper's own confirmed tool defaults 70.0/50/17, min_qcov_per_genome having no real wrapper default so 0.0 (no-op floor) was used deliberately for genes without a production override), plus 4 new `extract_<name>_per_gene` (`param_value_from_file` 0.1.0) steps, rewiring lexicmap_search's 4 broken `in:` ports onto these steps' typed output ports instead of `gene_query_panel`. Fix applied to galaxy-workflow.gxwf.yml (local source of truth) and re-validated clean (`gxwf validate`: 9 ok / 0 fail / 4 skip_tool_not_found, all 4 skips pre-existing UDT/toolshed-fetch gaps unrelated to this change).
raised by
debug-galaxy-workflow-output (phase 12)
observed at
issue
https://github.com/galaxyproject/foundry/issues/588
run-workflow-test-no-mechanism-to-install-authored-galaxyusertool-udtsmajorgaprun-workflow-test

Neither run-workflow-test's own packaged references (planemo.md, planemo-workflow-test-architecture.md, planemo-asserts-idioms.md, galaxy-workflow-invocation-failure-reference.md) nor author-galaxy-tool-wrapper's (which explicitly states its output is 'a single GalaxyUserTool YAML document, not Galaxy XML') document any mechanism by which a locally-authored GalaxyUserTool YAML definition (no Tool Shed presence) is supposed to reach a Planemo-managed Galaxy's toolbox for a workflow test run. `planemo test`'s only documented tool-injection option, `--extra_tools <file|directory>`, was tried against a directory holding this run's 3 UDT YAML files; planemo emits a `<tool_dir dir="...">` entry into the generated tool_conf.xml (confirmed by reading the generated file directly), and Galaxy's toolbox parses that tool_conf.xml, but Galaxy's classic `tool_dir` scanner only auto-discovers XML tool wrappers -- zero log lines anywhere reference any of the 3 UDT ids/files, and the subsequent real workflow-invocation attempt's HTTP 400 explicitly lists `lexicmap_streamer (version 1.0.0)`, `flatten_gene_summary_json_to_row (version 1.0.0)`, and `kmindex_hit_dedup_max_score (version 1.0.0)` among the 'required tools are not installed', proving the toolbox never registered them at all.

expected
Either document a real, working path for a GalaxyUserTool YAML to reach a Planemo-managed toolbox for testing (e.g. a `gxwf`/`galaxy-tool-util` command that lowers `class: GalaxyUserTool` to a classic Galaxy tool XML + script directory that `--extra_tools` can actually load, or an alternate Planemo/Galaxy API this skill bundle should cite), or state explicitly in run-workflow-test's own procedure that an authored UDT with no such lowering step is expected to fail tool-shed/toolbox resolution in a real Planemo run and name the concrete blocking condition as `not-run`/`fail`-with-tool-install-modality rather than leaving the caller to discover this empirically.
evidence
Phase 11 of this run (draft-manuscript-galaxy). Copied the 3 UDT YAMLs (galaxy-user-tool.yml, galaxy-user-tool-flatten-gene-summary.yml, galaxy-user-tool-kmindex-hit-dedup-max-score.yml) into a scratch directory and passed it via `planemo test --extra_tools <dir> --install_galaxy --test_index 2 ...`. Verified the generated tmp tool_conf.xml contained `<tool_dir dir=".../udt-tools" />`; grepped both this run's planemo-test1.log and planemo-test2.log for the 3 UDT ids/filenames/`GalaxyUserTool` and found zero matches anywhere in either log. The subsequent workflow-invocation attempt for test case 2 (`POST /api/workflows/.../invocations` -> HTTP 400) returned `err_msg: "Workflow was not invoked; the following required tools are not installed: ... lexicmap_streamer (version 1.0.0), flatten_gene_summary_json_to_row (version 1.0.0), kmindex_hit_dedup_max_score (version 1.0.0), ..."`, confirming the toolbox has no record of these 3 tool ids under any mechanism this run attempted.
raised by
run-workflow-test (phase 11)
observed at
issue
https://github.com/galaxyproject/foundry/issues/582
tests-format-job-schema-has-no-path-to-an-intermediate-step-input-portmajorgaptests-format (Job / TestJob $defs)

The harness's phase-9 task instruction directed constructing a synthetic LexicMap hits TSV and 'wiring it as the lexicmap_results input the test case feeds toward lexicmap_streamer_tiling_qc' so the am3 assertions would be checkable end-to-end. But lexicmap_results is not a top-level workflow input on galaxy-workflow.gxwf.yml -- it is wired to an internal step output (lexicmap_search/out_file). The tests-format schema's `Job` $def (`TestJob.job`) is `additionalProperties: <value-types>` with no structural provision for keying a value to anything but a top-level workflow input label, and the packaged planemo-workflow-test-architecture.md / planemo-asserts-idioms.md notes describe Planemo's `job:` block exclusively in terms of workflow-level inputs. There is no documented (or apparently possible) tests-format mechanism to inject a value onto an intermediate step's input port for a whole-workflow test.

expected
Either document explicitly (in tests-format's schema description or in planemo-workflow-test-architecture.md) that a synthetic fixture for an internal step is NOT expressible via `job:` and must instead be pursued via a real registered index/data-table entry or a separate component/tool-level test -- so a Mold is not directed to do something the format cannot express -- or, if Planemo/Galaxy actually has an undocumented mechanism for this (e.g. a `--test_index`-scoped step-parameter override), document and cite it.
evidence
This run: after confirming (by reading tests-format.schema.json's Job/TestJob $defs directly) that job keys can only bind workflow-level input labels, test case gene_e_j_am3_diagnostic_synthetic_lexicmap_index in galaxy-workflow.gxwf-tests.yml could not literally wire the synthetic hits TSV onto lexicmap_streamer_tiling_qc's lexicmap_results port. The synthetic fixture was instead staged under test-data/synthetic_am3/ and its expected effects validated by directly executing the real vendored lexicmap_streamer.py script outside of Planemo, with lexicmap_index_selection left as a documented placeholder pending real index construction (galaxy-test-plan.yml unresolved[0]/[1]).
raised by
implement-galaxy-workflow-test (phase 9)
observed at
issue
https://github.com/galaxyproject/foundry/issues/578
tool-util-cli-toolshed-fetch-rejects-real-filtered-list-collection-outputmajordefectgalaxy-tool-util-ts / @galaxy-tool-util/cli (gxwf, galaxy-tool-cache) -- ToolShed-fetch-to-ParsedTool decoder

`galaxy-tool-cache add`/`summarize` (and `gxwf draft-validate`'s own internal tool-state fetch) fail to fetch or parse a real, currently-published IUC Tool Shed wrapper -- toolshed.g2.bx.psu.edu/repos/iuc/kmindex/kmindex_query -- for every galaxy-suffixed version (tried and reproduced for 0.6.0+galaxy1, 0.6.0+galaxy2, 0.6.1+galaxy2, 0.6.1+galaxy3, 0.6.1+galaxy4, 0.6.1+galaxy5), raising a decode error at `outputs[1].structure: is missing` against the upstream parsedToolSchema's collection-output branch. Only the repo's original unsuffixed '0.6.0' version (which predates the wrapper's `<collection type="list"><filter>...</filter><discover_datasets .../></collection>`-shaped output, added by tools-iuc PR #8208 'support multiple indices simultaneously') parses successfully. `add --galaxy-url https://usegalaxy.org` was also tried as a fallback source and fails the same way (plus a second, `inputs is missing` error on that path).

expected
The ToolShed-fetch-to-ParsedTool decoder should populate `structure` (collection_type/discover_datasets/etc.) for a `<collection type="list">` output that declares `discover_datasets` directly and has no `structured_like`/rules -- this is an ordinary, common IUC wrapper shape (also present, filtered by a sibling `<filter>` block, which the schema has no field for at all -- a second, related lossiness worth tracking) -- rather than failing the whole fetch. `gxwf draft-validate` already degrades this failure gracefully to a `skip_tool_not_found` (not a hard fail) for tool-state checking, which is the right fallback behavior for validate; but `galaxy-tool-cache add`/`summarize` themselves give no such degrade and simply cannot produce a manifest for this real, in-production wrapper at all, blocking the normal automated discover -> summarize -> implement path for any workflow step using it.
evidence
Reproduced directly this iteration for kmindex_containment_screen (pinned tool_id toolshed.g2.bx.psu.edu/repos/iuc/kmindex/kmindex_query, tool_version 0.6.1+galaxy4, changeset b6fa25b6b436). Root-caused by fetching the wrapper's real upstream XML at the exact matching changeset (Tool Shed API's own `remote_repository_url` for this changeset pointed to github.com/galaxyproject/tools-iuc/tree/main/tools/kmindex; commit 7681be7f40 on that path declares `<tool ... version="@TOOL_VERSION@+galaxy4">`, an exact match) and comparing its `<outputs>` against the successfully-cached bare-'0.6.0' ParsedTool JSON, which lacks the collection output entirely. Worked around this run by hand-reconstructing galaxy-tool-summary.json's `parsed_tool`/`input_schemas` directly from that verified upstream XML rather than via the normal automated `galaxy-tool-cache` path (documented in that file's own `warnings[]`).
raised by
advance-galaxy-draft-step (phase 6)
observed at
issue
https://github.com/galaxyproject/foundry/issues/572
collection-pattern-mocs-ship-without-referenced-pagesminorgapgalaxy-collection-patterns (and sibling galaxy-conditionals-patterns / galaxy-tabular-patterns MOCs)

The skill bundle packages `galaxy-collection-patterns.md`, `galaxy-conditionals-patterns.md`, and `galaxy-tabular-patterns.md` as MOC/index pages (frontmatter `pattern_kind: moc`) that only list wikilink-style names of ~15-20 concrete pattern pages each (e.g. `[[fan-in-bundle-consume-and-flatten]]`, `[[collection-unbox-singleton]]`, `[[manifest-to-mapped-collection-lifecycle]]`, `[[tabular-concatenate-collection-to-table]]`). None of the referenced pattern pages themselves -- which per the MOC descriptions should carry the actual worked recipe, concrete tool_id, and state -- are packaged anywhere in this skill bundle's `references/` tree.

expected
Either package the linked pattern pages alongside their MOC (as this skill already does for other reference kinds, e.g. `galaxy-workflow-draft-format.md`), or have the MOC entries themselves carry the concrete tool_id / state worked example inline, so a cast skill that is explicitly told (Runtime Notes) not to fetch Foundry source files at runtime can actually resolve a pattern name to a usable recipe from packaged content alone.
evidence
For this run, resolving concrete tool identities for the fan-in/flatten/tabular-bridge steps (Collapse Collection, __FLATTEN__, collection_column_join) was only possible because the separately-supplied `iwc-comparison-notes.md` artifact (from a prior pipeline phase) happened to quote inline gxformat2 excerpts naming those tools. Had that artifact not carried those excerpts, the packaged collection/tabular pattern MOCs alone (the on-demand references this Mold's own SKILL.md directs it to for exactly this situation) would have given only a pattern *name* with no way to resolve it to a tool_id or worked state, forcing every such step to Deferred tier even where a concrete built-in exists.
raised by
freeform-summary-to-galaxy-template (phase 5)
observed at
issue
https://github.com/galaxyproject/foundry/issues/570
freeform-summary-to-galaxy-test-plan-silent-on-concrete-draft-and-test-data-refs-inputsminorgapfreeform-summary-to-galaxy-test-plan

The Mold's declared Inputs (freeform-summary, freeform-galaxy-interface, freeform-galaxy-data-flow, iwc-comparison-notes, iwc-exemplar-gxformat2) and its 'Labels and fixtures are assumed, not bound' procedure section both describe this skill as operating only against template-era briefs, directing label_status: assumed and workflow.label_source: interface-brief in every case. Nothing in the Mold's own SKILL.md anticipates or documents the case actually encountered in this run: a concrete gxformat2 workflow draft and resolved test-data-refs artifact already existed in the harness run-state by phase 8 and were handed to this invocation as extra grounding context, with an explicit instruction to keep the plan consistent with them. The Mold gives no guidance on whether `label_source` should then be 'draft' (since a concrete draft actually was read) or 'interface-brief' (since that is this Mold's only documented input class), nor on how `label_status` should reflect a label that was cross-checked against a real draft rather than merely assumed from a brief.

expected
Document an optional grounding-input case in this Mold's Inputs/Procedure: when a caller also supplies the concrete workflow draft and/or resolved test-data refs (as changeset-to-galaxy-test-plan and the *-test-to-galaxy-test-plan siblings already do for their own analogous 'carry forward' cases), state explicitly which `label_source` and `label_status` values apply, and how far the plan may rely on those artifacts before that reliance should instead be deferred to implement-galaxy-workflow-test's own workflow-label cross-check.
evidence
This run's harness passed galaxy-workflow.gxwf.yml (the concrete 9-step draft) and test-data-refs.json (phase 7's resolved gene E/J test-data scoping) as additional context alongside this Mold's normal declared inputs, with an instruction to avoid contradicting them. Absent any packaged guidance for this hybrid situation, this plan set workflow.label_source: draft and label_status: resolved throughout (since every label was in fact read from and matches the concrete draft's own ids), which is a reasoned but undocumented departure from the Mold's own stated 'assumed'/'interface-brief' default behavior.
raised by
freeform-summary-to-galaxy-test-plan (phase 8)
observed at
issue
https://github.com/galaxyproject/foundry/issues/577
galaxy-unprivileged-tools-lint-crashes-on-integer-input-default-value-zerominordefectGalaxy core -- POST /api/unprivileged_tools tool-creation lint (TestsCaseValidation)

Galaxy's real tool-creation lint on `POST /api/unprivileged_tools` (invoked via `input_models_for_tool_source` / `TestsCaseValidation`) throws an uncaught, unhelpfully-reported exception ('TestsCaseValidation ... exception is []', no further detail) when a GalaxyUserTool integer input declares `value: 0` as its default -- confirmed by bisecting the tool's own input list live against the real endpoint: identical input with `value: 1` registers successfully, `value: 0` fails every time. galaxy-user-tool-authoring.md (author-galaxy-tool-wrapper's own packaged reference) documents the `value:` field for scalar inputs generally but does not warn that a literal `0` default on an integer input is unsupported.

expected
Either fix Galaxy's lint to handle a zero-valued integer default (the underlying bug), or, until fixed, have galaxy-user-tool-authoring.md warn against declaring `value: 0` on an integer/float UDT input and recommend omitting the default (relying on the step's own explicit wired value) when zero is the semantically correct default.
evidence
draft-manuscript-galaxy, post-pipeline deploy step. `POST https://usegalaxy.org/api/unprivileged_tools` with the `lexicmap_streamer` UDT (max_internal_stops integer input, `value: 0`) -> HTTP 400, opaque lint exception. Removing the `value: 0` default from that one input (workflow always supplies it explicitly anyway) -> 200 OK, tool registered with a real `tool_uuid`. Re-added the same field with `value: 1` on a throwaway test copy to confirm the value itself (not the field's mere presence) was the trigger.
raised by
author-galaxy-tool-wrapper
observed at
issue
https://github.com/galaxyproject/foundry/issues/586
galaxy-user-tool-authoring-missing-element-identifier-expressionminorgapgalaxy-user-tool-authoring

galaxy-user-tool-authoring.md's section 3 ('Expression syntax in shell_command') documents exactly two ways to read a `data` input in a `shell_command`/`configfiles` expression -- a scalar/file path via `$(inputs.NAME.path)` -- and says nothing about a `data` input's other available File-object fields. In particular it never mentions `element_identifier`, even though the installed `@galaxy-tool-util/schema` package's own `gx-data.js` parameter-generation code declares, for the `job_runtime` state representation (the one governing values available inside a running job's command/configfile expressions), a File object shape of `{ class: 'File', basename, location, path, nameroot, nameext, format, size, element_identifier: S.optional(S.String) }` -- i.e. `$(inputs.NAME.element_identifier)` is a real, schema-backed expression, not merely `.path`.

expected
Extend galaxy-user-tool-authoring.md section 3 with an explicit line documenting `$(inputs.NAME.element_identifier)` (available when the input is a mapped collection element, matching the classic Galaxy tool-XML idiom already documented elsewhere in this same skill family's convert-nfcore-module-to-galaxy-tool notes: '`$input.element_identifier` in `<command>`'), alongside the existing `.path` documentation -- this is exactly the mechanism an authored UDT needs to preserve a Galaxy collection's per-element identifier into its output content without adding an extra collection-element-identifier-extraction producer step/port to the workflow topology.
evidence
Authoring flatten_gene_summary_json_to_row (a GalaxyUserTool mapped one call per gene over a summary_json collection) needed the mapped gene's element_identifier embedded as a literal output column, per this step's own _plan_state ('preserving element_identifier for the join'). galaxy-user-tool-authoring.md's packaged expression-syntax section, read upfront per this skill's own procedure, documents only `.path` and gives no indication `.element_identifier` exists or is valid. Confirmed the field's existence and validity only by grepping the installed `@galaxy-tool-util/cli` npm package's own schema source (`gx-data.js`) directly, outside any packaged skill reference -- exactly the kind of external verification this skill's Runtime Notes direct against ('use only files packaged in this skill bundle and user-supplied artifacts'). Had a different, plausible-but-wrong design been chosen instead (e.g. inserting a `collection_element_identifiers` producer step purely to recover the gene symbol as a wireable parameter), it would have been an avoidable topology change driven by a documentation gap, not a real tool-shape constraint.
raised by
advance-galaxy-draft-step (phase 6)
observed at
issue
https://github.com/galaxyproject/foundry/issues/468#issuecomment-5733273474
galaxy-workflow-test-plan-schema-fixture-required-for-scalar-typed-paramsminorgapgalaxy-workflow-test-plan (JobInput/Fixture $defs)

JobInput.fixture is required (non-optional) and always resolves to the Fixture $def, whose four fields (storage, location, checksum, provenance) and whose enum for `storage` (remote-url, in-repo, cvmfs-string, generated-toy, unresolved, null) are all phrased in file/collection-fixture terms. Neither the schema's own field descriptions nor any packaged on-demand note (iwc-test-data-conventions.md, planemo-asserts-idioms.md, galaxy-workflow-testability-design.md) says what to do for a JobInput that is a plain typed scalar workflow parameter (int, float, boolean, or a text param carrying a literal default, e.g. this workflow's kmindex_zvalue=6 or tiling_qc_allow_frameshifts=false) rather than a file or collection. iwc-test-data-conventions.md section 5 covers only the CVMFS/.loc 'bare string matching a data-table value' case, which is a different shape again (a reference-data selector, not an arbitrary typed parameter default).

expected
Either make `fixture` on JobInput conditionally optional/nullable-as-a-whole when the input is a plain scalar parameter (not a file/collection/data-table selector), or add an explicit Fixture convention for this case (e.g. storage: null with the literal default value carried in `location`, as this plan did) so different Molds/runs do not each invent their own encoding for the same common situation.
evidence
This run's workflow (galaxy-workflow.gxwf.yml) declares 15 workflow inputs, of which 12 are plain typed scalars with literal pinned defaults (kmindex_zvalue, kmindex_threshold, kmindex_output_format, kmindex_fast, lexicmap_top_n_genomes, lexicmap_advanced_all, and the 6 tiling_qc_* params). Each needed a JobInput entry (required by the TestCase schema) whose required `fixture` object has no natural file/location/checksum reading. Absent any documented convention, this plan used `storage: null` with the default value's string form placed in `location`, and `provenance` noting 'workflow default, per galaxy-workflow.gxwf.yml default' -- a reasoned choice, not a documented one.
raised by
freeform-summary-to-galaxy-test-plan (phase 8)
observed at
issue
https://github.com/galaxyproject/foundry/issues/576
gxwf-draft-validate-json-flag-emits-non-json-diagnostics-on-stdoutminordefectgalaxy-tool-util-ts / @galaxy-tool-util/cli (gxwf draft-validate) -- --json report emission

`gxwf draft-validate <file> --concrete --json` writes one or more human-readable diagnostic lines (e.g. `toolshed fetch failed (...) for iuc~kmindex~kmindex_query: <huge inline TS type dump>`, followed by an ASCII tree of the failing schema path) directly to stdout, ahead of the actual JSON report object, whenever a tool-state fetch during the --concrete pass fails to decode (same underlying decode failure as ledger entry `tool-util-cli-toolshed-fetch-rejects-real-filtered-list-collection-output`). This happens even though stderr is a separate stream the process already uses for nothing observed in this run's redirection test, and even though `--help` explicitly describes `--json` as '(Output structured JSON report)'.

expected
When `--json` is passed, stdout should contain only the single parseable JSON report object (matching the flag's own documented contract); any fetch-failure/decode-diagnostic text (which draft-validate itself already degrades gracefully into the report's own `skip_tool_not_found` status/errors array) should go to stderr, or be folded into the JSON report's own warnings/errors, not interleaved onto stdout ahead of the JSON payload.
evidence
Ran `gxwf draft-validate galaxy-workflow-draft.gxwf.yml --concrete --json 1>/tmp/dv.out 2>/tmp/dv.err` this iteration (implementing join_gene_summary_rows_into_manifest, an unrelated step -- the failing tool-state fetch was for a different, already-implemented step, kmindex_containment_screen/kmindex_query, whose Tool Shed fetch fails per the already-tracked cli defect above). `/tmp/dv.err` was empty; `/tmp/dv.out`'s first bytes were the literal diagnostic text `toolshed fetch failed (...` (confirmed via `head -c 1 | xxd` = `t`, not `{`), not JSON. Had to manually locate the first line starting with `{` and slice from there before `json.loads` would parse the report. The same command without `--json` (plain human-readable mode) is unaffected since it is not claiming to emit machine-parseable output. Non-blocking this iteration only because the diagnostic text happened to precede rather than interleave with the JSON block, and because I fell back to line-scanning; a caller doing a naive `stdout | jq` would hard-fail.
raised by
advance-galaxy-draft-step (phase 6)
observed at
issue
https://github.com/galaxyproject/foundry/issues/548#issuecomment-5733272931
gxwf-tool-search-underscore-repo-slug-query-zero-hitsminordefectgalaxy-tool-util-ts / @galaxy-tool-util/cli (gxwf tool-search) -- Tool Shed query tokenizer/ranker

`gxwf tool-search "collapse_collections"` (the literal Tool Shed repo-slug for the exact wrapper this iteration needed, toolshed.g2.bx.psu.edu/repos/nml/collapse_collections) returns `No hits for query: collapse_collections` and exits 2. The space-joined equivalent, `gxwf tool-search "collapse collections"`, also returns zero hits. Only a differently-worded query -- `gxwf tool-search "nml collapse"` (owner name plus one word) or `gxwf tool-search "Collapse Collection"` (the tool's display name, not its repo/id) -- surfaces the tool, and even then only as a lower-ranked hit (#3 of 5) in the owner-name case.

expected
The query tokenizer/ranker should score a repo-slug-style query (an underscore-joined or space-joined form of the actual `owner/repo` or `tool_id` string) as at least a partial match against that same repo's own `owner/repo` and `tool_id` fields, rather than zero hits -- a query built directly from a known real repo slug is a common, reasonable way to search and should not require the caller to already know the tool's display name or owner to find it.
evidence
Reproduced directly this iteration while resolving kmindex_hit_concat's wrapper (same wrapper already pinned earlier in this run as combine_gene_panel_to_bulk_fasta, nml/collapse_collections/collapse_dataset v5.1.0). `gxwf tool-search "collapse_collections"` and `gxwf tool-search "collapse collections"` both returned no hits; `gxwf tool-search "nml collapse"` returned the correct tool as row 3 of 5; `gxwf tool-search "Collapse Collection"` returned it as row 1 of 2. Did not block this iteration (the wrapper identity was already known from the draft's own Identity-pinned `tool_id` and a prior same-run resolution), but would block or mislead a cold discover-shed-tool search that started from only a Tool Shed repo slug.
raised by
advance-galaxy-draft-step (phase 6)
observed at
issue
https://github.com/galaxyproject/foundry/issues/574
implement-galaxy-tool-step-udt-binding-undocumentedminorgapimplement-galaxy-tool-step

summarize-galaxy-tool's own Inputs section states 'Authored UDTs from author-galaxy-tool-wrapper bypass this Mold,' correctly routing a locally-authored `GalaxyUserTool` around tool-summary generation. But nothing downstream documents what happens next: implement-galaxy-tool-step's declared Inputs list only `galaxy-tool-summary` (never a `galaxy-user-tool-definition`), and its procedure text (step 2, 'Bind to the tool summary') only covers a Tool-Shed-pinned wrapper or a bare/stock built-in id -- there is no documented convention for how a step's `tool_id`/`tool_version`/`state` should be populated when the resolved wrapper is an authored UDT instead of either of those two cases (e.g. whether `tool_id` should mirror the UDT's own `id` field with no `tool_shed_repository` block, by analogy to a bare/stock id, or something else).

expected
Extend implement-galaxy-tool-step's declared Inputs to include the `galaxy-user-tool-definition` artifact as an alternate input when the discover-or-author branch fell through to authoring, and add an explicit procedure step (or sub-case under step 2) for binding a step to a UDT: what `tool_id`/`tool_version` should hold, that no `tool_shed_repository` block applies, and how the UDT's own declared `inputs`/`outputs` names become the step's `in:`/`out:` port names -- mirroring the level of detail already given for the Tool-Shed-pin and bare/stock-id cases.
evidence
Authored a GalaxyUserTool wrapper this iteration for a step with a confirmed Tool Shed discovery miss. Absent any documented binding convention, proceeded by analogy: set the step's `tool_id` to the UDT's own `id`, `tool_version` to its `version`, and no `tool_shed_repository` block (treating it like a bare/stock tool id). `gxwf draft-validate --concrete` accepted this shape (`draft valid`, `Concrete: OK`) -- the tool_id triggered a live Tool Shed lookup that 404'd and was gracefully downgraded to a `skip_tool_not_found` (the same non-fatal bucket used for an unrelated tool whose fetch failed for network reasons), not validated against the UDT's own declared contract at all. So the binding convention used happened to pass, but this was inferred from a different case's documented pattern, and draft-validate's accept path gives no positive confirmation that a UDT-backed step's ports/state were checked against anything real.
raised by
advance-galaxy-draft-step (phase 6)
observed at
issue
https://github.com/galaxyproject/foundry/issues/573
paper-to-test-data-no-scoping-or-toolshed-fixture-guidanceminorgappaper-to-test-data

paper-to-test-data's SKILL.md is a single-paragraph procedure ('read freeform-summary, derive test inputs/outputs') with no packaged Load-On-Demand references and no guidance at all for the ordinary case this run hit: the paper's own named datasets (kmindex Logan shards, LexicMap Logan indices) are production/external-service scale and cannot become a fast test fixture as named. Its next-in-chain sibling, find-test-data, packages exactly this guidance -- references/notes/iwc-test-data-conventions.md's 'small is a documented subset of a real source, not a fabricated stand-in' rule, plus an explicit step to search IWC/Tool-Shed fixtures when the source's own named data is the wrong shape/scale. Run head-to-head on the same freeform-summary (this run's phix174 kmindex/LexicMap workflow), paper-to-test-data alone could only restate the summary's already-flagged gaps, while find-test-data's packaged convention led directly to real, reusable, already-committed Tool-Shed test-data (galaxyproject/tools-iuc tools/kmindex/test-data and tools/lexicmap/test-data) that resolved the equivalent structural fixture.

expected
paper-to-test-data should either package the same scoping-down / prefer-upstream-test-fixture guidance find-test-data has (so it is not systematically the weaker half of its own declared fallback chain for any workflow with externally-hosted/production-scale reference data), or its own doc should say explicitly when to fall through early (e.g. 'when the paper's cited data is production/external-service scale and not itself a downloadable fixture, this skill's output should mark those inputs resolved: false and the caller should proceed to find-test-data without re-deriving from the same summary') rather than leaving that judgment entirely to the calling harness.
evidence
This run (draft-manuscript-galaxy, phase 7): freeform-summary.md names 109 kmindex Logan shards and up to 25 LexicMap Logan indices (Stage B/C) as the workflow's reference-data universe, all hosted only at usegalaxy.org production scale; paper-to-test-data's procedure and references gave no path to anything smaller. find-test-data's iwc-test-data-conventions.md note, read for the same task, pointed directly at checking the pinned tools' own Tool Shed test-data directories, which surfaced real, already-CI-tested small fixtures (tools-iuc kmindex_query.xml test #6 'using register index', lexicmap.xml tests #3/#4/#6) usable as structural smoke-test data for this workflow's kmindex_containment_screen and lexicmap_search steps. Not blocking this run (the harness's own branch protocol tries both skills in order), but paper-to-test-data contributed no incremental value beyond a plain re-read of freeform-summary.md for this workflow's two hardest inputs.
raised by
paper-to-test-data (phase 7)
observed at
issue
https://github.com/galaxyproject/foundry/issues/575
tests-format-schema-silent-on-sample-sheet-column-definitions-shapeminorgapiwc-test-data-conventions (Collection.rows / sample_sheet shape)

galaxy-workflow.gxwf.yml's primary input, gene_query_panel, is `collection_type: sample_sheet` with 4 optional per-element `column_definitions` (the per-gene LexicMap sensitivity overrides). tests-format.schema.json's `Collection` $def does carry a `rows` field (additionalProperties: column-name -> array) seemingly meant for exactly this, but neither iwc-test-data-conventions.md (this skill's authoritative note on job/input YAML shapes, which documents List/Paired/list:paired/list:list:paired/composite_data in detail) nor any other packaged note mentions `sample_sheet`, `column_definitions`, or `rows` at all, and a corpus grep for these terms across the whole skill bundle returns nothing beyond the bare schema field.

expected
Add a worked `sample_sheet` + `rows:` example to iwc-test-data-conventions.md (or a note it references) alongside the existing collection-shape sections, so a Mold does not have to infer the shape from the schema's generic field alone.
evidence
galaxy-workflow.gxwf-tests.yml's test case 2 encodes gene_query_panel's per-gene align_min_match_pident/align_min_match_len/seed_min_prefix/min_qcov_per_genome overrides as `rows: {align_min_match_pident: [60.0, null], ...}` alongside `elements:` -- a reasoned best-effort construction against the bare schema field, passing `gxwf validate-tests --workflow` cleanly, but with no corpus precedent to confirm it is actually what Planemo/Galaxy expects at runtime.
raised by
implement-galaxy-workflow-test (phase 9)
observed at
issue
https://github.com/galaxyproject/foundry/issues/579

Timeline

how the draft grew

no checkpoint history — re-run with --checkpoint to get a per-phase and per-iteration record.

Everything else

files no Mold declares

14 of 34 files map to a declared artifact. The rest are below. 3 path(s) were ignored entirely.

sub-mold5 — declared by a Mold a phase invokes internally rather than by a phase itself
pathsizemodifieddeclared by
foundry-issue-drafts.md71.6 KB2026-09-18 18:33report-foundry-run-feedback
foundry-run-review.md14.6 KB2026-09-18 18:33report-foundry-run-feedback
galaxy-tool-pin.json3.2 KB2026-09-18 18:33discover-shed-tool
galaxy-tool-summary.json12.6 KB2026-09-18 18:33summarize-galaxy-tool
galaxy-user-tool.yml61.1 KB2026-09-18 18:33author-galaxy-tool-wrapper
tool-output6 — output of a tool the run drove, not an artifact any Mold declares
pathsizemodifieddeclared by
planemo-test1-output.html339.5 KB2026-09-18 18:33
planemo-test1-output.json2.9 KB2026-09-18 18:33
planemo-test1.log222.5 KB2026-09-18 18:33
planemo-test2-output.html340.3 KB2026-09-18 18:33
planemo-test2-output.json5.3 KB2026-09-18 18:33
planemo-test2.log221.7 KB2026-09-18 18:33
undeclared9 — no Mold declares this — should it be an output artifact?
pathsizemodifieddeclared by
deploy_fix.sh376 B2026-09-18 18:33
deploy_workflow.sh2.4 KB2026-09-18 18:33
draft-extract-report.json349 B2026-09-18 18:33
fix_payload.sh407 B2026-09-18 18:33
galaxy-user-tool-flatten-gene-summary.yml8.8 KB2026-09-18 18:33
galaxy-user-tool-kmindex-hit-dedup-max-score.yml9.2 KB2026-09-18 18:33
galaxy-vs-paper-comparison.md21.2 KB2026-09-18 18:33
lexicmap_streamer_fix.diff9.3 KB2026-09-18 18:33
paper-scale-invocation-params.json2.5 KB2026-09-18 18:33