# `dev_env` Role — Implementation Plan (iteration 1) > Built in the same 2026-06-11 session as the `ubongo` bring-up. A developer > interactive environment (zsh/tmux/nvim) for **workstation-class** hosts. **Goal:** Give `ubongo` (and future `mamba`) a clean interactive shell/editor setup, reproducibly, as a boma-native Ansible role — so the operator (and the `claude` agent user) can work comfortably over SSH. ## Decisions - **Separate role, never part of `base`.** `base` is the security/infra baseline for *every* host; a dev environment is only for human workstation-class hosts. Servers and service VMs must never get it. - **Stow, not templating.** Dotfiles are **real files** under `files/dotfiles/{zsh,tmux,nvim}/` (re-derived `$HOME`-relative from `fisi`'s live configs), symlinked into `~` with GNU stow. No Jinja-templated dotfiles (they rot; you'd edit templates not configs). - **Users:** `dev_env__users` (default `[]`). Set to `[sjat, claude]` for `ubongo` in `group_vars/control`. - **V4 (ADR-013):** configs/package-lists/install-mechanism *consulted* from V4 and **re-derived on boma's terms** — not its structure. V4 identifiers stripped from the dotfiles. ## Re-derivations vs V4 - **No Nerd Font** on `ubongo` — it's headless; fonts are a client-side concern. - **No system-wide LSP suite** — the operator's nvim uses **mason**, which self-installs LSPs/formatters inside nvim (needs only nvim + git + a C compiler + node). - **Pinned versions** (ADR-014): nvim `v0.12.2`, oh-my-posh `29.0.1` (V4 tracks "latest"). - **Plugins self-bootstrap**: lazy.nvim installs nvim plugins on first launch; the role only lays down config + pre-clones omz/tmux plugins. ## Tasks (role: `roles/dev_env/`) - `tasks/main.yml` — apt packages (`packages` tag) → include `neovim.yml`, `oh_my_posh.yml` → loop `per_user.yml` over `dev_env__users`. - `tasks/neovim.yml` — install pinned nvim release to `/opt`, symlink, version sentinel. - `tasks/oh_my_posh.yml` — install pinned oh-my-posh binary + deploy `zen.toml` to `/etc`. - `tasks/per_user.yml` — set login shell to zsh (`users`); clone oh-my-zsh + custom plugins + tmux/TPM plugins; copy dotfiles to `~/.dotfiles`; `stow` into `~` (`config`). - `defaults/main.yml`, `meta/main.yml`, `README.md`, `requirements.yml`. - `molecule/default/{converge,verify}.yml` — create a `tester` user, apply, assert packages + nvim/omp/zen present + shell=zsh + dotfiles stowed (symlinks). - `playbooks/workstation.yml` — apply `dev_env` to the `control` group (ubongo). - `inventories/production/group_vars/control/vars.yml` — `dev_env__users: [sjat, claude]`. ## Verify / apply - `make lint`; `make test ROLE=dev_env` (Molecule, Debian 13) must pass. - Apply to `ubongo`: `make check`/`deploy PLAYBOOK=workstation` from a host that can SSH to `ubongo` as `sjat` with `--ask-become-pass` (the Ansible-manages-ubongo connection isn't bootstrapped yet — handle at apply time). ## Deferred (iteration 2+) - A proper `workstations` inventory group (when `mamba` joins) instead of reusing `control`. - lazygit, extra CLI tooling, any system LSP/formatters mason can't cover. - Pinning tmux plugins to commits (currently `master` except catppuccin `v1.0.3`).