Architecture Overview
How DispatchAtlas is organized — five focused distribution packages with a one-way import direction, from the core domain model through benchmarks, solvers, campaigns, and analysis.
DispatchAtlas is a workspace of five focused distribution packages that share
the dispatchatlas Python namespace, plus a root aggregate package. The
architecture keeps domain contracts at the center and moves benchmark
generation, solving, campaign execution, analysis, documentation, and release
automation outward. Every dependency points inward, toward
dispatchatlas.core — never sideways between peer packages and never outward
toward tooling.
🧭 Dependency Direction
dispatchatlas.lab
/ | \
v | v
dispatchatlas.bench | dispatchatlas.solve
\ | /
v v v
dispatchatlas.core
^
|
dispatchatlas.analytica
(also reads stable campaign manifests as data)Every arrow means "imports". All arrows point toward dispatchatlas.core;
no arrow points outward or sideways. dispatchatlas.analytica deliberately
has no arrow to dispatchatlas.lab: it consumes the JSON manifests a
completed campaign leaves on disk, not the campaign runtime itself.
Derived from the package manifests (packages/*/pyproject.toml) and the
import statements in each package's src/ tree;
tests/architecture/test_import_boundaries.py re-verifies the table on every
continuous-integration run.
| Layer | Package | Responsibility | May import | Must not import |
|---|---|---|---|---|
| Domain | dispatchatlas.core | Scheduling contracts, validation, provenance, seeds, serialization, protocols. | Standard library and approved lightweight dependencies only. | Any other DispatchAtlas package. |
| Benchmark | dispatchatlas.bench | Benchmark taxonomy, generators, catalogs, materialization, citation evidence. | dispatchatlas.core. | Solver, campaign, analysis, or site runtime code. |
| Solver | dispatchatlas.solve | Solver metadata, registries, baselines, metaheuristics, operators, optional adapters. | dispatchatlas.core. | Benchmark generators, campaign runners, analysis exports, or site runtime code. |
| Campaign | dispatchatlas.lab | Reproducible campaign configuration, budgets, checkpoints, retries, execution. | dispatchatlas.core, dispatchatlas.bench, dispatchatlas.solve. | Analysis package or site runtime internals. |
| Analysis | dispatchatlas.analytica | Statistics, disclosure filtering, evidence bundles, portal datasets, the CLI. | dispatchatlas.core, plus stable campaign manifests read as JSON data. | Live campaign execution or site runtime internals. |
| Aggregate | dispatchatlas | Root distribution; exposes the version surface and pins the five packages through its all extra. | Nothing at runtime; composition happens through extras. | — |
📦 Package Roles
dispatchatlas.coreis the inner boundary. It defines the shared scheduling vocabulary (ProblemSpec,Schedule, objectives, constraints), validation, provenance and seed lineage, canonical serialization, and the protocols (BenchmarkProvider,Solver,ExperimentRunner,ResultRepository,DisclosurePolicy,AnalysisExporter) every outer package implements. Its manifest declares zero dependencies, so the domain stays importable everywhere.dispatchatlas.benchturns the domain vocabulary into benchmark evidence: generator families, domain profiles, smoke and full catalogs, characterization metrics, and a citation matrix that records where each family's assumptions come from.dispatchatlas.solveowns everything that produces schedules: solver metadata and capability descriptors, the solver registry, constructive baselines, permutation metaheuristics, the NDSO family, scheduling operators, and optional exact-solver adapters kept behind extras.dispatchatlas.labcomposes benchmarks and solvers into checkpointed, budgeted, environment-stamped campaigns with deterministic run identifiers, and owns the applicability matrix that reconciles every family against every solver. That matrix is why it is the only package allowed to see core, bench, and solve together: pairing them is the thing it exists to do.dispatchatlas.analyticareads a finished campaign directory —checkpoint.json,plan.json,environment.json, and result rows — and produces statistical summaries, evidence bundles, report scaffolds, and portal datasets. Manifest-based input keeps analysis reproducible from recorded artifacts alone.dispatchatlas(root) aggregates the five packages for one-command installation and carries the public version surface.
🔒 Why The Direction Is Enforced
The inward-only direction is a tested contract, not a convention:
- Testability. Core validates problems and schedules with no solver, campaign, or analysis machinery installed, so domain tests run with standard-library-only imports. Bench and solve test against core contracts without dragging in each other.
- Reproducibility. Because
dispatchatlas.analyticaconsumes recorded manifests rather than the live campaign runtime, any completed campaign can be re-analyzed byte-for-byte from its artifacts. - Independent release. Each package builds and version-pins separately; a solver change cannot silently alter benchmark or analysis behavior.
Import-boundary tests live in tests/architecture/:
test_import_boundaries.py walks every package source file with the ast
module and fails on any import that crosses the forbidden-import table above,
and test_workspace_privacy.py guards private research artifacts. The root
AGENTS.md (§ Package Boundary Summary) states that direction canonically and
CONTRIBUTING.md carries it for contributors; this page is the deep-dive on
top of them, and every pull request is reviewed against it.
🌐 Public Surfaces
The documentation site under site/ consumes approved exported data —
disclosure-filtered portal bundles and evidence summaries. It does not execute
live campaigns or bypass disclosure policy.
🛠️ Governance Surfaces
tools/ and CI may inspect all package code, build artifacts, and reports.
They gate quality from the outside and are never runtime dependencies of the
product packages.