Edits and change transactions
Mercury's change transactions apply one change vocabulary to every mutation path: a way for a later mutation to fail fast on stale assumptions, and an exactly-once record of what changed. Read anchors identify the content an edit expects, so a later edit can refuse stale assumptions before writing.
Read anchors
fa:<hex12>: Identifies the contents of a whole file.ra:<hex12>:L<start>+<n>: Identifies the exact returned line range, using one-based line positions.expected_anchor: Supplies the expected content to a mutation, verified against the current bytes before writing. A stale or malformed anchor returns a typed result naming the reason, a current anchor and the smallest reread that repairs the assumption.N#hhhh: Identifies a line by its one-based position and the first hex of its own hash when a Read asks forline_anchors. Identical lines share a hash and never share an address.
File and range digests are SHA-256 over CRLF-normalized text, truncated to 12 hex characters. Unicode codepoints are not normalized. These digests detect stale content and are not a security boundary.
Edit hunks
The Edit tool accepts one or more disjoint, one-based line replacements or insertions in hunks, applied atomically. A batch applies against the snapshot named by expected_anchor, which is required in this mode; a range anchor bounds the editable window. Stale, overlapping, out-of-bounds or unparseable hunks write nothing and name the failing hunk.
Anchor-qualified positions such as 12#ab3f carry endpoint hashes that are verified before anything is written. A batch whose hunks all use these positions can omit expected_anchor; external content drift still refuses the batch. A refusal answers the current neighborhood anchors and bounded moved-to candidates, but the engine never relocates the edit itself.
An Edit that touches lines the model has not read is refused, and the refusal carries those lines, widened by a small margin and each block with its own range anchor, so the edit is repeated without a Read. A Read of a file over the token cap answers with its first window as an ordinary result, and its first line names the file's size in tokens, the lines returned and the Read that continues from the window's end.
Change receipts
Every mutation-shaped tool call lands exactly one receipt: the intent plus the observed effect, recorded once at a single chokepoint. A cancelled or refused call never mints a partial receipt, and repeated no-change outcomes feed the repetition policy, which reports truthfully instead of looping.
ChangeSet operations
previewwithchanges: Produces an immutable, content-addressed plan without writing files.applywithchanges: Plans the set, obtains one aggregate permission decision and applies it.applywithplan_id: Applies a previously previewed plan. A stale plan is refused with current anchors.statuswithplan_id: Inspects a retained plan.discardwithplan_id: Retires a plan.
The JSON form targets existing text files, each with its required expected_anchor and its hunks. It refuses creation, deletion, movement, binary files, notebooks and executable targets by name. The optional patch dialect, patch beside changes, adds block edits, cross-file moves, whole-file deletion and file movement over the same anchors, committed through the same planner.
Preview a change set
To preview a change set, follow these steps:
- Read the target files to obtain their anchors.
- Call
ChangeSetwithpreviewand achangesmember for each file, including itsexpected_anchorand hunks.
The tool returns a retained plan and leaves the files unchanged.
Apply a previewed change set
To apply a previewed change set, follow these steps:
- Call
ChangeSetwithapplyand the returnedplan_id. - Approve the aggregate permission request if one is presented.
The complete set is applied and verified by reread, or the refusal names why nothing was written.
There is exactly one aggregate decision by the user per set, and one denied path means zero writes. Each executed set produces one effect, one receipt and one aggregate inline change-view card. Editor and language-server synchronization after the write is bounded, and a timeout is classified as indeterminate, never as success.
Limits and switches
- Set size: At most 16 files, 32 hunks per file, 128 hunks per set, 4 MB of staged bytes and 240 rendered diff lines, with per-file cuts named.
- Plans: At most 16 retained plans per owner, with a 30-minute lifetime.
MERCURY_CHANGE_RECEIPTS: Enabled by default;0removes anchors on reads, theexpected_anchorfield, their enforcement and the receipt record.MERCURY_EDIT_HUNKS: Enabled by default;0restores the plainexpected_anchorschema ofEdit.MERCURY_LINE_ANCHORS: Enabled by default;0removes theline_anchorsRead parameter, and hash spellings then refuse as unparseable.MERCURY_ANCHOR_PATCH: Opt-in; unset or0, theChangeSetschema carries no patch field.MERCURY_CHANGESET: Enabled by default and requires receipts and hunks;0removes the tool while the shared commit core keeps serving the Structure tool and language-server edits.
Related pages
Search and edit by syntax, Language servers, Sessions, Permission modes