Milestones and review in the new loop (M2.1, PR C)
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 1m48s

A work item starts from a fresh workspace: fetch, set aside (never
discard) leftover changes, branches and unpushed commits, a clean default
branch, and a branch of its own (D3, #62). start_milestone cuts the
milestone's branch; finish_milestone commits only the work, pushes and
opens a PR that closes the issue, under an intent, adopting an open PR and
treating a closed one as the operator's answer (D4). Between runs the
loop watches each item's PR: operator comments and inline review notes
(#69) reach the item, a merge or close hands back to the driver. A review
fix is checked after it's pushed and goes out as a new PR if the PR merged
first (D5). At boot an interrupted publish is settled against Gitea (L8).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
This commit is contained in:
dongarandClaude Opus 5.5 committed 2026-10-02 23:53:02 +00:00
1 parent f84bb70839
commit 21744efac1
9 files changed
+1004 -10

No files matched your search

+32
View File
@@ -259,6 +259,38 @@ class GitRepo:
out = self._git("status", "--porcelain", "--untracked-files=all", raw=True)
return sorted(line[3:] for line in out.splitlines() if line)
# -- a fresh workspace (D3) ----------------------------------------------
def fetch(self, *, credential: PushCredential | None = None) -> None:
"""Bring origin's branches up to date, pruning deleted ones. The
remote's URL in the clone carries no credential; this one fetch is
handed it."""
self._git("fetch", "-q", "--prune", "origin", credential=credential)
def local_branches(self) -> list[str]:
out = self._git("for-each-ref", "--format=%(refname:short)", "refs/heads")
return [line for line in out.splitlines() if line]
def rename_branch(self, old: str, new: str) -> None:
self._git("branch", "-m", old, new)
def branch_at(self, name: str, ref: str) -> None:
self._git("branch", name, ref)
def reset_to(self, branch: str, start: str) -> None:
"""Check out ``branch`` at ``start``, discarding what the work tree
had (anything worth keeping is set aside first), then remove every
untracked and ignored file: build artifacts never survive (D3)."""
self._git("checkout", "-q", "-f", "-B", branch, start)
self._git("clean", "-q", "-f", "-d", "-x")
def is_ancestor(self, commit: str, ref: str) -> bool:
try:
self._git("merge-base", "--is-ancestor", commit, ref)
except GitError:
return False
return True
def push(
self, remote_url: str, branch: str, *, credential: PushCredential | None = None
) -> None: