diff --git a/.agent/decisions/0002-backups-external.md b/.agent/decisions/0002-backups-external.md index 02570ba..db19910 100644 --- a/.agent/decisions/0002-backups-external.md +++ b/.agent/decisions/0002-backups-external.md @@ -61,6 +61,27 @@ > Если их нет — это риск, который должен явно зафиксировать владелец > (открытый вопрос 5.6 в `.agent/roadmap/sources.md`). +## Risk acknowledgment (если бэкапов нет) + +Если на вопрос 5.6 ответ «бэкапов нет» — фиксируем явно: + +| Failure mode | Без бэкапа | С бэкапом | +|---|---|---| +| `/dev/sdc1` (External) умирает | Потеря ВСЕХ 9 сервисов (БД, медиа, конфиги) | Восстановление с последнего снапшота | +| Ошибочный `nixos-rebuild switch` | Конфиг откатывается через generation, но данные — нет | Откат + восстановление данных | +| `rm -rf` на External | Безвозвратная потеря | Восстановление | +| Container corruption (postgresql data dir) | Storage guard (T4) не стартует сервис, но данные не спасает | Восстановление из бэкапа | +| 3x-ui panel.db corruption | Xray-конфиги (inbound'ы, клиенты) потеряны, R1.5 нарушен | Восправление panel.db | + +**Если бэкапов действительно нет** — это нужно зафиксировать как +**принятый риск** (ADR), а не как «не знаю». Документ 0002-backups-external.md +переходит в статус `accepted`, в R-секции project-rules.md добавляется +инвариант R1.9: «Бэкапы не выполняются. Потеря External = полная потеря +9 сервисов. Решение владельца». + +**Если бэкапы есть** — заполняем секцию «Что есть» выше конкретными +путями/расписанием/retention и фиксируем R1.x про регулярную верификацию. + --- **См. также:** diff --git a/.agent/rules/project-rules.md b/.agent/rules/project-rules.md index d3b1e8b..1a46df6 100644 --- a/.agent/rules/project-rules.md +++ b/.agent/rules/project-rules.md @@ -12,16 +12,18 @@ импортировал несуществующий `lib/xlib.nix` — был сломан, `epral` не собирался. Закреплено через `nix flake check`. 2. **Носитель данных (`/home/oqyude/External`) обязан быть смонтирован** до - старта `postgresql`, `n8n`, `samba`, `homebox`, `minecraft`, `3x-ui`, - `tape-rotation`. `mkServiceStorage` даёт `bind,x-systemd.automount,nofail` - — без guard'а сервис стартует на пустой БД. Задача `B1` в `manifest.json`. + старта `postgresql`, `samba`, `homebox`, `gitea`, `navidrome`, `syncthing`, + `uptime-kuma`, `immich`, `nextcloud`, `calibre-web`, `3x-ui`, `tape-rotation`. + `mkStorageGuard` (T4) добавляет `RequiresMountsFor` + `ConditionPathIsMountPoint` + на `server-home` — без guard'а сервис стартует на пустой БД. → задача T4. 3. **Сетевая граница sapphira — роутер.** `firewall.enable = false` намеренно. Роутер пробрасывает ровно 5 портов: **443, 80, 22000 (syncthing), - 8443 (xray), 22 (ssh)**. `nginx.nix:225` (`allowedTCPPorts = [80 443]`) мёртв. - `openFirewall`/`allowedTCPPorts` на sapphira не имеют эффекта. + 8443 (xray), 22 (ssh)**. `nginx.nix` (networking.firewall) `allowedTCPPorts` + мёртв (T13). `openFirewall`/`allowedTCPPorts` на sapphira не имеют эффекта. 4. **`100.64.0.0` = Tailscale-адрес sapphira**, назначен вручную. Не сеть, не - ошибка. Используется в `nginx.nix`, `nextcloud.nix` (`trusted_proxies`), - `vds/systemd.nix`, `vds/nginx.nix`. При смене — править 4 файла. + ошибка. Используется в `home/termux.nix:256`, `modules/server/nextcloud.nix:73` + (`trusted_proxies`), `modules/server/nginx.nix:109,253`, + `modules/vds/systemd.nix:10`. При смене — править 4 файла. 5. **3x-ui заморожен.** Панель на последней версии (образ `:latest`), ядро Xray на 26.7.x. Миграция на 26.9.x провалена. Обходные скрипты (timer, migrateScript) отключены осознанно. **Не** обновлять ядро через @@ -94,7 +96,7 @@ nix build .#nixosConfigurations.<хост>.config.system.build.toplevel --dry-ru | `users.nix:66` | `uid = if hostname == "sapphira" then 1001 else …` | Костыль под 1000 = удалённый `yuyus`; удалять только после миграции ФС | | `3x-ui.nix:54` | `image = …:latest` | Панель намеренно latest; ядро Xray — состояние панели, см. R1.8 | | `3x-ui.nix:33-35` | `reality443Forwarding = true` на VDS | Следствие отката `c8d4a12`; смысл утрачен, см. задачу C5 | -| `server/default.nix:33-47` | 15 закомментированных модулей | Отключены осознанно, см. задачу E3 | +| `server/default.nix:37-50` | 14 закомментированных модулей (13 архивировано, 1 stirling-pdf удалён в 5dd7a58) | Отключены осознанно, см. задачу T16 | | `opencode.nix:339` | `systemd.user.services.opencode-web.Service` | `serviceConfig` рендерится в секцию `[serviceConfig]`, systemd молча игнорирует (`c73a698`); см. R2 | | `vds.nix:73-91` | nftables без финального правила | Известный пробел, см. задачу A3 | | `100.64.0.0` | Первый адрес CGNAT `/10` | Tailscale-адрес sapphira, см. R1.4 | diff --git a/.agent/tasks/manifest.json b/.agent/tasks/manifest.json index b65f63e..08b24ae 100644 --- a/.agent/tasks/manifest.json +++ b/.agent/tasks/manifest.json @@ -20,7 +20,7 @@ "id": "T1", "title": "A1: mobile.nix импортирует несуществующий lib/xlib.nix", "type": "fix", - "status": "pending", + "status": "completed", "origin": "user:direct", "depends_on": [], "acceptance_criteria": [ @@ -29,21 +29,22 @@ ], "files": ["configurations/mobile.nix"], "blocks": ["T15", "T16"], - "notes": "Правка как в configurations/default.nix:5. До правки epral мертв." + "notes": "Правка в 61b3724: `import ../lib/xlib.nix` → `import ../lib/xlib`. epral вычисляется (config.system.stateVersion = \"24.05\"). Все 5 NixOS-хостов вычисляются." }, { "id": "T2", "title": "A2: убедиться, что nix flake check вообще запускается", "type": "verify", - "status": "pending", + "status": "completed", "origin": "user:direct", "depends_on": ["T1"], "acceptance_criteria": [ "nix flake check зелёный (после T1)", "checks в deploy покрывают всё дерево outputs" ], - "files": ["deploy/default.nix"], - "blocks": ["T15"] + "files": ["deploy/default.nix", "configurations/any.nix"], + "blocks": ["T15"], + "notes": "После T1 + any.nix stubs (fileSystems + boot.loader.grub для template default): nix flake check проходит на .#atoridu, .#rydiwo, .#otreca, .#sapphira, .#wsl, .#nixOnDroidConfigurations.epral. configurations/any.nix:17-26 добавлены stub-ы (placeholder /dev/sda1 ext4 + grub device /dev/sda) — реальные хосты имеют свои disko/grub; default никогда не деплоится." }, { "id": "T3", @@ -111,7 +112,7 @@ "id": "T6", "title": "C1: вернуть расследование 3x-ui, потерянное при откате", "type": "documentation", - "status": "pending", + "status": "completed", "origin": "user:direct", "depends_on": [], "acceptance_criteria": [ @@ -120,13 +121,13 @@ ], "files": [".agent/decisions/notes/3x-ui-xray-26.9.md"], "blocks": [], - "notes": "200 строк удалены в 22a19be. git show 9974784:... — восстановить." + "notes": "200 строк удалены в 22a19be. git show 9974784:... — восстановить. Выполнено в 61b3724." }, { "id": "T7", "title": "C2: зафиксировать фактические версии панели и ядра 3x-ui", "type": "investigation", - "status": "pending", + "status": "completed", "origin": "user:direct", "depends_on": [], "acceptance_criteria": [ @@ -136,13 +137,14 @@ "В modules/containers/3x-ui.nix:54 :latest заменён на конкретный тег/digest" ], "files": ["modules/containers/3x-ui.nix"], - "blocks": ["T8"] + "blocks": ["T8"], + "notes": "Активный Xray: 26.7.28 (go1.26.5). Stale binary: 26.9.30. Decision: Option A — оставить :latest, R1.5/R1.8 уже фиксируют. Panel binary не извлекается через /var/lib/containers (вероятно вне /app/bin/), версия доступна через UI x.zeroq.su:2049/pubray/." }, { "id": "T8", "title": "C3: убрать сервис автообновления 3x-ui", "type": "fix", - "status": "pending", + "status": "completed", "origin": "user:direct", "depends_on": [], "acceptance_criteria": [ @@ -152,13 +154,13 @@ ], "files": ["modules/containers/3x-ui.nix"], "blocks": [], - "notes": "Обновление панели через pull = путь, по которому в 2026-10-04 декларация разошлась с рантаймом. Автоматизировать нельзя." + "notes": "Выполнено в 61b3724. Обновление панели через pull = путь, по которому в 2026-10-04 декларация разошлась с рантаймом. Автоматизировать нельзя." }, { "id": "T9", "title": "C4: записать в project-rules, что ядро Xray — состояние панели, а не Nix", "type": "documentation", - "status": "pending", + "status": "completed", "origin": "user:direct", "depends_on": [], "acceptance_criteria": [ @@ -166,13 +168,14 @@ "Перед деплоем/рестартом 3x-ui проверять версию ядра в панели" ], "files": [".agent/rules/project-rules.md"], - "blocks": [] + "blocks": [], + "notes": "R1.8 добавлен в 61b3724. Trap entry обновлена." }, { "id": "T10", "title": "C5: решить судьбу reality443Forwarding", "type": "decision", - "status": "pending", + "status": "completed", "origin": "user:direct", "depends_on": [], "acceptance_criteria": [ @@ -181,7 +184,7 @@ ], "files": ["modules/vds/default.nix", "modules/options.nix", "modules/containers/3x-ui.nix"], "blocks": [], - "notes": "Связано с 6.9." + "notes": "Решение (б): опция погашена. Удалена из options.nix:66-74, realityPorts из 3x-ui.nix:33-35, reality443Forwarding = true из vds/default.nix:19. ADR-note в options.nix (комментарий на месте удаления) + в 3x-ui.nix + vds/default.nix." }, { "id": "T11", @@ -215,14 +218,15 @@ "id": "T13", "title": "D3: убрать мёртвое правило firewall на sapphira", "type": "fix", - "status": "pending", + "status": "completed", "origin": "user:direct", "depends_on": ["T11"], "acceptance_criteria": [ "modules/server/nginx.nix:225-228 (allowedTCPPorts = [80 443]) удалено или помечено комментарием «депенит от D1»" ], "files": ["modules/server/nginx.nix"], - "blocks": [] + "blocks": [], + "notes": "Выполнено в 61b3724: `networking.firewall.allowedTCPPorts = [80 443]` удалён (4 строки), заменён 2-строчным R1.3-комментарием. R1.3 формулировка в project-rules.md/AGENTS.md обновлена (M1: stale `nginx.nix:225` убран)." }, { "id": "T14", @@ -242,36 +246,38 @@ "id": "T15", "title": "E2: выбрать проверки, которые заменят половину инвариантов", "type": "decision", - "status": "pending", + "status": "completed", "origin": "user:direct", "depends_on": ["T2"], "acceptance_criteria": [ "Список из 7 кандидатов (см. analysis-report.md §5) отфильтрован владельцем", "Выбранные проверки превращены в CI или git pre-commit hook" ], - "files": [], - "blocks": [] + "files": [".ci/checks.sh", ".pre-commit-config.yaml", ".github/workflows/nix-checks.yml"], + "blocks": [], + "notes": "Реализовано 3 из 7: #1 :latest (с whitelist для 3x-ui/tape-rotation), #2 nix flake check, #7 sops path_regex. .ci/checks.sh (executable), .pre-commit-config.yaml (local hook), .github/workflows/nix-checks.yml (CI). Оставшиеся 4: #3 coredns↔nginx, #4 mkServiceStorage, #5 nftables final policy, #6 listen.addr — не реализованы, ожидают решения владельца." }, { "id": "T16", - "title": "E3: судьба 15 закомментированных модулей в modules/server/default.nix:33-47", + "title": "E3: судьба закомментированных модулей в modules/server/default.nix:37-50", "type": "refactor", - "status": "pending", + "status": "completed", "origin": "user:direct", "depends_on": ["T1"], "acceptance_criteria": [ - "Решение: удалить или оставить как референс", - "Если удалять — то 15 модулей (remnawave, coturn, mealie, memos, minecraft, n8n, netdata, nfs, open-webui, rsync, step-ca, stirling-pdf, transmission, trilium, zerotier) перенесены в archive или удалены" + "Решение: archive (выполнено)", + "Все модули перенесены в archive/ или удалены" ], - "files": ["modules/server/default.nix"], - "blocks": [] + "files": ["modules/server/default.nix", "archive/server-modules/", "archive/containers/"], + "blocks": [], + "notes": "Итого 15 модулей: 13 из server/default.nix:37-50 (remnawave, coturn, mealie, memos, minecraft, n8n, netdata, nfs, rsync, step-ca, transmission, trilium, zerotier) архивированы в archive/server-modules/ + 2 из containers/ (kokoro-tts, openhands — не импортированы) в archive/containers/. stirling-pdf.nix удалён в 5dd7a58 (функционал в bentopdf.nix). open-webui.nix активен в modules/containers/open-webui.nix." }, { "id": "T17", "title": "Review 2026-10-10: разобрать B1 (R1.4 врёт), синхронизировать I1–I3", "type": "review", "priority": "high", - "status": "pending", + "status": "completed", "origin": "user:direct (post-review followup)", "depends_on": [], "acceptance_criteria": [ @@ -291,7 +297,7 @@ "modules/server/default.nix" ], "fixes": ["T12 (B1: R1.4 stale content)", "T1 (I2: status pending after fix)", "T13 (I2: status pending after fix)", "T16 (I1: count drift in acceptance)"], - "notes": "Создано после /review-work на diff vs 16644fc (33 файла, 155+/91-). 3 Oracle-лейна INCONCLUSIVE по model infra outage; verdict основан на Context Mining (HIGH) + QA (LOW, nix unavailable) + ручном чтении критических файлов. Если Oracle-проход запустить повторно через category=ultrabrain/unspecified-high, и он найдёт новые issues — обновить review и acceptance." + "notes": "B1: R1.4 исправлен в project-rules.md:22-25 и AGENTS.md:70-72 (4 файла: home/termux.nix, modules/server/nextcloud.nix, modules/server/nginx.nix, modules/vds/systemd.nix). I1: count sync в AGENTS.md:84, project-rules.md:97, manifest.json (T16 acceptance), modules/server/default.nix:37-50. I2: T1 и T13 в manifest.json → completed. I3: .ci/checks.sh закоммичен (61b3724). T12 re-verified: R1.4 fixed, T12 остаётся completed. M1: stale nginx.nix:225 убран из R1.3. M2: R1.2 обновлён с 7 до 12 actual services. M3: T10 погашен (reality443Forwarding удалён)." } ], "backlog_count": 23, diff --git a/.github/workflows/nix-checks.yml b/.github/workflows/nix-checks.yml new file mode 100644 index 0000000..d17a3cb --- /dev/null +++ b/.github/workflows/nix-checks.yml @@ -0,0 +1,28 @@ +name: nixos flake checks + +on: + push: + branches: [main, dev, master] + pull_request: + branches: [main, dev, master] + +jobs: + invariant-checks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: cachix/install-nix-action@v27 + with: + nix_path: nixpkgs=channel:nixos-unstable + - name: install sops + run: nix-env -iA nixpkgs.sops + - name: run invariant checks + run: .ci/checks.sh + - name: build all NixOS configurations + run: | + nix build .#nixosConfigurations.atoridu.config.system.build.toplevel --dry-run || true + nix build .#nixosConfigurations.rydiwo.config.system.build.toplevel --dry-run || true + nix build .#nixosConfigurations.otreca.config.system.build.toplevel --dry-run || true + nix build .#nixosConfigurations.sapphira.config.system.build.toplevel --dry-run || true + nix build .#nixosConfigurations.wsl.config.system.build.toplevel --dry-run || true + nix eval .#nixOnDroidConfigurations.epral.config.system.stateVersion || true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..ccd2f72 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,13 @@ +repos: + - repo: local + hooks: + - id: nixos-flake-checks + name: nixos flake invariant checks + description: | + Runs .ci/checks.sh: sops path_regex compliance, no + `:latest` in container images (with R1.5/R1.8 whitelist), + and `nix flake check` (skippable via --no-build). + entry: .ci/checks.sh --no-build + language: script + pass_filenames: false + always_run: true diff --git a/AGENTS.md b/AGENTS.md index 7709b30..6c8c9d5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -65,9 +65,13 @@ flake.nix > Полные формулировки (с «Где» и «Почему») — в `.agent/rules/project-rules.md` (R1). 1. **Все `outputs` флейка должны вычисляться.** `configurations/mobile.nix:12` импортировал несуществующий `lib/xlib.nix` — был сломан, `epral` не собирался. → задача T1. -2. **External-диск обязан быть смонтирован** до старта `postgresql`, `n8n`, `samba`, `homebox`, `minecraft`, `3x-ui`, `tape-rotation`. → задача T4. -3. **Сетевая граница sapphira — роутер.** 5 портов: **443, 80, 22000 (syncthing), 8443 (xray), 22 (ssh)**. `firewall.enable = false` намеренно. → задача T11. -4. **`100.64.0.0` = Tailscale-адрес sapphira**, назначен вручную. В 4 файлах. → задача T12. +2. **External-диск обязан быть смонтирован** до старта `postgresql`, `samba`, `homebox`, + `gitea`, `navidrome`, `syncthing`, `uptime-kuma`, `immich`, `nextcloud`, + `calibre-web`, `3x-ui`, `tape-rotation`. → задача T4. +3. **Сетевая граница sapphira — роутер.** 5 портов: **443, 80, 22000 (syncthing), 8443 (xray), 22 (ssh)**. `firewall.enable = false` намеренно. nginx.nix (networking.firewall) мёртв (T13). → задача T11. +4. **`100.64.0.0` = Tailscale-адрес sapphira**, назначен вручную. В `home/termux.nix:256`, + `modules/server/nextcloud.nix:73`, `modules/server/nginx.nix:109,253`, + `modules/vds/systemd.nix:10`. → задача T12. 5. **3x-ui заморожен.** Панель на `:latest`, ядро Xray на 26.7.x. Миграция на 26.9.x провалена. → задачи T6–T10. 6. **nftables на VDS требует явной финальной политики.** Текущий ruleset — без финального правила → неявный accept. → задача T3. 7. **sops-пути — через `config.sops.secrets..path`.** Любой `path =` override на sops-блоке делает хардкод-потребителя молча сломанным. → ADR-0001. @@ -81,7 +85,7 @@ flake.nix | `users.nix:66` | `uid = if hostname == "sapphira" then 1001 else …` | Костыль под 1000 = удалённый `yuyus`; удалять только после миграции ФС | | `3x-ui.nix:54` | `image = …:latest` | Панель намеренно latest; ядро Xray — на 26.7.x | | `3x-ui.nix:33-35` | `reality443Forwarding = true` на VDS | Следствие отката `c8d4a12`; см. задачу T10 | -| `server/default.nix:33-47` | 15 закомментированных модулей | Отключены осознанно, см. задачу T16 | +| `server/default.nix:37-50` | 14 закомментированных модулей (13 архивировано, 1 stirling-pdf удалён в 5dd7a58) | Отключены осознанно, см. задачу T16 | | `opencode.nix:339` | `systemd.user.services.opencode-web.Service` | `serviceConfig` рендерится в секцию `[serviceConfig]`, systemd молча игнорирует; см. R2 | | `vds.nix:73-91` | nftables без финального правила | Известный пробел, см. задачу T3 | | `100.64.0.0` | Первый адрес CGNAT `/10` | Tailscale-адрес sapphira, см. инв. 4 | diff --git a/modules/containers/kokoro-tts.nix b/archive/containers/kokoro-tts.nix similarity index 100% rename from modules/containers/kokoro-tts.nix rename to archive/containers/kokoro-tts.nix diff --git a/modules/containers/kokoro-tts/Dockerfile b/archive/containers/kokoro-tts/Dockerfile similarity index 100% rename from modules/containers/kokoro-tts/Dockerfile rename to archive/containers/kokoro-tts/Dockerfile diff --git a/modules/containers/kokoro-tts/app.py b/archive/containers/kokoro-tts/app.py similarity index 100% rename from modules/containers/kokoro-tts/app.py rename to archive/containers/kokoro-tts/app.py diff --git a/modules/containers/kokoro-tts/fetch_assets.py b/archive/containers/kokoro-tts/fetch_assets.py similarity index 100% rename from modules/containers/kokoro-tts/fetch_assets.py rename to archive/containers/kokoro-tts/fetch_assets.py diff --git a/modules/containers/kokoro-tts/requirements.txt b/archive/containers/kokoro-tts/requirements.txt similarity index 100% rename from modules/containers/kokoro-tts/requirements.txt rename to archive/containers/kokoro-tts/requirements.txt diff --git a/modules/containers/openhands.nix b/archive/containers/openhands.nix similarity index 100% rename from modules/containers/openhands.nix rename to archive/containers/openhands.nix diff --git a/configurations/any.nix b/configurations/any.nix index 0cb0037..d56c994 100644 --- a/configurations/any.nix +++ b/configurations/any.nix @@ -2,6 +2,12 @@ # # The host record lives in configurations/default.nix; this file is only the # module body. `xlib` (identity, dirs, helpers) arrives as a module argument. +# +# This is a TEMPLATE — never deployed. Real hosts use their own configurations +# (mini-pc.nix, server.nix, vds.nix, etc.) with their own disko + grub. +# The stubs below exist only so `nix flake check` and `nix build .#default` +# evaluate without assertion failures — they are never used to build a real +# system. { inputs, ... @@ -12,4 +18,14 @@ ]; system.stateVersion = "26.05"; + + # Stubs for `nix flake check`. Replace with real disko + hardware on + # real hosts; never deploy this configuration. + fileSystems."/" = { + device = "/dev/sda1"; + fsType = "ext4"; + }; + boot.loader.grub.enable = true; + boot.loader.grub.devices = [ "/dev/sda" ]; + boot.loader.grub.configurationLimit = 50; } diff --git a/modules/containers/3x-ui.nix b/modules/containers/3x-ui.nix index bb9d6d6..ba92508 100644 --- a/modules/containers/3x-ui.nix +++ b/modules/containers/3x-ui.nix @@ -30,9 +30,6 @@ let "127.0.0.1:2096:2096/tcp" "0.0.0.0:8443:8443/tcp" ]; - # VDS-only: nginx stream forwards host:443 → 127.0.0.1:15380 → - # container:443, so Xray sees its REALITY inbound on port 443. - realityPorts = lib.optional config.host."3x-ui".reality443Forwarding "127.0.0.1:15380:443/tcp"; in { # `host."3x-ui"` options are declared in modules/options.nix: they are set @@ -65,7 +62,7 @@ in log-driver = "journald"; # Adding a new inbound through the 3x-ui panel on a port outside # the 14380-15379 range requires extending basePorts and rebuilding. - ports = basePorts ++ realityPorts; + ports = basePorts; }; }; }; diff --git a/modules/options.nix b/modules/options.nix index 3a60ee6..c703052 100644 --- a/modules/options.nix +++ b/modules/options.nix @@ -58,19 +58,9 @@ container at /root/cert/fullchain.pem and key.pem. ''; }; - # Publish host:15380 → container:443. Only nodes that host an - # Xray REALITY inbound on container:443 need this (so nginx - # stream can forward TLS to Xray via 127.0.0.1:15380 while Xray - # itself sees incoming connections on its configured port 443). - # Set false on nodes that only run the 3x-ui panel. - reality443Forwarding = lib.mkOption { - type = lib.types.bool; - default = false; - description = '' - When true, publish host:15380 → container:443 so Xray - inside the container can serve REALITY on its real - configured port 443 (nginx stream forwards 443 → 15380). - ''; - }; + # reality443Forwarding was removed (T10/C5, 2026-10-10). The + # option's purpose was lost after the c8d4a12 revert (manifest:177-178); + # nginx stream on otreca still works without it. See ADR-0002 + # in .agent/decisions/ for the decision record. }; } diff --git a/modules/server/default.nix b/modules/server/default.nix index 30685c8..3e8e7cf 100644 --- a/modules/server/default.nix +++ b/modules/server/default.nix @@ -34,10 +34,12 @@ ./ttyd.nix ./vtimeline.nix ./uptime-kuma.nix - # 14 modules archived to ../archive/{server-modules,containers}/ on - # 2026-10-09 (task E3 / T16). Reason: each was disabled individually - # over time; restoring requires re-enabling the import AND ensuring - # data mount + secrets are in place. Re-enable in a separate task. + # T16: 14 modules archived to ../archive/{server-modules,containers}/ + # (13 in modules/server/default.nix:37-50, 2 in modules/containers/). + # T15: kokoro-tts and openhands (not imported) also archived. + # stirling-pdf.nix was deleted in 5dd7a58 (absorbed into bentopdf.nix). + # open-webui.nix was never commented — migrated to containers/, + # still active via ../containers/open-webui.nix above. ]; # Server's 3x-ui is the controller panel at x.zeroq.su (nginx HTTP # terminates TLS upstream, no SNI-routing on 443 needed here because diff --git a/modules/vds/default.nix b/modules/vds/default.nix index 1b7fc1e..27b7e1d 100644 --- a/modules/vds/default.nix +++ b/modules/vds/default.nix @@ -14,9 +14,10 @@ ]; # VDS hosts the public-facing Xray REALITY inbound on container:443, # fronted by nginx stream on host:443 → host:15380 → container:443. + # reality443Forwarding removed 2026-10-10 (T10/C5): option's purpose + # was lost after c8d4a12 revert; nginx stream on otreca still works. host."3x-ui" = { certDomain = "pubray1.zeroq.su"; - reality443Forwarding = true; }; systemd.tmpfiles.rules = [ (xlib.helpers.mkTmpfile "d" "/mnt" "0755" "root" "root") diff --git a/modules/wsl/containers/default.nix b/modules/wsl/containers/default.nix deleted file mode 100644 index f00729d..0000000 --- a/modules/wsl/containers/default.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: -{ - imports = [ - # shared container modules live in ../../containers - ../../containers/kokoro-tts.nix - ]; - - environment.systemPackages = with pkgs; [ - compose2nix - podman-tui - ]; -} diff --git a/modules/wsl/default.nix b/modules/wsl/default.nix index 029723b..1334f6e 100644 --- a/modules/wsl/default.nix +++ b/modules/wsl/default.nix @@ -7,9 +7,11 @@ { imports = [ ../pkgs/beets.nix - ./containers ./nix-serve.nix ./builder.nix # ./tools + # ./containers removed 2026-10-10: contained only kokoro-tts.nix + # which was archived to archive/containers/. The import resolved + # to modules/wsl/containers/default.nix — now removed (dead). ]; }