Imported from galaxyproject/foundry (
AGENTS.md). Install upstream withnpx skills add galaxyproject/foundry. Copyright stays with the author.
Working in the Galaxy Workflow Foundry
Read first
Read content/meta/glossary.md immediately at session start. The Foundry uses domain-specific terminology — Mold, Pipeline, Phase, Branch, Cast, Pattern, CLI Mold, Foundry, axis, … — that isn't standard Galaxy or workflow vocabulary. The glossary is small, alphabetical, and worth loading in full before reasoning about anything else here. Misreading a Mold note without knowing what "Mold" means leads nowhere good.
Then orient
README.md— what this project is and why.content/meta/architecture.md— short system map and reading routes across the focused architecture records.content/meta/code-architecture.md— packages, applications, dependency direction, and implementation contracts.content/meta/content-model.md— note kinds, frontmatter, tags, links, references, and companions.content/meta/build-and-validation.md— validation, generation, casting, assembly, site builds, and drift gates.content/meta/repository-layout.md— physical placement and authored/generated ownership boundaries.content/meta/molds.md— Mold bucketing axes and the Mold-versus-reference boundary. Membership lives incontent/molds/.content/meta/mold-spec.md— Mold authoring contract (frontmatter, references, eval/usage/refinement). Load when authoring or editing a Mold or itseval.md.content/meta/harness-pipelines.md— pipeline narrative behindcontent/pipelines/.content/meta/casting.md— casting design.content/meta/corpus.md— IWC grounding; URL-not-mirror principle.
Authoring rules
- Frontmatter is contract. The single source of truth is the zod schema in
@galaxy-foundry/gxwf-foundry-note-schema, shared by the validator and the Astro site — there is no separate JSON-Schema mirror. One directory per note kind underpackages/gxwf-foundry-note-schema/src/types/, each holdingschema.ts(the contract),kind.md(what the kind is for, and why each required field is required), andexample.md(a minimal valid note);types/context.tsholds the base envelope and shared field primitives,types/index.tsis the one enumeration, andnote-schema.ts(buildNoteSchema) only assembles them into the discriminated union. Every kind is.strict(), so unknown fields are rejected. Add a field to that kind'ssrc/types/<kind>/schema.tsbefore using it in frontmatter anywhere. - Tags must be registered. Every tag a note uses lives in
meta_tags.yml. Vocabulary changes touch one file. - Wiki-link fields use
[[Target]]. Single-value fields (parent_pattern) and array fields (related_notes,related_patterns,related_molds,patterns,cli_commands,prompts). - Never wrap a body wiki-link in backticks. A backtick means this is the syntax, not this is a link — that is how
content/meta/architecture.mdnames the token and howcontent/research/gxy-sketches-alignment/index.mdwrites the template slot[[summary-<source>]]. The remark transform rewrites text nodes only, so a backticked citation never becomes a link. Write[[Target]]bare in prose. - Polished IWC references should survive corpus churn. Pattern pages, Mold pages, and other polished content should cite abstract IWC workflow IDs without generated extensions or fixture roots, e.g.
transcriptomics/rnaseq-pe/rnaseq-pe, plus step labels or step IDs when needed. Do not cite generated.ga/.gxwf.ymlpaths or line numbers in polished pages; reserve those for surveys, ad-hoc research notes, and local debugging evidence. - Validate before commit.
npm run validatechecks schema + cross-file resolution. Errors block; warnings are advisory. - A fixture is a claim, so check it. Any artifact you commit under
examples/asserts "this is what that Mold emits".make check-fixturessettles the schema half against the validator the Mold's cast declares — fix the fixture when it fails, never the schema. The other half no gate can settle: a fixture must also be able to produce the outcome the scenario bound to it claims. A schema-valid example that withholds what the Mold needs to reach its stated verdict is still a defect. - Mold IO schemas live in their packages. Source of truth for Foundry-authored schemas (
summary-nextflow,galaxy-tool-discovery) ispackages/<name>-schema/src/<name>.schema.json. The vendored test schema (tests) lives inpackages/tests-format-schema/src/, synced from@galaxy-tool-util/schema. Mold frontmatter cites schemas via[[wiki-link]]to atype: schemanote incontent/schemas/<name>.md; the note declarespackageandpackage_export, and cast imports the named runtime export at build time and serializes it into the bundle. Producer Molds attach a schema to their output viaoutput_artifacts[].schema; consumers inherit via sharedid. There is nocontent/schemas/*.schema.jsonmirror — only the human-readable schema notes live there. - Don't edit generated files by hand.
Dashboard.mdandIndex.mdare produced byscripts/generate-*.ts. Cast bundles undercasts/(SKILL.md,_provenance.json,_verify.json, copied references) are produced byfoundry-build cast/scripts/cast-mold.ts; change the Mold, caster, schema package, or reference source and regenerate instead. Assembled pipeline harnesses undercasts/claude/skills/pipeline-*/(SKILL.md,_assembly.json) are produced byfoundry-build assemble-pipeline <slug>/make assemble-pipelines; they project the Pipeline note'sphases:spine plus each Mold'ssummary/loop_endstateand the pipeline'sharness_notes— edit those sources and regenerate, don't hand-edit the harness.make check-assemble-pipelinesis the byte-diff drift gate. If generated cast files conflict during cherry-pick/merge, prefer rerunning the caster after resolving source files, not hand-patching generated JSON.glossary.mdis hand-curated and skipped by the validator.
Don't
- Don't weaken the schema to accept a non-conforming note. Reshape the note or extend the schema deliberately (with tests).
- Don't add ad-hoc frontmatter fields.
additionalProperties: falserejects them. - Don't write multi-paragraph comments in code. One short line max, only when intent isn't obvious from the code.
- Don't use Obsidian Templater. Foundry doesn't carry it; slash commands handle scaffolding.
Run
npm run validate # schema + cross-file checks
npm run test # vitest (root: validator + content tests)
npm run typecheck # tsc --noEmit (foundry-internal scripts/)
npm run format # prettier --check across every formatted directory
npm run format-fix # prettier --write across the same
npm run lint # eslint across the same
npm run packages-test # vitest across packages/* via pnpm -r
npm run packages-typecheck # tsc --noEmit across packages/* via pnpm -r
npm run packages-build # tsc emit across packages/*
Prettier and eslint cover packages/*/{src,test}, tests/ and scripts/ — every TypeScript directory that is ours. The one carve-out is a // prettier-ignore on the aligned Mold table in scripts/one-time/seed-mold-stubs.ts, which is one table rather than one directory. Enforcement also runs via pre-commit (.pre-commit-config.yaml). Install once per clone with pre-commit install; mirrors the galaxy-tool-util setup.
The top-level Makefile mirrors common entry points:
make validate # npm run validate
make test # npm run test
make typecheck # npm run typecheck
make fixtures # materialize Nextflow fixtures + IWC format2 + IWC skeletons
make fixtures-nextflow # materialize workflow-fixtures/pipelines/
make fixtures-cwl # materialize workflow-fixtures/cwl/
make fixtures-iwc # materialize workflow-fixtures/iwc-src, iwc-cleaned, iwc-format2
make fixtures-skeletons # materialize workflow-fixtures/iwc-skeletons from iwc-format2
make fixtures-verify # verify materialized fixture SHAs
make fixtures-clean # remove generated fixture dirs
make check is the full gate, and CI runs every part of it:
make check # validate check-generated check-planemo-pin check-vendored
# check-casts check-verify check-assemble-pipelines check-fixtures test
Two of those are worth knowing separately:
make check-fixturesruns every committed artifact fixture through the validator its Mold's cast declares, resolved from that cast's_verify.json. Nothing else looks atexamples/— a greenvalidatesays the notes are well formed, never that a fixture is what it claims to be. It also prints which declared artifacts have no committed fixture at all.make check-vendoredchecks the URL-sourced vendored files everywhere, and skips the ones resolving throughcommon_paths.ymlwhen the upstream checkout is absent, naming each. It reports the scope it actually covered;npm run check:vendored -- --strictfails instead of skipping, for a machine that has every upstream cloned.
Vendored planemo artifacts
Foundry vendors two planemo JSON artifacts so contributor laptops and CI don't need planemo installed:
packages/planemo-test-report-schema/src/test-report.schema.json— JSON Schema forplanemo test --test_output_json. Powers the convergence-loop gate in [[convert-nfcore-module-to-galaxy-tool]].packages/planemo-cli-meta/src/cli-meta.json— minimal command list feeding the validator's cli-command coverage check.
The vendored artifacts pin to the planemo release recorded in content/cli/planemo/index.md. planemo is only required when regenerating these artifacts. Normal Foundry work — npm run validate, npm run test, npm run packages-test, make validate, make test — reads the checked-in JSON.
Regenerate with:
make sync-planemo # all vendored planemo artifacts
make sync-planemo-cli # CLI manual pages under content/cli/planemo/
make sync-planemo-cli-meta # packages/planemo-cli-meta/
make sync-planemo-test-report-schema # packages/planemo-test-report-schema/
make check-planemo-cli # fail on planemo CLI page drift (CI)
Install the pinned planemo via:
uvx --from planemo==<version> planemo --version
Take the <version> from content/cli/planemo/index.md's package_version.
Generated fixtures
workflow-fixtures/ is the generated-corpus workspace used for research, not committed content. The generated directories are gitignored and may be absent in a fresh worktree:
workflow-fixtures/pipelines/— pinned Nextflow pipeline clones fromworkflow-fixtures/fixtures.yaml.workflow-fixtures/cwl/— pinned CWL workflow/tool repository clones fromworkflow-fixtures/fixtures.yaml.workflow-fixtures/iwc-src/— pinned IWC clone.workflow-fixtures/iwc-cleaned/— intermediate cleaned Galaxy workflows.workflow-fixtures/iwc-format2/— cleaned gxformat2 IWC corpus, cited as$IWC_FORMAT2/...in surveys and ad-hoc research only.workflow-fixtures/iwc-skeletons/— structural-only views, cited as$IWC_SKELETONS/...in surveys and ad-hoc research only.
Before launching or acting as a research subagent that needs corpus evidence, check whether the needed generated dirs exist. If they are missing, use the top-level fixture targets above. If you cannot materialize them, stop and report the missing target instead of inventing evidence.
When launching research subagents, ask for evidence quality explicitly. Reports should separate corpus-observed claims, architectural or design inferences, external-doc claims, and speculative or low-confidence claims. Do not let plausible mappings stand as corpus evidence unless they cite fixtures or existing Foundry notes.
For IWC survey work, prefer make fixtures-iwc fixtures-skeletons before mining $IWC_FORMAT2 or $IWC_SKELETONS. For Nextflow example work, prefer make fixtures-nextflow before reading workflow-fixtures/pipelines/. For CWL example work, prefer make fixtures-cwl before reading workflow-fixtures/cwl/.
Package layout
Publishable CLIs live under packages/<name>/ as a pnpm workspace; mirrors galaxy-tool-util-ts's structure. Runtime packages include @galaxy-foundry/summarize-nextflow; build/authoring tooling lives in @galaxy-foundry/build-cli with the foundry-build bin. Top-level scripts/ files are compatibility wrappers or repo-local one-offs. pnpm 10.x is the package manager (packageManager field is contractual). The npm wrappers above invoke pnpm -r under the hood.