# neurogenesis-sim: a short overview

This file is generated by `scripts/build_context.py` from the repository's documentation, for AI assistants and
readers who want the full picture without browsing the repository. Section 1 is generated from the code and the docs
(state, open work); the rest is the documentation as published, in the order of the site. Code blocks are real
commands and APIs; claims about results are about simulations. Repository: https://github.com/jobellet/neurogenesis-sim


# 1. Project status (generated)

- Commit `ba72f05` of 2026-11-04; file generated 2026-11-04.
- Registered developmental stages (32): `apoptosis`, `arbor_synapses`, `assign_receptors`, `cell_cycle_clock`, `choice_point`, `cluster_boutons`, `competitive_elimination`, `connect_by_hand`, `critical_period_gate`, `differentiate`, `express`, `express_receptors`, `fasciculate`, `freeze`, `grow_arbors`, `grow_axons`, `migrate`, `mosaic`, `myelinate`, `partner_select`, `pharmacology`, `place_by_hand`, `proliferate`, `prune`, `refine_by_activity`, `scale`, `seed_cells`, `set_transmitters`, `sort`, `temporal_competence`, `tissue_expand`, `transporter_switch`.
- Test functions: 514 in `tests/`.

## Open pull requests

- none

## Not done yet (collected from the roadmap, the stage reference and the PLACEHOLDER notes)

- (roadmap) Development: `BodyPlan` (regions, projections), one fixed growth order (placement → sign → differentiation → identity → axons), rule registry in 5 phases (placement, shift, target, probability, weight), knockouts, tonic currents; geometry, fields, `Tissue`, stage schedule (A1–A5, B1–B5, C1–C13, D2, D3; see `docs/STAGES.md`): chunked growth (D4), and the parts of C8, D1 and D2 marked partial below
- (roadmap) C8: partial: guidance rules as a stage; dense only up to 2048 cells per side, sparse cell-list search above (only three probability rules there, see D2); errors on missing guidance; `expression_gradient` target rule (target map from named graded expression columns, per axis gain and sign, min-max or raw levels; dense and sparse)
- (roadmap) B5 (Field operations): partial: `Tissue.cycling` (bool, per cell; `True` for `seed_cells` / `proliferate`, `False` for `place_by_hand`; carried by `add_cells` / `compact` / `subset` / `concatenate` / `to_network` / `from_network`; `proliferate` divides only cycling cells) done; `SparseConnectivity.plastic` (bool, per synapse; None = all plastic; carried by `take` / `concat` / `append` / `compact` / `subset` / `concatenate` and, in memory only, by `to_network` / `from_network`; `refine_by_activity`, `prune`, `scale` and `neuromodulate` leave non-plastic synapses untouched) done; `contacts` (C19) done.
- (roadmap) C19: partial: `contacts` and weight scaling done; `post_node` placement waits for N2/N3
- (roadmap) C18, C20: not done
- (roadmap) D2 (Sparse guidance): partial: `sparse_guidance` with an exact (dense) mode and a cell-list mode supporting three probability rules (`identity_expression`, `no_autapse`, `source_sign`); `grow_axons` uses the cell-list mode by default above 2048 cells per side (#44). The sparse mode draws different random numbers from the dense one, and the legacy `grow()` stays dense (fingerprints).
- (roadmap) K4b (Longer delays in the developmental stages): partial (#72): `grow_axons` (and its streamed variant), `connect_by_hand`, `myelinate`, `dendritic_attenuate` and `freeze` use the `max_delay` Param, default the storage bound of 255 ticks (`MAX_DELAY_TICKS`), and warn only when clipping. Still clipped at 31: `arbor_synapses` (`neurogenesis/stages/arbors.py`) and the connectome importer (`neurogenesis/data/importer.py`).
- (roadmap) J8 (Gene-expression atlases as fields): partial: annotation atlases as geometries (`neurogenesis.data.atlas`: NRRD / MetaImage volumes, structure ontologies with descendants, `structure_geometry` → `VoxelMaskGeometry`, `fit_to_box`), used by `examples/atlas_relay_mask.py` for the retina → relay example, run on the real P4 annotation of the Allen Developing Mouse Brain Atlas (manifest `examples/datasets/allen-devmouse-p4.json`; run 3 of the retina → relay use case, relay shaped by p2A because the P4 3D annotation does not delineate the dLGN). Gene-expression grids as fields and registration between ages are not done.
- (docs/background/literature.md) A comparison table with measured numbers (time to grow and simulate a reference circuit) against Cx3D / BioDynaMo, Brian 2 and NEST; a BibTeX file of all references; and short summaries of how each listed model maps onto toolbox stages and Params.
- (docs/changelog.md) Versioned release notes generated from tagged releases.
- (docs/citing.md) Software citation (Zenodo DOI per release, `CITATION.cff`) and the paper describing the toolbox, with BibTeX.
- (docs/faq.md) Questions collected from users once the repository is public.
- (docs/getting-started/installation.md) Download links to the release page, checksums, and screenshots of the installer on each platform, once the first release is tagged.
- (docs/getting-started/installation.md) `pip install neurogenesis-sim` from PyPI and a conda-forge package, once the package is published.
- (docs/integration/bridge.md) Small client libraries (`neurogenesis-bridge` for Node and Julia), and an example notebook driving the bridge from MATLAB.
- (docs/integration/cluster.md) A complete cluster recipe (SLURM and a cloud alternative): environment setup, GPU selection, checkpoint / resume of evolution, gathering islands, and measured scaling of simulate_counts with the number of networks.
- (docs/integration/file-formats.md) Further formats (roadmap phase J): NIR, PyNN scripts, NeuroML 2 / LEMS (Gleeson et al. 2010), gene-expression atlas grids as fields, NWB / neo recordings as fitting targets.
- (docs/integration/other-simulators.md) Cross-simulator checks (J6): the same grown networks simulated in the toolbox and, through SONATA and PyNN, in NEST and Brian 2, with spike statistics compared against declared tolerances.
- (docs/reference/cli.md) Planned: `neurogenesis run`, `neurogenesis stages --json`, `neurogenesis data list`.
- (docs/tutorials/cli.md) Planned commands: `neurogenesis run project.json` (run a Project's schedule and save the network), `neurogenesis stages --json` and `neurogenesis ui-schema` (catalogue of stages and Params, task H3), `neurogenesis validate module.json` (re-run a module's assays, task E4), `neurogenesis data fetch` (connectome datasets, task I1). An animated terminal recording (asciinema) of this tutorial.
- (docs/tutorials/desktop-apps.md) Screenshots of each app (network view, inspector, live development preview, schedule editor generated from the UI schema, evolution progress), a GIF of growing and simulating a project end to end, and installation instructions for the released packages.
- (docs/tutorials/fields-geometry.md) Figures: a gallery of geometries (sampled points), a layer stack painted on a curved sheet, and a pinwheel map with its charges; a GIF of cells migrating along a gradient until a stop field. Tutorial for painting fields in the desktop apps' field painter.
- (docs/tutorials/genomes-evolution.md) Tutorial on multi-island runs on a cluster (SLURM array jobs), checkpointing and resuming evolution, and a gallery of evolved modules with their audit reports.
- (docs/tutorials/index.md) Jupyter notebook versions of every tutorial (rendered with myst-nb, runnable on Binder / Colab), and a video walkthrough of tutorials 1–4.
- (docs/tutorials/modules.md) A module registry (roadmap G1): `neurogenesis install <module>`, semantic versions, compatibility with toolbox versions, and a browsable gallery of published modules with their validation reports and screenshots.
- (docs/tutorials/neuron-models-cost.md) A table of measured throughput on reference hardware (laptop CPU, workstation GPU, Apple silicon) and a "which model can I afford?" interactive calculator.
- (docs/tutorials/plasticity.md) Figures: the STDP window measured from the implementation; weight distributions before and after refinement by spontaneous waves; a GIF of receptive fields sharpening during activity-dependent refinement.
- (docs/tutorials/rules-plugins.md) A cookiecutter template for a plugin / module repository (package layout, tests, CI, docs) and a community index of published plugins.
- (docs/tutorials/schedules.md) A full worked example — a layered sheet grown from progenitors (seed → proliferate → migrate into layers → differentiate by layer → grow axons → refine by spontaneous waves → prune) — once the fix wave is merged (roadmap milestone M2, example G2.3), with a GIF of every stage.
- (docs/tutorials/viewer.md) A GIF of the viewer simulating a network while the camera orbits (`docs/_scripts/viewer_capture.py` writes it, but headless software-WebGL capture was too heavy for the documentation build machine; capture it on a desktop with a GPU).
- (docs/tutorials/viewer.md) A hosted web demo on GitHub Pages (the built viewer with preset networks), embedded in this page.
- (docs/use-cases/connectome-constrained.md) The full example once phases I and P are merged: dataset download, the imported subset in the viewer, the grown circuit next to it, and the comparison of their type-level statistics.
- (docs/use-cases/developmental-hypotheses.md) A worked knockout study on the topographic-map example (which genes are necessary for topography, measured across held-out seeds), with figures.
- (docs/use-cases/shared-modules.md) A worked example module (an ON / OFF sensory stage) with its capacity test, evolution logs, audit report and screenshots, published in its own repository and composed with the topographic-map example.
- (docs/use-cases/teaching.md) Ready-to-use course material: a 2-hour practical with exercises and solutions, slides, and a hosted web demo that needs no installation.
- (docs/use-cases/topographic-map.md) A quantitative study: precision vs sigma and number of map cells, across 100 development seeds, with and without activity-dependent refinement.
- (docs/STAGES.md) Not implemented: the inside-out layering test case as a test of `migrate` alone.
- (docs/STAGES.md) Not implemented: pruning inside the stage (follow with `prune`), other neuron models.
- (docs/STAGES.md) Not implemented: the legacy `receptor_sign` rule is not re-expressed as a profile.


# README

## neurogenesis-sim

**Grow spiking neural networks the way nervous systems are built, by hand, by genes, or both, and simulate them
cheaply.**
### Documentation
**<https://jobellet.github.io/neurogenesis-sim/>**: tutorials, use cases, integration guides, stage and API
reference, related work. **For AI assistants:** the whole documentation, with a generated status section (what
exists, what is not done, open pull requests), as one Markdown file to paste or upload into a chat:
[neurogenesis-sim-context.md](https://jobellet.github.io/neurogenesis-sim/neurogenesis-sim-context.md) (~70k tokens)
or the short [neurogenesis-sim-brief.md](https://jobellet.github.io/neurogenesis-sim/neurogenesis-sim-brief.md)
(~11k tokens); `python scripts/build_context.py` makes them locally. The site is built from `docs/` by `.github/workflows/docs.yml`; to build it locally:
`pip install -r docs/requirements.txt && sphinx-build -b html docs docs/_build/html`. Key files:
- `docs/ROADMAP.md`: target architecture (geometry, fields, tissue, stages, parameter sources, GUI), design rules and
  the task list.
- `AGENTS.md`: rules for contributors and agents (determinism, backward compatibility, low compute, tests).
- `docs/EXTENDING.md`: rules, plugins, knockouts, tonic currents, module projects.
- `docs/STAGES.md`: the registered stages, geometries, fields and sparse guidance: parameters, defaults, limits.
- `docs/NEURON_MODELS.md`: neuron models, units, cost estimates.
- `CONTRIBUTING.md`: code and module contributions.
- `docs/THIRD_PARTY.md`: software used and the literature behind each mechanism.
  
neurogenesis-sim is a general toolbox for building circuits through development. You describe where tissue is (2D or 3D
shapes) and what is already known about it (layers, areas, maps, cell positions). You then choose a sequence of
developmental stages (cell division, migration, differentiation, axon growth, pruning, activity-dependent refinement
...), and for every parameter of every stage you decide whether it is:
- set **by hand**;
- read from a **hand-drawn field** (for example a layer boundary or an orientation map);
- controlled by **genes** (and then evolved);
- or **fitted to data**.

The result is an integer leaky integrate-and-fire network, or a more detailed one, that can be simulated, measured,
evolved and shared as a module.

| Workflow | What you specify | What development does |
|---|---|---|
| Supervised (by hand) | geometry, cells, connections or connection rules | compiles and simulates exactly what you specified |
| Unsupervised (genetic) | a genome and a schedule of stages | genes control every stage; evolution searches genomes that work for every developmental seed |
| Semi-supervised | a hand-made scaffold (e.g. cortical layers, cytochrome-oxidase blobs, pinwheel centres) plus a schedule | genes and fitted parameters work on top of the scaffold |

The toolbox makes no assumption about species, organ, task or environment. Projects that use it define their own
geometries, stages, stimuli and objectives, and can publish working circuits (for example a retina with ON/OFF ganglion
cells) as modules that others reuse as-is.

**Status (2026-11-02).** Implemented and tested: the spiking kernels and neuron models, cost estimates, genomes and
evolution, modules with a registry and validation assays, geometries and fields, a configurable schedule of developmental
stages (`docs/STAGES.md`), supervised fitting (CMA-ES), connectome data import, pharmacology profiles, branching arbors
with SWC I/O, SONATA export / import, the bridge, the browser viewer and the macOS app. In progress: the Windows / Linux
app (H5). Planned: the remaining stages of the second wave (C18, C19, C20), further export formats (J3–J5: NIR, PyNN,
NeuroML 2), and lifting the remaining 31-tick delay clip in arbor synapses and the connectome importer (K4b; other
stages accept delays up to 255 ticks). Configurable stages are
young and their API may still change. Everything open is in `docs/ROADMAP.md` (tasks for parallel development, rules in
`AGENTS.md`); the generated status section of the AI context file (`scripts/build_context.py`) lists it in one place.

### What exists today
| Piece | Module | What it is |
|---|---|---|
| Spiking kernel | `neurogenesis.spiking` | Integer LIF neurons (bit-shift leak and synaptic decay, per-neuron threshold, refractory period, Poisson drivers, bursters, axonal delays up to 255 ticks through a multi-word spike history, neuron indices up to 2³², an array-backed synapse store). Identical spikes in Python (`reference`), JAX (`jax_backend`, CPU or GPU), the browser and the C library `nglif`. `batch.simulate_counts` runs many networks on sequences of stimuli. |
| Neuron models | `neurogenesis.spiking.models` | `lif_int` (default), `two_compartment` (soma + dendrite) and `hh` (Hodgkin–Huxley), switchable per simulation on the same network, sharing synapses, delays and drivers. See `docs/NEURON_MODELS.md`. |
| Cost estimates | `neurogenesis.cost` | Memory and time per model before running, calibrated on the actual machine (`python -m neurogenesis estimate --neurons 3e8 --synapses-per-neuron 5000`). Every simulation refuses networks that cannot fit. |
| Body plans and growth | `neurogenesis.development` | Regions (fixed or grown placement, roles, imposed sign) and allowed projections; one growth procedure: placement and sign → lateral-inhibition differentiation → molecular identity → axon guidance. Deterministic per development seed; parallel growth. |
| Developmental rules | `neurogenesis.development.rules` | Extension points in 5 phases. **placement:** mosaics. **guidance shift / target / probability:** identity-dependent targets and receptor expression, point-to-point topography, targets read from graded expression, laminar targeting, no autapse, sign-specific projections. **weight:** sign-inverting receptors. Each rule is inactive unless its gene is present; plugins travel with plans. |
| Knockouts, tonic currents | `neurogenesis.development` | `knockout(genome, regions, projections)`; standing currents per cell type (`genome["tonic"]`). |
| Genomes | `neurogenesis.genome` | Nested dicts; genes addressed by paths (into arrays too), coded in [0, 1] for evolution, grouped by mechanism, saved as JSON. |
| Evolution | `neurogenesis.evolution` | Island model with fresh development seeds each generation; choice on validation seeds; audits on held-out seeds (fitness = worst + 0.25 × mean − cost). |
| Modules | `neurogenesis.modules` | `Module` = plan + genome + inputs / outputs + validation + provenance + neuron model + version, saved as JSON; `compose` assembles modules (prefixed names, each keeps its genes, plugins and rules merged); a local registry (`python -m neurogenesis install`, `registry.get`). |
| Parameter profiles | `neurogenesis.profiles` | Default parameters for a species, region or age with the status of every number (`measured`, `derived`, `assumed`, `free`), its source and what was read; `extends` for species and region layers; `python -m neurogenesis profile check --all`. The toolbox never depends on a profile: any value can be a `Gene`, `Field` or `Fit`. |
| Validation | `neurogenesis.validation` | Declarative assays stored in modules (stimuli per region, readout, metric, gate, knockouts), rerun by `python -m neurogenesis validate module.json`. |
| Fitting | `neurogenesis.fitting`, `neurogenesis.evolution.semi_supervised` | `Fit` params fitted to data targets (cell counts, densities, layer thickness, connection statistics, firing rates) with CMA-ES over several development seeds (`python -m neurogenesis fit`); genes evolved with an inner fitting loop; Pareto evolution. |
| Development schedule | `neurogenesis.stages`, `neurogenesis.devcost` | A Project's ordered stages (seed, cell_cycle_clock, proliferate, apoptosis, tissue_expand, migrate, sort, mosaic, express, temporal_competence, differentiate, critical_period_gate, grow_axons, fasciculate, choice_point, partner_select, place / connect by hand, prune, scale, refine_by_activity, competitive_elimination, myelinate, freeze), each parameter a `Param`; cost per stage before running (`python -m neurogenesis estimate --project p.json`). Chunked growth streamed to disk for very large tissues (`neurogenesis.streaming`). See `docs/STAGES.md`. |
| Arbors, pharmacology, data | `neurogenesis.arbors`, `neurogenesis.pharmacology`, `neurogenesis.data` | Branching arbors (SWC I/O, `grow_arbors`, synapses with path-length delays); transmitter / receptor profiles compiled to signed weights by developmental context, and a per-cell chloride reversal potential that switches with maturation (`transporter_switch`); connectome manifests, verified downloads and streaming import (`python -m neurogenesis data fetch`); volume-transmitted neuromodulation (`neurogenesis.neuromodulation`) and passive dendritic attenuation (`neurogenesis.dendritic`). |
| Geometry and fields | `neurogenesis.geometry`, `neurogenesis.fields` | Primitives, CSG, meshes and voxel masks (`.npz`); grid, analytic, vector, label, layer-stack and pinwheel fields, gradients and distances; every field usable as a `Param`. |
| Interoperability | `neurogenesis.interop` | Export / import with a report of what is exact, approximated or dropped: SONATA (`python -m neurogenesis export net.json --format sonata --out dir`), exact round trip; one shared translation of the integer neuron into a current-based exponential LIF. |
| Bridge and apps | `neurogenesis.bridge`, `desktop/` | JSON-lines server (`python -m neurogenesis.bridge`), NGB1 binary networks, UI schema export (`python -m neurogenesis ui-schema`); native macOS app; Windows / Linux app in progress. |
| Analysis | `neurogenesis.analysis` | Frequency–current curves (from rest), mosaic regularity. |
| Viewer | `viz/` | Browser 3D viewer and sandbox (three.js): imports network JSON, shows neurons by role and sign, rasters, per-neuron inspection and editing. |

### Install and try
```
pip install -e ".[test]"                    # Python >= 3.10: numpy, jax (CPU; "jax[cuda12]" for GPU), matplotlib
cd viz && npm ci && npm run build:kernel && cd ..   # browser kernel, for the equivalence tests
JAX_PLATFORMS=cpu pytest -q
python examples/topographic_map.py --cpu    # a sensor sheet -> map circuit grown from a genome
python examples/hand_built_network.py      # supervised: every cell and synapse by hand
python examples/hand_drawn_column.py --cpu # semi-supervised: hand-drawn layers, genes choose cell types
python examples/pinwheel_sheet.py --cpu    # semi-supervised: density follows hand-placed pinwheels
python examples/evolved_development.py     # unsupervised: a genetic schedule evolved on a toy objective
python -m neurogenesis estimate --neurons 1e5 --synapses-per-neuron 1000 --seconds 1
cd viz && npm run dev                       # viewer at http://localhost:5173; import example_out/network.json
```

```python
from neurogenesis.development import BodyPlan, FixedPlacement, Region, grow
from neurogenesis.spiking.batch import simulate_counts
from neurogenesis.modules import Module

plan = BodyPlan("demo", regions=[Region("sensor", (0, 0, 0), (30, 30, 5), FixedPlacement(labels), role=1),
                                 Region("map", (50, 0, 0), (30, 30, 10))], projections=[("sensor", "map")])
net = grow(plan, genome, seed=0)                              # an SNNNetwork; net.save_json("network.json")
counts = simulate_counts([net], [currents], ticks=100, model="lif_int")   # or "two_compartment", "hh"
Module("demo", plan, genome, inputs=["sensor"], outputs=["map"]).save("demo.module.json")
```

### Continuous integration
GitHub Actions (`.github/workflows/ci.yml`), on every push:
- every test on Python 3.10 and 3.12;
- the browser kernel compiled, so that the Python / JAX / browser equivalence tests run and are never skipped;
- fixed CPU performance benchmarks on main, reported against the previous main run on the same machine type (report only; a regression above 30% is flagged);
- the cost estimator from the command line;
- the viewer type-checked and built.

### Reproducibility
- Same plan + genome + development seed → the same network, bit for bit.
- Same network + kernel seed → the same `lif_int` spikes in Python, JAX and the browser. Float models are deterministic
  per platform.
- Projects that depend on the toolbox should freeze fingerprints of the networks their results come from, and test them.

### Citing
See `CITATION.cff` (GitHub's "Cite this repository" button), and cite the methods and datasets you use
(`docs/THIRD_PARTY.md`).

### Licence
MIT (`LICENSE`). Third-party software and data keep their own licences (`docs/THIRD_PARTY.md`).


# Page: getting-started/concepts.md

## Core concepts

```text
Project (JSON + .npz, versioned schema)
├── Geometry          2D / 3D shapes: primitives, meshes, voxel masks
├── Fields            hand-made or generated data on the geometry (gradients, layers, maps, point sets)
├── Genome            nested dict of genes (numbers addressed by paths), evolvable
├── Schedule          ordered list of stages; each stage = operator + parameters (Params)
└── Plan              the original BodyPlan, still usable (compiled into a default schedule)

Tissue  (struct of arrays that stages transform: positions, lineage, types, expression, signs, connectivity)
   │  developmental stages: seed_cells, proliferate, apoptosis, migrate, sort, express, differentiate,
   │                         grow_axons, prune, scale, myelinate, refine_by_activity, ...
   ▼
SNNNetwork  →  simulate (lif_int | two_compartment | hh)  →  spikes, rates, metrics  →  fitness / fit / module
```

### Body plan
A `BodyPlan` lists **regions** (boxes in space with a placement rule, a role —
internal, input or output — and an optional imposed sign) and the **projections** allowed between them. `grow(plan,
genome, seed)` runs the fixed growth procedure: placement and sign → lateral-inhibition differentiation → molecular
identity → axon guidance. Same plan + genome + seed → the same network, bit for bit.

### Genome and genes
A genome is a nested dictionary of numbers and arrays. A **gene** is a path into it plus bounds, for example
`(("guidance", ("sensor", "map"), "sigma"), 0.02, 0.5)`. Genes are coded in [0, 1] for evolution
(`to_unit`, `from_unit`) and saved as JSON
(projection keys become `"src->dst"`). Gene groups (`guidance_genes`, `body_genes`, ...) collect the genes of a
mechanism.

### Rules
Rules are small functions in five phases (placement, guidance shift / target / probability, weight) that modify the
growth procedure. A rule is **inactive unless its gene is present**, so adding it to a plan changes no existing
network, and rules never draw random numbers. See extending.

### Stages and schedules (experimental)
A **stage** is a registered operator `Tissue × Params × rng → Tissue`. A **schedule** is an ordered list of stages,
each optionally repeated or conditioned (`when`). Each repetition gets its own random stream, derived from the
development seed and the stage name, so inserting a stage does not change the randomness of the others.

### Params
Every stage parameter is a **Param**, which says where its value comes from:

| Param | Meaning | JSON |
|---|---|---|
| `Const` | set by hand | `{"type": "Const", "value": 0.5}` |
| `Gene` | read from the genome (evolvable) | `{"type": "Gene", "path": ["death", "p"], "lo": 0, "hi": 0.5}` |
| `Field` | read from a field at each cell's position | `{"type": "Field", "name": "gradient", "transform": "log"}` |
| `Fit` | fitted to data (supervised) | `{"type": "Fit", "target": "...", "init": 1, "lo": 0, "hi": 2}` |
| `Expr` | a formula of other values | `{"type": "Expr", "formula": "2 * x"}` |

### Tissue
The `Tissue` is the state that stages transform: positions (float64), parent and clone
ids (lineage), birth stage, generation, cycling flag, cell type, region, expression channels, sign, neuron parameters,
alive flag, and sparse connectivity (pre, post, weight, delay). `tissue.to_network()` compiles it into an `SNNNetwork`.

### Spiking network and neuron models
An `SNNNetwork` holds neurons (integer LIF parameters: leak shift, synaptic shift, threshold, refractory period;
or drivers: Poisson, burster) and synapses (weight, delay in ticks of 1 ms, up to 255). The same network runs with
`lif_int` (bit-identical across implementations), `two_compartment` or `hh`. See neuron models.

### Evolution
`evolve` runs one island: each generation is evaluated on **fresh development
seeds**, so selected genomes must work for every developmental outcome, not one lucky network. `choose` picks the
best on validation seeds, `audit` re-tests on held-out seeds (fitness = worst + 0.25 × mean − cost).

### Modules
A `Module` = plan + genome + inputs / outputs + validation + provenance + neuron model,
saved as JSON. `compose` assembles modules into a larger system (region names get a prefix, each module keeps its
genes, links add projections).

### Determinism
- Same inputs and seed → identical outputs (development and the integer kernel).
- Float models are deterministic per platform.
- Projects that depend on the toolbox should freeze **fingerprints** of the networks their results come from.


# Page: background/design-principles.md

## Design principles

1. **General.** No species, organ, task or environment inside the toolbox. Projects bring their own regions, stimuli
   and objectives; species-specific data (transmitter profiles, datasets) are data files outside the core.
2. **Every parameter has a declared source.** By hand, from a field, from genes, fitted to data, or a formula — the
   same stage works in supervised, unsupervised and semi-supervised workflows.
3. **Deterministic.** Seeds in, identical networks and integer spikes out. Rules draw no random numbers; each stage
   repetition has its own random stream.
4. **Backward compatible.** New options are off by default; existing plans and genomes grow the same networks
   (checked by fingerprints).
5. **Low compute.** Linear in cells and synapses, local interactions through a shared cell list, integer kernels,
   struct-of-arrays. Every stage and model declares its cost, and the toolbox refuses what cannot fit before running.
6. **One kernel, several implementations, identical spikes.** Python, JAX, browser and C; any change to one is made to
   all, with equivalence tests.
7. **Robust to development.** Genomes are selected for working across development seeds, not for one network.
8. **Honest claims.** Results are statements about simulations; biological mechanisms are cited, and fidelity is not
   claimed beyond what is implemented and tested.
9. **Shareable.** Circuits are modules; extensions are plugins; apps learn the toolbox's stages and Params at run time.


# Page: development/agents.md

## Rules for contributors and coding agents


### What this repository is
A general toolbox to grow spiking neural networks from genes and hand-made specifications, simulate them cheaply, and
share working circuits as modules. The target is in `README.md` and the plan in `docs/ROADMAP.md`. **Pick one task from
the roadmap (e.g. "C4 migrate"), and stay within its scope.**

### Before you start
0. Get the overview in one read. `python scripts/build_context.py` writes two Markdown files built from the
   documentation (also published on the documentation site and as the `ai-context` artifact of the docs workflow):
   - `neurogenesis-sim-brief.md` (about 11k tokens): project status, README, core concepts, design principles, these
     rules, the CLI and a map of the package. Read it first.
   - `neurogenesis-sim-context.md` (about 70k tokens): the same status section, then every documentation page (roadmap,
     stage reference, formats, protocols, tutorials) in one file.

   Their first section is generated: commit, registered stages, open pull requests, and everything the docs mark as
   partial, not done, PLACEHOLDER or **Not implemented**. Check there that your task is not already done or in an open
   pull request. Both files are generated: never edit or commit them.
1. Read `README.md`, `docs/ROADMAP.md` (sections 1–3 and your task), `docs/EXTENDING.md`, `docs/NEURON_MODELS.md`.
2. Install and run the tests:
   ```
   pip install -e ".[test]"
   cd viz && npm ci && npm run build:kernel && cd ..   # browser kernel, for the equivalence tests
   JAX_PLATFORMS=cpu pytest -q
   ```
   All tests must pass before and after your change, and none may be skipped (CI fails on skipped kernel tests).
3. Work on a branch `task/<id>-<short-name>` and open a pull request that names the task id. Do not push to `main`.

### Invariants: never break these
- **Determinism.**
  - Same inputs and seed give identical outputs.
  - Development randomness comes only from the random streams given to a stage (`rng` argument, one stream per stage,
    see roadmap §2.1).
  - Rules (`neurogenesis.development.rules`) never draw random numbers.
  - Never use global NumPy random state, `random`, or time.
  - `legacy_stream` mode in `run_schedule()` exists exclusively for backward compatibility with legacy plans (fingerprints).
    New schedules must never use `legacy_stream=True`: it breaks the one-stream-per-stage isolation rule.
- **Backward compatibility.**
  - Existing plans and genomes must grow the same networks: `tests/test_development.py` and the legacy-compiler
    fingerprints of task A5.
  - New options are off by default.
  - If a change must alter existing networks, stop and ask the maintainer.
- **Kernel equivalence.** `lif_int` gives identical spikes in Python (`spiking/reference.py`), JAX
  (`spiking/jax_backend.py`), the browser (`viz/src/sim/kernel.ts`), and the portable C kernel `nglif` (`desktop/common/native/nglif/`). Any change to one must be made to all four,
  with the equivalence tests passing.
- **Desktop apps & shared contracts ownership.**
  - Jules agents never edit `desktop/mac/` (owned by the Mac agent) nor `desktop/avalonia/` (owned by the Avalonia agent).
  - `desktop/common/` and `neurogenesis/bridge/` are shared contracts (protocol, NGB1 binary network format, UI schema, visual spec, C kernel `nglif`, golden fixtures, runtime scripts).
  - Change them only in dedicated tasks with a version bump, an updated spec, and all apps' CI passing.
- **Protocol & schema versioning.** Any change to `desktop/common/PROTOCOL.md`, `UI_SCHEMA.md` or Project schema requires backward compatibility, explicit versioning and migration tests.
- **Generality.** No species, organ, task or environment names inside `neurogenesis/`. Use them only in `examples/`,
  in tests as toy content, or in separate module repositories.
- **Contracts.** The Project schema (A1), `Tissue` (A2), `Param` (A3) and the Stage interface (A4) are shared.
  - Change them only within those tasks, or in a dedicated PR that updates every user and the schema version.
  - A change to a contract must also update the docs, migrations and tests.

### Low-compute rules
- Scale linearly: O(N) cells, O(E) synapses.
  - Local interactions go through the shared cell list (task D1).
  - No dense N × N or Ns × Nd arrays except below a documented threshold (state it in the docstring, e.g. `N <= 2048`).
- Use struct-of-arrays, float32 (int32 for the integer kernel), vectorised NumPy or JAX, and no Python loops over
  cells or synapses in hot paths.
- Every stage and model declares its cost (bytes and operations as functions of N, E and its parameters).
  `neurogenesis.cost` uses this before running and refuses what cannot fit. Add a test that the declared cost is within
  a factor 3 of measurement.
- Prefer the CPU path working everywhere: GPUs must be optional, and results must not depend on the device beyond
  floating-point tolerance (integer paths are exact).

### How to add things
| You add... | Where | Must also |
|---|---|---|
| a developmental stage | `neurogenesis/stages/<name>.py`, `@register_stage` | params as `Param`s, cost declaration, neutral parameters = no-op, toy-tissue behaviour test, a docs entry |
| a guidance / placement / weight rule | `neurogenesis/development/rules.py` or a plugin, `@register(phase, name)` | inactive without its genes; listed in the plan's rules; test |
| a neuron model | `neurogenesis/spiking/models/<name>.py`, `register_model` | use `base.drivers` and `base.transmit`; `state_bytes`, `flops`, `substeps`; known-property tests; add to the parametrised tests in `tests/test_models.py` |
| a geometry or field type | `neurogenesis/geometry/`, `neurogenesis/fields/` | JSON round trip through the Project schema; sampling test |
| a GUI panel | `viz/src/ui/` | reads and writes Project files only (no hidden state); `npm run build` passes |
| an example | `examples/<name>.py` | runs on a laptop CPU in under ~5 min; a test in `tests/test_examples.py` |

### Style
- Match the surrounding code: concise docstrings that say what a function does and its units, few comments, and names
  that say what things are.
- Biological mechanisms in docstrings cite their source (first author, year, journal). Do not claim biological fidelity
  beyond what is implemented and tested.
- Units:
  - one tick = 1 ms;
  - local positions in [0, 1]³ inside a region's box;
  - space units in the box (they set conduction delays);
  - currents in toolbox units unless a model states its physical mapping.
- Commit messages: imperative summary line, a body saying what changed and how it was tested.

### Continuous integration
The repository is public, so GitHub-hosted CI is free: every pull request runs the jobs its changes touch (path
filters), and merges to `main` rebuild and publish the documentation site and the AI context files.
- **Do not use `[skip ci]`**, in pull-request commits or in squash-merge titles: every pull request is checked, and
  `main` must be built and its site published after every merge.
- Run the tests locally before pushing anyway (CI is the check, not the debugger), and batch commits: one push per
  finished step.
- All jobs (Python, viewer, `nglif` on Ubuntu / macOS / Windows, `mac-app`) run on every non-draft pull request whose
  files they cover, on `main` and by hand (`workflow_dispatch`); draft pull requests run the Python tests only.
  Runners and their variables are described in `.github/RUNNERS.md`.
- A pull request merges with green checks. Paste the local test summary in the description only when a check cannot
  run (e.g. a macOS-only step).

### Testing checklist for a pull request
- [ ] `JAX_PLATFORMS=cpu pytest -q` passes locally, with nothing skipped (kernel tests need `npm run build:kernel`).
- [ ] CI checks green (or, for a step CI cannot run, the local command and summary line in the description).
- [ ] Commits batched (one push per finished step); no `[skip ci]` in the squash title.
- [ ] New code has tests: determinism; neutral parameters = no-op; the documented behaviour; the cost declaration.
- [ ] Existing networks unchanged (development fingerprints).
- [ ] `cd viz && npm run build` passes if `viz/` changed.
- [ ] Golden fixtures and contract tests pass if `desktop/common/`, `neurogenesis/bridge/`, or `nglif` changed.
- [ ] Design and scope review pass against AGENTS.md and task contracts before merging.
- [ ] Docs updated: README status block and table (checked by `tests/test_readme_status.py`), `docs/EXTENDING.md` or the relevant guide, the roadmap status line of your task,
      `docs/STAGES.md` for a stage, and any PLACEHOLDER your work fills. The status section of the AI context files is
      built from these, so a stale status line or placeholder shows up there as work still to do.

### When unsure
Prefer the smallest change that fulfils the task's acceptance tests. Ask (in the PR) rather than changing a contract,
adding a heavy dependency, or altering existing networks. Pure-Python dependencies beyond numpy / jax / matplotlib need
the maintainer's approval.


# Page: reference/cli.md

## Command-line reference

### `python -m neurogenesis`

| Command | Purpose | Key options |
|---|---|---|
| `generate` | preset network (column, layered, microcircuit) | `--neurons --morphology --exc-ratio --pace-ratio --radius --height --layers --conduction-velocity --weight-scale --inh-scale --refractory --seed --out` |
| `simulate` | run the integer reference kernel | `--network --ticks --raster --seed` |
| `stats` | topology and degree statistics | `--network` |
| `export-presets` | three preset networks for the viewer | `--out-dir` |
| `estimate` | memory and time per neuron model; with `--project`, of a development schedule stage by stage | `--neurons --synapses-per-neuron --seconds --model (repeatable) --project --no-calibrate` |
| `fit` | fit a Project's `Fit` params to data targets (CMA-ES) | `--project --targets --seeds --iterations --seed --out` |
| `validate` | rerun a module's validation assays (exit 1 on failure) | `module.json --assays` |
| `install` | install a module into the local catalogue | `module.json --catalogue --force` |
| `modules` | list installed modules | `--catalogue` |
| `data info` / `data fetch` | dataset size, license, citation; resumable, checksum-verified download | `dataset --manifest --target --yes` |
| `profile check` / `profile show` / `profile report` | check that every parameter of a profile has a status and a source (exit 1 on failure); list parameters with their status; what a project's parameters rest on (`metadata.profiles`, genes, `Fit`) | `profiles --all --online`, `project` |
| `ui-schema` | export the versioned UI schema JSON for the desktop apps | `--project --calibrated` |
| `export` | write a network (JSON or NGB1) in another format; prints the export report | `network --format {sonata} --out` |
| `import` | read a network from another format into network JSON | `path --format {sonata} --out` |

Every command has `--help`. Worked examples: cli.

### `python -m neurogenesis.bridge`
JSON-lines server for apps and other programs. No options; see bridge protocol.

### Environment variables
| Variable | Effect |
|---|---|
| `JAX_PLATFORMS=cpu` | force JAX onto the CPU |
| `XLA_PYTHON_CLIENT_MEM_FRACTION` | fraction of GPU memory JAX may take |
| `NEUROGENESIS_CACHE` | calibration cache directory (default `~/.cache/neurogenesis`) |
| `NEUROGENESIS_MODULES` | module catalogue directory (default `~/.cache/neurogenesis/modules`) |
| `NEUROGENESIS_DATA`, `NEUROGENESIS_DATASETS` | dataset cache; extra manifest directory |
| `NEUROGENESIS_PROFILES` | pharmacology profile directory |

> **PLACEHOLDER.** Planned: `neurogenesis run`, `neurogenesis stages --json`, `neurogenesis data list`.


# Package map (each module's first docstring line)

- `neurogenesis/__init__.py`: neurogenesis-sim: spiking networks grown from genes.
- `neurogenesis/__main__.py`: python -m neurogenesis: command-line generation, simulation and statistics of networks.
- `neurogenesis/analysis.py`: Measures on grown networks.
- `neurogenesis/arbors.py`: Arbor morphologies as struct of arrays (N1): `ArborStore`, SWC read / write, path lengths, downsampling.
- `neurogenesis/bridge/__init__.py`: Bridge between the toolbox and its clients (the desktop apps): a JSON-lines server and the NGB1 network format.
- `neurogenesis/bridge/__main__.py`: Entry point of `python -m neurogenesis.bridge`: runs the local bridge server (`server.main`).
- `neurogenesis/bridge/ngb.py`: NGB1: the binary network format exchanged between the bridge and the desktop apps (desktop/common/PROTOCOL.md).
- `neurogenesis/bridge/server.py`: JSON-lines server that lets desktop apps (and any other client) drive the toolbox: python -m neurogenesis.bridge
- `neurogenesis/cli.py`: Command Line Interface (CLI) for SNN Morphogenetic Network Generation & Simulation.
- `neurogenesis/cost.py`: Compute cost of a simulation before running it: memory, operations and wall time, per neuron model, on this machine.
- `neurogenesis/data/__init__.py`: Connectome data layer (Phase I): dataset manifests and downloads, streaming import, registration, weight mapping.
- `neurogenesis/data/atlas.py`: Annotation atlases as geometries (part of roadmap J8): read a labelled volume and its structure ontology, and turn
- `neurogenesis/data/catalogue.py`: Dataset manifests and the resumable, checksum-verified downloader (I1).
- `neurogenesis/data/importer.py`: Streaming connectome import (I2), coordinate registration (I3) and synapse-count to weight mapping (I4).
- `neurogenesis/data/registration.py`: 
- `neurogenesis/data/skeletons.py`: Connectome skeleton import and simplification (N4).
- `neurogenesis/data/targets.py`: Cell-type statistics of a connectome as fitting targets (I5).
- `neurogenesis/dendritic.py`: Passive dendritic attenuation (N5): synaptic efficacy and delay from the distance along the dendrite.
- `neurogenesis/devcost.py`: Cost of a development schedule before running it (D3): cells, synapses, memory and time per stage.
- `neurogenesis/development/__init__.py`: Development of spiking networks from a body plan and a genome.
- `neurogenesis/development/differentiation.py`: Cell differentiation and molecular identity.
- `neurogenesis/development/grow.py`: Development of a spiking network from a body plan and a genome.
- `neurogenesis/development/legacy_compiler.py`: Legacy compiler (A5): a `BodyPlan` as a Stage schedule.
- `neurogenesis/development/parallel.py`: Parallel development in CPU processes (spawned; JAX restricted to the CPU there). Results equal the serial ones.
- `neurogenesis/development/plan.py`: Body plan: the declarative, genome-independent part of a nervous system.
- `neurogenesis/development/rules.py`: Developmental rules: the extension points of growth.
- `neurogenesis/development/sparse_guidance.py`: Sparse guidance (D2): synapse formation from the guidance rules without an all-pairs matrix.
- `neurogenesis/evolution/__init__.py`: Evolution of genomes (island model) and robustness to developmental randomness.
- `neurogenesis/evolution/islands.py`: Island evolution of genomes coded as [0, 1] gene vectors (neurogenesis.genome).
- `neurogenesis/evolution/robust.py`: Robustness to developmental randomness: a genome must work in every individual it grows, whatever the seed.
- `neurogenesis/evolution/semi_supervised.py`: Semi-supervised optimisation (E3): evolve `Gene` params with `Fit` params refitted in an inner loop or fixed, and
- `neurogenesis/expressions.py`: Restricted safe mathematical and logical expression evaluator.
- `neurogenesis/fields/__init__.py`: Fields (B3-B5): scalar, vector and label fields over space, point patterns and maps, and field operations.
- `neurogenesis/fields/core.py`: Field types (B3) and their JSON registry.
- `neurogenesis/fields/maps.py`: Point patterns and maps (B4).
- `neurogenesis/fields/ops.py`: Field operations (B5), composable in JSON: `Add`, `Subtract`, `Multiply`, `Threshold`, `GaussianSmooth`,
- `neurogenesis/fitting.py`: Supervised fitting of `Fit` params to data targets (E2).
- `neurogenesis/genome/__init__.py`: Genomes: nested dicts of genes; gene addressing, [0, 1] coding, gene groups and JSON.
- `neurogenesis/genome/genes.py`: Genes: (path, low, high) triples addressing values in a nested genome, and their [0, 1] coding for evolution.
- `neurogenesis/genome/groups.py`: Gene groups: the genes of one developmental mechanism for one region or projection.
- `neurogenesis/genome/io.py`: Genomes to and from JSON. Tuple keys (projections) become "src->dst"; arrays become lists and back.
- `neurogenesis/geometry/__init__.py`: Geometries (B1-B2): primitives, set operations, triangle meshes and voxel masks, with a JSON registry.
- `neurogenesis/geometry/mesh.py`: Closed triangle meshes as geometries (B2): `MeshGeometry` with `from_obj` / `from_stl`.
- `neurogenesis/geometry/primitives.py`: Geometry primitives (B1): the `Geometry` interface (`contains`, `sample_points`, `to_dict`), `Box`, `Sphere`,
- `neurogenesis/geometry/voxel.py`: Voxel-mask geometries (B2): `VoxelMaskGeometry`, a boolean occupancy grid with an origin and a voxel pitch.
- `neurogenesis/interop/__init__.py`: Import and export of networks in other simulators' formats (roadmap phase J).
- `neurogenesis/interop/core.py`: Format registry and export reports shared by every importer and exporter (roadmap task J1).
- `neurogenesis/interop/dynamics.py`: One translation of the integer LIF neuron into a current-based exponential LIF, shared by all exporters.
- `neurogenesis/interop/sonata.py`: SONATA network files: writer and reader (roadmap task J2).
- `neurogenesis/modules/__init__.py`: Shareable, composable modules (plan + genome + interface + validation).
- `neurogenesis/modules/module.py`: Shareable modules: a body plan, a genome, an interface and validation records.
- `neurogenesis/modules/registry.py`: Local module registry (G1): versioned modules installed into a catalogue, with toolbox compatibility checks.
- `neurogenesis/neuromodulation.py`: Neuromodulation by volume transmission (P5): a diffuse modulator gating three-factor plasticity.
- `neurogenesis/params.py`: Param sources (A3): how a stage parameter gets its value.
- `neurogenesis/performance.py`: Comparison helpers for fixed performance benchmarks.
- `neurogenesis/pharmacology.py`: Transmitter and receptor pharmacology as data (P1), compiled to signed integer weights (P3).
- `neurogenesis/profiles.py`: Parameter profiles with declared provenance, and profiles that extend other profiles.
- `neurogenesis/project/__init__.py`: Project format (A1): schema and versioning (`schema`), UI schema export for the desktop apps (`ui_schema`).
- `neurogenesis/project/io.py`: Project I/O for reading and writing projects.
- `neurogenesis/project/schema.py`: Project schema validation and migration.
- `neurogenesis/project/ui_schema.py`: UI schema export (H3): `export_ui_schema` describes the stage registry (Params, kinds, bounds, docs, cost
- `neurogenesis/spatial.py`: Cell lists (D1): O(N) fixed-radius neighbour queries without a dense distance matrix.
- `neurogenesis/spiking/__init__.py`: Integer leaky integrate-and-fire networks: data model, reference simulator, JAX kernel (bit-identical), batched runs.
- `neurogenesis/spiking/batch.py`: Batched simulation of many networks with the JAX kernel: each network sees its own sequence of constant stimuli.
- `neurogenesis/spiking/jax_backend.py`: JAX port of the integer spiking kernel (neurogenesis/spiking/reference.py, src/sim/sim.worker.ts), bit for bit.
- `neurogenesis/spiking/models/__init__.py`: Neuron models over one shared transmission layer (synapses, delays, drivers): choose the level of biophysical detail
- `neurogenesis/spiking/models/base.py`: Neuron models: a common interface over one shared transmission layer.
- `neurogenesis/spiking/models/hh.py`: Hodgkin-Huxley point neuron (squid giant axon, Hodgkin & Huxley 1952; modern sign convention, rest near -65 mV).
- `neurogenesis/spiking/models/lif_int.py`: The integer leaky integrate-and-fire kernel (neurogenesis.spiking.jax_backend), bit-identical to the reference.
- `neurogenesis/spiking/models/two_compartment.py`: Two-compartment integrate-and-fire neuron (soma + dendrite): an intermediate level between point neurons and
- `neurogenesis/spiking/morphology.py`: Statistical generation rules and morphogenetic 3D growth cone wiring engine.
- `neurogenesis/spiking/network.py`: Data structures and serialization for 3D Spiking Neural Networks (SNN).
- `neurogenesis/spiking/plasticity.py`: Plasticity rules (E1) on struct-of-arrays synapses, in JAX.
- `neurogenesis/spiking/reference.py`: Fast integer-only SNN simulation engine in Python.
- `neurogenesis/stages/__init__.py`: Stage registry and auto-discovery.
- `neurogenesis/stages/arbors.py`: Arbor growth (N2) and synapses on arbors with path-length conduction delays (N3).
- `neurogenesis/stages/base.py`: Stage interface and scheduler (A4).
- `neurogenesis/stages/bounds.py`: Declared safe ranges of stage parameters.
- `neurogenesis/stages/boutons.py`: Connection multiplicity (C19).
- `neurogenesis/stages/competition.py`: Competitive synapse elimination (C22).
- `neurogenesis/stages/connectivity.py`: Connectivity stages (C8-C9): `grow_axons` (axon guidance and synaptogenesis between region populations through the
- `neurogenesis/stages/critical_period.py`: Critical-period gate (C23): opens and closes synaptic plasticity through the per-synapse `plastic` mask (K6).
- `neurogenesis/stages/differentiation.py`: Expression and differentiation stages (C6-C7, C15).
- `neurogenesis/stages/expansion.py`: Tissue expansion (C24): positions dilate as the cell count grows.
- `neurogenesis/stages/fasciculation.py`: Fasciculation (C16) and Choice Point (C17) developmental stages.
- `neurogenesis/stages/freeze.py`: End of development (C13): validate a tissue and compile it to an `SNNNetwork`.
- `neurogenesis/stages/migration.py`: Migration and sorting stages (C4-C5).
- `neurogenesis/stages/partner.py`: Partner selection by recognition channels (C18).
- `neurogenesis/stages/pharmacology.py`: Transmitters, receptor expression and assignment (P2), and compilation in a developmental context (P3).
- `neurogenesis/stages/population.py`: Population stages (C1-C3, C14).
- `neurogenesis/stages/refinement.py`: Maturation stages (C10-C12): activity-dependent refinement during development.
- `neurogenesis/streaming.py`: Chunked and streaming growth (D4): axon growth for tissues whose synapses do not fit in memory.
- `neurogenesis/tissue.py`: Tissue state (A2): the struct-of-arrays state that stages read and write.
- `neurogenesis/validation.py`: Validation harness (E4): declarative assays stored in a module and rerun by `python -m neurogenesis validate`.
