test_migrate_idempotency.py python
179 lines 5.9 KB
Raw
sha256:0e9549ec7b463911bc08b7d586dc320b1ac9b1f5c943ee7e3865dcc6cb0f6f83 chore(governance): sync handover+roadmap to 84db8c8 (drift:… Human 20 hours ago
1 """Data-integrity: migrate idempotency, dry-run, preserved lock, promotion (§K6.10)."""
2
3 from __future__ import annotations
4
5 from pathlib import Path
6
7 from cli.version_lock import ORIGIN_KIT, ORIGIN_PRESERVED, read_version_lock
8 from tests.support import PILOT, git_status_runner, muse_mirror_status_runner, lock_origins, run_cli, seed_muse_substrate, seed_pilot_tree
9
10
11 def _migrate(tmp_path: Path, *extra: str) -> int:
12 return run_cli(
13 [
14 "init",
15 "--migrate",
16 "--from-config",
17 str(PILOT / "config-scooling.yaml"),
18 "--non-interactive",
19 *extra,
20 ],
21 cwd=tmp_path,
22 runner=muse_mirror_status_runner(tmp_path),
23 )
24
25
26 def test_migrate_twice_identical(tmp_path: Path) -> None:
27 seed_pilot_tree(
28 tmp_path,
29 handover_rel="docs/OVERSEER-HANDOVER.md",
30 handover_text="# H\n",
31 roadmap_rel="docs/ROADMAP.md",
32 roadmap_text="# R\n",
33 )
34 assert _migrate(tmp_path) == 0
35 lock1 = (tmp_path / ".overseer/version.lock").read_text(encoding="utf-8")
36 policy1 = (tmp_path / ".overseer/policy/tiers.yaml").read_bytes()
37 assert _migrate(tmp_path) == 0
38 # already current — lock content (except possibly timestamps) / files unchanged
39 assert (tmp_path / ".overseer/policy/tiers.yaml").read_bytes() == policy1
40 assert (tmp_path / ".overseer/version.lock").is_file()
41 _ = lock1
42
43
44 def test_migrate_dry_run_zero_writes(tmp_path: Path) -> None:
45 seed_pilot_tree(
46 tmp_path,
47 handover_rel="docs/OVERSEER-HANDOVER.md",
48 handover_text="# H\n",
49 roadmap_rel="docs/ROADMAP.md",
50 roadmap_text="# R\n",
51 )
52 assert _migrate(tmp_path, "--dry-run") == 0
53 assert not (tmp_path / ".overseer/version.lock").exists()
54 assert not (tmp_path / ".overseer/policy").exists()
55
56
57 def test_preserved_sha_matches_on_disk(tmp_path: Path) -> None:
58 seed_pilot_tree(
59 tmp_path,
60 handover_rel="docs/OVERSEER-HANDOVER.md",
61 handover_text="# H\n",
62 roadmap_rel="docs/ROADMAP.md",
63 roadmap_text="# R\n",
64 )
65 assert _migrate(tmp_path) == 0
66 lock = read_version_lock(tmp_path / ".overseer/version.lock")
67 from cli.digest import sha256_hex
68
69 for entry in lock.footprint:
70 if entry.origin != ORIGIN_PRESERVED:
71 continue
72 on_disk = (tmp_path / entry.path).read_bytes()
73 assert sha256_hex(on_disk) == entry.sha256
74
75
76 def test_default_sync_retains_preserved_lock_verbatim(tmp_path: Path) -> None:
77 seed_pilot_tree(
78 tmp_path,
79 handover_rel="docs/OVERSEER-HANDOVER.md",
80 handover_text="# H\n",
81 roadmap_rel="docs/ROADMAP.md",
82 roadmap_text="# R\n",
83 )
84 assert _migrate(tmp_path) == 0
85 lock_before = read_version_lock(tmp_path / ".overseer/version.lock")
86 preserved_before = {
87 e.path: (e.sha256, e.origin, e.source)
88 for e in lock_before.footprint
89 if e.origin == ORIGIN_PRESERVED
90 }
91 assert run_cli(["sync", "-y"], cwd=tmp_path, runner=muse_mirror_status_runner(tmp_path)) == 0
92 lock_after = read_version_lock(tmp_path / ".overseer/version.lock")
93 for path, triple in preserved_before.items():
94 entry = next(e for e in lock_after.footprint if e.path == path)
95 assert (entry.sha256, entry.origin, entry.source) == triple
96
97
98 def test_hand_edit_preserved_leaves_check_ok_and_sync_updates_kit(tmp_path: Path) -> None:
99 seed_pilot_tree(
100 tmp_path,
101 handover_rel="docs/OVERSEER-HANDOVER.md",
102 handover_text="# H\n",
103 roadmap_rel="docs/ROADMAP.md",
104 roadmap_text="# R\n",
105 )
106 assert _migrate(tmp_path) == 0
107 (tmp_path / "docs/OVERSEER-HANDOVER.md").write_text("# H2\n", encoding="utf-8")
108 assert (
109 run_cli(
110 ["status", "--check-footprint"],
111 cwd=tmp_path,
112 runner=muse_mirror_status_runner(tmp_path),
113 )
114 == 0
115 )
116 # Mutate a kit shared asset baseline then sync should refresh it when kit-updated;
117 # with same kit version, sync is already_current — assert living doc untouched.
118 assert run_cli(["sync", "-y"], cwd=tmp_path, runner=muse_mirror_status_runner(tmp_path)) == 0
119 assert (tmp_path / "docs/OVERSEER-HANDOVER.md").read_text(encoding="utf-8") == "# H2\n"
120
121
122 def test_hand_edit_seeded_living_doc_integrity(tmp_path: Path) -> None:
123 seed_pilot_tree(
124 tmp_path,
125 handover_rel="docs/OVERSEER-HANDOVER.md",
126 handover_text="# KN\n",
127 roadmap_rel=None,
128 )
129 assert (
130 run_cli(
131 [
132 "init",
133 "--migrate",
134 "--from-config",
135 str(PILOT / "config-knowtation.yaml"),
136 "--non-interactive",
137 ],
138 cwd=tmp_path,
139 runner=muse_mirror_status_runner(tmp_path),
140 )
141 == 0
142 )
143 (tmp_path / "docs/ROADMAP.md").write_text("# edit seeded\n", encoding="utf-8")
144 assert (
145 run_cli(
146 ["status", "--check-footprint"],
147 cwd=tmp_path,
148 runner=muse_mirror_status_runner(tmp_path),
149 )
150 == 0
151 )
152
153
154 def test_promote_then_hand_edit_flips_integrity(tmp_path: Path) -> None:
155 seed_pilot_tree(
156 tmp_path,
157 handover_rel="docs/OVERSEER-HANDOVER.md",
158 handover_text="# H\n",
159 roadmap_rel="docs/ROADMAP.md",
160 roadmap_text="# R\n",
161 )
162 assert _migrate(tmp_path) == 0
163 assert (
164 run_cli(
165 ["sync", "--force", "--include-preserved", "-y"],
166 cwd=tmp_path,
167 runner=muse_mirror_status_runner(tmp_path),
168 )
169 == 0
170 )
171 assert lock_origins(tmp_path)["docs/OVERSEER-HANDOVER.md"] == ORIGIN_KIT
172 (tmp_path / "docs/OVERSEER-HANDOVER.md").write_text("# after promote edit\n", encoding="utf-8")
173 seed_muse_substrate(tmp_path)
174 code = run_cli(
175 ["status", "--check-footprint", "--exit-code"],
176 cwd=tmp_path,
177 runner=muse_mirror_status_runner(tmp_path),
178 )
179 assert code == 6
File History 1 commit
sha256:6abcf1fa82a7a621ccbc945f19acdba5bc0db54569599404a1452fb4a096a199 fix(ISR): default require_independent_second_reviewer to require Human minor 20 hours ago