feat(cli): modern replacements for the classic coreutils tools, and sudo-rs #95

Merged
lyrathorpe merged 2 commits from feat/modern-cli-replacements into main 2026-08-19 17:21:40 +01:00
Owner

What

Two commits.

feat(cli) — modern replacements for the day-to-day utilities.

Four commands are shadowed by aliases. All four are read-only, so a wrong flag costs a retype rather than data:

Alias Runs
cat bat --paging=never
du dust
df dysk
ps procs

rm, grep, find and sed are deliberately left alone; their replacements (trash, rg, fd, sd) are reached by their own names. Reasoning is in home/README.md.

Also installed on every host: trash-cli, doggo, xh, ouch, jnv, hexyl, fq, tealdeer. dysk is used rather than duf, which is unmaintained upstream.

  • git: difftastic behind a git dft alias. diff.external is left unset, so delta remains the renderer for git diff/git show and for anything parsing them.
  • Work box only: kubecolor aliased over kubectl. It wraps the real kubectl and drops colour when stdout is not a terminal, so pipes are unchanged.

feat(security)security.sudo-rs.enable on every NixOS host, replacing sudo with the memory-safe implementation. Enabling it sets security.sudo.enable = false via mkDefault, so it is a swap rather than an addition. This fleet only uses the stock wheel-with-password policy, which sudo-rs implements fully. The macOS host is unaffected and keeps Apple's sudo with Touch ID.

Docs

home/README.md gains a "Replacing the classics" section: the alias map, where the aliases do and do not apply, a flag-gotcha table, what was left alone and why, and the sudo-rs behaviour and recovery path. The root README links to it, and the module catalogue notes the sudo swap.

Two gotchas are called out specifically because they fail silently rather than erroring:

  • dust -s is --apparent-size, not --summarize.
  • procs aux reads aux as a search keyword, returning only processes whose command line contains that string.

Both were verified against the real binaries rather than the man pages.

Validation

  • nix flake check passes: treefmt, deadnix, statix, pre-commit, and evaluation of all five NixOS hosts.
  • darwinConfigurations.lyrathorpe-mac and homeConfigurations."lyrathorpe@x86_64-linux" evaluate.
  • Alias scope confirmed in zsh: aliases expand after a variable-assignment prefix (KUBECONFIG=… kubectl … reaches kubecolor) but not after sudo.
  • bat's piped output is byte-identical to cat.

Deployment note

sudo-rs reaches every NixOS host, including the RPi5, which has key-only sshd and no root login. Rebuild that host last, and while console access is available. The recovery path is documented in modules/common-nixos.nix and home/README.md.

## What Two commits. **`feat(cli)`** — modern replacements for the day-to-day utilities. Four commands are shadowed by aliases. All four are read-only, so a wrong flag costs a retype rather than data: | Alias | Runs | | ----- | -------------------- | | `cat` | `bat --paging=never` | | `du` | `dust` | | `df` | `dysk` | | `ps` | `procs` | `rm`, `grep`, `find` and `sed` are deliberately left alone; their replacements (`trash`, `rg`, `fd`, `sd`) are reached by their own names. Reasoning is in `home/README.md`. Also installed on every host: `trash-cli`, `doggo`, `xh`, `ouch`, `jnv`, `hexyl`, `fq`, `tealdeer`. `dysk` is used rather than `duf`, which is unmaintained upstream. - git: difftastic behind a `git dft` alias. `diff.external` is left unset, so delta remains the renderer for `git diff`/`git show` and for anything parsing them. - Work box only: kubecolor aliased over `kubectl`. It wraps the real kubectl and drops colour when stdout is not a terminal, so pipes are unchanged. **`feat(security)`** — `security.sudo-rs.enable` on every NixOS host, replacing sudo with the memory-safe implementation. Enabling it sets `security.sudo.enable = false` via `mkDefault`, so it is a swap rather than an addition. This fleet only uses the stock wheel-with-password policy, which sudo-rs implements fully. The macOS host is unaffected and keeps Apple's sudo with Touch ID. ## Docs `home/README.md` gains a "Replacing the classics" section: the alias map, where the aliases do and do not apply, a flag-gotcha table, what was left alone and why, and the sudo-rs behaviour and recovery path. The root README links to it, and the module catalogue notes the sudo swap. Two gotchas are called out specifically because they fail *silently* rather than erroring: - `dust -s` is `--apparent-size`, not `--summarize`. - `procs aux` reads `aux` as a search keyword, returning only processes whose command line contains that string. Both were verified against the real binaries rather than the man pages. ## Validation - `nix flake check` passes: treefmt, deadnix, statix, pre-commit, and evaluation of all five NixOS hosts. - `darwinConfigurations.lyrathorpe-mac` and `homeConfigurations."lyrathorpe@x86_64-linux"` evaluate. - Alias scope confirmed in zsh: aliases expand after a variable-assignment prefix (`KUBECONFIG=… kubectl …` reaches kubecolor) but not after `sudo`. - bat's piped output is byte-identical to `cat`. ## Deployment note `sudo-rs` reaches every NixOS host, including the RPi5, which has key-only sshd and no root login. Rebuild that host last, and while console access is available. The recovery path is documented in `modules/common-nixos.nix` and `home/README.md`.
lyrathorpe added 2 commits 2026-08-19 17:14:38 +01:00
Adds Rust/Go replacements for the day-to-day utilities and shadows four of
them with aliases. Only read-only commands are shadowed (cat, du, df, ps), so a
wrong flag costs a retype rather than data; rm, grep, find and sed keep their
originals and the replacements are reached by their own names.

The aliases land in .zshrc, so they apply to interactive zsh only -- scripts,
`sudo <cmd>` and anything exec'd by another program still get the real binary.

New on every host: dust, dysk, procs, trash-cli, doggo, xh, ouch, jnv, hexyl,
fq and tealdeer. dysk is used rather than duf, which is unmaintained upstream.

git gains difftastic behind a `git dft` alias. diff.external is deliberately
left unset so delta remains the renderer for git diff/show and for anything
parsing them.

The work box gains kubecolor, aliased over kubectl; it wraps the real kubectl
and drops colour when stdout is not a terminal, so pipes are unchanged.

home/README.md documents the alias map, the flag incompatibilities (including
the two that fail silently: dust -s is --apparent-size, and procs reads a bare
`aux` as a search keyword) and the rationale for what was left alone.
feat(security): swap sudo for the memory-safe sudo-rs
CI / flake (push) Skipped
CI / flake (pull_request) Successful in 4m6s
dfafac8de9
security.sudo-rs.enable sets security.sudo.enable = false via mkDefault, so
this is a straight swap; the two modules assert against being on together.

The fleet only uses the stock policy -- wheel may run anything, with a password
-- which sudo-rs implements fully. It does not cover host aliases, LDAP/SSSD
sudoers, sudoreplay or most Defaults settings; needing any of those means
reverting to security.sudo. The macOS host is unaffected and keeps Apple's sudo
with Touch ID.

Recovery from a host that will not escalate is documented in the module and in
home/README.md: get a root shell that does not go through sudo, then roll back
the generation.
lyrathorpe merged commit d30d8f9892 into main 2026-08-19 17:21:40 +01:00
lyrathorpe deleted branch feat/modern-cli-replacements 2026-08-19 17:21:41 +01:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: lyrathorpe/nixfiles#95