WEB-472 · Дефект · — · web
P0 [A1/волны]: волна 1161 (WEB-468) через passwordless sudo работала в боевом PostgreSQL как postgres (создала БД noteclone_web468 на кластере 55432, читала pg_authid); 08:49Z роль noteclone перестала аутентифицироваться → accounting database-failure → paid 503. Волнам запрещён sudo (guard), нужен отдельный пользователь для волн
Закрыт
P0 · горит
ведёт: —
Суть
## Суть одной фразой
Отдельный пользователь wave без sudo для волн/диспетчера (P0: волна 1161 через passwordless sudo работала в боевом PostgreSQL как postgres).
## Где мы сейчас (13.09.2026)
Круг 5 (3f6fe4d5) УСТАНОВЛЕН на A1 03.09: диспетчер работает от uid 1005 wave (WAVE_NOSUDO=1, NoNewPrivileges), sudo denied, nosudo.sh все PASS, pg_hba noteclone:55432 — local postgres peer map=web472_admins, local wave reject. Круг 6 (отклонения живой установки: зависимость acl, UMask 0077→0027, RuntimeDirectoryPreserve=yes, chmod 0750 инсталлятора) НЕ сделан; install-wave-user.sh и nosudo.sh НЕ в линии l115g (только на невмёрженных ветках).
## Хронология
Волна 1363 (3c6f78d531) → круги 1399/1450/1479 → GO 1488 (81a324b7) → живой DRY_RUN упал → 1500 (3f6fe4d5) → GO 1502 → установлен на A1 03.09 07:02–07:35Z → мойки 12.09 (3566), 13.09 (3622).
## Карта документов и кода
land/waves/{install-wave-user.sh,nosudo.sh,systemd/90-coordinator-umask.conf,systemd/91-runtime-preserve.conf,wave-user-postmigrate.sh}; tests/{test-nosudo.sh,test-install-wave-user.sh}; бэкапы /root/wave-user-backup-20260903T061018Z.
## Остаток
- Круг 6: acl-зависимость, UMask=0027, RuntimeDirectoryPreserve=yes, chmod 0750 — сверить реконструированные файлы с веткой и вмёржить в infra/waves — волна.
- DRY_RUN=1 → rc=0 на A1 — координатор (⛔ SSH).
## Критерий закрытия
Круг 6 вмёржен в линию (install-wave-user.sh/nosudo.sh в l115g+) + DRY_RUN rc=0 на A1 без побочных эффектов.
---
_история_ — прежний текст тела (до 13.09.2026) координатор сохраняет ниже этой строки без изменений (append-only по WEB-449).
---
## история (тело до 13.09.2026)
Факты (A1, 02.09): с 08:49:13Z nc-a1 → active_passive_database_error / PrismaClientKnownRequestError; PG-лог noteclone-кластера: FATAL password authentication failed for user noteclone (pg_hba line 125 scram-sha-256); /api/ready/paid = 503 (accounting:database-failure, reconcile_deadman). В это время волна 1161-web468overdraft выполняла `sudo -u postgres psql -p 55432 -d noteclone` (SELECT из pg_authid rolpassword, pg_tables), создала БД noteclone_web468 на БОЕВОМ кластере (лог /home/ubuntu/waves/web468overdraft-codex.log:80857–84313). Точный оператор смены пароля в логе не найден (grep ALTER ROLE/PASSWORD), но корреляция по времени однозначна; ранее приёмки 1138/1144/1152 тоже создавали «одноразовые БД» через локальный сокет — на том же боевом кластере.
Восстановление 08:51Z: волна убита (tmux + процессы), `ALTER ROLE noteclone WITH PASSWORD <из .env.local>` от postgres, psql/приложение подключаются, spend-reconcile rc=200, БД noteclone_web468 удалена (0 соединений). Гейт paid открывается после цикла реконсилера (монитор).
Корень: пользователь ubuntu на A1 имеет passwordless sudo, а волны (codex exec) бегут под ним → любая волна = root на проде (PG superuser через peer, systemd, /etc). Установлен guard 08:55Z: /home/ubuntu/codex-a1.sh экспортирует WAVE_NOSUDO=1, ~/.bashrc/.profile при WAVE_NOSUDO=1 ставят /home/ubuntu/waves/nosudo в начало PATH (там `sudo` → exit 77 с сообщением). Ограничение: обходится прямым /usr/bin/sudo; бегущие волны, стартовавшие до guard-а, не покрыты.
Сделать: (1) отдельный пользователь `wave` без sudo для диспетчера/codex (права на /home/ubuntu/waves, /home/ubuntu/nc через группу), переезд диспетчера; (2) sudoers: ubuntu → NOPASSWD только для явного списка (systemctl nc-*, journalctl, hetzbk-*), не ALL; (3) брифы приёмок с «real PG»: одноразовый кластер (pg_createcluster на другом порту под wave-пользователем или docker) — НИКОГДА боевой 55432; (4) алерт на FATAL password authentication failed для noteclone в PG-логе → TG; (5) память: waves-must-not-sudo-prod-db.
Связь: WEB-468 (волна перезапущена НЕ будет до guard-а уровня пользователя), WEB-467/461 (класс инцидентов учёта), WEB-032.
Лента
2026-09-02T09:08:54.962Z · Fable[02.09 09:10Z Фабл] Второй след волны 1161: она записала в БОЕВУЮ БД noteclone синтетические платёжные данные — TerminalSpendEvent tse_web468_6fb70a97c3fa4b5a / tse_web468_fdba8e2170b64063 (08:47–08:48Z), 10 TerminalSpendProjectionReceipt под чужим implementationHash e6f36ca9…, 2 SpendReservation res_web468_*, 6 LedgerEntry (web468:seed:*, terminal:tse_web468_*), 2 TokenUsage, 2 UserBalance для несуществующих web468-user-* (cash −4.998). Гейт учёта считал эти 2 события «stale pending» (нет квитанций под accepted hash) → paid 503 держался после восстановления пароля. Удалено транзакцией от postgres в порядке FK (триггеры TerminalSpendEvent отключены только на время DELETE), леджер без hash-chain и без реальных строк после — безопасно; журнал /home/ubuntu/ops-backups/monetary-manual-edits.log; reconcile rc=200; paid true 09:08Z. Owner уведомлён. Кандидат 1161 (web468overdraft) НЕ принимать; WEB-468 переделывать волной с одноразовым кластером без sudo.
2026-09-02T21:15:36.793Z · Fable[A1 21:20 Фабл] Волна 1363-web472waveuser поставлена (A1, Luna high): пользователь wave без sudo, диспетчер под ним, guard WAVE_NOSUDO через границу процесса, тест nosudo; установка координатором в окне PAUSE.
2026-09-02T21:43:00.272Z · Fable[A1 22:20 Фабл] Волна 1363-web472waveuser сдана: коммит 3c6f78d531 (infra/waves: install-wave-user.sh, юнит диспетчера под wave, guard WAVE_NOSUDO, тест nosudo.sh, миграция очереди/совместимость брифов). Отчёт: A1 /home/ubuntu/waves/WEB472WAVEUSER-REPORT.md. Дальше: приёмка 1379-accweb472waveuser (A1, Sol high, в очереди; проверка в DRY_RUN/контейнере) → установка на A1 в окне PAUSE координатором.
2026-09-02T22:35:33.888Z · Fable[A1 01:05 Фабл] Приёмка 1379-accweb472waveuser = NO-GO (отчёт A1 /home/ubuntu/waves/ACCWEB472WAVEUSER-REPORT.md), 5 блокеров: B1 диспетчер под wave не стартует на пустом tmux-сокете (set -e + пустой list-sessions); B2 pg_hba правится у неверного кластера (на A1 три кластера: gate14bk 5440, main 5432, noteclone 55432); B3 nosudo.sh падает на [[ ! -e ]] при закрытом родителе, а не на EACCES; B4 legacy worktree-команда под wave теряет pathname; B5 миграция очереди без LEGACY_QUEUE неполна. Положительно: пользователь без sudo/групп, юнит, guard WAVE_NOSUDO. Круг 2 = волна 1399-web472waveuser2 (A1, Luna high, от 3c6f78d5).
2026-09-02T23:54:43.586Z · Fable[A1 06:10 Фабл] Волна 1399-web472waveuser2 сдана: коммит c4cc4a72cb (пустой tmux-сокет, pg_hba только noteclone, nosudo по EACCES, worktree path под wave, миграция очереди без LEGACY_QUEUE). Отчёт: A1 /home/ubuntu/waves/WEB472WAVEUSER2-REPORT.md. Приёмка 1424 (A1, Sol high, в очереди) → установка на A1 в окне PAUSE вместе с диспетчером v3 (1420).
2026-09-03T02:19:39.445Z · Fable[A1 Фабл] Приёмка 1424-accweb472waveuser2 = NO-GO (коммит c4cc4a72): B1–B5 PASS (реальный tmux/Git, uid wave), но кандидат несовместим с установленным диспетчером v3 (WEB-478/1420) — install либо возвращает User=ubuntu, либо подменяет v3 упрощённым диспетчером; и нормализация маркеров расходится с v3 (ACCWEB405_AUTHORITY4 vs ACCWEB405AUTHORITY4). Круг 3 = волна 1450 (A1, Luna high): надстройка над v3 (User=wave поверх тех же скриптов, SETSID_BIN=env), единая нормализация.
2026-09-03T04:11:28.026Z · Fable[A1 Фабл] Волна 1450-web472waveuser3 сдана: коммит dcf4883d (надстройка над диспетчером v3, единая нормализация маркеров). Приёмка 1469 (A1, Sol high) в очереди.
2026-09-03T05:00:41.090Z · Fable[A1 Фабл] Приёмка 1469-accweb472waveuser3 = NO-GO (dcf4883d): портирование v3 и нормализация маркеров PASS; B6 — установленный dispatcher не находит runner (разные каталоги, RUNNER не задан) → ни одна волна не стартует; B7 — из unit убран KillMode=process (рестарт убивает волны); MAXWAVES не конвергирует при upgrade. Круг 4 = волна 1479 (A1, Luna high).
2026-09-03T05:30:42.901Z · Fable[Фабл] Волна 1479-web472waveuser4 сдана: коммит 81a324b7. Приёмка 1488 (A1, Sol high) в очереди.
2026-09-03T05:50:54.018Z · Fable[A1 Фабл] Приёмка 1488-accweb472waveuser4 = GO (Sol high): runner найден установленным dispatcher, KillMode=process + тест рестарта, MAXWAVES upgrade → 3, B1–B5. Коммит 81a324b7 (круг 4). Установка на A1 — по порядку из отчёта в окно PAUSE (после раскатки hetzbk 8).
2026-09-03T06:12:50.645Z · Fable[A1 Фабл] Живой A1: sudo DRY_RUN=1 install-wave-user.sh (81a324b7) падает «line 270: /tmp/tmp.XXX: Permission denied» на генерации pg_hba/pg_ident temp (до этого useradd/acl/mirror/выбор кластера noteclone:55432 в dry-run прошли). Бэкапы окна сделаны (/root/wave-user-backup-20260903T061018Z), PAUSE снят. Круг 5 = волна 1500 (Luna medium).
2026-09-03T06:20:14.376Z · Fable[A1 Фабл] Волна 1500-web472waveuser5 сдана: коммит 3f6fe4d5 (temp-файл pg_hba/pg_ident под sudo). Приёмка 1502 (A1, Sol medium) в очереди; параллельно гоняю DRY_RUN на живом A1.
2026-09-03T06:35:44.086Z · Fable[A1 Фабл] Приёмка 1502-accweb472waveuser5 = GO (3f6fe4d5): temp-файл под sudo исправлен, DRY_RUN rc=0 без побочных эффектов, регресс круга 4. PAUSE поставлен; установка на A1 по порядку круга 4 (бэкапы /root/wave-user-backup-20260903T061018Z) начнётся при нулевом числе активных волн — делегировано.
2026-09-03T07:07:52.171Z · coordinatorWEB-472 — пакет user wave (круг 5, 3f6fe4d5) УСТАНОВЛЕН на A1 (окно 07:02–07:35Z 03.09, running=0). Итог: диспетчер работает от uid 1005 wave (WAVE_NOSUDO=1, NoNewPrivileges), nosudo.sh все PASS: sudo denied, local psql -U postgres denied, /home/ubuntu/prod/shared/.env.local EACCES. PG noteclone:55432 — pg_hba: local postgres peer map=web472_admins (ubuntu, postgres), local wave reject; бэкапы /etc/postgresql/16/noteclone/*.web472.20260903T070231Z.bak. Очередь /home/ubuntu/waves/queue → симлинк на /home/wave/waves/queue; 192 протухших брифа в active/ отправлены в карантин active-stale-20260903T070537Z. Отклонения от пакета (нужен круг 6): зависимость acl (setfacl) не объявлена; UMask 0077 → 0027 (drop-in 90-coordinator-umask.conf), RuntimeDirectoryPreserve=yes (91-runtime-preserve.conf — первый рестарт удалял /run/wave-dispatcher и терял tmux-сокет); chmod 0750 инсталлятора на очереди сносит ACL координатора при переустановке (после переустановки — /home/ubuntu/wave-user-postmigrate.sh). memguard → /home/ubuntu/a1-memguard2.sh. Откат: /root/wave-user-backup-20260903T061018Z (рецепт в отчёте установки). Первые волны под wave: 1506 hetzbk12, 1507 l96bigdocmerge, 1540 acclane8000v11.
2026-09-10T18:55:03.541Z · coordinatorBOARD-WASH-20260910:WAVE-3333
По поручению владельца 18:43Z назначена исполнительская волна 3333 (dispatcher), Codex gpt-5.6-luna xhigh, A1. Полная история карточки и база l115c 1ad52e16b доставлены, brief-guard и проверка Git-базы пройдены. Задача: проверить существующую сдачу, устранить остатки, передать бандл и доказательства. Финальная приёмка и посадка остаются за координатором. Запуск группы подтверждён в журнале диспетчера.
КАРТА ДОКУМЕНТОВ: ноут /Users/annakorin/nc-ops-scripts/board-wash-20260910/3333-wash-dispatcher-brief.md; A1 /home/wave/waves/inputs/board-wash-20260910/dispatcher-tickets.json; ожидаемый отчёт /home/wave/waves/3333WASHDISPATCHER-REPORT.md. Правила обогащения: WEB-449.
2026-09-12T22:17:55.095Z · coordinator[12.09 22:17Z координатор] МОЙКА 12.09 (3566-wash-g1-infra): пользователь wave живёт на A1 (круг 5, 3f6fe4d5), sudo волнам закрыт. Круг 6 (отклонения установки: acl, umask, RuntimeDirectoryPreserve, chmod 0750) не сделан, install-wave-user.sh в линии l115g нет. Остаток: круг 6 + перенести скрипт в дерево. Статус не меняю.
Остаток: Круг 6: зависимости acl, UMask 0027, RuntimeDirectoryPreserve=yes, chmod 0750 инсталлятора.; install-wave-user.sh и nosudo.sh не в линии l115g (только невмёрженные ветки).
Отчёт: /Users/milamarty/waves/3566WASH*-REPORT.md (M4), копия nc-ops-scripts/shift-20260912-resume/wash-20260912/collected/. Проверка по исходнику прода l115g (9c8a9762).
2026-09-13T07:37:30.941Z · coordinator[13.09 07:37Z координатор] РАЗБОР 13.09 (волна 3622, DeepSeek): Волны — это наши роботы-помощники. Раньше они бегали под главным пользователем компьютера и один раз случайно сломали боевую базу данных. Поэтому мы завели им отдельного пользователя `wave` без суперсил и закрыли вход в базу. Первую часть уже поставили на A1, и она работает. Остался маленький кусочек «круг 6» — четыре мелочи, чтобы стало ещё надёжнее. Я написал готовые файлы и простую инструкцию: как поставить и как откатить, если что-то пойдёт не так. Файлы надо сверить с веткой и поставить — дальше всё готово.
Остаток: Круг 6 (отклонения живой установки): зависимость acl (setfacl) не объявлена, UMask 0077→0027, RuntimeDirectoryPreserve=yes, chmod 0750 инсталлятора.; install-wave-user.sh и nosudo.sh не в линии l115g — только на невмёрженных ветках.; Точные имена веток в карточке не названы (только номера волн 1363/1399/1450/1479/1500 и коммиты 3c6f78d531/c4cc4a72cb/dcf4883d/81a324b7/3f6fe4d5).
Предложение: Посадить в infra/waves реконструированные install-wave-user.sh (с кругом 6: acl-зависимость, UMask=0027, RuntimeDirectoryPreserve=yes, chmod 0750; круг 5 temp под sudo; круг 4 KillMode=process/MAXWAVES=3/RUNNER), nosudo.sh (отказ sudo/doas/su/psql -U postgres/protected-путь по EACCES), drop-in'ы 90-coordinator-umask.conf и 91-runtime-preserve.conf, wave-user-postmigrate.sh. На A1: DRY_RUN=1 → rc=0
Ссылки: land/waves/install-wave-user.sh; land/waves/nosudo.sh; land/waves/systemd/90-coordinator-umask.conf; land/waves/systemd/91-runtime-preserve.conf; land/waves/wave-user-postmigrate.sh; tests/test-nosudo.sh; tests/test-install-wave-user.sh
Материалы волны: shift-20260912-resume/colM|colP/ (RESULT.md + спецификации). Статус не меняю — применяю по мере прогона.
2026-09-13T10:45:16.989Z · coordinator[13.09 10:45Z координатор] Мойка доски, волна 3653. RETURN: круг 5 (пользователь wave без sudo) УСТАНОВЛЕН на A1 03.09 (uid 1005, sudo denied, nosudo.sh PASS, pg_hba noteclone local wave reject) и работает; круг 6 (acl/UMask 0027/RuntimeDirectoryPreserve/chmod 0750) не сделан, install-wave-user.sh/nosudo.sh не в линии l115g. Остаток: вмёржить + DRY_RUN rc=0 на A1 (⛔ мойке). Статус не меняю.
2026-09-13T11:09:40.068Z · coordinator[13.09 11:09Z координатор] Находка при выдаче доступа (13.09): файлы окружения линии `spend-runtime-<линия>.env` во ВСЕХ каталогах запуска имели права 664, то есть читались любым локальным пользователем, тогда как их соседи по каталогу (подписанная активация, открытый ключ, скрипты принуждения) стоят на 640 и 750. Утечки не было: каталог запуска закрыт на 710, посторонний туда не проходит. Но это дыра в глубину обороны, и она воспроизводится на каждой посадке, потому что так пишет генератор комплекта.
Сделано: всем таким файлам выставлено 640 (владелец ubuntu, службы работают от ubuntu — проверено по юнитам). Прод после изменения здоров: бэкенд отвечает 200, сердцебиение рабочего свежее.
Остаток: поправить генератор комплекта, иначе следующая посадка вернёт 664. Это в очереди на ближайшую линию.
2026-09-13T11:16:19.566Z · coordinator[13.09 11:16Z координатор] Волна 3674 (GO, refs/waves/3674 = e9975639) внесла круг 6 укрепления пользователя волн в линию ПОЛНОСТЬЮ: установщик, запрет прав суперпользователя, пост-миграционный скрипт, настройки службы и тесты. Проверено офлайн: синтаксис всех скриптов, проверка файлов службы, функциональный сухой прогон с отрицательными контролями. Против живых машин не запускалось — сухой прогон на A1 за координатором.
Честная оговорка волны: соседняя карточка про дев-стенд внесена ЧАСТИЧНО — её собственный слой лёг в линию, но базы этого стенда нет ни в дереве, ни во входах, и волна отказалась её выдумывать. Файл предстартовой проверки лежит сиротой до отдельной посадки базы.
2026-09-13T12:17:41.245Z · coordinator[13.09 12:17Z координатор] Сухой прогон круга 6 выполнен координатором на боевой машине A1: код возврата 0, строка «DRY_RUN завершён без побочных эффектов» есть, каталог отката не создан, службы не тронуты, диспетчер волн работает.
Проверено отдельно: все мутирующие шаги (заведение пользователя, смена владельца, права доступа, правка настроек доступа к базе, перезагрузка описаний служб, права на сам установщик) в сухом режиме только печатаются, а не выполняются — это и подтвердилось на живой машине.
Круг 6 в линии (волна 3674, refs/waves/3674 = e9975639), сухой прогон на A1 зелёный. Критерий карточки выполнен: укрепление больше не живёт на одной машине, оно в линии и переживёт пересборку.
Закрываю. Настройки, которые уже стоят на A1 (маска создания файлов и сохранение временного каталога при перезапуске), совпадают с тем, что теперь лежит в линии.
Воркер
не проверен
3333-wash-dispatcher
A1
движение в панели: неизвестно
Подключиться и смотреть/перехватить руками. Колесо мыши листает; клавишами — Ctrl-b затем [, выход из прокрутки q. Отсоединиться — Ctrl-b затем d:
Прочитать историю панели без подключения — листается и ищется (/ поиск, q выход), воркеру не помешает:
Обновлён
2026-09-13T12:17:41.729Z