diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md
index e3207e069..066b6ea9a 100644
--- a/packages/coding-agent/CHANGELOG.md
+++ b/packages/coding-agent/CHANGELOG.md
@@ -2,6 +2,10 @@
## [Unreleased]
+
+### Changed
+- Documented Unicode escape semantics in the `write`, `replace`, `patch`, and `hashline` tool prompts. JSON natively decodes `\uXXXX`, so emitting `"\u2192"` (one backslash) writes the character → and emitting `"\\u2192"` (two backslashes) writes the literal 6-char escape sequence — useful for JS regex source, Python raw strings, JSON fixtures, and docs about Unicode.
+
## [14.7.0] - 2026-05-04
### Breaking Changes
diff --git a/packages/coding-agent/src/prompts/tools/hashline.md b/packages/coding-agent/src/prompts/tools/hashline.md
index 09cb8254f..f422d144e 100644
--- a/packages/coding-agent/src/prompts/tools/hashline.md
+++ b/packages/coding-agent/src/prompts/tools/hashline.md
@@ -99,3 +99,10 @@ If your replacement payload would render with even one unchanged line in the dif
- `= A..B` deletes the range; payload is what's written. If a payload edge line already exists immediately outside `A..B`, widen the range to cover it — otherwise it duplicates.
- Multiple ops in one patch are cheap. Prefer two narrow ops over one wide `=`.
+
+
+Your tool-call JSON is parsed before this tool sees `content`, so `\uXXXX` decodes natively.
+- To insert the **character** → (U+2192): emit `"\u2192"` (one backslash) in the JSON, or the literal → character.
+- To insert the **literal 6-char escape sequence** `\u2192` (source code that already contains `\u2192` — JS regex `/\u2192/`, Python `r"\u2192"`, JSON fixtures): emit `"\\u2192"` (two backslashes) in the JSON. The 6 chars arrive verbatim.
+- **NEVER** emit `"\\u2192"` when you intend the character →. That is a literal escape, not a Unicode character.
+
diff --git a/packages/coding-agent/src/prompts/tools/patch.md b/packages/coding-agent/src/prompts/tools/patch.md
index ec847d442..0e97242eb 100644
--- a/packages/coding-agent/src/prompts/tools/patch.md
+++ b/packages/coding-agent/src/prompts/tools/patch.md
@@ -50,6 +50,13 @@ Returns success/failure; on failure, error message indicates:
- **NEVER** use edit to fix indentation, whitespace, or reformat code. Formatting is a single command run once at the end (`bun fmt`, `cargo fmt`, `prettier —write`, etc.)—not N individual edits. If you see inconsistent indentation after an edit, leave it; the formatter will fix all of it in one pass.
+
+Your tool-call JSON is parsed before this tool sees `diff`, so `\uXXXX` decodes natively in `+` lines, ` ` context, and `op:create` payloads.
+- To match or add the **character** → (U+2192): emit `"\u2192"` (one backslash) in the JSON, or the literal → character.
+- To match or add the **literal 6-char escape sequence** `\u2192` (source code that already contains `\u2192` — JS regex `/\u2192/`, Python `r"\u2192"`, JSON fixtures): emit `"\\u2192"` (two backslashes) in the JSON. The 6 chars arrive verbatim.
+- **NEVER** emit `"\\u2192"` when you intend the character →. That is a literal escape, not a Unicode character.
+
+
# Create
`edit {"path":"hello.txt","edits":[{"op":"create","diff":"Hello\n"}]}`
diff --git a/packages/coding-agent/src/prompts/tools/replace.md b/packages/coding-agent/src/prompts/tools/replace.md
index b9882adbe..c0c127773 100644
--- a/packages/coding-agent/src/prompts/tools/replace.md
+++ b/packages/coding-agent/src/prompts/tools/replace.md
@@ -15,6 +15,13 @@ Returns success/failure status. On success, file modified in place with replacem
- You **MUST** read the file at least once in the conversation before editing. Tool errors if you attempt edit without reading file first.
+
+Your tool-call JSON is parsed before this tool sees `old_text` / `new_text`, so `\uXXXX` decodes natively.
+- To match or write the **character** → (U+2192): emit `"\u2192"` (one backslash) in the JSON, or the literal → character. Both arrive as →.
+- To match or write the **literal 6-char escape sequence** `\u2192` (e.g. `old_text` for source code that already contains `\u2192`, or `new_text` for JS regex `/\u2192/`, Python `r"\u2192"`, JSON fixtures): emit `"\\u2192"` (two backslashes) in the JSON. The 6 chars arrive verbatim.
+- **NEVER** emit `"\\u2192"` when you intend the character →. That is a literal escape, not a Unicode character.
+
+
Replace for content-addressed changes—you identify \_what* to change by its text.
diff --git a/packages/coding-agent/src/prompts/tools/write.md b/packages/coding-agent/src/prompts/tools/write.md
index 9576a790d..68df91bf6 100644
--- a/packages/coding-agent/src/prompts/tools/write.md
+++ b/packages/coding-agent/src/prompts/tools/write.md
@@ -12,3 +12,10 @@ Creates or overwrites file at specified path.
- You **MUST NOT** create documentation files (*.md, README) unless explicitly requested
- You **MUST NOT** use emojis unless requested
+
+
+Your tool-call JSON is parsed before this tool sees `content`, so `\uXXXX` decodes natively.
+- To write the **character** → (U+2192) on disk: emit `"\u2192"` (one backslash) in the JSON, or the literal `→` character. Both arrive at the tool as `→` and are written as 3 UTF-8 bytes.
+- To write the **literal 6-char escape sequence** `\u2192` on disk (JS regex `/\u2192/`, Python `r"\u2192"`, JSON fixtures, docs about Unicode): emit `"\\u2192"` (two backslashes) in the JSON. The parser delivers the 6 chars to the tool and we write them verbatim.
+- **NEVER** emit `"\\u2192"` (two backslashes) when you intend the character →. That writes the literal text `\u2192`, not the character.
+