Concepts
The ladder of collectives — nodes, reservoirs, bodies, agents, ensembles — and the sensorimotor contract. Read the ontology →
BrainlessLab is an extensible Julia lab for “brainless” cognition — behaviour that emerges from collectives of simple neuron-like nodes, with no homunculus and no hand-wired control. It is a Diverse Intelligences Summer Institute 2026 project, built as infrastructure for others to run experiments around a settled Falandays baseline.
The two angles share a single object of study: a class of entity — self-organising collectives of minimal, neuron-like units, the same object whether the units are nodes in a reservoir or agents in an ensemble. The work is to characterise that class, and it has two halves.
One half asks what the class can do: each task is not a problem to be solved but a test of a capacity for behavioural complexity — responsiveness, coordination, and, at the frontier, adaptation and memory. The capacities are an open, evolving set, carved by the tasks that probe them, closer to construct-validation than to a benchmark. A score is only a calibrated indicator that a capacity is present, never the capacity itself: a collective self-organises toward its own viability, not toward our task, so that it can be made to do the task is the thing worth measuring — and measuring it honestly means saying what the number is measured against.
The other half asks what makes that possible: the collective dynamics — the qualities (criticality, timescale separation, coupling) a collective must have for a capacity to appear. These are the real payoff, and the two halves meet where the same neurons-as-nodes-within-a-collective signatures are measured at the node scale and the agent scale.
These are the two angles by their proper names: cellular cognition (test and evolve node designs; read a capacity off a calibrated score) and collective intelligence (profile and sweep the dynamics that underwrite it). See Concepts for the ontology and Scoring for what a score means.
[compat] pins julia = "1.10").git clone https://github.com/…/brainless-lab.gitcd brainless-labEverything below runs from the brainless-lab/ root you just entered.
BrainlessLab ships a checked-in Manifest.toml, so you don’t resolve dependency
versions — you reproduce the pinned set. Launch Julia with the project active and
instantiate:
julia --project=. # from brainless-lab/ — activates BrainlessLab's own project
pkg> instantiate # materialise the pinned Manifest.toml (one-time)pkg> add CairoMakie # a Makie backend, for plottingThe compute core is Makie-free — simulate runs headless with no plotting
dependency. Plot methods live in a package extension (BrainlessLabMakieExt) that loads
automatically once a Makie backend is present, which is why CairoMakie is a separate
add rather than a baked-in dependency.
The separate tooling projects (bench/, profile/) have their own environments and are
instantiated in their own directories — see the onboarding notes for that
split.
using BrainlessLab, CairoMakie
sim = simulate(:wall; node=:falandays_base, ticks=300) # stable baseline, 1 agentvisualize(sim) # spike raster + rate + trajectorysimulate runs the rollout and returns a result you can render; visualize assembles a
static figure from it. The first Julia/Makie call spends noticeable time compiling —
that is normal, and repeat calls are much faster.
CairoMakie vs GLMakie — pick by whether you have a display:
CairoMakie draws static figures and GIFs (visualize, animate). It is the
headless-friendly path — use it over SSH, in CI, or with tooling --save / output-path
flags.
GLMakie backs the interactive explore(...) window (Play / Step / speed slider),
which needs a live display:
explore(:torus; node=:falandays_base, n_agents=6) # interactive swarm (needs GLMakie)On a headless machine, save static outputs with CairoMakie instead of opening a window.
A run is only as observable as what it recorded. simulate returns a SimResult
(often bound to sim) — the recorded trace of a rollout, which the visualisation layer
reads off the hot path. What gets kept is gated by record channels: pass
record=[…] to select them, e.g. record=[:effectors] to keep the motor-output vector
each tick. The engine’s only coupling to visualisation is a small channel-gated,
downsampling Recorder; visualize, animate, and replay(sim) all read the resulting
SimResult, and a saved run directory can be loaded back with replay(rundir).
Concepts
The ladder of collectives — nodes, reservoirs, bodies, agents, ensembles — and the sensorimotor contract. Read the ontology →
Tooling
The command-line verbs (bench, profile, sweep, ablate), their run
directories, and the per-project environment split. Set up the tools →