wiki(stostayer): ingest markdown-render-404 incident postmortem + NEXT_SESSION
Постмортем инцидента 2026-07-24: 404/500 на body_repair_service (stostayer.ru) = двойной корень. (1) код-баг snolla: viewModels/index.js `import markdown from 'markdown-it'; markdown();` — инстанс выброшен, markdown.render undefined, краш на markdown-поле-шаблонах (латентный ~3 мес с коммита 1e3f897 2026-04-21). (2) упаковка exact-pin-staleness: @snollajs/content-api@0.8.0 `workspace:*` запёк @snollajs/snolla:0.7.4 exact → фиксовая 0.7.7 легла top-level, content-api юзал nested баговую 0.7.4. yarn resolutions/patch не форсят exact-pin опубликованного пакета — решено публикацией @snollajs/content-api@0.8.2 (^0.7.7). Деплой stostayer-web:0.3.22 через pscp SSH:20435 + sudo docker load + Portainer PUT pullImage:false (без push в docker.stostayer.ru:443, бана нет). 4 URL → 200 публично. Pre-build чек yarn.lock single-snolla ловит класс. Cleanup workspace-caret-interpackage-deps — за vitya+snolla. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,50 +1,48 @@
|
|||||||
---
|
---
|
||||||
_last_updated_: 2026-07-21T14:45:00Z
|
_last_updated_: 2026-07-24T11:15:00Z
|
||||||
session_id: 2026-07-21-stostayer-web-0320-deploy
|
session_id: 2026-07-24-stostayer-markdown-render-fix
|
||||||
prev_session_id: 2026-07-21-ruvds-decomm
|
prev_session_id: 2026-07-21-stostayer-web-0320-deploy
|
||||||
---
|
---
|
||||||
|
|
||||||
# Next session handoff
|
# Next session handoff
|
||||||
|
|
||||||
## Эта сессия — деплой цен кондиционеров на stostayer.ru (legacy-web 0.3.20). ЗАВЕРШЁН ✅
|
## Эта сессия — починка 404/500 на body_repair_service (stostayer.ru). ЗАВЕРШЁН ✅
|
||||||
|
|
||||||
`stostayer.new` прислал deploy-request (повышение цен в `packages/web/components/ConditionerPrice.vue`, commit `4bbdbbf`). Задеплоено на прод. По ходу вскрылся и разрешён давний ESM-блокер.
|
stostayer.new сообщил: страницы `/kuzovnoj-malyarnij-remont/{zamena-elementov,rihtovka-kuzova,remont-bamperov,pokraska}` отдают 404. Корень оказался **двойной**, чинено координированно с snolla + stostayer.new.
|
||||||
|
|
||||||
### Что сделано
|
### Что сделано
|
||||||
- **ESM-блокер подтверждён + разрешён.** `packages/web` (Nuxt2/CJS) не собирался с master (ESM-миграция `c805e7e` data/api + ESM-переиздание snolla). Ретрофит 5 `require()`→dynamic `import()` (`nuxt.config.js`, `server/index.js`, 2 `serverMiddleware`→CJS). snolla-сессия починила bare-`get`-баг → опубликовала `@snollajs/snolla@0.7.6`. Образ `0.3.20` собран, build+runtime зелёные.
|
- **Корень 1 (код, snolla):** `@snollajs/snolla` `lib/viewModels/index.js:7-8` — `import markdown from 'markdown-it'; markdown();` (инстанс выброшен) → `markdown.render` undefined → краш `fillViewModel` на markdown-поле-шаблонах. Латентный ~3 мес (с коммита `1e3f897` 2026-04-21). snolla починила → `@snollajs/snolla@0.7.7` (0.7.x legacy-line) + `@snollajs/core@0.26.1` (master + TDD).
|
||||||
- **Деплой на прод.** Push `0.3.20` в `docker.stostayer.ru`, redeploy стека 16 (`0.3.18`→`0.3.20`, Portainer PUT через SSH:20435 + внутренний IP portainer). Контейнер Up, `RestartCount=0`, обслуживает реальный трафик.
|
- **Корень 2 (упаковка, exact-pin-staleness):** `@snollajs/content-api@0.8.0` декларил `@snollajs/snolla: workspace:*` → при publish yarn запёк exact `0.7.4` → фиксовая 0.7.7 легла top-level, content-api юзал свою **nested баговую 0.7.4**. Первый деплой 0.3.21 не починил (регрессии нет). yarn `resolutions`/patch НЕ спасают (не форсят exact-pin опубликованного пакета — stostayer.new эмпирически проверил). Решено публикацией **`@snollajs/content-api@0.8.2`** с `^0.7.7` (snolla), stostayer.new забампил `^0.8.2` (`ace20a1`) → одна snolla 0.7.7.
|
||||||
- **Verify.** `/remont-kondicionerov/{zapravka,diagnostika}-kondicionera` → 200, компонент `ConditionerPrice` рендерит новые цены (4790/3290/6190/3990/7890/4840), старые (4400/2900/5800/7500/4450) ушли. Bare `/remont-kondicionerov` 301→`/remont/remont-kondicionerov` (CMS, без компонента) — verify по sub-страницам.
|
- **Деплой 0.3.22:** собрал локально offline, транспорт **без push в `docker.stostayer.ru:443`** (бан-гочи) — `docker save|gzip` → `pscp` SSH:20435 → `sudo docker load` → Portainer PUT стека 16 `pullImage:false`. Verify: 4 URL → **200** публично через Angie/TLS, в логах нет `markdown.render`.
|
||||||
|
- **Wiki:** NEW `concepts/stostayer-markdown-render-404-incident-2026-07.md` (постмортем), index.md + log.md обновлены.
|
||||||
|
- **Memory:** NEW `stostayer-deploy-image-via-pscp-load-avoid-443-push.md` (pscp+load+pullImage:false техника + pre-build чек yarn.lock single-snolla).
|
||||||
|
|
||||||
### Инцидент по ходу (разрешён)
|
### ОСТАЁТСЯ (vitya решает сам со snolla — НЕ поднимать admin-сессии)
|
||||||
Первый push 3.33GB с VPN → VPN-IP бан у провайдера хоста → `:443` к хосту TLS-fail с операторского IP (сайт для остальных работал). Остановил push, оператор убрал VPN, **resume-push** добил остаток малым egress → без повторного бана. **Урок: единичный large-push тоже триггерит бан** (не только retry-storm). Memory `stostayer-push-ban-single-large-push`.
|
- **Cleanup `workspace-caret-interpackage-deps`** (snolla-таска: `workspace:*`→`workspace:^` по монорепо, чтоб класс exact-pin-staleness не повторялся). Scope-вопрос snolla: covers ли 0.7.x legacy-line content-api или только master + перенос peerDep-паттерна (master 0.12.0) на 0.7.x. **vitya сказал «я порешаю это со snolla»** — не админ-scope, не подхватывать.
|
||||||
|
- Multi-tenant находка (факультатив): на shared MoreThenCms-БД kupimknigi нашлись 2 чужих siteId (`919219B3`, `5A826EB9`, шаблоны `article_markdown`/`test` с markdown-полем) — если на snolla 0.7.x, тоже крашились; фикс закроет при их пересборке. Mapping siteId→сайт — за vitya (site-реестр).
|
||||||
|
|
||||||
### ОСТАЁТСЯ (follow-up)
|
## Recent commits (этот репо, .admin)
|
||||||
- **🔴 ESM-ретрофит НЕ закоммичен/НЕ запушен в stostayer.new master.** stostayer.new-сессия сказала «коммить и пушь ты» (у неё изменений нет локально, ретрофит делался в working-tree .admin-сессии на этой воркстейшн). Commit-message одобрен stostayer.new. **Оператор НЕ дал «го» на пуш в эту сессию** (Rule 4 — пуш в git-master = outward). → Ретрофит лежит **незакоммиченным в `C:/Users/vitya/projects/stostayer.new` working-tree** (5 файлов + `package.json` snolla `^0.7.6` + `yarn.lock` + `.dockerignore`; `.yarnrc.yml` восстановлен в оригинал — чист; `.tasks/*` не трогать — ими stostayer.new управляет). **Следующая сессия: получить «го» оператора → `git add` ретрофит-файлов → commit (message ниже) → `git push origin master`.** НЕ делать `git checkout`/`stash`/`clean` в stostayer.new до коммита — потеряешь ретрофит. Если потерян — реконструируем из образа 0.3.20 (client registry) + ранбука + memory `stostayer-web-esm-retrofit-snolla-076`.
|
- (этот коммит) `wiki(stostayer): ingest markdown-render-404 incident postmortem + NEXT_SESSION`
|
||||||
- Commit-message (одобрен stostayer.new): `fix(web): ESM-deps retrofit — require()→dynamic import(), pin snolla ^0.7.6` + body (см. письмо `stostayer.new/.claude-inbox/2026-07-21T14-28-00Z-admin.md`).
|
- `23b1a47c` wiki(stostayer): ingest stostayer-admin-minio-config
|
||||||
- После пуша stostayer.new тянет master + verify `packages/web` собирается.
|
- `95168e30` meta(handoff): NEXT_SESSION — RUVDS DECOMM 2026-07-21
|
||||||
- **✅ snolla yank 0.7.5 — DONE.** snolla-сессия сняла `@snollajs/snolla@0.7.5` с verdaccio (`npm unpublish --force`), verify: 0.7.x = только 0.7.6, `latest`=0.42.1 не сбит, exact-0.7.5 консьюмеров не было. Линия 0.7.x полностью закрыта.
|
|
||||||
- **Операторский IP 46.151.25.64** может ещё флапать по :443 к stostayer-хосту (бан egress-IP с инцидента) — для оператора; для посетителей сайта ограничений нет. Проходит само.
|
|
||||||
- **Побочная нота (не чинил):** vds-ops `ops.docker.logs` на контейнере `verdaccio` висит 300с (docker-socket-proxy + тяжёлый stdout) — snolla-сессия не смогла взять verdaccio-логи через MCP. Если понадобится独立-verify verdaccio-логов — чинить vds-ops (таймаут/стрим) или грепнуть лог-файл на хосте.
|
|
||||||
|
|
||||||
### Wiki / memory обновлено
|
## Open треки (из STATUS.md, не этой сессии)
|
||||||
- Ранбук `.wiki/concepts/stostayer-web-deploy-runbook.md`: БЛОКЕР→RESOLVED, push-секция (single-large-push gotcha), verify-секция (sub-страницы + smoke→prod-DB gotcha).
|
|
||||||
- Memory: `stostayer-web-esm-retrofit-snolla-076`, `stostayer-push-ban-single-large-push`, `stostayer-smoke-hits-prod-db`.
|
|
||||||
|
|
||||||
### Креды/доступы — не менялись
|
|
||||||
snolla-сессия: commit `63e5c60` (snolla repo, branch `fix/snolla-0.7.6-s3-get`), 0.7.6 в verdaccio. snolla-задача `snolla-074-get-bugfix-republish` закрыта (commit `46fe4040` в victor/snolla .tasks).
|
|
||||||
|
|
||||||
## Open треки
|
|
||||||
| Трек | Готовность | Entry-point |
|
| Трек | Готовность | Entry-point |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| stostayer.new закоммитить ESM-ретрофит | ⚪ за stostayer.new | working-tree stostayer.new (5 файлов + lockfile + .dockerignore) |
|
| tandemmebel-web-vds-deploy | 🔵 blocked — оператор нашёл НОВЫЙ визуальный дефект на sharp-staging (стек 20, https://tandemmebel.vds.kzntsv.site), специфику не назвал, «чиним в новой сессии». Cutover HELD | `.tasks/STATUS.md` §tandemmebel; sharp-staging жив на стеке 20 |
|
||||||
| snolla yank 0.7.5 | ⚪ за snolla (го дано) | snolla выполнит `npm unpublish @snollajs/snolla@0.7.5 --force` |
|
| on-snolla-vds-migration | 🟢 blocked by snolla-local-admin-restore — on.snolla.com (siteId B9ECDB50…) RUVDS IIS → VDS Node snolla-app 0.42.1, реконструкция шаблонов | `.wiki/concepts/snolla-local-admin-and-on-snolla-migration-design.md` §Task B |
|
||||||
| books-vds → vds-kzntsv консолидация | оценено, не лезет по RAM/disk | За user. |
|
| snolla-local-admin-restore | ⚪ ready — восстановить локальный .NET-админ (catch-all IIS `snolla`) копированием `C:\sites\snolla\` с RUVDS; `<alias>.snolla.com/admin` через hosts-override | design doc §Task A |
|
||||||
| MinIO upload-acceptance on.snolla | ⚪ follow-up оператора | из prev handoff |
|
| books-task-runner-registry-auth-cred | 🔵 blocked — cred в config-volume, но рабочий образ (88f2bee) содержит СТАРЫЙ registryGc; тега master-a3734d5 в реестре нет → CI не собрал v2-DELETE rewrite. In-app dryRun ждёт build+deploy | `.tasks/STATUS.md` §books-task-runner |
|
||||||
|
|
||||||
## Спроси user'а
|
## Спроси user'а
|
||||||
- **«го» на коммит+пуш ESM-ретрофита в `victor/stostayer.new` master** (незакоммичен в working-tree, stostayer.new ждёт пуш чтобы подтянуть+verify). Без него следующий legacy-web деплой упрётся в ту же ESM-стену.
|
- (нет новых ask-items — инцидент закрыт; cleanup vitya берёт на себя со snolla)
|
||||||
|
|
||||||
## Не делать
|
## Не делать (preemptive guards)
|
||||||
- **НЕ пушить упавший push повторно с того же egress** (VPN-ban).
|
- **НЕ лезть в прод-БД stostayer** (MSSQL `stostayer`/MariaDB) — vitya явно остановил при попытке SQL-запроса в начале сессии. Диагностика через логи контейнера + исходники node_modules, не через DB-запросы. SQL-свопы по чужим прод-БД — только если vitya дал go на read-доступ конкретному агенту.
|
||||||
- **НЕ коммитить в stostayer.new master** без координации с stostayer.new-сессией (их репо, их ESM-стратегия) — я оставил ретрофит в working-tree, они коммитят.
|
- **НЕ пушить образы в `docker.stostayer.ru:443`** с нашего VPN-egress — единичный large-push тоже банит VPN-IP (см. [[stostayer-push-ban-single-large-push]]). Транспорт образа через pscp SSH:20435 + docker load + `pullImage:false` (отработано, бана нет).
|
||||||
- snolla 0.7.5 yank — за snolla-сессией (го дано, но она исполняет).
|
- **НЕ подхватывать cleanup `workspace-caret-interpackage-deps`** — vitya решает со snolla сам.
|
||||||
|
- **НЕ встраивать JSON-payload в double-quoted `bash -c`** при Portainer PUT — кавычки payload ломают аргумент → 500. Писать payload в файл (`jq > /tmp/p.json`), `curl -d @/tmp/p.json`.
|
||||||
|
- Pre-build чек перед деплоем snolla-фиксов: `grep -E "^\"@snollajs/snolla@npm:" yarn.lock` → ОДНА версия; в образе `docker run --rm --entrypoint sh <img> -c 'find /usr/src/app -path "*@snollajs/snolla/package.json"'` → одна копия. Без этого деплой «успешно» не починит (exact-pin-staleness).
|
||||||
|
|
||||||
|
## Memory updates за сессию
|
||||||
|
- NEW `stostayer-deploy-image-via-pscp-load-avoid-443-push.md` — pscp+load+pullImage:false техника (без :443 push) + pre-build single-snolla чек.
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
---
|
||||||
|
title: stostayer 404/500 на body_repair_service — инцидент markdown.render + exact-pin-staleness (2026-07-24)
|
||||||
|
status: resolved
|
||||||
|
tags: [stostayer, snolla, postmortem, packaging, yarn, deploy, markdown-it]
|
||||||
|
related: [[stostayer-web-deploy-runbook]], [[snolla-live-prod-inplace-image-bump]]
|
||||||
|
updated: 2026-07-24
|
||||||
|
---
|
||||||
|
|
||||||
|
# stostayer 404/500 на body_repair_service — двойной корень
|
||||||
|
|
||||||
|
Постмортем инцидента: страницы шаблона `body_repair_service` на `www.stostayer.ru` отдавали 404 (фронт) / 500 (content-api). Починено 2026-07-24. Корень **двойной** — код-баг snolla + упаковка-баг (exact-pin-staleness).
|
||||||
|
|
||||||
|
## Симптом
|
||||||
|
|
||||||
|
```
|
||||||
|
https://www.stostayer.ru/kuzovnoj-malyarnij-remont/{zamena-elementov,rihtovka-kuzova,remont-bamperov,pokraska} → 404
|
||||||
|
GET /snolla/pages/viewModel?path=.../zamena-elementov → 500 { "message": "markdown.render is not a function" }
|
||||||
|
GET /snolla/pages?path=/kuzovnoj-malyarnij-remont/&template=body_repair_service → 500
|
||||||
|
```
|
||||||
|
Родитель `/kuzovnoj-malyarnij-remont` (шаблон `body_repair`, без markdown-поля) → 200. В БД страницы есть, `Published=true`, `Path` совпадает точно — **404 это не данных, это следствие 500** (фронт `packages/web/store/snolla.js` ловит 500, коммитит `page=null`, `_.vue` рендерит 404).
|
||||||
|
|
||||||
|
## Корень 1 — код-баг snolla (`markdown.render is not a function`)
|
||||||
|
|
||||||
|
`@snollajs/snolla` → `lib/viewModels/index.js`, строки 7–8:
|
||||||
|
```js
|
||||||
|
import markdown from 'markdown-it';
|
||||||
|
markdown(); // фабрику вызвали, инстанс ВЫБРОШЕН
|
||||||
|
// ...
|
||||||
|
viewModel[name] = value ? markdown.render(value) : null; // markdown — конструктор, .render нет → TypeError
|
||||||
|
```
|
||||||
|
Краш в `fillViewModel` на шаблонах с markdown-полем (`markItUpMarkdownEditorTemplate` / `markdownLiteralTemplate`). `body_repair` без такого поля → 200; `body_repair_service` с markdown-полем → краш. **Латентный ~3 мес** — ломается только при заходе на markdown-поле-страницу, никто не замечал.
|
||||||
|
|
||||||
|
**Фикс (snolla):** `import markdownit from 'markdown-it'; const markdown = markdownit();` → `markdown.render` работает. snolla выпустила `@snollajs/snolla@0.7.7` (0.7.x legacy-line) + `@snollajs/core@0.26.1` (master, + TDD `fillViewModel.markdown.test.js`, 259/259 green). Верифицировано: `markdown-it` 12.3.2 (snolla's nested) и 14.1.0 (root) — обе дают инстанс с `.render` через `markdownit()`.
|
||||||
|
|
||||||
|
Происхождение: предмонорепо-ный Node-snolla юзал другой markdown-движок (работало). Коммит `1e3f897` (2026-04-21, импорт в монорепо) сменил на `markdown-it` без регресс-прогона по field-типам → `markdown();` без присвоения. Класс «портовая опечатка при смене либы без регресса по field-типам».
|
||||||
|
|
||||||
|
## Корень 2 — упаковка (exact-pin-staleness) — почему фикс НЕ дошёл до прода первым деплоем
|
||||||
|
|
||||||
|
`@snollajs/content-api@0.8.0` (servит `/snolla/pages`) в `routes/pages.js` делает `import { ... } from '@snollajs/snolla'`. В опубликованном `content-api@0.8.0` его `package.json` жёстко: `"@snollajs/snolla": "0.7.4"` — **exact-пин, без `^`**.
|
||||||
|
|
||||||
|
Откуда: в монорепо snolla у content-api было `"@snollajs/snolla": "workspace:*"`. **При publish yarn разрешает `workspace:*` в точную текущую версию и запекает её константным пином.** В момент публикации content-api 0.8.0 snolla была 0.7.4 → в мир ушёл content-api с залитым `0.7.4`. Позже snolla выпустила фиксовую 0.7.7, но content-api 0.8.0 об этом не знает — навсегда просит 0.7.4.
|
||||||
|
|
||||||
|
**Дедуп-ловушка:** бамп `@snollajs/snolla` → `^0.7.7` в `packages/web` (top-level) НЕ поднимает content-api's exact-пин. Yarn ставит **две копии**:
|
||||||
|
- `node_modules/@snollajs/snolla` = **0.7.7** (top-level, фиксовая) — зовётся SSR-стороной Nuxt
|
||||||
|
- `node_modules/@snollajs/content-api/node_modules/@snollajs/snolla` = **0.7.4** (nested, баговая) — **её и зовёт content-api's routes/pages.js** (ближайшая резолвится)
|
||||||
|
|
||||||
|
content-api бегёт на баговой 0.7.4 → краш. Деплой 0.3.21 (snolla 0.7.7 top-level) не починил ничего (регрессии нет — 0.3.20 тоже 500).
|
||||||
|
|
||||||
|
### Почему yarn `resolutions` НЕ спас (вариант B — мёртв)
|
||||||
|
|
||||||
|
- `resolutions` в `packages/web/package.json` — yarn berry **игнорирует workspace-resolutions** (читает только root). → нет эффекта.
|
||||||
|
- root `resolutions: { "@snollajs/snolla": "0.7.7" }` (blanket) и scoped `"@snollajs/content-api/@snollajs/snolla": "0.7.7"` — **не форсят exact-пин, объявленный внутри чужого package.json**. yarn всё равно резолвит content-api в 0.7.4 по его package.json (stostayer.new эмпирически проверил, incl. patch на content-api — не держится).
|
||||||
|
|
||||||
|
**Вывод:** resolutions/patch не могут переписать exact-pin опубликованного пакета. Только новая публикация пакета с фиксовой зависимостью.
|
||||||
|
|
||||||
|
### Фикс упаковки (вариант A — единственный)
|
||||||
|
|
||||||
|
snolla опубликовала **`@snollajs/content-api@0.8.2`** с `"@snollajs/snolla": "^0.7.7"` (в монорепо `workspace:*`→`workspace:^`, запечётся `^0.7.7`). 0.8.1 уже был на verdaccio с запечённой 0.7.4 → нужна именно 0.8.2 (перепубликация той же версии = тот же 0.7.4). stostayer.new бампит `@snollajs/content-api` → `^0.8.2` в `packages/web` → yarn: content-api `^0.7.7` ∩ web `^0.7.7` → **одна** 0.7.7 top-level, nested 0.7.4 уходит. content-api зовёт фиксовую snolla.
|
||||||
|
|
||||||
|
## Деплой 0.3.22 (без push в `:443` — см. [[stostayer-deploy-image-via-pscp-load]])
|
||||||
|
|
||||||
|
Образ ~3.3GB. Push в `docker.stostayer.ru:443` банит VPN-egress (см. [[stostayer-web-deploy-runbook]] гоча). Транспорт без `:443`:
|
||||||
|
1. Build локально offline (`.yarnrc.yml` → `enableNetwork:false` + убрать `npmAuthToken`; `.yarn/cache` с 0.8.2+0.7.7).
|
||||||
|
2. `docker save | gzip -1` → ~0.8GB (`sw-0.3.22.tar.gz`, shared-layers).
|
||||||
|
3. `pscp` по SSH:20435 на хост `/tmp` (~10MB/s, ~80s) — **SSH не банится, только :443**.
|
||||||
|
4. На хосте: `echo pass | sudo -S bash -c 'gunzip -c /tmp/sw-0.3.22.tar.gz | docker load'` (sudo -S + inner pipe из файла — конфликта stdin нет).
|
||||||
|
5. Portainer PUT стека 16 **`pullImage:false`** (образ уже локально, НЕ тянуть из `:443`). Payload через `-d @/tmp/payload.json` (jq в файл) — НЕ встраивать JSON в double-quoted `bash -c` (кавычки payload ломают → 500).
|
||||||
|
6. Verify: `docker logs` → `READY Server listening`; `curl -H "Host: www.stostayer.ru" http://localhost:3000/<page>` + публичный `https://www.stostayer.ru/<page>` → 200.
|
||||||
|
|
||||||
|
**Pre-build чек** (ловит exact-pin-staleness до деплоя): перед build'ом `grep -E "^\"@snollajs/snolla@npm:" yarn.lock` → ожидать ОДНУ версию (фиксовую), без баговой. В собранном образе: `docker run --rm --entrypoint sh <img> -c 'find /usr/src/app -path "*@snollajs/snolla/package.json"'` → одна копия 0.7.7. Без этого чека первый деплой 0.3.21 прошёл «успешно» но не починил.
|
||||||
|
|
||||||
|
## Outcome
|
||||||
|
|
||||||
|
4 URL → 200 публично через Angie/TLS. `0.3.22` на проде (`stostayer-web` стек 16). Код-фикс (snolla 0.7.7 + core 0.26.1) + упаковка (content-api 0.8.2 `^0.7.7`). stostayer.new коммит `ace20a1`.
|
||||||
|
|
||||||
|
## Cleanup (open, не блокирует — за vitya)
|
||||||
|
|
||||||
|
snolla-таска `workspace-caret-interpackage-deps`: перевести `workspace:*`→`workspace:^` по монорепо, чтоб класс exact-pin-staleness не повторялся. Scope-вопрос: covers ли 0.7.x legacy-line content-api или только master. Отдельно: 0.7.x content-api не получил peerDep-паттерн (master-only, 0.12.0) — переносить ли зависит от срока жизни 0.7.x vs миграции stostayer на современную линию.
|
||||||
|
|
||||||
|
Multi-tenant находка (факультатив, snolla своп на kupimknigi): краш бьёт **любой** шаблон с markdown-полем на **любой** БД snolla (fillViewModel общий). На shared MoreThenCms-БД kupimknigi нашлись 2 чужих siteId (`919219B3`, `5A826EB9`, шаблоны `article_markdown`/`test`) — если они на snolla 0.7.x, тоже крашились; фикс закроет при их пересборке.
|
||||||
|
|
||||||
|
## Связи
|
||||||
|
|
||||||
|
- [[stostayer-web-deploy-runbook]] — каноничный деплой-рунбук (push-гочи, Portainer API с хоста).
|
||||||
|
- [[snolla-live-prod-inplace-image-bump]] — переиспользуемый рецепт in-place bump на ЖИВОМ snolla-стеке VDS (наш VDS, не клиент).
|
||||||
|
- [[stostayer-deploy-image-via-pscp-load]] (memory) — техника pscp+load+pullImage:false.
|
||||||
@@ -50,6 +50,7 @@ Catalog of all wiki pages. One line per page, organized by type. Updated on ever
|
|||||||
- [snolla-live-prod-inplace-image-bump](concepts/snolla-live-prod-inplace-image-bump.md) — переиспользуемый рецепт обновления образа на ЖИВОМ snolla-стеке VDS in-place (build→throwaway-staging-acceptance С VDS→env-preserving Portainer PUT→live-smoke); вкл. `put-stack.js`; отработан на тираже 0.42.1 (4 сайта: labtools/emspb/labtools.pro 2026-07-05 + tandemmebel 2026-07-12)
|
- [snolla-live-prod-inplace-image-bump](concepts/snolla-live-prod-inplace-image-bump.md) — переиспользуемый рецепт обновления образа на ЖИВОМ snolla-стеке VDS in-place (build→throwaway-staging-acceptance С VDS→env-preserving Portainer PUT→live-smoke); вкл. `put-stack.js`; отработан на тираже 0.42.1 (4 сайта: labtools/emspb/labtools.pro 2026-07-05 + tandemmebel 2026-07-12)
|
||||||
- [stostayer-web-deploy-runbook](concepts/stostayer-web-deploy-runbook.md) — деплой легаси web (`www.stostayer.ru`) на прод клиента: build→registry→Portainer-стек 16 через container-IP API с хоста; **БЛОКЕР: легаси не пересобрать с master (ESM-стена: top-level await @stostayer/data на build, ERR_REQUIRE_ESM @snollajs/snolla в рантайме)**; гоча — один push без retry (VPN-IP банится хостером)
|
- [stostayer-web-deploy-runbook](concepts/stostayer-web-deploy-runbook.md) — деплой легаси web (`www.stostayer.ru`) на прод клиента: build→registry→Portainer-стек 16 через container-IP API с хоста; **БЛОКЕР: легаси не пересобрать с master (ESM-стена: top-level await @stostayer/data на build, ERR_REQUIRE_ESM @snollajs/snolla в рантайме)**; гоча — один push без retry (VPN-IP банится хостером)
|
||||||
- [stostayer-admin-minio-config](concepts/stostayer-admin-minio-config.md) — локальная .NET-админка stostayer (:8090) на stostayer MinIO: креды НЕ в pass (в stostayer.new config), endpoint `minio-api.stostayer.ru` (minio.stostayer.ru — не API-порт), region `us-west-1` (не local); fix 2026-07-22 — 3 замены в Web.config, админка=прод единое хранилище
|
- [stostayer-admin-minio-config](concepts/stostayer-admin-minio-config.md) — локальная .NET-админка stostayer (:8090) на stostayer MinIO: креды НЕ в pass (в stostayer.new config), endpoint `minio-api.stostayer.ru` (minio.stostayer.ru — не API-порт), region `us-west-1` (не local); fix 2026-07-22 — 3 замены в Web.config, админка=прод единое хранилище
|
||||||
|
- [stostayer-markdown-render-404-incident-2026-07](concepts/stostayer-markdown-render-404-incident-2026-07.md) — постмортем 2026-07-24: 404/500 на body_repair_service = двойной корень (snolla `markdown();` без присвоения + exact-pin-staleness — content-api `workspace:*` запёк `@snollajs/snolla: 0.7.4`, фиксовая 0.7.7 легла top-level, content-api юзал nested баговую). Фикс snolla 0.7.7/core 0.26.1 + content-api 0.8.2 `^0.7.7`; деплой 0.3.22 через pscp+load (без :443 push). Pre-build чек yarn.lock на single-snolla ловит класс. Cleanup `workspace-caret-interpackage-deps` (vitya scope)
|
||||||
- [proxy-debugging-test-the-real-client](concepts/proxy-debugging-test-the-real-client.md) — анти-паттерн: свои curl/standalone-тесты «работают», а боевой клиент пользователя нет; источник истины — реальный клиент
|
- [proxy-debugging-test-the-real-client](concepts/proxy-debugging-test-the-real-client.md) — анти-паттерн: свои curl/standalone-тесты «работают», а боевой клиент пользователя нет; источник истины — реальный клиент
|
||||||
- [reality-pq-mldsa65-dest-incompatibility](concepts/reality-pq-mldsa65-dest-incompatibility.md) — REALITY+ML-DSA-65 (PQ) не работает с не-PQ dest (Akamai/intel шлёт HRR); fix = PQ-совместимый dest или выключить PQ; **caveat: снятие PQ ≠ рабочий Reality у GUI-клиентов**
|
- [reality-pq-mldsa65-dest-incompatibility](concepts/reality-pq-mldsa65-dest-incompatibility.md) — REALITY+ML-DSA-65 (PQ) не работает с не-PQ dest (Akamai/intel шлёт HRR); fix = PQ-совместимый dest или выключить PQ; **caveat: снятие PQ ≠ рабочий Reality у GUI-клиентов**
|
||||||
- [recovery-architecture-snapshot](concepts/recovery-architecture-snapshot.md) — текущая recovery architecture (2026-05-19/21, attempt 2)
|
- [recovery-architecture-snapshot](concepts/recovery-architecture-snapshot.md) — текущая recovery architecture (2026-05-19/21, attempt 2)
|
||||||
|
|||||||
@@ -110,3 +110,5 @@ Append-only log of wiki operations (ingests, promotions, lints, migrations).
|
|||||||
## [2026-06-27] refactor | books-vds: документирован публичный bookva-db endpoint :33306 (+ slovo/bookva DB-exposure, mongo/ES internal) в § Доступ; закрыт wiki-drift по порту
|
## [2026-06-27] refactor | books-vds: документирован публичный bookva-db endpoint :33306 (+ slovo/bookva DB-exposure, mongo/ES internal) в § Доступ; закрыт wiki-drift по порту
|
||||||
|
|
||||||
## [2026-07-05] decision | тираж snolla 0.42.1 (live-prod in-place bumps). NEW concepts/snolla-live-prod-inplace-image-bump.md (переиспользуемый рецепт build→staging-acceptance-С-VDS→env-preserving Portainer PUT `put-stack.js`→live-smoke). UPDATE 3 рунбука секцией «0.42.1 in-place bump»: labtools-vds-deploy-runbook (стек 17, `labtools:566d41c`), emspb-vds-deploy-runbook (18, `emspb:95a5c42`), labtools.pro-vds-deploy-runbook (19, `labtools-pro:0610432`). FIX orphan: все 3 рунбука добавлены в index.md (не были каталогизированы). Tasks `[labtools-ru|emspb|labtools-pro-deploy-snolla-0-42-1]` 🟢.
|
## [2026-07-05] decision | тираж snolla 0.42.1 (live-prod in-place bumps). NEW concepts/snolla-live-prod-inplace-image-bump.md (переиспользуемый рецепт build→staging-acceptance-С-VDS→env-preserving Portainer PUT `put-stack.js`→live-smoke). UPDATE 3 рунбука секцией «0.42.1 in-place bump»: labtools-vds-deploy-runbook (стек 17, `labtools:566d41c`), emspb-vds-deploy-runbook (18, `emspb:95a5c42`), labtools.pro-vds-deploy-runbook (19, `labtools-pro:0610432`). FIX orphan: все 3 рунбука добавлены в index.md (не были каталогизированы). Tasks `[labtools-ru|emspb|labtools-pro-deploy-snolla-0-42-1]` 🟢.
|
||||||
|
|
||||||
|
## [2026-07-24] ingest | concepts/stostayer-markdown-render-404-incident-2026-07.md — постмортем инцидента 404/500 на body_repair_service (stostayer.ru). Двойной корень: (1) код-баг snolla `import markdown from 'markdown-it'; markdown();` → инстанс выброшен, `markdown.render` undefined, краш на markdown-поле-шаблонах (латентный ~3 мес, с коммита 1e3f897 2026-04-21); (2) exact-pin-staleness — `@snollajs/content-api@0.8.0` `workspace:*` запёк `@snollajs/snolla: 0.7.4` exact → фиксовая 0.7.7 легла top-level, content-api юзал nested баговую 0.7.4. Фикс: snolla 0.7.7 + core 0.26.1 (код) + content-api 0.8.2 `^0.7.7` (упаковка). Деплой stostayer-web:0.3.22 через pscp SSH:20435 + sudo docker load + Portainer PUT pullImage:false (без push в :443, бана нет). Pre-build чек yarn.lock single-snolla ловит класс. index.md updated (+1). Cleanup `workspace-caret-interpackage-deps` — vitya scope. Memory: stostayer-deploy-image-via-pscp-load-avoid-443-push.md.
|
||||||
|
|||||||
Reference in New Issue
Block a user