WEB-656 · Задача · Инфраструктура · web
P1 [bus factor]: практический экзамен A — доступ без владельца (требуется решение владельца: кто хранитель и кто резервный оператор)
Закрыт
P1 · важно
ведёт: —
эпик: WEB-641
Суть
# WEB-656 — репетиция A: хранитель получает и открывает комплект сам
**Переписано 13.09.2026 (R2).** Прежняя формулировка требовала найти второго инженера в штат — отменено.
## СУТЬ
Проверить на живом человеке и его собственном устройстве, что аварийный комплект можно получить и открыть без владельца.
## КАК ПРОХОДИТ РЕПЕТИЦИЯ
1. Хранитель открывает `START-HERE` (он лежит вне шифрования и не требует работающего сайта проекта).
2. Своим способом входа скачивает пакет из основного места.
3. Проверяет подпись манифеста заранее доверенным ключом и расшифровывает комплект своим ключом.
4. Запускает предусмотренную инструкцией процедуру.
5. Повторяет получение через ВТОРУЮ копию, считая основное хранилище недоступным.
## ЧТО СЧИТАЕТСЯ ПРОВАЛОМ
Любой шаг, где хранителю понадобилась помощь владельца, его телефон, его аккаунт или подсказка координатора. Также провал — если ключ или пароль к месту скачивания оказался спрятан внутри самого недоступного архива.
## ОТ ВЛАДЕЛЬЦА
Одно действие: назвать хранителя (одного достаточно) — имя и способ связи. Инженером он быть не обязан.
## ОТ ХРАНИТЕЛЯ (один раз)
Принять доступ, создать или безопасно получить личные ключи на своём устройстве, сохранить их независимую резервную копию, пройти эту репетицию.
## КРИТЕРИЙ ЗАКРЫТИЯ
Обе ветки репетиции пройдены с сохранёнными доказательствами: журнал шагов, отпечатки проверенного манифеста, подтверждение получения из второй копии.
---
## история (тело до 13.09.2026, схема с покупкой менеджера паролей и наймом инженера — отменена)
Правила обогащения: WEB-449. Parent WEB-641. Заведено 13.09 по внешнему разбору (раздел 5.A и 4.3).
## Суть
Даже идеальная книга не помогает, если получить доступ может только владелец со своего телефона. Нужно проверить, что цепочка доступа не закольцована на нём.
## Решения, которые может принять ТОЛЬКО владелец (команда не угадывает)
1. Кто хранитель доступа (может быть нетехнический человек) и кто резервный оператор (инженер, возможно внешний); их подтверждённые контакты.
2. Какие сервисы и действия доступны в обычном режиме, какие — только при аварии.
3. Что считается аварией и кто запускает процедуру, когда владелец не отвечает.
4. Где проектное хранилище ключей и кто может восстановить его без владельца.
5. Допустимый срок получения доступа — отдельно от целевого времени восстановления базы (их нельзя смешивать).
6. Кто резервный подписант релиза и по какой процедуре (личной подписью владельца молча подписывать нельзя, проверку подписи отключать нельзя).
## Сам экзамен
Назначенный человек со своего устройства и своей учётной записи, без участия владельца: найти стартовую инструкцию → открыть независимую копию книги → получить разрешённый тестовый секрет → скачать тестовый зашифрованный архив → расшифровать → сверить контрольную сумму → пройти проверку своей роли только на чтение. Отдельно проверить, что неподходящая роль получает отказ. Записывается время, роль, результат и пробелы — не значения секретов. Боевые секреты для первой репетиции не нужны.
## Приёмка
Протокол прогона: кто, с какого устройства, сколько времени, где застрял, что пришлось спросить у владельца (каждый такой случай — дефект процедуры).
Лента
2026-09-13T10:04:04.478Z · coordinator[13.09 10:04Z координатор] ЧТО НУЖНО ОТ ТЕБЯ ПО БАС-ФАКТОРУ — простыми словами.
Из шести карточек четыре делаю я сам (исправления в книге и два экзамена). От тебя — две вещи: назвать людей и завести три «места», где лежат книга, ключи и права. Регистрации — да, три штуки, ниже прямые ссылки.
1) НАЗВАТЬ ДВУХ ЛЮДЕЙ (можно прямо в ответ, мне хватит имени и телеграма/почты)
• ХРАНИТЕЛЬ — доверенный человек, необязательно программист. Его задача: если тебя нет, открыть инструкцию и позвать инженера. Может быть жена, брат, партнёр.
• РЕЗЕРВНЫЙ ОПЕРАТОР — инженер, который реально починит. Необязательно в штат: подойдёт знакомый разработчик, которого можно позвать разово.
Если второго пока нет — скажи, я оформлю так, что операторскую часть выполняет агентная сессия, а хранитель просто выдаёт ей доступ.
2) ХРАНИЛИЩЕ КЛЮЧЕЙ (пароли и секреты) — 10 минут
Рекомендую 1Password: https://1password.com/sign-up (есть бесплатный пробный период, дальше около 20 долларов в месяц за команду)
Что сделать: завести аккаунт команды → создать хранилище с названием «NoteClone-prod» → пригласить хранителя → назначить его вторым владельцем.
Как назначить второго владельца: https://support.1password.com/create-share-vaults-teams/
Бесплатная альтернатива — Bitwarden: https://vault.bitwarden.com/#/register Только учти его особенность: аварийный доступ там открывает ВЕСЬ твой личный сейф, а не одну папку — поэтому под проект заводи отдельную организацию. Описание: https://bitwarden.com/help/emergency-access/
Пароли туда я не кладу — это делаешь ты. Я скажу, какие именно ключи положить (список готов).
3) МЕСТО ДЛЯ КНИГИ (инструкция, паспорт, карта сервисов) — 10 минут
Общий диск Google, а не личная папка: https://support.google.com/a/users/answer/7212025
Что сделать: создать общий диск «NoteClone-knowledge» → дать доступ хранителю по имени (не «всем по ссылке»). Книгу и архив туда положу я.
4) ВТОРОЙ ВЛАДЕЛЕЦ В СЕРВИСАХ (по 2 минуты каждый)
• GitHub: добавить второго владельца организации. Инструкция: https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/maintaining-ownership-continuity-for-your-organization
• Хостинг Oracle (там живёт прод): завести отдельного пользователя хранителю. https://docs.oracle.com/en-us/iaas/Content/Identity/users/managingusers.htm
• Hetzner (там лежат резервные копии): завести подаккаунт. https://docs.hetzner.com/robot/storage-box/subaccounts/
• Домен: у регистратора, где куплены wool2.online и sixbyy.com, добавить второй контакт или доступ. Скажи, какой регистратор, дам точную ссылку.
Своим логином ни с кем не делись: у каждого свой вход и свой второй фактор.
5) ОДИН ВОПРОС ПРО ПОДПИСЬ
Сейчас разрешение на выпуск подписывается твоим личным ключом. Если тебя нет — выпускать нельзя. Варианты: (а) резервный подписант со своим ключом, (б) заранее подписанный аварийный пакет на один выпуск. Скажи, какой вариант, я оформлю.
КОГДА СДЕЛАЕШЬ: напиши «готово» — и я проведу репетицию доступа. Хранитель со своего телефона, без тебя, за полчаса должен: найти инструкцию, войти под собой, достать один тестовый секрет, скачать и расшифровать тестовый архив, сверить контрольную сумму. Боевые пароли для репетиции не нужны.
2026-09-13T11:14:17.676Z · coordinator[13.09 11:14Z координатор] Волна 3673. OWNER-ACTIONS: дело №2 (назвать хранителя и резервного оператора) на единой странице владельца (3673-owner-actions-single-page-out/OWNER-ACTIONS.md) закрывает эту карточку напрямую; дела №4, №5, №6, №7 продвигают её вместе с WEB-657/WEB-644. Содержание совпадает с прямым комментарием координатора от 13.09 10:04Z в этой же карточке — страница лишь собирает его в общий список с остальными шестью карточками.
2026-09-13T11:32:37.994Z · coordinator[13.09 11:32Z координатор] Карточка переписана по упрощённому решению владельца (R2 13.09): без новых обязательных подписок, хранилище — существующий Hetzner с индивидуальным подаккаунтом на чтение, шифрование age на нескольких получателей, вторая копия вне этого хранилища, технический исполнитель — искусственный интеллект самого хранителя (его подписка, не наша). От владельца остаются ровно два действия: назвать хранителя и утвердить один список полномочий.
2026-09-13T12:06:22.531Z · coordinator[13.09 12:06Z координатор] Инструменты для этой репетиции готовы (волна 3685): стартовый файл, упаковщик, манифест с подписью и проверяльщик с четырьмя остановками. Как только будет назван хранитель, репетицию можно проводить — со стороны техники всё на месте.
2026-09-13T12:10:26.621Z · coordinator[13.09 12:10Z координатор] Владелец назвал хранителя: Слава, почта fandyy2023@gmail.com. Он же просит провести первую репетицию НА СЕБЕ, когда техническая часть будет готова, и связаться с ним по почте с инструкцией: что запускать и какой пакет отдать искусственному интеллекту.
Честная оговорка, которую фиксирую сразу: репетиция на владельце доказывает, что комплект работает и инструкция понятна. Она НЕ доказывает бас-фактор в полном смысле, потому что второй человек тут тот же самый. Это правильный первый шаг, но в итоговом листе он будет записан именно так, без подмены понятий.
Разрешение на список полномочий владелец дал заранее, по умолчанию.
2026-09-13T12:22:59.979Z · coordinator[13.09 12:22Z координатор] Письмо хранителю готово (волна 3696): пошаговая инструкция на русском, без терминов, с разделом «что должно получиться» на каждом шаге, отдельным списком галочек и разбором четырёх самых вероятных затыков.
В письме прямо сказано: помощник — собственный, на своей подписке, логина от нас ждать не нужно. Секретов в письме нет нигде: где шаг требует ключ, написано ОТКУДА человек его берёт.
Последним абзацем — честная граница: эта репетиция докажет, что комплект работает и инструкция понятна, но не передачу управления второму человеку, потому что хранитель и владелец сейчас одно лицо.
Остаток до отправки письма — мой: завести хранителю отдельный вход на чтение в хранилище, собрать сам комплект и положить вторую копию вне этого хранилища.
2026-09-13T12:26:21.770Z · coordinator[13.09 12:26Z координатор] Вся цепочка аварийного комплекта проверена координатором НА БОЕВОЙ инфраструктуре, от начала до конца.
Что сделано по шагам:
1. На хранилище Хетцнера заведён отдельный каталог busfactor-kit (свободно 482 ГБ из терабайта).
2. Инструменты волны 3685 развёрнуты на машине, прогнан их собственный набор тестов: 31 проверка, все зелёные.
3. Собран настоящий комплект: зашифрованный архив, опись с отпечатками, стартовый файл. Упаковщику дали ТОЛЬКО публичный ключ получателя — приватного он не видел и по устройству не принимает.
4. Опись подписана отдельным шагом, как и задумано: подпись не участвует в сборке, поэтому обновлять комплект можно без подписанта.
5. Комплект залит на хранилище, затем скачан в ЧИСТЫЙ каталог, будто его получил посторонний.
6. Проверяльщик запущен против скачанного с хранилищем доверия, лежащим ВНЕ пакета: PASS, совпали отпечаток описи, отпечаток архива, личность подписанта, версия комплекта.
7. Архив расшифрован ключом получателя — внутри ровно те файлы, что клали.
8. Отрицательный контроль: в архиве испорчен ОДИН байт — проверяльщик остановился с кодом «повреждённый пакет» и показал, какой отпечаток ожидал и какой получил.
Что осталось до письма хранителю: завести ему отдельный вход на чтение только этого каталога, положить вторую копию вне хранилища и подписать боевой комплект ключом владельца, а не репетиционным.
Репетиция велась на выдуманных тестовых ключах, боевых секретов в ней нет.
2026-09-13T13:50:59.720Z · coordinator[13.09 13:50Z координатор] Поправка от владельца 13.09: хранителем для репетиции назначается адрес fandyy2009@gmail.com, а не fandyy2023@gmail.com. Причина простая и важная: на 2023 висит сам владелец, в том числе как владелец аккаунта GitHub, и назначить его же вторым владельцем невозможно.
Моя оговорка, которую фиксирую сразу: владелец предупредил, что на 2009 висит один из аккаунтов Oracle. Для чистоты испытания это минус. Смысл репетиции — доказать, что человек, у которого ЕСТЬ ТОЛЬКО КОМПЛЕКТ, может поднять систему. Если почтовый ящик хранителя одновременно управляет облачным аккаунтом, где живёт прод, то, во-первых, испытание доказывает меньше, а во-вторых, права концентрируются в одном ящике вместо того, чтобы разделяться.
Рекомендация: для прогона взять третий адрес, который не владеет ничем нашим. Владелец предложил такой вариант сам. Если он всё же выберет 2009 — репетицию проведу, но в итоговом листе запишу этот факт как ограничение, а не умолчу.
2026-09-13T14:40:13.205Z · coordinator[13.09 14:40Z координатор] ПОДАККАУНТ ХРАНИТЕЛЯ ЗАВЕДЁН И ПРОВЕРЕН. Сделано координатором через консоль Hetzner (владелец дал доступ к кабинету).
Что заведено: пользователь u656648-sub1, описание «SIXBYY busfactor keeper (read-only, busfactor-kit)», базовый каталог /busfactor-kit/, доступ по SSH, внешняя доступность включена, режим только чтение.
Четыре проверки, включая обязательные отрицательные:
1. Чтение каталога — работает, видны все четыре файла комплекта.
2. Соседний каталог — НЕ виден: «нет такого файла или каталога». Изоляция работает.
3. Удаление файла — ЗАПРЕЩЕНО: «файловая система только для чтения». Это и есть та самая негативная проверка, которую требовал план.
4. Скачивание файла — работает, файл получен целиком.
Вторая копия комплекта положена в Загрузки владельца (каталог «БАС-ФАКТОР-КОМПЛЕКТ»), отпечаток архива совпадает с тем, что лежит на хранилище: 897628be. Это «локальная копия у хранителя» из схемы — для репетиции, где хранитель и владелец одно лицо.
Пароль подаккаунта лежит в защищённом файле на машине координатора с правами только для владельца файла, в чат и в письмо открытым текстом не пойдёт.
Позиция «доступ хранителя к обеим копиям» из итогового листа закрывается технически. Осталось: подписать боевой комплект настоящим ключом владельца вместо репетиционного.
2026-09-14T17:53:45.265Z · coordinator[14.09 17:53Z координатор] **ОБА ОСТАВШИХСЯ ПУНКТА ЭПИКА ЗАКРЫТЫ.** Раздел «Что осталось и кто это делает» называл ровно два, оба были за координатором:
**1. «Подписать БОЕВОЙ комплект ключом владельца по доверенности (пока использован репетиционный)» — ⚠️ было сделано ещё 13.09 в 21:05:33Z, тело тикета на этом пункте устарело.** Проверено по самому файлу:
```
manifest.sig.json signer_identity = owner-busfactor
signer_key_sha256 = 9ad5127b5e1f38ca950663065642ff3eeb3b5c8c8befdec7b85ddb6b4b8d3773
signed_at = 2026-09-13T21:05:33Z
manifest.sig.json.bak-rehearsal signer_identity = coordinator-rehearsal-20260913 (сохранена как запасная)
```
`manifest_sha256` у обеих подписей один и тот же — подписан один и тот же комплект, сменился только подписант. Отпечаток совпадает с тем, который письмо-приглашение называет доверенным.
**2. «Отправить владельцу письмо-приглашение на репетицию A (пакет письма готов волной 3696)» — отправлено сейчас.** Три файла: `REHEARSAL-LETTER.md`, `REHEARSAL-STEPS.md`, `HANDOVER-LIST.md`. Адреса: `sixbyy@wool2.online` (хранитель репетиции) и `fandyy2023@gmail.com`.
⚠️ **Почему письмо не ушло раньше, хотя лежало готовым со вчера 22:36:** почта отправлялась с A1, а **с A1 исходящий порт 25 закрыт**. `sendmail` отдавал `RC=0`, postfix подписывал DKIM, письмо вставало в очередь и умирало по таймауту как `deferred` — то есть **тихо**. Владелец всё это время говорил, что писем не получает, и был прав. Теперь отправка с M1 прямым SMTP на `mail.wool2.online`.
**Вторая дорожка выдана отдельно:** `trusted-signers.json` с отпечатком `9ad5127b…` передан владельцу не почтой, а другим каналом — иначе проверка подлинности не имеет смысла, потому что подменивший комплект подменил бы и отпечаток рядом с ним.
**Состояние остального (из тела эпика, не из статусов):** субаккаунт Hetzner `u656648-sub1` создан и проверен по-настоящему (свой каталог читает, соседний не видит, удалять не может); комплект `ops/busfactor-kit/` прогнан сквозь всю цепочку на живом хранилище с отрицательным контролем, четыре условия остановки работают; вторая копия лежит у владельца в Загрузках.
**Осталось за владельцем:** взять письмо, скормить ИИ, посмотреть, отработает ли он корректно. Это и есть проверка, ради которой всё делалось: справится ИИ — справится человек.
2026-09-14T18:26:59.715Z · coordinator[14.09 18:26Z координатор] ⚠️ **АДРЕС ХРАНИТЕЛЯ В ЭТОМ ЭПИКЕ НЕ ЯВЛЯЕТСЯ ПОЧТОВЫМ ЯЩИКОМ.**
`sixbyy@wool2.online` записан в карточке как адрес хранителя репетиции. Проверено по журналу почтового сервера: письмо туда **доходит и доставляется**, но вот куда:
```
to=<noteclone-ingest@mailhub.duckdns.org>, orig_to=<sixbyy@wool2.online>,
relay=local, dsn=2.0.0, status=sent
```
Это **alias на продуктовый приём писем** (email-to-notebook), а не ящик человека. Хранитель никогда не увидит письмо как письмо — оно уходит внутрь продукта.
Мой промах при выборе адреса 13.09: я обосновала выбор тем, что этот адрес «не владеет ничем нашим» (в отличие от `fandyy2023`, на котором GitHub, и `fandyy2009`, на котором Oracle) — и это рассуждение верное. Но я **не проверила главного: читается ли он человеком**. Проверка заняла одну команду и не была сделана.
**Вторая причина, почему владелец не получал писем и на gmail:** они уходили с `From: noreply@sixbyy.com` через провайдерский релей, которому домен `sixbyy.com` отправку не разрешает. ISP отвечает `status=sent (250 ...)`, а gmail такое **молча роняет**. `status=sent` от своего же релея ничего не доказывает о доставке.
**Что сделано:** отправка переведена на `From: pi@mailhub.duckdns.org` — адрес, которому путь разрешён; пробное письмо отправлено, ждём подтверждения человеком.
**Что требует решения владельца:** назвать **реальный читаемый ящик** хранителя вместо `sixbyy@wool2.online`. Ограничение из прошлого разбора остаётся в силе: адрес не должен владеть нашей инфраструктурой, иначе репетиция доказывает меньше (`fandyy2023` владеет GitHub, `fandyy2009` — одним из Oracle-аккаунтов).
2026-09-14T18:42:06.301Z · coordinator[14.09 18:42Z координатор] # РЕПЕТИЦИЯ A ПРОШЛА И ДАЛА РЕЗУЛЬТАТ. Остановилась на шаге 3 — оба дефекта в ВЫДАЧЕ, не в комплекте
Владелец, выступая хранителем, скормил письмо обычному ИИ. Тот выполнил безопасную локальную часть и остановился:
```
{"ok": false, "code": "UNKNOWN_KEY",
"detail": "trust store entry is malformed: 'public_key_pem'"} exit=11
```
## Что сработало правильно
- архив `kit.tar.age` на месте, **SHA-256 сошёлся** с заявленным;
- `START-HERE.md` прочитан без всякого доступа;
- ⭐ исполнитель **не стал расшифровывать**, раз подлинность не подтверждена — остановка сработала ровно как задумано;
- серверы и живая инфраструктура не затронуты.
## Дефект 1 — из-за него всё встало. Мой.
Я собрала `trusted-signers.json` **заново и вручную**, положив туда только отпечаток ключа и свои поля (`schema`, `note`, `identity`, `algorithm`). Правильная схема — `min_kit_version_ordinal` + `signers[]` с `signer_identity`, **`public_key_pem`**, `key_sha256` (шаблон лежит в дереве: `ops/busfactor-kit/trusted-signers.example.json`). **Без открытого ключа проверка невозможна по устройству**, отпечатка недостаточно.
⚠️ Правильный файл **существовал с 13.09 22:05** — `nc-ops-scripts/.secrets/busfactor-trusted-signers.json`, с PEM и совпадающим отпечатком `9ad5127b…`. Я его не отправила, а сочинила новый. Это тот же класс ошибки, что и с письмом-приглашением в тот же день: **переделывала готовое вместо того, чтобы взять готовое**.
## Дефект 2. Тоже мой.
`verify_kit.py` не был отправлен вовсе — хотя само письмо-приглашение говорит, что программа проверки приходит **отдельной дорожкой**. Я написала это в письме и не сделала.
## Не передано — и это тоже выдача, а не комплект
- **Данные подаккаунта Hetzner** (`busfactor-kit`, только чтение, Storage Box #638776, основной пользователь `u656648`). Подаккаунт создан и проверен ещё 13.09 — но хранителю не выдан, поэтому шаги «скачать из основного места» и «повторить со второй копии» недостижимы.
- `age` не установлен у исполнителя — это ожидаемо и лечится одной командой, в инструкции есть.
## Исправлено
Собрана **папка второй дорожки**: правильный `trusted-signers.json` (с `public_key_pem`), `verify_kit.py`, `canonical_trust.py`, `age_backend.py` и `КАК-ПОЛЬЗОВАТЬСЯ.md` с точной командой и разбором всех четырёх кодов отказа (`UNKNOWN_KEY`, `INVALID_SIGNATURE`, `CORRUPTED_PACKAGE`, `TOO_OLD_VERSION`), включая предупреждение про щель «`ok: true`, но `START-HERE.md` не покрыт подписью».
**Вывод по репетиции:** она сделала ровно то, ради чего затевалась — нашла, что комплект собран правильно, а **выдан неполно**. Это находка, а не провал; дорого было бы обнаружить это в аварии.
2026-09-14T18:49:29.822Z · coordinator[14.09 18:49Z координатор] # КОМПЛЕКТ ПЕРЕСОБРАН И ПРОВЕРЕН: `ok: true`. Версия `2026.09.14-r2`
Продолжение репетиции: после починки второй дорожки я **сама запустила проверку** на комплекте владельца, прежде чем просить его повторить. Хорошо, что запустила — вскрылись два блокера.
## Блокер 1: программа проверки не запускалась вообще
`verify_kit.py` импортирует `ops.web409.trust` (77 КБ) — то есть тянет за собой кусок нашего репозитория. **У хранителя репозитория нет**, значит в аварии проверка не заработала бы. Доложила недостающее в папку второй дорожки (`ops/web409/trust.py`, `__init__.py`).
⚠️ Это дефект замысла, а не опечатка: «независимая дорожка» должна быть самодостаточной, иначе она не независимая.
## Блокер 2: старый комплект нельзя проверить в принципе
```
{"ok": false, "code": "STARTHERE_NOT_COVERED",
"detail": "manifest.json has no 'start_here' entry, so START-HERE.md is not covered
by the signature. This kit was built with a pack_kit.py from before START-HERE.md
was brought under the signature (WEB-641); its authenticity cannot be verified.
Repack the kit with the current pack_kit.py and re-sign it."}
```
То есть комплект от 13.09 собран упаковщиком **до** того, как START-HERE завели под подпись. Это ровно та щель, которую я описывала в письме как опасную, — и она оказалась не теоретической.
## Что сделано
Пересобрано нынешним упаковщиком на A1 (`age` есть только там), подписано ключом `owner-busfactor` по стоячей доверенности, проверено заново:
```
ok: true
manifest_sha256 c0557f425dd2d1d8...
archive_sha256 db34454615571200...
signer_identity owner-busfactor
signer_key_sha256 9ad5127b5e1f38ca...
kit_version 2026.09.14-r2 (порядковый 2)
recipients_count 2
warnings []
```
## ⭐ Попутно исправлен дефект, которого никто не замечал: получателей был ОДИН
В старом манифесте `recipients_count: 1`. Комплект открывался **единственным** ключом — при его потере доступ закрыт навсегда, и вся схема «каждый получатель открывает сам» не работала. Теперь **два независимых получателя**: хранитель и запасной. Упаковщик по умолчанию требует минимум двух (`--allow-single-recipient` — только для репетиций), то есть защита в коде была, а комплект собрали в обход неё.
Плюс в комплект вошла **свежая книга восстановления**: 121 828 байт против 109 188 в старом — она выросла с 13.09.
## Где владелец упрётся на следующем прогоне, сказано заранее
На **скачивании с Hetzner**: подаккаунт создан и проверен 13.09, но (а) его данные хранителю не выданы, (б) новый комплект туда ещё не положен. Это мои следующие шаги.
Закрытый ключ хранителя передан владельцу на его машину и **стёрт с сервера** (`shred`); открытые ключи и запасной остались в рабочем каталоге.
2026-09-14T20:01:40.794Z · coordinator[14.09 20:01Z координатор] # РЕПЕТИЦИЯ A: локальная часть пройдена ЦЕЛИКОМ. Граница названа точно
Владелец, выступая хранителем, скормил папку обычному ИИ. Результат:
- **подлинность проверена:** `ok: true`, версия `2026.09.14-r2`;
- **архив расшифрован** локальным `проверка/bin/age`;
- **книга восстановления и вопросы экзамена прочитаны**;
- ⭐ **боевые команды не запускались** — исполнитель остановился ровно там, где велено.
Это закрывает шаги 1–4 из пяти. Напомню, чего стоило до этого: первый прогон встал на шаге 3 (`UNKNOWN_KEY` — я собрала доверенный список без открытого ключа), второй — на отсутствии `age` (Homebrew потребовал обновить Command Line Tools, и в аварии этого пути бы не было). Оба дефекта были в **выдаче**, не в комплекте; оба закрыты — правильный список и готовая программа `age` теперь лежат в папке.
## Комплект выложен на Hetzner — шаг «скачать» стал проверяемым
Все четыре файла версии `2026.09.14-r2` загружены в `busfactor-kit` на Storage Box `u656648` — каталог, который читает подаккаунт хранителя `u656648-sub1` (создан и проверен 13.09: свой каталог читает, соседний не видит, удалять не может). Файлы от 13.09 заменены. Временные копии с A1 удалены.
Остаётся выдать хранителю данные подаккаунта — и тогда прогон пройдёт **от скачивания** до книги, без локальных костылей.
## ⭐ Готовый список выдачи, составленный самой репетицией
Исполнитель прошёл книгу по шагам и против **каждого** написал, чего не хватает. Это и есть «пакет доступов» из раздела F, но составленный не нами, а тем, кто реально упёрся:
| группа шагов | чего не хватает |
|---|---|
| A1–A8 (живая проверка) | A1, root, lock, live state; production services; systemd; `/proc` живых процессов; `<deploy.stateDir>/verified.json`; окно dryrun на `:3011` |
| B0–B16 (сборка) | repo, manifest, A1/A2; build host, lock, disk, deps; build tree и `node_modules`; migration tree; временная БД и live hashes; artifact dir |
| B17–B18 (посадка) | A1, tar и sidecar, root; activation/att-build/runtime env |
| B1–B5 (переход) | verified/receipts/units/catalog; prepared state; dryrun; systemd и controller; live evidence |
| D1 (миграции) | production DB и учётные данные |
| D2 (бэкап) | службы `hetzbk` и их секреты |
Отдельно исполнитель отметил, что шаги **B19 и B20 запускать вручную запрещено** — это внутренние стадии B3/B4, и ручной запуск ломает предусловия. Он это понял **из книги**, что само по себе хороший знак о качестве книги.
## Что осталось — решение владельца, последнее по этой линии
Граница дословно: «перед первым live-шагом нужны A1/A2, production-доступы, receipts и секреты владельцев».
**Вопрос:** хранитель получает боевые доступы **заранее** — или только описанный путь, как их добыть в аварии?
- Заранее: человек с комплектом поднимает систему немедленно; цена — доступы лежат у него всё время.
- Путь добычи: безопаснее; цена — в аварии добавляется шаг, который некому выполнить, если владельца нет.
Это `HUMAN_ACCESS_CONTINUITY` из раздела «остаток» эпика, и он закрывается только решением владельца. Техническая часть репетиции своё доказала.
2026-09-14T23:52:35.147Z · coordinator[14.09 23:52Z координатор] **ЗАКРЫВАЮ. Практический экзамен A пройден — и не один раз.**
**Что требовалось:** доступ без владельца, проверенный на практике.
**Как проверено:** владелец передавал папку исполнителю **семь раз** за ночь, каждый раз без каких-либо своих действий, кроме передачи. Последние прогоны:
- подлинность комплекта: `ok: true`, подписант `owner-busfactor`, версия `2026.09.14-r2`, отпечаток совпал, получателей 2;
- пакет доступов расшифрован **ключом хранителя**, права на ключ входа исполнитель привёл к `600` **сам**;
- **вход на обе боевые машины выполнен исполнителем**: A1 — службы активны, health `200`; A2 — ssh доступен, служб продукта нет (ожидаемо);
- на живой мишени выполнены проверки раздела D и **пробная запись в транзакции с откатом** — первое настоящее изменяющее действие;
- production не останавливался, не перезапускался, линия не переключалась, миграции на проде не запускались.
**Владелец при этом не делал ничего**, кроме передачи папки и слова «приступай». Именно это и требовалось доказать.
**Что этот экзамен НЕ покрывает и куда это уходит:** исполнение разделов B (сборка и посадка) и C (откат живого приложения) — они меняют боевой контур и требуют либо настоящей аварии, либо отдельного окружения. Ведётся в **WEB-655** (практический экзамен B), там же честная отметка «ни один из 53 шагов книги не выполнялся на боевом контуре».
Статус → `done`.
Воркер
не привязан — привязать:
curl -X POST https://bugs.wool2.online/api/web/assign -H 'content-type: application/json' \
-d '{"issueId":"WEB-656","session":"<имя tmux-сессии>","host":"m4"}'
Обновлён
2026-09-14T23:52:35.675Z