A new package over nisse-core: it reviews every ready PR in the
repositories its account can read, and posts one COMMENT review.
- scheduler: each round, open PRs per readable repository (or the
configured repositories); an item per PR, ready unless draft or WIP;
closed with the PR. One review at a time, oldest first.
- reader: the repository at head and base from Gitea archives, unpacked
and read in Python (read_file, list_files, search_code), and its issues;
bound to the item's repository; no git, no shell.
- review: starts from the PR, commits, diff, comments, closed issues, CI;
comment drafts a point on any existing line; post_review posts one
COMMENT review at the head, inline where Gitea takes it, else as links in
the summary. ask_expert; vault and memory (memory/nisse-review).
- L8: posting is an intent; recovery asks Gitea for the marked review and
never posts twice; with Gitea down, the item waits.
- Failures retried, then said on the PR until the next push.
- Startup refuses an account that can push to or administer any repo.
- nisse-core gitea: readable_repositories, open_pull_requests, diff,
commits, archive, issue, search_issues, reviews, post_review; PR fields.
- Bring-up: scripts/review-bringup.sh; nisse-review.example.yaml.
- Tests: unit over a fake Gitea and scripted model; a live test
(NISSE_REVIEW_GITEA_TOKEN) reviews a PR in a fresh test repository.
- Docs: Development Plan M7.3, Tuning Guide (tuning.review.*).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J5Utyfzw7gF7UhjRDEtjTk
- The Dockerfile's test stage stacks on TEST_BASE: this build's agent by
default, or a published image. It adds only the test tools (uv export
of the dev group into the image's environment), never reinstalling the
agent, so the suite tests the image as published.
- scripts/e2e.sh --image passes NISSE_E2E_MODEL into the container.
- The plan marks M1.5 done: v0.1.0's published image passed the whole e2e
suite (9 of 9, 11m37s), with the release's own tests over it.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
- on: release (published), not on any v* tag: only a deliberate release
builds an image; the version is its tag without the v, plus latest.
- docker/login-action, setup-buildx and build-push-action, as the runner
already serves them for inlaw_outlaw; the version as a build argument
and image label.
- Comments on why the registry needs a personal token (the job token's
empty package scope) and that packages belong to the repository owner.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
- Dockerfile: built with uv into /opt/nisse (installed, not editable),
run on python:3.12-slim with openssh-client as user nisse; stateless,
with state in a /var/lib/nisse-dev volume, config mounted at
/etc/nisse-dev/nisse-dev.yaml, secrets as environment variables, keys
mounted read-only. 202 MB. Its `test` stage adds the tests and their
tools over the installed package (UV_NO_SYNC, so `uv run` never swaps
in the source tree); the default target is the agent.
- scripts/e2e.sh --image REF runs the suite inside an image's test stage,
on its own sshd.
- CI builds both images on every PR (nothing pushed); release.yml pushes
gitea.dongar.net/dongar/nisse-dev:<tag> and :latest on a v* tag, with
the REGISTRY_TOKEN secret.
- scripts/bringup.sh builds the code under test into an image and runs it
in the systemd unit (root, $E2E mounted at its own path); `plan` prints
what it would run; the build-VM set-aside reads the projects: config.
Checked: the image refuses to start without a config, runs as uid 10001;
one e2e test passed from the test stage (2m45s, $0).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE