Skip to content

Instantly share code, notes, and snippets.

@denysvitali
Created July 29, 2026 07:12
Show Gist options
  • Select an option

  • Save denysvitali/3f863cda4244315b8a8ac614ffb8060d to your computer and use it in GitHub Desktop.

Select an option

Save denysvitali/3f863cda4244315b8a8ac614ffb8060d to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# Patch Claude Code's out-of-band-write diff budget (GN_) from 16384 -> 0.
#
# Bug: for files >4kB, Claude Code keeps only a hash in readFileState. When the
# file is written out-of-band (codegen, protobufs, formatters), the "file
# changed" attachment is diffed against an empty cache, so the WHOLE file is
# inlined as `edited_text_file.snippet` until the cumulative budget GN_ (16384
# chars) is exhausted. That silently torches the context window.
#
# Fix: set the budget to 0 so every such snippet is dropped and the agent is
# told "the diff was omitted ... use the Read tool if you need the current
# content".
#
# Same-length byte substitution: "GN_=16384" -> "GN_=0x000"
#
# Usage:
# ./patch-claude-diff-budget.sh # patch all installed versions
# ./patch-claude-diff-budget.sh --check # report status only
# ./patch-claude-diff-budget.sh --restore # restore from .orig backups
# VERSIONS_DIR=/path ./patch-claude-diff-budget.sh
set -euo pipefail
VERSIONS_DIR="${VERSIONS_DIR:-$HOME/.local/share/claude/versions}"
# The budget symbol is minified and changes every release (GN_, $N_, Xzy, ...),
# so derive it from its only use site: `if(i>=SYM)s.snippet=""`.
USE_SITE_RE='if(i>=[A-Za-z0-9_$]\{1,8\})[A-Za-z0-9_$]\{1,3\}\.snippet=""'
budget_symbol() { # $1 = binary
# `|| true`: grep dies with SIGPIPE once head -1 closes the pipe, and
# `set -o pipefail` would otherwise turn that into a fatal error.
{ grep -a -o -m1 "$USE_SITE_RE" "$1" 2>/dev/null || true; } \
| sed 's/^if(i>=//; s/).*$//'
}
mode="patch"
case "${1:-}" in
--check) mode="check" ;;
--restore) mode="restore" ;;
"") ;;
*) echo "unknown arg: $1" >&2; exit 2 ;;
esac
[ -d "$VERSIONS_DIR" ] || { echo "no versions dir: $VERSIONS_DIR" >&2; exit 1; }
shopt -s nullglob
bins=("$VERSIONS_DIR"/*)
[ ${#bins[@]} -gt 0 ] || { echo "no binaries in $VERSIONS_DIR" >&2; exit 1; }
for bin in "${bins[@]}"; do
[ -f "$bin" ] || continue
case "$bin" in *.orig) continue ;; esac
name=$(basename "$bin")
if [ "$mode" = restore ]; then
if [ -f "$bin.orig" ]; then
tmp="$bin.restoring.$$"
cp -p "$bin.orig" "$tmp" && mv -f "$tmp" "$bin"
echo "$name: restored from backup"
else
echo "$name: no backup, skipped"
fi
continue
fi
sym=$(budget_symbol "$bin")
if [ -z "$sym" ]; then
echo "$name: budget use-site not found (different build?)"
continue
fi
FROM="$sym=16384"
TO="$sym=0x000"
n_from=$(grep -c -a -F "$FROM" "$bin" || true)
n_to=$(grep -c -a -F "$TO" "$bin" || true)
if [ "$mode" = check ]; then
if [ "$n_to" -gt 0 ]; then echo "$name: PATCHED ($TO)"
elif [ "$n_from" -gt 0 ]; then echo "$name: vulnerable ($FROM present)"
else echo "$name: symbol '$sym' found but no =16384 assignment"
fi
continue
fi
if [ "$n_to" -gt 0 ]; then echo "$name: already patched"; continue; fi
if [ "$n_from" -eq 0 ]; then echo "$name: pattern '$FROM' not found, skipped"; continue; fi
[ -f "$bin.orig" ] || cp -p "$bin" "$bin.orig"
# Patch a COPY, then rename over the original. The rename swaps the inode, so
# a currently-running claude process keeps its old mapping instead of having
# its text segment mutated underneath it.
tmp="$bin.patching.$$"
cp -p "$bin" "$tmp"
off=$(grep -a -b -o -F "$FROM" "$tmp" | head -1 | cut -d: -f1)
printf '%s' "$TO" | dd of="$tmp" bs=1 seek="$off" conv=notrunc status=none
if grep -q -a -F "$TO" "$tmp" && ! grep -q -a -F "$FROM" "$tmp"; then
mv -f "$tmp" "$bin"
echo "$name: patched at byte $off (backup: $name.orig)"
else
rm -f "$tmp"
echo "$name: patch verification FAILED, original untouched" >&2
exit 1
fi
done
echo
echo "Restart any running 'claude' sessions for the patch to take effect."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment