Casting takes a Mold — a typed reference manifest plus a procedural body — and produces a self-contained skill artifact for one target: no links back, no runtime dependency on the source. This record owns the semantics of that transformation and the provenance contract it must satisfy.
The caster is packages/statgen-foundry-cli, invoked as statgen-foundry-build <mold>. Almost all of it is @galaxy-foundry/cast; this Foundry supplies only where its notes are, what its kinds are called, and what a cast document says — everything else is the same wherever casting happens. Placement is declared in casts/claude/_target.yml, and pnpm check:casts re-casts every committed bundle and fails on any byte that moved — silently when nothing did, naming each Mold and what it found when something has. pnpm casts runs the same sweep for its output instead of its verdict, which is how a caster upgrade is absorbed; a Mold with no bundle yet is cast by name with pnpm cast <mold>. Sweeping is the package’s, and which bundles to sweep is ours: only what has been cast is checked, because an uncast Mold here is a decision rather than drift. build-and-validation draws the line between this record and the rest of what runs.
Per-kind dispatch
Casting is not one resolve-and-inline pass. Each reference kind names a transformation, and the kind discriminator is what selects it:
| Reference kind | Transformation | Lands at |
|---|---|---|
pattern | verbatim copy | references/patterns/<slug>.md |
research | verbatim copy | references/notes/<basename> |
Those two are the kinds reference_contract.yml registers, which is to say the kinds real Molds reference. research carries the most weight — the corpus notes behind every referee — and its size is managed by load: on-demand plus a trigger, never by compressing the note.
The parent Foundry registers five more (cli-command, cli-tool, schema, prompt, example) and treats eval as a manifest entry that is never packaged. None of those is registered here, so none has a dispatch rule to describe. Re-adding one is a deliberate one-line edit to reference_contract.yml made when a Mold first needs it, and the dispatch row is written then. A mold reference stays discouraged in either instance: shared content wants factoring into a kind that casts, not a Mold citing a Mold.
Every transformation above is mode: verbatim, which is the only mode this Foundry admits. The substrate ships one other, sidecar, where a renderer turns a note’s frontmatter into a structured runtime artifact. It is narrowed out of the inherited modes vocabulary in site/src/lib/reference-contract.ts, which records why — that renderer is one we would have to write, and we have no caster to write it in.
A narrowed vocabulary is a gate, not a note-to-self. mode: sidecar stayed spelled here long enough for three research refs to reach for it meaning “this source is paywalled, so do not carry it verbatim” — which is a statement about the SOURCE, not about how a bundle is built. That question is settled when a note is written and recorded in its derived: posture; casting an own-words summary verbatim redistributes our words, not the paper’s. Removing the term is what turns that mistake into a schema error at authoring time. Determinism is not a stylistic preference — it is what makes a cast byte-stable, and byte-stability is what makes a --check gate possible at all.
If a cast looks under-instructed, improve the Mold body or the referenced notes and re-cast. Hand-editing a generated SKILL.md puts the fix somewhere the next cast overwrites, and leaves the source still wrong.
Cast from structure, not rendered prose
When an upstream source ships both a structured form and a rendered human form, cast from the structured one: denser per token, schema-regular, and it preserves identifiers a Mold can cite. Reporting standards and checklists are the canonical case — PROBAST-AI signalling questions, ClinGen/PRS-RS items, MIQE — where a machine-readable form exists and the prose version is a site-rendering concern. The same holds for a method that ships a structured assumption or parameter description alongside a narrative vignette.
Empirical checks run at runtime, not cast time
Casting does not run permutation tests, simulations, or calibration. A calibrate Mold packages the procedure for constructing and running an empirical check; the check itself executes when the cast skill runs, against real data. Casting packages the referee; it does not referee.
This is what keeps casting deterministic and read-only. A cast that invoked a simulator would produce a different artifact on every run, and there would be nothing left to drift-check.
Provenance
Every cast writes a required _provenance.json recording the Mold object (name, path, revision, content hash, commit), cast_at, cast_history[], refs[], and the runtime artifacts handoff contract. Each entry in refs[] carries kind, mode, src and dst, used_at, load, evidence, src_hash, and dst_hash, and is sorted by (kind, src) so diffs stay stable.
This is the sharpest distinction from the prior art — a hand-authored skill repository has no derivation lineage to record, and cannot acquire one after the fact (positioning, Pillar 1). Provenance does not get lightened to make a cast smaller.
When casting runs, and how it goes stale
- Triggers — manual (
cast <mold> --target=<target>), CI on Mold change (re-cast and surface the diff), or watch-on-change. - Drift — a cast is stale when the Mold hash, any reference src or dst hash, the deterministic
SKILL.mdrender, or the target adapter changes. A--checkmode enumerates stale casts. - Versioning — no semver on Molds or casts. Identity is content hash plus commit SHA, and re-casting is the migration path.
- Reproducibility — assembly is byte-stable apart from timestamps. With no LLM phase there is no prompt or model identity to record and no non-reproducible byte in the output.
What casting does not do
- It does not write to the knowledge base. Casting is read-only against
content/; every write goes to the cast tree. - It does not run statistical tooling — R, Bioconductor, PLINK, simulators. That is the cast skill’s runtime job, for the reason above.
- It does not update Molds. A weak instruction gets migrated into the Mold body and re-cast, so the correction survives the next cast.
- It does not touch
eval.mdorscenarios.md. Those are how maintainers judge a Mold, and packaging them would hand the cast artifact its own answer key.
Minimum exercise
One target, Claude. Cast a handful of deliberately diverse Molds end to end and read the actual SKILL.md and _provenance.json output before scaling: a critique referee exercising pattern and research against the cautionary-bad corpus, a calibrate referee exercising the runtime-check packaging and probably a cli-command, and a Family-A guardrail exercising established-good corpus references. Diversity is the point — it is what puts every dispatch rule under load. If provenance holds and the artifacts read reasonably, scale.