Date: 2026-07-03 Scope: Full repository β dead code, duplication, unnecessary abstractions, performance, stale references. Method: Three exploration passes (nvim lua, zsh/shell, remaining packages) with grep-based cross-referencing. Every finding below carries its evidence; critical claims were re-verified by hand. No changes have been applied β this is a proposal document.
Decisions: All findings reviewed β 1β10 on 2026-07-03; 8 and 11β22 on 2026-07-05. Each carries a Decision line (β approved / β won't fix); executed findings also carry a Status line. Phases 1β5 (findings 4, 6, 8β15) were executed and committed on 2026-07-05; approved parts of 16β22 await execution.
Severity legend:
- π΄ Critical β actively hazardous or broken behavior
- π High β dead code / stale wiring, safe wins
- π‘ Medium β duplication worth consolidating
- π’ Low β polish, perf, thin abstractions
-
Where:
start.sh:4βfor dir in */; do stow -Rv "$dir"; done -
Evidence: During this audit an untracked
examples/dir (79 zero-byte files:app.py,App.tsx,Dockerfile, β¦) sat at repo root, absent from both.stowrcand.gitignore. A./start.shrun would have symlinked~/App.tsx,~/app.py, etc. into home. The directory has since been deleted, but the structural hazard remains: any stray root directory becomes a stow package. -
Suggested change: Make
start.shstow an explicit allowlist of packages, or at minimum add a guard (skip dirs not containing a dotfile/.configlayout). Alternatively adopt a convention: scratch dirs at root must be dot-prefixed or added to.stowrc+.gitignoreimmediately. -
How to test:
mkdir -p testjunk && touch testjunk/canary.txt ./start.sh # AFTER fix: no ~/canary.txt symlink appears rm -rf testjunk ~/canary.txt # cleanup
-
Risk: Allowlist must include every real package or one silently stops deploying β compare
ls -d */against the list when adding it. -
Decision: β Won't fix β
examples/was a test directory, already removed by hand. Nostart.shguard wanted.
-
Where:
zsh/zsh.d/fzf.zsh:9 -
Evidence:
if [[ "$" -eq 0 ]]; then
"$"is a literal string, not the arg count. In zsh arithmetic context a non-numeric string evaluates to 0, so the interactive fzf branch always runs, even when arguments are passed βfzf-rm somefilenever reachescommand rm "$@". Note this function is also unwired (see finding 4), so nothing currently hits the bug. -
Suggested change:
[[ "$#" -eq 0 ]]β or delete the function altogether per finding 4. -
How to test:
zsh -n zsh/zsh.d/fzf.zsh # syntax still valid zsh -ic 'touch /tmp/x; fzf-rm /tmp/x; [ ! -f /tmp/x ] && echo PASS'
-
Risk: None β currently unreachable dead-ish code.
-
Decision: β Approved β remove
fzf-rm(subsumed by finding 4: the whole file goes).
-
Where:
zsh/zsh.d/functions.zsh:204-221 -
Evidence: Function embeds an
ocp-apim-subscription-keyfor the Israel-Post API (marked#gitleaks:allow) plus a fixed street/house payload. Secret material committed to a dotfiles repo, loaded into every shell. -
Suggested change: Delete the function (one-off personal utility), or move key to an untracked env file (
~/.secrets.zshstyle) if still used. -
How to test:
grep -rn 'ocp-apim' zsh/ # should return nothing after fix gitleaks detect --no-banner # no allow-listed secret needed anymore
-
Risk: Losing the function; recreate on demand β the payload is hardcoded to one address anyway.
-
Decision: β Won't fix β key belongs to a public website's zipcode-lookup API, not personal or sensitive. Keep as-is.
-
Where:
zsh/zsh.d/fzf.zshβfzf-rm(line 8),fzf-man(19),fzf-eval(30),fzf-aliases-functions(34),fzf-git-status(45) -
Evidence: Zero hits for any of them in
zle -N,bindkey, oraliasacross the repo.fzf-rm/fzf-manwere clearly written to shadowrm/manbut nothing aliases them, so they're reachable only by typing the full function name. -
Suggested change: Delete, or wire up the ones you actually want (
alias rm=fzf-rmetc. / bindkey). -
How to test:
zsh -n zsh/zsh.d/fzf.zsh zsh -ic 'which fzf-man' # "not found" after deletion time zsh -ic exit # startup unchanged or marginally faster
-
Risk: None if genuinely unused; if muscle memory exists for typing them, keep + wire instead.
-
Decision: β Approved, expanded β delete
zsh/zsh.d/fzf.zshentirely (all five functions). Move the fzf loading it carries β[ -f ~/.fzf.zsh ] && source ~/.fzf.zshplus theFZF_DEFAULT_OPTS/FZF_CTRL_T_*/FZF_CTRL_R_OPTSexports β into.zshrc. -
Status: β Executed 2026-07-05 β file deleted, fzf block added to
.zshrc(own section before the zsh.d loop). Verified:fzf-man/fzf-rmunresolvable,FZF_CTRL_R_OPTSstill set, no bindkey conflicts inzsh.d,~/zsh.dis a folded stow symlink so no dangling link.
-
Where:
nvim/.config/nvim/lua/user/utils.lua:36βM.get_visual_selection_stay_in_visualnvim/.config/nvim/lua/user/git.lua:239βM.get_toplevel(async variant)nvim/.config/nvim/lua/user/init.lua:12β_G.put_text
-
Evidence: Full-tree grep for each name returns only the definition line. All callers of the git helper use
M.get_toplevel_sync(6 call sites: fzf.lua, actions.lua, gh-actions.lua, conflicts.lua, two run-buffer handlers).put_textis a:lua-prompt debug helper β keep only if you use it interactively. -
Suggested change: Delete all three (keep
put_textif used at the:luaprompt). -
How to test:
grep -rn 'get_visual_selection_stay_in_visual\|get_toplevel\b\|put_text' nvim/.config/nvim cd nvim/.config/nvim && make test # utils and git both have specs
-
Risk: Low.
utilsandgithave spec coverage; test suite catches accidental breakage. -
Decision: β Won't fix β keep all three.
put_textis used interactively at the:luaprompt; the other two are kept for possible future use.
-
Where:
zsh/zsh.d/kubectl.zsh:274-338(old, ~65 lines) vszsh/zsh.d/kubedebug-ng.zsh(414 lines, gum-based) -
Evidence: Two debug-pod launchers coexist.
completions.zsh:19still generates completion for the oldkubedebug, notkubedebug-ng. -
Suggested change: Delete the old function; update
completions.zsh:19to referencekubedebug-ng(or aliaskubedebug=kubedebug-ngfor muscle memory). -
How to test:
zsh -ic 'which kubedebug kubedebug-ng' # then in a live shell: kubedebug-ng against a test cluster/namespace
-
Risk: If the old one has flags/behavior the ng version lacks, diff them before deleting.
-
Decision: β Approved β delete old
kubedebugfromkubectl.zsh, renamekubedebug-ngβkubedebug(function and, if desired, thekubedebug-ng.zshfilename).completions.zsh:19then points at the right name automatically; verify it generates completion for the gum-based function. -
Status: β Executed 2026-07-05 β old function deleted from
kubectl.zsh; filegit mv'd tokubedebug.zshwith all self-references renamed. One deviation from the decision:kubedebugwas removed from the completion-generator list instead of kept β the new function takes no arguments, and the generator'skubedebug --helpprobe would launch the interactive gum menu. Stale generated~/.zsh/complete/_kubedebug(old-e/-p/-i/-sflags) deleted. Remaining manual test: runkubedebugagainst a live cluster.
-
Where:
automations/.local/bin/morning-routine.sh(95 lines, tracked) -
Evidence:
grep -rn morning-routineacross the repo returns only its own shebang-adjacent line. Only launchd plist inautomations/iscom.mosheavni.ghnotify.plist(drivesgh-notify.sh). No cron, no alias, no launchd job. README documentsgh-notify, nevermorning-routine. -
Suggested change: Delete, or add a plist if you meant to schedule it.
-
How to test:
launchctl list | grep -i morning # confirms nothing loaded stow -Rv automations && ls ~/.local/bin/ | grep morning # gone after fix
-
Risk: None visible β it was never scheduled.
-
Decision: β Won't fix β false positive. Invoked by a macOS Shortcut, an external reference repo greps cannot see. Keep.
-
Where:
ai/.claude/hooks/gsd-check-update-worker.jsandai/.claude/settings.json.bak(both untracked βai/.claude/hooks/is entirely gitignored; onlysettings.json,CLAUDE.md,.gitignoreare tracked there) -
Evidence: Live
settings.jsonreferences onlycaveman-*hooks. The.bak(dated May 4) references agsd-*hook suite that no longer exists except this one orphaned worker file, which nothing invokes. Local-machine cruft rather than repo dead code, but it lives inside the stowed~/.claudetree. -
Suggested change: Delete both (local
rmβ no commit involved). -
How to test:
grep -rn 'gsd-' ai/.claude/settings.json # empty β nothing references it # start a new claude session; hooks still function (caveman statusline etc.)
-
Risk: None β worker is invoked by nothing in current settings.
-
Decision: β Approved β delete all gsd relics (
gsd-check-update-worker.js,settings.json.bak, and anything elsegsd-*found underai/.claude/). Localrm, no commit involved. -
Status: β Resolved 2026-07-05 β files already gone;
find/grepforgsd/*.bakunderai/and~/.claude(symlink to it) return nothing.
-
Where: root
CLAUDE.md(AI config packages section + scope table line 94) and.cursor/rules/dotfiles-conventions.mdc:16 -
Evidence: Both claim
cursor/β stows~/AGENTS.mdand~/.cursor/rules/agents.mdc. Nocursor/directory exists; those symlinks are produced by theai/package (ai/AGENTS.md,ai/.cursor/rules/agents.mdc). -
Suggested change: Update both docs to attribute the symlinks to
ai/. -
How to test:
grep -rn 'cursor/' CLAUDE.md .cursor/rules/dotfiles-conventions.mdc | grep -v '\.cursor' ls -la ~/AGENTS.md # symlink target proves it comes from ai/
-
Risk: None β documentation-only. Stale docs actively mislead Claude/Cursor sessions, so this is high despite zero runtime impact.
-
Decision: β Approved β fix both docs to attribute the symlinks to
ai/. -
Status: β Executed 2026-07-05 β both docs updated (merged the
cursor/bullet intoai/, swapped the scope-table example tozsh/); verified~/AGENTS.md β .dotfiles/ai/AGENTS.md.
- Where:
nvim/.config/nvim/lua/user/options.lua:138-139(plus minor commented options at lines 23-24, 68, 123, 140) - Evidence:
lua/user/winbar.luadoes not exist; the only twouser.winbarmentions in the tree are these comment lines. Live winbar is set byuser.navic(navic.lua:113). - Suggested change: Delete the two winbar comment lines; sweep the other commented options while there.
- How to test:
nvim --headless '+quitall'starts clean; winbar still rendered by navic in a normal session. - Risk: None β comments.
- Decision: β Approved β delete the winbar comment lines.
- Status: β Executed 2026-07-05 β
options.lua:138-139removed;nvim --headless '+quitall'exits 0.
-
Where:
zsh/.zshrc:25(/usr/local/opt/curl/bin),:26(/usr/local/opt/ruby/bin),:34(/usr/local/opt/postgresql@15/bin) -
Evidence: Rest of config uses
/opt/homebrew. On this machine the/usr/local/optdirs likely don't exist β dead PATH entries scanned on every command lookup miss. -
Suggested change: Delete the three lines (or swap to
/opt/homebrew/opt/...if those kegs are installed). -
How to test:
ls /usr/local/opt/curl/bin /usr/local/opt/ruby/bin /usr/local/opt/postgresql@15/bin # confirm missing first zsh -ic 'which curl ruby psql' # still resolve after removal
-
Risk: Only if any keg genuinely lives in Intel prefix β the
lscheck settles it. -
Decision: β Approved β per PATH entry: if the keg exists under
/opt/homebrew/opt/..., switch the line to that path; if it doesn't exist there either, delete the line. -
Status: β Executed 2026-07-05 β curl switched to
/opt/homebrew/opt/curl/bin(keg exists,which curlresolves there); ruby and postgresql@15 lines deleted (kegs absent from both prefixes;rubyfalls back to/usr/bin/ruby,psqlwas already unresolvable before the change).
- Where:
zsh/zsh.d/functions.zsh:37-40 - Evidence: Calls
dialog -t ... -m ... --bannertext ... --textfield ...β flags not in standarddialog(1); looks like a removed third-party tool. No otherdialogreferences in the repo. - Suggested change: Delete, or rewrite with the actual escape sequence (
printf '\e]0;%s\a') / wezterm CLI. - How to test:
zsh -ic 'set-tab-title test'β currently errors; after rewrite, tab title changes. - Risk: None β currently broken anyway.
- Decision: β
Approved (revised) β initially rewritten with
printf '\e]0;%s\a', butterm-support.zshre-sets the title via aprecmdhook before every prompt, so any manual title is overwritten immediately (the olddialogversion had the same flaw). Function unused β deleted instead. - Status: β Executed 2026-07-05 β
set-tab-titleremoved fromfunctions.zsh; tab titles remain owned byterm-support.zshhooks.
-
Where:
updates.sh(218 lines) andcleanup.sh(267 lines) -
Evidence: Both define
brew_bundle_files(),log(), and near-identical tap-trustawkblocks (updates.sh:44-46/cleanup.sh:48-51). Divergence risk: fix a bug in one, forget the other. -
Suggested change: Extract a small sourced lib (e.g.
scripts/lib.sh, dot-prefixed or.stowrc-ignored) withlog,brew_bundle_files, tap parsing; source from both. -
How to test:
shellcheck updates.sh cleanup.sh scripts/lib.sh ./updates.sh # dry-run friendly sections first; same output as before extraction ./cleanup.sh # same list of removal candidates as before
-
Risk: Medium β these scripts mutate installed packages. Diff their output (list phases) before/after, don't just eyeball the code.
-
Decision: β Approved β extract the shared lib and source it from both scripts.
-
Status: β Executed 2026-07-05 β created
.scripts/lib.sh(dot-prefixed sostart.sh's*/glob never stows it):DOTFILES/CORP_BREWFILEdefaults,log,brew_bundle_files,brewfile_taps,trust_brewfile_taps. Both scripts source it; the tap-trust awk blocks are gone from both. Also removedeach_line()fromupdates.shβ defined but never called (audit miss). Verified:bash -n+shellcheckclean on all three;./cleanup.sh -doutput byte-identical before/after (sole diff line was brew's JSON-API cache-refresh notice on the first run). Pre-existing bug surfaced and fixed in a follow-up commit: in dry-run modebrew bundle cleanup(without--force) exits 1 when it finds candidates, andset -ekilled the script βcleanup.sh -dnever reached the asdf/npm/gh sections. Fixed with|| trueon the dry-run branch;cleanup.sh -dnow runs all sections and exits 0.
-
Where:
zsh/zsh.d/aliases.zsh -
Evidence:
:45gst='git status'β identical to ohmyzsh git plugin'sgst(plugins load first, zsh.d re-defines same thing).:46git_current_branch=...β shadows ohmyzsh's function of the same name with an alias.:47gb=...β silently replaces ohmyzsh'sgb='git branch'with an fzf-checkout pipeline (behavior change hiding behind a plugin name).:18-19dotfiles/dotbothcd ~/.dotfiles;:31-32lv/lvimidentical;:84-85globalSa/Srtbyte-identical.
-
Suggested change: Drop
gst; rename the fzf checkout to something non-colliding (e.g.gbf) or keep the override but comment it as deliberate; keep one of each identical pair. -
How to test:
zsh -ic 'type gst; type gb; type git_current_branch' # shows final winner + origin
-
Risk: Muscle-memory only. The
gbdecision is preference β flag, not mandate. -
Decision: β Approved, expanded β remove the ohmyzsh git plugin entirely (
.zsh_plugins.txt:11ohmyzsh/ohmyzsh path:plugins/git) and port only the essential aliases intoaliases.zsh:gpom,gmom,gl,gp,gcam,gcmsg,gpsup, plus suggested extras βgco(checkout),gcb(checkout -b),gd(diff),gaa(add --all),gpf(push --force-with-lease). Note:gpsup,gpom,gmomdepend on ohmyzsh'sgit_current_branch/git_main_branchhelper functions β port those two functions too (which also resolves thegit_current_branchalias-shadowing item above). Then dedupe: drop the redundantgstquestion (it becomes the only definition), keep the fzfgb(no longer collides), keep one of each identical alias pair (dotfiles/dot,lv/lvim,Sa/Srt). -
Status: β Executed 2026-07-05 β plugin line removed from
.zsh_plugins.txt; 12 aliases inaliases.zsh(gst gl gp gpf gaa gd gco gcb gcam gcmsg gpsup+ existing fzfgb);git_current_branchported as a function intofunctions.zsh(the shadowing alias ataliases.zsh:46removed). Notes:gpomdoes not exist in ohmyzsh and resolved to nothing even before this change;gprom,gmom, and thegit_main_branchhelper were ported first, then dropped on review (not actually used).gpfhardcodes the modern--force-with-lease --force-if-includesvariant. Deduped: keptdot,lv,Srt; droppeddotfiles,lvim,Sa. Verified in fresh shell: all aliases resolve, helper is a function fromzsh.d/functions.zsh, plugin-only aliases (grbm,glog,gsta) gone.
- Where:
GIT_DEFAULT_ORGdefaultmosheavniinzsh/zsh.d/functions.zsh:73andzsh/zsh.d/ghc.zsh:8; AWS account-id lookup (aws sts get-caller-identity | jq -r .Account) infunctions.zsh:64(ecr-login) and:168(docker_copy_between_regions) - Suggested change: Export
GIT_DEFAULT_ORGonce (e.g. in.zshrcor anenv.zsh); extractaws_account_id()helper. - How to test:
zsh -ic 'ghc <repo>'andzsh -ic 'ecr-login'behave as before. - Risk: Low.
- Decision: β
Approved β export
GIT_DEFAULT_ORGonce in.zshrc; extract theaws_account_id()helper. - Status: β Executed 2026-07-05 β
export GIT_DEFAULT_ORG=mosheavniadded to.zshrc; inline defaults removed fromclone()andghc().aws_account_id()added tofunctions.zsh(uses--query Account --output text, dropping the jq dependency) and used by bothecr-loginanddocker_copy_between_regions.
-
Where:
- q-to-close mapping implemented inline 4Γ:
lua/user/autocommands.lua:91,lua/user/init.lua:183,lua/user/input.lua:515,ftplugin/qf.lua lua/user/keymaps.lua:199-218: four near-identical copy-path closures (<leader>cfp/cfa/cfd/cfn) differing only inexpand()flag + message
- q-to-close mapping implemented inline 4Γ:
-
Suggested change: Small
utils.map_q_close(buf)helper for the first; table-driven loop for the second (same file already uses this pattern at lines 127-136 and 314-323). -
How to test:
cd nvim/.config/nvim && make test # manual: open qf window / parse_cert float / input list β q closes each # manual: <leader>cfp/cfa/cfd/cfn each yank correct path variant (:echo @+)
-
Risk: Low; keymaps has behavioral surface but the transforms are mechanical.
-
Decision: β Approved β extract the q-to-close helper and table-drive the copy-path closures.
-
Status: β Executed 2026-07-05 (phase 8) β copy-path closures table-driven (
cfp/cfa/cfd/cfnfrom one spec loop; verified headless: all four descs present,<leader>cfnyanks file name to+). Theutils.map_q_closehelper was implemented then reverted mid-phase on user request β the four q-close sites differ enough (plain close vs custom callbacks) that the abstraction hid more than it saved; inline mappings stay.
- Where: root
CLAUDE.md(Β§Architecture),.cursor/rules/dotfiles-conventions.mdc,README.mdβ same stow-package table restated in all three. - Suggested change: Pick one canonical home (CLAUDE.md, since both AI tools read it); others link to it. Note:
ai/AGENTS.mdvsai/.cursor/rules/agents.mdcduplication is by design (both written from one remote bysync-ai-config.sh) β leave it. - How to test: Docs-only; verify each file still parses/renders and cross-links resolve.
- Risk: None.
- Decision: β
Approved β CLAUDE.md becomes the canonical stow-layout doc; README and
.cursor/rules/dotfiles-conventions.mdclink to it instead of restating. - Status: β Executed 2026-07-06 (phase 9) β CLAUDE.md untouched (already canonical: layout bullets, scope table, AI config packages).
.cursor/rules/dotfiles-conventions.mdcreduced to a pointer (@CLAUDE.md, Architecture βΈ Stow Package Structure) β its unique facts (graphify-out/, agents.mdc mapping) were already covered by the CLAUDE.md table. README had meanwhile stopped restating the table; added a one-line link to CLAUDE.md above Usage.
-
Where:
nvim/.config/nvim/lua/user/pack/init.lua:31βrequire 'plugins.kubectl'()sits in the eager block, before thevim.scheduledeferred block (line 33). Enablesauto_refresh+ FileType autocmds in every session. -
Suggested change: Move into the deferred block, or lazy-init on first
:Kubectlinvocation β it's the only feature plugin not deferred, so eagerness may be deliberate; verify before moving. -
How to test:
nvim --startuptime /tmp/st.log +q && grep -i kubectl /tmp/st.log # before/after delta # manual: :Kubectl still works after the move
-
Risk: Low; if a keymap fires before deferred load, add a stub.
-
Decision: β Approved with a hard constraint β the
k8szsh alias (kubectl.zsh:189,nvim +"lua require(\"kubectl\").open()") is the primary entry point and is used more often than opening the plugin from inside nvim.+cmdexecutes beforevim.schedulecallbacks run, so simply moving setup into the deferred block breaks that alias. Defer only in a way thatopen()still works β e.g., lazy-init insideopen()/:Kubectl(run setup on first use), or leave eager if that proves messy. Must verify thek8salias end-to-end after the change. -
Status: β Executed 2026-07-05 (phase 8) β
plugins/kubectl.luanow registers only:KubectlOpen+ the menu action at startup; fullsetup()(plugin load, autocmds, auto_refresh) runs on first:KubectlOpen, guarded against re-entry. Thek8salias changed tonvim +KubectlOpenβ the command exists before+cmdexecutes (registered in the eager block), so the alias survives the deferral. Verified headless:exists(':KubectlOpen')= 2 at startup; startup pays 0.09ms module load (was full setup);:KubectlOpenruns clean and registers the 4kubectl_userautocmds. Live-cluster end-to-endk8scheck left to manual.
-
Where:
zsh/zsh.d/completions.zsh:22(bashcompinit),:35-37(threecomplete -C terraform/terragrunt/aws_completer) -
Evidence: Runs every shell start; the same file already implements a lazy
unfunctionpattern for kubectl/helm/etc. (lines 41-94). -
Suggested change: Convert the three to the existing lazy pattern; drop
bashcompinitif nothing else needs it. Also:19listsab(apachebench) in completion-generator targets β not installed/used anywhere; remove alongside thekubedebugfix (finding 6). -
How to test:
time zsh -ic exit # startup delta zsh -i β terraform <TAB>, aws <TAB> # completion still works on first use
-
Risk: First-tab-press latency instead of startup cost. Fair trade.
-
Decision: β Approved β convert terraform/terragrunt/aws to the existing lazy pattern (note: the lazy wrappers still call
complete -C, which needsbashcompinitβ load it lazily too or keep it if that's the simpler path); removeabfrom the completion-generator list. -
Status: β Executed 2026-07-05 (phase 7) β lazy at the completion layer, not the command layer:
compdef _lazy_bash_complete terraform terragrunt awsregisters a stub at startup; the first TAB loadsbashcompinit, re-registers the realcomplete -Ccompleter, and serves that same TAB via_bash_complete. (First attempt wrapped the commands, which only registered completion after running the tool once per session β broken UX, caught by user, rewritten.) Eagerbashcompinit+ three eagercompletelines removed;abdropped from the generator list. Verified with zpty-driven real TAB presses: terraform offersapply/destroy/workspace/β¦,aws sofferss3api/sts/β¦, terragrunt offersplan.
- Where / what:
zsh/zsh.d/functions.zsh:121-123docker_build_push=docker_build --push $*;:108-110grl=grep -rl $* .;:98-100gitcd=cd $(git rev-parse --show-toplevel);aliases.zsh:17dc='cd 'zsh/.bin/vdiffβ one-line nvim wrapper, zero references (kdiffby contrast is load-bearing:.zshrc:88KUBECTL_EXTERNAL_DIFF)aliases.zsh:26-29βvim/vi/v/sudoeditall βnvim;sudoedit=nvimsilently drops the privileged-edit semantics (realsudoeditcopies to temp, edits unprivileged, writes back as root)zsh/zsh.d/functions.zsh:223-260matrixβ screensaver toy in startup path
- Suggested change: Keep wrappers you actually type (they're muscle memory, cost β 0); delete
vdiffandmatrix; remove thesudoeditalias β that one changes behavior, not just spelling. - How to test:
zsh -ic 'which vdiff'not found;sudoedit /etc/hostsuses real sudoedit flow again. - Risk:
sudoeditalias removal is the only behavior change, and it restores correct behavior. - Decision: β
Partial β delete
vdiffand remove thesudoeditalias (restore real privileged-edit semantics). Keep everything else (matrix,grl,gitcd,docker_build_push,dc). - Status: β Executed 2026-07-05 (phase 6) β
zsh/.bin/vdiffdeleted;sudoeditalias removed fromaliases.zsh. Verified:vdiffunresolvable,sudoeditno longer aliased in a fresh shell.
- Where:
nvim/.config/nvim/lua/user/keymaps.lua:164-177β_G.op.diffput/diffgetroute a single ex-command throughoperatorfunc+g@l - Evidence: Callbacks take no motion and ignore the region β the operator machinery adds nothing unless it's there to make the mapping dot-repeatable.
- Suggested change: If dot-repeat is the point, add a comment saying so; otherwise flatten to plain
<cmd>diffput<cr>mappings. - How to test: In a diff (
nvim -d a b): mapping still puts/gets hunk; press.β if repeat worked before and matters, keep the indirection. - Risk: Losing dot-repeat if that was intentional. Check before flattening.
- Decision: β
Keep β the indirection is deliberately there for dot-repeat, and
operatorfunc+g@lis the canonical dependency-free idiom for making an ex-command mapping dot-repeatable (the only alternative is the vim-repeat plugin). Action: add a comment stating the intent so the next audit doesn't flag it. - Status: β Executed 2026-07-05 (phase 8) β dot-repeat intent comment added above the diffput/diffget mappings in
keymaps.lua.
| Item | Where | Note |
|---|---|---|
Redundant .stowrc ignores |
.stowrc β Brewfile, Brewfile.lock.json, BACKUP.md, snippets.xml, start.sh, .github |
Root files are never stowed (start.sh stows dirs only). Harmless noise; the load-bearing ignores are requirements.txt, install-skills.sh, sync-ai-config.sh, graphify-out. Verify with stow -nv <pkg> before pruning. |
| Version-pinned plugin path in statusline | ai/.claude/settings.json |
Hard-codes plugins/cache/caveman/caveman/ef6050c5e184/... β hash changes on plugin update, silently breaking statusline. Point at a stable path or resolve dynamically. |
gg-shield-action@master |
.github/workflows/gitguardian.yml |
Moving ref; pin to a tag/SHA. |
teams-call stale |
zsh/.bin/teams-call:5-6,35 |
Hardcodes one user + @company.com placeholder; bound to Alt-t via teams.zsh:12. Fix or delete both. |
| Former-employer ECR path | zsh/zsh.d/functions.zsh:171-172 |
docker_copy_between_regions hardcodes spotinst-production/. Parameterize or delete. |
| Plugin review | .zsh_plugins.txt β agkozak/zhooks, peterhurford/git-it-on.zsh |
zhooks is a debugging tool loaded permanently; confirm still wanted. |
| Empty dir | ai/.claude/agents/ |
Empty, gitignored, runtime-managed β safe to leave or remove. |
mwatch leftovers |
zsh/zsh.d/functions.zsh:48-49 |
Commented-out log lines. |
kns/ctx alias deps |
zsh/zsh.d/kubectl.zsh:176-177 |
Depend on kubens/kubectx binaries β confirm they're in Brewfile. |
| Personal PATH | zsh/.zshrc:40-44 |
~/Repos/moshe/devops-scripts/* loop β existence-guarded, but confirm still relevant. |
-
Decision: β Partial β six items approved, keep the rest:
teams-callβ remove the script (zsh/.bin/teams-call) and its related files (zsh/zsh.d/teams.zshwith the Alt-t widget/binding).docker_copy_between_regionsβ parameterize the hardcodedspotinst-production/ECR repo prefix..zsh_plugins.txtβ removeagkozak/zhooksandpeterhurford/git-it-on.zsh.- Remove the empty
ai/.claude/agents/directory. - Remove the commented-out log lines in
mwatch(functions.zsh). - Confirm
kubectxis in the Brewfile (it shipskubenstoo, covering thekns/ctxalias deps); add it if missing.
Kept as-is: redundant
.stowrcignores, version-pinned statusline plugin path,gg-shield-action@master, personal devops-scripts PATH loop. -
Status: β Executed 2026-07-05 (phase 6) β (1)
teams-call+teams.zshdeleted; Alt-t unbound, widget gone. (2)docker_copy_between_regionstakes-p REPO_PREFIX(default$ECR_REPO_PREFIX, empty = no prefix segment) βspotinst-productionscrubbed entirely, plus a stalespotinst/repocomment example inclone(). (3)zhooks+git-it-on.zshremoved from.zsh_plugins.txt; neither loads in a fresh shell. (4)ai/.claude/agents/already gone (same post-audit cleanup as finding 8). (5)mwatchcomment lines removed. (6)kubectxconfirmed in Brewfile line 55 (shipskubens) β nothing to add. Startup 0.04s.
- nvim lock vs specs: all 45 plugins in
nvim-pack-lock.jsonmap to live specs (SchemaStore added viaafter/lsp/*.lua; kubectl.nvim is a dev-path plugin). No orphaned plugin references. - Tests β modules: every
lua/tests/*_spec.luamaps to a real module; no orphan specs. - run-buffer handlers: all 12 registered in
handlers/init.lua. github-releases.txtvs Brewfile: no overlap (nektos/actintentionally GH-release-installed viaupdates.sh:128).- CI workflows:
lint.yml,ci.yml,gitguardian.ymlall wired; README badges resolve. (Only nit: the@masterpin above, andlint.ymlcopies lint configs out ofnvim/β coupling worth knowing, not worth changing.)
Executed 2026-07-05 (one commit per phase):
- Phase 1 β zero-risk deletions & docs: findings 8, 9, 10 (
d72a9465) - Phase 2 β small zsh fixes: findings 4, 11, 12, 15 (
96102d9d) - Phase 3 β kubedebug rename: finding 6 (
7d6683e2) β manual live-cluster test still pending - Phase 4 β git plugin migration: finding 14 (
62ffbee8) - Phase 5 β script lib extraction: finding 13 (
bdb44d33+ dry-run bugfix3277b17a)
Remaining (approved, not yet executed):
- Phase 6 β zsh/file deletions & small fixes (20 partial + 22 partial): delete
vdiff; removesudoeditalias; removeteams-call+teams.zsh; parameterizespotinst-production/; dropzhooks+git-it-on.zshplugins; remove emptyai/.claude/agents/; cleanmwatchcomment lines; confirmkubectxin Brewfile. Verify:zsh -neach file, fresh-shell alias/function checks,time zsh -ic exit. - Phase 7 β lazy completions (19): terraform/terragrunt/aws to the lazy pattern (mind
bashcompinitβ the wrappers still need it); dropabfrom the generator list. Verify: startup delta + first-tab completion for all three tools. - Phase 8 β nvim (16 + 18 + 21): q-to-close helper + table-driven copy-path closures; kubectl.nvim deferral honoring the
k8s-alias constraint (+cmdruns beforevim.scheduleβ lazy-init insideopen()or stay eager); dot-repeat intent comment on the diffput/diffget mappings. Verify:make test,nvim --headless '+quitall',k8salias end-to-end, manual keymap checks. - Phase 9 β docs dedup (17): CLAUDE.md canonical; README +
.cursor/rules/dotfiles-conventions.mdclink instead of restating. Verify: rendering + links.
Global regression check after any zsh phase: zsh -n each touched file, time zsh -ic exit vs baseline, pre-commit run --all-files, make test-zsh. After any nvim phase: make test-nvim (repo root) plus nvim --headless '+quitall'.