Skip to content

Latest commit

 

History

History
65 lines (62 loc) · 9.09 KB

File metadata and controls

65 lines (62 loc) · 9.09 KB
  • my dotfiles are managed with a normal git repository at ~/projects/dotfiles. Use regular git and tig from that repository.
  • commit every logical meaningful change after it was verified. stage individual hunks if necessary.
  • I value simplicity, minimalism and elegance. YAGNI, KISS, SoC.
  • automatically read relevant man pages and documentation websites before deciding or implementing anything
  • before suggesting any config syntax, look up the official documentation to verify the syntax is correct
  • configurations and programs should be resource friendly. Prefer rust(-script) over scripting languages. Allow the cpu to go into deep sleep states.
  • the nixos and home manager configurations should be the source of truth
  • when switching the current system, make sure to stay on the same specialization. You can simply use the already existing switch script.
  • automatically read analyze relevant log files and/or run commands like journalctl to get them
  • you can assume all binaries in the nix store exist when referencing like this: "${pkgs.mypackage}/bin/mycommand"
  • never search or grep the full nix store
  • you can read specific files and dirs, like ~/bin or ~/.config IN $HOME, but not list files in home
  • use nixos-option to find nixos options, e.g. services.xserver.xkb.layout
  • to figure out what exactly some software is doing, trace the nix build down to the source code.
  • use DeepWiki MCP to answer questions about some repository
  • for package investigations on flake-based systems, treat flake.lock as the source of truth for the pinned nixpkgs revision
  • when tracing a package, prefer querying the pinned flake input directly with nix flake metadata --json . and nix eval --impure --expr '(builtins.getFlake (toString ./.)).inputs.nixpkgs...' instead of assuming this repo exports packages or legacyPackages
  • when nix eval on a local path flake uses builtins.getFlake (toString ./.), add --impure
  • if nix eval or related commands fail on /nix/var/nix/daemon-socket/socket, immediately rerun with escalation instead of working around it
  • prefer this package tracing order: config reference -> pinned flake input -> package metadata via nix eval -> nixpkgs package definition or generated index -> installed runtime files -> upstream source/issues/PRs
  • for pkgs.gnomeExtensions.*, check pkgs/desktops/gnome/extensions/extensions.json and buildGnomeExtension.nix before assuming there is a dedicated *.nix package file
  • for GNOME extensions, note that nixpkgs version may be the extensions.gnome.org build number, while the human-facing extension version may live in embedded metadata like version-name
  • if a src.outPath store path is not realized or readable, inspect the pinned nixpkgs source tree and the installed runtime files under /run/current-system/sw or /etc/profiles/per-user/... instead
  • for live desktop investigations, prefer checking the actually installed runtime files and session state, not just the derivation metadata
  • if desktop debugging touches live GNOME session state, expect gnome-extensions, dconf, and /run/user/* access to require escalation
  • If a nix let binding is reused across the whole module, keep it in the top-level let.
  • If it is only used by one option block, move it into a local let right above that block.
  • Prefer the narrowest scope that still keeps the code readable.
  • for refactorings, use nvd to verify that the generated nix code is exactly the same before and after and only shows the desired changes. When comparing specializations, anchor on /nix/var/nix/profiles/system/specialisation/<name> — not /run/current-system/specialisation/<name>, which only resolves when the parent toplevel is booted (check cat /run/nixos/current-specialisation to see which spec is active).
  • to know how other people configure something, search their dotfiles on github. Use corresponding file path and language where appropriate.
  • if you found a good reference or documentation for the task at hand, add a comment in the code referring to that documentation for future quick retreival
  • If code should be moved to another file, always do it with shell commands to preserve the content verbatim and avoid copy paste errors
  • If any command is missing to to the job or investigate, you can access any command via an ad-hoc nix-shell
  • always add comments to document why things are the way they are. The comments should only refer to the current code, not to past code.
  • don't hardcode paths. whenever possible, use xdg dirs.
  • build incrementally during refactors, to catch errors early
  • if a task is not straightforward, think about which refactor would make the task easy. Then do this refactoring first and commit it before attempting the task.
  • once the user confirms a specific change is working, commit that change immediately (stage only the relevant hunks). Don't bundle it with later work or wait for more confirmations.
  • never run switch, nixos-rebuild switch, or any other system-activating rebuild yourself — the user always runs those manually. nixos-rebuild build (no activation) is fine for verification.
  • files written at runtime (not by nix) must carry a header comment naming the writer and the source template, e.g. AUTOGENERATED at runtime by noctalia from home/noctalia/templates/<file>. Edits are overwritten on the next theme change. JSON files and other formats without comment support are exempt.
  • agents are configured in modules/home-manager/profiles/ai-agents/
  • pi extensions are nix-managed: drop a *.ts into modules/home-manager/profiles/ai-agents/pi-extensions/ and pi-extensions.nix symlinks it into ~/.pi/agent/extensions/ (auto-discovered by pi; /reload to pick up changes)
  • pi extensions are gated by a reproducible check (pi-extensions-check.nix): tsgo type-check + oxlint + node --test, type-checked against the pinned pi's own type declarations. Run it explicitly with nix build .#checks.x86_64-linux.pi-extensions (or nix flake check). It also gates store-mode packaging, so a type/lint/test error fails switch/nixos-rebuild build; extensions listed in my.devLinks bypass the packaging gate (edit-live) but are still covered by the explicit run. Keep unit-testable logic in a pure core.ts with a *.test.ts (node:test); collect tools in arrays via pi's defineTool() to preserve param inference.
  • sandboxing is done with nono. all ai agents are wrapped by default by nono. home/config/nono/profiles/agent.json.
  • nono sandboxing should only allow what is necessary and disallow everything (except network access) by default. if some software needs access to a path that contains secrets/keys or critical information, suggest a safer way, so the agent gains the capability, but never sees the secrets. look at the nono docs for possibilities.
  • the sandbox should limit ai agent compromitation and reduce attack surface for supply chain attacks.
  • ssh keys should never rest in the file system. always per secret service in keepassxc.
  • the agent must never read sensitive keys directly; broker the capability instead, the way ssh-agent does. e.g. for wireless adb to android devices, run the key-holding adb -a nodaemon server outside the sandbox bound to the LAN ip (nono isolates loopback but shares the LAN interface) and have the sandboxed client reach it via ADB_SERVER_SOCKET=tcp:<host-lan-ip>:5037 — the agent speaks only the wire protocol and never sees ~/.android/adbkey.
  • when organizing nix architecture: prefer separate modules over options -> less coupling
  • I use neo keyboard layout. The keys iale (form arrow cross for left hand) vs ngrt (form arrow cross for right hand)

configuration entrypoints:

  • flake.nix # top-level NixOS flake
  • hosts-nixos//default.nix # host NixOS configuration
  • hosts-nixos//home.nix # host Home Manager configuration

Desktop specialisations and per-desktop gating

  • Each desktop is a NixOS specialisation built by modules/nixos/specialisation-helpers.nix, which sets my.desktop (and my.theme for themed desktops) via lib.mkForce. Boot picks one; switch [<spec>] switches.
  • ALL desktop modules are imported unconditionally (e.g. both desktops/herbstluftwm.nix and desktops/noctalia-niri.nix in hosts-nixos/<host>/home.nix), then each guards its whole body with lib.mkIf (desktop == "<name>"). Only the matching desktop's block is active per specialisation, so home-manager config IS effectively spec-scoped even though the imports are shared.
  • Practical consequence: settings placed inside a lib.mkIf (desktop == "X") block (e.g. xresources.properties for the X11 desktop) only land in that specialisation's generation — they do not leak into other desktops.
  • Display managers differ per desktop: herbstluftwm uses lightdm (its session-wrapper sources ~/.xprofile, runs xrdb -merge ~/.Xresources, then eval exec ~/.xsession to launch the WM — so ~/.Xresources / home-manager xresources.properties are merged); noctalia-niri uses greetd running niri-session directly, which never runs xrdb, so X resources are inert there.

sharing is caring

  • My friend Johannes has his private dotfiles repository here: git@github.com:cornerman/nixos.git (do temporary clones in /tmp)