Architecture and extension boundaries¶
Researcher index · Code reading order · Extension tutorial · GUI architecture
The framework separates shared MAPF problem/result contracts, method implementations, application orchestration and user interfaces. Decentralized coordination and centralized planning use the same experiment services. A researcher can run a study from Python, the CLI or HTTP. FastAPI, React and resource probing are optional adapters.
flowchart TD
CLI[CLI or Python study] --> APP[Application services]
GUI[React workspace] --> HTTP[FastAPI adapter]
HTTP --> APP
APP --> PLAN[Validated immutable plans]
APP --> JOB[One process supervisor]
APP --> STORE[Run and experiment repositories]
JOB --> POLICY[Optional resource admission and probe]
JOB --> SOLVER[Registered solver factory]
SOLVER --> ENGINE[Decentralized coordination and simulation]
SOLVER --> CENTRAL[Centralized planning]
SOLVER --> CHECK[Independent trajectory validator]
CHECK --> STORE
STORE --> ANALYSIS[All-outcome and paired analysis]
STORE --> REPLAY[Replay and portable artifacts]
Domain boundaries¶
AgentProtocol,EnvironmentProtocolandMAPFSolverProtocoldefine the existing strategy/solver contracts. Strategies receive local observations; their callbacks do not own the supervisor, database or negotiation ledger.engine/contracts.py:TickWorlddefines the queries and recording operations used by pipeline stages. Stages do not mutate privateWorldSimulationfields. The world owns tick advancement, diagnostics, executed history and frame storage.- The included negotiation protocol owns acknowledgements, commitments and transactional settlement. Refactoring a callback must not change conservation, same-tick protection, observation isolation or movement settings. Independent trajectory validation remains a separate boundary.
The five stages exposed by engine/pipeline.py compose perception and replanning,
local conflict detection, negotiation, atomic movement, and frame capture. Their
implementations own separate modules; the pipeline controls their order and stops
before later stages when a terminal condition is recorded. Perception and movement
capture every recipient's local view before mutating plans or positions. A failed
joint move does not advance simulated time. Conflict-result caching and sparse
occupancy updates have separate owners, while observation reuse invalidates only
the views affected by changed actors or configuration.
MAPFSolverProtocol is the shared entry point for another planning or coordination
method. The current decentralized engine composes TAOP-specific stages and agent
callbacks; a new protocol supplies its own coordination logic. It can reuse scenario,
supervision, storage, trajectory-validation and analysis services. Method-specific
parameters, capability descriptors and telemetry need explicit integration; see
adding a coordination protocol.
The world also owns one ObstacleMemory, partitioned by recipient. Observation
caching handles the current view; memory retains previously observed parked cells.
LocalEnvironment.config.obstacles remains the static scenario map, and its
immutable remembered_obstacles property supplies the learned cells to planning.
Keeping those values separate prevents a local observation from changing the
scenario identity or being mistaken for current visibility.
Application and persistence¶
ExperimentService compiles/exercises studies and enforces the declared budget.
ExperimentStore defines its persistence operations; SQLiteExperimentStore
uses the existing workspace schema. The public get_manifest() method returns
the frozen manifest. HTTP and CLI callers do not reach into private service
methods or issue experiment SQL. RunRepository continues to own durable jobs,
attempts, scenarios and checked artifacts.
The HTTP adapter composes separate catalog, scenario, job, experiment, run and archive route groups. MovingAI imports use the same core parsers as headless workflows; workspace size limits and immutable snapshot validation remain in the application layer. Experiment exports capture all planned trials alongside their paired analysis. Transport code owns SSE delivery and reconnection cursors, while the repository owns the event journal. Stopping an experiment returns its recorded final state, including completion that occurred before the stop request.
The HTTP composition root owns one lazily initialized WorkspaceServices object.
It synchronizes service creation and releases process ownership on normal or
exceptional shutdown. Request limits and error translation live at the transport
boundary; compatibility routes reuse the same owned supervisor.
Replay separates independent candidate assessment from frame construction.
SolutionAssessment records physical validity and first goal arrivals;
ReplayTimeline derives positions, lifecycle labels and hindsight occupancy while
preserving the availability of recorded decisions. Checked bundle imports verify
the validation receipt, canonical costs, identities and trajectory-derived frame
fields before saving anything. A matching checksum establishes integrity, not
source authentication or the truth of unobserved solver decisions.
JobSupervisor owns worker processes and their lifetime. ResourceAdmission
decides whether a queued job may start from a sampled observation; ResourceProbe
is its injectable measurement boundary. The optional psutil adapter handles OS
measurements. Tests can supply independent resource observations without changing
solver algorithms or pretending that a simulated pressure test measures performance.
Solver registration supplies constructor bindings, display identity and supported
weight controls. Job defaults/bounds/choices come from JobSubmissionRequest, also
used by the GUI descriptors and generated reference. Duplicate names and invalid
direct strategy names fail explicitly. Adding a new research parameter still
requires a versioned input contract and tests; arbitrary unvalidated keys are not
accepted as an extension mechanism.
File input and search ownership¶
core.movingai.parse_movingai_rows is the shared syntax and coordinate boundary.
It retains typed source metadata so workspace and article admission apply their
own map-reference and selection policies without parsing the text twice.
core.sampling owns synthetic generation and its deterministic draw order.
Article dimension repair is explicit and recorded; raw source hashes remain the
hashes of the unmodified bytes. Filtered prefixes and complete archive rosters
retain different eligibility rules and sampling receipts.
SpaceTimeAStar is the callable planner boundary. Its per-query SpaceTimeSearch
checks legal successors and stop conditions, while SearchFrontier owns
cost/heat dominance, parent links and stable heap insertion order. Built-in
reservation queries use primitive tuples; custom reservation methods retain
polymorphic dispatch. Candidate-result memoization belongs to the public planner,
not the frontier. No cache turns a bounded failure into proof of infeasibility.
Frontend ownership¶
App.tsx composes the workspace and cross-screen selection. SimulationControls
owns the configuration form; useJobMonitor owns stream/poll lifecycle and cleanup;
useRunComparison owns matching requests, stale-response invalidation and alignment.
ComparisonPanel, BatchControls and ArtifactPanel present those workflows.
Draft batch state persists through navigation via useBatchDraft. The existing
replay hook owns bounded frame caching, and Canvas rendering remains outside React
state updates.
Evidence and compatibility¶
Use the complete qualification commands in Contributing. Behavior-preservation checks compare executed paths, validation, measured metrics and normalized replay records against an unchanged reference. They supplement failure-mode, browser and installed-package checks; they do not establish universal correctness or historical paper-score equivalence. New source bytes have a new source hash even when finite regression behavior matches. Never update a frozen running study to the new checkout or relabel its recorded source identity.
Shared artifact I/O¶
mapf.artifact_io owns canonical JSON encoding and fsynced file replacement. The workspace repository and telemetry logger compose these small I/O primitives independently; importing the simulation or telemetry does not initialize the workspace database layer. The repository retains the existing helper import paths for compatibility. Process-isolated tests enforce that boundary and artifact/lifecycle tests check the unchanged persistence contract.