Skip to content

Harden persistence layer: atomic writes with cleanup, size limits, Unix permissions#40

Draft
Copilot wants to merge 2 commits into
mainfrom
copilot/review-database-connections
Draft

Harden persistence layer: atomic writes with cleanup, size limits, Unix permissions#40
Copilot wants to merge 2 commits into
mainfrom
copilot/review-database-connections

Conversation

Copy link
Copy Markdown

Copilot AI commented Apr 3, 2026

What

Centralizes all file persistence behind a new atomic_write module that guarantees temp file cleanup on error, restrictive Unix permissions (0o600), and size-bounded deserialization to prevent OOM from malicious or corrupt state files.

m1nd_core::atomic_write — new module:

  • write_atomic(path, data) — temp file + rename with deterministic .tmp cleanup on any failure path
  • read_with_limit(path, max_bytes) / read_to_string_with_limit(path, max_bytes) — reject files exceeding size cap before allocation

Refactored 8 save sites to use write_atomic:

  • snapshot.rssave_graph, save_plasticity_state, save_co_change_matrix
  • snapshot_bin.rssave_graph
  • tremor.rs, trust.rs, antibody.rssave_*_state
  • session.rssave_json_atomic

Deserialization guards:

  • Graph snapshots (JSON + bincode): 100 MB cap (MAX_DESERIALIZE_BYTES)
  • Boot memory: 10 MB cap (MAX_SIDECAR_BYTES)

Graph-plasticity consistency: persist() now holds the graph read lock across both graph and plasticity saves, eliminating the window where a crash could leave them out of sync.

Why

Prior code review identified:

  • Stale .tmp files accumulating on I/O errors (no cleanup in any error path)
  • Default file permissions exposing state to other users
  • Unbounded fs::read / bincode::deserialize vulnerable to OOM from oversized files
  • Graph and plasticity saves not under the same lock — crash between them produces inconsistent state on disk

Testing

  • cargo test --workspace passes (547+ tests)
  • cargo clippy --workspace clean
  • Documentation updated if needed
  • New tools registered in server.rs dispatch

New unit tests in atomic_write::tests: round-trip write, error cleanup, size limit rejection, Unix permission verification.

Breaking Changes

None

Copilot AI and others added 2 commits April 3, 2026 15:58
…e limits, Unix permissions

- Add `atomic_write` module with `write_atomic()` (temp file + rename with cleanup on error)
- Add `read_with_limit()` and `read_to_string_with_limit()` for size-bounded deserialization
- Set restrictive file permissions (0o600) on Unix for all persisted state files
- Refactor all 8 atomic write sites: snapshot.rs, snapshot_bin.rs, tremor.rs, trust.rs, antibody.rs, session.rs
- Add 100MB cap on graph snapshot deserialization (JSON and bincode)
- Add 10MB cap on boot memory deserialization
- Hold graph read lock during both graph and plasticity saves for consistency
- All 547 tests pass, clippy clean

Agent-Logs-Url: https://github.com/maxkle1nz/m1nd/sessions/3d2bff24-87d6-402e-b594-6263b60684b6

Co-authored-by: maxkle1nz <204379921+maxkle1nz@users.noreply.github.com>
…tension, simplify antibody save

Agent-Logs-Url: https://github.com/maxkle1nz/m1nd/sessions/3d2bff24-87d6-402e-b594-6263b60684b6

Co-authored-by: maxkle1nz <204379921+maxkle1nz@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants