- 7 admin per-task files moved from .tasks-imported/ to .tasks/ (renames) - NEXT-SESSION-PROMPT.md (iis-migration session handoff) kept as sibling - .tasks-imported/STATUS.md removed (content merged into admin STATUS.md) - admin STATUS.md gains 'Imported from MoreThenCms' section with all 7 admin done tasks verbatim. 4 CMS-domain task blocks excluded (stay in MoreThenCms): cms-admin-assets-root-folders-seed, cms-port-leak-fix, traefik-maljarka-502-bug, cms-maljarka-https-mode-bug-fix - morecms-subtree-split marked done (acceptance: 4 split branches exist with per-file history) - admin-subtree-import-and-cleanup marked active (in-progress this session) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
471 lines
41 KiB
Markdown
471 lines
41 KiB
Markdown
# Admin Task Board
|
||
_Updated: 2026-05-21_
|
||
|
||
<!--
|
||
Status legend:
|
||
🔴 Active — only one at a time
|
||
🟡 Paused — in progress, resumable
|
||
⚪ Ready — defined, not started
|
||
🟢 Done — kept until merged
|
||
🔵 Blocked — waiting on external input
|
||
-->
|
||
|
||
## 🟢 [admin-infra-project-pointers] — Bootstrap-pointers для design admin-infra-project. Pre-fills target's `.wiki/CLAUDE.md` Domain conventions ссылками на спецификацию. Дизайн не лежит в этом репо — только pointer-stub. Без этой таски следующий агент попадёт в дыру: where_stopped one-liner + пустой Domain conventions stub = угадывание порогов / pipeline-этапов вместо чтения готовых решений.
|
||
|
||
**Кто делает:** любой следующий агент в этом проекте. Это первая по приоритету таска промоушена — все остальные импл-таски ссылаются на pointers через .wiki/CLAUDE.md.
|
||
|
||
**Status:** done
|
||
**Closed:** 2026-05-21 — `.wiki/CLAUDE.md` Domain conventions заполнен design-context pointer-блоком (3 sources: `concepts/admin-infra-project.md`, archive `~/projects/.workshop/.archive/2026-05-21-admin-infra-project.md`, local `overview.md`). Unblocks migration chain.
|
||
**Where I stopped:** done
|
||
**Next action:** В `.wiki/CLAUDE.md` секции "Domain conventions" вставить блок (или заменить дефолтный setup-wiki stub):
|
||
|
||
### Mandatory: read design context before implementation
|
||
|
||
Before picking up any task in `.tasks/`, load the full design context. It does **not** live in this repo as a standalone source — only pointers do. Sources, in order:
|
||
|
||
1. **Local design (canonical):** `.wiki/concepts/admin-infra-project.md` — ingested via promote 2026-05-21. Identity, scope, content inventory, migration recipe (subtree-split + read-tree merge for populated prefixes), initial agenda.
|
||
2. **Brainstorm process trace (rationale):** `~/projects/.workshop/.archive/2026-05-21-admin-infra-project.md`. Why each decision was made (recommend vs menu trade-offs), what was rejected (filter-repo vs subtree-split, "admin-only" skills, splitting roadmap from ops), anti-patterns flagged during brainstorm.
|
||
3. **Local `overview.md`** — thin summary, quick orientation only — never the source of truth.
|
||
|
||
Do **not** invent migration recipes, file lists, taxonomies, or scope decisions from task `where_stopped` lines alone — those are pointers, not specifications. The concept doc and archive contain the rationale.
|
||
|
||
---
|
||
|
||
Закоммитить: `wiki(claude): add design-context pointers for admin-infra-project`.
|
||
**Branch:** n/a
|
||
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-21T10:21:59.082Z -->
|
||
|
||
---
|
||
|
||
## 🟢 [morecms-subtree-split] — Шаг 2 миграции: в `~/projects/MoreThenCms` создать 4 subtree-split ветки, каждая хранит per-file history своего dir'а. Эти ветки потом импортируются в admin (см. `admin-subtree-import-and-cleanup`).
|
||
|
||
См. `.wiki/concepts/admin-infra-project.md` §Migration mechanics шаг 2 для полного контекста.
|
||
|
||
**Status:** done
|
||
**Closed:** 2026-05-21 — 4 split branches созданы в `~/projects/MoreThenCms` (split-wiki-entities @24661c10, split-wiki-sources @a5e96432, split-wiki-concepts @c727aaa1, split-tasks @cbdc2b39). Acceptance: per-file history preserved (verified via subsequent subtree-add in admin). Не push'ились — служебные.
|
||
**Where I stopped:** (not started)
|
||
**Next action:** ```powershell
|
||
cd ~/projects/MoreThenCms
|
||
git subtree split --prefix=.wiki/entities -b split-wiki-entities
|
||
git subtree split --prefix=.wiki/sources -b split-wiki-sources
|
||
git subtree split --prefix=.wiki/concepts -b split-wiki-concepts
|
||
git subtree split --prefix=.tasks -b split-tasks
|
||
```
|
||
|
||
Acceptance: `git branch | grep split-` показывает 4 ветки. Каждая `git log split-<x>` содержит коммиты только относящиеся к соответствующему dir'у. **Не push'ить** эти ветки — они служебные, нужны только для local subtree-add в admin.
|
||
|
||
Done — пометить 🟢 + переходить к `admin-subtree-import-and-cleanup`.
|
||
**Branch:** n/a
|
||
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-21T10:22:50.307Z -->
|
||
|
||
---
|
||
|
||
## 🔴 [admin-subtree-import-and-cleanup] — Шаги 3-7 миграции: импорт 4 split-веток из MoreThenCms в admin (clean prefixes через `git subtree add`, populated prefixes — temp-prefix dance с `git subtree add` + `git mv` для history-preservation через merge-commit + rename; read-tree вариант spec'a отвергнут — не сохраняет parent-link к morecms history → `git log --follow` не доходит до morecms-era коммитов), cleanup CMS-следов из mixed splits, STATUS.md merge, index.md regen, push на Gitea.
|
||
|
||
Объединено в одну таску потому что: тот же agent, та же session, sequential steps без natural review-point между ними. См. `.wiki/concepts/admin-infra-project.md` §Migration mechanics шаги 3-7.
|
||
|
||
**Status:** active
|
||
**Where I stopped:** (not started)
|
||
**Next action:** **3a. Clean prefixes:**
|
||
```powershell
|
||
cd ~/projects/.admin
|
||
git remote add morecms ~/projects/MoreThenCms
|
||
git fetch morecms
|
||
git rm .wiki/entities/.gitkeep .wiki/sources/.gitkeep
|
||
git commit -m "prep: clear gitkeep before subtree import"
|
||
git subtree add --prefix=.wiki/entities morecms/split-wiki-entities
|
||
git subtree add --prefix=.wiki/sources morecms/split-wiki-sources
|
||
```
|
||
|
||
**3b. Mixed prefixes (`.wiki/concepts/` and `.tasks/` already have content):**
|
||
|
||
Preferred — `git read-tree` merge:
|
||
```powershell
|
||
git rm .wiki/concepts/.gitkeep
|
||
git commit -m "prep: clear concepts gitkeep before import"
|
||
git fetch morecms split-wiki-concepts
|
||
git read-tree --prefix=.wiki/concepts/ -u morecms/split-wiki-concepts
|
||
git commit -m "import: .wiki/concepts/ from MoreThenCms via subtree-split (history preserved via read-tree)"
|
||
|
||
git fetch morecms split-tasks
|
||
git read-tree --prefix=.tasks-imported/ -u morecms/split-tasks
|
||
git commit -m "import: .tasks/ from MoreThenCms via subtree-split (staged at .tasks-imported/)"
|
||
# Затем merge content with admin's existing STATUS.md (см. шаг 5).
|
||
```
|
||
|
||
Альтернатива при конфликтах — temp-prefix dance (`.tmp-concepts/`, `git mv`, `git rm -r .tmp-concepts`).
|
||
|
||
**4. Cleanup CMS-следов:**
|
||
```powershell
|
||
git rm .wiki/concepts/cms-admin-assets-root-folder-seed.md `
|
||
.wiki/concepts/cms-config-rewrite-pattern.md `
|
||
.wiki/concepts/cms-maljarka-https-mode-crash.md `
|
||
.wiki/concepts/cms-server-port-leak-fix.md `
|
||
.wiki/concepts/webconfig-password-xml-escape.md `
|
||
.tasks-imported/cms-admin-assets-root-folders-seed.md `
|
||
.tasks-imported/cms-admin-assets-root-folders-seed.inserted-rows.txt `
|
||
.tasks-imported/cms-maljarka-https-mode-bug-fix.md `
|
||
.tasks-imported/cms-port-leak-fix.md `
|
||
.tasks-imported/traefik-maljarka-502-bug.md
|
||
git commit -m "cleanup: drop CMS files imported via subtree (they stay in MoreThenCms)"
|
||
```
|
||
|
||
**5. STATUS.md merge:** скопировать non-CMS таски из `.tasks-imported/STATUS.md` в admin/.tasks/STATUS.md (сохраняя 🟢 done статусы); удалить `.tasks-imported/`; rename per-task files в `.tasks/`. Commit `tasks: merge imported MoreThenCms task history with admin live agenda`.
|
||
|
||
**6. index.md regen:** обновить `.wiki/index.md` чтобы catalog отражал импортированные entities/concepts/sources. Commit `wiki(index): refresh catalog after subtree import`.
|
||
|
||
**7. Push:** `git push origin master`.
|
||
|
||
Acceptance:
|
||
- `git log --follow .wiki/concepts/wd40efax-smr-cascade.md` показывает MoreThenCms-era коммиты (history preserved)
|
||
- `ls .wiki/entities/` содержит все 6 файлов
|
||
- `ls .wiki/concepts/` содержит 18 admin-domain + admin-infra-project (новый)
|
||
- `cat .tasks/STATUS.md` содержит и live agenda (pointers + impl + secrets + roadmap), и imported 🟢 done items
|
||
- Gitea web shows updated tree
|
||
|
||
Done — 🟢; unblock `morecms-cleanup-and-breadcrumb` + `resilience-roadmap-design`.
|
||
**Branch:** master
|
||
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-21T10:23:14.254Z -->
|
||
|
||
---
|
||
|
||
## 🔵 [morecms-cleanup-and-breadcrumb] — Шаги 8-10 миграции: в `~/projects/MoreThenCms` удалить мигрированные файлы (6 entities + 17 concepts + 3 sources + 7 tasks), обновить STATUS.md/index.md, добавить `.wiki/concepts/migrated-infra-to-admin.md` breadcrumb со списком «что куда уехало», push на Gitea.
|
||
|
||
См. `.wiki/concepts/admin-infra-project.md` §Migration mechanics шаги 8-10 + полный шаблон breadcrumb'а в §9.
|
||
|
||
**Очерёдность:** ТОЛЬКО после успешного push'а admin'а с импортированным контентом (`admin-subtree-import-and-cleanup` 🟢). Иначе риск удалить из MoreThenCms то что ещё не зафиксировано в admin.
|
||
|
||
**Status:** blocked
|
||
**Where I stopped:** (not started)
|
||
**Next action:** **8. Cleanup commit (drop migrated):**
|
||
```powershell
|
||
cd ~/projects/MoreThenCms
|
||
git rm .wiki/entities/* .wiki/sources/* `
|
||
.wiki/concepts/wd40efax-smr-cascade.md `
|
||
.wiki/concepts/hyper-backup-structure-and-recovery.md `
|
||
.wiki/concepts/vbox-windows-stability-tuning.md `
|
||
.wiki/concepts/mssql-container-data-restore.md `
|
||
.wiki/concepts/traefik-on-windows-docker-desktop.md `
|
||
.wiki/concepts/traefik-tcp-passthrough-vs-starttls.md `
|
||
.wiki/concepts/traefik-file-watch-wsl2-broken.md `
|
||
.wiki/concepts/docker-host-loopback-detect.md `
|
||
.wiki/concepts/compose-bcrypt-escape-trap.md `
|
||
.wiki/concepts/portainer-2.21-admin-password-regression.md `
|
||
.wiki/concepts/db-tls-self-signed-via-traefik-raw-tcp.md `
|
||
.wiki/concepts/rusonyx-vps-onboarding-quirks.md `
|
||
.wiki/concepts/registry-gc-mount-and-modify-flag.md `
|
||
.wiki/concepts/verdaccio-prune-semantics.md `
|
||
.wiki/concepts/recovery-architecture-snapshot.md `
|
||
.wiki/concepts/future-resilient-architecture-goals.md `
|
||
.wiki/concepts/iis-migration-2026-05-19-postmortem.md `
|
||
.tasks/vds-kzntsv-bootstrap.md .tasks/vds-gc-cron.md `
|
||
.tasks/vds-backup-rsync-kreknin.md .tasks/vds-ntfy-push.md `
|
||
.tasks/nas-recovery.md `
|
||
.tasks/iis-on-host-migration.md .tasks/iis-traefik-dead-routes-cleanup.md
|
||
```
|
||
|
||
Manually edit `.tasks/STATUS.md` — оставить только CMS-domain блоки (`cms-*`, `traefik-maljarka-502-bug`, `cms-maljarka-https-mode-bug-fix`). Manually edit `.wiki/index.md` — удалить мигрированные entries из catalog.
|
||
|
||
Commit: `migrate: drop infra content moved to OpeItcLoc03/admin (history preserved there via subtree split)`.
|
||
|
||
**9. Breadcrumb:** создать `.wiki/concepts/migrated-infra-to-admin.md` по шаблону в `.wiki/concepts/admin-infra-project.md` §9 (frontmatter + Migration table + "What stays here"). Также добавить запись в `.wiki/index.md` под Concepts.
|
||
|
||
Commit: `wiki(concepts): add migrated-infra-to-admin breadcrumb`.
|
||
|
||
**10. Push:** `git push origin master`.
|
||
|
||
Acceptance:
|
||
- `git log --oneline -3` в MoreThenCms показывает 2 cleanup-коммита поверх master
|
||
- `ls ~/projects/MoreThenCms/.wiki/entities/` пуст
|
||
- `ls ~/projects/MoreThenCms/.wiki/concepts/cms-*.md` показывает 4-5 CMS файлов (включая webconfig-password-xml-escape)
|
||
- Gitea web для MoreThenCms показывает обновлённую `.wiki/concepts/migrated-infra-to-admin.md`
|
||
|
||
Done — 🟢; unblock `verify-migration`.
|
||
**Blocker:** admin-subtree-import-and-cleanup
|
||
**Branch:** n/a
|
||
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-21T10:23:37.967Z -->
|
||
|
||
---
|
||
|
||
## 🔵 [verify-migration] — Шаг 11 миграции: end-to-end sanity check после migration push'ей. Подтвердить что projects-meta cache видит admin's tasks, knowledge_search находит migrated content, history preserved (`git log --follow`), и admin'ская архитектура целостная.
|
||
|
||
См. `.wiki/concepts/admin-infra-project.md` §Migration mechanics шаг 11.
|
||
|
||
**Status:** blocked
|
||
**Where I stopped:** (not started)
|
||
**Next action:** **Sync cache:**
|
||
```bash
|
||
node ~/projects/.common/lib/projects-meta-mcp/dist/sync.js
|
||
```
|
||
|
||
**Validation matrix:**
|
||
|
||
1. `mcp__projects-meta__tasks_aggregate project: "OpeItcLoc03/admin"` — должен вернуть все live admin tasks (`[admin-infra-project-pointers]`, impl-таски, `[resilience-roadmap-design]`, `[secrets-out-of-common]`, `[secrets-manager-adopt]`, review-umbrella).
|
||
2. `mcp__projects-meta__tasks_aggregate project: "OpeItcLoc03/MoreThenCms"` — НЕ должна возвращать infra-таски (vds-*, nas-recovery, iis-*). Должна показывать только CMS-domain (`[cms-maljarka-https-mode-bug-fix]`).
|
||
3. `mcp__projects-meta__knowledge_search query: "WD40EFAX SMR cascade" domain: "all"` — должен находить `OpeItcLoc03/admin:.wiki/concepts/wd40efax-smr-cascade.md`.
|
||
4. `mcp__projects-meta__knowledge_search query: "migrated infra admin" domain: "all"` — должен находить MoreThenCms breadcrumb.
|
||
5. `cd ~/projects/.admin && git log --follow .wiki/concepts/wd40efax-smr-cascade.md` — показывает MoreThenCms-era коммиты (proof history preserved).
|
||
6. `cd ~/projects/MoreThenCms && git log -p .wiki/concepts/wd40efax-smr-cascade.md` — последний коммит = удаление (`migrate:` prefix).
|
||
7. Открыть `https://git.kzntsv.site/OpeItcLoc03/admin` в браузере — wiki/tasks visible.
|
||
|
||
**Findings**, если есть, — отдельные follow-up tasks через `mcp__projects-meta__tasks_create`.
|
||
|
||
Done — 🟢 с close-note типа `verified end-to-end: tasks+wiki visible in admin, MoreThenCms clean, history preserved`.
|
||
**Blocker:** morecms-cleanup-and-breadcrumb
|
||
**Branch:** n/a
|
||
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-21T10:23:54.407Z -->
|
||
|
||
---
|
||
|
||
## 🔵 [resilience-roadmap-design] — Развернуть placeholder `.wiki/concepts/future-resilient-architecture-goals.md` (мигрирует из MoreThenCms в `admin-subtree-import-and-cleanup`) в полноценный fault-tolerance roadmap. Естественная отправная точка для глобальной цели пользователя: «создать отказоустойчивое решение, чтобы такие проблемы как 2026-05-18 не повторялись».
|
||
|
||
Это **design task** (не impl): продукт — обновлённая `concepts/future-resilient-architecture-goals.md` + потенциально цепочка impl-тасок-children. См. `concepts/admin-infra-project.md` §Initial admin agenda E.1.
|
||
|
||
**Status:** blocked
|
||
**Where I stopped:** (not started)
|
||
**Next action:** Прочитать pointers (через `admin-infra-project-pointers`). Затем:
|
||
|
||
1. **Inputs read:** `concepts/recovery-architecture-snapshot.md` (текущее состояние request flow + SPOF list), `concepts/future-resilient-architecture-goals.md` (placeholder с rough goals), `entities/*` (что есть в стеке физически).
|
||
|
||
2. **Expand roadmap** — заполнить:
|
||
- **RTO/RPO targets** per service (client websites, gitea, verdaccio, registry, ntfy, traefik, DB park). Recovery Time Objective vs Recovery Point Objective отдельно по каждому. Сейчас effective RTO для NAS-loss был ~15 часов (15h до восстановления через recovery VM), RPO = 1 day (Hyper Backup daily). Какой target ставим?
|
||
- **3-2-1 backup strategy** — 3 копии, 2 разных media, 1 off-site. Сейчас: VDS-data → kreknin (1 off-site daily rsync ✅), но recovery-host data → ?, client sites content → ?, source code → gitea+kreknin-mirror?
|
||
- **Multi-host strategy** — клиентский прод сейчас на recovery-host (single point of failure). Опции: secondary IIS host (cold/warm standby), full migration на VDS (cms-on-VDS option), bare-metal колокация. Trade-offs стоимости / сложности / RTO.
|
||
- **Monitoring stack** — сейчас минимально: ntfy push при backup-completion, ручная проверка через ssh. Опции: Uptime Kuma / Prometheus+Grafana / Synology Active Insight / external (Pingdom/UptimeRobot). Цель — early-warning для cascading failures (типа SMR-deg которая привела к 2026-05-18).
|
||
- **Runbook coverage** — какие incident-сценарии должны иметь runbook'и (NAS-loss, VDS-loss, client-site-down, traefik-crash, cert-expiry, DB-corruption, ransomware-recovery). Какие уже есть фактически (post-mortem chronologies в `sources/`), какие missing.
|
||
|
||
3. **Output structure:**
|
||
- `concepts/future-resilient-architecture-goals.md` — обновленный (живой документ, не frozen).
|
||
- Если roadmap большой — child concepts (`concepts/resilience-rto-rpo-targets.md`, `concepts/resilience-monitoring-stack.md`, etc.) с link'ами из основного.
|
||
- Impl-tasks для каждого road-map item — отдельные таски через `tasks_create` (например `[setup-uptime-kuma]`, `[secondary-iis-host-cold-standby]`, etc.).
|
||
|
||
4. **Constraints:** roadmap **не** review автоматически — это living document. Acceptance: user (vitya) подтвердил план, есть concrete impl-tasks для top-3 priority items, документ committed.
|
||
|
||
Done — 🟢 с close-note: «roadmap expanded; N impl-tasks created for first wave».
|
||
**Blocker:** admin-subtree-import-and-cleanup
|
||
**Branch:** n/a
|
||
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-21T10:24:24.685Z -->
|
||
|
||
---
|
||
|
||
## ⚪ [secrets-out-of-common] — Этап 1 secret-management фикса: вынести `~/projects/.common/secrets/` в `~/.config/projects-secrets/` (вне git-tree). Не блокирует migration (независимый workstream).
|
||
|
||
**Why это дыра:**
|
||
1. `.common/` — git-tracked tree. Один неаккуратный `git add .` из wrong dir / отключение gitignore rule → leak в историю.
|
||
2. Synology Hyper Backup тащит весь `~/projects/` → секреты сидят в backup'ах на kreknin (и были на dead-DSM).
|
||
3. IDE indexing / LSP / Cursor / Copilot — `.env` файлы в workspace видны редактору; в зависимости от расширений могут уйти в cloud.
|
||
4. Любой `find ~/projects | xargs grep` — даёт plain-text secrets.
|
||
|
||
Этап 1 — быстрый фикс, low-risk, обратимый. Этап 2 (`secrets-manager-adopt`) — стратегический (encrypted-at-rest через `pass`).
|
||
|
||
См. `concepts/admin-infra-project.md` §Initial admin agenda E.2.
|
||
|
||
**Status:** ready
|
||
**Where I stopped:** (not started)
|
||
**Next action:** **1. Audit:** `ls ~/projects/.common/secrets/` — какие файлы там лежат сейчас? Список ожидаемых из памяти:
|
||
- `interns.env` — API keys для cheap LLM endpoints
|
||
- `gitea-token.txt` — admin-scoped Gitea token (admin-scope per memory)
|
||
- `vds-kzntsv.env` — VDS creds (ssh + DB + portainer + ntfy)
|
||
- возможно другие
|
||
|
||
**2. Audit потребителей:**
|
||
- `~/projects/.common/lib/interns-mcp/` — где читается `interns.env`? Grep по `interns.env` или `dotenv` calls.
|
||
- `~/projects/.common/lib/projects-meta-mcp/` — где читается token? Часто это `~/.config/projects-mcp/auth.toml` отдельно (см. setup-projects-meta skill); но возможны cross-refs.
|
||
- `~/.claude.json` `mcpServers.*` — где ENV/args ссылаются на `.common/secrets/*`?
|
||
- `~/projects/.common/secrets/vds-kzntsv.env` — кто его читает (scripts? local docs only?).
|
||
|
||
**3. Migration:**
|
||
```bash
|
||
mkdir -p ~/.config/projects-secrets
|
||
cp -r ~/projects/.common/secrets/* ~/.config/projects-secrets/
|
||
chmod 600 ~/.config/projects-secrets/* # paranoid; Windows ACL отдельно
|
||
```
|
||
|
||
**4. Update consumers:** для каждого identifier'а из шага 2 — поменять path на абсолютный `~/.config/projects-secrets/<file>` или принять env-override (рекомендуется env-override: легче тестировать на других машинах).
|
||
|
||
**5. Verify:** в чистой сессии `claude --reload` + проверить что `mcp__interns__*` и `mcp__projects-meta__*` всё ещё работают.
|
||
|
||
**6. Cleanup `.common/secrets/`:**
|
||
- Удалить (`rm -rf ~/projects/.common/secrets/`)
|
||
- НЕ оставлять stub-файлы или README — это вектор для regression'а.
|
||
- Git: `cd ~/projects/.common && git add -A && git commit -m "secrets: move out of common (now at ~/.config/projects-secrets/)"` если `.common` git-tracked.
|
||
|
||
**7. Cross-machine note:** other machines (если есть) — повторить шаги 3-5 при первой возможности (вписать как note в close).
|
||
|
||
Acceptance: `ls ~/projects/.common/secrets/` returns ENOENT, MCP servers still work, no `.env` references to `.common/secrets/` в коде/configs.
|
||
|
||
Done — 🟢; unblock `secrets-manager-adopt`.
|
||
**Branch:** n/a
|
||
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-21T10:24:48.748Z -->
|
||
|
||
---
|
||
|
||
## 🔵 [secrets-manager-adopt] — Этап 2 secret-management: внедрить `pass` (gpg-based password-store) — encrypted-at-rest secrets + cross-machine sync через private Gitea repo с encrypted blobs.
|
||
|
||
Альтернатива — Bitwarden CLI (cloud vault, audit log). Recommend `pass` для one-user setup — нет cloud-dependency, gpg native, encrypted git-syncable.
|
||
|
||
**Why этап 2 нужен:** после `secrets-out-of-common` (этап 1) секреты лежат plaintext в `~/.config/projects-secrets/`. Этап 1 убирает риски 1+3 (git leak + IDE indexing), но не риск 4 (любой filesystem read даёт plaintext) и не риск 2 (Hyper Backup на kreknin всё ещё тащит plaintext если `~/.config/` в scope, что зависит от backup config). `pass` закрывает оба — secrets зашифрованы на диске, расшифровка только в RAM при `pass show`.
|
||
|
||
См. `concepts/admin-infra-project.md` §Initial admin agenda E.3.
|
||
|
||
**Status:** blocked
|
||
**Where I stopped:** (not started)
|
||
**Next action:** **1. Pre-install — gpg setup (Windows):**
|
||
- Install Gpg4win (https://www.gpg4win.org/) или через Scoop: `scoop install gpg`.
|
||
- `gpg --full-generate-key` — выбрать RSA 4096, без expiration ИЛИ 2-year expiration с rotation reminder.
|
||
- `gpg --list-secret-keys` — захватить fingerprint.
|
||
|
||
**2. Install pass:**
|
||
- MSYS2: `pacman -S pass` (если есть MSYS2)
|
||
- Scoop: `scoop install pass`
|
||
- Manual: pass is bash script — clone https://git.zx2c4.com/password-store/ и положить на PATH.
|
||
|
||
**3. Initialize store:**
|
||
```bash
|
||
pass init <gpg-fingerprint>
|
||
# Creates ~/.password-store/.gpg-id
|
||
```
|
||
|
||
**4. Migrate secrets:**
|
||
- Для каждого file/var в `~/.config/projects-secrets/`:
|
||
- `pass insert <category>/<name>` → вводим plaintext, pass сохраняет как `~/.password-store/<category>/<name>.gpg`
|
||
- Примеры:
|
||
- `pass insert gitea/admin-token`
|
||
- `pass insert vds-kzntsv/ssh-password`
|
||
- `pass insert vds-kzntsv/portainer-password`
|
||
- `pass insert interns/openai-key`
|
||
- `pass insert interns/anthropic-key`
|
||
- Сохранить mapping (какой `.env` key какой `pass`-path) — `concepts/secrets-pass-mapping.md` ingest в admin wiki.
|
||
|
||
**5. Update consumers** — заменить direct file reads на shell-out calls:
|
||
- `interns-mcp` config: вместо `OPENAI_API_KEY=<plain>` в env-файле → `OPENAI_API_KEY=$(pass show interns/openai-key)` в wrapper-скрипте startup.
|
||
- `~/.claude.json` `mcpServers.*` env: если поддерживает command-eval — `pass show ...`; иначе wrapper-script.
|
||
- Альтернатива — `pass`-aware loader script `~/.config/projects-secrets/load.sh` который populate'ит env vars из pass при session start.
|
||
|
||
**6. Cross-machine sync:** initialize private Gitea repo `OpeItcLoc03/password-store-private` (visibility=private), push `~/.password-store/`. На каждой машине: clone + `gpg --import` master key + работает.
|
||
|
||
**7. Cleanup plaintext:** удалить `~/.config/projects-secrets/*` (содержимое мигрировано в pass). Оставить пустой dir + README указывающий на pass.
|
||
|
||
**8. Verify:** в чистой сессии все MCP / scripts работают через pass-resolved secrets.
|
||
|
||
Acceptance: `ls ~/.config/projects-secrets/` пуст или содержит только README, все consumers работают, `pass git status` clean, encrypted blobs в Gitea private repo.
|
||
|
||
Done — 🟢; secret-management dyra closed.
|
||
**Blocker:** secrets-out-of-common
|
||
**Branch:** n/a
|
||
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-21T10:25:14.759Z -->
|
||
|
||
---
|
||
|
||
## 🔵 [admin-infra-project-review] — Code-review checkpoint для брейнсторма admin-infra-project (промоушен 2026-05-21).
|
||
|
||
**Спецификация:** `.wiki/concepts/admin-infra-project.md` (ingested 2026-05-21).
|
||
**Pre-impl bootstrap:** `admin-infra-project-pointers` — заполнил `.wiki/CLAUDE.md` Domain conventions design-context pointer'ами. Без неё review бы читал stub.
|
||
**Импл-таски (review против их acceptance criteria):** `morecms-subtree-split`, `admin-subtree-import-and-cleanup`, `morecms-cleanup-and-breadcrumb`, `verify-migration`, `resilience-roadmap-design`, `secrets-out-of-common`, `secrets-manager-adopt`.
|
||
|
||
**Кто делает:** **не имплементер.** Следующая сессия в этом проекте (другая модель / другой день / другой агент) поднимает таску с чистым контекстом. «Я только что это написал» bias = главный риск.
|
||
|
||
**Чек-лист ревью:**
|
||
- Прочитать спецификацию `concepts/admin-infra-project.md` (acceptance criteria каждой импл-таски).
|
||
- `git log --oneline` shipped-коммитов в `~/projects/.admin/` и `~/projects/MoreThenCms/` (по migrate:/cleanup:/wiki:/tasks: префиксам в commit-message).
|
||
- Для migration-цепочки:
|
||
- `git log --follow` на парах файлов admin VS MoreThenCms — history preserved per-file?
|
||
- Нет ли CMS-файлов в admin (cleanup сработал)?
|
||
- Нет ли admin-файлов в MoreThenCms (cleanup сработал)?
|
||
- `cat MoreThenCms/.wiki/concepts/migrated-infra-to-admin.md` — breadcrumb корректный, все listings соответствуют реальности?
|
||
- Для `verify-migration` — повторно прогнать его validation matrix; нет ли регрессий после resilience/secrets работ?
|
||
- Для `resilience-roadmap-design` — roadmap расширен **по существу** (RTO/RPO с цифрами, не «TBD»; concrete impl-tasks для top-3) ИЛИ остался stub-`<TBD>`-placeholder fake-completion'ом?
|
||
- Для `secrets-out-of-common` — `ls ~/projects/.common/secrets/` точно пуст? Git history `.common/` не содержит leak'нутых secrets в недавних коммитах?
|
||
- Для `secrets-manager-adopt` — `pass show` actually works для всех migrated entries? `~/.config/projects-secrets/` пуст или README-only?
|
||
- Сверить дизайн-decisions из спецификации со shipped state. Любое отклонение от §Migration mechanics / §Initial admin agenda / §Identity — flag.
|
||
- Findings — отдельные follow-up tasks (`<topic>-<gap>-fix` или подобное) через `tasks_create`.
|
||
|
||
**Закрытие:** только когда все findings зафайлены ИЛИ ревьюер подтвердил «нет findings» в close-note.
|
||
|
||
**Status:** blocked
|
||
**Where I stopped:** (not started)
|
||
**Next action:** Дождаться 🟢 у всех blocker-тасок (включая `admin-infra-project-pointers` — без него pointers в `.wiki/CLAUDE.md` не залиты, и review будет читать stub). Прочитать спецификацию (см. путь в description). Для каждой импл-таски: `git show <commit>`, прогнать acceptance criteria из её next_action, сверить с design-decisions в спецификации. Findings → новые follow-up tasks через `mcp__projects-meta__tasks_create`.
|
||
**Blocker:** migration: admin-subtree-import-and-cleanup, morecms-cleanup-and-breadcrumb, verify-migration; agenda: resilience-roadmap-design, secrets-out-of-common, secrets-manager-adopt
|
||
**Branch:** n/a
|
||
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-21T10:25:43.430Z -->
|
||
|
||
---
|
||
|
||
# Imported from MoreThenCms — 2026-05-21 subtree-split migration
|
||
|
||
Полное содержимое `.tasks/STATUS.md` из MoreThenCms на момент 2026-05-21, **CMS-domain блоки исключены** (остались в MoreThenCms): `cms-admin-assets-root-folders-seed`, `cms-port-leak-fix`, `traefik-maljarka-502-bug`, `cms-maljarka-https-mode-bug-fix`. История per-file сохранена через subtree-split + temp-prefix merge.
|
||
|
||
## 🟢 [vds-kzntsv-bootstrap] — VDS поднят, gitea/verdaccio/registry мигрированы (3/3 phases done 2026-05-20)
|
||
**Status:** done (2026-05-20 вечер — все 3 заявленные фазы закрыты)
|
||
**Where I stopped:** Phase 1 + Phase 2 завершены ✅. VDS `89.253.255.94 / vds.kzntsv.site` Ubuntu 24.04 upgraded через VNC. sudo vitya (NOPASSWD) + ssh-key + hardened sshd (key-only) + ufw 22/80/443 + DB-порты + fail2ban + docker 29.5.1 + buildx + compose. Traefik v2.11 на `traefik.vds.kzntsv.site` (basicAuth vitya:Pryakhin9). Portainer CE 2.21.5 на `portainer.vds.kzntsv.site` — **админ-пароль был принудительно изменён на `Pryakhin9-VDS-2026` (18 chars)** из-за hard min-12-char policy в Portainer 2.21+ (regression от 2.20). API key получен и сохранён в `vds-kzntsv.env`. 4 DB-стека (Postgres 16, MariaDB 11.4, Mongo 7, Redis 7) подняты с self-signed TLS, доступны снаружи через traefik raw-TCP passthrough на `<db>.vds.kzntsv.site:<port>` (HostSNI(*) — traefik tls.passthrough+SNI не работает с STARTTLS-протоколами PG/MariaDB; rawTCP forward, DBs терминируют TLS сами). Все DB passwords (PG/Maria/Mongo/Redis) — strong random hex16, сохранены в `vds-kzntsv.env`.
|
||
**Open questions:** LE certs для DBs (сейчас self-signed → клиент verify-skip; permanent fix позже через lego sidecar extract из traefik acme.json).
|
||
**Next action:** Phase 3 миграция с kreknin **ВСЯ DONE ✅**. 3.1 gitea (132 repos, 4 users, v1.25.5 на git.kzntsv.site). 3.2 verdaccio (8.6G storage, 2063 packages, secret 32 chars). 3.3 registry — **отказались от миграции** старых 35G images (user: «новых наделать могу»), fresh install на registry.kzntsv.site + Joxit UI на registry-ui.vds.kzntsv.site (DELETE_IMAGES=true для GUI cleanup, REGISTRY_STORAGE_DELETE_ENABLED для API delete). Auth vitya:Pryakhin9 (см. vds-kzntsv.env). Follow-up tasks: vds-gc-cron, vds-backup-rsync-kreknin, vds-ntfy-push.
|
||
**Branch:** master
|
||
|
||
---
|
||
|
||
## 🟢 [iis-on-host-migration] — attempt 2 close-out: 36h soak passed, 8/8 наших sites зеленые
|
||
**Status:** done (2026-05-21 close-out). Detail: Phase 11 в [iis-host-migration-2026-05-19](../.wiki/sources/iis-host-migration-2026-05-19.md).
|
||
**Close-out evidence:** traefik `Up 38h` (zero restarts), w3wp 8.8h (scheduled pool recycle ~29h default, не crash), 8/8 наших sites вернули `Microsoft-IIS/10.0` через full traefik HTTPS chain (`emspb/snolla/on.snolla/pilorama98/labtools.ru/labtools.pro/tandemmebel/kupimknigi`). Маljarka/sestech/ics-artmaterials оказались **off-infra** (DNS снят / parked / external nginx) — не наша инфра, не regression. Новая follow-up task ⚪ `iis-traefik-dead-routes-cleanup` (низкий приоритет — почистить yml для 3 dead доменов).
|
||
**VM savestate:** **done 2026-05-21 05:13 MSK** (45.6s, VMState=saved). Savestate file 1.73 GB (`C:\Users\vitya\VirtualBox VMs\snolla-recovery\Snapshots\2026-05-21T05-12-43-636491200Z.sav`). VBoxHeadless процессы освободили ~4 GB private memory. Resume: `VBoxManage startvm snolla-recovery --type headless` (~30 сек если понадобится). Disk delete (`unregistervm --delete`, ~95 GB) — позже через неделю uptime.
|
||
**Atomic revert (unchanged):** ```Get-ChildItem C:\Users\vitya\projects\docker\diskstation\traefik\data\custom\*.yml.bak-pre-attempt2-2026-05-19 | %{ Copy-Item $_.FullName -Destination ($_.FullName -replace '\.bak-pre-attempt2-2026-05-19$','') -Force }; Move-Item C:\Users\vitya\projects\docker\diskstation\traefik\data\custom\stostayer.yml.disabled C:\Users\vitya\projects\docker\diskstation\traefik\data\custom\stostayer.yml -Force -EA SilentlyContinue; Move-Item C:\Users\vitya\projects\docker\diskstation\traefik\data\custom\oldstostayer.yml.disabled C:\Users\vitya\projects\docker\diskstation\traefik\data\custom\oldstostayer.yml -Force -EA SilentlyContinue; docker restart traefik```
|
||
**Branch:** master
|
||
|
||
---
|
||
|
||
## 🟢 [iis-traefik-dead-routes-cleanup] — sestech + isc-artmaterials disabled, maljarka оказалась live
|
||
**Status:** done (2026-05-21 ~05:42 MSK; ~20 мин работы).
|
||
**Result:**
|
||
- `sestech.yml` → `.disabled` (backup `.bak-pre-dead-routes-cleanup-2026-05-21`). DNS `sestech.ru/www.sestech.ru → 31.31.205.163` = parking provider, наш traefik больше не отвечает (public requests идут на parking host через DNS).
|
||
- `isc-artmaterials.yml` → `.disabled` (backup created). DNS `ics-artmaterials.com/www → 87.236.16.28 = external nginx-reuseport WP-хостинг`, public traffic не через нас.
|
||
- **Maljarka — НЕ disabled** — оказалось yml route'ит `maljarka.tandemmebel.ru` (subdomain тандеммебели), не голый `maljarka.ru`. DNS → **94.19.247.14 = наш IP**, IIS backend отвечает 200 OK ("Малярка от Тандеммебель", 43KB). Live route, не dead. Изначальная task'а ошиблась с hostname.
|
||
**Smoke regression:** 4 live hosts (emspb/on.snolla/www.tandemmebel/kupimknigi) → Microsoft-IIS/10.0 без regression. File-provider auto-reload, traefik restart не понадобился.
|
||
**Side finding:** `maljarka.tandemmebel.ru` через traefik HTTPS → **502 Bad Gateway**, хотя backend (host.docker.internal:8089 + Host header) возвращает 200 OK. Конфиг yml identical к работающему `tandemmebel.yml`. Live bug. Новая follow-up ⚪ task `traefik-maljarka-502-bug` (CMS-domain — остаётся в MoreThenCms).
|
||
**Atomic revert:** ```Move-Item C:\Users\vitya\projects\docker\diskstation\traefik\data\custom\sestech.yml.disabled C:\Users\vitya\projects\docker\diskstation\traefik\data\custom\sestech.yml -Force; Move-Item C:\Users\vitya\projects\docker\diskstation\traefik\data\custom\isc-artmaterials.yml.disabled C:\Users\vitya\projects\docker\diskstation\traefik\data\custom\isc-artmaterials.yml -Force```
|
||
**Branch:** master
|
||
|
||
---
|
||
|
||
## 🟢 [vds-gc-cron] — weekly GC armed для verdaccio + registry на VDS
|
||
**Status:** done (2026-05-21 00:21 MSK; ~1ч работы). Детали в [vds-gc-cron.md](vds-gc-cron.md).
|
||
**Result:** `/etc/cron.d/vds-gc` armed — Sun 03:00 MSK registry-gc.sh, Sun 03:30 MSK verdaccio-prune.sh. Scripts в `/opt/stacks/gc/scripts/` (`notify.sh`, `registry-gc.sh`, `verdaccio-prune.sh`+`verdaccio-prune.js`). Logs в `/var/log/vds-gc/`. Notify через ntfy `vds-ops`.
|
||
**Verdaccio prune real run:** 8.5G → 6.8G (freed 1.7G), 7021 packages scanned, 1551 modified, 4524 tgz deleted, 0 errors, 73 locally-published versions защищены (@snollajs/* + similar — detected via `_distfiles[tgzName]` absent). Atomic JSON rewrite (`tmp + rename`) + `_rev` bump.
|
||
**Registry GC smoke:** alpine v1+v2 pushed → DELETE manifest → GC freed 61M (whole tree, since both tags pointed одну digest). Empty-storage guard added (first run на свежем registry — `/var/lib/registry/docker/registry/v2/repositories` отсутствует → skip+min-prio notify, не FAIL).
|
||
**Atomic revert:** `ssh vitya@89.253.255.94 'sudo rm /etc/cron.d/vds-gc; sudo systemctl restart cron; sudo rm -rf /opt/stacks/gc /var/log/vds-gc'`
|
||
**Branch:** master
|
||
|
||
---
|
||
|
||
## 🟢 [vds-backup-rsync-kreknin] — daily VDS→kreknin live, smoke green, cron armed
|
||
**Status:** done (2026-05-20 → 2026-05-21 00:00 first-run завершён успешно). Детали в [vds-backup-rsync-kreknin.md](vds-backup-rsync-kreknin.md).
|
||
**Result:** rsync `--link-dest` pipeline `/opt/stacks/backup/scripts/run.sh` под cron `0 5 * * *` (root) → kreknin `/volume1/NetBackup/vds-kzntsv/<DATE>/` + symlink `latest`. DB dumps (pg/maria/mongo/redis), system config (/etc/ssh, ufw, hosts, docker), ssh keys, /opt/stacks data. Notification dual-channel: email через msmtp+Yandex (`/etc/msmtprc`) + ntfy publish на `vds-backup` topic. Retention 7 daily snapshots. Smoke run done — 71,867 files / 11.74G в 21m27s, exit 0. Cron service installed (apt install cron — Ubuntu 24.04 не имел его) + enabled. Next run автоматически 2026-05-21 05:00 MSK.
|
||
**SPOF gap status:** closed for VDS — full restore from kreknin возможен (DB dumps + конфиги + ssh keys).
|
||
**Open:** phone-side smoke (user verifies ntfy push пришёл из реального backup run).
|
||
**Atomic revert:** `ssh vitya@89.253.255.94 'sudo systemctl stop cron; sudo rm /etc/cron.d/vds-backup; sudo apt-get remove -y cron msmtp msmtp-mta; sudo rm -rf /etc/msmtprc /opt/stacks/backup /var/log/vds-backup'`
|
||
**Branch:** master
|
||
|
||
---
|
||
|
||
## 🟢 [vds-ntfy-push] — self-hosted ntfy.vds.kzntsv.site live, phone-verified
|
||
**Status:** done (2026-05-20 вечер; ~30 min работы). Detail в [vds-ntfy-push.md](vds-ntfy-push.md).
|
||
**Result:** ntfy v2.11.0 на `ntfy.vds.kzntsv.site`, LE cert (R12, valid до 2026-08-18), admin user `vitya / Pryakhin9` (deny-all дефолт, admin role → rw to all), топики `vds-backup` + `vds-ops`. Phone-verified — оба push'а пришли в Android ntfy app (screenshot 22:54). Creds в `~/projects/.common/secrets/vds-kzntsv.env` + `/opt/stacks/ntfy/.env` (chmod 600).
|
||
**Integration ready for:** [[vds-backup-rsync-kreknin]] (publish status на `vds-backup`), monitoring scripts (на `vds-ops`).
|
||
**Atomic revert:** `ssh vitya@89.253.255.94 'cd /opt/stacks/ntfy && docker compose down -v && cd .. && rm -rf ntfy'` + remove ntfy entries из vds-kzntsv.env.
|
||
**Branch:** master
|
||
|
||
---
|
||
|
||
## 🟢 [nas-recovery] — клиентские сайты восстановлены, работают из публичного интернета
|
||
**Status:** done (2026-05-19 ~10:00 MSK — 15 часов работы)
|
||
**Final state:** OpenWRT NAT → traefik 2.6.6 (host:8000/4443) → VirtualBox VM snolla-recovery (IIS + CMS) + docker-стек на хосте (MSSQL/MinIO/ES/imgproxy/nginx). 13 client routes, 40 LE certs валидны. Проверено: пользовательский клиент из публичного интернета открывает snolla.com, pilorama98.ru, labtools.ru/pro, tandemmebel.ru, emspb.ru.
|
||
**Backup pull:** C:\nas-recovery\vm-sites\ (~11 GB inetpub/wwwroot + stayer/) — на случай если VM снова станет нестабильной.
|
||
**Open issues (минор):**
|
||
- X-Forwarded-Proto/Host: CMS делает redirect с портом 4443 в URL — нужно добавить middleware в traefik или включить trust в IIS.
|
||
- MinIO/Azure storage — пользователь упомянул "не так всё", ждём пояснение.
|
||
- docker-сокет проброс в traefik — daemon connection error (некритично, file-provider routing работает).
|
||
- VM в bridged-WiFi была нестабильной → переехали на NAT + port forwards.
|
||
- acme.json renewal через HTTP-01 фейлится для доменов с DNS не на нашем IP — нужно переключить на DNS-01 через REGRU (creds в env уже).
|
||
**Branch:** master
|
||
|
||
---
|