The disk phase was the dominant source of incomplete installs. Six
concrete failure modes addressed in one pass:
1. Live-ISO USB excluded from the disk picker. select_disk previously
filtered loop|ram|zram|sr but not the device the installer booted
from; picking it would format the boot media mid-install. New
detect_live_iso_devices walks /, /iso, /run/initramfs/live,
/nix/.ro-store, /nix/store and resolves each backing device to its
parent disk via lsblk -no PKNAME. Override with
NOMARCHY_INSTALL_ALLOW_ISO_TARGET=1 for the developer case.
2. 10 GiB minimum-capacity preflight. Disko fails late and obscurely
on undersized media; surface it while the picker is still open.
3. prewipe_target_drive rewritten:
- Enumerates every active dm-crypt mapping via dmsetup ls and
closes those whose backing device is on the target drive. The
old version only knew about the hardcoded names "crypted" /
"crypted_main" so an aborted multi-disk run or a non-Nomarchy
install would leave a holder open and silently break the wipe.
- Drops `|| true` from wipefs / sgdisk / dd. After the LUKS and
swap teardown above, a real failure means something is still
holding the device — surface that instead of papering over it.
- udevadm settle bounded to 30s so a flapping USB can't hang.
- Post-wipe sanity check: refuse to hand the disk to disko if
anything is still mounted off it.
4. run_disko_with_retry wraps the disko call. On failure, shows the
last 30 lines of output via gum style and offers Retry /
View full log / Abort. set -e is suspended for the disko call so
the exit code can be inspected. The previous bare `disko --mode
disko` aborted the whole installer with output scrolled past.
5. Sed-templated disko-golden.nix + disko-btrfs-multi.nix pair
replaced by a single disko-config.nix Nix function of
{ mainDrive, extraDrives ? [] } called via --argstr / --arg.
Templating Nix via shell-escaped string substitution caused at
least one production bug (3aadc36 fixed embedded-newline
escaping); function arguments are the right shape and eliminate
the entire class of escaping concerns. Single-disk path is
`extraDrives = []`; multi-disk gets BTRFS `-d single -m raid1`
plus the additional /dev/mapper/* devices. Hosts that shipped
/etc/disko-golden.nix now ship /etc/disko-config.nix.
6. EXIT trap added so the tmpfs LUKS key file (/dev/shm/nomarchy-
luks.key) is removed even if the script aborts between key-write
and the explicit unset. Replaced redundant `shred -u` on tmpfs
with `rm -f` (already in RAM).
Verification: bash -n on install.sh, nix-instantiate parse + strict
eval on disko-config.nix in both single and multi shapes, full
nix flake check --no-build evaluating all three NixOS configurations
(default, nomarchy-installer, nomarchy-live) plus the installerVm.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
134 lines
8.2 KiB
Markdown
134 lines
8.2 KiB
Markdown
# Nomarchy - Architecture & Directory Structure
|
|
|
|
Nomarchy is a NixOS-based distribution characterized by its **Modular Merging Architecture**. This design strictly separates the "Upstream" core (the distro's logic) from the "Downstream" configuration (the user's personal setup), while allowing for dynamic, state-based theming and a highly modular desktop environment.
|
|
|
|
## Table of Contents
|
|
1. [Core Principles](#core-principles)
|
|
2. [Root Directory](#root-directory)
|
|
3. [The `core/` Directory (Foundational)](#the-core-directory-foundational)
|
|
4. [The `features/` Directory (Apps & Desktop)](#the-features-directory-apps--desktop)
|
|
5. [The `themes/` Directory (Dynamic Theming)](#the-themes-directory-dynamic-theming)
|
|
6. [The `lib/` Directory (Shared Library)](#the-lib-directory-shared-library)
|
|
7. [The `installer/` & `hosts/` Directories (Deployment)](#the-installer--hosts-directories-deployment)
|
|
|
|
---
|
|
|
|
## Core Principles
|
|
|
|
### Upstream vs. Downstream
|
|
- **Upstream:** The code in this repository is treated as the "Upstream" source. It provides the base OS configurations, dynamic theming engine, and modular application logic.
|
|
- **Downstream:** A user's installation (typically in `/etc/nixos/`) imports the Upstream flake. The user layers their own `system.nix` and `home.nix` on top, overriding or extending the Upstream settings using native NixOS `lib.mkDefault` and `lib.mkForce` patterns.
|
|
|
|
### Hybrid Declarative State
|
|
While the system is defined declaratively, Nomarchy uses a small, local state file (`~/.config/nomarchy/state.json`) to manage user preferences like the active theme, fonts, and feature toggles. This allows for instant UI feedback (via the `env-update` script) without requiring a full system rebuild for every cosmetic change.
|
|
|
|
---
|
|
|
|
## Root Directory
|
|
|
|
- **`flake.nix`**: The master entry point for the entire distribution.
|
|
- **Inputs:** Defines external dependencies like `nixpkgs`, `home-manager`, `disko`, `stylix`, and others.
|
|
- **Outputs:**
|
|
- `nixosModules.system`: Exports the foundational OS logic (`./core`).
|
|
- `nixosModules.home`: Exports the application and desktop logic (`./features`).
|
|
- `nixosConfigurations`: Defines pre-configured targets like `nomarchy-installer`, `nomarchy-live`, and a testing `vm`.
|
|
- **`flake.lock`**: Locks dependency versions for reproducible builds.
|
|
- **`GEMINI.md`**: Foundational mandates and architectural rules for the Nomarchy Agent.
|
|
- **`STRUCTURE.md`**: (This file) Detailed architectural documentation.
|
|
- **`README.md`**: Project overview, installation instructions, and basic usage.
|
|
- **`TODO.md`**: Roadmap and pending tasks.
|
|
|
|
---
|
|
|
|
## The `core/` Directory (Foundational)
|
|
|
|
The `core/` directory contains the foundational modules required for a functional system and user environment.
|
|
|
|
### `core/system/` (OS-Level)
|
|
- **`default.nix`**: The central entry point for the system module, importing all OS components.
|
|
- **`options.nix`**: Defines the `nomarchy.system` configuration options (e.g., DNS, Timezone, Feature toggles).
|
|
- **`state.nix`**: Loads and applies the system-level state (from `/etc/nixos/state.json`).
|
|
- **`audio.nix`**: Configures Pipewire, Wireplumber, and audio-related settings.
|
|
- **`bluetooth.nix`**: Bluetooth stack and management tools.
|
|
- **`browser.nix`**: System-level browser configurations and protocols.
|
|
- **`network.nix`**: NetworkManager configuration, DNS optimization, and Wi-Fi powersave settings.
|
|
- **`hardware.nix`**: Generic hardware support and hardware-specific script triggers.
|
|
- **`virtualization.nix`**: Libvirtd, Docker, and VM guest support.
|
|
- **`impermanence.nix`**: Root-on-RAM/Impermanence setup for ephemeral root filesystems.
|
|
- **`scripts/`**: A collection of low-level system scripts (e.g., `nomarchy-hw-match`, `nomarchy-setup-dns`).
|
|
|
|
### `core/home/` (User-Level)
|
|
- **`default.nix`**: The entry point for the base Home Manager module.
|
|
- **`options.nix`**: Defines the `nomarchy` user options (Toggles, Theme, Fonts, etc.).
|
|
- **`state.nix`**: Loads and applies user-level state (from `~/.config/nomarchy/state.json`).
|
|
- **`behavior.nix`**: Deploys non-visual configs (Keybindings, Input settings, Window rules) with `lib.mkDefault`.
|
|
- **`configs.nix`**: Manages static configuration files and directories in `~/.config/`.
|
|
- **`bash.nix`**: Shell environment, aliases, and specialized `env-update` hooks.
|
|
- **`security.nix`**: Polkit, keyring management, and GPG settings.
|
|
- **`config/`**: Contains the physical source files for the base user configuration (e.g., `starship.toml`, `hypr/` behavior configs).
|
|
|
|
---
|
|
|
|
## The `features/` Directory (Apps & Desktop)
|
|
|
|
The `features/` directory contains optional, modular components that define the user's interactive environment.
|
|
|
|
- **`default.nix`**: Aggregates and enables all sub-modules in `features/`.
|
|
- **`apps/`**: Individual application modules.
|
|
- Each app (e.g., `alacritty`, `btop`, `vscode`, `ghostty`) has its own directory containing a `default.nix` and a `config/` subdirectory.
|
|
- Apps are configured using the "Individual File Management" pattern to avoid directory symlink conflicts with the theme loader.
|
|
- **`desktop/`**: The graphical environment core.
|
|
- **`hyprland/`**: The primary tiling window manager configuration.
|
|
- **`waybar/`**: The status bar configuration, including dynamic CSS generation.
|
|
- **`idle.nix`** & **`nightlight.nix`**: Management of screen timeouts and blue light filters.
|
|
- **`scripts/`**: High-level utility scripts (e.g., `nomarchy-update`, `nomarchy-theme-set`).
|
|
- **`utils/`**: Helper scripts like `nomarchy-launch-or-focus-tui` or `nomarchy-restart-*`.
|
|
|
|
---
|
|
|
|
## The `themes/` Directory (Dynamic Theming)
|
|
|
|
The theming system is the "soul" of Nomarchy, providing dynamic, consistent aesthetics across all applications.
|
|
|
|
### `themes/engine/` (The Logic)
|
|
- **`loader.nix`**: The core theme loader. It reads the active theme from state and selectively deploys app-specific themed configs (e.g., `btop.theme`, `kitty.conf`) to `~/.config/`.
|
|
- **`stylix.nix`**: Integration with Stylix for base color palette and wallpaper management.
|
|
- **`switcher.nix`**: Provides the `nomarchy-theme-selector` and `nomarchy-wallpaper-selector` tools.
|
|
- **`plymouth.nix`** & **`sddm.nix`**: System-level theming for the boot screen and login manager.
|
|
|
|
### `themes/palettes/` (The Data)
|
|
- Contains subdirectories for every available theme (e.g., `summer-night`, `nord`, `tokyo-night`).
|
|
- Each theme directory includes:
|
|
- `colors.toml`: The Base16 color definition.
|
|
- `backgrounds/`: A collection of theme-aware wallpapers.
|
|
- `apps/`: Themed overrides for specific applications (e.g., `btop.theme`, `vscode.json`).
|
|
|
|
### `themes/templates/` (The Blueprints)
|
|
- Contains `.tpl` files (e.g., `waybar.css.tpl`, `hyprland.conf.tpl`) used to generate dynamic configuration files that incorporate the current theme's color palette.
|
|
|
|
---
|
|
|
|
## The `lib/` Directory (Shared Library)
|
|
|
|
The `lib/` directory provides centralized logic and data structures to maintain consistency.
|
|
|
|
- **`default.nix`**: A shared Nix library providing helper functions:
|
|
- `readState`: Safely reads JSON/text state files.
|
|
- `getPalette` / `getColorScheme`: Resolves theme names to color data.
|
|
- `resolveWallpaper`: Logic for choosing the correct background image.
|
|
- `getIconsTheme`: Resolves the appropriate icon set for a theme.
|
|
- **`state-schema.nix`**: Defines the single source of truth for the shape and default values of the Nomarchy state (both system and home).
|
|
|
|
---
|
|
|
|
## The `installer/` & `hosts/` Directories (Deployment)
|
|
|
|
### `installer/` (Bootstrap)
|
|
- **`install.sh`**: The interactive TTY-based installer. It handles disk partitioning, NixOS installation, and generating a clean "Downstream" flake for the user.
|
|
- **`disko-config.nix`**: The disko partition layout (BTRFS on top of LUKS2). A Nix function of `{ mainDrive, extraDrives ? [] }` — single-disk path is `extraDrives = []`; multi-disk adds BTRFS `-d single -m raid1` across the extras. Invoked by `install.sh` via `disko --argstr mainDrive … --arg extraDrives '[…]'`.
|
|
- **`disko-btrfs-luks.nix`**: A simpler reference layout for disk management (not used by the installer).
|
|
|
|
### `hosts/` (Targets)
|
|
- **`nomarchy-installer.nix`**: Configuration for the minimal, TTY-based installation ISO.
|
|
- **`nomarchy-live.nix`**: Configuration for the full graphical live environment, used for testing and GUI-based installation.
|