realign.py python
112 lines 3.4 KB
Raw
sha256:4671b7f787ddbe63ced31c895b688c77ab495653b65a730b423329f26b3c1439 feat: K1-P1 complete — agent provenance, build-verification… Sonnet 4.6 patch 55 days ago
1 """Muse realignment guard (§5)."""
2
3 from __future__ import annotations
4
5 from adapters.base import VcsAdapter
6 from adapters.config import OverseerConfig
7 from adapters.errors import ReadError
8 from adapters.runner import CommandRunner, quote_arg
9 from tools.governance_hygiene.types import DriftReport, VerifiedReads
10
11
12 def plan_realign(
13 config: OverseerConfig,
14 adapter: VcsAdapter,
15 reads: VerifiedReads,
16 drift: DriftReport,
17 ) -> tuple[bool, str]:
18 """Return whether realign would run and a human-readable reason."""
19 if drift.d2_anchor_vs_canonical != "drifted":
20 return False, "D2 aligned — skip realign"
21 if config.vcs.regime != "muse+git-mirror":
22 return False, f"{config.vcs.regime}: realign no-op"
23 if reads.r1_github_main_sha is None:
24 return False, "missing R1 github main sha"
25 if not _github_superset_of_anchor(
26 adapter,
27 reads.r2_anchor_sha,
28 reads.r1_github_main_sha,
29 ):
30 return False, "R1 is not a content superset of anchor — operator required"
31 return True, "D2 drift + superset precondition met"
32
33
34 def execute_realign_guard(
35 config: OverseerConfig,
36 adapter: VcsAdapter,
37 reads: VerifiedReads,
38 drift: DriftReport,
39 *,
40 dry_run: bool,
41 ) -> tuple[str | None, str | None]:
42 """
43 Run §5 guard sequence.
44
45 Returns ``(summary, error_command)`` where error_command is set on verification failure.
46 """
47 should_run, reason = plan_realign(config, adapter, reads, drift)
48 if not should_run:
49 return reason, None
50
51 max_commits = config.thresholds.realign_max_commits
52 preview = adapter.realign(dry_run=True, max_commits=max_commits)
53 if isinstance(preview, ReadError):
54 return None, preview.command
55
56 if preview.would_import > max_commits:
57 return (
58 f"realign withheld: would_import={preview.would_import} > max={max_commits}",
59 None,
60 )
61
62 if dry_run:
63 return (
64 f"realign planned: would_import={preview.would_import} "
65 f"from {preview.from_ref} to {preview.to_ref}",
66 None,
67 )
68
69 applied = adapter.realign(dry_run=False, max_commits=max_commits)
70 if isinstance(applied, ReadError):
71 return None, applied.command
72
73 if not applied.applied:
74 return f"realign not applied: {applied.reason}", None
75
76 anchor = adapter.read_canonical_anchor()
77 if isinstance(anchor, ReadError):
78 return None, anchor.command
79
80 muse_main = config.vcs.muse.main_branch
81 head = adapter.read_head(f"muse:{muse_main}")
82 if isinstance(head, ReadError):
83 return None, head.command
84
85 if anchor.anchor_sha.lower() != head.sha.lower():
86 return None, "realign verification failed: anchor != muse main"
87
88 return (
89 f"realign applied: imported {applied.would_import} "
90 f"from {applied.from_ref} to {applied.to_ref}",
91 None,
92 )
93
94
95 def _github_superset_of_anchor(
96 adapter: VcsAdapter,
97 anchor_sha: str,
98 main_sha: str,
99 ) -> bool:
100 """True when ``main_sha`` contains ``anchor_sha`` (recovery precondition)."""
101 if anchor_sha.lower() == main_sha.lower():
102 return True
103 runner = adapter.runner
104 repo_root = str(adapter.repo_root)
105 cmd = (
106 "git merge-base --is-ancestor "
107 + quote_arg(anchor_sha)
108 + " "
109 + quote_arg(main_sha)
110 )
111 result = runner.run(cmd, cwd=repo_root)
112 return result.ok
File History 1 commit
sha256:4671b7f787ddbe63ced31c895b688c77ab495653b65a730b423329f26b3c1439 feat: K1-P1 complete — agent provenance, build-verification… Sonnet 4.6 patch 55 days ago