Съёмка — Linux CI, Validate 35454723038 на acf179e4; приёмка — Windows
владельца с HP_ALLOW_FOREIGN_CAPTURE (#455).
Объявлены ровно одиннадцать сцен AC8; необъявленных расхождений нет —
иначе accept.mjs отказал бы до записи.
Issue: #598
User-Visible: no
Release: v1.77.0-beta.1
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/35454723038
Приняты с полного линуксового артефакта Validate (прогон 35441152733,
`full=true` на вершине задачи, Chromium 151.0.7922.34): остальные 169 сцен
сохранены без изменений, свидетелей среды 106 при пороге 10.
Список объявленных сцен — измеренный, а не предсказанный. Прежняя редакция ТЗ
ожидала расхождения всего мебельного среза: рисунок и правда поменялся у всех 44
прежних символов (сверил `d` каждого против `origin/dev` — совпавших ноль), но
0.4.0 перерисовывает те же формы с другой точностью координат, и в пикселях
сдвиг остаётся ПОД порогом сцены 0,0005. Разошлись ровно те кадры, где видны
иконки меню:
| сцена | diffRatio | что видно |
|---|---|---|
| `furniture-categories-light` | 0,003388 | в «Технике» появились «Компьютер», «Вытяжка», «Духовка» |
| `furniture-placement-preview-light` | 0,003061 | превью размещения с новым набором |
| `tray-narrow-palette-en` | 0,002200 | та же палитра на узком вьюпорте (найдено ревью r1 M2) |
| `furniture-new-symbols-light` | новая | четыре новых предмета, каждый в своём default-размере |
Каждый кадр просмотрен глазами: в палитре прибавились три плитки, мебельные
иконки на месте и той же формы; на новой сцене видны компьютер, вытяжка, духовка
и кактус — вид сверху, к масштабу, спинкой к стене.
Сцены `furniture-variants-*`, `furniture-plan-art-dark`, `furniture-transform-*`,
`decor-over-*` и `isometric-stage3-overlays-dark` остались `passed` при
diffRatio 0,000003…0,000413 — они не объявлены намеренно: декларация утверждает
«я знаю, почему кадр другой», а они не другие.
Индекс эталонов впервые записан по схеме 2 (#571): `capturedOn: linux` — из
отчёта съёмки, `acceptedOn` — среда приёмки, рядом лежит прогон CI 35441152733.
Issue: #593
User-Visible: no
Release: v1.77.0-beta.1
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/35441152733
Встроенная библиотека мебели была смешанной: 44 предмета рисовал дизайнер, а
12 — код, прямоугольниками и эллипсами в unit box. Они выбивались из стиля, и
три категории меню (`computer`, `hood`, `oven`) вообще не открывались, потому
что вида сверху для них не было.
Пакет 0.4.0 перерисовывает все 56 существующих публичных ID и добавляет четыре
новых: `computer`, `hood`, `oven`, `cactus`. Каталог становится равен поставке:
60 символов, 32 непустые категории.
Совместимость. Ни один сохранённый план не мигрирует: положение, размер,
поворот, отражение, цвет, прозрачность и толщина линии не трогаются, а
default-размеры всех 56 прежних ID совпадают со старыми до числа — таблица
зашита в `test/furniture.test.mjs`, чтобы сдвиг было видно тестом, а не глазами.
Ловушка, ради которой примитивы удалены целиком. Библиотека собиралась союзом
каталога и `LEGACY_FURNITURE`, и обе половины несли ОДНИ И ТЕ ЖЕ публичные ID.
`BY_ID` — это `Map`, она оставляет последнюю запись, поэтому примитив молча
побеждал дизайнерский рисунок, который его заменял: задача выглядит выполненной,
12 предметов не обновились, ни один существующий тест этого не видит. Поэтому
`LEGACY_FURNITURE`, `RETAINED_IDS`, тип `Prim`, `box()` и `primitivePathD`
удалены, а на дубликаты в каталоге стоит тест и мутант.
Два продуктовых решения владельца (#593):
- `cactus` живёт в категории `plant`, а не `exercise`, как предлагал пакет:
плитка «Тренажёр» рисует тренажёр, и открывать её на кактус — врать о
содержимом палитры. `exercise` остаётся скрытой пустой категорией, непустых
становится 32, а не 33;
- при отказе ленивого чанка с рисунками не рисуется НИЧЕГО. Прежде 12
примитивов рисовались всегда, и `docs/FURNITURE.md` это обещал; обещание
снято. Это единственное место, где задача ухудшает наблюдаемое поведение, и
оно проверяется смоком, а не словом.
Бюджеты. Ревью ТЗ показало, что «бюджет ленивого графа защищён» было
заявлением без гейта: размеры печатались в отчёт и ни с чем не сравнивались.
Добавлены `lazyGraphCeilingViolation` и два настоящих потолка со своим мутантом.
Стартовый граф ушёл ниже полосы, поэтому `INITIAL_VIEW_GZIP_CEILING` опущен
292 400 → 291 400 — вторая половина храповика, без которой выигрыш отыграется.
Провенанс. Документ пакета воссоздан под 0.4.0: грант владельца, имя архива и
его SHA-256. Это единственная исполнимая защита от повторения истории #159, и
она не ослаблена — число проверок в тесте не уменьшилось, а мутант подменяет
хеш и обязан её покраснить.
Свидетели: пять новых мутантов, новая golden-сцена `furniture-new-symbols-light`
для четырёх новых ID, матрица 63 → 64. Шестой мутант правится, а не добавляется:
`furniture-placement-needs-art` ссылался на удалённое поле `g` и переставал
компилироваться — раннер честно отличал это от «пойман» и отчитывался
setup-failure. Ложь мутанта осталась прежней по смыслу, убрана только ветка про
примитив.
i18n: 7 ключей × 4 локали. `furn.cat_exercise` не добавлен — категория скрыта.
Issue: #593
User-Visible: yes
Приняты с полного линуксового артефакта Validate (прогон 35407468491,
full=true на материале ec23a351); остальные сцены сохранены без изменений.
Две пары кадров разного происхождения:
- room-temperature-dialog-desktop-en, room-temperature-dialog-mobile-ru —
объявленные AC7 сцены #594: диалог настроек комнаты собран из карточек
набора контролов, поля и их порядок соответствуют ТЗ;
- device-icon-state-table-light, device-icon-state-table-dark — долг #588,
расхождение воспроизводится на чистом dev и к #594 отношения не имеет;
принимаются здесь потому, что goldenAcceptanceRefusal запрещает приёмку
при любой неназванной разошедшейся сцене.
Issue: #594
User-Visible: no
Release: v1.76.0-beta.5
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/35407468491
Пятый вариант «Отображение»: маркер показывает выбранное значение и при этом
никогда не меняет цвет — ни по состоянию, ни по тревоге, ни по недоступности,
ни под цвет RGB-света, ни по активности.
Четыре прежних режима задавали одним выбором две независимые вещи: что
нарисовано внутри маркера и красится ли он состоянием. Поэтому вместо
сравнения с одним токеном появились два производных предиката рядом с
`normalizeDeviceDisplay` — `displayWantsValue` и `displayIsNeutral`, — и их
спрашивают политика, слой пульсации, внешний бейдж, редактор и три ветки
живого слоя пылесоса.
Две ловушки, из-за которых режим не сводится к одной строке в словаре:
- быстрый путь «статичному маркеру источники не нужны» (`sourceDetails: false`)
— это основной путь рендера плана, карточки пространства и PDF. Он оставлен
только режиму без значения: иначе число пропало бы именно на плане и
осталось в предпросмотре редактора;
- три ветки живого пылесоса сравнивают режим строкой и не читают политику,
поэтому зелёная политика их не гарантирует. Свидетель держит две
конфигурации карты: сопоставленная доказывает puck и след, несопоставленная
— бейдж маршрута (при совпадающей калибровке маршрут `ready`, и бейджа не
было бы ни в одном режиме). Бейдж проверяется при наполненном буфере
позиций, иначе его отсутствие объяснялось бы первой веткой.
Потолок initial View перецентрирован 291_700 → 292_400 без изменения общего
бюджета: измеренный факт 291 346 Б оставлял под прежним центром 354 Б —
внутри шумовой полосы метрики.
Эталон: в `device-icon-state-table-{light,dark}` включённая RGB-лампа
переведена в новый режим. Кадры обязаны разойтись; приёмка — отдельным
коммитом класса D с полного линуксового артефакта Validate.
Issue: #588
User-Visible: yes
Аудит 14.09, §4 и §9. `golden-report.json` не нёс платформу вовсе, поэтому
приёмщик вызывал `captureEnvironment()` у себя и записывал СВОЮ платформу как
платформу кадров. На `ad4000f9` это дало `"platform": "win32"` у кадров,
снятых Linux-прогоном 34853080375, а причина осознанного обхода осталась в
stdout и в индекс не попала — хотя `AGENTS.md` обещает след в обоих местах.
Сами PNG были и остаются целы: 101 свидетель совпал байт-в-байт. Врал
провенанс.
Что сделано:
- отчёт съёмки получил раздел `capture`: платформа, архитектура, сборка
Chromium, отпечаток материала и — в CI — прогон с попыткой и SHA. Схема
отчёта поднята до 2;
- приёмка читает среду съёмки из отчёта. Гейт чужой среды теперь судит обе
стороны: съёмку (из отчёта) и приёмку (свою). Отказ — до единой записи;
- индекс эталонов поднят до схемы 2 и различает `capturedOn` и `acceptedOn`,
несёт раздел `capture` и причину осознанного обхода в `foreignCapture`;
- отчёт схемы 1 платформы съёмки не несёт физически: это отдельная явная
ветка, `capturedOn` уезжает `null`. Выдумывать платформу нельзя — ровно этим
задача и вызвана;
- `--baselines=<dir>` у приёмки: без него проверить «отказ произошёл ДО
записи» можно было бы только порчей рабочего дерева, то есть никак (#556).
Осознанно отменено решение #455 «не трогать run.mjs»: ради ГЕЙТА цена
фингерпринта не окупалась, ради ПРОВЕНАНСА окупилась — платформу кадров знает
только тот, кто их снял. Плата разовая: пересобран бандл, индекс скриншотов
документации переснят отдельным коммитом. Тест #455 переписан под новый
инвариант, а не удалён.
Свидетели: `test/golden-capture-provenance.test.mjs` — семь проверок, все пять
сценариев приёмки из issue, включая «отказ до записи» и «подмена PNG и неполный
артефакт по-прежнему fail-closed». Мутанты `golden-index-invents-capture-platform`
(возвращает платформу приёмщика) и `golden-report-provenance-optional`
(разрешает отчёт схемы 2 без провенанса) прогнаны лично: оба краснеют.
npm test 2762/2761/0 fail, typecheck чистый.
Issue: #571
User-Visible: no
Девять golden-кадров приняты с полного линуксового артефакта Validate (прогон
35144164510, `full=true` на материале задачи); остальные 163 сохранены без
изменений, свидетелей среды 107.
Каждый разошедшийся кадр просмотрен глазами и объяснён:
- шесть мебельных (`furniture-variants-*`, `furniture-placement-preview-light`,
`furniture-plan-art-dark`, `furniture-transform-*`) — предметы занимают
заявленный бокс целиком. Там же видна вторая правка: у значка «Журнальный
стол, круглый» четыре ножки встали по местам внутри круга, а раньше две
болтались у нижнего края — ровно тот механизм смещения деталей, который
назван в шапке issue;
- два декоративных (`decor-over-opaque-hover-light`, `decor-over-glow-base-dark`)
— в сцене стоит диван, его контур дорос до границ бокса; форма, цвет и
положение прежние;
- `isometric-stage3-overlays-dark` — та же мебель в скрытом 2.5D-виде.
Посторонних изменений нет: расхождение 0,16–1,48 % пикселей кадра и целиком
внутри силуэтов мебели.
Индекс скриншотов документации переснят там же (прогон 35144241294): все
одиннадцать кадров совпали с закоммиченными байт-в-байт, принят только
отпечаток — мебель ни в один кадр документации не попадает.
Трейлер `Release:` называет ближайшую бету линейки по образцу #577 и #580;
если номер линейки окажется другим, он правится при подготовке кандидата.
Issue: #584
User-Visible: no
Release: v1.77.0-beta.1
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/35144164510
Двенадцать изометрических кадров приняты с полного линуксового артефакта
Validate прогона 35088061662; остальные 160 эталонов не менялись, свидетели
среды сходятся (104, floor 10).
Кадры пересняты дважды: сперва из-за продуктовой правки #583, затем из-за
ускорения расстановки подписей. Одиннадцать кадров совпадают с прогоном до
ускорения побайтно (maxΔ ≤ 2 — сглаживание), расстановку меняет один —
`isometric-large-warm-remount-dark`: в плотной комнате два маркера садятся друг
на друга вместо разъезда на 48 px. Это осознанная плата за скорость, заведена
отдельной задачей #585 с замерами обоих верных вариантов поиска; вид скрыт за
`hp_alpha` и пользователю не виден.
Issue: #583
User-Visible: no
Release: v1.76.0-beta.5
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/35088061662
Режим заливки комнаты и её цвет — два поля конфига под одним переключателем.
«Как у пространства» снимало только режим; цвет оставался и продолжал
применяться, потому что `roomCustomFillOf` отдавал цвет комнаты независимо от
того, чей режим `custom` действует. Так возникало безымянное состояние «режим
наследую, цвет свой» — Cabinet на даче.
Теперь цвет комнаты участвует в раскраске только вместе с её собственным
`fill_mode: 'custom'` (одна функция — все поверхности: карточка, space-card,
PDF, черновик диалога). Диалог загружает цвет в черновик только при своём
режиме, обнуляет его при уходе с «Свой цвет» и показывает строку цвета только
под этим радио; сохранение пишет `custom_fill` только с `fill_mode: 'custom'`,
иначе удаляет — включая сироту от прежнего редактора. Чтение конфиг не
переписывает: застрявшие комнаты выздоравливают обновлением.
- `test/logic.test.mjs`: AC1 — сирота и любой чужой режим → цвет пространства
- `demo/smoke_room_settings.mjs` шаг 7: свой цвет → «Как у пространства» →
ни режима, ни цвета, во View цвет пространства; сирота открывается как
наследование, сохранение её удаляет (проверено красным на базе: 9 фактов)
- `demo/smoke_space_settings.mjs`: override с собственным режимом + сирота
- `demo/golden/harness.mjs`: `roomCustomFill` ставит комнате её режим —
кадры `lighting-custom-glow-*` не меняются
- мутант `room-orphan-colour-wins-again`
- docs: ARCHITECTURE (#56), CONFIG-COMPATIBILITY, USER-GUIDE ru/en, TESTING;
отпечаток скриншотов принят попиксельно (11 кадров)
Issue: #581
User-Visible: yes
Новый Linux-кадр закрепляет две нарисованные части внешнего луча: физический тоннель окна и продолжение по чистому полу без шва. Два help-кадра ожидаемо включают новый глобальный селектор #577. Safe Resize отличается только стабильным растровым сглаживанием на 895 из 1062000 пикселей; геометрия и состояние интерфейса визуально совпадают.
Issue: #577
User-Visible: no
Release: v1.76.0-beta.3
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/34901679608
Accept the 13 visually reviewed Stage 4 isometric frames from the complete Linux Validate artifact. The other 156 baselines remain unchanged and 101 environment witnesses match.
Issue: #570
User-Visible: no
Release: v1.76.0-beta.3
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/34853080375
К2 задачи #532 назвала это заранее: промоушен поверхности контура в свой
композиционный слой делит SVG надвое, оставшееся содержимое ложится на другую
субпиксельную сетку, и диагональная штриховка стен сглаживается иначе. Кадры
полагалось пересмотреть на кандидате — они дожили до кандидата стабильного,
потому что golden-джоба гоняется только на дереве с трейлером `Release:`, а
мерж #532 такого трейлера не нёс.
Проверено по критериям AC3 самой #532: разошлись **ровно четыре** кадра
`day-cycle-{dawn,day,dusk,night}-dark`, средний цвет кадра сдвинулся на
0,001–0,080 из 255 при пороге 0,1, средний знаковый сдвиг на разошедшихся
пикселях от −0,19 до +0,87. Кадры просмотрены глазами: отличается только
сглаживание штриховки стен, палитра, геометрия, подписи и ореол те же.
Приняты из артефакта полного прогона Linux CI на этом же дереве, остальные
165 сцен сохранены без изменений, свидетелей среды 129.
Issue: #532
User-Visible: no
Release: v1.74.0
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/34641155082
Golden-джоба запускается только на кандидате с трейлером `Release:`, поэтому
Validate на мерже #530 её не гонял, и первый же релизный прогон
v1.74.0-beta.3 показал расхождение ровно в трёх сценах экспорта PDF:
`pdf-export-geometry-light`, `pdf-export-polish-light`,
`pdf-export-stepped-dimensions-light`.
Расхождение — это и есть предмет #530: план на листе крупнее, подписи
размеров стоят на чертеже, столбца выносов сбоку больше нет
(`sceneCoverage` 0.577). Кадры приняты с явным `--expect-change` из
артефакта того самого прогона (отпечаток исходников совпадает),
остальные 166 сцен сохранены без изменений, свидетелей среды 133.
Issue: #530
User-Visible: no
Release: v1.74.0-beta.3
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/34597337319
Re-acceptance after the version seam (#512 §7) from the full Validate
dispatch on 605991ef (run 34366858855): seven frames carried the version
text — three version-mismatch banners, three PDF footers, the support
preview — and now read `0.0.0-golden`; six of them were within threshold
and still showed stale betas (beta.4, beta.8). The other 162 frames are
kept as reviewed; 128 environment witnesses matched byte for byte.
Sub-threshold drift in nine unrelated frames (tray, resize handles,
compass, junction) is not accepted.
Issue: #512
User-Visible: no
Release: v1.74.0-beta.1
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/34366858855
Golden frames carried the card version text (about, version banner,
support/export previews), so every beta bump re-accepted up to 20
baselines that had not visually changed. The version now reaches the DOM
and stand requests through displayVersion() (src/card-version.ts); the
golden harness pins window.__HP_VERSION_OVERRIDE__ = '0.0.0-golden'
before the card is created. CARD_VERSION literals stay where the release
contract reads them; cache-busting and the console banner keep the literal.
Docs screenshots: `npm run docs:accept -- --identical` re-captures
locally, compares decoded RGBA pixels with the committed frames inside
Chromium (scripts/png-identical.mjs) and, only when every frame is
identical, refreshes the manifest fingerprints and captureScriptSha256;
bytes stay, any difference refuses with a per-frame count. First run on
this tree: 11/11 identical, manifest refreshed.
Mutants: version-seam-ignores-override, docs-identical-accepts-any-frame.
Issue: #512
User-Visible: no
Personally reviewed all 20 diffs from complete Linux capture34323743229: #505 header/control placement and beta version text only. 149 baselines remain untouched,112 exact witnesses. Product and timing guard unchanged; candidate reruns the same50ms search threshold after a single CI timing failure (local p95=17ms).
Issue: #505
User-Visible: no
Release: v1.73.0-beta.8
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/34323743229
Fifteen reviewed scenes from the CI matrix on dev 55d832ec: ten isometric
scenes without the painted overlay plates (#471) and five color-popover
scenes with the OK button (#476). Pixels taken from the Validate artifact,
not from a local capture.
Issue: #471
Release: v1.73.0-beta.2
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/34046189201
User-Visible: no
Каталог (id, группа, размеры) остаётся eager; SVG-пути 44 дизайнерских
символов — отдельный чанк за FurnitureArtRuntime (ready|pending|fallback,
нонс на повторе, отпечаток сборки, осевший отказ). Запуск при приёме плана,
бут-вуаль ждёт арт в пределах BOOT_MAX_MS, редактор отдаёт арт рантайму
синхронно (adopt при загрузке чанка). Магнит проверяет каталог, не арт.
Потолок initial View 300 500 → 290 500. Семь свидетелей, смок
smoke_furniture_lazy_art, golden-harness требует все предметы после бута.
Ядро −2 строки.
Issue: #474
User-Visible: no
Keep the raised overlay footprint as calculation-only geometry for collision, nudge and fit while removing its painted SVG surface and texture. Update Stage 3 contracts, smokes, golden harness rules and synchronized bundles.
Issue: #471
User-Visible: no
Вопрос владельца: зачем агенты снимают PNG на Windows, если кадры мы всё
равно не принимаем, тем более что WSL есть на обеих машинах. Ответ по
коду: этому ничто не мешало. Ни один из шести скриптов съёмки и приёмки
не знал, на какой он ОС — ни `process.platform`, ни win32, ни WSL не
упоминались нигде. Съёмка отрабатывала штатно, а стена появлялась на
приёмке, и текст стены говорил «сцен-свидетелей 0 из 10», то есть
подсказывал неверный вывод «надо объявить больше сцен» — от которого до
`--expect-change` на всю матрицу одна команда.
Причина запрета не политика, а физика: Windows растеризует текст через
DirectWrite, с другим субпиксельным сглаживанием и DPI, поэтому
байтового совпадения с принятым эталоном не даёт никогда, свидетелей
среды быть не может, и приёмка откажет всё равно. Флаги детерминизма из
#410 убирают разброс внутри среды, а не между ОС.
Что сделано:
- `golden:capture` отказывается до запуска браузера, в тексте отказа
готовая команда для WSL;
- `golden:verify` остаётся законным в любой среде: он ничего не
принимает, а как грубая проверка полезен;
- обе приёмки (golden и документации) отказываются в чужой среде;
- к отказу свидетелей приписывается фраза про расхождение среды — та
самая, которой не хватало, чтобы отказ не читался как «объяви больше
сцен»;
- платформа уезжает в манифесты рядом с версией Chromium: у кадров
появился провенанс среды;
- осознанный обход есть и требует причину: HP_ALLOW_FOREIGN_CAPTURE.
Главный урок задачи — про цену правки файла, у которого записан хеш.
Первая редакция встроила проверку в `demo/docs/capture.mjs`, и гейт
документации сразу покраснел: его sha записан в индексе скриншотов, и
`scripts/check-docs.mjs` их сверяет. То есть проверка, которая ничего не
рисует, стоила бы пересъёмки всех картинок документации и визуальной
приёмки владельца. Поэтому для документации отказ живёт шагом раньше —
`npm run docs:capture` вызывает `scripts/assert-capture-env.mjs` — и
шагом позже, на приёмке. По той же причине гейт golden стоит в
`demo/golden/policy.mjs`, а не в `run.mjs`: последний входит в корпус
sourceFingerprint. Тест закрепляет обе границы: гейт обязан быть в
policy.mjs и в npm-скрипте и обязан отсутствовать в двух
фингерпринтуемых файлах.
Платформа в юнитах — параметр, а не `process.platform`: иначе тест был
бы зелёным на Linux и красным на машине владельца, то есть тестом про
хост, а не про правило.
AGENTS.md приведён к состоянию после #401 (принимается любая среда,
доказавшая себя байтовым совпадением непринятых кадров) и разводит
проверку и съёмку — прежний текст сливал их в «advisory» и утверждал
«accepted only on a complete Linux CI artefact».
Свидетели, все проверены отрицательным прогоном: снятый гейт съёмки,
гейт, отказывающий и на verify, обход без причины, отказ без команды,
убранная приписка про среду, отцепленные гейты обеих приёмок,
переставшая бросать обёртка, npm-скрипт без проверки и возврат гейта в
каждый из двух фингерпринтуемых файлов. Проверка подключения сначала
смотрела только на импорт модуля и молча проходила, когда отказ
заменяли на `void` — теперь она проверяет вызов бросающей обёртки.
Гейты: npm test 1918 tests, 1917 pass, 0 fail; typecheck зелёный;
check-docs зелёный (индекс скриншотов не задет); pytest без HA 378
passed, 3 skipped.
Issue: #455
User-Visible: no