vs submodule
Submodules store a pointer, so a fresh clone is empty until you run submodule update --init. Subtree vendors the actual files — every repo is self-contained and clone-and-go. Better for public portfolio repos.
The system is built on one decision repeated consistently: draw a hard boundary between what is identical on every machine and what changes with the OS or the operator. Get the boundary right and a single Core can serve nine machines with zero special-casing.
If it changes when the operating system changes, it does not belong in Core.
If it changes when you as an operator change, it does not belong in Core.
Everything left over is Core — and it lives in exactly one place.
git subtree zsh modules, tmux base, nvim, git/delta dotfiles-{MacBook,Windows,Fedora,Arch,…} package manager, clipboard shim, paths dotfiles-Kali engagement scaffolding, C2, Impacket, wordlists
Each machine repo vendors dotfiles-core under core/ as a
git subtree. That physically copies Core in and commits it, so the repo clones and
works with no submodule flags — important, since these are public showcase repos
people will browse.
# one-time, inside an OS repo:
$
git subtree add --prefix=core https://github.com/Gerrrt/dotfiles-core main --squash
# later, to pull Core updates down:
$
git subtree pull --prefix=core https://github.com/Gerrrt/dotfiles-core main --squash
Maintainers fan a Core change out to every OS repo in one shot with
scripts/sync-core.sh, which prints the exact short SHA each repo
receives so a sync is traceable.
Submodules store a pointer, so a fresh clone is empty until you run submodule update --init. Subtree vendors the actual files — every repo is self-contained and clone-and-go. Better for public portfolio repos.
chezmoi (one repo + per-OS templates) is the most DRY answer and the right move if you ever collapse nine repos into one. This system keeps the nine-repo portfolio; switching later is a content migration, not a rewrite, because Core is already plain and OS-agnostic.
Load order is load-bearing. tools initializes atuin (registering its
widget), options runs compinit (fzf-tab + carapace need
it), and fzf defines its widgets before plugins
loads zsh-vi-mode, whose init fires the keybinding hook in bindings.
Every OS repo’s .zshrc sources the chain in this order:
Kali is the only repo that stacks three layers. Where every other repo’s loader
ends … os local, Kali inserts one more stage —
… os offensive local — for engagement scaffolding (scope-first
workspaces, an audit-trail logshell, NetExec/BloodHound CE helpers).
Engagement data never lives in the repo; it stays under
~/engagements, and every tool is for authorized engagements with
written rules of engagement only.
The design decisions above are documented in full inside the repos. These are the long-form references worth reading next:
The per-distro lookup that turns the Fedora template into Arch, openSUSE, Alpine, and Gentoo — package manager, clipboard backend, and quirks, side by side.
Read it ↗ dotfiles-KaliHow the Kali role layer maps to MITRE ATT&CK tactics — NetExec, BloodHound CE, Impacket, certipy-ad — and where loot lands under ~/engagements.
Read it ↗ dotfiles-coreThe supply-chain stance: SHA-pinned plugins, pinned CI actions and pre-commit hooks, and how to report an issue.
Read it ↗ dotfiles-WindowsThe structural audit behind the PowerShell host: fragment loader, coverage gate, and how the host layer bridges into WSL.
Read it ↗ dotfiles-MacBookMoving an existing Mac onto the ecosystem without trampling what is already there.
Read it ↗ dotfiles-ArchBare-metal groundwork for a minimal Arch box — user, sudo, git, and a UTF-8 locale — before bootstrap can run.
Read it ↗