Archives were downloaded and unpacked afresh for every run, which doesn't scale to very large repositories. Each repository is now cloned once, with its whole history, under scratch/repos/<owner>/<name>/ (head/ the clone, base/ a worktree when read). A run fetches every branch and the PR's refs/pull/N/head, checks out the head exactly, and fails if that head is gone. Only the latest repository is kept for now. Git runs walled off: none of the host's git configuration, links checked out as plain files, no hooks, submodules or LFS, only the Gitea URL's protocol, and the token as an http.extraHeader for that URL in git's environment only. A stop ends a git command; a cut-short first clone is removed. The reader never shows .git. GiteaClient.archive is gone. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J5Utyfzw7gF7UhjRDEtjTk
940 B
940 B
nisse-review
The Review Agent (Part R of the architecture): it reviews every pull request that is ready, in the repositories its Gitea account can read, and posts its review on the PR as a COMMENT review. It reads and comments; it never changes code, approves, or requests changes.
A thin application over nisse-core, with its own small scheduler:
config: its YAML configuration (nisse-review.example.yaml).state: its state store, and a review item (one per PR).scheduler: the duty (ready PRs), one review at a time, recovery after a crash.clones: each repository as a git clone kept between runs (the latest one), checked out at the PR's head and, when read, its base.reader: those trees, read-only, as the run's executor.review: one review run, and posting it.build,main: putting it together, and the access check at startup.
Bring-up on the development VM: scripts/review-bringup.sh.