846e5494ca66077b2dab9196e21b4e1caa608817
B2 specified the service account and its scoped token but never said the project repo's default branch must be protected — which turns out to be the load-bearing part of the PR gate. In Gitea, write access includes merging pull requests, and repository ownership does not restrict merging either. So an agent with the access it needs to push branches can also merge its own PR, and the review gate holds only because the agent's code does not call the merge endpoint. That is the advisory guarantee A4 exists to rule out. Verified rather than assumed: before protection was configured, the agent's own token merged its own PR (HTTP 200). With protection it is refused (405), as is a direct push to the default branch. The amendment says to assert both, so relaxing the protection later fails a test instead of silently removing the gate. 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.