Releases: dotgibson/dotfiles-core
Release list
v2.6.0
Added
seshdetection (HAVE_SESH) — finishing wiring Core already half-shipped.
sesh(joshmedeski's smart tmux session manager) was already driven by the
Ctrl-Gshell widget (fzf.zsh), theprefix + ftmux popup (tmux-sesh.sh),
a seededsesh/sesh.toml.example, and listed incore-doctor's integrations —
buttools.zshnever set aHAVE_SESHflag for it the way it does for the
other detected tools. (Detection itself still worked — theCtrl-G/prefix + f
fallback keys offcommand -v sesh, andcore-doctoralready probessesh
the same way.)tools.zshnow sets
HAVE_SESH(likeHAVE_GUM, no_core_wiredarm — sesh registers no persistent
shell hook, so presence ≈ wired), andPORTING-MATRIX.mdgains aseshrow +
footnote documenting thego install github.com/joshmedeski/sesh/v2@latestbuild
path (the v2 module path;gois already a pinned mise runtime) for the
distros that don't package it. Nocore.manifestchange — the.exampleis
already listed.RELEASE-RUNBOOK.md— the step-by-step, copy-paste recipe for cutting a release
(Core, the OS-repo fan-out rollout, and htpx), plus a "dry-run a new cross-repo
workflow before relying on it" habit and a troubleshooting table. Complements
RELEASE-STRATEGY.md(the policy); cross-linked from it andCLAUDE.md.
Changed
-
nvim: disable
<LeftDrag>and<LeftRelease>in all modes unconditionally.
Previously these were suppressed only when inside a$TMUXsession, in Normal and
Visual modes. They are now<Nop>in Normal, Insert, and Visual modes regardless of
environment, eliminating accidental mouse-drag selections during terminal use. -
bootstrap-test.ymlretries the per-distroprepstep (up to 5x with backoff).
The reusable links-only job ran the dep install once; a transient distro-mirror
timeout (notably openSUSE Tumbleweed's OSS CDN) then redded the job — and every Core
fan-out PR — on a network blip. The retry is fleet-wide (one place, every caller);
a genuinely broken prep still fails loud after the attempts are exhausted.
v2.5.0
Added
- jujutsu (
jj) as an OPT-IN, colocated git companion. Additive — it never replaces
git. Newjujutsu/config.toml(symlinked to~/.config/jj/config.toml, in
core.manifest) sets a sensible colocated-friendly default (ui.default-command = "log",
auto-local-bookmark; identity intentionally unset — jj does NOT inherit git's
user.name/user.email, so an opt-in author sets it once withjj config set --user user.name/user.email).tools.zshgainsHAVE_JJ
detection andaliases.zsha fewHAVE_JJ-guarded verbs (jjs/jjl/jjd); nothing
is aliased overgit. On a box withoutjjeverything is inert.PORTING-MATRIX.md
documents per-distro packaging (packaged on Arch/openSUSE/Gentoo/Fedora/Homebrew/nix;
cargo install jujutsuon Alpine(musl)/Debian-Kali — same pattern as yazi/ouch).
Changed
- zsh syntax highlighter swapped:
fast-syntax-highlighting→
zsh-users/zsh-syntax-highlighting(z-sy-h). The pin moves to z-sy-h (a maintained,
first-partyzsh-usersplugin) and the load order is corrected per its README: the
highlighter is now the LAST widget-wrapping plugin sourced, with
zsh-history-substring-searchdeferred immediately after it so its widgets get wrapped.
TheFAST_THEME/FAST_HIGHLIGHTtheming is replaced by minimalZSH_HIGHLIGHT_HIGHLIGHTERS
(main+brackets) andZSH_HIGHLIGHT_STYLESrecoloured to the Tokyo Night Storm palette. fleet-drift.shanchors to the latest released Core tag by default, not the working
tip. Fan-out stamps each OS repo with the Core tag it carries, so the dashboard now
measures against the newestvX.Y.Z(viagit describe), falling back to
origin/main/main/HEAD. An explicit--ref/$CORE_REF_SHAstill wins. This stops
the false "BEHIND by N" the report showed for every unreleased commit onmain
(CHANGELOG/auto-tag churn between releases); thefleet-drift.ymlworkflow drops its
--ref HEADaccordingly.
Fixed
-
auto-tag.shexit-code contract hardened + tested. Added a defence-in-depth guard so
_next_versionfails loudly (non-zero) on a non-X.Y.Zinput instead of producing a
garbage component, and the call site now propagates that failure rather than tagging a
bogusv. The behavioral suite (test-core.sh) now asserts the full exit-code contract
hermetically (no network/gh): success → 0, no-op → 0, validation error → 2, and a real
create failure (a--pushonto an already-taken tag name, tripping Guard 2) → non-zero. -
auto-tag.sh --releasefails CI when an opted-in Release create actually fails. The
gh release createerror branch calledfailbut the script still exited 0, so a real
failure (gh present, API error) went green with no Release. It nowexit 1s there — the
tag still stands (pushed above), but CI goes red so you create the Release manually. The
two non-failure exits stay deliberate: gh absent → skip, Release already exists → no-op.
Also added--releaseto theusage()synopsis line (it was only in the flag list) and
clarified its gh/skip semantics.
v2.4.1
Changed
tag-release.shrecipe spells out the land-then-tag order. The printed next-steps
now make the sequence explicit — land the release commit via PR (a merge commit), then
tagorigin/main(the merged tip) so the tag sits onmain's HEAD andgit describe
stays clean — instead of tagging the pre-merge commit and re-pointing. The two tag pushes
use;, not&&(an "already exists" on the first must not skip the second — thevN
move).PUSH=1now warns that it tags the pre-merge commit and prints the re-point steps.
v2.4.0
Added
- OS-repo / Windows auto-tags now publish a GitHub Release too (
auto-tag.sh --release). Core releases already become Releases on tag push (release.yml), but the
OS-repo tagsauto-tag.shcuts in CI were bare — no Releases page entry. A token-pushed
tag can't trigger a separateon: push: tagsworkflow (GitHub anti-recursion), so the
Release is now created in the SAME job:auto-tag.sh --releaserunsgh release create <tag> --generate-notesright after pushing (idempotent — a no-op if the Release exists;
a missingghjust leaves the tag, never fails).auto-tag-call.ymlgained arelease
input (defaulttrue) and passes--release, so every consumer of@v2gets Releases
on its next fan-out. Reusable beyondcore/consumers: any repo (e.g. dotfiles-Windows
on annvim//starship/sync) can call the workflow to self-tag-and-release.
v2.3.0
Fixed
auto-tag.shhardened against irregular tags + arg edge cases. Tag discovery now
filters to a strict^vX.Y.Z$regex instead of git's loose--listglob, so a
prerelease/suffixed tag (v1.2.3-rc1) or a moving major alias (v2) can no longer be
mistaken for the latest release (which would have double-tagged or fed a non-numeric
component into the bump). Version components are coerced base-10 (10#) so a zero-padded
tag (v1.08.0) doesn't trip octal arithmetic.--bump/--initial/--colornow error
cleanly on a missing value instead of mis-consuming the next flag.usage()documents
every flag + default, and the re-push hint quotes$REPO/$NEXT.auto-tag-call.ymlpins itsdotfiles-corecheckout to@v2. The script is now
fetched from the same major line callers pin the workflow to, so the tag-cutter's
behavior can't drift from the pinned@v2definition between releases (matching the
@vNpolicy). Dropped the redundantfetch-tags(fetch-depth 0 already brings tags).
v2.2.0
Added
- Automatic OS-repo release tagging on Core fan-out (
auto-tag-call.yml+
scripts/auto-tag.sh). An OS repo carries two version lines — the Core it vendors
(core.lock, advanced bysync-core.shon every sync) and its OWNvX.Y.Ztag, which
used to move only by hand and so drifted (most repos froze at an old tag; the newest had
none). A new reusableworkflow_calllets each OS repo cut its next tag automatically
when a fan-out lands newcore/on itsmain: PATCH-bump by default (a new Core is a
maintenance bump of the consumer),bump: minor|majorfor a deliberate release. The
version math lives inscripts/auto-tag.sh(shellcheck-clean, dry-run by default), is idempotent
(a no-op when HEAD is already avX.Y.Zrelease), and tags in CI — so no operator
round-trip and no reliance on a local tag push. Each OS repo adds a three-line caller
(on: pushtomain,paths: ['core/**']).
v2.1.1
Fixed
bootstrap.sh --links-onlyno longer aborts when zsh isn't installed.
blib_set_login_shelldidzsh_path="$(command -v zsh)"; with zsh absent that
substitution exits non-zero, and under the bootstrap'sset -eit aborted the run
before the[[ -n "$zsh_path" ]] || return 0guard that was meant to handle the
missing-zsh case — surfacing as a links-only CI failure in the one base image
without zsh preinstalled (gentoo/stage3). Nowcommand -v zsh || true, so the
guard decides, not errexit. No behavior change where zsh is present.tag-release.sh --pushno longer pushes the protectedmainbranch.main
enforces required status checks (GH013), so the old step —git push origin "$BRANCH" && git push origin "$TAG" && git push -f origin "$MAJOR", branch FIRST — had its
branch push rejected, which short-circuited the&&chain so the tags never pushed
either:--pushfailed outright and could never complete a release through the push
path. The step now pushes the immutablevX.Y.Ztag and force-moves thevNmajor
alias ONLY (tags aren't branch-protected), then prints the PR recipe to land the
release commit onmain(HEAD:release/vX.Y.Z→ PR → merge commit), matching how
releases actually ship (e.g. #95). The non-push recipe block was corrected the same way.
v2.1.0
Fixed
starship.tomlVPN segment no longer spams on Windows. The[custom.vpn]
probe (ifconfig …) is Unix-only; once the canonical file synced to the Windows
host verbatim, starship ran it every prompt and hitcommand_timeoutwith a noisy
custom command … timed outWARN. Split it into OS-gated[custom.vpn_macos]/
[custom.vpn_linux]modules (a custom module'sostakes one value — no "unix"),
so Windows matches neither and never runs the probe. Unchanged on macOS/Linux.
Added
- Core-integrity CI guard (
make core-integrity+core-integrity.yml). A
durable, CI-runnable tamper check: it compares each OS repo's vendoredcore/tree
object against the commit itscore.lockpins (content-addressed, so any hand-edit
diverges the hash). Replaces the local-only.git/hookscore-guard, which couldn't
run on a fresh clone or in CI. Companion tofleet-drift(integrity vs staleness) —
both run weekly and on demand. - Per-repo core-guard (
core-integrity-call.yml+core-integrity.sh --self).
A reusableworkflow_callan OS repo invokes from its own CI to BLOCK a hand-edit
to its vendoredcore/at PR time (prevention), where the central sweep only
DETECTS one after the fact. Runs the same tree-SHA comparison via a new--self
mode that checks exactly one repo against itscore.lock. Each OS repo adds a
three-line caller.
Changed
- Reusable-workflow pin policy:
@vNmoving major tag.tag-release.shnow
force-advances avNmajor tag (e.g.v2) to eachvN.xrelease, alongside the
immutablevX.Y.Ztag. Cross-repo callers of the fleet's reusable workflows
(bootstrap-test.yml,core-integrity-call.yml) pin to@vNinstead of@main:
deterministic between releases (a caller's CI can't change with zero diff in its
repo) yet still auto-propagating patch/minor guard fixes. Documented in
RELEASE-STRATEGY.md. (Foundation only — re-pinning the existing@maincallers
fleet-wide is a follow-up once av2tag is published.) fleet-drift.shlabels the Windows row by release tag too._check_repo
gained a fourthtag-keyargument (defaultcore_tag); the Windows row passes
tag, so oncedotfiles-Windows'snvim-sync.ps1stamps atag = <release>
field intonvim/.core-ref(its companion change), the dashboard showsv2.0.0
for Windows instead of the bare SHA — all nine rows now speak in release names.
Backward compatible: with no tag recorded it still falls back to the short SHA,
and the drift verdict stays SHA-based. Verified both paths against a fixture.starship.tomlis now cross-shell (one canonical file). Added
powershell_indicatorto[shell]so the single Corestarship.tomlrenders under
both zsh and PowerShell, and dotfiles-Windows now syncs this file verbatim (its new
starship-sync.ps1) instead of carrying a drifted copy. Benign on zsh — starship
only renders the active shell's indicator.
v2.0.0
Breaking — keybindings realigned. The zsh file-picker moved off
Ctrl+Fto
Ctrl+T, and the cross-shell keys were settled fleet-wide:Ctrl+Eatuin
TUI,Ctrl+Rquick fzf history,Ctrl+Gjump-to-session (navi dropped its
Ctrl+Gwidget for thenavicommand),Alt+Zzoxide jump. Update muscle
memory and re-source your shell (or restart it) after the nextmake sync. This is
the breaking change that makes this release 2.0.0 rather than a 1.x bump;
everything else below is additive or a fix.
Changed
/freshness-triagenow covers the CLI tool pins. The routine reviewed zsh/nvim/
actions bumps but said nothing aboutscripts/tool-versions.env— the one bump class
that also needsmake update-tool-checksumsto refresh its*_SHA256. Added a section
so a*_VERSIONchange without its checksum is flagged Hold (the audit only checks
the hash is present, not correct, so a stale hash otherwise fails late at the action's
sha256sum -cin CI). Routine-doc only; no code change.- Cross-shell keybindings aligned (PARITY.md decisions resolved). The four open
parity decisions are settled and implemented on both shells: Ctrl+T = file picker
(zsh moved offCtrl+F), Ctrl+E = atuin TUI / Ctrl+R = quick fzf history,
Ctrl+G = jump-to-session everywhere (zsh sesh; the host gets a psmux sessionizer,
with navi demoted from its Ctrl+G widget to thenavicommand), and Alt+Z = zoxide
jump +gaf/grf/grsffuzzy git staging ported to pwsh. Core's functional change is
the file-picker rebind (zsh/bindings.zsh:Ctrl+F→Ctrl+T), with the announced key
updated everywhere it appears (zsh/fzf.zshwarning + comments, thecore-helpcheat
row inzsh/functions.zsh,tmux/scripts/tmux-cheat.sh,README.md, and the
test-core.shassertions); the pwsh half lands indotfiles-Windows. The six rows
moved toaligned(file-picker, atuin, dir-jump, session-picker, fuzzy-git, cheat) are
each enforced by ascripts/parity-check.shneedle.make audit+make parity-checkgreen. bootstrap-lib.shgains opt-in dry-run + tallies (lib/bootstrap-lib.sh) — the
shared provisioning scaffold now honorsBLIB_DRY=1:blib_link/blib_seed/
blib_link_core/blib_write_zshrc_loader/blib_set_login_shellPRINT what they
would do and change nothing — every mutation (symlink, backup, seed copy, chmod, the tpm
clone, the ssh perms, the.zshrcwrite, thechsh) is guarded — so an OS bootstrap's
--dry-runcan preview the whole plan instead of each repo hand-rolling it.blib_link
also gained an idempotent already-correct-link no-op and a missing-source skip; the two
inline git/sesh seed blocks are unified into a newblib_seed;BLIB_*counters +
blib_wire_summarygive a "N linked · M seeded · K backed up" footer. Backward
compatible —BLIB_DRYdefaults off and the non-dry path is byte-for-byte the prior
behaviour, so the already-adopted Fedora/Arch/Alpine/openSUSE/Gentoo/Kali bootstraps are
unaffected. This unblocks MacBook adopting the shared scaffold without losing its
--dry-run. Verified: dry run creates zero files; a real run wires all 25 links + 2
seeds; a re-run backs up nothing.- De-forked
update.zsh's per-shell path (zsh/update.zsh) — the throttle check
and the upgrade nudge randate +%sonce andsed -n Nptwice on every
interactive shell, three subprocess spawns (~1.7 ms each, measured) on the critical
path before the first prompt — the exact fork tax this stack's cached inits + deferred
plugins exist to avoid. Replaced with zsh builtins:$EPOCHSECONDS(azsh/datetime
param) for the clock and$(<file)+${(f)…}for the two-line cache read, removing
all three forks (~5 ms off a warm shell) with byte-identical behaviour and adate
fallback if the module is unavailable. Profiled withmake profile; the_pkgup_*
parse + nudge unit tests are unchanged and green. (A profile-led pivot: caching
tools.zsh'scommand -vprobes — only ~1.8 ms total, and a stale cache could hide a
newly-installed tool — was measured and rejected as not worth the footgun.) - Dropped
dotfiles-Debianfrom the documented fleet. The Debian OS-native
repo was only ever planned, never created, and is no longer being pursued — so
the fleet docs that named it as a real target were ahead of reality. Removed it
from the OS-native repo lists (README.md,CLAUDE.md,CONTRIBUTING.md,
SECURITY.md,PORTING-MATRIX.md), reframed it inscripts/os-repos.txtfrom
"planned" to a documented permanent absence (so it is not re-added), and dropped
it from theclaude-routinesfleet-clone loop. This also reconciles the
"nine-repo system" / "seven vendoring OS repos" counts, which the phantom Debian
entry had thrown off by one. Debian distro-family facts (thebat→batcat/
fd→fdfindrenames, Kali being Debian-family) are unaffected and retained. - Hardened the Track B module selector (
lib/bootstrap-lib.sh) — two fixes from
review of the fan-out PRs.blib_selectnow fails fast on an unknown flag (a
*)arm warns +exit 1instead of silently falling through without recording a
selection, so a caller typo can't make filtering appear to "work" while wiring
everything). Andblib_selected_notenow mirrorsblib_want's precedence: since
--onlyis an allowlist that wins when set, a co-present--skipis ignored — the
note reports a single active mode (onlywhen set, otherwiseskip) rather than
appending a misleading(skipped: …)suffix that was never applied. Backward
compatible — the single-selector and no-selector paths are unchanged.test-core.sh
Section G gains an unknown-flag rejection case, a--skip/both-set precedence check on
the note, and aBLIB_MODULESdrift guard pinning the production group list to the
tested oracle.make auditgreen.
Added
- Auto-published GitHub Releases on tag push (
.github/workflows/release.yml).
Pushing avX.Y.Ztag now publishes the GitHub Release automatically, finishing
themake release … && make tag PUSH=1path. The Release body is the curated
CHANGELOG.mdsection for that version (not a git-cliff commit digest — CHANGELOG
is the source-of-truth prose), and the job refuses to publish unless the tag is a
clean SemVer that matchescore.versionat the tagged commit and the section
exists. Uses the built-inGITHUB_TOKENvia the preinstalledghCLI — no PAT,
no third-party action. Re-running updates the existing Release's notes idempotently.
Also refreshedcliff.toml's header (the repo DOES git-tag now) and
RELEASE-STRATEGY.md(§5 checklist + §6) to match. - Release-automation: the three gaps
RELEASE-STRATEGY.mdflagged are now
wired. (1)sync-core.shstamps acore_tagfield (git describeof the
vendored commit) into each OS repo'score.lock, andfleet-drift.shshows it
in theRECORDEDcolumn — so the drift dashboard speaks in named releases, not
just SHAs (the SHA still drives the verdict; the tag is display only, and the
line is emitted only once Core actually carries a tag, keepingcore.lock
byte-identical to today until the first release). (2) A newaudit-archleg in
ci.ymlruns the shell-scope audit insidearchlinux:latest(rolling glibc
toolchain, newer than Ubuntu LTS), mirroring the existingaudit-alpine
(musl/busybox) leg — so Core is proven on both named container userlands before
a tag. (3)scripts/tag-release.sh+make tagfinish a release: commit
core.version+CHANGELOG, create the annotatedvX.Y.Ztag, re-run the
audit gate; pushing is opt-in (make tag PUSH=1).make release VERSION=X.Y.Z && make tagis now the whole cut end to end. RELEASE-STRATEGY.md— the cadence, tagging, and rollout policy. The repo
shipped all the release machinery (core.version,scripts/release.sh, the
sync-core.shfan-out gate,core.lockprovenance, the Monday freshness/drift
bots) but no documented policy tying it together. The new doc adds that: Core
as the sole versioned unit, a three-track cadence (continuous / weekly pin bumps
/ monthly + security tags), SemVer mapped to host blast-radius, why the
three-layer subtree model beatscommon/-plus-conditionals, and a canary-first
staged rollout so a Core release reaches one OS before all eight. Registered in the audit's
META_ALLOWLIST. Docs-only; no behavioral change.dotfiles-Defensejoins the fleet as the defensive (blue) Role. The
three-layer model always had room for a second Role besidedotfiles-Kali;
defender-authored capability (Sigma rules, Sysmon baselines, Zeek/Suricata
tuning, SIEM content, the hunt/triage workflow, a Dockerized detection lab) now
has its own repo instead of living as attack-paired notes in Kali's
PURPLE-TEAM.md. Core is vendored into it like any OS/Role repo, so the fleet
grows: nine → ten config repos, eight → nine machine repos, seven →
eight Core-vendoring targets. This sync carries the count + Role-layer wording
updates fleet-wide (README.md,CLAUDE.md,ARCHITECTURE.md,SECURITY.md,
CONTRIBUTING.md, the issue templates) and addsdotfiles-Defenseto
scripts/os-repos.txtsosync-core.shfans Core into it. Docs/data only; no
behavioral change to Core.bootstrap-lib.shgains--only/--skipmodule selection (lib/bootstrap-lib.sh)
— the shared scaffold can now wire a SUBSET of the Core groups:zsh nvim tmux git prompt tools. Newblib_select <--only|--skip> <csv>(validates a comma-separated
selector — empty / leading / trailing / doubled commas and unknown groups all abort),
blib_want <group>(consulted byblib_link_core,blib_link_os_layer,
blib_write_zshrc_loader,blib_set_login_shell), and `blib_sel...