aboutsummaryrefslogtreecommitdiffstats
path: root/openspec/specs
diff options
context:
space:
mode:
authorGravatar Tom van der Lee <tom@vanderlee.io>2026-09-18 15:12:24 +0200
committerGravatar Tom van der Lee <tom@vanderlee.io>2026-09-18 15:12:24 +0200
commit4937d0d6f29895b514dcf8cd20c73a1aec446144 (patch)
tree7ff388ba4cca94e95489d30452b25badd7e49aa9 /openspec/specs
parent72b640f5ae65755c1d932b7b8ee88d2367e4036f (diff)
downloaddesktop-flake-4937d0d6f29895b514dcf8cd20c73a1aec446144.tar.gz
desktop-flake-4937d0d6f29895b514dcf8cd20c73a1aec446144.tar.bz2
desktop-flake-4937d0d6f29895b514dcf8cd20c73a1aec446144.zip
Archive four completed changes, sync main specs
add-nix-flake-bootstrap, add-host-bootstrap-script, add-dotfiles-stow-bootstrap, and add-developer-environment all had every task complete (verified via a real nix flake check and a real NixOS host build). Archived in dependency order so the two changes sharing the nix-flake-bootstrap capability merged additively. Main specs now exist for the first time: nix-flake-bootstrap (10 requirements), dotfiles-management (4), developer-environment (4). add-gnome-desktop remains active (not yet implemented).
Diffstat (limited to 'openspec/specs')
-rw-r--r--openspec/specs/developer-environment/spec.md33
-rw-r--r--openspec/specs/dotfiles-management/spec.md45
-rw-r--r--openspec/specs/nix-flake-bootstrap/spec.md91
3 files changed, 169 insertions, 0 deletions
diff --git a/openspec/specs/developer-environment/spec.md b/openspec/specs/developer-environment/spec.md
new file mode 100644
index 0000000..e21936f
--- /dev/null
+++ b/openspec/specs/developer-environment/spec.md
@@ -0,0 +1,33 @@
1## Purpose
2
3Provisions the developer's most-used CLI/client tooling through the shared home-manager profile and enables common baseline system services, such as SSH access, on every NixOS host built from this flake.
4
5## Requirements
6
7### Requirement: Developer CLI tools are provisioned via the shared home profile
8The shared home-manager profile SHALL include the user's evidenced most-used CLI and client tools, available identically wherever that profile is activated (standalone or via a NixOS host).
9
10#### Scenario: Tooling available after activation
11- **WHEN** the shared home profile is activated on any supported platform
12- **THEN** the provisioned developer CLI tools are available on `PATH` without any additional manual installation step
13
14### Requirement: Container and cloud tools are client-only
15Container and cloud-related packages provisioned by this capability SHALL provide client/CLI functionality only; they SHALL NOT attempt to provide or manage the underlying runtime or service (e.g. a container engine or cloud account).
16
17#### Scenario: No runtime is installed or managed
18- **WHEN** a container or cloud CLI tool is provisioned by the shared home profile
19- **THEN** no corresponding daemon, virtual machine, or account configuration is installed or managed by this capability — the tool simply connects to whatever runtime or account is already configured on the system
20
21### Requirement: Shell and prompt configuration defers to the user's personal dotfiles
22Where the user's personal dotfiles repository already owns a piece of shell or prompt configuration, the shared home profile SHALL provide only the underlying package, not a competing managed configuration for that same file.
23
24#### Scenario: Prompt tool provisioned without managed config
25- **WHEN** the shared home profile provisions a prompt tool whose configuration is already owned by the user's dotfiles repository
26- **THEN** the profile installs the tool's package but does not generate or manage a competing configuration file for it
27
28### Requirement: SSH access is enabled by default on NixOS hosts
29Every NixOS host built from this flake's shared system module SHALL have an SSH server enabled, with password authentication and root login disabled, and SHALL permit inbound SSH traffic through its firewall.
30
31#### Scenario: SSH reachable with key-based auth only
32- **WHEN** a NixOS host is built from the shared system module
33- **THEN** the SSH service is enabled, password authentication and root login are disabled, and the firewall permits inbound connections on the SSH port
diff --git a/openspec/specs/dotfiles-management/spec.md b/openspec/specs/dotfiles-management/spec.md
new file mode 100644
index 0000000..7585cc9
--- /dev/null
+++ b/openspec/specs/dotfiles-management/spec.md
@@ -0,0 +1,45 @@
1## Purpose
2
3Automatically clones a personal dotfiles repository into the user's home directory and symlinks its contents into place, so a fresh machine ends up with the same personal configuration without a manual clone-and-stow step.
4
5## Requirements
6
7### Requirement: Dotfiles cloning is opt-in via a configured repo URL
8The dotfiles clone-and-stow behavior SHALL only run when a repository URL has been explicitly configured; leaving it unset SHALL leave the home directory untouched by this feature.
9
10#### Scenario: No repo URL configured
11- **WHEN** no dotfiles repository URL has been set
12- **THEN** no clone or symlinking occurs during activation
13
14#### Scenario: Repo URL configured
15- **WHEN** a dotfiles repository URL has been set
16- **THEN** activation clones and symlinks that repository as described by the other requirements in this capability
17
18### Requirement: Existing dotfiles checkout is never overwritten
19If the dotfiles repository has already been cloned locally, the system SHALL NOT re-clone or otherwise modify that existing checkout.
20
21#### Scenario: Checkout already present
22- **WHEN** activation runs and a local dotfiles checkout already exists
23- **THEN** no clone operation is performed against that location, and the existing checkout's contents and git history are left untouched
24
25#### Scenario: Checkout missing
26- **WHEN** activation runs and no local dotfiles checkout exists yet
27- **THEN** the configured repository is cloned, including any git submodules it declares
28
29### Requirement: Dotfiles packages are symlinked into the home directory
30Each top-level package directory in the cloned dotfiles repository SHALL be symlinked into the home directory following the same package-to-target-path convention as GNU Stow (a package directory's contents mirror their target location under the home directory).
31
32#### Scenario: A package is linked
33- **WHEN** the dotfiles repository contains a top-level directory whose contents mirror a location under the home directory
34- **THEN** that content becomes reachable via a symlink at the corresponding path under the home directory
35
36#### Scenario: Non-package entries are ignored
37- **WHEN** the dotfiles repository contains top-level entries that are not package directories (ordinary files, or hidden/dot-prefixed directories such as version-control metadata)
38- **THEN** those entries are not treated as packages and produce no symlinks
39
40### Requirement: A conflicting package does not block the others
41If symlinking one package would conflict with an existing file or symlink not owned by this process, the system SHALL skip that package and continue processing the remaining packages, rather than aborting entirely.
42
43#### Scenario: One package conflicts
44- **WHEN** one dotfiles package's target path is already occupied by an unrelated existing file
45- **THEN** that package is skipped with a visible warning, and every other package is still processed
diff --git a/openspec/specs/nix-flake-bootstrap/spec.md b/openspec/specs/nix-flake-bootstrap/spec.md
new file mode 100644
index 0000000..955dc56
--- /dev/null
+++ b/openspec/specs/nix-flake-bootstrap/spec.md
@@ -0,0 +1,91 @@
1## Purpose
2
3Provides a single Nix flake that provisions NixOS hosts from a copyable template and provisions a shared, cross-platform home-manager user profile that installs standalone on non-NixOS systems, keeping both paths built from the same per-user module.
4
5## Requirements
6
7### Requirement: Shared home profile across activation methods
8The system SHALL apply the same home-manager user profile (shell, git, editor, CLI tools) whether it is activated as part of a NixOS system build or activated standalone via `home-manager switch` on a non-NixOS system.
9
10#### Scenario: NixOS-activated profile matches standalone profile
11- **WHEN** a NixOS host built with the `mkNixos` helper activates its `home-manager.users.tom` configuration
12- **THEN** the resulting user environment includes the same programs and settings as the `homeConfigurations."tom@linux"` output built with the `mkHome` helper, because both consume the same `users/tom.nix` module
13
14### Requirement: Standalone installation requires no root privileges
15The system SHALL allow the shared home profile to be installed on any non-NixOS system without modifying system-level configuration or requiring root/sudo.
16
17#### Scenario: Standalone home-manager switch
18- **WHEN** a user with Nix installed runs `home-manager switch --flake .#tom@linux` on a non-NixOS Linux system
19- **THEN** only the user's home directory is modified and no root privileges are required
20
21### Requirement: NixOS host template is not a live flake output
22The system SHALL provide a NixOS host template directory that is not wired into any `nixosConfigurations` output, so it cannot be accidentally built or installed before being customized for real hardware.
23
24#### Scenario: Flake check does not build the template
25- **WHEN** `nix flake check` is run against the repository
26- **THEN** no `nixosConfigurations` entry evaluates or builds the `hosts/template` directory directly
27
28### Requirement: Flakes remain enabled on installed NixOS systems
29Every NixOS host built from this flake SHALL have the `nix-command` and `flakes` experimental features enabled by default, so subsequent `nixos-rebuild` invocations do not require extra flags.
30
31#### Scenario: Rebuilding after install needs no extra flags
32- **WHEN** a NixOS system installed from this flake is rebuilt with `nixos-rebuild switch --flake <path>#<host>`
33- **THEN** the command succeeds without passing `--extra-experimental-features`
34
35### Requirement: Per-host and per-user state versions are explicit
36Each NixOS host and each home-manager user configuration SHALL declare its own `system.stateVersion` / `home.stateVersion` value; the shared helper functions SHALL NOT supply a default value.
37
38#### Scenario: Missing stateVersion fails evaluation
39- **WHEN** a host or user configuration omits its `stateVersion` setting
40- **THEN** evaluating that configuration fails rather than silently falling back to a shared default
41
42### Requirement: Repository evaluates under pure evaluation
43The flake's `homeConfigurations` and check outputs defined in this change SHALL evaluate and build using only pure evaluation, without requiring the `--impure` flag.
44
45#### Scenario: Pure flake check succeeds
46- **WHEN** `nix flake check` is run without `--impure`
47- **THEN** it completes successfully for all outputs defined in this change
48
49### Requirement: Host directories are auto-discovered as flake outputs
50Any directory under `hosts/` other than `hosts/template` that contains a valid host definition SHALL automatically become a `nixosConfigurations.<name>` output, without requiring any edit to `flake.nix`.
51
52#### Scenario: New host directory becomes buildable without touching flake.nix
53- **WHEN** a new directory `hosts/<name>/` is created containing `configuration.nix`, `hardware-configuration.nix`, and a `system` file, and `flake.nix` itself is left unmodified
54- **THEN** `nixosConfigurations.<name>` evaluates successfully as part of the flake's outputs
55
56#### Scenario: Template remains excluded from discovery
57- **WHEN** the flake's outputs are evaluated
58- **THEN** `hosts/template` does not appear as a `nixosConfigurations` entry, regardless of its contents
59
60### Requirement: Host creation is scripted
61The system SHALL provide a script that scaffolds a new NixOS host directory from the template, given a hostname, a target root path, and a state version.
62
63#### Scenario: Scaffolding a new host
64- **WHEN** the host creation script is run with a hostname, a `--root` path, and a `--state-version`
65- **THEN** a `hosts/<hostname>/` directory is created containing a `configuration.nix` with the hostname and state version filled in, a `system` file, and a `hardware-configuration.nix` copied from the given root
66
67#### Scenario: Refusing to overwrite an existing host
68- **WHEN** the host creation script is run with a hostname that already has a `hosts/<hostname>/` directory, without an explicit override flag
69- **THEN** the script fails without modifying the existing directory
70
71### Requirement: Hardware configuration source is always explicit
72The host creation script SHALL require an explicit root path for locating `hardware-configuration.nix` and SHALL NOT read from the invoking system's own `/etc/nixos` unless that path is explicitly given as the root.
73
74#### Scenario: No root provided
75- **WHEN** the host creation script is run without a root path specified
76- **THEN** the script fails with an error rather than falling back to any default location
77
78#### Scenario: Live installer environment targets the mounted install, not the live system
79- **WHEN** the host creation script is run from a NixOS live/installer environment with `--root /mnt` pointing at a freshly mounted install target
80- **THEN** the resulting `hardware-configuration.nix` is copied from `/mnt/etc/nixos/hardware-configuration.nix`, and the live environment's own `/etc/nixos/hardware-configuration.nix` is never read
81
82#### Scenario: Hardware configuration cannot be found or generated
83- **WHEN** the host creation script is run with a `--root` path that has no `hardware-configuration.nix` and no `nixos-generate-config` command is available to create one
84- **THEN** the script fails with a clear error instead of proceeding with a missing or stub file
85
86### Requirement: Install target matches the created host name
87The host attribute produced for a newly scaffolded host SHALL exactly match the hostname given to the creation script, so the host can be installed or rebuilt via `<flake>#<hostname>`.
88
89#### Scenario: Installing a newly scaffolded host
90- **WHEN** a host is scaffolded with a given hostname
91- **THEN** `nixos-install --flake <flake-path>#<hostname>` and `nixos-rebuild switch --flake <flake-path>#<hostname>` both resolve to the configuration that was just scaffolded