diff --git a/docs/Architecture-Build-Spec.md b/docs/Architecture-Build-Spec.md index 37b17f2..64b16b9 100644 --- a/docs/Architecture-Build-Spec.md +++ b/docs/Architecture-Build-Spec.md @@ -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).