Stop the guard from blocking commands that only mention the CLI #29

Closed
opened 2026-08-10 12:30:44 +00:00 by claude · 0 comments
Collaborator

Summary

tea-guard считает командой tea любую строку, где слово tea окружено
пробелами, — в том числе внутри закавыченного аргумента. Обычный вызов
python3 issue_new.py --title "..." блокируется, если в заголовке issue
упомянута команда CLI.

Spec

hooks/tea-guard.sh

Steps to reproduce

Все четыре случая пойманы на живой работе, тремя независимыми агентами.

  1. Заголовок issue содержит слово — блокируется создание локальной issue:
    python3 skills/issue/scripts/issue_new.py --type bug \
      --title "Warn that tea pulls create needs the repo checkout" \
      --label comp/use --severity low
    
  2. Сообщение коммита цитирует сырой вызов — блокируется коммит той самой
    правки, которая эти вызовы и убирает:
    git add -A && git commit -F- <<'EOF'
    feat: close issues through a script
    
    Единственным способом сменить state был сырой вызов
    tea api -X PATCH ... repos/OWNER/REPO/issues/N
    EOF
    
  3. То же на однострочном сообщении:
    git commit -m "route it through tea api"
    
  4. Поиск по репозиторию, который про tea и написан:
    grep -rn " tea " docs/
    grep -rn "tea api" skills/
    echo tea
    

Expected

Все четыре проходят. python3, git, grep, echo — это не CLI Gitea,
никакой идентичности они не используют, --login им не нужен. Гвард сторожит
запуски tea, а не тексты о них. Проверка должна смотреть на то, что реально
исполняется — первое слово команды и первые слова после ;, &&, ||, |,
( — а не на любое вхождение токена в строку.

Actual

Каждая из четырёх блокируется с exit 2:

PreToolUse:Bash hook error: [${CLAUDE_PLUGIN_ROOT}/hooks/tea-guard.sh]:
tea-guard: BLOCKED — every `tea` command must include --login "$GITEA_LOGIN"
(the guard substitutes the operator-pinned login). Run /tea:auth if no login
is pinned.

Совет в сообщении невыполним: добавлять --login в issue_new.py или в
git commit бессмысленно, а слой issue про логины вообще не знает. Обойти
можно только переписав человеческий текст под детектор — положить сообщение
коммита в файл и звать git commit -F <файл>, или выбросить слово из заголовка
issue. Заголовок issue #38 не содержит слова отдельным токеном именно поэтому.

Ложное срабатывание безопасно в смысле идентичности (хук блокирует, а не
пропускает под чужим логином), но оно ломает офлайновые слои, которые к гварду
отношения не имеют, диктует, какие слова можно писать в прозе, и
диагностируется только чтением исходника хука: сообщение говорит про --login,
а виновата прозаическая строка.

Environment

  • hooks/tea-guard.sh:88 (в других ветках :92) —
    re.search(r'(^|[;&|(]|\s)tea(\s|$)', cmd) применяется ко всей строке
    команды, без разбора на слова оболочки. Heredoc, кавычки и -m "…" для неё
    неотличимы от кода.

    if not re.search(r'(^|[;&|(]|\s)tea(\s|$)', cmd):
        allow_passthrough()
    
  • hooks/tea-guard.sh:28,127 — модуль shlex уже импортирован и используется:
    shlex.split(cmd) дал бы список слов, и проверять надо только те, что стоят
    на позиции команды.

  • Задевает именно этот репозиторий: он про tea, и слово встречается в
    заголовках, телах issue и сообщениях коммитов постоянно.

  • macOS 25.5.0, tea 0.14.1, Python 3.14.5. Воспроизведено на ветках main,
    feat/close-script, fix/no-store-for-label-payloads.

Acceptance criteria

  • python3 …/issue_new.py --title "… tea …" выполняется, а не блокируется
  • git commit -m "…" и git commit -F- с heredoc, где слово стоит
    отдельным токеном, проходят хук
  • grep -rn " tea " docs/ и echo tea проходят хук
  • настоящий вызов tea issues list без --login "$GITEA_LOGIN"
    по-прежнему блокируется
  • настоящий вызов с плейсхолдером по-прежнему переписывается на закреплённый
    логин
  • составные команды разбираются посегментно и остаются под охраной:
    cd x && tea issues list …, x | tea …, ( tea … ), подстановки
  • есть тест в tests/, который разводит по разным веткам строку, только
    упоминающую слово, и строку, которая его запускает — покрыты все четыре
    случая выше
<!-- tea:id stop-the-guard-from-blocking-commands-that-only --> ## Summary `tea-guard` считает командой `tea` любую строку, где слово `tea` окружено пробелами, — в том числе внутри закавыченного аргумента. Обычный вызов `python3 issue_new.py --title "..."` блокируется, если в заголовке issue упомянута команда CLI. ## Spec `hooks/tea-guard.sh` ## Steps to reproduce Все четыре случая пойманы на живой работе, тремя независимыми агентами. 1. Заголовок issue содержит слово — блокируется создание локальной issue: ```bash python3 skills/issue/scripts/issue_new.py --type bug \ --title "Warn that tea pulls create needs the repo checkout" \ --label comp/use --severity low ``` 2. Сообщение коммита цитирует сырой вызов — блокируется коммит той самой правки, которая эти вызовы и убирает: ```bash git add -A && git commit -F- <<'EOF' feat: close issues through a script Единственным способом сменить state был сырой вызов tea api -X PATCH ... repos/OWNER/REPO/issues/N EOF ``` 3. То же на однострочном сообщении: ```bash git commit -m "route it through tea api" ``` 4. Поиск по репозиторию, который про `tea` и написан: ```bash grep -rn " tea " docs/ grep -rn "tea api" skills/ echo tea ``` ## Expected Все четыре проходят. `python3`, `git`, `grep`, `echo` — это не CLI Gitea, никакой идентичности они не используют, `--login` им не нужен. Гвард сторожит запуски `tea`, а не тексты о них. Проверка должна смотреть на то, что реально исполняется — первое слово команды и первые слова после `;`, `&&`, `||`, `|`, `(` — а не на любое вхождение токена в строку. ## Actual Каждая из четырёх блокируется с exit 2: ``` PreToolUse:Bash hook error: [${CLAUDE_PLUGIN_ROOT}/hooks/tea-guard.sh]: tea-guard: BLOCKED — every `tea` command must include --login "$GITEA_LOGIN" (the guard substitutes the operator-pinned login). Run /tea:auth if no login is pinned. ``` Совет в сообщении невыполним: добавлять `--login` в `issue_new.py` или в `git commit` бессмысленно, а слой issue про логины вообще не знает. Обойти можно только переписав человеческий текст под детектор — положить сообщение коммита в файл и звать `git commit -F <файл>`, или выбросить слово из заголовка issue. Заголовок issue #38 не содержит слова отдельным токеном именно поэтому. Ложное срабатывание безопасно в смысле идентичности (хук блокирует, а не пропускает под чужим логином), но оно ломает офлайновые слои, которые к гварду отношения не имеют, диктует, какие слова можно писать в прозе, и диагностируется только чтением исходника хука: сообщение говорит про `--login`, а виновата прозаическая строка. ## Environment - `hooks/tea-guard.sh:88` (в других ветках `:92`) — `re.search(r'(^|[;&|(]|\s)tea(\s|$)', cmd)` применяется ко всей строке команды, без разбора на слова оболочки. Heredoc, кавычки и `-m "…"` для неё неотличимы от кода. ```python if not re.search(r'(^|[;&|(]|\s)tea(\s|$)', cmd): allow_passthrough() ``` - `hooks/tea-guard.sh:28,127` — модуль `shlex` уже импортирован и используется: `shlex.split(cmd)` дал бы список слов, и проверять надо только те, что стоят на позиции команды. - Задевает именно этот репозиторий: он про `tea`, и слово встречается в заголовках, телах issue и сообщениях коммитов постоянно. - macOS 25.5.0, `tea` 0.14.1, Python 3.14.5. Воспроизведено на ветках `main`, `feat/close-script`, `fix/no-store-for-label-payloads`. ## Acceptance criteria - [ ] `python3 …/issue_new.py --title "… tea …"` выполняется, а не блокируется - [ ] `git commit -m "…"` и `git commit -F-` с heredoc, где слово стоит отдельным токеном, проходят хук - [ ] `grep -rn " tea " docs/` и `echo tea` проходят хук - [ ] настоящий вызов `tea issues list` без `--login "$GITEA_LOGIN"` по-прежнему блокируется - [ ] настоящий вызов с плейсхолдером по-прежнему переписывается на закреплённый логин - [ ] составные команды разбираются посегментно и остаются под охраной: `cd x && tea issues list …`, `x | tea …`, `( tea … )`, подстановки - [ ] есть тест в `tests/`, который разводит по разным веткам строку, только упоминающую слово, и строку, которая его запускает — покрыты все четыре случая выше
claude added this to the Self-improvement milestone 2026-08-10 12:30:44 +00:00
claude added the
severity
medium
type
bug
comp/hooks
labels 2026-08-10 12:30:44 +00:00
naudachu added the comp/tea-guard label 2026-08-10 12:38:07 +00:00
claude changed reference from fix/no-store-for-label-payloads to fix/no-store-for-label-payloads 2026-08-10 12:51:23 +00:00
Sign in to join this conversation.