diff options
| author | 2026-09-18 15:12:24 +0200 | |
|---|---|---|
| committer | 2026-09-18 15:12:24 +0200 | |
| commit | 4937d0d6f29895b514dcf8cd20c73a1aec446144 (patch) | |
| tree | 7ff388ba4cca94e95489d30452b25badd7e49aa9 /openspec/changes/archive/2026-09-18-add-developer-environment | |
| parent | 72b640f5ae65755c1d932b7b8ee88d2367e4036f (diff) | |
| download | desktop-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/changes/archive/2026-09-18-add-developer-environment')
5 files changed, 128 insertions, 0 deletions
diff --git a/openspec/changes/archive/2026-09-18-add-developer-environment/.openspec.yaml b/openspec/changes/archive/2026-09-18-add-developer-environment/.openspec.yaml new file mode 100644 index 0000000..d28e909 --- /dev/null +++ b/openspec/changes/archive/2026-09-18-add-developer-environment/.openspec.yaml | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | schema: spec-driven | ||
| 2 | created: 2026-09-17 | ||
diff --git a/openspec/changes/archive/2026-09-18-add-developer-environment/design.md b/openspec/changes/archive/2026-09-18-add-developer-environment/design.md new file mode 100644 index 0000000..33fdfb9 --- /dev/null +++ b/openspec/changes/archive/2026-09-18-add-developer-environment/design.md | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | ## Context | ||
| 2 | |||
| 3 | See proposal.md - Why. This builds on the shared `modules/home` and `modules/nixos/common.nix` layers from `add-nix-flake-bootstrap`, and follows the file-ownership precedent set by `add-dotfiles-stow-bootstrap` (home-manager's `programs.git` was removed there because `~/dotfiles/git/.gitconfig` already owns `~/.gitconfig`; the same conflict now applies to `~/.bashrc` and the prompt config). Package selection is grounded in a direct exploration of this machine (Homebrew, PATH, shell configs) and `~/dotfiles`, followed by a Q&A with the user. Nix is still not installed on this machine, so nothing here can be locally evaluated or run. | ||
| 4 | |||
| 5 | ## Goals / Non-Goals | ||
| 6 | |||
| 7 | **Goals:** | ||
| 8 | - Bring the flake's provisioned packages in line with actually-evidenced usage on the user's machine, not a generic/assumed list. | ||
| 9 | - Keep file-ownership conflicts resolved the same way as the established precedent: dotfiles wins for any file it already manages. | ||
| 10 | - Enable a sensible, secure-by-default SSH baseline for any future NixOS host, without requiring a live host to exist yet. | ||
| 11 | |||
| 12 | **Non-Goals:** | ||
| 13 | - Managing per-project language runtime versions (node/python/rust) via Nix — pyenv/nvm/rustup already own that; per-project pinned toolchains belong in project-level flake devShells later, a separate future change. | ||
| 14 | - Replacing Mason's role in managing neovim's LSP servers/formatters/debuggers. | ||
| 15 | - Making Docker Desktop/OrbStack or any cloud account itself Nix-managed — only client/CLI tools are in scope. | ||
| 16 | - Fixing the plaintext `HOMEBREW_GITHUB_API_TOKEN` found in `~/.bash_profile` during exploration — flagged to the user, not addressed here since it's outside any file this repo manages. | ||
| 17 | |||
| 18 | ## Decisions | ||
| 19 | |||
| 20 | **`programs.bash` is not enabled, even though bash is now the primary shell.** Enabling it would make home-manager generate and own `~/.bashrc`, directly conflicting with `~/dotfiles/bash/.bashrc` (a real Stow package containing the user's actual PATH/alias/pyenv/nvm/rustup setup). Consistent with the `~/.gitconfig` precedent, the dotfiles-owned file wins. Consequence: `programs.starship`/`programs.direnv`'s automatic shell-hook injection has nowhere to write into for bash even if those modules were kept enabled — moot here since both are removed outright per user instruction, but worth recording as the underlying reason those integrations wouldn't have worked cleanly anyway. | ||
| 21 | |||
| 22 | **`programs.starship` and `programs.direnv` are removed outright, not left as-is.** This was an explicit correction from the user during plan review (the first draft kept them). `liquidprompt` replaces starship as the package Nix provisions, with its actual configuration and shell activation fully owned by `~/dotfiles/liquidprompt/` — matching the same "package via Nix, config via dotfiles" split already established for git. direnv was reconsidered once (the user asked why it mattered — per-project flake devShell auto-activation) and still explicitly removed after that explanation, so this is a confirmed, informed decision, not an overlooked default. | ||
| 23 | |||
| 24 | **`yq-go` over `yq`.** nixpkgs carries both the older Python-based `yq` (a thin `jq` wrapper for YAML) and `yq-go` (mikefarah's Go-based standalone tool) under different attribute names. The Go version is what's conventionally meant by "yq" in modern Kubernetes/Terraform-adjacent workflows, which matches this user's evidenced tooling (kubectl, terraform). Picking the wrong one would be a functionally different CLI with different syntax, not just a version difference. | ||
| 25 | |||
| 26 | **`terraform`'s nixpkgs availability is flagged as a risk, not silently assumed.** HashiCorp's BSL license change means recent nixpkgs may require `nixpkgs.config.allowUnfree = true` for `terraform`, or may have removed it in favor of `opentofu`. This can't be verified without Nix installed locally; the task list treats it as an implementation-time check rather than asserting it will just work. | ||
| 27 | |||
| 28 | **`services.openssh.settings.PasswordAuthentication = false` and `PermitRootLogin = "no"`.** The user already has SSH keys configured (4 hosts in `~/.ssh/config`), so key-only auth costs nothing and is the standard secure default. `networking.firewall.allowedTCPPorts = [ 22 ]` is the only firewall change that actually matters (NixOS's firewall is already enabled by default) — kept alongside an explicit `enable = true` purely as visible documentation of intent. | ||
| 29 | |||
| 30 | **A new `modules/home/dev-tools.nix` file, separate from the existing `cli-tools.nix`.** Keeps this change's additions traceable to this specific capability, matching the repo's established one-concern-per-file module convention rather than growing the original baseline file indefinitely. | ||
| 31 | |||
| 32 | ## Risks / Trade-offs | ||
| 33 | |||
| 34 | - **No Nix-managed per-project environment activation after removing direnv** → Mitigation: this was a deliberate, explained trade-off the user confirmed twice; pyenv/nvm/rustup remain fully functional as the existing mechanism. | ||
| 35 | - **Prompt/shell integration (liquidprompt) depends entirely on the external `~/dotfiles` repo being present and correctly stowed** → Mitigation: this is exactly what the `add-dotfiles-stow-bootstrap` change already automates; no new risk introduced here, just a new consumer of that existing mechanism. | ||
| 36 | - **`terraform` may fail to evaluate without an unfree-package allowance** → Mitigation: flagged explicitly as a task-level check; if it fails, the fallback is either adding `nixpkgs.config.allowUnfree = true` or substituting `opentofu`, decided when Nix is actually available to test. | ||
| 37 | - **No local way to verify any of this evaluates or builds, since Nix isn't installed here** → Mitigation: same as every prior change — careful manual construction and package-name review now; `nix flake check` deferred until Nix is available. This remains the real acceptance gate across all changes in this repo, not any individual task checkbox. | ||
diff --git a/openspec/changes/archive/2026-09-18-add-developer-environment/proposal.md b/openspec/changes/archive/2026-09-18-add-developer-environment/proposal.md new file mode 100644 index 0000000..24b34a5 --- /dev/null +++ b/openspec/changes/archive/2026-09-18-add-developer-environment/proposal.md | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | ## Why | ||
| 2 | |||
| 3 | The flake currently ships a minimal, generic package set. The user is a software developer whose actual machine already relies on a specific set of CLI tools (git-adjacent, container/cloud tooling) and a specific shell/prompt setup that the flake doesn't reflect yet, and has no common system services (like sshd) enabled for future NixOS hosts. This change brings the flake's declared packages/services in line with real, evidenced usage. | ||
| 4 | |||
| 5 | ## What Changes | ||
| 6 | |||
| 7 | - Add `modules/home/dev-tools.nix`: `gh`, `tmux`, `htop`, `yq-go`, `tree-sitter`, `docker`, `docker-compose`, `kubectl`, `awscli2`, `terraform` — user-level CLI/client tools, added to `modules/home/default.nix`'s imports. Container/cloud entries are client-only; the actual runtime (OrbStack/Docker Desktop) and cloud infrastructure stay outside Nix's control. | ||
| 8 | - **BREAKING**: `modules/home/shell.nix` drops `programs.zsh` (bash is now the primary managed shell), drops `programs.starship` (replaced by `liquidprompt`, already Stow-managed via the user's dotfiles), and drops `programs.direnv`/`nix-direnv` entirely — a real removal of a feature present since the first change in this repo, per explicit user instruction rather than an addition being skipped. | ||
| 9 | - `modules/home/shell.nix` adds `pkgs.liquidprompt` as a package (its config/activation stays fully owned by the user's dotfiles repo, matching the precedent already set for git and bash). | ||
| 10 | - `modules/nixos/common.nix`: `users.users.tom.shell` changes from `pkgs.zsh` to `pkgs.bash`; the `programs.zsh.enable = true` line is removed; `services.openssh` is enabled with `PasswordAuthentication = false` and `PermitRootLogin = "no"`; `networking.firewall` is set with port 22 explicitly allowed. | ||
| 11 | - Update `README.md` to document the new packages, the CLI-only caveat for docker/kubectl/awscli/terraform, the bash-primary shell switch, and that liquidprompt's config is dotfiles-owned. | ||
| 12 | |||
| 13 | ## Capabilities | ||
| 14 | |||
| 15 | ### New Capabilities | ||
| 16 | - `developer-environment`: the flake provisions a developer's most-used CLI/client tooling via home-manager and enables common baseline system services (starting with sshd + a firewall allowance) via the shared NixOS module. | ||
| 17 | |||
| 18 | ### Modified Capabilities | ||
| 19 | (none — this doesn't change any requirement from `nix-flake-bootstrap` or `dotfiles-management`; the shell/prompt/direnv changes are implementation details of the new capability's package/service set, not a change to what those other capabilities promise) | ||
| 20 | |||
| 21 | ## Impact | ||
| 22 | |||
| 23 | - Affected code: `modules/home/dev-tools.nix` (new), `modules/home/shell.nix`, `modules/home/default.nix`, `modules/nixos/common.nix`, `README.md`. | ||
| 24 | - No live NixOS host exists yet, so the `services.openssh`/`networking.firewall` additions only take effect once a real host is scaffolded — same situation as every prior NixOS-side change in this repo. | ||
| 25 | - Nix is still not installed on this development machine, so package-name correctness (`yq-go`, `awscli2`, `tree-sitter`, `terraform`'s licensing/availability) can only be verified by manual review here, not by actually building — same constraint as every prior change. | ||
| 26 | - User-visible: anyone relying on the previously-configured `zsh`/`starship`/`direnv` home-manager setup loses it entirely once this change lands; bash + liquidprompt (dotfiles-owned) replaces it, and there is no Nix-managed per-project environment activation mechanism (direnv) after this change. | ||
| 27 | - Not in scope: a plaintext `HOMEBREW_GITHUB_API_TOKEN` was found in `~/.bash_profile` (not Nix-managed) during exploration — flagged to the user separately, not addressed by this change. | ||
diff --git a/openspec/changes/archive/2026-09-18-add-developer-environment/specs/developer-environment/spec.md b/openspec/changes/archive/2026-09-18-add-developer-environment/specs/developer-environment/spec.md new file mode 100644 index 0000000..aff76b5 --- /dev/null +++ b/openspec/changes/archive/2026-09-18-add-developer-environment/specs/developer-environment/spec.md | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | ## Purpose | ||
| 2 | |||
| 3 | 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. | ||
| 4 | |||
| 5 | ## ADDED Requirements | ||
| 6 | |||
| 7 | ### Requirement: Developer CLI tools are provisioned via the shared home profile | ||
| 8 | 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). | ||
| 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 | ||
| 15 | 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). | ||
| 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 | ||
| 22 | 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. | ||
| 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 | ||
| 29 | 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. | ||
| 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/changes/archive/2026-09-18-add-developer-environment/tasks.md b/openspec/changes/archive/2026-09-18-add-developer-environment/tasks.md new file mode 100644 index 0000000..21fcd86 --- /dev/null +++ b/openspec/changes/archive/2026-09-18-add-developer-environment/tasks.md | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | ## 1. Developer CLI tools | ||
| 2 | |||
| 3 | - [x] 1.1 Create `modules/home/dev-tools.nix` with `home.packages = with pkgs; [ gh tmux htop yq-go tree-sitter docker docker-compose kubectl awscli2 ];` — verify by reading the package list against design.md's decisions (especially `yq-go` not `yq`) (note: `terraform` omitted per task 1.3's outcome, see below) | ||
| 4 | - [x] 1.2 Add `./dev-tools.nix` to `modules/home/default.nix`'s imports — verify by grep confirming the import is present | ||
| 5 | - [x] 1.3 Check whether `terraform` evaluates cleanly under this flake's `nixpkgs` pin, or requires `nixpkgs.config.allowUnfree = true` / substitution with `opentofu` — verify by consulting nixpkgs' current licensing status for `terraform` (blocked on local verification since Nix isn't installed; record the finding or the substitution decision in this task's notes once checked) (resolved via web research, not local build: confirmed via [NixOS/nixpkgs#253470](https://github.com/NixOS/nixpkgs/issues/253470) that terraform ≥1.6.0 is unfree/BSL-licensed and requires `nixpkgs.config.allowUnfree = true`. Presented this finding plus three options — allow unfree flake-wide, substitute opentofu, or drop terraform — to the user; they chose to drop it. `terraform` is not in the final package list.) | ||
| 6 | |||
| 7 | ## 2. Shell and prompt | ||
| 8 | |||
| 9 | - [x] 2.1 Rewrite `modules/home/shell.nix` to remove `programs.zsh`, `programs.starship`, and `programs.direnv` entirely, replacing its contents with `home.packages = [ pkgs.liquidprompt ];` — verify by reading the file and confirming none of the three removed program blocks remain | ||
| 10 | - [x] 2.2 Confirm no other file in `modules/home/` re-enables `programs.zsh`, `programs.starship`, or `programs.direnv` — verify by grepping `modules/home/` for each (grep across all of `modules/home/` found zero matches for any of the three) | ||
| 11 | |||
| 12 | ## 3. NixOS common module: shell, sshd, firewall | ||
| 13 | |||
| 14 | - [x] 3.1 In `modules/nixos/common.nix`, change `users.users.tom.shell` from `pkgs.zsh` to `pkgs.bash`, and remove the `programs.zsh.enable = true;` line — verify by reading the file | ||
| 15 | - [x] 3.2 Add `services.openssh = { enable = true; settings = { PasswordAuthentication = false; PermitRootLogin = "no"; }; };` — verify by reading the added block (**correction, 2026-09-18: this locked the user out of the first real host, `floep`. Key-only auth was enabled with no `authorizedKeys` ever provisioned for `tom` — the "you already have SSH keys" justification in design.md referred to keys existing on client machines, not that this host trusted any of them. Fixed in a later commit by adding `users.users.tom.openssh.authorizedKeys.keys` to `modules/nixos/common.nix`, sourced from `https://github.com/tomvanderlee.keys`. Recovery required local UTM console access since SSH itself was the thing that was broken.**) | ||
| 16 | - [x] 3.3 Add `networking.firewall = { enable = true; allowedTCPPorts = [ 22 ]; };` — verify by reading the added block | ||
| 17 | |||
| 18 | ## 4. Documentation | ||
| 19 | |||
| 20 | - [x] 4.1 Update `README.md` to document the new `modules/home/dev-tools.nix` packages, the "CLI-only, not the runtime" caveat for docker/kubectl/awscli/terraform, the bash-primary shell switch (including the sshd/firewall additions for future NixOS hosts), and that liquidprompt's configuration is entirely dotfiles-owned — verify by reading the updated sections for consistency with the actual module changes (also updated the layout bullet for `modules/nixos/common.nix` and the dotfiles-precedent note to mention bash/.bashrc alongside git/.gitconfig, and added an explicit note on why terraform was dropped) | ||
| 21 | |||
| 22 | ## 5. Validation | ||
| 23 | |||
| 24 | - [x] 5.1 Run `nix flake check` and confirm the updated `modules/home` and `modules/nixos/common.nix` evaluate without error, including resolving the `terraform` question from task 1.3 (blocked — Nix is not installed on this machine; run this once Nix is available, e.g. via a real install or CI — this is the real acceptance gate, not the individual checkboxes above) (run by the user on a Linux machine with Nix, 2026-09-18: passed with no errors, confirming `yq-go`, `awscli2`, `tree-sitter`, `docker`, `docker-compose`, `kubectl`, `gh`, `tmux`, `htop`, and `liquidprompt` all resolve correctly in nixpkgs) | ||
| 25 | - [x] 5.2 Manually trace through each spec scenario in `specs/developer-environment/spec.md` against the implemented modules, confirming each is satisfied by inspection given #5.1 cannot run locally (all 4 scenarios traced and satisfied: `dev-tools.nix` flows through the same shared `modules/home` path consumed by both `mkNixos` and `mkHome`; grep confirms no `virtualisation`/daemon config was added anywhere; `shell.nix` is package-only for liquidprompt with no competing managed config; `services.openssh` + `networking.firewall` in `common.nix` match the SSH scenario exactly) | ||
| 26 | |||
| 27 | --- | ||
| 28 | |||
| 29 | **Verification note:** as with every prior change, Nix is not installed on this machine, so task 5.1 (`nix flake check`) could not be executed and remains the outstanding acceptance gate — now shared across four changes in this repo. Package-name correctness (`yq-go`, `awscli2`, `tree-sitter`, `docker`, `docker-compose`, `kubectl`, `gh`, `tmux`, `htop`, `liquidprompt`) was reviewed manually but not verified against a real nixpkgs evaluation. | ||
