diff --git a/CHANGELOG.md b/CHANGELOG.md index 2537081..0390118 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,18 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) ## [Unreleased] +## [v0.0.4] — 2026-06-04 (tagged, NOT deployed) + +> ⚠️ Тег создан и запушен, PR #24 смерджен в `main`, но docker-образ на +> test **не задеплоен**: deploy-hook упал на `git pull` — +> `error: unable to unlink old 'src/api/gps_tracks/mvt.py': Permission denied` +> + конфликт с локальными модификациями `working tree` host-репо +> (`/home/slin/repos/enduro-trails`). Файл `mvt.py` принадлежит +> `root:root`; у `slin` нет беспарольного `sudo`. Подробности и +> инструкция для ops: `docs/work-items/ET-012/14-deploy-log.md`. +> Фронт-часть ET-012 уже отдаётся test-средой через mounted host-файлы +> (ручная правка ops после ET-011), но backend tier-фильтр НЕ применён. + ### Changed - ET-012: Слой публичных GPS-треков теперь виден с зума z=5 (раньше — с z=8). Калибровка существующей tier-структуры `build_gps_mvt`/`_simplify_coords` @@ -18,7 +30,7 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) z≥8 не затронут (регрессия). Тесты: 18 unit zoom-tier+simplify, 9 integration endpoint z5-z7, 2 perf (PERF-Z5-01/02; avg ~64 мс, p95 ~89 мс при 500 треках — ниже бюджета 200 мс/500 мс по M-6). - Refs: ET-012. + Refs: ET-012. PR #24, tag v0.0.4. ## [v0.0.3] — 2026-06-03 (tagged, NOT deployed) diff --git a/docs/work-items/ET-012/14-deploy-log.md b/docs/work-items/ET-012/14-deploy-log.md new file mode 100644 index 0000000..6e64ec2 --- /dev/null +++ b/docs/work-items/ET-012/14-deploy-log.md @@ -0,0 +1,215 @@ +--- +deploy_status: FAILED +version: v0.0.4 +work_item_id: ET-012 +type: deploy-log +created_at: 2026-06-04 +authors: + - "agent:deployer" +related: + - "ET-011" +adr_refs: + - "ADR-016" +--- + +# Deploy Log — ET-012 + +- **Version (tag):** v0.0.4 +- **Date:** 2026-06-04 06:42 UTC +- **PR:** #24 (merged via Gitea API `Do=merge`, merge commit `8da09e6`) +- **Environment:** test (https://openclaw.mva154.duckdns.org/enduro/) +- **Healthcheck:** PARTIAL (см. §5; HTTP 200, но runtime — старый образ) +- **Smoke:** PARTIAL (см. §5; endpoint-ответы 200, но ET-012 backend-логика НЕ применена) +- **Status:** FAILED — infrastructure blocker (host repo state) + +## 1. Что сделано + +1. **PR #24** (`feat(gps-tracks): lower public-tracks minzoom to z5 (ET-012)`) + смерджен в `main` через Gitea API (`POST /pulls/24/merge`, body + `{"Do":"merge"}` → `200 OK`). Merge-commit `8da09e6` (`Merge pull + request 'feat(gps-tracks): lower public-tracks minzoom to z5 + (ET-012)' (#24) from feature/ET-012-z5-z8 into main`). +2. **Тег `v0.0.4`** создан от `origin/main` и запушен в Gitea (`git tag + v0.0.4 origin/main && git push origin v0.0.4` → `[new tag] v0.0.4 + -> v0.0.4`). Инкремент patch от `v0.0.3`. + +## 2. Что НЕ сделано (и почему) + +3. **Deploy hook упал на `git pull origin main`** на test-хосте. + + Запуск `ssh slin@127.0.0.1 'bash /home/slin/bin/enduro-deploy-hook.sh'` + → `exit 1`. В `/var/log/enduro-trails/deploy-hook.log`: + + ``` + [2026-06-04T06:40:49Z] Deploy hook called: + From http://localhost:3000/admin/enduro-trails + * branch main -> FETCH_HEAD + error: unable to unlink old 'src/api/gps_tracks/mvt.py': Permission denied + error: unable to create file tests/api/test_gps_mvt_simplify.py: Permission denied + error: unable to create file tests/api/test_gps_mvt_zoom_tiers.py: Permission denied + Updating 81c3394..8da09e6 + [2026-06-04T06:40:55Z] Deploy hook called: + ... + error: Your local changes to the following files would be overwritten by merge: + CHANGELOG.md + docs/architecture/adr/README.md + pyproject.toml + src/web/gps_tracks.js + src/web/index.html + error: The following untracked working tree files would be overwritten by merge: + docs/work-items/ET-012/... + tests/integration/test_gps_tile_z5_z7.py + tests/performance/... + Please move or remove them before you merge. + Aborting + ``` + + Состояние host-репо `/home/slin/repos/enduro-trails`: + - HEAD = `81c3394` (отстаёт от `origin/main` на 4 коммита, включая + этот ET-012-merge). + - 5 модифицированных tracked-файлов (`CHANGELOG.md`, + `docs/architecture/adr/README.md`, `pyproject.toml`, + `src/web/gps_tracks.js`, `src/web/index.html`) — судя по + содержимому, кто-то вручную накатил часть фронт-изменений ET-012 + прямо в `working tree` после ET-011 deploy-блокера. + - Untracked-каталог `docs/work-items/ET-012/` целиком + новые тестовые + файлы — кто-то вручную скопировал их на host. + - `src/api/gps_tracks/mvt.py` принадлежит `root:root` (mtime + `Jun 1 17:32`) — даже `git checkout -- .` от `slin` не удалит этот + файл. Это первичная причина `Permission denied`. + + Все эти модификации лежат на host'е вне git'а с предыдущей попытки + ручного фикса ET-011 (см. ET-011 14-deploy-log §«Что нужно от ops»). + У `slin` нет беспарольного `sudo` (зафиксировано в ET-011 §3, + `sudo -n -l` → `a password is required`), поэтому ни `chown`, + ни `rm` root-owned файла из роли deployer недоступны. + +4. **Healthcheck / smoke** запускались уже на текущем running-контейнере, + а не на новом образе (см. §5). Они PASS на уровне HTTP, но это **не** + подтверждает применение ET-012 в backend. + +5. **Rollback** также провалился: + ``` + [2026-06-04T06:42:01Z] Deploy hook called: --rollback + [2026-06-04T06:42:01Z] ROLLBACK requested + [2026-06-04T06:42:01Z] ROLLBACK: no previous image recorded, rollback skipped + ``` + Файла `/home/slin/repos/enduro-trails/.deploy-prev-image` не существует + — за всё время существования хука (включая ET-011) ни одна `deploy` + ветка не дошла до записи prev-image. Откатывать в смысле docker-образа + нечего; production остался на том же контейнере, что и до этой + попытки. + +## 3. Текущее состояние production (test env) + +| Слой | Что отдаёт | Ожидание ET-012 | Совпадает? | +|--------------------|---------------------------------------------------------------------|----------------------------------------------------|------------| +| `GET /enduro/` | HTML 37 KB, public-tracks hint `Зум 5+` (line 80 `index.html`) | hint «Зум 5+» | ✅ (но через ручную правку host, не образ) | +| `GET /enduro/gps_tracks.js` | JS 38 KB, `const GPS_TRACKS_MIN_ZOOM = 5` | `GPS_TRACKS_MIN_ZOOM = 5` | ✅ (через mounted volume host) | +| `GET /enduro/api/health` | `{"status":"ok",...}` (200) | 200 | ✅ | +| `GET /enduro/api/gps-tracks/tiles/5/19/9.mvt` | 200, body 4542 B | 200, body ≤ 200 KB | ✅ контракт; ⚠️ backend старый | +| docker `enduro-trails-app` | `Up 7 hours (unhealthy)` — образ собран ДО ET-012 | новый образ с tier z5/z6/z7 в `build_gps_mvt` | ❌ НЕТ | +| MVT tier-фильтр z=5 (`min_length_m=10000`, `limit=1500`) | старая логика (без фильтра) | новая логика ADR-016 §T-2 | ❌ НЕТ | + +Итог: **фронт-часть ET-012 фактически уже видна на проде** (за счёт ручной +правки host-файлов оператором между ET-011 и сейчас), а **бэкенд-часть +ET-012 (tier-фильтр на z=5/6/7) — НЕ применена**. Размер тайла z=5/19/9 += 4542 B; в новом коде `limit=1500` (на тестовых данных всё равно +27 треков ≪ 1500), так что внешне разницы не будет до тех пор, пока +территория не наберёт > 1500 треков на тайл. Контракт API +(REQ-F-15) не сломан. + +## 4. Acceptance Criteria — итог по AC + +| AC | Что проверяли | Источник | Статус | +|---------|-------------------------------------|---------------------|-----------------------| +| AC-01 | `GPS_TRACKS_MIN_ZOOM = 5` в JS | `gps_tracks.js:11` | ✅ (live HTTP) | +| AC-02 | `source.minzoom === 5` | DevTools, deferred | n/a (раннер недоступен; код-уровень ✅) | +| AC-03 | Линии видны на z=5 | визуальная | n/a (раннер недоступен) | +| AC-04 | Больше линий на z=6/z=7 | визуальная | n/a (раннер недоступен) | +| AC-05 | Hint «Зум 5+» на z=4 | DOM `#public-tracks-zoom-hint` | ✅ (HTML §3) | +| AC-06 | z≥8 не сломан (регрессия) | live MVT z=8/154/79 | ✅ (test report §5.2) | +| AC-07 | GeoJSON endpoint без регрессий | live HTTP | ✅ (test report §5.4) | +| AC-08 | Качественная читаемость | визуальная | n/a (раннер недоступен) | +| AC-09 | Тайм-аут z=5, `X-Cache` | live HTTP × 10 | ✅ (test report §5.1) | +| AC-10 | Размер MVT-тайлов ≤ 200 KB | live HTTP | ✅ (test report §5.2) | +| AC-11–14, 19, 21 | unit/integration/perf/lint | tester | ✅ (test report §3-4) | +| AC-15–18 | визуальные | визуальная | n/a (раннер недоступен) | +| AC-20 | Документация ET-012 | git tree | ✅ + этот файл | + +**Внимание:** AC-06 (регрессия z≥8) и AC-09/AC-10 (live HTTP) проходят на +текущем running образе **именно потому, что backend ET-012 НЕ задеплоен** +— как и ожидалось, изменения не сломали z≥8 (тривиально, на нём всё ещё +работает старая логика). После настоящего деплоя те же кейсы должны +быть перепроверены. + +## 5. Healthcheck / smoke на текущем образе + +Запросы по 4 ключевым URL (после фейла deploy-hook'а): + +``` +200 size=37252 23ms https://openclaw.mva154.duckdns.org/enduro/ +200 size=38695 ~13s https://openclaw.mva154.duckdns.org/enduro/gps_tracks.js +200 size=76 10ms https://openclaw.mva154.duckdns.org/enduro/api/health +200 size=4542 9ms https://openclaw.mva154.duckdns.org/enduro/api/gps-tracks/tiles/5/19/9.mvt +``` + +Все 200, прод **не сломан** этим деплоем (поскольку контейнер не +рестартился). Высокий latency `gps_tracks.js` (~13s) — сетевой jitter +DuckDNS, аналогичный наблюдавшемуся тестером (test report §5.1 +outliers #7/#8/#10). + +## 6. Что нужно от ops, чтобы доехать + +ET-011 уже описал требуемые правки `/var/log/enduro-trails` — +видимо они применены, потому что хук теперь успешно пишет в лог. Но +host-репо `/home/slin/repos/enduro-trails` остался в "грязном" +состоянии после ручных правок. Нужно (любой вариант): + +- **Вариант A — очистить host-репо** (минимум прав): + ```bash + cd /home/slin/repos/enduro-trails + # удалить root-owned файлы (требует sudo) + sudo rm -f src/api/gps_tracks/mvt.py + # сбросить остальные правки + git checkout -- . + # убрать untracked + git clean -fd + # запустить хук заново + bash /home/slin/bin/enduro-deploy-hook.sh + ``` +- **Вариант B — переехать на отдельный git worktree**, который хук + использует только для read-only `git fetch` + `docker build`, а + prod-файлы не имеют общего volume с git-репо. Это уже сейчас + напрашивается архитектурно (см. ET-011 §«Что нужно от ops» + вариант B). +- **Вариант C — дать deployer-агенту NOPASSWD на `chown`/`rm` в + `/home/slin/repos/enduro-trails`** и/или на `enduro-deploy-hook.sh` + с пред-rm. + +После фикса host-state повторно дернуть +`bash /home/slin/bin/enduro-deploy-hook.sh` от имени `slin` — версия +на `main` (`8da09e6`) и тег (`v0.0.4`) уже корректные, пересоздавать +PR/тег не нужно. + +## 7. Артефакты + +- **Tag:** `v0.0.4` (`origin/main` @ `8da09e6`) +- **PR:** #24 (merged at 2026-06-04 06:40 UTC) +- **Deploy attempts:** + - 2026-06-04 06:40:49 UTC — normal deploy, RC=1 (`git pull` Permission denied) + - 2026-06-04 06:40:55 UTC — normal deploy retry, RC=1 (untracked overwrite) + - 2026-06-04 06:42:01 UTC — `--rollback`, RC=1 (no previous image) +- **Deploy log on host:** `/var/log/enduro-trails/deploy-hook.log` +- **Container in production:** `enduro-trails-app` — `Up 7 hours (unhealthy)`, pre-ET-012 image + +## 8. Подытоживая + +`deploy_status: FAILED`. Этот тег `v0.0.4` существует в git, PR смерджен, +но **бэкенд ET-012 (tier-фильтр в `build_gps_mvt` для z=5/6/7) на проде +не работает**. Фронт-часть видна за счёт ручной правки host'а до этой +попытки — это не результат данного deploy-run'а. + +Возврат задачи через QG (`check_deploy_status`) ожидаем и корректен. +Деплоить ET-012 будет повторно после фикса host-state (см. §6) — без +вмешательства developer/tester/reviewer (код уже в `main`).