From 39c14b0c6420ea1e1604201a1b8891edf24bb280 Mon Sep 17 00:00:00 2001 From: Tom van der Lee Date: Thu, 17 Sep 2026 13:18:25 +0200 Subject: Propose GNOME desktop for NixOS hosts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Planning artifacts only (proposal, spec, design, tasks) — GDM+GNOME, NetworkManager, PipeWire, and CUPS+Avahi printing, applied unconditionally to every NixOS host via modules/nixos/common.nix. Not yet implemented. --- openspec/changes/add-gnome-desktop/.openspec.yaml | 2 ++ openspec/changes/add-gnome-desktop/design.md | 33 ++++++++++++++++++++++ openspec/changes/add-gnome-desktop/proposal.md | 26 +++++++++++++++++ .../add-gnome-desktop/specs/gnome-desktop/spec.md | 33 ++++++++++++++++++++++ openspec/changes/add-gnome-desktop/tasks.md | 23 +++++++++++++++ 5 files changed, 117 insertions(+) create mode 100644 openspec/changes/add-gnome-desktop/.openspec.yaml create mode 100644 openspec/changes/add-gnome-desktop/design.md create mode 100644 openspec/changes/add-gnome-desktop/proposal.md create mode 100644 openspec/changes/add-gnome-desktop/specs/gnome-desktop/spec.md create mode 100644 openspec/changes/add-gnome-desktop/tasks.md diff --git a/openspec/changes/add-gnome-desktop/.openspec.yaml b/openspec/changes/add-gnome-desktop/.openspec.yaml new file mode 100644 index 0000000..d28e909 --- /dev/null +++ b/openspec/changes/add-gnome-desktop/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-09-17 diff --git a/openspec/changes/add-gnome-desktop/design.md b/openspec/changes/add-gnome-desktop/design.md new file mode 100644 index 0000000..09e2481 --- /dev/null +++ b/openspec/changes/add-gnome-desktop/design.md @@ -0,0 +1,33 @@ +## Context + +See proposal.md - Why. This extends `modules/nixos/common.nix` from `add-nix-flake-bootstrap` (already carrying flakes/gc/locale/user/ssh/firewall settings applied to every NixOS host) with a desktop environment. Confirmed via direct Q&A: GNOME applies unconditionally to every NixOS host, not as an opt-in per-host module — every NixOS machine this flake provisions is meant to be a desktop. Nix is still not installed on this development machine, so nothing here can be locally evaluated. + +## Goals / Non-Goals + +**Goals:** +- A NixOS host built from this flake boots directly into a usable GNOME desktop: login, networking, audio, and printing all work without additional manual setup. +- Keep the addition to the already-established `modules/nixos/common.nix` pattern — no new module file needed, since this applies universally like the rest of that file's contents. + +**Non-Goals:** +- Per-user GNOME customization (dconf settings, GNOME Shell extensions via home-manager) — a system-level toggle only. +- Any change to the user's `~/dotfiles` `herbstluftwm`/`xorg` packages or the dotfiles-stow automation (`add-dotfiles-stow-bootstrap`) — unrelated; that repo's tiling-WM configuration is untouched. +- Fully removing Xorg/XWayland from the system. GDM defaults to a Wayland GNOME session already; XWayland (X11-app compatibility) and an optional Xorg fallback session remain present as standard NixOS/GNOME infrastructure — not something this change attempts to strip out. + +## Decisions + +**Added directly to `modules/nixos/common.nix`, not a separate opt-in module.** Per the user's explicit choice, GNOME applies to every NixOS host unconditionally — the same scope as everything else already in that file (flakes, ssh, firewall, gc policy). A separate `modules/nixos/desktop-gnome.nix` that hosts import individually was considered and rejected specifically because the user wants it universal, not per-host. + +**NetworkManager, PipeWire, and printing/Avahi are included as necessary companions, not scope creep.** A GNOME desktop without working networking, audio, or discoverable printers would only be partially functional: +- `networking.networkmanager.enable = true` — GNOME's Settings → Network and the top-bar network menu are built against NetworkManager; without it they don't work. +- `services.pipewire.enable` + `pulse.enable`, plus `security.rtkit.enable` — the current standard NixOS audio stack GNOME expects, including PulseAudio-compatible clients. +- `services.printing.enable` (CUPS) + `services.avahi` (`nssmdns4`, `openFirewall`) — printing was explicitly requested; Avahi is included alongside it so network/AirPrint-style printers are actually discoverable rather than requiring manual IP-based setup. `openFirewall = true` specifically because `add-developer-environment` already enabled `networking.firewall` with only port 22 allowed — without this, printer discovery (mDNS) traffic would be silently blocked by that firewall. + +**Module option paths used reflect NixOS's current (post-migration) namespace, flagged as an implementation-time risk.** NixOS has been moving `services.xserver.displayManager.*` / `services.xserver.desktopManager.*` into standalone `services.displayManager.*` / `services.desktopManager.*`. The design uses the newer paths as pinned to `nixos-unstable`, consistent with this repo's existing pattern of flagging package/option-naming uncertainty explicitly (`yq-go` vs `yq`, `terraform`'s licensing) rather than asserting confidently what can't be verified locally. If evaluation fails once Nix is available, the fallback is the older nested paths under `services.xserver.*`. + +**Wayland is the default GNOME session; this isn't a special decision requiring extra configuration.** Confirmed directly with the user: current NixOS GDM + GNOME already defaults to a Wayland session without any extra option needed — `services.xserver.enable = true` remains required only as the underlying toggle that XWayland and the display/desktop manager modules currently build on, not as a signal that the login session itself will be Xorg-based. + +## Risks / Trade-offs + +- **Cannot verify the exact module option paths or that GNOME actually boots successfully, since Nix isn't installed and no live NixOS host exists** → Mitigation: same as every prior change in this repo — careful manual construction and review now, `nix flake check` and an actual boot test deferred until Nix/a real host are available. This remains the real acceptance gate, not any individual task checkbox. +- **Every future NixOS host from this flake gets a full desktop stack, including any headless/server host** → Mitigation: this was an explicit, confirmed user choice (not a default I assumed) — if a headless host is ever needed, that's a follow-up change to reintroduce host-level opt-out, not a gap in this change. +- **Firewall now allows mDNS/printer-discovery traffic (`openFirewall = true` on Avahi) in addition to SSH** → Mitigation: scoped to what Avahi's own module opens (mDNS/printer discovery ports), not a blanket firewall disable; consistent with the existing "explicit, minimal firewall allowance" pattern from `add-developer-environment`. diff --git a/openspec/changes/add-gnome-desktop/proposal.md b/openspec/changes/add-gnome-desktop/proposal.md new file mode 100644 index 0000000..09a2e80 --- /dev/null +++ b/openspec/changes/add-gnome-desktop/proposal.md @@ -0,0 +1,26 @@ +## Why + +NixOS hosts built from this flake currently have no desktop environment at all — just a headless system. The user wants GNOME enabled as the default desktop on every NixOS system this flake provisions. + +## What Changes + +- `modules/nixos/common.nix` gains: `services.xserver.enable`, `services.displayManager.gdm.enable`, `services.desktopManager.gnome.enable` — GNOME with GDM as the login manager, applied unconditionally to every NixOS host (not an opt-in per-host module), confirmed via direct Q&A. +- `networking.networkmanager.enable = true` — required for GNOME's own network settings UI to function. +- `services.pipewire` (`enable`, `pulse.enable`) + `security.rtkit.enable` — the standard NixOS audio stack GNOME expects. +- `services.printing.enable = true` (CUPS) + `services.avahi` (`enable`, `nssmdns4`, `openFirewall`) — printing support with network/AirPrint printer discovery, added per explicit user request; `openFirewall` so the firewall enabled in the prior `add-developer-environment` change doesn't block discovery traffic. +- Update `README.md` to document that NixOS hosts now boot into GNOME by default, with these companions. + +## Capabilities + +### New Capabilities +- `gnome-desktop`: NixOS hosts built from this flake boot into a working GNOME desktop (login manager, networking, audio, printing) by default. + +### Modified Capabilities +(none — this doesn't change any requirement from `nix-flake-bootstrap`, `dotfiles-management`, or `developer-environment`; it's a new, additive system capability) + +## Impact + +- Affected code: `modules/nixos/common.nix`, `README.md`. +- Applies to every NixOS host built from this flake going forward. There is still no live NixOS host (only `hosts/template/`), so this only takes effect once a real host is scaffolded via `scripts/bootstrap-host.sh` — same situation as every prior NixOS-side change in this repo. +- Nix is still not installed on this development machine, so the exact module option paths (`services.displayManager.*`/`services.desktopManager.*`, which NixOS has been migrating out of the older `services.xserver.displayManager.*`/`services.xserver.desktopManager.*` nesting) can only be verified by manual review here, not by actually building — flagged explicitly as an implementation-time risk, not asserted with full confidence. +- Out of scope: per-user GNOME customization (dconf settings, Shell extensions), and any change to the user's existing `~/dotfiles` `herbstluftwm`/`xorg` packages, which this change doesn't touch. diff --git a/openspec/changes/add-gnome-desktop/specs/gnome-desktop/spec.md b/openspec/changes/add-gnome-desktop/specs/gnome-desktop/spec.md new file mode 100644 index 0000000..ee932c2 --- /dev/null +++ b/openspec/changes/add-gnome-desktop/specs/gnome-desktop/spec.md @@ -0,0 +1,33 @@ +## Purpose + +Provides a working GNOME desktop environment, including login, networking, audio, and printing, on every NixOS host built from this flake. + +## ADDED Requirements + +### Requirement: GNOME is the default desktop on every NixOS host +Every NixOS host built from this flake's shared system module SHALL boot into a GNOME desktop session via a graphical login manager, without requiring per-host opt-in. + +#### Scenario: Graphical login is available after boot +- **WHEN** a NixOS host built from this flake's shared system module finishes booting +- **THEN** a graphical login manager is presented, and selecting the default session starts a GNOME desktop + +### Requirement: Desktop networking is functional +The desktop environment SHALL provide working network configuration through its own UI, not require a separate manual networking setup step. + +#### Scenario: Network settings are usable from the desktop +- **WHEN** a user opens the desktop's network configuration UI +- **THEN** available networks can be viewed and configured without additional manual setup outside the desktop environment + +### Requirement: Desktop audio is functional +The desktop environment SHALL provide working audio output and input, including compatibility with applications expecting a PulseAudio-compatible audio server. + +#### Scenario: Audio applications can play sound +- **WHEN** an application on the desktop attempts to play or capture audio +- **THEN** the audio server is running and available to handle the request + +### Requirement: Printing is supported and printers are discoverable +The desktop environment SHALL support printing to CUPS-compatible printers, and SHALL be able to discover network printers automatically without requiring the firewall to be manually reconfigured. + +#### Scenario: A network printer is discoverable +- **WHEN** a network printer advertises itself on the local network +- **THEN** it can be discovered and configured for printing without the host's firewall blocking the discovery traffic diff --git a/openspec/changes/add-gnome-desktop/tasks.md b/openspec/changes/add-gnome-desktop/tasks.md new file mode 100644 index 0000000..e30615d --- /dev/null +++ b/openspec/changes/add-gnome-desktop/tasks.md @@ -0,0 +1,23 @@ +## 1. GNOME desktop and login manager + +- [ ] 1.1 In `modules/nixos/common.nix`, add `services.xserver.enable = true;` — verify by reading the file +- [ ] 1.2 Add `services.displayManager.gdm.enable = true;` and `services.desktopManager.gnome.enable = true;` — verify by reading the added block, and flag the option-path uncertainty from design.md (post-migration `services.displayManager.*`/`services.desktopManager.*` vs. older `services.xserver.displayManager.*`/`services.xserver.desktopManager.*`) as a known risk to re-check once `nix flake check` can run + +## 2. Networking and audio companions + +- [ ] 2.1 Add `networking.networkmanager.enable = true;` — verify by reading the added line +- [ ] 2.2 Add `services.pipewire = { enable = true; pulse.enable = true; };` and `security.rtkit.enable = true;` — verify by reading the added block + +## 3. Printing + +- [ ] 3.1 Add `services.printing.enable = true;` — verify by reading the added line +- [ ] 3.2 Add `services.avahi = { enable = true; nssmdns4 = true; openFirewall = true; };` — verify by reading the added block, and confirm `openFirewall = true` is present so mDNS/printer discovery isn't blocked by the firewall enabled in `add-developer-environment` + +## 4. Documentation + +- [ ] 4.1 Update `README.md` to document that NixOS hosts from this flake now boot into GNOME (GDM login) by default, with NetworkManager, PipeWire, and CUPS+Avahi printing enabled as necessary companions — verify by reading the updated section for consistency with the actual module changes + +## 5. Validation + +- [ ] 5.1 Run `nix flake check` and confirm `modules/nixos/common.nix` still evaluates without error with the new services added, resolving the option-path question from task 1.2 (blocked — Nix is not installed on this machine, and there's still no live NixOS host to boot; run this once Nix/a real host are available — this is the real acceptance gate, not the individual checkboxes above) +- [ ] 5.2 Manually trace through each spec scenario in `specs/gnome-desktop/spec.md` against the implemented module, confirming each is satisfied by inspection given #5.1 cannot run locally -- cgit v1.3