Files
dotconfs/README.md
T
thomas.koppandClaude Opus 5 f2a8d4dec1 docs: describe the role layout and drop the -k from the installer
The README still described the 2021 arrangement. It now documents the three
roles, the rc.d layout and packages.sh, and spends most of its length on the
load order - because that is where this fails quietly. Theme and plugins must
precede oh-my-zsh, which consumes both while sourcing; the prompt colour must
follow .p10k.zsh, which assigns it. Both were got wrong once, and the first
produced a shell reporting ZSH_THEME=powerlevel10k while running without it.

The installer line loses its -k. Disabling certificate verification against a
host that has a valid certificate removes exactly the protection that matters
when piping a remote script into a shell.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 22:33:38 +02:00

161 lines
5.6 KiB
Markdown

# dotconfs
Configuration for three machines out of one repository: an Arch desktop, an
Arch server and a Mac. The role is decided when the shell starts, not when
files are deployed.
The bare-repository technique is from
[an Atlassian post](https://developer.atlassian.com/blog/2016/02/best-way-to-store-dotfiles-git-bare-repo/):
a git directory in `$HOME/.cfg` with `$HOME` as its work tree, driven by an
alias. No symlinks, no extra tooling.
## Roles
| Role | Machine | Prompt |
|---|---|---|
| `desktop` | beastix — Arch, KDE | powerlevel10k, blue |
| `server` | shron — Arch, headless | powerlevel10k, ASCII, **red** |
| `mobile` | the Mac — macOS, Apple Silicon | ys, green once p10k is there |
Red on the server is a guard, not decoration. shron carries mail, web and
cloud, and the prompt should answer "which machine is this" before the next
command is typed.
The role lives in `~/.config/dotconfs/role`, one word, and is **not** tracked —
a shared copy would defeat the purpose. Write it before the first login.
Without it the shell falls back to `desktop`.
## Layout
```
.zshrc stub: role, then oh-my-zsh, then the fragments
.zprofile login shells only; Homebrew's shellenv
.config/zsh/rc.d/
05-pre-omz.zsh theme and plugins - must precede oh-my-zsh
10-aliases.zsh shared
20-functions.zsh shared
30-path.zsh shared
50-desktop.zsh exactly one of these is sourced
50-server.zsh
50-mobile.zsh
90-local.zsh machine-local, never committed
.config/zsh/p10k-server.zsh the server's prompt, ASCII and font-agnostic
packages/ one plain list per platform and role
.scripts/packages.sh check | install
.scripts/curate.sh derive a package list from usage
```
Every machine checks out every file. A KDE configuration on the server is a few
inert kilobytes and costs less than the machinery needed to avoid it.
### Load order
It matters, and getting it wrong fails quietly:
1. powerlevel10k instant prompt — must be first, it may print
2. role
3. `05-pre-omz.zsh`**theme and plugins**, because oh-my-zsh consumes both
while it is being sourced. Set afterwards, they are ignored: an early
attempt reported `ZSH_THEME=powerlevel10k` from a shell running without it.
4. oh-my-zsh
5. `10-` to `40-` — shared
6. `50-<role>.zsh`**the prompt colour**, because `~/.p10k.zsh` assigns
`POWERLEVEL9K_CONTEXT_BACKGROUND` itself and is sourced in `30-path.zsh`
7. `90-local.zsh` — last, so it can override anything
Theme before oh-my-zsh, colour after `.p10k.zsh`. Two constraints pulling in
opposite directions.
## Portability
Anything that depends on a command is guarded by whether that command exists,
rather than duplicated per role:
```sh
(( $+commands[lsd] )) && alias ls='lsd'
```
Without the guard, `alias ls='lsd'` turns `ls` into a broken command on a
machine without lsd. The Mac is such a machine.
Plugins are assembled per role and then filtered by what is installed. Naming
a plugin that is absent produces an oh-my-zsh warning at every single login.
## Packages
Lists are plain names, one per line — data, not code, so they port to
`home-manager` and `environment.systemPackages` almost unchanged.
```
.scripts/packages.sh what is missing, what is extra
.scripts/packages.sh install install what is missing
```
**It never removes anything.** Extras are reported and left alone: on a server,
individual packages carry mail and web services.
`curate.sh` derives a candidate list from four usage signals, because each one
alone is blind to something — shell history sees no GUI application, KDE's
activity database sees no chat client, autostart sees only what starts by
itself, and flatpaks never appear in `pacman -Qqe`. On beastix that turned 512
explicit packages into 62.
## Secrets
Credentials live beside the code that reads them and are never committed. The
waybar mail module imports from `mailsecrets.py`; `.gitignore` covers that,
private keys, `.netrc`, `.pgpass`, and `.config/kdeconnect/`, which holds the
device certificate.
Machine-local overrides and anything sensitive belong in
`.config/zsh/rc.d/90-local.zsh`, which is sourced last and never tracked.
`config add -f` still bypasses all of it. The ignore list guards against
carelessness, not intent.
## Setting up a new machine
```sh
curl -Ls https://ls.shron.de/dotconf | /bin/bash
```
The installer clones into `$HOME/.cfg`, defines the alias and moves anything in
the way to `.config-backup`. Write the role file before the first login:
```sh
mkdir -p ~/.config/dotconfs && echo server > ~/.config/dotconfs/role
```
Then, by hand:
```sh
config config --local status.showUntrackedFiles no
config checkout master
```
> Earlier revisions of this file used `curl -Lks`. The `-k` disables
> certificate verification against a host that has a valid certificate,
> removing precisely the protection that matters when piping a remote script
> into a shell. It is gone.
## Day to day
```sh
config status
config add .zshrc
config commit -m "..."
config push
```
`status.showUntrackedFiles=no` keeps `$HOME` from drowning the output.
Servers pull over HTTPS rather than SSH: a machine that only consumes
configuration has no business holding push credentials.
## History
Everything before 2026-08-07 is on `archive/2021-i3-sway`. That tree described
an i3/sway desktop that no longer exists — its display menu drove `xrandr`
outputs the machine does not have — while the live files had moved on by years.
`master` was rebuilt from the running configuration rather than merged with it.