- V2 Priority: system instructions override user message, но LLM может
отличать легитимный код от вредоносного
- Тест: legit urllib3=safe/LOW, poisoned backdoor=malicious/CRITICAL
- Hard Gate убран — был слишком агрессивен (flag любой ctypes.CDLL)
- constants.py: новый LLM_ANALYSIS_SYSTEM_PROMPT с защитой от injection
- Явное разделение: message = CLAIMS (untrusted), code = FACTS
- Инструкция игнорировать user message при конфликте с code/rule
- examples/test-prompt-variants.py: тест 3 вариантов промпта
- Результат: baseline=safe (обманут), V2/V3=malicious (устояли)
- examples/test-prompt-poisoning.py: 4 вектора атаки с оригинальным промптом
- Добавлен статус {"status": "analyzing"} в finding.report на время LLM-анализа
- Кнопка рескана (Retry) под LLM-отчётом в ручном режиме
- LLM-статистика на дашборде: analysed / pending
- Защита от двойного анализа через per-finding asyncio.Lock
- _llm_spinner.html — фрагмент спиннера для состояния analysing
- Удалён мёртвый код: constants, i18n, CSS, queries
- Фиксы: _env_int, индексы БД, UnicodeDecodeError, time.mktime и др.
- Шаблоны: shared includes (_status_badge, _pagination)
- AGENTS.md: workflow (lint, test, commit, rebuild)
Nexus присылает initiator в формате 'username/IP' (напр. admin/172.21.0.3).
Теперь initiator и source_ip правильно разделяются из этого поля.
Лог Webhook payload выводит распарсенные значения.
- constants.py: APP_VERSION, LLM_DEFAULT_TEMPERATURE, LLM_RESPONSE_FORMAT
- main.py: версия из APP_VERSION (вместо хардкод '0.1.0'×2)
- llm.py: temperature и response_format из constants
Всего: 85 тестов, ruff clean
- i18n.py: формальный русский (сканирования, панель управления, и т.д.)
- Все шаблоны: замена хардкод-строк на t(key, request.state.lang)
- dashboard_stats_fragment: добавлен request в контекст
- AGENTS.md: документация для разработчиков (архитектура, конвенции,
common tasks, testing, Docker, webhooks)
- README.md: добавлена AI-поме тка в конце
- README.en.md: полная английская версия документации
3.6 UI: убрать stat-minibar и heatmap с дашборда
3.2 AI disclaimer под каждым LLM-вердиктом
3.4 LLM_MAX_CONCURRENT_ANALYSES + Semaphore в llm.py
3.1 Scan.initiator + source_ip, webhook захватывает, UI показывает
- setup-nexus.sh: создание go-proxy (proxy.golang.org) и npm-proxy (registry.npmjs.org)
- nexus_client.py: extract_go_info() и extract_npm_info() для парсинга путей
Go: packages/github.com/gorilla/mux/@v/v1.8.0.zip → name=github.com/gorilla/mux ver=v1.8.0
npm: packages/lodash/-/lodash-4.17.21.tgz → name=lodash ver=4.17.21
- nexus_client.py: EXTRACTORS dict + extract_package_info() универсальный extractor
- webhooks.py: _detect_ecosystem() — определяет экосистему из asset.format
- harvester.py: использует extract_package_info() вместо extract_pypi_info()
- Всё в Docker-контейнере, на хосте ничего не ставится
- GuardDog поддерживает go и npm из коробки
- select status-filter: добавлен name="status" (htmx берёт name, не id)
- search input + status select: взаимные hx-include
(поиск включает статус, статус включает поиск)
Фильтр-бар вынесен из _scans_table.html / _packages_table.html
в scans_list.html / packages_list.html — вне htmx target.
htmx заменяет только таблицу, фильтр остаётся на месте.
- config.py: MAX_CONCURRENT_SCANS (default=4)
- harvester.py: глобальный _scan_semaphore оборачивает scan_package()
— при N одновременных сканах, (N+1)-й будет ждать освобождения слота
— download и SHA256 не лимитируются, только guarddog subprocess
- docker-compose.yml, .env.example: переменная добавлена
- constants.py: RELEVANT_WEBHOOK_ACTIONS теперь только UPDATED
(CREATED игнорируется, Nexs proxy шлёт UPDATED при обновл кэша)
- harvester.py: asyncio.Lock на каждый download_url
— при параллельных вебхуках только первый пройдёт, остальные skipped
— lock проверяется + DB re-check внутри критической секции
- tests: обновлены фикстуры (CREATED→UPDATED), добавлен тест ignores_created
- Возможности: новый пункт про LLM
- Архитектура: LLM API на диаграмме
- Переменные: все 8 новых env-переменных в таблице
- Новый раздел LLM-анализ: описание, примеры конфигурации
(OpenAI, Groq, Ollama), формат ответа
- API: добавить /findings/{id}/analyze, /export endpoints
- Структура: constants.py, queries.py, llm.py
При добавлении нового поля в модель (report в Finding) старое create_all
не добавляет колонку в существующую БД → 500 ошибка.
Теперь _migrate() проверяет PRAGMA table_info и добавляет
недостающие колонки через ALTER TABLE