Files

107 lines
4.9 KiB
Markdown

# system-config
A small, declarative Arch configuration managed by Decman.
## Design
- **Concerns live in `packages/`**: each concern has a native (`*-repo.txt`)
and AUR (`*-aur.txt`) list, plus an optional global npm (`*-npm.txt`) list
for command packages unavailable through Arch packaging.
- **Hosts live in `hosts.py`**: a host composes package concerns and explicit
system state. `desktop()` owns this desktop's boot, storage, NVIDIA, input,
SDDM, network-policy, and user-session configuration.
- **System files live in `config/system/`**: shared files go in `common/`;
hardware, sleep/logind, and boot policy go in the relevant host directory.
- **State lives in `manifests/`**: units follow the same concern and host
scopes as packages.
- **Python glue lives in `modules/`**: package and system-state adapters only.
Decman owns the listed system files and selected durable home configuration.
yadm owns remaining portable dotfiles; application state, browser profiles,
NetworkManager connection profiles, and project build output remain unmanaged.
## System policy
- `config/system/common/pacman/pacman.conf` enables only the official core,
extra, and multilib repositories. No debug repository is enabled.
- `config/system/common/makepkg/makepkg.conf` sets `OPTIONS` with `!debug`, so
newly built packages do not produce debug packages.
- `config/system/common/locale/` owns locale generation and system locale.
- `config/system/common/keyboard/` owns console and X11 keyboard policy.
- `config/system/laptop/sleep.conf.d/` owns sleep policy; the logind drop-in
remains in `config/system/laptop/systemd/`.
- `config/system/laptop/power/tlp.conf` owns laptop power policy. TLP reads
`/etc/tlp.conf` after drop-ins, so a whole-file policy is required here.
- `config/system/{laptop,desktop}/boot/mkinitcpio.conf` owns encrypted-root
and resume initramfs hooks for each host; its module rebuilds the initramfs
after a change.
- `config/system/laptop/refind/` owns the laptop ESP rEFInd configuration and
encrypted-root kernel options. It is intentionally laptop-only.
- `config/system/laptop/iwlwifi.conf` retains the Wi-Fi 6 stability workaround;
NetworkManager owns Wi-Fi power saving for battery use.
- `config/user/{common,laptop,desktop}/` owns selected active user dotfiles.
Host-specific Hyprland and Noctalia variants are selected by host composition.
- EnvyControl's generated NVIDIA blacklist and udev files are intentionally
unmanaged so GPU modes can be switched outside of Decman.
Changing the debug policy does not uninstall debug packages already installed;
remove those explicitly in a separate reviewed package change.
## Package concerns
| Scope | Concerns |
| --- | --- |
| Shared | core, wayland, fonts, development, productivity, media, research, network, services |
| Laptop | hardware, legacy; hardware units |
| Desktop | shared concerns, `common/hardware`, and a reviewable `desktop/local` set; host state is in `config/system/desktop/` |
Every package must have a named purpose. Add a new concern when an existing one
does not explain a package. Missing packages from `*-npm.txt` are installed
globally after the pacman and AUR steps; unrelated global npm packages are not
removed. System and user units use the same naming:
`manifests/common/<concern>-{system,user}.txt` or
`manifests/laptop/<concern>-system.txt`.
## Commands
From the repository root, run common workflows through the
`./system-config/decman` wrapper, which uses fixed Decman arguments:
```bash
./system-config/decman verify
./system-config/decman dry-run
./system-config/decman apply
```
`dry-run` and `apply` first run `verify`. They invoke Decman with `--no-hooks`,
matching the deliberately review-first direct commands below. `apply` changes
system state; use it only after reviewing the dry run.
The wrapper locates its configuration relative to itself, so its commands run
from the `system-config` directory. Command output and errors stream directly
to the terminal. If a child command fails, the wrapper prints the failed command
and returns its exit status. A missing executable returns `127`, another
execution error (including a permission error) returns `126`, and an
interrupted workflow returns `130`.
```bash
sudo decman --source source.py --dry-run --no-hooks
sudo decman --source source.py --no-hooks
```
`verify.py` proves that every currently explicit package appears exactly once
in the active desktop profile, including global npm command packages. The
ignored dependency lists prevent Decman's orphan cleanup from removing
dependencies during adoption.
After intentional package changes, regenerate and review concern lists:
```bash
./system-config/decman refresh-package-state
yadm diff -- system-config
```
`refresh-package-state` runs `split-packages`, `refresh-orphan-guards`, and
`verify` in that order. Those individual file-changing commands are also
available through the dispatcher when only one is needed.