From 0bca6dfb145459c1b564e21bc9bf9610a1e5f996 Mon Sep 17 00:00:00 2001 From: Sergey Matyunin Date: Mon, 24 Aug 2026 13:55:50 +0300 Subject: [PATCH] docs: add evidence and rollback to resize spec Issue: #289 User-Visible: no --- docs/specs/289-no-mixed-role-resize.md | 42 +++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/docs/specs/289-no-mixed-role-resize.md b/docs/specs/289-no-mixed-role-resize.md index 2544e263..c2fad36b 100644 --- a/docs/specs/289-no-mixed-role-resize.md +++ b/docs/specs/289-no-mixed-role-resize.md @@ -117,12 +117,18 @@ moving edge, чей сдвиг на 43 шага создал бы mixed-role int `{enabled:false, reason:'partial-shared'}`; pointer capture, preview, history и write не создаются. +**Доказательство:** table-driven unit в `test/resize.test.mjs` плюс +production-bundle pointer smoke на минимизированной fixture. + ### AC2. Причина доступна человеку RU: «Нельзя сдвинуть только часть общей стены». EN передаёт тот же смысл. Disabled handle сохраняет hit area, `aria-disabled`, localized accessible name, tooltip на hover/focus и toast на click/tap. Он не запускает drag. +**Доказательство:** production-path DOM/source test для i18n/ARIA и browser +smoke для click, focus, tap и нулевой history/config write. + ### AC3. Directed safe range не перепрыгивает смену роли Для fixture, где один direction имеет несколько безопасных grid nodes, а @@ -130,6 +136,9 @@ tooltip на hover/focus и toast на click/tap. Он не запускает d endpoint-to-endpoint node. Он не перескакивает через запрещённый node к более дальнему валидному polygon. Обратное безопасное направление остаётся рабочим. +**Доказательство:** pure unit для последовательности grid candidates и browser +smoke, сравнивающий фактическую preview/commit coordinate с первым unsafe node. + ### AC4. Разрешённые сценарии #277 сохраняются - non-shared outer wall изменяет одну room; @@ -139,6 +148,9 @@ endpoint-to-endpoint node. Он не перескакивает через за - zero-range handle #281 disabled по своей точной причине; - pinch, pointercancel и lostpointercapture дают ноль записей. +**Доказательство:** table-driven positive unit matrix и существующие +`smoke_room_resize` pointer scenarios без ослабления их exact assertions. + ### AC5. Persisted model чиста После каждого разрешённого commit `checkMixedRoleRecords` возвращает ноль. @@ -146,6 +158,9 @@ endpoint-to-endpoint node. Он не перескакивает через за preflight также возвращают ноль нарушений. Exact forbidden repro оставляет JSON config/layout byte-equivalent. +**Доказательство:** `scripts/model-invariants.mjs`/targeted invariant unit на +before/after candidate и byte-for-byte assertion forbidden config/layout. + ### AC6. Preview и commit используют один proof Ownership profile входит в immutable `SafeResizePlan`/его signature и @@ -153,6 +168,9 @@ Ownership profile входит в immutable `SafeResizePlan`/его signature и owners изменились, весь жест отменяется с `resize.commit_failed`, без partial write. Commit принимает только exact preview. +**Доказательство:** unit, подменяющий owner signature между preview/pointerup, +и production smoke с нулём history/config writes после rejected commit. + ### AC7. Production-bundle smoke `demo/smoke_room_resize.mjs` выполняет реальную попытку forbidden 43-step drag, @@ -189,13 +207,29 @@ handle и cancellation не сохраняют геометрию. получает новый глобальный `O(R×E)` анализ: он проверяет подготовленный plan и contiguous deltas. Действующие p95 budgets из `docs/RESIZE.md` сохраняются. -## 8. Ожидаемые файлы +## 8. Риски и меры + +- Слишком строгий ownership profile может отключить безопасные outer/exact + shared стены. Мера: positive AC3/AC4 и exact reason matrix, запрещающая + blanket-disable. +- Слишком мягкий профиль снова позволит одному thickness record описывать + shared и outer intervals. Мера: AC1/AC5, `checkMixedRoleRecords` и мутант AC8. +- Preview и pointerup могут проверить разные owners после внешнего обновления. + Мера: immutable signature и atomic reject AC6. + +## 9. Откат + +Чистый revert implementation-коммита возвращает прежнюю eligibility; миграция +и feature flag не требуются, потому что persisted geometry/schema не меняются. + +## 10. Ожидаемые файлы Product code: - `src/resize.ts`; - `src/houseplan-card.ts` только для передачи profile/UX, если требуется; -- `src/i18n/en.json`, `src/i18n/ru.json`. +- `src/i18n/en.json`, `src/i18n/ru.json`, включая + `resize.disabled.partial-shared`. Tests/evidence: @@ -212,7 +246,7 @@ Tests/evidence: `docs/TESTING.md`; - `docs/CHANGELOG.md`, `docs/CHANGELOG.ru.md`. -## 9. Release и порядок интеграции +## 11. Release и порядок интеграции Implementation-коммит имеет `Issue: #289`, `User-Visible: yes` и оба changelog. Если меняется вид disabled handle, targeted golden/docs screenshots @@ -221,7 +255,7 @@ changelog. Если меняется вид disabled handle, targeted golden/doc Инфраструктурная #260 должна попасть в `dev` до финальной пересъёмки, но не входит в product branch #289. -## 10. Принятые технические предположения +## 12. Принятые технические предположения 1. Существующий reason key `partial-shared` переиспользуется, но его текст меняется на принятое владельцем объяснение.