diff --git a/openspec/changes/slice-0-skeleton/design.md b/openspec/changes/slice-0-skeleton/design.md index 89a6db6..7593bc7 100644 --- a/openspec/changes/slice-0-skeleton/design.md +++ b/openspec/changes/slice-0-skeleton/design.md @@ -147,3 +147,4 @@ D-7 и таймаут (с укороченными настройками). `Smb | 45 | 2026-10-04 | R-20: дедлайн = `min(reply_deadline, старт + SCAN_TIMEOUT_SECONDS)`, `старт` — момент записи файла в горячую папку (после получения слота); `on_request` не блокируется: валидирует, регистрирует `job_id` и запускает задачу задания (ack -> семафор -> обработка) | ожидание слота входит в `reply_deadline` через `min`; колбэк NATS должен возвращаться быстро (T11.4) | нет | | 46 | 2026-10-04 | Задача 5.3 (подробно — 15 решений в отчёте исполнителя): задание, получившее слот после `reply_deadline`, отвечает `TIMEOUT` без записи файла и чтения S3 (ack уже опубликован); ответ ИС, не являющийся JSON, перечитывается через `SCAN_POLL_SECONDS` и принимается, когда стал JSON или перестал меняться (на дедлайне — последний прочитанный; затем `INVALID_FORMAT`); дедупликация в двух структурах (`_active` не вытесняется, `_done` — LRU `DONE_CACHE_SIZE`); `SCHEMA_MISMATCH` не регистрирует `job_id`; `error.message` ≤ 4000 символов, суррогаты заменяются; `raw/` пишется с `application/json` (не-JSON — `application/octet-stream`); нормализатор вызывается через `to_thread`; `stop()` не публикует конверты отменённых заданий (D-2); сбой SMB-сессии виден через `healthy()` (listdir с теми же учётными данными), без флага; проба `hotfolder`: таймаут 2 с, кэш 5 с, одна проба за раз; NATS подключается в фоновой задаче lifespan, ошибка `connect`/`subscribe` -> `nats = down` до перезапуска; порядок остановки: отмена подключения -> `worker.stop()` -> drain NATS -> S3 -> SMB; `/healthcheck` всегда 200 | экономия ИС; недописанный ответ на шаре без атомарного rename; ограничения размера публикации | поздний результат отброшен; неподвижная ошибка NATS требует перезапуска пода; зависший `poll` по SMB (до 60 с) не прерывается дедлайном (T12.2) | | 47 | 2026-10-04 | Задача 5.4: общая обвязка тестов воркера — `api/tests/worker_helpers.py` и `api/tests/unit/conftest.py`; ответ ИС для освобождения одного слота пишет тест (не `process_once`); отсутствие утечки слотов проверяется поведением (повторный `start()`); отмена воркера во время `to_thread(hotfolder.put)` не прерывает запись в потоке (файл уже в ИС, конверта нет, D-2) | эмулятор ответил бы на все четыре файла сразу; образец arm-core | возможна повторная отправка в ИС после рестарта (OQ-15) | +| 48 | 2026-10-04 | Задача 6.1: интеграционный тест поднимает настоящий lifespan `create_app` и эмулятор в процессе теста против compose NATS/MinIO (tmp-каталог горячей папки); синтетический успешный ответ `ok_doc.json` строится по форме §11 `05-domain-rules.md`; сценарии 1–2 пропускаются без `../fixtures`, недоступная инфраструктура — падение; тест ждёт подписку шлюза по фоновой задаче `nats-connect`; `ResourceWarning` aiohttp о теле > 1 МиБ отфильтрован в одном модуле (загрузка скана 1,29 МБ) | контейнера `scan-emulator` ещё нет (R-7); fixtures не содержат успешных ответов (R-10) | интеграционный тест может забрать чужие запросы из общей queue group `scan-gateway` на общем NATS (T14.1) |