Two things surfaced from actual use this session:
1. Tab completion (tools/setup-completion.bash, added earlier) required
manually editing ~/.bashrc — easy to skip or get wrong (confirmed
live: the source line never actually landed the first time). base
now wires it in automatically (idempotent, checked by grep first),
matching how it already touches ~/.bashrc for SSH Host aliases.
2. No pruning existed anywhere for the *.backup.<timestamp> files ~60
different services create before overwriting a live config
(Caddyfile, /etc/fstab, etc) — every one of them backs up, none
clean up, so they accumulate forever on a box reconfigured
regularly. tools/prune-old-backups.sh prunes by file mtime (not by
parsing the timestamp out of the filename — robust to the
%Y%m%d-%H%M%S vs %Y%m%d_%H%M%S inconsistency across services),
always keeping the single newest backup per distinct file
regardless of age. Verified both the normal case (mixed old/new,
prunes only the old ones) and the edge case (every backup for a
file is old, keeps the newest one anyway) against real fixtures.
base offers it as a daily systemd timer (prompted, since it deletes
files — unlike the tab-completion wiring, which doesn't).
Also added logrotate for Caddy's own access logs
(/var/log/caddy/*.log), which had no rotation at all and grow
unbounded on an active box. Uses copytruncate specifically: the log
directory is bind-mounted into the running Caddy container and read
live by CrowdSec, so truncating in place avoids either of them needing
to notice or react to a rotation happening.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H4k6J1qXXyYxhGEgnJaMvn