From a757556f9dc87879e34ea6b02307320739b749d0 Mon Sep 17 00:00:00 2001 From: testclient-admin Date: Sun, 30 Aug 2026 09:57:07 +0000 Subject: [PATCH 1/3] Level 0: security scanning for pull requests --- .gitea/workflows/security.yml | 46 ++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/.gitea/workflows/security.yml b/.gitea/workflows/security.yml index 02e06f7..24a5467 100644 --- a/.gitea/workflows/security.yml +++ b/.gitea/workflows/security.yml @@ -591,6 +591,8 @@ jobs: и прочее — для них есть свои агенты; дублирование только шумит. Тебе НЕЛЬЗЯ писать, править или исполнять код — только read/grep/glob/lsp. + Инструмента "list" НЕ существует — для просмотра содержимого + директорий используй glob (например "**/*"), а не list. Тебе дают путь к репозиторию, уже склонированному локально. В отличие от PR-ревью, у тебя нет дифа — смотри на весь проект. @@ -657,6 +659,8 @@ jobs: такой (это домен другого агента — auth). Не дублируй чужие домены. Тебе НЕЛЬЗЯ писать, править или исполнять код — только read/grep/glob/lsp. + Инструмента "list" НЕ существует — для просмотра содержимого + директорий используй glob (например "**/*"), а не list. Тебе дают путь к репозиторию, уже склонированному локально. Смотри на весь проект, не только на недавние изменения. @@ -727,6 +731,8 @@ jobs: пользовательского ввода. Не дублируй домены других агентов (auth, authz). Тебе НЕЛЬЗЯ писать, править или исполнять код — только read/grep/glob/lsp. + Инструмента "list" НЕ существует — для просмотра содержимого + директорий используй glob (например "**/*"), а не list. Тебе дают путь к репозиторию, уже склонированному локально. Смотри на весь проект, не только на недавние изменения. Учти: детерминированные сканеры (semgrep/gitleaks) уже гоняются на каждый PR — фокусируйся на том, что @@ -797,6 +803,8 @@ jobs: allowlist). Не дублируй домены других агентов. Тебе НЕЛЬЗЯ писать, править или исполнять код — только read/grep/glob/lsp. + Инструмента "list" НЕ существует — для просмотра содержимого + директорий используй glob (например "**/*"), а не list. Тебе дают путь к репозиторию, уже склонированному локально. Смотри на весь проект, не только на недавние изменения. @@ -866,6 +874,8 @@ jobs: криптографию, а не "нашёл строку похожую на ключ". Тебе НЕЛЬЗЯ писать, править или исполнять код — только read/grep/glob/lsp. + Инструмента "list" НЕ существует — для просмотра содержимого + директорий используй glob (например "**/*"), а не list. Тебе дают путь к репозиторию, уже склонированному локально. Смотри на весь проект. @@ -934,6 +944,8 @@ jobs: не будет действовать недобросовестно. Тебе НЕЛЬЗЯ писать, править или исполнять код — только read/grep/glob/lsp. + Инструмента "list" НЕ существует — для просмотра содержимого + директорий используй glob (например "**/*"), а не list. Тебе дают путь к репозиторию, уже склонированному локально. Смотри на весь проект. @@ -1008,6 +1020,8 @@ jobs: выводом, находка проходит без реальной проверки. Тебе НЕЛЬЗЯ писать, править или исполнять код — только read/grep/glob/lsp. + Инструмента "list" НЕ существует — для просмотра содержимого + директорий используй glob (например "**/*"), а не list. Как проверять: - Открой указанный файл и строки — действительно ли код выглядит так, как @@ -1053,11 +1067,20 @@ jobs: for domain in "${DOMAIN_ARR[@]}"; do echo "=== домен: $domain ===" set +e - ./opencode run --agent "audit-$domain" --format json \ + # timeout, не голый opencode: живьём поймали модель, + # зациклившуюся на несуществующем инструменте "list" + # (retry без самокоррекции) — без внешней границы + # такой домен держит job часами вместо ожидаемых + # единиц минут на пустом репозитории. 480с — щедрый + # запас над нормой (~1 минута на домен), не жёсткий + # лимит по содержанию: таймаут просто списывает + # домен как "без находок", а не блокирует остальные. + timeout 480 ./opencode run --agent "audit-$domain" --format json \ "Проведи аудит своего домена по всему репозиторию. Репозиторий уже склонирован в текущей директории (рабочая копия main)." \ > "/tmp/audit-results/$domain.jsonl" 2>"/tmp/audit-results/$domain.log" CODE=$? set -e + [ "$CODE" = "124" ] && echo " ПРЕВЫШЕН ТАЙМАУТ (480с) — домен $domain засчитан как без находок" echo " код завершения: $CODE" echo " --- stderr ---" tail -30 "/tmp/audit-results/$domain.log" || true @@ -1151,11 +1174,22 @@ jobs: payload_text = json.dumps(cand, ensure_ascii=False) with open(f"/tmp/audit-results/verify-{i}.jsonl", "w") as out, \ open(f"/tmp/audit-results/verify-{i}.log", "w") as errlog: - subprocess.run( - ["./opencode", "run", "--agent", "audit-verifier", "--format", "json", - f"Проверь эту находку (JSON), репозиторий уже склонирован рядом: {payload_text}"], - stdout=out, stderr=errlog, - ) + # timeout: та же причина, что и у доменных + # агентов (см. комментарий там) — верификатор + # читает те же read/grep/glob/lsp и рискует + # той же ловушкой на несуществующем "list". + timed_out = False + try: + subprocess.run( + ["./opencode", "run", "--agent", "audit-verifier", "--format", "json", + f"Проверь эту находку (JSON), репозиторий уже склонирован рядом: {payload_text}"], + stdout=out, stderr=errlog, timeout=480, + ) + except subprocess.TimeoutExpired: + timed_out = True + if timed_out: + print(f" candidate {i} ({cand.get('_domain')}): ПРЕВЫШЕН ТАЙМАУТ верификатора (480с) — находка отброшена, не подтверждена") + continue verdict_text = last_text(f"/tmp/audit-results/verify-{i}.jsonl") try: verdict = json.loads(verdict_text) if verdict_text else {} -- 2.54.0 From 31ccd9fe46c211db4bb03baf24bbb3852b29a2be Mon Sep 17 00:00:00 2001 From: testclient-admin Date: Sun, 30 Aug 2026 09:57:07 +0000 Subject: [PATCH 2/3] Level 0: security scanning for pull requests -- 2.54.0 From 2610530cd8f385cc3bc3e3ac19961daf1fd17a7f Mon Sep 17 00:00:00 2001 From: testclient-admin Date: Sun, 30 Aug 2026 09:57:08 +0000 Subject: [PATCH 3/3] Level 0: security scanning for pull requests -- 2.54.0