Skip to main content

octl_core/
lib.rs

1//! Core library for orchestratectl.
2//!
3//! See `issues/orchestratectl-mvp/design.md` for the canonical schema and
4//! protocol references. This crate provides:
5//!
6//! - The on-disk schema types ([`Manifest`], [`Node`], [`Event`],
7//!   [`Discussion`], [`SpinoffProposal`]).
8//! - Atomic write helpers ([`atomic`]) and per-run advisory `flock`
9//!   ([`RunLock`]).
10//! - The canonical mutation entry point
11//!   ([`append_and_apply_event`]): append one
12//!   event and fold it into the projections under the run's `flock`.
13//!
14//! Higher-level supervisor and CLI logic live in their own crates / issues.
15//!
16//! `octl-core` is the canonical library surface, so public items are required
17//! to carry doc comments (`#![warn(missing_docs)]`). Lint-level policy
18//! otherwise lives in the workspace `[workspace.lints]` table (pedantic clippy).
19#![warn(missing_docs)]
20
21pub mod atomic;
22pub mod cancel;
23pub mod envelope;
24pub mod error;
25pub mod events;
26pub mod ids;
27pub mod lock;
28pub mod paths;
29pub mod plan;
30pub mod projections;
31pub mod reducer;
32pub mod report;
33pub mod schema;
34
35#[cfg(test)]
36mod stress_tests;
37
38pub use cancel::{cancel_run, cancel_run_unlocked, CancelOutcome};
39pub use envelope::SCHEMA_VERSION;
40pub use error::{Error, Result};
41pub use events::{
42    append_and_apply_event, append_and_apply_idempotent, append_and_apply_unlocked,
43    find_prior_with_key, quarantine_corrupt_lines, quarantine_corrupt_lines_unlocked,
44    read_all_events, recover_last_seq, AppendOutcome, AppendResult, PriorEvent, Quarantine,
45};
46pub use ids::{format_node_id, new_discussion_id, new_proposal_id, new_run_id};
47pub use lock::{Exclusive, LockedRun, RunLock, Shared};
48pub use paths::{nofollow, run_dir, validate_run_id, RunPaths};
49pub use plan::{
50    parse_and_validate_plan, plan_v3_json_schema, validate_plan, Acceptance, Baseline, Check,
51    Chunk, Feature, Plan, PlanValidationError, Tier, PLAN_SCHEMA_VERSION, PLAN_V3_JSON_SCHEMA,
52    PROVENANCE_REQUIRED_SCHEMA, SUPPORTED_PLAN_SCHEMAS, TOLERATED_OPTIONAL_FIELDS,
53};
54pub use projections::{
55    read_discussion, read_discussion_opt, read_manifest, read_manifest_opt, read_node,
56    read_node_opt, read_spinoff, read_spinoff_opt, write_node,
57};
58pub use reducer::{plan_projections, VIA_EXPLICIT_MERGE};
59pub use report::{validate_report_payload, ReportValidationError};
60pub use schema::{
61    is_run_id_prefix, ChildRef, Discussion, DiscussionId, DiscussionStatus, Event,
62    IdValidationError, Kind, Lifecycle, Manifest, Node, NodeId, ProposalId, RunId, SpinoffProposal,
63    SpinoffStatus, Status, STATE_SCHEMA_VERSION, SUPPORTED_STATE_SCHEMAS,
64};
65
66/// Ensure the orchestratectl root directory exists (`<root>/runs`,
67/// `<root>/logs`). Idempotent.
68pub fn ensure_root(root: &std::path::Path) -> Result<()> {
69    for sub in ["runs", "logs"] {
70        let p = root.join(sub);
71        std::fs::create_dir_all(&p).map_err(|e| Error::io(&p, e))?;
72    }
73    Ok(())
74}