refactor: move from den based to flake-parts based
This commit is contained in:
@@ -1,101 +1,83 @@
|
||||
# Repository Guidelines
|
||||
|
||||
## Project Structure & Module Organization
|
||||
This repository is a Den-based NixOS flake. `flake.nix` evaluates `./modules` through `import-tree`, so normal `.nix` files under `modules/` are auto-imported.
|
||||
This repository is a simplified `flake-parts` NixOS flake. `flake.nix` imports `./modules` through `import-tree`, so normal `.nix` files under `modules/` are loaded automatically unless their file or directory name starts with `_`.
|
||||
|
||||
- `modules/den.nix` imports the Den flake module and the `lux` namespace.
|
||||
- `modules/defaults.nix` sets repo-wide Den defaults, enables `den._.mutual-provider`, and configures `den.ctx.hm-host`.
|
||||
- `modules/schema.nix` defines the custom Den host and user schema used by this repo.
|
||||
- `modules/infra.nix` defines `den.hosts.x86_64-linux.<name>`, each host entity's `users` attrset, and the host/user data attached to those entities.
|
||||
- `modules/bundles.nix` defines bundle aspects that group other aspects. A bundle aspect may exist only to compose `includes`; `local-session` is an example.
|
||||
- `modules/hosts/` contains host-specific composition and hardware data for `orion`, `polaris`, and `zenith`.
|
||||
- `modules/features/` contains reusable aspects. In this repo, "feature" is only a directory label, not a Den primitive.
|
||||
- `modules/users/` defines per-user aspects.
|
||||
- `modules/secrets/` wires `sops-nix` and stores the encrypted `secrets.yaml`.
|
||||
- `.agents/den/` is a local checkout of Den with source, docs, and examples.
|
||||
- `modules/flake-parts.nix` defines the `flake-parts` setup, formatter, and the exported `nixosConfigurations`.
|
||||
- `modules/hosts/<name>/default.nix` defines one top-level `flake.modules.nixos.<host>` module and assembles that machine by importing reusable features, user modules, and host-local helpers.
|
||||
- `modules/hosts/<name>/_*.nix` are private host-local helper modules such as hardware and disk layout files.
|
||||
- `modules/users/<name>.nix` defines one reusable NixOS user module and the baseline Home Manager imports for that account.
|
||||
- `modules/features/*.nix` contains reusable NixOS and Home Manager feature modules.
|
||||
- `modules/features/<feature>/default.nix` is used when a feature needs private helper files, for example `niri/_bindings.nix`.
|
||||
- `modules/features/services/*.nix` contains reusable service-oriented NixOS modules.
|
||||
- `modules/secrets/sops.nix` wires `sops-nix` for both NixOS and Home Manager.
|
||||
- `modules/secrets/secrets.yaml` stores encrypted secrets, with `.sops.yaml` defining SOPS creation rules.
|
||||
- `modules/_treefmt.nix` configures repository formatting.
|
||||
|
||||
Keep host files thin. Shared behavior belongs in `modules/features/` or `modules/bundles.nix`.
|
||||
When Den behavior is unclear, read `.agents/den/modules/` and `.agents/den/nix/lib/` first. Use `.agents/den/templates/ci/` as example code. Use `.agents/den/docs/` only for design rationale, terminology, and usage guidance.
|
||||
Do not infer Den behavior from surface symptoms or from where an aspect is included; reason from the actual context pipeline.
|
||||
Keep host files thin. Shared behavior belongs in `modules/features/` or `modules/users/`. Host files should mainly compose imports and hold host-only settings such as monitor layouts, hardware quirks, boot tweaks, and machine-local firewall or service choices.
|
||||
|
||||
## Den Mental Model
|
||||
Den is aspect-first and context-driven.
|
||||
## Mental Model
|
||||
This repo is direct module composition around `flake.modules`, not the old inventory-driven dendritic design.
|
||||
|
||||
- Host, user, and home are entity kinds in Den. This repo defines host and user entities; it does not define standalone home entities under `modules/`.
|
||||
- An aspect is the unit of behavior. A single aspect may define `nixos`, `homeManager`, `darwin`, `user`, or other class fragments for one concern.
|
||||
- A context stage applies a resolved aspect to a context; Den then follows `into.*` and `provides.*`.
|
||||
- `homeManager` is a forwarding class.
|
||||
- Reusable building blocks are exposed as `flake.modules.nixos.<name>` and `flake.modules.homeManager.<name>`.
|
||||
- Host modules are the composition root. They import the reusable NixOS modules they need, enable Home Manager, and add any host-specific Home Manager imports inline.
|
||||
- User modules define the Unix user plus that account’s baseline Home Manager setup.
|
||||
- There is no `config.repo`, inventory schema, profiles layer, or attachment builder anymore.
|
||||
|
||||
In practice:
|
||||
|
||||
- Including an aspect does not by itself create a forwarding path.
|
||||
- Parametric matching does not by itself create a forwarding path.
|
||||
- A class fragment reaches its final option path only if a context stage or forwarding class actually puts it there.
|
||||
- If you cannot name the context stage and forwarding path, treat the claim as unverified.
|
||||
- Prefer importing a feature module directly over inventing a repo-local option just to toggle it.
|
||||
- Put cross-host reusable behavior in `modules/features/`.
|
||||
- Put account-specific defaults in `modules/users/`.
|
||||
- Keep private helper files `_`-prefixed so `import-tree` does not expose them as top-level modules.
|
||||
- Match the existing split between NixOS composition in host modules and Home Manager composition in user or host modules.
|
||||
|
||||
## Den Context Stages And Forwarding Mechanisms
|
||||
These are the mechanisms most relevant to the context pipeline in this repo.
|
||||
## Current Host Composition
|
||||
There are three exported hosts:
|
||||
|
||||
- `den.ctx.host`: host context stage; applies `fixedTo { host; } host.aspect`
|
||||
- `den.ctx.user`: user context stage from `den.ctx.host.into.user`; applies `fixedTo { host; user; } user.aspect`
|
||||
- `den._.mutual-provider`: battery included on `den.ctx.user` in this repo; routes host-to-user and user-to-host through `provides.<name>`, host-to-all-users through `provides.to-users`, user-to-hosts through `provides.to-hosts`, and user-to-other-users on the same host through the same user context pipeline. In Den generally it also has standalone-home behavior, but this repo does not use standalone `den.homes`
|
||||
- `den.ctx.hm-host` / `den.ctx.hm-user`: derived home-env context stages
|
||||
- `den._.define-user`: battery included by `den.default` in this repo; defines base OS user fields and base `homeManager.home.username` / `home.homeDirectory` fields
|
||||
- `homeManager`: forwarding class into `home-manager.users.<name>`
|
||||
- `den._.os-user`: framework battery forwarding the `user` class into `users.users.<name>`; useful in Den generally, but not used in this repo today
|
||||
- `den._.forward`: battery for custom class/path forwarding
|
||||
- `orion`: server-oriented host with `kiri`, SOPS, and service modules such as Caddy, Gitea, Vaultwarden, Radicale, Actual, and OpenSSH.
|
||||
- `polaris`: graphical desktop host with `kiri` and `ergon`, hardware imports, Niri, Steam, local desktop features, and host-specific monitor layout.
|
||||
- `zenith`: graphical laptop host with `kiri` and `ergon`, Niri, laptop hardware support, firmware updates, and host-specific monitor layout.
|
||||
|
||||
## Den Helper Functions
|
||||
These are the Den helpers that matter most in this repo.
|
||||
When adjusting user-facing software, check whether it belongs in:
|
||||
|
||||
- `den.lib.perHost`: exact `{ host }` wrapper
|
||||
- `den.lib.perUser`: exact `{ host, user }` wrapper
|
||||
- `den.lib.perHome`: exact `{ home }` wrapper; not used by this flake today
|
||||
- `den.lib.parametric`: explicit parametric wrapper; default matching is `atLeast`
|
||||
- `den.lib.parametric.exactly`: explicit exact-match wrapper
|
||||
- a user baseline in `modules/users/<name>.nix`
|
||||
- a reusable Home Manager feature in `modules/features/*.nix`
|
||||
- a host-local extension inside `modules/hosts/<name>/default.nix`
|
||||
|
||||
## Den Forwarding Proof Obligation
|
||||
When making or reviewing any Den forwarding change, do not infer behavior from where code is declared or included.
|
||||
|
||||
You must identify all four of these explicitly:
|
||||
|
||||
1. Source: which aspect actually owns the class fragment?
|
||||
2. Context stage: which `den.ctx.*` stage applies it?
|
||||
3. Destination: which final evaluated option path should contain the result?
|
||||
4. Mechanism: which `into.*` transition reaches the context stage, and which class application, `provides.*`, forwarding class, or `den._.forward` step places it at the destination?
|
||||
|
||||
If any of those answers are missing, unclear, or based on analogy, treat the claim as unverified.
|
||||
|
||||
Before presenting a forwarding claim as a recommendation or review finding, verify it at the evaluated destination with `nix eval`.
|
||||
|
||||
Minimum checks:
|
||||
|
||||
- host-selected `homeManager` behavior: inspect `nixosConfigurations.<host>.config.home-manager.users.<user>`
|
||||
- OS user forwarding via `user` class: inspect `nixosConfigurations.<host>.config.users.users.<user>`
|
||||
- mutual host/user forwarding through `provides.<name>`, `provides.to-users`, or `provides.to-hosts`: inspect the final destination option, not the declaration site
|
||||
- custom forwarding through `den._.forward`: inspect the exact target path created by the forwarder
|
||||
Be careful not to move host-specific Home Manager imports into a user baseline unless that behavior should apply on every host that imports that user module.
|
||||
|
||||
## Validation And Development Commands
|
||||
Run commands from the repository root.
|
||||
|
||||
- `nix build --no-link --show-trace .#nixosConfigurations.<host>.config.system.build.toplevel`: baseline validation for one host without activation and without creating a `result` symlink.
|
||||
- `nix build --no-link --show-trace .#nixosConfigurations.orion.config.system.build.toplevel .#nixosConfigurations.polaris.config.system.build.toplevel .#nixosConfigurations.zenith.config.system.build.toplevel`: validate all currently defined hosts in one invocation.
|
||||
- `nixos-rebuild build --flake .#<host>`: use the standard rebuild path without activation when you specifically want `nixos-rebuild` semantics.
|
||||
- `nix fmt`: format Nix files using the flake-provided `nixfmt` formatter.
|
||||
- `nix eval .#nixosConfigurations.<host>.config.<option>`: inspect a single option while iterating.
|
||||
- `nix build --no-link --show-trace .#nixosConfigurations.<host>.config.system.build.toplevel`: baseline validation for one host.
|
||||
- `nix build --no-link --show-trace .#nixosConfigurations.orion.config.system.build.toplevel .#nixosConfigurations.polaris.config.system.build.toplevel .#nixosConfigurations.zenith.config.system.build.toplevel`: validate all defined hosts in one invocation.
|
||||
- `nixos-rebuild build --flake .#<host>`: use when you specifically want `nixos-rebuild` semantics without activation.
|
||||
- `nix eval --json .#nixosConfigurations.<host>.config.<option>`: inspect a single evaluated option while iterating.
|
||||
- `nix fmt`: format the repository using the flake-provided formatter from `modules/_treefmt.nix`.
|
||||
- `nix store diff-closures <old> <new>`: compare built system closures when reviewing refactors for parity or regressions.
|
||||
|
||||
This repo does not define a `checks` output or a first-party test suite. Treat evaluation and build-only checks as the baseline. `nix flake check` is therefore not the baseline validation command here. `nixos-rebuild dry-activate` is not a baseline validation command either: it is activation-oriented, applies to the target system being rebuilt, and its own help text says the reported change set is not guaranteed to be complete.
|
||||
|
||||
For Den context-stage or forwarding changes, use the destination checks above.
|
||||
This repo does not define a first-party `checks` output. Validation is primarily host builds plus targeted `nix eval` checks.
|
||||
|
||||
## Coding Style & Naming Conventions
|
||||
Use two-space indentation and standard Nix attrset formatting. Prefer small `let` bindings, lowerCamelCase local names, and lowercase file names such as `sops-password.nix`. Match the surrounding module style instead of reformatting unrelated code.
|
||||
Use two-space indentation and standard Nix attrset formatting. Prefer small `let` bindings, lowerCamelCase local names, and lowercase file names.
|
||||
|
||||
Prefer Den composition through `includes`; avoid host-specific duplication when a reusable aspect or bundle aspect is clearer.
|
||||
Keep the configuration aspect-first. When a class fragment must cross context boundaries, express that through an explicit forwarding mechanism instead of relying on implicit host/user propagation.
|
||||
- Define reusable modules as `flake.modules.nixos.<name>` or `flake.modules.homeManager.<name>`.
|
||||
- Keep one obvious feature per file or directory.
|
||||
- Use `default.nix` only when the feature needs private helper files alongside it.
|
||||
- Match surrounding style instead of reformatting unrelated code.
|
||||
- Prefer explicit host imports over hidden indirection.
|
||||
|
||||
## Commit
|
||||
Follow the history style: short imperative subjects, optionally with a conventional prefix, for example `refactor: restructure openssh config`. Keep each commit focused on one concern.
|
||||
Follow the existing history style: short imperative subjects, optionally with a conventional prefix, for example `refactor: simplify host composition`.
|
||||
|
||||
## Security & Configuration Tips
|
||||
Never commit plaintext secrets. Add or update secrets through `modules/secrets/secrets.yaml` and reference them via `config.sops.secrets.<name>.path`. Be explicit about firewall, SSH, disk, boot, or firmware changes; those are the highest-risk edits here.
|
||||
Never commit plaintext secrets. Add or update secrets through `modules/secrets/secrets.yaml` and reference them via `config.sops.secrets.<name>.path`.
|
||||
|
||||
Be explicit and cautious with changes to:
|
||||
|
||||
- firewall and OpenSSH settings
|
||||
- disk layout and boot configuration
|
||||
- SOPS key handling and admin user access
|
||||
- firmware, hardware, and authentication settings
|
||||
- host-vs-user module boundaries, because it is easy to accidentally broaden behavior to the wrong machines
|
||||
|
||||
Reference in New Issue
Block a user