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::collections::{HashMap, HashSet};

use crate::runtime::goal::agent::types::{
    AcceptedGoalAgentAccessSet, GoalAgentAccessConflict, GoalAgentRejectedTask,
    GoalAgentTaskPolicy, GoalAgentTaskProposal,
};
use crate::runtime::goal::state::GoalState;
use crate::runtime::goal::task_graph::{GoalTaskGraph, GoalTaskStatus};

pub(crate) fn validate_goal_agent_task_proposals(
    state: &GoalState,
    task_graph: &GoalTaskGraph,
    run_id: &str,
    proposals: Vec<GoalAgentTaskProposal>,
    allow_existing_task_ids: bool,
) -> GoalAgentTaskPolicy {
    let existing_task_ids: HashSet<String> = task_graph
        .tasks
        .iter()
        .map(|task| task.id.clone())
        .collect();
    let mut known_dependencies: HashSet<String> = task_graph
        .tasks
        .iter()
        .filter(|task| task.status == GoalTaskStatus::Done)
        .map(|task| task.id.clone())
        .collect();
    let mut accepted_dependency_closures: HashMap<String, HashSet<String>> = HashMap::new();
    let mut accepted_access_sets: Vec<AcceptedGoalAgentAccessSet> = Vec::new();
    let mut seen_ids = HashSet::new();
    let mut accepted_tasks = Vec::new();
    let mut rejected_tasks = Vec::new();

    for proposal in proposals.iter().cloned() {
        let dependency_closure =
            proposal_dependency_closure(&proposal, &accepted_dependency_closures);
        if let Some(reason) = reject_goal_agent_task_proposal(
            &proposal,
            &mut seen_ids,
            &known_dependencies,
            &existing_task_ids,
            &accepted_access_sets,
            &dependency_closure,
            allow_existing_task_ids,
        ) {
            rejected_tasks.push(GoalAgentRejectedTask {
                task: proposal,
                reason,
            });
            continue;
        }

        known_dependencies.insert(proposal.id.clone());
        accepted_access_sets.push(AcceptedGoalAgentAccessSet {
            task_id: proposal.id.clone(),
            read_set: proposal.read_set.clone(),
            write_set: proposal.write_set.clone(),
        });
        accepted_dependency_closures.insert(proposal.id.clone(), dependency_closure);
        accepted_tasks.push(proposal);
    }

    GoalAgentTaskPolicy {
        goal_id: state.goal_id.clone(),
        run_id: run_id.to_string(),
        max_agents: state.max_agents.unwrap_or(1).max(1),
        proposed_tasks: proposals,
        accepted_tasks,
        rejected_tasks,
    }
}

fn reject_goal_agent_task_proposal(
    proposal: &GoalAgentTaskProposal,
    seen_ids: &mut HashSet<String>,
    known_dependencies: &HashSet<String>,
    existing_task_ids: &HashSet<String>,
    accepted_access_sets: &[AcceptedGoalAgentAccessSet],
    dependency_closure: &HashSet<String>,
    allow_existing_task_ids: bool,
) -> Option<String> {
    if proposal.id.trim().is_empty() {
        return Some("task id must not be empty".to_string());
    }
    if proposal.title.trim().is_empty() {
        return Some("task title must not be empty".to_string());
    }
    if proposal.description.trim().is_empty() {
        return Some("task description must not be empty".to_string());
    }
    if !seen_ids.insert(proposal.id.clone()) {
        return Some("duplicate task id rejected by goal policy".to_string());
    }
    if !allow_existing_task_ids && existing_task_ids.contains(&proposal.id) {
        return Some("task id already exists in the goal graph".to_string());
    }
    if proposal.budget_secs == 0 {
        return Some("task budget must be greater than zero".to_string());
    }

    let policy_text = format!(
        "{} {} {}",
        proposal.id,
        proposal.description,
        proposal.write_set.join(" ")
    )
    .to_ascii_lowercase();
    if policy_text.contains("crates.io") || policy_text.contains("publish") {
        return Some("publishing is disabled for GitHub-only goal execution".to_string());
    }

    if let Some(path) = proposal
        .read_set
        .iter()
        .chain(proposal.write_set.iter())
        .find(|path| !crate::runtime::goal::state::is_safe_goal_agent_path(path))
    {
        return Some(format!(
            "path is outside the allowed goal policy roots: {path}"
        ));
    }

    if let Some(dep) = proposal
        .dependencies
        .iter()
        .find(|dep| !known_dependencies.contains(*dep))
    {
        return Some(format!("dependency is not accepted or completed: {dep}"));
    }

    if let Some((task_id, conflict)) =
        first_unordered_access_conflict(proposal, accepted_access_sets, dependency_closure)
    {
        let GoalAgentAccessConflict { kind, path } = conflict;
        return Some(format!("{kind} with accepted task {task_id}: {path}"));
    }

    None
}

fn proposal_dependency_closure(
    proposal: &GoalAgentTaskProposal,
    accepted_dependency_closures: &HashMap<String, HashSet<String>>,
) -> HashSet<String> {
    let mut closure = HashSet::new();
    for dependency in &proposal.dependencies {
        closure.insert(dependency.clone());
        if let Some(upstream) = accepted_dependency_closures.get(dependency) {
            closure.extend(upstream.iter().cloned());
        }
    }
    closure
}

fn first_unordered_access_conflict(
    proposal: &GoalAgentTaskProposal,
    accepted_access_sets: &[AcceptedGoalAgentAccessSet],
    dependency_closure: &HashSet<String>,
) -> Option<(String, GoalAgentAccessConflict)> {
    for accepted in accepted_access_sets {
        if dependency_closure.contains(&accepted.task_id) {
            continue;
        }
        if let Some(path) = crate::runtime::goal::agent::path_policy::first_conflicting_path(
            &proposal.write_set,
            &accepted.write_set,
        ) {
            return Some((
                accepted.task_id.clone(),
                GoalAgentAccessConflict {
                    kind: "write-set conflict",
                    path,
                },
            ));
        }
        if let Some(path) = crate::runtime::goal::agent::path_policy::first_conflicting_path(
            &proposal.read_set,
            &accepted.write_set,
        ) {
            return Some((
                accepted.task_id.clone(),
                GoalAgentAccessConflict {
                    kind: "read/write conflict",
                    path,
                },
            ));
        }
        if let Some(path) = crate::runtime::goal::agent::path_policy::first_conflicting_path(
            &proposal.write_set,
            &accepted.read_set,
        ) {
            return Some((
                accepted.task_id.clone(),
                GoalAgentAccessConflict {
                    kind: "write/read conflict",
                    path,
                },
            ));
        }
    }
    None
}

pub(crate) fn goal_agent_task_policy_payload(
    proposal: &GoalAgentTaskProposal,
    reason: Option<&str>,
) -> serde_json::Value {
    serde_json::json!({
        "task_id": proposal.id,
        "title": proposal.title,
        "risk": proposal.risk,
        "budget_secs": proposal.budget_secs,
        "dependencies": proposal.dependencies,
        "read_set": proposal.read_set,
        "write_set": proposal.write_set,
        "reason": reason,
    })
}