Skip to content

Configuration reference

Everything a user writes is one of four document kinds: an experiment, a sweep, a schedule, or a reward specification. This page is their complete field-level contract. Every field on it is checked against the models when the documentation is tested, so a field added to the code without a row here fails the build.

Two rules hold for all four:

  • An unknown key is an error, not a no-op. Every model rejects a key it does not declare, with a message naming it — so a misspelled or misplaced key fails at load rather than silently changing nothing.
  • The free-form surfaces are deliberate. kwargs and params mappings pass through untouched to whatever they construct; a schedule's axes are an open set; trace rows and bundle manifests tolerate extra fields. Everything else is closed.

The experiment document

One document fully specifies a run — L1 walks a complete one. Loaded by skyfall-crl run --config, or in Python via ExperimentConfig.from_yaml_file / from_dict.

Section Required Meaning
env yes which environment to build
algorithm yes which backend trains, and with what
rollout no how much experience per update, and in total
regime no which configuration-shift provider labels (and may drive) the run
run no identity and outputs
reward no hand scoring to the composable reward system — absence is meaningful: without it the environment scores itself, which is the Tier-1 path

env

Field Type Default Meaning
id str required A registered Gymnasium id (CartPole-v1) or a dotted package.module:factory — how anything not in the registry, including a module loaded with --plugin, is selected.
kwargs mapping {} Passed to the factory verbatim. Free-form.

algorithm

Field Type Default Meaning
name str required A registered backend (discrete_hill_climbing, ppo, ppo_ewc, ppo_lcm, or one a plugin registered). Checked against the registry at load, so a typo fails before any compute — which also means a plugin's config must be read after the plugin registers.
params mapping {} The backend's constructor arguments. Free-form; seeds like replay_seed and fisher_seed live here.
policy mapping or absent absent The policy the backend trains, when it should not build its own default — required for export, since the bundle must record how to rebuild it.

algorithm.policy

Field Type Default Meaning
id str required A dotted package.module:factory. Resolved at build time, so naming a policy that needs torch costs nothing until the run starts.
kwargs mapping {} Passed to the factory verbatim. Free-form.

rollout

Field Type Default Meaning
window_steps int > 0 64 Steps per window — an administrative slice, one update each; a window boundary ends nothing.
total_steps int > 0 1024 Steps the whole run collects.
auto_reset bool false Start a new episode when one genuinely ends. Off is the safe default: in a persistent world a reset destroys the world. An environment with real terminal states — CartPole — needs it on.

regime

Field Type Default Meaning
provider str constant A registered provider. constant is a stationary control; scheduled follows a schedule; a plugin may register a detector.
params mapping {} The provider's constructor arguments — for scheduled, {schedule: <the mapping, or a path to a YAML file holding it>}. Free-form.

An environment that reports its own labels (info["regime"], the Tier-2 way) wins over this section, which may then be omitted entirely.

run

Everything here ends up in the trace's run metadata, which is what grouping and aggregation key on.

Field Type Default Meaning
name str run Becomes the rows' run_id.
seed int unset Seeds the environment's reset — and nothing else. Anything else the seed should reach is written where it belongs (params, kwargs), which in a sweep is what ${seed} is for.
task str unset The task label, when a sweep varies one.
policy_id str unset Recorded policy identity.
algorithm_id str unset The family label a comparison groups on. Filled in from algorithm.name when unset; a sweep sets it to the family's name.
output_dir str unset Directory to write <run name>/traces.jsonl under.
trace_path str unset Exact trace file path; overrides output_dir.

reward

Field Type Default Meaning
spec str or mapping required if the section is present A registered spec name (paper), an inline specification, or a path to a YAML/JSON file. Naming the section and omitting the spec is an error — there is no default reward, deliberately.

The sweep document

A matrix of experiments as one document — L4 builds one. Loaded by skyfall-crl run --matrix.

Field Type Default Meaning
base mapping required What every cell shares: an experiment document, minus whatever the axes supply.
families mapping one unnamed arm Name → overrides. Each family is one arm; its name becomes the cells' algorithm_id. Two arms may share a backend and differ only in params — a family is an arm, not necessarily an algorithm.
seeds list of int [0] One cell per seed per family (per task).
tasks list or mapping none A task axis: a list of names (labels only) or name → overrides (a task that changes the environment). Cells record the task in run.task; a family that pools several tasks is flagged by aggregate.
output_dir str unset Where every cell writes <cell name>/traces.jsonl.

Merging is section-wise, one level deep. A family's {algorithm: {params: ...}} replaces base's algorithm.params mapping wholesale and keeps algorithm.name; deeper merging is deliberately not done, because a nested merge cannot express removing a key.

${seed} is substituted wherever it appears — exact string matches, however deeply nested — and becomes that cell's integer seed. This is how the seed reaches the policy's initialisation or a replay draw: the author writes it where it belongs, rather than the harness guessing which knob was meant.

Cell names are <family>-seed<N>, or <family>-<task>-seed<N> with a task axis, and become each cell's run.name. Expansion order is family, then task, then seed — families outermost, so an interrupted sweep leaves whole arms finished.

The schedule mapping

The scheduled provider's document — regimes and schedules explains the concepts. Written inline under regime.params.schedule, or as its own YAML file.

Key Type Default Meaning
regimes list required The configurations, in order.
shift_mode abrupt | cyclic | linear_drift abrupt How one gives way to the next: whole at the boundary; wrapping around for as long as the run lasts; or easing numeric axes over the final drift_window steps (values that cannot be blended switch at the window's midpoint).
drift_window int ≥ 1 50 The easing window for linear_drift.

Each entry in regimes:

Key Type Default Meaning
regime_id str required The label the trace records.
duration_steps int until the run ends May be omitted only on the last entry.
alias_of str Repeat another entry's axes under this new label — the recurrence forgetting requires. The origin is recorded on every row.
anything else An axis. The set is deliberately open. Known names something ships code to read: ticket_arrival_rate, chaos_type_distribution, capacity_multiplier, priority_distribution, affected_service_distribution, deadline_tightness_multiplier, demand_surge_multiplier, workforce_capacity, job_duration_distribution, service_level_distribution. A key within a small edit distance of one of these warns (tickt_arival_rate is almost never intentional); a key literally named axes is rejected as certain nesting-by-mistake; a genuinely new name passes untouched.

The reward specification

The reward as data — rewards as data explains the model. Selected by name, written inline, or loaded from a file; resolvable from all three by resolve_reward_spec.

Field Type Default Meaning
name str required The specification's own name, recorded wherever the reward travels.
components list required The terms.
aggregation str weighted_sum How contributions combine. weighted_sum is the only shipped aggregation.
gates list [] Conditional zeroing rules.

Each entry in components:

Field Type Default Meaning
type str required A registered component — one of the seven built-ins, or one a plugin registered. Resolved when the engine is built, not when the document parses.
weight float the component's own Override for this specification.
clip [low, high] the component's own Override for this specification. The clip is also what makes the ceiling derivable.
params mapping {} The component's constructor arguments. Free-form.

Each entry in gates:

Field Type Default Meaning
component str required Whose contribution is gated.
unless_any_positive list of str [] The contribution is zeroed for the step unless at least one named component's contribution is positive — for terms that should pay only alongside real progress.

Four specifications ship as both registered names and editable YAML templates (skyfall_crl/rewards/spec_files/): paper, experiment, eval8, verification_progress — all describing MORPHEUS's operational model, which is why none of them is ever a default.