mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
docs: #398 spec revision 3 per SPEC-REVIEW-398-r2
User-Visible: no Issue: #398
This commit is contained in:
@@ -3,7 +3,8 @@
|
|||||||
- Issue: https://github.com/Matysh/houseplan-card/issues/398
|
- Issue: https://github.com/Matysh/houseplan-card/issues/398
|
||||||
- Приоритет: P2, infra/tests; полный трек — класс B (тесты и гейт), меняется
|
- Приоритет: P2, infra/tests; полный трек — класс B (тесты и гейт), меняется
|
||||||
правило, а не продуктовый код
|
правило, а не продуктовый код
|
||||||
- Ревизия: 2 (2026-08-31) — по SPEC-REVIEW-398-r1 (Medium: путь 2 несовместим с AC4)
|
- Ревизия: 3 (2026-08-31) — по SPEC-REVIEW-398-r2 (Medium: статический гвард
|
||||||
|
против самоочищающегося файла)
|
||||||
|
|
||||||
## Сценарий
|
## Сценарий
|
||||||
|
|
||||||
@@ -84,7 +85,19 @@ custom_components.houseplan.coordinate_canonicalization
|
|||||||
`custom_components` за время `exec_module`, — тогда после вызова остаются ровно
|
`custom_components` за время `exec_module`, — тогда после вызова остаются ровно
|
||||||
пустышки conftest. Проверено исполнением, включая повторный вызов подряд.
|
пустышки conftest. Проверено исполнением, включая повторный вызов подряд.
|
||||||
|
|
||||||
Единственное исключение остаётся одно — `tests_backend/conftest.py`.
|
**Исключений в статическом гварде два, и это не возврат снятого пути.**
|
||||||
|
Гвард читает исходники, не исполняя их, и физически не может знать, что
|
||||||
|
`load_pure` возвращает `sys.modules` в исходное состояние сразу после
|
||||||
|
`exec_module`. По букве AC1 он обязан отклонить `pure_imports.py` — но тогда
|
||||||
|
файл, делающий ровно то, чего задача требует, оказывается вне закона.
|
||||||
|
|
||||||
|
Поэтому исключений в списке два — `tests_backend/conftest.py` (условная
|
||||||
|
подмена, контракт #394) и `tests_backend/pure_imports.py` (запись, снимаемая
|
||||||
|
тем же вызовом). Разница со снятым «путём 2» существенная: там файл
|
||||||
|
исключался ВМЕСТО очистки, здесь — при обязательной очистке, которую держит
|
||||||
|
исполняемый AC4 и отдельный AC8. Статический список отвечает на вопрос «кому
|
||||||
|
разрешено писать в `sys.modules`», исполняемая проверка — на вопрос «осталось
|
||||||
|
ли что-нибудь после»; подменять второе первым и было исходной ошибкой #394.
|
||||||
|
|
||||||
## Скоуп / не-скоуп
|
## Скоуп / не-скоуп
|
||||||
|
|
||||||
@@ -117,8 +130,13 @@ custom_components.houseplan.coordinate_canonicalization
|
|||||||
`sys.modules.setdefault(...)`/`update(...)` тоже отклоняются либо приводят к
|
`sys.modules.setdefault(...)`/`update(...)` тоже отклоняются либо приводят к
|
||||||
явному отказу «не могу доказать безопасность». Доказательство: по одному
|
явному отказу «не могу доказать безопасность». Доказательство: по одному
|
||||||
контракту на форму.
|
контракту на форму.
|
||||||
- **AC3**. `tests_backend/conftest.py` остаётся разрешённым и остаётся
|
- **AC3**. Список статических исключений состоит ровно из двух поимённых
|
||||||
единственным исключением; список зафиксирован тестом, его рост краснеет.
|
файлов — `tests_backend/conftest.py` и `tests_backend/pure_imports.py`;
|
||||||
|
любой третий краснеет. Доказательство: контрактный тест на список.
|
||||||
|
- **AC8**. Исключение не превращается в дыру: `pure_imports.py` обязан
|
||||||
|
восстанавливать `sys.modules` в `finally`, и это проверяется отдельно от
|
||||||
|
гварда. Доказательство: тест, который убирает восстановление и получает
|
||||||
|
красный AC4 (мутант `pure-imports-stops-cleaning`).
|
||||||
- **AC4**. После прогона всего `tests_backend/` в `sys.modules` нет ключей
|
- **AC4**. После прогона всего `tests_backend/` в `sys.modules` нет ключей
|
||||||
`custom_components*` сверх тех, что положил conftest. Доказательство:
|
`custom_components*` сверх тех, что положил conftest. Доказательство:
|
||||||
исполняемая проверка, а не чтение исходников.
|
исполняемая проверка, а не чтение исходников.
|
||||||
@@ -136,7 +154,7 @@ custom_components.houseplan.coordinate_canonicalization
|
|||||||
1. Синтетический файл с записью через переменную → гвард краснеет (AC1).
|
1. Синтетический файл с записью через переменную → гвард краснеет (AC1).
|
||||||
2. По контракту на каждую форму из AC2.
|
2. По контракту на каждую форму из AC2.
|
||||||
3. `conftest.py` со своей условной подменой → зелено (AC3).
|
3. `conftest.py` со своей условной подменой → зелено (AC3).
|
||||||
4. Попытка добавить второй файл в список исключений → красный.
|
4. Попытка добавить третий файл в список исключений → красный (AC3).
|
||||||
|
|
||||||
**Backend** (`tests_backend/test_backend_quality.py` или новый файл):
|
**Backend** (`tests_backend/test_backend_quality.py` или новый файл):
|
||||||
|
|
||||||
@@ -145,8 +163,10 @@ custom_components.houseplan.coordinate_canonicalization
|
|||||||
|
|
||||||
**Мутант** (`scripts/mutation-gate.mjs`):
|
**Мутант** (`scripts/mutation-gate.mjs`):
|
||||||
|
|
||||||
- `sysmodules-guard-blind-to-variable`: вернуть запись через переменную в
|
- `sysmodules-guard-blind-to-variable`: добавить запись через переменную в
|
||||||
`pure_imports.py` → гвард красный.
|
файл ВНЕ списка исключений → гвард красный.
|
||||||
|
- `pure-imports-stops-cleaning`: убрать восстановление `sys.modules` из
|
||||||
|
`finally` в `pure_imports.py` → исполняемая проверка AC4 красная (AC8).
|
||||||
|
|
||||||
## Риски
|
## Риски
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user