Deterministic code editing protocol — reference implementation of the Scope Anchoring standard.
First, build the project:
cargo build --releaseThen run the examples in the AnchorScope Tutorial using:
# From project root
target/release/anchorscope --helpOr install globally:
cargo install --path .
anchorscope --helpSee the AnchorScope Tutorial for a comprehensive guide covering all features with practical examples:
- Multi-Level Anchoring: Nest anchors to isolate precise targets within large scopes
- True ID & Alias: Auto-generated True IDs and human-readable aliases via
label - Buffer Visualization: Inspect the anchor tree with
tree - External Tool Pipeline: Bridge with external tools via
pipeandpaths - Deterministic Safety: Learn how
HASH_MISMATCH,NO_MATCH, andAMBIGUOUS_REPLACEMENTprevent unsafe edits
AnchorScope is a minimal reference implementation of the Scope Anchoring protocol, a deterministic code editing protocol that guarantees exact region identification and safe replacement through deterministic hash verification.
Unlike traditional search-replace tools that rely on heuristics or fuzzy matching, AnchorScope enforces byte-level exactness, making it suitable for agent-based systems where correctness and reproducibility are paramount.
See the full specification: docs/SPEC.md
AnchorScope operations follow a strict pipeline:
- READ — Load file content, normalize line endings (CRLF → LF), validate UTF-8
- MATCH — Find all exact byte-level occurrences of the anchor; count results
- HASH — When exactly one match exists, compute xxh3_64 hash of the matched anchored scope
- BUFFER_WRITE — Store a normalized copy of the matched scope and compute True ID
- WRITE — Replace the matched scope if hash verification succeeds; invalidate buffer
All phases execute on normalized byte sequences. No transformations other than CRLF→LF normalization are permitted.
AnchorScope enforces correctness by design: it does not attempt to resolve ambiguity.
anchorscope read --file <path> --anchor "<string>"
# or
anchorscope read --file <path> --anchor-file <path>Output (exit 0 on success):
start_line=<1-based line>
end_line=<1-based line>
scope_hash=<16-char hex string>
true_id=<16-char hex string>
content=<matched bytes as UTF-8>
scope_hash is used as --expected-hash in write.
true_id uniquely identifies this anchor within its parent scope and is used by label, pipe, paths, and tree.
anchorscope write \
--file <path> \
--anchor "<string>" \
--expected-hash <hex> \
--replacement "<string>"
# or with anchor file
anchorscope write \
--file <path> \
--anchor-file <path> \
--expected-hash <hex> \
--replacement "<string>"
# or using buffer replacement (created by `pipe`)
anchorscope write \
--true-id <true_id> \
--anchor "<string>" \
--expected-hash <hex> \
--from-replacementReplacement source is always explicit. --replacement and --from-replacement are mutually exclusive:
| Situation | Result |
|---|---|
--replacement only |
Use inline string |
--from-replacement only |
Use buffer/{true_id}/replacement |
| Both specified | AMBIGUOUS_REPLACEMENT |
| Neither specified | NO_REPLACEMENT |
Exit 0 on success, 1 on any error condition.
anchorscope label \
--name <name> \
--true-id <hash>Assigns a human-readable alias to a True ID (generated by read).
Exit 0 on success, 1 on any error.
anchorscope tree --file <path>Displays the current Anchor Buffer structure. Shows True IDs, aliases (if any), and presence of replacement files.
Note: The --file argument is required. There is no command to show all buffers at once.
Example output:
099375c8a05dbedb (\?\C:\path\to\file.rs)
├── 445a9ef90dcde6a5 [calculate_area]
└── 8db42edf7905d28f [helper]
anchorscope pipe --true-id {true_id} --out | external-tool | anchorscope pipe --true-id {true_id} --in
# or using label
anchorscope pipe --label {alias} --out | external-tool | anchorscope pipe --label {alias} --in--out: streamsbuffer/{true_id}/contentto stdout--in: reads from stdin, validates and normalizes, writes tobuffer/{true_id}/replacement
anchorscope pipe --true-id {true_id} --tool external-tool --file-io
# or with tool arguments
anchorscope pipe --true-id {true_id} \
--tool <external-tool> \
--file-io \
--tool-args "<arg1> <arg2>"- Passes
buffer/{true_id}/contentpath to external tool - External tool reads
contentand writes output to a path provided bypipe pipevalidates and normalizes output, then stores it asreplacement--tool-argspasses space-separated arguments to the external tool
anchorscope paths --true-id {true_id}
# or
anchorscope paths --label {alias}Returns absolute paths of content and replacement for the given True ID or alias.
AnchorScope uses the system temporary directory (%TEMP%\anchorscope\ on Windows, $TMPDIR/anchorscope/ on Unix) for storing auto-generated label metadata. These files are ephemeral and are automatically cleaned up after a successful write operation.
{TMPDIR}/anchorscope/
├── {file_hash}/
│ ├── content ← normalized copy of the original file
│ ├── source_path ← absolute path to the original file
│ └── {true_id}/
│ ├── content ← normalized copy of the matched anchored scope
│ └── replacement ← output from external tool (created by `pipe`, optional)
└── labels/
└── {alias}.json ← alias → true_id mapping (created by `label`)
You can inspect these files for debugging:
tree %TEMP%\anchorscope\ # Windows
tree $TMPDIR/anchorscope/ # macOS/LinuxPass the anchor as a command-line string. Requires proper shell escaping for newlines and special characters:
anchorscope read --file src.rs --anchor $'fn main() {\n\tprintln!("Hello");\n}'Inline arguments are assumed to be valid UTF-8 by the CLI layer and are not validated by AnchorScope itself.
Read the anchor from a file. No escaping required; preserves exact byte content including newlines:
echo 'fn main() {
println!("Hello");
}' > anchor.txt
anchorscope read --file src.rs --anchor-file anchor.txtFile-based anchors are recommended for multi-line anchors and agent-generated workflows.
AnchorScope provides the following guarantees:
- Byte-level matching: Only exact byte equality is accepted. No character-level logic, no Unicode normalization.
- Complete search: All possible starting positions are evaluated; overlapping matches are detected and counted.
- Symmetric normalization: CRLF→LF normalization applies identically to file content, anchor, and replacement.
- Hash determinism: xxh3_64 produces identical output for identical byte sequences.
- Single-location semantics: Operations succeed only when exactly one match exists.
- Atomic replacement: The entire file is reconstructed as
prefix + replacement + suffixwith no modifications to prefix or suffix. - Persistent normalization: Written files are stored in normalized form (LF only).
AnchorScope returns a specific error condition for each failure mode. Errors are printed to stderr; exit code 1 indicates failure.
| Condition | Output | Description |
|---|---|---|
NO_MATCH |
NO_MATCH |
Zero occurrences of anchor found |
MULTIPLE_MATCHES (N) |
MULTIPLE_MATCHES (N) |
Anchor appears at N>1 positions |
HASH_MISMATCH |
HASH_MISMATCH: expected=... actual=... |
Matched scope differs from expected |
DUPLICATE_TRUE_ID |
DUPLICATE_TRUE_ID |
Same True ID found at multiple buffer locations |
LABEL_EXISTS |
LABEL_EXISTS |
Alias already points to a different True ID |
AMBIGUOUS_REPLACEMENT |
AMBIGUOUS_REPLACEMENT |
Both --replacement and --from-replacement provided |
NO_REPLACEMENT |
NO_REPLACEMENT |
Neither --replacement nor --from-replacement given |
IO_ERROR: ... |
IO_ERROR: <type> |
File I/O, permission, or UTF-8 validation failure |
Error evaluation order is strict:
- Count matches (must be exactly 1)
- If count ≠ 1, return match-count error
- If count = 1, compute and compare hash
- If hash mismatch, return
HASH_MISMATCH - If hash matches, perform write (may yield
IO_ERROR)
Traditional search-replace tools make implicit assumptions:
- Fuzzy matching tolerates minor variations
- Whitespace trimming "corrects" formatting
- Heuristics guess intent when patterns are ambiguous
- Multi-line overlaps are partially matched
These conveniences introduce non-determinism. The same anchor may match different regions across implementations or after minor edits. This breaks agent-based workflows where reproducibility is essential.
AnchorScope eliminates all guesswork:
- No fuzzy matching — only exact byte sequences
- No trimming — whitespace is significant
- No early termination — all candidates evaluated
- No recovery — failures are explicit and require human or orchestration-layer intervention
The result is a protocol that behaves identically across all compliant implementations, enabling reliable automation and deterministic anchoring of edits.
This repository is the reference implementation of the AnchorScope protocol as defined in the Scope Anchoring specification. It implements the full v1.3.0 scope:
- Single-file operations
- Exact multi-line anchor matching
- xxh3_64 hash verification
- True ID-based Anchor Buffer with multi-level nesting
- External tool integration via
pipeandpaths - Deterministic error handling
- UTF-8 validation and CRLF→LF normalization (irreversible)
The implementation is deliberately minimal and strict. No optional features, no compatibility modes, no heuristics.
AnchorScope is a reference implementation provided "as-is".
As the founder of the Scope Anchoring protocol, my primary focus is on the specification itself and higher-level tools.
The goal of this repository is to keep the implementation minimal, stable, and strictly aligned with the specification.
- Maintenance: Active feature development and rapid Pull Request responses are not guaranteed.
- Forks: Independent implementations and forks are highly encouraged.
- Bugs: Only critical bugs affecting the deterministic nature of the protocol will be prioritized.
AnchorScope is built upon these excellent open-source libraries:
- xxhash-rust (BSL-1.0) — High-performance XXH3 implementation.
- clap (MIT/Apache-2.0) — Flexible Command Line Argument Parser.
- tempfile (MIT/Apache-2.0) — Robust temporary file management for testing.
For typical editing workflows, use the following sequence:
# 1. Read to get True ID and hash
anchorscope read --file file.rs --anchor "fn main()"
# 2. (Optional) Create label for easier reference
anchorscope label --name "main" --true-id <true_id>
# 3. Prepare replacement via pipe
anchorscope pipe --label "main" --out | transform-tool | anchorscope pipe --label "main" --in
# 4. Write with hash verification
anchorscope write --label "main" --from-replacement- LLM-driven code editing where determinism is critical
- Multi-step edits requiring state persistence
- External tool integration with content transformation
- Debugging buffer state with tree/paths commands
- Multi-line anchor matching with exact byte preservation
| Command | Purpose |
|---|---|
read |
Locate and hash an anchored scope |
write |
Replace scope with hash verification |
label |
Assign human-readable alias to True ID |
tree |
Visualize buffer structure |
pipe |
Bridge with external tools |
paths |
Get buffer file paths for debugging |
This project is licensed under the MIT License. See the LICENSE file for the full text.
THE SOFTWARE IS PROVIDED "AS IS", without warranty of any kind. As this is a reference implementation of a file-editing protocol, the author is not responsible for any data loss or unintended file modifications resulting from its use. Always use version control and test in a safe environment.
Copyright (c) 2026 kmlaborat