Record the monorepo decision in the spec

Part H's repository-layout item is resolved: one repo, three packages.
Naming (S0), scope (S0.1), the step-10 extraction, and the repository
layout section are updated to match.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
dongarandClaude Fable 5 committed 2026-09-04 22:13:45 +00:00
1 parent 94aa51135f
commit 69375c0da1
1 file changed
+25 -21
+25 -21
View File
@@ -26,15 +26,17 @@ overnight and expects to be treated well in return. Three artifacts:
| Sysadmin Agent | `nisse-ops` | Operates infrastructure (Part C) |
Throughout this document, **Dev Agent** and **Sysadmin Agent** name the *roles* in
conceptual discussion; `nisse-dev` and `nisse-ops` name the *artifacts* — repos,
conceptual discussion; `nisse-dev` and `nisse-ops` name the *artifacts* — packages,
container images, VM hostnames, Matrix identities, and service accounts. Use the
same string across all of those: the VM, the container, the Caddy host, the Matrix
account, and the Bitwarden machine account for a given agent all share one name, so
that grepping the infrastructure for `nisse-ops` finds everything.
Published under a personal GitHub account rather than an org; `github.com/nisse` is
squatted and GitHub does not reclaim inactive usernames. The repo names carry the
identity. `nisse-core` is free on PyPI if packages are ever published.
The three artifacts live as three packages in **one repository, `nisse`** (decision
recorded in Part H). Directory and package names carry the identity. If mirrored to
GitHub, it goes under a personal account rather than an org — `github.com/nisse` is
squatted and GitHub does not reclaim inactive usernames. `nisse-core` is free on
PyPI if packages are ever published.
---
@@ -53,8 +55,9 @@ Both are thin applications over a shared **`nisse-core`** library. The library i
consumers that don't exist yet. Build the Dev Agent as if the library were internal,
then lift the seams that proved real.
Whether the three artifacts live in one repository or three is **an open decision**
(Part H). It changes what the extraction step in the build order concretely means.
The three artifacts live in **one repository** (decided — Part H), so the
extraction step in the build order is a package split within one tree, not a repo
split.
### Guiding principles (apply to everything below)
@@ -712,12 +715,9 @@ each agent is built — not standing up the service itself.
10. **Extract `nisse-core`**; build the **Sysadmin Agent** (`nisse-ops`): policy
engine (C2), SSO + scoped browser (A8/A6), secrets (A7), Vikunja control (C4),
Outline runbooks (D), scheduled checks, alert intake.
- Under a monorepo, extraction is a **package split** within one tree: move code
behind a package boundary, no release machinery required.
- Under three repos, it is a **repo split plus a version-pinning contract**:
`nisse-core` gets tagged releases, and `nisse-dev` pins a version rather than
tracking `main`, or every core change becomes a coordinated two-repo bump.
This is the step the open repo-layout decision (Part H) actually bites on.
- With the monorepo layout (Part H, decided), extraction is a **package split**
within one tree: move code behind a package boundary, no release machinery
required.
---
@@ -744,12 +744,16 @@ each agent is built — not standing up the service itself.
The rest resolve when reached, not now.
- **Repository layout:** one monorepo with three packages vs. three separate repos.
Three repos match the build order and give each artifact its own CI and release
cadence, at the cost of version-pinning `nisse-core` from Gitea and coordinating
bumps every time the shared interface moves. A monorepo is less friction while
`nisse-core` is still being extracted from a working `nisse-dev` and its seams are
still moving. Splitting later is easy; merging later is not. Decide by step 10.
- **Repository layout — decided: one monorepo, three packages.** For a solo
operator, three repos tripled the admin surface (tokens, CI, webhooks,
permissions, backups) and imposed a version-pinning contract on `nisse-core` —
coordinated bumps every time the shared interface moves — while buying nothing:
the repo boundary was never a trust boundary in this design (the VM is), and
independent release cadence is irrelevant solo. A monorepo is also less friction
while `nisse-core` is being extracted from a working `nisse-dev` and its seams
are still moving. One repo can still build both agent images via path-filtered
CI. Splitting later stays easy if a real need appears; merging later would not
have been.
- **Sysadmin browser access to network gear:** standing vs. per-task hand-off. The
lock-yourself-out risk argues for per-task.
- **Policy action taxonomy (C2):** the concrete list of which operations are
@@ -792,9 +796,9 @@ infra/ # (future) Terraform + cloud-init (Part F)
nisse-dev.tf | nisse-ops.tf | templates/
```
Shown as three sibling trees. Under a monorepo they become three packages under one
root; under three repos, three checkouts. Either way the module boundaries are the
same, which is the point of deciding this late (Part H).
These are three packages under one repository root (`nisse`), plus `docs/` for this
specification (Part H, decided). The module boundaries are what matter; the package
boundary is where the step-10 extraction lands.
`log/` carries the canonical event log and its renderer (A10); `delegation/` carries
the delegation harness and `ask_expert` (A13/A14).