omk 0.5.0

A Rust runtime for Kimi CLI. Turns prompts into proof-backed engineering runs with gates, worktrees, and replay.
Documentation
use std::path::Path;

use crate::runtime::goal::proof::{build_verified_proof, GoalProof};
use crate::runtime::goal::state::{
    FileSystemGoalStateStore, GoalPhase, GoalState, GoalStateStore, GoalStatus,
};
use crate::runtime::goal::task_graph::GoalTaskGraph;
use crate::runtime::goal::{budget, evidence, proof, state, verifier};

pub async fn review_goal(goal_id: &str, project_dir: &Path) -> anyhow::Result<GoalProof> {
    let mut state = crate::runtime::goal::resolve_goal(goal_id).await?;
    super::ensure_goal_can_continue(&state)?;
    budget::ensure_budget_available(&mut state, "goal review").await?;
    let phase_start = tokio::time::Instant::now();
    state.status = GoalStatus::Running;
    state.phase = GoalPhase::VerificationDesign;
    state.updated_at = chrono::Utc::now();
    state.completed_at = None;
    FileSystemGoalStateStore::new().save(&state).await?;

    let mut state = crate::runtime::goal::resolve_goal(goal_id).await?;
    let mut task_graph = GoalTaskGraph::load(&state.state_dir).await?;
    let prior_proof = GoalProof::load(&state.state_dir).await?;
    let now = chrono::Utc::now();

    let review_evidence =
        verifier::write_goal_review_evidence(&state, &task_graph, &prior_proof, project_dir, now)
            .await?;
    let mut updated_tasks = Vec::new();
    if let Some(task) =
        verifier::apply_goal_review_task_result(&mut task_graph, &review_evidence, now)
    {
        updated_tasks.push(task);
    }
    if let Some(task) =
        verifier::apply_goal_security_review_task_result(&mut task_graph, &review_evidence, now)
    {
        updated_tasks.push(task);
    }
    verifier::append_goal_review_task_events(&state, &updated_tasks).await?;
    task_graph.save(&state.state_dir).await?;

    evidence::record_artifact_path_once(
        &mut state,
        "review",
        review_evidence.review_path.clone(),
        now,
    );
    evidence::record_artifact_path_once(
        &mut state,
        "security_review",
        review_evidence.security_review_path.clone(),
        now,
    );
    state.status = GoalStatus::NotReady;
    state.phase = GoalPhase::Proof;
    state.updated_at = now;
    state.completed_at = Some(now);
    FileSystemGoalStateStore::new().save(&state).await?;

    let proof = build_verified_proof(
        &state,
        &task_graph,
        prior_proof.gates,
        prior_proof.changed_files,
        prior_proof.git,
        prior_proof.post_mutation_gates_ran,
        now,
    );
    proof::write_json_artifact(&state.state_dir.join(state::GOAL_PROOF_FILE), &proof).await?;
    super::append_proof_event(&state, &proof).await?;
    budget::append_budget_checkpoint(&state, "review_completed").await?;

    let phase_duration = tokio::time::Instant::now() - phase_start;
    if let Ok(tracker) = budget::init_goal_cost_tracker(&state) {
        let cost = crate::cost::types::SessionCost {
            session_type: "review".to_string(),
            name: "goal review".to_string(),
            started_at: chrono::Utc::now(),
            ended_at: Some(chrono::Utc::now()),
            estimate: crate::cost::estimator::CostEstimate {
                input_tokens: 0,
                output_tokens: 0,
                duration_secs: phase_duration.as_secs(),
                worker_count: 1,
                estimated_usd: 0.0,
                tier: crate::cost::estimator::PricingTier::Standard,
            },
            actual_usd: None,
        };
        let _ = tracker.record(cost).await;
    }

    Ok(proof)
}

pub(crate) async fn run_post_mutation_cycle(
    state: &GoalState,
    project_dir: &Path,
    task_graph: &mut GoalTaskGraph,
    verification_proof: GoalProof,
    agent_execution_succeeded: bool,
    agent_evidence: &evidence::GoalAgentRunEvidence,
    now: chrono::DateTime<chrono::Utc>,
) -> anyhow::Result<(
    Vec<crate::runtime::gates::GateResult>,
    Option<crate::runtime::goal::evidence::GoalGitEvidence>,
    Vec<String>,
    bool,
)> {
    let mut proof_gates = verification_proof.gates;
    let mut proof_git = verification_proof.git;
    let mut proof_changed_files = agent_evidence.changed_files.clone();
    let mut post_mutation_gates_ran = false;

    if agent_execution_succeeded && !proof_changed_files.is_empty() {
        let gate_config = crate::runtime::gates::load_or_detect_gates(project_dir).await;
        let gate_artifacts = state
            .state_dir
            .join(state::GOAL_ARTIFACTS_DIR)
            .join(state::GOAL_GATE_ARTIFACTS_DIR)
            .join("post-mutation");
        proof_gates = crate::runtime::gates::run_gates_with_evidence(
            &gate_config,
            project_dir,
            Some(&gate_artifacts),
        )
        .await;
        verifier::append_gate_events(state, &proof_gates).await?;
        proof_git = evidence::detect_git_evidence(project_dir).await;
        proof_changed_files = crate::runtime::gates::detect_changed_files(project_dir).await;
        if let Some(task) =
            verifier::apply_local_verification_task_result(task_graph, &proof_gates, now)
        {
            verifier::append_local_verification_task_events(state, &task).await?;
        }
        post_mutation_gates_ran = true;
    }

    Ok((
        proof_gates,
        proof_git,
        proof_changed_files,
        post_mutation_gates_ran,
    ))
}