adapter.py python
118 lines 4.1 KB
Raw
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 1 day ago
1 """Muse-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 GIT_FORBIDDEN = "git forbidden in this regime"
18
19
20 class MuseOnlyAdapter(BaseAdapter):
21 """MuseHub backend — git and mirror are hard no-ops."""
22
23 def status(self) -> StatusResult | ReadError:
24 branch_result = self._muse("branch", "--show-current")
25 if isinstance(branch_result, ReadError):
26 return branch_result
27 dirty_result = self._muse_dirty()
28 if isinstance(dirty_result, ReadError):
29 return dirty_result
30 return StatusResult(
31 regime=self.regime,
32 dirty=dirty_result,
33 branch=branch_result.stdout,
34 notes=["canonical=muse", "git-forbidden"],
35 muse_dirty=dirty_result,
36 git_dirty=None,
37 )
38
39 def read_head(self, ref: str) -> HeadResult | ReadError:
40 if ref.startswith("origin/") or ref.startswith(self.config.vcs.git.remote + "/"):
41 return ReadError("read_head", GIT_FORBIDDEN)
42 muse_ref = ref.removeprefix("muse:")
43 return self._muse_rev_parse_sha(muse_ref)
44
45 def read_canonical_anchor(self) -> AnchorResult | ReadError:
46 main = self.config.vcs.muse.main_branch
47 if not main:
48 return ReadError("read_canonical_anchor", "muse.main_branch not configured")
49 head = self.read_head(f"muse:{main}")
50 if isinstance(head, ReadError):
51 return head
52 return AnchorResult(anchor_sha=head.sha, source=f"muse:{main}")
53
54 def realign(self, *, dry_run: bool, max_commits: int) -> RealignResult:
55 return RealignResult(
56 would_import=0,
57 applied=False,
58 from_ref=None,
59 to_ref=None,
60 reason="single-history",
61 )
62
63 def commit_feature(
64 self,
65 *,
66 branch: str,
67 message: str,
68 paths: list[str],
69 ) -> CommitResult | ReadError | WriteError:
70 unsafe = self._validate_paths(paths)
71 if unsafe:
72 return unsafe
73 if self._is_protected_branch(branch):
74 return WriteError(
75 "commit_feature",
76 f"refused protected branch {branch!r}",
77 )
78
79 # §GSW.6.1: skip checkout when Muse HEAD is already on the branch —
80 # dirty handover/roadmap paths must never fail the commit here.
81 current = self._muse("rev-parse", "--abbrev-ref", "HEAD")
82 if isinstance(current, ReadError):
83 return current
84 if current.stdout.strip() != branch:
85 # §GSW.6.2: bare checkout refuses dirty tracked files (Muse 0.2.x);
86 # retry with --autoshelf to carry them. --force is forbidden.
87 checkout = self._muse("checkout", branch)
88 if isinstance(checkout, ReadError):
89 checkout = self._muse("checkout", "--autoshelf", branch)
90 if isinstance(checkout, ReadError):
91 return checkout
92
93 if paths:
94 for path in paths:
95 # Muse 0.2.x has no top-level `add`; staging is `muse code add`
96 # (matches the KH2 remediation string). Found live in GSW land-b.
97 add = self._muse("code", "add", path)
98 if isinstance(add, ReadError):
99 return add
100
101 commit = self._muse("commit", "-m", message)
102 if isinstance(commit, ReadError):
103 return commit
104
105 head = self._muse_rev_parse_sha("HEAD")
106 if isinstance(head, ReadError):
107 return head
108 return CommitResult(committed=True, sha=head.sha)
109
110 def mirror(self, *, dry_run: bool) -> MirrorResult:
111 return MirrorResult(
112 diff_summary="",
113 pushed=False,
114 reason=GIT_FORBIDDEN,
115 )
116
117 def _git(self, *args: str) -> CommandResult | ReadError:
118 return ReadError("git", GIT_FORBIDDEN)
File History 2 commits
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 1 day ago
sha256:4671b7f787ddbe63ced31c895b688c77ab495653b65a730b423329f26b3c1439 feat: K1-P1 complete — agent provenance, build-verification… Sonnet 4.6 patch 52 days ago