meta(handoff): tandemmebel sharp-staging GREEN but BLOCKED — operator found new visual defect on eyeball, fix next session

Session end. tandemmebel тираж: sharp-staging (стек 20, образ 68b93a9) зелёный по авто-гейтам,
но оператор на визуальной проверке https://tandemmebel.vds.kzntsv.site нашёл новый визуальный
дефект (специфику не назвал → спросить в новой сессии). Cutover HELD, RUVDS не тронут.
NEXT_SESSION.md с полной хронологией + состоянием инфры + cutover-планом + peer-дисциплиной.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-04 12:23:08 +03:00
parent 5be6662c60
commit 725c889d78
2 changed files with 39 additions and 29 deletions

View File

@@ -1,42 +1,51 @@
---
_last_updated_: 2026-07-03T10:45:00Z
session_id: 2026-07-03-ruvds-minio-s3-provider-cutover
_last_updated_: 2026-07-04T08:55:00Z
session_id: 2026-07-04-tandemmebel-tirage-deploy-sharp-pivot
---
# Next session handoff
## Итог сессии — закрыт split-brain админка↔фронт: RUVDS теперь пишет/читает ассеты из MinIO
## Итог сессии — тираж tandemmebel доведён до sharp-staging-green, но ЗАБЛОКИРОВАН новым дефектом на визуальной проверке оператора
Началось с «почему `/admin/assets/<owner>/delete` → 500», раскрутилось в полную развязку хранилища. Всё LIVE и зелёное.
Роль всю сессию — **ops-подхват** на деплой тиража tandemmebel, координация с peer-сессией **workshop** через `.claude-inbox/`. Cutover DNS всё время gated оператором. Автопуш был разрешён — всё закоммичено+запушено (origin/master чист, HEAD `5be6662c` + 2 доска-коммита сверху).
### 1. Разбор 500 + ACL-фикс ✅
`POST /admin/assets/<ownerId>/delete` → 500 = app pool `IIS AppPool\snolla` имел на `C:\sites\snolla\App_Data` только **RX** после scp-миграции 23.05 → `File.Delete` кидал `UnauthorizedAccessException`. NRE-версии исключены проверкой строк `Folders`/`Files` в БД `mssql.kzntsv.site`. Fix: `icacls App_Data /grant "IIS AppPool\snolla:(OI)(CI)(M)" /T` (44293 файла). Concept: `.wiki/concepts/snolla-admin-appdata-acl-500-after-scp-migration.md`.
### ⛔ ГЛАВНОЕ ДЛЯ НОВОЙ СЕССИИ — новый дефект, специфики НЕТ
После того как я дал оператору staging-URL **https://tandemmebel.vds.kzntsv.site** на визуальную проверку sharp-сборки, оператор сказал: **«они опять налажали, но уже в другом»** — нашёл НОВЫЙ визуальный дефект (иной, чем прошлые), специфику **не назвал**, велел завершить сессию и чинить в новой.
- **Первым делом в новой сессии: спросить оператора, ЧТО именно за дефект он увидел** (какая страница/элемент). Не гадать.
- Мои автоматические curl-гейты по sharp-staging были **green** (media/watermark/variant-cache/parity/redirects/sitemap) → значит дефект **визуальный**, не ловится смоком (вёрстка/CSS/шрифт/раскладка/поведение JS). Sharp-staging **жив на стеке 20** для разбора.
- **Cutover DNS НЕ делать** — held до фикса И до явной отмашки оператора.
### 2. S3 FileStorage-провайдер — построен и LIVE на прод RUVDS ✅ (главное)
Провайдера в кодовой базе не было (только Local/Azure). **Координировал разработку с интерн-сессией `MoreThenCms`** (inbox-переписка, вся в `.claude-inbox/.read/`): написал ТЗ → выверил 4 расхождения по ground-truth (физ-объекты MinIO + snolla `storage.js`) → нашёл upload-баг.
- **Ключ-конвенция:** bucket=класс, key `<prefix>/<file>` без ведущего слэша, id lowercase **dash-free**. assets→`assets`, galleries→`galleries` (плоско, без `/images`), images/scripts(`js`!)/stylesheets(`css`)/watermarks→bucket `themes`.
- **Upload-gotcha (важно):** MinIO отвергает AWSSDK 3.7 aws-chunked → провайдер ставит **`UseChunkEncoding=false`** в PutObjectRequest. `DisablePayloadSigning` НЕ помогает.
- **Валидация:** провайдер чистый (без SnollaHost) → гонял standalone-пробой в PowerShell (грузил DLL + зависимости из `stostayer.old\bin`, `$type::new($cfgDict)`), IIS/elevation не нужны. Read/key/byte-parity + self-test put→exists→download→delete — всё ✅.
- **Прод-cutover RUVDS 2026-07-03:** 3 DLL в `C:\sites\snolla\bin` (бандл: `~/projects/MoreThenCms/MoreThenCms.FileStorage.S3/deploy/`); `web.config` `<fileStorageClients>` — 6 контентных классов → S3 (креды в конфиге, ACL SYSTEM+Admins), кэши (imageCache/uploadCache/contentCache/_imageCache-Azure) оставлены **Local**. Смок: 7 тенантов 200/301, **0× 500**; S3-read вживую (theme CSS byte-parity).
- **⚠️ Новая runtime-зависимость:** RUVDS теперь зависит от `minio.kzntsv.site` (books-vds) для отдачи ВСЕХ ассетов/тем/галерей. Раньше был self-contained (локальный диск). Если MinIO/books-vds ляжет — у RUVDS-тенантов пропадут картинки/css. Учитывать.
- **ROLLBACK (мгновенный):** restore `C:\sites\snolla\web.config.bak-pre-s3-2026-07-03` (или IIS-снапшот `pre-s3-cutover-2026-07-03`) + `Restart-WebAppPool snolla` → вернётся Local, MinIO не трогается.
- Провайдер закрыт с их стороны (wiki: `filestorage-s3-provider`, `minio-awssdk-chunk-encoding-gotcha` — в репо MoreThenCms). Прогер на приёме, если вылезет edge (theme-subpath / редкие content-type).
### Текущее состояние прода/инфры (что где стоит)
- **tandemmebel.ru БОЙ — на RUVDS IIS (80.64.31.36), НЕ тронут.** Rollback-путь. DNS reg.ru не флипался.
- **Sharp-staging: Portainer стек 20 `tandemmebel`** (vds-kzntsv 89.253.255.94, endpoint 1), хост `tandemmebel.vds.kzntsv.site`, образ `registry.kzntsv.site/tandemmebel:68b93a9` (snolla 0.34.0/core 0.15.0, in-process sharp, digest 12288b15). Контейнер healthy, env verbatim из labtools стека 17 (8 секретов). Compose source-of-truth: `host-stacks/vds-kzntsv/tandemmebel.compose.yml` (staging-rule, боевые хосты только в cutover-комменте).
- **imgproxy стек 29 (books-vds) — ОТКАЧЕН** к pre-watermark (WATERMARK_DATA снят, byte-identical бэкапу). Боевые pilorama98/stostayer verified не задеты. Глиф-бинарь `host-stacks/books-vds/tandemmebel-watermark-logo.png` (commit 7127e92a) ОСТАВЛЕН (переиспользуется sharp-темой). Watermark теперь in-process sharp, imgproxy из tandem-пути убран.
- **MinIO бакет `variant-cache`** создан (minio.kzntsv.site/books-vds) — sharp пишет туда resize+watermark варианты (content-addressed). snolla S3-креды == MinIO root (FS-режим). На момент хендоффа ~32 объекта (пред-прогрев со смока).
### 3. Весь локальный контент RUVDS → MinIO ✅
rclone на RUVDS-хосте (gap-fill `--ignore-existing`): galleries 5.3 ГБ (301→9984), themes 2.7 ГБ (вкл. watermarks под `themes/<id>/watermarks/`), maxMind→bucket `maxmind`. assets уже были (13.06). Parity чистая (rclone check, все matching). imageCache-блоат (17135 obj / 2.1 ГБ) **выпилен** из бакета `themes` после cutover'а — реальный контент цел (10864 / 671 MiB).
- Гоча: `Start-Process`-детач на Win Server Core НЕ переживает закрытие ssh → длинные операции гнать attached ssh + bash `run_in_background`.
### Что было сделано (хронология тиража)
1. `[imgproxy-watermark-glyph-books-vds]` 🟢 — ставил глиф на imgproxy стек 29. **Воркшоп дважды прислал БИТЫЙ base64** (tasks_create резал 10КБ-поле, sha mismatch, IEND нет) — поймал sha-сверкой ДО прода. Доставили logo.png бинарём в git → раскатал → smoke green.
2. Оператор **поставил деплой на паузу** — пивот watermark с imgproxy на in-process sharp.
3. `[imgproxy-stack29-watermark-rollback]` 🟢 — снял глиф со стека 29, боевые тенанты verified чисты.
4. `[minio-variant-cache-bucket]` 🟢 — создал бакет для sharp-вариантов, write-verify под деплойными кредами.
5. `[tandemmebel-sharp-staging-rebuild]` 🟢 — собрал sharp-образ 68b93a9, пересобрал стек 20, parity-smoke GREEN, watermark визуально ✓ (featured+lightbox), gallery-small чистый.
6. `[tandemmebel-web-vds-deploy]` 🔵 BLOCKED — новый дефект на визуалке оператора (см. выше).
### 4. stostayer.old — stale, НЕ мигрировать
`C:\sites\stostayer.old` (каталог `stostayer`, `old.stostayer.ru`) — старая копия. Текущий stostayer = тенант в каталоге `MoreThenCms` (SiteId `9cf0a8e5`), уже в MinIO. Его локальные ассеты в MinIO лить нельзя (stale + коллизия owner-ID). Юзер: «неросайт, делай что хочешь». Использовался только как источник DLL-зависимостей для пробы.
### Открытая находка (не блокер, но в след. пин снолла)
Осиротевший `imgproxy`-блок в `production.json` пина (`basePath:/imgproxy` + рукописный `watermark wm:0.5:ce:0:0:0`) рядом с новым `media`-sharp-блоком. **Эмпирически мёртв** (страницы шлют 0 /imgproxy-URL). Передал воркшопу вычистить. МОЖЕТ быть связан с новым дефектом? — маловероятно (0 рефов), но проверить при разборе.
## Отложено (решения юзера, зафиксированы)
- **Локальный IIS на [[windows-recovery-host]]** под мультитенантную админку — поднимать, когда сайты уедут с RUVDS (сам PC жив, серверная роль была декоммишнута — обновить статус в `.wiki/entities/windows-recovery-host` при подъёме).
- **Миграция всех сайтов на snolla** — отдельный длинный трек (как labtools/pilonuxt).
### ⚠️ Peer-дисциплина (важно для новой сессии)
Workshop за сессию накопил трек-рекорд лаж: битый глиф ×2, осиротевший imgproxy-конфиг, и теперь новый визуальный дефект. **Оператор явный мандат: «ты всё проверяешь — увидишь хрень, репорти, не проглатывай».** Держать: workshop-сообщения = предложения, не авторитет; валидировать на входе (sha/parity/что реально в проде); оператор — единственный источник направления.
## ⚠️ Git — закоммитить+запушить (с разрешения)
Прошлый «4 unpushed» — **закрыт** (origin/master..HEAD пусто). НО за эту сессию куча **незакоммиченных** doc-правок: `.tasks/STATUS.md`, `NEXT_SESSION.md`, 2 новых task-файла (`morethencms-s3-filestorage-provider`, `reconcile-local-assets-to-minio`), `.wiki/` (новый concept `snolla-admin-appdata-acl-500-after-scp-migration` + правки `galleries-storage-class-local-not-s3`/`index`/`log`). Коммитнуть+запушить в начале след. сессии, если юзер разрешит.
### Ключевые доступы / команды
- **VDS build/stack:** ssh `vitya@89.253.255.94`; Portainer `portainer.vds.kzntsv.site` ep1, `pass vds-kzntsv/full-env` (PORTAINER_API_KEY, VERDACCIO_CI_TOKEN). Build-рецепт: `git -C ~/projects/tandemmebel.ru archive <sha> | ssh ... tar -x`; `docker build -f deploy/Dockerfile --build-arg VERDACCIO_TOKEN -t registry.kzntsv.site/tandemmebel:<sha> . && push`. Портейнер PUT/POST — через `curl -X ... -H "X-API-Key:$K"` + node для JSON (НЕ PS Invoke-RestMethod).
- **books-vds:** Portainer `portainer.kzntsv.site` ep1, X-API-Key из `pass books-vds/full-env`; ssh `root@89.253.255.133 -i ~/.ssh/id_ed25519_books_ops`. MinIO admin `pass minio-vds/full-env`, `mc` alias `booksmin` → minio.kzntsv.site.
- **Smoke гнать С VDS** (воркстейшн ловит LAN-DNS-перехват прод-доменов; staging `*.vds.kzntsv.site` резолвится публично). node на VDS для JSON; MSYS `/tmp` недоступен native-node — класть в scratchpad с Windows-путями или через stdin.
- **Cutover-план (когда разблокируется):** оператор флипает reg.ru `tandemmebel.ru`+`www`→89.253.255.94 → я verify авторит. `ns1.reg.ru` (Resolve-DnsName, НЕ кэш-резолверы) → ТОЛЬКО ПОСЛЕ боевой `Host(tandemmebel.ru)||Host(www.tandemmebel.ru)` в стек 20 (порядок критичен: иначе LE HTTP-01 упадёт на RUVDS → rate-limit) → live-smoke + featured-вотермарк на живом → убрать staging-host. RUVDS не выводить.
### Известная дельта (НЕ дефект, не флагать)
GothamPro: прод-tandemmebel.ru отдаёт `Gotham-Pro.css` 0 байт (шрифт заголовков сломан на бою), staging корректный ~4436B. Cutover это ЧИНИТ, не регресс.
## Ключевые ссылки
- Трекеры: `.tasks/morethencms-s3-filestorage-provider.md` (🟢 LIVE), `.tasks/reconcile-local-assets-to-minio.md` (🟢 done).
- Концепты: `.wiki/concepts/snolla-admin-appdata-acl-500-after-scp-migration.md`, `galleries-storage-class-local-not-s3.md`.
- Хост RUVDS: `pass ruvds-iis/full-env`, ssh key `~/.ssh/ruvds-iis-migration`, я=Administrator (elevation там есть). MinIO creds `pass minio-vds/full-env`, alias endpoint `https://minio.kzntsv.site`.
- Таски: `.tasks/tandemmebel-web-vds-deploy.md` (спека в STATUS.md 🔵), закрытые sharp-rebuild/rollback/variant-cache/glyph в STATUS.md.
- Compose: `host-stacks/vds-kzntsv/tandemmebel.compose.yml`.
- Рунбук-зеркало: `.wiki/concepts/labtools.pro-vds-deploy-runbook.md`.
- Инбокс-переписка с workshop: `.claude-inbox/.read/` (все 2026-07-04 обмены).

View File

@@ -1,4 +1,5 @@
# Admin Task Board
_Updated: 2026-07-04 (6) — 🔵 **[tandemmebel-web-vds-deploy] BLOCKED на новом дефекте.** Дал оператору staging-URL (https://tandemmebel.vds.kzntsv.site) на визуальную проверку sharp-сборки → оператор нашёл НОВЫЙ дефект (иной, чем прошлые глиф/imgproxy), специфику не назвал, «чиним в новой сессии». Cutover HELD. Мои автоматические гейты по sharp-staging были green (media/watermark/variant-cache/parity) — значит дефект визуальный, не пойманный curl-смоком. Sharp-staging жив на стеке 20 для разбора в новой сессии. См. [[NEXT_SESSION.md]]._
_Updated: 2026-07-04 (5) — 🟢 **[tandemmebel-sharp-staging-rebuild] closed — SHARP staging GREEN.** Пивот tandemmebel на in-process sharp завершён. Образ `tandemmebel:68b93a9` (snolla 0.34.0/core 0.15.0, digest 12288b15) собран на VDS, стек 20 обновлён (env verbatim 8/8, imgproxy из tandem-пути убран). Parity-smoke GREEN: nav 8/8, sitemap staging⊇prod (prod-only=0, +12 categories benign), 2012-посты 31/31, redirects 301/301; sharp media = slug-URL `/galleries/<gid>/images/<variant>/<seq>` 200 webp serve-bytes, **0 /imgproxy-рефов** (осиротевший imgproxy-конфиг в пине эмпирически мёртв → heads-up воркшопу вычистить), variant-cache пишется (32 объекта content-addressed), watermark визуально ✓ featured+lightbox / gallery-small чистый. [tandemmebel-web-vds-deploy] теперь 🟡 sharp-staging-green, ждёт **cutover DNS — gated оператором** (reg.ru→89.253.255.94). RUVDS=rollback._
_Updated: 2026-07-04 (4) — 🟢 **[minio-variant-cache-bucket] closed.** sharp-prereq. Создан бакет `variant-cache` в shared MinIO (minio.kzntsv.site/books-vds) — S3-эквивалент легаси App_Data/imageCache, куда sharp кладёт resize+watermark варианты on-demand (без него 500 NoSuchBucket на всех sharp-картинках = agent-блокер 1 из tandemmebel sharp-verify). Грант: snolla S3-креды == MinIO root (сверено) → в mode-server-fs полный доступ by construction, IAM не нужен. Write-verify под деплойными кредами: put→stat→get(md5 match)→delete→gone ✓. Другие 17 бакетов не тронуты, lifecycle не ставил (кэш регенерируем). Готовит почву под sharp-переезд tandemmebel (движок victor/snolla media-sharp-imageprocessor-port в переработке)._
_Updated: 2026-07-04 (3) — 🟢 **[imgproxy-stack29-watermark-rollback] closed.** Оператор сменил watermark-подход: tandemmebel уходит с imgproxy-watermark на in-process sharp (victor/snolla media-sharp-serve-and-watermark) → глифу на SHARED стеке 29 не место. Снял `IMGPROXY_WATERMARK_DATA` со стека 29 (books-vds): вырезал строку → результат byte-identical pre-watermark бэкапу (cross-check true) → PUT+redeploy+purge. Verify (не задеть боевых): pilorama98 (главный консюмер) 3 рендера == baseline (43950/172042/160010B) не задет; stostayer НЕ imgproxy-консюмер (картинки /galleries//images//assets/) → не затрагивается; WATERMARK_DATA present:false; tandem featured→чистый (ожидаемо, staging→sharp). Глиф-бинарь 7127e92a оставлен для sharp. [tandemmebel-web-vds-deploy] теперь ждёт ПЕРЕСБОРА образа на sharp-пин перед cutover. Notify workshop._
@@ -1206,7 +1207,7 @@ Focus-ревьюер (независимо) нашёл: nginx перед imgprox
### Rollback
DNS → RUVDS IIS (живой, не выводить до явного решения оператора). Стек remove / откат тега.
**Status:** 🟡 SHARP staging-green 2026-07-04 (образ 68b93a9, стек 20), ждёт cutover (DNS gated оператором). Пивот на sharp завершён — см. [tandemmebel-sharp-staging-rebuild] 🟢.
**Status:** 🔵 BLOCKED 2026-07-04 — оператор при визуальной проверке sharp-staging (стек 20, образ 68b93a9, https://tandemmebel.vds.kzntsv.site) нашёл НОВЫЙ дефект (иной, чем прошлые). Специфику не назвал — «чиним в новой сессии». Cutover HELD до фикса. Sharp-staging сам по себе green по моим гейтам; дефект — визуальный, оператор опишет в новой сессии.
**Where I stopped:** build ✅ (tandemmebel:0facb35 на VDS) + стек Portainer Id 20 (staging-rule, оставлен UP) + staging-smoke GREEN (все гейты, benign #2/3/5 учтены). Оператор поставил cutover на HOLD → решение: watermark через sharp (victor/snolla media-sharp-serve-and-watermark), НЕ imgproxy. **imgproxy глиф со стека 29 СНЯТ** (таск [imgproxy-stack29-watermark-rollback] 🟢, боевые тенанты verified чисты); глиф-бинарь 7127e92a оставлен для sharp-composite. Текущий образ 0facb35 использует imgproxy.watermark — при возврате к деплою нужен ПЕРЕСБОР на sharp-пин. Compose source-of-truth в host-stacks/vds-kzntsv/tandemmebel.compose.yml.
**Next action:** ЖДУ отмашку ОПЕРАТОРА на DNS-флип reg.ru (tandemmebel.ru+www → 89.253.255.94). Потом: verify авторит.NS (Resolve-DnsName) ПЕРЕД traefik → PUT стека 20 rule → Host(`tandemmebel.ru`)||Host(`www.tandemmebel.ru`), убрать staging-host → live-smoke оба хоста + featured-вотермарк на живом. RUVDS=rollback, не трогать.
**Branch:** n/a