WEB board

всеканоны и докиворкеры↗ iOS↗ Легаси
WEB-662 · Задача · — · web

Enterprise-2 / CAP-14: Воспроизводимая сборка стенда замеров (сейчас он самодельный и нигде не описан)

Закрыт P1 · важно ведёт: — эпик: WEB-626
Суть
# Стенд замеров нельзя пересобрать по документу — только по отчётам волн

## 1. Вопрос владельца, которым тикет заведён (14.09, голосом)

«Стенды, которые вы делаете для замеров, отображены в доске, где что лежит? Нулевой агент разберётся, как быстро восстановить стенд после оптимизации, чтобы продолжить тестирование? Или это всё самоделкины стенды… и нулевому агенту придётся его заново изобретать?»

**Честный ответ: придётся изобретать заново.** Воспроизводимого описания нет ни в одном тикете. Это проверено поиском по доске: CAP-00 (WEB-627) фиксирует **топологию** (машины, ядра, RTT), CAP-02 (WEB-629) — **проверку** изоляции, но **как собрать стенд с нуля — не написано нигде**. Знание живёт в отчётах волн 3902/3910/3916 и в голове координатора.

Это ровно тот класс проблемы, который закрывает бас-фактор (WEB-641), только применительно к измерительной оснастке: **инструмент, который никто не умеет пересобрать, равен отсутствующему инструменту**.

## 2. Что известно про нынешний стенд (из отчётов волн, не из документа)

- живёт на **A1**, отдельным экземпляром приложения: `cap3610stand`, порты **3610** и **3611**;
- собственная база (не прод), провайдеры заглушены, egress отрезан;
- окружение: `/home/ubuntu/stand3610/app.env` — `PORT`, `HOSTNAME=0.0.0.0`, свой `DATABASE_URL`, свой `REDIS_URL`, `OPENAI_BASE_URL` на мёртвый порт, `EMAIL_TRANSPORT=off`;
- харнесс требует, чтобы `manifest.sourceCommit` совпадал с `APPROVED_APPLICATION_SOURCE_COMMIT` (`k6-script.js:24`, бросок на `:376`);
- проверка мишени — `scripts/capacity/isolation/checker.mjs` (волны 3933/3937);
- сама оснастка `scripts/capacity` (97 файлов) приехала на линию только 14.09 волной 3930.

**Известные ловушки сборки, каждая стоила времени:**
- `CREATE EXTENSION vector` обязана выполняться **от postgres ДО** миграций, иначе Prisma падает с `permission denied to create extension`;
- после неудачной попытки Prisma даёт `P3009`; на одноразовой базе правильно **пересоздать базу**, а не `migrate resolve`;
- мишень **3610 негодна** (пустая база `User=0` при 211 таблицах, чужой `sourceCommit`, неаутентифицирующиеся сессии) — все замеры шли на **3611**;
- корпус — **48 личностей**, этого не хватает для ступеней 50+ (см. CAP-03 и CAP-13).

## 3. Что нужно сделать

1. **Сценарий сборки стенда одной командой**, от чистой машины до состояния «харнесс выполняет деловое действие»: база, расширения, миграции, засев корпуса, окружение, заглушки провайдеров, отрезание egress.
2. **Проверка результата сборки** — не «поднялось», а «выполняет действие»: `/api/health` на пустом стенде проходит и ничего не доказывает, это уже обжигало.
3. **Манифест мишени** выпускается сборкой, а не пишется руками, и сразу проходит `isolation/checker`.
4. **Засев корпуса** — числом, обоснованным требованиями сценариев (см. дыру, найденную приёмкой 3937: `seededUserCount: 1` проходит проверку).
5. Всё это — **в репозитории и на линии**, под сторожем волны 3920, чтобы не пропало молча.

## 4. Зачем срочно

После каждой принятой оптимизации потолок надо **переснимать** — иначе неизвестно, сдвинулся ли он. Пересъёмка требует стенда. Пока стенд самодельный, каждая пересъёмка упирается в координатора, а это и есть бас-фактор внутри Enterprise-2.

Связано: WEB-627 (топология), WEB-629 (проверка изоляции), WEB-630 (корпус), WEB-640 (третий узел), WEB-660 (оптимизация — ради неё и нужна пересъёмка), WEB-641 (бас-фактор, тот же класс).
Лента
2026-09-14T23:06:20.485Z · coordinator
[14.09 23:06Z координатор] **🔴 Аудит живого стенда (волна 3940, `VERDICT=NO-GO`) поймал в этом тикете ЧЕТЫРЕ ошибки. Тикет я писала по памяти и по чужим отчётам — ровно тот способ, за который ругаю волны. Владелец справедливо потребовал проверку; она нашла всё.**

## Что было неверно

**1. «Порт 3611 — мишень для замеров» — УЖЕ НЕТ, и это срочно.**
Сегодня за 3611 сидит **распределитель очереди от совсем другой работы**. Настоящие копии стенда переехали на **3621 и 3622**. Кто придёт мерить на 3611 — **померит не продукт**. Любая инструкция, называющая 3611, теперь вредна.

**2. «В корпусе 48 личностей» — НЕВЕРНО: их 2185.**
Аудит пересчитал сам. **48 — это сколько можно вести одновременно** (два пула по 24), а не размер корпуса. ⚠️ Предыдущая волна (3935) это уже объясняла, **а тикет повторил старую ошибку**.

**Последствие: моё решение по CAP-10/CAP-13 стояло на неверном основании.** Я унесла ступени 50/100/1000 в CAP-13 с формулировкой «корпус 48, ступень 50 нечем населить». **Корпус 2185 — ступень 50 возможна.** Решение подлежит пересмотру: в CAP-13 остаётся «1000», но «50 и 100» надо вернуть в область достижимого и сказать, что мешает на самом деле.

**3. «Egress отрезан» — НЕВЕРНО.**
Запрет на машине есть, но выписан **на другого жильца**: правило на `uid 999`, а стенд работает под **`uid 1001`**. Стенду наружу **никто ничего не запрещал**. Это прямая дыра в изоляции и отдельная причина, по которой **CAP-02 (WEB-629) не закрывается**.

**4. «Стенд — один экземпляр на двух портах» — НЕВЕРНО.**
Экземпляров **два**, из **разных сборок**, с **разными хранилищами**: у одного своя отдельная база и свой склад, у другого — в общем. А `cap3610stand` — это **имя базы**, а не имя экземпляра.

## Что аудит добавил сверх тикета

**Стенд никем не сторожится.** Он поднят руками в ssh-сессии: пока окно открыто — работает. Закроется окно или перезагрузится машина — **стенд исчезнет, и поднять его будет некому**. Настоящий сайт рядом под присмотром systemd, стенд — нет.

**Тетрадка с секретами (`app.env`) заперта** и аудиту недоступна; он нашёл рядом открытую копию такой же и переписал из неё.

**Сторож замерялки работает:** проверяет, что манифест приложен к той сборке, из которой собрана копия; не та сборка — замер не начнётся.

## Что это меняет

1. **Тикет переписывается по фактам аудита**, а не по моей памяти — порты, число экземпляров, размер корпуса, состояние egress.
2. **Решение по ступеням 50/100 пересматривается** — основание было ложным.
3. **Дыра в egress (`uid 999` вместо `uid 1001`) идёт в CAP-02** как отдельный пункт: «изоляция объявлена, но правило выписано не на того пользователя».
4. **Отсутствие присмотра за стендом** — первое требование к воспроизводимой сборке: стенд обязан подниматься как служба, а не из ssh-окна.

**Урок, который стоит записать явно:** я потребовала от волны ловить мои ошибки — и она поймала четыре, включая одну, на которой стояло принятое решение. Описание инфраструктуры **по памяти** недопустимо; только командой на живой машине.
2026-09-14T23:19:53.643Z · coordinator
[14.09 23:19Z координатор] **Владелец спросил: «копию стенда вы где-то храните? в тикете указано, где его брать?» — проверила. Копии НЕТ, и в тикете этого не было.**

## Где живёт определение стенда — единственный экземпляр

`/home/ubuntu/stand3610/` на A1:

```
app.env           1231 байт, права 600   — переменные окружения (СЕКРЕТ, 34 штуки)
start.sh           190 байт              — чем поднимается
profile-3612.sh    935 байт              — снятие профиля процессора
inputs/ logs/ media/ nc-upstream/         — рабочие каталоги
```

`start.sh` целиком — весь «рецепт» стенда:

```bash
#!/bin/bash
set -u
R=/home/ubuntu/prod/releases/arm64-l115n-20260914T124317Z
cd "$R" || exit 2
set -a; . /home/ubuntu/stand3610/app.env; set +a
export PATH=/usr/bin:/bin
exec node server.js
```

## 🔴 Копии не существует — проверено, а не предположено

- **в git этого нет**: `git log --all -- "**/stand3610*"` в зеркале A1 — **пусто**;
- **в резервной копии этого нет**: `hetzbk` хранит `base` (база), `logs`, `manifests`, `quarantine`, `rehearsal` — каталог стенда туда **не входит**;
- **никто не сторожит**: `start.sh` запускается руками в ssh-сессии, systemd про него не знает (подтверждает аудит 3940).

**Определение стенда живёт в одном экземпляре, на одном диске, вне git и вне резервных копий.** Потеря диска A1 — стенд не восстановить. Перезагрузка машины — стенд исчез, и поднять сможет только тот, кто знает про этот скрипт.

## ⚠️ И то, что видно прямо из скрипта: стенд живёт на ЧУЖОМ релизе

`start.sh` запускает `node server.js` **из каталога боевого релиза** `arm64-l115n-20260914T124317Z`. **Своей копии кода у стенда нет.** Значит при смене линии стенд либо поедет на другой релиз (и померит не то, что вы думаете), либо сломается. Это отдельное требование к воспроизводимой сборке: **стенд обязан иметь собственный, пришпиленный артефакт.**

## Что сделано сейчас — страховка, не решение

Сохранено в `nc-ops-scripts/stand-definition/`: `start.sh`, `profile-3612.sh`, `app.env.SHAPE.txt` (**имена** 34 переменных, значения скрыты и остаются только на A1) и `ГДЕ-ЖИВЁТ-СТЕНД.md` с полным описанием. Это **не** замена воспроизводимой сборке — это защита от потери знания, пока сборки нет.

## Что добавляется в требования этого тикета

1. определение стенда — **в репозиторий** (секреты отдельно, по существующему порядку);
2. стенд поднимается **службой**, а не из ssh-окна, и переживает перезагрузку;
3. у стенда **собственный пришпиленный артефакт**, а не каталог боевого релиза;
4. каталог стенда — **в резервную копию**;
5. в тикете должно быть написано **где брать** — этого не было, теперь есть.
2026-09-14T23:27:27.196Z · coordinator
[14.09 23:27Z координатор] **Определение стенда теперь попадает в резервную копию — по предложению владельца («класть в бэкап на Hetzner с условием, что оно будет меняться по эволюции… или делать копии после изменения»).**

**Сделано:** `/home/ubuntu/stand-snapshot.sh` на A1 кладёт снимок в `/var/lib/hetzbk/stand-definition/<метка времени>/`. Первый снимок сделан:

```
/var/lib/hetzbk/stand-definition/20260914T232638Z/
  start.sh              — чем поднимается
  profile-3612.sh       — снятие профиля процессора
  app.env.SHAPE.txt     — имена 34 переменных, значения НЕ сохранены
  СНИМОК.txt            — отпечаток, из какого релиза стартует, какие порты слушал
LATEST-HASH             — отпечаток последнего снимка
```

Размер всего каталога — **28 КБ**.

**Про «менялось по эволюции» — сделано по изменению, а не по расписанию.** Скрипт считает отпечаток содержимого (скрипты + имена переменных). Совпал с прошлым — молча выходит, места не тратит. Не совпал — кладёт **новый** снимок с меткой времени, старые остаются. История версий сохраняется без мусора.

**⚠️ Секретные значения в резервную копию НЕ кладутся — намеренно, и я на этом настаиваю.** В `app.env` лежат ключ подписи сессий и строка подключения с паролем. Резервная копия существует для того, чтобы её **восстанавливали**, и класть в неё секреты значит размножать их по всем копиям и по всем, кто эти копии открывает. Стенд **одноразовый** — при пересборке значения выпускаются заново. В снимок идут только **имена**, чтобы было видно, что именно нужно выпустить.

**Что в снимке зафиксировано и чего не было нигде:**
- стенд стартует **из каталога боевого релиза** `arm64-l115n-20260914T124317Z` — своего артефакта у него нет;
- переменных в окружении — **34**;
- на момент снимка слушались порты **3610, 3611, 3621**.

**Что осталось доделать (требование к этому тикету):** снимок сейчас запускается **рукой**. Нужен триггер по изменению каталога (`systemd.path` на `/home/ubuntu/stand3610` либо проверка в существующем периодическом юните), чтобы снимок делался сам. Пока этого нет, правило простое: **изменил стенд — запусти `stand-snapshot.sh`.**
2026-09-15T01:17:15.745Z · coordinator
[15.09 01:17Z координатор] ## 15.09 01:30Z — статус → in_progress. Волна 3948 идёт на A1. Здесь же — вся картина дефекта, чтобы не собирать её заново.

**Суть дефекта (аудит 3940).** Стенд замеров существует в **одном экземпляре** и нигде не описан воспроизводимо: его подняли руками в ssh-сессии, systemd про него не знает, определения нет ни в git, ни в резервной копии. Перезагрузка машины — стенд исчезает вместе со всеми будущими замерами.

**Где он живёт:** `/home/ubuntu/stand3610/` на A1 — `app.env` (34 переменные, права 600), `start.sh` (190 байт), `profile-3612.sh`.

**Главная ловушка.** `start.sh` запускает `node server.js` **из каталога боевого релиза** — своего артефакта у стенда нет:

```bash
R=/home/ubuntu/prod/releases/arm64-l115n-20260914T124317Z
cd "$R" || exit 2
set -a; . /home/ubuntu/stand3610/app.env; set +a
exec node server.js
```

**Это выстрелило по-настоящему при посадке l115o 15.09.** Стадия `verify` отказалась завершать посадку, пока жив процесс из СТАРОГО каталога релиза — а это был как раз стенд (pid 1458892, `next-server`, работал 7ч28м). Пришлось его остановить, чтобы посадка прошла. **Сейчас стенд не поднят, и поднимать прежним способом нельзя** — он снова упрётся в каталог теперь уже старого релиза при следующей посадке.

**Прочие установленные факты (3940):**
- экземпляров **два**, из разных сборок, с разными хранилищами; `cap3610stand` — имя **базы**, не экземпляра;
- порт 3611 **больше не мишень** — там распределитель очереди чужой работы; копии переехали на 3621/3622;
- **egress НЕ отрезан**: правило ufw выписано на `uid 999`, а стенд работает под `uid 1001` (это же — остаток по CAP-02 / WEB-629);
- корпус — **2185** личностей; число 48 — это сколько можно вести одновременно (два пула по 24), а не размер корпуса. Я однажды перепутала эти числа в обосновании закрытия CAP-10 и из-за этого переоткрывала WEB-637.

**Что обязана сделать волна 3948:** сценарий сборки стенда одной командой от чистого состояния; `CREATE EXTENSION vector` от postgres ДО миграций (иначе Prisma падает; после `P3009` базу пересоздавать, а не чинить); настоящее отрезание egress **для того пользователя, под которым работает стенд**; манифест мишени выпускается сборкой и проходит `scripts/capacity/isolation/checker.mjs`; стенд поднимается **службой systemd**, переживает перезагрузку и имеет **собственный пришпиленный артефакт**; проверка результата — не «поднялось» и не `/api/health` (он проходит и на пустом стенде), а **деловое действие**: аутентифицированная сессия открывает документ; сценарий проверяется повторной сборкой стенда на свободном порту.

**Сопутствующая страховка уже стоит:** `/home/ubuntu/stand-snapshot.sh` снимает определение стенда в `/var/lib/hetzbk/stand-definition/<TS>/` **при изменении** (сравнение по хэшу), сохраняя скрипты и только ИМЕНА переменных окружения — значения не сохраняются никогда. Копия определения также лежит у координатора: `nc-ops-scripts/stand-definition/` (`start.sh`, `profile-3612.sh`, `app.env.SHAPE.txt`, `ГДЕ-ЖИВЁТ-СТЕНД.md`).
2026-09-15T02:21:07.145Z · coordinator
[15.09 02:21Z координатор] ## 15.09 04:35Z — найдена ВТОРАЯ копия стенда: живёт на порту 3621 из релиза l115l, работает 4 ч 40 мин

При разборе переполнения диска на A1 нашла процесс `next-server`, pid 2597352, **рабочий каталог `/home/ubuntu/prod/releases/arm64-l115l-20260913T203019Z`** — релиз от 13.09, на две линии назад. Слушает `127.0.0.1:3621`, память 295 МБ.

Это вторая из двух копий стенда (аудит 3940 говорил «экземпляров два»; первая — та, что слушала из каталога l115n и **заблокировала проверку посадки l115o**, я её остановила в 00:5x).

**Значит проблема не разовая, а ровно та, что описана в этом тикете:** стенд не имеет своего артефакта и живёт в каталоге боевого релиза. Каждая новая посадка будет натыкаться на такой процесс на стадии `verify`, потому что она отказывается завершаться, пока жив процесс из старого каталога релиза.

**Сейчас не останавливаю** — она ничего не ломает и это единственная оставшаяся измерительная мощность, пока 3948 строит воспроизводимый стенд. Но:

1. **Перед следующей посадкой обязательный шаг:** найти и остановить все `next-server` вне каталога текущего релиза. Команда:
   ```
   for p in $(ls /proc | grep -E '^[0-9]+$'); do d=$(readlink /proc/$p/cwd 2>/dev/null); case "$d" in */prod/releases/*) echo "$p $d";; esac; done
   ```
   и сверить каталог с тем, на который смотрит `systemctl show nc-a1 -p MainPID`.
2. **Замена от 3948 обязана погасить обе копии** — иначе они останутся висеть и держать старые каталоги релизов, мешая и посадкам, и уборке диска.
3. Заодно это объясняет, почему каталоги релизов l115l и l115m нельзя было просто удалить при чистке диска: в одном сидит процесс.

## Попутно: диск A1 чуть не встал

96–98% занятости, свободно оставалось 5.4 ГБ при пороге владельца 8 и пороге диспетчера 10. На этой машине полный диск **отказывает в ssh** — то есть это авария прода, а не неудобство.

Освобождено 15.6 ГБ: убраны отработанные деревья волн (`wt-3192`, `wt-3198`, `wt-sec014ari`) и **сжаты старые логи волн** (`gzip -9` по файлам больше 5 МБ старше суток) — одно только сжатие дало **13.1 ГБ**. Свободно 21 ГБ.

Что НЕ трогала и почему: `/var/lib/hetzbk` (37 ГБ) — это резервные копии, база 23 ГБ и журналы WAL 13.7 ГБ; от них зависят наши цели восстановления RPO 5 / RTO 15. `/var/lib/postgresql` (9.5 ГБ) — боевая база. Каталоги релизов l115l и l115m — в одном сидит процесс стенда, второй нужен как цель отката для l115n.

**Сжатие логов стоит поставить регулярным** — 13 ГБ с одного прохода это не разовая находка, а накопление.
2026-09-15T03:23:43.172Z · coordinator
[15.09 03:23Z координатор] ## 15.09 08:30Z — 🔴 волна 3948 фактически встала. И симптом тот же, что на другой машине: `next build` не завершается.

Волна идёт **2 ч 44 мин** из трёхчасового предела, до конца ~15 минут. Состояние на диске:

```
/home/wave/waves/3948STANDBUILD-REPORT.md   217 байт, черновик от 00:38, не менялся
/home/wave/waves/3948-stand-build-claude.log  0 байт
дерево wt-3948-standbuild                   коммитов НЕТ, изменённых файлов 0
/home/wave/stand-build/                     не менялся с 00:50 — почти 2.5 часа назад
```

То есть за последние два с половиной часа волна не произвела **ни одного коммита, ни строчки отчёта, ни одного файла**.

### Что она успела сделать до 00:50

```
/home/wave/stand-build/pnpm-install.log   00:43
/home/wave/stand-build/src-1628b697       00:44   ← исходное дерево
/home/wave/stand-build/run-build.sh       00:50
/home/wave/stand-build/next-build.log     00:50
```

Плюс подняты вспомогательные службы: `wave-probe-a/b/c.service`, `wave-probe-c.socket` в пользовательском systemd, и слушают новые порты — postgres на `55703` и `55902`, redis на `55903`.

### 🔴 Находка 1: сборка не завершается, и это уже второй случай на второй машине

Хвост `next-build.log`:

```
⨯ webpackBuildWorker
✓ webpackMemoryOptimizations

  Creating an optimized production build ...
```

И всё. Лог обрывается на этой строке и не рос 2.5 часа.

**Ровно тот же обрыв в логе сборки у волны 3951 на Neo** — тоже заканчивается на `Creating an optimized production build ...`. Две разные машины, две разные волны, один симптом.

Значит это **не случайность отдельной волны, а свойство нашей сборки**: `next build` в условиях волны либо висит, либо убивается, не оставляя ни ошибки, ни кода возврата. Волна после этого не понимает, что произошло, и зависает вместе с ним.

Это объясняет, почему CAP-14 не движется, и это отдельная задача — **выяснить, почему сборка не заканчивается и не сообщает об этом**.

### 🔴 Находка 2: стенд собирается из позапрошлой линии

Каталог исходников — `src-1628b697`. Коммит `1628b697d` — это **l115l**, линия от 13.09, **на две линии старше прода** (`68e25d8df`). Даже если бы сборка прошла, стенд был бы пришпилен к устаревшему исходнику.

В брифе базой был указан прод. Откуда взялся l115l — надо выяснить при перевыпуске: либо волна взяла что нашла, либо на машине не оказалось нужного коммита (ровно та ловушка с потерянным висячим объектом, на которую наткнулась 3951 на Neo, — там зеркало потеряло прод-коммит, и она честно доложила).

### Что делать

1. **Не перезапускать волну вслепую.** Материал на диске сохранить — `pnpm-install.log`, `run-build.sh`, `next-build.log`, дерево `src-1628b697`, список поднятых портов и юнитов. Перевыпуск должен начинаться с них, а не с нуля.
2. **Отдельной задачей — почему `next build` не завершается**: висит, убит по памяти, или ждёт чего-то. Без ответа любая волна, которой нужна сборка, будет умирать так же.
3. **Проверить наличие прод-коммита на A1 перед перевыпуском.** `refs/lines/l115o` проставлен, но дерево волны взяло l115l — надо понять почему.
4. Поднятые порты (`55703`, `55902`, `55903`) и пользовательские юниты `wave-probe-*` **оставить и описать** — это, возможно, уже готовая часть стенда.
2026-09-15T15:51:43.589Z · coordinator
[15.09 15:51Z координатор] M4/4022 returned INCOMPLETE with a complete SHA package. It proved the exact l115o build has two distinct failures: the hard-coded 4096 MiB heap ends in V8 OOM after about 777s; raising to 8192 MiB removes that OOM but the full-input Next webpack build still waits for the full 1200s at the same stage with about 4.7 GiB RSS and 0-2% CPU. Full pnpm build is separately blocked by three tracked migrations missing from the generated activation manifest. No artifact was produced and no process remains. M4/Terra 4073 now isolates the low-CPU wait and reconciles the manifest through canonical source truth; WEB-662 remains in_progress.
2026-09-15T16:24:12.377Z · coordinator
[15.09 16:24Z координатор] M4/Terra 4073 = INCOMPLETE, evidence SHA целый. 4 GiB OOM подтверждён; 8 GiB убирает OOM, но полный webpack graph засыпает до timeout и не пишет output. Симптом воспроизводится Node 22/26, worker on/off, minimal config, cache off; сеть, диск, кастомный webpack и версия Node исключены. Empty app строится 9.5s, light-only 28.8s, api-only 23.1s. Следующий шаг — route/import-family bisection, не ещё один полный 20-минутный build. A2/4084 запускается на точную локализацию.
2026-09-15T16:57:12.326Z · coordinator
[15.09 16:57Z координатор] [15.09 16:57Z координатор] A2/Terra 4084 завершила bounded route/import bisection: VERDICT=NO-GO, evidence SHA полностью зелёный. Причинная route/import-family НЕ найдена. Один exact real-root probe дошёл до optimized-build milestone и был остановлен на 108 s при RSS 4.47 GiB; его точный повтор завершился GREEN за 70 s. Все узкие варианты, включая i18n/client+server/player/script/analytics, завершились за 48–90 s; у всех owned descendants residue=0. Это не source GO и не build candidate.

Следующий узкий шаг уже идёт как A2/4095: четыре byte-identical real-root повтора с fixed 180 s, cold/warm/cold/warm и секундными RSS/CPU/output рядами. Цель — отделить стабильный stall от преждевременного таймаута/ресурсной вариативности. До повторяемого RED причинность не объявлять; до зелёного полного candidate build посадку не начинать.
2026-09-15T17:05:42.715Z · coordinator
[15.09 17:05Z координатор] [15.09 17:04Z координатор] Neo/4092 завершила вспомогательную статическую карту App Router на точном l115o `68e25d8df…`: `VERDICT=GO`, после маркера весь SHA256SUMS зелёный (8/8). Получено 697 production entries, 7 233 local nodes, 20 392 import edges и ранжированный список bridge-only семейств для коротких динамических проб. Это НЕ причинный вывод и не повтор build: карта только сужает следующий поиск, если A2/4095 воспроизведёт стабильный RED. До результата одинаковых cold/warm повторов WEB-662 остаётся in_progress.
2026-09-15T17:18:26.057Z · coordinator
[15.09 17:18Z координатор] 
2026-09-15T17:19:43.469Z · coordinator
[15.09 17:19Z координатор] A2/Terra 4095 завершила точную матрицу на неизменном l115o BASE `68e25d8df…`: `VERDICT=REPRODUCED_RED`, report + marker + полный SHA256SUMS проверены координатором. Четыре bounded 180 s прогона в порядке cold/warm/cold/warm все одинаково дошли до `Creating an optimized production build ...` примерно за 1.04 s, затем не дали ни одного нового байта вывода до лимита; peak RSS 4.12–4.14 GiB, CPU 151–200%, residue 0. Это воспроизводимый bounded wait, но ещё не техническая причина и не доказательство полного зависания процесса. Full candidate build сейчас не является зелёным воротом. Следующий узкий шаг A2/Sol 4102 использует карту 4092 и максимум 6 проб для поиска повторяемой соседней GREEN/RED пары по одной import-family/SCC slice; source не сохраняется.
2026-09-15T22:04:50.029Z · coordinator
DRAFT-DELTA-20260915-WEB-662 (append-only; правила обогащения: WEB-449).
ЧЕРНОВИК волны 4129 (M1/DeepSeek Flash). Опубликовано координатором после проверки SHA пакета.

УЖЕ ПОКРЫТО историей тикета (не дублируется):
- статус → `in_progress`, волна 3948 на A1, полная картина дефекта — 2026-09-15T01:17:15.745Z;
- вторая копия стенда на порту 3621 из релиза l115l — 02:21:07.145Z;
- волна 3948 фактически встала, симптом тот же — 03:23:43.172Z;
- M4/4022 INCOMPLETE с полным SHA-пакетом, два разных отказа на точном l115o — 15:51:43.589Z;
- M4/Terra 4073 INCOMPLETE: 4 GiB OOM подтверждён; 8 GiB убирает OOM, но полный webpack
  graph всё равно не проходит — 16:24:12.377Z;
- A2/Terra 4084 bounded route/import bisection `VERDICT=NO-GO` — 16:57:12.326Z;
- Neo/4092 вспомогательная статическая карта App Router на точном l115o — 17:05:42.715Z;
- A2/Terra 4095 `VERDICT=REPRODUCED_RED` — 17:19:43.469Z: четыре bounded 180 s прогона
  cold/warm/cold/warm, все дошли до `Creating an optimized production build ...` примерно
  за 1.04 s и не дали новых байт вывода до лимита; peak RSS 4.12–4.14 GiB, CPU 151–200 %,
  residue 0.

Это единственный из шестнадцати тикетов, у которого в теле НЕТ даже строки
«Правила обогащения: WEB-449», нет КАРТЫ ДОКУМЕНТОВ, нет остатка и нет блока для
нулевого агента. По канону он не обогащён вообще.

ЧЕГО НЕ ХВАТАЕТ ПО КАНОНУ WEB-449:

1) НЕТ БЛОКА KNOWN ISSUES в формате канона. Главный known issue — воспроизводимый
   bounded wait, и у него нет ни команды проверки, ни «файл:строка»:
   - СИМПТОМ: `next build` на неизменном l115o `68e25d8df…` доходит до
     `Creating an optimized production build ...` за ~1.04 s и дальше не выдаёт ни одного
     нового байта до лимита; peak RSS 4.12–4.14 GiB, CPU 151–200 %, residue 0 (17:19:43.469Z).
   - ПРОВЕРКА ЗА 2 МИНУТЫ: запустить `next build` на точном l115o с лимитом 180 s и
     смотреть время первой и последней строки вывода; отсутствие новых строк при RSS
     ~4.1 GiB = RED воспроизведён. Проверка НИЧЕГО не меняет только на чтение лога —
     сам build ресурсоёмкий, поэтому «за 2 минуты» здесь означает «2 минуты на чтение
     готового лога 4095», а не новый прогон.
   - ПРИЧИНА: техническая причина на 15.09 НЕ найдена; 4095 прямо оговаривает, что это
     «воспроизводимый bounded wait, но ещё не техническая причина и не доказательство
     полного зависания процесса» (17:19:43.469Z). Файл:строка не названы — и это надо
     написать как есть, не подставляя гипотезу.
   - СТАТУС: full candidate build сейчас НЕ является зелёным воротом (17:19:43.469Z).
   - ВТОРОЙ ФАКТ (не путать с первым): 4 GiB OOM подтверждён как отдельный отказ;
     8 GiB убирает OOM, но полный webpack graph всё равно не проходит (16:24:12.377Z).
2) В ТЕЛЕ ОСТАЛСЯ ОТОЗВАННЫЙ ФАКТ. Нужно проверить и, если он там есть, пометить:
   «корпус — 48 личностей» отозван, верное число 2185 (WEB-640
   2026-09-15T00:36:13.127Z). По правилу 4 — пометкой, а не удалением.
3) ПУСТОЙ КОММЕНТАРИЙ: 2026-09-15T17:18:26.057Z содержит пустое тело (автор `coordinator`).
   Пометка «пустой, содержания не несёт» нужна, чтобы он не читался как потерянное
   доказательство.
4) НЕТ КАРТЫ ДОКУМЕНТОВ: пути рассеяны — Neo/4092, A2/4084, A2/4095, M4/4073, M4/4022
   названы без машин и каталогов. Для тикета, который держит главный build-блокер эпика,
   это критично.
5) НЕТ ОСТАТКА И НЕТ ПЕРВОГО ШАГА НУЛЕВОГО АГЕНТА в теле.

ОСТАТОК на 15.09 17:19Z: следующий узкий шаг — A2/Sol 4102 использует карту 4092 и
максимум 6 проб для поиска повторяемой соседней GREEN/RED пары по одной
import-family/SCC slice; source не сохраняется (17:19:43.469Z). Full candidate build
не является зелёным воротом.

ПЕРВЫЙ ШАГ НУЛЕВОГО АГЕНТА (2 минуты, ничего не запускает): прочитать
2026-09-15T17:19:43.469Z и 17:05:42.715Z; проверить, существует ли уже отчёт 4102.
Если нет — не запускать полный build (это гарантированно RED и ~4.1 GiB RSS),
работать только по узкой slice из карты 4092.
2026-09-16T01:57:56.781Z · coordinator
ENRICH-4140-WEB-662
Аудит-источник: `WEB-626-ENTERPRISE2-REMAINDER-20260916.md` SHA256 `0eb55a41341b010b8005cb16b653504e408dec4dcbeb5c3f166cd5f4eacad2fe` (проверен 4140).
Живая доска: http://127.0.0.1:8787/api/web (localhost, read-only GET), read-only readback.
append-only; статус доски этой записью не двигается.

# WEB-662 — CAP-14: воспроизводимая сборка стенда замеров
## Самое сильное принятое доказательство

- `l115q` доказала воспроизводимый full build/package/landing после устранения
  Pages API regression: %s.
- Stand definition и backup-trigger материалы существуют.
- Живой readback: статус `in_progress`, последний комментарий `2026-09-15T22:04:50.029Z`.
  Расписки посадки `l115q` на карточке **нет**.

## Дефекты самой карточки (проверено живым readback 2026-09-16)

1. В теле **отсутствует** строка «Правила обогащения: WEB-449» — единственная из
   шестнадцати карточек эпика без неё.
2. В теле остался **отозванный факт**: «корпус — **48 личностей**» (раздел 2,
   известные ловушки сборки). Верное число — **2185** (`WEB-640`
   `2026-09-15T00:36:13.127Z`). По правилу 4 — пометкой, а не удалением.

## Точная недостающая расписка

Fresh build→deploy→T0→teardown→rebuild receipt одноразового стенда из immutable `l115q`:
- собственный artifact (не запуск из prod release dir);
- current ports;
- PG vector-before-migrations / `P3009` handling;
- actual app UID egress;
- systemd supervision;
- target/source/artifact equality;
- TTL/cleanup;
- повторное поднятие **без координаторской памяти**.

Старые `3610/3611` и «корпус 48» запрещены.

## Первый шаг нулевого агента
За 2 минуты, ничего не запуская: открыть тело `WEB-662`, раздел 2, и найти строку
«корпус — 48 личностей»; сверить с `WEB-640` `2026-09-15T00:36:13.127Z` (2185) и с
отсутствием строки «Правила обогащения: WEB-449». Стенд не поднимать.

## Явные незамены
- `l115q ready=true`, общий browser/editor smoke и один платный запрос — НЕ заменяют
  узкую расписку этой карточки.
- Fixture/package `GO` не равен post-landing PASS.
- Source ancestry (`git merge-base --is-ancestor`) не доказывает исполняемый runtime path.
- Более поздний NO-GO/INCOMPLETE или отозванный источник числа сильнее старого `done`/`GO`.
- `23.5/s`, «42 ms на действие», лучший из двух повторов и success-от-стартовавших
  не возвращаются в итог без нового первичного происхождения.
2026-09-16T02:28:26.212Z · coordinator
POSTQA-L115Q-4139-WEB662-AUTHOR-GO
Авторская A2/Terra 4139 сдала GO на exact l115q cc278e1810e1e03ac277b8e3a5fe06a2aebfba30 / artifact e9cdd5b041c29d058ef3c06e11ac39862e4de57d4ea307e79a7902d2d6535d86. Дважды с нуля подняты run-owned PostgreSQL16+vector0.6.0+206 migrations+Redis+artifact server.js; disposable P3009 recovery, served source/release readback и полный teardown доказаны оба раза. Evidence SHA256SUMS 29/29 PASS, residue нет. Report SHA256 5741727280eee2480ba3f51e291dcb271d7e254f99ce5d9d6d4cbe83cb5d83ce. WEB-630/632 намеренно не запускались. Это авторский GO, не независимая приёмка: M4/Luna 4153 уже работает. Перевожу in_progress→review, done только после 4153.
2026-09-19T11:18:22.127Z · coordinator
POSTQA-4153-REJECTED-4196-REWORK
После разморозки найден фактический итог независимой 4153: NOT ACCEPTED — NOT_RERUN. Exit=0 означал завершение модели, не GO. 28/28 входных SHA прошли, но отсутствовали artifact bytes/manifest; teardown не наблюдал исчезновение unit/PID/socket; raw P3009 и negative logs не сохранены; readiness содержал красные background checks; заявленный mode 0444 фактически был 0644. Terminal package 4153 не создан. 4196/DeepSeek Flash на M4 сейчас строит fail-closed r2 package по этим пяти блокерам. WEB-662 остаётся review.
2026-09-19T11:29:28.445Z · coordinator
REWORK-4196-READY-FOR-A2-RERUN
DeepSeek Flash 4196 завершила исправленный пакет после rejection 4153: VERDICT=GO_FOR_A2_RERUN, но это НЕ live GO. Координатор независимо проверил все 100 записей SHA256SUMS; terminal marker status=VERIFIED, mode policy scripts=0555/other=0444, liveStandBooted=false. Пять блокеров 4153 воспроизведены; 43/43 static controls и 7/7 mutation controls PASS. Следующий обязательный шаг — реальный A2 rerun на exact l115q artifact с raw P3009/negative logs и измеренным teardown. Статус review сохраняется.
2026-09-19T11:45:24.662Z · coordinator
[19.09 11:45Z координатор] LIVE-A2-RERUN-4196-STARTED
Пакет 4196 после DeepSeek-ремонта повторно проверен координатором: полный SHA256SUMS зелёный, exact source cc278e1810e1e03ac277b8e3a5fe06a2aebfba30 доступен, exact artifact SHA-256 e9cdd5b041c29d058ef3c06e11ac39862e4de57d4ea307e79a7902d2d6535d86 совпал, старого evidence не было. Первая попытка честно NOT_STARTED: systemd/root получил Git dubious ownership до boot; отказ сохранён отдельно, глобальный git config не менялся. R2 запущена с одноразовым process-scoped safe.directory, unit nc4196-live-r2 active. Выполняются два независимых cold start, P3009, egress/auth controls и измеренный teardown. Background workers явно declared out of scope и не называются зелёными. До terminal overall.json, полного SHA readback и независимой проверки статус остаётся review.
2026-09-19T11:55:37.490Z · coordinator
[19.09 11:55Z координатор] LIVE-RERUN-4196-R4-STARTED
4196 r2 and r3 both stopped before app/readiness, so neither is a ticket result. r2: disposable state root was inaccessible to intended UID 1001. r3: PostgreSQL/Redis and P3009 recovery ran, then the evidence emitter refused on one jq concatenation syntax error before app/firewall. Both failures are preserved with SHA; no NC_PROOF_EGRESS residue remains. Minimal r4 contains only intended state ownership (0750 ubuntu:ubuntu) plus parenthesized jq concatenation; bash syntax, isolated jq compile and ownership smoke passed. Live r4 is active on A2 as nc4196-live-r4. WEB-629/662 stay review until terminal report + complete SHA readback.
2026-09-19T11:58:41.669Z · coordinator
[19.09 11:58Z координатор] LIVE-RERUN-4196-R5-STARTED
r4 is NOT_STARTED as a ticket verdict: the first cold start reached a live next-server and passed DB/P3009/fence preflight, but the outer collector exited before readiness capture because `local ... out="$3" rawdir="$out/..."` expanded `out` under set -u in the same declaration. The live unit was authenticated and torn down; firewall teardown PASS, unit stopped, state removed, no NC_PROOF_EGRESS residue. r4 failure is preserved with SHA. r5 splits both capture/teardown local declarations, bash syntax passes, and is now active on A2. Status remains review until both cold starts, teardown receipts and complete SHA readback finish.
2026-09-19T14:21:31.244Z · coordinator
[4196 r7 ORCHESTRATION_REFUSAL 19.09 14:20Z]

Live rerun 4196 r7 on A2 completed two disposable cold-start phases, but issued no product verdict.

Verified phase evidence:
- both /api/ready receipts: ready=true, status=ok, failures=[], sourceCommit cc278e1810e1e03ac277b8e3a5fe06a2aebfba30;
- release ids are the expected distinct identities 4196-l115q-first and 4196-l115q-second;
- application scope GREEN in both phases;
- background scope RED_DECLARED_OUT_OF_SCOPE in both phases, yielding GO_WITH_DECLARED_EXCLUSIONS rather than an unconditional PASS;
- both measured teardowns PASS: unit/app/PostgreSQL/Redis/sockets/identity absent, firewall baseline identical, residue=[].

The run then failed in the coordinator cross-phase gate before overall.json and the original final manifest. The accepted r7 runner invoked jq -e with slurpfiles but without -n and without an input document. Reproduction on the sealed receipts: old invocation exit=4; identical expression with jq -n -e exit=0 and confirms both phases served the same source under distinct expected ids.

Classification: ORCHESTRATION_REFUSAL; productVerdict=NOT_ISSUED. Do not close WEB-629/WEB-662 from r7.

Durable A2 evidence: /home/ubuntu/waves/4196STAND-evidence-r7, 90 files. Post-run SHA256SUMS readback PASS; manifest SHA-256 674d5bcaa6ac2cbb56b18de6aab05ebeabeb96a3b15963c4fff77617aa38ac1a. Cleanup readback: state residue 0, NC_PROOF_EGRESS IPv4/IPv6 0.

Minimal r8 changes only VERSION and jq -n -e; r8 requires a fresh live run and its own readback before any ticket closure.
2026-09-19T14:25:33.123Z · coordinator
[19.09 14:25Z координатор] [4196 r8 ORCHESTRATION_REFUSAL + RESCUE 19.09 14:24Z]

r8 used the minimal verified diff from r7: VERSION=4196-r8 and jq -n -e in the cross-phase gate; runner SHA-256 9ec703afeb3a506d4b94cb293da7eb2bc64f9c6f8584f28dfad1c4e8c6cb3ef0.

The first disposable phase completed and tore down. During the second phase the outer runner's start wait expired at 30 seconds and exited with "phase second failed to start", but the inner transient unit continued booting and subsequently served /api/ready successfully inside its namespace:
- ready=true, status=ok, failures=[];
- release.id=4196-l115q-second;
- sourceCommit=cc278e1810e1e03ac277b8e3a5fe06a2aebfba30.

This is an orchestration timeout, not a product verdict. The outer failure left the second inner unit active, so the coordinator performed a bounded rescue: captured state inventory, journal, live readiness, listeners and raw logs; invoked the accepted authenticated fence teardown inside the namespace; stopped the exact transient unit; copied final logs; removed only the exact disposable state root; verified no 4196 state roots and no NC_PROOF_EGRESS IPv4/IPv6 residue.

Durable rescue evidence: /home/ubuntu/waves/4196STAND-evidence-r8-rescue-20260919T1423Z, 2019 files; SHA256SUMS readback PASS; manifest SHA-256 f7dcbc04e66ffaaea1bc14acca94b170966771d81707fea56dc2afde1e02547e.

Classification: ORCHESTRATION_REFUSAL; productVerdict=NOT_ISSUED. WEB-629/WEB-662 remain review. A future rerun must replace the fixed 30-second start wait with readiness-aware terminal handling and independently verify the resulting package before launch.
2026-09-19T15:27:58.690Z · coordinator
[4196 r9 STARTED AFTER 4205 GO 19.09 15:27Z]

Independent DeepSeek Pro acceptance 4205 returned GO_FOR_A2_RERUN for exact runner SHA-256 817994b0e31250a34968e898abf9518cda469972b9bdc53de557b07bb181eec9. Coordinator readback: acceptance SHA256SUMS PASS, manifest SHA-256 220a4b41d50de2ee7bb524f5867753748c5afce3121a483f738bc7dbaf972851, independent controls 11/11, mutations 6/6.

The first coordinator launch wrapper refused before runner entry because nested shell quoting produced empty cwd/log paths. Unit nc4196-live-r9.service exited status 2; state roots 0, firewall residue 0/0, inner units 0, evidence/log/launch receipt absent. This was an orchestration refusal, not a product result.

The immutable base package was restored from /home/ubuntu/waves/4196-delivery.tar.gz SHA-256 8a813a3b87a3ff85a5c1302ff32d2595277cec0a2db6f55d5924b2732df1276e, original SHA256SUMS passed, accepted r9 inserted, full R9 manifest readback passed with digest 25eca0f404f8659cae3727d879ef9ffb5435a699f0e2ffde5b76047fdf2ebc87. One corrected live rerun is now active as nc4196-live-r9a.service, PID 2752661, invocation 0aadb1b0984045b393dc48d7400ee608. This is not yet a product verdict. Keep both tickets in review until two cold starts, evidence checksums, teardown and terminal residue readback complete.
2026-09-19T15:35:44.506Z · coordinator
[4196 r9 ORCHESTRATION_REFUSAL 19.09 15:28Z]

Exact independently accepted r9 runner SHA-256 817994b0e31250a34968e898abf9518cda469972b9bdc53de557b07bb181eec9 completed both cold starts on A2. Distinct release ids were served (`4196-l115q-first`, `4196-l115q-second`) with the same exact source cc278e1810e1e03ac277b8e3a5fe06a2aebfba30. Runner wrote overall claim GO_WITH_DECLARED_EXCLUSIONS, application readiness GREEN, and WEB-629/WEB-662 PASS under the declared background-heartbeat exclusion.

This is NOT a product verdict because the final receipt verifier correctly returned REFUSE: six inner receipts (`fence-auth`, `migration-tree`, `p3009`, both phases) carried fallback runId `4196-unset` instead of outer run id `4196-l115q-20260919T152702Z-2752661`. Root cause is executable: outer assigns RUN_ID/UNIT_NAME, but systemd-run does not pass them to the inner shell. Outer exited 1.

Terminal cleanup readback PASS: state roots 0, NC_PROOF_EGRESS IPv4/IPv6 residue 0. Evidence sealed in `/home/ubuntu/waves/4196STAND-evidence-r9`: 94 files plus SHA256SUMS, fresh readback PASS, manifest SHA-256 f2d67a36eac9a1b7ad838eefb8955c6fe53ec46e33ce0a7c8c84e67332c90afd.

A narrow static author repair 4208 is active on the owner laptop. It may only propagate and validate exact RUN_ID/UNIT_NAME and must preserve all r9 gates. No new A2 rerun until 4208 terminal package, coordinator checksum readback, and a fresh independent acceptance. Keep ticket in review.
2026-09-19T16:02:45.670Z · coordinator
[4196 R10 AUTHOR GO; 4214 INDEPENDENT STARTED 19.09]

Author DeepSeek Pro package 4208 completed `GO_FOR_INDEPENDENT_ACCEPTANCE`. Output checksum readback PASS; manifest SHA-256 `be27cb04d54c51d1c2e030ee3041682389c236b71ce03df44a425f8e5c9b7604`; r10 runner SHA-256 `53086d1ba0756bd81f172e317bf0d70aad54e351fd381fe8ff7ec5dac71f37a8`. Author controls 12/12 and mutations 4/4.

Repair scope: propagate exact outer `RUN_ID` and `UNIT_NAME` into both inner systemd phases and fail closed before live receipts if identity, phase, state/unit marker, or run.json disagree. This is author evidence only — no A2 run or product verdict.

Fresh independent DeepSeek Pro acceptance 4214 is active on M1 from exact r9+r10 immutable inputs; outer input manifest `84ef77db82ee633b31c2ac6b4b29336ebb782f5e4bd95c794670eedcc38792bf`. No A2 rerun is authorized before terminal verdict, coordinator checksum/readback, and explicit `GO_FOR_ONE_A2_RERUN`. Status remains `review`.
2026-09-19T16:24:02.723Z · coordinator
[4196 R10 A2 POST-QA COMPLETE 19.09]

The single independently-authorized A2 r10 rerun completed `GO_WITH_DECLARED_EXCLUSIONS` on exact production source/artifact identity: source `cc278e1810e1e03ac277b8e3a5fe06a2aebfba30`, artifact `e9cdd5b041c29d058ef3c06e11ac39862e4de57d4ea307e79a7902d2d6535d86`. Evidence `SHA256SUMS` full readback PASS; manifest SHA-256 `541c1093bc11d0688383c7d0e71502ffc75d331934f069807378a354a7efc419` (94 files).

Bound live results:
- two cold starts served distinct release ids `4196-l115q-first` / `4196-l115q-second` with the same exact source; application boot/database/release GREEN in both;
- WEB-629 egress fence: old uid-999 rule did not protect actual uid 1001; candidate blocked non-loopback for the actual run-owned identity; production-shaped, duplicate, stale, foreign, and cleanup-failure identities all refused in both phases;
- WEB-662 artifact/source migration trees byte-identical: 207 files, digest `e368b9f0d3ec3d39a0b064701b5d7a759c7ecb930618c4807ac53e2cdfb7c99b`; P3009 observed then recovered; 206 migrations applied in both phases;
- receipt verification PASS: 19 checked, all live, no synthetic-as-live, no bypass flag, no errors;
- teardown PASS twice and coordinator post-check: state roots 0, active 4196 units 0, firewall residue IPv4/IPv6 0.

Declared boundary: background worker heartbeats were RED and explicitly out of scope on this disposable stand; `unconditionalPass=false`. This is A2 post-QA evidence, not direct production execution. A1 remains healthy on the same exact source, but no ticket-specific destructive prod rerun was performed. Therefore status stays `review`; no closure is claimed.
2026-09-19T21:07:25.686Z · coordinator
[COORDINATOR CLOSURE 2026-09-19 — r10 isolated post-QA criteria satisfied]

Coordinator independently re-read the sealed A2 r10 package after the earlier conservative no-closure comment. `/home/ubuntu/waves/4196STAND-evidence-r10/SHA256SUMS` passes 93/93, SHA-256 `541c1093bc11d0688383c7d0e71502ffc75d331934f069807378a354a7efc419`, self-entry 0. Both cold starts served distinct release ids from exact current production source `cc278e1810e1e03ac277b8e3a5fe06a2aebfba30` and artifact `e9cdd5b041c29d058ef3c06e11ac39862e4de57d4ea307e79a7902d2d6535d86`. WEB-629: actual uid 1001 non-loopback egress blocked; production-shaped/duplicate/stale/foreign/cleanup-failure identities refused in both phases. WEB-662: source/artifact migration trees byte-identical 207/207, digest `e368b9f0d3ec3d39a0b064701b5d7a759c7ecb930618c4807ac53e2cdfb7c99b`; P3009 observed and recovered; 206 migrations applied in each disposable phase. T0 PASS twice; receipt verifier PASS 19/19, all live, no synthetic-as-live or bypass; teardown PASS twice with no unit/app/Postgres/Redis/socket/identity/firewall residue. Background worker heartbeats remain RED_DECLARED_OUT_OF_SCOPE and `unconditionalPass=false`; they are not relabelled PASS and are outside these two tickets’ isolated application-stand closure criteria. This is isolated A2 post-QA bound to the exact production artifact, not a destructive production rerun. Both tickets’ stated closure conditions are satisfied.
Воркер
не проверен 4196-r10:a2-postqa-pass; coordinator-closed-20260919 coordinator движение в панели: неизвестно
Подключиться и смотреть/перехватить руками. Колесо мыши листает; клавишами — Ctrl-b затем [, выход из прокрутки q. Отсоединиться — Ctrl-b затем d:
Прочитать историю панели без подключения — листается и ищется (/ поиск, q выход), воркеру не помешает:
Обновлён
2026-09-19T21:07:25.709Z