haz-exec 0.1.0

Async task execution engine for haz.
Documentation
//! Workspace-wide scheduler that turns a validated [`TaskGraph`]
//! into a sequence of [`run_task`](crate::run_task) calls subject
//! to the workspace's concurrency caps.
//!
//! The public surface is [`run_graph`]: a single async function
//! that walks the graph, admits ready tasks in canonical
//! `(ProjectName, TaskName)` order subject to the workspace's
//! global cap (`EXEC-004`) and per-tag caps (`EXEC-005`), and
//! threads each completed task's `(stdout, stderr)` content
//! hashes into every downstream call so cache-key derivation has
//! the predecessor-stream contribution it needs (`CACHE-007` /
//! `DAG-017`).
//!
//! The loop is built on [`futures::stream::FuturesUnordered`].
//! Each pushed future borrows `ctx` and owns a snapshot of the
//! current predecessor map; awaiting completion returns the
//! `(TaskId, Result<CompletedRecord, RunTaskError>)` pair so the
//! main body can re-acquire its own mutable borrows. The
//! `outcomes` map stores the broader [`RunOutcome`] sum
//! (Completed wraps the record; Skipped lands once the cascade
//! work in a follow-up commit wires the variant).
//!
//! Mutex composition (`EXEC-006` condition 3, `EXEC-007`) is
//! delivered through a lookup-then-spawn pipeline: each admitted
//! task first runs [`cache_lookup_phase`]; on a hit the
//! scheduler records the outcome immediately, and on a miss it
//! consults its live mutex hold set before acquiring the mutex and
//! driving [`run_fresh`]. Cache hits never touch the hold set
//! per `MUTEX-007`. A task whose mutex is incompatible after
//! lookup is returned to `ready` per `MUTEX-005`, its slot is
//! released, and the next admission round re-evaluates.
//!
//! Cancellation (`EXEC-012..015`), the formal `Skipped` state and
//! its typed diagnostics (`EXEC-011`), runtime cycle / overlap
//! detection (`EXEC-019..020`), and live-mode output
//! presentation (`EXEC-016`) are all wired through this module
//! alongside the lookup-then-spawn pipeline.
//!
//! [`TaskGraph`]: haz_dag::graph::TaskGraph

pub(super) mod cascade;
pub(super) mod cycle;
pub(super) mod overlap;
pub(super) mod scheduler;
pub(super) mod state;
pub(super) mod steps;

#[cfg(test)]
mod test_fixtures;

pub use crate::run_graph::scheduler::{
    RunGraphError, RunGraphOutcome, RuntimeInvariantViolation, run_graph,
};