test_governance_drift.py python
145 lines 5.5 KB
Raw
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 10 hours ago
1 """Unit tests for governance drift detection (§8 unit tier)."""
2
3 from __future__ import annotations
4
5 from dataclasses import replace
6
7 from tools.governance_hygiene.drift import detect_drift
8 from tools.governance_hygiene.parse import pr_matches_row
9 from tools.governance_hygiene.types import MergedPullRequest, QueueRow, VerifiedReads
10
11
12 def _reads(github_main: str = "cafebabe") -> VerifiedReads:
13 return VerifiedReads(
14 regime="git-only",
15 r1_github_main_sha=github_main,
16 r1_command="git rev-parse origin/main",
17 r2_anchor_sha=github_main,
18 r2_source="origin/main",
19 r3_canonical_main_sha=github_main,
20 r3_command="git rev-parse origin/main",
21 r4_merged_prs=(),
22 r5_branch="main",
23 r5_dirty=False,
24 r5_regime="git-only",
25 )
26
27
28 def test_detect_drift_d1_drifted_d2_d3_aligned() -> None:
29 handover = "| **main HEAD** | `deadbeef` |"
30 roadmap = "| **9A-5 Governance Hygiene Agent** | Auto | **TODO** | x |"
31 drift = detect_drift(_reads("cafebabe"), handover, roadmap)
32 assert drift.d1_handover_vs_git == "drifted"
33 assert drift.d2_anchor_vs_canonical == "aligned"
34 assert drift.d3_queue_vs_merged == "aligned"
35
36
37 def test_detect_drift_fully_aligned() -> None:
38 handover = "| **main HEAD** | `cafebabe` |"
39 roadmap = "| **9A-5 Governance Hygiene Agent** | Auto | **TODO** | x |"
40 drift = detect_drift(_reads(), handover, roadmap)
41 assert drift.fully_aligned is True
42
43
44 def _row(label: str, status: str = "**NEXT**") -> QueueRow:
45 return QueueRow(phase_label=label, model="Thinking", status=status, deliverable="x", raw_line="|")
46
47
48 _GSW_LAND_B_TITLE = "Mirror: mirror: GSW land-b docs sync + muse code add staging fix"
49 _GSW_CLOSEOUT_TITLE = (
50 "Mirror: mirror: GSW closeout — queue PLS post-land sync + pr_matches_row slice-token fix"
51 )
52
53
54 def test_pr_match_rejects_generic_fragment_overlap() -> None:
55 """Live GSW land-b regression: a mirror PR title sharing only boilerplate
56 words (land / sync / main / post) must never stamp an unrelated open row."""
57 assert pr_matches_row(_GSW_LAND_B_TITLE, _row("**PLS-a Post-land main sync freeze**")) is False
58 assert pr_matches_row(_GSW_LAND_B_TITLE, _row("**PLS-b Post-land main sync build**")) is False
59
60
61 def test_pr_match_rejects_bare_prefix_when_compound_id_exists() -> None:
62 """Live PR #55 closeout: title 'queue PLS …' must not stamp open PLS-a/PLS-b.
63 Compound slice IDs (PLS-a) are required; bare PLS is not enough."""
64 assert pr_matches_row(_GSW_CLOSEOUT_TITLE, _row("**PLS-a Post-land main sync freeze**")) is False
65 assert pr_matches_row(_GSW_CLOSEOUT_TITLE, _row("**PLS-b Post-land main sync build**")) is False
66 assert pr_matches_row(
67 "feat(PLS-a): freeze post-land main sync",
68 _row("**PLS-a Post-land main sync freeze**"),
69 ) is True
70
71
72 def test_pr_match_accepts_compound_slice_id() -> None:
73 assert pr_matches_row(
74 "mirror: GSW-FIX governance-sync write-path",
75 _row("**GSW-FIX → main**"),
76 ) is True
77 # Bare GSW without the compound GSW-FIX is not enough when the label has one.
78 assert pr_matches_row(_GSW_LAND_B_TITLE, _row("**GSW-FIX → main**")) is False
79
80
81 def test_pr_match_accepts_non_compound_slice_token() -> None:
82 """Labels without hyphenated IDs still match on a distinctive token (PMHF)."""
83 assert pr_matches_row(
84 "Mirror: PMHF post-merge handover freshness land closeout",
85 _row("**PMHF → main**"),
86 ) is True
87
88
89 def test_pr_match_rejects_visibility_checklist_overlap() -> None:
90 """Live ONS land-b regression: Contributor PR #63 title sharing only
91 English product words (visibility / checklist) must never stamp the
92 open Tier-3 row ``Public repository visibility flip`` DONE."""
93 contributor_title = (
94 "Mirror: mirror: Contributor prep — CONTRIBUTING, laundry purge, "
95 "visibility checklist"
96 )
97 assert (
98 pr_matches_row(
99 contributor_title,
100 _row("**Public repository visibility flip**"),
101 )
102 is False
103 )
104 # Full-label substring still matches when the PR is truly about the flip.
105 assert (
106 pr_matches_row(
107 "Mirror: Public repository visibility flip — Settings private→public",
108 _row("**Public repository visibility flip**"),
109 )
110 is True
111 )
112
113
114 def test_pr_match_requires_word_boundary() -> None:
115 """Slice IDs must match as whole words — `PLS` inside `pulse` is no match."""
116 assert pr_matches_row("chore: pulse metrics cleanup", _row("**PLS-a Post-land main sync freeze**")) is False
117
118
119 def test_pr_match_full_label_substring_still_matches() -> None:
120 assert pr_matches_row(
121 "feat: K10 Honesty module ledger gates",
122 _row("**K10 Honesty module**"),
123 ) is True
124
125
126 def test_detect_drift_d3_ignores_mention_of_queued_slice() -> None:
127 """D3 stays aligned when a merged PR only *mentions* a still-open slice."""
128 handover = "| **main HEAD** | `cafebabe` |"
129 roadmap = (
130 "| **PLS-a Post-land main sync freeze** | Thinking | **NEXT** | x |\n"
131 "| **PLS-b Post-land main sync build** | Auto | **QUEUED** | x |"
132 )
133 reads = replace(
134 _reads(),
135 r4_merged_prs=(
136 MergedPullRequest(
137 number=55,
138 title=_GSW_CLOSEOUT_TITLE,
139 merge_commit_sha="4650171" + "0" * 33,
140 merged_at="2026-07-31T16:45:00Z",
141 ),
142 ),
143 )
144 drift = detect_drift(reads, handover, roadmap)
145 assert drift.d3_queue_vs_merged == "aligned"
File History 2 commits
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 10 hours ago
sha256:4671b7f787ddbe63ced31c895b688c77ab495653b65a730b423329f26b3c1439 feat: K1-P1 complete — agent provenance, build-verification… Sonnet 4.6 patch 52 days ago