safe-fs-ops
Conservative filesystem mutation primitives with SQLite-backed leases, resource claims, operation journaling, checkpoints, and recovery hooks.
safe-fs-ops is for tools that need to change local files without pretending
the filesystem has real transactions. It records intent before mutation, keeps
durable proof for supported rollback paths, coordinates concurrent workers with
leases and claims, and fails closed when recovery would require guessing.
Status
This package is pre-1.0 alpha. The current public surface is ready for careful integration in tools that can tolerate explicit recovery semantics, especially workspace-scoped writes, deletes, directory creation, no-replace renames, directory capture, snapshot bundles, and tree backup artifacts.
It is not a sandbox, a general command rollback engine, or a generic rm -rf
replacement. If another tool mutates a directory after you hand it control,
safe-fs-ops can only restore state that you explicitly snapshotted, backed up,
captured, or journaled first.
Install
uv add safe-fs-ops
Python 3.12 or newer is required.
Quick Start
from pathlib import Path
from safe_fs_ops import SafeWorkspace
workspace = SafeWorkspace.open(
Path(".safe-fs-ops/state.sqlite"),
owner="worker-a",
)
settings = workspace.file("settings.toml")
with workspace.transaction(
name="update-settings",
resources={"settings": settings},
rollback="automatic",
) as tx:
tx.write_text(tx.r.settings, "enabled = true\n")
The transaction acquires a workspace lease, claims settings.toml, records a
journal batch, captures rollback proof for supported operations, performs the
write, records checkpoints, and releases claims on exit.
Common Patterns
Back up named files before invoking another tool:
root = workspace.tree(project_root)
with workspace.transaction(
name="prepare-risky-tool",
resources={"root": root},
) as tx:
backup_result = tx.backup_tree(
tx.r.root,
["pyproject.toml", "src/package/__init__.py"],
)
Capture a directory before tearing it down:
worktree = workspace.directory(".git/worktrees/topic")
quarantine = ".safe-fs-ops/quarantine/worktree-topic"
with workspace.transaction(
name="capture-worktree",
resources={"worktree": worktree},
rollback="automatic",
) as tx:
tx.capture_directory(tx.r.worktree, quarantine_path=quarantine)
Resume pending recovery work after a crash or lease handoff:
error = workspace.recover_pending_batches(run_id="run-123")
if error is not None:
raise error
Documentation
- Docs index: entry points for the documentation set.
- Public API: supported imports, workspace usage, transactions, phased operations, and advanced modules.
- Recovery model: what automatic rollback can and cannot do, and how pending recovery is resumed.
- Filesystem primitives: lower-level path, mutation, snapshot, content-addressed, backup, capture, and restore helpers.
- Development: local setup, tests, slow-test markers, build, and release notes.
- Source review: current public-interface assessment, strengths, sharp edges, and remaining risks.
- Design notes: longer-running architecture notes and historical extraction context.
Development
uv sync
uv run pytest -q
uv run mypy src
uv build
The default test run skips opt-in stress tests and slow recovery integration tests. Run the recovery-heavy tests with:
uv run pytest -q --slow-recovery -m slow_recovery
The project also defines task aliases:
mise run test
mise run test-slow
mise run test-full
mise run test-stress
License
MIT. See LICENSE.
Release files for safe-fs-ops 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| safe_fs_ops-0.1.1.tar.gz | 158.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| safe_fs_ops-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 371.2 kB
Release files / safe_fs_ops-0.1.1.tar.gz
| Download URL | safe_fs_ops-0.1.1.tar.gz |
|---|---|
| Size | 158.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ca5373c4533bb1b285e1360ad3750d120a8d449e96b015b8127aac8544545ab3
|
|
BLAKE2b-256 checksum How to use checksums |
2451d2a9145069471162313dee350d53e7912e6499411b2ff986242209797a38
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / safe_fs_ops-0.1.1-py3-none-any.whl
| Download URL | safe_fs_ops-0.1.1-py3-none-any.whl |
|---|---|
| Size | 212.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2002d2a13b2f9bb4cbef455d789cfe0b51dd56a685df94074d5c554c7e2485fb
|
|
BLAKE2b-256 checksum How to use checksums |
d6ce9e9a384cadde64d80b32dced32f06cd47fec646f4cc7f865567bfa4b98a9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|