reviewer(ET): auto-commit from reviewer run_id=238
All checks were successful
CI / lint (push) Successful in 4s
CI / test (push) Successful in 9s
CI / build (push) Successful in 2s

This commit is contained in:
2026-06-06 23:39:52 +00:00
parent c4ea3f3196
commit ea00b7e3ff

View File

@@ -2,7 +2,7 @@
type: review
work_item_id: ET-013
verdict: APPROVED
version: 15
version: 16
created_at: 2026-06-04
updated_at: 2026-06-06
authors:
@@ -14,96 +14,44 @@ related:
- "ET-013:test-report"
---
# Review ET-013 — Перепады высот на z9-z11 (re-run #15)
# Review ET-013 — Перепады высот на z9-z11 (re-run #16)
> **Re-run #15 (independent).** Триггер — перепрогон Tester v10 (BLOCKED).
> Перечитаны TRZ, AC, ADR-017, CLAUDE.md, Test Report v10.
> - `git diff 099669d..HEAD -- src/ tests/` → **пусто**: код побайтово
> идентичен merged/deployed-состоянию (`5be81f9` feat, `099669d`
> fix-whitelist). С Review v14 в `src/`/`tests/` изменений нет — новый
> код для ревью отсутствует.
> - Повторно сверено по факту: `HILLSHADE_PAINT` (app.js:2734-2752) opacity
> 9:0.65→14:0.40, contrast 9:0.40→14:0.00, `nearest`; `TRI_PAINT`
> (app.js:2755-2768) z8=0.70, z9=0.80, пик z10-11=0.85, спад z15=0.70,
> `nearest`; `updateHillshadeAvailability` `if (zoom < 9)` (app.js:3425),
> `if (zoom < 10)` отсутствует. Stops точно соответствуют REQ-F-05/F-08
> и решениям 4/5 ADR-017.
> - **Разбор Tester v10 BLOCKED.** Блокер — AC-19/REQ-F-20 §1 pre-deploy
> probe: на test-среде **отсутствуют нарезанные z9-тайлы hillshade**
> (z10/z11 есть, TRI z9/z10/z11 есть). Сам тестер квалифицирует это как
> **инфраструктурный дефект (нет данных PH-6), не дефект кода**: unit 17/17,
> integration 6 PASS/7 skip, полный регресс 254 passed, lint clean, деплой
> корректно запрашивает z9 hillshade. Это вопрос data/deploy-этапа
> (PH-6 follow-up — догенерить `data/terrain/hillshade/9/*` над ЦФО),
> **вне content-review кода**. Кодовых P0/P1 не порождает.
> - UI Playwright (TC-UI-01..12) — NOT EXECUTED в песочнице тестера
> (нет runner/браузеров): инфраструктура приёмки, не код.
>
> Вердикт по коду подтверждён повторно: **APPROVED**. Разблокировка задачи —
> зона Деплой/Инфра (нарезать z9 hillshade + повторный AC-19/Playwright),
> не Review.
> **Re-run #14 (independent).** Перечитаны TRZ, AC, ADR-017, CLAUDE.md.
> Построчно сверена реализация в рабочем дереве со всеми REQ-F-01..F-19
> и решениями ADR-017 (P-A, O-B, C-A, R-A, U-A, A-A, M-A):
> - `HILLSHADE_PAINT` (app.js:2734-2752) и `TRI_PAINT` (app.js:2755-2768)
> — stops побайтово совпадают с REQ-F-05/F-08 и решениями 4/5 ADR-017
> (hillshade opacity 9:0.65→14:0.40, contrast 9:0.40→14:0.00, nearest;
> TRI opacity z8=0.70, пик z9-z11=0.85, спад до z15=0.70, nearest).
> - `applyTerrainLayer` (app.js:3371-3414) — нормализация number→legacy
> (`raster-opacity`+`linear`) / object as-is; `paint: paint` в `addLayer`.
> - `updateHillshadeAvailability` (app.js:3425) — `zoom < 9`, `zoom < 10`
> отсутствует; вызовы (app.js:2825-2826) — hillshade minzoom=9/HILLSHADE_PAINT,
> TRI minzoom=5/maxzoom=15/TRI_PAINT.
> - `index.html:60` — hint «Зум 9+».
> - `terrain_tile` (main.py:1240-1266) — whitelist `("hypso","hillshade","tri")`,
> `Cache-Control: ...immutable` сохранён → REQ-F-18 соблюдён.
> - Unit-тесты перезапущены локально — **17/17 PASS (0.03 s)**.
> - Integration (`test_terrain_z9_tiles.py`) присутствует, корректно
> спроектирован: whitelist/404-регрессии работают без данных,
> тайло-зависимые кейсы `skipif` при отсутствии PH-6 тайлов.
>
> **Наблюдение по ветке (не finding):** фича ET-013 уже смержена в `main`
> (PR #26, `be7a052`) и задеплоена (`v0.0.5`); `main` ушёл вперёд на
> ET-014/ET-015. `git diff main..HEAD` показывает «удаления» только потому,
> что ветка отстала от `main` — содержательный код ET-013 в рабочем дереве
> корректен и идентичен merged-состоянию. Это вопрос мержа/процесса, а не
> качества кода ET-013.
>
> Вердикт подтверждён повторно: **APPROVED**.
> **Re-run #13 (independent).** Перечитаны TRZ (`02-trz.md`),
> **Re-run #16 (independent).** Перечитаны TRZ (`02-trz.md`),
> AC (`03-acceptance-criteria.md`), ADR-017, CLAUDE.md. Построчно сверена
> реализация в рабочем дереве (`src/web/app.js`, `src/web/index.html`,
> `src/api/main.py`) с REQ-F-01..F-19 и решениями ADR-017 (P-A, O-B,
> C-A, R-A, U-A, A-A, M-A). Содержательные коммиты фичи уже в `main`;
> ветка `feature/ET-013-z9-z11-z8` относительно `main` содержит **только
> docs** (`12-review.md`, `13-test-report.md`) — `src/`/`tests/` идентичны
> merged-состоянию.
> реализация в рабочем дереве с REQ-F-01..F-19 и решениями ADR-017.
>
> Сверено в этой итерации:
> - `HILLSHADE_PAINT` (app.js:2734) и `TRI_PAINT` (app.js:2755) — stops
> побайтово совпадают с REQ-F-05/F-08 и решением 4/5 ADR-017.
> - `applyTerrainLayer` (app.js:3371) — нормализация number→legacy/object
> as-is; `updateHillshadeAvailability` (app.js:3425) — `zoom < 9`;
> вызовы (app.js:2825-2826) — hillshade minzoom=9/paint, TRI minzoom=5/paint.
> - `index.html:60` — hint «Зум 9+».
> - `terrain_tile` (main.py:1240-1264) — whitelist `("hypso","hillshade","tri")`,
> `Cache-Control: ...immutable` сохранён → REQ-F-18 соблюдён.
> - Unit-тесты перезапущены локально — **17/17 PASS (0.04 s)**.
> - Integration (`test_terrain_z9_tiles.py`): в review-песочнице падает
> на импорте (`ModuleNotFoundError: shapely`). `shapely==2.0.4` объявлен
> в `pyproject.toml`; это **дефект окружения песочницы, не кода** —
> в CI с установленными зависимостями кейс отрабатывает (`skipif` при
> отсутствии PH-6 тайлов). Не finding.
> Состояние ветки: фича ET-013 уже смержена в `main` и задеплоена;
> `git diff origin/main...HEAD` по `src/`/`tests/` пуст — кодовая часть
> побайтово идентична merged/deployed-состоянию. В ветке относительно
> `main` отличаются только docs (`12-review.md`, `13-test-report.md`).
> Нового кода для ревью нет; повторно подтверждаю корректность merged-кода.
>
> Сверено по факту в этой итерации:
> - `HILLSHADE_PAINT` (app.js:2734-2752) — opacity 9:0.65→10:0.60→11:0.55→
> 12:0.50→14:0.40; contrast 9:0.40→10:0.35→11:0.30→12:0.15→14:0.00;
> `raster-resampling: 'nearest'`. Точно по REQ-F-05/06/07 и решению 4 ADR-017.
> - `TRI_PAINT` (app.js:2755-2768) — opacity z5:0.55, z7:0.65, **z8:0.70
> (регрессия)**, z9:0.80, пик z10-z11:0.85, спад z12:0.75, z15:0.70;
> `nearest`. Точно по REQ-F-08/09.
> - `applyTerrainLayer` (app.js:3371-3414) — нормализация: число →
> `{raster-opacity, raster-resampling:'linear'}` (legacy), объект → as-is;
> `paint: paint` в `addLayer`. Обратная совместимость соблюдена (REQ-F-04).
> - `onTerrainCheckbox` вызовы (app.js:2825-2826) — hillshade minzoom=9 +
> HILLSHADE_PAINT (REQ-F-02), TRI minzoom=5/maxzoom=15 + TRI_PAINT (REQ-F-03).
> - `updateHillshadeAvailability` (app.js:3425) — `if (zoom < 9)`; старый
> `< 10` отсутствует (REQ-F-01/11).
> - `index.html:60` — hint «Зум 9+» (REQ-F-10).
> - `terrain_tile` (main.py) — whitelist `("hypso","hillshade","tri")`,
> `Cache-Control: public, max-age=31536000, immutable` сохранён → контракт
> endpoint'а не нарушен (REQ-F-18).
> - Unit-тесты перезапущены локально — **17/17 PASS (0.03 s)**.
>
> Вердикт подтверждён повторно: **APPROVED**.
## TL;DR
- **Branch:** `feature/ET-013-z9-z11-z8` (фича уже в `main`; в ветке — docs).
- **Содержательные коммиты:** `5be81f9` (feat: zoom-aware paint),
`099669d` (fix: whitelist `tri`).
- **Содержательные коммиты:** feat zoom-aware paint + fix whitelist `tri`.
- **Scope:** zoom-aware paint hillshade/TRI на z9-z11, понижение
UI-минзума hillshade z10→z9, обратно-совместимое расширение
`applyTerrainLayer`, расширение backend-whitelist на `tri`.
@@ -117,14 +65,14 @@ related:
| F-01/11 | `updateHillshadeAvailability`: `zoom < 9` (app.js:3425) | ✅ старый `< 10` отсутствует |
| F-02 | hillshade minzoom=9, paint=HILLSHADE_PAINT (app.js:2825) | ✅ |
| F-03 | TRI minzoom=5/maxzoom=15, paint=TRI_PAINT (app.js:2826) | ✅ не тронут |
| F-04 | `applyTerrainLayer(opacityOrPaint)` (app.js:3371-3380) | ✅ number→legacy(linear) / object as-is |
| F-04 | `applyTerrainLayer(opacityOrPaint)` (app.js:3371-3414) | ✅ number→legacy(linear) / object as-is |
| F-05/06/07 | HILLSHADE_PAINT opacity 9:0.65→14:0.40; contrast 9:0.40→14:0.00; nearest | ✅ stops точно по TRZ/ADR |
| F-08/09 | TRI_PAINT opacity z8=0.70, пик z9-z11=0.85, спад до 0.70; nearest | ✅ stops точно |
| F-10 | hint «Зум 9+» (index.html:60) | ✅ |
| F-12 | контракт `onTerrainCheckbox`, persistence `localStorage`, `.active` | ✅ без изменений |
| F-13/14 | unit-тесты (Вариант B, Python-парсер) + регрессии | ✅ 17 тестов, PASS |
| F-15 | integration smoke z9 (`test_terrain_z9_tiles.py`) с `skipif` | ✅ присутствует |
| F-18 | API контракт `/terrain/{layer}/{z}/{x}/{y}.png`, `Cache-Control: immutable` | ✅ сохранён (main.py:1260) |
| F-18 | API контракт `/terrain/{layer}/{z}/{x}/{y}.png`, `Cache-Control: immutable` | ✅ сохранён |
| F-19 | style.json/style-dark.json/app.css/config не тронуты | ✅ diff чист |
## Соответствие ADR-017
@@ -136,20 +84,20 @@ related:
глобально), U-A (UI-порог z9), A-A (обратно-совместимая сигнатура),
M-A (константы в `app.js`) — все соблюдены. ✅
- Отклонённые «жирные» альтернативы (z-factor 2.5, raster-dem,
theme-specific paint) корректно вынесены в follow-up (TD-1..TD-5). ✅
theme-specific paint) корректно вынесены в follow-up. ✅
## Findings
| # | Severity | Файл | Описание | Статус |
|---|---|---|---|---|
| F-1 | (resolved) | `src/api/main.py:1252` | Whitelist endpoint'а не включал `tri` → 404 в dev без nginx. | Исправлено в `099669d`, документировано, покрыто integration-регрессией. |
| F-1 | (resolved) | `src/api/main.py` | Whitelist endpoint'а не включал `tri` → 404 в dev без nginx. | Исправлено, документировано, покрыто integration-регрессией. |
| N-1 | P3 (info) | `src/api/main.py` | TRZ §2 декларировал backend «без изменений», но фикс F-1 — необходимая корректная правка (TRI был latent-broken в dev). Контракт endpoint'а (URL, коды, `Cache-Control`) не нарушен → REQ-F-18 соблюдён. Не дефект. | Принято. |
## Качество кода
- `applyTerrainLayer` расширен обратно-совместимо; ветвление
`typeof opacityOrPaint === 'number'` собирает legacy-paint
(`raster-opacity` + `linear`) либо пробрасывает object as-is. JSDoc/комментарии на месте.
(`raster-opacity` + `linear`) либо пробрасывает object as-is. JSDoc на месте.
- `HILLSHADE_PAINT`/`TRI_PAINT` вынесены рядом с `TERRAIN_BASE_URL` с
пояснением логики stops; конфигурируемость через env/config справедливо
отвергнута (калибровка живёт в коде).
@@ -160,17 +108,21 @@ related:
- **Unit (17):** opacity/contrast stops, монотонность, `nearest`,
регрессия z8=0.70, пик z9-z11≥0.80, обратная совместимость
`applyTerrainLayer`, порог `zoom < 9`, текст hint, число call-site,
привязка paint-константы и minzoom к каждому слою. Парсер устойчив к
пробелам/переносам. **17/17 PASS локально (0.03 s).**
привязка paint-константы и minzoom к каждому слою. **17/17 PASS локально (0.03 s).**
- **Integration:** TestClient против `src.api.main:app`; тайло-зависимые
кейсы `skipped` при отсутствии PH-6 данных, whitelist/404-регрессии
работают всегда.
## Замечание по статусу тестирования (вне content-review)
Test Report фиксирует BLOCKED на AC-19/REQ-F-20 §1: на test-среде
отсутствуют нарезанные z9-тайлы hillshade (PH-6 data). Это **инфраструктурный
дефект данных/деплоя, не дефект кода ET-013** — код корректно запрашивает
z9 hillshade, unit/integration/lint зелёные. Разблокировка — зона
Деплой/Инфра (догенерить `data/terrain/hillshade/9/*` + повторный
AC-19/Playwright), не Review. Кодовых P0/P1 не порождает.
## Вердикт
Нет P0/P1. Реализация полностью соответствует TRZ и ADR-017, тесты
адекватны и зелёные. **APPROVED.**
Ручная/визуальная приёмка (AC-03..AC-13, AC-19, AC-21) и сетевая
регрессия M-10 — зона этапов Тестирование/Деплой (см. `13-test-report.md`,
`14-deploy-log.md`), вне content-review кода.