affdb9e8aa87d7640505240e00ead79fbe745c26
- poller.py: CommentPoller polls PR comments rather than taking webhooks, keeping the VM outbound-only (B3). On an outage it backs off exponentially, caps, and retries indefinitely while logging: polling is pure intake, so an outage delays a reaction but never fails a task or forces a transition - prime() marks the existing thread as seen without delivering it, so starting a watch does not re-address feedback already handled - Review loop: a comment in PR_OPEN enters the canonical transcript, the executor responds, and the fix is pushed to the same branch with a reply on the PR. No intent is recorded for a follow-up push — the PR already exists, so a repeated push is harmless, unlike opening a second PR - Comment authors are checked against a separate Gitea operator allowlist: a PR comment is an instruction channel into an agent that writes code, so it is operator-scoped, and a Gitea login is not a Matrix MXID (A4 per-channel allowlists) - Orchestrator now holds a lock: transport and the poller deliver on separate threads, and state transitions must not interleave - Backoff timings are injectable, so the outage path is tested in milliseconds instead of being untestable Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Nisse
Two self-hosted AI agents sharing a common library, named for the Nordic farm spirit that keeps the place running overnight and expects to be treated well in return.
| Package | Role |
|---|---|
nisse-core/ |
Shared library both agents sit on (Part A) |
nisse-dev/ |
Dev Agent — plans and implements software projects (Part B) |
nisse-ops/ |
Sysadmin Agent — operates infrastructure (Part C) |
One repository, three packages. The library does not exist as code yet: it is
extracted from nisse-dev once that agent works (build-order step 10), as a
package split within this tree.
Architecture
The system-level specification lives at
docs/Architecture-Build-Spec.md. It covers the
shared library, both agents, the supporting services, the build order, and the
remaining open decisions.