# infra-inventory ## Goal Полная инвентаризация инфраструктуры kzntsv на **двух уровнях detail**: 1. **Public-вид** — все (босс в `.workshop`, агенты в любом проекте, разрабы) видят общую карту: «где что живёт». Канонические hostnames, IP-карта, anti-aliases. Light, без секретов и внутренней topology. 2. **Admin-вид** — админ видит полную картину «на чём всё едет»: стэки + версии, internal IPs, network topology, volumes, backup paths, depends-on graph, restart policies, pointer'ы на bootstrap-concept'ы каждой машины, runbook'и куда лезть если упало. Heavy. **Без этой карты любой агент / разраб угадывает hostname по software name** (последний инцидент: ляпнул `gitea.kzntsv.site` вместо `git.kzntsv.site`, перепутал source/destination IP в traefik access-логах, построил неверную причину 404). ## Deliverable A — public inventory **Где:** `OpeItcLoc03/projects-wiki/concepts/infrastructure-inventory.md` через `mcp__projects-meta__knowledge_ingest`. **Audience:** агенты во всех проектах, разрабы, босс. Single source of truth для canonical hostnames. **Содержит:** - Таблица **машин**: имя | физ. расположение / провайдер | public IP | назначение (high-level — «VDS Rusonyx, прод-площадка»; БЕЗ internal IP, версий, volumes) - Таблица **subdomain → host**: subdomain | public IP | какая машина | что обслуживает (high-level — «Gitea», без версии) - Раздел **canonical hostnames** — авторитетный список (`git.kzntsv.site`, `registry.kzntsv.site`, `board.kzntsv.site`, и т.д.) с пометкой «не угадывать по software name» - Раздел **anti-aliases** — hostnames которые звучат правильно но не существуют: `gitea.kzntsv.site` ❌ (use `git.kzntsv.site`), и другие если найдутся - Раздел **wildcard / apex** — что апекс `kzntsv.site` и `*.kzntsv.site` указывают на 94.19.247.14 (НЕ VDS); не пускать сюда production traffic - Pointer на admin-detailed концепт (без раскрытия её содержимого) ## Deliverable B — admin-detailed stack **Где:** `~/projects/.admin/.wiki/concepts/infrastructure-stack.md` (admin-local; commit + push в `OpeItcLoc03/admin`). **Audience:** только админ. Полный context на чём всё едет. **Содержит:** - Per-machine sub-section: hostname, public IP, internal IP, OS, ssh access (как, ключи где), ops-MCP endpoint - Per-stack sub-section на каждой машине: имя стэка | путь на хосте (`/opt/stacks//`) | docker-compose файл | сервисы (имя + образ + версия) | внешние ports | internal network | volumes (paths + что хранит) | env vars / secrets pointers (где лежит, не value) | restart policy | depends-on graph - Network topology: какие docker networks (`proxy`, etc.), какие хосты в них, как traefik видит контейнеры - Backup-карта: что бэкапится, куда, какой cron / rsync source, где runbook - Disaster-recovery pointers: на bootstrap-concept каждой машины (vds-kzntsv-bootstrap, etc.), где restore-инструкции - Per-stack runbook pointer: «если упало X — см. концепт Y, секцию Z» ## Acceptance criteria - (A) `projects-wiki/concepts/infrastructure-inventory.md` ingested, доступен через `mcp__projects-meta__knowledge_get({slug: "concepts/infrastructure-inventory"})` - (B) `.admin/.wiki/concepts/infrastructure-stack.md` commited + pushed, перечислен в `.admin/.wiki/index.md` - (A) ↔ (B) cross-references: public ссылается на admin как «detailed context for admin», admin ссылается на public как «if you need the high-level picture» - Pointer в `.admin/.wiki/CLAUDE.md` Domain conventions: «Перед любым hostname-mention свериться с public infra-inventory; для ops-decisions — admin infrastructure-stack» - Pointer в `~/projects/claude-skills/skills/using-vds-ops/SKILL.md` body и `using-synology-ops/SKILL.md` body (когда тот skeleton получит body): «Canonical hostnames — projects-wiki/concepts/infrastructure-inventory» - Smoke: на тестовый вопрос «какой hostname у Gitea?» любой агент в любом проекте находит `git.kzntsv.site` через `knowledge_search` или `knowledge_ask` ## Источники для probing-фазы - `mcp__projects-meta__knowledge_search` по existing bootstrap-concept'ам (vds-kzntsv-bootstrap, vds-ntfy-push, vds-backup-rsync-kreknin, owncloud-vds-deploy, mssql-vds-migration, minio-imgproxy-vds-migration, portainer-stack-management-vds, etc.) - `mcp__vds-ops__ops_docker_ps` — что running на VDS (имена контейнеров → имена стэков через `com.docker.compose.project` label) - `mcp__vds-ops__ops_docker_inspect ` для каждого — образ+версия, network, mounts, env (env masked, но keys видны) - `mcp__synology-ops__ops_docker_ps` + inspect — то же для NAS - `nslookup` для known subdomain'ов (probe-list: `git`, `registry`, `traefik.vds`, `mssql`, `board`, `imgproxy.vds`, `opsmcp.vds`, `opsmcp`, owncloud-host, и любые другие найденные в проектах) - `rg -F "kzntsv.site"` по `~/projects/` — каноничный список где упоминаются hostnames - `git remote -v` на любом clone → `git_base_url` для Gitea canonical - `~/.config/projects-mcp/auth.toml` → подтверждение Gitea base URL - `~/projects/.admin/.tasks/STATUS.md` header — какие deploy'и закрыты, что live ## Pending - [ ] Probing-фаза (общая для A и B): собрать сырые данные через MCP probes + nslookup + rg - [ ] Write deliverable A (light) — таблицы + canonical + anti-aliases - [ ] Ingest A через `knowledge_ingest` - [ ] Write deliverable B (heavy) — per-machine, per-stack, networks, backups, DR pointers - [ ] Commit B в `.admin/.wiki/concepts/infrastructure-stack.md` + update `.wiki/index.md` - [ ] Cross-references A↔B - [ ] Pointer в `.admin/.wiki/CLAUDE.md` Domain conventions - [ ] Pointer в using-vds-ops / using-synology-ops skill bodies (когда у них появится body) ## Decisions log - 2026-05-22: таска создана из incident'а (агент перепутал `gitea.` vs `git.`, source vs destination IP в traefik access-логах, построил неверный root-cause 404 для board-viewer deploy). User: «никакого `gitea.kzntsv.site` нет, есть только `git.kzntsv.site`, нужна инвентаризация чтобы и боссы и агенты и разрабы знали железо». - 2026-05-22: расширена scope — было «single page», стало two-tier (public + admin-detailed). User: «у все должно быть общее представление, где что живёт, а у админа — полное представление, на чём всё едет». Public = mental map для всех, admin = runbook на чём всё едет. ## Notes - Это не оперативная таска (не блокирует deploy). Но без неё каждый новый агент/сессия рискует повторить ту же ошибку. Приоритет — высокий по latency: чем дольше нет inventory, тем больше circular incident'ов. - A и B shared probing-фазу делают один раз; potом разносятся по нужным level of detail. - B содержит pointer'ы на secrets locations (pass-store paths), но НЕ сами secrets.