docs: define verified regression recovery plan and executor prompt

This commit is contained in:
ik
2026-09-10 06:07:36 +07:00
parent 4f68d6b004
commit 98e7649f9d
4 changed files with 146 additions and 6 deletions
+2 -2
View File
@@ -6,7 +6,7 @@ RF4 Spotter — неофициальный сервис свежих точек
## Статус разработки
**Повторная приёмка 9 сентября 2026 (`9ae05ef`): к деплою пока не готов.** Найдены регрессии после последних исправлений: невалидный Caddyfile, несовместимость activity API с detail-страницами, поломка research cooldown CLI и незавершённые UI/SEO/защита интервалов. Python: **10 failed, 86 passed, 1 skipped**; Astro check/build и web unit проходят, но не покрывают эти сценарии. [Отчёт с доказательствами](docs/REGRESSION_AUDIT_2026-09-09.md), [план R01R15](docs/ROADMAP.md#повторная-приёмка-9-сентября-2026). Следующие задачи — R01 и R02. До R05 не запускать текущий production bootstrap: он наследует реальные источники и публичные порты. Ниже описаны реализованные возможности; прежние успешные проверки не означают приёмку текущей ревизии.
**Проверка 10 сентября 2026 (`4f68d6b`): к деплою пока не готов.** Python: **107 passed, 1 skipped**; Astro check/build, web unit и Caddy adapt проходят. Исправлены синтаксис Caddy и потребители activity envelope, но остаются цикл readiness/scheduler, неатомарный cooldown, ошибки пагинации/фильтров и другие недоработки. [Актуальный план A01–A13](docs/RECOVERY_PLAN_2026-09-10.md), [промпт исполнителю](docs/RECOVERY_PROMPT.md). Начинать с A01, затем A02. Bootstrap больше не запускает реальные парсеры, но требует обновления проверки миграции и изолированной proxy/scheduler-приёмки. Ниже описаны реализованные возможности, а не гарантия приёмки текущей ревизии.
Web Docker-образ устанавливает зависимости через `npm ci` по lock-файлу и удаляет devDependencies после сборки. Локальные `.env` исключены из web build context.
@@ -20,7 +20,7 @@ Web Docker-образ устанавливает зависимости чере
Идёт исправление аудита: актуальные изменения и ограничения перечислены в [AUDIT_FIXES.md](docs/AUDIT_FIXES.md). Production Compose включает community scheduler; страницы rules/privacy реализованы. Для запуска остаются сервер, DNS/TLS, секреты, внешний backup и контакты. Шкала 72 часов использует полную выборку по времени поступления; одинаковые поля разных источников больше не считаются доказательством одного события. Фоновая публикация обновляет кэш API в пределах TTL, не мгновенно.
Предыдущий полный аудит 8 сентября: [отчёт](docs/PROJECT_AUDIT_2026-09-08.md). T01/T02 исправили маршруты формы и конфликт admin-аутентификации; `sh deploy/test-proxy-routing.sh` проверял Astro redirects, API, Basic/Bearer и отказы на прежней ревизии. На текущей ревизии повторный запуск блокирует R01. Подключение scheduler к исходящей сети добавлено, но интеграционная приёмка T03 ещё нужна. Актуальная последовательность работ находится в [плане повторной приёмки](docs/ROADMAP.md#повторная-приёмка-9-сентября-2026).
Предыдущий полный аудит 8 сентября: [отчёт](docs/PROJECT_AUDIT_2026-09-08.md). T01/T02 исправили маршруты формы и конфликт admin-аутентификации; `sh deploy/test-proxy-routing.sh` проверял Astro redirects, API, Basic/Bearer и отказы на прежней ревизии. Синтаксис Caddy теперь исправен. Подключение scheduler к исходящей сети добавлено; актуальная интеграционная приёмка входит в [план A01A13](docs/RECOVERY_PLAN_2026-09-10.md).
На ширинах 320, 390, 768 и 1280 px ранее проверено отсутствие горизонтального переполнения основных страниц. Это не полная визуальная приёмка: аудит обнаружил неверную desktop-компоновку фильтров; наполненные карточки, длинные названия, клавиатура и zoom остаются отдельной задачей.
+107
View File
@@ -0,0 +1,107 @@
# План устранения регрессий — 10 сентября 2026
База проверки: `4f68d6b`. Приоритет выше прежних R/T/D/U/S-пакетов. Они сохраняют контекст требований, но не образуют параллельную очередь. Промпт исполнителю: [RECOVERY_PROMPT.md](RECOVERY_PROMPT.md).
## Исходное состояние
Проверено: 107 Python-тестов проходят, 1 пропущен; Astro check/build, web unit и Caddy adapt проходят. Это не полная приёмка: проверки не покрывают обнаруженные ниже сценарии. Несовместимость activity envelope исправлена у четырёх потребителей по коду; история site cooldown теперь включает disabled endpoint. Не повторять эти изменения без нового воспроизведения.
`REGRESSION_FIXES_REPORT.md` устарел, содержит противоречивые статусы. Новые задачи ниже пока не выполнены. Источники в сеть для этой проверки не опрашивались.
## Порядок и критерии приёмки
### A01 · P0 · Убрать зависимость восстановления импорта от его свежести (R12)
- [ ] Разделить готовность API обслуживать запросы и здоровье импорта. Старые/failed/running импорты не должны мешать запуску scheduler, способного восстановить сбор.
- [ ] Сохранить отдельную тревогу по каждому enabled источнику/площадке с учётом ротации, backoff, последнего успеха и зависших попыток. Разбирать JSON мониторинга, а не искать любое `status:ready`.
- [ ] Приёмка: запуск на пустой БД, перезапуск после простоя более часа, failed/stalled источники и исправные DB/MinIO; scheduler стартует, деградация сбора заметна. Не обходить проблему безусловно зелёным `/ready`.
Основание: `readiness.py` возвращает false для stale импорта, а production scheduler зависит от `api: service_healthy`. Stale-сценарий воспроизведён на SQLite; запуск стека после простоя ещё проверить.
### A02 · P1 · Гарантировать общий интервал парсинга (R03/R04)
- [ ] Атомарная операция check-and-reserve: один lock на чтение/проверку/запись; не обнулять файл до блокировки, flush до unlock. Безопасное поведение при повреждении/недоступности state и миграция старых ключей.
- [ ] Один ключ площадки для её доменов/endpoint; отключение источника не удаляет историю cooldown. Production CLI, scheduler и исследовательские команды не должны обходить общий лимит: выбрать общий authority либо запретить независимый сетевой research-путь для production.
- [ ] Приёмка: два конкурентных процесса — максимум одна разрешённая попытка; неудачный HTTP расходует интервал; disabled/re-enabled, старый state, повреждение, перезапуск. Все тесты без внешних запросов.
Основание: `_write_state` открывает `w` до flock, check/reserve разделены, ошибки чтения превращаются в пустую историю.
### A03 · P1 · Проверять каждый сетевой переход до I/O (R11)
- [ ] Валидировать scheme/host/port исходного URL и каждого redirect до обращения; ограничить переходы, время и размер ответа. Согласовать нормализацию с A02.
- [ ] Приёмка: запрещённые initial/redirect URL не вызывают transport; цепочки redirect и ответы больше лимита проверены на fixtures. Не считать проверку конечного response.url защитой до запроса.
### A04 · P1 · Восстановить фильтры и пагинацию (R08/R09/R02)
- [ ] Связные label/select в сетке; period/sort доступны mobile с JS и без JS, selected корректен для 6/12/24/72.
- [ ] Выбрать понятную модель: серверные страницы с next/previous либо настоящее накопление. Не изображать накопление пустым массивом нового SSR-запроса. Заменять offset через set, не добавлять дубли.
- [ ] Завершить навигацию records/catalogs, сохранение фильтров, честные счётчики и поведение недопустимого/слишком большого offset.
- [ ] Приёмка: 45+ записей — достижимы все три страницы без цикла, повторов и потерь; назад/вперёд и смена фильтра. Desktop/mobile/no-JS/keyboard, пустая выдача и длинные названия; SSR всех четырёх activity detail-потребителей.
Основание: `offset=20&offset=20` остаётся второй страницей; mobile CSS скрывает поля внутри нового details; selected исправлен не для всех периодов.
### A05 · P1 · Сохранить заявку при отказах формы (R10)
- [ ] Восстанавливать черновик и фокус для create_error/rate_limited/server_error/timeout; выдерживать недоступность sessionStorage. Не заявлять о восстановлении file input.
- [ ] Завершить обработку multipart/413/429/timeout и безопасный повтор после неизвестного результата создания; отдельный retry изображения не создаёт второй улов.
- [ ] Приёмка: ошибки до создания и после сохранения, double submit, timeout, повторная загрузка; данные не теряются, дубли не создаются. Уже добавленную обработку TimeoutError сохранить.
### A06 · P1 · Правильно определить клиента через production proxy (R13)
- [ ] Определить доверенные peer/цепочку Caddy → Astro → API, согласовать настройки Uvicorn и CIDR окружения. Не доверять всем Docker-сетям или любому XFF без обоснования; валидировать получаемый адрес.
- [ ] Приёмка: два клиента имеют независимые лимиты через реальную proxy-цепочку; поддельный XFF недоверенного входа не меняет bucket; прямой доступ и отсутствующие заголовки имеют явную политику.
Основание: production defaults доверяют только loopback, тогда как peer Astro находится в Docker-сети. Проверка helper на loopback не заменяет проверку цепочки.
### A07 · P1 · Согласовать фильтры сигналов, время и оценки (R06/R15)
- [ ] Убрать раннее исключение рыбы без external ID там, где допустим подтверждённый fallback; единые правила alias/name и точная review_note. Не вводить нечёткое автоматическое сопоставление.
- [ ] Определить поведение mapped/unmapped неполных сигналов при slug-фильтрах. Источник и пометки неполноты обязательны.
- [ ] Адресная оценка точки/рыбы вместо top-100; явное поведение для нескольких видов на точке. Проверить confidence для 0/1/2 игроков и убрать недоказуемые обещания защиты от накрутки.
- [ ] Сохранить различие неизвестного времени улова и публикации/получения. Приёмка: fixtures с отсутствующим ID, неизвестным временем, анонимными игроками и несколькими рыбами одной точки.
### A08 · P1 · Завершить HTTP/SEO-контракт ошибок (R07/S03)
- [ ] Согласовать status/noindex/Cache-Control/Retry-After/JSON-LD для главной и detail-страниц. Успешный справочник плюс сбой activity не должен оставлять индексируемую страницу ошибки.
- [ ] Проверить единый origin, canonical, trailing slash и пагинацию; не считать одно `trailingSlash: never` выполнением всего S03.
- [ ] Приёмка: 200 populated/empty, 404, 422, 503; на ошибке нет вводящего в заблуждение Dataset/CollectionPage, URL соответствуют выбранной политике.
### A09 · P2 · Вернуть автономность CLI (R14)
- [ ] Использовать статический registry при argparse, enabled выбирать в рабочем пути команды через переданную сессию.
- [ ] Приёмка: `python -m app.cli --help` и help подкоманд работают без БД; реальные команды сохраняют проверки enabled и общего cooldown.
Основание: CLI всё ещё вызывает `configured_sources()` для choices; падение help без БД воспроизведено.
### A10 · P1 · Починить bootstrap и приёмку миграций (R05)
- [ ] Заменить устаревшее ожидание `0013` проверкой актуального Alembic head; проверить upgrade с прежней ревизии и чистую БД.
- [ ] Изолированные loopback-порты/локальные домены, fixture-источники и запрет внешнего egress. Вернуть проверку Caddy/scheduler безопасно, не просто добавить сервисы production.
- [ ] Приёмка: Caddy adapt, реальные 413 и маршруты; форма → модерация → публикация через proxy, Basic/Bearer, старый импорт после рестарта. Не трогать рабочие volumes.
Основание: head теперь `48094a7d1b92`, bootstrap ожидает `0013`. Опасный запуск реальных источников убран, но сквозная приёмка исключённых сервисов отсутствует.
### A11 · P2 · Сделать CI и зависимости воспроизводимыми (T08)
- [ ] Использовать реальный инструмент аудита зависимостей с явной политикой отказов, без `pip audit ... || true`.
- [ ] Согласовать Python-версию генерации locks, CI и Docker; образы тоже устанавливают закреплённые зависимости. Проверить, что последующий `pip install -e .` не нарушает pins.
- [ ] Приёмка: clean install/build; audit действительно запускается и не скрывает технические ошибки; web unit и новые адресные regression tests запускаются в CI. Не выполнять несвязанный массовый upgrade.
### A12 · P2 · Завершить историю изменений импорта (D09)
- [ ] Хранить значимые версии/изменённые значения с provenance, а не только тип события. Неизменённый повтор не создаёт ложную редакцию. Определить срок хранения, удаление и права доступа.
- [ ] Приёмка: create → unchanged → changed, частичный сбой/rollback и повтор; прежняя версия восстанавливается из истории, источники не смешиваются. Проверить FK/индексы/миграцию.
### A13 · Приёмка и документация
- [ ] Актуализировать REGRESSION_FIXES_REPORT: по одному статусу на ID, никаких pending-коммитов и взаимоисключающих разделов; связать R с A. README и ROADMAP отражают факты.
- [ ] Полный Python suite и web check/build/unit; объяснить каждый skip. Одна общая наполненная SSR/браузерная матрица и один изолированный production acceptance после адресных проверок.
- [ ] Для каждого A — коммит, команды/результаты, остаточные риски. Только выполненные критерии дают `[x]`. Зелёные старые тесты не заменяют новый regression case.
## Организация работы
Порядок: A01 → A02 → A03 → A04 → A05 → A06 → A07 → A08 → A09 → A10 → A11 → A12 → A13. Адресные unit/fixture-проверки выполнять по ходу, Docker объединять по инфраструктурным пакетам. Если обнаружена новая опасная регрессия, сначала воспроизвести и добавить в этот план с приоритетом.
Ограничения: сохранять Astro/FastAPI/PostgreSQL; не удалять чужие изменения, данные и volumes; не менять стек и не ослаблять тесты ради зелёного результата. Сетевой парсинг не чаще раза за 30 минут на площадку по всем путям запуска, включая неудачные попытки. Для данного пакета реальные источники не нужны.
После A13: сверка старого backlog по доказательствам, затем каталог/detail-очередь D05/S02, визуальная идентичность и компоненты V/U, постоянный SEO-контент и performance S, эксплуатационные T. Реальный деплой и внешние интеграции — отдельная стадия, не подразумеваемое разрешение этого плана.
+33
View File
@@ -0,0 +1,33 @@
# Промпт исполнителю плана исправлений
Скопируйте текст ниже в задачу нейросети, имеющей доступ к репозиторию.
```text
Работай в репозитории RF4 Spotter. Реализуй план docs/RECOVERY_PLAN_2026-09-10.md, а не только предложи изменения.
Сначала прочитай полностью применимые AGENTS.md, RECOVERY_PLAN_2026-09-10.md, ROADMAP.md, REGRESSION_AUDIT_2026-09-09.md, REGRESSION_FIXES_REPORT.md и README.md. Проверь git status и актуальную ревизию. План A01–A13 имеет приоритет над прежней очередью R/T/D/U/S. Старый fixes report противоречив: не принимай отметку «исправлено» за доказательство.
Начни с A01. Затем выполняй A02–A13 по порядку. Для каждого пункта:
1. Подтверди дефект на текущем коде. Если уже исправлен, предъяви проверку и не переписывай работающий код.
2. Найди первопричину и все связанные потребители, конфигурации, миграции и контракты.
3. Добавь небольшой regression case, воспроизводящий дефект до исправления; для требований безопасности проверь и отрицательный сценарий.
4. Исправь первопричину и проверь критерии приёмки из плана, включая соседние сценарии.
5. Обнови статус в плане, ROADMAP/README при изменении поведения и fixes report. Закрывай пункт только при выполнении всех критериев; частичное выполнение оставляй открытым с остатком.
6. Сделай отдельный осмысленный коммит только своих относящихся к пункту изменений. Не коммить чужие файлы, секреты или IDE-настройки.
Обязательные ограничения:
- Сохраняй Astro + FastAPI + PostgreSQL; никаких Next.js/Vinext, смены стека, несвязанных рефакторингов и массовых обновлений зависимостей.
- Сохраняй чужую работу. Не удаляй данные/volumes, не сбрасывай git и cooldown. Не выполняй деплой, push или внешние публикации без отдельного поручения.
- Все тесты парсеров — fixtures/mock transport, без реального scraping. Интервал источников минимум 30 минут на площадку суммарно по endpoint, процессам и способам запуска; ошибки тоже расходуют интервал.
- Источник каждой записи и всех составляющих агрегата обязателен. Неполные данные публикуются с явной пометкой, неизвестное время не подменяется известным.
- Не ослабляй assertions, не отключай проверки, не скрывай ошибки через || true или успешные пустые ответы. Не устраняй цикл readiness безусловно зелёным healthcheck: оставь достоверные отдельные сигналы отказов.
- Сборка Astro не доказывает корректность runtime JSON. Проверь все API-потребители и SSR, данные/пустоту/ошибку, три страницы пагинации и сохранение фильтров.
- UI проверь desktop/mobile, с JS и без него, клавиатурой, zoom и длинными названиями. Для ошибок согласуй HTTP, noindex, cache и structured data.
- Proxy trust и rate limit проверяй по реальной цепочке Caddy → Astro → API, не только unit-тестом helper.
- Docker запускай для необходимых инфраструктурных проверок и общей изолированной приёмки; не перезапускай весь стек после каждой правки.
- Не приписывай себе непроведённые проверки. Указывай точные команды, результаты, skip и ограничения среды. Если проверка заблокирована, пункт не считается принятым.
Не останавливайся на новом плане: начни реализацию A01 и продолжай по согласованному порядку, пока можешь безопасно работать. Если нужны новые полномочия или существенный выбор владельца, объясни конкретный блокер и спроси, не додумывай разрешение.
После каждого пакета кратко сообщай: причина → исправление → доказательство проверки → коммит → остаток → следующий пункт. В конце сверь все A01–A13 с критериями, а не только с зелёным тестовым прогоном.
```
+4 -4
View File
@@ -1,10 +1,10 @@
# План работ RF4 Spotter
Приоритет: [повторный аудит 9 сентября 2026](REGRESSION_AUDIT_2026-09-09.md) после сторонних исправлений. Пакет R01–R15 ниже имеет приоритет над [аудитом 8 сентября](PROJECT_AUDIT_2026-09-08.md) и историческими чекбоксами; [AUDIT_FIXES.md](AUDIT_FIXES.md) сохраняет историю исправлений.
Приоритет: [план восстановления A01–A13 от 10 сентября](RECOVERY_PLAN_2026-09-10.md), [промпт исполнителю](RECOVERY_PROMPT.md). Он заменяет очередь R01–R15 после повторной проверки исправлений. Предыдущие аудиты и [AUDIT_FIXES.md](AUDIT_FIXES.md) сохраняют контекст и историю.
Этот файл — рабочий источник правды по развитию проекта. После завершения задачи её чекбокс меняется с `[ ]` на `[x]`, рядом добавляется ссылка на коммит или короткое подтверждение проверки. Новые задачи добавляются в соответствующий этап, а не хранятся только в переписке.
Последняя сверка изменений кода и production-конфигурации: 9 сентября 2026 года (`c6fdc96..9ae05ef`). Python: 10 failed / 86 passed / 1 skipped; Astro check/build и web unit — успешно; Caddy adapt — ошибка. Визуальная приёмка обновлённого UI ещё не выполнена.
Последняя сверка: 10 сентября 2026 (`4f68d6b`). Python: 107 passed / 1 skipped; Astro check/build, web unit и Caddy adapt проходят. При этом остаются функциональные регрессии; зелёные проверки не означают готовность к деплою. Полная визуальная/production-приёмка ещё не выполнена.
Обозначения:
@@ -180,11 +180,11 @@
## Ближайший рабочий пакет
Production-контур требует исправлений до запуска. Следующая задача — **R01**, затем **R02**. Текущая сборка не считается принятой по результатам проверок прежних коммитов. Старые T/D/U/V/S сохраняются как тематический backlog, а не параллельная очередь дублирующих исправлений.
Следующая задача — **A01: цикл readiness/scheduler**, затем A02: атомарный общий cooldown. Чекбоксы и критерии текущей очереди ведутся в [RECOVERY_PLAN_2026-09-10.md](RECOVERY_PLAN_2026-09-10.md); не дублировать их статусы здесь. После A13 сверить прежние R/T/D/U/V/S по доказательствам.
### Повторная приёмка 9 сентября 2026
Доказательства и критерии приёмки: [повторный аудит](REGRESSION_AUDIT_2026-09-09.md). В этом проходе изменена только документация, исправления ниже ещё не выполнены.
Исторический пакет: [повторный аудит](REGRESSION_AUDIT_2026-09-09.md). Часть изменений уже внесена, но полная приёмка перечисленных требований не завершена. Текущие остатки и новые регрессии учтены в A01–A13; этот список не задаёт следующий шаг.
- [ ] R01 (P0, T05): исправить невалидный Caddyfile, проверить adapt, 413 и маршруты.
- [ ] R02 (P0, U03/D08): согласовать activity envelope со всеми страницами; SSR populated/empty и API regression tests.