parse_grep: шаблон, -i -v -E -c -C N, а также -C2, -iv, -- и grep в начале. Неподдерживаемый флаг, второй аргумент, незакрытая кавычка или кривой regex — ошибка с подсказкой, а не молчаливый игнор.
Разбор через shlex.split, ничего не исполняется: $(rm -rf /) — просто текст шаблона.
Без -E шаблон работает как в grep (BRE): + ? | ( ) { } — буквальные символы.
run: модуль regex с таймаутом на строку и общим бюджетом 3 с. Не больше 500 строк вывода, группы с контекстом разделены --, как в grep.
to_command показывает пользователю, что именно искалось.
Журналlog_queries (L-6): кто, по какому контейнеру, что искал, сколько строк получил.
Ботapp/bot/routers/logs.py: выбор контейнера (L-1); хвост 50/200 строк или 5 мин/1 ч/24 ч (L-2); «🔎 Свой grep» по последним 24 ч (L-3); длинный результат — файлом .log (L-5). «🤖 Спросить агента» — заглушка до #18.
Логи Docker: не больше 50 000 строк и 5 МБ, при обрезке сохраняются новейшие.
Попутный фикс
В шагах ввода коммита (имя файла, папки, содержимое, сообщение) кнопки меню и /menu, /help проглатывались как ввод: «🩺 Статус» становился именем файла. Общий фильтр free_input в app/bot/menu.py применён ко всем шагам; регрессионный тест — в test_commit_edit.py.
Closes #16
## Что сделано
- **grep-движок** `app/logs/grep.py` (ARCHITECTURE §2.7):
- `parse_grep`: шаблон, `-i -v -E -c -C N`, а также `-C2`, `-iv`, `--` и `grep` в начале. Неподдерживаемый флаг, второй аргумент, незакрытая кавычка или кривой regex — ошибка с подсказкой, а не молчаливый игнор.
- Разбор через `shlex.split`, ничего не исполняется: `$(rm -rf /)` — просто текст шаблона.
- Без `-E` шаблон работает как в grep (BRE): `+ ? | ( ) { }` — буквальные символы.
- `run`: модуль `regex` с таймаутом на строку и общим бюджетом 3 с. Не больше 500 строк вывода, группы с контекстом разделены `--`, как в grep.
- `to_command` показывает пользователю, что именно искалось.
- **Журнал** `log_queries` (L-6): кто, по какому контейнеру, что искал, сколько строк получил.
- **Бот** `app/bot/routers/logs.py`: выбор контейнера (L-1); хвост 50/200 строк или 5 мин/1 ч/24 ч (L-2); «🔎 Свой grep» по последним 24 ч (L-3); длинный результат — файлом `.log` (L-5). «🤖 Спросить агента» — заглушка до #18.
- **Логи Docker**: не больше 50 000 строк и 5 МБ, при обрезке сохраняются новейшие.
## Попутный фикс
В шагах ввода коммита (имя файла, папки, содержимое, сообщение) кнопки меню и `/menu`, `/help` проглатывались как ввод: «🩺 Статус» становился именем файла. Общий фильтр `free_input` в `app/bot/menu.py` применён ко всем шагам; регрессионный тест — в `test_commit_edit.py`.
## Как проверено
- 222 теста (44 новых), покрытие 92%, ruff, mypy strict.
- ReDoS: `(a+)+$` модуль `regex` оптимизирует сам, `(a|aa)+$` по-настоящему взрывается — строки пропускаются по таймауту, поиск укладывается в бюджет.
- Вход 100 000 строк обрабатывается полностью.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
- app/logs/grep.py: подмножество grep (шаблон, -i -v -E -c -C N), разбор
shlex без исполнения, BRE → regex, таймаут на строку и бюджет на поиск,
лимиты 200 символов / 500 строк вывода
- app/logs/journal.py: каждый поиск в log_queries (L-6)
- бот: выбор контейнера, хвост 50/200 строк или 5 мин/1 ч/24 ч, свой grep
по 24 ч, длинный результат — файлом .log (L-5)
- логи Docker: не больше 50 000 строк и 5 МБ, сохраняются новейшие
- fix: кнопки меню и /menu, /help больше не проглатываются шагами ввода
(имя файла, содержимое, сообщение коммита, grep) — фильтр free_input
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #16
Что сделано
app/logs/grep.py(ARCHITECTURE §2.7):parse_grep: шаблон,-i -v -E -c -C N, а также-C2,-iv,--иgrepв начале. Неподдерживаемый флаг, второй аргумент, незакрытая кавычка или кривой regex — ошибка с подсказкой, а не молчаливый игнор.shlex.split, ничего не исполняется:$(rm -rf /)— просто текст шаблона.-Eшаблон работает как в grep (BRE):+ ? | ( ) { }— буквальные символы.run: модульregexс таймаутом на строку и общим бюджетом 3 с. Не больше 500 строк вывода, группы с контекстом разделены--, как в grep.to_commandпоказывает пользователю, что именно искалось.log_queries(L-6): кто, по какому контейнеру, что искал, сколько строк получил.app/bot/routers/logs.py: выбор контейнера (L-1); хвост 50/200 строк или 5 мин/1 ч/24 ч (L-2); «🔎 Свой grep» по последним 24 ч (L-3); длинный результат — файлом.log(L-5). «🤖 Спросить агента» — заглушка до #18.Попутный фикс
В шагах ввода коммита (имя файла, папки, содержимое, сообщение) кнопки меню и
/menu,/helpпроглатывались как ввод: «🩺 Статус» становился именем файла. Общий фильтрfree_inputвapp/bot/menu.pyприменён ко всем шагам; регрессионный тест — вtest_commit_edit.py.Как проверено
(a+)+$модульregexоптимизирует сам,(a|aa)+$по-настоящему взрывается — строки пропускаются по таймауту, поиск укладывается в бюджет.🤖 Generated with Claude Code