The InferenceSpec¶
An inference run is described by a typed InferenceSpec — a small JSON document that says
what to infer (probes, priors, systematics, external likelihoods, sampler) without a line
of how. A deterministic compiler turns the spec into the Firecrown factory YAML and the
CosmoSIS pipeline.ini / values.ini / priors.ini. This is the
tool-priority invariant applied to inference: the model picks the
choices, deterministic code owns every emitted byte.
The spec replaces the older text-driven path (parsing ## inference priors: /
## inference sampler: out of the task) as the recommended way to run inference. The legacy
build_cosmosis_inference / run_inference tools still work, but the spec path adds a
checkable document of record and a human review gate.
The document of record¶
The validated spec is copied to inference/{label}/inference_spec.json and its sha256 is
recorded in the compiled manifest.json. Every compiled artefact traces back to exactly
that document — the spec is the record of what was run, editable and re-compilable, not a
pile of hand-tweaked INI files. Each generated file carries a
GENERATED … DO NOT EDIT BY HAND; edit spec, recompile header for the same reason.
Compiler determinism¶
compile_inference is pure given a spec: same spec, byte-identical config. It never guesses
firecrown syntax — the systematics wiring (IA factories, per-bin PhotoZShift /
MultiplicativeShearBias, clustering bias) is read off the installed firecrown, and the
per-parameter defaults come from firecrown's own named constants, so a version bump that
changes a default fails loudly at import rather than silently baking a stale number. The
Boltzmann settings are reconciled: the union of what the two-point likelihood and every
external likelihood need becomes the camb configuration — a CMB likelihood, for instance,
automatically turns on lensed Cℓ and raises lmax, which is easy to forget by hand and
silently biases the theory vector if missed.
Registry curation policy¶
External likelihoods (e.g. Planck) are named, never wired by hand. The likelihood
registry (cosmotron_mcp/inference/likelihood_registry/, one curated YAML per entry)
maps a name to its module, options, nuisance parameters (with literature-standard priors
cited to an in-repo source, never recalled from memory), and Boltzmann requirements. Each
entry carries verified_against provenance; an entry whose module could not be exercised on
the machine that wrote it is marked UNVERIFIED and the loader warns. Adding a likelihood
is a reviewed PR — a new entry with a test — not something a spec can invent. This mirrors
the no-fabrication rule: the system refuses to make up a likelihood or a prior.
The dry-run gate¶
Before a real chain is launched, dry_run_inference runs the compiled config once through
CosmoSIS's test sampler (a single likelihood evaluation) plus static parameter-coverage
checks — every sampled parameter is consumed by some module, every prior names a real
parameter, every registry nuisance is present. The verdict is deterministic: PASS iff
a finite log-likelihood and zero coverage errors. No model judgement, exactly like the
deterministic reviewer and the
systematics gate. A FAIL still returns the compiled
paths and the report so a human can inspect, but the run stops.
The human spec gate¶
The @inference agent drafts the spec, fills its value slots, validates it, and then
stops at SPEC_READY: — the orchestrator presents the parameterisation (sampled
parameters, priors, external likelihoods, sampler) to the user and waits for explicit
approval before anything compiles or launches. It mirrors the plan gate: default-on, and
skippable only by an explicit ## inference gate: skip declaration in the task (see
task syntax) or the session's skip_gates flag — prose never skips.
Skipping the gate skips only the human pause; validation and the dry-run still run, and a
dry-run FAIL still stops the run.