test_governance_freshness_status.py python
157 lines 5.0 KB
Raw
sha256:0e9549ec7b463911bc08b7d586dc320b1ac9b1f5c943ee7e3865dcc6cb0f6f83 chore(governance): sync handover+roadmap to 84db8c8 (drift:… Human 1 day ago
1 """Integration: status --exit-code + dry-run marker stamp (§GFG.9 integration)."""
2
3 from __future__ import annotations
4
5 import json
6 from pathlib import Path
7
8 from cli.kit_root import kit_root
9 from tests.support import (
10 FIXTURES,
11 git_status_runner,
12 make_runner,
13 ok,
14 run_cli,
15 seed_governance_freshness,
16 write_config,
17 )
18
19
20 def _aligned_handover(tip: str = "cafebabe") -> str:
21 return (
22 f"| GitHub `main` | `{tip}` |\n"
23 f"| **main HEAD** | `{tip}` |\n"
24 )
25
26
27 def _seed_aligned(tmp_path: Path, tip: str = "cafebabe") -> None:
28 write_config(tmp_path, "config-git-only.yaml")
29 (tmp_path / ".overseer" / "version.lock").write_text(
30 "lock_version: 1\nkit_version: 0.1.0\nconfig_version: 1\n"
31 "footprint_digest: sha256:" + ("0" * 64) + "\n"
32 "installed_at: \"2026-01-01T00:00:00Z\"\nsynced_at: \"2026-01-01T00:00:00Z\"\n"
33 "footprint: []\n",
34 encoding="utf-8",
35 )
36 docs = tmp_path / "docs"
37 docs.mkdir(parents=True, exist_ok=True)
38 (docs / "OVERSEER-HANDOVER.md").write_text(_aligned_handover(tip), encoding="utf-8")
39 (docs / "ROADMAP.md").write_text("## Build queue\n\n", encoding="utf-8")
40
41
42 def _runner(tip: str = "cafebabe"):
43 return make_runner(
44 {
45 "git rev-parse --abbrev-ref HEAD": ok("main"),
46 "git status --porcelain": ok(""),
47 "git rev-parse origin/main": ok(tip),
48 "gh pr list": ok("[]"),
49 "git remote get-url origin": ok("[email protected]:owner/repo.git"),
50 }
51 )
52
53
54 def test_status_exit_2_when_d1_drifted(tmp_path: Path, capsys) -> None:
55 assert (
56 run_cli(
57 ["init", "--from-config", str(FIXTURES / "config-git-only.yaml"), "--non-interactive"],
58 cwd=tmp_path,
59 runner=git_status_runner(tip="cafebabe"),
60 )
61 == 0
62 )
63 handover = tmp_path / "docs"
64 # Prefer whatever init wrote; force stale claim
65 for path in handover.glob("*HANDOVER*"):
66 path.write_text("| GitHub `main` | `deadbeef` |\n", encoding="utf-8")
67 capsys.readouterr()
68 code = run_cli(
69 ["status", "--json", "--exit-code"],
70 cwd=tmp_path,
71 runner=git_status_runner(tip="cafebabe"),
72 json_mode=True,
73 )
74 assert code == 2
75 payload = json.loads(capsys.readouterr().out)
76 assert payload["governance_freshness"]["state"] == "drifted"
77
78
79 def test_status_exit_2_when_marker_absent(tmp_path: Path, capsys) -> None:
80 assert (
81 run_cli(
82 ["init", "--from-config", str(FIXTURES / "config-git-only.yaml"), "--non-interactive"],
83 cwd=tmp_path,
84 runner=git_status_runner(),
85 )
86 == 0
87 )
88 tip = "cafebabe"
89 for path in (tmp_path / "docs").glob("*HANDOVER*"):
90 text = path.read_text(encoding="utf-8")
91 path.write_text(
92 text.rstrip() + f"\n\n| Item | Value |\n| --- | --- |\n| GitHub `main` | `{tip}` |\n",
93 encoding="utf-8",
94 )
95 marker = tmp_path / ".overseer" / "last_governance_sync"
96 if marker.exists():
97 marker.unlink()
98 capsys.readouterr()
99 code = run_cli(
100 ["status", "--json", "--exit-code"],
101 cwd=tmp_path,
102 runner=git_status_runner(tip=tip),
103 json_mode=True,
104 )
105 assert code == 2
106 payload = json.loads(capsys.readouterr().out)
107 assert payload["governance_freshness"]["state"] == "stale_marker"
108
109
110 def test_status_exit_0_when_aligned_and_marker_matches(tmp_path: Path, capsys) -> None:
111 assert (
112 run_cli(
113 ["init", "--from-config", str(FIXTURES / "config-git-only.yaml"), "--non-interactive"],
114 cwd=tmp_path,
115 runner=git_status_runner(),
116 )
117 == 0
118 )
119 seed_governance_freshness(tmp_path)
120 capsys.readouterr()
121 code = run_cli(
122 ["status", "--json", "--exit-code"],
123 cwd=tmp_path,
124 runner=git_status_runner(),
125 json_mode=True,
126 )
127 assert code == 0
128 payload = json.loads(capsys.readouterr().out)
129 assert payload["governance_freshness"]["state"] == "ok"
130 assert payload["governance_freshness"]["ok"] is True
131 # timestamp-only legacy surface
132 assert payload["last_governance_sync"]
133 assert "\n" not in payload["last_governance_sync"]
134
135
136 def test_dry_run_aligned_stamps_marker_without_doc_writes(tmp_path: Path) -> None:
137 _seed_aligned(tmp_path)
138 handover = tmp_path / "docs" / "OVERSEER-HANDOVER.md"
139 roadmap = tmp_path / "docs" / "ROADMAP.md"
140 before_h = handover.read_text(encoding="utf-8")
141 before_r = roadmap.read_text(encoding="utf-8")
142 runner = _runner()
143 code = run_cli(
144 ["governance-sync", "--json"],
145 cwd=tmp_path,
146 runner=runner,
147 kit=kit_root(),
148 json_mode=True,
149 )
150 assert code == 0
151 assert handover.read_text(encoding="utf-8") == before_h
152 assert roadmap.read_text(encoding="utf-8") == before_r
153 marker = tmp_path / ".overseer" / "last_governance_sync"
154 assert marker.is_file()
155 body = marker.read_text(encoding="utf-8")
156 assert "r1=cafebabe" in body
157 assert "r3=cafebabe" in body
File History 1 commit
sha256:6abcf1fa82a7a621ccbc945f19acdba5bc0db54569599404a1452fb4a096a199 fix(ISR): default require_independent_second_reviewer to require Human minor 1 day ago