1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
import json
import os
import subprocess
import sys
from pathlib import Path
SCRIPT = Path(__file__).parents[1] / "rulesets-write-boundary.py"
def run_hook(payload: dict, rulesets: Path) -> dict | None:
proc = subprocess.run(
[sys.executable, str(SCRIPT)],
input=json.dumps(payload),
text=True,
capture_output=True,
env={**os.environ, "RULESETS_ROOT": str(rulesets)},
check=True,
)
return json.loads(proc.stdout) if proc.stdout else None
def test_allows_write_from_rulesets_session(tmp_path):
rulesets = tmp_path / "rulesets"
rulesets.mkdir()
target = rulesets / "file"
result = run_hook(
{
"cwd": str(rulesets),
"tool_name": "Write",
"tool_input": {"file_path": str(target)},
},
rulesets,
)
assert result is None
def test_blocks_absolute_cross_project_write(tmp_path):
rulesets = tmp_path / "rulesets"
other = tmp_path / "other"
rulesets.mkdir()
other.mkdir()
result = run_hook(
{
"cwd": str(other),
"tool_name": "Edit",
"tool_input": {"file_path": str(rulesets / "rule.md")},
},
rulesets,
)
assert result["hookSpecificOutput"]["permissionDecision"] == "deny"
assert "inbox-send rulesets" in result["hookSpecificOutput"][
"permissionDecisionReason"
]
def test_blocks_write_reached_through_symlink(tmp_path):
rulesets = tmp_path / "rulesets"
other = tmp_path / "other"
installed = tmp_path / "installed"
rulesets.mkdir()
other.mkdir()
(rulesets / "rules").mkdir()
installed.symlink_to(rulesets / "rules", target_is_directory=True)
result = run_hook(
{
"cwd": str(other),
"tool_name": "Write",
"tool_input": {"file_path": str(installed / "todo-format.md")},
},
rulesets,
)
assert result["hookSpecificOutput"]["permissionDecision"] == "deny"
assert str(rulesets) in result["systemMessage"]
def test_blocks_apply_patch_target(tmp_path):
rulesets = tmp_path / "rulesets"
other = tmp_path / "other"
rulesets.mkdir()
other.mkdir()
patch = (
f"*** Begin Patch\n*** Update File: {rulesets / 'file'}\n"
"@@\n-old\n+new\n*** End Patch\n"
)
result = run_hook(
{
"cwd": str(other),
"tool_name": "apply_patch",
"tool_input": {"input": patch},
},
rulesets,
)
assert result["hookSpecificOutput"]["permissionDecision"] == "deny"
def test_allows_unrelated_write(tmp_path):
rulesets = tmp_path / "rulesets"
other = tmp_path / "other"
rulesets.mkdir()
other.mkdir()
result = run_hook(
{
"cwd": str(other),
"tool_name": "Edit",
"tool_input": {"file_path": str(other / "file")},
},
rulesets,
)
assert result is None
|