Skip to content
This repository was archived by the owner on Aug 27, 2026. It is now read-only.

Commit 1d522fa

Browse files
committed
Merge remote-tracking branch 'origin/main' into perf/loc-and-call-latency
# Conflicts: # crates/tokenzero-mcp/src/codemode/exec.rs # crates/tokenzero-mcp/src/codemode/journal.rs # crates/tokenzero-recovery/src/embedded_store.rs # crates/tokenzero-recovery/tests/zeroref_conformance_matrix.rs
2 parents a5e3405 + 70cae13 commit 1d522fa

4 files changed

Lines changed: 1273 additions & 160 deletions

File tree

crates/tokenzero-mcp/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ serde_json.workspace = true
2121
sha2.workspace = true
2222
similar.workspace = true
2323
thiserror.workspace = true
24+
tempfile.workspace = true
2425
tokenzero-core = { path = "../tokenzero-core", version = "1.0.2" }
2526
tokenzero-filters = { path = "../tokenzero-filters", version = "1.0.2" }
2627
tokenzero-pulse = { path = "../tokenzero-pulse", version = "1.0.2" }
@@ -31,4 +32,3 @@ fastmcp-rust.workspace = true
3132
[dev-dependencies]
3233
assert_cmd.workspace = true
3334
proptest.workspace = true
34-
tempfile.workspace = true

crates/tokenzero-mcp/src/codemode/exec.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1525,7 +1525,7 @@ fn prepare_json_transaction(
15251525
};
15261526
}
15271527
Ok(_) => {}
1528-
Err(message) if message.contains("journal not found") => {}
1528+
Err(message) if message.starts_with("journal not found:") => {}
15291529
Err(message) => return Err(message),
15301530
}
15311531
let mut seen_targets = std::collections::HashSet::new();

crates/tokenzero-mcp/src/codemode/journal.rs

Lines changed: 13 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,6 @@ mod flows {
196196
use sha2::{Digest, Sha256};
197197
use std::fs::{self, OpenOptions};
198198
use std::io::{self, Write};
199-
use std::sync::atomic::{AtomicU64, Ordering};
200199
use std::time::{SystemTime, UNIX_EPOCH};
201200

202201
pub fn sha256_bytes(bytes: &[u8]) -> String {
@@ -771,13 +770,13 @@ mod flows {
771770
}
772771

773772
fn read_journal(path: &Path) -> Result<PlanJournal, String> {
774-
let bytes = fs::read(path).map_err(|e| {
775-
if e.kind() == io::ErrorKind::NotFound {
776-
format!("journal not found: {e}")
777-
} else {
778-
format!("read journal: {e}")
773+
let bytes = match fs::read(path) {
774+
Ok(bytes) => bytes,
775+
Err(err) if err.kind() == io::ErrorKind::NotFound => {
776+
return Err(format!("journal not found: {}", path.display()));
779777
}
780-
})?;
778+
Err(err) => return Err(format!("read journal {}: {err}", path.display())),
779+
};
781780
let journal: PlanJournal =
782781
serde_json::from_slice(&bytes).map_err(|e| format!("parse journal: {e}"))?;
783782
if journal.version != PLAN_JOURNAL_VERSION {
@@ -795,36 +794,13 @@ mod flows {
795794
pub fn atomic_write(path: &Path, bytes: &[u8]) -> io::Result<()> {
796795
let parent = path.parent().unwrap_or_else(|| Path::new("."));
797796
fs::create_dir_all(parent)?;
798-
static NEXT_TMP_ID: AtomicU64 = AtomicU64::new(0);
799-
let nonce = SystemTime::now()
800-
.duration_since(UNIX_EPOCH)
801-
.unwrap_or_default()
802-
.as_nanos();
803-
let tmp = parent.join(format!(
804-
".{}.{}.{nonce}.{}.tmp",
805-
path.file_name()
806-
.and_then(|v| v.to_str())
807-
.unwrap_or("journal"),
808-
std::process::id(),
809-
NEXT_TMP_ID.fetch_add(1, Ordering::Relaxed)
810-
));
811-
let result = (|| {
812-
let mut file = OpenOptions::new().create_new(true).write(true).open(&tmp)?;
813-
file.write_all(bytes)?;
814-
file.sync_all()?;
815-
fs::rename(&tmp, path)?;
816-
// Directory fsync is Unix-only: on Windows a directory handle
817-
// cannot be opened via `File::open` (no FILE_FLAG_BACKUP_SEMANTICS),
818-
// which would spuriously fail every journal write after the rename
819-
// already succeeded.
820-
#[cfg(unix)]
821-
File::open(parent)?.sync_all()?;
822-
Ok(())
823-
})();
824-
if result.is_err() {
825-
let _ = fs::remove_file(&tmp);
826-
}
827-
result
797+
let mut tmp = tempfile::NamedTempFile::new_in(parent)?;
798+
tmp.write_all(bytes)?;
799+
tmp.as_file().sync_all()?;
800+
tmp.persist(path).map_err(|err| err.error)?;
801+
#[cfg(unix)]
802+
File::open(parent)?.sync_all()?;
803+
Ok(())
828804
}
829805

830806
fn pin_hash(reference: &str) -> Option<String> {

0 commit comments

Comments
 (0)