@sebastienrousseau/dotfiles 0.2.500 → 0.2.502
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +154 -0
- package/README.md +113 -45
- package/docs/.vitepress/reports/localization-readability-audit.md +4 -0
- package/docs/AI.md +8 -2
- package/docs/CNAME +1 -0
- package/docs/COPYRIGHT +1 -1
- package/docs/NAMING_CONVENTIONS.md +7 -0
- package/docs/README.md +4 -0
- package/docs/_config.yml +59 -0
- package/docs/adr/ADR-001-ci-cd-pipeline.md +17 -0
- package/docs/adr/ADR-002-shell-performance.md +9 -0
- package/docs/adr/ADR-003-security-first.md +18 -0
- package/docs/adr/ADR-004-cli-architecture.md +14 -0
- package/docs/adr/ADR-005-chezmoi-choice.md +10 -0
- package/docs/adr/ADR-006-shell-selection.md +9 -0
- package/docs/adr/ADR-007-multi-shell-parity.md +10 -1
- package/docs/adr/ADR-008-alias-system-architecture.md +10 -0
- package/docs/adr/ADR-009-wallpaper-driven-theming.md +131 -0
- package/docs/adr/ADR-010-starship-transient-prompt.md +144 -0
- package/docs/adr/ADR-011-nushell-tier3-keep.md +144 -0
- package/docs/adr/README.md +7 -0
- package/docs/architecture/ARCHITECTURE.md +4 -0
- package/docs/architecture/INTEROP.md +8 -0
- package/docs/architecture/REPO_LAYOUT.md +5 -1
- package/docs/architecture/WALKTHROUGH.md +4 -0
- package/docs/architecture/fleet-deployment.md +4 -0
- package/docs/archive/EUXIS_2026_REVIEW.md +11 -3
- package/docs/archive/LEGACY_ROADMAP.md +45 -27
- package/docs/archive/MILESTONE_v0.2.493.md +4 -0
- package/docs/archive/PLAN.md +46 -8
- package/docs/archive/REPO_AUDIT.md +8 -0
- package/docs/guides/INSTALL.md +4 -0
- package/docs/guides/NEOVIM_IDE_GUIDE.md +9 -0
- package/docs/guides/THEMING.md +8 -0
- package/docs/guides/TROUBLESHOOTING.md +28 -0
- package/docs/guides/WSL2_NIX_TROUBLESHOOTING.md +70 -1
- package/docs/index.md +6 -2
- package/docs/interop/A2A.md +7 -0
- package/docs/interop/POWERSHELL.md +102 -0
- package/docs/manual/00-introduction.md +5 -1
- package/docs/manual/01-concepts/01-architecture.md +4 -0
- package/docs/manual/01-concepts/02-trust-model.md +6 -2
- package/docs/manual/01-concepts/03-theme-engine.md +4 -0
- package/docs/manual/01-concepts/04-fleet.md +7 -1
- package/docs/manual/01-concepts/05-self-healing.md +8 -1
- package/docs/manual/02-tutorials/01-first-install.md +5 -0
- package/docs/manual/02-tutorials/02-add-wallpaper.md +5 -0
- package/docs/manual/02-tutorials/03-create-profile.md +6 -0
- package/docs/manual/02-tutorials/04-encrypt-secret.md +6 -0
- package/docs/manual/02-tutorials/05-deploy-fleet.md +5 -1
- package/docs/manual/03-reference/01-dot-cli.md +67 -45
- package/docs/manual/03-reference/02-config-files.md +8 -2
- package/docs/manual/03-reference/03-environment.md +4 -0
- package/docs/manual/03-reference/04-templates.md +7 -1
- package/docs/manual/03-reference/05-feature-flags.md +72 -3
- package/docs/manual/04-cookbook/01-recipes.md +4 -0
- package/docs/manual/04-cookbook/02-troubleshooting.md +32 -0
- package/docs/manual/04-cookbook/03-faq.md +8 -0
- package/docs/manual/05-appendices/A-platform-matrix.md +4 -0
- package/docs/manual/05-appendices/B-security-checklist.md +6 -0
- package/docs/manual/05-appendices/C-glossary.md +4 -0
- package/docs/manual/05-appendices/D-bibliography.md +5 -1
- package/docs/manual/05-appendices/E-license.md +4 -0
- package/docs/manual/_toc.yml +1 -1
- package/docs/manual/command-index.md +16 -8
- package/docs/manual/concept-index.md +4 -0
- package/docs/manual/index.md +66 -0
- package/docs/operations/ATTESTATION.md +5 -0
- package/docs/operations/CI_CADENCE.md +107 -0
- package/docs/operations/CI_COMPOSITES.md +156 -0
- package/docs/operations/COMPLETIONS.md +123 -0
- package/docs/operations/COVERAGE.md +182 -0
- package/docs/operations/DRIFT.md +107 -0
- package/docs/operations/HARD_AUDIT_2026.md +631 -0
- package/docs/operations/MAINTENANCE.md +5 -1
- package/docs/operations/MIGRATION.md +14 -6
- package/docs/operations/OPERATIONS.md +24 -0
- package/docs/operations/PERFORMANCE.md +133 -0
- package/docs/operations/REGISTRY.md +89 -0
- package/docs/operations/RELIABILITY.md +6 -0
- package/docs/operations/ROADMAP.md +36 -18
- package/docs/operations/ROADMAP_2026.md +665 -0
- package/docs/operations/TESTING.md +4 -0
- package/docs/operations/TRACEABILITY.md +7 -0
- package/docs/operations/TRUSTED_AGENT_WORKSTATION.md +4 -0
- package/docs/operations/VERSION_SYNC.md +54 -5
- package/docs/reference/ALIASES.md +7 -0
- package/docs/reference/ALIASES_CHEATSHEET.md +5 -1
- package/docs/reference/ALIASES_DEPRECATIONS.md +5 -1
- package/docs/reference/FEATURES.md +4 -0
- package/docs/reference/FONTS.md +4 -0
- package/docs/reference/POWERSHELL_PARITY.md +80 -0
- package/docs/reference/PROFILES.md +4 -0
- package/docs/reference/SCREENSHOTS.md +4 -0
- package/docs/reference/SCRIPTS.md +4 -0
- package/docs/reference/SUPPORT_MATRIX.md +10 -4
- package/docs/reference/THEMES.md +4 -0
- package/docs/reference/TOOLS.md +4 -0
- package/docs/reference/UTILS.md +16 -12
- package/docs/registry.json +6 -0
- package/docs/security/AI_ACT_COMPLIANCE.md +4 -0
- package/docs/security/AUDIT_BYPASS.md +103 -0
- package/docs/security/AUTOMATION_SECRETS.md +4 -0
- package/docs/security/CI_EGRESS_ALLOWLIST.md +127 -0
- package/docs/security/CI_PINNING.md +113 -0
- package/docs/security/COMMIT_SIGNING.md +138 -0
- package/docs/security/COMPLIANCE.md +5 -0
- package/docs/security/DEPS_DEV_EXCEPTIONS.md +86 -0
- package/docs/security/DISCLOSURE.md +130 -0
- package/docs/security/ENCRYPTION.md +5 -0
- package/docs/security/FMEA.md +4 -0
- package/docs/security/HISTORY_FILTERING.md +132 -0
- package/docs/security/INCIDENT_RESPONSE.md +4 -0
- package/docs/security/INSTALL_VERIFICATION.md +122 -0
- package/docs/security/KEYS.md +4 -0
- package/docs/security/KEY_ROTATION.md +85 -1
- package/docs/security/MCP_POLICY.md +9 -0
- package/docs/security/POLICY_RELEASES.md +4 -0
- package/docs/security/README.md +4 -0
- package/docs/security/SCORECARD.md +140 -0
- package/docs/security/SECRETS.md +12 -0
- package/docs/security/SECURITY.md +4 -0
- package/docs/security/SECURITY_CHECKLIST.md +11 -0
- package/docs/security/SHELL_EXEMPTIONS.md +145 -0
- package/docs/security/SOUP_REGISTER.md +4 -0
- package/docs/security/THREAT_MODEL.md +10 -0
- package/docs/security/VERIFICATION_VALIDATION.md +5 -1
- package/docs/security/security-pubkey.asc +15 -0
- package/docs/themes/README.md +4 -0
- package/docs/themes/VISUAL_INTEGRITY_REPORT.md +4 -0
- package/dot_config/ai/identity.md +3 -0
- package/dot_config/ai/patterns/architect.md +2 -0
- package/dot_config/ai/patterns/hardener.md +2 -0
- package/dot_config/ai/patterns/refactor.md +2 -0
- package/dot_config/alacritty/alacritty.toml.tmpl +3 -3
- package/dot_config/atuin/config.toml.tmpl +47 -0
- package/dot_config/dotfiles/agent-card.json +1 -1
- package/dot_config/dotfiles/boot/README.md +2 -0
- package/dot_config/dotfiles/grub/README.md +2 -0
- package/dot_config/dotfiles/lock/README.md +2 -0
- package/dot_config/fish/conf.d/direnv.fish +4 -0
- package/dot_config/fish/conf.d/init.fish.tmpl +21 -0
- package/dot_config/fish/conf.d/mise-activate.fish +5 -0
- package/dot_config/fish/functions/_cached_eval.fish +84 -11
- package/dot_config/fish/functions/_cached_eval_clear.fish +17 -0
- package/dot_config/foot/foot.ini.tmpl +3 -3
- package/dot_config/fuzzel/fuzzel.ini.tmpl +2 -2
- package/dot_config/ghostty/config.tmpl +3 -3
- package/dot_config/git/hooks/executable_commit-msg +146 -0
- package/dot_config/goose/config.yaml +2 -2
- package/dot_config/gtk-3.0/gtk.css.tmpl +2 -2
- package/dot_config/gtk-3.0/settings.ini.tmpl +2 -2
- package/dot_config/gtk-4.0/gtk.css.tmpl +2 -2
- package/dot_config/gtk-4.0/settings.ini.tmpl +2 -2
- package/dot_config/kitty/kitty.conf.tmpl +3 -3
- package/dot_config/mise/config.toml +1 -1
- package/dot_config/niri/config.kdl.tmpl +2 -2
- package/dot_config/nushell/cached_eval.nu +80 -0
- package/dot_config/nushell/env.nu.tmpl +21 -13
- package/dot_config/shell/00-core-paths.sh.tmpl +9 -1
- package/dot_config/shell/05-core-safety.sh +1 -0
- package/dot_config/shell/10-secrets.sh +1 -0
- package/dot_config/shell/40-fzf-defaults.sh.tmpl +1 -0
- package/dot_config/shell/40-ls-colors.sh +1 -0
- package/dot_config/shell/50-logic-functions-core.sh.tmpl +1 -0
- package/dot_config/shell/50-logic-functions.sh.tmpl +1 -0
- package/dot_config/shell/51-logic-functions-extra.sh.tmpl +1 -0
- package/dot_config/shell/90-ux-aliases.sh.tmpl +1 -0
- package/dot_config/shell/91-ux-aliases-lazy.sh.tmpl +1 -0
- package/dot_config/shell/README.md +25 -8
- package/dot_config/starship.toml.tmpl +2 -2
- package/dot_config/tmux/tmux.conf.tmpl +3 -3
- package/dot_config/user-dirs.dirs +1 -0
- package/dot_config/vscode/settings.json.tmpl +2 -2
- package/dot_config/waybar/config.jsonc.tmpl +2 -2
- package/dot_config/waybar/style.css.tmpl +2 -2
- package/dot_config/wezterm/wezterm.lua.tmpl +3 -3
- package/dot_config/zsh/dot_zshrc.tmpl +207 -17
- package/dot_config/zsh/rc.d/00-alias-shims.zsh +28 -6
- package/dot_config/zsh/rc.d/30-options.zsh.tmpl +27 -7
- package/dot_local/bin/executable_bm +2 -0
- package/dot_local/bin/executable_dot +56 -9
- package/dot_local/bin/executable_dot-bootstrap +0 -1
- package/dot_local/bin/executable_dot-load-benchmark +1 -1
- package/dot_local/bin/executable_dot-theme-sync +8 -8
- package/dot_local/bin/executable_notify +2 -0
- package/dot_local/bin/executable_open +2 -0
- package/dot_local/bin/executable_tour +4 -2
- package/dot_local/bin/executable_up +3 -1
- package/dot_local/share/man/man1/dot.1 +1 -1
- package/dot_local/share/zsh/completions/_dot +4 -0
- package/install.sh +53 -38
- package/package.json +1 -1
- package/scripts/ci/check-dangerous-chmod.sh +19 -0
- package/scripts/ci/check-deps-dev.sh +236 -0
- package/scripts/ci/check-insecure-tls.sh +61 -0
- package/scripts/ci/check-regression-traceability.sh +67 -0
- package/scripts/ci/check-shell-preamble.sh +106 -0
- package/scripts/ci/dot-cli-startup-bench.sh +126 -0
- package/scripts/ci/install-chezmoi-verified.sh +4 -1
- package/scripts/ci/lint-reusable-pins.sh +78 -0
- package/scripts/ci/run-coverage.sh +451 -0
- package/scripts/ci/validate-chezmoidata.sh +25 -0
- package/scripts/ci/windows-smoke-test.ps1 +136 -0
- package/scripts/diagnostics/doctor.sh +203 -5
- package/scripts/diagnostics/drift-dashboard.sh +177 -13
- package/scripts/diagnostics/health.sh +21 -4
- package/scripts/diagnostics/perf.sh +304 -77
- package/scripts/diagnostics/workstation-attestation.sh +6 -1
- package/scripts/dot/commands/agent.sh +33 -27
- package/scripts/dot/commands/agents.sh +325 -0
- package/scripts/dot/commands/ai.sh +75 -10
- package/scripts/dot/commands/aliases.sh +10 -8
- package/scripts/dot/commands/core.sh +10 -4
- package/scripts/dot/commands/fleet.sh +278 -3
- package/scripts/dot/commands/init.sh +184 -0
- package/scripts/dot/commands/meta.sh +7 -4
- package/scripts/dot/commands/registry.sh +263 -0
- package/scripts/dot/commands/tools.sh +49 -1
- package/scripts/dot/lib/bento.sh +2 -1
- package/scripts/dot/lib/log.sh +6 -0
- package/scripts/dot/lib/platform.sh +22 -8
- package/scripts/dot/lib/ui.sh +145 -2
- package/scripts/dot/lib/utils.sh +6 -1
- package/scripts/git-hooks/pre-commit-audit.sh +1 -1
- package/scripts/git-hooks/pre-push +66 -3
- package/scripts/lib/secrets_provider.sh +32 -6
- package/scripts/ops/heal-chezmoi.sh +41 -6
- package/scripts/ops/rollback.sh +14 -0
- package/scripts/qa/powershell-contract.ps1 +95 -0
- package/scripts/security/check-disclosure-key-expiry.sh +110 -0
- package/scripts/security/lock-configs.sh +11 -2
- package/scripts/theme/merge-wallpaper.sh +4 -0
- package/scripts/theme/switch.sh +20 -10
- package/scripts/version-sync.sh +3 -0
- package/dot_config/atuin/config.toml +0 -40
- package/dot_local/bin/__pycache__/executable_dot-load-benchmark-ptycpython-312.pyc +0 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
---
|
|
2
|
+
render_with_liquid: false
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Code Coverage
|
|
6
|
+
|
|
7
|
+
This page documents how coverage is measured, what the threshold is,
|
|
8
|
+
how to run it locally, and how to triage a regression. Closes the
|
|
9
|
+
docs slice of [#856](https://github.com/sebastienrousseau/dotfiles/issues/856).
|
|
10
|
+
|
|
11
|
+
## Why pure bash xtrace (and not kcov)
|
|
12
|
+
|
|
13
|
+
The repo's primary code surface is bash (~140 shell files under
|
|
14
|
+
`scripts/`, hundreds more in `.chezmoitemplates/`). Standard
|
|
15
|
+
language-specific coverage tools (`coverage.py`, `cargo tarpaulin`,
|
|
16
|
+
`go cover`) don't apply.
|
|
17
|
+
|
|
18
|
+
We originally targeted [kcov](https://github.com/SimonKagstrom/kcov),
|
|
19
|
+
but kcov v43 on Ubuntu 24.04 + bash 5.2 cannot produce bash-script
|
|
20
|
+
coverage in any configuration we tried:
|
|
21
|
+
|
|
22
|
+
- Without bash debug symbols, kcov's ptrace backend fails to resolve
|
|
23
|
+
breakpoints and emits zero lines.
|
|
24
|
+
- With `bash-dbgsym` installed, kcov switches into C-binary tracking
|
|
25
|
+
mode and emits coverage entries for bash's internal C headers
|
|
26
|
+
(`ctype.h`, `stdio.h`, `wchar.h`) instead of the `.sh` files we
|
|
27
|
+
want measured.
|
|
28
|
+
|
|
29
|
+
Instead we use bash's own xtrace mechanism:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
PS4='+@COV@:${LINENO}:${BASH_SOURCE}:@ ' # encode line + source
|
|
33
|
+
BASH_ENV=/tmp/cov-setup.sh # `set -x` in every bash
|
|
34
|
+
bash test.sh 2>traces/test.trace # capture stderr per test
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`BASH_ENV` is inherited by every non-interactive bash invocation, so
|
|
38
|
+
subprocess `bash $SCRIPT_FILE` calls inside tests are also traced
|
|
39
|
+
automatically. The runner parses every trace for `:LINENO:FILE:`
|
|
40
|
+
matches and emits standard `lcov.info` that Codecov ingests natively.
|
|
41
|
+
|
|
42
|
+
## Where it runs
|
|
43
|
+
|
|
44
|
+
| Surface | What runs |
|
|
45
|
+
|---|---|
|
|
46
|
+
| **PR + push to master** | `.github/workflows/coverage.yml` → `Coverage / kcov` job → uploads lcov.info to Codecov and fails the build below `MIN_COVERAGE_PCT` (currently `0`, ratcheted up each slice). |
|
|
47
|
+
| **Local dev** | `bash scripts/ci/run-coverage.sh` — works on Linux + macOS (xtrace is a bash primitive, no platform tools needed). |
|
|
48
|
+
| **macOS dev** | Supported. xtrace-based instrumentation runs on macOS bash 3.2+ and Homebrew bash 5.x. |
|
|
49
|
+
|
|
50
|
+
## The current floor
|
|
51
|
+
|
|
52
|
+
`MIN_COVERAGE_PCT=0` in `.github/workflows/coverage.yml`. Slice 1
|
|
53
|
+
of [#883](https://github.com/sebastienrousseau/dotfiles/issues/883)
|
|
54
|
+
established the baseline at **~2.7% measured** (~613 of ~22 500 lines
|
|
55
|
+
across 231 files). Successive slices raised it; the current measured
|
|
56
|
+
value sits at **~47%**.
|
|
57
|
+
|
|
58
|
+
To tighten:
|
|
59
|
+
|
|
60
|
+
1. Land a slice that bumps measured coverage.
|
|
61
|
+
2. Wait until two-three Codecov runs report a stable value (no
|
|
62
|
+
per-PR jitter).
|
|
63
|
+
3. Edit `MIN_COVERAGE_PCT` upward, ideally by ≤15 percentage points
|
|
64
|
+
per bump.
|
|
65
|
+
4. Note the floor change in the commit message + this page.
|
|
66
|
+
|
|
67
|
+
### Why not the 95% target from #883
|
|
68
|
+
|
|
69
|
+
The roadmap originally targeted ≥95% measured. After working through
|
|
70
|
+
all six slices, the achievable ceiling with xtrace-only instrumentation
|
|
71
|
+
is closer to **~50%** on this codebase. The remaining gap is structural,
|
|
72
|
+
not aspirational:
|
|
73
|
+
|
|
74
|
+
- **System-mutation surface** — large parts of the repo orchestrate
|
|
75
|
+
real OS state (`chezmoi apply`, `gpg`, `pass`/`age` keystores,
|
|
76
|
+
`gsettings`, signal-driven app reload, `git reset --hard`,
|
|
77
|
+
filesystem backups). Exercising these requires either a destroyable
|
|
78
|
+
sandbox (Docker / VM) or per-call mocks for every system tool.
|
|
79
|
+
- **Platform-gated branches** — every diagnostic and theme script
|
|
80
|
+
has Darwin / Linux / WSL forks. The xtrace runner only sees the
|
|
81
|
+
fork for the host it ran on; the others remain "uncovered"
|
|
82
|
+
forever from that one run's perspective. CI runs both macOS and
|
|
83
|
+
Linux but reports them separately.
|
|
84
|
+
- **Interactive UIs** — `fzf`, `gum`, `cmatrix`, `niri`, and the
|
|
85
|
+
Ghostty/Tmux reload helpers can't return to the test under
|
|
86
|
+
`bash -x` within a timeout budget. These are excluded at the
|
|
87
|
+
aggregator level.
|
|
88
|
+
- **Animated demo helpers** — same as interactive UIs.
|
|
89
|
+
|
|
90
|
+
`scripts/ci/run-coverage.sh` has a `SKIP_PATHS` set that removes
|
|
91
|
+
genuinely-untestable scripts from the lcov denominator. Within the
|
|
92
|
+
files that remain, individual mutation-only function bodies are
|
|
93
|
+
fenced with `# LCOV_EXCL_START` / `# LCOV_EXCL_STOP` and a one-line
|
|
94
|
+
rationale comment. Every exclusion line names the reason (`rm -rf
|
|
95
|
+
real $HOME`, `signals live apps`, `gpg keystore`, etc.) so future
|
|
96
|
+
maintainers can re-evaluate if the test infrastructure changes.
|
|
97
|
+
|
|
98
|
+
The graduated approach in this doc replaces the original 95% target.
|
|
99
|
+
The honest floor is the achievable one.
|
|
100
|
+
|
|
101
|
+
## Running locally
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
bash scripts/ci/run-coverage.sh # Linux or macOS
|
|
105
|
+
|
|
106
|
+
# Output:
|
|
107
|
+
# coverage/traces/<file>.trace — per-test xtrace logs
|
|
108
|
+
# coverage/lcov.info — lcov-format report Codecov ingests
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Open `coverage/lcov.info` in any lcov visualizer
|
|
112
|
+
(`genhtml coverage/lcov.info -o coverage/html`) for the per-file
|
|
113
|
+
heatmap.
|
|
114
|
+
|
|
115
|
+
## Triaging a regression
|
|
116
|
+
|
|
117
|
+
When the `Coverage / kcov` PR check fails:
|
|
118
|
+
|
|
119
|
+
1. Pull the workflow's `coverage-lcov` artifact (30-day retention).
|
|
120
|
+
2. Compare against the previous master run by downloading its
|
|
121
|
+
`coverage-lcov` artifact too.
|
|
122
|
+
3. Identify the file(s) where the line-coverage dropped.
|
|
123
|
+
4. Either:
|
|
124
|
+
- Add tests covering the new code, or
|
|
125
|
+
- If the new code is provably unreachable in the test corpus
|
|
126
|
+
(e.g., a platform-specific branch only macOS tests exercise),
|
|
127
|
+
update the test suite to invoke it. Don't carve out global
|
|
128
|
+
exemptions — they accumulate.
|
|
129
|
+
|
|
130
|
+
## Why not 100% yet
|
|
131
|
+
|
|
132
|
+
The previous workflow advertised "100% Coverage" without measuring
|
|
133
|
+
anything. Going from `0% measured` to `100% enforced` overnight is a
|
|
134
|
+
recipe for either:
|
|
135
|
+
|
|
136
|
+
- Suppressing the gate to ship anything ("just lower the threshold,
|
|
137
|
+
we'll fix it later"), or
|
|
138
|
+
- Padding the test suite with assertions that don't actually
|
|
139
|
+
exercise the code under test.
|
|
140
|
+
|
|
141
|
+
So this page documents a graduated approach: start with a measured
|
|
142
|
+
floor at 50%, ratchet upward as the test surface catches up to the
|
|
143
|
+
code surface. The previous aspirational "100%" labels in CI/job
|
|
144
|
+
names + branch-protection contexts have been renamed to match
|
|
145
|
+
reality (`Test / Unit Tests` instead of `Test / Unit Tests (100%
|
|
146
|
+
Coverage)`).
|
|
147
|
+
|
|
148
|
+
## Codecov integration
|
|
149
|
+
|
|
150
|
+
Codecov (free OSS tier) is the canonical badge + PR-comment source.
|
|
151
|
+
The upload uses the
|
|
152
|
+
[`codecov/codecov-action`](https://github.com/codecov/codecov-action)
|
|
153
|
+
in tokenless mode (works for public repos out of the box; private
|
|
154
|
+
repos need `CODECOV_TOKEN`).
|
|
155
|
+
|
|
156
|
+
The Codecov GitHub App posts a status check on each PR with the
|
|
157
|
+
line-by-line diff coverage. Combine with this workflow's job-level
|
|
158
|
+
threshold to get two independent signals.
|
|
159
|
+
|
|
160
|
+
## Excluded paths
|
|
161
|
+
|
|
162
|
+
`scripts/ci/run-coverage.sh` excludes:
|
|
163
|
+
|
|
164
|
+
- `tests/**` itself (don't measure coverage of the tests).
|
|
165
|
+
- `.git/`, `node_modules/`.
|
|
166
|
+
- Paths matched by `KCOV_EXCLUDE_PATTERN` (defaults reasonable).
|
|
167
|
+
|
|
168
|
+
Included paths (`KCOV_INCLUDE_PATH`):
|
|
169
|
+
|
|
170
|
+
- `scripts/`
|
|
171
|
+
- `.chezmoitemplates/functions/`
|
|
172
|
+
- `dot_local/bin/`
|
|
173
|
+
|
|
174
|
+
Adjust via the env vars at the top of `run-coverage.sh`.
|
|
175
|
+
|
|
176
|
+
## References
|
|
177
|
+
|
|
178
|
+
- [Bash xtrace + PS4 + BASH_ENV docs](https://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html).
|
|
179
|
+
- [`scripts/ci/run-coverage.sh`](../../scripts/ci/run-coverage.sh).
|
|
180
|
+
- [`.github/workflows/coverage.yml`](../../.github/workflows/coverage.yml).
|
|
181
|
+
- Issue [#856](https://github.com/sebastienrousseau/dotfiles/issues/856) (closed) /
|
|
182
|
+
[#883](https://github.com/sebastienrousseau/dotfiles/issues/883) (coverage roadmap).
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
render_with_liquid: false
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Drift Detection & Remediation
|
|
6
|
+
|
|
7
|
+
This page documents how this repo detects drift between the chezmoi
|
|
8
|
+
source-of-truth and what's actually deployed on a host, how to read
|
|
9
|
+
the report, and how to remediate. Managed under
|
|
10
|
+
[#875](https://github.com/sebastienrousseau/dotfiles/issues/875).
|
|
11
|
+
|
|
12
|
+
## What "drift" means here
|
|
13
|
+
|
|
14
|
+
Four distinct classes are tracked. The same `dot drift` command (and
|
|
15
|
+
the nightly CI workflow) surfaces all four.
|
|
16
|
+
|
|
17
|
+
| Class | Meaning | How to detect | Typical fix |
|
|
18
|
+
|---|---|---|---|
|
|
19
|
+
| **Managed drift** | A chezmoi-managed file's deployed copy differs from what a fresh `chezmoi apply` would produce. The standard case. | `chezmoi status` (M / MM / A / R rows) | Either update the source so apply is idempotent, or accept the deployed change and re-add. |
|
|
20
|
+
| **Untracked source** | The chezmoi source tree contains files git doesn't know about — usually in-progress local edits that haven't been committed. | `git -C <source-dir> ls-files --others --exclude-standard` | Commit, stash, or `.gitignore` the file. |
|
|
21
|
+
| **Orphan deployed** | A file under `$HOME` was previously chezmoi-managed but the source has since been deleted. Chezmoi no longer claims it, so a fresh apply leaves it behind silently. | Inventoried in `${XDG_STATE_HOME}/dotfiles/orphans` (populated by `dot heal` / `dot drift`) | `chezmoi remove --force` the path, or re-add the source if the file is still wanted. |
|
|
22
|
+
| **Stale source** | The deployed file is *newer* than its source. The next `chezmoi apply` would silently revert the user's hand-edit. Reverse-drift trap. | Compare mtimes for each managed target vs the resolved source-path | Promote the deployed change into the source (`chezmoi re-add`) or revert the deployed file. |
|
|
23
|
+
|
|
24
|
+
## Reading the report
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
dot drift # human-readable (uses the ui.sh formatting)
|
|
28
|
+
dot drift --json # single JSON object — used by the nightly workflow
|
|
29
|
+
dot drift --diff # also print `chezmoi diff` for managed drift
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
JSON shape:
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"managed_drift": 0,
|
|
37
|
+
"untracked_source": 0,
|
|
38
|
+
"orphan_deployed": 0,
|
|
39
|
+
"stale_source": 0,
|
|
40
|
+
"total": 0
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Exit code: `0` if every class is clean; `1` if any drift is found;
|
|
45
|
+
`2` if a prerequisite (chezmoi, git) is missing.
|
|
46
|
+
|
|
47
|
+
## How the nightly check works
|
|
48
|
+
|
|
49
|
+
`.github/workflows/drift-detection.yml` runs `dot drift --json` against
|
|
50
|
+
a fresh checkout of `master` every day at 04:00 UTC. If `total != 0`
|
|
51
|
+
it opens (or updates) a tracking issue labelled
|
|
52
|
+
`type:chore + priority:medium` with the JSON summary, full
|
|
53
|
+
`chezmoi diff`, and `chezmoi status` attached as a workflow artifact.
|
|
54
|
+
|
|
55
|
+
The workflow itself ignores the failing exit code (`|| true`) for the
|
|
56
|
+
dashboard step — the actionable signal is the issue, not a red CI
|
|
57
|
+
indicator.
|
|
58
|
+
|
|
59
|
+
## Force a local drift check
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
dot drift # default — what you'd run before opening a PR
|
|
63
|
+
dot drift --json | jq '.' # for scripting / dashboards
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
To force a full re-comparison after a tool upgrade or a force-apply:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
chezmoi apply --refresh-externals # refetch external sources
|
|
70
|
+
dot drift # re-scan
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Historical incidents
|
|
74
|
+
|
|
75
|
+
### 2026-05-12 — `core.hooksPath` drift
|
|
76
|
+
|
|
77
|
+
The deployed `~/.gitconfig` contained a `hooksPath = ~/.git-templates/hooks`
|
|
78
|
+
line that wasn't in `dot_gitconfig.tmpl`. The line had been added
|
|
79
|
+
directly to the deployed file (manually, not via chezmoi), then sat
|
|
80
|
+
silently for weeks while the global `commit-msg` hook (at
|
|
81
|
+
`~/.config/git/hooks/commit-msg`) never fired — because `hooksPath`
|
|
82
|
+
was pointing at an empty directory. The result: every commit
|
|
83
|
+
authored on this machine silently shipped without the
|
|
84
|
+
`Assisted-by:` trailer mandated by `dot_claude/CLAUDE.md`.
|
|
85
|
+
|
|
86
|
+
Detection failure: no nightly drift check existed at the time.
|
|
87
|
+
|
|
88
|
+
Resolution: commit `f060683b` brought `hooksPath` into the chezmoi
|
|
89
|
+
template; this drift class is exactly what the new `stale_source`
|
|
90
|
+
signal catches going forward.
|
|
91
|
+
|
|
92
|
+
This incident is the canonical worked example for why the four-class
|
|
93
|
+
report exists rather than just `chezmoi status`.
|
|
94
|
+
|
|
95
|
+
## Configuration surface
|
|
96
|
+
|
|
97
|
+
| Variable | Default | Purpose |
|
|
98
|
+
|---|---|---|
|
|
99
|
+
| `DOTFILES_DRIFT_SHOW_DIFF` | `0` | When `1`, append `chezmoi diff` (excluding scripts/install/tests) to the report. Equivalent to `--diff`. |
|
|
100
|
+
|
|
101
|
+
## References
|
|
102
|
+
|
|
103
|
+
- `scripts/diagnostics/drift-dashboard.sh` — the dashboard itself.
|
|
104
|
+
- `.github/workflows/drift-detection.yml` — the nightly scanner.
|
|
105
|
+
- `tests/unit/diagnostics/test_drift_dashboard.sh` — JSON contract test.
|
|
106
|
+
- `dot heal` / `dot rollback` — drift remediation commands.
|
|
107
|
+
- Issue [#875](https://github.com/sebastienrousseau/dotfiles/issues/875).
|