@sebastienrousseau/dotfiles 0.2.519 → 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 +182 -0
  2. package/README.md +1163 -163
  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 +3 -3
  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
@@ -35,7 +35,7 @@ Integrated tools organized by role in the workflow.
35
35
  | Tool | Purpose | Description |
36
36
  | :--- | :--- | :--- |
37
37
  | **Pueue** | Task queue | Offload long-running tasks to a background daemon |
38
- | **Wasmtime** | Wasm runtime | Run pre-compiled Rust/Zig tools as WebAssembly modules |
38
+ | **Wasmtime** | Wasm runtime | Runs `lib/wasm-tools` (`dot-sys.wasm`) for `dot attest --verify` |
39
39
  | **SOPS** | Secrets operations | Encrypted secrets with automatic en/decryption |
40
40
 
41
41
  ---
@@ -198,6 +198,7 @@ Every `dot` command's individually-enforced subcommands (see `dot help`).
198
198
  | `dot agent conformance` | Run the A2A conformance test suite |
199
199
  | `dot mcp doctor` | Run the MCP policy/supply-chain/config audit |
200
200
  | `dot mcp registry` | Show the configured MCP server registry |
201
+ | `dot mcp serve` | Run the stdio MCP server (JSON-RPC 2.0 on stdin/stdout) |
201
202
  | `dot secrets edit` | Edit the encrypted secrets file (age) |
202
203
  | `dot secrets set` | Store a secret value under a key |
203
204
  | `dot secrets get` | Retrieve a secret value (--raw for plaintext) |
@@ -370,7 +370,7 @@ bash tests/unit/test_dot_commands_apply.sh
370
370
 
371
371
  | File | Purpose | Location |
372
372
  |------|---------|----------|
373
- | SECURITY.md | Vulnerability reporting | `.github/SECURITY.md` |
373
+ | SECURITY.md | Vulnerability reporting | `SECURITY.md` |
374
374
  | CONTRIBUTING.md | Contribution guidelines | `.github/CONTRIBUTING.md` |
375
375
  | CODEOWNERS | Code ownership | `.github/CODEOWNERS` |
376
376
  | INCIDENT_RESPONSE.md | Incident response plan | `docs/security/` |
@@ -34,7 +34,7 @@ gpg --fingerprint security@sebastienrousseau.com
34
34
  ```
35
35
 
36
36
  The fingerprint must match the one published in
37
- [`.github/SECURITY.md`](https://github.com/sebastienrousseau/dotfiles/blob/main/.github/SECURITY.md). Cross-verify
37
+ [`SECURITY.md`](https://github.com/sebastienrousseau/dotfiles/blob/main/SECURITY.md). Cross-verify
38
38
  against the SSH signing key in `dot_config/git/allowed_signers.tmpl`
39
39
  — the maintainer signs commits with the same identity, so both
40
40
  fingerprints derive from the same identity claim.
@@ -75,7 +75,7 @@ subjects in plain text).
75
75
  ## 5. Acknowledgement
76
76
 
77
77
  You should receive an acknowledgement within the SLA in
78
- [`.github/SECURITY.md`](https://github.com/sebastienrousseau/dotfiles/blob/main/.github/SECURITY.md):
78
+ [`SECURITY.md`](https://github.com/sebastienrousseau/dotfiles/blob/main/SECURITY.md):
79
79
 
80
80
  | Severity | Initial response |
81
81
  |---|---|
@@ -107,7 +107,7 @@ The maintainer commits to:
107
107
  - Public credit at fix time in the release notes (unless you
108
108
  request anonymity at report time).
109
109
  - A backport to any actively-supported release line listed in
110
- `.github/SECURITY.md`.
110
+ `SECURITY.md`.
111
111
 
112
112
  ## What NOT to do
113
113
 
@@ -122,7 +122,7 @@ The maintainer commits to:
122
122
 
123
123
  ## See also
124
124
 
125
- - [`.github/SECURITY.md`](https://github.com/sebastienrousseau/dotfiles/blob/main/.github/SECURITY.md) — policy
125
+ - [`SECURITY.md`](https://github.com/sebastienrousseau/dotfiles/blob/main/SECURITY.md) — policy
126
126
  overview + fingerprint.
127
127
  - [`docs/security/KEY_ROTATION.md`](KEY_ROTATION.md) — schedule for
128
128
  when the disclosure key is rotated.
@@ -26,56 +26,144 @@ Drift between the shell and Go port IS the bug class the
26
26
  fuzzer is designed to surface — if the Go port accepts a string
27
27
  the shell rejects (or vice-versa), one of them has a hole.
28
28
 
29
+ ## Where the harnesses live
30
+
31
+ The framework ships three Go binaries as well as the shell, so
32
+ harnesses live in four modules:
33
+
34
+ | Module | Harnesses | Runs against |
35
+ |--------|-----------|--------------|
36
+ | `fuzz` | 11 | ports of the shell helpers **and** of the two binaries' parsers — this is the package OSS-Fuzz and ClusterFuzzLite compile |
37
+ | `defaults/dot_local/share/dot-ui` | 8 | the real dot-ui implementation, in-module |
38
+ | `defaults/dot_local/share/dot-ai-tui` | 11 | the real dot-ai-tui implementation, in-module |
39
+ | `defaults/dot_local/share/dot-mcp` | 5 | the real MCP server, in-module — everything a peer can put on the wire |
40
+
41
+ `dot-ui` and `dot-ai-tui` are `package main` in their own modules,
42
+ which OSS-Fuzz's `compile_native_go_fuzzer` cannot import — it needs a
43
+ library package. Their parsers are therefore **ported** into
44
+ `fuzz` alongside the shell ports, and fuzzed
45
+ in-module as well. The in-module targets are the ones that catch real
46
+ bugs on every push; the ports are what runs continuously at scale.
47
+ The same lockstep rule applies: drift between a port and its original
48
+ is a bug in one of them.
49
+
29
50
  ## Harnesses today
30
51
 
52
+ ### Ports (built by OSS-Fuzz / ClusterFuzzLite)
53
+
31
54
  | Harness | Mirrors | What it proves |
32
55
  |---------|---------|----------------|
33
56
  | `FuzzValidateName` | `scripts/dot/lib/utils.sh:101` (`validate_name`) | Every accepted name contains only `[a-zA-Z0-9._-]`; no shell metacharacter slips through; empty input refused. |
34
57
  | `FuzzInitURLResolver` | `scripts/dot/commands/init.sh` (URL construction in `dot init <user\|owner/repo\|url>`) | Accepted URLs use `https://` / `git@` / `ssh://` only; plain HTTP refused; no shell metacharacters in constructed URLs; one input shape per acceptable form. |
58
+ | `FuzzUIEventLine` | dot-ui `run.go` (`parseEvent`, `renderBar`) | A line either decodes to valid JSON or is refused; an accepted event round-trips; the derived progress width is always a legal repeat count. |
59
+ | `FuzzUIHexColor` | dot-ui `theme.go` (`parseColor`) | An accepted `DOT_UI_*` value is a literal `#rgb`/`#rrggbb` with no metacharacter or escape sequence — these are interpolated into terminal escapes. |
60
+ | `FuzzUIPickFilter` | dot-ui `pick.go` (`fuzzyMatch`, `readItems`) | No blank candidate survives; every candidate matches itself in any script; a query longer than the candidate never matches. |
61
+ | `FuzzUIPickArgs` | dot-ui `main.go` (`parsePickArgs`) | The parser never invents a value; every prefix of the argument list is safe. |
62
+ | `FuzzUITableRows` | dot-ui `table.go` (`runTable` input) | The `\x1f` split is reversible, so no cell can merge into or leak across a neighbouring column. |
63
+ | `FuzzAISessionFile` | dot-ai-tui `main.go` (`parseSession`) | A malformed session file decodes to nothing, never to a partial or mutated transcript; a valid one round-trips. |
64
+ | `FuzzAISqliteOutput` | dot-ai-tui `main.go` (`filterSqliteOutput`) | No `~/.sqliterc` meta line (`.timer`, `Run Time:`) survives into the cost/run data the cockpit renders. |
65
+ | `FuzzAIFenceTag` | dot-ai-tui `main.go` (`langRe`, `highlight`) | Every fence info string taken from model output is refused or a short identifier, so an unbounded chroma lexer lookup cannot stall rendering; prose segments survive segmentation. |
66
+ | `FuzzAIGatewayURL` | dot-ai-tui `main.go` (`gatewayURL`) | The health-check URL always keeps the `http` scheme and the configured host and port verbatim. |
67
+
68
+ ### In-module (against the real implementation)
69
+
70
+ | Module | Harnesses |
71
+ |--------|-----------|
72
+ | dot-ui | `FuzzParseEvent`, `FuzzStepApply`, `FuzzParseColor`, `FuzzFuzzyMatch`, `FuzzPickKeys`, `FuzzRunTable`, `FuzzReadItems`, `FuzzParsePickArgs` |
73
+ | dot-ai-tui | `FuzzHighlight`, `FuzzBuildPrompt`, `FuzzHandleSlash`, `FuzzPalette`, `FuzzWindowRows`, `FuzzRenderTranscript`, `FuzzParseSession`, `FuzzFilterSqliteOutput`, `FuzzGatewayURL`, `FuzzModelKeys`, `FuzzModelCycle` |
74
+ | dot-mcp | `FuzzReadFrames`, `FuzzDecodeRequest`, `FuzzValidateArgs`, `FuzzServeSession`, `FuzzBuildCallResult` |
75
+
76
+ Each module's `FEATURES.md` maps every harness to the feature it
77
+ covers, and a matrix test fails if a harness is missing from it.
78
+
79
+ ### Findings so far
80
+
81
+ | Harness | Bug | Fix |
82
+ |---------|-----|-----|
83
+ | `FuzzStepApply` | `{"t":"progress","cur":-1,"total":1}` produced a negative `strings.Repeat` count and panicked the run view mid-apply. | Clamp the bar width to `[0, w]`. |
84
+ | `FuzzFuzzyMatch` | The picker compared a query **byte** against a candidate **rune**, so no non-ASCII query could match — not even the identical string. | Compare both sides as runes. |
85
+ | `FuzzHighlight` | A 5 000-character fenced-block language tag stalled every render for 13s (chroma's unknown-lexer lookup is linear in the tag length). | Validate fence tags against a short-identifier pattern and memoise the lookup. |
86
+ | `FuzzRenderTranscript` | An empty transcript on a 12-row terminal with the palette open asked the splash for a negative height and panicked on a slice bound. | Drop the "recent runs" block when it does not fit; clamp the splash height. |
87
+
88
+ ### Harness files must be self-contained
89
+
90
+ `compile_native_go_fuzzer` rewrites **one** `*_test.go` file into a
91
+ regular `.go` file and builds it **without** the package's other test
92
+ files. A harness that references a symbol declared in a sibling
93
+ `_test.go` therefore passes `go test` everywhere and fails only inside
94
+ the OSS-Fuzz / ClusterFuzzLite container:
95
+
96
+ ```
97
+ ./dot_ui_parsers_test.go_fuzz.go:117:21: undefined: dangerousChars
98
+ 2026/09/07 01:14:42 failed to build packages:exit status 1
99
+ ```
100
+
101
+ So a shared constant is deliberately **duplicated** per harness file
102
+ rather than factored out. If sharing is genuinely warranted, put the
103
+ symbol in a non-test `.go` file in the package — those the builder keeps.
104
+
105
+ `tools/ci/check-fuzz-harness-self-contained.sh` enforces this by
106
+ type-checking each harness alone in a scratch module; it runs in the
107
+ `Fuzz / Harness self-containment` job on every relevant PR.
35
108
 
36
109
  Add a harness when:
37
110
 
38
111
  - a new `dot <subcommand>` accepts user input via `$1` / `--flag`,
39
112
  - a new regex appears in `scripts/dot/lib/utils.sh`,
40
- - a new "construct a URL / path / shell-eval string" code path lands.
113
+ - a new "construct a URL / path / shell-eval string" code path lands,
114
+ - a new function in `dot-ui`, `dot-ai-tui` or `dot-mcp` parses or transforms
115
+ stdin, an environment variable, a key stream or model output —
116
+ add it in-module *and* port it to `fuzz`.
41
117
 
42
118
  ## Running locally
43
119
 
44
120
  ```sh
45
- cd oss-fuzz-integration/fuzz
121
+ # Ports (also what OSS-Fuzz builds)
122
+ cd fuzz
123
+ go test -run '^$' -fuzz=FuzzValidateName -fuzztime=30s ./...
124
+ go test -run '^$' -fuzz=FuzzUIEventLine -fuzztime=30s ./...
46
125
 
47
- # 30-second smoke (find regressions quickly)
48
- go test -run TestNothing -fuzz=FuzzValidateName -fuzztime=30s ./...
49
- go test -run TestNothing -fuzz=FuzzInitURLResolver -fuzztime=30s ./...
126
+ # In-module, against the real implementation
127
+ cd defaults/dot_local/share/dot-ui
128
+ go test -run '^$' -fuzz=FuzzStepApply -fuzztime=30s ./...
50
129
 
51
- # Longer run when investigating a flake
52
- go test -run TestNothing -fuzz=FuzzValidateName -fuzztime=10m ./...
130
+ cd defaults/dot_local/share/dot-ai-tui
131
+ go test -run '^$' -fuzz=FuzzHighlight -fuzztime=30s ./...
132
+
133
+ # Replay every committed corpus in a module (no fuzzing, no flakes)
134
+ go test -run '^Fuzz' -v ./...
53
135
  ```
54
136
 
137
+ Each module's README lists every harness with a copy-pasteable
138
+ command.
139
+
55
140
  Failures land in `testdata/fuzz/Fuzz<Name>/` as auto-saved
56
141
  reproducers. Commit them — they become permanent regression
57
- guards via `go test ./...`.
142
+ guards, replayed by `go test ./...` and by the `replay` job in
143
+ `.github/workflows/fuzz.yml`.
58
144
 
59
145
  ## OSS-Fuzz integration (pending)
60
146
 
61
- The `oss-fuzz-integration/` directory contains everything OSS-Fuzz
147
+ The `fuzz/oss-fuzz/` directory contains everything OSS-Fuzz
62
148
  needs to onboard this project:
63
149
 
64
150
  ```
65
- oss-fuzz-integration/
151
+ fuzz/oss-fuzz/
66
152
  ├── project.yaml # OSS-Fuzz project metadata
67
153
  ├── Dockerfile # build environment
68
154
  ├── build.sh # compiles every harness in fuzz/
69
155
  └── fuzz/ # the harnesses themselves
70
156
  ├── go.mod
71
157
  ├── validate_name_test.go
72
- └── init_url_resolver_test.go
158
+ ├── init_url_resolver_test.go
159
+ ├── dot_ui_parsers_test.go # ports of the dot-ui parsers
160
+ └── dot_ai_tui_parsers_test.go # ports of the dot-ai-tui parsers
73
161
  ```
74
162
 
75
163
  To onboard:
76
164
 
77
165
  1. Fork `github.com/google/oss-fuzz`.
78
- 2. Copy `oss-fuzz-integration/` contents to `projects/dotfiles/` in the fork.
166
+ 2. Copy `fuzz/oss-fuzz/` contents to `projects/dotfiles/` in the fork.
79
167
  3. Verify locally per <https://google.github.io/oss-fuzz/getting-started/new-project-guide/#testing-locally>:
80
168
 
81
169
  ```sh
@@ -95,16 +183,23 @@ which runs OSS-Fuzz-style fuzzing on every PR in this repo
95
183
 
96
184
  ## CI workflow
97
185
 
98
- `.github/workflows/fuzz.yml` (planned) runs each harness for
99
- 60 seconds on every PR touching:
186
+ `.github/workflows/fuzz.yml` has two gates:
100
187
 
101
- - `scripts/dot/lib/utils.sh`
102
- - `scripts/dot/commands/init.sh`
103
- - `oss-fuzz-integration/**`
188
+ - **replay** — on every push and PR, every committed corpus (seed
189
+ entries plus the minimized crashers of previously-fixed findings) is
190
+ replayed in all three modules with `go test -run '^Fuzz'`. No
191
+ fuzzing, so no flakes: a fixed crash cannot silently come back.
192
+ - **fuzz** — a 60-second window per harness (configurable via
193
+ `workflow_dispatch`) on PRs touching an input-parsing surface:
194
+ `scripts/dot/lib/utils.sh`, `scripts/dot/commands/init.sh`,
195
+ `fuzz/**`, `.clusterfuzzlite/**` or either Go
196
+ module.
104
197
 
105
198
  This is the local equivalent of CIFuzz and catches the
106
199
  "shell-regex-change without Go-port update" drift class before
107
- PR merge.
200
+ PR merge. The per-module test workflows (`dot-ui-test.yml`,
201
+ `cockpit-test.yml`) replay their own corpus too, so the guard holds
202
+ even when only one module changes.
108
203
 
109
204
  ## See also
110
205
 
@@ -6,7 +6,7 @@ render_with_liquid: false
6
6
 
7
7
  This page tracks two distinct key lifecycles:
8
8
 
9
- 1. **Disclosure key** — the GPG key reporters use to encrypt vulnerability reports to the maintainer. Single key, public, rotated annually or on compromise. Source of truth for the active fingerprint is `.github/SECURITY.md`.
9
+ 1. **Disclosure key** — the GPG key reporters use to encrypt vulnerability reports to the maintainer. Single key, public, rotated annually or on compromise. Source of truth for the active fingerprint is `SECURITY.md`.
10
10
  2. **Secrets encryption keys** — the Age and SOPS keys that protect encrypted dotfiles in this repo. Multiple keys, per-machine, rotated annually or on personnel / device change.
11
11
 
12
12
  Both sections live here so a single audit can confirm the project's
@@ -69,13 +69,13 @@ marks reflect this repo's posture at the time of writing — the
69
69
  | Code-Review | ⚠ | Single-maintainer repo; PRs are self-merged after CI. Scorecard scores 0/30 here by design — see `Open findings` below. |
70
70
  | Signed-Commits | ✓ | Enforced by pre-push hook (`scripts/git-hooks/pre-push`) and at-push by branch protection (#853 + #857). |
71
71
  | Dependency-Update-Tool | ✓ | Dependabot configured for github-actions / npm / docker / devcontainers / uv. |
72
- | Fuzzing | ⚠ | `install.sh` fuzz harness lives under `tests/fuzz/` (closes #881), but it's shell-based and Scorecard's heuristic only recognizes OSS-Fuzz / ClusterFuzzLite / native Go fuzz / libFuzzer / Atheris. None support shell. Property tests under `tests/unit/functions/test_property_*.sh` cover the closest equivalent surface. |
72
+ | Fuzzing | ⚠ | `install.sh` fuzz harness lives under `fuzz/install/` (closes #881), but it's shell-based and Scorecard's heuristic only recognizes OSS-Fuzz / ClusterFuzzLite / native Go fuzz / libFuzzer / Atheris. None support shell. Property tests under `tests/unit/functions/test_property_*.sh` cover the closest equivalent surface. |
73
73
  | License | ✓ | MIT at repo root (`LICENSE`). |
74
74
  | Maintained | ✓ | Active commit cadence; the [README](https://github.com/sebastienrousseau/dotfiles/blob/main/README.md) lists the current `dotfiles_version`. |
75
75
  | Pinned-Dependencies | ⚠ | Closed 8 of 14 findings this cycle (every Dockerfile base + every workflow action + 2 `curl \| sh` installers + the `npm install -g npm` upgrade step). 5 residual findings stay open by design — see `Open findings`. |
76
76
  | SAST | ✓ | CodeQL (`.github/workflows/codeql.yml`) + Checkov + Grype. |
77
77
  | SBOM | ✓ | Generated per PR by `sbom-diff.yml` and per release by `security-release.yml`. |
78
- | Security-Policy | ✓ | `.github/SECURITY.md` + this page + `docs/security/THREAT_MODEL.md`. |
78
+ | Security-Policy | ✓ | `SECURITY.md` + this page + `docs/security/THREAT_MODEL.md`. |
79
79
  | Token-Permissions | ✓ | Top-level `permissions:` blocks restricted to `contents: read`. `write` scopes scoped to the jobs that need them (#886). |
80
80
  | Vulnerabilities | ✓ | Grype gate hard-fails on `high` / `critical` on `main` (#852). |
81
81
  | Webhooks | n/a | No external webhooks configured. |
@@ -117,7 +117,7 @@ false positives in Scorecard's regex.
117
117
 
118
118
  | Alert | Action |
119
119
  |---|---|
120
- | `FuzzingID` (medium) | Dismiss as **Won't fix** with comment: "Repo is bash + Go-template + Lua. ClusterFuzzLite / OSS-Fuzz / native Go fuzz / libFuzzer / Atheris (the frameworks Scorecard recognises) all target compiled languages, none support shell. The `tests/fuzz/fuzz_install.sh` harness + property tests under `tests/unit/functions/test_property_*.sh` cover the equivalent surface." |
120
+ | `FuzzingID` (medium) | Dismiss as **Won't fix** with comment: "Repo is bash + Go-template + Lua. ClusterFuzzLite / OSS-Fuzz / native Go fuzz / libFuzzer / Atheris (the frameworks Scorecard recognises) all target compiled languages, none support shell. The `fuzz/install/fuzz_install.sh` harness + property tests under `tests/unit/functions/test_property_*.sh` cover the equivalent surface." |
121
121
  | `CIIBestPracticesID` (low) | Apply at <https://www.bestpractices.dev/projects/new>. ~67 self-attested questions, free, 1-2 hours. After silver-tier approval, paste the badge into `README.md` next to the existing Scorecard badge. Most criteria already met (signed commits, CI, security policy, license). |
122
122
 
123
123
  ## Closed this cycle
@@ -187,13 +187,13 @@ verify-dot-release v0.2.502 # verify specific tag
187
187
  `security@sebastienrousseau.com` (encrypted to the WKD-published
188
188
  GPG key — fingerprint
189
189
  `55AFAD364FD9DB3819E61F0C8D688FAFA9144693`). Acknowledgement
190
- SLA: 72 hours per `.github/SECURITY.md`.
190
+ SLA: 72 hours per `SECURITY.md`.
191
191
 
192
192
  ---
193
193
 
194
194
  ## See also
195
195
 
196
- - `.github/SECURITY.md` — coordinated disclosure policy.
196
+ - `SECURITY.md` — coordinated disclosure policy.
197
197
  - `docs/security/KEY_ROTATION.md` — disclosure-key rotation procedure.
198
198
  - `docs/security/SCORECARD.md` — OpenSSF Scorecard posture.
199
199
  - `docs/operations/HARD_AUDIT_2026.md` Part 7 — the GPG key generation + WKD publication record.
package/install.sh CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # SPDX-License-Identifier: MIT
2
+ # SPDX-License-Identifier: Apache-2.0 OR MIT
3
3
  # Copyright (c) 2015-2026 Sebastien Rousseau
4
4
  # Universal Dotfiles Installer (Zero-Dependency)
5
5
  # Usage: gh repo clone sebastienrousseau/dotfiles && cd dotfiles && ./install.sh
@@ -71,7 +71,7 @@ show_help() {
71
71
  Usage: install.sh [version] [options]
72
72
 
73
73
  Arguments:
74
- version The version (tag or branch) to install (default: v0.2.519)
74
+ version The version (tag or branch) to install (default: v0.2.520)
75
75
 
76
76
  Options:
77
77
  --help Show this help message
@@ -87,7 +87,7 @@ EOF
87
87
  }
88
88
 
89
89
  main() {
90
- local version="v0.2.519"
90
+ local version="v0.2.520"
91
91
  local version_set=0
92
92
  local minimal=0
93
93
  local provision="${DOTFILES_PROVISION:-0}"
@@ -117,7 +117,7 @@ main() {
117
117
  # like `foobar` doesn't trigger a 30s+ network download attempt.
118
118
  # Caught by the install.sh fuzz harness (#881).
119
119
  if [[ ! "$arg" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+([-+][a-zA-Z0-9.-]+)?$ ]]; then
120
- error "Unrecognized positional argument '$arg' — expected a semver version (e.g. v0.2.519)."
120
+ error "Unrecognized positional argument '$arg' — expected a semver version (e.g. v0.2.520)."
121
121
  fi
122
122
  version="$arg"
123
123
  version_set=1
@@ -369,7 +369,7 @@ main() {
369
369
  # 6. Initialize & Apply
370
370
  step "Applying Configuration..."
371
371
 
372
- # ── Auto-migration for v0.2.519 reorg ─────────────────────────────────
372
+ # ── Auto-migration for v0.2.520 reorg ─────────────────────────────────
373
373
  # If the user is upgrading from a pre-0.2.503 install, run the
374
374
  # migration script BEFORE `chezmoi apply` so the reorg's source-
375
375
  # path moves don't cause chezmoi to delete deployed files.
@@ -378,7 +378,7 @@ main() {
378
378
  for migrate_src in "$SOURCE_DIR" "$LEGACY_SOURCE_DIR"; do
379
379
  migrate_script="$migrate_src/install/migrate/migrate-v0_2-to-v0_2_503.sh"
380
380
  if [[ -x "$migrate_script" ]]; then
381
- echo " Running v0.2.519 migration (idempotent; safe on fresh installs)..."
381
+ echo " Running v0.2.520 migration (idempotent; safe on fresh installs)..."
382
382
  "$migrate_script" || echo " migration exited non-zero — continuing apply"
383
383
  break
384
384
  fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sebastienrousseau/dotfiles",
3
- "version": "0.2.519",
3
+ "version": "0.2.520",
4
4
  "description": "The Trusted Shell Platform — Universal dotfiles managed by Chezmoi. Features Bash & Zsh for macOS, Linux & WSL. Rust modern tooling & enterprise-grade security.",
5
5
  "main": "install.sh",
6
6
  "bin": {
@@ -48,7 +48,7 @@
48
48
  "email": "sebastienrousseau@users.noreply.github.com",
49
49
  "url": "https://sebastienrousseau.com"
50
50
  },
51
- "license": "MIT",
51
+ "license": "Apache-2.0 OR MIT",
52
52
  "bugs": {
53
53
  "url": "https://github.com/sebastienrousseau/dotfiles/issues"
54
54
  },
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # SPDX-License-Identifier: MIT
2
+ # SPDX-License-Identifier: Apache-2.0 OR MIT
3
3
  # Copyright (c) 2015-2026 Sebastien Rousseau
4
4
  # Compat shim: the canonical script moved to tools/ci/ during the repo reorg.
5
5
  # Pinned reusable workflows on main still reference the old path;
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # SPDX-License-Identifier: MIT
2
+ # SPDX-License-Identifier: Apache-2.0 OR MIT
3
3
  # Copyright (c) 2015-2026 Sebastien Rousseau
4
4
  # Compat shim: the canonical script moved to tools/ci/ during the repo reorg.
5
5
  # Pinned reusable workflows on main still reference the old path;
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # SPDX-License-Identifier: MIT
2
+ # SPDX-License-Identifier: Apache-2.0 OR MIT
3
3
  # Copyright (c) 2015-2026 Sebastien Rousseau
4
4
  # Compat shim: the canonical script moved to tools/ci/ during the repo reorg.
5
5
  # Pinned reusable workflows on main still reference the old path;
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # SPDX-License-Identifier: MIT
2
+ # SPDX-License-Identifier: Apache-2.0 OR MIT
3
3
  # Copyright (c) 2015-2026 Sebastien Rousseau
4
4
  set -euo pipefail
5
5
 
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # SPDX-License-Identifier: MIT
2
+ # SPDX-License-Identifier: Apache-2.0 OR MIT
3
3
  # Copyright (c) 2015-2026 Sebastien Rousseau
4
4
  ## A2A v0.3 and agent card conformance validation.
5
5
 
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # SPDX-License-Identifier: MIT
2
+ # SPDX-License-Identifier: Apache-2.0 OR MIT
3
3
  # Copyright (c) 2015-2026 Sebastien Rousseau
4
4
  # Alias governance checks:
5
5
  # - duplicate alias names
@@ -54,6 +54,31 @@ if [[ -f "$SCRIPT_DIR/../../package.json" ]]; then
54
54
  fi
55
55
  repo_version="${repo_version:-0.0.0}"
56
56
 
57
+ # ripgrep is preferred but is NOT guaranteed to be installed (the CI
58
+ # runners and minimal setups often lack it, which is why
59
+ # aliases-manifest.sh already carries a grep fallback). Without one
60
+ # here, `rg` exiting 127 reads as "no match": every gated override was
61
+ # reported as ungated, and this gate failed with false errors on any
62
+ # machine without ripgrep.
63
+ _gov_grep_file() { # <ere-pattern> <file>
64
+ if command -v rg >/dev/null 2>&1; then
65
+ rg -q "$1" "$2"
66
+ else
67
+ grep -qE "$1" "$2"
68
+ fi
69
+ }
70
+
71
+ _gov_grep_tree() { # <ere-pattern> <dir>...
72
+ local pattern="$1"
73
+ shift
74
+ if command -v rg >/dev/null 2>&1; then
75
+ rg -q --glob '*.sh' --glob '*.aliases.sh' --glob '*.tmpl' "$pattern" "$@" 2>/dev/null
76
+ else
77
+ grep -rqE --include='*.sh' --include='*.aliases.sh' --include='*.tmpl' \
78
+ "$pattern" "$@" 2>/dev/null
79
+ fi
80
+ }
81
+
57
82
  # 1) Duplicate alias names
58
83
  dupes="$(awk -F'\t' '{count[$1]++} END {for (k in count) if (count[k] > 1) print k}' "$tmp_manifest" | sort)"
59
84
  if [[ -n "$dupes" ]]; then
@@ -77,7 +102,7 @@ while IFS=$'\t' read -r name _value file _line; do
77
102
  if [[ "$file" == *"/aliases/gnu/"* ]]; then
78
103
  continue
79
104
  fi
80
- if ! rg -q 'DOTFILES_(ENABLE|SAFE|ALIAS)' "$file"; then
105
+ if ! _gov_grep_file 'DOTFILES_(ENABLE|SAFE|ALIAS)' "$file"; then
81
106
  echo "ERROR: risky override '$name' in $file is not gated by a DOTFILES_* flag"
82
107
  errors=$((errors + 1))
83
108
  fi
@@ -111,7 +136,9 @@ if [[ -f "$deprecations_file" ]]; then
111
136
  alias_found=1
112
137
  fi
113
138
  function_found=0
114
- if rg -q --glob '*.sh' --glob '*.aliases.sh' --glob '*.tmpl' "^[[:space:]]*(function[[:space:]]+)?${alias_name}[[:space:]]*\\(\\)" "$SCRIPT_DIR/../../defaults/.chezmoitemplates/aliases" "$SCRIPT_DIR/../../scripts/dot"; then
139
+ if _gov_grep_tree "^[[:space:]]*(function[[:space:]]+)?${alias_name}[[:space:]]*\\(\\)" \
140
+ "$SCRIPT_DIR/../../defaults/.chezmoitemplates/aliases" \
141
+ "$SCRIPT_DIR/../../scripts/dot"; then
115
142
  function_found=1
116
143
  fi
117
144
  if [[ $alias_found -eq 1 || $function_found -eq 1 ]]; then
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # SPDX-License-Identifier: MIT
2
+ # SPDX-License-Identifier: Apache-2.0 OR MIT
3
3
  # Copyright (c) 2015-2026 Sebastien Rousseau
4
4
  set -euo pipefail
5
5
 
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # SPDX-License-Identifier: MIT
2
+ # SPDX-License-Identifier: Apache-2.0 OR MIT
3
3
  # Copyright (c) 2015-2026 Sebastien Rousseau
4
4
  # Emit alias manifest as TSV:
5
5
  # name<TAB>value<TAB>file<TAB>line
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env bash
2
+ # SPDX-License-Identifier: Apache-2.0 OR MIT
3
+ # Copyright (c) 2015-2026 Sebastien Rousseau
4
+ ## Verify workstation attestation evidence with the WebAssembly verifier.
5
+ ##
6
+ ## Runs `lib/wasm-tools` built for `wasm32-wasip1` under `wasmtime` and feeds
7
+ ## it an evidence record on stdin. The module has no filesystem, no network
8
+ ## and no environment: it reads the document, applies the policy and writes a
9
+ ## verdict. Nothing about the verdict depends on the tools installed on the
10
+ ## machine under review — which is the point, since that machine is the one
11
+ ## making the claims.
12
+ ##
13
+ ## Usage: dot attest --verify [--json|-j] [--max-age SECS] [FILE]
14
+ ## dot attest --json | bash scripts/diagnostics/attest-verify.sh
15
+ ##
16
+ ## Exit codes: 0 every check passed, 1 a check failed, 2 the evidence or the
17
+ ## toolchain was unusable.
18
+
19
+ set -euo pipefail
20
+
21
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
22
+ REPO_ROOT="${REPO_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
23
+ export REPO_ROOT
24
+
25
+ # shellcheck source=../../lib/dot/ui.sh
26
+ # shellcheck disable=SC1091
27
+ source "$SCRIPT_DIR/../../lib/dot/ui.sh"
28
+
29
+ CRATE_DIR="$REPO_ROOT/lib/wasm-tools"
30
+ WASM_TARGET="wasm32-wasip1"
31
+ DEFAULT_MODULE="$CRATE_DIR/target/$WASM_TARGET/release/dot-sys.wasm"
32
+
33
+ JSON_MODE=0
34
+ MAX_AGE=""
35
+ EVIDENCE_FILE=""
36
+ while [[ $# -gt 0 ]]; do
37
+ case "$1" in
38
+ --json | -j)
39
+ JSON_MODE=1
40
+ shift
41
+ ;;
42
+ --max-age | -a)
43
+ MAX_AGE="${2:-}"
44
+ shift 2
45
+ ;;
46
+ --verify | -V)
47
+ # Accepted so the flag can be forwarded verbatim from `dot attest`.
48
+ shift
49
+ ;;
50
+ --help | -h)
51
+ cat <<'USAGE'
52
+ Usage: dot attest --verify [--json|-j] [--max-age SECS] [FILE]
53
+
54
+ Runs the wasm32-wasip1 build of lib/wasm-tools under wasmtime and checks an
55
+ evidence record against the workstation policy. Reads FILE, or stdin, or a
56
+ fresh `dot attest --json` when given neither.
57
+
58
+ --json, -j emit the machine-readable verdict
59
+ --max-age SECS freshness window for `generated_at` (`any` to lift it)
60
+ --help, -h print this text
61
+
62
+ Exit codes: 0 every check passed, 1 a check failed, 2 unusable input or
63
+ toolchain.
64
+ USAGE
65
+ exit 0
66
+ ;;
67
+ --)
68
+ shift
69
+ break
70
+ ;;
71
+ -*)
72
+ echo "attest-verify: unknown option $1" >&2
73
+ exit 2
74
+ ;;
75
+ *)
76
+ EVIDENCE_FILE="$1"
77
+ shift
78
+ ;;
79
+ esac
80
+ done
81
+
82
+ # Resolve the WebAssembly runtime. `wasmtime` is pinned in mise.toml, shipped
83
+ # by flake.nix and the Brewfile, and checked by `dot doctor`.
84
+ WASMTIME_BIN="${WASMTIME:-wasmtime}"
85
+ if ! command -v "$WASMTIME_BIN" >/dev/null 2>&1; then
86
+ echo "attest-verify: no WebAssembly runtime found (looked for '$WASMTIME_BIN')." >&2
87
+ echo "attest-verify: install it with 'mise install wasmtime' or set WASMTIME." >&2
88
+ exit 2
89
+ fi
90
+
91
+ # Resolve the module, building it on demand when a Rust toolchain is present.
92
+ MODULE="${DOT_SYS_WASM:-$DEFAULT_MODULE}"
93
+ if [[ ! -f "$MODULE" ]]; then
94
+ if [[ -n "${DOT_SYS_WASM:-}" ]]; then
95
+ echo "attest-verify: DOT_SYS_WASM points at a missing file: $MODULE" >&2
96
+ exit 2
97
+ fi
98
+ if ! command -v cargo >/dev/null 2>&1; then
99
+ echo "attest-verify: no verifier at $MODULE and no cargo to build one." >&2
100
+ echo "attest-verify: build it with:" >&2
101
+ echo " cargo build --release --target $WASM_TARGET --manifest-path lib/wasm-tools/Cargo.toml" >&2
102
+ exit 2
103
+ fi
104
+ echo "attest-verify: building the verifier for $WASM_TARGET ..." >&2
105
+ cargo build --quiet --release --target "$WASM_TARGET" \
106
+ --manifest-path "$CRATE_DIR/Cargo.toml" --bin dot-sys >&2
107
+ fi
108
+
109
+ # Collect the evidence: an explicit file, a pipe, or a fresh attestation.
110
+ evidence=""
111
+ if [[ -n "$EVIDENCE_FILE" ]]; then
112
+ if [[ ! -f "$EVIDENCE_FILE" ]]; then
113
+ echo "attest-verify: no such evidence file: $EVIDENCE_FILE" >&2
114
+ exit 2
115
+ fi
116
+ evidence="$(cat "$EVIDENCE_FILE")"
117
+ elif [[ ! -t 0 ]]; then
118
+ evidence="$(cat)"
119
+ else
120
+ evidence="$(bash "$SCRIPT_DIR/workstation-attestation.sh" --json)"
121
+ fi
122
+
123
+ module_args=(verify)
124
+ [[ "$JSON_MODE" -eq 1 ]] && module_args+=(--json)
125
+ [[ -n "$MAX_AGE" ]] && module_args+=(--max-age "$MAX_AGE")
126
+
127
+ set +e
128
+ verdict="$(printf '%s' "$evidence" | "$WASMTIME_BIN" run "$MODULE" "${module_args[@]}")"
129
+ status=$?
130
+ set -e
131
+
132
+ if [[ "$JSON_MODE" -eq 1 ]]; then
133
+ printf '%s\n' "$verdict"
134
+ exit "$status"
135
+ fi
136
+
137
+ ui_init
138
+ ui_dot_banner "Diagnostics"
139
+ ui_header "Attestation Verification"
140
+ printf '%s\n' "$verdict"
141
+ if [[ "$status" -eq 0 ]]; then
142
+ ui_ok "Verdict" "every check passed"
143
+ else
144
+ ui_err "Verdict" "see the failed checks above"
145
+ fi
146
+ ui_info "Verifier" "$MODULE (wasm32-wasip1, $("$WASMTIME_BIN" --version | head -n 1))"
147
+ exit "$status"
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # SPDX-License-Identifier: MIT
2
+ # SPDX-License-Identifier: Apache-2.0 OR MIT
3
3
  # Copyright (c) 2015-2026 Sebastien Rousseau
4
4
  ## Shell Performance Benchmark.
5
5
  ##