diff --git a/CHANGELOG.md b/CHANGELOG.md index ae3fd5a..5d38c3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,21 @@ CalVer image tags (`stable-YYYY.MM.N`, `dev-YYYY.MM.N`) are produced for every C ## [Unreleased] +### Fixed +- `agnes init` now runs `_chmod_workspace_hooks(workspace)` for OVERRIDE + mode too (Initial Workspace Template seed-repo flow), not just the + DEFAULT path. Override-mode workspaces seeded from an admin's + template repo were leaving hooks like + `.claude/hooks/skill-nudge/nudge.sh` and + `.claude/hooks/prompt-history/log-prompt.sh` non-executable when + the seed repo's git checkout didn't preserve the +x bit + (`core.filemode=false`, archive extractions, FUSE/NFS mounts), and + every SessionStart fired `Permission denied`. The chmod helper + already recurses (`rglob`) so subdir-scoped hook layouts were + covered — the bug was that the call site sat inside the + `if not override_active:` block. Moved out to a common step + before the first pull so every init path runs it. + ## [0.55.4] — 2026-05-19 ### Security diff --git a/cli/commands/init.py b/cli/commands/init.py index b35d555..dffe817 100644 --- a/cli/commands/init.py +++ b/cli/commands/init.py @@ -493,7 +493,6 @@ def init( ), encoding="utf-8") install_claude_hooks(workspace) install_claude_commands(workspace) - _chmod_workspace_hooks(workspace) # ------------------------------------------------------------------ # Step 6: CLAUDE.local.md stub — only when absent. `--force` does NOT @@ -511,6 +510,22 @@ def init( encoding="utf-8", ) + # ------------------------------------------------------------------ + # Always chmod +x hook scripts that landed on disk, regardless of + # which path seeded the workspace. In DEFAULT mode the hooks come + # from `install_claude_hooks` above; in OVERRIDE mode they come + # from the admin's initial-workspace-template clone — and `git + # checkout` of that template doesn't reliably preserve the +x bit + # (filemode=false repos, archive extractions, FUSE/NFS mounts), + # so hooks like `.claude/hooks/skill-nudge/nudge.sh` or + # `.claude/hooks/prompt-history/log-prompt.sh` could land non- + # executable and fire `Permission denied` on the very next + # SessionStart. `_chmod_workspace_hooks` recurses (`rglob`) so + # subdir-scoped hook layouts are covered. Best-effort, no-op on + # Windows NTFS. + # ------------------------------------------------------------------ + _chmod_workspace_hooks(workspace) + # ------------------------------------------------------------------ # Step 7: first pull. `run_pull` records per-stage failures inside # `result.errors` rather than raising for transient issues, so any