Skip to content

Commit b0d1d9c

Browse files
committed
fix(rules): close 3 Greptile findings on Tier 1 block rules
1. **Edit/MultiEdit bypass reachability documented and tested** (block-standup-not-in-escritorio + block-goodnight-not-in-escritorio). The dispatcher's bypass scan already runs against the full raw tool_input JSON via `parse-input.sh INPUT_RAW`, so a marker in any string-valued field (`new_string`, `old_string`, `edits[].new_string`) short-circuits the rule. Add explicit `allows-bypass-marker-edit-tool` and `allows-bypass-marker-multiedit-tool` tests for both rules and a clarifying comment so a future maintainer doesn't reintroduce the reachability concern. Renames `allows-bypass-marker` -> `allows-bypass-marker-write-tool` to keep the tool-shape symmetry. 2. **Combined --force + --force-with-lease defense-in-depth tested** (block-git-force-push-no-lease). Add `allows-force-with-lease-and-force-combined` with the exact pathological-ordering command the design doc calls out, locking in the not_pattern safety net against future regex refactors. 3. **pnpm dlx / yarn dlx playwright invocations tested** (block-playwright-headless). Add `blocks-pnpm-dlx-playwright-headless`, `blocks-yarn-dlx-playwright-headless`, and `allows-pnpm-dlx-playwright-headed`. The pattern already covers these forms; the tests pin that behavior. Tests: 128 -> 136 passing (+8).
1 parent 940350d commit b0d1d9c

2 files changed

Lines changed: 146 additions & 4 deletions

File tree

hooks/rules/rules.json

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,6 +1452,33 @@
14521452
},
14531453
"expected_exit": 0
14541454
},
1455+
{
1456+
"name": "blocks-pnpm-dlx-playwright-headless",
1457+
"input": {
1458+
"tool_input": {
1459+
"command": "pnpm dlx playwright test"
1460+
}
1461+
},
1462+
"expected_exit": 2
1463+
},
1464+
{
1465+
"name": "blocks-yarn-dlx-playwright-headless",
1466+
"input": {
1467+
"tool_input": {
1468+
"command": "yarn dlx playwright test"
1469+
}
1470+
},
1471+
"expected_exit": 2
1472+
},
1473+
{
1474+
"name": "allows-pnpm-dlx-playwright-headed",
1475+
"input": {
1476+
"tool_input": {
1477+
"command": "pnpm dlx playwright test --headed"
1478+
}
1479+
},
1480+
"expected_exit": 0
1481+
},
14551482
{
14561483
"name": "allows-bypass-marker",
14571484
"input": {
@@ -1520,6 +1547,15 @@
15201547
},
15211548
"expected_exit": 0
15221549
},
1550+
{
1551+
"name": "allows-force-with-lease-and-force-combined",
1552+
"input": {
1553+
"tool_input": {
1554+
"command": "git push -f origin main --force-with-lease"
1555+
}
1556+
},
1557+
"expected_exit": 0
1558+
},
15231559
{
15241560
"name": "allows-bypass-marker",
15251561
"input": {
@@ -1666,14 +1702,40 @@
16661702
"expected_exit": 0
16671703
},
16681704
{
1669-
"name": "allows-bypass-marker",
1705+
"name": "allows-bypass-marker-write-tool",
16701706
"input": {
16711707
"tool_input": {
16721708
"file_path": "/tmp/daily-standup.md",
16731709
"content": "# Standup // hook-bypass: standup-non-desktop-acknowledged"
16741710
}
16751711
},
16761712
"expected_exit": 0
1713+
},
1714+
{
1715+
"name": "allows-bypass-marker-edit-tool",
1716+
"input": {
1717+
"tool_input": {
1718+
"file_path": "/tmp/daily-standup.md",
1719+
"old_string": "# Old",
1720+
"new_string": "# Standup // hook-bypass: standup-non-desktop-acknowledged"
1721+
}
1722+
},
1723+
"expected_exit": 0
1724+
},
1725+
{
1726+
"name": "allows-bypass-marker-multiedit-tool",
1727+
"input": {
1728+
"tool_input": {
1729+
"file_path": "/tmp/daily-standup.md",
1730+
"edits": [
1731+
{
1732+
"old_string": "# A",
1733+
"new_string": "# B // hook-bypass: standup-non-desktop-acknowledged"
1734+
}
1735+
]
1736+
}
1737+
},
1738+
"expected_exit": 0
16771739
}
16781740
]
16791741
},
@@ -1748,14 +1810,40 @@
17481810
"expected_exit": 0
17491811
},
17501812
{
1751-
"name": "allows-bypass-marker",
1813+
"name": "allows-bypass-marker-write-tool",
17521814
"input": {
17531815
"tool_input": {
17541816
"file_path": "/tmp/next-day-2026-05-09.md",
17551817
"content": "# Handoff // hook-bypass: goodnight-non-desktop-acknowledged"
17561818
}
17571819
},
17581820
"expected_exit": 0
1821+
},
1822+
{
1823+
"name": "allows-bypass-marker-edit-tool",
1824+
"input": {
1825+
"tool_input": {
1826+
"file_path": "/tmp/next-day-2026-05-09.md",
1827+
"old_string": "# Old",
1828+
"new_string": "# Handoff // hook-bypass: goodnight-non-desktop-acknowledged"
1829+
}
1830+
},
1831+
"expected_exit": 0
1832+
},
1833+
{
1834+
"name": "allows-bypass-marker-multiedit-tool",
1835+
"input": {
1836+
"tool_input": {
1837+
"file_path": "/tmp/next-day-2026-05-09.md",
1838+
"edits": [
1839+
{
1840+
"old_string": "# A",
1841+
"new_string": "# B // hook-bypass: goodnight-non-desktop-acknowledged"
1842+
}
1843+
]
1844+
}
1845+
},
1846+
"expected_exit": 0
17591847
}
17601848
]
17611849
}

hooks/rules/rules.yaml

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,6 +1177,21 @@
11771177
tool_input:
11781178
command: 'npm test'
11791179
expected_exit: 0
1180+
- name: blocks-pnpm-dlx-playwright-headless
1181+
input:
1182+
tool_input:
1183+
command: 'pnpm dlx playwright test'
1184+
expected_exit: 2
1185+
- name: blocks-yarn-dlx-playwright-headless
1186+
input:
1187+
tool_input:
1188+
command: 'yarn dlx playwright test'
1189+
expected_exit: 2
1190+
- name: allows-pnpm-dlx-playwright-headed
1191+
input:
1192+
tool_input:
1193+
command: 'pnpm dlx playwright test --headed'
1194+
expected_exit: 0
11801195
- name: allows-bypass-marker
11811196
input:
11821197
tool_input:
@@ -1234,6 +1249,11 @@
12341249
tool_input:
12351250
command: 'git push origin feature-x'
12361251
expected_exit: 0
1252+
- name: allows-force-with-lease-and-force-combined
1253+
input:
1254+
tool_input:
1255+
command: 'git push -f origin main --force-with-lease'
1256+
expected_exit: 0
12371257
- name: allows-bypass-marker
12381258
input:
12391259
tool_input:
@@ -1347,12 +1367,31 @@
13471367
file_path: '/home/user/repo/docs/notes.md'
13481368
content: '# Notes'
13491369
expected_exit: 0
1350-
- name: allows-bypass-marker
1370+
- name: allows-bypass-marker-write-tool
13511371
input:
13521372
tool_input:
13531373
file_path: '/tmp/daily-standup.md'
13541374
content: '# Standup // hook-bypass: standup-non-desktop-acknowledged'
13551375
expected_exit: 0
1376+
# Edit and MultiEdit expose `new_string` / `old_string` / `edits[]` instead
1377+
# of `content`, so we lock in that the bypass marker placed in any of those
1378+
# fields still short-circuits the rule. The dispatcher scans the entire raw
1379+
# tool_input JSON for the marker, so any string-valued field is reachable.
1380+
- name: allows-bypass-marker-edit-tool
1381+
input:
1382+
tool_input:
1383+
file_path: '/tmp/daily-standup.md'
1384+
old_string: '# Old'
1385+
new_string: '# Standup // hook-bypass: standup-non-desktop-acknowledged'
1386+
expected_exit: 0
1387+
- name: allows-bypass-marker-multiedit-tool
1388+
input:
1389+
tool_input:
1390+
file_path: '/tmp/daily-standup.md'
1391+
edits:
1392+
- old_string: '# A'
1393+
new_string: '# B // hook-bypass: standup-non-desktop-acknowledged'
1394+
expected_exit: 0
13561395

13571396
- id: block-goodnight-not-in-escritorio
13581397
description: Block /goodnight handoff files (`next-day-*.md` / `goodnight-*.md`) anywhere outside ~/Escritorio (memory feedback_goodnight_desktop.md)
@@ -1407,9 +1446,24 @@
14071446
file_path: '/home/user/repo/docs/notes.md'
14081447
content: '# Notes'
14091448
expected_exit: 0
1410-
- name: allows-bypass-marker
1449+
- name: allows-bypass-marker-write-tool
14111450
input:
14121451
tool_input:
14131452
file_path: '/tmp/next-day-2026-05-09.md'
14141453
content: '# Handoff // hook-bypass: goodnight-non-desktop-acknowledged'
14151454
expected_exit: 0
1455+
- name: allows-bypass-marker-edit-tool
1456+
input:
1457+
tool_input:
1458+
file_path: '/tmp/next-day-2026-05-09.md'
1459+
old_string: '# Old'
1460+
new_string: '# Handoff // hook-bypass: goodnight-non-desktop-acknowledged'
1461+
expected_exit: 0
1462+
- name: allows-bypass-marker-multiedit-tool
1463+
input:
1464+
tool_input:
1465+
file_path: '/tmp/next-day-2026-05-09.md'
1466+
edits:
1467+
- old_string: '# A'
1468+
new_string: '# B // hook-bypass: goodnight-non-desktop-acknowledged'
1469+
expected_exit: 0

0 commit comments

Comments
 (0)