Repository navigation
arch 0001 packaging versioning
Status: accepted — implemented.
Date: 2026-09-11 · Issue: ARCH-0001 Phased repo split: core library, deploy targets, dashboard
Owner: Capsize Games (maintainer) · Depends on: plans/arch-0001-target-topology.md
Adopt PEP 621 pyproject.toml as the
single packaging authority for each distribution, one file per distribution
under the packages/ workspace. The monolithic setup.py has been retired;
tests/test_packaging_profiles.py now reads the new files.
The four distributions and their import roots are fixed by
plans/arch-0001-target-topology.md:
spikeforge / spikeforge, spikeforge-server / server,
spikeforge-targets / spikeforge_targets, spikeforge-hub / spikeforge_hub. The private npm
package spikeforge-dashboard lives in
capsize-games/spikeforge-dashboard.
Install is one command from a clone — ./install.sh installs all four
distributions editable (core + targets + hub + server) — and, once the
distributions are published, pip install "spikeforge[all]" (library bundle:
core + targets + hub) or pip install spikeforge-server (server).
web is removed from core and became the base dependencies of the server
distribution. The hub, norse, and lava extras migrated to the
distributions that own their code: the hub extra folded into spikeforge-hub's
base dependencies, and norse/lava became spikeforge-targets extras. The
table records the pre-split mapping and the delivered end state.
| Extra (today) | Phase 1 owner | After extraction | Notes |
|---|---|---|---|
dev |
spikeforge |
spikeforge |
pytest, pytest-cov, ruff |
nir |
spikeforge |
spikeforge |
nir_bridge stays in core |
events |
spikeforge |
spikeforge |
events/ stays in core; event_runtime/ moves Phase 3 |
onnx |
spikeforge |
spikeforge |
onnx_bridge stays in core, lazy |
tracking |
spikeforge |
spikeforge |
tracking/ sinks stay in core, lazy |
tracking-wandb |
spikeforge |
spikeforge |
lazy sink |
docs |
spikeforge |
spikeforge |
mkdocs-material |
web |
removed | — | becomes spikeforge-server base deps |
hub |
spikeforge |
spikeforge-hub base dep |
extra removed once hub/ leaves |
norse |
spikeforge |
spikeforge-targets extra |
extra removed once targets/backends/ leaves |
lava |
spikeforge |
spikeforge-targets extra |
extra removed once targets/backends/ leaves |
torch>=2.5, torchvision>=0.20, snntorch>=1.0, matplotlib>=3.8,
Pillow>=10.0, numpy>=1.26, psutil>=5.9 — exactly the current
install_requires in setup.py. None of the core-boundary
forbidden list (plans/arch-0001-core-boundary.md)
appears here, which is what makes a headless install provable.
fastapi>=0.110, uvicorn[standard]>=0.27, websockets>=12.0,
pydantic>=2.5 (the current web extra, promoted to base), plus a pin on the
core distribution and, after Phases 3–4, pins on spikeforge-targets and spikeforge-hub
because 24 server files import those capability roots today.
Each console script is owned by exactly one distribution. The table records the delivered end state.
| Console script | Owner | Entry point |
|---|---|---|
spikeforge |
spikeforge |
main:main |
spikeforge-encodings |
spikeforge |
main_encodings:main |
spikeforge-verify |
spikeforge |
spikeforge.cli.verify:main |
spikeforge-records |
spikeforge |
spikeforge.cli.records_cli:main |
spikeforge-benchmark |
spikeforge |
spikeforge.benchmark.cli:main |
spikeforge-energy |
spikeforge-targets |
spikeforge_targets.energy.cli:main |
spikeforge-targets |
spikeforge-targets |
spikeforge_targets.cli.target_cli:main |
spikeforge-hub |
spikeforge-hub |
spikeforge_hub.cli:main |
spikeforge-server |
spikeforge-server |
server.__main__:main |
No script name is owned by two distributions at once.
-
Per-distribution versions. Each
pyproject.tomlcarries its ownversion. The delivered versions arespikeforge 0.3.0,spikeforge-targets 0.1.0,spikeforge-hub 0.1.0, andspikeforge-server 0.1.0. Satellites pin core with the compatible-release formspikeforge~=0.3.0;spikeforge-serveradditionally pinsspikeforge-targets~=0.1.0andspikeforge-hub~=0.1.0, and the coreallextra bundlesspikeforge-targets~=0.1.0plusspikeforge-hub~=0.1.0. -
Protocol version is independent.
protocol_versionis"1.0"(plans/arch-0001-protocol-contract.md) and does not track any package version. A package release may ship without a protocol change; a protocol change requires its own MINOR/MAJOR rule. -
Cross-repo pinning uses compatible-release on a minor. Satellites pin core
with
spikeforge~=X.Y.0(for0.x,~=0.3.0means>=0.3.0,<0.4.0) because a pre-1.0 minor may be breaking. Core never pins a satellite; the server and monorepo dev environment pin satellites. -
Compatibility matrix. A repo-root
compatibility.jsonrecords, per release tag, the exact triples (satellite version, core version,protocol_version) and the dashboard bundle version. CI asserts every satellite's declared pin equals the matrix entry, and the release workflow refuses to publish a satellite whose core pin is not in the matrix.
{
"protocol_version": "1.0",
"releases": [
{ "spikeforge": "0.3.0", "spikeforge-server": "0.1.0",
"spikeforge-targets": "0.1.0", "spikeforge-hub": "0.1.0", "dashboard": "0.1.0" }
]
}-
Tag scheme.
<distribution>-v<version>, for examplespikeforge-v0.3.0orspikeforge-server-v0.1.0. Tags are the only release trigger. -
Workflow. A single
.github/workflows/release.ymlparses the tag prefix, selectspackages/<distribution>, runspython -m build, and publishes to PyPI with OIDC trusted publishing (no long-lived tokens). One job definition, many distributions, so the per-repo CI overhead concern inplans/repo_topology_plan.md§5 stays bounded. -
Dashboard. The npm package is
private: true, so there is no npm publish. A dashboard "release" builds the Vite bundle and publishes a versioned build artifact;spikeforge-serverconsumes a pinned bundle version fromcompatibility.json. After the Phase 2 extraction this artifact is built incapsize-games/spikeforge-dashboard, not here. -
Ordering. Core tags first; satellites pin the just-released core; the
protocol authority (
protocol/) is published only as part of a core release. A protocolprotocol_versionbump is always accompanied by a server release and a dashboard bundle release, in that order.
The proof is external, not asserted: the headless CI step builds
packages/spikeforge with no extras, installs the wheel into a clean
venv, asserts importlib.util.find_spec is None for all thirteen forbidden
distributions, imports spikeforge, and asserts the wheel contains no
server/ entries. The runtime equivalent is the extended blocked-deps gate.
Both are specified in
plans/arch-0001-core-boundary.md. The two
mechanisms are complementary: the wheel test proves the artifact is clean; the
blocker proves the code degrades honestly when the SDKs vanish.
Extraction was always additive first, subtractive second: the new repository
is created and pushed from history before the code is deleted here. After the
subtraction the monorepo still works because the core repo's development
requirements pin the satellite at the exact version recorded in
compatibility.json (for example spikeforge-targets==0.1.0), so the dev venv
and CI have the moved code available. The published core distribution does
not depend on the satellite.
Because the project is pre-1.0 and has never been published to a package index,
the extraction shipped without legacy import-path aliases. The old
spikeforge.{targets,energy,event_runtime,hub} paths were deleted outright;
importers use the owning root directly (spikeforge_targets,
spikeforge_targets.energy, spikeforge_targets.event_runtime,
spikeforge_hub). There is no shim, no DeprecationWarning window, and no
dual-path lifetime to retire later.
git subtree was used for single-directory extractions and git filter-repo
for the multi-directory spikeforge-targets extraction, so history is
preserved.
# Phase 3 — spikeforge-targets absorbs four prefixes (renamed to the new root).
git filter-repo \
--path spikeforge_targets \
--path spikeforge_targets/energy \
--path spikeforge_targets/event_runtime \
--path-rename spikeforge/:spikeforge_targets/ \
--force
# then: git remote add origin git@github.com:capsize-games/spikeforge-targets.git && git push -u origin main
# Phase 4 — spikeforge-hub is a single-directory split (the spikeforge-server
# split stays on the shelf because trigger T4 did not fire).
git subtree split --prefix=spikeforge_hub -b spikeforge-hub-split
# Phase 2 — the dashboard is a single-directory split.
git subtree split --prefix=client -b spikeforge-dashboard-splitThe extractions ran on throwaway clones of the core repo; the extraction PRs
only removed the moved paths and added the pins. The pre-extraction commit
remains in core's history as the rollback point
(plans/arch-0001-migration-plan.md).
-
PEP 621 packaging is now the authority. The pre-split tree had no
pyproject.tomland nosetup.cfg; packaging lived only insetup.py.setup.pyis now retired andtests/test_packaging_profiles.pyreads the per-distributionpackages/*/pyproject.tomlfiles. -
server/no longer leaks into core. The core distribution's package discovery excludesserver/,tests/,spikeforge_targets/, andspikeforge_hub/— seeplans/arch-0001-target-topology.md.
-
plans/arch-0001-target-topology.md— distributions and import roots. -
plans/arch-0001-core-boundary.md— the forbidden list the headless proof checks. -
plans/arch-0001-protocol-contract.md— the independentprotocol_version. -
plans/arch-0001-migration-plan.md— the ordered extraction steps.
- Home
- Architecture
- Backend Execution
- Benchmarks
- Dashboard
- Development
- Event Datasets
- Event Runtime And Energy
- Features
- Implications And Boundaries
- Interop Foldins
- Interpreter Spine
- Introspection
- Model Deployment
- Model Hub
- Notes
- Operational Maturity
- Production Workflows
- Project Layout
- Quickstart
- Requirements
- Sequence Primitives
- Streaming Timeseries
- Targets And Interop
- Usage
- Arch 0001 Adr Repo Topology
- Arch 0001 Core Boundary
- Arch 0001 Decision Metrics
- Arch 0001 Migration Plan
- Arch 0001 Packaging Versioning
- Arch 0001 Protocol Contract
- Arch 0001 Risk Register
- Arch 0001 Target Topology
- Backend Execution Plan
- Ecosystem Listings
- Ecosystem Roadmap
- Event Runtime Plan
- Hub Expansion Plan
- Plans
- Interop Foldins Plan
- Interpreter Spine Plan
- Memory System Research
- Model Hub Plan
- Operations Plan
- Production Toolkit Plan
- Production Use Cases
- Professional Roadmap
- Repo Topology Plan
- Sequence Primitives Plan
- Use Case Audio Keyword Spotting
- Use Case Biosignal Medical Monitoring
- Use Case Computational Neuroscience
- Use Case Edge Power Budgets
- Use Case Event Camera Vision
- Use Case Intrusion Anomaly Detection
- Use Case Low Latency Sensor Stream
- Use Case Rl Control Robotics
- Use Case Spiking Transformers
- Use Case Streaming Timeseries