Plan format
What belongs in a plan?
A Plan names a question, version, operation and evidence state. Its targets contain
compositions and stable identities for world pairing, construction and mechanism
streams. The shared EvaluationSpec defines independent repetitions; the
NumericalPolicy defines arithmetic and random-stream policy.
The current portable syntax is format brainlesslab-plan, version 4:
format = "brainlesslab-plan"format_version = 4id = "cue-example"operation = "profile"question = "Can this reservoir retain a transient cue for 32 ticks?"version = "1"evidence = "exploratory"
[evaluation]blocks = 2trials_per_block = 4horizon = 48warmup = 0construction_scope = "block"root_seed = 97seed_partition = "development"
[numerics]dtype = "float64"fast_math = falsereduction = "ordered"rng = "philox-host-v1"
[[targets]]id = "baseline"controller = "reservoir"[targets.composition]count = 32input_gain = 1.0[targets.composition.node]kind = "sorn"[targets.composition.task]kind = "delayed_cue"[targets.composition.task.options]delays = [32]Save this as a new TOML file, then pass its path to brainlesslab check. The
maintained repository example can be checked directly:
uv run brainlesslab check python/plans/delayed-cue.tomlA successful check reports resolved targets, task ports, horizons and seed policy without simulation. Unknown options, incompatible horizons and unsupported evidence claims fail before execution.
Fields and defaults
Unknown fields are rejected. TOML has no null value: omit evaluation.horizon to
use each task’s default. Python API defaults are the same as portable-plan defaults.
| Table | Fields and defaults |
|---|---|
| Root | Required format, format_version, id and at least one target; operation="profile", question="", version="1", evidence="exploratory", diagnostic=false |
evaluation | blocks=1, trials_per_block=1, omitted horizon, warmup=0, construction_scope="block", root_seed=0, seed_partition="development" |
numerics | dtype="float64", fast_math=false, reduction="ordered", rng="philox-host-v1" |
targets | Required unique id; label="", pairing_key="paired-worlds", construction_key="paired-construction", mechanism_key="paired-mechanism", controller="reservoir", no interventions |
targets.composition | count=200, input_gain=1.0 |
targets.composition.node | kind="falandays"; parameters table defaults to empty |
targets.composition.task | kind="delayed_cue"; options table defaults to empty |
targets.interventions | Array of tables with required tick and verb |
Operations are profile, sweep, ablate, benchmark and calibrate. The development
runner accepts planned, exploratory, tuned, frozen and retired evidence states;
it rejects confirmed and promoted. A state label does not establish evidence.
Blocks, trials, node count and one-based intervention ticks must be positive integers.
Root seed and warm-up must be non-negative integers. A supplied horizon must exceed
warm-up and contain the task’s scoring opportunity. Construction scope is
evaluation, block or trial; its inferential meaning is explained in
trials, blocks and random streams.
Numerics support float64 or float32 with strict ordered reduction, disabled fast math and the versioned host RNG. Input gain must be finite and non-negative. Controller availability and model/task options are checked against the selected task and model.
Timed interventions
Add interventions after the target’s task options, for example:
[[targets.interventions]]tick = 16verb = "freeze_weights"The supported verbs are freeze_weights, freeze_plasticity, blind_input and
shuffle_input. They require a reservoir controller and a valid tick within the
horizon. Redundant interventions and changes that cannot affect the configured
mechanism are rejected. Read paired comparisons
before treating an intervention as a causal control.
Keep execution choices separate
ExecutionSpec controls backend, batch size, managed memory, cache, thread count and
recording. These choices do not belong in the scientific TOML plan and must not
silently shorten a task or reduce the declared node count.
read_plan(path) and write_plan(plan, path) provide the Python boundary.
Profile, sweep, ablation, benchmark and calibration use the same plan schema.
The run command preserves both submitted and resolved values in a record.
See evaluation for seed and reset rules, then records to inspect a completed run.