docs: AI project context (docs/ai) and repository documentation refresh
- docs/ai/: stable, repo-verified context - README, architecture, tech-stack, edge-cases, plan (confirmed active work only), migration-tofu (the blue-green OpenTofu migration runbook and per-service findings), legacy-warning, links. - AGENTS.md: slimmed to a working contract that points at docs/ai instead of restating it; CLAUDE.md is an adapter that @-includes it. - README.md, ansible/README.md, ansible/roles/README.md, roles/lxc_docker_host/README.md: bring wording in line with the current control plane (Makefile entry point, registry, tofu, memoir-bot gone). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012uoq5AVK8mkBgg83Mq6o5V
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
5e27ba2513
commit
d2e1e6876a
@@ -0,0 +1,104 @@
|
||||
# Edge Cases и риски
|
||||
|
||||
## Proxmox Provisioning
|
||||
|
||||
- Handled: ряд service playbooks проверяет hostname существующего VMID перед
|
||||
изменением контейнера.
|
||||
- Gap: generic `roles/pve_lxc` не содержит общего foreign-VMID guard; часть callers
|
||||
и direct `pct` playbooks также не выполняет ownership assertion.
|
||||
- Gap: некоторые `pct start` tasks считают любой return code `255` допустимым, что
|
||||
может скрыть ошибку, не связанную с already-running state.
|
||||
- Unknown: `--check --diff` не моделирует Proxmox module calls и command-heavy
|
||||
playbooks полностью. `make dry-*` является preview, а не isolated simulation.
|
||||
|
||||
## Validation Semantics
|
||||
|
||||
- `playbooks/check.yml` проверяет Ansible reachability и `expected_lan_ip`.
|
||||
- `playbooks/status.yml` подавляет многие command errors и отображает DOWN/failed
|
||||
состояния в отчете; успешный exit code не означает healthy infrastructure.
|
||||
- `make lint` запускает ansible-lint и yamllint из корня репозитория и включает
|
||||
all-playbook syntax loop, то есть воспроизводит CI.
|
||||
- CI workflow не исполняется без включенных Gitea Actions и runner.
|
||||
- Ansible roles не имеют Molecule, idempotence или integration test harness.
|
||||
|
||||
## Network Failure Domains
|
||||
|
||||
- Потеря `ru-vps` нарушает обычный ProxyJump к большинству hosts и public Caddy.
|
||||
- Потеря OpenVPN site tunnel нарушает private upstream path public services.
|
||||
- Потеря Mihomo одновременно затрагивает egress Hermes, внешние Uptime Kuma probes,
|
||||
emergency Telegram и Gyro notifications.
|
||||
- Normal SSH использует `StrictHostKeyChecking=accept-new`; emergency и Gyro paths
|
||||
требуют заранее проверенных pinned host keys.
|
||||
- Proxmox API TLS validation по шаблону `.env.example` отключен по умолчанию.
|
||||
|
||||
## Secrets и Privilege
|
||||
|
||||
- Handled: ignored `.env`, Vault, `0600`, `no_log` и external password files не
|
||||
позволяют хранить ожидаемые secrets в tracked config.
|
||||
- Constraint: никогда не переносить значения из ignored/archived `.env` в docs,
|
||||
output или commits.
|
||||
- Risk: `bootstrap-pve-api-token.yml` вращает privileged token и переписывает весь
|
||||
корневой `.env` целиком, а не построчно. Теряются `MONITORING_*`, `EMERGENCY_*` и
|
||||
`PROXMOX_ROOT_PASSWORD`. С 2026-09-02 у задачи `backup: true`, но восстанавливать
|
||||
придётся вручную. Запускать только как отдельную осознанную операцию.
|
||||
- Constraint: строки в `.env` пишутся с префиксом `export`, и это не стиль:
|
||||
`bootstrap-monitoring-pve-token.yml` ищет их через `regexp: "^export NAME="`.
|
||||
Убрать префикс — значит получить дубликаты строк вместо обновления.
|
||||
- Risk: LXC управляются как root, shell hosts используют `ansible` с passwordless sudo.
|
||||
|
||||
## Backups и Updates
|
||||
|
||||
- Handled: SQLite backup API + integrity check, atomic MariaDB dump, per-profile
|
||||
`flock`, PBS/restic freshness audit и selective restore.
|
||||
- Gap: update failures не запускают automatic rollback; backup только обеспечивает
|
||||
возможность ручного recovery.
|
||||
- Gap: PBS audit проверяет freshness, но не выполняет restore или PBS data integrity
|
||||
drill. Обычный `restic check` не читает все data packs.
|
||||
- Gap: recurring Grimmory audit проверяет non-empty SQL dump, но не импортирует его
|
||||
во временную MariaDB.
|
||||
- Gap: CT 148 `emergency-bot` не имеет backup/monitoring в service registry.
|
||||
- Constraint: code-only downgrade Grimmory после Flyway migration запрещен; нужен
|
||||
previous image вместе с pre-upgrade database backup.
|
||||
- Concurrency: нет repository-wide lock от одновременных operator/update runs;
|
||||
preflight через `pgrep vzdump` имеет race до запуска нового backup.
|
||||
- Handled: storage-level `prune-backups` on PVE storage `pbs` removed
|
||||
declaratively; retention now runs centrally in PBS `prune-pbs`, so the PBS
|
||||
side is the only authority for PBS-backed retention. The weekly PBS-container
|
||||
backup on storage `backup` with `keep-last=2` remains an intentional
|
||||
exception.
|
||||
|
||||
## Monitoring
|
||||
|
||||
- Active Uptime Kuma и frozen Prometheus stack не должны запускаться как две
|
||||
параллельные monitoring architectures без отдельного решения.
|
||||
- Hardcoded Prometheus targets могут расходиться с inventory и service registry.
|
||||
- Central monitoring на `cloud-pc` не может независимо сообщить о полном отказе
|
||||
своего node без внешнего наблюдателя.
|
||||
|
||||
## Reverse Proxy и Firewall
|
||||
|
||||
- Handled: reverse proxy metadata, Caddyfile, container config и upstreams проходят
|
||||
validation до/после restart.
|
||||
- Constraint: Ansible не управляет lifecycle Caddy container на `ru-vps`.
|
||||
- Constraint: не упрощать Grimmory OPDS/KOReader handlers и не удалять его
|
||||
`DOCKER-USER` protection без эквивалентных compatibility/security checks.
|
||||
- Constraint: не включать cluster-wide PVE firewall без аудита всех guests с
|
||||
`firewall=1`.
|
||||
|
||||
## Grimmory MCP
|
||||
|
||||
- Handled и tested: pagination guards, optional 204/404 resources, concurrent auth
|
||||
promises, credential ownership/mode/no-follow checks, vault path containment,
|
||||
cover size/type validation, atomic note writes и preservation of user markers.
|
||||
- Gap: full sync не транзакционен и может завершиться с частично обновленным vault.
|
||||
- Gap: нет mutex для concurrent sync/index rebuild.
|
||||
- Gap: поиск existing note для каждой книги повторно сканирует весь notes directory.
|
||||
- External dependency: Python и vault-owned index script должны существовать и
|
||||
завершиться в timeout; они не управляются этим репозиторием.
|
||||
|
||||
## Требующие проверки состояния
|
||||
|
||||
- Завершена ли initial UI configuration AdGuard.
|
||||
- Создана ли DHCP reservation/exclusion для Grimmory `192.168.1.34`.
|
||||
- Настроены ли Gyro Vault secrets; tracked configuration не подтверждает их наличие.
|
||||
- Является ли отсутствие backup для CT 148 намеренным решением.
|
||||
Reference in New Issue
Block a user