pub trait Workspace: Send + Sync {
Show 40 methods
// Required methods
fn root(&self) -> &Path;
fn read(&self, relative: &Path) -> Result<String>;
fn read_bytes(&self, relative: &Path) -> Result<Vec<u8>>;
fn write(&self, relative: &Path, content: &str) -> Result<()>;
fn write_bytes(&self, relative: &Path, content: &[u8]) -> Result<()>;
fn append_bytes(&self, relative: &Path, content: &[u8]) -> Result<()>;
fn exists(&self, relative: &Path) -> bool;
fn is_file(&self, relative: &Path) -> bool;
fn is_dir(&self, relative: &Path) -> bool;
fn remove(&self, relative: &Path) -> Result<()>;
fn remove_if_exists(&self, relative: &Path) -> Result<()>;
fn remove_dir_all(&self, relative: &Path) -> Result<()>;
fn remove_dir_all_if_exists(&self, relative: &Path) -> Result<()>;
fn create_dir_all(&self, relative: &Path) -> Result<()>;
fn read_dir(&self, relative: &Path) -> Result<Vec<DirEntry>>;
fn rename(&self, from: &Path, to: &Path) -> Result<()>;
fn write_atomic(&self, relative: &Path, content: &str) -> Result<()>;
fn set_readonly(&self, relative: &Path) -> Result<()>;
fn set_writable(&self, relative: &Path) -> Result<()>;
// Provided methods
fn absolute(&self, relative: &Path) -> PathBuf { ... }
fn absolute_str(&self, relative: &str) -> String { ... }
fn agent_dir(&self) -> PathBuf { ... }
fn agent_logs(&self) -> PathBuf { ... }
fn agent_tmp(&self) -> PathBuf { ... }
fn plan_md(&self) -> PathBuf { ... }
fn issues_md(&self) -> PathBuf { ... }
fn status_md(&self) -> PathBuf { ... }
fn notes_md(&self) -> PathBuf { ... }
fn commit_message(&self) -> PathBuf { ... }
fn checkpoint(&self) -> PathBuf { ... }
fn start_commit(&self) -> PathBuf { ... }
fn review_baseline(&self) -> PathBuf { ... }
fn prompt_md(&self) -> PathBuf { ... }
fn prompt_backup(&self) -> PathBuf { ... }
fn agent_config(&self) -> PathBuf { ... }
fn agents_toml(&self) -> PathBuf { ... }
fn pipeline_log(&self) -> PathBuf { ... }
fn xsd_path(&self, name: &str) -> PathBuf { ... }
fn xml_path(&self, name: &str) -> PathBuf { ... }
fn log_path(&self, name: &str) -> PathBuf { ... }
}Expand description
Trait defining the workspace filesystem interface.
This trait abstracts file operations relative to a repository root, allowing for both real filesystem access (production) and in-memory storage (testing).
Required Methods§
Sourcefn read_bytes(&self, relative: &Path) -> Result<Vec<u8>>
fn read_bytes(&self, relative: &Path) -> Result<Vec<u8>>
Read a file as bytes relative to the repository root.
Sourcefn write(&self, relative: &Path, content: &str) -> Result<()>
fn write(&self, relative: &Path, content: &str) -> Result<()>
Write content to a file relative to the repository root. Creates parent directories if they don’t exist.
Sourcefn write_bytes(&self, relative: &Path, content: &[u8]) -> Result<()>
fn write_bytes(&self, relative: &Path, content: &[u8]) -> Result<()>
Write bytes to a file relative to the repository root. Creates parent directories if they don’t exist.
Sourcefn append_bytes(&self, relative: &Path, content: &[u8]) -> Result<()>
fn append_bytes(&self, relative: &Path, content: &[u8]) -> Result<()>
Append bytes to a file relative to the repository root. Creates the file if it doesn’t exist. Creates parent directories if needed.
Sourcefn exists(&self, relative: &Path) -> bool
fn exists(&self, relative: &Path) -> bool
Check if a path exists relative to the repository root.
Sourcefn is_file(&self, relative: &Path) -> bool
fn is_file(&self, relative: &Path) -> bool
Check if a path is a file relative to the repository root.
Sourcefn is_dir(&self, relative: &Path) -> bool
fn is_dir(&self, relative: &Path) -> bool
Check if a path is a directory relative to the repository root.
Sourcefn remove_if_exists(&self, relative: &Path) -> Result<()>
fn remove_if_exists(&self, relative: &Path) -> Result<()>
Remove a file if it exists, silently succeeding if it doesn’t.
Sourcefn remove_dir_all(&self, relative: &Path) -> Result<()>
fn remove_dir_all(&self, relative: &Path) -> Result<()>
Remove a directory and all its contents relative to the repository root.
Similar to std::fs::remove_dir_all, this removes a directory and everything inside it.
Returns an error if the directory doesn’t exist.
Sourcefn remove_dir_all_if_exists(&self, relative: &Path) -> Result<()>
fn remove_dir_all_if_exists(&self, relative: &Path) -> Result<()>
Remove a directory and all its contents if it exists, silently succeeding if it doesn’t.
Sourcefn create_dir_all(&self, relative: &Path) -> Result<()>
fn create_dir_all(&self, relative: &Path) -> Result<()>
Create a directory and all parent directories relative to the repository root.
Sourcefn read_dir(&self, relative: &Path) -> Result<Vec<DirEntry>>
fn read_dir(&self, relative: &Path) -> Result<Vec<DirEntry>>
List entries in a directory relative to the repository root.
Returns a vector of DirEntry-like information for each entry.
For production, this wraps std::fs::read_dir.
For testing, this returns entries from the in-memory filesystem.
Sourcefn rename(&self, from: &Path, to: &Path) -> Result<()>
fn rename(&self, from: &Path, to: &Path) -> Result<()>
Rename/move a file from one path to another relative to the repository root.
This is used for backup rotation where files are moved to new names. Returns an error if the source file doesn’t exist.
Sourcefn write_atomic(&self, relative: &Path, content: &str) -> Result<()>
fn write_atomic(&self, relative: &Path, content: &str) -> Result<()>
Write content to a file atomically using temp file + rename pattern.
This ensures the file is either fully written or not written at all, preventing partial writes or corruption from crashes/interruptions.
§Implementation details
WorkspaceFs: Usestempfile::NamedTempFilein the same directory, writes content, syncs to disk, then atomically renames to target. On Unix, temp file has mode 0600 for security.MemoryWorkspace: Just callswrite()since in-memory operations are inherently atomic (no partial state possible).
§When to use
Use write_atomic() for critical files where corruption would be problematic:
- XML outputs (issues.xml, plan.xml, commit_message.xml)
- Agent artifacts (PLAN.md, commit-message.txt)
- Any file that must not have partial content
Use regular write() for:
- Log files (append-only, partial is acceptable)
- Temporary/debug files
- Files where performance matters more than atomicity
Sourcefn set_readonly(&self, relative: &Path) -> Result<()>
fn set_readonly(&self, relative: &Path) -> Result<()>
Set a file to read-only permissions.
This is a best-effort operation for protecting files like PROMPT.md backups. On Unix, sets permissions to 0o444. On Windows, sets the readonly flag. In-memory implementations may no-op since permissions aren’t relevant for testing.
Returns Ok(()) on success or if the file doesn’t exist (nothing to protect). Returns Err only if the file exists but permissions cannot be changed.
Sourcefn set_writable(&self, relative: &Path) -> Result<()>
fn set_writable(&self, relative: &Path) -> Result<()>
Set a file to writable permissions.
Reverses the effect of set_readonly.
On Unix, sets permissions to 0o644.
On Windows, clears the readonly flag.
In-memory implementations may no-op since permissions aren’t relevant for testing.
Returns Ok(()) on success or if the file doesn’t exist.
Provided Methods§
Sourcefn absolute_str(&self, relative: &str) -> String
fn absolute_str(&self, relative: &str) -> String
Resolve a relative path to an absolute path as a string.
Sourcefn agent_logs(&self) -> PathBuf
fn agent_logs(&self) -> PathBuf
Path to the .agent/logs directory.
Sourcefn commit_message(&self) -> PathBuf
fn commit_message(&self) -> PathBuf
Path to .agent/commit-message.txt.
Sourcefn checkpoint(&self) -> PathBuf
fn checkpoint(&self) -> PathBuf
Path to .agent/checkpoint.json.
Sourcefn start_commit(&self) -> PathBuf
fn start_commit(&self) -> PathBuf
Path to .agent/start_commit.
Sourcefn review_baseline(&self) -> PathBuf
fn review_baseline(&self) -> PathBuf
Path to .agent/review_baseline.txt.
Sourcefn prompt_backup(&self) -> PathBuf
fn prompt_backup(&self) -> PathBuf
Path to .agent/PROMPT.md.backup.
Sourcefn agent_config(&self) -> PathBuf
fn agent_config(&self) -> PathBuf
Path to .agent/config.toml.
Sourcefn agents_toml(&self) -> PathBuf
fn agents_toml(&self) -> PathBuf
Path to .agent/agents.toml.
Sourcefn pipeline_log(&self) -> PathBuf
fn pipeline_log(&self) -> PathBuf
Path to .agent/logs/pipeline.log.