From b159e4847e7f0c28850f5c7d07e1a8db79d26844 Mon Sep 17 00:00:00 2001 From: vitya Date: Fri, 22 May 2026 17:13:51 +0300 Subject: [PATCH] =?UTF-8?q?tasks:=20[infra-inventory]=20scope=20=E2=86=92?= =?UTF-8?q?=20two-tier=20(public=20+=20admin-detailed)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User clarification: «у все должно быть общее представление, где что живёт, а у админа — полное представление, на чём всё едет». Расширение scope существующей таски (создана несколькими минутами ранее с single-page подходом): - Deliverable A — light в projects-wiki/concepts/infrastructure-inventory.md (audience: все агенты, разрабы, босс). Канонические hostnames + IP-map + anti-aliases. Mental map для design-conversations. - Deliverable B — heavy в .admin/.wiki/concepts/infrastructure-stack.md (audience: только админ). Per-stack: версии, internal IPs, volumes, depends-on graph, backup paths, DR runbook pointers. На чём всё едет. Probing-фаза общая, потом split по level of detail. A и B cross-references. --- .tasks/STATUS.md | 7 +-- .tasks/infra-inventory.md | 94 +++++++++++++++++++++++++++------------ 2 files changed, 69 insertions(+), 32 deletions(-) diff --git a/.tasks/STATUS.md b/.tasks/STATUS.md index 81b1f91..c96ce5d 100644 --- a/.tasks/STATUS.md +++ b/.tasks/STATUS.md @@ -10,13 +10,14 @@ _Updated: 2026-05-22 (Сессия: MSSQL Express 2022 live (`mssql.kzntsv.site: 🔵 Blocked — waiting on external input --> -## ⚪ [infra-inventory] — единая страница в global wiki: машины, IP, subdomain'ы, canonical hostnames + anti-aliases +## ⚪ [infra-inventory] — two-tier инвентаризация: public-карта в global wiki + admin-detailed runbook локально **Status:** ready -**Where I stopped:** (not started — создана 2026-05-22 из инцидента: агент ляпнул `gitea.kzntsv.site` (не существует, canonical = `git.kzntsv.site`), плюс перепутал source/destination IP в traefik access-логах, построил неверный root-cause 404) -**Next action:** см. полный план в `infra-inventory.md`. Pre-impl probes: `nslookup` для known kzntsv.site subdomain'ов; `mcp__vds-ops__ops_docker_ps` + `mcp__synology-ops__ops_docker_ps`; `mcp__projects-meta__knowledge_search` по existing bootstrap-concept'ам; `rg "kzntsv.site"` по `~/projects/`. Финал — `mcp__projects-meta__knowledge_ingest` в `OpeItcLoc03/projects-wiki/concepts/infrastructure-inventory.md` + pointer в `.admin/.wiki/CLAUDE.md`. +**Where I stopped:** (not started — создана 2026-05-22 из инцидента `gitea.` vs `git.` + перепутанный source/dest IP в traefik access-логах; scope расширена в тот же день — single-page → two-tier per user «у все общее представление, у админа полное») +**Next action:** см. полный план в `infra-inventory.md`. Шаги: (1) probing-фаза одна для обоих — `nslookup` известных subdomain'ов + `vds-ops`/`synology-ops` `ops_docker_ps`/`inspect` + `knowledge_search` по существующим bootstrap-concept'ам + `rg "kzntsv.site"` по `~/projects/`. (2) Write A — light public в `projects-wiki/concepts/infrastructure-inventory.md` (машины, canonical hostnames, anti-aliases) → `knowledge_ingest`. (3) Write B — heavy admin в `.admin/.wiki/concepts/infrastructure-stack.md` (per-stack: версии, internal IPs, volumes, depends-on, backup paths, DR pointers) → commit + push. (4) Cross-refs A↔B + pointer в `.admin/.wiki/CLAUDE.md` Domain conventions. **Branch:** n/a + --- diff --git a/.tasks/infra-inventory.md b/.tasks/infra-inventory.md index 633df2a..6a14c9f 100644 --- a/.tasks/infra-inventory.md +++ b/.tasks/infra-inventory.md @@ -2,49 +2,85 @@ ## Goal -Полная инвентаризация инфраструктуры kzntsv: какие машины существуют, где они физически, какие IP, какие домены/субдомены на них смотрят, какие стеки/сервисы крутятся. Результат — единая страница в global wiki (`projects-wiki/concepts/infrastructure-inventory.md`), доступная всем (босс в `.workshop`, агенты в любом проекте, разрабы). **Без этой карты любой агент / разраб угадывает hostname по software name** (последний инцидент: ляпнул `gitea.kzntsv.site` вместо `git.kzntsv.site`, перепутал source/destination IP в access-логах, построил неверную причину 404). +Полная инвентаризация инфраструктуры 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 -- Единая страница `projects-wiki/concepts/infrastructure-inventory.md` ингествованная через `mcp__projects-meta__knowledge_ingest` -- Содержит таблицу: **машина** | **физ. расположение / провайдер** | **public IP** | **internal IP** (если применимо) | **назначение** | **что крутится** -- Содержит таблицу: **subdomain** | **IP** | **на какой машине** | **что обслуживает** | **TLS-resolver** (если traefik) -- Явно зафиксированы **canonical hostnames** для каждого сервиса: `git.kzntsv.site` (Gitea, **НЕ** `gitea.kzntsv.site`), `registry.kzntsv.site`, `traefik.vds.kzntsv.site`, `mssql.kzntsv.site`, `board.kzntsv.site`, owncloud-host, и т.д. -- Раздел «aliases / wildcard» — что апекс и wildcard указывают, что туда **не** надо роутить production-traffic -- Раздел «not on this host» — anti-aliases (`gitea.kzntsv.site` не существует, использовать `git.kzntsv.site`; и аналоги если есть) -- Pointers — для каждого хоста ссылка на соответствующую `.wiki/concepts/-bootstrap.md` если есть, на ops-MCP endpoint если есть (`opsmcp.vds.kzntsv.site`, `opsmcp.kzntsv.site` для NAS) +- (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` по существующим bootstrap-concept'ам (vds-kzntsv-bootstrap, vds-ntfy-push, owncloud-vds-deploy, etc. — в `.admin/.tasks/` уже куча) -- `vds-ops` MCP (`mcp__vds-ops__ops_docker_ps`) — что running на VDS -- `synology-ops` MCP — что running на NAS -- `git remote -v` на любом локальном clone → canonical Gitea hostname -- Public DNS probes (`nslookup`) для всех known subdomain -- `~/.config/projects-mcp/auth.toml` — Gitea base URL (canonical) -- Existing concept в `.admin/.wiki/concepts/` если есть (проверить перед написанием с нуля) +- `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 -- [ ] Inventory машин (как минимум: VDS Rusonyx, NAS Synology, dev-машина DESKTOP-NSEF0UK; возможно есть ещё) -- [ ] Inventory subdomain'ов через `nslookup` / list of known hostnames в проектах (`rg -tjsonl "kzntsv.site"` по `~/projects/`) -- [ ] Cross-check каждого hostname с реальным docker stack через ops-MCP -- [ ] Anti-aliases (hostnames которые «звучат правильно» но не существуют — `gitea.`, может другие — `git-registry.`, `nas.`, etc.) -- [ ] Ingest в global wiki через `mcp__projects-meta__knowledge_ingest({target_project: "OpeItcLoc03/projects-wiki", pagePath: "concepts/infrastructure-inventory.md", ...})` -- [ ] Pointer в `.admin/.wiki/CLAUDE.md` Domain conventions: «Перед любым hostname-mention свериться с `projects-wiki/concepts/infrastructure-inventory.md` (canonical names + anti-aliases)» -- [ ] Pointer в `~/projects/claude-skills/` skill `using-vds-ops` body и `using-synology-ops` body: «Canonical hostnames — см. infrastructure-inventory» (когда тот skeleton получит body) - -## Acceptance — visible - -- Любой агент в любом проекте на вопрос «какой hostname у Gitea?» сначала глянет в инвентаризацию, а не ляпнет `gitea.kzntsv.site` по аналогии с software name -- Босс в `.workshop/` при дизайне нового стека (например, новый сервис на VDS) сразу видит занятые subdomain'ы и не предлагает конфликтующие +- [ ] 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». Single source of truth → global wiki. +- 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. +