@sebastienrousseau/dotfiles 0.2.512 → 0.2.513

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +2 -2
  3. package/docs/COPYRIGHT +1 -1
  4. package/docs/manual/00-introduction.md +1 -1
  5. package/docs/manual/01-concepts/02-trust-model.md +2 -1
  6. package/docs/manual/03-reference/03-environment.md +1 -1
  7. package/docs/manual/04-cookbook/03-faq.md +1 -1
  8. package/docs/manual/05-appendices/B-security-checklist.md +2 -1
  9. package/docs/operations/COVERAGE.md +7 -8
  10. package/docs/operations/REGISTRY.md +20 -19
  11. package/docs/reference/POWERSHELL_PARITY.md +28 -27
  12. package/docs/schema/dot-registry-v1.json +33 -0
  13. package/docs/security/SCORECARD.md +1 -1
  14. package/install.sh +20 -11
  15. package/package.json +1 -1
  16. package/scripts/diagnostics/a2a-conformance.sh +0 -0
  17. package/scripts/diagnostics/health.sh +4 -1
  18. package/scripts/diagnostics/mcp-doctor.sh +0 -0
  19. package/scripts/diagnostics/verify_state.sh +0 -0
  20. package/scripts/diagnostics/workstation-attestation.sh +0 -0
  21. package/scripts/dot/commands/ai.sh +3 -1
  22. package/scripts/dot/commands/fleet.sh +1 -1
  23. package/scripts/dot/commands/registry.sh +164 -15
  24. package/scripts/dot/powershell/Dot.psm1 +146 -26
  25. package/scripts/fonts/install-nerd-fonts.sh +16 -10
  26. package/scripts/git-hooks/pre-commit-audit.sh +1 -1
  27. package/scripts/ops/heal-tools.sh +39 -111
  28. package/scripts/ops/post-apply-repair.sh +0 -0
  29. package/scripts/qa/reliability-audit.sh +3 -3
  30. package/scripts/qa/scorecard-snapshot.sh +3 -3
  31. package/scripts/qa/validate-examples.sh +0 -0
  32. package/scripts/qa/wsl-contract.sh +0 -0
  33. package/scripts/tools/detect-collisions.py +0 -0
  34. package/scripts/version-sync.sh +27 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,54 @@
2
2
 
3
3
  This file documents all notable changes to this project.
4
4
 
5
+ ## v0.2.513 — 2026-08-06
6
+
7
+ - **Verified module registry installation.** `dot registry install` now validates the v1 index, verifies immutable archive SHA-256 digests, rejects traversal and link-bearing archives, previews with chezmoi by default, and applies only with explicit `--yes`. CI validates the published registry contract and JSON Schema.
8
+ - **Native PowerShell daily workflow.** `dot.ps1` now handles core chezmoi operations, status, doctor, mise inventory, agent checks/listing, and local fleet status without bash. Windows CI exercises the cmdlets directly, and the parity matrix now distinguishes native behavior from bash bridges.
9
+ - **Checksum-verified self-healing tools.** Nushell, Pueue, Wasmtime, SOPS, Yazi, and Zellij recovery now uses exact mise/aqua pins instead of mutable GitHub release URLs and unverified executable downloads.
10
+ - **Reproducible toolchain lock.** The development toolchain now ships a cross-platform `mise.lock` covering Linux, macOS, and Windows with exact download URLs and available SHA-256 checksums. Font archives, distro signing keys, and binary archives now fail closed on integrity or unsafe archive structure.
11
+
12
+ ### Security
13
+
14
+ - Enforce signed commits, linear history, required merge/reliability/DCO/PR
15
+ signature checks, conversation resolution, and up-to-date branches on
16
+ `main`.
17
+ - Default GitHub Actions tokens to read-only, disable workflow PR approvals,
18
+ enable secret push protection, and pin the SLSA reusable workflow to its
19
+ immutable commit.
20
+ - Verify every remotely executed installer against a committed SHA-256
21
+ allowlist. CI rejects direct download-to-shell execution and verifier
22
+ bypasses.
23
+
24
+ ### Fixed
25
+
26
+ - Make CLI snapshots hermetic across hosts by normalizing platform facts,
27
+ installed-tool paths, versions, health counts, and timing measurements.
28
+ - Keep `dot health` best-effort when an interactive zsh startup probe fails or
29
+ omits timing output, so macOS diagnostics still reach the health summary.
30
+ - Measure both unit and mandatory regression tests in Bash coverage, retain
31
+ function-probe xtrace, and cache source normalization. Measured line
32
+ coverage rises to 59.32%, the enforced floor rises to 58%, and aggregation
33
+ now completes in seconds instead of minutes.
34
+ - Run the reliability audit's integration phase without repeating the full
35
+ unit and regression suites.
36
+ - Keep `master` as a verified, fast-forward-only compatibility mirror of
37
+ `main` for historical raw-content install URLs.
38
+ - Package a self-contained `dot` distribution including command modules,
39
+ operational scripts, policies, schemas, help data, and the verified-download
40
+ manifest. Previously published archives omitted the command modules required
41
+ by most subcommands.
42
+ - Add `make install PREFIX=... DESTDIR=...` and `make uninstall` using the
43
+ same tested staging path as release archives. Published releases now run a
44
+ provenance-verified clean-install smoke test on Linux and macOS.
45
+ - Store CLI benchmark baselines under `XDG_CACHE_HOME` instead of requiring a
46
+ writable source checkout.
47
+ - Make focused help work for `apply`, `agents`, and `registry`.
48
+ - Make an explicit version-sync target update `package.json` atomically and
49
+ distinguish historical roadmap versions from current-version references.
50
+ - Correct documentation that conflated 100% executable-module mapping with
51
+ measured Bash line coverage.
52
+
5
53
  ## v0.2.512 — 2026-07-21
6
54
 
7
55
  ### Added
package/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  <p align="center">
12
12
  <a href="https://github.com/sebastienrousseau/dotfiles/actions"><img src="https://img.shields.io/github/actions/workflow/status/sebastienrousseau/dotfiles/ci.yml?style=for-the-badge&logo=githubactions&logoColor=white" alt="Build" /></a>
13
- <a href="https://github.com/sebastienrousseau/dotfiles/releases/latest"><img src="https://img.shields.io/badge/Version-v0.2.512-blue?style=for-the-badge&logo=semanticrelease&logoColor=white" alt="Version" /></a>
13
+ <a href="https://github.com/sebastienrousseau/dotfiles/releases/latest"><img src="https://img.shields.io/badge/Version-v0.2.513-blue?style=for-the-badge&logo=semanticrelease&logoColor=white" alt="Version" /></a>
14
14
  <a href="https://github.com/sebastienrousseau/dotfiles/releases"><img src="https://img.shields.io/github/downloads/sebastienrousseau/dotfiles/total?style=for-the-badge&logo=github&logoColor=white" alt="Downloads" /></a>
15
15
  <a href="https://codespaces.new/sebastienrousseau/dotfiles"><img src="https://img.shields.io/badge/Open%20in-Codespaces-blue?style=for-the-badge&logo=github&logoColor=white" alt="Open in GitHub Codespaces" /></a>
16
16
  <a href="https://scorecard.dev/viewer/?uri=github.com/sebastienrousseau/dotfiles"><img src="https://img.shields.io/ossf-scorecard/github.com/sebastienrousseau/dotfiles?style=for-the-badge&logo=linuxfoundation&logoColor=white&label=OpenSSF%20Scorecard" alt="OpenSSF Scorecard" /></a>
@@ -52,7 +52,7 @@
52
52
 
53
53
  ```bash
54
54
  curl -fsSL -o /tmp/dotfiles-install.sh \
55
- https://raw.githubusercontent.com/sebastienrousseau/dotfiles/v0.2.512/install.sh
55
+ https://raw.githubusercontent.com/sebastienrousseau/dotfiles/v0.2.513/install.sh
56
56
  echo "d5a04c5e2813a93a63c8ecce9655cf3d107f6068862c6eba84a92cf22f801c7e /tmp/dotfiles-install.sh" \
57
57
  | shasum -a 256 -c
58
58
  bash /tmp/dotfiles-install.sh
package/docs/COPYRIGHT CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- * 🅳🅾🆃🅵🅸🅻🅴🆂 (v0.2.512) - <https://github.com/sebastienrousseau/dotfiles>
2
+ * 🅳🅾🆃🅵🅸🅻🅴🆂 (v0.2.513) - <https://github.com/sebastienrousseau/dotfiles>
3
3
  * Made With ❤️ in London, United Kingdom
4
4
  * Designed by
5
5
  * Copyright (c) 2015-2026. All rights reserved.
@@ -4,7 +4,7 @@ render_with_liquid: false
4
4
 
5
5
  # Introduction
6
6
 
7
- This manual describes `.dotfiles` v0.2.512 — a trusted agent workstation baseline for macOS, Linux, and WSL.
7
+ This manual describes `.dotfiles` v0.2.513 — a trusted agent workstation baseline for macOS, Linux, and WSL.
8
8
 
9
9
  The repository is more than a personal dotfiles collection. It ships as workstation infrastructure: signed, attested, multi-platform, AI-aware, and self-healing. Chezmoi handles templating and platform differences. The `dot` CLI sits on top and coordinates lifecycle operations.
10
10
 
@@ -160,7 +160,8 @@ See [Fleet Architecture](04-fleet.md) for the full model.
160
160
  | Shellcheck zero-warnings | `ci.yml` | Yes |
161
161
  | Gitleaks scan | `ci.yml` | Yes |
162
162
  | Copyright headers | `ci-enforced.yml` | Yes |
163
- | 100% unit test coverage | `ci-enforced.yml` | Yes |
163
+ | 100% executable module mapping | `ci-enforced.yml` | Yes |
164
+ | Measured Bash line coverage | `coverage.yml` | Ratcheted floor; see `docs/operations/COVERAGE.md` |
164
165
  | Reliability (macOS + Linux) | `ci-enforced.yml` | Yes |
165
166
  | Checkov infrastructure scan | `ci-enforced.yml` | On severity MEDIUM+ |
166
167
  | SBOM (CycloneDX) | `ci.yml` | No (informational) |
@@ -75,7 +75,7 @@ Variables relevant in GitHub Actions.
75
75
  | `CI` | Set to `true` in CI; disables prompts |
76
76
  | `GITHUB_ACTIONS` | GHA-specific; enables step summary output |
77
77
  | `CHEZMOI_VERSION` | Pinned chezmoi version for CI |
78
- | `COVERAGE_THRESHOLD` | Test coverage threshold (100 in enforced CI) |
78
+ | `COVERAGE_THRESHOLD` | Executable module-mapping threshold (100 in enforced CI; not line coverage) |
79
79
  | `DOTFILES_TEST_MODE` | Skip network-dependent tests |
80
80
 
81
81
  ## Secret-Related
@@ -25,7 +25,7 @@ Only via WSL2. Native Windows PowerShell support exists for baseline parity (ali
25
25
 
26
26
  ### Is it production-ready?
27
27
 
28
- Yes — it's the author's daily driver across multiple hosts and receives regular releases (see `CHANGELOG.md`). CI enforces 100% test coverage, zero-warning linting, WCAG AAA for themes, SBOM + CVE scanning, and signed commits on every merge.
28
+ Yes — it's the author's daily driver across multiple hosts and receives regular releases (see `CHANGELOG.md`). CI enforces 100% executable-module mapping and a ratcheted measured Bash line-coverage floor, plus zero-warning linting, WCAG AAA for themes, SBOM + CVE scanning, and signed-commit verification. The current measured coverage and exclusions are documented in `docs/operations/COVERAGE.md`.
29
29
 
30
30
  ### Can I fork it and use it without attribution?
31
31
 
@@ -71,7 +71,8 @@ Every PR to main must pass:
71
71
  - [x] Detect-secrets baseline diff
72
72
  - [x] TruffleHog verified scan
73
73
  - [x] Copyright headers present
74
- - [x] 100% unit test coverage
74
+ - [x] 100% executable module mapping
75
+ - [ ] 100% measured line and branch coverage (current ratchet is documented in `docs/operations/COVERAGE.md`)
75
76
  - [x] Reliability tests (macOS + Ubuntu)
76
77
  - [x] Checkov infra scan
77
78
  - [x] Version sync (bumped across all files)
@@ -43,18 +43,18 @@ matches and emits standard `lcov.info` that Codecov ingests natively.
43
43
 
44
44
  | Surface | What runs |
45
45
  |---|---|
46
- | **PR + push to main** | `.github/workflows/coverage.yml` → `Coverage / kcov` job → uploads lcov.info to Codecov and fails the build below `MIN_COVERAGE_PCT` (currently `49`, ratcheted up after measured integer-floor gains). |
46
+ | **PR + push to main** | `.github/workflows/coverage.yml` → `Coverage / kcov` job → uploads lcov.info to Codecov and fails the build below `MIN_COVERAGE_PCT` (currently `58`, ratcheted up after measured integer-floor gains). |
47
47
  | **Local dev** | `bash tools/ci/run-coverage.sh` — works on Linux + macOS (xtrace is a bash primitive, no platform tools needed). |
48
48
  | **macOS dev** | Supported. xtrace-based instrumentation runs on macOS bash 3.2+ and Homebrew bash 5.x, with a Perl alarm fallback when GNU `timeout`/`gtimeout` is unavailable. |
49
49
 
50
50
  ## The current floor
51
51
 
52
- `MIN_COVERAGE_PCT=49` in `.github/workflows/coverage.yml`. Slice 1
52
+ `MIN_COVERAGE_PCT=58` in `.github/workflows/coverage.yml`. Slice 1
53
53
  of [#883](https://github.com/sebastienrousseau/dotfiles/issues/883)
54
54
  established the baseline at **~2.7% measured** (~613 of ~22 500 lines
55
55
  across 231 files). Successive slices raised it; the current measured
56
- value sits at **50.16%** (`6205/12371` lines, re-measured on the merged tree; gate floored at 49 for local<->CI drift + run variance) after the eighth core
57
- coverage-ratchet slice added `jwt` portability coverage and
56
+ value sits at **59.32%** (`7523/12682` lines, measured on v0.2.513; gate floored at 58 for local<->CI drift + run variance). This release now traces both mandatory unit and regression suites, replays the function exerciser's captured xtrace, and caches source-path normalization so aggregation completes in seconds instead of minutes. It builds on the earlier parser correction for nested Bash execution prefixes and deterministic branch-driving tests for Scorecard snapshots, examples coverage, and `httpdebug`. It builds on the eighth core
57
+ coverage-ratchet slice, which added `jwt` portability coverage and
58
58
  branch-driving function coverage for `apihealth`, `apiload`, and
59
59
  `apilatency`. This builds on the prior helper slice that drove
60
60
  `scripts/dot/commands/restore.sh` to 75.17%,
@@ -89,10 +89,9 @@ To tighten:
89
89
 
90
90
  ### Why not the 95% target from #883
91
91
 
92
- The roadmap originally targeted ≥95% measured. After working through
93
- all six slices, the achievable ceiling with xtrace-only instrumentation
94
- is closer to **~50%** on this codebase. The remaining gap is structural,
95
- not aspirational:
92
+ The roadmap originally targeted ≥95% measured. The current xtrace-only
93
+ measurement is **59.32%** on this codebase. The remaining gap is largely
94
+ structural:
96
95
 
97
96
  - **System-mutation surface** — large parts of the repo orchestrate
98
97
  real OS state (`chezmoi apply`, `gpg`, `pass`/`age` keystores,
@@ -20,7 +20,9 @@ This page documents the JSON contract and the contribution flow. It is the §3 /
20
20
  dot registry list # list every published module
21
21
  dot registry search rust # filter by keyword
22
22
  dot registry info rust-dev-setup # full metadata for one module
23
- dot registry install rust-dev-setup # apply to this workstation (scaffold)
23
+ dot registry install rust-dev-setup # verify and preview changes
24
+ dot registry install rust-dev-setup --yes # verify, persist, and apply
25
+ dot registry installed # list locally installed modules
24
26
  dot registry url # show active registry URL
25
27
  dot registry set-url <url> # point at a different registry
26
28
  ```
@@ -44,44 +46,43 @@ A registry index is a single JSON document:
44
46
  "version": "1.2.0",
45
47
  "tags": ["rust", "language", "dev"],
46
48
  "maintainer": "alice@example.com",
47
- "sha256": "f9a2c1b…",
49
+ "archive_url": "https://example.com/rust-dev-setup-1.2.0.tar.gz",
50
+ "sha256": "f9a2c1b0a8d27c41b99c8c93641a0d476a0e54b23161847c47c780025ac7c4a1",
48
51
  "license": "MIT"
49
52
  }
50
53
  ]
51
54
  }
52
55
  ```
53
56
 
54
- Required keys: `name` (kebab-case, 32 chars), `description` ( 200 chars), `repo` (HTTPS clone URL), `version` (semver).
57
+ Required keys: `name` (kebab-case, no more than 32 characters), `description` (no more than 200 characters), `version` (semver), `archive_url` (immutable HTTPS archive), and `sha256` (64 lowercase hexadecimal characters).
55
58
 
56
- Recommended keys: `tags` (lower-case array), `maintainer`, `sha256` (pinned at publish time so installers can verify), `license` (SPDX identifier).
59
+ Optional keys: `repo` (HTTPS project URL), `tags` (lower-case array), `maintainer`, and `license` (SPDX identifier). The machine-readable contract is [`docs/schema/dot-registry-v1.json`](../schema/dot-registry-v1.json).
57
60
 
58
61
  ## Contributing a module
59
62
 
60
- 1. Build your module as a chezmoi-source-compatible directory at `https://github.com/<you>/<module>.git`. The contents are overlaid onto the consumer's chezmoi source dir during install.
63
+ 1. Build a gzip-compressed tar archive containing a chezmoi-source-compatible directory. Publish it at an immutable HTTPS URL, such as a versioned GitHub release asset.
61
64
  2. Open a PR against `sebastienrousseau/dotfiles` adding one entry to `docs/registry.json` (alphabetical by `name`).
62
65
  3. The PR runs CI checks for:
63
- - Schema validity (`jq` against the JSON contract).
64
- - `repo` URL resolves and is a public git repo.
65
- - `sha256` matches the latest tag at `repo`.
66
+ - Runtime contract validity and unique, sorted module names.
67
+ - Valid JSON for both the index and its published JSON Schema.
68
+ - A pinned SHA-256 digest for every archive.
66
69
  4. Once merged, the GitHub Pages workflow re-deploys the registry; `dot registry list` picks it up within 6 hours (or immediately if the consumer purges the cache).
67
70
 
68
- ## Install pipeline (scaffold today, full in Phase 2)
71
+ ## Install pipeline
69
72
 
70
- `dot registry install <name>` currently prints what *would* happen. The full pipeline lands as follows:
73
+ `dot registry install <name>` is preview-first and does not mutate the workstation. Pass `--yes` only after reviewing the chezmoi dry-run. The installer:
71
74
 
72
75
  1. Resolve the module entry from the registry index.
73
- 2. Clone the module to `$XDG_DATA_HOME/dotfiles/modules/<name>/<version>`.
74
- 3. Verify the clone's HEAD matches `sha256` from the registry.
75
- 4. Source the module's `module.toml` (if present) for declared profiles + feature flags.
76
- 5. Merge the module's chezmoi source into the consumer's chezmoi source dir under a namespaced subtree (`/registry/<name>/...`).
77
- 6. Run `chezmoi apply --include /registry/<name>/**` so only the module's files are written.
78
-
79
- The sandboxed apply (point 6) requires changes to `dot sync` to accept an include filter — that is its own roadmap issue and tracked separately.
76
+ 2. Download the versioned archive using HTTPS and TLS 1.2 or newer.
77
+ 3. Verify the archive against the registry's SHA-256 digest.
78
+ 4. Reject absolute paths, parent traversal, symbolic links, and hard links before extraction.
79
+ 5. Run `chezmoi apply --dry-run` against the isolated module source.
80
+ 6. With `--yes`, persist it at `${XDG_DATA_HOME:-~/.local/share}/dotfiles/modules/<name>/<version>` and apply that exact verified source.
80
81
 
81
82
  ## Security model
82
83
 
83
- - Modules execute with the consumer's user privileges via chezmoi `run_onchange_*` scripts. The trust contract is identical to consuming any third-party dotfiles repo.
84
- - Pinning `sha256` lets a consumer verify the registry entry hasn't been tampered with between publish and install.
84
+ - Modules execute with the consumer's user privileges via chezmoi scripts. Review the default dry-run and publisher before passing `--yes`.
85
+ - The SHA-256 pin binds installation to the reviewed archive bytes, even if the hosting release later changes.
85
86
  - The registry index itself is fetched over HTTPS; the GitHub Pages cert chain provides transport integrity.
86
87
 
87
88
  ## Why this lives in this repo (for now)
@@ -12,9 +12,9 @@ This document tracks what is supported on Windows-native PowerShell 7.4 LTS / 7.
12
12
 
13
13
  | Tier | Meaning | Examples |
14
14
  |---|---|---|
15
- | **Full** | Native PowerShell path; tested in CI on `windows-latest`. | `dot version`, `dot help`, `dot agents check` (via WSL-bash fallback). |
15
+ | **Full** | Native PowerShell path; tested in CI on `windows-latest`. | `dot version`, `dot help`, `dot agents check`. |
16
16
  | **WSL-bridged** | Runs under WSL2 bash with the same UX as Linux. | All `dot` subcommands, the test suite, the cold-start bench. |
17
- | **Stub** | The command exists as a PowerShell entry-point but delegates to bash. | `dot init`, `dot fleet apply` (require chezmoi/ssh; both Windows-installable). |
17
+ | **Bash-bridged** | The PowerShell dispatcher delegates to Git Bash or WSL bash and fails clearly when bash is unavailable. | `dot registry`, `dot fleet apply`, Unix-specific diagnostics. |
18
18
  | **N/A** | The command targets a Unix-only surface and is not exposed on PowerShell. | Wallpaper-driven theming via macOS `defaults`; Linux-only `lock-configs.sh`. |
19
19
 
20
20
  ## Command-by-command matrix
@@ -22,26 +22,24 @@ This document tracks what is supported on Windows-native PowerShell 7.4 LTS / 7.
22
22
  | Command | Windows-native | WSL2 | macOS | Linux |
23
23
  |---|---|---|---|---|
24
24
  | `dot version` | **Full (native)** — `Get-DotVersion` cmdlet in `scripts/dot/powershell/Dot.psm1`; reads `.chezmoidata.toml` directly, no bash | Full | Full | Full |
25
- | `dot help` | **Full (native)** — `Invoke-DotHelp` cmdlet; `dot help <subcmd>` still bash-bridged | Full | Full | Full |
26
- | `dot doctor` | Full (subset of checks; some Unix-only checks return N/A) | Full | Full | Full |
27
- | `dot init <user>` | Full (requires `chezmoi` on PATHinstall via `scoop install chezmoi`) | Full | Full | Full |
25
+ | `dot help` | **Full (native)** — `Invoke-DotHelp`; detailed Unix command help remains bash-bridged | Full | Full | Full |
26
+ | `dot status` | **Full (native)** structured clean/drifted result from chezmoi | Full | Full | Full |
27
+ | `dot diff` / `apply` / `sync` / `update` | **Full (native)** direct, exit-code-checked chezmoi operations | Full | Full | Full |
28
+ | `dot add` / `remove` / `init` / `cd` | **Full (native)** — direct chezmoi operations and source-path lookup | Full | Full | Full |
29
+ | `dot doctor` | **Full (native baseline)** — PowerShell, chezmoi, git, repo data, and module checks; Unix-only diagnostics are bash-bridged | Full | Full | Full |
28
30
  | `dot agents check` | **Full (native)** — `Test-DotAgentsSync` cmdlet; CI smoke test runs the cmdlet directly | Full | Full | Full |
29
- | `dot agents render` / `list` | Stub (bash-bridged`render` is a multi-harness mustache-equivalent rewrite, tracked as a separate ticket) | Full | Full | Full |
30
- | `dot fleet status` / `drift` / `events` | Full | Full | Full | Full |
31
- | `dot fleet apply` | Stub (bash-bridged + requires Windows OpenSSH `ssh.exe` on PATH; no native pwsh-side test in CI yet tracked in ROADMAP §C5 follow-up) | Full | Full | Full |
32
- | `dot fleet namespace set` | Full | Full | Full | Full |
33
- | `dot registry list` / `search` / `info` | Full | Full | Full | Full |
34
- | `dot registry install <name>` | Scaffold (no behavior yet on any platform) | Scaffold | Scaffold | Scaffold |
35
- | `dot agent` / `dot mode` | Full | Full | Full | Full |
36
- | `dot ai` / `dot ai-setup` / `dot ai-query` | Full | Full | Full | Full |
37
- | AI bridges (`cl`, `codex`, `copilot`, `gemini`, `goose`, etc.) | Full when the underlying AI CLI is installed (scoop / winget / native) | Full | Full | Full |
31
+ | `dot agents list` | **Full (native)**structured harness/path/rendered records | Full | Full | Full |
32
+ | `dot agents render` | Bash-bridged | Full | Full | Full |
33
+ | `dot env list` | **Full (native)**mise text or JSON inventory | Full | Full | Full |
34
+ | `dot env emit` | Bash-bridged | Full | Full | Full |
35
+ | `dot fleet status` | **Full (native)** node, version, OS, architecture, and drift | Full | Full | Full |
36
+ | `dot fleet drift` / `events` / `apply` / `namespace` | Bash-bridged | Full | Full | Full |
37
+ | `dot registry list` / `search` / `info` / `install` | Bash-bridged; Unix path is verified, checksum-pinned, and preview-first | Full | Full | Full |
38
+ | `dot agent` / `mode` / AI commands | Bash-bridged | Full | Full | Full |
38
39
  | `dot lint` | WSL-bridged (shellcheck/shfmt are Unix-native) | Full | Full | Full |
39
- | `dot perf` | Full (uses pwsh `Measure-Command` on the PS path) | Full | Full | Full |
40
- | `dot health` | Full | Full | Full | Full |
41
- | `dot tools` | Full (uses winget/scoop on Windows; brew/apt elsewhere) | Full | Full | Full |
42
- | `dot theme` (wallpaper-driven) | Stub (Windows wallpaper API needs additional work) | Stub (X11 only — Wayland support pending) | Full | Full (X11 only) |
43
- | `dot wallpaper` | Stub | Stub | Full | Full |
44
- | `dot security firewall` | Full (Windows Defender Firewall via `Set-NetFirewallProfile`) | N/A | Full (pf) | Full (ufw/firewalld) |
40
+ | `dot perf` / `health` / `tools` | Bash-bridged | Full | Full | Full |
41
+ | `dot theme` / `wallpaper` | N/A on native Windows | Limited | Full | Full (desktop-dependent) |
42
+ | `dot security firewall` | Bash-bridged; no native Defender mutation | N/A | Full (pf) | Full (ufw/firewalld) |
45
43
  | `dot security lock-configs` | N/A (Windows ACL model differs; tracked) | N/A | Full (`chflags uchg`) | Full (`chattr +i`) |
46
44
  | Shell startup integration | Full (`Microsoft.PowerShell_profile.ps1` ships) | Full (zsh, bash, fish) | Full (zsh, bash, fish, nu) | Full (zsh, bash, fish, nu) |
47
45
 
@@ -51,27 +49,30 @@ This document tracks what is supported on Windows-native PowerShell 7.4 LTS / 7.
51
49
  |---|---|
52
50
  | `dot version` exits 0 | windows-latest, ubuntu-latest, macos-latest, macos-14 |
53
51
  | `dot help` exits 0 | windows-latest, ubuntu-latest, macos-latest, macos-14 |
54
- | `dot agents check` exits 0 | windows-latest (via bash on PATH), ubuntu-latest, macos-latest, macos-14 |
52
+ | `dot agents check` exits 0 | windows-latest (native), ubuntu-latest, macos-latest, macos-14 |
53
+ | Native module import, agent-body sync, harness inventory, doctor baseline, and chezmoi diff | windows-latest |
54
+ | Native dispatcher version, help, and agents check | windows-latest |
55
55
  | PowerShell ≥ 7.4 | windows-latest (smoke test at `tools/ci/windows-smoke-test.ps1`) |
56
56
  | PSScriptAnalyzer Error-level findings | windows-latest |
57
57
  | `chezmoi --version` exits 0 | windows-latest (via scoop), all Unix matrices |
58
58
  | `bash tools/ci/dot-cli-startup-bench.sh` median < 200ms | macos-latest |
59
59
  | `bash tools/ci/dot-cli-startup-bench.sh` median < 150ms | ubuntu-latest |
60
60
 
61
- ## Known parity gaps (deferred to follow-up PRs)
61
+ ## Known parity gaps
62
62
 
63
63
  These are scoped in [`ROADMAP_2026 §C5`](../operations/ROADMAP_2026.md) but not in this PR's scope:
64
64
 
65
- 1. **Native PowerShell `dot.ps1` dispatcher.** Today the Windows path either uses `bash dot` (when bash is on PATH via Git for Windows / WSL) or shells out via `pwsh -Command`. A truly idiomatic PowerShell dispatcher with native cmdlet semantics (verb-noun naming, `[CmdletBinding()]`, pipeline support) is a separate effort.
66
- 2. **Wallpaper-driven theming on Windows.** Requires SystemParametersInfo W32 API or `Set-ItemProperty HKCU:\Control Panel\Desktop`. macOS-native today.
67
- 3. **`dot security lock-configs` for Windows.** Needs an ACL/EFS-based equivalent of `chattr +i` / `chflags uchg`. Not in this PR's scope; documented here so it doesn't get re-discovered.
68
- 4. **Native Windows installer signing.** The repo signs the bootstrap tarball via Cosign keyless; a SignTool-signed `install.ps1` for code-signing-enforced enterprises is a future enhancement.
65
+ 1. **Registry and fleet mutation.** Verified registry installation and multi-node fleet application still use the explicit bash bridge.
66
+ 2. **Wallpaper-driven theming.** Native Windows wallpaper extraction and application are not implemented.
67
+ 3. **Windows config locking.** There is no ACL/EFS equivalent of the Unix immutable-file operation.
68
+ 4. **Authenticode signing.** Release provenance covers the archive, but `install.ps1` and `dot.ps1` are not Authenticode-signed for enterprise execution policies.
69
69
 
70
70
  ## Source-of-truth files
71
71
 
72
72
  - `.github/workflows/ci.yml` — `test-windows` job (pwsh + scoop + chezmoi + smoke)
73
73
  - `tools/ci/windows-smoke-test.ps1` — the actual gate
74
- - `dot_config/powershell/Microsoft.PowerShell_profile.ps1` — the deployed PowerShell profile (if present)
74
+ - `bin/dot.ps1` and `scripts/dot/powershell/Dot.psm1` — native dispatcher and cmdlets
75
+ - `defaults/dot_config/powershell/Microsoft.PowerShell_profile.ps1.tmpl` — deployed profile
75
76
  - `scripts/dot/lib/platform.sh` — the dot_path_to_unix/native bridge (H9 audit fix)
76
77
 
77
78
  ## Why this matters
@@ -0,0 +1,33 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://sebastienrousseau.github.io/dotfiles/schema/dot-registry-v1.json",
4
+ "title": "Dot Module Registry v1",
5
+ "description": "Integrity-pinned index consumed by dot registry.",
6
+ "type": "object",
7
+ "required": ["version", "modules"],
8
+ "additionalProperties": false,
9
+ "properties": {
10
+ "version": { "const": 1 },
11
+ "updated": { "type": "string", "format": "date-time" },
12
+ "registry": { "type": "string", "minLength": 1 },
13
+ "modules": {
14
+ "type": "array",
15
+ "items": {
16
+ "type": "object",
17
+ "required": ["name", "version", "description", "archive_url", "sha256"],
18
+ "additionalProperties": false,
19
+ "properties": {
20
+ "name": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]{0,31}$" },
21
+ "version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+([+-][0-9A-Za-z.-]+)?$" },
22
+ "description": { "type": "string", "maxLength": 200 },
23
+ "archive_url": { "type": "string", "pattern": "^https://" },
24
+ "sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
25
+ "repo": { "type": "string", "pattern": "^https://" },
26
+ "tags": { "type": "array", "items": { "type": "string" }, "uniqueItems": true },
27
+ "maintainer": { "type": "string", "minLength": 1 },
28
+ "license": { "type": "string", "minLength": 1 }
29
+ }
30
+ }
31
+ }
32
+ }
33
+ }
@@ -35,7 +35,7 @@ Aggregate score **7.6 / 10** at 2026-05-17T08:11:51Z.
35
35
  | Token-Permissions | 10 | GitHub workflow tokens follow principle of least privilege |
36
36
  | Vulnerabilities | 10 | 0 existing vulnerabilities detected |
37
37
 
38
- *Refresh: `scripts/qa/scorecard-snapshot.sh` · CI check: `lint/scorecard-snapshot` (planned).*
38
+ *Refresh: `scripts/qa/scorecard-snapshot.sh` · Monitoring: `.github/workflows/scorecard.yml`.*
39
39
  <!-- END scorecard-snapshot -->
40
40
 
41
41
  [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/sebastienrousseau/dotfiles/badge)](https://scorecard.dev/viewer/?uri=github.com/sebastienrousseau/dotfiles)
package/install.sh CHANGED
@@ -2,7 +2,7 @@
2
2
  # SPDX-License-Identifier: MIT
3
3
  # Copyright (c) 2015-2026 Sebastien Rousseau
4
4
  # Universal Dotfiles Installer (Zero-Dependency)
5
- # Usage: bash -c "$(curl -fsSL https://raw.githubusercontent.com/sebastienrousseau/dotfiles/main/install.sh)"
5
+ # Usage: gh repo clone sebastienrousseau/dotfiles && cd dotfiles && ./install.sh
6
6
  # (or ./install.sh locally)
7
7
 
8
8
  # This installer uses bash features (set -o pipefail, arrays, [[ ]]). If it is
@@ -12,7 +12,7 @@
12
12
  # it parses in any shell before bash takes over.
13
13
  if [ -z "${BASH_VERSION:-}" ]; then
14
14
  echo "install.sh requires bash. Run: bash install.sh" >&2
15
- echo " or: bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/sebastienrousseau/dotfiles/main/install.sh)\"" >&2
15
+ echo " clone: gh repo clone sebastienrousseau/dotfiles && cd dotfiles && ./install.sh" >&2
16
16
  exit 1
17
17
  fi
18
18
 
@@ -71,7 +71,7 @@ show_help() {
71
71
  Usage: install.sh [version] [options]
72
72
 
73
73
  Arguments:
74
- version The version (tag or branch) to install (default: v0.2.512)
74
+ version The version (tag or branch) to install (default: v0.2.513)
75
75
 
76
76
  Options:
77
77
  --help Show this help message
@@ -87,7 +87,7 @@ EOF
87
87
  }
88
88
 
89
89
  main() {
90
- local version="v0.2.512"
90
+ local version="v0.2.513"
91
91
  local version_set=0
92
92
  local minimal=0
93
93
  local provision="${DOTFILES_PROVISION:-0}"
@@ -117,7 +117,7 @@ main() {
117
117
  # like `foobar` doesn't trigger a 30s+ network download attempt.
118
118
  # Caught by the install.sh fuzz harness (#881).
119
119
  if [[ ! "$arg" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+([-+][a-zA-Z0-9.-]+)?$ ]]; then
120
- error "Unrecognized positional argument '$arg' — expected a semver version (e.g. v0.2.512)."
120
+ error "Unrecognized positional argument '$arg' — expected a semver version (e.g. v0.2.513)."
121
121
  fi
122
122
  version="$arg"
123
123
  version_set=1
@@ -158,8 +158,15 @@ main() {
158
158
  brew install gum >/dev/null 2>&1
159
159
  elif [[ "$target_os" == "debian" || "$target_os" == "wsl2" ]]; then
160
160
  sudo mkdir -p /etc/apt/keyrings
161
- curl -fsSL https://repo.charm.sh/apt/gpg.key |
162
- sudo gpg --batch --yes --dearmor -o /etc/apt/keyrings/charm.gpg
161
+ charm_key_tmp="$(mktemp -t charm-key.XXXXXX)"
162
+ if ! curl --proto '=https' --tlsv1.2 -fsSL \
163
+ -o "$charm_key_tmp" https://repo.charm.sh/apt/gpg.key; then
164
+ rm -f "$charm_key_tmp"
165
+ return 1
166
+ fi
167
+ sudo gpg --batch --yes --dearmor \
168
+ -o /etc/apt/keyrings/charm.gpg "$charm_key_tmp"
169
+ rm -f "$charm_key_tmp"
163
170
  # Pin the Charm GPG key fingerprint — a DNS attacker swapping
164
171
  # repo.charm.sh/apt/gpg.key for a forged key with the same uid
165
172
  # would otherwise pass the prior "any fid: present" check.
@@ -362,7 +369,7 @@ main() {
362
369
  # 6. Initialize & Apply
363
370
  step "Applying Configuration..."
364
371
 
365
- # ── Auto-migration for v0.2.512 reorg ─────────────────────────────────
372
+ # ── Auto-migration for v0.2.513 reorg ─────────────────────────────────
366
373
  # If the user is upgrading from a pre-0.2.503 install, run the
367
374
  # migration script BEFORE `chezmoi apply` so the reorg's source-
368
375
  # path moves don't cause chezmoi to delete deployed files.
@@ -371,7 +378,7 @@ main() {
371
378
  for migrate_src in "$SOURCE_DIR" "$LEGACY_SOURCE_DIR"; do
372
379
  migrate_script="$migrate_src/install/migrate/migrate-v0_2-to-v0_2_503.sh"
373
380
  if [[ -x "$migrate_script" ]]; then
374
- echo " Running v0.2.512 migration (idempotent; safe on fresh installs)..."
381
+ echo " Running v0.2.513 migration (idempotent; safe on fresh installs)..."
375
382
  "$migrate_script" || echo " migration exited non-zero — continuing apply"
376
383
  break
377
384
  fi
@@ -443,14 +450,16 @@ main() {
443
450
  if [[ -d "$prov_dir" ]]; then
444
451
  local script
445
452
  # run_once_install_* (shells) first, then numbered run_onchange_* in order.
453
+ # The fixed globs contain no user-controlled filenames.
454
+ # shellcheck disable=SC2012
446
455
  while IFS= read -r script; do
447
456
  [[ -f "$script" ]] || continue
448
457
  echo " → $(basename "$script")"
449
458
  if [[ "$script" == *.tmpl ]]; then
450
- chezmoi execute-template <"$script" | bash ||
459
+ chezmoi execute-template <"$script" | DOTFILES_SOURCE_DIR="$SOURCE_DIR" bash ||
451
460
  echo " (step exited non-zero — continuing)"
452
461
  else
453
- bash "$script" || echo " (step exited non-zero — continuing)"
462
+ DOTFILES_SOURCE_DIR="$SOURCE_DIR" bash "$script" || echo " (step exited non-zero — continuing)"
454
463
  fi
455
464
  done < <(ls "$prov_dir"/run_once_install_* "$prov_dir"/run_onchange_* 2>/dev/null | sort)
456
465
  fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sebastienrousseau/dotfiles",
3
- "version": "0.2.512",
3
+ "version": "0.2.513",
4
4
  "description": "The Trusted Shell Platform — Universal dotfiles managed by Chezmoi. Features Bash & Zsh for macOS, Linux & WSL. Rust modern tooling & enterprise-grade security.",
5
5
  "main": "install.sh",
6
6
  "bin": {
File without changes
@@ -386,7 +386,10 @@ check_performance() {
386
386
 
387
387
  if has_command zsh; then
388
388
  local startup_time
389
- startup_time=$({ time zsh -i -c exit; } 2>&1 | grep real | awk '{print $2}' | sed 's/[ms]//g')
389
+ # Startup timing is diagnostic only. A user's interactive configuration
390
+ # may exit non-zero or omit a `real` row, which must not abort health under
391
+ # `set -euo pipefail` before the summary is printed.
392
+ startup_time=$({ time zsh -i -c exit; } 2>&1 | awk '/real/ { print $2; exit }' | sed 's/[ms]//g' || true)
390
393
  if [[ -n "$startup_time" ]]; then
391
394
  check "Shell startup time" "pass"
392
395
  else
File without changes
File without changes
File without changes
@@ -90,6 +90,8 @@ _ai_refresh_status_cache() {
90
90
  # shellcheck disable=SC2016
91
91
  local _TO=""
92
92
  command -v timeout >/dev/null 2>&1 && _TO="timeout 8 "
93
+ # Variables expand inside the child Bash probe.
94
+ # shellcheck disable=SC2016
93
95
  local probe_script='
94
96
  payload="$1"; out_dir="$2"; to="$3"
95
97
  i="${payload%%|*}"; entry="${payload#*|}"
@@ -418,7 +420,7 @@ ${prompt}"
418
420
  fi
419
421
  elif [[ "$tool_bin" == "agy" ]]; then
420
422
  ui_warn "$tool" "not installed"
421
- ui_info "Install" "curl -fsSL -o /tmp/agy-install.sh https://antigravity.google/cli/install.sh && bash /tmp/agy-install.sh"
423
+ ui_info "Install" "dot ai install agy (checksum verified)"
422
424
  exit 1
423
425
  elif [[ "$tool_bin" == "kimi" ]]; then
424
426
  ui_warn "$tool" "not installed"
@@ -73,7 +73,7 @@ _fleet_emit_event() {
73
73
  endpoint="$(sed -n 's/^endpoint = "\(.*\)"/\1/p' "$data_file" | head -1)"
74
74
  fi
75
75
  if [[ -n "$endpoint" ]] && [[ "$endpoint" == https://* ]]; then
76
- curl -fsSL -X POST -H "Content-Type: application/json" \
76
+ curl --proto '=https' --tlsv1.2 -fsSL -X POST -H "Content-Type: application/json" \
77
77
  -d "$payload" "$endpoint" >/dev/null 2>&1 || true
78
78
  fi
79
79
  }