This repo is the Core layer — the config that is identical on every machine —
authored once here and vendored into each OS repo's core/ via git subtree.
A change here fans out to all eight OS repos, so the bar is: is this truly Core,
and is it healthy?
Before adding anything, run the README's test. It belongs here only if:
- it is identical on every machine (not OS-specific), and
- it is not offensive/engagement tooling.
Otherwise it lives elsewhere:
| If it changes when… | It belongs in… |
|---|---|
| the operating system changes (pkg manager, paths, clipboard) | the OS repo (dotfiles-{MacBook,Fedora,Arch,…}) |
| you as an operator change (C2/wordlists; or detections/hunts) | dotfiles-Kali (offense) / dotfiles-Defense (defense) |
| neither — it's the same everywhere | here |
core.manifest is the canonical inventory of what Core ships. Adding a new Core
file means adding its path to core.manifest in the same change — the audit
enforces this in both directions:
- every path listed in the manifest must exist on disk, and
- every tracked file must be either listed in the manifest or in the audit's repo-meta allowlist (docs, CI config, dev tooling).
Repo-meta and dev tooling (this file, LICENSE, .github/, scripts/sync-core.sh,
scripts/audit-core.sh, …) are not vendored into OS repos, so they live in the
allowlist in scripts/audit-core.sh rather than the manifest.
scripts/audit-core.sh is the test suite. It checks manifest↔filesystem drift,
executable-bit invariants, shell syntax (bash -n / zsh -n), luacheck, and
shellcheck. It degrades gracefully — a missing linter is skipped, not failed —
so it runs on a bare box as well as in CI.
./scripts/audit-core.sh # full run
./scripts/audit-core.sh --quiet # only skips/failures + summaryThe same script runs in CI (.github/workflows/ci.yml) on every push and PR, so
local and CI share one definition of "healthy."
pip install pre-commit && pre-commit install
pre-commit run --all-filesThis wires up shellcheck, the standard whitespace/shebang hooks, and the audit
itself at commit time. Two deliberate non-checks:
- shfmt is not enforced. The scripts here use an intentional compact
one-liner style that
shfmtwould expand. - luacheck only runs via the audit (from inside
nvim/), because it discovers.luacheckrcby searching up from the working directory — run from the repo root it missesnvim/.luacheckrcand floods false "undefined vim" warnings.
- Executable bits matter. Anything invoked by path (the
bin/clip shims, thescripts/dev tooling andtmux/scripts/popups, the maint runner) must be+x; thezsh/*.zshmodules are sourced, so they must stay non-executable. The audit asserts both, so a regression fails CI rather than reaching a machine. - Indentation is 2-space across the tree (
.editorconfig). - Keep OS-specific bits out. Strip clipboard/paths/package-manager logic into the OS repo; Core stays portable.
Use a Conventional Commits prefix so the
log reads as a changelog and tooling can group it (dependabot already commits with
a ci prefix; see dependabot.yml):
type(scope): short imperative summary
optional body explaining the why
Common types here: fix, feat, test, ci, docs, chore, perf. The
scope is the Core area touched — zsh, nvim, tmux, audit, changelog, etc.
A user-visible change should land in CHANGELOG.md under [Unreleased] in the
same commit.
- Confirm it's Core (the table above).
- Drop it into the matching path.
- Strip out anything OS-specific.
- Add the path to
core.manifest. - Wire the symlink into each OS repo's
bootstrap.shif it needs one. ./scripts/audit-core.sh— green before you push../scripts/sync-core.shto vendor it into every OS repo.