# Conventions ## Lua version target Author against a subset valid under **both Lua 5.4 and 5.5**: Arch/Artix currently package Lua 5.4, while this repo is authored/syntax-checked locally with `lua55`. Avoid 5.5-only stdlib additions. `docs/CONVENTIONS.md` (this file) is the one place a Windows-side checker and a Linux-side interpreter could silently diverge — if you're unsure whether something is 5.4-safe, don't use it. ## Naming Service directories under `services/` follow Artix's own `s6-scripts` catalog convention: - A daemon's directory is named `-srv` (e.g. `dbus-srv`). - Its logger is named `-log` (e.g. `dbus-log`), wired via `producer-for`/`consumer-for`. - Logs land in `/var/log/` (not `/var/log/-srv`). - Early-boot oneshots (category 1) and one-off oneshots (`coldplug`, `net-lo`, etc.) are named after the action they perform, no suffix (e.g. `mount-cgroups`, `hostname`). - Bundles are named after the target they represent (`boot`, `mount`, `setup`, `ttys`, `graphical`, `default`), not suffixed. ## Adding a new `-srv`/`-log` daemon pair Don't hand-author a new service directory pair. Add a row to `tools/catalog.lua` and rerun: ``` lua55 tools/gen-services.lua ``` This regenerates every entry in the catalog (idempotent — safe to rerun after editing one row). ## Swapping the default display manager `services/default/contents.d/` currently includes `sddm-srv`/`sddm-log` (Artix's own flagship display manager). To switch to GDM or LightDM, remove the `sddm-*` entries from `services/default/contents.d/` and add `gdm-srv`/`gdm-log` or `lightdm-srv`/`lightdm-log` instead — all three are already generated and ready to enable. ## Exec strategy - `longrun` `run` scripts **must** end with `s6.exec({...})` (from `src/lua/s6lua.lua`, backed by the native `s6exec.so` module) as their last statement. This is what makes the supervised process the real daemon rather than a lingering Lua interpreter — see the root README and the plan history for why `os.execute("exec ...")` does not work here. - `oneshot` `up`/`down` scripts and longrun `finish` scripts do **not** need `s6.exec` — they run to completion and exit, so `s6.run`/`os.execute` is safe and preferred (simpler, no native dependency). ## Git executable bit Windows checkouts don't set the tree's executable-bit metadata on `git add`. Run `tools/set-exec-bits.ps1` before committing any new `run`/`up`/`down`/`finish`/`reload`/`check` file — the syntax and lint checks won't catch a missing exec bit, but `s6-supervise` will fail silently on the real target. ## Known unverified gaps Artix's `s6-scripts` gitea repo blocked automated fetches during research, so the daemon argv/flags in `tools/catalog.lua` (chronyd, bluetoothd, acpid, cupsd in particular) are reconstructed from each daemon's documented foreground-mode flag rather than confirmed byte-for-byte against a reference script. Spot-check before relying on this in production.