# 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 configuration with Catppuccin Mocha skin (#314)
  - Added `kube-linter` to Brewfile.cli (#319)
  - Added `kubesec` to Brewfile.cli (#318)

- **Neovim**
  - Added `ts_ls` (TypeScript) to mason-lspconfig ensure_installed (#269)
  - Added DAP configuration with `js-debug-adapter` support (#270)

- **macOS**
  - Added Finder List View as default view mode (#511)
  - Added Finder path bar, status bar, and folders-first sorting

- **Dot CLI**
  - Added `dot packages` command to list installed packages (#375)

- **Testing**
  - Added 14 security validation tests in `test_security_fixes.sh`
  - Added unit tests for TOCTOU prevention, input validation, and safe parsing

### Changed

- Updated all version references to v0.2.477
- **CI/CD consolidation**
  - Consolidated 5 workflow files into 3 (`ci.yml`, `codeql.yml`, `security-release.yml`)
  - Implemented 5-stage pipeline: LINT → SECURITY → TEST → QUALITY → BENCHMARK
  - Added consistent naming convention: `Category / Specifics`
  - Added concurrency groups for faster PR feedback
  - Merged Docker tests and benchmarks into main CI workflow

### Fixed

- **Security hardening (OWASP)**
  - `mount_read_only.sh`: Input validation and secure temp file with `mktemp`
  - `chezmoi-apply.sh`/`chezmoi-update.sh`: Safe flag parsing with `read -ra`
  - `tmux-sessionizer`: Session name sanitization to prevent injection
  - `install.sh`: Escaped sed metacharacters for safe pattern matching
  - `teleport.sh`: Added tar safety flags (`--no-absolute-names`)
  - `permission.aliases.sh`: Added warnings for overly permissive modes (666/777)
  - `genpass.sh`: Numeric input validation
  - `backup.sh`: Enhanced error handling for tar operations
  - `age-init.sh`: Safe JSON output with `json.dumps`

- **Cross-platform compatibility**
  - `99-custom.paths.sh`: Added macOS guards and path existence checks
  - `00-default.paths.sh`: Added darwin guard for Homebrew, Linuxbrew support
  - `view-source.sh`: Plain curl command for portability
  - `configuration.aliases.sh`: File existence checks before sourcing
  - `install_neovim.sh`: Linux-only guard, user-local fallback when no sudo
  - `upgrade_neovim_nightly.sh`: Platform guard, sudo fallback
  - `run_before_00-audit.sh`: Container-safe hostname detection
  - Removed hardcoded `/usr/bin` paths in `last.sh`, `hexdump.sh`, `httpdebug.sh`, `caffeine.sh`

## v0.2.476

### Added

- **AI CLI Tools (NPM-based)**
  - Added `claude` (@anthropic-ai/claude-code) - Anthropic Claude CLI for AI-powered coding
  - Added `gemini` (@google/gemini-cli) - Google Gemini CLI for terminal AI assistance
  - Added `codex` (@openai/codex) - OpenAI Codex CLI for code generation and understanding
  - Added `opencode` (opencode-ai) - OpenCode AI assistant with TUI
  - Added `droid` (@factory/cli) - Factory AI Droid for intelligent code orchestration
  - All tools installed globally via npm/fnm
  - Auto-install fnm and Node.js LTS if not present

### Changed

- Updated all version references to v0.2.476

## v0.2.474


### Added

- **Shell configuration**
  - Added `.profile` with POSIX-compatible login shell configuration
  - Added `.bashrc` fallback for non-Zsh environments
  - Added `.inputrc` with enhanced Readline configuration
  - Added `.vimrc` legacy support for environments without Neovim
  - Added `.Xresources` with X11 configuration and Catppuccin theme

- **Database CLI configuration**
  - Added `.psqlrc` with enhanced PostgreSQL CLI configuration
  - Added `.sqliterc` with SQLite CLI settings
  - Added `mycli` configuration for MySQL CLI
  - Added `redis-cli` configuration
  - Added `mongosh` configuration for MongoDB Shell

- **Kubernetes tooling**
  - Added `kubectx` and `kubens` aliases for context/namespace switching
  - Added `stern` aliases for multi-pod log tailing
  - Added `kube-linter` aliases for manifest linting
  - Added `kubesec` aliases for security scanning
  - Added `minikube` configuration and aliases
  - Enhanced Kubernetes aliases with comprehensive kubectl shortcuts

- **Nix integration**
  - Added `packages` output to Nix flake
  - Added `dot-utils` meta-package derivation
  - Added `tmux`, `eza`, `yq`, `age`, `gnupg` to package list
  - Added install hook script for `nix profile install`

- **Dot CLI**
  - Added `dot --version` to display version information
  - Added `dot add` to add files to chezmoi source
  - Added `dot status` to show configuration drift
  - Added `dot cd` to print source directory path
  - Enhanced `dot tools` with `install` subcommand for Nix shell

- **Docker tooling**
  - Added comprehensive Docker aliases (`dco`, `dprune`, `dlogsf`, `dexec`)
  - Added Docker Compose aliases (`dco` for `docker compose`)
  - Added Docker Buildx aliases for multi-platform builds
  - Added Lazydocker configuration (`config.yml`)
  - Added support for Dive and Hadolint

- **Tmux enhancements**
  - Added vim-style copy bindings (`v` for selection, `y` for yank)
  - Added tmux-sessionizer script for fuzzy session switching
  - Updated clipboard integration for macOS and Linux

- **CI/CD**
  - Added Luacheck CI for Lua linting
  - Added shfmt format checking for shell scripts
  - Added Gitleaks secrets scanner
  - Added link rot checker for documentation
  - Added idempotency double-run test
  - Expanded test matrix to include macOS-13, macOS-14, and multiple Ubuntu versions

- **Completions**
  - Added Bash completion for the `dot` CLI
  - Enhanced Zsh completion with command descriptions

- **Documentation**
  - Enhanced installation guide with Nix instructions
  - Enhanced troubleshooting guide with more common issues
  - Added comprehensive tools list with tables
  - Added aliases reference documentation
  - Added feature flags documentation
  - Enhanced architecture documentation with diagrams
  - Enhanced CODEOWNERS with detailed ownership rules
  - Enhanced contributing guide with PR guidelines

### Changed

- Updated all version references to v0.2.474
- Made shebangs portable (`#!/usr/bin/env bash`)
- Improved documentation with Apple-style clarity
- Updated Brewfile.cli with Kubernetes tools

### Fixed

- Fixed duplicate alias conflicts in Docker aliases

## v0.2.474

- See the release notes and commit history for detailed changes.

## v0.2.472

- See the release notes and commit history for detailed changes.
