Skip to main content

OrchestratorHandle

Struct OrchestratorHandle 

Source
pub struct OrchestratorHandle { /* private fields */ }
Expand description

The primary public API for embedding xchecker.

OrchestratorHandle provides a stable interface for creating specs and running phases programmatically. It is the canonical way to use xchecker outside of the CLI.

§Overview

Use OrchestratorHandle to:

  • Create and manage specs programmatically
  • Execute individual phases or the full workflow
  • Query spec status and artifacts
  • Configure execution options

§Construction

There are two ways to create an OrchestratorHandle:

§Threading

OrchestratorHandle is NOT guaranteed Send or Sync in 1.x. Treat as single-threaded; concurrent use is undefined behavior. This may be relaxed in future versions.

§Mutability

Methods that execute phases take &mut self to encode “sequential use only” semantics. This prevents accidental concurrent use at compile time.

§Sync vs Async

Public APIs are synchronous and manage their own async runtime internally. Tokio is an implementation detail not exposed to library consumers.

§Example

use xchecker_engine::orchestrator::OrchestratorHandle;
use xchecker_engine::types::PhaseId;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Using environment-based config discovery
    let mut handle = OrchestratorHandle::new("my-spec")?;

    // Run a single phase
    handle.run_phase(PhaseId::Requirements).await?;

    // Check status
    let status = handle.status()?;
    println!("Artifacts: {}", status.artifacts.len());

    // Get the spec ID
    println!("Spec: {}", handle.spec_id());
    Ok(())
}

§Using Explicit Configuration

use xchecker_engine::config::Config;
use xchecker_engine::orchestrator::OrchestratorHandle;

// Create explicit config programmatically
let config = Config::discover(&Default::default())?;
let handle = OrchestratorHandle::from_config("my-spec", config)?;

§Error Handling

All methods return Result types. Errors are returned as XCheckerError which provides:

Implementations§

Source§

impl OrchestratorHandle

Source

pub fn new(spec_id: &str) -> Result<Self, XCheckerError>

Create a handle using environment-based config discovery.

This uses the same discovery logic as the CLI:

  • XCHECKER_HOME environment variable
  • Upward search for .xchecker/config.toml
  • Built-in defaults

Acquires an exclusive lock on the spec directory.

§Errors

Returns error if:

  • Configuration discovery fails
  • Orchestrator creation fails
  • Lock cannot be acquired
§Example
use xchecker_engine::orchestrator::OrchestratorHandle;

let handle = OrchestratorHandle::new("my-spec")?;
Source

pub fn from_config(spec_id: &str, config: Config) -> Result<Self, XCheckerError>

Create a handle using explicit configuration.

This does NOT probe the global environment or filesystem for config. Use this when you need deterministic behavior independent of the user’s environment.

§Errors

Returns error if:

  • Orchestrator creation fails
  • Lock cannot be acquired
§Example
use xchecker_engine::config::Config;
use xchecker_engine::orchestrator::OrchestratorHandle;

// Create explicit config programmatically
let config = Config::discover(&Default::default())?;
let handle = OrchestratorHandle::from_config("my-spec", config)?;
Source

pub fn with_force(spec_id: &str, force: bool) -> Result<Self, XCheckerError>

Create a handle with force flag for lock override.

Use with caution: forcing lock override can lead to race conditions if another process is actively working on the spec.

§Errors

Returns error if orchestrator creation fails.

Source

pub fn with_config_and_force( spec_id: &str, config: OrchestratorConfig, force: bool, ) -> Result<Self, XCheckerError>

Create a handle with custom OrchestratorConfig and force flag.

This is used by the CLI when it needs to pass specific orchestrator configuration options.

§Errors

Returns error if orchestrator creation fails.

Source

pub fn readonly(spec_id: &str) -> Result<Self, XCheckerError>

Create a read-only handle for status inspection.

Does not acquire locks, allowing inspection while another process is actively working on the spec.

§Errors

Returns error if orchestrator creation fails.

Source

pub async fn run_phase(&mut self, phase: PhaseId) -> Result<ExecutionResult>

Execute a single phase.

Behavior matches the CLI xchecker resume --phase <phase> command. Takes &mut self to enforce sequential use.

§Errors

Returns error if transition is invalid or execution fails.

§Example
use xchecker_engine::orchestrator::OrchestratorHandle;
use xchecker_engine::types::PhaseId;

let mut handle = OrchestratorHandle::new("my-spec")?;
handle.run_phase(PhaseId::Requirements).await?;
Source

pub async fn run_all(&mut self) -> Result<ExecutionResult>

Execute all phases in sequence.

Stops on first failure. Behavior matches the CLI xchecker spec command. Takes &mut self to enforce sequential use.

§Errors

Returns error if any phase fails.

§Example
use xchecker_engine::orchestrator::OrchestratorHandle;

let mut handle = OrchestratorHandle::new("my-spec")?;
handle.run_all().await?;
Source

pub fn status(&self) -> Result<StatusOutput, XCheckerError>

Get the current spec status.

Returns StatusOutput which is part of the stable public API.

§Errors

Returns error if status generation fails.

Source

pub fn last_receipt_path(&self) -> Option<PathBuf>

Get the path to the most recent receipt.

Returns None if no receipts have been written.

Source

pub fn spec_id(&self) -> &str

Get the spec ID this handle operates on.

Source

pub fn can_run_phase(&self, phase: PhaseId) -> Result<bool>

Check if a phase can be run.

Validates that all dependencies are satisfied and have successful receipts.

§Returns

true if the phase can be executed, false otherwise.

Source

pub fn current_phase(&self) -> Result<Option<PhaseId>>

Get the current phase state.

Returns the last successfully completed phase, or None if no phases have been completed.

Source

pub fn legal_next_phases(&self) -> Result<Vec<PhaseId>>

Get legal next phases from current state.

Returns a list of phases that can be validly executed based on the current workflow state.

Source

pub fn set_config(&mut self, key: &str, value: &str)

Set a configuration option.

Common keys include:

  • model: LLM model to use
  • phase_timeout: Timeout in seconds
  • apply_fixups: Whether to apply fixups or preview
Source

pub fn get_config(&self, key: &str) -> Option<&String>

Get a configuration option.

Returns None if the key is not set.

Source

pub fn set_dry_run(&mut self, dry_run: bool)

Enable or disable dry-run mode.

In dry-run mode, phases are simulated without calling the LLM.

Source

pub fn orchestrator_config(&self) -> &OrchestratorConfig

Get the current orchestrator configuration.

Returns a reference to the configuration used for phase execution.

Trait Implementations§

Source§

impl SpecDataProvider for &OrchestratorHandle

Source§

fn base_path(&self) -> &Path

Get the base path for the spec
Source§

fn spec_id(&self) -> &str

Get the spec ID
Source§

fn receipt_manager(&self) -> &ReceiptManager

Get the receipt manager
Source§

fn phase_completed(&self, phase: PhaseId) -> bool

Check if a phase is completed
Source§

fn pending_fixups_result(&self) -> PendingFixupsResult

Get the pending fixups result

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more