[Fable 5][P3] scrape_cadastre: перманентный не-WAF фейл не инкрементит targets_failed → job вечно 'running'; cleanup-таска не в beat #1236

Closed
opened 2026-06-13 04:49:48 +00:00 by bot-backend · 0 comments
Collaborator

Из армейского ревью Claude Fable 5 (2026-06-11)

Confirmed by 2/2 адверсариальных верификатора, severity P3 (data-integrity), confidence 0.7.

Файл

backend/app/workers/tasks/scrape_cadastre.py:269

Evidence (цитата кода)

_update_job(
    db,
    job_id,
    last_error=f"{type(e).__name__}: {e}"[:500],
    heartbeat=True,
)

Why bug

Generic except-ветка bulk_harvest_quarter_task пишет только last_error — без targets_failed_inc (в отличие от WAF-ветки). После исчерпания autoretry (max_retries=3) квартал теряется из учёта: done+failed никогда не достигает targets_total → _maybe_finish_job не срабатывает → cadastre_jobs застревает в 'running' с протухшим heartbeat. Компенсирующая cleanup_cadastre_zombies (docstring: «Запускается через beat») ОТСУТСТВУЕТ в beat_schedule.py и не вызывается ниоткуда (grep по репо пуст) — job не переводится даже в 'paused'.

Suggested fix

В generic except при self.request.retries >= max_retries добавлять targets_failed_inc=1 + вызывать _maybe_finish_job; зарегистрировать tasks.cadastre.cleanup_zombies в beat_schedule.py.

Verify notes

  • [real/P3] Трасса: не-WAF ошибка (httpx.ConnectError ⊂ autoretry_for=(Exception,)) → все 4 попытки в except пишут лишь last_error+heartbeat, без targets_failed_inc → после max_retries=3 FAILURE, done+failed<total → _maybe_finish_job (только success-path) не закроет job → вечный 'running', stale heartbeat. cleanup_cadastre_zombies нигде не вызывается: в beat_schedule.py нет 'cadastre'. P3: данные не теряются, новые job не блокируются, есть ручной cancel/resume.
  • [real/P3] Защиты нет. Generic except (261-282) пишет только last_error+heartbeat — без targets_failed_inc и _maybe_finish_job, даже на финальной autoretry-попытке (нет gate по retries, нет on_failure). beat_schedule.py: «cadastre» — 0 вхождений; nspd-geo-zombie-cleanup чистит только nspd_geo_jobs; TASK_MAP и lifecycle.py без cadastre. API зомби не реапит, resume требует paused/failed → stuck-'running' не возобновить. P3: admin-фича, данные не теряются, workaround cancel+новый job.

Provenance

  • Finders: workers
  • Confidence: 0.7
  • Originally batched at: main@d796027
## Из армейского ревью Claude Fable 5 (2026-06-11) Confirmed by 2/2 адверсариальных верификатора, severity **P3** (data-integrity), confidence 0.7. ## Файл [`backend/app/workers/tasks/scrape_cadastre.py:269`](backend/app/workers/tasks/scrape_cadastre.py:269) ## Evidence (цитата кода) ``` _update_job( db, job_id, last_error=f"{type(e).__name__}: {e}"[:500], heartbeat=True, ) ``` ## Why bug Generic except-ветка bulk_harvest_quarter_task пишет только last_error — без targets_failed_inc (в отличие от WAF-ветки). После исчерпания autoretry (max_retries=3) квартал теряется из учёта: done+failed никогда не достигает targets_total → _maybe_finish_job не срабатывает → cadastre_jobs застревает в 'running' с протухшим heartbeat. Компенсирующая cleanup_cadastre_zombies (docstring: «Запускается через beat») ОТСУТСТВУЕТ в beat_schedule.py и не вызывается ниоткуда (grep по репо пуст) — job не переводится даже в 'paused'. ## Suggested fix В generic except при self.request.retries >= max_retries добавлять targets_failed_inc=1 + вызывать _maybe_finish_job; зарегистрировать tasks.cadastre.cleanup_zombies в beat_schedule.py. ## Verify notes - [real/P3] Трасса: не-WAF ошибка (httpx.ConnectError ⊂ autoretry_for=(Exception,)) → все 4 попытки в except пишут лишь last_error+heartbeat, без targets_failed_inc → после max_retries=3 FAILURE, done+failed<total → _maybe_finish_job (только success-path) не закроет job → вечный 'running', stale heartbeat. cleanup_cadastre_zombies нигде не вызывается: в beat_schedule.py нет 'cadastre'. P3: данные не теряются, новые job не блокируются, есть ручной cancel/resume. - [real/P3] Защиты нет. Generic except (261-282) пишет только last_error+heartbeat — без targets_failed_inc и _maybe_finish_job, даже на финальной autoretry-попытке (нет gate по retries, нет on_failure). beat_schedule.py: «cadastre» — 0 вхождений; nspd-geo-zombie-cleanup чистит только nspd_geo_jobs; TASK_MAP и lifecycle.py без cadastre. API зомби не реапит, resume требует paused/failed → stuck-'running' не возобновить. P3: admin-фича, данные не теряются, workaround cancel+новый job. ## Provenance - Finders: `workers` - Confidence: 0.7 - Originally batched at: main@d796027
bot-backend added the
Fable 5 ревью
label 2026-06-13 04:49:48 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#1236
No description provided.