UNPKG

@sebastienrousseau/dotfiles

Version:

The Trusted Shell Platform — Universal dotfiles managed by Chezmoi. Features Bash & Zsh for macOS, Linux & WSL. Rust modern tooling & enterprise-grade security.

443 lines (337 loc) 56.8 kB
# Changelog This file documents all notable changes to this project. ## v0.2.503 (unreleased) Polish + cross-platform + Scorecard release **plus** the incremental repo reorganisation per `docs/operations/RFC_v0_2_503_reorganization.md`. The reorg ships in phases across this PR; each phase is independently atomic and verified by `dot lint` + the existing test matrix. ### Added - **`STRUCTURE.md`** + **`scripts/README.md`** — repo-map docs so a new contributor orients in <30s. Explains the chezmoi naming contract that forces the current layout. - **`MAINTAINERS.md`** + **`GOVERNANCE.md`** — formal single-maintainer declaration + decision/RFC process. Required by the OpenSSF Best Practices badge application; contextualises the Scorecard `Code-Review` 0/30 score. - **`docs/operations/ROADMAP_V0_2_503.md`** — seven-workstream scope for this release. - **`docs/operations/RFC_v0_2_503_reorganization.md`** — 267-line formal RFC for the v0.2.503 framework / user-config split. Covers target layout (Debian/aws-cli discipline), `.chezmoiroot` strategy, 7-step idempotent migration script, distribution surface table, ~5-week implementation plan. - **`docs/security/VERIFY_RELEASE.md`** — end-user "how to verify a `dot` release" walkthrough. Three independent attestations (SBOM, Cosign keyless, SLSA L3); identity-bound `cosign verify-blob` recipe; `slsa-verifier` recipe; one-liner `verify-dot-release` shell function. - **`install/{homebrew/dot.rb, scoop/dot.json, aur/PKGBUILD}`** + **`install/README.md`** — distribution-channel scaffolds for the v0.2.503 standalone-CLI tarball. Publication checklist per channel. - **`scripts/qa/check-version-consistency.sh`** — catches drift between `.chezmoidata.toml` (source-of-truth) and the 8 human-visible version surfaces (CLI banner, man page, bento splash, README badge, etc.). `--quiet` mode for hooks; `--fix` for auto-correct. Wired into pre-push. - **`tools/docs/generate-command-index.sh`** — regenerates `docs/manual/command-index.md` from `dot help all` (caught 9 missing entries, 58 → 67). `--check` mode for CI gating. - **`scripts/qa/scorecard-snapshot.sh`** — refreshes the per-check table in `docs/security/SCORECARD.md` from `api.scorecard.dev` between BEGIN/END markers. - **`.github/workflows/doc-drift.yml`** — gates PRs on the two new `--check` hooks (`command-index`, `version-consistency`). - **`.github/ISSUE_TEMPLATE/scorecard.md`** — Scorecard regression issue scaffold matching the triage flow in `SCORECARD.md`. - **`.github/PULL_REQUEST_TEMPLATE.md`** — Euxis signature block embedded so contributors don't trip `pr-signature.yml`. - **`tools/ci/windows-smoke-test.ps1`** — native `chezmoi apply --dry-run` check (no bash required). Catches Go-template syntax errors on Windows. - **README badges** — OpenSSF Best Practices ("in progress") + License (MIT) shields. ### Fixed - **`LICENSE`** — normalised 1284-line MIT+GPL3+GPL2+Apache+QRCode conglomerate to clean 21-line MIT. GitHub's license detector now returns `MIT` (was `NOASSERTION`). Expected effect: Scorecard `License` 9 → 10. - **`.github/workflows/scorecard.yml`** — wired `SCORECARD_TOKEN` PAT path (falls back to `github.token` when absent). Unlocks `Branch-Protection` + `Webhooks` checks from `-1` to 10 once the maintainer creates the PAT (one-time setup, ~5 min per `docs/security/SCORECARD.md`). - **Version sweep** — `scripts/version-sync.sh 0.2.503` across 26 files, plus manual fixups for `bento.sh` banner and man-page header (not in version-sync's file list — now in `check-version-consistency.sh` spec to prevent recurrence). ### Documentation - **`docs/security/SCORECARD.md`** — added baseline snapshot (7.6 / 10 at 2026-05-17), updated "Closed this cycle" log with v0.2.502 + PR #894 SLSA backfill, full PAT-creation walkthrough for unblocking the `-1` checks. ### Reorganisation (per RFC, incremental phases) - **Phase 0 — RFC in-scope.** `RFC_v0_2_503_reorganization.md` repositioned from "deferred to v0.3.0" to "shipping in v0.2.503". CHANGELOG + ROADMAP + scaffold docs updated. - **Phase 1 — `lib/` move.** `scripts/dot/lib/{utils,ui,platform,log,bento}.sh` → `lib/dot/{utils,ui,platform,log,bento}.sh`. Every `source` path in `scripts/dot/commands/*.sh` updated. Non-breaking for end users (lib is not chezmoi-deployed). - **Phase 2 — `bin/` dispatcher.** `dot_local/bin/executable_dot{,-bootstrap,-theme-sync,-load-benchmark-pty}` → `bin/<name>`. Chezmoi-deployed wrappers at the old paths still exec the canonical for backward compatibility on existing installs. - **Phase 3 — `share/` man + completions.** Man pages, zsh completions, and shell-init fragments moved out of `dot_local/share/` into top-level `share/`. - **Phase 4 — `defaults/` + `.chezmoiroot`.** All 33 chezmoi-tracked source paths (every `dot_*`, `private_dot_*`, `run_onchange_*`, `.chezmoi*`) moved into `defaults/`; `.chezmoiroot=defaults` activated. Chezmoi natively re-bases its source-root; the included migration script (`install/migrate/migrate-v0_2-to-v0_2_503.sh`) handles the user-machine transition idempotently. Repo root is now strictly project metadata + framework distribution; all user-config payload lives under `defaults/`. New `resolve_chezmoi_source_dir()` in `lib/dot/utils.sh` separates chezmoi-content lookups from repo-root lookups. - **Phase 5 — `tools/` split.** Repo-only ops (`scripts/{ci,release,maintenance,docs}` → `tools/{ci,release,maintenance,docs}`). 68 references swept across workflows, CHANGELOG, READMEs, PR template, PowerShell parity matrix. - **Phase 6 — automatic seamless migration.** `install/migrate/migrate-v0_2-to-v0_2_503.sh` wired into `install.sh`, `chezmoi run_before` hook, and direct invocation. State-file guard at `$XDG_STATE_HOME/dotfiles/v0_2_503-migration/.complete` ensures real work runs exactly once per host. Snapshot kept for inspection. ### Big-ticket features (per "what else" iterations) - **`dot env emit`** — v1 workstation-environment manifest emitter. JSON Schema 2020-12 at `docs/schema/dot-env-v1.json`; doc + downstream-consumer matrix at `docs/operations/MANIFEST.md`. Closes R3 §7.4 strategic-reversal item ahead of the 2026-09-17 / 2026-09-11 AGNTCon + EU CRA windows. - **Native PowerShell module** — `scripts/dot/powershell/Dot.psm1` + `bin/dot.ps1` dispatcher. `dot version` / `dot help` / `dot agents check` now zero-bash on Windows. POWERSHELL_PARITY.md updated, smoke test extended. - **OSS-Fuzz scaffold** — `oss-fuzz-integration/` ready-to-PR upstream bundle. Two native Go fuzzers (`FuzzValidateName`, `FuzzInitURLResolver`) verified at 2M+ execs each. CI workflow runs them per PR. `docs/security/FUZZING.md` covers onboarding + when-to-add-a-harness. ### Phase 1 hardening (test framework + CI quality gates) - **`DOT_STRICT=1` test mode** — promotes silent `command not found` / `unbound variable` inside `cov_exercise_functions_file` to test failures. Default stays tolerant. Caught the `require_source_dir` regression that escaped pre-v0.2.503 review. Regression test in `tests/unit/misc/test_cov_strict_mode.sh`. Documented in `docs/operations/TESTING.md`. - **Pre-commit drift gates** — `command-index-drift` + `version-consistency` hooks added to `.pre-commit-config.yaml`. Same checks already enforced by `doc-drift.yml` in CI; now also caught at commit time so contributors don't push, wait for CI, and then re-push. - **FINAL SUMMARY per-file failure list** — `test_runner.sh` now lists which test files failed (not just the total count). With 4000+ assertions a single failure was previously a 3-grep search through the run log; now it's at the bottom of the summary. - **`perf-baseline.yml` on push** — added `feat/**` push trigger so regressions catch at PR time, not the Monday cron. Cron remains source-of-truth for the recorded baseline; push runs are measure-only and emit `::warning::` on regression. - **`bump-reusable-pins.yml`** — auto-PR caller workflows (`ci.yml`, `ci-enforced.yml`) when a `reusable-*.yml` merges to master. Closes the two-commit fix-and-bump-pin foot-gun that bit us on the shfmt globstar fix. SHA-pinned, signed via `ACTIONS_BOT_SIGNING_KEY`. ### Phase 2 release engineering (signing + packaging + distribution) - **`release-package-dot.yml`** — on `release.created`, stages bin/lib/share/completions into a canonical `dot-VERSION/` tree and produces a deterministic `dot-VERSION.tar.gz` + `.zip` (sorted, TZ=UTC, owner=0, zip -X -D). Reproducible across runners. Uploaded as release assets. - **`security-release.yml` manifest job** — on `release.published`, builds `ALL_SHA256SUMS` over every release asset and Cosign-keyless-signs it. One signed manifest now covers every artefact in a release; downstream verification is `cosign verify-blob ALL_SHA256SUMS` then `sha256sum -c ALL_SHA256SUMS`. SBOM + SLSA L3 provenance were already in place. - **`release-attestation-check.yml`** — weekly watchdog that walks the latest release, asserts the full attestation bundle (SBOM + sig + cert + intoto + manifest + sig + cert) is present, opens / comments on a tracking issue if anything is missing. Catches silent upload failures the release-time workflow can't detect. - **`release-distribute-{homebrew,scoop,aur}.yml`** — three sibling workflows that, on `release.published`, hash the new release artefacts and ship to each distribution channel. Homebrew + Scoop open PRs to `sebastienrousseau/{homebrew-tap,scoop-bucket}`. AUR pushes directly to `ssh://aur@aur.archlinux.org/dotfiles-git.git` via `AUR_SSH_KEY`. All idempotent, signed-commit, default-branch-detection, comment-on-existing-PR for re-runs. Three were drafted by Mistral Vibe via the new delegator (see below); 49% saved vs Claude. - **`docs/operations/RELEASE_PIPELINE.md`** — end-to-end map of all five release workflows, their triggers, dependencies, and secrets. Single source of truth for the release flow. ### AI cost optimization - **`/vibe` Claude Code skill** ported from [pcx-wave/vibe-skill](https://github.com/pcx-wave/vibe-skill) and shipped via chezmoi to `~/.claude/skills/vibe/`. Delegates coding tasks to a cheap model (Mistral Vibe / DeepSeek / Gemini Flash) while Claude only sees the final `git diff` + tool-call summary (~500-1500 tokens per delegation regardless of how many file reads happen internally). Slash commands: `/vibe`, `/vibeon`, `/vibeoff`, `/vibestatus`, `/vibe-model-pick`, `/vibe-model-clear`, `/vibe-report`. - **`dot ai delegate "<prompt>"`** + **`dot ai cost [--since N]`** — CLI shims so the same delegator + cost reporter work from the terminal without Claude Code. Both expose the underlying `vibe-delegate` / `delegate-report` tools deployed by the skill. - **Unified provider log** — every `dot ai <provider>` invocation now appends a JSONL entry to `~/.local/share/delegate-runs.jsonl`, so `dot ai cost` reports spend across Claude + Gemini + Aider + Vibe etc., not just Vibe. Token-level fields stay zero for providers that don't surface them; the report tolerates the gap. - **`docs/architecture/AI_COST_OPTIMIZATION.md`** — pattern, prices, deployed pieces, state files, provider coverage matrix, future work (budget guard, prompt cache, model routing, rate-limit awareness). ## v0.2.502 — 2026-05-17 ### Added - **`dot agents`** — multi-harness AI agent context generator. `CLAUDE.md` is canonical; `dot agents render` mirrors it into `AGENTS.md` (the cross-harness standard read by Codex/Copilot/Cursor/Windsurf/Amp/Devin), `.cursor/rules/dotfiles.mdc`, and `.codex/config.toml`. `dot agents check` returns rc 0 when in sync (suitable for a pre-commit hook). Round-1 audit gap #1 closed. - **`dot init <github-user|owner/repo|url>`** — analogue to `chezmoi init`. Bootstrap a foreign dotfiles repo through this framework's harness with `--dry-run`, `--no-apply`, `--force` flags; an interactive trust prompt warns before SSH/HTTPS clones; refuses plain HTTP. Owner/repo and bare-user shorthands validated against `[A-Za-z0-9._-]+` to block shell-metacharacter injection. - **`dot fleet apply`** — SSH-based fleet reconciliation across hosts in `~/.config/dotfiles/fleet.toml`. Parallel fan-out (default 4-way) via background-job semaphore (no `xargs -d` so it works on macOS BSD xargs too). Hostnames validated against `[A-Za-z0-9._@:+/-]+` before fan-out. Flags: `--host`, `--cmd "<shell>"` (trust boundary — warning shown), `--dry-run`, `--jobs <n>`. Per-host stderr captured; collision-safe `mktemp -d -t dotfiles-fleet.XXXXXX` temp dir. - **`dot registry`** — JSON-indexed module marketplace scaffold. Subcommands `list / search / info / install / url / set-url`. Default registry at `https://sebastienrousseau.github.io/dotfiles/registry.json` (published from `docs/registry.json` via GitHub Pages). 6h cache TTL; `set-url` validates HTTPS-only (or `file://` for testing) and writes atomically via `mktemp + mv`. Full module contract + contribution flow in [`docs/operations/REGISTRY.md`](docs/operations/REGISTRY.md). - **Sub-100ms CLI cold-start gate** — `tools/ci/dot-cli-startup-bench.sh` measures median dispatcher startup under a clean `env -i`. New workflow `.github/workflows/dot-cli-bench.yml` runs on every PR touching `bin/dot` or `scripts/dot/**`. Current observation: median 47ms locally; CI budget 250ms. - **`docs/operations/HARD_AUDIT_2026.md`** — consolidated audit (round 1 + round 2 addendum) of operational reliability, performance, documentation accuracy, cross-platform parity, security posture, competitor positioning, 2026 industry trends, and adoption playbook. Produced from twelve parallel research-agent runs. ### Fixed - **`install.sh`** — removed the unverified `get.chezmoi.io` curl|sh fallback. The SHA256-verified installer is now the only path; if it fails, we refuse to bootstrap rather than silently degrading (H6). - **`scripts/dot/lib/platform.sh`** — `dot_path_to_unix` / `dot_path_to_native` return rc 2 with a stderr error when called in WSL without `wslpath`, instead of silently echoing a Windows-format path (H9). - **`bin/dot`** — user-provided custom commands now run in a subshell so a `exit` in the user script can't kill the whole CLI (H1). - **`scripts/dot/commands/fleet.sh`** — `dot fleet namespace set` writes via `mktemp + mv` instead of the brittle GNU/BSD `sed -i` dance (H3). - **`dot_config/zsh/dot_zshrc.tmpl`** — `_cached_eval` uses `mktemp` instead of `${cache}.tmp.$$`, eliminating the PID-collision race under shell recycling (H4). - **`scripts/dot/commands/meta.sh`** — cache-clear uses `find ... -type f -delete` with a directory guard instead of `rm -rf "$cache_dir/zsh"/*-init.zsh`, which expanded the literal pattern when no files matched (H5). - **`scripts/dot/commands/agent.sh`** — replaced three `set +e / "$@" / set -e` blocks with idiomatic `if !` so bash errexit suspension is implicit (M4). - **`scripts/dot/commands/core.sh`** — `cmd_status` captures chezmoi stderr and inspects the exit code, so a chezmoi crash is now distinguishable from a clean tree (M1). - **`scripts/dot/lib/ui.sh`** — `ui_run_cmd` guards the rc-file read with `[[ -s ]]` to avoid races between the subshell write and the parent read (M3). - **`scripts/security/lock-configs.sh`** — pre-checks `sudo` availability and TTY attachment before attempting `chattr +i`, instead of failing per-file in automation (M5). - **`tools/ci/install-chezmoi-verified.sh`** — unsupported-architecture error now names the supported set (x86_64/amd64, arm64/aarch64) and points at the upstream release page (M7). - **`docs/manual/03-reference/01-dot-cli.md`** + **`docs/manual/command-index.md`** — removed six commands that were documented but never shipped (`dot verify`, `dot benchmark`, `dot prewarm`, `dot clean-cache`, `dot remove`, `dot update`). Added the new `agents`, `init`, `registry`, and `fleet apply` sections (C3). - **Version drift** — bumped `v0.2.501` → `v0.2.502` in five doc surfaces (`docs/manual/00-introduction.md`, `docs/manual/_toc.yml`, `docs/index.md`, `docs/manual/03-reference/02-config-files.md` × 2) (C2). - **`docs/manual/index.md`** — new landing page for `https://doc.dotfiles.io/manual/` (the Jekyll site was 404ing because `jekyll-readme-index` had no `README.md`/`index.md` to render in `docs/manual/`). ### Security - **`scripts/dot/commands/agents.sh`** — render only writes when the resolved root contains `.chezmoidata.toml`, so a user running `dot agents render` from inside an unrelated git repo can't accidentally write agent configs there. Output files get explicit `chmod 0644`. - **`scripts/dot/commands/init.sh`** — owner/repo and bare-user shorthands are now validated against `[A-Za-z0-9._-]+` before URL construction. - **`scripts/dot/commands/fleet.sh`** — hostnames validated against `[A-Za-z0-9._@:+/-]+` before SSH fan-out; an attacker controlling `fleet.toml` can no longer inject shell metacharacters. - **`scripts/dot/commands/registry.sh`** — `set-url` refuses non-HTTPS schemes (with a `file://` exemption for local testing) and writes config atomically. ### Documentation - **`docs/operations/REGISTRY.md`** — module contract, JSON schema, and contribution flow for the new registry. - **`docs/operations/COVERAGE.md`** — documents the achieved unit-test floor (~47%) plus the structural ceiling for xtrace-only instrumentation; closes #883. ### Round 3 (HARD_AUDIT_2026.md Part 7) - **C1 closed — GPG disclosure key published.** Generated `security@sebastienrousseau.com` ed25519 + cv25519 keypair, fingerprint `55AFAD364FD9DB3819E61F0C8D688FAFA9144693`, expires 2029-05-15. Published to WKD at `sebastienrousseau.github.io/.well-known/openpgpkey/`. Repo carries the armored public key at `docs/security/security-pubkey.asc`. - **`.github/workflows/verify-gpg-wkd.yml`** (N1) — imports both the in-repo `.asc` and the live WKD-fetched key, compares fingerprints, fails loud on mismatch. Runs on push/PR + weekly schedule (Mondays 09:00 UTC). Wires the expiry monitor as the final step. - **`scripts/security/check-disclosure-key-expiry.sh`** (N2) — monitors the 2029-05-15 expiry; warns at 90 days remaining, fails CI at 30 days. - **`dot fleet apply --verify-hosts`** (N4) — closes the TOFU window per-invocation. Aborts the apply unless every host in `fleet.toml` is already present in `~/.ssh/known_hosts`. - **`install.sh` Charm GPG pin** (N5) — pins `CHARM_GPG_EXPECTED_FPR=C026D31B92F9BBE91D5DB75AB07AE17C9E0A6585`; aborts (removing the keyring file) on mismatch. - **`scripts/lib/secrets_provider.sh` exit codes** (N6) — `dot_secrets_get` now returns `2` (no provider), `3` (provider returned empty / key not found), or the provider's own rc; stderr names provider + key for diagnosis. - **R3 docs drifts** — purged 5 orphan dispatch routes + 1 orphan help-table entry in `bin/dot`; relabelled `dot agents` + `dot fleet apply` from "Full" to "Stub (bash-bridged)" on Windows-native in `docs/reference/POWERSHELL_PARITY.md`; corrected Microsoft Build 2026 date from "2026-05-19 in Seattle" to actual `2026-06-02 to 2026-06-03 in San Francisco (Fort Mason)` in `ROADMAP_2026.md`. - **R3 mocked-SSH test catches 2 real bugs.** `tests/unit/fleet/test_fleet_apply_mocked_ssh.sh` (5 tests with PATH-shim overriding `ssh`) caught: (a) subshell counter loss via pipe — fixed with `done < <(printf '%s\n' "$entries")`; (b) RETURN trap referencing `local tmpdir` failed under `set -u` — fixed with `printf -v _cleanup 'rm -rf %q' "$tmpdir"`. - **R3 strategic reversal.** Ship `dot env emit` BEFORE `--attest` (driven by AGNTCon Amsterdam 2026-09-17 deadline + EU CRA SBOM binding 2026-09-11). Full rationale in `HARD_AUDIT_2026.md` §7.4. ### Round 4 (HARD_AUDIT_2026.md Part 8) - **Zero reliability findings** — second consecutive 0-finding round. 4 of 5 candidate perf claims were false positives (SSH-agent guard, completion-chain forks, FNM completion, carapace defer) caught by live verification. - **Documentation completeness fixes:** - `README.md` — removed 4 stale references to ghost commands `dot verify` / `dot benchmark` / `dot prewarm` (none ship). Routed to `dot secrets verify`, `dot perf`, `dot health`. - `docs/manual/03-reference/05-feature-flags.md` — documented the 9 previously-undocumented flags (`alias_wrapper`, `zellij`, `fuzzel`, `mako`, `foot`, `kanshi`, `touch`, `t2`, `surface`) with purpose + platform applicability + requirements. - `dot_local/share/man/man1/dot.1` — header bumped `v0.2.500 → v0.2.502`, `April → May 2026`. - `dot_config/zsh/rc.d/30-options.zsh.tmpl` — completion-block comment no longer references the non-existent `dot prewarm`. - **Strategic outputs** (deferred to follow-up PRs / R5): - OSPS Baseline v2026.02.19 Level-2 adoption path documented as the cross-walk for EU CRA Article 24, NIS2 Article 21, SSDF v1.2. - **R5 headline** identified: Shai-Hulud-class personal-device defence (credential-locality policy + honeytoken + shell-init integrity manifest + post-incident playbook in `SECURITY.md`). - **Strategic leapfrog** identified: `dot attest --format=trustmee-wasm` — Wasm-verifiable workstation attestation (composes SLSA-Graduated + arXiv:2602.13148 TrustMee + MCP-exposed workstation state). No competitor reaches this. - **Top-5 de-facto adoption gaps**: Homebrew tap, AUR `PKGBUILD`, Scoop manifest, Hyprland config, awesome-dotfiles listing. ### Performance + polish (post-R4) - **`dot_config/zsh/dot_zshrc.tmpl`** — `_cached_eval_impl` writes use `>|` (force-clobber) instead of `>`, so the just-`mktemp`'d temp file is not rejected when the user has `setopt noclobber` set globally via `dot_config/shell/05-core-safety.sh:15`. Fixes the `_cached_eval_impl:64: file exists` warning surfaced on every interactive shell with a cache miss. - **`dot_config/shell/00-core-paths.sh.tmpl`** — system paths added via `path_prepend` (which removes duplicates first) instead of `PATH="...:${PATH}"`, eliminating the duplicate-system-path bloat that accumulates when the parent shell already had those entries (macOS launchd default). - **`dot_config/zsh/dot_zshrc.tmpl`** — re-apply `typeset -U path` after `_dotfiles_async_init` runs cached `export PATH=...` from mise/atuin/etc, since those bypass zsh's `-U` flag on the `path` array. - **`scripts/diagnostics/doctor.sh`** — only flag tools that actually emit shell-init eval and are not already lazy-loaded; raise PATH-length thresholds (60 ok / 120 warn) to match a populated mise-managed dev machine; skip `nu` when `cached_eval.nu` is present. - **`dot_config/git/hooks/executable_commit-msg`** — replaced hardcoded `/Users/seb` path with `${HOME}` so the hook is portable across hosts. - **`dot_config/fish/conf.d/{direnv,mise-activate}.fish`** — empty shadow files that override Homebrew `vendor_conf.d` to prevent eager init. fish dedupes `conf.d/` by basename, user wins. Saves ~140ms on every fish shell start; both tools are loaded lazily via `_cached_eval` in `init.fish`. - **`.devcontainer/Dockerfile`** — chezmoi install now goes through `tools/ci/install-chezmoi-verified.sh` (SHA256-verified) instead of the unverified `curl -fsSL https://get.chezmoi.io` fallback. Closes R4 §8.3 P3 / mirrors R1 H6 fix in `install.sh`. - **`typos.toml`** — extended file exclusions (`**/*.asc`, `**/*.pgp`, `**/*.gpg`, `**/*.sig`) to skip armored cryptographic blobs; added `fpr` / `FPR` to the allow-list (GPG `--with-colons` fingerprint column label). ## v0.2.501 ### Added - **Warp + iTerm2 theme support** — the two terminals the theme system did not yet cover are now first-class. `dot_warp/themes/dotfiles.yaml.tmpl` deploys a Warp theme; `run_onchange_22-iterm2-profile.sh.tmpl` writes an iTerm2 Dynamic Profile to `~/Library/Application Support/iTerm2/DynamicProfiles/dotfiles.json`. Both pick up the active theme's `.term` palette, so one `chezmoi apply` switches all six supported terminals (kitty, alacritty, wezterm, foot, warp, iterm2). The README's "Why this repo is different" surface lists this under wallpaper-driven themes. - **Starship Transient Prompt (fish)** — `dot_config/fish/conf.d/init.fish.tmpl` calls `enable_transience` after the cached `starship init`, collapsing past prompts to the `[character]` glyph in scrollback. The zsh implementation is a forward-compatibility hook only — Starship 1.24.2 does not yet ship `enable_transience` for zsh (upstream tracker [starship/starship#3522](https://github.com/starship/starship/issues/3522)). Rationale and rejected alternatives recorded in [ADR-010](docs/adr/ADR-010-starship-transient-prompt.md). - **`_cached_eval` enhancements (#847)** — `EVALCACHE_DISABLE=true` bypass for debugging, realpath sidecar pin to catch PATH-shadow swaps, file-path argument mtime check, init-failure handling (warns and returns rc instead of caching an empty output), and a new `_cached_eval_clear` helper. Applied to all three implementations (zsh, bash, fish). Adds shdoc docstrings. - **JSON Schema for `.chezmoidata.toml`** — `config/chezmoidata.schema.json` (draft-07) plus `.taplo.toml` and a new `lint-chezmoidata` CI job. Catches typos in feature flags, profile names, `default_shell`, and `node_manager` at PR time. - **OIDC trusted publishing for npm (#836)** — `publish-npm` workflow authenticates via OIDC instead of a long-lived `NPM_TOKEN`. Provenance is attached to every published tarball. The migration is breaking on the CI side: `NPM_TOKEN` is no longer used. **Manual followup needed before the first OIDC release**: configure Trusted Publishing on npmjs.com for `@sebastienrousseau/dotfiles` pointing at `sebastienrousseau/dotfiles` + `.github/workflows/npm-publish.yml`. - **`lint-copyright` in `ci.yml` (#834)** — the fast CI pipeline now runs the reusable copyright-header lint. Previously only `ci-enforced.yml` ran it. - **Test coverage roadmap, Slices 1–5d (#883)** — replaced the broken kcov pipeline with a pure bash xtrace runner that works on Linux and macOS. Eight iterations land the floor at **33% measured, 36.73% real (5,783 / 15,744 lines)**: - Slice 1: 2.72% baseline + xtrace runner (`PS4 + BASH_ENV`). - Slice 2: 12.01% — 59 shallow → deep conversions via new `tests/framework/coverage_helpers.sh` (sandbox + safe-mode entry-point exercise). - Slice 3: 18.90% — 47 auto-generated exercise tests + 119 deep conversions. - Slice 4: 19.16% — smart-output shims (`chezmoi`, `git`, `curl`) and subcommand probes. - Slice 5: 34.10% — `cov_exercise_functions_file` helper (source + call each function), sandbox `$HOME/.dotfiles` symlink unblocks scripts that guard on a managed checkout, `test_auto_dot_driver.sh` drives the top-level `dot` dispatcher through 70 read-only subcommands, aggregator filters lines after `set +o xtrace` (intentionally unmeasurable in `security-score.sh` / `scorecard.sh`) and structural-only keywords (`fi`, `done`, etc.). - Slice 5b: 33.73% honest — PS4 `set -u` guard (`${BASH_SOURCE:-}`) and SF: path canonicalization (collapses duplicate keys like `commands/../lib/log.sh`). - Slice 5c: 36.10% — `cov_exercise_functions_file` added to every existing auto-test. - Slice 5d: 36.73% — seven more auto-tests for scripts the existing-test scan had skipped. `MIN_COVERAGE_PCT` floor: 0 → 10 → 17 → 18 → 30 → **33** (3-point cushion absorbs cross-platform jitter). - **GitHub Pages deploy of `docs/` to doc.dotfiles.io** — new `.github/workflows/pages.yml` builds the Jekyll site (cayman theme, kramdown, Liquid disabled for chezmoi-template snippets) and publishes on every push to master that touches `docs/**`. Replaces the old approach where `manual-publish.yml` deployed the multi-format manual to Pages. - **PR consolidation — 8 Dependabot bumps (#839–#846)** — major bumps: `actions/deploy-pages` 4→5, `softprops/action-gh-release` 2→3, `actions/download-artifact` 4→8.0.1, `docker/setup-buildx-action` 3→4, `actions/upload-pages-artifact` 3→5, `actions/github-script` 8→9. Minor and SHA-only refreshes for `actions/cache`, `actions/setup-node`, `bridgecrewio/checkov-action`, `devcontainers/ci`, `docker/login-action`, the `github/codeql-action` family, and `trufflesecurity/trufflehog`. All actions remain pinned by full commit SHA. - **Re-source guards** on the five shared library files where re-sourcing would corrupt state: `tests/framework/{assertions,mocks}.sh` and `scripts/dot/lib/{utils,ui,log}.sh`. - **`tests/unit/ci/test_validate_chezmoidata.sh`** — 13 assertions covering the new schema-validator script. Restores the 100% module-coverage floor that the schema commit had broken. - **`tests/unit/ci/test_check_*.sh`** — four new module-coverage tests for `check-insecure-tls`, `check-dangerous-chmod`, `check-regression-traceability`, and `run-coverage`. Keeps module coverage at 221/221. - **`docs/operations/COVERAGE.md`** — documents the why-not-kcov decision (Ubuntu 24.04 bash 5.2 incompatibility) and the xtrace approach (`PS4 + BASH_ENV`). - **`.chezmoiignore`** — new file at the repo root. Excludes 880 → 408 paths from chezmoi's managed surface: build artifacts (`coverage/`, `nightly-reports/`, `_build/`), repo metadata (`README.md`, `CHANGELOG.md`, `LICENSE`, `.github/`, `.git/`), documentation tree (`docs/`, intended for doc.dotfiles.io, not `$HOME`), and CI scaffolding (`scripts/`, `tests/`, `examples/`, `install/`, `nix/`, `config/`, `.well-known/`). Also gates `dot_warp/` to macOS via a template conditional. Before this file, any developer machine that had run the test suite locally would have ~600 MB of coverage trace data deployed under `~/coverage/` on the next `chezmoi apply`. - **Goose and Codex CLI in `dot ai`** — both AI agents now appear in the status surface under "Agents (autonomous)". `goose` and `codex` are wired in `_ai_mise_pkg` (so `dot ai-setup` knows their install targets), in the bridge `case` (so `dot goose --pattern X "prompt"` and `dot codex --pattern X "prompt"` route correctly), and in the route table in `bin/dot`. - **Spinner feedback on slow operations** — `dot ai` now shows `Probing N AI tools (cached for 300s)…` during the cold-cache refresh. Previously the command sat silent for 15–30s on the first run after the 5-min TTL expired. ### Changed - **README rewrite for accuracy and readability** — three concrete inaccuracies fixed: PowerShell was incorrectly listed as Tier-3 (ADR-007 does not place it in the tier system), `dot bundle --manual` was a flag that does not exist (correct command is `dot manual --offline`), and the supported-terminal list missed Warp and iTerm2. Six coverage gaps filled (Starship Transient, JSON Schema, OIDC, `_cached_eval` enhancements, Bash as explicit Tier-1, and several previously-unmentioned `dot` subcommands). Command count corrected from "30+" to "over 80". Flesch baseline 28.3 → 42.9 raw / 47.7 prose-only. - **Header badges unified to `for-the-badge` style** — OpenSSF Scorecard and Codespaces badges now use shields.io renderings at the same height as Build / Version / Downloads. - **`manual-publish.yml`** — Pages-deploy steps removed. The workflow now only builds the multi-format manual and attaches it to releases. - **Coverage runner is now Linux + macOS** — the kcov-only runner had a hard Darwin skip. The xtrace runner works on both, so the pre-commit hook can invoke it on developer machines regardless of platform. - **`MIN_COVERAGE_PCT` in `.github/workflows/coverage.yml`** — raised from aspirational `50` (which never measured anything) to a real `10` floor based on the Slice 2 baseline. Ratchets up with each subsequent slice. - **`dot ai` runs probes in parallel** — the 14-tool cold-cache refresh now runs via `xargs -P` (defaults to `$(nproc)` workers, override via `DOTFILES_AI_PROBE_JOBS`). Cold-cache wall-time on a fast laptop: 6.2s → 1.9s. Warm-cache (within the 5-min TTL): ~0.07s, unchanged. ### Fixed - **`core.hooksPath` config gap** — the global `commit-msg` hook is now tracked under chezmoi and pointed at by the user's git config, so the AI-attribution trailer fires on every commit. - **Liquid templating false-mangle of chezmoi snippets in docs** — 14 files containing `{{ … }}` Go-template syntax inside code blocks were being silently evaluated as Liquid by Jekyll. Bulk-wrapped with `{% raw %}` / `{% endraw %}`. - **Multiple `A && B || C` antipatterns** — restructured to proper `if/then/else` blocks across `tests/fuzz/fuzz_install.sh`, `tests/snapshots/test_snapshots.sh`, three diagnostics tests, two security tests, and `tests/unit/security/test_pre_push_bypass.sh`. - **macOS reliability gate** — the `cov_exercise_script` helper now probes for `timeout` then `gtimeout` (coreutils on macOS) before falling back to no-timeout. The previous version returned `rc=127` for every script on macOS-latest. - **Windows chezmoi installer fallback** — `setup-chezmoi` composite action now uses the upstream installer's `-t v$version` flag on Windows (Git Bash). The previous positional-arg form made chezmoi try to run itself as a subcommand and exit non-zero. - **Typos hook allowlist** — added 9 entries for alias names (`yout`, `hom`, `cod`, `dsk`, `dwn`, `mus`, `pic`, `wth`) and SLSA terminology (`intoto`, `writeable`) that the hook incorrectly flagged. - **`tools/ci/check-insecure-tls.sh` and `compliance-guard.yml`** — both now exclude themselves and the `tests/` tree from the curl/wget/chmod pattern scans. The scanners were flagging their own legitimate pattern fixtures. - **`dot health --fix` chezmoi-sync detection** — `chezmoi status` output has two columns: column 1 (last-applied vs. actual) and column 2 (actual vs. target). The health dashboard previously counted both columns, so a single uncommitted edit to a source file (column-1-only drift, normal during development) was reported as "1 file out of sync" even though `chezmoi apply` had nothing to fix. The dashboard now counts only column-2 drift (the apply-actionable kind) and surfaces source-only drift as an informational footnote. - **`dot health --fix` post-apply verification** — `heal_chezmoi_drift` previously ran `chezmoi apply --force` via `_pkg_install`, which silenced stdout/stderr. When apply partially failed (e.g., on conflicting files), the next health-check pass showed the same drift count and the user had no signal that anything was wrong. The heal now captures the apply log, re-runs `chezmoi status` to verify the drift cleared, and reports either "✓ X file(s) synced" or "⚠ X applied, Y still drifted — run `chezmoi diff` to inspect". On hard failure, the last 5 lines of the apply log are surfaced inline. - **`ui_spinner_stop` rc=1 on a TTY** — the function's last line was `[[ ! -t 1 ]] && printf "\n"`, which evaluates to rc=1 when stdout is a TTY. Under `set -euo pipefail`, that rc killed every caller, including `_ai_refresh_status_cache` — silently leaving the user with an empty cache file. Added explicit `return 0`. - **macOS `xargs -I{} -n1` payload splitting** — `_ai_refresh_status_cache` originally passed `-n1` on top of `-I{}`, which on BSD-xargs triggers a quirk where the input line is word-split on whitespace. Entries like `"0|Agents (autonomous)|…"` arrived as `["0|Agents", "(autonomous)|…", …]`, garbling every probe. Removed the `-n1` (it's redundant with `-I{}`). - **macOS `xargs` apostrophe-quote bug** — BSD-xargs reads `Block's coding agent` as an unterminated single quote, aborts parsing, and drops every record after the offending one. Switched the probe pipeline to null-delimited input (`printf '%s\0' …` + `xargs -0`). This was masking Goose's presence: it had been silently absent from `dot ai` even when installed. - **AI dispatcher route gaps** — four bridge tools (`autohand`, `vibe`, `qwen`, `zai`) were accepted by the bridge `case` in `ai.sh` but missing from the route table in `bin/dot`. `dot autohand …` was hitting "Unknown ai command". Routes filled in. - **`run_ai_with_context` missing handlers for Goose and Codex** — `dot codex "prompt"` and `dot goose "prompt"` would route correctly through the dispatcher and bridge case but then fall through to "Unsupported tool" because the per-tool execution case was missing. Added `codex)` and `goose)` arms. ### Security - **OIDC trusted publishing for npm** — see Added above. Drops the long-lived `NPM_TOKEN` from CI. - **SHA-pinned GitHub Actions everywhere** — confirmed across all workflows after the Dependabot consolidation. - **`bash-dbgsym` not required** — the kcov-based coverage runner needed Ubuntu's debug symbols for bash, which created a supply-chain question (additional apt source). The xtrace replacement removes that requirement. ## v0.2.500 ### Added - **Wallpaper-driven theme engine** — themes are no longer hand-crafted. `extract-theme.py` uses K-Means clustering in CIELAB color space to extract dominant colors from any wallpaper image and generate a full terminal palette (16 ANSI colors, accent, bg/fg, panel, border) with WCAG AAA contrast enforcement. - **Automatic wallpaper discovery** — `rebuild-themes.sh` scans system wallpapers (macOS `/System/Library/Desktop Pictures/`, Linux `/usr/share/backgrounds/`) and custom wallpapers (`~/Pictures/Wallpapers/`). Custom overrides system. Themes are cached and only regenerated when wallpapers change. - **`dot theme rebuild`** — new command to regenerate themes from discovered wallpapers. Supports `--force` (ignore cache) and `--list` (show wallpapers without rebuilding). Parallel processing (4 jobs). - **System wallpaper fallback** — when no custom wallpaper exists, `wallpaper-sync.sh` maps theme names to platform-native wallpapers before falling back to "skip gracefully". - **HEIC → PNG auto-conversion** on Linux via `magick`/`heif-convert`/`convert`. - **macOS accent from wallpaper** — `macos_accent` field in generated themes maps wallpaper dominant hue to macOS accent color. `dot-theme-sync` reads it from themes.toml instead of a hardcoded case statement. - **Build artifact redirection** — Cargo, Go, pip, uv, Zig caches → `/tmp/builds/`. ### Changed - **themes.toml is now auto-generated** — run `dot theme rebuild` after adding wallpapers. Do not edit manually. - **Theme family derived from themes.toml** — `get_theme_family()` in `switch.sh` reads the `family` field dynamically instead of hardcoded case patterns. - **macOS appearance refresh** — kills cfprefsd/SystemUIServer/Dock/System Settings after accent changes. - **Graceful wallpaper fallback** — theme switching works without custom wallpapers. Core changes (colors, accent, dark/light) always apply; wallpaper is optional. ### Removed - **Static theme definitions** — all hand-crafted theme entries replaced by wallpaper-driven generation. ## v0.2.497 ### Added - **Verified chezmoi installer** — `install.sh` prefers `tools/ci/install-chezmoi-verified.sh` with SHA256 checksum validation before falling back to `get.chezmoi.io`. - **detect-secrets baseline** — `.secrets.baseline` for pre-commit secret scanning alongside gitleaks. - **Lua plugin module headers** — `@module` docstrings for ui.lua, coding.lua, lsp.lua, editor.lua, dap.lua explaining plugin selection rationale. ### Changed - **CI hardening** — Pinned `nix-installer` to SHA, removed `continue-on-error` from Home Manager build, replaced `mapfile` with portable `while read` loops. - **Plugin version pins** — toggleterm pinned to `^2`, venv-selector uses `version = false` instead of `branch = "main"`. - **DAP port configurable** — `DAP_DEV_SERVER_PORT` environment variable overrides default port 3000. - **SSH template hardening** — Added `hasKey` guard for `.chezmoi.kernel` in SSH config template. - **Test framework** — Restored `TESTS_PASSED`/`TESTS_FAILED` counter names for backward compatibility with 383 test files; fixed `mock_os` PATH restoration between test cases. - **Documentation** — Fixed default shell reference (Zsh → Fish) in INSTALL.md, added CI badge and test runner to README, added function docstrings to `utils.sh`. ### Fixed - **Shell compatibility** — Replaced zsh-only `unfunction` with POSIX `unset -f` in shell templates. - **Quote nesting** — Fixed broken double-quote nesting in `run_onchange_after_fonts.sh.tmpl`. - **Quoted expansion** — Added missing quotes around `$ZINIT_HOME` in zinit bootstrap. - **JSON injection** — Escaped double quotes in `health.sh` JSON output fields. - **Arithmetic portability** — Replaced `$(seq ...)` with `((i=N; i>=1; i--))` in `log-rotate.sh`. ## v0.2.496 ### Added - **Startup budget tracking** — CI now captures per-component timing from `DOTFILES_DEBUG=1` and fails on regression. - **Behavioral unit tests** — 10 critical functions now have runtime behavior tests (extract, genpass, encode64, path_prepend, platform detection, lazy loaders). - **Property-based tests** — `property_testing.sh` framework wired up with roundtrip, idempotence, and length-invariant tests. - **git-cliff configuration** — Automated CHANGELOG generation from conventional commits. - **Nix CI gate** — Home Manager activation package built and validated in CI. ### Changed - **Performance** — Lazy-loaded `thefuck` (~200ms saving) and cached `carapace` output via `_cached_eval` (~50ms saving). - **Starship timeout** — Reduced `command_timeout` from 2000ms to 500ms for snappier prompts in large repos. - **PATH consolidation** — All PATH mutations now originate from `00-core-paths.sh.tmpl`; removed scattered prepends from zshenv/zprofile stubs. - **heal.sh modular split** — Broken into domain modules (heal-shell, heal-tools, heal-perms, heal-cache) for testability. - **dot CLI modular split** — Subcommands dispatched to individual scripts in `scripts/dot/commands/` for maintainability. ### Fixed - **Security** — Replaced `curl|sh` pipes in `heal.sh` (starship, atuin) with download-to-temp + shebang validation. Pinned all heal.sh GitHub release versions with SHA256 checksums. - **Security** — `install.sh` now uses the secure `install/lib/chezmoi.sh` library instead of inline `curl|sh`. - **Security** — `dot-bootstrap` Nix installer now downloads to temp file with validation before execution. - **Security** — Extended `insecure-tls-check` pre-commit hook to cover `.tmpl` files. - **Security** — Added `sudo` availability guard in `heal.sh` before package manager calls. - **Documentation** — Fixed placeholder URLs in WSL2 troubleshooting guide. - **Documentation** — Added ADR-007 and ADR-008 to ADR index. - **Documentation** — Linked hero-shot.svg from README; updated hero-shot to show factual `dot doctor` output. - **Reliability** — `bench.sh` now uses `mktemp` instead of hardcoded `/tmp/bench.json`. ## v0.2.495 ### Fixed - **Installation failure (Issue #807)**: Resolved "unbound variable" errors in `install.sh` by correctly initializing color and path variables. - **Shell Compatibility**: Fixed syntax errors when running `install.sh` with `sh` by ensuring the script runs with `bash` and updating documentation accordingly. - **Broken Links**: Updated installation instructions in `README.md` and `docs/guides/INSTALL.md` to use the GitHub raw URL, bypassing issues with the `dotfiles.io` redirect. - **Documentation Sync**: Synchronized versioning and installation commands across all documentation and source files. ### Changed - **Repository Restructuring**: Reorganized non-deployed files for improved discoverability. - Docs categorized into `architecture/`, `guides/`, `reference/`, `security/`, `operations/` subdirectories. - Tests promoted to top-level `tests/` with domain-based unit test subdirectories. - Function templates grouped into subdirectories matching `groups.json` groups. - `install/helpers/` merged into `install/lib/`. - Renamed `.chezmoitemplates/gnome/` to `.chezmoitemplates/desktop/`. - Added `docs/NAMING_CONVENTIONS.md` standardization guide. - Added `dot_config/.module-manifest.json` for logical grouping of flat config directories. ## v0.2.493 ### Added - Implementation of `_cached_eval` for Zsh, Bash, and Fish for ultra-fast startup. - Full integration of `zoxide` and `atuin` in Nushell with caching. - Explicit management of `sgpt`, `poetry`, `fisher`, `micro`, and `pueue` configs. - Robust `target_os` detection for Arch/CachyOS in `install.sh`. ### Changed - Refactored `install.sh` to use a modular `main()` function. - Moved XDG exports in `dot_bashrc` above interactive checks. - Optimized Zellij configuration with 2026-ready UX (rounded corners, compact layout). ### Fixed - Resolved 100% of security alerts regarding `apt-get` recommendations. - Achieved 100.00% module test coverage with new maintenance tests. - Fixed Nix profile sourcing drift in `dot_zshenv`. - Resolved CI failures across linting, formatting, and unit test suites. ### Added - **2026 Frontier Stack** — Full support for Fish (Autoloading) and Nushell (Structured Data). - **Deterministic Portability** — Nix Flakes integration for bit-for-bit identical environments. - **Async Task Management** — Integrated Pueue daemon for non-blocking background operations. - **Local AI RAG** — `dot-ai` semantic search over your dotfiles configuration. - **Wasm Runtime** — Wasmtime support for ultra-fast, pre-compiled Rust/Zig tools. - **One-Command Provisioner** — `dot-bootstrap` for instant environment setup on clean servers. - **OS Theme Sync** — `dot theme sync` to match OS appearance (macOS/GNOME). - **Yazi Synergy** — `yy` wrapper for "cd-on-exit" directory navigation. ### Changed - **Fish Shell** — Transitioned from monolithic aliases to a dynamic function autoloading pipeline. - **Starship** — Added async indicators for background tasks and Nix environments. - **Diagnostics** — `dot doctor` and `dot heal` are now mise-aware and 2026-stack compatible. - **Neovim** — Migrated IDE toolchain (LSPs/Linters) into the Nix Flake. ## v0.2.491 ### Added - **Fast mode** — `DOTFILES_FAST=1` skips heavy startup work for the quickest first prompt. - **Runtime toggles** — `DOTFILES_DEFER_ZINIT` and `DOTFILES_ENABLE_COLORS` controls. - **Ultra-fast mode** — `DOTFILES_ULTRA_FAST=1` runs a minimal init path. - **Minimal prompt** — `DOTFILES_ULTRA_FAST_PROMPT=1` keeps the ultra-fast prompt lightweight. - **AI opt-in** — `DOTFILES_AI=1` enables AI helper scripts. ### Changed - **Deferred tool init** — Atuin, Starship, Zoxide, and FZF now load after the first prompt. - **Zinit bootstrap** — Deferred by default to reduce first-prompt latency. - Updated all version references to v0.2.491. ### Documentation - Added performance mode guidance and updated benchmark wording to reflect real-world variance. ## v0.2.478 ### Added - **Lazy alias loading** — Tool-specific aliases (~137KB across 35+ categories) now load after the first prompt via a `precmd` hook, keeping shell startup fast while retaining full alias coverage. - **GPG signature verification** in `install.sh` — Verifies chezmoi release checksums against the upstream GPG signature with graceful degradation when `gpg` is unavailable. - **Unit tests for all refactored scripts** — 100 new tests across 7 test files covering alias split, lazy hooks, FNM fix, PATH entries, GPG verification, CI pinning, gitleaks config, heal.sh fixes, and `dot new` Python guard. ### Changed - **Alias split architecture** — Separated monolithic alias template into eager (`90-ux-aliases.sh`, 14 core categories) and lazy (`91-ux-aliases-lazy.sh`, 35+ tool categories). - **FNM triple initialization fixed** — Removed eager `eval "$(fnm env)"` from `.zshrc` and duplicate lazy-load block from `30-options.zsh`; single lazy-load via wrapper functions remains. - **CI chezmoi version pinned** to v2.47.1 with correct `-t` tag flag (was `-v`, which is invalid for `get.chezmoi.io`). - **`dot_zshenv` PATH entries** — Added idempotent `~/.local/bin` and `/opt/homebrew/bin` PATH guards so tools are available before `.zshrc` loads. - **`dot new` Python guard** — Moved Python pre-flight check before filesystem operations to avoid creating empty directories on failure. - Updated all version references to v0.2.478. ### Fixed - **`heal.sh` SC2015** — Replaced `A && B || C` pattern with proper `if/then` to satisfy shellcheck. - **`heal.sh` shfmt formatting** — Fixed case branch spacing and pipe operator alignment. - **Gitleaks false positive** — Allowlisted chezmoi GPG public key fingerprint via inline annotation and commit SHA. ### Documentation - Added shell startup flow (16 phases) to `ARCHITECTURE.md` with rc.d and shell/ load order tables. - Added alias system documentation covering eager/lazy split, glob ordering, and manifest convention. - Added startup flow diagram to `README.md`. ## v0.2.477 ### Added - **Topgrade provisioning parity** across macOS, Linux, and WSL - Added `topgrade`, `mise`, `rustup`, `tmux`, `pipx`, `ruby`, `yazi` to Brewfile.cli - Added Linux binary installs for topgrade, mise, yazi with SHA256 verification - Added rustup via official installer with `--no-modify-path` - Added `cargo-install-update` for topgrade's cargo step - Added `gh` (GitHub CLI) to Linux package managers - Added `tmux`, `pipx`, `ruby` to Linux system packages - Created `run_onchange_12-tmux-plugins.sh.tmpl` for tpm provisioning - Added chezmoi-managed `topgrade.toml.tmpl` with platform-specific disable lists - Moved stylua and delta installs after rustup so cargo is available - Replaced yazi hint-only block with actual binary download - **Security and GPG** - Added `gnupg` to Brewfile.cli and Linux package lists (#381) - Updated GPG agent cache TTL to 1 day (86400 seconds) (#392) - **Node.js tooling** - Added `.npmrc` config with scoped registries support (#439) - Added `.yarnrc.yml` for Yarn Berry configuration (#440) - Added `.noderc` for Node REPL configuration (#271) - Added `eslint_d` global install for fast linting (#441, #267) - Added `prettier_d` global install for fast formatting (#442, #268) - Added `typescript` and `typescript-language-server` global installs - **Bun** - Added `bunfig.toml` configuration (#447, #273) - Added Bun paths to core-paths - **Kubernetes** - Added KUBECONFIG merge logic for `~/.kube/config.d/*` (#487, #313) - Added `hm` alias for `helm` (#489, #315) - Added K9s config