sebastienrousseau/dotfiles
sebastienrousseau/dotfiles has 82 GitHub stars and 16 forks. GitHot measured 0 stars in 24 hours, 0 in 7 days, and 0 in 15 days. Last checked 2026-11-15 05:02 UTC. Last push 2026-11-02.
What you can do
- Wallpaper-driven themes - K-Means clustering in CIELAB extracts terminal palettes from any wallpaper; WCAG AAA enforced; Apple-compatible dynamic HEIC dark/light; 228 generated themes; dot theme rebuild
- AI and MCP native - Agent profiles (dot agent mode), MCP policy and registry audit (dot mcp), agent card, checkpoints and conformance (dot agent), AI commit messages (dot config save), the dot ai cockpit and local gateway
- Cryptographic attestation - Signed commits and tags, machine-readable workstation evidence (dot attest), policy-bundle releases, the signing check in dot doctor, dot secret check
- Fleet management - Multi-node status, drift, events, namespaces and RBAC enforcement mode (dot fleet); dot fleet apply over SSH; dot fleet push to bring up a remote host
Measured star growth
- in 24h
- 0
- in 7 days
- 0
- in 15 days
- 0
- in 1 month
- Collecting history
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
About
Cross-platform developer workstation control plane powered by chezmoi — adaptive terminal themes, AI CLI workflows, read-only MCP, WASM attestations, encrypted secrets, and SLSA-verified releases.
Developer ToolsREADME.md
Original
.dotfiles
Declarative dotfiles for macOS, Linux, WSL, and Windows-native
PowerShell 7.5+. Multi-shell by default. Sub-100ms
dot cold-start. Wallpaper-driven themes. Signed and
attested releases. Fleet apply over SSH.
Contents
Getting started
- Install — one-line installer, verified installer, release archive, Homebrew, Scoop, AUR, npm, Nix, chezmoi, source
- Requirements — toolchain floor, platforms, shells
- Quick Start — install, verify, switch a theme, apply in six commands
The dotfiles family (framework + five in-repo satellites)
- The dotfiles family —
dot,dot-ui,dot-ai-tui,dot mcp,dot-mcp,dot-sys, the module registry at a glance
Framework reference
- One-minute migration from another dotfiles manager — yadm, GNU Stow, a bare repository, plain chezmoi
- Why this approach? — design rationale
- Capabilities at a glance — the current surface by theme
- Five shells, one alias hub — parity tiers from ADR-007
- Comparison — short matrix against chezmoi, holman, nikitabobko
- Benchmarks — startup budgets and the measurement method
- Features — what is included, by area
What it does
- Wallpaper-driven themes — K-Means in CIELAB, WCAG AAA, 228 generated themes
- Agent governance (ask / plan / apply / audit) — bounded profiles, MCP policy, attestation
- Self-healing and rollback —
dot doctor,dot doctor fix,dot doctor rollback - Fleet apply — every host in
fleet.tomlover SSH - The
dotCLI — the command surface, grouped by intent - Configuration —
.chezmoidata.toml, profiles, session flags - Examples — runnable example index
Operational
- When not to use .dotfiles — limitations
- Development — make targets, fuzzing, hardening gates, CI
- Security — reporting, posture, supply chain
- Documentation — all reference docs
- Acknowledgements
- Stability guarantees — SemVer axis, output stability, toolchain discipline
- License
Install
Verified release installer
The default installation path is pinned to a release and fails before
execution if the installer bytes do not match the reviewed SHA256. Never pipe
the moving main branch directly into a shell. The per-release hash and its
release process are documented in
docs/security/INSTALL_VERIFICATION.md.
curl -fsSL -o /tmp/dotfiles-install.sh \
https://github.com/sebastienrousseau/dotfiles/releases/download/v0.2.541/dotfiles-install-0.2.541.sh
if command -v sha256sum >/dev/null 2>&1; then
echo "1ad4bba73b8357b8abd6128af9fd5f957763f16832716db141a92c9415b02ae5 /tmp/dotfiles-install.sh" | sha256sum -c -
else
echo "1ad4bba73b8357b8abd6128af9fd5f957763f16832716db141a92c9415b02ae5 /tmp/dotfiles-install.sh" | shasum -a 256 -c -
fi
bash /tmp/dotfiles-install.sh
The script needs git, curl, and sha256sum or shasum. It downloads a
checksum-verified chezmoi binary, clones the pinned release to
~/.dotfiles, applies it, and puts dot on PATH. The installer is
idempotent across macOS, Ubuntu, Debian, Arch, WSL2, and GitHub Codespaces.
Pre-built release archive (dot CLI only)
Every tag publishes dot-<version>.tar.gz and .zip with the
dispatcher, lib/dot, the bundled plugins and runtime scripts, the
man page, zsh / bash / fish completions,
and a Makefile honouring the usual install prefix and staging
directory. The archive
carries SLSA build provenance (keyless, via Fulcio + Rekor):
gh release download v0.2.541 --repo sebastienrousseau/dotfiles --pattern 'dot-*.tar.gz'
gh attestation verify dot-0.2.541.tar.gz --repo sebastienrousseau/dotfiles
tar -xzf dot-0.2.541.tar.gz
make -C dot-0.2.541 install PREFIX=/usr/local
release-install-smoke.yml
repeats exactly this sequence on a clean Ubuntu and macOS runner
after every release: verify provenance, make install into an
empty staging directory, run dot version, make uninstall, assert
nothing is left behind.
Package managers
| Channel | Install |
|---|---|
| Homebrew (macOS / Linux) | brew install sebastienrousseau/tap/dot |
| Scoop (Windows) | scoop bucket add sebastienrousseau https://github.com/sebastienrousseau/scoop-bucket && scoop install dot |
| AUR (Arch) | paru -S dot-cli-git |
| npm | npx -p @sebastienrousseau/dotfiles dotfiles-install (runs the same install.sh) |
| Nix | nix profile install ~/.dotfiles/nix#dot-utils after cloning; nix develop ~/.dotfiles/nix for the dev shell |
The Homebrew formula and Scoop manifest are regenerated per tag by
release-distribute-homebrew.yml
and
release-distribute-scoop.yml
from the templates under pkg/; the AUR
package is pushed by
release-distribute-aur.yml.
The per-channel templates and the maintainer runbook are in
pkg/README.md; the end-to-end pipeline is
docs/operations/RELEASE_PIPELINE.md.
With chezmoi directly
The repository is a chezmoi source tree (.chezmoiroot points at
defaults/), so chezmoi's own bootstrap works:
chezmoi init --apply sebastienrousseau
install.sh does the equivalent after its preflight checks: it
clones the pinned release tag to ~/.dotfiles, points chezmoi's
sourceDir at it, and applies. Going direct, you give up the verified
chezmoi download, the pinned tag, and the git / curl checks.
Build from source
git clone https://github.com/sebastienrousseau/dotfiles.git ~/.dotfiles
cd ~/.dotfiles
./install.sh # full install from the local checkout
make install PREFIX=~/.local # or: stage only the dot CLI
./install.sh --minimal selects the minimal profile (written to this
host's chezmoi config) and skips --provision.
dot config export ~/Downloads builds an offline .tar.zst for an
air-gapped host; unpack it and run ./install.sh --force.
CI/CD and Docker options
Silent install (no prompts):
# After downloading and verifying /tmp/dotfiles-install.sh as shown above:
DOTFILES_SILENT=1 DOTFILES_NONINTERACTIVE=1 \
bash /tmp/dotfiles-install.sh --force
Docker sandbox:
docker run --rm -e DOTFILES_NONINTERACTIVE=1 ubuntu:24.04 bash -c \
'apt-get update -qq && apt-get install -y -qq git curl sudo >/dev/null 2>&1 \
&& git clone --depth 1 https://github.com/sebastienrousseau/dotfiles.git ~/.dotfiles \
&& bash ~/.dotfiles/install.sh \
&& export PATH="$HOME/.local/bin:$PATH" \
&& dot doctor'
dot config apply --sandbox launches the same preview through Docker or Podman
from an installed machine.
Profiles and session flags
Everything heavy is off, deferred, or cached by default. Pick a profile per machine and flip session flags when you need less.
| Switch | Where | Effect | Documented in |
|---|---|---|---|
profile = "laptop" (default) |
~/.config/chezmoi/chezmoi.toml |
zsh runs compinit by default; the OS tuning scripts use the laptop set |
docs/reference/PROFILES.md |
profile = "minimal" |
same | zsh skips compinit unless DOTFILES_ENABLE_COMPINIT=1 |
same |
profile = "server" |
same | As minimal in zsh; the OS tuning scripts use the server set |
same |
[features] flags |
defaults/.chezmoidata.toml |
alias_wrapper, dms, ai_theme_sync, zellij, linux_desktop, niri, waybar, fuzzel, mako, foot, kanshi, touch, t2, surface, corral_gitea_mirror; CI checks each is a boolean |
docs/reference/FEATURES.md |
DOTFILES_FAST=1 |
environment | Skip heavy layers (zinit, completions, lazy runtime managers) | Configuration |
DOTFILES_ULTRA_FAST=1 |
environment | Bare minimum shell: paths, aliases, prompt | docs/ARCHITECTURE.md |
DOTFILES_DEFER_TOOLS=1 (default) |
environment | Resolve heavy binaries asynchronously after the first prompt | defaults/dot_config/zsh/dot_zshrc.tmpl |
DOTFILES_AI=1 (default) |
environment | 1 loads the zsh AI helper scripts; 1 also lets apply build dot-ai-tui (0 is off) |
docs/reference/PROFILES.md |
DOTFILES_ARTIFACT_MODE=1 |
environment | Minimal prompt plus the async Bento dashboard | docs/ARCHITECTURE.md |
DOTFILES_DEBUG=1 / DOTFILES_TRACE=1 |
environment | Per-stage startup timing / full trace to stderr | docs/manual/03-reference/03-environment.md |
EVALCACHE_DISABLE=true |
environment | Bypass _cached_eval for debugging |
Features |
Requirements
Bash 5.0 or newer, zsh 5.8 or newer. These are the Tier-1 shells and the floor the test suite runs on: Ubuntu and macOS (Apple Silicon) runners on every push, Windows when shell code changes, and an Intel macOS runner in the weekly extended run (
nightly.yml).install.shandlib/dotavoid bash-4-only constructs where macOS's stock/bin/bash3.2 has to run them (the notes are inlib/dot/ui.sh), but 3.2 is not a supported interactive shell.chezmoi 2.73.3 or newer, git 2.34 or newer, curl. CI pins chezmoi
2.73.3and installs it through a checksum-verified fetch;install.shdoes the same on your machine.A supported platform. macOS 15+ (Apple Silicon and Intel), Ubuntu 22.04+, Debian 12+, WSL2, NixOS 23.11+ are CI-tested or supported; Fedora and Arch are community-supported. The full table, with per-tool floors, is
docs/MINIMUM-TOOLCHAIN.md.Windows. PowerShell 7.5+ runs the native
dot.ps1for the daily workflow (apply, status, doctor, mise inventory, agent checks, fleet status); theTest / Windowsjob exercises the cmdlets onwindows-latestwhenever shell or Windows code changes.
Minimum-toolchain policy. The floor is the version CI
exercises, not the oldest version that happens to work. It is
raised only in a release whose CHANGELOG.md entry names the new
floor and the reason, never silently. The version axis on which it
may move, and the table mapping every supported platform and tool
to its floor live in
docs/MINIMUM-TOOLCHAIN.md;
this README makes no distro-compatibility claim that table does not
back.
Quick Start
# First download and verify /tmp/dotfiles-install.sh as shown in Install.
bash /tmp/dotfiles-install.sh
dot doctor # audit tools, paths, portability, security
dot help tour # interactive tour of shells, secrets, themes, performance
dot theme rebuild # generate themes from the wallpapers on this machine
dot theme toggle # swap dark and light within the current family
dot sync # apply the source tree; the next shell hydrates its caches
First 5 Minutes
- Check —
dot doctorvalidates tools, paths, and security. - Explore —
dot help tourwalks through shells, secrets, themes, and performance. - Customize — edit
~/.config/chezmoi/chezmoi.tomlfor per-machine settings (Profiles). - Toggle features — flip flags in
.chezmoidata.toml(Feature Flags). - Apply —
dot syncapplies the config, and the next interactive shell hydrates its caches through_cached_eval.
Upgrades between versions are covered in
docs/operations/MIGRATION.md.
The dotfiles family
One repository, one release train: the dot framework plus five
satellites that ship inside it and version with it. The version
number in defaults/.chezmoidata.toml is the compatibility contract:
CI's Generators / version-consistency job checks it against every
human-visible version surface (among them package.json, bin/dot,
the man page, the bento banner, this README's badge, CLAUDE.md
and AGENTS.md) on every push to main.
| Component | What it is | Use case |
|---|---|---|
dot (bin/dot + lib/dot) |
Bash dispatcher and shared library — lifecycle, diagnostics, themes, secrets, fleet, agents | Everything below; also shipped alone as the release archive. |
dot-ui (defaults/dot_local/share/dot-ui) |
Go renderer for tables, pickers, and progress used by dot |
Consistent terminal UI across every subcommand; built on apply by a run_onchange hook. |
dot-ai-tui (defaults/dot_local/share/dot-ai-tui) |
Go Bubble Tea cockpit behind dot ai |
Install, run, chat with, and meter Claude, Codex, Copilot, Aider, OpenCode and friends from one screen. |
dot mcp (docs/security/MCP_POLICY.md) |
MCP policy, supply-chain, and registry audit over mcp-policy.json / mcp-registry.json |
Keep Model Context Protocol servers inside an allowlist before an agent touches them. |
dot-mcp (defaults/dot_local/share/dot-mcp) |
Go stdio MCP server behind dot mcp serve — JSON-RPC 2.0, four read-only tools, five resources |
Let an MCP client audit this workstation's policy, agent mode, attestation and drift without being able to change it. |
dot-sys (lib/wasm-tools) |
Rust crate built for wasm32-wasip1 and run under wasmtime |
dot attest verify: check a workstation evidence record in a sandbox with no filesystem, network or environment, so the verdict does not depend on the machine being reviewed. |
Module registry (docs/operations/REGISTRY.md) |
JSON index of reusable dotfile modules, schema at docs/schema/dot-registry-v1.json |
dot cli list --available and dot cli install with SHA-256-verified archives and a chezmoi preview before apply. The published index has no modules yet, and --available lists the whole index (a search term is ignored). |
Install the pieces
# The framework (everything, chezmoi-managed)
bash /tmp/dotfiles-install.sh # after the verified download above
# Only the dot CLI, from the attested release archive
gh release download v0.2.541 --repo sebastienrousseau/dotfiles --pattern 'dot-*.tar.gz'
# The Go satellites are (re)built on apply by
# defaults/run_onchange_24-build-dot-ui.sh.tmpl
# defaults/run_onchange_25-build-dot-ai-tui.sh.tmpl
# defaults/run_onchange_26-build-dot-mcp.sh.tmpl
# A registry module
dot cli list --available && dot cli install <module> --yes
Per-host quick links
| If you use… | Drop-in config |
|---|---|
| Claude Code | the shipped dotfiles-bootstrap skill — /skills discovers it and runs dot config init with profile-aware safety defaults |
| Cursor / Codex / Windsurf / Zed / Roo / Cline / Aider / Continue / Jules / Antigravity | dot agent context apply regenerates every harness stub from CLAUDE.md; dot agent context check fails when they drift |
| A2A-capable agents | the agent card at .well-known/agent.json, shown by dot agent card show and checked by dot agent card check (docs/interop/A2A.md) |
| Ghostty / Alacritty / Kitty / WezTerm / Warp / iTerm2 / tmux / Neovim / VS Code | themed on every dot theme switch — see Wallpaper-driven themes |
How good is this, really?
The rating is a set of programs, and each one prints the command next to the number.
dot doctor score # system health and security scorecard
dot security score show -j # workstation security posture, JSON
dot doctor --score # tools, paths, portability, AI analysis
make test # the reliability audit CI runs
What the repository can show today:
- OpenSSF Scorecard 8.3 / 10 at the last recorded snapshot
(2026-10-29), written into
docs/security/SCORECARD.mdwith the per-check breakdown byscripts/qa/scorecard-snapshot.sh, run by hand.scorecard.ymlruns the analysis weekly, and the badge above is live. - OpenSSF Best Practices: passing (100%), project 12840.
- Unit, integration, and regression suites, a golden-snapshot suite for
dot --help/version/doctor/perf/health, and aninstall.shfuzz harness — seetests/README.md. - Bash line coverage floor 98% (96% for behavioural tests
alone) measured by pure
xtrace, no kcov, ratcheted up slice by slice with the history recorded incoverage.yml. - Every third-party action SHA-pinned, and Harden Runner in
every workflow except
branch-drift-guard.yml.
The gaps, so nobody has to find them:
- Scorecard's
Code-Reviewcheck scores 0: one maintainer, merges gated by CI rather than by a second reviewer. - OSS-Fuzz onboarding is prepared under
fuzz/oss-fuzz/but not yet submitted; ClusterFuzzLite runs in the meantime. - Repology tracks one packaging (AUR
dot-cli-git); Homebrew and Scoop go through this project's own tap and bucket. - Nushell sits at Tier 3 with under 5% feature parity (ADR-011).
Each number above names the command or the file that produced it.
The Scorecard breakdown is
docs/security/SCORECARD.md, the
coverage history is in
coverage.yml, and
docs/STRUCTURE.md maps every top-level path
to the component that owns it. The rest of this README covers the
framework surface.
One-minute migration from another dotfiles manager
The one-minute version is dot config init. It clones any GitHub user's
dotfiles repository through this harness, refuses to clobber an
existing chezmoi source without --force, insists on HTTPS, and
previews with --dry-run:
dot config init alice --dry-run # preview: what github.com/alice/dotfiles would do
dot config init alice # clone + apply through the dot harness
dot config init https://... --no-apply
Coming from a specific tool? The headline mapping is below, and
dot config init <user> --dry-run shows the repository URL and
target directory it would use before anything is written.
| Coming from | What changes |
|---|---|
| yadm | bare-repo tracking → a chezmoi source tree; yadm alt → .tmpl files driven by .chezmoidata.toml; yadm encrypt → age / SOPS through dot secret |
| GNU Stow | one package directory per tool → one dot_config/<tool>/ tree, deployed by chezmoi apply instead of a symlink farm |
bare git repository (config alias) |
$HOME as work tree → ~/.dotfiles as source; config status → dot status / dot diff |
| plain chezmoi | keep your source tree as it is; gain dot doctor / doctor fix / theme / secret / fleet on top; chezmoi apply → dot sync |
Upgrades between versions of this project are a different document:
docs/operations/MIGRATION.md.
Why this approach?
Most dotfiles repositories are personal collections. This one is
built as workstation infrastructure: chezmoi is the templating
engine (ADR-005), dot is the
lifecycle CLI on top (ADR-004),
and every claim on this page has a test, a workflow, or a document
behind it.
Three choices you will not find in mathiasbynens/, holman/, or
paulirish/:
- Wallpaper-driven terminal themes. K-Means clustering in
CIELAB extracts a palette from any wallpaper; the engine enforces
WCAG AAA (7:1) contrast and writes
themes.tomlitself. 228 generated themes ship today (ADR-009). - First-class agent governance. Bounded profiles (
ask/plan/apply/audit), MCP policy enforcement, A2A discovery, and signed attestation logs for every agent session (docs/security/MCP_POLICY.md,docs/interop/A2A.md). - Verified multi-shell parity. One alias and function hub feeds zsh, bash, fish, nushell, and PowerShell; a parity contract runs the canonical command surface in every available shell on every PR (ADR-007).
Two architectural choices make the rest cheap:
- Lazy hydration. The prompt paints first from static escape
codes; tool initialisations (
mise,atuin,zoxide,starship) run through_cached_eval, which sources cachedinitoutput and invalidates on the binary's mtime and realpath. Heavy binaries resolve asynchronously after the first prompt (ADR-002). - Idempotent, verifiable apply.
dot syncis chezmoi apply plus drift detection;dot doctor fixrepairs tools, symlinks, and missing files;dot doctor rollbackreturns to a known-good state; a chaos test (scripts/ops/chaos.sh) breaks things on purpose to prove the loop closes.
The default install is signed (SSH ed25519 commits enforced on
main), attested (SLSA provenance and Cosign-signed SBOM per
release), multi-platform (macOS, Linux, WSL2, Apple Silicon CI
runners, Windows PowerShell), and schema-checked (.chezmoidata.toml
against config/chezmoidata.schema.json
via taplo on every PR).
Capabilities at a glance
| Theme | Headline deliverables |
|---|---|
| Wallpaper-driven themes | K-Means clustering in CIELAB extracts terminal palettes from any wallpaper; WCAG AAA enforced; Apple-compatible dynamic HEIC dark/light; 228 generated themes; dot theme rebuild |
| AI and MCP native | Agent profiles (dot agent mode), MCP policy and registry audit (dot mcp), agent card, checkpoints and conformance (dot agent), AI commit messages (dot config save), the dot ai cockpit and local gateway |
| Cryptographic attestation | Signed commits and tags, machine-readable workstation evidence (dot attest), policy-bundle releases, the signing check in dot doctor, dot secret check |
| Fleet management | Multi-node status, drift, events, namespaces and RBAC enforcement mode (dot fleet); dot fleet apply over SSH; dot fleet push to bring up a remote host |
| Self-healing | dot doctor fix, dot doctor rollback, dot config export; chezmoi drift, broken symlinks, missing files, checksum-verified tool recovery |
| Sub-second startup | Lazy loading, _cached_eval, mtime-based cache invalidation, realpath sidecar pins; dot doctor perf show, dot doctor perf measure, dot doctor status |
| Multi-shell parity | Tier 1 (full): zsh, bash. Tier 2 (bridged): fish. Tier 3 (compatible): nushell. PowerShell as a contract-tested parity target (tests/integration/test_shell_parity.sh) |
| Private build caches | Go, pip, uv, and Zig caches live under ~/.cache/dot/builds via mise [env]; Cargo keeps a per-project ./target (no shared lock), with sccache sharing dependencies and rust-target-tmp moving ./target out of the repository |
| Encrypted secrets | age and SOPS at rest; macOS Keychain, pass, or age-encrypted store selected by policy; dot secret, dot secret check, dot secret key new, dot secret cert |
| Portable runtimes | mise for managed toolchains with a cross-platform mise.lock; Nix flake for strict reproducibility; dot tool, dot system update |
| Schema-validated config | .chezmoidata.toml checked against a JSON Schema in CI; dot tool export writes a v1-schema environment manifest; the registry index has its own schema |
| Supply chain | SHA-pinned actions, Harden Runner, SLSA L3 provenance, Cosign keyless signing, SPDX SBOM, OpenSSF Scorecard and Best Practices, gitleaks + detect-secrets + TruffleHog, dependency review, CodeQL, Checkov |
Five shells, one alias hub
The dotfiles expose one command surface over five shells through a hub-and-spoke bridge (ADR-007):
- Hub — canonical aliases and functions live once, in Bash/POSIX,
under
defaults/.chezmoitemplates/aliases/anddefaults/.chezmoitemplates/functions/. Adding one propagates to every shell. - Tier 1 (full): zsh, bash — direct inclusion, lazy loading,
_cached_eval, stagedrc.dmodules. - Tier 2 (bridged): fish — a runtime bash bridge with a cached
abbrtable (878 entries source in 34 ms, down from 170 ms when they werealiasfunctions), plus nativedotcompletions. - Tier 3 (compatible): nushell — simple aliases extracted and
cached to
~/.cache/nushell/bash-aliases.nu; functions delegate to bash at roughly 5 ms per call (ADR-011 explains why it stays). - PowerShell — a managed profile, the native
dot.ps1for the daily workflow, and a parity contract that runs on every PR (docs/reference/POWERSHELL_PARITY.md).
tests/integration/test_shell_parity.sh
verifies the canonical command surface and a runtime smoke in every
shell present on the runner; the Reliability Gate workflow adds
WSL and PowerShell contract jobs.
dot cli completion show zsh # completions are generated from the command registry,
dot cli completion show fish # never hand-maintained — bash, zsh, fish, and nu
dot shell alias status --tiers # which alias tiers and ecosystems are enabled here
dot shell alias show gco # provenance and deprecation status of one alias
Comparison
.dotfiles is the only dotfiles distribution in this comparison
that ships wallpaper-derived WCAG-AAA themes, agent governance,
cryptographic attestation, a self-healing CLI, and fleet apply on
top of a stock chezmoi source tree.
| This repo | chezmoi | holman/dotfiles | nikitabobko/dotfiles | |
|---|---|---|---|---|
| Cross-platform (macOS/Linux/WSL) | ✓ | ✓ | macOS-leaning | macOS only |
| Multi-shell parity (zsh/fish/nu/pwsh) | ✓ | — | bash only | zsh only |
| Wallpaper-driven themes (K-Means) | ✓ | — | — | — |
| AI / MCP integration | ✓ | — | — | — |
| Cryptographic attestation | ✓ | — | — | — |
| Self-healing CLI | ✓ | — | — | — |
| Fleet management | ✓ | — | — | — |
| Encrypted secrets (age/SOPS) | ✓ | ✓ | — | — |
| Build artifact redirection | ✓ | — | — | — |
| Schema-validated config | ✓ | — | — | — |
chezmoi is the underlying templating engine. This repo is the
opinionated reference implementation on top of it, and
plain chezmoi users can adopt it without moving their source tree.
Benchmarks
Two budgets are enforced in CI, and both state their method.
dot cold start — tools/ci/dot-cli-startup-bench.sh runs
dot version eleven times under a clean env -i shell and takes
the median. dot-cli-bench.yml
fails the build above the budget on every push and PR touching
bin/dot or scripts/dot/; a median more than 15% over the previous
baseline is a warning.
| Runner | Budget (median of 11) | Observed |
|---|---|---|
Linux (ubuntu-latest) |
150 ms | within budget on every green run |
| macOS | 200 ms | within budget on every green run |
| Local macOS, bash 5.x | — | ~47 ms (recorded in the workflow header and CHANGELOG.md) |
Interactive shell startup — dot doctor perf show (backed by
scripts/diagnostics/perf.sh, hyperfine-style warm-up plus three
runs, mean) measures every installed shell against a per-shell
target, compares with a recorded baseline in
~/.cache/dotfiles/perf-baseline.json, and flags any shell more
than 10% slower. perf-baseline.yml
records the reference weekly on Ubuntu and measures every push to a
feat/** branch that touches shell code.
| Shell | Target (mean) | Override |
|---|---|---|
| zsh | 250 ms | DOTFILES_PERF_TARGET_ZSH_MS |
| bash | 60 ms | DOTFILES_PERF_TARGET_BASH_MS |
| fish | 200 ms | DOTFILES_PERF_TARGET_FISH_MS |
| nushell | 500 ms | DOTFILES_PERF_TARGET_NU_MS |
| PowerShell | 600 ms | DOTFILES_PERF_TARGET_PWSH_MS |
Measured deltas that shipped with their method in CHANGELOG.md:
fish startup 217 ms → 119 ms by emitting the alias bridge as
abbr instead of alias (#963); ~140 ms saved per fish start by
shadowing Homebrew's eager direnv / mise vendor_conf.d hooks;
20–50 ms saved per tool by _cached_eval
(docs/ARCHITECTURE.md).
The original threshold and the hyperfine --warmup 3 --runs 10 "zsh -i -c exit" recipe are in
ADR-002.
Numbers on your own machine:
dot doctor perf show # every installed shell vs its target
dot doctor perf show --baseline # record this machine's known-good point
dot doctor perf measure # per-component startup profile
dot doctor perf --ready # time to heavy-layer readiness
Budgets, baseline lifecycle, and the regression-issue pipeline are
documented in
docs/operations/PERFORMANCE.md;
the harnesses are
tools/ci/dot-cli-startup-bench.sh
and benches/.
Features
| Shells and navigation | Zsh loads in stages through small rc.d modules, not one startup script. Fish uses _cached_eval and deferred loading. Bash ships full parity with zsh for tooling and aliases. Nushell handles structured workflows (Tier 3). PowerShell keeps cross-platform and WSL sessions on the same baseline with a pwsh parity contract in CI. Starship, Zoxide, Atuin, and fzf for navigation and recall. Starship Transient Prompt collapses past prompts to a single glyph on fish; the zsh hook is in place for when upstream lands the matching function (ADR-010). |
| Development and runtimes | mise manages language versions in user space with a cross-platform mise.lock (Linux, macOS, Windows, exact URLs and SHA-256s). Nix Flakes for strict reproducibility when speed is not the priority. Pueue queues long-running tasks instead of extra tabs. Neovim ships as a full Lua editor, not a starter template. Lazygit for terminal git. Build caches (Go, pip, uv, Zig) live under a private ~/.cache/dot/builds; Cargo keeps a per-project ./target. _cached_eval caches expensive tool init output with mtime and realpath invalidation; EVALCACHE_DISABLE=true bypasses it. |
| AI, agents, and MCP | Agent profiles (dot agent mode): ask, plan, apply, audit. Pattern library (dot ai pattern): architect, hardener, refactor, bundled in dot_config/ai/patterns/. MCP policy enforcement (dot mcp). AI commit messages (dot config save). The dot ai cockpit installs and runs Codex, Copilot, Antigravity, Aider, OpenCode and friends from one Bubble Tea TUI; dot ai gateway serve exposes your Claude subscription locally to any Anthropic- or OpenAI-protocol tool (ADR-012, docs/AI.md). Every agent session is logged with a policy hash and an outcome. |
| Security, trust, governance | age and SOPS keep secrets encrypted at rest and out of history. SSH ed25519 signing plus trust metadata back every commit. Gitleaks, detect-secrets, TruffleHog, policy checks, and compliance workflows. dot attest records machine state, policy, prompt, and model metadata in tracked JSON. Telemetry controls and local-first defaults (dot security telemetry apply, dot security dns apply, dot security firewall apply, dot security usb apply, dot security lock apply, dot security disk show). SPDX SBOM and Grype CVE scanning in CI. npm releases authenticate through OIDC trusted publishing with provenance, never a long-lived token. |
| Themes | 228 wallpaper-derived themes, dark and light paired; dot theme, dot theme toggle, dot theme family, dot theme sync with the OS appearance; dot theme wallpaper set rotate and dot theme wallpaper set sync. See Wallpaper-driven themes. |
| Fleet and remote | dot fleet status, drift, events, namespace, RBAC enforce mode; dot fleet apply runs dot sync (or a custom --cmd) on every host in fleet.toml; dot fleet push deploys the environment to a fresh host over SSH; dot config export builds an offline archive. |
| Diagnostics | dot doctor (deep audit, --ai analysis), dot doctor status dashboard, dot doctor score, dot security score show, dot fleet drift, dot doctor snapshot new, dot doctor metric list (JSONL observability), dot shell history list, dot tool list --packages. |
| Distribution | Release archives with a PREFIX / DESTDIR Makefile, man page (share/man/man1/dot.1), generated completions, Homebrew tap, Scoop bucket, AUR, npm, Nix; dot config uninstall removes the managed environment. |
Wallpaper-driven themes
Drop a wallpaper. Get a theme.
dot theme rebuild discovers system wallpapers and your custom
ones. On macOS it looks in /System/Library/Desktop Pictures/. On
Linux it looks in /usr/share/backgrounds/. Custom wallpapers live
in ~/Pictures/Wallpapers/ (DOTFILES_WALLPAPER_DIR overrides).
K-Means clustering in CIELAB colour space extracts the dominant
colours; the engine generates a 16-colour terminal palette, enforces
WCAG AAA contrast (7:1 for fg/bg, accent text on accent, and c15 on
bg), and assembles defaults/.theme-manifest/themes.toml on its own.
Extraction runs four jobs in parallel, results are cached in
~/.cache/dotfiles/themes/, and only changed wallpapers are
regenerated.
| Tier | Source | Format |
|---|---|---|
| System | macOS /System/Library/Desktop Pictures/Linux /usr/share/backgrounds/ |
.heic, .jpg, .png |
| Custom | ~/Pictures/Wallpapers/ (overrides system on name collision) |
Apple-compatible dynamic HEIC (single file, both appearances) |
dot theme # interactive picker (paired themes only)
dot theme set maui # select a family and follow OS appearance
dot theme plan maui --mode auto --json # inspect the pure transaction plan
dot theme tahoe-dark # switch directly
dot theme toggle # swap dark and light within the current family
dot theme mode light # pin a manual appearance
dot theme mode auto # resume following the OS appearance
dot theme family # cycle between theme families
dot theme sync # enable auto mode and sync immediately
dot theme rebuild # regenerate from current wallpapers
Maui is the default family. Its dynamic HEIC supplies both wallpaper
appearances, while the resolved maui-light or maui-dark palette keeps
terminals and applications aligned. On macOS, a LaunchAgent watches the
system appearance preference and reruns the sync automatically. Runtime
selection is machine-local in ~/.config/chezmoi/chezmoi.toml, so using the
picker does not modify the dotfiles checkout.
On theme switch, every managed surface updates. Terminals: Ghostty,
Alacritty, Kitty, WezTerm, Warp, iTerm2, tmux. Editors: Neovim and
VS Code. The theme also sets GTK and icon themes, the macOS accent
colour and dark-mode toggle (with a forced UI refresh), the browser
colour mode, and the wallpaper. On Linux the engine converts HEIC to
PNG through magick or heif-convert.
Full guide: docs/guides/THEMING.md.
Rationale: ADR-009.
Agent governance (ask / plan / apply / audit)
Agents run under a named profile that bounds what they may do, and every run leaves evidence:
dot agent mode list # ask / plan / apply / audit
dot agent mode set plan # switch the active profile
dot agent mode run plan git status # run one command under a profile, with a checkpoint
dot agent check # validate agent-profiles.json and the default
dot agent log # tail the session audit log
dot agent checkpoint list # saved run checkpoints (save / list / show / replay)
dot fleet policy set strict # advisory → strict RBAC for agent profiles
The MCP side is policy-first: dot mcp check audits configured
Model Context Protocol servers against
defaults/dot_config/dotfiles/mcp-policy.json (allowlist, supply
chain, config), and dot mcp list shows the configured servers.
dot attest export writes the workstation's version,
platform, signing settings, active profile, and policy hash as
tracked JSON (docs/operations/ATTESTATION.md).
The A2A agent card and conformance suite are in
docs/interop/A2A.md; the trust model that
ties signing, secrets, profiles, and attestation together is
docs/manual/01-concepts/02-trust-model.md.
Self-healing and rollback
The CLI is idempotent, and it checks its own work.
dot doctor # deep audit: tools, paths, portability, AI analysis
dot doctor fix # auto-fix tools, chezmoi drift, broken symlinks, missing files
dot doctor rollback # return to a previous known-good state
dot doctor snapshot new # capture a baseline to compare against later
Tool recovery is checksum-verified: Nushell, Pueue, Wasmtime, SOPS,
Yazi, and Zellij are restored from exact mise / aqua pins, never
from a mutable release URL. dot doctor status renders the cache and tool
state as a live dashboard (-j for JSON); its output, like
doctor, perf, version, and --help, is pinned by golden
snapshots in tests/snapshots/.
Fleet apply
# ~/.config/dotfiles/fleet.toml (DOTFILES_FLEET_HOSTS overrides the path)
[hosts.laptop]
ssh = "[email protected]"
profile = "workstation"
dot fleet # this node: id, namespace, version, OS, drift, last apply
dot fleet drift # configuration drift across managed files
dot fleet apply # every host runs: dot sync && dot doctor --quiet
dot fleet apply --cmd uptime # or an arbitrary command — this is the trust boundary
dot fleet namespace list # the active namespace (multi-tenant isolation)
dot fleet log show # recent fleet events from the local log
Hostnames are validated against [A-Za-z0-9._@:+/-]+ before any SSH
fan-out; first connections use StrictHostKeyChecking=accept-new,
so pre-populate ~/.ssh/known_hosts if your threat model allows no
TOFU window. dot fleet push brings a fresh machine up over SSH
before it joins the fleet. The concept chapter is
docs/manual/01-concepts/04-fleet.md.
The dot CLI
Commands are spelled dot <domain> [object] <verb> (ADR-020), with
the shortcuts dot apply, sync, diff, status, edit, cd and
update for the daily loop; the tables below group them by intent.
dot help shows the overview, dot help all the full reference,
dot help <keyword> filters it. The
command index is generated from the
plugin manifests (through the command table) and checked in CI.
Start here
dot config init <user> |
Bootstrap any GitHub user's dotfiles repository through this harness |
dot sync |
Apply dotfiles to this machine (--pull to fetch first, --check to preview) |
dot doctor |
Check the environment and surface issues |
dot help tour |
Open the guided tour |
dot agent context apply |
Sync CLAUDE.md → AGENTS.md and every harness stub |
dot fleet apply |
SSH out to every host in ~/.config/dotfiles/fleet.toml |
dot cli list --available |
Browse reusable dotfile modules from the registry |
Daily use
dot status / dot diff |
Show local drift; preview pending changes |
dot edit / dot config add |
Open the source directory; add a file to the source |
dot system update |
Update toolchains, plugins, and dotfiles |
dot config save |
Generate an AI commit message from the staged diff |
dot help |
Find commands by keyword |
Inspect and repair
dot doctor fix |
Auto-fix tools, chezmoi drift, and broken symlinks |
dot doctor rollback |
Return to a previous known-good state |
dot attest export |
Export workstation evidence |
dot config export |
Create an offline tarball of the dotfiles environment |
AI and agents
dot ai |
AI fleet cockpit — run, chat, install, serve a local gateway, cost |
dot mcp |
Inspect MCP policy and registry |
dot agent mode |
Show or set the agent profile (ask / plan / apply / audit) |
dot agent |
Agent metadata, logs, checkpoints, conformance |
dot ai pattern |
List bundled AI patterns (architect, hardener, refactor) |
Configuration commands
dot theme / dot theme rebuild |
Switch theme or regenerate from wallpapers |
dot tool |
Managed tool versions (list, install, update, remove, set, export) |
dot config profile |
Show or switch the active profile |
dot secret |
Edit, show, set, list, export encrypted secrets |
dot theme font install |
Install or patch Nerd Fonts |
Fleet and performance
dot fleet |
Multi-node status, drift, events, namespace |
dot doctor perf show |
Measure shell startup |
dot doctor score / dot security score show |
Health and security scorecards |
dot doctor status |
Live dashboard for caches and tool state |
Full reference: docs/reference/UTILS.md
· manual chapter:
docs/manual/03-reference/01-dot-cli.md
· man dot after install.
Architecture
graph TD
A[User Shell] --> B{dot CLI}
B --> C[Lifecycle: config sync / config apply / doctor rollback / doctor fix]
B --> D[Diagnostics: doctor / doctor drift / doctor perf / doctor score]
B --> E[AI & Agents: ai / mcp / agent / agent mode]
B --> F[Themes: theme / theme rebuild]
B --> G[Fleet & Attest: fleet / attest]
C --> H[Chezmoi Source]
F --> I[Wallpaper Discovery<br/>System + Custom]
I --> J[K-Means CIELAB Engine]
J --> K[themes.toml<br/>WCAG AAA enforced]
K --> H
H --> L[Zsh / Fish / Bash / Nushell / PowerShell]
H --> M[Mise / Nix Toolchains]
H --> N[MCP Policy / Agent Profiles]
L --> O[~/.cache/shell Fast Init]
G --> P[Signed Attestation Logs]
Root layout: bin/ (dispatcher), lib/dot/
(shared bash library), plugins/ (one plugin per dot domain),
defaults/ (the chezmoi source tree, via .chezmoiroot), scripts/
(runtime scripts), tools/ (repo-only ops), install/ (opt-in
provisioning and migration scripts), pkg/ (packaging channel
templates). The
map of every top-level path, with the history of the reorganisation
that produced it, is docs/STRUCTURE.md; the
contributor-facing
design is
docs/ARCHITECTURE.md.
Configuration
Machine data (.chezmoidata.toml)
# defaults/.chezmoidata.toml — repo-wide defaults, schema-checked in CI
dotfiles_version = "0.2.541"
[features]
alias_wrapper = false # confirm destructive aliases
dms = true # Dank Material Shell accents (niri borders, GTK) via dot-theme-sync
ai_theme_sync = true # wallpaper-aware AI CLI appearance
zellij = false
linux_desktop = false # mako, environment.d and systemd user units
[tools]
node_manager = "mise" # mise | fnm | nvm
dot secret also reads an optional [secrets.policy] table
(provider = "auto" | "macos-keychain" | "pass" | "plain-enc",
auto_load) from this file; a [data.secrets.policy] table in ~/.config/chezmoi/chezmoi.toml (written by scripts/ops/setup.sh) overrides it for one host, and DOTFILES_SECRETS_PROVIDER overrides both.
The Lint / Chezmoidata Schema job fails a merge on a wrong type
(a non-boolean flag, an unknown default_shell or node_manager).
It does not catch a misspelt flag or profile name: unknown flags
and custom profiles are allowed
(config/chezmoidata.schema.json).
Per-machine overrides (~/.config/chezmoi/chezmoi.toml)
[data]
profile = "laptop" # laptop | minimal | server
machine = "work-macbook"
default_shell = "zsh"
[data.features]
linux_desktop = false
Hardware presets (macbook-t2, surface-pro, geekom-a9) live in
defaults/.chezmoidata/hardware.toml and are selected with
machine = "<preset>". Run dot sync after editing.
Session flags
| Variable | Default | Effect |
|---|---|---|
DOTFILES_FAST=1 |
0 | Skip heavy layers (zinit, completions) |
DOTFILES_ULTRA_FAST=1 |
0 | Bare minimum shell (aliases + prompt) |
DOTFILES_AI=1 |
1 (exported by the shipped zsh, bash, fish, nu and pwsh profiles) | 1 loads the zsh AI helper scripts; 1 also lets apply build dot-ai-tui (0 is off) |
DOTFILES_PROFILE |
the chezmoi profile |
Read by the OS tuning scripts (scripts/tuning/); .zshrc re-exports it from the chezmoi profile on every start |
DOTFILES_NONINTERACTIVE=1 |
unset | Skip prompts (CI) |
DOTFILES_SILENT=1 |
unset | Suppress non-error output |
DOTFILES_SOURCE_DIR |
~/.dotfiles |
Override the source directory |
DOTFILES_WALLPAPER_DIR |
~/Pictures/Wallpapers |
Custom wallpaper directory |
DOTFILES_DEBUG=1 |
unset | Print shell-init timing to stderr |
The complete list is
docs/manual/03-reference/03-environment.md;
the strategy for choosing chezmoi data over Nix over runtime flags is
docs/CONFIG_STRATEGY.md.
Examples
Run all examples (each one is bounded by a 60 s timeout and executed
in CI by the Examples Contract job):
make examples
Selected examples
| Category | Example | Purpose |
|---|---|---|
| CLI | example-dot-commands |
dot CLI command modules |
example-command-reference |
Complete dot command reference, one usage line per public command |
|
example-cli-utilities |
CLI utility scripts deployed to ~/.local/bin |
|
example-functions |
Shell function library categories | |
| Operations | example-install-uninstall |
Installation and uninstall scripts |
example-ops |
Operations and maintenance scripts | |
example-diagnostics |
Diagnostics and health-check utilities | |
example-platform-contract |
lib/dot/platform.sh: platform id, host OS, the portability contract |
|
example-fleet |
Fleet management (multi-machine dotfiles operations) | |
| Themes | example-theme |
Theme and wallpaper engine |
| Security | example-secrets |
Encrypted secrets (age) management |
example-security |
Security operations and hardening scripts | |
example-git-hooks |
The hook installer and the pre-push reliability gate | |
| AI | example-ai-patterns |
The dot ai fleet: command surface, steering styles, gateway |
| Quality | example-test-suite |
Running the unit and integration suites |
example-testing-framework |
Testing framework capabilities: assertions and mocks | |
example-coverage-gate |
The module coverage gate | |
example-qa |
Quality assurance and validation scripts | |
| Packaging | mise-plugin-dot/ |
A mise plugin that installs dot |
The full set, including one example-dot-* script per dot area,
is in examples/.
When not to use .dotfiles
A few cases where another tool fits better, listed because the short answer is "we don't do that" rather than because of a disagreement on priorities.
You want a dependency-free shell config. The full setup (
install.sh --provision) brings chezmoi, mise, starship, zoxide, atuin, fzf, and a Go toolchain for the TUI satellites. Leaving out--provision(or passing--minimal) andDOTFILES_ULTRA_FAST=1cut that down, but the framework assumes it may install things. A single.zshrcis lighter.You need full parity on nushell. Nushell is Tier 3: simple aliases plus bash-delegated functions, under 5% of the zsh feature set, kept deliberately as a reference target (ADR-011).
You need Windows without WSL to be first-class. The native
dot.ps1covers the daily workflow (apply, status, doctor, mise, agents, fleet status); themes,dot doctor fix, and most diagnostics still need bash. Windows CI verifies the PowerShell surface, not the whole CLI.You are on Fedora or Arch and need CI-backed support. Both are community-supported: the code is expected to work, but the matrix runs Ubuntu, macOS (Apple Silicon on every push, Intel in the weekly extended run), and Windows (
docs/reference/SUPPORT_MATRIX.md).You do not want
applyto run scripts.chezmoi applyruns therun_onchange_*hooks underdefaults/(the Go satellite builds, terminal profiles, fonts, completion caches) when their source changes. They are idempotent and previewable withdot sync --check, but they are scripts running as you. Package and toolchain provisioning underinstall/provision/runs only withinstall.sh --provision.You need a second reviewer on every merge. This is a single-maintainer project gated by CI, DCO, and signed commits, not by code review; the Scorecard
Code-Reviewcheck says so.
If you hit a case that should be on this list, please open an issue; that is how it gets fixed or moved into the supported set.
Development
make # reliability audit: syntax, unit, module coverage, examples, docs + traceability coverage
make test-quick # the same, quick mode
make test-unit # unit only
make test-integration # with integration suites
make examples # run every example under a timeout
make install # stage the dot CLI under $(DESTDIR)$(PREFIX) (default /usr/local)
make uninstall
./tests/framework/test_runner.sh --jobs auto # unit suite, parallel
bash tests/snapshots/test_snapshots.sh # golden CLI output
bash fuzz/install/fuzz_install.sh # install.sh under adversarial input
bash tools/docs/generate-command-index.sh --check
bash scripts/verify-release-versions
Toolchain setup, the task map, and how to reproduce every CI gate
locally are in DEVELOPMENT.md and
docs/operations/TESTING.md. Commit signing,
the DCO trailer, branch names, and the regression-test convention
are in CONTRIBUTING.md. A
devcontainer boots to a working
make for Codespaces.
Fuzzing
Native Go fuzz harnesses ship under
fuzz/ for the
user-input surfaces that were ported out of the shell so they could
be fuzzed at all, among them FuzzValidateName (the name validator
behind lib/dot/utils.sh) and FuzzInitURLResolver (the URL
resolver behind dot config init); the three Go satellites carry
their own in-module harnesses. A shell harness,
fuzz/install/fuzz_install.sh, drives
install.sh itself with unknown flags, garbage positionals, symlink
loops in $HOME, an empty PATH, 4 KB arguments, and NUL bytes in
the environment, and asserts every case exits cleanly or fails fast
but never hangs. It has already found two real bugs (a missing -h
alias; unknown positionals triggering a 30 s network fetch).
fuzz.ymlruns each Go harness for 60 s on every push tomainand on every PR touching the parsing surfaces. Go replays the committed seed corpus undertestdata/fuzz/before exploring, so a fixed crash cannot silently return.cflite_pr.ymlbuilds the ClusterFuzzLite fuzzers (AddressSanitizer) on PRs touching the harnesses or.clusterfuzzlite/, so the build OSS-Fuzz runs cannot break unseen; the fuzzing itself runs infuzz.yml.install-fuzz.ymlruns theinstall.shharness weekly on Ubuntu and macOS, and on every PR touchinginstall.sh; a scheduled failure opens a tracking issue.- OSS-Fuzz: the project definition is ready in
fuzz/oss-fuzz/(libFuzzer, ASan + UBSan, x86_64); the upstream submission togoogle/oss-fuzzhas not been filed yet.
cd fuzz
go test -run TestNothing -fuzz='^FuzzValidateName$' -fuzztime=60s ./...
go test -run TestNothing -fuzz='^FuzzInitURLResolver$' -fuzztime=60s ./...
The harness layout and the OSS-Fuzz submission steps are in
docs/security/FUZZING.md; the shared
corpus lives beside the harnesses under
fuzz/testdata/.
Hardening gates in place of Miri
- ShellCheck at severity
erroris a hard gate on every push (reusable-shell-lint.yml,fail_on_shellcheck: true), withshfmtformatting checked alongside; the same hooks run in pre-commit. Fish and Nushell configs have their own lint jobs. - Coverage by
xtrace, not kcov.tools/ci/run-coverage.shturns onset -xthroughBASH_ENVin every bash process the suite spawns and aggregates the lines that executed. The floor is 98% (96% for behavioural tests alone); the measured history is in the workflow file. A separate 100% module-mapping floor (tests/framework/module_coverage.sh) fails the build when an executable module has no test file at all. - Reliability Gate runs the audit on
ubuntu-latest,macos-latest, andmacos-15(both Apple Silicon), then the examples contract, the WSL contract, and the PowerShell contract (docs/operations/RELIABILITY.md). - Cross-platform portability scan rejects GNU-only
sed,grep, anddateidioms and runs the critical scripts on each OS (cross-platform-test.yml). - Generators cannot drift: the command index is regenerated
from the plugin manifests (through the command table) and diffed;
every version surface (among them
package.json,bin/dot, the man page,lib/dot/bento.sh, this README's badge,CLAUDE.mdandAGENTS.md) is checked against.chezmoidata.toml;.chezmoidata.tomlitself is validated against its JSON Schema.dot agent context checkdoes the same for the AI-harness stubs locally. - Golden snapshots pin the user-facing text of
dot --help,dot version,dot doctor,dot doctor perf show, anddot doctor statusafter scrubbing paths, timings, and colours.
CI
| Workflow | Trigger | Purpose |
|---|---|---|
ci.yml |
push, PR, schedule | Shell / Lua / Fish / Nushell / copyright lint, chezmoidata schema, secrets scan, dependency audit, TruffleHog, SBOM + Grype, link check, tests on Linux, macOS, Windows, Docker |
ci-enforced.yml |
push, PR | The stricter enforced gate reusing the shared lint and test-suite workflows |
reliability-gate.yml |
push, PR | Reliability audit on three runners + examples, WSL, PowerShell contracts |
coverage.yml |
push, PR | xtrace line coverage with the 98% floor and delta gate |
cross-platform-test.yml |
push, PR | Portability scan and runtime checks per OS |
dot-cli-bench.yml / perf-baseline.yml |
push, PR / weekly + feat/** |
Cold-start budget; shell-startup baseline and regression issues |
fuzz.yml / cflite_pr.yml / install-fuzz.yml |
push, PR / PR / weekly + PR | Go harnesses; ClusterFuzzLite; install.sh fuzz |
doc-drift.yml |
push, PR | Command index and version-consistency generators |
dco.yml / pr-signature.yml / verify-tag-signature.yml |
PR / PR / tag | DCO trailer, PR description signature, signed annotated tags |
scorecard.yml / codeql.yml / dependency-review.yml / security-enhanced.yml / deps-dev-validation.yml |
weekly / push, PR | OpenSSF Scorecard, CodeQL, dependency review (fail-on-severity: high), Checkov, deps.dev validation |
release-package-dot.yml / security-release.yml |
release | dot-<v>.tar.gz + .zip with SLSA provenance; SPDX SBOM, Cosign signature, unified ALL_SHA256SUMS manifest |
release-install-smoke.yml / release-distribute-*.yml |
release | Clean-install smoke on Ubuntu + macOS; Homebrew, Scoop, AUR fan-out |
npm-publish.yml / manual-publish.yml / pages.yml |
release, push | npm via OIDC trusted publishing; the manual in nine formats; the site |
The cadence and the composite actions are documented in
docs/operations/CI_CADENCE.md and
docs/operations/CI_COMPOSITES.md.
Security
Reporting: never open a public issue for a vulnerability — use
GitHub Security Advisories
or [email protected]; see
SECURITY.md for the response SLA (Critical: 24 h
initial response, 48 h target; High: 72 h / 7 days; Medium: 5 / 30
business days; Low: 10 / 90), the supported-version table, and the
GPG key for encrypted reports
(docs/security/DISCLOSURE.md,
docs/security/KEY_ROTATION.md).
A dotfiles framework is code that runs as you, on every login, on
every machine you own. The posture below closes the vectors that
matter for that shape — remote script execution, secrets at rest,
agents with shell access, and the pipeline that ships it — at the
architectural level, not behind opt-in flags. The full analysis is
docs/security/THREAT_MODEL.md.
Installer and remote-execution controls
- No unverified download runs. Where
chezmoiis missing,install.shinstalls it with Homebrew whenbrewis present; otherwise it fetches the release tarball throughtools/ci/install-chezmoi-verified.sh, or, when that helper is not beside it, an embedded verifier that checks the tarball against a pinned SHA-256 (and the upstream checksum file when it can fetch it). Either refuses on mismatch and never falls back to a remote script. - Every third-party installer the framework can execute is
allowlisted by SHA-256 in
security/remote-installers.sha256(Claude, Kimi, Goose, Antigravity, xAI, and the rest). CI rejects anycurl | shthat bypasses the verifier. - Size and structure limits.
lib/dot/verified-download.shcaps scripts at 512 KiB and archives at 100 MiB by default, caps checksum manifests at 2 MiB, and fails closed on empty files; registry archives are rejected when they contain path traversal or link entries. Fonts, distro signing keys, and binary archives go through the same path. dot config initis HTTPS-only, refuses to overwrite an existing source directory without--force, and prints the source URL it is about to run scripts from.- Self-healing never fetches mutable URLs. Tool recovery uses exact mise / aqua pins with checksums.
Secrets
dot secretselects a provider by policy — macOS Keychain,pass, or an age-encrypted local store — and loads buckets into the environment on demand (eval "$(dot secret export ai)"), so keys are never in plaintext files or shell history.- age and SOPS encrypt chezmoi-managed secret files at rest;
dot secret initbootstraps the key,dot secret key newencrypts an SSH key locally,dot secret certmanages short-lived certificates. dot secret checkaudits hygiene and leakage surface on the workstation; gitleaks, detect-secrets, and TruffleHog run on every push and in pre-commit; the history-filtering procedure is written down indocs/security/HISTORY_FILTERING.md.
Agents and MCP
- Every agent runs under a bounded profile (
ask/plan/apply/audit) with checkpoints and a session audit log;dot fleet policy set strictturns the profile RBAC from advisory into enforced. - MCP servers must appear in
mcp-policy.jsonand passdot mcp check(policy, supply chain, config) before use. dot attestrecords the workstation state with the policy hash so an audit can check what an agent was allowed to do when it ran.
Supply chain
- Every third-party GitHub Action is pinned to a commit SHA, and
the pins are linted (
Lint / Reusable Workflow Pins). The one tag reference is the SLSA generator reusable workflow, which its maintainers require to be referenced by release tag (docs/security/CI_PINNING.md). - Harden Runner in every workflow except
branch-drift-guard.yml, with the jobs proven local-only in egress-block mode and an explicit endpoint list (docs/security/CI_EGRESS_ALLOWLIST.md). - Releases carry provenance: SLSA L3 build attestation on the
dotarchive (gh attestation verify), an SPDX SBOM signed with Cosign keyless (Fulcio + Rekor), and one signedALL_SHA256SUMSmanifest covering every asset; the verification recipe isdocs/security/VERIFY_RELEASE.md. - Signed everything: SSH ed25519 commit signatures enforced on
main, signed annotated tags verified by workflow, DCO and PR signature checks required, GPG key published over WKD and checked weekly (verify-gpg-wkd.yml). - npm via OIDC trusted publishing with provenance attached, no long-lived token.
- Scans on every push: dependency review (
fail-on-severity: high), CodeQL, Checkov, Grype against the SBOM, Dependabot with grouped updates; OpenSSF Scorecard weekly, with the snapshot indocs/security/SCORECARD.mdrefreshed by hand (scripts/qa/scorecard-snapshot.sh). - SPDX headers on source files, checked by the copyright lint job.
Notes
- Template injection is a real surface for a chezmoi tree:
.tmplfiles render with chezmoi data before deployment, so.chezmoidata.tomlis schema-validated and the trust boundary is documented per surface in the threat model. _cached_evaloutput files under~/.cache/shell/are sourced on startup; the cache key includes the tool binary's mtime and realpath so a swapped binary invalidates its cache.
Documentation
The four entry points, identical across every repo in the family:
- User Manual — the rendered book:
concepts, tutorials, reference, cookbook, appendices; also
dot help --manual,dot help --manual pdf,dot help --manual text | less, anddot help --manual --offlinefrom the bundled snapshot - Command reference — every
dotsubcommand, generated from the plugin manifests;man dotafter install - Developer docs — toolchain, task map, reproducing every CI gate locally
- Family map — what lives in-repo, the component that owns it, and where to make which change
The manual is published in nine formats (single- and multi-page
HTML, PDF, EPUB, ASCII text, compressed variants, Markdown source)
and rebuilds on every change from docs/manual/.
| Document | Covers |
|---|---|
docs/STRUCTURE.md |
Every top-level path, the chezmoi naming contract, where to make which change. |
docs/ARCHITECTURE.md |
Startup strategies, _cached_eval, lazy hydration, artifact and ultra-fast modes. |
docs/adr/ |
Decision records, from CI/CD, shell performance, the CLI architecture and multi-shell parity to plugin trust, read-only MCP isolation, the command naming system and the family's version lockstep. |
docs/reference/ |
Aliases, feature flags, fonts, PowerShell parity, profiles, scripts, support matrix, themes, tools, dot utilities. |
docs/security/ |
Threat model, install verification, fuzzing, secrets, encryption, MCP policy, commit signing, CI pinning, egress allowlist, key rotation, release verification, Scorecard, compliance, incident response. |
docs/operations/ |
Release pipeline, version sync, performance, reliability, coverage, drift, registry, attestation, CI cadence, migration between versions. |
docs/guides/ |
Install, theming, Neovim IDE, troubleshooting, WSL2 + Nix. |
docs/packaging.md |
For distro maintainers: licence grant, toolchain floors, dependency pin model, offline build/test, signature verification. |
SECURITY.md · GOVERNANCE.md · CONTRIBUTING.md · CODE_OF_CONDUCT.md |
Reporting, decision model, contribution workflow, community expectations. |
CHANGELOG.md |
Per-release notes. The complete record — every release appears here. |
AGENTS.md / CLAUDE.md |
Invariants for AI-assisted contributors; CLAUDE.md is canonical, AGENTS.md is rendered from it. |
Acknowledgements
This framework stands on tools whose maintainers did the hard part:
chezmoi for the source-tree
model that makes every apply reproducible, mise
and Nix for toolchains that survive a reinstall,
age and SOPS
for secrets that stay encrypted, and the Charmbracelet libraries
behind the Go satellites. The security posture leans on
Sigstore, SLSA,
OpenSSF Scorecard, and
StepSecurity Harden Runner.
Bug reports with a reproduction and a failing test are the most
useful contribution this project receives; the regression-test
convention in CONTRIBUTING.md exists so that
every one of them stays fixed.
Stability guarantees
Versioning. SemVer with
defaults/.chezmoidata.tomlas the source of truth, mirrored to the non-template version surfaces byscripts/version-sync.shand checked in CI. During the0.2.xseries every release is a patch bump; a change that breaks an existing machine (a renamed command, a moved managed path, a changed flag default) is called out in itsCHANGELOG.mdentry and, where relevant, indocs/operations/MIGRATION.mdwith a migration or rollback script underinstall/migrate/(GOVERNANCE.md).Output stability. For a tool that generates files, output is API. Machine-readable outputs carry a schema version —
dot tool exportconforms todocs/schema/dot-env-v1.json, the registry index todocs/schema/dot-registry-v1.json— and a change to their shape is a new schema version, not an edit tov1. Generated artefacts that other tools consume (themes.toml, shell completions,AGENTS.mdand the harness stubs, the command index) are produced by generators whose output is diffed in CI; a behavioural change to what a generator emits is treated as breaking and recorded in the changelog even when no command-line flag moves. The human-facing text ofdot --help,version,doctor,perf, andhealthis pinned by golden snapshots and changes only with a deliberate snapshot update in the same commit.Minimum toolchain. Raised only with the reason recorded in the
CHANGELOG.mdentry, never silently — policy, version axis, and history indocs/MINIMUM-TOOLCHAIN.md.Deprecations are announced before removal with the removal release named up front:
docs/reference/ALIASES_DEPRECATIONS.mdrecords each deprecated alias, its replacement, and itsRemove Inversion, anddot shell alias show <alias>reports the same from the CLI. The deprecation window is the span between the release that adds the row and the release named inRemove In.
License
Dual-licensed under Apache 2.0 or MIT, at your option. See LICENSE-APACHE and LICENSE-MIT.
See CHANGELOG.md for release history.
THE ARCHITECT ᛫ Sebastien Rousseau THE ENGINE ᛞ EUXIS ᛫ Enterprise Unified Execution Intelligence System