How the Plane Abstraction in OpenResearch Shares Data Structures Across the CLI
The Plane abstraction centralizes data structures like Run, RunLog, and ProjectEdit in src/plane.rs, then exposes them through a LocalPlane implementation that transforms stored database rows into these shared structs, creating a single source of truth for all CLI commands.
The OpenResearch CLI (alphaXiv/OpenResearch) manages machine learning research projects through a unified interface for experiments, runs, and logs. At the heart of this architecture lies the Plane abstraction, which consolidates data definitions in src/plane.rs and implements concrete operations in LocalPlane. This design ensures that commands like orx project view and orx logs operate on consistent, type-safe data structures without duplicating logic.
Centralizing Data Structures in src/plane.rs
The file src/plane.rs serves as the canonical source for data shapes used throughout the CLI. Rather than scattering definitions across command modules, the Plane abstraction declares shared structs that represent printable run fields, log metadata, and edit payloads.
Key structures defined here include (plane.rs#L6-L22, plane.rs#L45-L99, plane.rs#L101-L146):
Run– Printable run fields and statusRunLog– Log content with byte-range metadataRunListing– Paginated run collectionsLogRequest– Parameters for reading log segmentsDescInput– Description payloads for experimentsProjectEdit– Updates to project configurationCreateExperimentSpec– Specifications for new experiments
By housing these types in a single file, src/plane.rs establishes a shared contract. Any change to the data model—such as adding a field to Run—automatically propagates to every command that consumes the Plane abstraction.
Resolving Operations with LocalPlane
While src/plane.rs defines what data looks like, src/plane/local_plane.rs defines how to fetch and manipulate it. The LocalPlane struct bundles a Store handle (database connection) with resolved project or experiment rows, acting as the concrete implementation of the Plane abstraction.
Resolver functions in src/plane.rs construct these instances:
resolve_project(plane.rs#L123-L131) creates aLocalPlanebound to a specific projectresolve_experiment(plane.rs#L133-L141) binds to an experiment contextresolve_run(plane.rs#L143-L151) prepares a plane for run-specific operations
The LocalPlane type itself lives in src/plane/local_plane.rs (local_plane.rs#L16-L25) and encapsulates the logic for transforming raw database rows into the public structs defined in src/plane.rs.
Transforming Stored Data into Shared Structs
Methods on LocalPlane query the underlying Store and map internal types (like StoredRun) into the shared abstractions defined in src/plane.rs. This ensures CLI commands receive fully-formed, validated data structures rather than raw database records.
Listing runs: The list_runs method queries the store and converts each StoredRun into the public Run struct using Run::from (local_plane.rs#L41-L53):
let plane = resolve_project(store, "proj123")?;
let listing = plane.list_runs().await?;
for run in listing.runs {
println!("{} – {}", run.id, run.status);
}
Reading logs: The read_log method builds a RunLog containing raw bytes plus pagination metadata (local_plane.rs#L55-L100):
let plane = resolve_run(store, "run456")?;
let log = plane
.read_log(LogRequest {
mode: "head".into(),
max_bytes: Some(1024),
..Default::default()
})
.await?;
println!("Log ({} bytes): {}", log.content.len(), log.footer());
Editing projects: High-level operations like edit_project accept the shared ProjectEdit struct defined in src/plane.rs, ensuring type consistency across the boundary:
let plane = resolve_project(store, "proj123")?;
plane.edit_project(ProjectEdit {
name: Some("New Name".into()),
run_command: None
}).await?;
Hiding Implementation Details with Re-Exports
To maintain clean separation between interface and implementation, src/plane.rs re-exports LocalPlane at the bottom of the file (plane.rs#L155-L156):
pub(crate) use local_plane::LocalPlane;
This pattern allows CLI command modules to import from crate::plane without knowing whether they are interacting with a local or remote implementation. The abstraction cleanly separates the shared data structures from their retrieval logic, enabling future extensions (such as a remote API plane) without changing consumer code.
Maintaining a Single Source of Truth
Because all high-level CLI commands flow through resolve_* → LocalPlane → shared structs, the Plane abstraction guarantees consistency. When a developer modifies Run in src/plane.rs, the change immediately affects list_runs in local_plane.rs and every command that displays run information.
This architecture eliminates data drift between commands. Whether executing orx exp launch, orx project view, or orx logs, the CLI operates on the same validated structures defined in the central Plane module.
Summary
- Central definitions: All shared data structures (
Run,RunLog,ProjectEdit, etc.) live insrc/plane.rs, creating a type contract for the entire CLI. - Concrete implementation:
LocalPlaneinsrc/plane/local_plane.rsimplements the logic for fetching and transforming database rows into these shared structs. - Resolver pattern: Functions like
resolve_projectandresolve_runconstructLocalPlaneinstances bound to specific contexts, ensuring properStoreinitialization. - Method mapping: Operations like
list_runsandread_logconvert internal storage types into public Plane structs, maintaining abstraction boundaries. - Clean imports: Re-exporting
LocalPlanefromsrc/plane.rshides implementation details while exposing a unified interface to command modules.
Frequently Asked Questions
What is the Plane abstraction in OpenResearch?
The Plane abstraction is an architectural layer in the OpenResearch CLI (alphaXiv/OpenResearch) that unifies how commands interact with projects, experiments, runs, and logs. It consists of shared data structures defined in src/plane.rs and a concrete LocalPlane implementation that handles data retrieval and transformation, allowing CLI commands to work with consistent, type-safe structs regardless of the underlying storage mechanism.
Which data structures are shared in src/plane.rs?
The file defines critical CLI-facing structs including Run (run metadata and status), RunLog (log content with pagination info), RunListing (collections of runs), LogRequest (parameters for log queries), DescInput (experiment descriptions), ProjectEdit (project configuration updates), and CreateExperimentSpec (experiment creation parameters). These types form the common language used across all CLI operations.
How does LocalPlane differ from the structs in plane.rs?
While src/plane.rs declares the shape of data (structs like Run and RunLog), LocalPlane in src/plane/local_plane.rs provides the behavior for obtaining and manipulating that data. It wraps a Store handle and implements methods like list_runs and read_log that query the database and transform internal storage types into the public structs defined in src/plane.rs.
Why does OpenResearch use resolver functions instead of direct instantiation?
Resolver functions like resolve_project, resolve_experiment, and resolve_run in src/plane.rs ensure that every LocalPlane instance is properly initialized with both a Store connection and validated context (such as a resolved project row). This pattern centralizes error handling for "not found" scenarios and guarantees that CLI commands receive a fully configured Plane abstraction ready for operations, rather than constructing dependencies manually in each command handler.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →