Architecture¶
DOTS is a profile-driven workstation layer. Humans use ./dots; automation
uses bootstrap.sh / setup.sh. Declarative registries own desired state —
helpers execute it.
Entrypoints¶
| Script | Role |
|---|---|
dots |
Unified CLI (wizard, status, packages, models, check, update) |
bootstrap.sh |
Profile resolution → Stage 0 → setup → health gate |
setup.sh |
Install / refresh (packages, links, optional components) |
configure.sh |
Create/edit profile TOML only (no installs) |
scripts/check.sh |
Health verification for a resolved profile |
Execution graph¶
profile resolution
↓
Stage 0 (CLT / Homebrew / Python as needed)
↓
backup (unmanaged targets)
↓
package acquisition (groups + selected optional Brewfiles)
↓
configuration helpers
↓
link / relink (configs/links.toml)
↓
optional component configuration (post-link)
↓
health verification (scripts/check.sh)
--show / --dry-run never mutate. Consent for AI clients is explicit profile /
--with listing — binary presence alone does not authorize configuration.
Layers of desired state¶
profiles machine-role presets (home / work / server / …)
package groups portable tool sets (core, modern, dev, security, …)
optional components --with ids (herdr, hermes, mactools, …)
supergroups expand to component ids (e.g. ai)
managed links repo files → home paths
skills packs / standalone via skills CLI
models local model registry + pull policy
language servers local code-intelligence binaries + editor clients
runtime.env generated non-secret runtime
local.sh host overrides (never overwritten)
Source of truth¶
| Thing | Authority |
|---|---|
optional components / platforms / omit_from_all |
configs/components.toml |
| component → Brewfile mapping | configs/components.toml (brewfile =) |
| supergroups | configs/components.toml |
| package groups (required/optional ids) | configs/packages/groups.toml |
| Homebrew group ownership | brew/groups/*.Brewfile |
| optional component Homebrew fragments | brew/Brewfile.<id> |
| convenience aggregate Brewfile | brew/Brewfile (not canonical ownership) |
| Linux native package names | configs/packages/{apt,pacman,dnf,xbps}.toml |
| managed file links | configs/links.toml |
| skill packs | configs/skills/manifest.toml |
| local model policy | configs/models.toml |
| language-server inventory / providers / filetypes | configs/lsp/servers.toml |
| built-in profiles | configs/bootstrap/profiles/*.toml |
| agent routing defaults | configs/agents/router.toml (+ skills/agent-router/SKILL.md) |
supported --with ids |
loaded from configs/components.toml (not edited in setup.sh) |
Do not invent a second registry. Prefer extending these files over new
hard-coded case maps.
Language-server ownership¶
configs/lsp/servers.toml
→ authoritative server, filetype, provider, health, and Neovim-id registry
→ brew/Brewfile.lsp realizes Homebrew formulae
→ helpers/lsp.sh selects native Linux packages or trusted fallbacks
→ configs/nvim/lua/config/lsp_servers.lua is generated client configuration
→ ./dots lsp is the human-facing orchestration and status surface
DOTS owns PATH-visible server binaries. Neovim consumes those binaries and does not use Mason to install private duplicate copies. Other LSP clients can use the same executables.
brew/Brewfile role¶
brew/Brewfile is a convenience / backward-compatible aggregate of workstation
groups for bare ./setup.sh. Canonical ownership is:
Add new packages to the owning group or component Brewfile — not the aggregate.
scripts/tests/repository_contract_test.sh checks aggregate ↔ group drift.
There is no packages.txt.
Provisioning and runtime precedence¶
Provisioning: repository defaults < built-in profile < custom profile < CLI
--with / --without / --packages.
Runtime: shell/exports.sh < runtime.env < local.sh < process env.
Machine-local (never committed):
~/.config/dots/runtime.env # generated from profile (non-secret)
~/.config/dots/local.sh # your host overrides (never overwritten)
~/.config/dots/profiles/ # user-owned custom profiles
Dormant / unclassified syms/ entries¶
configs/links.toml lists active managed links. Other files under syms/ may
remain in the tree without being linked:
| Status | Examples |
|---|---|
| active | listed in configs/links.toml |
| template | gitconfig.template, docker_config.json.template |
| legacy / deprecated | init.vim (Neovim uses configs/nvim), screenrc, xonshrc |
| dormant / optional | curlrc, dircolors, exrc, gemrc, config.fish, … |
Do not delete dormant files casually. Document before promoting them into
configs/links.toml.