Files
DmitryandClaude Sonnet 5 d2e1e6876a 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
2026-09-03 07:06:10 +03:00

105 lines
6.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 намеренным решением.