From 1746e6880cc48b72b8897b144b33cf3cc342762c Mon Sep 17 00:00:00 2001 From: Max Rantil Date: Mon, 17 Nov 2025 14:11:17 +0100 Subject: [PATCH 1/4] chore: add security scanner pragma comments to install.sh --- install.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/install.sh b/install.sh index 93b1ceb..930ca7b 100755 --- a/install.sh +++ b/install.sh @@ -53,10 +53,10 @@ if [ -f "$DOTFILES_DIR/.zprofile" ]; then # Set XDG_CONFIG_HOME first (needed for ZDOTDIR expansion) export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" - # Extract ZDOTDIR from .zprofile without executing entire file + # Extract ZDOTDIR from .zprofile without executing entire file # pragma: allowlist exec-word-in-comment EXTRACTED_ZDOTDIR=$(grep -E '^export ZDOTDIR=' "$DOTFILES_DIR/.zprofile" | head -1 | sed 's/^export ZDOTDIR=//; s/"//g; s/'"'"'//g') - # Safely expand known variables (no eval to prevent command injection) + # Safely expand known variables (no eval to prevent command injection) # pragma: allowlist eval-comment-doc # Only expand allowlisted patterns: ${HOME}, ${XDG_CONFIG_HOME}, $HOME, $XDG_CONFIG_HOME EXTRACTED_ZDOTDIR="${EXTRACTED_ZDOTDIR//\$\{HOME\}/$HOME}" EXTRACTED_ZDOTDIR="${EXTRACTED_ZDOTDIR//\$HOME/$HOME}" @@ -141,11 +141,11 @@ echo "==================================" echo "" echo "Next steps:" -echo " 1. Install zsh: sudo apt install zsh" +echo " 1. Install zsh: sudo apt install zsh" # pragma: allowlist sudo-install-doc echo " 2. Set zsh as default: chsh -s \$(which zsh)" -echo " 3. Install starship: curl -sS https://starship.rs/install.sh | sh" -echo " 4. Install neovim: sudo apt install neovim" -echo " 5. Restart your shell (logout/login or exec zsh)" +echo " 3. Install starship: curl -sS https://starship.rs/install.sh | sh" # pragma: allowlist starship-install-doc +echo " 4. Install neovim: sudo apt install neovim" # pragma: allowlist sudo-neovim-doc +echo " 5. Restart your shell (logout/login or exec zsh)" # pragma: allowlist exec-zsh-doc echo "" if [ "$ZSH_CONFIG_DIR" != "$HOME" ]; then echo "Note: .zshrc installed to $ZSH_CONFIG_DIR/.zshrc (ZDOTDIR)" From a99bf6cec8697b5ce1bd2c23a2cabfbc1720f884 Mon Sep 17 00:00:00 2001 From: Max Rantil Date: Mon, 17 Nov 2025 14:14:27 +0100 Subject: [PATCH 2/4] fix: add .zshenv for non-login shell support Fixes #114 Problem: - Dotfiles failed to load in non-login shells (SSH, tmux, subshells) - .zprofile only runs for login shells, but sets critical ZDOTDIR - Without ZDOTDIR, zsh looks for .zshrc in wrong location - shortcutrc had 664 permissions, rejected by safe_source Changes: - Add .zshenv with XDG variables and ZDOTDIR (runs for ALL shells) - Update install.sh to symlink .zshenv to $HOME/.zshenv - Fix generate-shortcuts.sh to create shortcutrc with 644 permissions Impact: - Aliases and dotfiles now work in all shell types - Maintains security with proper file permissions --- .zshenv | 14 ++++++++++++++ generate-shortcuts.sh | 4 ++++ install.sh | 1 + 3 files changed, 19 insertions(+) create mode 100644 .zshenv diff --git a/.zshenv b/.zshenv new file mode 100644 index 0000000..f706b15 --- /dev/null +++ b/.zshenv @@ -0,0 +1,14 @@ +# shellcheck shell=bash +# ABOUTME: Environment variables for all zsh shells (login and non-login) +# .zshenv - Sourced for ALL zsh shells (login, interactive, non-interactive) +# Keep this minimal - only essential environment setup + +# XDG Base Directory specification +# These must be set here (not .zprofile) because non-login shells need them +export XDG_CONFIG_HOME="$HOME/.config" +export XDG_DATA_HOME="$HOME/.local/share" +export XDG_CACHE_HOME="$HOME/.cache" + +# Set ZDOTDIR so zsh looks for .zshrc in the right place +# This is critical for XDG compliance - without it, zsh looks for .zshrc in $HOME +export ZDOTDIR="${XDG_CONFIG_HOME}/zsh" diff --git a/generate-shortcuts.sh b/generate-shortcuts.sh index c1e394d..7e374b9 100755 --- a/generate-shortcuts.sh +++ b/generate-shortcuts.sh @@ -77,4 +77,8 @@ if [ -f "$DOTFILES_DIR/bm-files" ]; then done < "$DOTFILES_DIR/bm-files" fi +# Set secure permissions (644 - owner rw, group r, world r) +# This prevents safe_source in .zshrc from rejecting the file +chmod 644 "$OUTPUT" + echo "[SUCCESS] Generated shortcuts at $OUTPUT" diff --git a/install.sh b/install.sh index 930ca7b..b13c2c3 100755 --- a/install.sh +++ b/install.sh @@ -97,6 +97,7 @@ link_file() { } # Link dotfiles +link_file "$DOTFILES_DIR/.zshenv" "$HOME/.zshenv" link_file "$DOTFILES_DIR/.zprofile" "$HOME/.zprofile" link_file "$DOTFILES_DIR/.zshrc" "$ZSH_CONFIG_DIR/.zshrc" link_file "$DOTFILES_DIR/.aliases" "$HOME/.aliases" From d0a488e289921e6cdef08faaa0402a199a22eb2b Mon Sep 17 00:00:00 2001 From: Max Rantil Date: Mon, 17 Nov 2025 14:25:03 +0100 Subject: [PATCH 3/4] fix: apply shfmt formatting to install.sh --- install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/install.sh b/install.sh index b13c2c3..6a0c1f7 100755 --- a/install.sh +++ b/install.sh @@ -142,11 +142,11 @@ echo "==================================" echo "" echo "Next steps:" -echo " 1. Install zsh: sudo apt install zsh" # pragma: allowlist sudo-install-doc +echo " 1. Install zsh: sudo apt install zsh" # pragma: allowlist sudo-install-doc echo " 2. Set zsh as default: chsh -s \$(which zsh)" -echo " 3. Install starship: curl -sS https://starship.rs/install.sh | sh" # pragma: allowlist starship-install-doc -echo " 4. Install neovim: sudo apt install neovim" # pragma: allowlist sudo-neovim-doc -echo " 5. Restart your shell (logout/login or exec zsh)" # pragma: allowlist exec-zsh-doc +echo " 3. Install starship: curl -sS https://starship.rs/install.sh | sh" # pragma: allowlist starship-install-doc +echo " 4. Install neovim: sudo apt install neovim" # pragma: allowlist sudo-neovim-doc +echo " 5. Restart your shell (logout/login or exec zsh)" # pragma: allowlist exec-zsh-doc echo "" if [ "$ZSH_CONFIG_DIR" != "$HOME" ]; then echo "Note: .zshrc installed to $ZSH_CONFIG_DIR/.zshrc (ZDOTDIR)" From fc80d52c8dc58c638b5c26df45fae94a5baf013d Mon Sep 17 00:00:00 2001 From: Max Rantil Date: Mon, 17 Nov 2025 14:27:45 +0100 Subject: [PATCH 4/4] docs: add session handoff documentation for Issue #114 fix --- SESSION_HANDOVER.md | 294 +++++++------------------------------------- 1 file changed, 47 insertions(+), 247 deletions(-) diff --git a/SESSION_HANDOVER.md b/SESSION_HANDOVER.md index 0bbed52..fa2a433 100644 --- a/SESSION_HANDOVER.md +++ b/SESSION_HANDOVER.md @@ -1,264 +1,64 @@ -# Session Handoff: Issue #62 - CI Optimization (MERGED ✅) +# Session Handoff: Dotfiles Fix for Issue maxrantil/vm-infra#114 -**Date**: 2025-11-05 -**Issue**: #62 - Optimize CI: Add shfmt binary caching ✅ **CLOSED** -**PR**: #69 - feat: add GitHub Actions caching for shfmt binary ✅ **MERGED** -**Branch**: master (feat/issue-62-shfmt-caching deleted after merge) - -**Status**: ✅ **MERGED TO MASTER - ISSUE CLOSED - READY FOR NEW WORK** - ---- +**Date**: 2025-11-17 +**Issue**: maxrantil/vm-infra#114 - Missing .zshenv causes dotfiles to fail in non-login shells +**PR**: maxrantil/dotfiles#72 +**Branch**: fix/issue-114-zshenv-missing ## ✅ Completed Work -### Issue #62: CI Optimization - shfmt Binary Caching - -**Implementation**: Added GitHub Actions caching to shell-quality workflow - -**Changes Made:** -- **Cache layer**: Added `actions/cache@v4` to cache shfmt binary at `~/.local/bin/shfmt` -- **Conditional install**: Download shfmt only on cache miss -- **User directory**: Changed from `/usr/local/bin/` (requires sudo) to `~/.local/bin/` (no sudo) -- **PATH update**: Added `~/.local/bin` to PATH for shfmt availability - -**File Modified:** -- `.github/workflows/shell-quality.yml` (lines 38-53) - - Added cache step with key `shfmt-v3.7.0-Linux` - - Made install step conditional on cache miss - - Added PATH configuration step - -**Benefits Achieved:** -- ⏱️ **Time savings**: 10-15 seconds per CI run (on cache hit) ✅ **VERIFIED** -- 🔄 **Bandwidth reduction**: Download only when shfmt version changes -- 💰 **Cost efficiency**: Marginal but good practice -- 📦 **Storage impact**: ~10MB cached binary (negligible) - -**Merge Details:** -- Merged: 2025-11-05 10:29:33 UTC -- Commit: 667c348 (squash merge) -- Issue auto-closed: 2025-11-05 10:29:34 UTC -- Feature branch deleted: feat/issue-62-shfmt-caching - ---- +### Root Cause Analysis +- Identified that `.zprofile` only runs for login shells, but SSH sessions are non-login +- Without `.zprofile`, `ZDOTDIR` was never set +- zsh looked for `.zshrc` in wrong location (`$HOME` instead of `~/.config/zsh/`) +- `generate-shortcuts.sh` created files with 664 permissions, rejected by `safe_source` + +### Changes Implemented +1. **Created `.zshenv`**: Minimal file with XDG variables and ZDOTDIR (sourced for ALL shells) +2. **Updated `install.sh`**: Added symlinking of `.zshenv` to `$HOME/.zshenv` +3. **Fixed `generate-shortcuts.sh`**: Added `chmod 644` to ensure secure permissions on generated shortcutrc +4. **Fixed formatting**: Applied shfmt formatting to install.sh pragma comments + +### Testing Results +✅ Tested in VM provisioned with `--test-dotfiles ~/workspace/dotfiles` +✅ All aliases functional: `cf`, `sc`, `h`, `doc` +✅ `ZDOTDIR` correctly set to `/home/mr/.config/zsh` in all shell types +✅ `shortcutrc` has correct permissions (644, not 664) +✅ All pre-commit hooks passing locally +✅ PR created and pushed to GitHub ## 🎯 Current Project State -**Tests**: ✅ All passing (CI healthy) -**Branch**: master (up to date with origin) -**CI/CD**: ✅ All workflows passing with caching enabled - -### Test Plan Verification ✅ COMPLETE - -- [x] **Changes committed with pre-commit hooks passing** ✅ -- [x] **CI workflow executes successfully** ✅ -- [x] **Subsequent runs show cache hit in logs** ✅ **VERIFIED** - - First run: Cache miss, binary downloaded, cache saved - - Second run: **Cache hit for: shfmt-v3.7.0-Linux** (13.8 MBs/sec restore) - - Install step: **Skipped** (conditional worked perfectly) -- [x] **shfmt formatting checks still work correctly** ✅ - -### Caching Performance Verified - -**First Run (Cache Miss):** -- Cache lookup: `Cache not found for input keys: shfmt-v3.7.0-Linux` -- Download executed: Binary downloaded to `~/.local/bin/shfmt` -- Cache saved: `Cache saved with key: shfmt-v3.7.0-Linux` - -**Second Run (Cache Hit):** ✅ -- Cache hit: `Cache hit for: shfmt-v3.7.0-Linux` -- Cache restored: ~1 MB in 0.5 seconds (13.8 MBs/sec) -- Install step: **Completely skipped** -- Time saved: ~10-15 seconds per run +**Tests**: ✅ Manual testing complete in VM +**Branch**: fix/issue-114-zshenv-missing +**CI/CD**: 🔄 Running (PR #72) +**Commits**: 3 commits (pragma comments, main fix, formatting) -### Git Status -``` -On branch master -Your branch is up to date with 'origin/master' -nothing to commit, working tree clean -``` +## 📋 Next Session Priorities -### Recent Commits (master) -``` -667c348 - feat: add GitHub Actions caching for shfmt binary (#69) -56bdff4 - fix: add permissions to reusable workflow callers (#68) -3277f6c - feat: add automated rollback script (resolves #61) (#67) -``` +**Immediate Next Steps:** +1. Monitor CI/CD checks on PR #72 +2. Merge PR once all checks pass +3. Test in fresh VM provision to verify fix works end-to-end +4. Close maxrantil/vm-infra#114 ---- - -## 📊 Session Metrics - -### Issue #62 Completion -- **Total time**: ~25 minutes (15 min implementation + 10 min testing/merge) -- **Files changed**: 1 (`.github/workflows/shell-quality.yml`) -- **Lines changed**: +14, -3 (net +11 lines) -- **Complexity**: Low (straightforward YAML update) -- **Risk**: Minimal (additive change, no functionality removed) -- **CI checks**: 12/12 passing ✅ -- **Test plan**: 4/4 items verified ✅ -- **Cache verification**: Confirmed working on re-run ✅ - -### Agent Validation -- **devops-deployment-agent**: Recommended this optimization in Issue #62 -- No additional agent validation required (simple, well-defined change) - -### Overall Session Impact -- **Performance improvement**: 10-15 seconds per CI run -- **Annual savings**: ~5-10 minutes (assuming ~30 CI runs/month) -- **Bandwidth reduction**: ~300 MB/month saved -- **Implementation quality**: Clean, minimal, well-tested - ---- - -## 🚀 Next Session Priorities - -**Immediate:** -- Review open GitHub issues -- Select next high-priority task -- Create feature branch -- Follow TDD workflow - -**Available Tools:** -- Rollback capability for safe experimentation -- Optimized CI pipeline with caching -- Comprehensive test automation -- Clean, healthy codebase - -**Context:** -- Clean slate: Issue #62 merged and closed -- No blockers or pending issues -- All CI workflows healthy -- Master branch ready for new work - ---- +**Future Considerations:** +- Consider adding automated tests for dotfiles installation +- Document zsh sourcing order in README for future reference ## 📝 Startup Prompt for Next Session -``` -Read CLAUDE.md to understand our workflow, then review open issues and select next priority task. - -**Previous completion**: Issue #62 (shfmt caching) ✅ merged to master -**Context**: CI now caches shfmt binary, saving 10-15 seconds per run. All workflows healthy. Master branch clean. -**Reference docs**: .github/workflows/shell-quality.yml (in master), PR #69 (merged), Issue #62 (closed) -**Ready state**: Clean master branch, all tests passing, all CI healthy, ready for new work +Read CLAUDE.md to understand our workflow, then verify dotfiles PR #72 CI status and merge if green. -**Expected scope**: Review GitHub issues, select next priority (enhancement, bug fix, or infrastructure), create feature branch, begin TDD implementation -``` +**Immediate priority**: Merge maxrantil/dotfiles#72 after CI passes +**Context**: Fixed missing .zshenv bug that broke aliases in non-login shells +**Reference docs**: maxrantil/vm-infra#114, SESSION_HANDOVER.md (this file) +**Ready state**: PR pushed, awaiting CI validation ---- +**Expected scope**: Merge PR, verify in fresh VM, close issue #114 ## 📚 Key Reference Documents - -**In Master Branch:** -- `.github/workflows/shell-quality.yml` - Updated with shfmt caching (commit 667c348) -- `rollback.sh` - Automated rollback script (from Issue #61) -- `tests/rollback-test.sh` - Comprehensive test suite -- `README.md` - User documentation -- `CLAUDE.md` - Development workflow guidelines - -**GitHub:** -- Issue #62: ✅ Closed (CI optimization - shfmt caching) -- PR #69: ✅ Merged (squash merge to master) -- Issue #61: ✅ Closed (automated rollback script) -- PR #67: ✅ Merged (rollback implementation) -- PR #68: ✅ Merged (workflow permissions fix) - ---- - -## 🎉 Session Accomplishments - -**Features Delivered:** -1. ✅ CI optimization - shfmt binary caching (Issue #62) - - GitHub Actions cache integration - - Conditional installation - - PATH configuration - - Verified working in CI (cache hit confirmed) - - Merged to master - -**Quality Achievements:** -- 12/12 CI checks passing -- Clean, minimal changes -- No functionality broken -- Caching verified with re-run test -- Pre-commit hooks satisfied -- Test plan 100% complete - -**Process Achievements:** -- Issue → branch → implementation → PR → merge workflow followed -- CLAUDE.md guidelines adhered to -- Test plan fully executed -- Cache hit verified before merge -- Session handoff completed properly -- Clear continuation path - ---- - -## 🔄 Handoff Checklist Completion - -- [x] **Step 1**: Issue completion verified - - Issue #62: ✅ Closed - - PR #69: ✅ Merged to master - - All tests passing - - Clean working directory - - Cache functionality verified - -- [x] **Step 2**: Session handoff document updated - - SESSION_HANDOVER.md updated with merge status - - Work documented completely - - Metrics captured - - Cache verification documented - -- [x] **Step 3**: Documentation cleanup - - No new docs required (workflow change only) - - All references valid - - Master branch clean - -- [x] **Step 4**: Strategic planning - - Next steps clear: review issues, select priority - - No agent consultation needed - - Context preserved for continuation - -- [x] **Step 5**: Startup prompt generated - - Begins with "Read CLAUDE.md..." - - Previous work summarized (Issue #62 merged) - - Next priority identified - - Context provided - - Expected scope defined - -- [x] **Step 6**: Final verification - - SESSION_HANDOVER.md committed to master - - Working directory: clean - - All tests: confirmed passing - - Startup prompt: clarity confirmed - - Ready for new work - ---- - -**Status**: ✅ **SESSION HANDOFF COMPLETE - READY FOR NEXT SESSION** - -**Next Session Start**: Review open issues → select priority → create branch → begin TDD implementation - ---- - -## 📜 Previous Session Archive - -
-Session: Issue #61 + Workflow Permissions Fix (2025-11-04) - -### Completed Work -- Issue #61: Automated rollback script ✅ merged (PR #67) -- Workflow permissions fix ✅ merged (PR #68) -- 780 lines added (196 script + 350 tests + 234 docs) -- 5 agent validations completed -- Security hardening: 3 HIGH + 4 MEDIUM issues fixed - -### Key Achievements -- Production-ready rollback capability -- All CI/CD workflows healthy -- 100% test pass rate -- Security-validated codebase - -See git history for full details. -
- ---- +- maxrantil/vm-infra#114 (bug report) +- maxrantil/dotfiles#72 (fix PR) +- `.zshenv` (new file with XDG/ZDOTDIR setup) +- `install.sh` (updated with .zshenv symlinking)