mod agent;
mod autonomy;
mod credential;
mod governor;
mod health;
pub(crate) mod identity;
mod monitor;
mod monitor_service;
pub mod platform;
pub(crate) mod resource;
mod roadmap;
mod service;
mod state;
mod status;
mod supervisor;
use anyhow::{bail, Result};
use clap::Subcommand;
use std::path::PathBuf;
#[derive(Subcommand, Debug)]
pub enum OsAction {
Init {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Status {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Doctor {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Agent {
#[command(subcommand)]
action: AgentAction,
},
Credential {
#[command(subcommand)]
action: CredentialAction,
},
Resource {
#[command(subcommand)]
action: ResourceAction,
},
Governor {
#[command(subcommand)]
action: GovernorAction,
},
Monitor {
#[command(subcommand)]
action: MonitorAction,
},
Host {
#[command(subcommand)]
action: HostAction,
},
Supervisor {
#[command(subcommand)]
action: SupervisorAction,
},
Service {
#[command(subcommand)]
action: ResidentServiceAction,
},
Autonomy {
#[command(subcommand)]
action: AutonomyAction,
},
Identity {
#[command(subcommand)]
action: IdentityAction,
},
AgentList {
#[arg(long, default_value_t = 20)]
limit: usize,
},
CredentialStatus,
ResourceStatus,
}
#[derive(Subcommand, Debug)]
pub enum AutonomyAction {
Policy {
#[command(subcommand)]
action: AutonomyPolicyAction,
},
Classify {
operation: autonomy::Operation,
#[arg(long)]
actor: Option<String>,
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Queue {
#[command(subcommand)]
action: AutonomyQueueAction,
},
}
#[derive(Subcommand, Debug)]
pub enum AutonomyPolicyAction {
Show {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Set {
#[arg(long, action = clap::ArgAction::Set)]
enabled: bool,
#[arg(long)]
max_automatic_level: autonomy::AutonomyLevel,
#[arg(long, default_value_t = 1)]
max_attempts: u32,
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
}
#[derive(Subcommand, Debug)]
pub enum AutonomyQueueAction {
List {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Add {
operation: autonomy::Operation,
#[arg(long)]
summary: String,
#[arg(long)]
program: String,
#[arg(long = "arg")]
args: Vec<String>,
#[arg(long)]
verify_program: Option<String>,
#[arg(long = "verify-arg")]
verify_args: Vec<String>,
#[arg(long)]
rollback_program: Option<String>,
#[arg(long = "rollback-arg")]
rollback_args: Vec<String>,
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Approve {
id: String,
#[arg(long)]
approve: bool,
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Cancel {
id: String,
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
}
#[derive(Subcommand, Debug)]
pub enum IdentityAction {
Lease {
#[command(subcommand)]
action: LeaseAction,
},
}
#[derive(Subcommand, Debug)]
pub enum LeaseAction {
Issue {
actor: String,
#[arg(long)]
scope: String,
#[arg(long)]
issued_by: String,
#[arg(long, default_value_t = 3600)]
ttl_secs: u64,
#[arg(long)]
reason: String,
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
List {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Revoke {
id: String,
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
}
#[derive(Subcommand, Debug)]
pub enum AgentAction {
List {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
#[arg(long)]
include_chat_sessions: bool,
#[arg(long, default_value_t = 20)]
limit: usize,
},
Register {
name: String,
#[arg(long)]
provider: String,
#[arg(long)]
model: Option<String>,
#[arg(long)]
session_id: Option<String>,
#[arg(long)]
owner: Option<String>,
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Heartbeat {
id: String,
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Transition {
id: String,
status: state::AgentStatus,
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
}
#[derive(Subcommand, Debug)]
pub enum CredentialAction {
Status {
#[arg(long)]
json: bool,
},
}
#[derive(Subcommand, Debug)]
pub enum ResourceAction {
Show {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Set {
#[arg(long)]
max_active_agents: Option<usize>,
#[arg(long)]
max_tokens_per_request: Option<u64>,
#[arg(long)]
max_daily_cost_usd: Option<f64>,
#[arg(long, default_value_t = 300)]
stale_after_secs: u64,
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Check {
#[arg(long, default_value_t = 1)]
requested_agents: usize,
#[arg(long, default_value_t = 0)]
estimated_tokens: u64,
#[arg(long, default_value_t = 0.0)]
estimated_cost_usd: f64,
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Topology {
#[arg(long)]
json: bool,
},
Pressure {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Reservation {
#[command(subcommand)]
action: ReservationAction,
},
}
#[derive(Subcommand, Debug)]
pub enum ReservationAction {
List {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Reserve {
#[arg(long)]
actor: String,
#[arg(long)]
cpu_cores: Option<usize>,
#[arg(long)]
memory_bytes: Option<u64>,
#[arg(long)]
accelerator_name: Option<String>,
#[arg(long)]
ttl_secs: Option<i64>,
#[arg(long)]
reason: String,
#[arg(long)]
allow_overcommit: bool,
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Release {
id: String,
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
}
#[derive(Subcommand, Debug)]
pub enum GovernorAction {
Status {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
#[arg(long)]
deep: bool,
},
Capacity {
#[command(subcommand)]
action: CapacityAction,
},
Roadmap {
#[command(subcommand)]
action: RoadmapAction,
},
}
#[derive(Subcommand, Debug)]
pub enum HostAction {
Status {
#[arg(long)]
json: bool,
},
Capabilities {
#[arg(long)]
json: bool,
},
}
#[derive(Subcommand, Debug)]
pub enum MonitorAction {
Sample {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Show {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Service {
#[command(subcommand)]
action: MonitorServiceAction,
},
}
#[derive(Subcommand, Debug)]
pub enum MonitorServiceAction {
Install {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long, default_value_t = 60)]
interval_secs: u64,
#[arg(long)]
json: bool,
},
Status {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Uninstall {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
}
#[derive(Subcommand, Debug)]
pub enum ResidentServiceAction {
Install {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long, default_value_t = 60)]
interval_secs: u64,
#[arg(long)]
allow_protected_path: bool,
#[arg(long)]
json: bool,
},
Start {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long, default_value_t = 60)]
interval_secs: u64,
#[arg(long)]
allow_protected_path: bool,
#[arg(long)]
json: bool,
},
Stop {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long, default_value_t = 60)]
interval_secs: u64,
#[arg(long)]
json: bool,
},
Restart {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long, default_value_t = 60)]
interval_secs: u64,
#[arg(long)]
allow_protected_path: bool,
#[arg(long)]
json: bool,
},
Status {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long, default_value_t = 60)]
interval_secs: u64,
#[arg(long)]
json: bool,
},
Uninstall {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long, default_value_t = 60)]
interval_secs: u64,
#[arg(long)]
json: bool,
},
Run {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long, default_value_t = 60)]
interval_secs: u64,
},
}
#[derive(Subcommand, Debug)]
pub enum SupervisorAction {
#[command(hide = true)]
HookCheck {
#[arg(long, default_value = ".")]
dir: PathBuf,
},
Tick {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Status {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
SelfTest {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Halt {
#[arg(long)]
reason: String,
#[arg(long)]
actor: String,
#[arg(long, default_value = ".")]
dir: PathBuf,
},
Unlock {
#[arg(long)]
approve: bool,
#[arg(long)]
reason: String,
#[arg(long)]
actor: String,
#[arg(long, default_value = ".")]
dir: PathBuf,
},
Quarantine {
#[command(subcommand)]
action: SupervisorQuarantineAction,
},
#[command(alias = "service")]
Scheduler {
#[command(subcommand)]
action: MonitorServiceAction,
},
}
#[derive(Subcommand, Debug)]
pub enum SupervisorQuarantineAction {
Set {
mode: supervisor::QuarantineMode,
#[arg(long)]
reason: String,
#[arg(long)]
actor: String,
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Clear {
#[arg(long)]
approve: bool,
#[arg(long)]
reason: String,
#[arg(long)]
actor: String,
#[arg(long, default_value = ".")]
dir: PathBuf,
},
}
#[derive(Subcommand, Debug)]
pub enum CapacityAction {
Show {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Set {
#[arg(long, default_value = "convergence")]
mode: String,
#[arg(long, default_value_t = 2)]
max_active_programs: usize,
#[arg(long, default_value_t = 0)]
max_architecture_changes: usize,
#[arg(long, default_value_t = 0)]
max_new_dependencies: usize,
#[arg(long, default_value_t = 1)]
max_active_experiments: usize,
#[arg(long, default_value_t = 70)]
allocation_consolidation_pct: u8,
#[arg(long, default_value_t = 20)]
allocation_onboarding_and_packaging_pct: u8,
#[arg(long, default_value_t = 10)]
allocation_experiments_pct: u8,
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
}
#[derive(Subcommand, Debug)]
pub enum RoadmapAction {
List {
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Add(Box<RoadmapAddArgs>),
Promote {
#[arg(long)]
id: String,
#[arg(long)]
approve: bool,
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
Demote {
#[arg(long)]
id: String,
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
},
}
#[derive(clap::Args, Debug)]
pub struct RoadmapAddArgs {
#[arg(long)]
tier: roadmap::ProposalTier,
#[arg(long)]
action: state::RoadmapItemAction,
#[arg(long)]
priority: state::RoadmapPriority,
#[arg(long)]
objective: String,
#[arg(long)]
evidence: String,
#[arg(long)]
scope: String,
#[arg(long)]
out_of_scope: String,
#[arg(long)]
dependencies: String,
#[arg(long)]
risks: String,
#[arg(long)]
deliverables: String,
#[arg(long)]
owner: String,
#[arg(long)]
reviewer: String,
#[arg(long)]
acceptance_criteria: String,
#[arg(long)]
exit_criteria: String,
#[arg(long)]
definition_of_done: String,
#[arg(long)]
rollback_path: String,
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
json: bool,
}
pub fn dispatch(action: OsAction) -> Result<()> {
match action {
OsAction::Init { dir, json } => {
let root = state::project_root(&dir)?;
let current = state::initialize(&root)?;
if json {
println!("{}", serde_json::to_string_pretty(¤t)?);
} else {
println!(
"Initialized Yana OS state at {}",
state::state_path(&root).display()
);
println!(
"Resource policy is unset; preflight remains fail-closed until configured."
);
}
}
OsAction::Status { dir, json } => {
let root = state::project_root(&dir)?;
let unified = status::aggregate(&root)?;
status::print(&unified, json)?;
}
OsAction::Doctor { dir, json } => {
let root = state::project_root(&dir)?;
let report = health::inspect(&root);
health::print(&report, json)?;
if report.failed() {
bail!("Yana OS doctor found blocking failures");
}
}
OsAction::Agent { action } => dispatch_agent(action)?,
OsAction::Credential { action } => match action {
CredentialAction::Status { json } => credential::status(json)?,
},
OsAction::Resource { action } => dispatch_resource(action)?,
OsAction::Governor { action } => dispatch_governor(action)?,
OsAction::Monitor { action } => dispatch_monitor(action)?,
OsAction::Host { action } => dispatch_host(action)?,
OsAction::Supervisor { action } => dispatch_supervisor(action)?,
OsAction::Service { action } => dispatch_resident_service(action)?,
OsAction::Autonomy { action } => dispatch_autonomy(action)?,
OsAction::Identity { action } => dispatch_identity(action)?,
OsAction::AgentList { limit } => agent::legacy_list(limit),
OsAction::CredentialStatus => credential::status(false)?,
OsAction::ResourceStatus => resource::legacy_status(),
}
Ok(())
}
fn dispatch_supervisor(action: SupervisorAction) -> Result<()> {
match action {
SupervisorAction::HookCheck { dir } => {
use std::io::Read;
let root = state::project_root(&dir)?;
let mut input = String::new();
std::io::stdin().read_to_string(&mut input)?;
let result = supervisor::hook_check(&root, &input);
if !result.stdout.is_empty() {
print!("{}", result.stdout);
}
if !result.stderr.is_empty() {
eprint!("{}", result.stderr);
}
if result.exit_code != 0 {
std::process::exit(result.exit_code);
}
}
SupervisorAction::Tick { dir, json } => {
let root = state::project_root(&dir)?;
supervisor::print(&supervisor::tick(&root)?, json, "Yana Giám Thị tick")?;
}
SupervisorAction::Status { dir, json } => {
let root = state::project_root(&dir)?;
supervisor::print(
&supervisor::dashboard(&root)?,
json,
"Yana Giám Thị dashboard",
)?;
}
SupervisorAction::SelfTest { dir, json } => {
let root = state::project_root(&dir)?;
let report = supervisor::self_test(&root);
supervisor::print(&report, json, "Yana Giám Thị self-test")?;
if !report.passed {
bail!("Giám Thị self-test found blocking failures");
}
}
SupervisorAction::Halt { reason, actor, dir } => {
let root = state::project_root(&dir)?;
supervisor::halt(&root, &reason, &actor)?;
println!(
"Giám Thị halted all supported engines for {}",
root.display()
);
}
SupervisorAction::Unlock {
approve,
reason,
actor,
dir,
} => {
let root = state::project_root(&dir)?;
supervisor::unlock(&root, approve, &reason, &actor)?;
println!("Human unlock ceremony completed for {}", root.display());
}
SupervisorAction::Quarantine { action } => match action {
SupervisorQuarantineAction::Set {
mode,
reason,
actor,
dir,
json,
} => {
let root = state::project_root(&dir)?;
supervisor::print(
&supervisor::set_quarantine(&root, mode, &reason, &actor)?,
json,
"Yana Giám Thị quarantine",
)?;
}
SupervisorQuarantineAction::Clear {
approve,
reason,
actor,
dir,
} => {
let root = state::project_root(&dir)?;
supervisor::clear_quarantine(&root, approve, &reason, &actor)?;
println!("Giám Thị quarantine cleared for {}", root.display());
}
},
SupervisorAction::Scheduler { action } => match action {
MonitorServiceAction::Install {
dir,
interval_secs,
json,
} => {
let root = state::project_root(&dir)?;
monitor_service::print(&monitor_service::install(&root, interval_secs)?, json)?;
}
MonitorServiceAction::Status { dir, json } => {
let root = state::project_root(&dir)?;
monitor_service::print(&monitor_service::status(&root)?, json)?;
}
MonitorServiceAction::Uninstall { dir, json } => {
let root = state::project_root(&dir)?;
monitor_service::print(&monitor_service::uninstall(&root)?, json)?;
}
},
}
Ok(())
}
fn dispatch_resident_service(action: ResidentServiceAction) -> Result<()> {
match action {
ResidentServiceAction::Install {
dir,
interval_secs,
allow_protected_path,
json,
} => {
let root = state::project_root(&dir)?;
service::runtime::preflight(&root, allow_protected_path)?;
service::manager::print(
&service::runtime::manager(&root, interval_secs)?.install()?,
json,
)?;
}
ResidentServiceAction::Start {
dir,
interval_secs,
allow_protected_path,
json,
} => {
let root = state::project_root(&dir)?;
service::runtime::preflight(&root, allow_protected_path)?;
service::manager::print(
&service::runtime::manager(&root, interval_secs)?.start()?,
json,
)?;
}
ResidentServiceAction::Stop {
dir,
interval_secs,
json,
} => {
let root = state::project_root(&dir)?;
service::manager::print(
&service::runtime::manager(&root, interval_secs)?.stop()?,
json,
)?;
}
ResidentServiceAction::Restart {
dir,
interval_secs,
allow_protected_path,
json,
} => {
let root = state::project_root(&dir)?;
service::runtime::preflight(&root, allow_protected_path)?;
service::manager::print(
&service::runtime::manager(&root, interval_secs)?.restart()?,
json,
)?;
}
ResidentServiceAction::Status {
dir,
interval_secs,
json,
} => {
let root = state::project_root(&dir)?;
service::manager::print(
&service::runtime::manager(&root, interval_secs)?.status()?,
json,
)?;
}
ResidentServiceAction::Uninstall {
dir,
interval_secs,
json,
} => {
let root = state::project_root(&dir)?;
service::manager::print(
&service::runtime::manager(&root, interval_secs)?.uninstall()?,
json,
)?;
}
ResidentServiceAction::Run { dir, interval_secs } => {
let root = state::project_root(&dir)?;
service::runtime::run(&root, interval_secs)?;
}
}
Ok(())
}
fn dispatch_host(action: HostAction) -> Result<()> {
use platform::contract::TelemetryBackend;
match action {
HostAction::Status { json } => {
let profile = platform::backend().host_profile()?;
platform::profile::print(&profile, json)?;
}
HostAction::Capabilities { json } => {
let profile = platform::backend().host_profile()?;
platform::profile::print_capabilities(&profile.capabilities, json)?;
}
}
Ok(())
}
fn dispatch_monitor(action: MonitorAction) -> Result<()> {
match action {
MonitorAction::Sample { dir, json } => {
let root = state::project_root(&dir)?;
let snapshot = monitor::collect(&root);
monitor::persist(&root, &snapshot)?;
monitor::print(&snapshot, json)?;
}
MonitorAction::Show { dir, json } => {
let root = state::project_root(&dir)?;
monitor::print(&monitor::load(&root)?, json)?;
}
MonitorAction::Service { action } => match action {
MonitorServiceAction::Install {
dir,
interval_secs,
json,
} => {
let root = state::project_root(&dir)?;
let report = monitor_service::install(&root, interval_secs)?;
monitor_service::print(&report, json)?;
}
MonitorServiceAction::Status { dir, json } => {
let root = state::project_root(&dir)?;
monitor_service::print(&monitor_service::status(&root)?, json)?;
}
MonitorServiceAction::Uninstall { dir, json } => {
let root = state::project_root(&dir)?;
monitor_service::print(&monitor_service::uninstall(&root)?, json)?;
}
},
}
Ok(())
}
fn dispatch_autonomy(action: AutonomyAction) -> Result<()> {
match action {
AutonomyAction::Policy { action } => match action {
AutonomyPolicyAction::Show { dir, json } => {
let root = state::project_root(&dir)?;
autonomy::print_json_or_debug(&autonomy::load_policy(&root)?, json)?;
}
AutonomyPolicyAction::Set {
enabled,
max_automatic_level,
max_attempts,
dir,
json,
} => {
let root = state::project_root(&dir)?;
let policy = autonomy::AutonomyPolicy {
enabled,
max_automatic_level,
max_attempts,
};
autonomy::save_policy(&root, &policy)?;
autonomy::print_json_or_debug(&policy, json)?;
}
},
AutonomyAction::Classify {
operation,
actor,
dir,
json,
} => {
let root = state::project_root(&dir)?;
let policy = autonomy::load_policy(&root)?;
let decision = match actor {
None => autonomy::evaluate(&policy, operation),
Some(actor) => {
let actor = identity::ActorId(actor);
let leases = identity::active_leases_for_actor(&root, &actor)?;
autonomy::evaluate_for_actor(autonomy::ActorEvaluationRequest {
policy: &policy,
operation,
actor: &actor,
actor_leases: &leases,
now_unix_secs: identity::lease_store::now_unix_secs(),
})
}
};
autonomy::print_json_or_debug(&decision, json)?;
}
AutonomyAction::Queue { action } => match action {
AutonomyQueueAction::List { dir, json } => {
let root = state::project_root(&dir)?;
autonomy::print_json_or_debug(&autonomy::load_queue(&root)?, json)?;
}
AutonomyQueueAction::Add {
operation,
summary,
program,
args,
verify_program,
verify_args,
rollback_program,
rollback_args,
dir,
json,
} => {
if verify_program.is_none() && !verify_args.is_empty() {
bail!("--verify-arg requires --verify-program");
}
if rollback_program.is_none() && !rollback_args.is_empty() {
bail!("--rollback-arg requires --rollback-program");
}
let root = state::project_root(&dir)?;
let action = autonomy::enqueue(
&root,
autonomy::NewAction {
operation,
summary,
command: autonomy::ActionCommand { program, args },
verification: verify_program.map(|program| autonomy::ActionCommand {
program,
args: verify_args,
}),
rollback: rollback_program.map(|program| autonomy::ActionCommand {
program,
args: rollback_args,
}),
},
)?;
autonomy::print_json_or_debug(&action, json)?;
}
AutonomyQueueAction::Approve {
id,
approve,
dir,
json,
} => {
let root = state::project_root(&dir)?;
autonomy::print_json_or_debug(&autonomy::approve(&root, &id, approve)?, json)?;
}
AutonomyQueueAction::Cancel { id, dir, json } => {
let root = state::project_root(&dir)?;
autonomy::print_json_or_debug(&autonomy::cancel(&root, &id)?, json)?;
}
},
}
Ok(())
}
fn dispatch_identity(action: IdentityAction) -> Result<()> {
match action {
IdentityAction::Lease { action } => match action {
LeaseAction::Issue {
actor,
scope,
issued_by,
ttl_secs,
reason,
dir,
json,
} => {
let root = state::project_root(&dir)?;
let issued = identity::issue_lease(
&root,
identity::lease::GrantRequest {
actor: identity::ActorId(actor),
scope: identity::LeaseScope(scope),
issued_by: identity::ActorId(issued_by),
issued_at_unix_secs: identity::lease_store::now_unix_secs(),
ttl_secs,
reason,
},
)?;
if json {
println!("{}", serde_json::to_string_pretty(&issued)?);
} else {
identity::lease_store::print_list(std::slice::from_ref(&issued), false)?;
}
}
LeaseAction::List { dir, json } => {
let root = state::project_root(&dir)?;
identity::lease_store::print_list(&identity::list_leases(&root)?, json)?;
}
LeaseAction::Revoke { id, dir, json } => {
let root = state::project_root(&dir)?;
identity::revoke_lease(&root, &id)?;
if json {
println!("{}", serde_json::json!({ "revoked": id }));
} else {
println!("Revoked lease {id}");
}
}
},
}
Ok(())
}
fn dispatch_governor(action: GovernorAction) -> Result<()> {
match action {
GovernorAction::Status { dir, json, deep } => {
let root = state::project_root(&dir)?;
let report = governor::status(&root, deep);
governor::print_status(&report, json)?;
if report.failed() {
bail!("Evolution Governor status found blocking failures");
}
}
GovernorAction::Capacity { action } => match action {
CapacityAction::Show { dir, json } => {
let root = state::project_root(&dir)?;
governor::print_capacity(&governor::load_capacity(&root)?, json)?;
}
CapacityAction::Set {
mode,
max_active_programs,
max_architecture_changes,
max_new_dependencies,
max_active_experiments,
allocation_consolidation_pct,
allocation_onboarding_and_packaging_pct,
allocation_experiments_pct,
dir,
json,
} => {
let root = state::project_root(&dir)?;
let capacity = governor::set_capacity(
&root,
governor::GovernorCapacity {
mode,
max_active_programs,
max_architecture_changes,
max_new_dependencies,
max_active_experiments,
allocation_consolidation_pct,
allocation_onboarding_and_packaging_pct,
allocation_experiments_pct,
},
)?;
governor::print_capacity(&capacity, json)?;
}
},
GovernorAction::Roadmap { action } => dispatch_roadmap(action)?,
}
Ok(())
}
fn dispatch_roadmap(action: RoadmapAction) -> Result<()> {
match action {
RoadmapAction::List { dir, json } => {
let root = state::project_root(&dir)?;
roadmap::print_view(&roadmap::list(&root)?, json)?;
}
RoadmapAction::Add(args) => {
let RoadmapAddArgs {
tier,
action,
priority,
objective,
evidence,
scope,
out_of_scope,
dependencies,
risks,
deliverables,
owner,
reviewer,
acceptance_criteria,
exit_criteria,
definition_of_done,
rollback_path,
dir,
json,
} = *args;
let root = state::project_root(&dir)?;
let item = roadmap::add(
&root,
roadmap::NewRoadmapItem {
tier,
action,
priority,
objective,
evidence,
scope,
out_of_scope,
dependencies,
risks,
deliverables,
owner,
reviewer,
acceptance_criteria,
exit_criteria,
definition_of_done,
rollback_path,
},
)?;
roadmap::print_item(&item, json)?;
}
RoadmapAction::Promote {
id,
approve,
dir,
json,
} => {
let root = state::project_root(&dir)?;
roadmap::print_item(&roadmap::promote(&root, &id, approve)?, json)?;
}
RoadmapAction::Demote { id, dir, json } => {
let root = state::project_root(&dir)?;
roadmap::print_item(&roadmap::demote(&root, &id)?, json)?;
}
}
Ok(())
}
fn dispatch_agent(action: AgentAction) -> Result<()> {
match action {
AgentAction::List {
dir,
json,
include_chat_sessions,
limit,
} => {
let root = state::project_root(&dir)?;
let inventory = agent::inventory(&root, include_chat_sessions, limit)?;
agent::print_inventory(&inventory, json)?;
}
AgentAction::Register {
name,
provider,
model,
session_id,
owner,
dir,
json,
} => {
let root = state::project_root(&dir)?;
let record = agent::register(&root, name, provider, model, session_id, owner)?;
agent::print_agent(&record, json)?;
}
AgentAction::Heartbeat { id, dir, json } => {
let root = state::project_root(&dir)?;
agent::print_agent(&agent::heartbeat(&root, &id)?, json)?;
}
AgentAction::Transition {
id,
status,
dir,
json,
} => {
let root = state::project_root(&dir)?;
agent::print_agent(&agent::transition(&root, &id, status)?, json)?;
}
}
Ok(())
}
fn dispatch_resource(action: ResourceAction) -> Result<()> {
match action {
ResourceAction::Show { dir, json } => {
let root = state::project_root(&dir)?;
resource::print_policy(&resource::get_policy(&root)?, json)?;
}
ResourceAction::Set {
max_active_agents,
max_tokens_per_request,
max_daily_cost_usd,
stale_after_secs,
dir,
json,
} => {
let root = state::project_root(&dir)?;
let policy = resource::set_policy(
&root,
state::ResourcePolicy {
max_active_agents,
max_tokens_per_request,
max_daily_cost_usd,
stale_after_secs,
},
)?;
resource::print_policy(&policy, json)?;
}
ResourceAction::Check {
requested_agents,
estimated_tokens,
estimated_cost_usd,
dir,
json,
} => {
let root = state::project_root(&dir)?;
let decision = resource::check(
&root,
requested_agents,
estimated_tokens,
estimated_cost_usd,
)?;
resource::print_decision(&decision, json)?;
if !decision.allowed {
bail!("resource preflight denied");
}
}
ResourceAction::Topology { json } => {
resource::topology::print(&resource::topology::collect()?, json)?;
}
ResourceAction::Pressure { dir, json } => {
let root = state::project_root(&dir)?;
resource::pressure::print(&resource::pressure::collect(&root), json)?;
}
ResourceAction::Reservation { action } => dispatch_reservation(action)?,
}
Ok(())
}
fn dispatch_reservation(action: ReservationAction) -> Result<()> {
match action {
ReservationAction::List { dir, json } => {
let root = state::project_root(&dir)?;
resource::reservation::print_list(&resource::reservation::list(&root)?, json)?;
}
ReservationAction::Reserve {
actor,
cpu_cores,
memory_bytes,
accelerator_name,
ttl_secs,
reason,
allow_overcommit,
dir,
json,
} => {
let root = state::project_root(&dir)?;
let reservation = resource::reservation::reserve(
&root,
resource::reservation::ReserveRequest {
actor,
cpu_cores,
memory_bytes,
accelerator_name,
ttl_secs,
reason,
allow_overcommit,
},
)?;
resource::reservation::print_list(&[reservation], json)?;
}
ReservationAction::Release { id, dir, json } => {
let root = state::project_root(&dir)?;
resource::reservation::release(&root, &id)?;
if json {
println!("{}", serde_json::json!({ "released": id }));
} else {
println!("Released reservation {id}");
}
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use clap::{error::ErrorKind, Parser};
#[derive(Debug, Parser)]
struct RoadmapCli {
#[command(subcommand)]
action: RoadmapAction,
}
#[test]
fn add_requires_acceptance_criteria_at_the_cli_boundary() {
let error = RoadmapCli::try_parse_from([
"roadmap",
"add",
"--tier",
"next",
"--action",
"stabilize",
"--priority",
"p1",
"--objective",
"fix golden path",
"--evidence",
"verified failure",
"--scope",
"runtime",
"--out-of-scope",
"new providers",
"--dependencies",
"capability runtime",
"--risks",
"regression",
"--deliverables",
"passing tests",
"--owner",
"runtime maintainer",
"--reviewer",
"anh",
"--exit-criteria",
"evidence recorded",
"--definition-of-done",
"tests pass",
"--rollback-path",
"remove wiring",
])
.unwrap_err();
assert_eq!(error.kind(), ErrorKind::MissingRequiredArgument);
assert!(error.to_string().contains("--acceptance-criteria"));
}
}