adapter.py python
106 lines 3.3 KB
Raw
sha256:4671b7f787ddbe63ced31c895b688c77ab495653b65a730b423329f26b3c1439 feat: K1-P1 complete — agent provenance, build-verification… Sonnet 4.6 patch 53 days ago
1 """Git-only VCS adapter backend (§4)."""
2
3 from __future__ import annotations
4
5 from adapters.base import BaseAdapter
6 from adapters.errors import ReadError, WriteError
7 from adapters.runner import CommandResult
8 from adapters.types import (
9 AnchorResult,
10 CommitResult,
11 HeadResult,
12 MirrorResult,
13 RealignResult,
14 StatusResult,
15 )
16
17
18 class GitOnlyAdapter(BaseAdapter):
19 """Single-history Git backend for external developers."""
20
21 def status(self) -> StatusResult | ReadError:
22 branch_result = self._git("rev-parse", "--abbrev-ref", "HEAD")
23 if isinstance(branch_result, ReadError):
24 return branch_result
25 dirty_result = self._git("status", "--porcelain")
26 if isinstance(dirty_result, ReadError):
27 return dirty_result
28 return StatusResult(
29 regime=self.regime,
30 dirty=bool(dirty_result.stdout.strip()),
31 branch=branch_result.stdout,
32 notes=["canonical=git", "single-history"],
33 )
34
35 def read_head(self, ref: str) -> HeadResult | ReadError:
36 if ref.startswith("muse:"):
37 return ReadError(
38 "read_head",
39 "muse refs forbidden in git-only regime",
40 )
41 result = self._git("rev-parse", ref)
42 if isinstance(result, ReadError):
43 return result
44 sha = result.stdout.splitlines()[-1].strip()
45 if not sha:
46 return ReadError(f"git rev-parse {ref}", "empty sha")
47 return HeadResult(sha=sha, kind="git")
48
49 def read_canonical_anchor(self) -> AnchorResult | ReadError:
50 remote = self.config.vcs.git.remote
51 main = self.config.vcs.git.main_branch
52 ref = f"{remote}/{main}"
53 head = self.read_head(ref)
54 if isinstance(head, ReadError):
55 return head
56 return AnchorResult(anchor_sha=head.sha, source=ref)
57
58 def realign(self, *, dry_run: bool, max_commits: int) -> RealignResult:
59 return RealignResult(
60 would_import=0,
61 applied=False,
62 from_ref=None,
63 to_ref=None,
64 reason="single-history",
65 )
66
67 def commit_feature(
68 self,
69 *,
70 branch: str,
71 message: str,
72 paths: list[str],
73 ) -> CommitResult | ReadError | WriteError:
74 unsafe = self._validate_paths(paths)
75 if unsafe:
76 return unsafe
77 if self._is_protected_branch(branch):
78 return WriteError(
79 "commit_feature",
80 f"refused protected branch {branch!r}",
81 )
82
83 checkout = self._git("checkout", branch)
84 if isinstance(checkout, ReadError):
85 return checkout
86
87 if paths:
88 add = self._git("add", "--", *paths)
89 if isinstance(add, ReadError):
90 return add
91
92 commit = self._git("commit", "-m", message)
93 if isinstance(commit, ReadError):
94 return commit
95
96 head = self._git("rev-parse", "HEAD")
97 if isinstance(head, ReadError):
98 return head
99 return CommitResult(committed=True, sha=head.stdout.strip())
100
101 def mirror(self, *, dry_run: bool) -> MirrorResult:
102 return MirrorResult(
103 diff_summary="",
104 pushed=False,
105 reason="single-history",
106 )
File History 1 commit
sha256:4671b7f787ddbe63ced31c895b688c77ab495653b65a730b423329f26b3c1439 feat: K1-P1 complete — agent provenance, build-verification… Sonnet 4.6 patch 53 days ago