moonflowgraph

    A MoonBit task graph and provenance trace library for reproducible research and agent workflows.

    workflow
    dag
    provenance
    agent
    research
    Download zip
    Version
    0.3.0
    License
    Apache-2.0
    Last updated
    2 months ago
    Downloads
    51

    #MoonFlowGraph Executable Examples

    ///|
    test {
    let graph = FlowGraph::new()
    guard graph.add_task(TaskNode::new("collect_papers", "Collect papers"))
    is Ok(_) else {
    fail("expected first task")
    }
    guard graph.add_task(TaskNode::new("write_report", "Write report")) is Ok(_) else {
    fail("expected second task")
    }
    guard graph.add_dependency(
    TaskId::new("collect_papers"),
    TaskId::new("write_report"),
    )
    is Ok(_) else {
    fail("expected dependency")
    }
    guard graph.plan() is Ok(plan) else { fail("expected valid graph") }
    debug_inspect(plan.order().length(), content="2")
    debug_inspect(plan.batches().length(), content="2")
    guard graph.roots() is Ok(roots) else { fail("expected roots") }
    guard graph.leaves() is Ok(leaves) else { fail("expected leaves") }
    debug_inspect(roots[0].value(), content="\"collect_papers\"")
    debug_inspect(leaves[0].value(), content="\"write_report\"")
    guard graph.to_mermaid() is Ok(mermaid) else { fail("expected Mermaid") }
    debug_inspect(mermaid.contains("task_0 --> task_1"), content="true")
    let trace = Trace::new()
    guard graph.to_json_checked(plan, trace) is Ok(snapshot) else {
    fail("expected checked JSON")
    }
    debug_inspect(snapshot.contains("\"schema_version\": 1"), content="true")
    guard RunSnapshot::from_json(snapshot) is Ok(imported_snapshot) else {
    fail("expected run snapshot import")
    }
    debug_inspect(imported_snapshot.audit() is Ok(_), content="true")
    let workflow_json = graph.to_workflow_spec().to_json()
    guard FlowGraph::from_workflow_json(workflow_json) is Ok(round_trip) else {
    fail("expected workflow import")
    }
    debug_inspect(round_trip.task_count(), content="2")
    }

    Dependency

    pub struct Dependency {
    // private fields
    } derive(Eq,
    Debug
    )

    Directed dependency edge: before must finish before after.

    Dependency::after

    fn Dependency::after(self : Dependency) -> TaskId

    Return the successor endpoint of this dependency.

    Dependency::before

    fn Dependency::before(self : Dependency) -> TaskId

    Return the predecessor endpoint of this dependency.

    Dependency::new

    fn Dependency::new(before : TaskId, after : TaskId) -> Dependency

    Build a dependency edge.

    ExecutionPlan

    pub struct ExecutionPlan {
    // private fields
    } derive(Eq,
    Debug
    )

    A validated execution plan with serial order and parallel-ready batches.

    ExecutionPlan::batches

    fn ExecutionPlan::batches(self : ExecutionPlan) -> Array[Array[TaskId]]

    Return a detached copy of the parallel execution batches.

    ExecutionPlan::order

    fn ExecutionPlan::order(self : ExecutionPlan) -> Array[TaskId]

    Return a detached copy of the serial execution order.

    ExecutionPlan::snapshot

    fn ExecutionPlan::snapshot(self : ExecutionPlan) -> ExecutionPlan

    Return a detached copy of an execution plan, including nested batches.

    FlowGraph

    pub struct FlowGraph {
    // private fields
    } derive(
    Debug
    )

    Mutable workflow graph.

    FlowGraph::add_dependency

    fn FlowGraph::add_dependency(self : FlowGraph, before : TaskId, after : TaskId) -> Result[Unit, GraphError]

    Add a dependency edge. Duplicate edges are rejected; endpoint existence is checked by validate.

    FlowGraph::add_task

    fn FlowGraph::add_task(self : FlowGraph, node : TaskNode) -> Result[Unit, GraphError]

    Add a task node. Duplicate ids return DuplicateTask.

    FlowGraph::dependencies

    fn FlowGraph::dependencies(self : FlowGraph) -> Array[Dependency]

    Return a detached copy of dependency edges.

    FlowGraph::dependencies_snapshot

    fn FlowGraph::dependencies_snapshot(self : FlowGraph) -> Array[Dependency]

    Return a detached copy of dependency edges.

    FlowGraph::dependency_count

    fn FlowGraph::dependency_count(self : FlowGraph) -> Int

    Return the number of dependency edges.

    FlowGraph::execution_batches

    fn FlowGraph::execution_batches(self : FlowGraph) -> Result[Array[Array[TaskId]], GraphError]

    Return parallel-ready batches. Tasks in the same batch have no dependencies between them.

    FlowGraph::find_task

    fn FlowGraph::find_task(self : FlowGraph, id : TaskId) -> TaskNode?

    Find a task by id.

    FlowGraph::from_workflow_json

    fn FlowGraph::from_workflow_json(input : String) -> Result[FlowGraph, WorkflowSpecError]

    Parse workflow-spec-v1 JSON and return a validated graph.

    FlowGraph::leaves

    fn FlowGraph::leaves(self : FlowGraph) -> Result[Array[TaskId], GraphError]

    Return tasks with no outgoing dependency edges.

    FlowGraph::new

    fn FlowGraph::new() -> FlowGraph

    Create an empty flow graph.

    FlowGraph::plan

    fn FlowGraph::plan(self : FlowGraph) -> Result[ExecutionPlan, GraphError]

    Create a full execution plan.

    FlowGraph::predecessors

    fn FlowGraph::predecessors(self : FlowGraph, id : TaskId) -> Result[Array[TaskId], GraphError]

    Return immediate predecessor ids for a task.

    FlowGraph::ready_tasks

    fn FlowGraph::ready_tasks(self : FlowGraph, done : Array[TaskId]) -> Result[Array[TaskId], GraphError]

    Return tasks whose predecessors are all in done.

    FlowGraph::roots

    fn FlowGraph::roots(self : FlowGraph) -> Result[Array[TaskId], GraphError]

    Return tasks with no incoming dependency edges.

    FlowGraph::runnable_tasks

    fn FlowGraph::runnable_tasks(self : FlowGraph) -> Result[Array[TaskId], GraphError]

    Return pending or ready tasks whose predecessors have succeeded.

    Failed or skipped predecessors block their successors. Callers that manage completion separately should continue using ready_tasks(done).

    FlowGraph::snapshot

    fn FlowGraph::snapshot(self : FlowGraph) -> FlowGraph

    Return a detached copy of this graph and all task metadata arrays.

    FlowGraph::snapshot_json

    fn FlowGraph::snapshot_json(self : FlowGraph, trace : Trace) -> Result[String, SnapshotError]

    Build a fresh plan, validate trace references, and render JSON.

    FlowGraph::snapshot_markdown

    fn FlowGraph::snapshot_markdown(self : FlowGraph, trace : Trace) -> Result[String, SnapshotError]

    Build a fresh plan, validate trace references, and render Markdown.

    FlowGraph::successors

    fn FlowGraph::successors(self : FlowGraph, id : TaskId) -> Result[Array[TaskId], GraphError]

    Return immediate successor ids for a task.

    FlowGraph::task_count

    fn FlowGraph::task_count(self : FlowGraph) -> Int

    Return the number of task nodes.

    FlowGraph::tasks

    fn FlowGraph::tasks(self : FlowGraph) -> Array[TaskNode]

    Return a detached copy of task nodes and their metadata arrays.

    FlowGraph::tasks_snapshot

    fn FlowGraph::tasks_snapshot(self : FlowGraph) -> Array[TaskNode]

    Return a detached copy of task nodes and their metadata arrays.

    FlowGraph::to_json

    fn FlowGraph::to_json(self : FlowGraph, plan : ExecutionPlan, trace : Trace) -> String

    Render a compact JSON string for tooling or snapshot artifacts.

    This compatibility API trusts the supplied plan. New code should prefer to_json_checked or snapshot_json.

    FlowGraph::to_json_checked

    fn FlowGraph::to_json_checked(self : FlowGraph, plan : ExecutionPlan, trace : Trace) -> Result[String, SnapshotError]

    Validate a supplied plan and trace before rendering JSON.

    FlowGraph::to_markdown

    fn FlowGraph::to_markdown(self : FlowGraph, plan : ExecutionPlan, trace : Trace) -> String

    Render a graph, plan, and trace as a Markdown execution report.

    This compatibility API trusts the supplied plan. New code should prefer to_markdown_checked or snapshot_markdown.

    FlowGraph::to_markdown_checked

    fn FlowGraph::to_markdown_checked(self : FlowGraph, plan : ExecutionPlan, trace : Trace) -> Result[String, SnapshotError]

    Validate a supplied plan and trace before rendering Markdown.

    FlowGraph::to_mermaid

    fn FlowGraph::to_mermaid(self : FlowGraph) -> Result[String, GraphError]

    Render a validated task graph as a Mermaid flowchart.

    FlowGraph::to_workflow_spec

    fn FlowGraph::to_workflow_spec(self : FlowGraph) -> WorkflowSpec

    Convert a graph into workflow-spec-v1 input JSON semantics.

    Runtime task status is intentionally not preserved in workflow specs.

    FlowGraph::topological_sort

    fn FlowGraph::topological_sort(self : FlowGraph) -> Result[Array[TaskId], GraphError]

    Return a topological execution order.

    FlowGraph::transition_status

    fn FlowGraph::transition_status(self : FlowGraph, id : TaskId, status : TaskStatus) -> Result[Unit, StatusTransitionError]

    Update a task through the documented execution-state machine.

    update_status remains available for replay and compatibility. Normal execution should prefer this checked method.

    FlowGraph::update_status

    fn FlowGraph::update_status(self : FlowGraph, id : TaskId, status : TaskStatus) -> Result[Unit, GraphError]

    Update the status of an existing task.

    FlowGraph::validate

    fn FlowGraph::validate(self : FlowGraph) -> Result[Unit, GraphError]

    Validate all edge endpoints and cycle freedom.

    FlowGraph::validate_plan

    fn FlowGraph::validate_plan(self : FlowGraph, plan : ExecutionPlan) -> Result[Unit, SnapshotError]

    Check that a plan still exactly matches the graph's deterministic plan.

    FlowGraph::validate_snapshot

    fn FlowGraph::validate_snapshot(self : FlowGraph, plan : ExecutionPlan, trace : Trace) -> Result[Unit, SnapshotError]

    Check graph validity, plan freshness, and trace task references together.

    FlowGraph::validate_trace

    fn FlowGraph::validate_trace(self : FlowGraph, trace : Trace) -> Result[Unit, SnapshotError]

    Check that every trace event refers to a task in this graph.

    GraphError

    pub(all) enum GraphError {
    DuplicateTask(TaskId)
    DuplicateDependency(Dependency)
    MissingTask(TaskId)
    MissingDependencyEndpoint(Dependency)
    CycleDetected(Array[TaskId])
    } derive(Eq,
    Debug
    )

    Graph errors retain the ids and edges needed for useful diagnostics.

    GraphError::message

    fn GraphError::message(self : GraphError) -> String

    Return a readable diagnostic message for a graph error.

    RunSnapshot

    pub struct RunSnapshot {
    // private fields
    } derive(
    Debug
    )

    A validated run-snapshot-v1 artifact containing graph, plan, and trace data.

    RunSnapshot::audit

    fn RunSnapshot::audit(self : RunSnapshot) -> Result[Unit, RunSnapshotError]

    Validate graph structure, serialized plan, trace references, and lifecycle.

    RunSnapshot::from_json

    fn RunSnapshot::from_json(input : String) -> Result[RunSnapshot, RunSnapshotError]

    Parse and audit a run-snapshot-v1 JSON string.

    RunSnapshot::graph

    fn RunSnapshot::graph(self : RunSnapshot) -> FlowGraph

    Return a detached graph copy.

    RunSnapshot::plan

    Return a detached execution-plan copy.

    RunSnapshot::to_json

    fn RunSnapshot::to_json(self : RunSnapshot) -> String

    Render this audited snapshot in canonical run-snapshot-v1 form.

    RunSnapshot::trace

    fn RunSnapshot::trace(self : RunSnapshot) -> Trace

    Return a detached trace copy.

    RunSnapshotError

    pub(all) enum RunSnapshotError {
    InvalidRunSnapshotJson(String)
    UnsupportedRunSnapshotSchema(String)
    MissingRunSnapshotField(String)
    InvalidRunSnapshotField(String)
    RunSnapshotGraphError(GraphError)
    RunSnapshotPlanMismatch
    RunSnapshotUnknownTraceTask(TaskId)
    InvalidTraceLifecycle(TaskId, TraceEventType)
    RunSnapshotStatusMismatch(TaskId, TaskStatus, String)
    } derive(Eq,
    Debug
    )

    Errors raised while parsing or auditing run-snapshot-v1 JSON.

    RunSnapshotError::message

    fn RunSnapshotError::message(self : RunSnapshotError) -> String

    Return a readable diagnostic for snapshot import and audit errors.

    SnapshotError

    pub(all) enum SnapshotError {
    SnapshotGraphError(GraphError)
    StaleExecutionPlan
    UnknownTraceTask(TaskId)
    } derive(Eq,
    Debug
    )

    Errors raised when a plan or trace no longer matches its graph.

    SnapshotError::message

    fn SnapshotError::message(self : SnapshotError) -> String

    Return a readable diagnostic for snapshot validation.

    StatusTransitionError

    pub(all) enum StatusTransitionError {
    TransitionMissingTask(TaskId)
    InvalidStatusTransition(TaskId, TaskStatus, TaskStatus)
    } derive(Eq,
    Debug
    )

    Errors raised by checked task-status transitions.

    StatusTransitionError::message

    fn StatusTransitionError::message(self : StatusTransitionError) -> String

    Return a readable diagnostic for a checked status transition.

    TaskId

    pub struct TaskId {
    // private fields
    } derive(Eq,
    Debug
    )

    Task identifier used by the public graph API.

    TaskId::new

    fn TaskId::new(value : String) -> TaskId

    Build a task id.

    TaskId::value

    fn TaskId::value(self : TaskId) -> String

    Return the raw string value of this task id.

    TaskNode

    pub struct TaskNode {
    // private fields
    } derive(Eq,
    Debug
    )

    A node in a reproducible research or agent workflow.

    TaskNode::description

    fn TaskNode::description(self : TaskNode) -> String

    Return this task's description.

    TaskNode::id

    fn TaskNode::id(self : TaskNode) -> TaskId

    Return this task's id.

    TaskNode::inputs

    fn TaskNode::inputs(self : TaskNode) -> Array[String]

    Return a detached copy of this task's input labels.

    TaskNode::new

    fn TaskNode::new(id : String, title : String) -> TaskNode

    Build a basic pending task.

    TaskNode::outputs

    fn TaskNode::outputs(self : TaskNode) -> Array[String]

    Return a detached copy of this task's output labels.

    TaskNode::snapshot

    fn TaskNode::snapshot(self : TaskNode) -> TaskNode

    Return a detached copy of a task node and its metadata arrays.

    TaskNode::status

    fn TaskNode::status(self : TaskNode) -> TaskStatus

    Return this task's execution status.

    TaskNode::tags

    fn TaskNode::tags(self : TaskNode) -> Array[String]

    Return a detached copy of this task's tags.

    TaskNode::title

    fn TaskNode::title(self : TaskNode) -> String

    Return this task's title.

    TaskNode::with_description

    fn TaskNode::with_description(self : TaskNode, description : String) -> TaskNode

    Add a short description.

    TaskNode::with_inputs

    fn TaskNode::with_inputs(self : TaskNode, inputs : Array[String]) -> TaskNode

    Add input labels or artifacts.

    TaskNode::with_outputs

    fn TaskNode::with_outputs(self : TaskNode, outputs : Array[String]) -> TaskNode

    Add output labels or artifacts.

    TaskNode::with_status

    fn TaskNode::with_status(self : TaskNode, status : TaskStatus) -> TaskNode

    Override status.

    TaskNode::with_tags

    fn TaskNode::with_tags(self : TaskNode, tags : Array[String]) -> TaskNode

    Add topic tags.

    TaskStatus

    pub(all) enum TaskStatus {
    Pending
    Ready
    Running
    Succeeded
    Failed(String)
    Skipped(String)
    } derive(Eq,
    Debug
    )

    Execution status tracked for each task node.

    TaskStatus::can_transition_to

    fn TaskStatus::can_transition_to(self : TaskStatus, next : TaskStatus) -> Bool

    Return whether a status transition is valid for normal execution.

    TaskStatus::kind

    fn TaskStatus::kind(self : TaskStatus) -> String

    Return a stable machine-readable status kind without an error reason.

    TaskStatus::label

    fn TaskStatus::label(self : TaskStatus) -> String

    Return a stable human-readable task status label.

    TaskStatus::reason

    fn TaskStatus::reason(self : TaskStatus) -> String?

    Return the reason attached to a failed or skipped status.

    Trace

    pub struct Trace {
    // private fields
    } derive(
    Debug
    )

    Mutable trace log.

    Trace::event_count

    fn Trace::event_count(self : Trace) -> Int

    Return the number of recorded events.

    Trace::events

    fn Trace::events(self : Trace) -> Array[TraceEvent]

    Return a detached copy of events in append order.

    Trace::events_for

    fn Trace::events_for(self : Trace, task_id : TaskId) -> Array[TraceEvent]

    Return events for a single task id in append order.

    Trace::events_snapshot

    fn Trace::events_snapshot(self : Trace) -> Array[TraceEvent]

    Return a detached copy of events in append order.

    Trace::latest_for

    fn Trace::latest_for(self : Trace, task_id : TaskId) -> TraceEvent?

    Return the most recently appended event for a task.

    Trace::new

    fn Trace::new() -> Trace

    Build an empty trace log.

    Trace::record

    fn Trace::record(self : Trace, event : TraceEvent) -> Unit

    Append an event.

    Trace::snapshot

    fn Trace::snapshot(self : Trace) -> Trace

    Return a detached copy of this trace log.

    Trace::summary_markdown

    fn Trace::summary_markdown(self : Trace) -> String

    Render a compact Markdown summary of trace events.

    TraceEvent

    pub struct TraceEvent {
    // private fields
    } derive(Eq,
    Debug
    )

    A single trace event. Timestamp is a string so users can choose wall-clock, logical, or deterministic timestamps.

    TraceEvent::event_type

    fn TraceEvent::event_type(self : TraceEvent) -> TraceEventType

    Return this event's type.

    TraceEvent::message

    fn TraceEvent::message(self : TraceEvent) -> String

    Return this event's human-readable message.

    TraceEvent::new

    fn TraceEvent::new(task_id : TaskId, event_type : TraceEventType, message : String, timestamp : String) -> TraceEvent

    Build a trace event.

    TraceEvent::task_id

    fn TraceEvent::task_id(self : TraceEvent) -> TaskId

    Return the task id associated with this event.

    TraceEvent::timestamp

    fn TraceEvent::timestamp(self : TraceEvent) -> String

    Return this event's timestamp string.

    TraceEventType

    pub(all) enum TraceEventType {
    Planned
    Started
    Completed
    FailedEvent
    SkippedEvent
    Note
    } derive(Eq,
    Debug
    )

    Event type for provenance trace.

    TraceEventType::label

    fn TraceEventType::label(self : TraceEventType) -> String

    Return a stable human-readable event type label.

    WorkflowSpec

    pub struct WorkflowSpec {
    // private fields
    } derive(Eq,
    Debug
    )

    Workflow input definition, separated from run-snapshot JSON output.

    WorkflowSpec::dependencies

    fn WorkflowSpec::dependencies(self : WorkflowSpec) -> Array[Dependency]

    Return a detached copy of workflow dependency edges.

    WorkflowSpec::from_json

    fn WorkflowSpec::from_json(input : String) -> Result[WorkflowSpec, WorkflowSpecError]

    Parse, type-check, and validate a workflow-spec-v1 JSON string.

    WorkflowSpec::new

    fn WorkflowSpec::new(tasks : Array[WorkflowTaskSpec], dependencies : Array[Dependency]) -> WorkflowSpec

    Build a workflow spec from tasks and dependency edges.

    WorkflowSpec::tasks

    Return a detached copy of workflow task specs.

    WorkflowSpec::to_graph

    fn WorkflowSpec::to_graph(self : WorkflowSpec) -> Result[FlowGraph, GraphError]

    Convert this workflow definition into a validated flow graph.

    WorkflowSpec::to_json

    fn WorkflowSpec::to_json(self : WorkflowSpec) -> String

    Render this workflow spec as workflow-spec-v1 JSON.

    WorkflowSpecError

    pub(all) enum WorkflowSpecError {
    InvalidWorkflowJson(String)
    UnsupportedWorkflowSchema(String)
    MissingWorkflowField(String)
    InvalidWorkflowField(String)
    WorkflowGraphError(GraphError)
    } derive(Eq,
    Debug
    )

    Errors raised while parsing and validating workflow-spec-v1 JSON.

    WorkflowSpecError::message

    fn WorkflowSpecError::message(self : WorkflowSpecError) -> String

    Return a readable diagnostic for workflow spec errors.

    WorkflowTaskSpec

    pub struct WorkflowTaskSpec {
    // private fields
    } derive(Eq,
    Debug
    )

    A task definition in workflow-spec-v1 input JSON.

    Unlike TaskNode, this type models user-supplied workflow structure and does not carry runtime execution status.

    WorkflowTaskSpec::description

    fn WorkflowTaskSpec::description(self : WorkflowTaskSpec) -> String

    Return this workflow task description.

    WorkflowTaskSpec::id

    Return this workflow task id.

    WorkflowTaskSpec::inputs

    fn WorkflowTaskSpec::inputs(self : WorkflowTaskSpec) -> Array[String]

    Return a detached copy of this workflow task's input labels.

    WorkflowTaskSpec::new

    fn WorkflowTaskSpec::new(id : String, title : String) -> WorkflowTaskSpec

    Build a workflow task spec.

    WorkflowTaskSpec::outputs

    fn WorkflowTaskSpec::outputs(self : WorkflowTaskSpec) -> Array[String]

    Return a detached copy of this workflow task's output labels.

    WorkflowTaskSpec::snapshot

    Return a detached copy of a workflow task spec.

    WorkflowTaskSpec::tags

    fn WorkflowTaskSpec::tags(self : WorkflowTaskSpec) -> Array[String]

    Return a detached copy of this workflow task's tags.

    WorkflowTaskSpec::title

    fn WorkflowTaskSpec::title(self : WorkflowTaskSpec) -> String

    Return this workflow task title.

    WorkflowTaskSpec::with_description

    fn WorkflowTaskSpec::with_description(self : WorkflowTaskSpec, description : String) -> WorkflowTaskSpec

    Add a short description to a workflow task spec.

    WorkflowTaskSpec::with_inputs

    fn WorkflowTaskSpec::with_inputs(self : WorkflowTaskSpec, inputs : Array[String]) -> WorkflowTaskSpec

    Add input labels or artifacts to a workflow task spec.

    WorkflowTaskSpec::with_outputs

    fn WorkflowTaskSpec::with_outputs(self : WorkflowTaskSpec, outputs : Array[String]) -> WorkflowTaskSpec

    Add output labels or artifacts to a workflow task spec.

    WorkflowTaskSpec::with_tags

    fn WorkflowTaskSpec::with_tags(self : WorkflowTaskSpec, tags : Array[String]) -> WorkflowTaskSpec

    Add topic tags to a workflow task spec.