diff --git a/docs/specs/220-space-tab-reorder.md b/docs/specs/220-space-tab-reorder.md index 37875eb1..534b48d2 100644 --- a/docs/specs/220-space-tab-reorder.md +++ b/docs/specs/220-space-tab-reorder.md @@ -104,16 +104,39 @@ открыта — открытая остаётся открытой; перетащили открытую — она открыта на новом месте. -### 8.3. Развязка `firstSpaceId` +### 8.3. Маркеры не двигаются: материализация вместо нового поля -Fallback-пространство перестаёт зависеть от позиции. `buildDevices` получает -`firstSpaceId` не как «первый по порядку», а как **стабильный якорь**: id -пространства, которое было первым на момент первой сборки конфигурации, и -которое не меняется от перестановки вкладок. +Обязательное свойство одно: **ни один маркер не меняет `space` из-за изменения +порядка**. Достигается оно не хранением якоря, а тем, что перестановка делает +явной ту привязку, которая до неё держалась на позиции. -Реализация — на усмотрение автора (§18), обязательное свойство одно: **ни один -маркер не меняет `space` из-за изменения порядка**. Это проверяется AC3 и -мутантом. +**Норматив.** В той же транзакции записи, что и новый порядок, каждый маркер, +чьё пространство сегодня разрешается через `firstSpaceId` — то есть у него нет +ни `area`, ведущей в пространство, ни собственного `space` — получает явное +`space`, равное тому пространству, в котором он находится **сейчас**, до +перестановки. После этого его размещение от порядка не зависит вовсе, и +`firstSpaceId` перестаёт быть для него значимым. + +**Почему так, а не якорь в `settings`.** Первая редакция ТЗ предполагала хранить +id «первого» пространства отдельным полем. Ревью r1 (M2) справедливо указало, +что это новое поле конфигурации, которое §9 в том же документе отрицал. +Материализация решает ту же задачу без расширения схемы: + +- новых полей нет — `CONFIG_SCHEMA`, `scripts/config-field-registry.mjs` и + `docs/CONFIG-COMPATIBILITY.md` не трогаются; +- запись идёт одним `config/set` с уже существующими полями маркеров; +- правка данных минимальна и сохраняет наблюдаемое состояние: маркер остаётся + ровно там, где пользователь его видел; +- откат не нужен: явное `space` — валидное и предпочтительное состояние, + которое карточка и так пишет при любом сохранении маркера. + +**Граница.** Материализуются только маркеры, разрешавшиеся через +`firstSpaceId`. Маркеры с `area` или с уже заданным `space` не трогаются — +проверяется AC3. + +Если исполнитель обнаружит случай, который материализация не покрывает +(например, маркер вообще не попал в текущую модель), это не повод возвращать +якорь молча: такой случай выносится в ревью как находка. ### 8.4. Навигация @@ -128,10 +151,23 @@ Fallback-пространство перестаёт зависеть от по такие панели». Показывается один раз за сессию, независимо от числа перестановок, и не блокирует работу. -## 9. Данные, i18n, a11y, privacy, security +## 9. Данные, i18n, a11y, touch, privacy, security -- **Данные:** только порядок элементов массива `spaces`. Ни одно поле не - добавляется и не удаляется; миграции и compatibility-полей нет. +**Touch editor: not exposed.** Классификация по `docs/TOUCH-SUPPORT.md` §153: +перетаскивание вкладок на сенсорных экранах не появляется вовсе — ни как +degraded-вариант, ни как долгое нажатие. Это решение владельца §4.1, а не +недоделка. Обоснование: вкладки живут во View, где переключение пространств — +fully supported на тач и release-blocking; любой жест на вкладке рискует съесть +тап. Порядок пространств меняется на десктопе, как и остальная работа с планом. + +Safety floor §69 того же документа соблюдён по построению: на тач-устройстве +поведение вкладок не меняется ни на йоту, значит ни потери данных, ни случайной +мутации при мультитаче новая функция внести не может. + +- **Данные:** порядок элементов массива `spaces` плюс материализация неявной + привязки маркеров (§8.3). Новых полей конфигурации не появляется, схема и + `CONFIG_SCHEMA` не меняются — см. §8.3 о том, почему выбран путь без нового + поля и что это значит для `docs/CONFIG-COMPATIBILITY.md`. - **i18n:** один новый ключ тоста (en + ru) и, при необходимости, `title` вкладки в режиме редактора. - **a11y:** без изменений — клавиатурной навигации в редакторах нет и не @@ -165,8 +201,9 @@ Fallback-пространство перестаёт зависеть от по **Доказательство:** `smoke`. 3. **AC3 — маркеры не двигаются.** Конфигурация с маркером, чьё размещение опирается на fallback-пространство, после перестановки даёт то же `space` - для каждого маркера. Тест красный до развязки §8.3. - **Доказательство:** `unit` (`buildDevices`). + для каждого маркера; такой маркер получает явное `space` в той же записи, а + маркеры с `area` или с уже заданным `space` остаются побитово прежними. + Тест красный до §8.3. **Доказательство:** `unit` (`buildDevices` + запись). 4. **AC4 — навигация следует порядку.** После перестановки `swipeTarget` возвращает нового соседа немедленно, без перезагрузки. **Доказательство:** `unit` + `smoke`. @@ -201,7 +238,8 @@ Fallback-пространство перестаёт зависеть от по |---|---|---| | `tab-reorder-not-persisted` | перестановка меняет только локальную модель, `_writeConfig` не зовётся | смок AC1 | | `tab-reorder-eats-click` | убрать порог смещения — любой pointerdown начинает drag | смок AC2 | -| `first-space-follows-order` | вернуть `firstSpaceId = _model[0]?.id` | юнит AC3 | +| `reorder-skips-materialization` | записывать новый порядок, не материализуя привязку маркеров | юнит AC3 | +| `materialization-touches-bound-markers` | материализовать `space` и у маркеров с `area` | юнит AC3 | | `tab-reorder-ignores-pointer-type` | снять проверку `pointerType === 'mouse'` | юнит AC5 | ## 15. Release-артефакты @@ -227,9 +265,10 @@ Fallback-пространство перестаёт зависеть от по 2. **Механика вставки** — вставка перетаскиваемой вкладки перед той, над серединой которой отпущена мышь. Альтернатива (обмен местами) отвергнута: при переносе через несколько позиций она даёт неожиданный результат. -3. **Способ развязки `firstSpaceId`** (§8.3): предполагается хранить якорь в - `settings` при первой записи конфигурации и читать его вместо `_model[0]`. - Если автор найдёт способ без нового поля — свойство важнее реализации. +3. **Материализация привязки** (§8.3) выполняется в том же `config/set`, что и + порядок, а не отдельной записью: две записи дали бы окно, в котором порядок + уже новый, а привязка ещё старая. Ревизия r2: прежняя редакция предлагала + якорь в `settings` — отвергнута по M2 ревью r1 как новое поле конфигурации. 4. **Тост о числовом `floor`** показывается всегда, а не только когда числовой `floor` действительно где-то используется: карточка не видит чужие панели, поэтому условие проверить нечем.