Rio
adr/0021-plain-text-config-xdg.mdRaw Markdown · GitHub ↗

ADR-0021: Plain-text configuration in XDG locations, never executed

  • Status: Accepted; session storage amended by ADR-0031
  • Date: 2026-06-25
  • Deciders: jka
  • Decision: D21

Context

Tcl makes it tempting to use a Tcl script as a configuration file. That runs arbitrary code at start-up and turns a typo into a start-up failure. rio also holds different kinds of state (human-written settings, machine-written session data, secrets) that have different owners and different handling needs.

Decision

State is kept in three separate kinds of file.

  • User settings are a flat key = value file with [section] headers and # comments, UTF-8. They are data. rio parses them and never sources them. The parser is rio::conf, shared with themes, manifests and other conf files.
  • Session and workspace state is written by rio as JSON and is not meant for hand editing.
  • Secrets (API keys) are kept apart from both, in a store under the data directory with the directory at 0700 and each file at 0600 (rio-core/secret.tcl).

Locations follow the XDG Base Directory specification: $XDG_CONFIG_HOME/rio/ (default ~/.config/rio/) for configuration and $XDG_DATA_HOME/rio/ (default ~/.local/share/rio/) for data. A project may carry its own settings in .rio/ at its root.

Consequences

  • Configuration is diff-friendly, readable, and cannot execute code.
  • A broken configuration file degrades to defaults rather than stopping rio; this rule is applied to every later file rio reads (key maps, preferences, allow-lists, certificate exceptions).
  • ADR-0031 moved personal session state out of the project tree, so .rio/ holds only project-level, committable material (prompts, allow-lists, plans).
  • The intended Windows locations (%APPDATA%, %LOCALAPPDATA%) were never implemented. On Windows 11 Tcl derives HOME from HOMEDRIVE and HOMEPATH, so the XDG fallback resolves under %USERPROFILE% and works. The cost is that the 0600/0700 permissions are a no-op on NTFS; the key file inherits the profile's permissions.