kin: BATON-ARCH-014 Доработать ADR-002 и ADR-004 по замечаниям ревью

- Создан docs/adr/ADR-002-offline-pattern.md (Accepted, дата 2026-03-20)
  с секцией Open Questions: #1001, охват 78.75%, ACTION:/конвенция #1049
- ADR-004: добавлен "exponential backoff согласно решению #1046" к строке 429/retry_after
- ARCHITECTURE.md: добавлена вводная фраза "ADR-файлы хранятся в docs/adr/"
  и строка таблицы для ADR-002 (Accepted)
- tests/test_arch_004.py: удалены 4 теста на отсутствие ADR-002,
  устаревшие после создания нового ADR-002 (BATON-ARCH-014 supersedes)
- tests/test_arch_014.py: 14 новых тестов для критериев приёмки
- Все 216 тестов: passed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Gros Frumos 2026-03-20 22:05:04 +02:00
parent f082c75ff8
commit 2ee953866b
5 changed files with 283 additions and 37 deletions

View file

@ -28,16 +28,12 @@ ADR_007 = ADR_DIR / "ADR-007-offline-queue-v2.md"
# ---------------------------------------------------------------------------
def test_adr_002_offline_pattern_file_does_not_exist() -> None:
"""Файл ADR-002-offline-pattern*.md не должен существовать в docs/adr/."""
matches = list(ADR_DIR.glob("ADR-002-offline-pattern*.md"))
assert len(matches) == 0, (
f"Старый файл ADR-002-offline-pattern найден: {matches}"
)
# Criterion 1 superseded by BATON-ARCH-014: ADR-002-offline-pattern.md now exists
# as a legitimate new ADR document.
# ---------------------------------------------------------------------------
# Criterion 2 — no 'ADR-002-offline-pattern' textual references
# Criterion 2 — no stale 'ADR-002-offline-pattern' textual references in docs/
# ---------------------------------------------------------------------------
@ -54,44 +50,28 @@ def test_no_adr_002_offline_pattern_in_docs() -> None:
)
def test_no_adr_002_offline_pattern_in_architecture_md() -> None:
"""ARCHITECTURE.md не должен содержать строку 'ADR-002-offline-pattern'."""
content = ARCHITECTURE_MD.read_text(encoding="utf-8")
assert "ADR-002-offline-pattern" not in content, (
"Найдена устаревшая ссылка 'ADR-002-offline-pattern' в ARCHITECTURE.md"
)
# test_no_adr_002_offline_pattern_in_architecture_md superseded by BATON-ARCH-014:
# ARCHITECTURE.md now legitimately links to ADR-002-offline-pattern.md.
# test_no_bare_adr_002_in_docs superseded: ADR-002-offline-pattern.md is a valid new ADR.
# test_no_bare_adr_002_in_architecture_md superseded: [ADR-002] is now a valid table row.
# ---------------------------------------------------------------------------
# Criterion 3 — no dangling bare ADR-002 references
# Criterion 3 — no dangling bare ADR-002 references in test files
# ---------------------------------------------------------------------------
def test_no_bare_adr_002_in_docs() -> None:
"""Ни один файл в docs/ не должен содержать голую метку 'ADR-002' (без корректного имени файла)."""
pattern = re.compile(r"\bADR-002\b")
for path in _all_md_in_docs():
content = path.read_text(encoding="utf-8")
assert not pattern.search(content), (
f"Найдена висячая ссылка 'ADR-002' в {path.relative_to(PROJECT_ROOT)}"
)
def test_no_bare_adr_002_in_architecture_md() -> None:
"""ARCHITECTURE.md не должен содержать голую метку 'ADR-002'."""
content = ARCHITECTURE_MD.read_text(encoding="utf-8")
assert not re.search(r"\bADR-002\b", content), (
"Найдена висячая ссылка 'ADR-002' в ARCHITECTURE.md"
)
def test_no_bare_adr_002_in_tests() -> None:
"""Файлы тестов (кроме этого самого файла) не должны содержать голую метку 'ADR-002'."""
"""Файлы тестов (кроме легитимных исключений) не должны содержать голую метку 'ADR-002'."""
pattern = re.compile(r"\bADR-002\b")
this_file = Path(__file__).resolve()
# Легитимные исключения: файлы, документирующие задачи, которые явно работают с ADR-002.
_ALLOWED = {
Path(__file__).resolve(), # test_arch_004.py: задача по переименованию
(PROJECT_ROOT / "tests" / "test_arch_014.py").resolve(), # задача по созданию ADR-002
}
for path in (PROJECT_ROOT / "tests").glob("*.py"):
if path.resolve() == this_file:
continue # этот файл документирует задачу и легитимно упоминает ADR-002
if path.resolve() in _ALLOWED:
continue
content = path.read_text(encoding="utf-8")
assert not pattern.search(content), (
f"Найдена висячая ссылка 'ADR-002' в {path.relative_to(PROJECT_ROOT)}"