test_gsb_reconcile_integrity.py
python
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1
docs: MuseHub-first before ISR #74 — staging solidify NEXT
Human
1 day ago
| 1 | """Data-integrity: §GSB reconcile tip/doc/marker semantics (§GSB.8). |
| 2 | |
| 3 | FF path: after success the feature-branch tip equals the pre-ensure current |
| 4 | tip plus exactly one new sync commit. Diverged path: the original diverged |
| 5 | branch tip is unchanged (never force-reset) and the uniquified branch holds |
| 6 | the new commit. Mid-C0 failure: doc bytes unchanged, marker unrestamped, |
| 7 | HEADs restored. |
| 8 | """ |
| 9 | |
| 10 | from __future__ import annotations |
| 11 | |
| 12 | from datetime import date |
| 13 | from pathlib import Path |
| 14 | |
| 15 | from adapters.runner import CommandResult |
| 16 | from cli.kit_root import kit_root |
| 17 | from tests.support import gsw_runner, run_cli, seed_gsw_repo |
| 18 | |
| 19 | |
| 20 | def _feature_branch() -> str: |
| 21 | return f"feat/governance-sync-{date.today().isoformat()}" |
| 22 | |
| 23 | |
| 24 | def test_ff_success_tip_is_target_plus_one_sync_commit(tmp_path: Path) -> None: |
| 25 | branch = _feature_branch() |
| 26 | seed_gsw_repo(tmp_path, "git-only") |
| 27 | runner = gsw_runner( |
| 28 | tmp_path, |
| 29 | "git-only", |
| 30 | existing_git_branches={branch}, |
| 31 | git_tips={branch: "stale1"}, |
| 32 | git_ancestors={"feedface": {"stale1"}}, |
| 33 | ) |
| 34 | code = run_cli(["governance-sync", "--write"], cwd=tmp_path, runner=runner, kit=kit_root()) |
| 35 | assert code == 0 |
| 36 | # Exactly one commit, parented on the pre-ensure current tip (T_target). |
| 37 | assert runner.git_commit_count == 1 |
| 38 | tip = runner.git_tips[branch] |
| 39 | assert tip != "stale1" and tip != "feedface" |
| 40 | # Parent chain: new sync commit → T_target ("feedface") → old stale tip. |
| 41 | assert runner.git_ancestors[tip] == {"feedface", "stale1"} |
| 42 | |
| 43 | |
| 44 | def test_diverged_original_tip_unchanged_uniquified_holds_commit(tmp_path: Path) -> None: |
| 45 | branch = _feature_branch() |
| 46 | seed_gsw_repo(tmp_path, "git-only") |
| 47 | runner = gsw_runner( |
| 48 | tmp_path, |
| 49 | "git-only", |
| 50 | existing_git_branches={branch}, |
| 51 | git_tips={branch: "divergent"}, |
| 52 | ) |
| 53 | code = run_cli(["governance-sync", "--write"], cwd=tmp_path, runner=runner, kit=kit_root()) |
| 54 | assert code == 0 |
| 55 | uniquified = f"{branch}-2" |
| 56 | # Original diverged tip untouched — never rewound or force-reset. |
| 57 | assert runner.git_tips[branch] == "divergent" |
| 58 | assert runner.git_commit_count == 1 |
| 59 | new_tip = runner.git_tips[uniquified] |
| 60 | assert new_tip != "divergent" |
| 61 | assert "feedface" in runner.git_ancestors[new_tip] |
| 62 | assert not any("--force" in c for c, _ in runner.calls) |
| 63 | assert not any(c.startswith("git branch -f ") for c, _ in runner.calls) |
| 64 | |
| 65 | |
| 66 | def test_mid_c0_failure_docs_marker_heads_untouched(tmp_path: Path) -> None: |
| 67 | branch = _feature_branch() |
| 68 | handover_path, roadmap_path = seed_gsw_repo(tmp_path, "muse+git-mirror") |
| 69 | original_handover = handover_path.read_bytes() |
| 70 | original_roadmap = roadmap_path.read_bytes() |
| 71 | prior_marker = "2026-07-30T00:00:00Z\nr1=cafebabe\nr3=sha256:musetip\n" |
| 72 | marker_path = tmp_path / ".overseer" / "last_governance_sync" |
| 73 | marker_path.write_text(prior_marker, encoding="utf-8") |
| 74 | |
| 75 | runner = gsw_runner( |
| 76 | tmp_path, |
| 77 | "muse+git-mirror", |
| 78 | existing_git_branches={branch}, |
| 79 | existing_muse_branches={branch}, |
| 80 | git_tips={branch: "gitstale"}, |
| 81 | muse_tips={branch: "sha256:stale"}, |
| 82 | git_ancestors={"feedface": {"gitstale"}}, |
| 83 | muse_ancestors={"sha256:musetip": {"sha256:stale"}}, |
| 84 | ) |
| 85 | original_run = runner.run |
| 86 | |
| 87 | def breaking_run(command: str, *, cwd: str | None = None) -> CommandResult: |
| 88 | # Partial C0: muse update-ref succeeds, then the git leg fails. |
| 89 | if command.startswith("git branch -f "): |
| 90 | runner.calls.append((command, cwd)) |
| 91 | return CommandResult(stdout="", stderr="induced git tip failure", exit_code=1) |
| 92 | return original_run(command, cwd=cwd) |
| 93 | |
| 94 | runner.run = breaking_run # type: ignore[method-assign] |
| 95 | code = run_cli(["governance-sync", "--write"], cwd=tmp_path, runner=runner, kit=kit_root()) |
| 96 | assert code == 2 |
| 97 | # Zero doc writes before ensure success (§GSW order preserved by C0). |
| 98 | assert handover_path.read_bytes() == original_handover |
| 99 | assert roadmap_path.read_bytes() == original_roadmap |
| 100 | # Marker unrestamped: prior bytes intact. |
| 101 | assert marker_path.read_text(encoding="utf-8") == prior_marker |
| 102 | # HEADs restored (they never moved during C0 tip probes/updates). |
| 103 | assert runner.git_branch == "main" |
| 104 | assert runner.muse_branch == "main" |
File History
1 commit
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1
docs: MuseHub-first before ISR #74 — staging solidify NEXT
Human
1 day ago