@sebastienrousseau/dotfiles 0.2.508 → 0.2.510
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 +30 -0
- package/README.md +5 -5
- package/docs/COPYRIGHT +1 -1
- package/docs/GOVERNANCE.md +2 -2
- package/docs/adr/ADR-011-nushell-tier3-keep.md +2 -2
- package/docs/guides/INSTALL.md +3 -3
- package/docs/index.md +116 -27
- package/docs/interop/A2A.md +2 -2
- package/docs/interop/POWERSHELL.md +4 -4
- package/docs/manual/00-introduction.md +3 -3
- package/docs/manual/01-concepts/02-trust-model.md +3 -3
- package/docs/manual/01-concepts/04-fleet.md +1 -1
- package/docs/manual/02-tutorials/01-first-install.md +1 -1
- package/docs/manual/02-tutorials/05-deploy-fleet.md +2 -2
- package/docs/manual/03-reference/02-config-files.md +1 -1
- package/docs/manual/03-reference/04-templates.md +1 -1
- package/docs/manual/04-cookbook/01-recipes.md +1 -1
- package/docs/manual/04-cookbook/02-troubleshooting.md +1 -1
- package/docs/manual/05-appendices/B-security-checklist.md +1 -1
- package/docs/manual/command-index.md +76 -1
- package/docs/manual/index.md +1 -1
- package/docs/operations/ARCHITECTURE_ROADMAP.md +145 -0
- package/docs/operations/CI_CADENCE.md +2 -2
- package/docs/operations/COMPLETIONS.md +2 -2
- package/docs/operations/COVERAGE.md +4 -4
- package/docs/operations/DRIFT.md +1 -1
- package/docs/operations/MAINTENANCE.md +6 -6
- package/docs/operations/PERFORMANCE.md +6 -6
- package/docs/operations/RELIABILITY.md +1 -1
- package/docs/operations/ROADMAP_V0_2_503.md +1 -1
- package/docs/operations/TRACEABILITY.md +2 -0
- package/docs/operations/TRUSTED_AGENT_WORKSTATION.md +6 -6
- package/docs/operations/VERSION_SYNC.md +3 -3
- package/docs/reference/UTILS.md +82 -0
- package/docs/security/AUDIT_BYPASS.md +3 -3
- package/docs/security/AUTOMATION_SECRETS.md +1 -1
- package/docs/security/CI_PINNING.md +10 -10
- package/docs/security/COMMIT_SIGNING.md +10 -10
- package/docs/security/DEPS_DEV_EXCEPTIONS.md +4 -4
- package/docs/security/DISCLOSURE.md +3 -3
- package/docs/security/INCIDENT_RESPONSE.md +1 -1
- package/docs/security/INSTALL_VERIFICATION.md +2 -2
- package/docs/security/MCP_POLICY.md +4 -4
- package/docs/security/SCORECARD.md +7 -7
- package/docs/security/SECURITY_CHECKLIST.md +1 -1
- package/docs/security/SHELL_EXEMPTIONS.md +2 -2
- package/docs/security/SOUP_REGISTER.md +4 -4
- package/docs/stylesheets/extra.css +444 -0
- package/docs/themes/hero-shot.svg +1 -1
- package/install.sh +17 -6
- package/package.json +1 -1
- 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/dot/commands/agent.sh +7 -6
- package/scripts/dot/commands/ai.sh +8 -5
- package/scripts/dot/commands/appearance.sh +14 -1
- package/scripts/dot/commands/completion.sh +134 -0
- package/scripts/dot/commands/core.sh +8 -0
- package/scripts/dot/commands/diagnostics.sh +16 -0
- package/scripts/dot/commands/fleet.sh +7 -3
- package/scripts/dot/commands/lint.sh +55 -30
- package/scripts/dot/commands/secrets.sh +61 -7
- package/scripts/dot/commands/security.sh +8 -0
- package/scripts/dot/powershell/Dot.psm1 +1 -1
- package/scripts/git-hooks/pre-commit-audit.sh +1 -1
- package/scripts/ops/heal-tools.sh +28 -0
- package/scripts/ops/teleport.sh +2 -2
- package/scripts/qa/examples-coverage.sh +94 -0
- package/scripts/version-sync.sh +29 -2
- package/docs/_config.yml +0 -59
package/docs/manual/index.md
CHANGED
|
@@ -8,7 +8,7 @@ render_with_liquid: false
|
|
|
8
8
|
|
|
9
9
|
A trusted agent workstation baseline for macOS, Linux, and WSL. Chezmoi handles templating and platform differences; the `dot` CLI coordinates lifecycle operations on top.
|
|
10
10
|
|
|
11
|
-
This manual is generated from the Markdown sources in [`docs/manual/`](https://github.com/sebastienrousseau/dotfiles/tree/
|
|
11
|
+
This manual is generated from the Markdown sources in [`docs/manual/`](https://github.com/sebastienrousseau/dotfiles/tree/main/docs/manual) and published in nine formats per release. The HTML edition you are reading is the canonical online version.
|
|
12
12
|
|
|
13
13
|
## Read it your way
|
|
14
14
|
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Architecture & Roadmap — cross-shell consistency, performance, decoupling"
|
|
3
|
+
date: 2026-07-01
|
|
4
|
+
status: living document
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Architecture & Roadmap
|
|
8
|
+
|
|
9
|
+
This document captures a deep-dive across four fronts — cross-shell
|
|
10
|
+
consistency, real startup performance, the 2026 competitive/research
|
|
11
|
+
landscape, and a plan to decouple optional subsystems (`dot ai`, MCP, LSP)
|
|
12
|
+
into companion repos around a stable core. It is the source of truth for
|
|
13
|
+
the multi-phase program tracked below.
|
|
14
|
+
|
|
15
|
+
> Honesty policy: every performance number here is **measured** with
|
|
16
|
+
> `hyperfine` (warmed up), reproducible with the harness in
|
|
17
|
+
> `tests/performance/bench.sh` (interactive sessions, all installed shells)
|
|
18
|
+
> and `dot benchmark`. Estimates are labelled as such. The
|
|
19
|
+
> built-in `dot doctor` perf readout historically **understated** real
|
|
20
|
+
> startup because it timed a narrower slice — Phase 0 reconciles that.
|
|
21
|
+
|
|
22
|
+
## 1. Measured performance baseline (2026-07-01, Apple Silicon)
|
|
23
|
+
|
|
24
|
+
Method: `hyperfine -N --warmup 5` on the deployed config; `exit`-on-launch.
|
|
25
|
+
|
|
26
|
+
| Shell | Startup (mean) | rc cost over ~7ms spawn | vs <30ms target |
|
|
27
|
+
|---------|----------------|-------------------------|-----------------|
|
|
28
|
+
| nushell | 24.8 ms | — | meets |
|
|
29
|
+
| bash | 51.1 ms | +43.6 ms | 1.7× over |
|
|
30
|
+
| zsh | 66.3 ms | +59.6 ms | 2.2× over |
|
|
31
|
+
| fish | 128.8 ms | bash-bridge tax | 4.3× over |
|
|
32
|
+
|
|
33
|
+
Baselines (pure process spawn, no rc): `zsh -fc exit` 6.7 ms,
|
|
34
|
+
`bash --norc` 7.5 ms.
|
|
35
|
+
|
|
36
|
+
Cost attribution (uncached tool-init subprocess cost, what `_cached_eval`
|
|
37
|
+
caches away): `mise activate` 17.7 ms, `atuin init` 7.1 ms,
|
|
38
|
+
`starship init` 4.0 ms, `zoxide init` 2.4 ms. `_cached_eval` **is**
|
|
39
|
+
working (cache files fresh; `zcompdump` is `zcompile`d), which is why zsh
|
|
40
|
+
is 66 ms and not ~97 ms.
|
|
41
|
+
|
|
42
|
+
**<30ms verdict (honest):** not reachable for the *full eager stack*
|
|
43
|
+
(mise + starship + atuin + zoxide + fzf + zinit + ~97 alias files + ~53
|
|
44
|
+
functions + compinit) on zsh/bash without tradeoffs. It **is** reachable
|
|
45
|
+
as a tunable "fast profile" + first-prompt deferral. nushell already
|
|
46
|
+
meets it; fish (bash-bridge) is the worst and the biggest opportunity.
|
|
47
|
+
|
|
48
|
+
## 2. Cross-shell consistency
|
|
49
|
+
|
|
50
|
+
- bash/zsh are native + single-source; **fish and nushell are bash
|
|
51
|
+
*bridges*** — they filter aliases and wrap functions via `bash -c`
|
|
52
|
+
subshells, adding a runtime bash dependency and silent parity loss.
|
|
53
|
+
- Parity gap: bash/zsh ~53 functions; fish 27 native; nushell 0 native;
|
|
54
|
+
~26 functions have no native impl; behaviour drifts (e.g. `goto` loses
|
|
55
|
+
directory grouping in fish/nu).
|
|
56
|
+
- Duplication: eza-detection logic in bash + 7 fish files + nu wrappers;
|
|
57
|
+
`_cached_eval` reimplemented four times.
|
|
58
|
+
- Direction: a **manifest-driven single source of truth** (one
|
|
59
|
+
alias/function spec → per-shell generators). This also removes the
|
|
60
|
+
class of parse-time collision that produced the zsh alias-shim bug.
|
|
61
|
+
|
|
62
|
+
## 3. Decoupling architecture
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
dotfiles (CORE)
|
|
66
|
+
dot CLI · lib/dot/ui.sh · utils.sh · chezmoi base · plugin API
|
|
67
|
+
| | | |
|
|
68
|
+
dotfiles-ai dotfiles-mcp dotfiles-lsp (future)
|
|
69
|
+
dot ai, registry, dot/alias/
|
|
70
|
+
cockpit, policy, chezmoi-template
|
|
71
|
+
gateway mcp-doctor completions
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Readiness (from the coupling audit):
|
|
75
|
+
|
|
76
|
+
| Subsystem | Coupling | Effort | Notes |
|
|
77
|
+
|-----------|----------|--------|-------|
|
|
78
|
+
| MCP | low (declarative JSON + one `cmd_mcp`) | low | isolated by design |
|
|
79
|
+
| LSP | none (one nvim plugin file) | trivial | already a lazy.nvim plugin |
|
|
80
|
+
| `dot ai` | high (ui.sh, utils.sh, dispatcher, chezmoi hooks) | high | needs the two contracts below |
|
|
81
|
+
|
|
82
|
+
Two foundational contracts must exist before AI can move cleanly:
|
|
83
|
+
|
|
84
|
+
1. **Extract `lib/dot/ui.sh` into a versioned shared lib** — AI *and* MCP
|
|
85
|
+
depend on it; without this, decoupling means duplication.
|
|
86
|
+
2. **A `dot` plugin/extension API** — manifest-registered subcommands so
|
|
87
|
+
companion repos add `dot ai` / `dot mcp` without forking the
|
|
88
|
+
dispatcher.
|
|
89
|
+
|
|
90
|
+
## 4. 2026 landscape — gaps worth adopting (highest value first)
|
|
91
|
+
|
|
92
|
+
- **`dotfiles-mcp` with a secrets-redaction + allowlist policy layer** — a
|
|
93
|
+
genuine gap no existing dotfiles-MCP fills; reuses the gitleaks / Atuin
|
|
94
|
+
`history_filter` posture. Expose introspection via MCP **Resources**,
|
|
95
|
+
actions via **Tools**.
|
|
96
|
+
- **`dotfiles-lsp`** = `dot` subcommand completions + alias awareness +
|
|
97
|
+
**chezmoi-template-data-aware** completions → a novel *combination*
|
|
98
|
+
(weekend-scale MVP using just-lsp / tcl-lsp patterns).
|
|
99
|
+
- Password-manager templating (1Password/Bitwarden), SOPS for shared
|
|
100
|
+
secrets, **Bats** tests (reviewer lingua franca), devcontainer/Codespaces
|
|
101
|
+
fast install path.
|
|
102
|
+
|
|
103
|
+
Context: chezmoi has won the dotfiles category; mise is baseline; Starship
|
|
104
|
+
has overtaken Powerlevel10k (maintenance-only); MCP spec 2025-11-25 is
|
|
105
|
+
under the Linux Foundation and safe to build on.
|
|
106
|
+
|
|
107
|
+
## 5. Staged roadmap
|
|
108
|
+
|
|
109
|
+
Each phase ships as its own reviewed PR with before/after benchmarks.
|
|
110
|
+
|
|
111
|
+
| Phase | Work | Risk | Target payoff |
|
|
112
|
+
|-------|------|------|---------------|
|
|
113
|
+
| **0** | Honest benchmark harness in-repo; make `dot doctor` report real numbers | low | truth in metrics |
|
|
114
|
+
| **1** | Perf quick-wins audit (deferral, compinit, zcompile, mise ordering) | low | verify + record baseline |
|
|
115
|
+
| **2** | Extract `lib/dot/ui.sh` → versioned shared lib | med | unblocks decoupling |
|
|
116
|
+
| **3** | `dot` plugin API + carve out `dotfiles-mcp` (lowest-risk repo) | med | proves the model |
|
|
117
|
+
| **4** | Cross-shell manifest (single source → per-shell generators); de-bash-bridge fish | high | consistency + fish speed |
|
|
118
|
+
| **5** | `dotfiles-ai` as a plugin repo | high | the decoupling goal |
|
|
119
|
+
| **6** | `dotfiles-lsp` MVP | low | differentiation |
|
|
120
|
+
| **7** | Docs + `examples/` + published honest benchmarks | med | completeness |
|
|
121
|
+
|
|
122
|
+
### Status
|
|
123
|
+
|
|
124
|
+
- **Phase 0 — done** (`feat/v0.2.509`): `tests/performance/bench.sh` now times
|
|
125
|
+
every shell *interactively* (fish was measured non-interactively, faking
|
|
126
|
+
~12ms vs the real ~118ms) and includes nushell; `dot doctor` reports the
|
|
127
|
+
real medians.
|
|
128
|
+
- **Phase 1 — done (audit)** (`feat/v0.2.509`): the documented quick-wins are
|
|
129
|
+
**already implemented** in the deployed config, verified:
|
|
130
|
+
- `compinit` deferred to first prompt, `-C` + daily-audit cache
|
|
131
|
+
(`~/.config/zsh/rc.d/30-options.zsh`).
|
|
132
|
+
- Eagerly-sourced hub files are `zcompile`d (`.zwc` present).
|
|
133
|
+
- Plugins turbo-deferred (`zinit ice wait lucid`), fzf backgrounded, and
|
|
134
|
+
mise/atuin/starship/zoxide inits deferred to post-prompt hydration and
|
|
135
|
+
cached via `_cached_eval`.
|
|
136
|
+
- `mise activate` ordering is a non-issue here: zsh uses `add-zsh-hook`
|
|
137
|
+
(appends, no overwrite) and bash manages `PROMPT_COMMAND` explicitly.
|
|
138
|
+
- Net: `zsh -ic exit` (which runs before the prompt, so it excludes the
|
|
139
|
+
deferred inits) is ~66ms of *eager* rc — dominated by sourcing the large
|
|
140
|
+
aggregated alias/function hubs. No safe further quick-win remains.
|
|
141
|
+
- **Consequence:** sub-30ms is not reachable by tuning; it needs Phase 4
|
|
142
|
+
(manifest → cut the eager alias/function volume) or a lean profile.
|
|
143
|
+
fish (~118ms) is the biggest single opportunity (bash-bridge), also
|
|
144
|
+
Phase 4.
|
|
145
|
+
- Phases 2–7 — planned; sequencing subject to review.
|
|
@@ -102,6 +102,6 @@ When adding a new workflow:
|
|
|
102
102
|
|
|
103
103
|
## References
|
|
104
104
|
|
|
105
|
-
- [`nightly.yml`](
|
|
106
|
-
- [`security-enhanced.yml`](
|
|
105
|
+
- [`nightly.yml`](https://github.com/sebastienrousseau/dotfiles/blob/main/.github/workflows/nightly.yml) — the workflow whose cadence flip triggered this page.
|
|
106
|
+
- [`security-enhanced.yml`](https://github.com/sebastienrousseau/dotfiles/blob/main/.github/workflows/security-enhanced.yml) — earlier daily→weekly reduction.
|
|
107
107
|
- Issue [#861](https://github.com/sebastienrousseau/dotfiles/issues/861).
|
|
@@ -116,8 +116,8 @@ their lifecycle.
|
|
|
116
116
|
|
|
117
117
|
## References
|
|
118
118
|
|
|
119
|
-
- [`dot_config/zsh/rc.d/30-options.zsh.tmpl`](
|
|
120
|
-
- [`run_onchange_after_zcompile-completions.sh.tmpl`](
|
|
119
|
+
- [`dot_config/zsh/rc.d/30-options.zsh.tmpl`](https://github.com/sebastienrousseau/dotfiles/blob/main/defaults/dot_config/zsh/rc.d/30-options.zsh.tmpl) — the deferred-compinit logic.
|
|
120
|
+
- [`run_onchange_after_zcompile-completions.sh.tmpl`](https://github.com/sebastienrousseau/dotfiles/blob/main/defaults/run_onchange_after_zcompile-completions.sh.tmpl) — the apply-time precompile hook.
|
|
121
121
|
- [`zsh` completion docs](https://zsh.sourceforge.io/Doc/Release/Completion-System.html).
|
|
122
122
|
- ADR-002 (Shell Performance Optimization).
|
|
123
123
|
- Issue [#864](https://github.com/sebastienrousseau/dotfiles/issues/864).
|
|
@@ -43,7 +43,7 @@ matches and emits standard `lcov.info` that Codecov ingests natively.
|
|
|
43
43
|
|
|
44
44
|
| Surface | What runs |
|
|
45
45
|
|---|---|
|
|
46
|
-
| **PR + push to
|
|
46
|
+
| **PR + push to main** | `.github/workflows/coverage.yml` → `Coverage / kcov` job → uploads lcov.info to Codecov and fails the build below `MIN_COVERAGE_PCT` (currently `0`, ratcheted up each slice). |
|
|
47
47
|
| **Local dev** | `bash tools/ci/run-coverage.sh` — works on Linux + macOS (xtrace is a bash primitive, no platform tools needed). |
|
|
48
48
|
| **macOS dev** | Supported. xtrace-based instrumentation runs on macOS bash 3.2+ and Homebrew bash 5.x. |
|
|
49
49
|
|
|
@@ -117,7 +117,7 @@ heatmap.
|
|
|
117
117
|
When the `Coverage / kcov` PR check fails:
|
|
118
118
|
|
|
119
119
|
1. Pull the workflow's `coverage-lcov` artifact (30-day retention).
|
|
120
|
-
2. Compare against the previous
|
|
120
|
+
2. Compare against the previous main run by downloading its
|
|
121
121
|
`coverage-lcov` artifact too.
|
|
122
122
|
3. Identify the file(s) where the line-coverage dropped.
|
|
123
123
|
4. Either:
|
|
@@ -176,7 +176,7 @@ Adjust via the env vars at the top of `run-coverage.sh`.
|
|
|
176
176
|
## References
|
|
177
177
|
|
|
178
178
|
- [Bash xtrace + PS4 + BASH_ENV docs](https://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html).
|
|
179
|
-
- [`tools/ci/run-coverage.sh`](
|
|
180
|
-
- [`.github/workflows/coverage.yml`](
|
|
179
|
+
- [`tools/ci/run-coverage.sh`](https://github.com/sebastienrousseau/dotfiles/blob/main/tools/ci/run-coverage.sh).
|
|
180
|
+
- [`.github/workflows/coverage.yml`](https://github.com/sebastienrousseau/dotfiles/blob/main/.github/workflows/coverage.yml).
|
|
181
181
|
- Issue [#856](https://github.com/sebastienrousseau/dotfiles/issues/856) (closed) /
|
|
182
182
|
[#883](https://github.com/sebastienrousseau/dotfiles/issues/883) (coverage roadmap).
|
package/docs/operations/DRIFT.md
CHANGED
|
@@ -47,7 +47,7 @@ Exit code: `0` if every class is clean; `1` if any drift is found;
|
|
|
47
47
|
## How the nightly check works
|
|
48
48
|
|
|
49
49
|
`.github/workflows/drift-detection.yml` runs `dot drift --json` against
|
|
50
|
-
a fresh checkout of `
|
|
50
|
+
a fresh checkout of `main` every day at 04:00 UTC. If `total != 0`
|
|
51
51
|
it opens (or updates) a tracking issue labelled
|
|
52
52
|
`type:chore + priority:medium` with the JSON summary, full
|
|
53
53
|
`chezmoi diff`, and `chezmoi status` attached as a workflow artifact.
|
|
@@ -17,11 +17,11 @@ This runbook captures recovery and release maintenance operations for this repos
|
|
|
17
17
|
|
|
18
18
|
**Procedure:**
|
|
19
19
|
|
|
20
|
-
1. Create a backup ref for current `
|
|
20
|
+
1. Create a backup ref for current `main`.
|
|
21
21
|
2. Build a rewritten signed baseline commit from the current tree.
|
|
22
22
|
3. Push the rewritten branch to remote.
|
|
23
|
-
4. Temporarily allow force-push on `
|
|
24
|
-
5. Force-update `
|
|
23
|
+
4. Temporarily allow force-push on `main` protections/rulesets.
|
|
24
|
+
5. Force-update `main` to the rewritten signed baseline.
|
|
25
25
|
6. Disable force-push again immediately.
|
|
26
26
|
7. Re-run CI and verify required checks are green.
|
|
27
27
|
8. Repoint the release tag/target as needed.
|
|
@@ -30,7 +30,7 @@ This runbook captures recovery and release maintenance operations for this repos
|
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
32
|
git verify-commit HEAD
|
|
33
|
-
gh run list --workflow ci.yml --branch
|
|
33
|
+
gh run list --workflow ci.yml --branch main --limit 1
|
|
34
34
|
gh release view v0.2.501 --json tagName,targetCommitish,url
|
|
35
35
|
```
|
|
36
36
|
|
|
@@ -38,10 +38,10 @@ gh release view v0.2.501 --json tagName,targetCommitish,url
|
|
|
38
38
|
|
|
39
39
|
For every release update:
|
|
40
40
|
|
|
41
|
-
1. `
|
|
41
|
+
1. `main` branch is clean and synced.
|
|
42
42
|
2. CI is green on the release commit.
|
|
43
43
|
3. Annotated release tag points to the intended commit.
|
|
44
|
-
4. GitHub release target is correct (`
|
|
44
|
+
4. GitHub release target is correct (`main` or explicit commit).
|
|
45
45
|
5. Branch protections/rulesets are restored to strict state.
|
|
46
46
|
6. Local apply has completed:
|
|
47
47
|
|
|
@@ -20,7 +20,7 @@ lifecycle, and the regression-alert pipeline. Managed under
|
|
|
20
20
|
|
|
21
21
|
`dot perf` measures every installed shell and flags any whose mean
|
|
22
22
|
exceeds its target. The numbers come from
|
|
23
|
-
[`scripts/diagnostics/perf.sh`](
|
|
23
|
+
[`scripts/diagnostics/perf.sh`](https://github.com/sebastienrousseau/dotfiles/blob/main/scripts/diagnostics/perf.sh) —
|
|
24
24
|
warm-up + 3 runs by default.
|
|
25
25
|
|
|
26
26
|
## The baseline
|
|
@@ -100,7 +100,7 @@ spiking from 5ms steady-state to 200ms once).
|
|
|
100
100
|
|
|
101
101
|
## CI workflow
|
|
102
102
|
|
|
103
|
-
[`.github/workflows/perf-baseline.yml`](
|
|
103
|
+
[`.github/workflows/perf-baseline.yml`](https://github.com/sebastienrousseau/dotfiles/blob/main/.github/workflows/perf-baseline.yml)
|
|
104
104
|
runs weekly on Sunday at 03:00 UTC on `ubuntu-latest`. It:
|
|
105
105
|
|
|
106
106
|
1. Restores the previous week's baseline from a workflow artifact.
|
|
@@ -116,7 +116,7 @@ each developer's box and aren't synced.
|
|
|
116
116
|
## Adjusting the budget
|
|
117
117
|
|
|
118
118
|
Per-shell targets live in
|
|
119
|
-
[`scripts/diagnostics/perf.sh`](
|
|
119
|
+
[`scripts/diagnostics/perf.sh`](https://github.com/sebastienrousseau/dotfiles/blob/main/scripts/diagnostics/perf.sh)
|
|
120
120
|
under `shell_target_for()`. Bumping a target should always come with:
|
|
121
121
|
|
|
122
122
|
- A commit-message rationale explaining why slower is acceptable
|
|
@@ -126,8 +126,8 @@ under `shell_target_for()`. Bumping a target should always come with:
|
|
|
126
126
|
|
|
127
127
|
## References
|
|
128
128
|
|
|
129
|
-
- [`scripts/diagnostics/perf.sh`](
|
|
130
|
-
- [`tests/unit/diagnostics/test_perf_percentiles.sh`](
|
|
131
|
-
- [`.github/workflows/perf-baseline.yml`](
|
|
129
|
+
- [`scripts/diagnostics/perf.sh`](https://github.com/sebastienrousseau/dotfiles/blob/main/scripts/diagnostics/perf.sh)
|
|
130
|
+
- [`tests/unit/diagnostics/test_perf_percentiles.sh`](https://github.com/sebastienrousseau/dotfiles/blob/main/tests/unit/diagnostics/test_perf_percentiles.sh) — percentile math contract
|
|
131
|
+
- [`.github/workflows/perf-baseline.yml`](https://github.com/sebastienrousseau/dotfiles/blob/main/.github/workflows/perf-baseline.yml)
|
|
132
132
|
- ADR-002 (Shell Performance Optimization)
|
|
133
133
|
- Issue [#863](https://github.com/sebastienrousseau/dotfiles/issues/863)
|
|
@@ -78,7 +78,7 @@ Target the [public Scorecard report](https://scorecard.dev/viewer/?uri=github.co
|
|
|
78
78
|
| Check | Today (baseline) | Path to 10 |
|
|
79
79
|
|---|---|---|
|
|
80
80
|
| **Binary-Artifacts** | 10 (no binaries committed) | Maintain — pre-commit guard rejecting any committed binary. |
|
|
81
|
-
| **Branch-Protection** | needs token | Already configured on `
|
|
81
|
+
| **Branch-Protection** | needs token | Already configured on `main` (required reviews, signed commits, status-check gating, linear history). Verify in `gh api repos/.../branches/main/protection` and document in `docs/security/`. |
|
|
82
82
|
| **CI-Tests** | 10 (CI passes on every PR) | Maintain — current 75-check matrix is comprehensive. |
|
|
83
83
|
| **CII-Best-Practices** / OpenSSF Best Practices badge | not present | Apply for the badge at [bestpractices.coreinfrastructure.org](https://www.bestpractices.dev/) and embed the badge in README. |
|
|
84
84
|
| **Code-Review** | needs verification | Already enforced via branch protection; document in CONTRIBUTING.md. |
|
|
@@ -39,3 +39,5 @@ It is enforced by `bash ./scripts/qa/traceability-coverage.sh`.
|
|
|
39
39
|
| BT-27 | Workstation environment manifest emitter (`dot env emit`) | `scripts/dot/commands/env-emit.sh` | `tests/unit/dot-cli/test_cmd_env_emit.sh` | `docs/operations/MANIFEST.md`, `docs/schema/dot-env-v1.json` |
|
|
40
40
|
| BT-28 | Cross-file version-string consistency contract | `scripts/qa/check-version-consistency.sh` | `tests/unit/qa/test_check_version_consistency.sh` | `docs/operations/RELIABILITY.md` |
|
|
41
41
|
| BT-29 | OpenSSF Scorecard nightly snapshot artefact | `scripts/qa/scorecard-snapshot.sh` | `tests/unit/qa/test_scorecard_snapshot.sh` | `docs/security/SCORECARD.md` |
|
|
42
|
+
| BT-30 | Shell completion generator (`dot completion <shell>`) | `scripts/dot/commands/completion.sh` | `tests/unit/dot-cli/test_dot_completion.sh` | `docs/reference/UTILS.md` |
|
|
43
|
+
| BT-31 | Examples coverage contract (feature/command → example) | `scripts/qa/examples-coverage.sh` | `tests/unit/misc/test_qa_examples_coverage.sh` | `docs/reference/UTILS.md` |
|
|
@@ -20,12 +20,12 @@ It defines a signed, local-first workstation baseline for agentic development on
|
|
|
20
20
|
|
|
21
21
|
The source of truth lives in tracked JSON artifacts:
|
|
22
22
|
|
|
23
|
-
- [policy-bundles.json](
|
|
24
|
-
- [agent-profiles.json](
|
|
25
|
-
- [mcp-policy.json](
|
|
26
|
-
- [mcp-registry.json](
|
|
27
|
-
- [model-registry.json](
|
|
28
|
-
- [prompt-registry.json](
|
|
23
|
+
- [policy-bundles.json](https://github.com/sebastienrousseau/dotfiles/blob/main/defaults/dot_config/dotfiles/policy-bundles.json)
|
|
24
|
+
- [agent-profiles.json](https://github.com/sebastienrousseau/dotfiles/blob/main/defaults/dot_config/dotfiles/agent-profiles.json)
|
|
25
|
+
- [mcp-policy.json](https://github.com/sebastienrousseau/dotfiles/blob/main/defaults/dot_config/dotfiles/mcp-policy.json)
|
|
26
|
+
- [mcp-registry.json](https://github.com/sebastienrousseau/dotfiles/blob/main/defaults/dot_config/dotfiles/mcp-registry.json)
|
|
27
|
+
- [model-registry.json](https://github.com/sebastienrousseau/dotfiles/blob/main/defaults/dot_config/dotfiles/model-registry.json)
|
|
28
|
+
- [prompt-registry.json](https://github.com/sebastienrousseau/dotfiles/blob/main/defaults/dot_config/dotfiles/prompt-registry.json)
|
|
29
29
|
|
|
30
30
|
## Enterprise path
|
|
31
31
|
|
|
@@ -35,7 +35,7 @@ This system provides automated version synchronization through:
|
|
|
35
35
|
|
|
36
36
|
**Triggers**:
|
|
37
37
|
|
|
38
|
-
- Push to `
|
|
38
|
+
- Push to `main` branch when `package.json` changes
|
|
39
39
|
- Pull requests affecting `package.json`
|
|
40
40
|
- Manual dispatch with optional target version
|
|
41
41
|
|
|
@@ -146,8 +146,8 @@ Version changes in `package.json` automatically trigger synchronization:
|
|
|
146
146
|
# Developer updates package.json version
|
|
147
147
|
npm version patch
|
|
148
148
|
|
|
149
|
-
# Push to
|
|
150
|
-
git push origin
|
|
149
|
+
# Push to main
|
|
150
|
+
git push origin main
|
|
151
151
|
|
|
152
152
|
# GitHub Actions automatically:
|
|
153
153
|
# 1. Detects version change
|
package/docs/reference/UTILS.md
CHANGED
|
@@ -22,6 +22,7 @@ The `dot` command is the main interface for managing dotfiles. Run `dot version`
|
|
|
22
22
|
| `dot diff` | Show local changes (excludes scripts) |
|
|
23
23
|
| `dot status` | Show configuration drift |
|
|
24
24
|
| `dot remove <path>` | Safely remove a managed file |
|
|
25
|
+
| `dot uninstall` | Remove the managed dotfiles environment (prompts unless `--force`) |
|
|
25
26
|
| `dot cd` | Print source directory path |
|
|
26
27
|
| `dot edit` | Open source in your editor |
|
|
27
28
|
| `dot clean-cache` | Clear generated shell initialization caches |
|
|
@@ -39,6 +40,7 @@ The `dot` command is the main interface for managing dotfiles. Run `dot version`
|
|
|
39
40
|
| Command | Description |
|
|
40
41
|
|---------|-------------|
|
|
41
42
|
| `dot doctor` | Run system health checks (`--score/-s`,`--heal/-H`) |
|
|
43
|
+
| `dot secret-audit` | Audit secret hygiene and leakage surface |
|
|
42
44
|
| `dot health` | Run the health dashboard (`--verbose/-v`,`--json/-j`,`--fix/-f`,`--force/-F`) |
|
|
43
45
|
| `dot heal` | Auto-repair missing tools, chezmoi drift, broken symlinks, and critical files (`--dry-run/-n`,`--force/-f`) |
|
|
44
46
|
| `dot smoke-test` | Verify toolchains (Rust, Go, AI CLIs) |
|
|
@@ -69,6 +71,7 @@ The `dot` command is the main interface for managing dotfiles. Run `dot version`
|
|
|
69
71
|
| Command | Description |
|
|
70
72
|
|---------|-------------|
|
|
71
73
|
| `dot env` | Show managed runtime and tool versions |
|
|
74
|
+
| `dot env emit` | Emit a portable workstation environment manifest (SBOM) |
|
|
72
75
|
| `dot profile` | Show or switch the active configuration profile |
|
|
73
76
|
| `dot keys` | Show the keybindings and signing reference |
|
|
74
77
|
| `dot tools` | Show tools documentation |
|
|
@@ -78,6 +81,7 @@ The `dot` command is the main interface for managing dotfiles. Run `dot version`
|
|
|
78
81
|
| `dot learn` | Start the guided onboarding tour |
|
|
79
82
|
| `dot docs` | Show the main repository documentation |
|
|
80
83
|
| `dot log-rotate` | Rotate `~/.local/share/dotfiles.log` |
|
|
84
|
+
| `dot completion <bash\|zsh\|fish\|nu>` | Generate shell completions from the command registry |
|
|
81
85
|
| `dot lint` | Lint shell scripts (`--check/-c`,`--fix/-f`) |
|
|
82
86
|
|
|
83
87
|
## Universal Scripts
|
|
@@ -142,6 +146,7 @@ prints a one-line hint. See [AI.md](../AI.md) for the full surface.
|
|
|
142
146
|
| Command | Description |
|
|
143
147
|
|---------|-------------|
|
|
144
148
|
| `dot backup` | Create a compressed backup |
|
|
149
|
+
| `dot policy` | Check and enforce security policies across the environment |
|
|
145
150
|
| `dot encrypt-check` | Check disk encryption status |
|
|
146
151
|
| `dot firewall` | Apply firewall hardening |
|
|
147
152
|
| `dot telemetry` | Disable telemetry |
|
|
@@ -157,3 +162,80 @@ prints a one-line hint. See [AI.md](../AI.md) for the full surface.
|
|
|
157
162
|
| `dot fleet drift` | Check configuration drift across managed files |
|
|
158
163
|
| `dot fleet namespace` | Show or set the active fleet namespace |
|
|
159
164
|
| `dot fleet events` | Show recent local fleet events |
|
|
165
|
+
| `dot teleport <user@host>` | Deploy the dotfiles environment to a remote host over SSH |
|
|
166
|
+
|
|
167
|
+
## Subcommands
|
|
168
|
+
|
|
169
|
+
Every `dot` command's individually-enforced subcommands (see `dot help`).
|
|
170
|
+
|
|
171
|
+
| Command | Description |
|
|
172
|
+
|---|---|
|
|
173
|
+
| `dot fleet status` | Show this node's fleet status: id, namespace, version, OS, drift, last apply |
|
|
174
|
+
| `dot fleet enforce` | Show or set RBAC enforcement mode (advisory/strict) for agent profiles |
|
|
175
|
+
| `dot fleet apply` | SSH to every host in fleet.toml and run dot sync (or a custom --cmd) |
|
|
176
|
+
| `dot ai chat` | Start an interactive AI session with a chosen tool |
|
|
177
|
+
| `dot ai tools` | Show installed AI CLI tools and their versions |
|
|
178
|
+
| `dot ai install` | Install AI CLI tools via mise/native installers |
|
|
179
|
+
| `dot ai serve` | Run the local AI gateway/proxy that routes non-Claude providers |
|
|
180
|
+
| `dot ai cost` | Report AI spend across every provider from the unified run log |
|
|
181
|
+
| `dot ai login` | Interactive setup/authentication for installed AI CLI tools |
|
|
182
|
+
| `dot ai doctor` | Diagnose AI tooling configuration and connectivity |
|
|
183
|
+
| `dot ai ask` | Context-aware RAG query over your dotfiles |
|
|
184
|
+
| `dot ai run` | Run a one-shot prompt with an AI tool |
|
|
185
|
+
| `dot ai delegate` | Delegate a coding task to a cheaper AI model under agent policy |
|
|
186
|
+
| `dot mode list` | List available agent operating profiles (ask/plan/apply/audit) |
|
|
187
|
+
| `dot mode current` | Show the active agent profile and its policy |
|
|
188
|
+
| `dot mode show` | Show details of a specific agent profile |
|
|
189
|
+
| `dot mode set` | Switch the active agent profile |
|
|
190
|
+
| `dot mode run` | Run a command under a given agent profile with a checkpoint |
|
|
191
|
+
| `dot mode doctor` | Validate the agent-profiles.json config and default profile |
|
|
192
|
+
| `dot agent card` | Show the local agent card metadata |
|
|
193
|
+
| `dot agent log` | Tail the agent session audit log |
|
|
194
|
+
| `dot agent checkpoint` | Manage agent run checkpoints (save/list/show/replay) |
|
|
195
|
+
| `dot agent delegate` | Delegate execution to an allowed sub-agent |
|
|
196
|
+
| `dot agent a2a-card` | Show or validate the A2A v0.3 agent card |
|
|
197
|
+
| `dot agent conformance` | Run the A2A conformance test suite |
|
|
198
|
+
| `dot mcp doctor` | Run the MCP policy/supply-chain/config audit |
|
|
199
|
+
| `dot mcp registry` | Show the configured MCP server registry |
|
|
200
|
+
| `dot secrets edit` | Edit the encrypted secrets file (age) |
|
|
201
|
+
| `dot secrets set` | Store a secret value under a key |
|
|
202
|
+
| `dot secrets get` | Retrieve a secret value (--raw for plaintext) |
|
|
203
|
+
| `dot secrets list` | List indexed secret keys |
|
|
204
|
+
| `dot secrets load` | Emit export lines for a secrets bucket (use with eval) |
|
|
205
|
+
| `dot secrets provider` | Show the active secrets provider |
|
|
206
|
+
| `dot env list` | List managed tool versions via mise |
|
|
207
|
+
| `dot env prune` | Show or remove orphan tool installs (--yes to commit) |
|
|
208
|
+
| `dot env install` | Install requested tool versions via mise |
|
|
209
|
+
| `dot env use` | Pin a tool version globally/locally via mise |
|
|
210
|
+
| `dot registry list` | List modules in the configured module registry |
|
|
211
|
+
| `dot registry search` | Filter registry modules by keyword |
|
|
212
|
+
| `dot registry info` | Print full metadata for a registry module |
|
|
213
|
+
| `dot registry install` | Install a registry module (scaffold) |
|
|
214
|
+
| `dot registry url` | Show the active registry URL |
|
|
215
|
+
| `dot registry set-url` | Override the registry URL (https only; persists) |
|
|
216
|
+
| `dot theme list` | Show all available terminal/wallpaper themes |
|
|
217
|
+
| `dot theme set` | Set a theme by name (interactive picker if omitted) |
|
|
218
|
+
| `dot theme toggle` | Toggle light/dark within the current theme family |
|
|
219
|
+
| `dot theme sync` | Sync the dotfiles theme with system dark/light mode |
|
|
220
|
+
| `dot theme family` | Cycle between theme families |
|
|
221
|
+
| `dot theme current` | Show the current theme info |
|
|
222
|
+
| `dot theme rebuild` | Regenerate themes from system and custom wallpapers |
|
|
223
|
+
| `dot wallpaper sync` | Sync wallpaper from your library |
|
|
224
|
+
| `dot wallpaper rotate` | Rotate to the next wallpaper in your library |
|
|
225
|
+
| `dot tools install` | Enter the Nix development shell with all managed tools |
|
|
226
|
+
| `dot tools docs` | Show the full tools markdown documentation |
|
|
227
|
+
| `dot profile show` | Show the active configuration profile and feature flags |
|
|
228
|
+
| `dot profile set` | Set the active configuration profile (run dot sync to apply) |
|
|
229
|
+
| `dot agents list` | Show recognised AI agent harnesses and their config paths |
|
|
230
|
+
| `dot agents check` | Verify AGENTS.md tracks CLAUDE.md (exit 1 if drifted) |
|
|
231
|
+
| `dot agents render` | Regenerate AGENTS.md and per-harness config from CLAUDE.md |
|
|
232
|
+
| `dot aliases list` | List all shell aliases shipped by the dotfiles |
|
|
233
|
+
| `dot aliases search` | Search aliases by term |
|
|
234
|
+
| `dot aliases why` | Show details and deprecation status for a single alias |
|
|
235
|
+
| `dot aliases stats` | Show alias usage counts from shell history |
|
|
236
|
+
| `dot aliases cheatsheet` | Generate the alias cheatsheet markdown |
|
|
237
|
+
| `dot aliases tiers` | Show which alias tiers/ecosystems are enabled |
|
|
238
|
+
| `dot patterns list` | List AI steering patterns |
|
|
239
|
+
| `dot patterns view` | View an AI steering pattern |
|
|
240
|
+
| `dot patterns edit` | Edit an AI steering pattern in $EDITOR |
|
|
241
|
+
| `dot keys sign-check` | Verify git commit-signing configuration and key availability |
|
|
@@ -5,7 +5,7 @@ render_with_liquid: false
|
|
|
5
5
|
# Pre-Push Audit Bypass
|
|
6
6
|
|
|
7
7
|
This page documents when the pre-push reliability audit can be bypassed,
|
|
8
|
-
how to do it, and why the answer is "almost never on `
|
|
8
|
+
how to do it, and why the answer is "almost never on `main`."
|
|
9
9
|
|
|
10
10
|
## Background
|
|
11
11
|
|
|
@@ -57,7 +57,7 @@ bypassed?" without git archaeology.
|
|
|
57
57
|
|
|
58
58
|
Short list — anything outside this is suspicious:
|
|
59
59
|
|
|
60
|
-
- **Hotfix push to a non-
|
|
60
|
+
- **Hotfix push to a non-main branch** when CI infrastructure itself
|
|
61
61
|
is the audit blocker (e.g., the audit pre-flight depends on a remote
|
|
62
62
|
service that's down). The fix should land *before* the
|
|
63
63
|
infrastructure recovers; bypass is the bridge.
|
|
@@ -66,7 +66,7 @@ Short list — anything outside this is suspicious:
|
|
|
66
66
|
|
|
67
67
|
When bypass is **not** legitimate:
|
|
68
68
|
|
|
69
|
-
- Routine `
|
|
69
|
+
- Routine `main` pushes. The whole point of the audit is to guard
|
|
70
70
|
the protected branch.
|
|
71
71
|
- Pushes whose audit failure is "annoying" — the right move is to fix
|
|
72
72
|
the failure, not skip the check.
|
|
@@ -21,6 +21,6 @@ render_with_liquid: false
|
|
|
21
21
|
## Provisioning notes
|
|
22
22
|
|
|
23
23
|
1. Store the SSH signing private key in GitHub Actions as `ACTIONS_BOT_SIGNING_KEY`.
|
|
24
|
-
2. Store the matching public key in [allowed_signers](
|
|
24
|
+
2. Store the matching public key in [allowed_signers](https://github.com/sebastienrousseau/dotfiles/blob/main/defaults/dot_config/git/allowed_signers.tmpl).
|
|
25
25
|
3. Rotate the key on personnel or workstation change.
|
|
26
26
|
4. Fail closed when secrets are absent.
|
|
@@ -17,7 +17,7 @@ Every external dependency the CI pipeline consumes must be pinned by
|
|
|
17
17
|
When `ci.yml` calls a reusable via `./.github/workflows/reusable-X.yml`,
|
|
18
18
|
GitHub resolves the reusable from the **same ref as the calling
|
|
19
19
|
workflow at run time**. For an in-repo PR that's the PR's branch —
|
|
20
|
-
fine. The risk is the inverse: a malicious push to `
|
|
20
|
+
fine. The risk is the inverse: a malicious push to `main` (or any
|
|
21
21
|
ref the calling workflow might resolve from) can swap reusable
|
|
22
22
|
content under a CI run, with no audit trail in the PR diff.
|
|
23
23
|
|
|
@@ -29,11 +29,11 @@ site — visible in the PR diff, reviewable, revertible.
|
|
|
29
29
|
|
|
30
30
|
```yaml
|
|
31
31
|
# Acceptable — full SHA pin.
|
|
32
|
-
uses: sebastienrousseau/dotfiles/.github/workflows/reusable-shell-lint.yml@b0615f8fb5c0f3826f58904a5567eff11b6c500e #
|
|
32
|
+
uses: sebastienrousseau/dotfiles/.github/workflows/reusable-shell-lint.yml@b0615f8fb5c0f3826f58904a5567eff11b6c500e # main
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
The trailing comment is a human-readable hint at what the SHA
|
|
36
|
-
represented when it was pinned (typically `
|
|
36
|
+
represented when it was pinned (typically `main`, sometimes a tag
|
|
37
37
|
like `v0.2.501`). The hint is documentation only — the SHA is what
|
|
38
38
|
GitHub uses.
|
|
39
39
|
|
|
@@ -44,7 +44,7 @@ GitHub uses.
|
|
|
44
44
|
uses: ./.github/workflows/reusable-shell-lint.yml
|
|
45
45
|
|
|
46
46
|
# Rejected — branch ref is mutable.
|
|
47
|
-
uses: sebastienrousseau/dotfiles/.github/workflows/reusable-shell-lint.yml@
|
|
47
|
+
uses: sebastienrousseau/dotfiles/.github/workflows/reusable-shell-lint.yml@main
|
|
48
48
|
|
|
49
49
|
# Rejected — tag ref is mutable (tags can be moved).
|
|
50
50
|
uses: sebastienrousseau/dotfiles/.github/workflows/reusable-shell-lint.yml@v0.2.501
|
|
@@ -57,20 +57,20 @@ rejected forms above.
|
|
|
57
57
|
## Refreshing pinned SHAs
|
|
58
58
|
|
|
59
59
|
`bump-reusable-pins.yml` handles this automatically. On every push to
|
|
60
|
-
`
|
|
60
|
+
`main` that touches `.github/workflows/reusable-*.yml`, the bot scans
|
|
61
61
|
caller workflows for stale pins and opens a PR bumping them to the new
|
|
62
62
|
SHA. Signed with `ACTIONS_BOT_SIGNING_KEY` so the resulting commit
|
|
63
63
|
passes `Verify Commit Signatures`.
|
|
64
64
|
|
|
65
65
|
The manual recipe below stays here as a fallback — for example, if you
|
|
66
|
-
need to bump pins before a merge to
|
|
66
|
+
need to bump pins before a merge to main, or if the bot's run failed
|
|
67
67
|
and you want to short-circuit waiting for the next push trigger.
|
|
68
68
|
|
|
69
69
|
```sh
|
|
70
|
-
# 1. Land the change to the reusable on
|
|
71
|
-
# 2. After merge, capture the new
|
|
72
|
-
git fetch origin
|
|
73
|
-
PIN=$(git rev-parse origin/
|
|
70
|
+
# 1. Land the change to the reusable on main via a PR.
|
|
71
|
+
# 2. After merge, capture the new main SHA:
|
|
72
|
+
git fetch origin main
|
|
73
|
+
PIN=$(git rev-parse origin/main)
|
|
74
74
|
echo "$PIN"
|
|
75
75
|
|
|
76
76
|
# 3. Bump every call site:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Commit Signing — Policy & Setup
|
|
2
2
|
|
|
3
|
-
Every commit that reaches `
|
|
3
|
+
Every commit that reaches `main` in this repository must carry a
|
|
4
4
|
cryptographic signature that GitHub can verify. The policy is enforced
|
|
5
5
|
in three independent layers, so a single bypass does not break the
|
|
6
6
|
chain. This document explains the policy, walks through SSH and GPG
|
|
@@ -24,16 +24,16 @@ is missing. The chain below removes every escape hatch.
|
|
|
24
24
|
`git verify-commit` against every commit in the push range. A
|
|
25
25
|
single unverified commit aborts the push. `--no-verify` skips
|
|
26
26
|
this layer; the next two catch it.
|
|
27
|
-
3. **GitHub Rulesets** — `.github/rulesets/
|
|
28
|
-
`required_signatures` on `refs/heads/
|
|
27
|
+
3. **GitHub Rulesets** — `.github/rulesets/main.json` declares
|
|
28
|
+
`required_signatures` on `refs/heads/main`. The rule is part
|
|
29
29
|
of the repo so it's reproducible across forks. Apply with
|
|
30
|
-
`gh ruleset import .github/rulesets/
|
|
30
|
+
`gh ruleset import .github/rulesets/main.json`.
|
|
31
31
|
4. **`compliance-guard.yml` workflow** — runs on every PR targeting
|
|
32
|
-
`
|
|
32
|
+
`main`. Walks the commit range with `git verify-commit` and
|
|
33
33
|
marks unsigned commits in the PR summary; fails the workflow
|
|
34
34
|
when `unsigned_count > 0`.
|
|
35
35
|
|
|
36
|
-
A merge to `
|
|
36
|
+
A merge to `main` therefore requires (Ruleset accepts the push) AND
|
|
37
37
|
(the workflow's signed-commit check passes) AND (the maintainer's
|
|
38
38
|
push key is allowed). The protection holds even if a contributor's
|
|
39
39
|
local hooks are missing or skipped.
|
|
@@ -100,7 +100,7 @@ git log "$(git merge-base @{u} HEAD)..HEAD" \
|
|
|
100
100
|
for c in $(git rev-list "$(git merge-base @{u} HEAD)..HEAD"); do
|
|
101
101
|
git verify-commit "$c" >/dev/null 2>&1 \
|
|
102
102
|
&& echo "✓ $c" \
|
|
103
|
-
|| echo "✗ $c — unsigned, will be rejected by
|
|
103
|
+
|| echo "✗ $c — unsigned, will be rejected by main ruleset"
|
|
104
104
|
done
|
|
105
105
|
```
|
|
106
106
|
|
|
@@ -112,7 +112,7 @@ done
|
|
|
112
112
|
| `error: Load key "/.../id_ed25519": Permission denied` | SSH key permissions too open | `chmod 600 ~/.ssh/id_ed25519` |
|
|
113
113
|
| GitHub shows "Unverified" on a commit signed locally | Signing key not uploaded to GitHub | `gh ssh-key add … --type signing` (SSH) or `gh gpg-key add` (GPG) |
|
|
114
114
|
| Pre-push hook rejects a merge commit you didn't author | Upstream commit lacks a signature | Either pull the rebased branch, or fast-forward instead of merging |
|
|
115
|
-
| Ruleset import via `gh` complains "invalid JSON" | Rulesets API expects the `target` + `rules` envelope, not just the rules array | Use the file as-is — `gh ruleset import .github/rulesets/
|
|
115
|
+
| Ruleset import via `gh` complains "invalid JSON" | Rulesets API expects the `target` + `rules` envelope, not just the rules array | Use the file as-is — `gh ruleset import .github/rulesets/main.json` |
|
|
116
116
|
|
|
117
117
|
## Re-applying the ruleset after a manual edit
|
|
118
118
|
|
|
@@ -121,14 +121,14 @@ file-of-truth wins. Re-apply:
|
|
|
121
121
|
|
|
122
122
|
```sh
|
|
123
123
|
gh api -X POST repos/{owner}/{repo}/rulesets \
|
|
124
|
-
--input .github/rulesets/
|
|
124
|
+
--input .github/rulesets/main.json
|
|
125
125
|
```
|
|
126
126
|
|
|
127
127
|
(or `-X PUT` against the existing ruleset's ID if it already exists).
|
|
128
128
|
|
|
129
129
|
## References
|
|
130
130
|
|
|
131
|
-
- `.github/rulesets/
|
|
131
|
+
- `.github/rulesets/main.json` — the enforced policy.
|
|
132
132
|
- `.github/workflows/compliance-guard.yml` — the workflow that
|
|
133
133
|
fails PRs containing unsigned commits.
|
|
134
134
|
- `scripts/git-hooks/pre-push` — the local pre-push gate.
|