use crate::capture::{append, Decision};
use crate::store::Store;
use crate::tick::Tick;
use std::path::Path;
pub struct CorrectArgs {
pub id: String,
pub authority: Option<String>,
pub jurisdiction: Option<String>,
pub provenance: Option<String>,
pub blame: Option<String>,
}
pub fn run(repo: &Path, a: CorrectArgs) -> Result<Tick, String> {
let store = Store::at(repo);
if !store.exists() {
return Err("no .evolving/ store here — run `ev init` first".into());
}
let target = store
.read_tick(&a.id)
.map_err(|e| format!("reading {}: {e}", a.id))?
.ok_or_else(|| format!("no such tick: {}", a.id))?;
if a.authority.is_none() && a.jurisdiction.is_none() && a.provenance.is_none() {
return Err(
"ev correct needs at least one of --authority / --jurisdiction / --provenance".into(),
);
}
if let Some(v) = &a.authority {
crate::capture::validate_authority(v)?;
}
if let Some(v) = &a.jurisdiction {
crate::tick::validate_jurisdiction(v)?;
}
if let Some(v) = &a.provenance {
crate::tick::validate_provenance(v)?;
}
let authority = a.authority.clone().or_else(|| target.authority.clone());
let jurisdiction = a
.jurisdiction
.clone()
.or_else(|| target.jurisdiction.clone());
let provenance = a.provenance.clone().or_else(|| target.provenance.clone());
if authority == target.authority
&& jurisdiction == target.jurisdiction
&& provenance == target.provenance
{
return Err(format!(
"tick {} already carries those tags — nothing to correct",
a.id
));
}
if crate::tick::detect_only_carries_test(jurisdiction.as_deref(), &target.grounds) {
return Err(format!(
"cannot set jurisdiction {} on a decision that carries a test check (detect-only)",
jurisdiction.as_deref().unwrap_or("")
));
}
let blame = crate::capture::resolve_blame(repo, a.blame.clone())?;
let child = append(
repo,
Decision {
observe: target.observe.clone(),
decision: target.decision.clone(),
grounds: target.grounds.clone(),
blame,
authority,
jurisdiction,
source_ref: target.source_ref.clone(),
provenance,
},
)?;
crate::events::append(&store, "correct", Some(&child), None, None);
Ok(child)
}