fix(claude-hooks): review fixes — git -C variant, main-hotfix false positive, known-bypass docstring
This commit is contained in:
parent
0bbfd0e13e
commit
4ecb639492
1 changed files with 13 additions and 11 deletions
|
|
@ -7,8 +7,10 @@ Deny-префиксы в settings.json позиционны и обходятс
|
||||||
внутри powershell/pwsh/bash -c.
|
внутри powershell/pwsh/bash -c.
|
||||||
|
|
||||||
Ограничение (как у check-secret-read.py): видит только текст top-level команды —
|
Ограничение (как у check-secret-read.py): видит только текст top-level команды —
|
||||||
опасная операция внутри вызываемого скрипта не детектится. Fail-open по дизайну:
|
опасная операция внутри вызываемого скрипта не детектится. Known-bypass (осознанно):
|
||||||
это tripwire-слой поверх deny-правил и review, а не единственная защита.
|
long-form `rm --recursive --force`, PowerShell-алиасы ri/rd/del, сокращения -Rec.
|
||||||
|
Fail-open по дизайну: это tripwire-слой поверх deny-правил и review, а не
|
||||||
|
единственная защита.
|
||||||
|
|
||||||
Протокол: exit 0 = allow, exit 2 + stderr = block (сообщение уходит Claude).
|
Протокол: exit 0 = allow, exit 2 + stderr = block (сообщение уходит Claude).
|
||||||
"""
|
"""
|
||||||
|
|
@ -19,23 +21,23 @@ import sys
|
||||||
|
|
||||||
# (pattern, объяснение). Все паттерны применяются к полной строке команды.
|
# (pattern, объяснение). Все паттерны применяются к полной строке команды.
|
||||||
PATTERNS: list[tuple[str, str]] = [
|
PATTERNS: list[tuple[str, str]] = [
|
||||||
(r"git\s+push\b[^\n]*?\s(-f|--force(?:-with-lease|-if-includes)?)\b",
|
(r"git\s+(?:-C\s+\S+\s+)?push\b[^\n]*?\s(-f|--force(?:-with-lease|-if-includes)?)\b",
|
||||||
"git push --force/-f/--force-with-lease запрещён без явного approval юзера"),
|
"git push --force/-f/--force-with-lease запрещён без явного approval юзера"),
|
||||||
(r"git\s+push\b[^\n]*?--no-verify",
|
(r"git\s+(?:-C\s+\S+\s+)?push\b[^\n]*?--no-verify",
|
||||||
"git push --no-verify запрещён (pre-push hooks обязательны)"),
|
"git push --no-verify запрещён (pre-push hooks обязательны)"),
|
||||||
(r"git\s+push\b[^\n]*\s\S+\s+(\S+:)?main\b",
|
(r"git\s+(?:-C\s+\S+\s+)?push\b[^\n]*\s\S+\s+(\S+:)?main(?![\w/-])",
|
||||||
"прямой push в main запрещён — только ветка + PR (git-pr.md)"),
|
"прямой push в main запрещён — только ветка + PR (git-pr.md)"),
|
||||||
(r"git\s+commit\b[^\n]*?--amend\b",
|
(r"git\s+(?:-C\s+\S+\s+)?commit\b[^\n]*?--amend\b",
|
||||||
"git commit --amend запрещён без явного approval юзера"),
|
"git commit --amend запрещён без явного approval юзера"),
|
||||||
(r"git\s+commit\b[^\n]*?(--no-verify\b|\s-n\b)",
|
(r"git\s+(?:-C\s+\S+\s+)?commit\b[^\n]*?(--no-verify\b|\s-n\b)",
|
||||||
"git commit --no-verify/-n запрещён (pre-commit hooks обязательны)"),
|
"git commit --no-verify/-n запрещён (pre-commit hooks обязательны)"),
|
||||||
(r"git\s+rebase\b[^\n]*?(\s-i\b|--interactive\b)",
|
(r"git\s+(?:-C\s+\S+\s+)?rebase\b[^\n]*?(\s-i\b|--interactive\b)",
|
||||||
"git rebase -i/--interactive запрещён"),
|
"git rebase -i/--interactive запрещён"),
|
||||||
(r"git\s+reset\b[^\n]*?--hard\b",
|
(r"git\s+(?:-C\s+\S+\s+)?reset\b[^\n]*?--hard\b",
|
||||||
"git reset --hard запрещён (уничтожает локальные изменения)"),
|
"git reset --hard запрещён (уничтожает локальные изменения)"),
|
||||||
(r"git\s+clean\b[^\n]*?\s-[a-zA-Z]*f",
|
(r"git\s+(?:-C\s+\S+\s+)?clean\b[^\n]*?\s-[a-zA-Z]*f",
|
||||||
"git clean -f* запрещён (удаляет untracked-файлы)"),
|
"git clean -f* запрещён (удаляет untracked-файлы)"),
|
||||||
(r"git\s+checkout\b[^\n]*?\s-f\b",
|
(r"git\s+(?:-C\s+\S+\s+)?checkout\b[^\n]*?\s-f\b",
|
||||||
"git checkout -f запрещён (теряет незакоммиченные изменения)"),
|
"git checkout -f запрещён (теряет незакоммиченные изменения)"),
|
||||||
(r"\brm\b(?=[^\n|;&]*\s-[a-zA-Z]*r)(?=[^\n|;&]*\s-[a-zA-Z]*f)",
|
(r"\brm\b(?=[^\n|;&]*\s-[a-zA-Z]*r)(?=[^\n|;&]*\s-[a-zA-Z]*f)",
|
||||||
"rm -rf (и вариации -fr / -r -f) запрещён"),
|
"rm -rf (и вариации -fr / -r -f) запрещён"),
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue