# Codex: режим полного удаления в установщике

## Репозиторий

- https://github.com/ochenstarik-ui/server-monitor-manager
- База: `main` @ `f7b10ac`
- Ветка: `codex/uninstall-mode`
- `main` защищён: PR обязателен, обязательны статусы `build-and-test` и `build`, force-push запрещён
- один PR — одна тема; описание PR заполняется **после** завершения CI
- теги в этом задании не создаются, релиз не выпускается

## Задача

В `deploy/smm-setup.sh` есть интерактивный режим: запуск без аргументов спрашивает роль и ставит Hub или узел. Строка выбора сейчас такая:

```
Choose role: 1) Hub  2) Node
```

Нужен **третий пункт: удалить систему с этой машины полностью.**

Это единственный предмет задания. Установочная часть не переделывается.

## Почему существующих команд недостаточно

`uninstall-agent`, `uninstall-control` и `uninstall-monitor` в `deploy/ochenstarik-server-monitor-manager.sh` снимают свои компоненты, но после них на машине остаётся:

- системные пользователи и группы `ochenstarik-smm-control`, `ochenstarik-smm-agent`, `ochenstarik-monitor`;
- конфигурация `/etc/wireguard/smm0.conf` и включённый юнит `wg-quick@smm0`;
- таблица nftables `inet ochenstarik_smm` и интерфейс `smm0`;
- каталоги состояния под `/var/lib/ochenstarik-server-monitor-manager*` и `/etc/ochenstarik-server-monitor-manager`;
- запись в `/etc/sudoers.d/ochenstarik-smm-control`;
- файл `/etc/sysctl.d/90-ochenstarik-smm-mesh.conf`;
- вспомогательные файлы в `/usr/local/libexec` и `/usr/local/sbin`.

Владелец проходил эту уборку вручную и знает список поимённо. Задача — сделать так, чтобы этого больше не требовалось.

## Требования к поведению

1. **Сначала показать, что будет удалено, потом спрашивать.** Список строится по фактическому состоянию машины: какие юниты найдены, какие пользователи существуют, есть ли таблица nftables, есть ли интерфейс `smm0`, какие каталоги непусты. Не печатать шаблон, в котором половина строк не относится к делу.

2. **Подтверждение — набранным словом, а не `y/N`.** Прецедент в проекте есть: `uninstall-control` требует `--confirm-destroy-control`. Случайное нажатие не должно сносить Hub вместе с его удостоверяющим центром.

3. **Порядок: сначала остановить службы, потом удалять юниты.** Это не педантизм, а известный случай. Юниты удалили при работающем процессе, процесс осиротел, продолжил держать порт 7443, и `userdel` отказал, потому что у пользователя оставался живой процесс. Правильная последовательность: `systemctl disable --now`, затем `pkill -u` по каждому пользователю, пауза, `pkill -9 -u`, и только после этого удаление файлов и учётных записей.

4. **Идемпотентность.** На машине, где ничего не устанавливалось, режим отрабатывает без ошибок, ничего не меняет и возвращает нулевой код.

5. **Ничего чужого.** На серверах владельца работает 3x-ui. Удаляются только объекты с собственными именами: юниты `ochenstarik-smm-*`, три перечисленных пользователя, таблица `inet ochenstarik_smm`, интерфейс `smm0`, каталоги под своими путями. Никаких `rm -rf` по маскам, способным задеть соседа по машине.

6. **Две глубины удаления.** Снять программу, сохранив резервные копии и базу Control, либо снести всё вместе с ними. Второе — отдельным подтверждением: вместе с базой уходит удостоверяющий центр, а с ним все выданные сертификаты и вся регистрация узлов. Отменить это будет нечем.

7. **В конце — проверка.** Напечатать состояние после уборки: свободны ли порты `7443` и `51820`, остались ли маршруты `10.77.0.`, остались ли юниты `ochenstarik-smm-*`, остались ли пользователи. Владелец проверяет чистоту именно этими четырьмя вопросами.

8. **Неинтерактивный вариант.** Команда с обязательным флагом подтверждения, без вопросов — для скриптов и повторной приёмки. Без флага команда отказывается работать.

## Тесты

В `tests/bootstrap/`:

- на машине без установленной системы режим отрабатывает без ошибок и ничего не меняет;
- после полной установки и последующего удаления не остаётся ни юнитов, ни пользователей, ни таблицы nftables, ни интерфейса, ни каталогов состояния;
- посторонний юнит и посторонний пользователь, созданные до удаления, остаются нетронутыми;
- неинтерактивный вариант без флага подтверждения отказывается работать;
- удаление при работающих службах не оставляет процессов, удерживающих порты.

## Границы

Antigravity ведёт Control и веб-консоль. **Не трогать:** `src/**`, `.github/workflows/windows-build.yml`.

Ваша область: `deploy/**`, `tests/bootstrap/**`, `docs/linux-bootstrap.md`.

## Критерий приёмки

- третий пункт выбора роли удаляет систему целиком;
- перед удалением показан список того, что найдено на машине;
- подтверждение требует набранного слова;
- службы останавливаются до удаления юнитов;
- посторонние объекты не затрагиваются;
- две глубины удаления, вторая с отдельным подтверждением;
- в конце напечатано состояние машины;
- неинтерактивный вариант работает только с флагом подтверждения;
- перечисленные тесты присутствуют и проходят;
- PR открыт, CI зелёный, PR не смержен до зелёного;
- тег не создаётся.

## Отчёт

В описании PR, раздельно: что проверено локально, что в CI со ссылками на прогоны, что не проверялось и почему.
