reviewing

This commit is contained in:
Danilo Reyes
2026-01-30 16:42:29 -06:00
parent 5da9abf1b7
commit d448e0f6c8
13 changed files with 271 additions and 40 deletions

52
docs/constitution.md Normal file
View File

@@ -0,0 +1,52 @@
# AI Constitution for the NixOS Repository
## Scope and Audience
- Audience: AI assistants and contributors needing an authoritative description of repository rules, structure, and workflows.
- Scope: Repo-wide conventions, module categories, host roles, secrets handling, proxy rules, documentation locations, and maintenance triggers.
- Authority: This constitution is the source of truth for AI. If human-facing docs differ, update both with the recorded resolution in `specs/001-ai-docs/research.md`.
## Repository Overview
- Architecture: Flake-based repo using `flake-parts` with inputs for pkgs (stable/unstable), stylix, home-manager, sops-nix, and service overlays. Common modules are composed through `parts/core.nix` and `parts/hosts.nix`.
- Module auto-import: `modules/modules.nix` auto-imports `.nix` files under `modules/apps`, `modules/dev`, `modules/scripts`, `modules/servers`, `modules/services`, `modules/shell`, and `modules/network`, excluding `librewolf.nix`. Factories live in `modules/factories/` (`mkserver`, `mkscript`), and shared options are in `modules/nix` and `modules/users`.
- Hosts and toggles: Host definitions live in `hosts/<name>/configuration.nix` with host-specific toggles in `hosts/<name>/toggles.nix`. The `my` namespace carries toggles for apps/dev/scripts/services/shell, feature flags like `enableProxy` and `enableContainers`, and per-host `interfaces` and `ips` maps.
- Main server and proxies: `my.mainServer` selects the host that should serve traffic by default (default `miniserver`; overridden to `server` in `hosts/server/toggles.nix`). Reverse proxies use helpers in `parts/core.nix` (`proxy`, `proxyReverse`, `proxyReverseFix`, `proxyReversePrivate`) and pick IPs from `my.ips` plus the hostName/ip set by `mkserver` options.
- Secure hosts and secrets: `my.secureHost` gates SOPS secrets. Secure hosts load secrets from `secrets/*.yaml` and wireguard definitions; non-secure hosts (e.g., `hosts/emacs`) skip secret-dependent services. Default SOPS file is `secrets/secrets.yaml` via `config/base.nix`.
## Coding Conventions
- No blank lines between code blocks; keep markdown examples tight.
- Minimize comments; prefer clear naming and shared helpers (`modules/factories/mkserver.nix`, `modules/factories/mkscript.nix`) to avoid duplication.
- Use business-level, technology-agnostic language in AI docs; reserve implementation detail for module code.
## Terminology and Naming Standards
- Module: A Nix module under `modules/<category>/<name>.nix` auto-imported into the system.
- Factory: Shared option constructors in `modules/factories/` (use `mkserver` for server modules, `mkscript` for script units).
- Options: Settings under the `my` namespace (e.g., `my.services.<service>`, `my.scripts.<script>`).
- Toggles: Enablement maps in `hosts/<name>/toggles.nix` controlling categories (apps/dev/shell/scripts/services/servers/units) and features (`enableProxy`, `enableContainers`).
- Servers: Reverse-proxied services under `modules/servers/`, normally created with `mkserver` options.
- Scripts: Units defined via `mkscript` with `enable`, `install`, `service`, `users`, `timer`, and `package` fields.
- Playbooks: Workflow guides under `docs/playbooks/` for repeatable tasks.
- Reference map: Navigation index under `docs/reference/index.md` for paths and responsibilities.
## Secrets Map and secureHost Behavior
- Secrets files: `secrets/certs.yaml`, `secrets/env.yaml`, `secrets/gallery.yaml`, `secrets/homepage.yaml`, `secrets/keys.yaml`, `secrets/wireguard.yaml`, `secrets/secrets.yaml`, plus `secrets/ssh/` for host keys.
- Placement rules: Keep secrets aligned to their file purpose (certificates → `certs.yaml`; environment/service env vars → `env.yaml`; media/gallery creds → `gallery.yaml`; homepage widgets → `homepage.yaml`; SSH/private keys → `keys.yaml`; WireGuard peers → `wireguard.yaml`; misc defaults → `secrets.yaml`).
- secureHost gating: Only hosts with `my.secureHost = true` load SOPS secrets and WireGuard interfaces. Hosts with `secureHost = false` must avoid secret-dependent services and skip SOPS entries.
## Module Categories and Active Hosts
- Module categories: apps, dev, scripts, servers, services, shell, network, users, nix, patches. Factories sit in `modules/factories/` and are imported explicitly.
- Active hosts: `workstation`, `server`, `miniserver`, `galaxy`, `emacs`. Host roles and secure status are defined in `hosts/<name>/configuration.nix` and toggles in `hosts/<name>/toggles.nix`.
## Precedence and Conflict Resolution
- Precedence: This constitution is authoritative for AI. Human docs must be updated to match. If conflicts are found, align human docs to the constitution and log the resolution in `specs/001-ai-docs/research.md`.
- Conflict handling steps: identify the divergent rule, cite the source files, decide the authoritative rule per this constitution, update both the source file and the relevant doc, and record the decision and timestamp.
## Maintenance Triggers and Update Process
- Triggers: New factory/helper, new module category, new host, new toggle set, new proxy rule, new secret category/file, change to `my.mainServer` or `my.ips`, stylix scheme changes, or new auto-import filters.
- Update flow: (1) Amend the relevant module or toggle files; (2) Update `docs/constitution.md` for rules/terminology changes; (3) Update playbooks under `docs/playbooks/` affected by the change; (4) Update `docs/reference/index.md` for navigation paths; (5) Note the decision in `specs/001-ai-docs/research.md` and refresh `quickstart.md` if discoverability shifts.
- Validation: Confirm discoverability within two clicks (constitution → reference map/playbook), secrets map completeness, and alignment with success criteria SC-001SC-004.
## Quick Reference and Navigation
- Constitution: `docs/constitution.md` (this file)
- Reference map: `docs/reference/index.md` (paths, hosts, secrets, proxies, stylix)
- Playbooks: `docs/playbooks/*.md` (add module/server/script/host toggle/secret, plus template)
- Planning artifacts: `specs/001-ai-docs/` (plan, research, data-model, quickstart, contracts)

View File

@@ -0,0 +1,18 @@
# Playbook: Add a Host Toggle
- Name: Add or adjust host toggles
- Purpose: Enable categories, services, or features per host in `hosts/<name>/toggles.nix`.
- Prerequisites: Identify host role (see Hosts and Roles), secureHost setting, and whether proxies/containers are required.
- Inputs: Toggle category (apps/dev/scripts/services/servers/units), users list, proxy/container flags, mainServer override, network interface names.
- Steps:
1. Open `hosts/<name>/toggles.nix` and adjust category maps using helper patterns (`enableList` with `mkEnabled`, `mkEnabledWithUsers`, or `mkEnabledIp`).
2. Set feature flags such as `enableProxy`, `enableContainers`, and `mainServer` when the host should own proxied services.
3. Add service toggles under `servers` with proxy/ip data as needed; align IPs to `my.ips` (e.g., `mkEnabledIp` for remote hosts).
4. Ensure `interfaces` entries exist for network-facing services and match `my.interfaces` defaults unless intentionally overridden.
5. Reconcile toggle changes with secrets and secureHost: avoid enabling secret-backed services on hosts with `secureHost = false`.
- Validation:
- Toggle sets align with host capabilities and `my.secureHost`.
- Proxy- or container-dependent services have `enableProxy`/`enableContainers` enabled.
- IP/interface values match `docs/reference/index.md` entries.
- Outputs: Updated host toggle file reflecting new enablement and infrastructure flags.
- References: `docs/constitution.md` (Hosts and toggles, Main server and proxies), `docs/reference/index.md` (Hosts and Roles, Proxy rules, Network maps)

View File

@@ -0,0 +1,18 @@
# Playbook: Add a NixOS Module
- Name: Add a module under `modules/<category>/`
- Purpose: Introduce a new module following auto-import and toggle conventions.
- Prerequisites: Identify target host(s) and toggle category; confirm `my.secureHost` if secrets are involved.
- Inputs: Module name, category (apps/dev/scripts/servers/services/shell/network), required options, secret needs, proxy requirements if server-facing.
- Steps:
1. Choose the category path from `docs/reference/index.md` and create `modules/<category>/<name>.nix` (auto-import picks it up; avoid names filtered out such as `librewolf.nix`).
2. Define options under `my.<category>` or reuse factories (`mkserver` for servers, `mkscript` for scripts) instead of hand-rolled patterns.
3. If the module needs secrets, guard references with `lib.mkIf config.my.secureHost` and map them to the correct secrets file (see secrets map).
4. For networked services, align host selection with `my.mainServer` and `my.ips`; enable reverse proxy via `enableProxy` when applicable.
5. Wire toggles for target hosts in `hosts/<host>/toggles.nix`, ensuring users/groups and containers/proxy flags are set.
- Validation:
- Module loads without extra imports (auto-import applies).
- Toggle wiring matches intended hosts; secureHost gating present for secrets.
- Proxy and port choices align with `my.mainServer`, `my.ips`, and firewall rules.
- Outputs: New module file and updated host toggles if required.
- References: `docs/constitution.md` (Module Categories, Secrets Map, Main server and proxies), `docs/reference/index.md` (Module Directories, Proxy rules, Secrets Map)

View File

@@ -0,0 +1,17 @@
# Playbook: Add a Script Unit
- Name: Add a script via `mkscript`
- Purpose: Ship a script package with optional user service and timer.
- Prerequisites: Identify target users (`my.toggleUsers.scripts` defaults), secureHost status if the script needs secrets, and whether a timer/service is required.
- Inputs: Script name, package derivation, description, timer schedule, users list, service needs.
- Steps:
1. Add a definition under `my.scripts.<name>` in `modules/scripts/<name>.nix` using `mkscript` options (`enable`, `install`, `service`, `users`, `timer`, `package`, `description`).
2. Ensure the package exposes the executable name used by the service/timer.
3. For user scoping, set `users` to a single user or list; defaults come from `my.toggleUsers.scripts`.
4. If secrets are required, guard references with `lib.mkIf config.my.secureHost` and map them to the appropriate secrets file.
5. Enable the script toggle in `hosts/<host>/toggles.nix` under `scripts` or `units`, and ensure timers/services are expected on that host.
- Validation:
- Script installs for intended users; systemd user service/timer activates only when `enable` and `service` are true.
- secureHost gating present for any secrets; no orphaned timers.
- Outputs: New script module and updated host toggles if needed.
- References: `docs/constitution.md` (Terminology, Secrets Map), `docs/reference/index.md` (Module Directories, Secrets Map, Hosts and Roles)

View File

@@ -0,0 +1,17 @@
# Playbook: Add a Secret Entry
- Name: Add or update a secret
- Purpose: Place secrets in the correct SOPS file with secureHost gating.
- Prerequisites: Target host(s) must have `my.secureHost = true`; identify secret type and consumer service/module.
- Inputs: Secret name, target file (certs/env/gallery/homepage/keys/wireguard/secrets), owner/group if file material is written, consuming module path.
- Steps:
1. Choose the correct secrets file from the map in `docs/constitution.md` and add the entry there (YAML, encrypted via sops-nix).
2. If a private key or file path is required, specify `owner`, `group`, and target path consistent with the consuming module.
3. In the consuming module, reference the secret under `config.sops.secrets.<name>` and guard with `lib.mkIf config.my.secureHost`.
4. For WireGuard entries, update `secrets/wireguard.yaml` and corresponding interface configuration under the target host.
5. Avoid adding secrets for hosts with `secureHost = false`; instead route the workload to a secure host or skip enablement.
- Validation:
- Secret lives in the correct file and encrypts with SOPS; file ownership matches service user where applicable.
- Module references are gated by `secureHost` and align with host toggles.
- Outputs: Updated secrets file and gated module references.
- References: `docs/constitution.md` (Secrets Map and secureHost), `docs/reference/index.md` (Secrets Map, Hosts and Roles)

View File

@@ -0,0 +1,18 @@
# Playbook: Add a Server Module with mkserver
- Name: Add a reverse-proxied server module
- Purpose: Stand up a server using `modules/factories/mkserver.nix` with correct proxy and host routing.
- Prerequisites: Target host must have `my.enableProxy = true` and container support if needed; confirm `my.secureHost` for secrets.
- Inputs: Service name, desired subdomain, port, proxy type (standard/fix/private), cron needs, secrets/env vars.
- Steps:
1. Create `modules/servers/<name>.nix` and import `mkserver` options to define `enable`, `enableProxy`, `port`, `host`, `hostName`, `url`, `ip`, `enableSocket`, and `certPath` as needed.
2. Default host routing uses `my.mainServer` and `my.ips`; override `hostName`/`ip` only when the service must live elsewhere.
3. For reverse proxy behavior, select helper from `parts/core.nix`: `proxyReverse` (standard), `proxyReverseFix` (preserve host headers/websockets), or `proxyReversePrivate` (mutual TLS).
4. Place secrets/env references in the appropriate file from the secrets map and guard with `lib.mkIf config.my.secureHost`.
5. Enable the service toggle in `hosts/<host>/toggles.nix` under `servers` (and `enableProxy` if not already set); add any firewall/static ports needed.
- Validation:
- Service resolves to the expected URL and IP per `my.ips` and `my.mainServer`.
- Proxy helper matches the protocol needs; SSL settings align with cert sources.
- Secrets load only on secure hosts; firewall assertions pass.
- Outputs: New server module with mkserver options and updated host toggles/firewall settings.
- References: `docs/constitution.md` (Main server and proxies, Secrets Map), `docs/reference/index.md` (Proxy rules, Module Directories, Secrets Map, Hosts and Roles)

View File

@@ -0,0 +1,15 @@
# Playbook Template
- Name:
- Purpose:
- Prerequisites: (toggles, hosts, secureHost, required secrets)
- Inputs: (paths, options, credentials, ports)
- Steps:
1.
2.
3.
- Validation:
-
-
- Outputs:
- References: `docs/constitution.md` (relevant sections) and `docs/reference/index.md` (paths/hosts/proxies/secrets)

64
docs/reference/index.md Normal file
View File

@@ -0,0 +1,64 @@
# Reference Map
## Module Directories
- apps → `modules/apps/` (desktop/workstation apps, auto-imported)
- dev → `modules/dev/` (language toolchains and dev shells, auto-imported)
- scripts → `modules/scripts/` (script units built via `mkscript`, auto-imported)
- servers → `modules/servers/` (reverse-proxied services built via `mkserver`)
- services → `modules/services/` (supporting services like syncthing, wireguard)
- shell → `modules/shell/` (shell customizations and CLI tooling)
- network → `modules/network/` (networking rules, firewall helpers)
- users → `modules/users/` (user-related options)
- nix → `modules/nix/` (Nix configuration and helpers)
- patches → `patches/` (patch artifacts referenced by modules)
- factories → `modules/factories/` (`mkserver.nix`, `mkscript.nix` shared helpers)
## Auto-Import Rules
- Source: `modules/modules.nix` uses `inputs.self.lib.autoImport` to load `.nix` files from module directories.
- Filter: Excludes `librewolf.nix`; all other `.nix` files in target dirs are loaded automatically.
- Implication: Place new modules in the correct category directory with a `.nix` filename; no manual import wiring required unless adding a new factory.
## Hosts and Roles
- Configs: `hosts/<name>/configuration.nix` with toggles in `hosts/<name>/toggles.nix`.
- Active hosts: `workstation`, `server`, `miniserver`, `galaxy`, `emacs`.
- Roles:
- workstation: developer desktop; provides build power for distributed builds.
- server: primary services host (overrides `my.mainServer = "server"` and enables proxies/containers).
- miniserver: small-footprint server; default `mainServer` in shared options.
- galaxy: small server variant using nixpkgs-small.
- emacs: VM profile, `my.secureHost = false` for secret-free usage.
- Network maps: `my.ips` and `my.interfaces` declared in `modules/modules.nix`; host toggles may override.
## Proxy, Firewall, and Networking
- Proxy enablement: `my.enableProxy` toggles Nginx reverse proxy; assertions require at least one `my.servers.*.enableProxy` when enabled.
- Proxy helpers: use `parts/core.nix` helpers (`proxy`, `proxyReverse`, `proxyReverseFix` for header preservation, `proxyReversePrivate` for mutual TLS). `mkserver` supplies `host`, `ip`, `url`, and `enableProxy` defaults per service.
- Main server selection: `my.mainServer` chooses where services live by default; `mkserver` sets `isLocal` based on this and picks IPs from `my.ips`.
- Firewall generation: `inputs.self.lib.generateFirewallPorts` combines static ports, additional ports, and service ports from `my.servers` (excluding native firewall services). Use `my.network.firewall` settings and `getServicesWithNativeFirewall` to derive open ports.
## Secrets Map
- Files and purposes:
- `secrets/certs.yaml` → certificates and TLS material.
- `secrets/env.yaml` → environment variables for services (e.g., lidarr-mb-gap).
- `secrets/gallery.yaml` → media/gallery credentials.
- `secrets/homepage.yaml` → homepage widget secrets.
- `secrets/keys.yaml` → SSH/private keys and key ownership.
- `secrets/wireguard.yaml` → WireGuard peers and private keys.
- `secrets/secrets.yaml` → default SOPS file (general secrets, fallback when unspecified).
- `secrets/ssh/` → host SSH keys and related artifacts.
- secureHost: Only hosts with `my.secureHost = true` consume SOPS entries and WireGuard interfaces. Keep secret references behind `lib.mkIf config.my.secureHost`.
## Stylix and Theming
- Stylix module: `config/stylix.nix` and stylix inputs in `flake.nix` apply theming. Host toggle `my.stylix.enable` controls activation (see host toggles).
- Schemes and assets: Imported via Stylix inputs; wallpapers/fonts sourced from external flakes (`wallpapers`, `fonts`).
## Playbooks and Templates
- Playbook template: `docs/playbooks/template.md`
- Workflows: `docs/playbooks/add-module.md`, `add-server.md`, `add-script.md`, `add-host-toggle.md`, `add-secret.md`
- Constitution link-back: `docs/constitution.md` sections on terminology, proxies, secrets, and maintenance.
## Quick Audit Checklist
- Module coverage: All categories (apps, dev, scripts, servers, services, shell, network, users, nix, patches) have corresponding entries and auto-import rules.
- Host coverage: Active hosts listed with roles and secureHost status; `mainServer` noted.
- Proxy rules: `enableProxy` usage, proxy helper selection, and `my.ips` mappings documented.
- Secrets map: Every secrets file and secureHost gating captured; new secret types aligned to file purposes.
- Discoverability: Paths reachable within two clicks from `docs/constitution.md`.