From 4937d0d6f29895b514dcf8cd20c73a1aec446144 Mon Sep 17 00:00:00 2001 From: Tom van der Lee Date: Fri, 18 Sep 2026 15:12:24 +0200 Subject: 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). --- openspec/specs/developer-environment/spec.md | 33 ++++++++++ openspec/specs/dotfiles-management/spec.md | 45 ++++++++++++++ openspec/specs/nix-flake-bootstrap/spec.md | 91 ++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 openspec/specs/developer-environment/spec.md create mode 100644 openspec/specs/dotfiles-management/spec.md create mode 100644 openspec/specs/nix-flake-bootstrap/spec.md (limited to 'openspec/specs') 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 @@ +## Purpose + +Provisions 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. + +## Requirements + +### Requirement: Developer CLI tools are provisioned via the shared home profile +The 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). + +#### Scenario: Tooling available after activation +- **WHEN** the shared home profile is activated on any supported platform +- **THEN** the provisioned developer CLI tools are available on `PATH` without any additional manual installation step + +### Requirement: Container and cloud tools are client-only +Container 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). + +#### Scenario: No runtime is installed or managed +- **WHEN** a container or cloud CLI tool is provisioned by the shared home profile +- **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 + +### Requirement: Shell and prompt configuration defers to the user's personal dotfiles +Where 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. + +#### Scenario: Prompt tool provisioned without managed config +- **WHEN** the shared home profile provisions a prompt tool whose configuration is already owned by the user's dotfiles repository +- **THEN** the profile installs the tool's package but does not generate or manage a competing configuration file for it + +### Requirement: SSH access is enabled by default on NixOS hosts +Every 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. + +#### Scenario: SSH reachable with key-based auth only +- **WHEN** a NixOS host is built from the shared system module +- **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 @@ +## Purpose + +Automatically 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. + +## Requirements + +### Requirement: Dotfiles cloning is opt-in via a configured repo URL +The 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. + +#### Scenario: No repo URL configured +- **WHEN** no dotfiles repository URL has been set +- **THEN** no clone or symlinking occurs during activation + +#### Scenario: Repo URL configured +- **WHEN** a dotfiles repository URL has been set +- **THEN** activation clones and symlinks that repository as described by the other requirements in this capability + +### Requirement: Existing dotfiles checkout is never overwritten +If the dotfiles repository has already been cloned locally, the system SHALL NOT re-clone or otherwise modify that existing checkout. + +#### Scenario: Checkout already present +- **WHEN** activation runs and a local dotfiles checkout already exists +- **THEN** no clone operation is performed against that location, and the existing checkout's contents and git history are left untouched + +#### Scenario: Checkout missing +- **WHEN** activation runs and no local dotfiles checkout exists yet +- **THEN** the configured repository is cloned, including any git submodules it declares + +### Requirement: Dotfiles packages are symlinked into the home directory +Each 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). + +#### Scenario: A package is linked +- **WHEN** the dotfiles repository contains a top-level directory whose contents mirror a location under the home directory +- **THEN** that content becomes reachable via a symlink at the corresponding path under the home directory + +#### Scenario: Non-package entries are ignored +- **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) +- **THEN** those entries are not treated as packages and produce no symlinks + +### Requirement: A conflicting package does not block the others +If 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. + +#### Scenario: One package conflicts +- **WHEN** one dotfiles package's target path is already occupied by an unrelated existing file +- **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 @@ +## Purpose + +Provides 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. + +## Requirements + +### Requirement: Shared home profile across activation methods +The 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. + +#### Scenario: NixOS-activated profile matches standalone profile +- **WHEN** a NixOS host built with the `mkNixos` helper activates its `home-manager.users.tom` configuration +- **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 + +### Requirement: Standalone installation requires no root privileges +The system SHALL allow the shared home profile to be installed on any non-NixOS system without modifying system-level configuration or requiring root/sudo. + +#### Scenario: Standalone home-manager switch +- **WHEN** a user with Nix installed runs `home-manager switch --flake .#tom@linux` on a non-NixOS Linux system +- **THEN** only the user's home directory is modified and no root privileges are required + +### Requirement: NixOS host template is not a live flake output +The 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. + +#### Scenario: Flake check does not build the template +- **WHEN** `nix flake check` is run against the repository +- **THEN** no `nixosConfigurations` entry evaluates or builds the `hosts/template` directory directly + +### Requirement: Flakes remain enabled on installed NixOS systems +Every 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. + +#### Scenario: Rebuilding after install needs no extra flags +- **WHEN** a NixOS system installed from this flake is rebuilt with `nixos-rebuild switch --flake #` +- **THEN** the command succeeds without passing `--extra-experimental-features` + +### Requirement: Per-host and per-user state versions are explicit +Each 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. + +#### Scenario: Missing stateVersion fails evaluation +- **WHEN** a host or user configuration omits its `stateVersion` setting +- **THEN** evaluating that configuration fails rather than silently falling back to a shared default + +### Requirement: Repository evaluates under pure evaluation +The flake's `homeConfigurations` and check outputs defined in this change SHALL evaluate and build using only pure evaluation, without requiring the `--impure` flag. + +#### Scenario: Pure flake check succeeds +- **WHEN** `nix flake check` is run without `--impure` +- **THEN** it completes successfully for all outputs defined in this change + +### Requirement: Host directories are auto-discovered as flake outputs +Any directory under `hosts/` other than `hosts/template` that contains a valid host definition SHALL automatically become a `nixosConfigurations.` output, without requiring any edit to `flake.nix`. + +#### Scenario: New host directory becomes buildable without touching flake.nix +- **WHEN** a new directory `hosts//` is created containing `configuration.nix`, `hardware-configuration.nix`, and a `system` file, and `flake.nix` itself is left unmodified +- **THEN** `nixosConfigurations.` evaluates successfully as part of the flake's outputs + +#### Scenario: Template remains excluded from discovery +- **WHEN** the flake's outputs are evaluated +- **THEN** `hosts/template` does not appear as a `nixosConfigurations` entry, regardless of its contents + +### Requirement: Host creation is scripted +The 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. + +#### Scenario: Scaffolding a new host +- **WHEN** the host creation script is run with a hostname, a `--root` path, and a `--state-version` +- **THEN** a `hosts//` 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 + +#### Scenario: Refusing to overwrite an existing host +- **WHEN** the host creation script is run with a hostname that already has a `hosts//` directory, without an explicit override flag +- **THEN** the script fails without modifying the existing directory + +### Requirement: Hardware configuration source is always explicit +The 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. + +#### Scenario: No root provided +- **WHEN** the host creation script is run without a root path specified +- **THEN** the script fails with an error rather than falling back to any default location + +#### Scenario: Live installer environment targets the mounted install, not the live system +- **WHEN** the host creation script is run from a NixOS live/installer environment with `--root /mnt` pointing at a freshly mounted install target +- **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 + +#### Scenario: Hardware configuration cannot be found or generated +- **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 +- **THEN** the script fails with a clear error instead of proceeding with a missing or stub file + +### Requirement: Install target matches the created host name +The 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 `#`. + +#### Scenario: Installing a newly scaffolded host +- **WHEN** a host is scaffolded with a given hostname +- **THEN** `nixos-install --flake #` and `nixos-rebuild switch --flake #` both resolve to the configuration that was just scaffolded -- cgit v1.3