Concerns (6 files): - coding-style.md (163 lines): patterns, anti-patterns, error handling, SOLID - naming.md (105 lines): naming conventions table per language - documentation.md (149 lines): docstrings, WHY vs WHAT, README standards - testing.md (134 lines): AAA pattern, mocking philosophy, TDD - git-workflow.md (118 lines): conventional commits, branch naming, PR format - project-structure.md (82 lines): directory layout, entry points, config placement Languages (4 files): - python.md (224 lines): uv, ruff, pyright, pytest, pydantic, idioms, anti-patterns - typescript.md (150 lines): strict mode, discriminated unions, satisfies, as const - nix.md (129 lines): flake structure, module patterns, alejandra, anti-patterns - shell.md (100 lines): set -euo pipefail, shellcheck, quoting, POSIX Frameworks (1 file): - n8n.md (42 lines): workflow design, node patterns, Error Trigger, security Context budget: 975 lines (concerns + python) < 1500 limit Refs: T6-T16 of rules-system plan
2.5 KiB
2.5 KiB
Nix Code Conventions
Formatting
- Use
alejandrafor formatting - camelCase for variables,
PascalCasefor types - 2 space indentation (alejandra default)
- No trailing whitespace
Flake Structure
{
description = "Description here";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
in {
packages.default = pkgs.hello;
devShells.default = pkgs.mkShell {
buildInputs = [ pkgs.hello ];
};
}
);
}
Module Patterns
Standard module function signature:
{ config, lib, pkgs, ... }:
{
options.myService.enable = lib.mkEnableOption "my service";
config = lib.mkIf config.myService.enable {
services.myService.enable = true;
};
}
Conditionals and Merging
- Use
mkIffor conditional config - Use
mkMergeto combine multiple config sets - Use
mkOptionDefaultfor defaults that can be overridden
config = lib.mkMerge [
(lib.mkIf cfg.enable { ... })
(lib.mkIf cfg.extraConfig { ... })
];
Anti-Patterns (AVOID)
with pkgs;
Bad: Pollutes namespace, hard to trace origins
{ pkgs, ... }:
{
packages = with pkgs; [ vim git ];
}
Good: Explicit references
{ pkgs, ... }:
{
packages = [ pkgs.vim pkgs.git ];
}
builtins.fetchTarball
Use flake inputs instead. fetchTarball is non-reproducible.
Impure operations
Avoid import <nixpkgs> in flakes. Always use inputs.
builtins.getAttr / builtins.hasAttr
Use lib.attrByPath or lib.optionalAttrs instead.
Home Manager Patterns
{ config, pkgs, lib, ... }:
{
home.packages = with pkgs; [ ripgrep fd ];
programs.zsh.enable = true;
xdg.configFile."myapp/config".text = "...";
}
Overlays
{ config, lib, pkgs, ... }:
let
myOverlay = final: prev: {
myPackage = prev.myPackage.overrideAttrs (old: { ... });
};
in
{
nixpkgs.overlays = [ myOverlay ];
}
Imports and References
- Use flake inputs for dependencies
libis always available in modules- Reference packages via
pkgs.packageName - Use
callPackagefor complex package definitions
File Organization
flake.nix # Entry point
modules/ # NixOS modules
services/
my-service.nix
overlays/ # Package overrides
default.nix