Adjust store dump export paths

This commit is contained in:
Bryan Helmkamp 2026-04-22 16:13:27 -04:00
parent 090e1022ed
commit 6ba533a3a4
No known key found for this signature in database
7 changed files with 23 additions and 24 deletions

View file

@ -50,7 +50,7 @@ After each node, the metadata branch is updated with:
- **`run.json`** — Refreshed projection snapshot with the new current checkpoint
- **`stages/{node_id}@{visit}/...`** — Per-stage execution trace files (prompts, responses, status, diffs, stdout/stderr, and tool metadata)
- **`retro/*.md`** — Retro prompt/response text when present
- **`stages/retro/*.md`** — Retro prompt/response text when present
## What's in a checkpoint

View file

@ -143,4 +143,4 @@ Retros are also available via the REST API. See the [list retros](/api-reference
## Storage
Retros are stored in durable run state. If you need files on disk, `fabro store dump` materializes retro text under `retro/` alongside `run.json`, stage files, and the rest of the exported run data.
Retros are stored in durable run state. If you need files on disk, `fabro store dump` materializes retro text under `stages/retro/` alongside `run.json`, stage files, and the rest of the exported run data.

View file

@ -38,14 +38,14 @@ Reconstructed metadata branches and `fabro store dump` exports now use the same
- `run.json` for the current projection snapshot, including the current checkpoint
- `graph.fabro` for workflow source
- `retro/*.md` for retro prompt/response text
- `stages/retro/*.md` for retro prompt/response text
- `stages/{node_id}@{visit}/...` for per-stage prompt, response, status, diff, stdout, and stderr files
`fabro store dump` adds export-only history surfaces on top of that shared layout:
- `events.jsonl` for the durable event stream
- `checkpoints/*.json` for checkpoint history snapshots
- `artifacts/nodes/{node_id}/visit-{n}/...` for exported artifact payloads
- `artifacts/{node_id}@{visit}/...` for exported artifact payloads
## Browsing runs

View file

@ -390,12 +390,12 @@ mod tests {
store
.write_snapshot(
&run_id,
&[("retro/prompt.md", b"how did it go?")],
&[("stages/retro/prompt.md", b"how did it go?")],
"finalize run",
)
.unwrap();
let data = branch_entry(dir.path(), &run_id, "retro/prompt.md");
let data = branch_entry(dir.path(), &run_id, "stages/retro/prompt.md");
assert_eq!(data, b"how did it go?");
let spec = MetadataStore::read_run_spec(dir.path(), &run_id)

View file

@ -783,11 +783,11 @@ mod tests {
);
assert_eq!(
std::fs::read_to_string(output.path().join("retro/prompt.md")).unwrap(),
std::fs::read_to_string(output.path().join("stages/retro/prompt.md")).unwrap(),
"How did it go?"
);
assert_eq!(
std::fs::read_to_string(output.path().join("retro/response.md")).unwrap(),
std::fs::read_to_string(output.path().join("stages/retro/response.md")).unwrap(),
"Smooth enough"
);
@ -815,19 +815,14 @@ mod tests {
assert!(!output.path().join("blobs").exists());
assert_eq!(
std::fs::read(
output
.path()
.join("artifacts/nodes/code/visit-2/src/lib.rs")
)
.unwrap(),
std::fs::read(output.path().join("artifacts/code@2/src/lib.rs")).unwrap(),
b"fn main() {}"
);
assert_eq!(
std::fs::read(
output
.path()
.join("artifacts/nodes/artifact-only/visit-7/logs/output.txt")
.join("artifacts/artifact-only@7/logs/output.txt")
)
.unwrap(),
b"hello"

View file

@ -254,8 +254,7 @@ include = ["assets/**"]
"run export should hydrate blob refs\n{run_json}"
);
assert_eq!(
fs::read_to_string(output_dir.join("artifacts/nodes/big/visit-1/assets/shared/report.txt"))
.unwrap(),
fs::read_to_string(output_dir.join("artifacts/big@1/assets/shared/report.txt")).unwrap(),
"exported"
);
}

View file

@ -120,10 +120,13 @@ impl RunDump {
}
if let Some(prompt) = state.retro_prompt.as_ref() {
entries.push(RunDumpEntry::text("retro/prompt.md", prompt.clone()));
entries.push(RunDumpEntry::text("stages/retro/prompt.md", prompt.clone()));
}
if let Some(response) = state.retro_response.as_ref() {
entries.push(RunDumpEntry::text("retro/response.md", response.clone()));
entries.push(RunDumpEntry::text(
"stages/retro/response.md",
response.clone(),
));
}
Self { entries }
@ -402,9 +405,11 @@ fn artifact_dump_path(stage_id: &StageId, filename: &str) -> Result<PathBuf> {
let node_id_segment = validate_single_path_segment("node id", stage_id.node_id())?;
let filename_path = validate_relative_path("artifact filename", filename)?;
Ok(PathBuf::from("artifacts")
.join("nodes")
.join(node_id_segment)
.join(format!("visit-{}", stage_id.visit()))
.join(format!(
"{}@{}",
node_id_segment.display(),
stage_id.visit()
))
.join(filename_path))
}
@ -540,8 +545,8 @@ mod tests {
assert!(paths.contains(&"run.json"));
assert!(paths.contains(&"graph.fabro"));
assert!(paths.contains(&"retro/prompt.md"));
assert!(paths.contains(&"retro/response.md"));
assert!(paths.contains(&"stages/retro/prompt.md"));
assert!(paths.contains(&"stages/retro/response.md"));
assert!(paths.contains(&"stages/build@2/prompt.md"));
assert!(paths.contains(&"stages/build@2/response.md"));
assert!(paths.contains(&"stages/build@2/status.json"));