93 lines
5.0 KiB
YAML
93 lines
5.0 KiB
YAML
work_item: ORCH-057
|
||
stage: analysis
|
||
author_agent: analyst
|
||
status: ready-for-review
|
||
created_at: 2026-06-10
|
||
model_used: claude-opus-4-8
|
||
title: "Нормализация legacy root-owned файлов при миграции на uid 1000 (детект + защита worktree)"
|
||
framework: pytest
|
||
scope: >
|
||
Покрывается: классификация ошибки прав в ensure_worktree (внятная actionable-ошибка),
|
||
детект несоответствия владельца (fs_normalize.scan_ownership), идемпотентность на чистой среде,
|
||
fail-safe/never-raise, scope/kill-switch (self-hosting only при пустом CSV), опц. self-heal-noop
|
||
без прав. ВНЕ покрытия: реальный chown под root (требует привилегий — проверяется на staging
|
||
вручную), правка docker-compose/entrypoint (инфра, ручная проверка на 8501).
|
||
notes: >
|
||
Все FS-зависимые тесты используют tmp_path и monkeypatch os.getuid/os.stat — без реального chown
|
||
и без записи в /repos. Telegram/Plane мокаются. Полный регресс tests/ должен оставаться зелёным;
|
||
STAGE_TRANSITIONS/QG_CHECKS/схема БД не затрагиваются — отдельные guard-тесты не требуются, но
|
||
существующие тесты на инварианты должны пройти без изменений.
|
||
|
||
tests:
|
||
- id: TC-01
|
||
type: unit
|
||
description: "ensure_worktree при git-fatal 'could not create leading directories / Permission denied' поднимает RuntimeError с диагнозом legacy-root + лечащей командой, а не сырой git stderr"
|
||
module: tests/test_git_worktree_perm.py
|
||
expected: PASS
|
||
|
||
- id: TC-02
|
||
type: unit
|
||
description: "ensure_worktree при ошибке, НЕ связанной с правами (например branch conflict), сохраняет прежний контракт сообщения (не подменяет смысл)"
|
||
module: tests/test_git_worktree_perm.py
|
||
expected: PASS
|
||
|
||
- id: TC-03
|
||
type: unit
|
||
description: "scan_ownership на дереве с файлом uid != target_uid возвращает mismatch=True и список затронутых корней"
|
||
module: tests/test_fs_normalize.py
|
||
expected: PASS
|
||
|
||
- id: TC-04
|
||
type: unit
|
||
description: "scan_ownership на чистом дереве (все файлы target_uid) возвращает mismatch=False (идемпотентный no-op)"
|
||
module: tests/test_fs_normalize.py
|
||
expected: PASS
|
||
|
||
- id: TC-05
|
||
type: unit
|
||
description: "scan_ownership never-raise: при недоступном/несуществующем корне деградирует в WARNING и не бросает наружу"
|
||
module: tests/test_fs_normalize.py
|
||
expected: PASS
|
||
|
||
- id: TC-06
|
||
type: unit
|
||
description: "applies(repo): пустой ORCH_FS_NORMALIZE_REPOS → True только для self-hosting репо (orchestrator), False для enduro-trails; непустой CSV — по списку"
|
||
module: tests/test_fs_normalize.py
|
||
expected: PASS
|
||
|
||
- id: TC-07
|
||
type: unit
|
||
description: "kill-switch ORCH_FS_NORMALIZE_ENABLED=False → scan/normalize инертны (no-op), поведение 1:1 как до ORCH-057"
|
||
module: tests/test_fs_normalize.py
|
||
expected: PASS
|
||
|
||
- id: TC-08
|
||
type: unit
|
||
description: "normalize без прав (uid 1000, чужие root-файлы, ORCH_FS_NORMALIZE_AUTO=True) → no-op + честный лог 'нужна операторская процедура', НЕ исключение"
|
||
module: tests/test_fs_normalize.py
|
||
expected: PASS
|
||
|
||
- id: TC-09
|
||
type: unit
|
||
description: "TTL-кэш детекта: повторный вызов в окне TTL не пере-сканирует дерево (по образцу preflight._cache); force/reset инвалидирует"
|
||
module: tests/test_fs_normalize.py
|
||
expected: PASS
|
||
|
||
- id: TC-10
|
||
type: integration
|
||
description: "startup-хук lifespan при mismatch вызывает send_telegram (мок) и логирует WARNING; при ошибке детекта старт сервиса не падает (never-fatal)"
|
||
module: tests/test_fs_normalize_startup.py
|
||
expected: PASS
|
||
|
||
- id: TC-11
|
||
type: integration
|
||
description: "опц. гейт claim'а: при обнаруженном mismatch без прав исход job внятный (FR-1-сообщение / не-claim) ДО launch, а не сырой git-fatal"
|
||
module: tests/test_fs_normalize_startup.py
|
||
expected: PASS
|
||
|
||
- id: TC-12
|
||
type: integration
|
||
description: "GET /queue (если реализован read-only блок fs_ownership) отдаёт {enabled,target_uid,mismatch,roots,checked_at} и не 5xx-ит при выключенном флаге"
|
||
module: tests/test_api_queue.py
|
||
expected: PASS
|