ainl-contracts 0.1.4

Shared policy contracts for repo intelligence, context freshness, and impact-first tooling (no OpenFang deps)
Documentation
//! Mission control-plane types (graph-native mission substrate).

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::path::PathBuf;

/// Stable mission identifier.
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct MissionId(pub String);

impl MissionId {
    pub fn as_str(&self) -> &str {
        &self.0
    }
}

impl From<String> for MissionId {
    fn from(s: String) -> Self {
        Self(s)
    }
}

impl From<&str> for MissionId {
    fn from(s: &str) -> Self {
        Self(s.to_string())
    }
}

/// Lifecycle state for a long-running mission.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
#[serde(rename_all = "snake_case")]
pub enum MissionState {
    #[default]
    AwaitingInput,
    Initializing,
    Running,
    Paused,
    OrchestratorTurn,
    Completed,
    Cancelled,
}

/// Optional capability flags stored on the mission record.
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct MissionCapabilityFlags {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub coding_domain: Option<bool>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub auto_remediation: Option<bool>,
}

/// A mission: objective + milestone grouping + workspace root.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Mission {
    pub mission_id: MissionId,
    pub objective_md: String,
    pub state: MissionState,
    #[serde(default)]
    pub milestone_ids: Vec<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub mission_root: Option<PathBuf>,
    pub created_at: DateTime<Utc>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub last_orchestrator_turn_at: Option<DateTime<Utc>>,
    #[serde(default)]
    pub capability_flags: MissionCapabilityFlags,
}