Repository navigation
arch 0001 core boundary
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
The spikeforge distribution MUST install and import without any of the
following distributions present. This list is the enforced core boundary and is
frozen for protocol_version 1.0.
fastapi
pydantic
uvicorn
huggingface_hub
nir
nirtorch
onnx
onnxruntime
norse
lava
lava-nc
tonic
tensorboard
wandb
The list mixes distribution names and import roots deliberately. Where they
differ: distribution lava-nc is imported as lava; huggingface_hub,
pydantic, fastapi, uvicorn, nir, nirtorch, onnx, onnxruntime,
tonic, tensorboard, and wandb use the same token for both.
Three tiers define what "forbidden" means. A core module violates the boundary if it breaks tier 1 or tier 2; tier 3 is explicitly permitted.
-
Tier 1 — never a required dependency. None of the forbidden distributions
may appear in the core distribution's
[project].dependencies. They may appear only in the core's optional extras (plans/arch-0001-packaging-versioning.md). -
Tier 2 — never imported at import time. No core module may perform a
top-level
import fastapi,from pydantic import ..., and so on. A core module that needs an optional SDK must import it inside a function, through one of the existing lazy modules, and degrade honestly when it is absent. -
Tier 3 — lazy access is allowed. The core-owned lazy modules
(
nir_bridge/api.py,onnx_bridge/api.py,events/tonic_api.py,tracking/tensorboard_sink.py,tracking/wandb_sink.py,tracking/sink_probe.py) may import a forbidden SDK inside a function and report availability rather than raise. These modules are the only sanctioned exception sites and are enumerated in the static scan's allow-list. The backend and hub probes (spikeforge_targets/probe.py,spikeforge_targets/backends/api.py,spikeforge_hub/probe.py) moved out of core with their distributions and are no longer core exception sites.
The server distribution is exempt by construction: fastapi, pydantic, and
uvicorn are its base dependencies
(plans/arch-0001-target-topology.md).
That is why core no longer packages server/ — the pre-split tree did, via
setup.py, which was the single largest boundary violation in the tree; the
core distribution now excludes server/ in its package discovery.
Enforcement has two independent mechanisms; both must pass.
The existing blocker at
scripts/blocked_deps/sitecustomize.py
makes a listed package unimportable at runtime so graceful-degradation paths are
exercised even when the optional extras are installed. Its BLOCKED set today
covers the SDKs but not fastapi, pydantic, or uvicorn, which were only
ever exercised because server/ shipped in the same distribution. Extend it:
BLOCKED = frozenset(
{
# server stack — must be absent from a headless core install
"fastapi",
"pydantic",
"uvicorn",
# data/event SDKs
"onnx",
"onnxruntime",
"onnxscript",
"tonic",
# logging/tracking SDKs
"tensorboard",
"wandb",
# model hub
"huggingface_hub",
# deploy backends
"norse",
"lava",
"lava-nc",
"spinnaker2",
"sinabs",
"rockpool",
}
)The blocked-deps CI job then proves every available: false and typed
unavailable path — including "the server stack is not installed" — in one run.
Add scripts/check_core_boundary.py, run in a new core-boundary job. It walks
the core distribution's packages (everything in include = ["spikeforge*"],
exclude = ["server*", "spikeforge_targets*", "spikeforge_hub*"]), parses each module's AST,
and fails if any module-level import names a forbidden root. Function-local
imports are permitted only inside the enumerated shim allow-list; a
function-local import of a forbidden SDK anywhere else is a failure too, so the
boundary cannot be widened silently.
check_core_boundary.py
forbidden = {fastapi, pydantic, uvicorn, huggingface_hub, nir, nirtorch,
onnx, onnxruntime, norse, lava, tonic, tensorboard, wandb}
scan roots = spikeforge/** and main.py, main_encodings.py
exclude = server*, tests*, spikeforge_targets*, spikeforge_hub*
rule = no module-level import of a forbidden root, anywhere
rule = no function-level import of a forbidden root outside
{"spikeforge.nir_bridge.api",
"spikeforge.onnx_bridge.api",
"spikeforge.events.tonic_api",
"spikeforge.tracking.tensorboard_sink",
"spikeforge.tracking.wandb_sink",
"spikeforge.tracking.sink_probe"}
Add a headless verification step that builds the distribution with no
extras and asserts the boundary from the outside:
python -m build packages/spikeforge # no extras requested
python -m venv /tmp/headless && . /tmp/headless/bin/activate
pip install dist/spikeforge-*.whl
python - <<'PY'
import importlib.util as u
for mod in ("fastapi", "pydantic", "uvicorn", "huggingface_hub",
"nir", "nirtorch", "onnx", "onnxruntime",
"norse", "lava", "tonic", "tensorboard", "wandb"):
assert u.find_spec(mod) is None, f"core install leaked forbidden dep: {mod}"
import spikeforge # must import cleanly with the forbidden set absent
PYThe wheel must not contain server/ either, verified by listing the archive and
asserting no server/ entry is present.
-
The old
blocked-depsgate had a blind spot.sitecustomize.pyblocked the SDKs but notfastapi/pydantic/uvicorn, so it could not catch a core-code import of the server stack.BLOCKEDnow includes the server stack. -
The
webextra was the wrong home for the server stack. The oldsetup.pyextras declaredweb = [fastapi, uvicorn, websockets, pydantic]; those are now the base dependencies of thespikeforge-serverdistribution andwebis gone from core (plans/arch-0001-packaging-versioning.md). -
nirstays core-optional, not core-required.nir_bridgestays in the core distribution and satisfies the boundary because its SDK imports are lazy.huggingface_huband the backend SDKs moved out of core withspikeforge-hubandspikeforge-targetsrespectively. They are forbidden only as required deps of core.
-
plans/arch-0001-target-topology.md— which distribution owns which root. -
plans/arch-0001-packaging-versioning.md— extras placement that keeps core headless. -
plans/arch-0001-migration-plan.md— when the server leaves core. -
plans/arch-0001-risk-register.md— the boundary-drift risk and its owner.
- 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