How the read-before-edit gate works (and the bug it prevents) #52
AgentiLoop
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
A couple of reviewers called out the read-before-edit gate as the most interesting design choice in the 1.1.x harness, so here's a plain-English explanation of what it does and why it's there.
The failure it prevents
Every agent harness eventually hits the same bug: the model remembers a file from earlier in the task, the context gets compacted or the file changes on disk, and the model confidently issues a
replace "old text" with "new text"edit against a version of the file that no longer exists. Best case the edit fails to match. Worst case it matches something it shouldn't and silently corrupts the file.What the gate does
edit_file,apply_diffanddiff_applyrefuse to touch a file unless both of these are true:file(action:"read")in this task.If either check fails, the tool returns a refusal — but the refusal isn't a dead end. The refusal auto-reads the file and returns the full, numbered, current contents. The file is now marked as read, so the model's very next call can be the edit, with
old_string/ line numbers copied from what it just received. No wasted round-trip.If the file changed on disk mid-task (you edited it in Xcode, a formatter ran, a build step regenerated it, another tab touched it), the model gets "File has been modified since you last read it" plus a diff snippet of what changed, surfaced at the start of the next turn.
What's exempt
write_file(whole-file overwrite) — there's nothing to mismatch against.Why it pairs with context compaction
The gate matters most because of compaction. When Agent! compresses a long task's context, the model can lose the literal file contents it read 40 turns ago. Without the gate, it would happily edit from a half-remembered version. With it, the edit bounces, the model gets fresh contents, and the edit lands on reality. Oversized tool results are also spilled to disk and recoverable via
restore_tool_result, so the model can pull back an earlier read instead of re-reading from scratch.Related safety layers
The gate is one row of the table in the README's Privacy & Safety section. The others: the Shell Safety Service (hard-blocks
rm -rf /,rm -rf ~, bare-globrm -rf, enforced client-side and daemon-side), per-edit file snapshots with one-click rollback or task-scopedrewind_task, XPC same-team code-signing checks, and tool-execution gating so the model can't claim it did something it never called a tool for.Questions about how it behaves in a specific workflow? Ask below.
All reactions