@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.
- package/CHANGELOG.md +191 -0
- package/README.md +1164 -164
- package/docs/ARCHITECTURE.md +117 -0
- package/docs/COPYRIGHT +1 -1
- package/docs/ECOSYSTEM.md +220 -0
- package/docs/GOLD-STANDARD-AUDIT.md +352 -0
- package/docs/GOVERNANCE.md +1 -1
- package/docs/MAINTAINERS.md +1 -1
- package/docs/MINIMUM-TOOLCHAIN.md +100 -0
- package/docs/README.md +1 -1
- package/docs/STRUCTURE.md +1 -1
- package/docs/architecture/ARCHITECTURE.md +11 -108
- package/docs/architecture/REPO_LAYOUT.md +4 -4
- package/docs/guides/MACOS_ICLOUD_SYMLINKS.md +121 -0
- package/docs/index.md +3 -3
- package/docs/manual/00-introduction.md +1 -1
- package/docs/manual/03-reference/01-dot-cli.md +28 -3
- package/docs/manual/command-index.md +24 -4
- package/docs/manual/concept-index.md +2 -0
- package/docs/migration/README.md +81 -0
- package/docs/migration/from-bare-git-repo.md +156 -0
- package/docs/migration/from-gnu-stow.md +165 -0
- package/docs/migration/from-plain-chezmoi.md +148 -0
- package/docs/migration/from-yadm.md +187 -0
- package/docs/operations/PERFORMANCE_BUDGETS.md +196 -0
- package/docs/operations/REGISTRY.md +1 -1
- package/docs/operations/RELEASE_PIPELINE.md +4 -4
- package/docs/operations/TESTING.md +3 -3
- package/docs/operations/TRACEABILITY.md +1 -0
- package/docs/packaging.md +222 -0
- package/docs/reference/FEATURE-MATRIX.md +646 -0
- package/docs/reference/TOOLS.md +1 -1
- package/docs/reference/UTILS.md +1 -0
- package/docs/security/COMPLIANCE.md +1 -1
- package/docs/security/DISCLOSURE.md +4 -4
- package/docs/security/FUZZING.md +113 -18
- package/docs/security/KEY_ROTATION.md +1 -1
- package/docs/security/SCORECARD.md +3 -3
- package/docs/security/VERIFY_RELEASE.md +2 -2
- package/install.sh +6 -6
- package/package.json +2 -2
- package/scripts/ci/check-copyright-headers.sh +1 -1
- package/scripts/ci/check-shell-preamble.sh +1 -1
- package/scripts/ci/guard-gitleaks-checkout.sh +1 -1
- package/scripts/demo/record.sh +1 -1
- package/scripts/diagnostics/a2a-conformance.sh +1 -1
- package/scripts/diagnostics/alias-governance.sh +30 -3
- package/scripts/diagnostics/aliases-cheatsheet.sh +1 -1
- package/scripts/diagnostics/aliases-manifest.sh +1 -1
- package/scripts/diagnostics/attest-verify.sh +147 -0
- package/scripts/diagnostics/benchmark.sh +1 -1
- package/scripts/diagnostics/conflicts.sh +1 -1
- package/scripts/diagnostics/doctor-unified.sh +6 -2
- package/scripts/diagnostics/doctor.sh +56 -10
- package/scripts/diagnostics/drift-dashboard.sh +3 -2
- package/scripts/diagnostics/health.sh +43 -10
- package/scripts/diagnostics/history-analysis.sh +1 -1
- package/scripts/diagnostics/mcp-doctor.sh +2 -2
- package/scripts/diagnostics/perf.sh +1 -1
- package/scripts/diagnostics/scorecard.sh +3 -2
- package/scripts/diagnostics/secret-governance.sh +1 -1
- package/scripts/diagnostics/security-score.sh +1 -1
- package/scripts/diagnostics/smoke-test.sh +1 -1
- package/scripts/diagnostics/snapshot.sh +1 -1
- package/scripts/diagnostics/verify.sh +1 -1
- package/scripts/diagnostics/verify_state.sh +1 -1
- package/scripts/diagnostics/version-locks.sh +1 -1
- package/scripts/diagnostics/workstation-attestation.sh +26 -1
- package/scripts/dot/commands/agent.sh +64 -14
- package/scripts/dot/commands/agents.sh +24 -8
- package/scripts/dot/commands/ai.sh +20 -7
- package/scripts/dot/commands/aliases.sh +1 -1
- package/scripts/dot/commands/appearance.sh +1 -1
- package/scripts/dot/commands/completion.sh +42 -5
- package/scripts/dot/commands/core.sh +1 -1
- package/scripts/dot/commands/diagnostics.sh +1 -1
- package/scripts/dot/commands/env-emit.sh +1 -1
- package/scripts/dot/commands/fleet.sh +41 -18
- package/scripts/dot/commands/init.sh +1 -1
- package/scripts/dot/commands/lint.sh +1 -1
- package/scripts/dot/commands/manual.sh +1 -1
- package/scripts/dot/commands/meta.sh +115 -10
- package/scripts/dot/commands/patterns.sh +1 -1
- package/scripts/dot/commands/registry.sh +43 -7
- package/scripts/dot/commands/restore.sh +1 -1
- package/scripts/dot/commands/secrets.sh +1 -1
- package/scripts/dot/commands/security.sh +1 -1
- package/scripts/dot/commands/tools.sh +21 -7
- package/scripts/fonts/install-nerd-fonts.sh +1 -1
- package/scripts/fonts/patch-fonts.sh +1 -1
- package/scripts/git-hooks/install.sh +1 -1
- package/scripts/git-hooks/pre-commit-audit.sh +2 -2
- package/scripts/lib/secrets_provider.sh +19 -4
- package/scripts/nvim/headless-upgrade.lua +81 -0
- package/scripts/ops/ai-setup.sh +1 -1
- package/scripts/ops/bundle.sh +1 -1
- package/scripts/ops/chaos.sh +1 -1
- package/scripts/ops/chezmoi-apply.sh +1 -1
- package/scripts/ops/chezmoi-diff.sh +1 -1
- package/scripts/ops/chezmoi-remove.sh +3 -3
- package/scripts/ops/chezmoi-update.sh +6 -2
- package/scripts/ops/heal-chezmoi.sh +1 -1
- package/scripts/ops/heal-system.sh +1 -1
- package/scripts/ops/heal-tools.sh +1 -1
- package/scripts/ops/heal.sh +1 -1
- package/scripts/ops/post-apply-repair.sh +1 -1
- package/scripts/ops/prewarm.sh +1 -1
- package/scripts/ops/release.sh +1 -1
- package/scripts/ops/rollback.sh +11 -2
- package/scripts/ops/setup.sh +1 -1
- package/scripts/ops/teleport.sh +1 -1
- package/scripts/qa/check-feature-matrix.sh +296 -0
- package/scripts/qa/check-version-consistency.sh +7 -119
- package/scripts/qa/coverage-baseline.sh +1 -1
- package/scripts/qa/docs-coverage.sh +9 -3
- package/scripts/qa/examples-coverage.sh +1 -1
- package/scripts/qa/reliability-audit.sh +1 -1
- package/scripts/qa/scorecard-snapshot.sh +1 -1
- package/scripts/qa/traceability-coverage.sh +9 -2
- package/scripts/qa/validate-examples.sh +66 -3
- package/scripts/qa/wsl-contract.sh +1 -1
- package/scripts/secrets/age-init.sh +1 -1
- package/scripts/secrets/create-secrets-file.sh +1 -1
- package/scripts/secrets/encrypt-ssh-key.sh +1 -1
- package/scripts/security/backup.sh +1 -1
- package/scripts/security/check-disclosure-key-expiry.sh +1 -1
- package/scripts/security/dns-doh.sh +1 -1
- package/scripts/security/encryption-check.sh +1 -1
- package/scripts/security/enforce-policies.sh +315 -98
- package/scripts/security/firewall.sh +1 -1
- package/scripts/security/lock-configs.sh +1 -1
- package/scripts/security/lock-screen.sh +1 -1
- package/scripts/security/manage-secrets.sh +1 -1
- package/scripts/security/ssh-cert.sh +1 -1
- package/scripts/security/telemetry-kill.sh +1 -1
- package/scripts/security/usb-safety.sh +1 -1
- package/scripts/theme/apply-gnome-theme.sh +1 -1
- package/scripts/theme/extract-heic-frames.sh +1 -1
- package/scripts/theme/extract-theme.py +284 -6
- package/scripts/theme/install-boot-logo.sh +1 -1
- package/scripts/theme/install-catppuccin-themes.sh +1 -1
- package/scripts/theme/install-cursors.sh +1 -1
- package/scripts/theme/install-file-icons.sh +1 -1
- package/scripts/theme/install-grub-theme.sh +1 -1
- package/scripts/theme/install-lock-icon.sh +1 -1
- package/scripts/theme/merge-wallpaper.sh +1 -1
- package/scripts/theme/rebuild-themes.sh +64 -5
- package/scripts/theme/switch.sh +46 -19
- package/scripts/theme/wallpaper-rotate.sh +1 -1
- package/scripts/theme/wallpaper-sync.sh +1 -1
- package/scripts/tools/cmatrix.sh +1 -1
- package/scripts/tools/detect-collisions.py +1 -1
- package/scripts/tools/emoji-picker.sh +1 -1
- package/scripts/tools/figlet-banner.sh +1 -1
- package/scripts/tools/log-rotate.sh +1 -1
- package/scripts/tools/lolcat-wrap.sh +1 -1
- package/scripts/tools/pipes.sh +1 -1
- package/scripts/tuning/linux.sh +1 -1
- package/scripts/tuning/macos.sh +1 -1
- package/scripts/uninstall.sh +1 -1
- package/scripts/verify-release-versions +156 -0
- package/scripts/version-sync.sh +63 -3
- 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.
|
package/docs/GOVERNANCE.md
CHANGED
|
@@ -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 |
|
|
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
|
|
package/docs/MAINTAINERS.md
CHANGED
|
@@ -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
|
|
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](
|
|
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/` +
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
14
|
+
This file is a pointer so existing links keep resolving. Do not add
|
|
15
|
+
content here.
|
|
110
16
|
|
|
111
|
-
|
|
112
|
-
{
|
|
113
|
-
"group_name": ["group_name/function1.sh", "group_name/function2.sh"]
|
|
114
|
-
}
|
|
115
|
-
```
|
|
17
|
+
Neighbouring architecture documents are unaffected:
|
|
116
18
|
|
|
117
|
-
|
|
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
|