Skip to content

feat: add read-before-write file guard - #5

Open
thomwebb wants to merge 1 commit into
mpfaffenberger:mainfrom
thomwebb:feature/read-before-write
Open

feat: add read-before-write file guard#5
thomwebb wants to merge 1 commit into
mpfaffenberger:mainfrom
thomwebb:feature/read-before-write

Conversation

@thomwebb

Copy link
Copy Markdown
Collaborator

Summary

  • add the builtin read_before_write plugin and register it through the code_puppy.plugins entry-point group
  • require a session-scoped observation before targeted edits and reject stale (st_mtime_ns, st_size) versions
  • prevent blind create_file(overwrite=True) clobbers while leaving no-clobber creates and delete_file behavior unchanged
  • record successful reads/mutations, including ranged reads, not-found observations, Pydantic read results, and hook-context-wrapped results
  • isolate observations by conversation root and full subagent chain, with canonical tool-effective path handling
  • fail open with warnings on internal errors and support read_before_write_enabled = 0 / false

Hardening

The implementation also covers raw Pydantic argument coercion, session working directories, ~ paths, symlinks, pre/post identity races, mutation snapshot correlation, blocked-call cleanup, and direct post-call fallback behavior.

The design is based on DeepSeek Harness's MIT-licensed fs-observation-policy; attribution is included in the plugin package.

Scope and limitations

  • YOLO mode does not bypass the guard
  • delete_file, shell redirection, and browser/MCP writes are not guarded in v1
  • versions intentionally use local stat metadata rather than content hashes
  • tiny non-atomic stat/write races and host-only filesystem-backend revisions require core revision/CAS support and are documented

Verification

  • uv run pytest tests/test_read_before_write.py tests/test_read_before_write_identity_races.py -v — 40 passed
  • PYTEST_DEBUG_TEMPROOT=/tmp uv run pytest -q — 1957 passed, 2 skipped
  • uv run ruff check .
  • uv run ruff format --check .
  • adversarial review: PASS, no blocking findings

@mpfaffenberger

Copy link
Copy Markdown
Owner

Why?

@thomwebb

thomwebb commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator Author

the argument for it is it prevents blind edits where the file might have changed since they last read it. i ported it over from deepseek because it seems like a decent idea, but i'm not married to it

@thomwebb

Copy link
Copy Markdown
Collaborator Author

@mpfaffenberger how about as an opt-in feature?

@WSxDemise

Copy link
Copy Markdown
Contributor

[Wes's CodePuppy Agent Review]

PR Summary

Adds the built-in read-before-write guard, its entry-point registration, and focused coverage.

Scope/parity: No Jira ticket was present; every changed hunk supports the stated implementation and the description matches the diff.

Qodo Merge Triage

Qodo: not configured for OSS/public GitHub.

Code Review Findings

Really Should Fix These

None.

Nits

None.

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.

3 participants