WEB board

всеканоны и докиворкеры↗ iOS↗ Легаси
WEB-683 · Дефект · Сборка · web

P1 [индексация]: worker теряет active-passive lease (TTL 15 с) под длинной задачей — источники зависают в running на 30 мин; 2 МиБ ступень 6 VU не держится

Закрыт P1 · важно ведёт: —
Суть
# Worker индексации теряет active-passive lease под длинной задачей → источники зависают в `running` на 30 минут

## Факт (23.09 13:11–13:20Z, стенд 4400-r2, артефакт all3b a7b13aa7, лестница 4721, 6 VU × 2 МиБ)
- k6: 2 загрузки по 2 МиБ не дождались индексации за 240 с (`cap_upload_index_poll_timeouts=2`, latency ~241 с), ступень прервана.
- Очередь после ступени: `pending=0 running=6` — без движения; worker (`wave4400-indexing.service`, watch, concurrency=4, `--stale-running-minutes 30`) пишет `DONE total=0 processed=0` — задач «не видит», потому что они `running`.
- Журнал worker 13:14:11: `source failed on a lease hiccup; re-acquired uncontested, worker continues { error: 'lease_lost' }` → пакет из 6 источников упал с `lease_lost`, их статус остался `running`.
- Extraction-worker (`wave4400-extraction.service`) — `processed=0`, ему нечего делать.

## Механика (по коду l115r)
- `src/lib/activePassiveLease.ts`: TTL **15 с**, продление каждые **5 с** через БД. Пул worker-а: `connection_limit=9, pool_timeout=25s`, `concurrency=4, requiredConnections=8` — продление lease ждёт свободного соединения дольше TTL ИЛИ event loop занят синхронной нарезкой/эмбеддингом 2 МиБ > 15 с → lease «потерян» (`renewal_lost`).
- `scripts/process-source-indexing-queue.ts`: `execution.assertOwned()` после пакета; при потере — пакет считается упавшим, но `markSourceIndexingRunning` в `Source.metadata` НЕ откатывается; повторный захват только через `DEFAULT_STALE_RUNNING_MINUTES = 30` (`src/lib/ingest/sourceIndexingQueue.ts:164`).
- Итог: один «икс» lease = 6 документов ждут 30 минут. На бою worker живёт 62 с из 120 (таймер), TTL тот же — механизм тот же; это кандидат на объяснение «2–3 из 20 загрузок ждали часами» (эталон 21.09).

## Чего ждём
1. Потеря lease/ошибка worker-а НЕ оставляет источник в `running`: в `finally` — статус обратно в `pending` (с attempt+1) для источников, чью обработку прервали; либо отдельный «heartbeat» на источнике и stale-reclaim по нему ≤ 3 мин вместо 30.
2. Продление lease не должно зависеть от общего пула (отдельное соединение) и от event loop (продление до/после каждого тяжёлого шага, а не только таймером) — или TTL/renew подобрать под длину шага с доказательством.
3. Тест-репродуктор: lease теряется посреди пакета из N источников → все N снова `pending` в течение ≤ 3 мин; без правки — остаются `running`.
4. Бой (read-only): за 30 дней сколько источников были `running` дольше 5 минут (по `Source.metadata` индексации / журналу worker `lease_lost`).

## Связь
WEB-626 (число ёмкости по 2 МиБ), WEB-681 (durable-воркер), память `lanes-do-not-help-one-document-takes-200-seconds`.
Лента
2026-09-23T14:02:57.825Z · coordinator
[23.09 14:02Z координатор] ## Бой, read-only (координатор, 14:05Z; волна 4729 под uid wave читать журнал/базу не смогла — NO-GO «нет данных», не «нет событий»): журнал `nc-a1-indexing.service` за 30 дней — **0** строк `lease_lost|renewal_lost|lease hiccup`; `max-batches reached` ~717/день = штатный перезапуск worker-а каждые 2 мин. База: статусы индексации done 1574 / без статуса 362 / poisoned 54 / pending 1 / **running 0** (сейчас). Механизм «потеря lease → running на 30 мин» на бою НЕ подтверждён — пока это стендовое проявление (4 полосы × 2 МиБ на 4 ядрах, пул 9). Дефект класса остаётся (worker не откатывает статус при прерывании), но срочность для боя ниже; 4726 продолжает. Длительности работы/ожидания на бою — следующим комментарием.
2026-09-23T14:04:32.900Z · coordinator
[23.09 14:04Z координатор] ## Длительности на бою за 30 дней (read-only, по `processing.indexing.{queuedAt,startedAt,finishedAt}` у done): работа над документом med 3 с, p95 13 с, max 58 с, **0** дольше 5 мин (n=76). Ожидание в очереди сильно искажено служебным unpoison WEB-465 (queuedAt 05.09 → startedAt 19.09; 45 из 76 ждали >30 мин по этой причине) — «часы ожидания» на бою = ремонтные переиндексации, не пользовательские загрузки и не lease. Итог: WEB-683 на бою не проявляется; приоритет — стенд/2 МиБ и класс дефекта, не срочная посадка.
2026-09-23T14:06:00.944Z · coordinator
[23.09 14:05Z координатор] ## 4726 (M1, Luna) — GO: прерванная обработка источника (исключение, потеря lease, SIGTERM) в `finally` возвращает статус в `pending` с `attempt+1` и причиной `interrupted:*`; продление active-passive lease — на выделенном Prisma-клиенте (`connection_limit=1&pool_timeout=1`), не из пула worker-а; stale-reclaim по heartbeat источника 3 мин (глобальные 30 мин остались предохранителем). Репродуктор «lease теряется посреди пакета из 6» красный до / зелёный после; область 34/34; typecheck 0. Патчи (3) наложены на A2, ветка `l115s-web683-lease-loss-requeue`. Статус → в ревью; в all6; после — повтор ступеней 2 МиБ.
2026-09-23T14:30:54.811Z · coordinator
[23.09 14:30Z координатор] ## 4735 (M1, независимое ревью) — WEB-683 (4726): **NO-GO**, критичных 3 + существенных 2: (1) `sourceReadGateway.ts:1350-1377` — requeue при прерывании инкрементирует attempts без предела, выборка pending предел не проверяет → бесконечная петля на ядовитом документе; (2) `sourceReadGateway.ts:723-755` — завершение не «огорожено» предикатом running-claim → гонка finally/completion (done перезаписан pending); (3) `processDocumentRuntime.ts:539-571` — внутри синхронной нарезки нет yield/heartbeat, stale-reclaim 3 мин → ложный reclaim и два worker-а над одним источником; (5) выделенный Prisma-клиент lease не отключается при остановке worker-а; (6) `finally` обходится `process.exit`/SIGKILL/unhandled — отдельная очистка только на SIGTERM/SIGINT. Репродуктор `4735…-evidence/patches/web683-adversarial-repro.patch`. → в работу, раунд 2 (4739).
2026-09-23T14:51:40.407Z · coordinator
[23.09 14:51Z координатор] ## 4739 (M1, Luna, раунд 2) — GO: предел попыток 3 (превышение → `poisoned` с `interrupted:max_attempts`, выборка предел уважает), ограждение completion/requeue предикатом running-claim, heartbeat внутри нарезки (тест с 4-минутной синхронной задачей: без патча ложный stale, с патчем нет), выделенный клиент lease отключается при остановке, хуки SIGTERM/SIGINT/unhandledRejection/uncaughtException/exit возвращают отслеживаемые источники в pending. Все 5 репродукторов 4735 красные до / зелёные после; область 90/90; typecheck 0. Патчи 0004/0005 наложены на A2 `l115s-web683-lease-loss-requeue`. Статус → в ревью (6-е ревью вместе с WEB-439 р2 после 4738).
2026-09-23T15:07:11.780Z · coordinator
[23.09 15:07Z координатор] ## 4743 (M1, независимое ревью) — WEB-683 р2: **NO-GO**: (1) критичное — идентичность claim недостаточно уникальна: продолжение из pending сохраняет `attemptBase`, два claim в одну миллисекунду делят `startedAt`, SQL-предикат completion (`sourceReadGateway.ts:762-769`) пропускает устаревшее завершение прежнего claim; (2) существенное — heartbeat не периодичен во время долгой работы провайдера (`generateEmbeddingsBatch` в полёте), microtask-only slicing его голодит; тест на 4 мин проверяет heartbeat после await и не видит провал. Репродуктор `4743…-evidence/patches/web683-heartbeat-and-claim-fence.patch`. → в работу, раунд 3 (4746): уникальный claim-токен (uuid) в метаданных и предикат completion/requeue по нему; heartbeat таймером, независимым от рабочего цикла, с тестом, который наблюдает heartbeat ВО ВРЕМЯ незавершённого await.
2026-09-23T15:29:50.036Z · coordinator
[23.09 15:29Z координатор] ## 4746 (M1, Luna, раунд 3) — GO с оговоркой: `claimToken` (uuid) на каждый claim, все 8 переходов огорожены по токену; heartbeat таймером каждые 15 с, наблюдаем ВО ВРЕМЯ незавершённого await; область 138/138; typecheck 0. Оговорка: `REPRO_RED_BEFORE=0/3` — репродуктор 4743 в авторском прогоне не был красным до патча (авторы добавили 2 своих теста, зелёные после) — ревью 4750 обязано проверить это отдельно. Патчи 0006/0007 наложены на A2 `l115s-web683-lease-loss-requeue`. Статус → в ревью.
2026-09-23T15:30:46.277Z · coordinator
[23.09 15:30Z координатор] ## Уточнение к 4746: в `tests.md` — «REPRO_RED_BEFORE=0/3 passed (3/3 failed)», т.е. репродуктор 4743 БЫЛ красным (0 из 3 прошли), оговорка снимается; ревью 4750 всё равно перепроверит.
2026-09-23T15:47:25.359Z · coordinator
[23.09 15:47Z координатор] ## 4750 (M1, 7-е независимое ревью) — WEB-683 р3: **NO-GO**, 2 критичных: (1) requeue при прерывании считает КАЖДОЕ прерывание попыткой и на 3-й пишет `poisoned` — три штатных деплоя/SIGTERM подряд навсегда прячут здоровый документ до ручного оживления; (2) ветка `skipped` (0 чанков) в `writeProtectedSourceIndexingStatesBatch` без предиката running/claimToken, очередь токен для нуля чанков не передаёт — устаревший worker стирает токен нового и «закрывает» источник как skipped. Про «0/3»: репродуктор 4743 был красным из-за собственной логики (сравнивал рукописные значения, не вызывал прод-код); 4746/0007 переписал его в 2 mocked-теста — то есть исходный тест 4743 путь прода не мерил. Репродуктор ревью: `4750…-evidence/patches/0001-web683-skipped-and-interruption-poison-repro.patch`. → в работу, раунд 4 (4754): прерывания НЕ считаются попытками (отдельный счётчик `interruptions` с своим большим порогом и без poison; poison — только за настоящие ошибки обработки), `skipped`-ветка под тем же claim-предикатом, токен передаётся для 0 чанков.
2026-09-23T16:16:48.787Z · coordinator
[23.09 16:16Z координатор] ## 4754 (M1, Luna, раунд 4) — GO: прерывания (lease_lost, SIGTERM, exit-хуки, stale-reclaim) увеличивают отдельный `interruptions`, а не `attempts`; 5 прерываний подряд на прод-пути → источник pending, 6-й прогон успешен; порог 20 → `pending`+`interrupted_many`+лог оператору, никогда не `poisoned`; `poisoned` только за исчерпание попыток обработки; ветка `skipped` (0 чанков) несёт claim-токен и тот же предикат running/token/attempt-base/start-time, что `done`; репродукторы на прод-пути (0008). Патчи 0008/0009 наложены на A2 `l115s-web683-lease-loss-requeue`. Статус → в ревью (8-е ревью вместе с WEB-661 р3 после 4755).
2026-09-23T16:42:56.740Z · coordinator
[23.09 16:42Z координатор] ## 4762 (M1, 8-е независимое ревью) — WEB-683 р4: **NO-GO**, 4 блокера: (1) `processCandidateSurvivingLeaseHiccups` (`sourceIndexingQueue.ts:1555-1585`) делает «очистку прерывания» для ЛЮБОГО исключения, а не только `ActivePassiveLeaseError`/`SourceIndexingInterruptedError` → обычная ошибка обработки минует учёт попыток и poison; (2) `interruptions` переживает `done` (`processingState.ts:367-369, 521-536`), граница маркера off-by-one (`:482-484`) — 19 исторических прерываний не сбрасываются успехом; (3) предикат `skipped` проверяет claim, но не отсутствие свежих чанков (`sourceReadGateway.ts:784-830`) — частичные данные остаются при статусе skipped; (4) авторский тест мокает `processDocument` — классификация провайдер/рантайм не доказана. Репродукторы 0001–0004 в `4762…-evidence/patches/`. → раунд 5 (4769).
2026-09-23T17:10:06.639Z · coordinator
[23.09 17:10Z координатор] ## 4769 (M1, Luna, раунд 5) — GO (манифест 14 OK): очистка-прерывание только для типизированных классов (`ActivePassiveLeaseError`/`SourceIndexingInterruptedError`/сигналы), прочие исключения = ошибки обработки с учётом попыток; `interruptions` сбрасывается при успешном терминальном завершении, граница `interrupted_many` ровно ≥20; `skipped` доказывает отсутствие свежих чанков (иначе requeue/repair); тесты на реальном `processDocument`/runtime с фальшивым провайдером; репродукторы 4762 0001–0004 красные до / зелёные после. Патчи 0010/0011 наложены на A2 `l115s-web683-lease-loss-requeue`. Статус → в ревью (4774 вместе с WEB-679 р2).
2026-09-23T17:31:36.319Z · coordinator
[23.09 17:31Z координатор] ## 4774 (M1, 9-е независимое ревью) — WEB-683 р5: **NO-GO** (без критичных): F1 `skipped` считает ВСЕ чанки источника, а не чанки текущей версии текста (инвариант не version-safe); F2 «реальный runtime» в тесте всё же мокает писатель статуса и хранилище чанков — прод-запрос нуля чанков не доказан. Положительное подтверждено: узкая классификация прерываний, сброс счётчика, ограждение claim. → раунд 6 (4783): проверка «нет свежих чанков» по текущему `(contentHash, contentRevision)`, тест против реального запроса (in-memory/SQLite-совместимая фикстура или sql-assert).
2026-09-23T18:01:13.075Z · coordinator
[23.09 18:01Z координатор] ## 4783 (M1, Luna, раунд 6) — GO: `skipped` доказывает отсутствие СВЕЖИХ чанков текущей пары `(contentHash, contentRevision)` (version-safe), тест исполняет реальный SQL-предикат нуля свежих чанков; репродуктор 4774 красный до / зелёный после; область 62/62; typecheck 0. Патчи 0012/0013 наложены на A2 `l115s-web683-lease-loss-requeue` (13 коммитов). Статус → в ревью (4790 вместе с WEB-679 р3).
2026-09-23T18:17:47.401Z · coordinator
[23.09 18:17Z координатор] ## 4790 (M1, независимое ревью WEB-683 р6) — NO-GO (0 крит.): «настоящий SQL» приёмки гонялся через sqlite3 по ручной схеме, а боевые запросы — PostgreSQL-специфичные (`IS NOT DISTINCT FROM`, `#>>`, `::jsonb`, `LATERAL`) — доказательство не переносится на боевой диалект. Проверок пропущенных обновлений `(contentHash, contentRevision)` в import/sync/realtime — не найдено (хорошо). Раунд 7: то же доказательство на настоящем PostgreSQL (эфемерный instance на M1) — следующая волна.
2026-09-23T18:51:34.325Z · coordinator
[23.09 18:51Z координатор] ## 4798 (M1, WEB-683 раунд 7) — GO: доказательство «пропущенные куски исключаются свежестью» переписано на настоящий PostgreSQL 17.8 (эфемерный instance, `prisma db push`), sqlite-вариант удалён; репродуктор 4790 красный→зелёный, 5/5, typecheck 0. Патчи 0014–0015 на A2 `l115s-web683-lease-loss-requeue` cc7f47fc28 (15). Дальше: ревью р7.
2026-09-23T19:27:29.179Z · coordinator
[23.09 19:27Z координатор] ## 4803 (M1, независимое ревью WEB-683 р7) — NO-GO, 3 находки: (1) PG-доказательство на `prisma db push` исполняется, но на `prisma migrate deploy` (боевая схема) ломается на `document_chunk_slot_matches_generation` — схемы неэквивалентны; (2) при потере heartbeat (пауза GC/event loop) старый worker продолжает provider embedding и upsert кусков ПОСЛЕ stale-reclaim — claim token не доходит до side effect; (3) без `DATABASE_URL` тест зелёный с `tests 0`. Раунд 8 — следующая волна.
2026-09-23T20:03:31.181Z · coordinator
[23.09 20:03Z координатор] ## СОСТОЯНИЕ НА 23.09 20:2xZ (для нулевого агента)
- Что это: worker индексации терял active-passive lease под длинной задачей (2 МиБ) и оставлял документы «в работе» на 30 мин (стенд 4721; на бою за 30 дней 0 случаев). Починка: откат в pending при прерывании, lease на выделенном соединении, stale по heartbeat, claim token, «пропущенные куски исключаются свежестью».
- Где код: A2 ветка `l115s-web683-lease-loss-requeue` = cc7f47fc28 (15 коммитов; worktree `wt-l115s-web683`). Раунд 6 (13) — в all8; р7+ — в all9.
- Раунды: 1–7 (4726/4739/4746/4754/4769/4783/4798), ревью 6 (4790/4803 последние); 4803 (19:08Z) NO-GO: доказательство работает на `prisma db push`, но не на схеме миграций (`document_chunk_slot_matches_generation`); после stale-reclaim старый worker всё ещё пишет (claim token не в side effects); без DATABASE_URL тест зелёный при 0 тестов.
- Сейчас: раунд 8 — волна 4808 на M1 (`~/wt-l115s-f`, вместе с WEB-679), 19:30Z, на схеме `migrate deploy`. Блокирует число ёмкости по 2 МиБ (лестница 2 МиБ повторяется после посадки этого набора).
2026-09-23T20:10:01.715Z · coordinator
[23.09 20:09Z координатор] ## 4808 (M1, WEB-683 раунд 8) — GO: PG-доказательство переведено на схему `prisma migrate deploy` (расхождение push↔migrate закрыто, `schema-diff.md`); claim token/generation передаётся во все пишущие side effects (chunk upsert, embedding, status) и проверяется в самом UPDATE/INSERT — старый worker после stale-reclaim не может записать; без DATABASE_URL тест падает явно. Репродукторы 4803 зелёные, 25/25, typecheck 0. Патчи 0016–0017 на A2 `l115s-web683-lease-loss-requeue` = 389d1b6945 (17). ЛОВУШКА сдачи: волна не перегенерировала `patches-683/` после последних коммитов — серия восстановлена из ветки (`m1:~/waves/4808-regen/`). СОСТОЯНИЕ: раунд 8 принят → ревью 4812 (M1).
2026-09-23T20:43:53.944Z · coordinator
[23.09 20:43Z координатор] ## 4812 (M1, независимое ревью WEB-683 р8) — NO-GO: claim token стоит в 7 из 13 пишущих мест (`side-effects.md`): без fence — `documentStore.addDocument` (document.upsert, крит.), начальный `vectorStore.removeDocuments` (deleteMany, крит.), `writeSourceMetadataKeys`, entity/wiki persistence, `recordIndexingCompletionEffects`; пакет по 64 строки не атомарен при потере claim посреди. 6/7 прошлых закрыты; PG-тесты на схеме миграций исполнены. СОСТОЯНИЕ: раунд 9 — волна 4819 (M1, f): обязательный claim-контекст во все 13 мест, атомарность пакета.
2026-09-23T21:51:57.391Z · coordinator
[23.09 21:51Z координатор] ## 4819 (M1, WEB-683 раунд 9) — GO: claim token/generation во ВСЕХ 13 пишущих местах (`side-effects-after.md`), потеря claim посреди пакета не оставляет частичных кусков, репродуктор 4812 3/3 зелёный, 38/38 на PostgreSQL 17.8, typecheck 0. Патчи 0018–0022 на A2 `l115s-web683-lease-loss-requeue` (22 коммита). СОСТОЯНИЕ: → ревью 4830 (M1, c). После принятия — блокер числа ёмкости по 2 МиБ снимается посадкой all9.
2026-09-23T22:26:13.939Z · coordinator
[23.09 22:26Z координатор] ## 4830 (M1, независимое ревью WEB-683 р9) — NO-GO: собственный пересчёт нашёл 15 пишущих мест worker-а, fence в 13: (14) `publishIntegrationSourceBody` — UPDATE содержимого/хеша/метаданных Source без claim token (только CAS по contentRevision), (15) при выключенном NER `reconcileStaleSourceEntities` чистит метаданные без fence. Оба воспроизведены на PostgreSQL 17 после реального stale-reclaim; 3/4 прошлых закрыты; generation без переполнения/повторов. СОСТОЯНИЕ: раунд 10 — волна 4837 (M1, f): fence в 14/15 + собственный пересчёт 15/15.
2026-09-23T23:00:30.286Z · coordinator
[23.09 23:00Z координатор] Волна 4837 (WEB-683 раунд 10): GO. Места 14 и 15 из ревью 4830 (публикация тела интеграции и очистка NER-сущностей) теперь под fence: 15/15 побочных эффектов с токеном, репродукторы 6/6, область 42/42 на PostgreSQL 17.8. Серия 24 коммита → A2 `l115s-web683-lease-loss-requeue-r10` (c6ea0bb922). Независимое ревью — волна 4841.
2026-09-23T23:14:30.490Z · coordinator
[23.09 23:14Z координатор] СОСТОЯНИЕ НА 23.09 23:12Z — волна 4841 (независимое ревью WEB-683 р10, Codex Luna, M1): VERDICT=GO. Патчи наложились без конфликтов; области 8/8 (до ревью было 7/8); PostgreSQL 17.8; мест записи 15/15 под fence; атак 63/63 отбиты; прежние находки 2/2 закрыты; новых находок 0; typecheck 0. Ветка A2 `l115s-web683-lease-loss-requeue-r10` (c6ea0bb922, 24 коммита) ПРИНЯТА в сборку all9. Статус review до посадки l115s.
2026-09-24T04:27:21.023Z · coordinator
[24.09 04:27Z координатор] Волна 4884 (M1, пробная сборка all9: all8d + принятые наборы 683/593/661/664/439/685ф1). Швы слияния исправлены 3 коммитами без ослабления тестов: 683 — проверки на хэш содержимого при создании (81/81 без PG); 593 — учтён 29-й вызов freshness из all8 (37/40, 3 пропуска — нужен PG); 661 — перепривязка происхождения фабрики (218/218). Вердикт волны NO-GO только из-за полного typecheck: 3277 против базы 2136, из новых 2191 вне 685. Проверяю тот же typecheck на базе all8d — если там столько же, долг общий, не от наборов. Патчи: A2 /home/ubuntu/patches-4884/, HEAD 77915901.
2026-09-25T08:42:23.987Z · coordinator
[25.09 08:42Z координатор] VERDICT=CLOSE — WEB-683.

Lease-loss теперь возвращает interrupted sources в pending, heartbeat живёт на длинных шагах, а claim token+generation проходит через все 15 side-effect write paths. All9 commits: `c6ea0bb922`, `86221faf6`; ключи `src/lib/ingest/sourceIndexingQueue.ts:555-567,1056-1616,1383-1408`, `src/lib/ingest/sourceClaim.ts:19-32`. Локально 17/17 selected cases зелёные; board 4819/4837/4841 дал GO, PG17.8 и 15/15 fences.

Что ломалось: первоначальный `lease_lost` оставлял 6 источников running на 30 минут; ревью 4830 нашло ещё два unfenced writes (integration body и NER cleanup), раунд 10 закрыл их. Остаток: capacity 2 MiB/live `running >5m` — посадочный эпик; direct SQL status update запрещён.

Старт: открыть `requeueSourceIndexingOnInterruption`, `assertIndexingClaim`, heartbeat tests; live canary запускать только с разрешением координатора. Доска: http://127.0.0.1:8787/api/web/issues/WEB-683.


Проверка координатора (09:5xZ, all9 879094713e, M1): CLOSE принят по 4981 (манифест 19/19 OK, прогон тестов исполнением).
2026-09-26T22:24:48.716Z · coordinator
[26.09 22:24Z координатор] Волна 5079 (Astra, стенд 4400-r2), 26.09 22:24Z, NO-GO, манифест 32/32.
Причина lease_lost на стенде: CPU-участок обработки war-and-peace.txt (3.5 млн символов) cpuMs=33552 при TTL 15000 / renew 5000 блокирует event loop → local_expiry_checkpoint → lease_lost; WEB-683 cleanup возвращает claim без траты попыток → крупный документ может бесконечно возвращаться в pending. Это продуктовый риск и для прода на больших документах. Продуктовый патч (yield/renew вне основного потока) с тестом заказан в 5080, без деплоя.
2026-09-26T22:57:06.234Z · coordinator
[26.09 22:57Z координатор] 5081 (Astra, стенд), 26.09 22:55Z, NO-GO по условию брифа (причина кодовая → патч и STOP), манифест 50/50.
Причина 503 paid readiness на app-a: activePassiveLeaseFence держит WeakSet/AsyncLocalStorage локально модулю, а в артефакте 5069 он скопирован в несколько server chunks (23374, 32252, 71666, realtime socket). Cron spend-reconcile через другую копию повторно оборачивает http.request → direct-deny self-check честно падает. Живое воспроизведение: PASS → reconcile → FAIL за <1 с. Конфигурация app-a от b/c/d не отличается.
Патч готов (не развёрнут). Сборка r8 = 0e96058c + 5075 + 5077 + 5080 lease + 5081 fence → волна 5082 (Sol).
Воркер
не привязан — привязать: curl -X POST https://bugs.wool2.online/api/web/assign -H 'content-type: application/json' \ -d '{"issueId":"WEB-683","session":"<имя tmux-сессии>","host":"m4"}'
Обновлён
2026-09-25T08:42:36.788Z