Files
Nomarchy/docs/STRUCTURE.md
Bernardo Magri f318585dc4 fix(installer): harden disk selection and partitioning phase
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>
2026-04-30 19:42:00 +01:00

8.2 KiB

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
  2. Root Directory
  3. The core/ Directory (Foundational)
  4. The features/ Directory (Apps & Desktop)
  5. The themes/ Directory (Dynamic Theming)
  6. The lib/ Directory (Shared Library)
  7. 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.