Волна 5 эпика #674, перенос ТЗ (класс C). Из 240 файлов `docs/specs/` в `legacy/specs/` уехали 219: на них не ссылается ни один живой файл (код, тесты, скрипты, workflow, документы вне архива и ревью). Остались 21 ТЗ — на которые ссылаются код, ADR, ISOMETRIC, SUN, RADAR, LIGHT (`docs/specs/067`), DECOR-EDITOR, support-relay, и те, на которые ссылаются они сами; README каталога объясняет, где искать остальное. Открытых issue с файлом ТЗ среди перенесённых нет. Относительные ссылки перенесённых файлов переписаны (`../X` → `../../docs/X`, соседние оставшиеся ТЗ → `../../docs/specs/…`) — все 26 резолвятся. Попутно: битая ссылка в `089-isometric-view-stage1.md:8` на удалённый `089-isometric-view.md` — теперь команда `git show` по истории. Строка в `legacy/README.md`. Issue: #682 User-Visible: no Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
6.2 KiB
Issue #280 — backend принимает доказанный Optimize rehost
- Дата: 2026-08-24
- Тип: regression bug · приоритет P1
- Issue: #280
- Ветка:
issue/280-optimize-rehost-backend - Статус ТЗ: одобрено self-review по решению владельца
Связанные контракты: #132, #186, #199, #224 и #276;
docs/CONFIG-COMPATIBILITY.md, docs/WALL-THICKNESS.md, docs/TESTING.md.
1. Проблема
#276 намеренно удаляет exact coincident partition и материализует её hosted
opening как ordinary room-wall opening. Backend при любом surviving opening
безусловно запрещает host != null → host == null, поэтому preview beta.8
успешен, а единственный Optimize write отклоняется как host removed.
Frontend mock не является доказательством server acceptance. Исправление должно сохранить общий запрет и дать исключение только специальному WS Optimize, если backend самостоятельно доказывает тот же безопасный переход.
2. Пользовательский результат
Apply для exact reconciliation #276 атомарно сохраняет candidate. Дверь/окно/
ворота не двигаются, partition исчезает, reload видит обычный room-wall
opening, а одноразовый Undo возвращает прежний partition и explicit host.
Обычный config/set и crafted Optimize без полного доказательства остаются
fail-closed с invalid_partition_opening_host.
3. Backend-контракт доказательства
validate_partition_opening_hosts() получает keyword-only capability,
включаемую только ws_plan_optimize. Capability не является доверием клиенту:
каждый снятый host должен пройти все проверки.
Для одного surviving opening backend требует:
- предыдущий host имеет
kind: partition, а предыдущий partition существует; - partition с этим id отсутствует в candidate;
- его полный отрезок является однозначной solid shared boundary ровно двух разных candidate rooms: оба endpoints лежат на collinear room edges;
- candidate physical wall envelope на всём отрезке не уже удалённого тела:
covering exact wall record имеет достаточный
cm, либо действующий default15 cmуже достаточен; - candidate
x/yравны точкеa + t × (b-a), angle совпадает с осью modulo 180°, length полностью помещается в отрезок; - все поля, кроме
hostи материализуемыхx/y/angle, byte-semantically равны предыдущему opening; - новый slot не перекрывает другой candidate opening на той же физической оси; every removed host в batch проходит проверку.
Coordinate tolerance — 1e-8 normalized units для девятизначной storage
канонизации. Он не используется для near/partial wall matching: collinearity и
coverage всё равно должны доказать полный исходный segment.
4. Scope
Входит:
- pure backend delta-proof и узкий Optimize-only call site;
- exact shared fixture, ordinary-write и crafted-candidate negative matrix;
- HA websocket success/atomic failure/Undo regression для Linux CI;
- cross-stack fixture: результат настоящего
optimizePlans()равен candidate, который принимает Python validator; - backend/config compatibility docs и оба changelog.
Не входит: общий отказ от host guard, доверие frontend counters, nearest-wall эвристика, изменение schema/model version или геометрии #276.
5. Acceptance criteria
- Privacy-minimized #276 fixture проходит frontend optimizer и backend Optimize-validation; второй Optimize — no-op.
- Тот же host removal при capability=false отклоняется.
- Отклоняются: partition остался; partial/non-shared/ambiguous wall; более узкий envelope; сдвиг/поворот/длина/тип/id/связи; overlap; unsafe второй opening в batch.
ws_plan_optimizeпередаёт capability,config/set— нет; validation завершается до первого store write.- Linux HA integration доказывает save/reload/Undo и неизменность revisions/ backup при failure.
- Pure backend, frontend unit, typecheck/build и targeted smoke зелёные.
6. Совместимость, security и performance
Schema и stored result уже поддерживаются старыми версиями: ordinary opening и room wall. Новый capability недоступен из payload и не расширяет права WS. Proof линейно обходит rooms/walls/openings только при явном Optimize и только для реально снятых hosts; render и обычные state updates не затрагиваются.
7. Self-review ТЗ
- Исключение привязано к server command, но не доверяет его происхождению.
- Доказательство покрывает identity, geometry, envelope и conflicts, а не только факт удаления partition.
- Позитивный cross-stack fixture закрывает точный разрыв тестов beta.8.
- Негативный ordinary config/set сохраняет прежнюю security/compat guarantee.
Вердикт: approved. Внешнее spec-review пропущено по прямому решению владельца.