feat: enhance safety and crash resilience in file operations; add fsync to critical writes and checks for path traversal

This commit is contained in:
asepharyana
2026-07-12 11:49:33 +07:00
parent 8767beef39
commit 87d0aac596
9 changed files with 79 additions and 26 deletions
+14 -6
View File
@@ -18,23 +18,31 @@ pub struct Harness;
impl Harness {
/// Decide whether a tool call is allowed to execute.
///
/// Flow: if the tool isn't flagged risky, allow immediately → otherwise
/// defer to `classify`.
/// Flow: if the tool isn't flagged risky, allow immediately → basic
/// content checks (path traversal) → defer to `classify`.
///
/// Why: `_args` and `_workspace_roots` are accepted for a future
/// content-aware classifier but currently unused — `classify` is a
/// stub that always allows.
/// Why: `classify` is currently a stub that always allows; the basic
/// checks here serve as defense-in-depth alongside the shell filters
/// and `resolve_path` in the tool modules.
///
/// Return: `Verdict::Allow` or `Verdict::Block(reason)`.
pub fn gate_tool_call(
tool_name: &str,
_args: &serde_json::Value,
args: &serde_json::Value,
_workspace_roots: &[&std::path::Path],
) -> Verdict {
if !crate::tool::tool_is_risky(tool_name) {
return Verdict::Allow;
}
// Basic path traversal check for file-mutating tools.
if matches!(tool_name, "write" | "edit" | "delete") {
if let Some(path) = args.get("path").and_then(|v| v.as_str()) {
if path.contains("..") {
return Verdict::Block("path traversal detected in 'path' argument".to_string());
}
}
}
Self::classify(tool_name)
}