Skip to content

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.