Write all imported files with the session rename as the commit point. The session is staged at `temp_path` (a non-`.jsonl` name, invisible to repo listings), replay-validated there, and only renamed into place after every sidecar landed. Any failure removes everything written so a failed import leaves no orphan or partial session behind.
(
repo: &JsonlSessionRepo,
session_path: &Path,
temp_path: &Path,
session_content: &str,
sidecars: &[(PathBuf, String)],
)
| 448 | /// there, and only renamed into place after every sidecar landed. Any failure removes |
| 449 | /// everything written so a failed import leaves no orphan or partial session behind. |
| 450 | async fn commit_import( |
| 451 | repo: &JsonlSessionRepo, |
| 452 | session_path: &Path, |
| 453 | temp_path: &Path, |
| 454 | session_content: &str, |
| 455 | sidecars: &[(PathBuf, String)], |
| 456 | ) -> Result<()> { |
| 457 | let result = async { |
| 458 | tokio::fs::write(temp_path, session_content) |
| 459 | .await |
| 460 | .with_context(|| format!("write {}", temp_path.display()))?; |
| 461 | let staged = repo.open(temp_path).await?; |
| 462 | staged |
| 463 | .build_context() |
| 464 | .await |
| 465 | .context("validate imported session")?; |
| 466 | for (path, content) in sidecars { |
| 467 | tokio::fs::write(path, content) |
| 468 | .await |
| 469 | .with_context(|| format!("write {}", path.display()))?; |
| 470 | } |
| 471 | tokio::fs::rename(temp_path, session_path) |
| 472 | .await |
| 473 | .with_context(|| format!("rename into {}", session_path.display())) |
| 474 | } |
| 475 | .await; |
| 476 | if result.is_err() { |
| 477 | let _ = tokio::fs::remove_file(temp_path).await; |
| 478 | for (path, _) in sidecars { |
| 479 | let _ = tokio::fs::remove_file(path).await; |
| 480 | } |
| 481 | } |
| 482 | result |
| 483 | } |
| 484 | |
| 485 | /// The archive carries the full transcript, so it is created owner-only and never |
| 486 | /// truncates an existing file. |
no test coverage detected