hermes-bot / scripts /patch_sandbox_isolation.py
Z User
EMERGENCY FIX: Disable sandbox patch - indentation bug broke terminal
7f68bf3
#!/usr/bin/env python3
"""Patch hermes-agent: sandbox isolation DISABLED (2026-05-09 emergency fix).
The original patch had a CRITICAL indentation bug in the Popen hook:
old_popen = "proc = subprocess.Popen(\n args," # no leading spaces
new_popen = " # Hermes Bot patch: ...\n" # 8 leading spaces
→ str.replace doubled indentation (8+8=16 spaces) → IndentationError
→ local.py failed to import → terminal tool completely broken
This no-op version preserves the file so start.sh doesn't error,
but does NOT inject any code into local.py.
Re-enable after rewriting with correct indentation matching (include
leading spaces in old_popen to prevent double-indentation).
"""
import sys
import os
import glob
def patch_file(filepath: str) -> bool:
"""No-op: sandbox isolation patch is disabled."""
# If previously patched, REMOVE the sandbox code to restore clean state
with open(filepath, "r") as f:
content = f.read()
if "sandbox_wrap" not in content:
print(f" [local.py] Clean (no sandbox code found)")
return True
# Remove the sandbox wrapper code block
sandbox_start = content.find("# ── Hermes Bot patch: Sandbox isolation for dangerous commands ──")
if sandbox_start < 0:
sandbox_start = content.find("# Hermes Bot patch: Sandbox isolation for dangerous commands")
if sandbox_start < 0:
print(f" [local.py] sandbox_wrap found but no injection marker — manual cleanup needed")
return True
# Find the insertion point: the line before the sandbox block
# Walk backwards to find the start of the injected block
line_start = content.rfind("\n", 0, sandbox_start)
if line_start < 0:
line_start = 0
else:
line_start += 1 # skip the \n
# Find the end of the sandbox code block
# The block ends with a blank line before the next original code
# Look for the pattern that indicates end of injected code
# The sandbox code block ends with the closing of should_sandbox function
sandbox_end_markers = [
"\n\ndef _resolve_safe_cwd", # original function after injection point
"\n\ndef _build_provider_env", # alternative
"\n\nclass LocalEnvironment", # if injected before class
]
sandbox_end = -1
for marker in sandbox_end_markers:
pos = content.find(marker, sandbox_start)
if pos > 0:
sandbox_end = pos
break
if sandbox_end < 0:
# Fallback: find the next top-level def or class after sandbox_start
import re
m = re.search(r'\n(def |class )', content[sandbox_start + 100:])
if m:
sandbox_end = sandbox_start + 100 + m.start()
else:
print(f" [local.py] Could not find end of sandbox block — skipping cleanup")
return False
# Also remove the hook code from _run_bash if present
hook_pattern = " # Hermes Bot patch: auto-sandbox dangerous commands\n"
new_content = content[line_start:sandbox_end]
new_content2 = new_content.replace(hook_pattern, "")
if len(new_content2) < len(new_content):
# Remove the if should_sandbox block too
import re
new_content2 = re.sub(
r'\n if should_sandbox\(cmd_string\):\n.*?(?=\n proc = subprocess\.Popen)',
'\n',
new_content2,
flags=re.DOTALL,
)
content = content[:line_start] + new_content2 + content[sandbox_end:]
print(f" [local.py] Removed sandbox hook from _run_bash")
else:
content = content[:line_start] + content[sandbox_end:]
print(f" [local.py] Removed sandbox wrapper code block")
with open(filepath, "w") as f:
f.write(content)
print(f" [local.py] Sandbox isolation REMOVED (emergency fix)")
return True
if __name__ == "__main__":
print("Sandbox isolation patch: DISABLED (emergency fix 2026-05-09)")
print(" Reason: indentation bug caused local.py IndentationError")
candidates = [
"/app/hermes-agent/tools/environments/local.py",
]
candidates.extend(
glob.glob("/app/venv/lib/**/tools/environments/local.py", recursive=True)
)
filepath = None
for c in candidates:
if os.path.isfile(c):
filepath = c
break
if not filepath:
print(" local.py not found — nothing to do")
sys.exit(0)
patch_file(filepath)
print(" Terminal tool should now work normally")