metaagent: install v3.0.0, migrate docs/arch/* → .agent/

- install.sh: .agent/src/ (PROTOCOLS, COMMANDS, TEMPLATES, install.sh/ps1, GUIDE)
- .temp/ добавлен в .gitignore
- .agent/checkpoints.json: phases.init=completed, project_type=existing
- .agent/rules/project-rules.md: R1-R5 (инварианты, ловушки, куда лезть, проверки)
- .agent/context/analysis-report.md: стек, архитектура, конвенции, кандидаты CI
- .agent/context/project-state.md: сжатый слепок (хосты, сервисы, ADR)
- .agent/roadmap/sources.md: открытые вопросы слоёв 0-11 (бывший invariants.md)
- .agent/tasks/manifest.{json,md}: 16 задач A1-F + 23 в backlog
- .agent/decisions/0001-sops-secrets-paths.md: ADR для инварианта S1
- AGENTS.md: metaagent-шапка + сжатая выжимка nixos (yaml frontmatter сохранён)
- удалены docs/arch/{map,invariants,todo}.md
This commit is contained in:
2026-10-09 20:37:14 +03:00
parent 7c9aa24779
commit 16644fcc0b
48 changed files with 4389 additions and 916 deletions
@@ -0,0 +1,83 @@
# ADR-0001: sops-пути — только через `config.sops.secrets.<name>.path`
**Статус:** accepted
**Дата:** 2026-10-09
**Контекст:**
sops-nix материализует секреты на `/run/secrets/<attr>` по умолчанию.
Атрибут sops-блока (`config.sops.secrets.<attr>`) — единственный источник
истины для on-disk пути. Любой `path =` override на sops-блоке плюс хардкод
`"/run/secrets/<attr>"` в потребителе делает потребителя **молча**
сломанным: `nixos-rebuild` проходит, сервис стартует, файл читается — но
контент от прошлой версии или пустой. Симптом приходит из рантайма, не из CI.
До этой правки (см. «Обратное») в кодовой базе были хардкоды путей в 5
местах: `authelia.nix`, `open-webui.nix`, `tape-rotation.nix`, `remnawave.nix`.
В `remnawave.nix` тот же риск был двойной: путь хардкожен и в генераторе,
и в контейнере → расхождение двух копий = silent breakage.
**Рассматриваемые альтернативы:**
1. **A. `${config.sops.secrets.<attr>.path}`** — единая точка истины. Любой
`path =` override автоматически подхватывается потребителем.
2. **B. Хелпер `sopsPath = name: "/run/secrets/${name}"`** — был в `authelia.nix:51`
до правки. Компактнее в написании, но тащит хардкод `/run/secrets/` в API
и делает невозможным `path =` override без правки потребителя.
3. **C. `let envFile = "/run/secrets/${name}"; in { … }` для композитных
случаев** — для `remnawave.nix`, где один и тот же env-файл читается и
генератором, и контейнером. Используется, но с явным комментарием.
**Решение:** выбран вариант **A** для прямого доступа к одному секрету и
вариант **C** для композитных env-файлов в `remnawave.nix` (с комментарием).
**Обоснование:**
- **Единая точка истины.** Атрибут sops-блока — единственное место, где
определяется on-disk путь. Потребитель ссылается на `${config.sops.secrets.<attr>.path}`.
- **Симметрия с `mkUserSecret`.** `users.nix:33-41` уже использует этот
паттерн (`config.sops.secrets.<name>.path`) — единый стиль по репо.
- **Без хелпера.** `sopsPath = name: "/run/secrets/${name}"` выглядит
компактнее, но скрывает хардкод `/run/secrets/`. Когда кто-то добавит
`path = "/var/lib/..."` в sops-блок, потребитель через хелпер молча
сломается.
- **Двухкопийный env-файл в remnawave.nix** — композитный случай, где
`let`-биндинг в одном scope с комментарием «не дублировать литерал»
делает связь явной.
**Последствия:**
- Позитивные:
- `nix flake check` (после T1, T2) ловит несоответствие путей в compile-time.
- `path =` override в sops-блоке не ломает потребителя молча.
- Единый стиль по репо: 5 мест исправлены, новые пишутся по образцу.
- Негативные:
- Длиннее в написании, чем `"/run/secrets/${name}"`.
- Риски:
- Если кто-то добавит нового потребителя sops и напишет литерал
`/run/secrets/<name>` — молчаливое расхождение. Защита: код-ревью +
кандидат в CI-проверки (`secrets/missing-paths.nix` или grep).
**Invariant:**
> Любой потребитель sops-секрета в `modules/` ссылается на путь через
> `${config.sops.secrets.<attr>.path}`, а не через литерал
> `"/run/secrets/<attr>"`. Атрибут sops-блока — единственный источник
> истины для on-disk пути.
Зафиксировано в `.agent/rules/project-rules.md` (R1.7) + `analysis-report.md §8`.
**Обратное (где было сломано до этой правки):**
- `modules/server/authelia.nix:51,108,109` — через хелпер `sopsPath = name: "/run/secrets/${name}"`.
- `modules/containers/open-webui.nix:95` — литеральный хардкод.
- `modules/containers/tape-rotation.nix:61` — литеральный хардкод.
- `modules/containers/remnawave.nix:61, 129, 136` — литеральный хардкод, в двух местах (генератор + контейнер).
**Затронутые файлы (после правки):**
- `modules/server/authelia.nix:107-108`
- `modules/containers/open-webui.nix:101`
- `modules/containers/tape-rotation.nix:63`
- `modules/containers/remnawave.nix:16, 70, 138, 145` — `let`-биндинг для композитного env-файла (вариант C).
+14
View File
@@ -0,0 +1,14 @@
{
"version": "3.0.0",
"updated_at": "2026-10-09T20:30",
"decisions": [
{
"id": "0001",
"title": "sops-пути — только через config.sops.secrets.<name>.path",
"status": "accepted",
"date": "2026-10-09",
"file": ".agent/decisions/0001-sops-secrets-paths.md",
"tags": ["sops", "secrets", "security", "invariant"]
}
]
}