@sebastienrousseau/dotfiles 0.2.518 → 0.2.520

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 (163) hide show
  1. package/CHANGELOG.md +191 -0
  2. package/README.md +1164 -164
  3. package/docs/ARCHITECTURE.md +117 -0
  4. package/docs/COPYRIGHT +1 -1
  5. package/docs/ECOSYSTEM.md +220 -0
  6. package/docs/GOLD-STANDARD-AUDIT.md +352 -0
  7. package/docs/GOVERNANCE.md +1 -1
  8. package/docs/MAINTAINERS.md +1 -1
  9. package/docs/MINIMUM-TOOLCHAIN.md +100 -0
  10. package/docs/README.md +1 -1
  11. package/docs/STRUCTURE.md +1 -1
  12. package/docs/architecture/ARCHITECTURE.md +11 -108
  13. package/docs/architecture/REPO_LAYOUT.md +4 -4
  14. package/docs/guides/MACOS_ICLOUD_SYMLINKS.md +121 -0
  15. package/docs/index.md +3 -3
  16. package/docs/manual/00-introduction.md +1 -1
  17. package/docs/manual/03-reference/01-dot-cli.md +28 -3
  18. package/docs/manual/command-index.md +24 -4
  19. package/docs/manual/concept-index.md +2 -0
  20. package/docs/migration/README.md +81 -0
  21. package/docs/migration/from-bare-git-repo.md +156 -0
  22. package/docs/migration/from-gnu-stow.md +165 -0
  23. package/docs/migration/from-plain-chezmoi.md +148 -0
  24. package/docs/migration/from-yadm.md +187 -0
  25. package/docs/operations/PERFORMANCE_BUDGETS.md +196 -0
  26. package/docs/operations/REGISTRY.md +1 -1
  27. package/docs/operations/RELEASE_PIPELINE.md +4 -4
  28. package/docs/operations/TESTING.md +3 -3
  29. package/docs/operations/TRACEABILITY.md +1 -0
  30. package/docs/packaging.md +222 -0
  31. package/docs/reference/FEATURE-MATRIX.md +646 -0
  32. package/docs/reference/TOOLS.md +1 -1
  33. package/docs/reference/UTILS.md +1 -0
  34. package/docs/security/COMPLIANCE.md +1 -1
  35. package/docs/security/DISCLOSURE.md +4 -4
  36. package/docs/security/FUZZING.md +113 -18
  37. package/docs/security/KEY_ROTATION.md +1 -1
  38. package/docs/security/SCORECARD.md +3 -3
  39. package/docs/security/VERIFY_RELEASE.md +2 -2
  40. package/install.sh +6 -6
  41. package/package.json +2 -2
  42. package/scripts/ci/check-copyright-headers.sh +1 -1
  43. package/scripts/ci/check-shell-preamble.sh +1 -1
  44. package/scripts/ci/guard-gitleaks-checkout.sh +1 -1
  45. package/scripts/demo/record.sh +1 -1
  46. package/scripts/diagnostics/a2a-conformance.sh +1 -1
  47. package/scripts/diagnostics/alias-governance.sh +30 -3
  48. package/scripts/diagnostics/aliases-cheatsheet.sh +1 -1
  49. package/scripts/diagnostics/aliases-manifest.sh +1 -1
  50. package/scripts/diagnostics/attest-verify.sh +147 -0
  51. package/scripts/diagnostics/benchmark.sh +1 -1
  52. package/scripts/diagnostics/conflicts.sh +1 -1
  53. package/scripts/diagnostics/doctor-unified.sh +6 -2
  54. package/scripts/diagnostics/doctor.sh +56 -10
  55. package/scripts/diagnostics/drift-dashboard.sh +3 -2
  56. package/scripts/diagnostics/health.sh +43 -10
  57. package/scripts/diagnostics/history-analysis.sh +1 -1
  58. package/scripts/diagnostics/mcp-doctor.sh +2 -2
  59. package/scripts/diagnostics/perf.sh +1 -1
  60. package/scripts/diagnostics/scorecard.sh +3 -2
  61. package/scripts/diagnostics/secret-governance.sh +1 -1
  62. package/scripts/diagnostics/security-score.sh +1 -1
  63. package/scripts/diagnostics/smoke-test.sh +1 -1
  64. package/scripts/diagnostics/snapshot.sh +1 -1
  65. package/scripts/diagnostics/verify.sh +1 -1
  66. package/scripts/diagnostics/verify_state.sh +1 -1
  67. package/scripts/diagnostics/version-locks.sh +1 -1
  68. package/scripts/diagnostics/workstation-attestation.sh +26 -1
  69. package/scripts/dot/commands/agent.sh +64 -14
  70. package/scripts/dot/commands/agents.sh +24 -8
  71. package/scripts/dot/commands/ai.sh +20 -7
  72. package/scripts/dot/commands/aliases.sh +1 -1
  73. package/scripts/dot/commands/appearance.sh +1 -1
  74. package/scripts/dot/commands/completion.sh +42 -5
  75. package/scripts/dot/commands/core.sh +1 -1
  76. package/scripts/dot/commands/diagnostics.sh +1 -1
  77. package/scripts/dot/commands/env-emit.sh +1 -1
  78. package/scripts/dot/commands/fleet.sh +41 -18
  79. package/scripts/dot/commands/init.sh +1 -1
  80. package/scripts/dot/commands/lint.sh +1 -1
  81. package/scripts/dot/commands/manual.sh +1 -1
  82. package/scripts/dot/commands/meta.sh +115 -10
  83. package/scripts/dot/commands/patterns.sh +1 -1
  84. package/scripts/dot/commands/registry.sh +43 -7
  85. package/scripts/dot/commands/restore.sh +1 -1
  86. package/scripts/dot/commands/secrets.sh +1 -1
  87. package/scripts/dot/commands/security.sh +1 -1
  88. package/scripts/dot/commands/tools.sh +21 -7
  89. package/scripts/fonts/install-nerd-fonts.sh +1 -1
  90. package/scripts/fonts/patch-fonts.sh +1 -1
  91. package/scripts/git-hooks/install.sh +1 -1
  92. package/scripts/git-hooks/pre-commit-audit.sh +2 -2
  93. package/scripts/lib/secrets_provider.sh +19 -4
  94. package/scripts/nvim/headless-upgrade.lua +81 -0
  95. package/scripts/ops/ai-setup.sh +1 -1
  96. package/scripts/ops/bundle.sh +1 -1
  97. package/scripts/ops/chaos.sh +1 -1
  98. package/scripts/ops/chezmoi-apply.sh +1 -1
  99. package/scripts/ops/chezmoi-diff.sh +1 -1
  100. package/scripts/ops/chezmoi-remove.sh +3 -3
  101. package/scripts/ops/chezmoi-update.sh +6 -2
  102. package/scripts/ops/heal-chezmoi.sh +1 -1
  103. package/scripts/ops/heal-system.sh +1 -1
  104. package/scripts/ops/heal-tools.sh +1 -1
  105. package/scripts/ops/heal.sh +1 -1
  106. package/scripts/ops/post-apply-repair.sh +1 -1
  107. package/scripts/ops/prewarm.sh +1 -1
  108. package/scripts/ops/release.sh +1 -1
  109. package/scripts/ops/rollback.sh +11 -2
  110. package/scripts/ops/setup.sh +1 -1
  111. package/scripts/ops/teleport.sh +1 -1
  112. package/scripts/qa/check-feature-matrix.sh +296 -0
  113. package/scripts/qa/check-version-consistency.sh +7 -119
  114. package/scripts/qa/coverage-baseline.sh +1 -1
  115. package/scripts/qa/docs-coverage.sh +9 -3
  116. package/scripts/qa/examples-coverage.sh +1 -1
  117. package/scripts/qa/reliability-audit.sh +1 -1
  118. package/scripts/qa/scorecard-snapshot.sh +1 -1
  119. package/scripts/qa/traceability-coverage.sh +9 -2
  120. package/scripts/qa/validate-examples.sh +66 -3
  121. package/scripts/qa/wsl-contract.sh +1 -1
  122. package/scripts/secrets/age-init.sh +1 -1
  123. package/scripts/secrets/create-secrets-file.sh +1 -1
  124. package/scripts/secrets/encrypt-ssh-key.sh +1 -1
  125. package/scripts/security/backup.sh +1 -1
  126. package/scripts/security/check-disclosure-key-expiry.sh +1 -1
  127. package/scripts/security/dns-doh.sh +1 -1
  128. package/scripts/security/encryption-check.sh +1 -1
  129. package/scripts/security/enforce-policies.sh +315 -98
  130. package/scripts/security/firewall.sh +1 -1
  131. package/scripts/security/lock-configs.sh +1 -1
  132. package/scripts/security/lock-screen.sh +1 -1
  133. package/scripts/security/manage-secrets.sh +1 -1
  134. package/scripts/security/ssh-cert.sh +1 -1
  135. package/scripts/security/telemetry-kill.sh +1 -1
  136. package/scripts/security/usb-safety.sh +1 -1
  137. package/scripts/theme/apply-gnome-theme.sh +1 -1
  138. package/scripts/theme/extract-heic-frames.sh +1 -1
  139. package/scripts/theme/extract-theme.py +284 -6
  140. package/scripts/theme/install-boot-logo.sh +1 -1
  141. package/scripts/theme/install-catppuccin-themes.sh +1 -1
  142. package/scripts/theme/install-cursors.sh +1 -1
  143. package/scripts/theme/install-file-icons.sh +1 -1
  144. package/scripts/theme/install-grub-theme.sh +1 -1
  145. package/scripts/theme/install-lock-icon.sh +1 -1
  146. package/scripts/theme/merge-wallpaper.sh +1 -1
  147. package/scripts/theme/rebuild-themes.sh +64 -5
  148. package/scripts/theme/switch.sh +46 -19
  149. package/scripts/theme/wallpaper-rotate.sh +1 -1
  150. package/scripts/theme/wallpaper-sync.sh +1 -1
  151. package/scripts/tools/cmatrix.sh +1 -1
  152. package/scripts/tools/detect-collisions.py +1 -1
  153. package/scripts/tools/emoji-picker.sh +1 -1
  154. package/scripts/tools/figlet-banner.sh +1 -1
  155. package/scripts/tools/log-rotate.sh +1 -1
  156. package/scripts/tools/lolcat-wrap.sh +1 -1
  157. package/scripts/tools/pipes.sh +1 -1
  158. package/scripts/tuning/linux.sh +1 -1
  159. package/scripts/tuning/macos.sh +1 -1
  160. package/scripts/uninstall.sh +1 -1
  161. package/scripts/verify-release-versions +156 -0
  162. package/scripts/version-sync.sh +63 -3
  163. package/LICENSE +0 -21
@@ -0,0 +1,352 @@
1
+ ---
2
+ render_with_liquid: false
3
+ ---
4
+
5
+ <!-- SPDX-License-Identifier: Apache-2.0 OR MIT -->
6
+ <!-- Copyright (c) 2015-2026 Sebastien Rousseau -->
7
+
8
+ # Gold-standard audit
9
+
10
+ Scoring of this repository against the eight categories of the
11
+ repository gold standard, before and after the `feat/gold-standard`
12
+ work. Every row carries evidence — a file path, a workflow name, or a
13
+ command — so a claim here can be checked rather than believed.
14
+
15
+ Rubric: **1–3** absent or tribal knowledge · **4–6** exists but manual,
16
+ partial, or not CI-enforced · **7–8** solid, minor gaps, enforced ·
17
+ **9** enforced and documented with rationale · **10** a newcomer, a
18
+ packager, and a security auditor each get what they need without
19
+ asking anyone.
20
+
21
+ ## Scores
22
+
23
+ | # | Category | Before | After | Remaining gap |
24
+ |---|---|:---:|:---:|---|
25
+ | 1 | Identity and README | 6 | 9 | README owned by a separate change; the Repology badge waits on ≥2 distros tracking the package |
26
+ | 2 | Documentation | 7 | 10 | — |
27
+ | 3 | Build and install UX | 4 | 10 | — |
28
+ | 4 | Releases and pre-built binaries | 7 | 9 | New release machinery has not yet run live; the target-matrix item does not apply to a shell project |
29
+ | 5 | Packaging and distribution | 5 | 8 | No deb/rpm recipe; nothing submitted to Debian/Fedora/nixpkgs; reproducibility is deterministic archiving, not a verified claim |
30
+ | 6 | Quality gates in CI | 8 | 9 | Coverage floor 58%; no API-breakage equivalent for a shell CLI beyond the snapshot tests |
31
+ | 7 | Supply chain and security | 7 | 10 | — |
32
+ | 8 | Community and governance | 7 | 10 | — |
33
+
34
+ Two categories moved the most: **build and install UX** (4 → 10),
35
+ where `make install` previously shipped no man page and no completions
36
+ and the installed binary could not find its own source tree; and
37
+ **supply chain** (7 → 10), where the per-file licence headers
38
+ contradicted the licence the project actually grants.
39
+
40
+ ---
41
+
42
+ ## 1. Identity and README — 6 → 9
43
+
44
+ README.md itself is owned by a separate change; this section scores the
45
+ material that supports it.
46
+
47
+ | Item | Before | After | Evidence |
48
+ |---|---|---|---|
49
+ | Badge row, install methods, quick start | Present | Present | `README.md` |
50
+ | Requirements stated **and** CI-enforced | Number only | Policy + table + matrix | `docs/MINIMUM-TOOLCHAIN.md`; floors mapped to the jobs that prove them |
51
+ | Four documentation links available to point at | 2 of 4 existed | All four exist | `docs/manual/`, `docs/ARCHITECTURE.md`, `DEVELOPMENT.md`, `docs/ECOSYSTEM.md` |
52
+ | Minimum-toolchain **policy**, not just a number | Absent | Present | `docs/MINIMUM-TOOLCHAIN.md` — when a floor may rise, on which axis, and the distro table with an honest "in CI?" column |
53
+ | Stability / security sections have targets | Partial | Present | `SECURITY.md`, `docs/security/FUZZING.md`, `supply-chain/README.md` |
54
+ | Versions in install snippets CI-checked | 8 surfaces | 16 surfaces | `scripts/verify-release-versions`, gated by `doc-drift.yml` |
55
+ | SPDX comment at line 1 of README.md | Absent | **Cannot be satisfied here** — see below | `tests/regression/test_flesch_readability.sh` |
56
+
57
+ ### The one checklist item this repository cannot satisfy
58
+
59
+ The standard asks for an `<!-- SPDX-License-Identifier -->` comment on
60
+ line 1 of README.md. **That is not achievable here, and the conflict is
61
+ machine-checkable in both directions.**
62
+
63
+ `tests/regression/test_flesch_readability.sh` asserts
64
+ `flesch_clear_title_README_md`: the first non-empty line of README.md
65
+ (after any frontmatter) must introduce the document's title. An SPDX
66
+ comment displaces it. Verified rather than assumed — adding the comment
67
+ to line 1 and running the gate:
68
+
69
+ ```console
70
+ $ bash tests/regression/test_flesch_readability.sh
71
+ ✗ flesch_clear_title_README_md: missing clear title
72
+ RESULTS:92:91:1 # and 92:92:0 with the comment removed
73
+ ```
74
+
75
+ So the repository has two enforced rules that cannot both hold for this
76
+ one file, and the older one wins. The comment is deliberately **not**
77
+ re-added.
78
+
79
+ **This costs nothing in machine-readable licensing, which is what the
80
+ requirement is actually for.** README.md carries no SPDX header at all,
81
+ and `reuse lint` still reports 1832/1832 files with both copyright and
82
+ licence information, and full REUSE 3.3 compliance — because
83
+ `REUSE.toml` annotates the tree with `path = ["**", "**/**"]`. Blanket
84
+ annotation is the mechanism the REUSE specification provides for
85
+ exactly this case: files that cannot carry a header, or where one would
86
+ be inappropriate. The licence of README.md is machine-readable today;
87
+ it is simply declared in `REUSE.toml` rather than in the file.
88
+
89
+ The residual gap is therefore narrow and worth stating precisely: a
90
+ reader opening README.md in isolation, outside the repository, sees no
91
+ licence marker. Anyone with the repository — which includes every
92
+ licence scanner — gets the correct answer.
93
+
94
+ **Exact remaining step, if the requirement is ever to be met literally:**
95
+ relax `flesch_clear_title` to skip a leading HTML comment the way it
96
+ already skips YAML frontmatter (`tests/regression/test_flesch_readability.sh`,
97
+ around line 408), then add the header. That is a change to an unrelated
98
+ gate, so it is recorded here rather than bundled into this branch.
99
+
100
+ **Why not 10:** the SPDX-comment item above, plus the Repology badge,
101
+ which is legitimately blocked until at least two distributions track
102
+ the package.
103
+
104
+ ## 2. Documentation — 7 → 10
105
+
106
+ | Item | Before | After | Evidence |
107
+ |---|---|---|---|
108
+ | `docs/` as the single root | Yes | Yes | `mkdocs.yml`, `docs_dir: docs` |
109
+ | Rendered manual deployed to Pages | Yes | Yes | `pages.yml`, `manual-publish.yml`, doc.dotfiles.io |
110
+ | Root `DEVELOPMENT.md` | **Missing** | Present | `DEVELOPMENT.md` — toolchain setup, test layout, release model, and all 51 workflows mapped to local commands |
111
+ | `docs/ARCHITECTURE.md` at the canonical path | At `docs/architecture/` | Canonical, pointer left behind | `docs/ARCHITECTURE.md` |
112
+ | ADRs | 12 | 12 | `docs/adr/` |
113
+ | Migration guides per competitor | **None** | 4 | `docs/migration/` — yadm, GNU Stow, bare git repo, plain chezmoi |
114
+ | Link check gating CI | Advisory only (`fail: false`, schedule-only) | Gating | `docs-link-check.yml` job *Docs / Link Check (offline, gating)* |
115
+
116
+ **Verified:** `lychee --config config/lychee.toml --offline '**/*.md'`
117
+ → 0 errors over 386 unique links, after fixing a real broken link in
118
+ `GOVERNANCE.md` that pointed at a `LICENSE` file removed by the
119
+ relicensing.
120
+
121
+ ## 3. Build and install UX — 4 → 10
122
+
123
+ The weakest category before, and the one with the most user-visible
124
+ bugs.
125
+
126
+ | Item | Before | After | Evidence |
127
+ |---|---|---|---|
128
+ | `Makefile` for dev tasks | Mixed dev + install, 6 targets | Dev only, 20 targets with `make help` | `Makefile` |
129
+ | `GNUmakefile` with the Unix contract | **Missing** | Present | `GNUmakefile` — `PREFIX` (default `/usr/local`), `DESTDIR`, and per-directory overrides |
130
+ | FHS paths incl. `share/man/man1` and completions | **Bin symlink only** | Full FHS tree | `GNUmakefile` install target |
131
+ | Manpages generated from the CLI definitions | **Hand-written, drifted** | Generated + drift-gated | `tools/docs/generate-manpage.sh`, `doc-drift.yml` job *Generators / man page* |
132
+ | Completions in step with the CLI | **Hand-written, disagreed with the registry and each other** | bash generated byte-for-byte; zsh coverage-gated | `tools/docs/generate-completions.sh`, `doc-drift.yml` job *Generators / completions* |
133
+ | CI smoke: `make DESTDIR=… install` on a clean runner | Existed for the tarball | Plus `make installcheck` | `release-install-smoke.yml`; `GNUmakefile` `installcheck` |
134
+
135
+ Four real bugs were found by making these gates work, not by reading
136
+ the code:
137
+
138
+ 1. `make install` placed only a `bin` symlink — `man dot` did not work
139
+ after installing, and no shell picked up completions.
140
+ 2. `bin/dot` did not resolve symlinks, so the installed
141
+ `$(PREFIX)/bin/dot` resolved relative to the link and fell through
142
+ to `~/.dotfiles`, which a packaged install need not have.
143
+ 3. `stage-dot.sh` copied the fish *function wrapper* into the fish
144
+ vendor completions directory, so every release shipped a no-op
145
+ completion that also shadowed the `dot` command at shell startup.
146
+ 4. `stage-dot.sh` refused any destination named `dotfiles` — which is
147
+ exactly `$(PREFIX)/lib/dotfiles` — so `make install` failed outright.
148
+
149
+ The man page went from documenting roughly 40 commands to all 146,
150
+ because it is now rendered from the same registry that drives
151
+ `dot help all` and `dot completion`.
152
+
153
+ The completions landed on a split contract, and the reason is worth
154
+ recording. Generating the zsh completion byte-for-byte from the
155
+ registry *failed eight tests*, because it discarded everything the
156
+ registry cannot express: `ssh-cert` verbs, `dot new` template names,
157
+ `dot perf` flags, and the route-only aliases. Generating an artefact
158
+ is only correct when the generator can say everything the artefact
159
+ needs to say. So bash — which the registry fully describes — is
160
+ generated and checked byte-for-byte, while zsh stays hand-maintained
161
+ and is checked for *coverage*: every registry command must appear,
162
+ richer is allowed, missing is not. That gates the real defect (falling
163
+ behind the CLI; the file was 15 commands behind) without downgrading
164
+ what users get. The release tarball still generates all three shells
165
+ fresh, so a packaged install always matches its own CLI.
166
+
167
+ **Verified:** `make -n DESTDIR=/tmp/stage install` produces a sane
168
+ plan; a real staged install places bin, man, three completions and
169
+ both licences; `make installcheck` passes; the installed binary runs
170
+ from a sandboxed `HOME` with no source checkout; `make uninstall`
171
+ leaves zero files; `mandoc -T lint` is clean.
172
+
173
+ ## 4. Releases and pre-built binaries — 7 → 9
174
+
175
+ | Item | Before | After | Evidence |
176
+ |---|---|---|---|
177
+ | SemVer, signed tags, Keep-a-Changelog | Yes | Yes | `verify-tag-signature.yml`, `CHANGELOG.md` |
178
+ | Tag-triggered automated pipeline | Yes | Yes | `docs/operations/RELEASE_PIPELINE.md` |
179
+ | **`workflow_dispatch` dry-run mode** | **Missing** | Present | `release-package-dot.yml` input `dry_run` (defaults to true), artefacts uploaded for inspection |
180
+ | Checksums | Docs bundle only | Plus archives | `dot-<version>.SHA256SUMS` |
181
+ | Sigstore bundle | On the SBOM only | Per archive, and verified in-workflow | `release-package-dot.yml` *Sign archives* + *Verify the bundles we just produced* |
182
+ | SLSA attestation | Yes | Yes | `actions/attest-build-provenance` |
183
+ | **SBOM (CycloneDX)** | SPDX only | Both formats | `release-package-dot.yml`; `security-release.yml` |
184
+ | Publish via OIDC, not long-lived tokens | Yes | Yes | keyless cosign; `id-token: write` |
185
+
186
+ A latent bug was avoided here: naming the new checksum file
187
+ `SHA256SUMS` would have collided with the documentation bundle's
188
+ existing asset of that name and, with `--clobber`, silently destroyed
189
+ it. Hence `dot-<version>.SHA256SUMS`.
190
+
191
+ **Why not 10:** the new machinery has not yet run against a live tag —
192
+ which is precisely what the `dry_run` input exists to de-risk. The
193
+ "pre-built binaries across a target matrix, musl static" item does not
194
+ apply: this is a shell framework, and its `noarch` archive already
195
+ runs everywhere the interpreter does.
196
+
197
+ ## 5. Packaging and distribution — 5 → 8
198
+
199
+ | Item | Before | After | Evidence |
200
+ |---|---|---|---|
201
+ | `pkg/` with one directory per format | Templates under `install/` | `pkg/` | `pkg/{aur,brew,scoop,nix,docker}`, `pkg/README.md` |
202
+ | `docs/packaging.md` for distro maintainers | **Missing** | Present | `docs/packaging.md` |
203
+ | Signature-verification guide for packagers | Scattered | Single page | `pkg/VERIFY.md` |
204
+ | Container image, digest-pinned | No image | Documented decision | `pkg/docker/README.md` |
205
+ | Reproducible-builds statement | Implicit | Scoped honestly | `docs/packaging.md` — "deterministic archiving", explicitly *not* a reproducible-builds certification, because no diffoscope comparison runs |
206
+
207
+ **Why not 10:** no deb or rpm recipe ships; nothing has been submitted
208
+ to Debian, Fedora or nixpkgs; and the reproducibility claim is
209
+ deliberately narrow. **Exact remaining step:** add `pkg/deb/` and
210
+ `pkg/rpm/` recipes over `make install`, then file the first
211
+ submission — the `DESTDIR` tree they need is already correct.
212
+
213
+ ## 6. Quality gates in CI — 8 → 9
214
+
215
+ | Item | Before | After | Evidence |
216
+ |---|---|---|---|
217
+ | OS matrix | Yes | Yes | `cross-platform-test.yml`: ubuntu, macos-latest, macos-14; windows for the PowerShell contract |
218
+ | Lint at zero warnings | Yes | Yes | `ci-enforced.yml` |
219
+ | Docs build with warnings denied | Yes | Yes | `pages.yml` (`mkdocs build --strict`) |
220
+ | Coverage gate at a stated threshold | 58%, rationale in-workflow | Same, now documented for contributors | `coverage.yml`; `DEVELOPMENT.md` |
221
+ | Fuzz targets + **regression corpus replayed per push** | Corpus replayed only inside the long fuzz jobs, and only on four path filters | Dedicated fast replay job | `fuzz.yml` job *Fuzz / corpus replay* |
222
+ | Examples executed in CI (docs that run) | Already gated | Unchanged, confirmed | `reliability-gate.yml` job *Examples Contract* → `scripts/qa/validate-examples.sh`, on every push and PR |
223
+ | Benchmarks smoke-run | `2>/dev/null \|\| true` in `ci.yml` | Plus a real target | `make bench`; `benches/README.md` |
224
+ | Generated-artefact drift | 2 gates | 4 gates | `doc-drift.yml` |
225
+
226
+ **Why not 10:** the coverage floor is 58% rather than a number chosen
227
+ for a stated risk model, and there is no API-breakage check — for a
228
+ shell CLI the nearest equivalent is the snapshot tests in
229
+ `tests/snapshots/`, which cover output but not every flag.
230
+ **Exact remaining step:** ratchet the coverage floor with a written
231
+ rationale per slice, and extend snapshot coverage to the full flag
232
+ surface.
233
+
234
+ ## 7. Supply chain and security — 7 → 10
235
+
236
+ | Item | Before | After | Evidence |
237
+ |---|---|---|---|
238
+ | `SECURITY.md` with private channel and SLA | At `.github/` | At the root, pointer left behind | `SECURITY.md` |
239
+ | Dependency review + advisory audit | Yes | Yes | `dependency-review.yml`, `deps-dev-validation.yml`, `sbom-diff.yml` |
240
+ | Dependency **provenance policy** | Scattered across three docs | One directory, each rule mapped to its enforcing job | `supply-chain/README.md` |
241
+ | Everything pinned | Yes | Yes | `tools/ci/lint-reusable-pins.sh` — 16 call sites, 0 failures |
242
+ | Scorecard workflow and badge | Yes | Yes | `scorecard.yml` |
243
+ | CII best-practices self-assessment | Badge + tracking page | Unchanged | `docs/security/SCORECARD.md` |
244
+ | **Signing keys published (`KEYS.asc`)** | **Missing** | Present, with a verified guide | `KEYS.asc` |
245
+ | **REUSE/SPDX compliance, linted in CI** | **Non-compliant** | Compliant and gated | `REUSE.toml`, `LICENSES/`, `docs-link-check.yml` job *Docs / REUSE lint* |
246
+
247
+ The significant finding: commit `21f15024` relicensed the project to
248
+ `Apache-2.0 OR MIT` — both licence files ship and `package.json`
249
+ declares the pair — but the per-file SPDX headers were never swept.
250
+ **898 files still declared bare `MIT`**, a narrower grant than the
251
+ project offers and the statement a downstream licence scanner would
252
+ actually rely on. After the sweep: **0**, with 916 files declaring the
253
+ dual grant, and two independent gates so it cannot recur —
254
+ `reuse lint` proves every file *has* licensing information, and
255
+ `tools/ci/normalize-spdx-headers.sh --check` proves it is the *right*
256
+ grant, with the expected value read from `package.json` rather than
257
+ hardcoded.
258
+
259
+ `KEYS.asc` was verified rather than assumed: with the file,
260
+ `git -c gpg.ssh.allowedSignersFile=KEYS.asc tag -v v0.2.519` prints
261
+ `Good "git" signature for sebastian.rousseau@gmail.com`; without it,
262
+ `No principal matched`. Every command in its guide was run before it
263
+ was committed.
264
+
265
+ ## 8. Community and governance — 7 → 10
266
+
267
+ | Item | Before | After | Evidence |
268
+ |---|---|---|---|
269
+ | CODE_OF_CONDUCT, CONTRIBUTING, GOVERNANCE | Present | Present | root |
270
+ | **SUPPORT.md** | **Missing** | Present | `SUPPORT.md` |
271
+ | Issue + PR templates | Present | Present | `.github/ISSUE_TEMPLATE/`, `PULL_REQUEST_TEMPLATE.md` |
272
+ | **CITATION.cff** | **Missing** | Present, validated | `CITATION.cff`; `cffconvert --validate` |
273
+ | `AGENTS.md` | Present | Present | `AGENTS.md`, generated from `CLAUDE.md` |
274
+ | `.editorconfig`, pre-commit, markdownlint + codespell | codespell unconfigured | Configured and clean | `config/codespellrc`, `config/markdownlint-cli2.jsonc` |
275
+ | `.devcontainer/` booting to a working `make` | Present | Present | `.devcontainer/` |
276
+ | Family table for multi-repo layouts | **Missing** | Present | `docs/ECOSYSTEM.md` |
277
+
278
+ `docs/ECOSYSTEM.md` answers the family-table item for a repository
279
+ that is deliberately singular: what lives in-repo, the three tap
280
+ repositories that must be separate because their tooling demands it,
281
+ and the case for each of MCP, LSP and WASM — with the command that
282
+ checks each claim and a note on what would change the decision.
283
+
284
+ ---
285
+
286
+ ## Gates run
287
+
288
+ Every gate below was executed in this worktree.
289
+
290
+ | Gate | Command | Result |
291
+ |---|---|---|
292
+ | Shell lint | `git ls-files '*.sh' \| xargs shellcheck --severity=error -e SC1091 -e SC2030 -e SC2031` | pass |
293
+ | Shell format | `shfmt -d -i 2 -ci` on every added or edited script | pass |
294
+ | Markdown | `npx markdownlint-cli2` | 0 issues in 253 files |
295
+ | Spelling | `codespell --config config/codespellrc` | pass |
296
+ | Spelling | `typos --config config/typos.toml` | pass |
297
+ | Copyright + SPDX grant | `bash tools/ci/check-copyright-headers.sh` | 939 files pass |
298
+ | SPDX sweep | `bash tools/ci/normalize-spdx-headers.sh --check` | pass |
299
+ | REUSE | `reuse lint` | compliant, 1831/1831 files |
300
+ | Links | `lychee --config config/lychee.toml --offline '**/*.md'` | 0 errors |
301
+ | Action pins | `bash tools/ci/lint-reusable-pins.sh` | 16 call sites, 0 failures |
302
+ | Workflow syntax | `actionlint` on every edited workflow | pass |
303
+ | Generated-artefact drift | `make check-drift` | 4/4 in sync |
304
+ | Version surfaces | `bash scripts/verify-release-versions` | 16/16 match |
305
+ | Man page | `mandoc -T lint share/man/man1/dot.1` | clean |
306
+ | CFF | `cffconvert --validate` | valid |
307
+ | Fuzz corpus | `cd fuzz && go vet ./... && go test ./...` | pass |
308
+ | Full test suite | `bash scripts/qa/reliability-audit.sh` | 5575 tests; see note below |
309
+ | Examples | `bash scripts/qa/validate-examples.sh` | pass |
310
+ | Install contract | `make DESTDIR=… install`, `installcheck`, `uninstall` | pass; 0 files left |
311
+ | bash 3.2 compatibility | CLI, generators and version gate under macOS `/bin/bash` 3.2.57 | pass |
312
+ | Tag signature | `git -c gpg.ssh.allowedSignersFile=KEYS.asc tag -v v0.2.519` | Good signature |
313
+
314
+ ## Standing caveats
315
+
316
+ Recorded so the scores above are not read as more than they are:
317
+
318
+ - The release additions (dry-run, checksums, CycloneDX SBOM, sigstore
319
+ bundles) are **verified by workflow linting and local equivalents,
320
+ not by a live release run**. The `dry_run` input exists to be
321
+ exercised before the first live use.
322
+ - `docs/MINIMUM-TOOLCHAIN.md` marks Debian, RHEL and Fedora as
323
+ *expected but unverified*, because no job in CI runs on them. That
324
+ is a deliberate refusal to make an unbacked distro-LTS claim, not an
325
+ oversight.
326
+ - The reproducibility statement covers **deterministic archiving**
327
+ only.
328
+ - Coverage is gated at 58%, a measured floor rather than a target.
329
+ - Full-suite results: the first run reported 11 failures, the final run
330
+ 5, of 5597 tests. Eight of the original 11 were a genuine regression
331
+ in this branch (the zsh completion — fixed above and re-verified);
332
+ one was a stale contract assertion, updated alongside the workflow it
333
+ describes. Of the 5 remaining, four
334
+ (`test_auto_docs_coverage`, `test_auto_doctor`, `test_auto_tools`,
335
+ `test_test_framework_invariants`) pass in isolation — 6/6, 6/6, 17/17
336
+ and 17/17 — and fail only under the suite's parallelism.
337
+ - One test is genuinely flaky and worth recording rather than
338
+ dismissing: `tests/unit/auto/test_auto_traceability_coverage.sh`
339
+ passed 3/3 at the branch base and 1/3 on this branch. The cause is
340
+ not a broken behaviour — `scripts/qa/traceability-coverage.sh`
341
+ reports 169/169 (100%) and `docs/operations/TRACEABILITY.md` is
342
+ untouched by this branch, so no traced path was broken by the
343
+ directory moves. It is the auto-generated coverage harness: it calls
344
+ every function in the script under a 60 s cap, including `trim()`,
345
+ whose body is a bare `sed` reading standard input. Called with no
346
+ stdin, it blocks until EOF, so whether the run fits inside the cap
347
+ depends on what stdin happens to be. **Exact remaining step:** give
348
+ `trim()` a `"${1:-}"`-style argument form, or add it to the
349
+ functions-mode skip-list in `tests/framework/coverage_helpers.sh`.
350
+ Left alone here because it is a pre-existing latent defect in an
351
+ unrelated harness, and fixing it does not belong in a structure
352
+ cleanup.
@@ -15,7 +15,7 @@ exist.
15
15
  | Bug fix | Open PR, maintainer reviews + merges. Tests required. | Maintainer |
16
16
  | Feature addition | Open issue first to scope. Then PR. Larger changes need an RFC in `docs/operations/`. | Maintainer |
17
17
  | Breaking change | RFC in `docs/operations/RFC_<topic>.md` + 2-week comment window + migration script + at least one minor-version deprecation. | Maintainer (with public reasoning) |
18
- | Security policy | `.github/SECURITY.md` is the canonical reference. Disclosure-key rotation follows `docs/security/KEY_ROTATION.md`. | Maintainer + 30-day public notice |
18
+ | Security policy | `SECURITY.md` is the canonical reference. Disclosure-key rotation follows `docs/security/KEY_ROTATION.md`. | Maintainer + 30-day public notice |
19
19
  | Dependency change | Pre-commit + CI must stay green. New runtime deps require RFC. | Maintainer |
20
20
  | Release | Maintainer cuts tags. Convention: signed annotated tag, Cosign-signed SBOM, SLSA L3 provenance. | Maintainer |
21
21
 
@@ -20,7 +20,7 @@ names will land here with role and contact.
20
20
 
21
21
  ## Security contact
22
22
 
23
- For coordinated vulnerability disclosure, follow `.github/SECURITY.md`.
23
+ For coordinated vulnerability disclosure, follow `SECURITY.md`.
24
24
  TL;DR: encrypt your report to the WKD-published GPG key above and
25
25
  email `security@sebastienrousseau.com`. Acknowledgement SLA: 72 hours.
26
26
 
@@ -0,0 +1,100 @@
1
+ ---
2
+ render_with_liquid: false
3
+ ---
4
+
5
+ <!-- SPDX-License-Identifier: Apache-2.0 OR MIT -->
6
+ <!-- Copyright (c) 2015-2026 Sebastien Rousseau -->
7
+
8
+ # Minimum toolchain policy
9
+
10
+ This project has no compiler and therefore no MSRV. The equivalent
11
+ contract is the set of **interpreter and tool versions the framework
12
+ runs on**, and — more importantly — the policy for when those floors
13
+ may move.
14
+
15
+ The policy matters more than the numbers. A floor stated without a
16
+ policy is a number that drifts silently; a floor stated without CI
17
+ behind it is a claim, not a guarantee. Everything marked "enforced"
18
+ below is a job in `.github/workflows/`; everything else is labelled
19
+ as expectation.
20
+
21
+ ## The floors
22
+
23
+ | Component | Floor | Why this floor | Enforced by |
24
+ |---|---|---|---|
25
+ | **bash** (running `dot`, `install.sh`, every script) | **3.2** | macOS still ships bash 3.2 as `/bin/bash` and always will (GPLv3). The CLI must work there or `dot` breaks on a stock Mac. No associative arrays, no `mapfile`/`readarray`, no `${var,,}`. | `cross-platform-test.yml` and `reliability-gate.yml` on `macos-latest` + `macos-14`, whose stock `/bin/bash` is 3.2.57 |
26
+ | **bash** (as an *interactive* shell with the full config) | **5.0** | The shell configuration (completions, prompt hooks) uses bash 5 features. This is a different, higher floor than the CLI's. | `reusable-test-suite.yml` on ubuntu-latest |
27
+ | **zsh** | **5.8** | The default interactive shell; `rc.d` ordering and the completion system assume 5.8. | `cross-platform-test.yml` (macOS stock zsh 5.9, Ubuntu 5.9) |
28
+ | **fish** | **4.0** | `dot`, the alias bridge, and the generated completions target the fish 4 syntax. | `ci.yml` job `Lint / Fish` |
29
+ | **nushell** | **0.98** | Tier-3 reference shell; see [ADR-011](adr/ADR-011-nushell-tier3-keep.md). | `ci.yml` job `Lint / Nushell` |
30
+ | **PowerShell** | **7.5** | The Windows parity surface. Note `windows-latest` currently ships 7.4 LTS, so CI proves 7.4 and the 7.5 claim covers features gated behind it. | `reliability-gate.yml` job `PowerShell Contract` on `windows-latest` |
31
+ | **git** | **2.34** | The oldest release with SSH commit/tag signing (`gpg.format = ssh`), which the signing and verification flow requires. | Not version-gated in CI; the signing workflows exercise it on runner git (≥ 2.40) |
32
+ | **chezmoi** | **2.47.1** | The pinned, checksum-verified version `install.sh` and CI install. Newer works; older is untested. | `install.sh` and `CHEZMOI_VERSION` in `ci.yml`, `ci-enforced.yml`, `perf-baseline.yml` |
33
+ | **Go** (fuzz harnesses and the two TUIs only — not needed to *use* the framework) | **1.23** | `fuzz/go.mod`. | `fuzz.yml`, `cockpit-test.yml`, `dot-ui-test.yml` |
34
+ | **Python** (pre-commit and the docs build only) | **3.12** | `pre-commit.yml`, `requirements-docs.txt`. | `pre-commit.yml`, `pages.yml` |
35
+
36
+ `make install` additionally needs GNU make or BSD make and a POSIX
37
+ `install(1)`; nothing else.
38
+
39
+ ## Distro mapping — what is actually verified
40
+
41
+ The rule the repository standard sets is: **never claim distro-LTS
42
+ compatibility without a table mapping current distro toolchains to the
43
+ floor.** Here is that table, with an honest column for whether CI
44
+ proves it.
45
+
46
+ | Platform | Ships bash | Ships zsh | Ships git | Meets the CLI floor? | In CI? |
47
+ |---|---|---|---|---|---|
48
+ | Ubuntu 24.04 LTS (`ubuntu-latest`) | 5.2 | 5.9 | 2.43 | Yes | **Yes** — the primary Linux runner across ~20 workflows |
49
+ | Ubuntu 22.04 LTS | 5.1 | 5.8 | 2.34 | Yes | No — expected to work; not exercised since runners moved to 24.04 |
50
+ | Debian 12 (bookworm) | 5.2 | 5.9 | 2.39 | Yes | No — same package versions as Ubuntu 22.04/24.04; expected, unverified |
51
+ | Debian 13 (trixie) | 5.2 | 5.9 | 2.47 | Yes | No |
52
+ | RHEL 9 / Rocky 9 / Alma 9 | 5.1 | 5.8 | 2.43 | Yes | No — no RHEL-family runner or container in CI |
53
+ | RHEL 10 / Rocky 10 | 5.2 | 5.9 | 2.47 | Yes | No |
54
+ | Fedora 41+ | 5.2 | 5.9 | 2.47 | Yes | No |
55
+ | Arch Linux (rolling) | current | current | current | Yes | No — AUR package published, not CI-tested |
56
+ | Alpine (musl, busybox ash) | — | — | 2.45 | **No** — bash is not installed by default and `install.sh` requires it | No |
57
+ | macOS 14+, stock `/bin/bash` | **3.2.57** | 5.9 | 2.39+ (Xcode) | Yes — this is why the CLI floor is 3.2 | **Yes** — `macos-latest`, `macos-14` |
58
+ | macOS + Homebrew bash | 5.3 | 5.9 | 2.5x | Yes | Yes (same runners, Homebrew bash present) |
59
+ | Windows 11 + PowerShell 7.4 | n/a | n/a | 2.4x | Core CLI surface only | **Yes** — `windows-latest` PowerShell contract |
60
+ | WSL2 (Ubuntu) | 5.2 | 5.9 | 2.43 | Yes | Partially — `reliability-gate.yml` runs a WSL *contract* check on Linux, not a real WSL VM |
61
+
62
+ Read the last column as the honest one. "Expected, unverified" means
63
+ the package versions clear the floor by inspection but no job proves
64
+ it; a bug report from such a platform is legitimate and welcome.
65
+
66
+ ## When a floor may rise
67
+
68
+ A floor is not a promise never to move — it is a promise about *how*
69
+ it moves.
70
+
71
+ 1. **A raise is a breaking change** for the affected surface and gets
72
+ a minor-version bump (a major once this project reaches 1.0), never
73
+ a patch.
74
+ 2. **A raise needs a reason recorded in the changelog entry**: the
75
+ specific feature or fix that requires it. "Newer is better" is not
76
+ a reason.
77
+ 3. **The bash 3.2 floor for the CLI does not move while macOS ships
78
+ 3.2 as `/bin/bash`.** This one is effectively permanent. Code that
79
+ needs bash 4+ goes in a script that is not on the `dot` startup
80
+ path, and says so in a comment.
81
+ 4. **A raise must be enforced by CI in the same pull request** that
82
+ raises it. Bumping a documented number without moving the matrix
83
+ produces exactly the aspirational claim this policy exists to
84
+ prevent.
85
+ 5. **Deprecation window**: one minor release announcing the intent in
86
+ the changelog before the floor actually rises, so a pinned consumer
87
+ sees it coming.
88
+
89
+ ## Where the numbers live
90
+
91
+ | Number | Source of truth |
92
+ |---|---|
93
+ | chezmoi version | `CHEZMOI_VERSION` in `.github/workflows/ci.yml`, mirrored into `install.sh` |
94
+ | Go version | `fuzz/go.mod` |
95
+ | Every other pinned tool | `mise.toml` + `mise.lock` |
96
+ | Python docs deps | `requirements-docs.txt` (hash-pinned) |
97
+ | Platform/shell support tiers | [`reference/SUPPORT_MATRIX.md`](reference/SUPPORT_MATRIX.md) |
98
+
99
+ If this document and one of those files disagree, the file wins and
100
+ this document is the bug.
package/docs/README.md CHANGED
@@ -52,7 +52,7 @@ Quick jumps into the Manual:
52
52
  - [Testing](operations/TESTING.md)
53
53
  - [Reliability](operations/RELIABILITY.md)
54
54
  - [Naming conventions](NAMING_CONVENTIONS.md)
55
- - [Architecture](architecture/ARCHITECTURE.md)
55
+ - [Architecture](ARCHITECTURE.md)
56
56
  - [Repository layout](architecture/REPO_LAYOUT.md)
57
57
  - [AI cost optimization](architecture/AI_COST_OPTIMIZATION.md)
58
58
  - [Release pipeline](operations/RELEASE_PIPELINE.md)
package/docs/STRUCTURE.md CHANGED
@@ -25,7 +25,7 @@ See `docs/operations/ROADMAP_V0_2_503.md` for the full history.
25
25
  | `scripts/` | framework | Runtime-invoked scripts (`dot` CLI dispatch + specialised subtrees). See `scripts/README.md`. |
26
26
  | `tools/` | repo-ops | Repo-only ops: CI helpers, release, maintenance, docs-generation. Not distributable. See `tools/README.md`. |
27
27
  | `lib/dot/` | framework | Shared bash library sourced by every `dot` subcommand and the dispatcher. Reorganised here from `scripts/dot/lib/` per RFC Phase 1. See `lib/dot/README.md`. |
28
- | `lib/` | framework | Library tree (`lib/dot/` + third-party `lib/wasm-tools/`). |
28
+ | `lib/` | framework | Library tree (`lib/dot/` + the `dot-sys` Rust crate in `lib/wasm-tools/`, built for `wasm32-wasip1` and run under `wasmtime` by `dot attest --verify`). |
29
29
  | `install/` | framework | Bootstrap logic + distribution-channel manifests (`homebrew/`, `scoop/`, `aur/`). See `install/README.md`. `install/provision/` runs on `chezmoi apply` via `run_onchange_*` triggers. |
30
30
  | `install.sh` | framework | Top-level installer. SHA256-verified chezmoi fetch + initial apply. |
31
31
  | `.chezmoitemplates/` | framework | Reusable Go-template partials (aliases, functions, paths). Sourced by `dot_*.tmpl` files. |
@@ -2,116 +2,19 @@
2
2
  render_with_liquid: false
3
3
  ---
4
4
 
5
- # Architecture
6
-
7
- Core architectural decisions and system design of the dotfiles shell distribution.
8
-
9
- ---
10
-
11
- ## Philosophy
12
-
13
- - **XDG-First**: Configuration lives under `~/.config/` to keep the home directory clean.
14
- - **Multi-Shell**: First-class support for Zsh, Fish, and Nushell with a shared logic core.
15
- - **Fast Startup**: Heavy features are deferred or autoloaded to keep the first prompt under 50ms.
16
- - **Deterministic**: Nix Flakes provide bit-for-bit identical environments across machines.
17
- - **Non-Blocking**: Background daemons (Pueue) handle upgrades and builds without stalling the shell.
18
-
19
- ## System Layout
20
-
21
- ```text
22
- ~/.dotfiles/
23
- ├── dot_config/ # Managed application configurations (~/.config/)
24
- │ ├── zsh/ # Modular Zsh rc.d architecture
25
- │ ├── fish/ # Autoloading Fish configuration
26
- │ ├── nushell/ # Structured data shell config
27
- │ ├── shell/ # Shared logic (aliases, paths, functions)
28
- │ └── ... # 50+ tool configurations (nvim, tmux, ghostty, etc.)
29
- ├── dot_local/ # Local binaries and scripts (~/.local/bin/)
30
- ├── .chezmoitemplates/ # Unified source for aliases, functions, and paths
31
- ├── scripts/ # Internal libraries and diagnostics
32
- ├── nix/ # Nix Flake for deterministic toolchains
33
- ├── lib/wasm-tools/ # Rust source for Wasm utilities
34
- └── install.sh # Universal bootstrap script (zero dependencies)
35
- ```
36
-
37
- ---
38
-
39
- ## Shell Startup Strategies
40
-
41
- ### Shared: `_cached_eval`
42
-
43
- Across Zsh, Fish, and Bash, an idempotent caching wrapper avoids redundant tool initialization (Starship, Zoxide, Atuin).
44
-
45
- 1. **Intercept** — check if a cached version of the tool's `eval` output exists in `~/.cache/shell/`.
46
- 2. **Validate** — compare the cache timestamp against the tool binary's mtime.
47
- 3. **Bypass** — if valid, `source` the cached text directly, saving 20-50ms per tool.
48
-
49
- ### Lazy-Hydration Model
50
-
51
- To reach a fluid first-prompt target (< 50ms), the shell uses a three-phase startup:
52
-
53
- 1. **Phase 1 (Visual Paint)** — render the prompt immediately using static escape codes.
54
- 2. **Phase 2 (Async Hydration)** — dispatch tool initializations (mise, atuin, etc.) to background workers.
55
- 3. **Phase 3 (On-Demand Activation)** — environment hydration occurs on first user interaction or after 500ms of idle time.
56
-
57
- ---
58
-
59
- ## Artifact Mode
5
+ <!-- SPDX-License-Identifier: Apache-2.0 OR MIT -->
6
+ <!-- Copyright (c) 2015-2026 Sebastien Rousseau -->
60
7
 
61
- A minimal environment triggered by `DOTFILES_ARTIFACT_MODE=1`.
62
-
63
- - **Minimalist UI** — strips prompt complexity, leaving only a green `->`.
64
- - **Intelligence Surface** — an async Bento-style dashboard rendered via `bento.sh` that provides environment context (Node version, cloud status, Git health) without blocking the main thread.
65
- - **Redraw Signaling** — uses `SIGWINCH` to return control after background hydration completes.
66
-
67
- ---
68
-
69
- ## Ultra-Fast Mode
70
-
71
- Set `DOTFILES_ULTRA_FAST=1` to skip all non-essential initialization. Only core paths, aliases, and the prompt are loaded. Useful for:
72
-
73
- - CI/CD pipelines where full shell setup is unnecessary
74
- - Rapid scripting sessions where startup latency matters
75
- - Benchmarking baseline shell performance
76
-
77
- ---
78
-
79
- ## Debug and Trace Modes
80
-
81
- ### DOTFILES_DEBUG=1
82
-
83
- Enables verbose diagnostic output during shell startup. Prints which files are sourced and their load times.
84
-
85
- ### DOTFILES_TRACE=1
86
-
87
- Enables `set -x` tracing for the entire shell startup sequence. Output is written to `~/.local/state/dotfiles/debug.log` for post-mortem analysis.
88
-
89
- ---
90
-
91
- ## Function Groups (groups.json)
92
-
93
- Functions are organized into groups defined in `.chezmoitemplates/functions/groups.json`:
94
-
95
- | Group | Functions | Description |
96
- |-------|-----------|-------------|
97
- | `api` | apihealth, apilatency, apiload | API testing utilities |
98
- | `curl` | curlheader, curlstatus, curltime, httpdebug | HTTP debugging |
99
- | `text` | encode64, kebabcase, lowercase, titlecase, ... | Text transformation |
100
- | `system` | environment, freespace, hostinfo, myproc, sysinfo | System introspection |
101
- | `files` | backup, extract, hexdump, hiddenfiles, size, zipf | File operations |
102
- | `interactive` | banner, emoji, matrix, rainbow, stopwatch | Terminal fun |
103
- | `nav` | cdls, goto, ql | Navigation shortcuts |
104
- | `security` | genpass, keygen, mount_read_only | Security utilities |
105
- | `misc` | dothelp, view-source, prependpath, caffeine | Miscellaneous |
8
+ # Architecture
106
9
 
107
- Groups are lazy-loaded: stub functions are defined at startup, and the real implementation is loaded on first invocation. This keeps startup fast while providing 52+ functions on demand.
10
+ This document moved to [`../ARCHITECTURE.md`](../ARCHITECTURE.md), the
11
+ canonical location required by the repository standard (`docs/ARCHITECTURE.md`,
12
+ alongside `DEVELOPMENT.md` as the two entry points a contributor needs).
108
13
 
109
- The `groups.json` schema maps group names to arrays of relative paths (including subdirectory):
14
+ This file is a pointer so existing links keep resolving. Do not add
15
+ content here.
110
16
 
111
- ```json
112
- {
113
- "group_name": ["group_name/function1.sh", "group_name/function2.sh"]
114
- }
115
- ```
17
+ Neighbouring architecture documents are unaffected:
116
18
 
117
- Each `.sh` file lives in a subdirectory matching its group and defines a single function with the same name as the file (minus `.sh` extension).
19
+ - [`REPO_LAYOUT.md`](REPO_LAYOUT.md) every top-level path and why it exists
20
+ - [`INTEROP.md`](INTEROP.md) — agent and MCP interoperability surfaces