mirror of
https://github.com/moons-14/dotfiles.git
synced 2026-10-06 08:48:11 +09:00
feat hosts
This commit is contained in:
@@ -7,6 +7,10 @@ flake. `flake.nix` defines inputs and delegates flake outputs through
|
|||||||
flake-parts. Keep configuration with the component that owns it, rather than in
|
flake-parts. Keep configuration with the component that owns it, rather than in
|
||||||
the root flake or an unrelated host.
|
the root flake or an unrelated host.
|
||||||
|
|
||||||
|
This file documents the current repository contract, not a hypothetical future
|
||||||
|
layout. When a structural, ownership, profile, host-role, or validation change
|
||||||
|
makes any statement here stale, update `AGENTS.md` in the same change.
|
||||||
|
|
||||||
| Path | Responsibility |
|
| Path | Responsibility |
|
||||||
| ----------------------- | ----------------------------------------------------------------------------------------------------------------- |
|
| ----------------------- | ----------------------------------------------------------------------------------------------------------------- |
|
||||||
| `modules/applications/` | One software component, including GUI applications, window managers, desktop environments, CLI tools, and editors |
|
| `modules/applications/` | One software component, including GUI applications, window managers, desktop environments, CLI tools, and editors |
|
||||||
@@ -31,23 +35,26 @@ Before adding configuration, decide whether it is owned by an application,
|
|||||||
system foundation, service, hardware family, user, profile, or individual host.
|
system foundation, service, hardware family, user, profile, or individual host.
|
||||||
Prefer the following placements:
|
Prefer the following placements:
|
||||||
|
|
||||||
| Configuration | Placement |
|
| Configuration | Placement |
|
||||||
| ---------------------------------------------------- | ------------------------------------------------ |
|
| ---------------------------------------------------- | ------------------------------------------------------- |
|
||||||
| Nix settings shared by every system host | `modules/systems/nix/common.nix` |
|
| Nix settings shared by every system host | `modules/systems/nix/common.nix` |
|
||||||
| NixOS-only boot configuration | `modules/systems/boot/.../nixos.nix` |
|
| NixOS-only boot configuration | `modules/systems/boot/.../nixos.nix` |
|
||||||
| Ghostty-specific configuration | `modules/applications/ghostty/` |
|
| Ghostty-specific configuration | `modules/applications/ghostty/` |
|
||||||
| niri-specific configuration | `modules/applications/niri/` |
|
| niri-specific configuration | `modules/applications/niri/` |
|
||||||
| Applications selected for the niri environment | `modules/profiles/interface/niri/meta.nix` |
|
| Desktop applications shared by GNOME and niri | `modules/profiles/interface/linux-desktop/meta.nix` |
|
||||||
| GNOME itself | `modules/applications/gnome/` |
|
| Applications and services specific to niri | `modules/profiles/interface/niri/meta.nix` |
|
||||||
| Docker daemon and Docker group membership | `modules/services/docker/nixos.nix` |
|
| GNOME itself | `modules/applications/gnome/` |
|
||||||
| Reusable ThinkPad-family configuration | `modules/hardwares/thinkpad/` |
|
| A Linux package plus its macOS Homebrew cask | `modules/applications/<name>/home.nix` and `darwin.nix` |
|
||||||
| The laptop unit composition | `modules/profiles/platform/laptop/meta.nix` |
|
| Docker daemon and Docker group membership | `modules/services/docker/nixos.nix` |
|
||||||
| The development-environment unit composition | `modules/profiles/workload/development/meta.nix` |
|
| The laptop unit composition | `modules/profiles/platform/laptop/meta.nix` |
|
||||||
| A user's OS- and Home Manager-specific configuration | `modules/users/<name>/` |
|
| The Intel ThinkPad X1 composition | `modules/profiles/platform/thinkpad-x1/meta.nix` |
|
||||||
| x1g13-specific monitor layout | `hosts/x1g13/home.nix` |
|
| The development-environment unit composition | `modules/profiles/workload/development/meta.nix` |
|
||||||
| x1g13-specific disk UUID | `hosts/x1g13/nixos.nix` |
|
| Cross-platform fingerprint selection | `modules/profiles/security/fingerprint/meta.nix` |
|
||||||
| Package replacement or addition | `overlays/` |
|
| A user's OS- and Home Manager-specific configuration | `modules/users/<name>/` |
|
||||||
| Formatter, checks, or Git hooks | `flake/` |
|
| Host-specific monitor layout | `hosts/<name>/home.nix` |
|
||||||
|
| Generated host disk UUIDs | `hosts/<name>/hardware-configuration.nix` |
|
||||||
|
| Package replacement or addition | `overlays/` |
|
||||||
|
| Formatter, checks, or Git hooks | `flake/` |
|
||||||
|
|
||||||
## Unit Discovery and Identity
|
## Unit Discovery and Identity
|
||||||
|
|
||||||
@@ -283,12 +290,12 @@ use fully qualified unit IDs:
|
|||||||
# modules/profiles/interface/niri/meta.nix
|
# modules/profiles/interface/niri/meta.nix
|
||||||
{
|
{
|
||||||
includes = [
|
includes = [
|
||||||
|
"profiles.interface.linux-desktop"
|
||||||
"applications.niri"
|
"applications.niri"
|
||||||
"applications.ghostty"
|
|
||||||
"applications.noctalia"
|
"applications.noctalia"
|
||||||
"applications.vicinae"
|
"services.ly"
|
||||||
"applications.nautilus"
|
"services.swayidle"
|
||||||
"services.xdg-portal"
|
"services.swaylock"
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -301,41 +308,89 @@ in `meta.includes`.
|
|||||||
|
|
||||||
Application metadata should include only dependencies technically required for
|
Application metadata should include only dependencies technically required for
|
||||||
the application to work. A profile owns the user's choice to adopt several
|
the application to work. A profile owns the user's choice to adopt several
|
||||||
otherwise independent applications together. For example, niri may include the
|
otherwise independent applications together. For example, the niri application
|
||||||
Wayland foundation and xdg-desktop-portal as technical dependencies, while
|
includes the Wayland foundation as a technical dependency. The
|
||||||
`profiles.interface.niri` selects Ghostty, Vicinae, Noctalia, and Nautilus.
|
`profiles.interface.linux-desktop` profile selects Ghostty, Nautilus, and
|
||||||
Ghostty must not depend on niri, and niri-specific keybindings remain owned by
|
Vicinae because both GNOME and niri use them, while `profiles.interface.niri`
|
||||||
the niri unit.
|
selects only the niri-specific shell and services. Ghostty must not depend on
|
||||||
|
niri, and niri-specific keybindings remain owned by the niri unit.
|
||||||
|
|
||||||
## Profiles
|
## Profiles
|
||||||
|
|
||||||
Profiles compose units by purpose or form factor; they do not replace clear
|
Profiles compose units by purpose or form factor; they do not replace clear
|
||||||
application, system, service, or hardware ownership. Suitable profile namespaces
|
application, system, service, or hardware ownership. The current profile
|
||||||
include:
|
structure is:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
modules/profiles/
|
modules/profiles/
|
||||||
|
├── README.md
|
||||||
├── base/
|
├── base/
|
||||||
├── interface/
|
├── interface/
|
||||||
│ ├── niri/
|
│ ├── cli/
|
||||||
|
│ ├── linux-desktop/
|
||||||
│ ├── gnome/
|
│ ├── gnome/
|
||||||
│ ├── cli-minimal/
|
│ └── niri/
|
||||||
│ └── cli-interactive/
|
├── networking/
|
||||||
|
│ ├── tailscale-client/
|
||||||
|
│ └── tailscale-subnet-router/
|
||||||
├── platform/
|
├── platform/
|
||||||
|
│ ├── nixos/
|
||||||
│ ├── laptop/
|
│ ├── laptop/
|
||||||
│ ├── thinkpad/
|
│ ├── thinkpad-x1/
|
||||||
│ ├── desktop/
|
│ ├── desktop/
|
||||||
│ ├── vm/
|
│ └── vm/
|
||||||
│ └── wsl/
|
|
||||||
├── workload/
|
├── workload/
|
||||||
│ ├── development/
|
│ ├── development/
|
||||||
│ ├── personal/
|
│ ├── personal/
|
||||||
│ ├── server/
|
│ ├── server/
|
||||||
│ └── remote/
|
│ └── remote-access/
|
||||||
└── security/
|
└── security/
|
||||||
└── secure-boot/
|
├── fingerprint/
|
||||||
|
├── secrets/
|
||||||
|
├── secure-boot/
|
||||||
|
└── tpm-storage/
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`modules/profiles/README.md` is the compatibility inventory for this structure.
|
||||||
|
Whenever a profile is added, removed, renamed, changes host-class support, or
|
||||||
|
changes meaning, update that README and every affected `hosts/default.nix`
|
||||||
|
selection in the same change. Remove stale profile directories and references;
|
||||||
|
do not retain compatibility aliases.
|
||||||
|
|
||||||
|
The profile layers have these responsibilities:
|
||||||
|
|
||||||
|
- `base` contains only invariants required by every supported host. It currently
|
||||||
|
includes only `systems.nix`; optional secrets, interface, hardware, and
|
||||||
|
workloads do not belong there.
|
||||||
|
- `interface` describes how the host is operated. `interface.cli` is shared by
|
||||||
|
NixOS and macOS and includes `tio`. `interface.linux-desktop` owns the common
|
||||||
|
GNOME/niri desktop selection, including Ghostty, Nautilus, and Vicinae. GNOME
|
||||||
|
and niri remain independently selectable and do not imply CLI or personal
|
||||||
|
workloads.
|
||||||
|
- `platform` describes NixOS foundations and physical or virtual form factors.
|
||||||
|
macOS does not need an empty symmetric platform profile.
|
||||||
|
- `workload` describes optional host uses. `workload.development` and
|
||||||
|
`workload.personal` are cross-platform profiles, not `*-linux` variants.
|
||||||
|
- `networking` describes network roles and topology rather than user workloads.
|
||||||
|
- `security` describes optional security policies. Select
|
||||||
|
`security.fingerprint` instead of listing `systems.fingerprint` directly in a
|
||||||
|
host. The underlying `systems.fingerprint` unit owns NixOS fingerprint
|
||||||
|
authentication and macOS Touch ID sudo configuration through its class
|
||||||
|
fragments.
|
||||||
|
|
||||||
|
Do not split a semantic profile into `*-linux` and cross-platform variants merely
|
||||||
|
because an application is installed differently on each OS. Keep the semantic
|
||||||
|
profile cross-platform when its purpose is shared, and implement OS differences
|
||||||
|
inside the owning application unit. For example, Chrome, Vesktop, draw.io,
|
||||||
|
Slack, and Zoom use Linux Home Manager configuration in `home.nix` and macOS
|
||||||
|
Homebrew casks in `darwin.nix`. Guard a Linux-only Home Manager package with the
|
||||||
|
host platform when the same unit also has a Darwin implementation.
|
||||||
|
|
||||||
|
An explicitly OS-specific profile is appropriate when the composition itself is
|
||||||
|
OS-specific, such as `interface.linux-desktop`, `platform.nixos`, or a NixOS
|
||||||
|
subnet-router. Do not create an OS suffix for a thin package difference that the
|
||||||
|
owning application unit can express.
|
||||||
|
|
||||||
The `desktop/` name above is a form-factor profile under `profiles/platform/`,
|
The `desktop/` name above is a form-factor profile under `profiles/platform/`,
|
||||||
not a top-level module category.
|
not a top-level module category.
|
||||||
|
|
||||||
@@ -352,6 +407,10 @@ conditions holds:
|
|||||||
- Other units depend on it.
|
- Other units depend on it.
|
||||||
- It involves a daemon, permissions, or user groups.
|
- It involves a daemon, permissions, or user groups.
|
||||||
|
|
||||||
|
`security.tpm-storage` intentionally does not own a disk identifier. A host that
|
||||||
|
selects it must define `boot.initrd.luks.devices.cryptroot.device` in its own
|
||||||
|
NixOS module.
|
||||||
|
|
||||||
## Registry Responsibilities
|
## Registry Responsibilities
|
||||||
|
|
||||||
Implement unit discovery with Nix standard functionality such as
|
Implement unit discovery with Nix standard functionality such as
|
||||||
@@ -416,49 +475,46 @@ A host registry may use a specification like this:
|
|||||||
```nix
|
```nix
|
||||||
# hosts/default.nix
|
# hosts/default.nix
|
||||||
{
|
{
|
||||||
x1g13 = {
|
x1g9 = {
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
|
stateVersion = "26.05";
|
||||||
user = "moons";
|
user = "moons";
|
||||||
path = ./x1g13;
|
path = ./x1g9;
|
||||||
|
|
||||||
profiles = [
|
profiles = [
|
||||||
"base"
|
"base"
|
||||||
"platform.thinkpad"
|
"interface.cli"
|
||||||
"interface.niri"
|
|
||||||
"interface.gnome"
|
"interface.gnome"
|
||||||
"workload.development"
|
"interface.niri"
|
||||||
|
"platform.thinkpad-x1"
|
||||||
|
"security.fingerprint"
|
||||||
"workload.personal"
|
"workload.personal"
|
||||||
"security.secure-boot"
|
|
||||||
];
|
|
||||||
|
|
||||||
applications = [
|
|
||||||
"codex-desktop"
|
|
||||||
];
|
|
||||||
|
|
||||||
units = [
|
|
||||||
"services.tailscale"
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
macbook = {
|
m2 = {
|
||||||
system = "aarch64-darwin";
|
system = "aarch64-darwin";
|
||||||
|
stateVersion = "26.05";
|
||||||
user = "moons";
|
user = "moons";
|
||||||
path = ./macbook;
|
path = ./m2;
|
||||||
|
|
||||||
profiles = [
|
profiles = [
|
||||||
"base"
|
"base"
|
||||||
"platform.laptop"
|
"interface.cli"
|
||||||
|
"security.fingerprint"
|
||||||
"workload.development"
|
"workload.development"
|
||||||
"workload.personal"
|
"workload.personal"
|
||||||
];
|
];
|
||||||
|
|
||||||
applications = [
|
|
||||||
"ghostty"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The current role assignment is intentional: x1g9 is a full NixOS desktop with
|
||||||
|
niri, GNOME, ly, the shared Linux desktop applications, and the personal
|
||||||
|
workload. m2 is the daily-use macOS development and personal machine. Keep the
|
||||||
|
desktop sessions independently selectable, and keep m2's development and
|
||||||
|
personal profiles usable on Darwin.
|
||||||
|
|
||||||
Treat entries in `profiles` and `applications` as IDs relative to their
|
Treat entries in `profiles` and `applications` as IDs relative to their
|
||||||
respective category roots. Add the category prefixes during host construction:
|
respective category roots. Add the category prefixes during host construction:
|
||||||
|
|
||||||
@@ -471,24 +527,29 @@ selectedUnits =
|
|||||||
```
|
```
|
||||||
|
|
||||||
`units` is an escape hatch for fully qualified service, system, hardware, or
|
`units` is an escape hatch for fully qualified service, system, hardware, or
|
||||||
other unit IDs. Prefer profiles for the main composition; do not make hosts list
|
other unit IDs. Do not use it when an existing profile expresses the concern or
|
||||||
large numbers of low-level units directly.
|
when the concern is reusable enough to deserve a small profile. For example,
|
||||||
|
select `security.fingerprint`; do not write
|
||||||
|
`units = [ "systems.fingerprint" ];`. Prefer profiles for the main composition
|
||||||
|
and keep `units` empty unless a genuinely exceptional low-level selection is
|
||||||
|
required.
|
||||||
|
|
||||||
Host modules use normal Nix module semantics and are not Registry-guarded
|
Host modules use normal Nix module semantics and are not Registry-guarded
|
||||||
configuration fragments. For example:
|
configuration fragments. For example:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
hosts/x1g13/
|
hosts/
|
||||||
├── nixos.nix
|
├── x1g9/
|
||||||
├── home.nix
|
│ ├── nixos.nix
|
||||||
├── hardware-configuration.nix
|
│ └── hardware-configuration.nix
|
||||||
└── disko.nix
|
└── m2/
|
||||||
|
└── darwin.nix
|
||||||
```
|
```
|
||||||
|
|
||||||
`hosts/x1g13/nixos.nix` may explicitly load `hardware-configuration.nix` and
|
`hosts/x1g9/nixos.nix` explicitly loads `hardware-configuration.nix` with the
|
||||||
`disko.nix` with the normal top-level Nix module `imports`. Do not confuse these
|
normal top-level Nix module `imports`. A future host-local `disko.nix` would be
|
||||||
host imports with the prohibition on top-level `imports` in unit configuration
|
loaded the same way. Do not confuse these host imports with the prohibition on
|
||||||
fragments.
|
top-level `imports` in unit configuration fragments.
|
||||||
|
|
||||||
Derive the system class from the host's `system`:
|
Derive the system class from the host's `system`:
|
||||||
|
|
||||||
@@ -527,6 +588,16 @@ When implementing or modifying modules:
|
|||||||
- Do not override a path-derived unit ID from `meta.nix`.
|
- Do not override a path-derived unit ID from `meta.nix`.
|
||||||
- Keep technical application dependencies separate from the applications a
|
- Keep technical application dependencies separate from the applications a
|
||||||
personal environment chooses to combine in a profile.
|
personal environment chooses to combine in a profile.
|
||||||
|
- Keep cross-platform profile names semantic. Put Linux package installation in
|
||||||
|
an application's `home.nix` and the corresponding macOS Homebrew cask in its
|
||||||
|
`darwin.nix`; do not create a thin `*-linux` profile for that difference.
|
||||||
|
- Keep shared GNOME/niri selections in `profiles.interface.linux-desktop` and
|
||||||
|
session-specific applications or services in the respective GNOME or niri
|
||||||
|
profile.
|
||||||
|
- Keep `modules/profiles/README.md`, the profile directories, and host profile
|
||||||
|
selections synchronized whenever any of them changes.
|
||||||
|
- Prefer an existing or newly justified profile over a host-level `units` entry
|
||||||
|
for reusable concerns such as fingerprint authentication.
|
||||||
- Do not rely on module-list ordering to override values. Use Nix module
|
- Do not rely on module-list ordering to override values. Use Nix module
|
||||||
priorities such as `lib.mkDefault`, `lib.mkForce`, `lib.mkBefore`, or
|
priorities such as `lib.mkDefault`, `lib.mkForce`, `lib.mkBefore`, or
|
||||||
`lib.mkAfter` explicitly when required.
|
`lib.mkAfter` explicitly when required.
|
||||||
@@ -563,6 +634,20 @@ dependency closure through `meta.includes`, missing-unit errors, and class
|
|||||||
dispatch. Verify that helper files are ignored until explicitly imported and
|
dispatch. Verify that helper files are ignored until explicitly imported and
|
||||||
that directories without a directly contained reserved file remain namespaces.
|
that directories without a directly contained reserved file remain namespaces.
|
||||||
|
|
||||||
|
For profile changes, additionally:
|
||||||
|
|
||||||
|
- Check for stale profile IDs after every add, removal, or rename.
|
||||||
|
- Evaluate every affected real host without switching it.
|
||||||
|
- Evaluate a cross-platform profile on both NixOS and nix-darwin, even when only
|
||||||
|
one current host selects it.
|
||||||
|
- Confirm `modules/profiles/README.md` accurately states compatibility and any
|
||||||
|
required host-owned values.
|
||||||
|
- When adding a Darwin application fragment, verify the resulting
|
||||||
|
`homebrew.casks` selection as well as module evaluation.
|
||||||
|
- Preserve the intended host roles: x1g9 provides niri, GNOME, ly, and the
|
||||||
|
personal application set, while m2 remains the daily-use development and
|
||||||
|
personal machine.
|
||||||
|
|
||||||
## Commit and Pull Request Guidelines
|
## Commit and Pull Request Guidelines
|
||||||
|
|
||||||
Recent history favors short, lowercase, imperative subjects such as `fix` and
|
Recent history favors short, lowercase, imperative subjects such as `fix` and
|
||||||
|
|||||||
+3
-2
@@ -8,9 +8,11 @@
|
|||||||
profiles = [
|
profiles = [
|
||||||
"base"
|
"base"
|
||||||
"interface.cli"
|
"interface.cli"
|
||||||
|
"interface.gnome"
|
||||||
|
"interface.niri"
|
||||||
"platform.thinkpad-x1"
|
"platform.thinkpad-x1"
|
||||||
"security.fingerprint"
|
"security.fingerprint"
|
||||||
"security.secrets"
|
"workload.personal"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -24,7 +26,6 @@
|
|||||||
"base"
|
"base"
|
||||||
"interface.cli"
|
"interface.cli"
|
||||||
"security.fingerprint"
|
"security.fingerprint"
|
||||||
"security.secrets"
|
|
||||||
"workload.development"
|
"workload.development"
|
||||||
"workload.personal"
|
"workload.personal"
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -44,10 +44,11 @@ when removing it from any supported host would make that host invalid.
|
|||||||
| `security.tpm-storage` | NixOS with a host-defined LUKS device |
|
| `security.tpm-storage` | NixOS with a host-defined LUKS device |
|
||||||
|
|
||||||
Select independent concerns independently in `hosts/default.nix`. For example,
|
Select independent concerns independently in `hosts/default.nix`. For example,
|
||||||
a minimal NixOS laptop can combine `base`, `platform.thinkpad-x1`, and
|
a NixOS desktop can combine `interface.gnome` and `interface.niri` to provide
|
||||||
`interface.cli`, while a daily-use macOS development machine can add
|
both sessions while sharing `interface.linux-desktop`; niri supplies ly. A
|
||||||
`workload.development` and `workload.personal`. Hardware support does not
|
daily-use macOS development machine can add `workload.development` and
|
||||||
implicitly select an interface or workload.
|
`workload.personal`. Hardware support does not implicitly select an interface
|
||||||
|
or workload.
|
||||||
|
|
||||||
`security.tpm-storage` deliberately does not own a disk identifier. A host that
|
`security.tpm-storage` deliberately does not own a disk identifier. A host that
|
||||||
selects it must define `boot.initrd.luks.devices.cryptroot.device` in its
|
selects it must define `boot.initrd.luks.devices.cryptroot.device` in its
|
||||||
|
|||||||
Reference in New Issue
Block a user