test_governance_idempotency.py file-level

at main · View file ↗ · Intel ↗

History
1 files
1 commits
0 hotspots
0 🧊 dead
0 💥 blast risk
sha256:6 fix(ISR): default require_independent_second_reviewer to require Opera… · aaronrene · Sep 2, 2026
1 """Data-integrity tests for governance-sync idempotency (§8 data-integrity tier)."""
2
3 from __future__ import annotations
4
5 import json
6 from pathlib import Path
7 from unittest.mock import patch
8
9 from cli.kit_root import kit_root
10 from tests.support import FIXTURES, ok, make_runner, run_cli, write_config
11
12
13 def _seed(tmp_path: Path) -> None:
14 write_config(tmp_path, "config-git-only.yaml")
15 docs = tmp_path / "docs"
16 docs.mkdir(parents=True, exist_ok=True)
17 (docs / "OVERSEER-HANDOVER.md").write_text(
18 (FIXTURES / "governance-handover-drift.md").read_text(encoding="utf-8"),
19 encoding="utf-8",
20 )
21 (docs / "ROADMAP.md").write_text(
22 (FIXTURES / "governance-roadmap-drift.md").read_text(encoding="utf-8"),
23 encoding="utf-8",
24 )
25
26
27 def _runner(tmp_path: Path):
28 return make_runner(
29 {
30 "git rev-parse --abbrev-ref HEAD": ok("main"),
31 "git status --porcelain": ok(""),
32 "git rev-parse origin/main": ok("cafebabe"),
33 "gh pr list": ok("[]"),
34 "git remote get-url origin": ok("[email protected]:owner/repo.git"),
35 # §GSW.3.1: branch ensure precedes doc writes on the apply path.
36 "git checkout -b": ok(""),
37 "git checkout main": ok(""),
38 }
39 )
40
41
42 def test_governance_sync_second_run_aligned(tmp_path: Path) -> None:
43 _seed(tmp_path)
44 runner = _runner(tmp_path)
45 code1 = run_cli(["governance-sync"], cwd=tmp_path, runner=runner, kit=kit_root())
46 assert code1 == 0
47 handover = (FIXTURES / "governance-handover-drift.md").read_text(encoding="utf-8").replace(
48 "deadbeef",
49 "cafebabe",
50 )
51 (tmp_path / "docs" / "OVERSEER-HANDOVER.md").write_text(handover, encoding="utf-8")
52 code2 = run_cli(["governance-sync"], cwd=tmp_path, runner=runner, kit=kit_root())
53 assert code2 == 0
54
55
56 def test_mid_apply_failure_leaves_no_commit(tmp_path: Path) -> None:
57 _seed(tmp_path)
58 runner = _runner(tmp_path)
59 calls = {"n": 0}
60
61 def flaky_write(path: Path, text: str) -> None:
62 calls["n"] += 1
63 if calls["n"] == 2:
64 from cli.atomic import WriteFailure
65
66 raise WriteFailure(path, OSError("simulated"))
67 from cli.atomic import atomic_write_text as real
68
69 real(path, text)
70
71 with patch("tools.governance_hygiene.engine.atomic_write_text", side_effect=flaky_write):
72 code = run_cli(
73 ["governance-sync", "--write"],
74 cwd=tmp_path,
75 runner=runner,
76 kit=kit_root(),
77 )
78 assert code == 5
79 assert not (tmp_path / ".overseer" / "last_governance_sync").exists()