Rename final.json to conclusion.json and RunFinal to Conclusion

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Bryan Helmkamp 2026-03-06 10:48:07 -05:00
parent deda9bd512
commit af6e091ef3
5 changed files with 33 additions and 33 deletions

View file

@ -712,14 +712,14 @@ pub async fn run_command(
Ok(o) => (o.status.to_string(), o.failure_reason().map(String::from)),
Err(e) => ("fail".to_string(), Some(e.to_string())),
};
let run_final = crate::run_final::RunFinal {
let conclusion = crate::conclusion::Conclusion {
timestamp: Utc::now(),
status,
duration_ms: run_duration_ms,
failure_reason,
final_git_commit_sha: last_git_sha.lock().unwrap().clone(),
};
let _ = run_final.save(&logs_dir.join("final.json"));
let _ = conclusion.save(&logs_dir.join("conclusion.json"));
}
// Finish progress bars before printing summary

View file

@ -139,10 +139,10 @@ pub fn scan_runs(base: &Path) -> Result<Vec<RunInfo>> {
}
fn read_status(run_dir: &Path) -> String {
let final_path = run_dir.join("final.json");
if final_path.exists() {
if let Ok(run_final) = crate::run_final::RunFinal::load(&final_path) {
return run_final.status;
let conclusion_path = run_dir.join("conclusion.json");
if conclusion_path.exists() {
if let Ok(conclusion) = crate::conclusion::Conclusion::load(&conclusion_path) {
return conclusion.status;
}
"unknown".to_string()
} else if run_dir.join("run.pid").exists() {
@ -307,7 +307,7 @@ mod tests {
base: &Path,
dir_name: &str,
manifest: Option<serde_json::Value>,
final_json: Option<serde_json::Value>,
conclusion_json: Option<serde_json::Value>,
pid_file: bool,
) -> PathBuf {
let dir = base.join(dir_name);
@ -319,10 +319,10 @@ mod tests {
)
.unwrap();
}
if let Some(f) = final_json {
if let Some(c) = conclusion_json {
fs::write(
dir.join("final.json"),
serde_json::to_string_pretty(&f).unwrap(),
dir.join("conclusion.json"),
serde_json::to_string_pretty(&c).unwrap(),
)
.unwrap();
}

View file

@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
use crate::error::{ArcError, Result};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RunFinal {
pub struct Conclusion {
pub timestamp: DateTime<Utc>,
pub status: String,
pub duration_ms: u64,
@ -16,19 +16,19 @@ pub struct RunFinal {
pub final_git_commit_sha: Option<String>,
}
impl RunFinal {
impl Conclusion {
pub fn save(&self, path: &Path) -> Result<()> {
let json = serde_json::to_string_pretty(self)
.map_err(|e| ArcError::Checkpoint(format!("run_final serialize failed: {e}")))?;
.map_err(|e| ArcError::Checkpoint(format!("conclusion serialize failed: {e}")))?;
std::fs::write(path, json)?;
Ok(())
}
pub fn load(path: &Path) -> Result<Self> {
let data = std::fs::read_to_string(path)?;
let run_final: Self = serde_json::from_str(&data)
.map_err(|e| ArcError::Checkpoint(format!("run_final deserialize failed: {e}")))?;
Ok(run_final)
let conclusion: Self = serde_json::from_str(&data)
.map_err(|e| ArcError::Checkpoint(format!("conclusion deserialize failed: {e}")))?;
Ok(conclusion)
}
}
@ -36,8 +36,8 @@ impl RunFinal {
mod tests {
use super::*;
fn sample_run_final() -> RunFinal {
RunFinal {
fn sample_conclusion() -> Conclusion {
Conclusion {
timestamp: Utc::now(),
status: "success".to_string(),
duration_ms: 12345,
@ -49,11 +49,11 @@ mod tests {
#[test]
fn save_and_load_roundtrip() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("final.json");
let path = dir.path().join("conclusion.json");
let run_final = sample_run_final();
run_final.save(&path).unwrap();
let loaded = RunFinal::load(&path).unwrap();
let conclusion = sample_conclusion();
conclusion.save(&path).unwrap();
let loaded = Conclusion::load(&path).unwrap();
assert_eq!(loaded.status, "success");
assert_eq!(loaded.duration_ms, 12345);
@ -66,7 +66,7 @@ mod tests {
#[test]
fn load_nonexistent_file() {
let result = RunFinal::load(Path::new("/nonexistent/final.json"));
let result = Conclusion::load(Path::new("/nonexistent/conclusion.json"));
assert!(result.is_err());
}
@ -76,23 +76,23 @@ mod tests {
let path = dir.path().join("bad.json");
std::fs::write(&path, "not json").unwrap();
let result = RunFinal::load(&path);
let result = Conclusion::load(&path);
assert!(result.is_err());
}
#[test]
fn optional_fields_omitted_when_none() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("final.json");
let path = dir.path().join("conclusion.json");
let run_final = RunFinal {
let conclusion = Conclusion {
timestamp: Utc::now(),
status: "fail".to_string(),
duration_ms: 500,
failure_reason: None,
final_git_commit_sha: None,
};
run_final.save(&path).unwrap();
conclusion.save(&path).unwrap();
let raw: serde_json::Value =
serde_json::from_str(&std::fs::read_to_string(&path).unwrap()).unwrap();
@ -103,17 +103,17 @@ mod tests {
#[test]
fn failure_reason_present() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("final.json");
let path = dir.path().join("conclusion.json");
let run_final = RunFinal {
let conclusion = Conclusion {
timestamp: Utc::now(),
status: "fail".to_string(),
duration_ms: 100,
failure_reason: Some("timeout".to_string()),
final_git_commit_sha: None,
};
run_final.save(&path).unwrap();
let loaded = RunFinal::load(&path).unwrap();
conclusion.save(&path).unwrap();
let loaded = Conclusion::load(&path).unwrap();
assert_eq!(loaded.failure_reason.as_deref(), Some("timeout"));
}

View file

@ -20,7 +20,7 @@ pub mod parser;
pub mod preamble;
pub mod retro;
pub mod retro_agent;
pub mod run_final;
pub mod conclusion;
pub mod stylesheet;
pub mod transform;
pub mod validation;

View file

@ -190,7 +190,7 @@ Each run's logs directory contains a standard set of files:
| `live.json` | Last event snapshot (overwritten during run) |
| `checkpoint.json` | Final execution state |
| `retro.json` | Retrospective (if retro generation is enabled) |
| `final.json` | Terminal status (`completed`, `failed`, `canceled`) |
| `conclusion.json` | Terminal status (`completed`, `failed`, `canceled`) |
### Inspecting stages and turns