diff --git a/docs/specs/385-audit-lows.md b/docs/specs/385-audit-lows.md index 38155047..43900f59 100644 --- a/docs/specs/385-audit-lows.md +++ b/docs/specs/385-audit-lows.md @@ -4,7 +4,7 @@ - Приоритет: P3, polish; полный трек (четыре несвязанные поверхности — фронт-UI, фронт-модель, инфраструктурный скрипт, бэкенд; критерий «одна поверхность» §5 не выполняется — прецеденты #369, SPEC-REVIEW-376-r1 H1) -- Ревизия: 1 (2026-08-30) +- Ревизия: 2 (2026-08-30) — по SPEC-REVIEW-385-r1 (M1 + Low) ## Сценарий @@ -42,10 +42,21 @@ `scripts/process-gate.mjs:139-155`: `parseRecords` зовёт дорогую проверку (2×`git show` на каждый src-файл) для КАЖДОГО коммита, хотя потребляется она только для стабильных релизных (`/^Release v\d/` без beta/candidate, :134). -Контракт: проверка вычисляется только для коммитов, чей subject проходит тот -же релизный предикат (вынести предикат в общую константу/функцию, чтобы гейт -и вычислитель не разошлись). Семантика гейта не меняется: для нерелизных -`releaseSourceViolations` остаётся null, как и сегодня при `() => null`. +Контракт: проверка вычисляется только для коммитов, для которых `isRelease` +истинно, и предикат — это **буквально вынесенное целиком выражение из +`process-gate.mjs:133-135`, оба дизъюнкта**: +`(/^Release v\d/.test(subject) && !/-(beta|rc|alpha)\.|candidate/i.test(subject)) || Boolean(one('Release'))` — +НЕ пересказ по памяти и НЕ только первый дизъюнкт. Второй дизъюнкт +(`Release:`-трейлер) уже сегодня делает `isRelease` истинным для штатных +бета-коммитов приёмки эталонов (пример: `5f6ee657`), и суженный предикат дал +бы им `releaseSourceViolations: null` при `isRelease: true` → `evaluateCommit` +(:196-203) счёл бы ВСЕ их src-файлы нарушением → ложный отказ pre-push/CI. +Реализация: выражение выносится в одну функцию (например, +`isReleaseSubject(subject, one)`), которую используют И `makeCommit`, И гейт +вычисления в `parseRecords`; AC4 доказывает переиспользование. Семантика +гейта не меняется: для нерелизных `releaseSourceViolations` остаётся null, +как и сегодня при `() => null`; для релизных (по ПОЛНОМУ предикату) — +вычисляется, как сегодня. **(г) Асимметрия обезвреживания внешних ссылок при экспорте.** `custom_components/houseplan/import_export.py:504-519`: внешний @@ -120,11 +131,14 @@ Обычный `git revert`: флагов, миграций, персистентных данных нет. Откат (а) возвращает молчаливый сброс, остальное — косметика. -**DoR-примечания:** миграция/compatibility — нет; touch — не влияет. +**DoR-примечания:** миграция/compatibility — нет; touch — не влияет; +производительность — (в) сокращает работу pre-push/CI-гейта на длинных +диапазонах (только выигрыш, бенч не требуется), продуктовый рантайм не задет. ## Release-артефакты -- CHANGELOG + CHANGELOG.ru: user-visible запись про (а) («повторный клик по - выбранной привязке больше не сбрасывает источник значения»), (б)–(г) — - «мелкие уточнения»; ссылка #385. +- CHANGELOG + CHANGELOG.ru: user-visible запись только про (а) («повторный + клик по выбранной привязке больше не сбрасывает источник значения»), + ссылка #385. (б)–(г) видимого поведения не меняют и в changelog НЕ входят + (согласовано с разделом UX; коммит с ними — User-Visible: no). - Доки: не задеты.