scientific_workflow/lib.rs
1//! Rust primitives for reproducible scientific workflows.
2//!
3//! `scientific-workflow` provides the data and execution foundations needed to
4//! describe scientific systems, record their evolution, and organize scoped
5//! computational work. The crate is intentionally divided by responsibility:
6//! state representation, in-memory state time series, storage, orchestration, and
7//! language bridges remain separate modules rather than accumulating behind
8//! one monolithic interface.
9//!
10//! # Module boundaries (public API ownership)
11//!
12//! The boundary map is strict: each module owns only one slice of behavior, and
13//! callers move data between boundaries without duplicating the same concern.
14//!
15//! - `study`: declarative study/phase/task planning and run execution. It owns
16//! declaration validation, scheduling, cancellation, execution timing, and
17//! progress summaries. It does not own model semantics, storage formats, or
18//! schema declarations.
19//! - `configuration`: experiment-space declarations (`fixed.json` + `sweep.json`)
20//! and resolved combinations. It owns parameter expansion only. It does not
21//! own task construction, state schemas, persistence, or execution control.
22//! - `system_state`: typed heterogeneous fielded state values and schema.
23//! - `time_series`: ordered in-memory complete-state collections for analysis.
24//! - `storage`: asynchronous buffered persistence and completed-run reconstruction.
25//! - `execution`: directory-scoped recording lifecycle and path derivation.
26//! - `artifact`: immutable input content-addressed publication under an execution
27//! scope, plus strict load-time verification.
28//! - `rng_record`: validated reproducibility metadata for caller-owned RNG sources.
29//! - `prelude`: curated import surfaces that preserve public boundaries.
30//!
31//! # Study vocabulary
32//!
33//! A [`study::Study`] is the largest scope. It owns scheduling, cancellation,
34//! recording, and display for an ordered set of [`study::Phase`] values. A
35//! phase owns many [`study::Task`] values plus their concurrency, delay,
36//! timeout, dependency, and failure policies. A task owns one workload, which
37//! reports progress, detail, messages, and cancellation through
38//! [`study::TaskContext`]. Progress and one-shot work are modes of the same
39//! task type.
40//!
41//! [`configuration`] is deliberately outside that hierarchy. It resolves a
42//! directory containing `fixed.json` and `sweep.json` into every deterministic
43//! [`configuration::ResolvedConfiguration`]. The downstream application decides
44//! how each combination becomes a task and owns all paths, schemas, model
45//! inputs, storage, and other effects captured by the workload.
46//!
47//! # Supporting modules
48//!
49//! [`execution`] creates collision-resistant or caller-named execution scopes
50//! and deterministic task recording paths. [`artifact`] atomically publishes
51//! and verifies content-addressed immutable bytes. [`rng_record`] stores
52//! validated RNG provenance while leaving random generation to applications.
53//!
54//! [`system_state`] provides:
55//!
56//! - JSON-defined, immutable field layouts;
57//! - optional natural-language field descriptions without persisted Rust types;
58//! - heterogeneous concrete Rust payloads behind a typed API;
59//! - clone-free payload insertion, mutation, and extraction;
60//! - explicit per-payload cloning of complete states;
61//! - mutable, checked time-point progression.
62//!
63//! Type erasure and boxing remain internal to that module. Consumer crates
64//! work with their original concrete payload types.
65//!
66//! [`time_series`] provides the in-memory analysis collection for complete,
67//! ordered states. It enforces shared-layout identity and increasing simulation
68//! indices, offers a lightweight borrowed view, and permits field-level
69//! mutation without exposing mutable state time. It deliberately performs no
70//! serialization, chunking, or filesystem IO.
71//!
72//! [`storage`] provides named partial-state streams with writer-owned sampling
73//! intervals, borrowed JSON encoding only when due, bounded asynchronous
74//! persistence through one worker per recording, byte-targeted chunking, atomic recording
75//! metadata, automatic operational timing, terminal summaries, name-selected payload
76//! decoders, and verified full-series or latest-state reconstruction.
77//! Import [`prelude::basics`] for these scientific primitives and
78//! [`prelude::study`] only at orchestration boundaries.
79//!
80//! # Basic use
81//!
82//! ```no_run
83//! use scientific_workflow::prelude::basics::*;
84//!
85//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
86//! let spec = SystemStateSchema::load_json_template("state.json")?;
87//! let mut state = spec.create_empty_state(SimulationTime::from_iteration(0));
88//!
89//! assert!(
90//! state
91//! .insert_payload("population", vec![10_u64, 20, 30])?
92//! .is_none()
93//! );
94//! state
95//! .payload_mut::<Vec<u64>>("population")?
96//! .push(40);
97//! let time = state.advance_simulation_time(None)?;
98//! assert_eq!(time.iteration(), 1);
99//! let population = state.take_payload::<Vec<u64>>("population")?;
100//!
101//! assert_eq!(population, vec![10, 20, 30, 40]);
102//! # Ok(())
103//! # }
104//! ```
105//!
106//! Future orchestration-layer features will organize scoped workflow execution
107//! without changing the public state-value ownership or storage contracts.
108//!
109//! # Release stability
110//!
111//! This crate is a test release. Public API behavior is allowed to change across
112//! updates without backward compatibility guarantees.
113//!
114//! ## Downstream no-overlap policy
115//!
116//! For downstream consumers, preserve boundary ownership:
117//! keep orchestration in `study`, persistence in `storage`, and pure state in
118//! `system_state`/`time_series`. Do not implement overlapping behavior in a
119//! downstream layer; if a seam is missing, negotiate an explicit API addition.
120
121mod clock;
122
123pub mod artifact;
124pub mod configuration;
125pub mod execution;
126pub mod prelude;
127pub mod rng_record;
128pub mod storage;
129#[path = "study.rs"]
130pub mod study;
131pub mod system_state;
132pub mod time_series;