From 6dd422186ee9b902b409abbb1fdfa6898caba198 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Mon, 2 Mar 2026 11:46:31 -0500 Subject: [PATCH] Rename progress.ndjson to progress.jsonl Co-Authored-By: Claude Opus 4.6 (1M context) --- crates/arc-cli/tests/cli.rs | 18 +++++++++--------- crates/arc-workflows/src/cli/run.rs | 8 ++++---- crates/arc-workflows/src/retro.rs | 12 ++++++------ crates/arc-workflows/src/retro_agent.rs | 8 ++++---- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/crates/arc-cli/tests/cli.rs b/crates/arc-cli/tests/cli.rs index 88b9ef7c9..e65bdcb2f 100644 --- a/crates/arc-cli/tests/cli.rs +++ b/crates/arc-cli/tests/cli.rs @@ -456,10 +456,10 @@ fn dry_run_legacy_tool() { .success(); } -// == NDJSON logging =========================================================== +// == JSONL logging ============================================================ #[test] -fn dry_run_writes_ndjson_and_live_json() { +fn dry_run_writes_jsonl_and_live_json() { let tmp = tempfile::tempdir().unwrap(); let logs_dir = tmp.path().join("logs"); @@ -476,14 +476,14 @@ fn dry_run_writes_ndjson_and_live_json() { .assert() .success(); - // progress.ndjson must exist and contain valid JSON lines - let ndjson_path = logs_dir.join("progress.ndjson"); - assert!(ndjson_path.exists(), "progress.ndjson should exist"); - let ndjson_content = std::fs::read_to_string(&ndjson_path).unwrap(); - let lines: Vec<&str> = ndjson_content.lines().collect(); + // progress.jsonl must exist and contain valid JSON lines + let jsonl_path = logs_dir.join("progress.jsonl"); + assert!(jsonl_path.exists(), "progress.jsonl should exist"); + let jsonl_content = std::fs::read_to_string(&jsonl_path).unwrap(); + let lines: Vec<&str> = jsonl_content.lines().collect(); assert!( !lines.is_empty(), - "progress.ndjson should have at least one line" + "progress.jsonl should have at least one line" ); // Every line must be valid JSON with timestamp, run_id, and event keys @@ -513,7 +513,7 @@ fn dry_run_writes_ndjson_and_live_json() { let run_id = last_line["run_id"].as_str().unwrap(); assert!(!run_id.is_empty(), "run_id should be non-empty"); - // live.json must exist and contain valid JSON matching the last NDJSON line + // live.json must exist and contain valid JSON matching the last JSONL line let live_path = logs_dir.join("live.json"); assert!(live_path.exists(), "live.json should exist"); let live_content: serde_json::Value = diff --git a/crates/arc-workflows/src/cli/run.rs b/crates/arc-workflows/src/cli/run.rs index 145b076a1..fc75344ff 100644 --- a/crates/arc-workflows/src/cli/run.rs +++ b/crates/arc-workflows/src/cli/run.rs @@ -195,9 +195,9 @@ pub async fn run_command(args: RunArgs, styles: &'static Styles) -> anyhow::Resu } }); - // NDJSON progress log + live.json snapshot + // JSONL progress log + live.json snapshot { - let ndjson_path = logs_dir.join("progress.ndjson"); + let jsonl_path = logs_dir.join("progress.jsonl"); let live_path = logs_dir.join("live.json"); let run_id = Arc::new(Mutex::new(String::new())); let run_id_clone = Arc::clone(&run_id); @@ -210,14 +210,14 @@ pub async fn run_command(args: RunArgs, styles: &'static Styles) -> anyhow::Resu "run_id": *run_id_clone.lock().unwrap(), "event": event, }); - // Append to progress.ndjson + // Append to progress.jsonl if let Ok(line) = serde_json::to_string(&envelope) { let line = arc_util::redact::redact_jsonl_line(&line); use std::io::Write; if let Ok(mut f) = std::fs::OpenOptions::new() .create(true) .append(true) - .open(&ndjson_path) + .open(&jsonl_path) { let _ = writeln!(f, "{line}"); } diff --git a/crates/arc-workflows/src/retro.rs b/crates/arc-workflows/src/retro.rs index 66ae4de6d..458b786d9 100644 --- a/crates/arc-workflows/src/retro.rs +++ b/crates/arc-workflows/src/retro.rs @@ -172,11 +172,11 @@ impl Retro { } } -/// Extract stage durations from `progress.ndjson` by reading `StageCompleted` events. +/// Extract stage durations from `progress.jsonl` by reading `StageCompleted` events. pub fn extract_stage_durations(logs_root: &Path) -> HashMap { let mut durations = HashMap::new(); - let ndjson_path = logs_root.join("progress.ndjson"); - let Ok(data) = std::fs::read_to_string(&ndjson_path) else { + let jsonl_path = logs_root.join("progress.jsonl"); + let Ok(data) = std::fs::read_to_string(&jsonl_path) else { return durations; }; for line in data.lines() { @@ -517,9 +517,9 @@ mod tests { } #[test] - fn extract_stage_durations_from_ndjson() { + fn extract_stage_durations_from_jsonl() { let dir = tempfile::tempdir().unwrap(); - let ndjson = dir.path().join("progress.ndjson"); + let jsonl = dir.path().join("progress.jsonl"); let event1 = serde_json::json!({ "timestamp": "2025-01-01T00:00:00.000Z", @@ -568,7 +568,7 @@ mod tests { serde_json::to_string(&event1).unwrap(), serde_json::to_string(&event2).unwrap() ); - std::fs::write(&ndjson, content).unwrap(); + std::fs::write(&jsonl, content).unwrap(); let durations = extract_stage_durations(dir.path()); assert_eq!(durations.get("plan"), Some(&5000)); diff --git a/crates/arc-workflows/src/retro_agent.rs b/crates/arc-workflows/src/retro_agent.rs index 6d87b1a62..0f85a25e0 100644 --- a/crates/arc-workflows/src/retro_agent.rs +++ b/crates/arc-workflows/src/retro_agent.rs @@ -15,7 +15,7 @@ use crate::retro::RetroNarrative; const RETRO_SYSTEM_PROMPT: &str = r#"You are a workflow run retrospective analyst. Your job is to analyze a completed workflow run and generate a structured retrospective. You have access to the run's data files: -- `progress.ndjson` — the full event stream (stage starts/completions, agent tool calls, errors, retries) +- `progress.jsonl` — the full event stream (stage starts/completions, agent tool calls, errors, retries) - `checkpoint.json` — final execution state with node outcomes - `manifest.json` — run metadata (if available) @@ -109,7 +109,7 @@ const SUBMIT_RETRO_SCHEMA: &str = r#"{ }"#; /// Run a retro agent session that analyzes workflow run data and produces -/// a structured narrative. The agent explores `progress.ndjson` and other +/// a structured narrative. The agent explores `progress.jsonl` and other /// files via tool access, then calls `submit_retro` with its analysis. pub async fn run_retro_agent( sandbox: &Arc, @@ -172,7 +172,7 @@ pub async fn run_retro_agent( let prompt = format!( "Analyze the workflow run data at `{retro_data_dir}/` and generate a retrospective. \ - The key file is `{retro_data_dir}/progress.ndjson` which contains the full event stream. \ + The key file is `{retro_data_dir}/progress.jsonl` which contains the full event stream. \ Also check `{retro_data_dir}/checkpoint.json` for stage outcomes. \ Use grep to search for interesting signals (failures, retries, errors, approach changes) \ rather than reading the entire file. When done, call the `submit_retro` tool with your analysis." @@ -228,7 +228,7 @@ async fn upload_data_files( .await .map_err(|e| anyhow::anyhow!("Failed to create retro data dir: {e}"))?; - let files = ["progress.ndjson", "checkpoint.json", "manifest.json"]; + let files = ["progress.jsonl", "checkpoint.json", "manifest.json"]; for filename in &files { let source = logs_root.join(filename); if source.exists() {